|
@@ -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 @@ cleanup3:
|
|
|
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;
|
|
|
}
|
|
|
|