aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parisc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parisc')
-rw-r--r--drivers/parisc/Kconfig5
-rw-r--r--drivers/parisc/ccio-dma.c27
-rw-r--r--drivers/parisc/iommu-helpers.h6
-rw-r--r--drivers/parisc/pdc_stable.c6
-rw-r--r--drivers/parisc/sba_iommu.c52
5 files changed, 68 insertions, 28 deletions
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig
index 1d3b84b4af3f..553a9905299a 100644
--- a/drivers/parisc/Kconfig
+++ b/drivers/parisc/Kconfig
@@ -103,6 +103,11 @@ config IOMMU_SBA
103 depends on PCI_LBA 103 depends on PCI_LBA
104 default PCI_LBA 104 default PCI_LBA
105 105
106config IOMMU_HELPER
107 bool
108 depends on IOMMU_SBA || IOMMU_CCIO
109 default y
110
106#config PCI_EPIC 111#config PCI_EPIC
107# bool "EPIC/SAGA PCI support" 112# bool "EPIC/SAGA PCI support"
108# depends on PCI 113# depends on PCI
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index d08b284de196..62db3c3fe4dc 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)]); \
@@ -341,10 +346,11 @@ static int ioc_count;
341 * of available pages for the requested size. 346 * of available pages for the requested size.
342 */ 347 */
343static int 348static int
344ccio_alloc_range(struct ioc *ioc, size_t size) 349ccio_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, 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((unsigned long long)dma_get_seg_boundary(dev) + 1,
370 1ULL << IOVP_SHIFT) >> 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
@@ -760,7 +769,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size,
760 ioc->msingle_pages += size >> IOVP_SHIFT; 769 ioc->msingle_pages += size >> IOVP_SHIFT;
761#endif 770#endif
762 771
763 idx = ccio_alloc_range(ioc, size); 772 idx = ccio_alloc_range(ioc, dev, size);
764 iovp = (dma_addr_t)MKIOVP(idx); 773 iovp = (dma_addr_t)MKIOVP(idx);
765 774
766 pdir_start = &(ioc->pdir_base[idx]); 775 pdir_start = &(ioc->pdir_base[idx]);
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h
index 97ba8286c596..a9c46cc2db37 100644
--- a/drivers/parisc/iommu-helpers.h
+++ b/drivers/parisc/iommu-helpers.h
@@ -96,8 +96,8 @@ iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents,
96 96
97static inline unsigned int 97static inline unsigned int
98iommu_coalesce_chunks(struct ioc *ioc, struct device *dev, 98iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
99 struct scatterlist *startsg, int nents, 99 struct scatterlist *startsg, int nents,
100 int (*iommu_alloc_range)(struct ioc *, size_t)) 100 int (*iommu_alloc_range)(struct ioc *, struct device *, size_t))
101{ 101{
102 struct scatterlist *contig_sg; /* contig chunk head */ 102 struct scatterlist *contig_sg; /* contig chunk head */
103 unsigned long dma_offset, dma_len; /* start/len of DMA stream */ 103 unsigned long dma_offset, dma_len; /* start/len of DMA stream */
@@ -166,7 +166,7 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
166 dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE); 166 dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE);
167 sg_dma_address(contig_sg) = 167 sg_dma_address(contig_sg) =
168 PIDE_FLAG 168 PIDE_FLAG
169 | (iommu_alloc_range(ioc, dma_len) << IOVP_SHIFT) 169 | (iommu_alloc_range(ioc, dev, dma_len) << IOVP_SHIFT)
170 | dma_offset; 170 | dma_offset;
171 n_mappings++; 171 n_mappings++;
172 } 172 }
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index de34aa9d3136..f9f9a5f1bbd0 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -829,7 +829,7 @@ static ssize_t pdcs_autoboot_write(struct kobject *kobj,
829 struct kobj_attribute *attr, 829 struct kobj_attribute *attr,
830 const char *buf, size_t count) 830 const char *buf, size_t count)
831{ 831{
832 return pdcs_auto_write(kset, attr, buf, count, PF_AUTOBOOT); 832 return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOBOOT);
833} 833}
834 834
835/** 835/**
@@ -845,7 +845,7 @@ static ssize_t pdcs_autosearch_write(struct kobject *kobj,
845 struct kobj_attribute *attr, 845 struct kobj_attribute *attr,
846 const char *buf, size_t count) 846 const char *buf, size_t count)
847{ 847{
848 return pdcs_auto_write(kset, attr, buf, count, PF_AUTOSEARCH); 848 return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOSEARCH);
849} 849}
850 850
851/** 851/**
@@ -1066,7 +1066,7 @@ pdc_stable_init(void)
1066 } 1066 }
1067 1067
1068 /* Don't forget the root entries */ 1068 /* Don't forget the root entries */
1069 error = sysfs_create_group(stable_kobj, pdcs_attr_group); 1069 error = sysfs_create_group(stable_kobj, &pdcs_attr_group);
1070 1070
1071 /* register the paths kset as a child of the stable kset */ 1071 /* register the paths kset as a child of the stable kset */
1072 paths_kset = kset_create_and_add("paths", NULL, stable_kobj); 1072 paths_kset = kset_create_and_add("paths", NULL, stable_kobj);
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index d06627c3f353..8c4d2c13d5f2 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -29,6 +29,7 @@
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/scatterlist.h> 31#include <linux/scatterlist.h>
32#include <linux/iommu-helper.h>
32 33
33#include <asm/byteorder.h> 34#include <asm/byteorder.h>
34#include <asm/io.h> 35#include <asm/io.h>
@@ -313,6 +314,12 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
313#define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n))) 314#define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n)))
314#define RESMAP_IDX_MASK (sizeof(unsigned long) - 1) 315#define RESMAP_IDX_MASK (sizeof(unsigned long) - 1)
315 316
317static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr,
318 unsigned int bitshiftcnt)
319{
320 return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3)
321 + bitshiftcnt;
322}
316 323
317/** 324/**
318 * sba_search_bitmap - find free space in IO PDIR resource bitmap 325 * sba_search_bitmap - find free space in IO PDIR resource bitmap
@@ -324,19 +331,36 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
324 * Cool perf optimization: search for log2(size) bits at a time. 331 * Cool perf optimization: search for log2(size) bits at a time.
325 */ 332 */
326static SBA_INLINE unsigned long 333static SBA_INLINE unsigned long
327sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) 334sba_search_bitmap(struct ioc *ioc, struct device *dev,
335 unsigned long bits_wanted)
328{ 336{
329 unsigned long *res_ptr = ioc->res_hint; 337 unsigned long *res_ptr = ioc->res_hint;
330 unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]); 338 unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
331 unsigned long pide = ~0UL; 339 unsigned long pide = ~0UL, tpide;
340 unsigned long boundary_size;
341 unsigned long shift;
342 int ret;
343
344 boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
345 1ULL << IOVP_SHIFT) >> IOVP_SHIFT;
346
347#if defined(ZX1_SUPPORT)
348 BUG_ON(ioc->ibase & ~IOVP_MASK);
349 shift = ioc->ibase >> IOVP_SHIFT;
350#else
351 shift = 0;
352#endif
332 353
333 if (bits_wanted > (BITS_PER_LONG/2)) { 354 if (bits_wanted > (BITS_PER_LONG/2)) {
334 /* Search word at a time - no mask needed */ 355 /* Search word at a time - no mask needed */
335 for(; res_ptr < res_end; ++res_ptr) { 356 for(; res_ptr < res_end; ++res_ptr) {
336 if (*res_ptr == 0) { 357 tpide = ptr_to_pide(ioc, res_ptr, 0);
358 ret = iommu_is_span_boundary(tpide, bits_wanted,
359 shift,
360 boundary_size);
361 if ((*res_ptr == 0) && !ret) {
337 *res_ptr = RESMAP_MASK(bits_wanted); 362 *res_ptr = RESMAP_MASK(bits_wanted);
338 pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map); 363 pide = tpide;
339 pide <<= 3; /* convert to bit address */
340 break; 364 break;
341 } 365 }
342 } 366 }
@@ -365,11 +389,13 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
365 { 389 {
366 DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr); 390 DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr);
367 WARN_ON(mask == 0); 391 WARN_ON(mask == 0);
368 if(((*res_ptr) & mask) == 0) { 392 tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
393 ret = iommu_is_span_boundary(tpide, bits_wanted,
394 shift,
395 boundary_size);
396 if ((((*res_ptr) & mask) == 0) && !ret) {
369 *res_ptr |= mask; /* mark resources busy! */ 397 *res_ptr |= mask; /* mark resources busy! */
370 pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map); 398 pide = tpide;
371 pide <<= 3; /* convert to bit address */
372 pide += bitshiftcnt;
373 break; 399 break;
374 } 400 }
375 mask >>= o; 401 mask >>= o;
@@ -404,7 +430,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
404 * resource bit map. 430 * resource bit map.
405 */ 431 */
406static int 432static int
407sba_alloc_range(struct ioc *ioc, size_t size) 433sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
408{ 434{
409 unsigned int pages_needed = size >> IOVP_SHIFT; 435 unsigned int pages_needed = size >> IOVP_SHIFT;
410#ifdef SBA_COLLECT_STATS 436#ifdef SBA_COLLECT_STATS
@@ -412,9 +438,9 @@ sba_alloc_range(struct ioc *ioc, size_t size)
412#endif 438#endif
413 unsigned long pide; 439 unsigned long pide;
414 440
415 pide = sba_search_bitmap(ioc, pages_needed); 441 pide = sba_search_bitmap(ioc, dev, pages_needed);
416 if (pide >= (ioc->res_size << 3)) { 442 if (pide >= (ioc->res_size << 3)) {
417 pide = sba_search_bitmap(ioc, pages_needed); 443 pide = sba_search_bitmap(ioc, dev, pages_needed);
418 if (pide >= (ioc->res_size << 3)) 444 if (pide >= (ioc->res_size << 3))
419 panic("%s: I/O MMU @ %p is out of mapping resources\n", 445 panic("%s: I/O MMU @ %p is out of mapping resources\n",
420 __FILE__, ioc->ioc_hpa); 446 __FILE__, ioc->ioc_hpa);
@@ -710,7 +736,7 @@ sba_map_single(struct device *dev, void *addr, size_t size,
710 ioc->msingle_calls++; 736 ioc->msingle_calls++;
711 ioc->msingle_pages += size >> IOVP_SHIFT; 737 ioc->msingle_pages += size >> IOVP_SHIFT;
712#endif 738#endif
713 pide = sba_alloc_range(ioc, size); 739 pide = sba_alloc_range(ioc, dev, size);
714 iovp = (dma_addr_t) pide << IOVP_SHIFT; 740 iovp = (dma_addr_t) pide << IOVP_SHIFT;
715 741
716 DBG_RUN("%s() 0x%p -> 0x%lx\n", 742 DBG_RUN("%s() 0x%p -> 0x%lx\n",