diff options
Diffstat (limited to 'arch/ia64/hp')
-rw-r--r-- | arch/ia64/hp/common/hwsw_iommu.c | 15 | ||||
-rw-r--r-- | arch/ia64/hp/common/sba_iommu.c | 47 | ||||
-rw-r--r-- | arch/ia64/hp/sim/simscsi.c | 13 |
3 files changed, 53 insertions, 22 deletions
diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 80f8ef013939..a5a5637507be 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -17,7 +17,7 @@ #include <asm/machvec.h> /* swiotlb declarations & definitions: */ -extern void swiotlb_init_with_default_size (size_t size); +extern int swiotlb_late_init_with_default_size (size_t size); extern ia64_mv_dma_alloc_coherent swiotlb_alloc_coherent; extern ia64_mv_dma_free_coherent swiotlb_free_coherent; extern ia64_mv_dma_map_single swiotlb_map_single; @@ -67,11 +67,20 @@ void hwsw_init (void) { /* default to a smallish 2MB sw I/O TLB */ - swiotlb_init_with_default_size (2 * (1<<20)); + if (swiotlb_late_init_with_default_size (2 * (1<<20)) != 0) { +#ifdef CONFIG_IA64_GENERIC + /* Better to have normal DMA than panic */ + printk(KERN_WARNING "%s: Failed to initialize software I/O TLB," + " reverting to hpzx1 platform vector\n", __FUNCTION__); + machvec_init("hpzx1"); +#else + panic("Unable to initialize software I/O TLB services"); +#endif + } } void * -hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags) +hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) { if (use_swiotlb(dev)) return swiotlb_alloc_coherent(dev, size, dma_handle, flags); diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 11957598a8b9..bdccd0b1eb60 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1076,7 +1076,7 @@ void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, int dir) * See Documentation/DMA-mapping.txt */ void * -sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags) +sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) { struct ioc *ioc; void *addr; @@ -2028,9 +2028,40 @@ static struct acpi_driver acpi_sba_ioc_driver = { static int __init sba_init(void) { + if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb")) + return 0; + acpi_bus_register_driver(&acpi_sba_ioc_driver); - if (!ioc_list) + if (!ioc_list) { +#ifdef CONFIG_IA64_GENERIC + extern int swiotlb_late_init_with_default_size (size_t size); + + /* + * If we didn't find something sba_iommu can claim, we + * need to setup the swiotlb and switch to the dig machvec. + */ + if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) + panic("Unable to find SBA IOMMU or initialize " + "software I/O TLB: Try machvec=dig boot option"); + machvec_init("dig"); +#else + panic("Unable to find SBA IOMMU: Try a generic or DIG kernel"); +#endif return 0; + } + +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB) + /* + * hpzx1_swiotlb needs to have a fairly small swiotlb bounce + * buffer setup to support devices with smaller DMA masks than + * sba_iommu can handle. + */ + if (ia64_platform_is("hpzx1_swiotlb")) { + extern void hwsw_init(void); + + hwsw_init(); + } +#endif #ifdef CONFIG_PCI { @@ -2048,18 +2079,6 @@ sba_init(void) subsys_initcall(sba_init); /* must be initialized after ACPI etc., but before any drivers... */ -extern void dig_setup(char**); -/* - * MAX_DMA_ADDRESS needs to be setup prior to paging_init to do any good, - * so we use the platform_setup hook to fix it up. - */ -void __init -sba_setup(char **cmdline_p) -{ - MAX_DMA_ADDRESS = ~0UL; - dig_setup(cmdline_p); -} - static int __init nosbagart(char *str) { diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index a18983a3c934..a3fe97531134 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c @@ -205,10 +205,11 @@ simscsi_get_disk_size (int fd) char buf[512]; /* - * This is a bit kludgey: the simulator doesn't provide a direct way of determining - * the disk size, so we do a binary search, assuming a maximum disk size of 4GB. + * This is a bit kludgey: the simulator doesn't provide a + * direct way of determining the disk size, so we do a binary + * search, assuming a maximum disk size of 128GB. */ - for (bit = (4UL << 30)/512; bit != 0; bit >>= 1) { + for (bit = (128UL << 30)/512; bit != 0; bit >>= 1) { req.addr = __pa(&buf); req.len = sizeof(buf); ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ); @@ -225,8 +226,10 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode) { unsigned long offset; - offset = ( (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16) - | (sc->cmnd[4] << 8) | (sc->cmnd[5] << 0))*512; + offset = (((unsigned long)sc->cmnd[2] << 24) + | ((unsigned long)sc->cmnd[3] << 16) + | ((unsigned long)sc->cmnd[4] << 8) + | ((unsigned long)sc->cmnd[5] << 0))*512UL; if (sc->use_sg > 0) simscsi_sg_readwrite(sc, mode, offset); else |