X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fparisc%2Fsba_iommu.c;h=8c4d2c13d5f246057a42d73ac518637973fca79e;hb=b33d24c4cc14ee40d83a7e1ea0bfb9567d6059aa;hp=f1e7ccd5475bb413888272112e1937d67e4d5f36;hpb=ee9f4b5d95d03d1546f0d06cbe384bd4ab97bcba;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index f1e7ccd..8c4d2c1 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -109,12 +111,10 @@ static unsigned long piranha_bad_128k = 0; #ifdef SBA_AGP_SUPPORT static int sba_reserve_agpgart = 1; -module_param(sba_reserve_agpgart, int, 1); +module_param(sba_reserve_agpgart, int, 0444); MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART"); #endif -#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1)) - /************************************ ** SBA register read and write support @@ -314,6 +314,12 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) #define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n))) #define RESMAP_IDX_MASK (sizeof(unsigned long) - 1) +static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr, + unsigned int bitshiftcnt) +{ + return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3) + + bitshiftcnt; +} /** * sba_search_bitmap - find free space in IO PDIR resource bitmap @@ -325,19 +331,36 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) * Cool perf optimization: search for log2(size) bits at a time. */ static SBA_INLINE unsigned long -sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) +sba_search_bitmap(struct ioc *ioc, struct device *dev, + unsigned long bits_wanted) { unsigned long *res_ptr = ioc->res_hint; unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]); - unsigned long pide = ~0UL; + unsigned long pide = ~0UL, tpide; + unsigned long boundary_size; + unsigned long shift; + int ret; + + boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1, + 1ULL << IOVP_SHIFT) >> IOVP_SHIFT; + +#if defined(ZX1_SUPPORT) + BUG_ON(ioc->ibase & ~IOVP_MASK); + shift = ioc->ibase >> IOVP_SHIFT; +#else + shift = 0; +#endif if (bits_wanted > (BITS_PER_LONG/2)) { /* Search word at a time - no mask needed */ for(; res_ptr < res_end; ++res_ptr) { - if (*res_ptr == 0) { + tpide = ptr_to_pide(ioc, res_ptr, 0); + ret = iommu_is_span_boundary(tpide, bits_wanted, + shift, + boundary_size); + if ((*res_ptr == 0) && !ret) { *res_ptr = RESMAP_MASK(bits_wanted); - pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map); - pide <<= 3; /* convert to bit address */ + pide = tpide; break; } } @@ -352,7 +375,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) ** SBA HW features in the unmap path. */ unsigned long o = 1 << get_order(bits_wanted << PAGE_SHIFT); - uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o); + uint bitshiftcnt = ALIGN(ioc->res_bitshift, o); unsigned long mask; if (bitshiftcnt >= BITS_PER_LONG) { @@ -366,11 +389,13 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) { DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr); WARN_ON(mask == 0); - if(((*res_ptr) & mask) == 0) { + tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt); + ret = iommu_is_span_boundary(tpide, bits_wanted, + shift, + boundary_size); + if ((((*res_ptr) & mask) == 0) && !ret) { *res_ptr |= mask; /* mark resources busy! */ - pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map); - pide <<= 3; /* convert to bit address */ - pide += bitshiftcnt; + pide = tpide; break; } mask >>= o; @@ -405,7 +430,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) * resource bit map. */ static int -sba_alloc_range(struct ioc *ioc, size_t size) +sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size) { unsigned int pages_needed = size >> IOVP_SHIFT; #ifdef SBA_COLLECT_STATS @@ -413,9 +438,9 @@ sba_alloc_range(struct ioc *ioc, size_t size) #endif unsigned long pide; - pide = sba_search_bitmap(ioc, pages_needed); + pide = sba_search_bitmap(ioc, dev, pages_needed); if (pide >= (ioc->res_size << 3)) { - pide = sba_search_bitmap(ioc, pages_needed); + pide = sba_search_bitmap(ioc, dev, pages_needed); if (pide >= (ioc->res_size << 3)) panic("%s: I/O MMU @ %p is out of mapping resources\n", __FILE__, ioc->ioc_hpa); @@ -711,7 +736,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, ioc->msingle_calls++; ioc->msingle_pages += size >> IOVP_SHIFT; #endif - pide = sba_alloc_range(ioc, size); + pide = sba_alloc_range(ioc, dev, size); iovp = (dma_addr_t) pide << IOVP_SHIFT; DBG_RUN("%s() 0x%p -> 0x%lx\n", @@ -779,7 +804,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, offset = iova & ~IOVP_MASK; iova ^= offset; /* clear offset bits */ size += offset; - size = ROUNDUP(size, IOVP_SIZE); + size = ALIGN(size, IOVP_SIZE); spin_lock_irqsave(&ioc->res_lock, flags); @@ -846,7 +871,7 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size, if (!hwdev) { /* only support PCI */ *dma_handle = 0; - return 0; + return NULL; } ret = (void *) __get_free_pages(gfp, get_order(size)); @@ -947,7 +972,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, ** w/o this association, we wouldn't have coherent DMA! ** Access to the virtual address is what forces a two pass algorithm. */ - coalesced = iommu_coalesce_chunks(ioc, sglist, nents, sba_alloc_range); + coalesced = iommu_coalesce_chunks(ioc, dev, sglist, nents, sba_alloc_range); /* ** Program the I/O Pdir @@ -1799,7 +1824,7 @@ sba_proc_open(struct inode *i, struct file *f) return single_open(f, &sba_proc_info, NULL); } -static struct file_operations sba_proc_fops = { +static const struct file_operations sba_proc_fops = { .owner = THIS_MODULE, .open = sba_proc_open, .read = seq_read, @@ -1831,7 +1856,7 @@ sba_proc_bitmap_open(struct inode *i, struct file *f) return single_open(f, &sba_proc_bitmap_info, NULL); } -static struct file_operations sba_proc_bitmap_fops = { +static const struct file_operations sba_proc_bitmap_fops = { .owner = THIS_MODULE, .open = sba_proc_bitmap_open, .read = seq_read, @@ -1911,8 +1936,8 @@ sba_driver_callback(struct parisc_device *dev) global_ioc_cnt *= 2; } - printk(KERN_INFO "%s found %s at 0x%lx\n", - MODULE_NAME, version, dev->hpa.start); + printk(KERN_INFO "%s found %s at 0x%llx\n", + MODULE_NAME, version, (unsigned long long)dev->hpa.start); sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL); if (!sba_dev) {