From: James Bottomley pci_dev.consistent_dma_mask was introduced to get around problems in the IA64 Altix machine. Now, we have a use for it in x86: the aacraid needs coherent memory in a 31 bit address range (2GB). Unfortunately, x86 is converted to the dma model, so it can't see the pci_dev by the time coherent memory is allocated. The solution to all of this is to move pci_dev.consistent_dma_mask to dev.coherent_dma_mask and make x86 use it in the dma_alloc_coherent() calls. This should allow me to make the aacraid set the coherent mask instead of using it's current dma_mask juggling. --- 25-akpm/arch/i386/kernel/pci-dma.c | 3 ++- 25-akpm/arch/parisc/kernel/drivers.c | 1 + 25-akpm/arch/parisc/kernel/pci-dma.c | 2 +- 25-akpm/drivers/eisa/eisa-bus.c | 1 + 25-akpm/drivers/mca/mca-bus.c | 1 + 25-akpm/drivers/pci/pci.c | 2 +- 25-akpm/drivers/pci/probe.c | 2 +- 25-akpm/include/linux/device.h | 6 ++++++ 25-akpm/include/linux/pci.h | 5 ----- 25-akpm/sound/core/memalloc.c | 8 ++++---- 10 files changed, 18 insertions(+), 13 deletions(-) diff -puN arch/i386/kernel/pci-dma.c~move-dma_consistent_dma_mask arch/i386/kernel/pci-dma.c --- 25/arch/i386/kernel/pci-dma.c~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/arch/i386/kernel/pci-dma.c Thu Feb 26 14:41:01 2004 @@ -20,8 +20,9 @@ void *dma_alloc_coherent(struct device * /* ignore region specifiers */ gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); - if (dev == NULL || (*dev->dma_mask < 0xffffffff)) + if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) gfp |= GFP_DMA; + ret = (void *)__get_free_pages(gfp, get_order(size)); if (ret != NULL) { diff -puN arch/parisc/kernel/drivers.c~move-dma_consistent_dma_mask arch/parisc/kernel/drivers.c --- 25/arch/parisc/kernel/drivers.c~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/arch/parisc/kernel/drivers.c Thu Feb 26 14:41:01 2004 @@ -618,6 +618,7 @@ static void parisc_generic_device_regist tmp1); /* make the generic dma mask a pointer to the parisc one */ dev->dev.dma_mask = &dev->dma_mask; + dev->dev.coherent_dma_mask = dev->dma_mask; pr_debug("device_register(%s)\n", dev->dev.bus_id); device_register(&dev->dev); } diff -puN arch/parisc/kernel/pci-dma.c~move-dma_consistent_dma_mask arch/parisc/kernel/pci-dma.c --- 25/arch/parisc/kernel/pci-dma.c~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/arch/parisc/kernel/pci-dma.c Thu Feb 26 14:41:01 2004 @@ -372,7 +372,7 @@ static void * pa11_dma_alloc_consistent ** ISA cards will certainly only support 24-bit DMA addressing. ** Not clear if we can, want, or need to support ISA. */ - if (!dev || *dev->dma_mask != 0xffffffff) + if (!dev || *dev->coherent_dma_mask < 0xffffffff) gfp |= GFP_DMA; #endif return (void *)vaddr; diff -puN drivers/eisa/eisa-bus.c~move-dma_consistent_dma_mask drivers/eisa/eisa-bus.c --- 25/drivers/eisa/eisa-bus.c~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/drivers/eisa/eisa-bus.c Thu Feb 26 14:41:01 2004 @@ -187,6 +187,7 @@ static int __init eisa_init_device (stru edev->dev.parent = root->dev; edev->dev.bus = &eisa_bus_type; edev->dev.dma_mask = &edev->dma_mask; + edev->dev.coherent_dma_mask = edev->dma_mask; sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot); for (i = 0; i < EISA_MAX_RESOURCES; i++) { diff -puN drivers/mca/mca-bus.c~move-dma_consistent_dma_mask drivers/mca/mca-bus.c --- 25/drivers/mca/mca-bus.c~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/drivers/mca/mca-bus.c Thu Feb 26 14:41:01 2004 @@ -106,6 +106,7 @@ int __init mca_register_device(int bus, sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot); mca_dev->dma_mask = mca_bus->default_dma_mask; mca_dev->dev.dma_mask = &mca_dev->dma_mask; + mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask; if (device_register(&mca_dev->dev)) return 0; diff -puN drivers/pci/pci.c~move-dma_consistent_dma_mask drivers/pci/pci.c --- 25/drivers/pci/pci.c~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/drivers/pci/pci.c Thu Feb 26 14:41:01 2004 @@ -686,7 +686,7 @@ pci_set_consistent_dma_mask(struct pci_d if (!pci_dma_supported(dev, mask)) return -EIO; - dev->consistent_dma_mask = mask; + dev->dev.coherent_dma_mask = mask; return 0; } diff -puN drivers/pci/probe.c~move-dma_consistent_dma_mask drivers/pci/probe.c --- 25/drivers/pci/probe.c~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/drivers/pci/probe.c Thu Feb 26 14:41:01 2004 @@ -570,7 +570,6 @@ pci_scan_device(struct pci_bus *bus, int /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) set this higher, assuming the system even supports it. */ dev->dma_mask = 0xffffffff; - dev->consistent_dma_mask = 0xffffffff; if (pci_setup_device(dev) < 0) { kfree(dev); return NULL; @@ -582,6 +581,7 @@ pci_scan_device(struct pci_bus *bus, int pci_name_device(dev); dev->dev.dma_mask = &dev->dma_mask; + dev->dev.coherent_dma_mask = 0xffffffffull; return dev; } diff -puN include/linux/device.h~move-dma_consistent_dma_mask include/linux/device.h --- 25/include/linux/device.h~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/include/linux/device.h Thu Feb 26 14:41:01 2004 @@ -285,6 +285,12 @@ struct device { detached from its driver. */ u64 *dma_mask; /* dma mask (if dma'able device) */ + u64 coherent_dma_mask;/* Like dma_mask, but for + alloc_coherent mappings as + not all hardware supports + 64 bit addresses for consistent + allocations such descriptors. */ + struct list_head dma_pools; /* dma pools (if dma'ble) */ void (*release)(struct device * dev); diff -puN include/linux/pci.h~move-dma_consistent_dma_mask include/linux/pci.h --- 25/include/linux/pci.h~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/include/linux/pci.h Thu Feb 26 14:41:01 2004 @@ -392,11 +392,6 @@ struct pci_dev { this if your device has broken DMA or supports 64-bit transfers. */ - u64 consistent_dma_mask;/* Like dma_mask, but for - pci_alloc_consistent mappings as - not all hardware supports - 64 bit addresses for consistent - allocations such descriptors. */ u32 current_state; /* Current operating state. In ACPI-speak, this is D0-D3, D0 being fully functional, and D3 being off. */ diff -puN sound/core/memalloc.c~move-dma_consistent_dma_mask sound/core/memalloc.c --- 25/sound/core/memalloc.c~move-dma_consistent_dma_mask Thu Feb 26 14:41:01 2004 +++ 25-akpm/sound/core/memalloc.c Thu Feb 26 14:41:01 2004 @@ -100,13 +100,13 @@ static void *snd_pci_hack_alloc_consiste if (hwdev == NULL) return pci_alloc_consistent(hwdev, size, dma_handle); dma_mask = hwdev->dma_mask; - cdma_mask = hwdev->consistent_dma_mask; + cdma_mask = hwdev->dev.coherent_dma_mask; mask = (unsigned long)dma_mask && (unsigned long)cdma_mask; hwdev->dma_mask = 0xffffffff; /* do without masking */ - hwdev->consistent_dma_mask = 0xffffffff; /* do without masking */ + hwdev->dev.coherent_dma_mask = 0xffffffff; /* do without masking */ ret = pci_alloc_consistent(hwdev, size, dma_handle); hwdev->dma_mask = dma_mask; /* restore */ - hwdev->consistent_dma_mask = cdma_mask; /* restore */ + hwdev->dev.coherent_dma_mask = cdma_mask; /* restore */ if (ret) { /* obtained address is out of range? */ if (((unsigned long)*dma_handle + size - 1) & ~mask) { @@ -648,7 +648,7 @@ void *snd_malloc_pci_page(struct pci_dev dma_addr_t addr; unsigned long mask; - mask = pci ? (unsigned long)pci->consistent_dma_mask : 0x00ffffffUL; + mask = pci ? (unsigned long)pci->dev.coherent_dma_mask : 0x00ffffffUL; ptr = (void *)__get_free_page(GFP_KERNEL); if (ptr) { addr = virt_to_phys(ptr); _