1 From: George Kashperko <george@znau.edu.ua>
3 broadcom-wl driver bound to ssb device with ssb driver probe
4 have osh handle struct pdev pointer value initialized with
5 ssb_device pointer. Later on pdev is used with legacy pci
6 dma api as pci_dev thus causing oops sometimes.
8 The patch replaces legacy pci dma api and pass relevant
9 device struct pointer to avoid crashes.
10 Signed-off-by: George Kashperko <george@znau.edu.ua>
12 driver/linux_osl.c | 28 +++++++++++++++++++++++-----
13 1 file changed, 23 insertions(+), 5 deletions(-)
14 --- a/driver/linux_osl.c
15 +++ b/driver/linux_osl.c
17 #include <asm/paccess.h>
21 +#include <linux/ssb/ssb.h>
24 #define PCI_CFG_RETRY 10
26 @@ -364,12 +367,27 @@ osl_dma_consistent_align(void)
30 +static struct device *
31 +osl_get_dmadev(osl_t *osh)
34 + if (osh->bustype == SI_BUS) {
35 + /* This can be SiliconBackplane emulated as pci with Broadcom or
36 + * ssb device. Less harmful is to check for pci_bus_type and if
37 + * no match then assume we got ssb */
38 + if (((struct pci_dev *)osh->pdev)->dev.bus != &pci_bus_type)
39 + return ((struct ssb_device *)osh->pdev)->dma_dev;
42 + return &((struct pci_dev *)osh->pdev)->dev;
46 osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap)
48 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
50 - return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap));
51 + return (dma_alloc_coherent(osl_get_dmadev(osh), size, (dma_addr_t*)pap, GFP_ATOMIC));
55 @@ -377,7 +395,7 @@ osl_dma_free_consistent(osl_t *osh, void
57 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
59 - pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
60 + dma_free_coherent(osl_get_dmadev(osh), size, va, (dma_addr_t)pa);
64 @@ -386,13 +404,13 @@ osl_dma_map(osl_t *osh, void *va, uint s
65 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
67 if (direction == DMA_TX)
68 - return (pci_map_single(osh->pdev, va, size, PCI_DMA_TODEVICE));
69 + return (dma_map_single(osl_get_dmadev(osh), va, size, PCI_DMA_TODEVICE));
72 dma_cache_inv((uint)va, size);
73 return (virt_to_phys(va));
75 - return (pci_map_single(osh->pdev, va, size, PCI_DMA_FROMDEVICE));
76 + return (dma_map_single(osl_get_dmadev(osh), va, size, PCI_DMA_FROMDEVICE));
80 @@ -404,7 +422,7 @@ osl_dma_unmap(osl_t *osh, uint pa, uint
82 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
83 dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
84 - pci_unmap_single(osh->pdev, (uint32)pa, size, dir);
85 + dma_unmap_single(osl_get_dmadev(osh), (uint32)pa, size, dir);