blob: d6dd5f0aaeadf16689cfdbddaed6e0eb8df4ddb6 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From: 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