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 | ||
