aboutsummaryrefslogtreecommitdiffstats
path: root/lib/swiotlb.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /lib/swiotlb.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'lib/swiotlb.c')
-rw-r--r--lib/swiotlb.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index ac25cd28e807..5fddf720da73 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -28,6 +28,7 @@
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/ctype.h> 29#include <linux/ctype.h>
30#include <linux/highmem.h> 30#include <linux/highmem.h>
31#include <linux/gfp.h>
31 32
32#include <asm/io.h> 33#include <asm/io.h>
33#include <asm/dma.h> 34#include <asm/dma.h>
@@ -97,6 +98,8 @@ static phys_addr_t *io_tlb_orig_addr;
97 */ 98 */
98static DEFINE_SPINLOCK(io_tlb_lock); 99static DEFINE_SPINLOCK(io_tlb_lock);
99 100
101static int late_alloc;
102
100static int __init 103static int __init
101setup_io_tlb_npages(char *str) 104setup_io_tlb_npages(char *str)
102{ 105{
@@ -109,6 +112,7 @@ setup_io_tlb_npages(char *str)
109 ++str; 112 ++str;
110 if (!strcmp(str, "force")) 113 if (!strcmp(str, "force"))
111 swiotlb_force = 1; 114 swiotlb_force = 1;
115
112 return 1; 116 return 1;
113} 117}
114__setup("swiotlb=", setup_io_tlb_npages); 118__setup("swiotlb=", setup_io_tlb_npages);
@@ -121,8 +125,9 @@ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
121 return phys_to_dma(hwdev, virt_to_phys(address)); 125 return phys_to_dma(hwdev, virt_to_phys(address));
122} 126}
123 127
124static void swiotlb_print_info(unsigned long bytes) 128void swiotlb_print_info(void)
125{ 129{
130 unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT;
126 phys_addr_t pstart, pend; 131 phys_addr_t pstart, pend;
127 132
128 pstart = virt_to_phys(io_tlb_start); 133 pstart = virt_to_phys(io_tlb_start);
@@ -140,7 +145,7 @@ static void swiotlb_print_info(unsigned long bytes)
140 * structures for the software IO TLB used to implement the DMA API. 145 * structures for the software IO TLB used to implement the DMA API.
141 */ 146 */
142void __init 147void __init
143swiotlb_init_with_default_size(size_t default_size) 148swiotlb_init_with_default_size(size_t default_size, int verbose)
144{ 149{
145 unsigned long i, bytes; 150 unsigned long i, bytes;
146 151
@@ -176,14 +181,14 @@ swiotlb_init_with_default_size(size_t default_size)
176 io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); 181 io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
177 if (!io_tlb_overflow_buffer) 182 if (!io_tlb_overflow_buffer)
178 panic("Cannot allocate SWIOTLB overflow buffer!\n"); 183 panic("Cannot allocate SWIOTLB overflow buffer!\n");
179 184 if (verbose)
180 swiotlb_print_info(bytes); 185 swiotlb_print_info();
181} 186}
182 187
183void __init 188void __init
184swiotlb_init(void) 189swiotlb_init(int verbose)
185{ 190{
186 swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */ 191 swiotlb_init_with_default_size(64 * (1<<20), verbose); /* default to 64MB */
187} 192}
188 193
189/* 194/*
@@ -260,7 +265,9 @@ swiotlb_late_init_with_default_size(size_t default_size)
260 if (!io_tlb_overflow_buffer) 265 if (!io_tlb_overflow_buffer)
261 goto cleanup4; 266 goto cleanup4;
262 267
263 swiotlb_print_info(bytes); 268 swiotlb_print_info();
269
270 late_alloc = 1;
264 271
265 return 0; 272 return 0;
266 273
@@ -281,6 +288,32 @@ cleanup1:
281 return -ENOMEM; 288 return -ENOMEM;
282} 289}
283 290
291void __init swiotlb_free(void)
292{
293 if (!io_tlb_overflow_buffer)
294 return;
295
296 if (late_alloc) {
297 free_pages((unsigned long)io_tlb_overflow_buffer,
298 get_order(io_tlb_overflow));
299 free_pages((unsigned long)io_tlb_orig_addr,
300 get_order(io_tlb_nslabs * sizeof(phys_addr_t)));
301 free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
302 sizeof(int)));
303 free_pages((unsigned long)io_tlb_start,
304 get_order(io_tlb_nslabs << IO_TLB_SHIFT));
305 } else {
306 free_bootmem_late(__pa(io_tlb_overflow_buffer),
307 io_tlb_overflow);
308 free_bootmem_late(__pa(io_tlb_orig_addr),
309 io_tlb_nslabs * sizeof(phys_addr_t));
310 free_bootmem_late(__pa(io_tlb_list),
311 io_tlb_nslabs * sizeof(int));
312 free_bootmem_late(__pa(io_tlb_start),
313 io_tlb_nslabs << IO_TLB_SHIFT);
314 }
315}
316
284static int is_swiotlb_buffer(phys_addr_t paddr) 317static int is_swiotlb_buffer(phys_addr_t paddr)
285{ 318{
286 return paddr >= virt_to_phys(io_tlb_start) && 319 return paddr >= virt_to_phys(io_tlb_start) &&
@@ -453,7 +486,7 @@ do_unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
453 486
454 /* 487 /*
455 * Return the buffer to the free list by setting the corresponding 488 * Return the buffer to the free list by setting the corresponding
456 * entries to indicate the number of contigous entries available. 489 * entries to indicate the number of contiguous entries available.
457 * While returning the entries to the free list, we merge the entries 490 * While returning the entries to the free list, we merge the entries
458 * with slots below and above the pool being returned. 491 * with slots below and above the pool being returned.
459 */ 492 */
@@ -517,7 +550,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
517 dma_mask = hwdev->coherent_dma_mask; 550 dma_mask = hwdev->coherent_dma_mask;
518 551
519 ret = (void *)__get_free_pages(flags, order); 552 ret = (void *)__get_free_pages(flags, order);
520 if (ret && swiotlb_virt_to_bus(hwdev, ret) + size > dma_mask) { 553 if (ret && swiotlb_virt_to_bus(hwdev, ret) + size - 1 > dma_mask) {
521 /* 554 /*
522 * The allocated memory isn't reachable by the device. 555 * The allocated memory isn't reachable by the device.
523 */ 556 */
@@ -539,7 +572,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
539 dev_addr = swiotlb_virt_to_bus(hwdev, ret); 572 dev_addr = swiotlb_virt_to_bus(hwdev, ret);
540 573
541 /* Confirm address can be DMA'd by device */ 574 /* Confirm address can be DMA'd by device */
542 if (dev_addr + size > dma_mask) { 575 if (dev_addr + size - 1 > dma_mask) {
543 printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", 576 printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n",
544 (unsigned long long)dma_mask, 577 (unsigned long long)dma_mask,
545 (unsigned long long)dev_addr); 578 (unsigned long long)dev_addr);