Root/package/broadcom-wl/patches/006-generic-dma-api.patch

1From: George Kashperko <george@znau.edu.ua>
2
3broadcom-wl driver bound to ssb device with ssb driver probe
4have osh handle struct pdev pointer value initialized with
5ssb_device pointer. Later on pdev is used with legacy pci
6dma api as pci_dev thus causing oops sometimes.
7
8The patch replaces legacy pci dma api and pass relevant
9device struct pointer to avoid crashes.
10Signed-off-by: George Kashperko <george@znau.edu.ua>
11---
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
16@@ -25,6 +25,9 @@
17 #include <asm/paccess.h>
18 #endif /* mips */
19 #include <pcicfg.h>
20+#ifdef CONFIG_SSB
21+#include <linux/ssb/ssb.h>
22+#endif
23 
24 #define PCI_CFG_RETRY 10
25 
26@@ -364,12 +367,27 @@ osl_dma_consistent_align(void)
27     return (PAGE_SIZE);
28 }
29 
30+static struct device *
31+osl_get_dmadev(osl_t *osh)
32+{
33+#ifdef CONFIG_SSB
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;
40+ }
41+#endif
42+ return &((struct pci_dev *)osh->pdev)->dev;
43+}
44+
45 void*
46 osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap)
47 {
48     ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
49 
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));
52 }
53 
54 void
55@@ -377,7 +395,7 @@ osl_dma_free_consistent(osl_t *osh, void
56 {
57     ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
58 
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);
61 }
62 
63 uint BCMFASTPATH
64@@ -386,13 +404,13 @@ osl_dma_map(osl_t *osh, void *va, uint s
65     ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
66 
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));
70     else {
71 #ifdef mips
72         dma_cache_inv((uint)va, size);
73         return (virt_to_phys(va));
74 #else /* mips */
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));
77 #endif /* mips */
78     }
79 }
80@@ -404,7 +422,7 @@ osl_dma_unmap(osl_t *osh, uint pa, uint
81 
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);
86 }
87 
88 
89

Archive Download this file



interactive