aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parisc/ccio-dma.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-03-04 17:29:28 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-03-04 19:35:17 -0500
commit466634488e80968f12e73dd1fe6af5c37a1fbfe2 (patch)
treed738011402f57e5366c42bd4b2a525637ffdbcd1 /drivers/parisc/ccio-dma.c
parent7c8cda625acd9b704100994626fb6d2fb4ffb9c2 (diff)
iommu: parisc: make the IOMMUs respect the segment boundary limits
Make PARISC's two IOMMU implementations not allocate a memory area spanning LLD's segment boundary. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Kyle McMartin <kyle@parisc-linux.org> Cc: Matthew Wilcox <matthew@wil.cx> Cc: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/parisc/ccio-dma.c')
-rw-r--r--drivers/parisc/ccio-dma.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 1695facfca3a..60d338cd8009 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -43,6 +43,7 @@
43#include <linux/proc_fs.h> 43#include <linux/proc_fs.h>
44#include <linux/seq_file.h> 44#include <linux/seq_file.h>
45#include <linux/scatterlist.h> 45#include <linux/scatterlist.h>
46#include <linux/iommu-helper.h>
46 47
47#include <asm/byteorder.h> 48#include <asm/byteorder.h>
48#include <asm/cache.h> /* for L1_CACHE_BYTES */ 49#include <asm/cache.h> /* for L1_CACHE_BYTES */
@@ -302,13 +303,17 @@ static int ioc_count;
302*/ 303*/
303#define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \ 304#define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \
304 for(; res_ptr < res_end; ++res_ptr) { \ 305 for(; res_ptr < res_end; ++res_ptr) { \
305 if(0 == (*res_ptr & mask)) { \ 306 int ret;\
306 *res_ptr |= mask; \ 307 unsigned int idx;\
307 res_idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \ 308 idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
308 ioc->res_hint = res_idx + (size >> 3); \ 309 ret = iommu_is_span_boundary(idx << 3, pages_needed, 0, boundary_size);\
309 goto resource_found; \ 310 if ((0 == (*res_ptr & mask)) && !ret) { \
310 } \ 311 *res_ptr |= mask; \
311 } 312 res_idx = idx;\
313 ioc->res_hint = res_idx + (size >> 3); \
314 goto resource_found; \
315 } \
316 }
312 317
313#define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \ 318#define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \
314 u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \ 319 u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \
@@ -345,6 +350,7 @@ ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
345{ 350{
346 unsigned int pages_needed = size >> IOVP_SHIFT; 351 unsigned int pages_needed = size >> IOVP_SHIFT;
347 unsigned int res_idx; 352 unsigned int res_idx;
353 unsigned long boundary_size;
348#ifdef CCIO_SEARCH_TIME 354#ifdef CCIO_SEARCH_TIME
349 unsigned long cr_start = mfctl(16); 355 unsigned long cr_start = mfctl(16);
350#endif 356#endif
@@ -360,6 +366,9 @@ ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
360 ** ggg sacrifices another 710 to the computer gods. 366 ** ggg sacrifices another 710 to the computer gods.
361 */ 367 */
362 368
369 boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, 1 << IOVP_SHIFT);
370 boundary_size >>= IOVP_SHIFT;
371
363 if (pages_needed <= 8) { 372 if (pages_needed <= 8) {
364 /* 373 /*
365 * LAN traffic will not thrash the TLB IFF the same NIC 374 * LAN traffic will not thrash the TLB IFF the same NIC