ssb: Fix usage of struct device used for DMAing
Subsystems (4)
PATCH 1/1 ssb: Fix usage of struct device used for DMAing
This fixes DMA on architectures where DMA is nontrivial, like PPC64. We must use the host-device's (PCI) struct device for any DMA operation instead of the SSB device. For this we add a new struct device pointer to the SSB device structure that will always point to the right device for DMAing.
Without this patch b43 and b44 drivers won't work on complex-DMA architectures, that for example need dev->archdata for DMA operations.
---
John, this is a bugfix for 2.6.25
drivers/net/wireless/b43/dma.c +14 -13
@@ -328,10 +328,10 @@ static inlinedma_addr_t dmaaddr;if (tx) { - dmaaddr =dma_map_single (ring->dev->dev->dev, + dmaaddr =dma_map_single (ring->dev->dev->dma_dev, buf, len,DMA_TO_DEVICE ); }else { - dmaaddr =dma_map_single (ring->dev->dev->dev, + dmaaddr =dma_map_single (ring->dev->dev->dma_dev, buf, len,DMA_FROM_DEVICE ); }
@@ -343,9 +343,10 @@ static inline dma_addr_t addr, size_t len, int tx) { if (tx) { - dma_unmap_single(ring->dev->dev->dev, addr, len, DMA_TO_DEVICE); + dma_unmap_single(ring->dev->dev->dma_dev, +addr ,len ,DMA_TO_DEVICE ); } else { -dma_unmap_single (ring->dev->dev->dev, +dma_unmap_single (ring->dev->dev->dma_dev, addr, len,DMA_FROM_DEVICE ); } }
@@ -355,7 +356,7 @@ static inline dma_addr_t addr, size_t len) {B43_WARN_ON (ring->tx); -dma_sync_single_for_cpu (ring->dev->dev->dev, +dma_sync_single_for_cpu (ring->dev->dev->dma_dev, addr, len,DMA_FROM_DEVICE ); }
@@ -364,7 +365,7 @@ static inline dma_addr_t addr, size_t len) {B43_WARN_ON (ring->tx); -dma_sync_single_for_device (ring->dev->dev->dev, +dma_sync_single_for_device (ring->dev->dev->dma_dev, addr, len,DMA_FROM_DEVICE ); }
@@ -380,7 +381,7 @@ static inlinestatic int alloc_ringmemory (struct b43_dmaring *ring) { -struct device *dev = ring->dev->dev->dev; +struct device *dma_dev = ring->dev->dev->dma_dev;gfp_t flags =GFP_KERNEL ;/* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
@@ -394,7 +395,7 @@ static int alloc_ringmemory(struct b43_d*/ if (ring->type ==B43_DMA_64BIT ) flags |=GFP_DMA ; - ring->descbase =dma_alloc_coherent (dev,B43_DMA_RINGMEMSIZE , + ring->descbase =dma_alloc_coherent (dma_dev,B43_DMA_RINGMEMSIZE , &(ring->dmabase), flags);if (!ring->descbase) {b43err (ring->dev->wl,"DMA ringmemory allocation failed\n" );
@@ -407,9 +408,9 @@ static int alloc_ringmemory(struct b43_dstatic void free_ringmemory (struct b43_dmaring *ring) { -struct device *dev = ring->dev->dev->dev; +struct device *dma_dev = ring->dev->dev->dma_dev; -dma_free_coherent (dev,B43_DMA_RINGMEMSIZE , +dma_free_coherent (dma_dev,B43_DMA_RINGMEMSIZE , ring->descbase, ring->dmabase); }
@@ -818,7 +819,7 @@ struct b43_dmaring *b43_setup_dmaring(st goto err_kfree_meta;/* test for ability to dma to txhdr_cache */ - dma_test =dma_map_single (dev->dev->dev, + dma_test =dma_map_single (dev->dev->dma_dev, ring->txhdr_cache,b43_txhdr_size (dev),DMA_TO_DEVICE );
@@ -833,7 +834,7 @@ struct b43_dmaring *b43_setup_dmaring(stif (!ring->txhdr_cache) goto err_kfree_meta; - dma_test =dma_map_single (dev->dev->dev, + dma_test =dma_map_single (dev->dev->dma_dev, ring->txhdr_cache,b43_txhdr_size (dev),DMA_TO_DEVICE );
@@ -847,7 +848,7 @@ struct b43_dmaring *b43_setup_dmaring(st } } -dma_unmap_single (dev->dev->dev, +dma_unmap_single (dev->dev->dma_dev, dma_test,b43_txhdr_size (dev),DMA_TO_DEVICE ); }
drivers/ssb/main.c +8 -6
@@ -462,15 +462,18 @@ static int ssb_devices_register(struct s#ifdef CONFIG_SSB_PCIHOST sdev->irq = bus->host_pci->irq; dev->parent = &bus->host_pci->dev; + sdev->dma_dev = &bus->host_pci->dev;#endif break ;case SSB_BUSTYPE_PCMCIA :#ifdef CONFIG_SSB_PCMCIAHOST sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; dev->parent = &bus->host_pcmcia->dev; + sdev->dma_dev = &bus->host_pcmcia->dev;#endif break ;case SSB_BUSTYPE_SSB : + sdev->dma_dev = dev;break ; }
@@ -1164,15 +1167,14 @@ EXPORT_SYMBOL(ssb_dma_translation);int ssb_dma_set_mask (struct ssb_device *ssb_dev,u64 mask) { -struct device *dev = ssb_dev->dev; +struct device *dma_dev = ssb_dev->dma_dev;#ifdef CONFIG_SSB_PCIHOST -if (ssb_dev->bus->bustype ==SSB_BUSTYPE_PCI && - !dma_supported (dev, mask)) -return -EIO ; +if (ssb_dev->bus->bustype ==SSB_BUSTYPE_PCI ) +return dma_set_mask (dma_dev, mask);#endif - dev->coherent_dma_mask = mask; - dev->dma_mask = &dev->coherent_dma_mask; + dma_dev->coherent_dma_mask = mask; + dma_dev->dma_mask = &dma_dev->coherent_dma_mask;return 0 ; }
include/linux/ssb/ssb.h +4 -0
@@ -137,6 +137,10 @@ struct ssb_device {const struct ssb_bus_ops *ops;struct device *dev; +/* Pointer to the device that has to be used for +* any DMA related operation. */ +struct device *dma_dev; +struct ssb_bus *bus;struct ssb_device_id id;
drivers/net/b44.c +26 -26
196 lines not on this page · raw message
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html