diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/swiotlb.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 45bc1f83a5ad..f114bf6a8e13 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -170,7 +170,7 @@ void __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) | |||
170 | * Statically reserve bounce buffer space and initialize bounce buffer data | 170 | * Statically reserve bounce buffer space and initialize bounce buffer data |
171 | * structures for the software IO TLB used to implement the DMA API. | 171 | * structures for the software IO TLB used to implement the DMA API. |
172 | */ | 172 | */ |
173 | void __init | 173 | static void __init |
174 | swiotlb_init_with_default_size(size_t default_size, int verbose) | 174 | swiotlb_init_with_default_size(size_t default_size, int verbose) |
175 | { | 175 | { |
176 | unsigned long bytes; | 176 | unsigned long bytes; |
@@ -206,8 +206,9 @@ swiotlb_init(int verbose) | |||
206 | int | 206 | int |
207 | swiotlb_late_init_with_default_size(size_t default_size) | 207 | swiotlb_late_init_with_default_size(size_t default_size) |
208 | { | 208 | { |
209 | unsigned long i, bytes, req_nslabs = io_tlb_nslabs; | 209 | unsigned long bytes, req_nslabs = io_tlb_nslabs; |
210 | unsigned int order; | 210 | unsigned int order; |
211 | int rc = 0; | ||
211 | 212 | ||
212 | if (!io_tlb_nslabs) { | 213 | if (!io_tlb_nslabs) { |
213 | io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); | 214 | io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); |
@@ -229,16 +230,32 @@ swiotlb_late_init_with_default_size(size_t default_size) | |||
229 | order--; | 230 | order--; |
230 | } | 231 | } |
231 | 232 | ||
232 | if (!io_tlb_start) | 233 | if (!io_tlb_start) { |
233 | goto cleanup1; | 234 | io_tlb_nslabs = req_nslabs; |
234 | 235 | return -ENOMEM; | |
236 | } | ||
235 | if (order != get_order(bytes)) { | 237 | if (order != get_order(bytes)) { |
236 | printk(KERN_WARNING "Warning: only able to allocate %ld MB " | 238 | printk(KERN_WARNING "Warning: only able to allocate %ld MB " |
237 | "for software IO TLB\n", (PAGE_SIZE << order) >> 20); | 239 | "for software IO TLB\n", (PAGE_SIZE << order) >> 20); |
238 | io_tlb_nslabs = SLABS_PER_PAGE << order; | 240 | io_tlb_nslabs = SLABS_PER_PAGE << order; |
239 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; | ||
240 | } | 241 | } |
242 | rc = swiotlb_late_init_with_tbl(io_tlb_start, io_tlb_nslabs); | ||
243 | if (rc) | ||
244 | free_pages((unsigned long)io_tlb_start, order); | ||
245 | return rc; | ||
246 | } | ||
247 | |||
248 | int | ||
249 | swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) | ||
250 | { | ||
251 | unsigned long i, bytes; | ||
252 | |||
253 | bytes = nslabs << IO_TLB_SHIFT; | ||
254 | |||
255 | io_tlb_nslabs = nslabs; | ||
256 | io_tlb_start = tlb; | ||
241 | io_tlb_end = io_tlb_start + bytes; | 257 | io_tlb_end = io_tlb_start + bytes; |
258 | |||
242 | memset(io_tlb_start, 0, bytes); | 259 | memset(io_tlb_start, 0, bytes); |
243 | 260 | ||
244 | /* | 261 | /* |
@@ -288,10 +305,8 @@ cleanup3: | |||
288 | io_tlb_list = NULL; | 305 | io_tlb_list = NULL; |
289 | cleanup2: | 306 | cleanup2: |
290 | io_tlb_end = NULL; | 307 | io_tlb_end = NULL; |
291 | free_pages((unsigned long)io_tlb_start, order); | ||
292 | io_tlb_start = NULL; | 308 | io_tlb_start = NULL; |
293 | cleanup1: | 309 | io_tlb_nslabs = 0; |
294 | io_tlb_nslabs = req_nslabs; | ||
295 | return -ENOMEM; | 310 | return -ENOMEM; |
296 | } | 311 | } |
297 | 312 | ||