Root/target/linux/ar71xx/patches-3.3/115-MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch

1From 83d74abc7d549f5d6292b0474be080983239c0bd Mon Sep 17 00:00:00 2001
2From: Gabor Juhos <juhosg@openwrt.org>
3Date: Sun, 20 Nov 2011 10:29:36 +0100
4Subject: [PATCH 15/35] MIPS: ath79: allow to use board specific pci_plat_dev_init functions
5
6Th current implementation causes NULL pointer dereference
7if 'pci_data' is not set:
8
9pci 0000:00:00.0: BAR 0: assigned [mem 0x10000000-0x1000ffff 64bit]
10pci 0000:00:00.0: BAR 0: set to [mem 0x10000000-0x1000ffff 64bit] (PCI
11address [0x10000000-0x1000ffff])
12CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 802daca0, ra == 802e78a4
13Oops[#1]:
14Cpu 0
15$ 0 : 00000000 80420000 00000000 00000000
16$ 4 : 00000000 00000000 00000001 00000001
17$ 8 : 00000001 0000032c 81c54700 00000001
18$12 : 0000032d 0000000f 00000000 ffffffff
19$16 : 81c14c00 00000001 802dac74 80195f98
20$20 : 802ea050 00000000 00000000 00000000
21$24 : 00000003 800617f0
22$28 : 81c20000 81c21e70 00000000 802e78a4
23Hi : 00000000
24Lo : 4190ab00
25epc : 802daca0 0x802daca0
26    Not tainted
27ra : 802e78a4 0x802e78a4
28Status: 1000c003 KERNEL EXL IE
29Cause : 00800008
30BadVA : 00000000
31PrId : 00019374 (MIPS 24Kc)
32Modules linked in:
33Process swapper (pid: 1, threadinfo=81c20000, task=81c18000, tls=00000000)
34Stack : 00000000 8027d5d8 802e8ae0 00000000 01000000 802e8b5c 81c50600 00000000
35        802ff290 00000000 80420000 802ea0bc 00000000 00000000 80420000 802ff290
36        80420000 80060930 33390000 00000000 00002308 80140a80 00000028 802d0000
37        00000000 800ba024 802ff004 802ff0c8 802ff290 00000000 00000000 00000000
38        00000000 802d897c 01234567 7f827068 00000000 0045f798 00460000 00000000
39
40This can be avoided by calling the 'ar724x_pci_add_data'
41function from the board specific setup code. However it
42makes no sense to use that function for every board,
43especially when the board does not needs to set the
44platform_data field of any PCI device.
45
46The patch allows the board setup code to specify a board
47specific function if that is required.
48
49Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
50
51v2: - no changes
52
53The pci_irq_map function can throw another NULL pointer
54dereference, that will be fixed in a subsequent patch.
55---
56 arch/mips/ath79/mach-ubnt-xm.c | 13 ++++++++++++-
57 arch/mips/ath79/pci.c | 14 ++++++++------
58 arch/mips/ath79/pci.h | 4 +++-
59 3 files changed, 23 insertions(+), 8 deletions(-)
60
61--- a/arch/mips/ath79/mach-ubnt-xm.c
62+++ b/arch/mips/ath79/mach-ubnt-xm.c
63@@ -85,16 +85,27 @@ static struct ath9k_platform_data ubnt_x
64 static struct ar724x_pci_data ubnt_xm_pci_data[] = {
65     {
66         .irq = ATH79_PCI_IRQ(0),
67- .pdata = &ubnt_xm_eeprom_data,
68     },
69 };
70 
71+static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
72+{
73+ switch (PCI_SLOT(dev->devfn)) {
74+ case 0:
75+ dev->dev.platform_data = &ubnt_xm_eeprom_data;
76+ break;
77+ }
78+
79+ return 0;
80+}
81+
82 static void __init ubnt_xm_pci_init(void)
83 {
84     memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
85            sizeof(ubnt_xm_eeprom_data.eeprom_data));
86 
87     ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
88+ ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
89     ath79_register_pci();
90 }
91 #else
92--- a/arch/mips/ath79/pci.c
93+++ b/arch/mips/ath79/pci.c
94@@ -14,6 +14,7 @@
95 #include <asm/mach-ath79/pci.h>
96 #include "pci.h"
97 
98+static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
99 static struct ar724x_pci_data *pci_data;
100 static int pci_data_size;
101 
102@@ -38,14 +39,15 @@ int __init pcibios_map_irq(const struct
103 
104 int pcibios_plat_dev_init(struct pci_dev *dev)
105 {
106- unsigned int devfn = dev->devfn;
107-
108- if (devfn > pci_data_size - 1)
109- return PCIBIOS_DEVICE_NOT_FOUND;
110+ if (ath79_pci_plat_dev_init)
111+ return ath79_pci_plat_dev_init(dev);
112 
113- dev->dev.platform_data = pci_data[devfn].pdata;
114+ return 0;
115+}
116 
117- return PCIBIOS_SUCCESSFUL;
118+void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
119+{
120+ ath79_pci_plat_dev_init = func;
121 }
122 
123 int __init ath79_register_pci(void)
124--- a/arch/mips/ath79/pci.h
125+++ b/arch/mips/ath79/pci.h
126@@ -13,14 +13,16 @@
127 
128 struct ar724x_pci_data {
129     int irq;
130- void *pdata;
131 };
132 
133 void ar724x_pci_add_data(struct ar724x_pci_data *data, int size);
134 
135 #ifdef CONFIG_PCI
136+void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
137 int ath79_register_pci(void);
138 #else
139+static inline void
140+ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
141 static inline int ath79_register_pci(void) { return 0; }
142 #endif
143 
144

Archive Download this file



interactive