Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 74838b75 authored by Konrad Rzeszutek Wilk's avatar Konrad Rzeszutek Wilk
Browse files

swiotlb: add the late swiotlb initialization function with iotlb memory



This enables the caller to initialize swiotlb with its own iotlb
memory late in the bootup.

See git commit eb605a57
"swiotlb: add swiotlb_tbl_map_single library function" which will
explain the full details of what it can be used for.

CC: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
[v1: Fold in smatch warning]
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent fc2341df
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ extern int swiotlb_force;
extern void swiotlb_init(int verbose);
extern void swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose);
extern unsigned long swiotlb_nr_tbl(void);
extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs);

/*
 * Enumeration for sync targets
+24 −9
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ void __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
 * Statically reserve bounce buffer space and initialize bounce buffer data
 * structures for the software IO TLB used to implement the DMA API.
 */
void __init
static void __init
swiotlb_init_with_default_size(size_t default_size, int verbose)
{
	unsigned long bytes;
@@ -206,8 +206,9 @@ swiotlb_init(int verbose)
int
swiotlb_late_init_with_default_size(size_t default_size)
{
	unsigned long i, bytes, req_nslabs = io_tlb_nslabs;
	unsigned long bytes, req_nslabs = io_tlb_nslabs;
	unsigned int order;
	int rc = 0;

	if (!io_tlb_nslabs) {
		io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
@@ -229,16 +230,32 @@ swiotlb_late_init_with_default_size(size_t default_size)
		order--;
	}

	if (!io_tlb_start)
		goto cleanup1;

	if (!io_tlb_start) {
		io_tlb_nslabs = req_nslabs;
		return -ENOMEM;
	}
	if (order != get_order(bytes)) {
		printk(KERN_WARNING "Warning: only able to allocate %ld MB "
		       "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
		io_tlb_nslabs = SLABS_PER_PAGE << order;
		bytes = io_tlb_nslabs << IO_TLB_SHIFT;
	}
	rc = swiotlb_late_init_with_tbl(io_tlb_start, io_tlb_nslabs);
	if (rc)
		free_pages((unsigned long)io_tlb_start, order);
	return rc;
}

int
swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
{
	unsigned long i, bytes;

	bytes = nslabs << IO_TLB_SHIFT;

	io_tlb_nslabs = nslabs;
	io_tlb_start = tlb;
	io_tlb_end = io_tlb_start + bytes;

	memset(io_tlb_start, 0, bytes);

	/*
@@ -288,10 +305,8 @@ swiotlb_late_init_with_default_size(size_t default_size)
	io_tlb_list = NULL;
cleanup2:
	io_tlb_end = NULL;
	free_pages((unsigned long)io_tlb_start, order);
	io_tlb_start = NULL;
cleanup1:
	io_tlb_nslabs = req_nslabs;
	io_tlb_nslabs = 0;
	return -ENOMEM;
}