Skip to contentSkip to conversation

move dma_consistent_dma_mask to the generic device

PATCH In review James Bottomley 3 participants 4 messages Feb 26, 2004 – Mar 3, 2004

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 move dma_consistent_dma_mask to the generic device

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.

I copied Matthew because parisc also has a parisc_device that needed to be converted over.

James

===== arch/i386/kernel/pci-dma.c 1.11 vs edited =====

arch/i386/kernel/pci-dma.c +3 -1
@@ -20,8 +20,10 @@
 	/* ignore region specifiers */
 	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
 
-	if (dev == NULL || (*dev->dma_mask < 0xffffffff))
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) {
+	  printk("COHERENT MASK 0x%llx\n", dev->coherent_dma_mask);
 		gfp |= GFP_DMA;
+	}
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 
 	if (ret != NULL) {

===== arch/parisc/kernel/drivers.c 1.10 vs edited =====

arch/parisc/kernel/drivers.c +1 -0
@@ -618,6 +618,7 @@
 		 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);
 }

===== arch/parisc/kernel/pci-dma.c 1.7 vs edited =====

arch/parisc/kernel/pci-dma.c +1 -1
@@ -372,7 +372,7 @@
 ** 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;

===== drivers/eisa/eisa-bus.c 1.14 vs edited =====

drivers/eisa/eisa-bus.c +1 -0
@@ -187,6 +187,7 @@
 	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++) {

===== drivers/mca/mca-bus.c 1.5 vs edited =====

drivers/mca/mca-bus.c +1 -0
@@ -106,6 +106,7 @@
 	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;

===== drivers/pci/pci.c 1.61 vs edited =====

drivers/pci/pci.c +1 -1
@@ -691,7 +691,7 @@
 	if (!pci_dma_supported(dev, mask))
 		return -EIO;
 
-	dev->consistent_dma_mask = mask;
+	dev->dev.coherent_dma_mask = mask;
 
 	return 0;
 }

===== drivers/pci/probe.c 1.59 vs edited =====

drivers/pci/probe.c +1 -1
@@ -566,7 +566,6 @@
 	/* 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;
@@ -578,6 +577,7 @@
 	pci_name_device(dev);
 
 	dev->dev.dma_mask = &dev->dma_mask;
+	dev->dev.coherent_dma_mask = 0xffffffffull;
 
 	return dev;
 }

===== include/linux/device.h 1.115 vs edited =====

include/linux/device.h +6 -0
@@ -285,6 +285,12 @@
 					   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);

===== include/linux/pci.h 1.117 vs edited =====

include/linux/pci.h +0 -5
@@ -392,11 +392,6 @@
 					   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. */
#1 lore raw
Quoted 4 lines · James Bottomley

pci_dev.consistent_dma_mask was introduced to get around problems in the
IA64 Altix machine.

Quoted 8 lines

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.

A bit more grepping is needed.

sound/core/memalloc.c: In function `snd_pci_hack_alloc_consistent':
sound/core/memalloc.c:103: structure has no member named `consistent_dma_mask'

#2 lore raw
Quoted 4 lines · Andrew Morton

A bit more grepping is needed.

sound/core/memalloc.c: In function `snd_pci_hack_alloc_consistent':
sound/core/memalloc.c:103: structure has no member named `consistent_dma_mask'

Mea culpa, I don't have any boxes that define this hack, so I didn't see it. This sound memalloc is horribly illegal under the API...I suppose we're just lucky the Altix doesn't have a sound card ;-)

This incremental patch should fix it up (I compiled it on parisc by including it in the hacked architectures).

James

===== sound/core/memalloc.c 1.16 vs edited =====

sound/core/memalloc.c +3 -3
@@ -100,13 +100,13 @@
 	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) {
#3 lore raw
In reply to James Bottomley
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"James" == James Bottomley <[email protected]> writes:

James> pci_dev.consistent_dma_mask was introduced to get around James> problems in the IA64 Altix machine.

James> Now, we have a use for it in x86: the aacraid needs coherent James> memory in a 31 bit address range (2GB). Unfortunately, x86 is James> converted to the dma model, so it can't see the pci_dev by the James> time coherent memory is allocated.

James,

Could you add this one to your patchset, it fixes the sn2 code to work with the new location of the mask.

Thanks,
Jes

ia64/sn/io/machvec/pci_dma.c renamed from ia64/sn/io/machvec/pci_dma.c~ +2 -2
@@ -152,7 +152,7 @@
 	 *   pcibr_dmatrans_addr ignores a missing PCIIO_DMA_A64 flag on
 	 *   PCI-X buses.
 	 */
-	if (hwdev->consistent_dma_mask == ~0UL)
+	if (hwdev->dev.coherent_dma_mask == ~0UL)
 		*dma_handle = pcibr_dmatrans_addr(vhdl, NULL, phys_addr, size,
 					  PCIIO_DMA_CMD | PCIIO_DMA_A64);
 	else {
@@ -169,7 +169,7 @@
 		}
 	}
 
-	if (!*dma_handle || *dma_handle > hwdev->consistent_dma_mask) {
+	if (!*dma_handle || *dma_handle > hwdev->dev.coherent_dma_mask) {
 		if (dma_map) {
 			pcibr_dmamap_done(dma_map);
 			pcibr_dmamap_free(dma_map);