diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/rpadlpar_core.c | 35 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_pci.c | 72 |
3 files changed, 47 insertions, 61 deletions
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 7f868edaa72d..2ee7eb513e6c 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -165,6 +165,20 @@ static int pci_add_secondary_bus(struct device_node *dn, | |||
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
168 | static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, | ||
169 | struct device_node *dev_dn) | ||
170 | { | ||
171 | struct pci_dev *tmp = NULL; | ||
172 | struct device_node *child_dn; | ||
173 | |||
174 | list_for_each_entry(tmp, &parent->devices, bus_list) { | ||
175 | child_dn = pci_device_to_OF_node(tmp); | ||
176 | if (child_dn == dev_dn) | ||
177 | return tmp; | ||
178 | } | ||
179 | return NULL; | ||
180 | } | ||
181 | |||
168 | static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) | 182 | static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) |
169 | { | 183 | { |
170 | struct pci_controller *hose = dn->phb; | 184 | struct pci_controller *hose = dn->phb; |
@@ -180,21 +194,18 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) | |||
180 | pci_bus_add_devices(hose->bus); | 194 | pci_bus_add_devices(hose->bus); |
181 | 195 | ||
182 | /* Confirm new bridge dev was created */ | 196 | /* Confirm new bridge dev was created */ |
183 | dev = rpaphp_find_pci_dev(dn); | 197 | dev = dlpar_find_new_dev(hose->bus, dn); |
184 | if (!dev) { | 198 | if (dev) { |
185 | printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__); | 199 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { |
186 | return NULL; | 200 | printk(KERN_ERR "%s: unexpected header type %d\n", |
187 | } | 201 | __FUNCTION__, dev->hdr_type); |
202 | return NULL; | ||
203 | } | ||
188 | 204 | ||
189 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { | 205 | if (pci_add_secondary_bus(dn, dev)) |
190 | printk(KERN_ERR "%s: unexpected header type %d\n", | 206 | return NULL; |
191 | __FUNCTION__, dev->hdr_type); | ||
192 | return NULL; | ||
193 | } | 207 | } |
194 | 208 | ||
195 | if (pci_add_secondary_bus(dn, dev)) | ||
196 | return NULL; | ||
197 | |||
198 | return dev; | 209 | return dev; |
199 | } | 210 | } |
200 | 211 | ||
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 9f050fde80c2..8ecff0b950e8 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h | |||
@@ -93,7 +93,6 @@ extern int num_slots; | |||
93 | /* function prototypes */ | 93 | /* function prototypes */ |
94 | 94 | ||
95 | /* rpaphp_pci.c */ | 95 | /* rpaphp_pci.c */ |
96 | extern struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn); | ||
97 | extern int rpaphp_claim_resource(struct pci_dev *dev, int resource); | 96 | extern int rpaphp_claim_resource(struct pci_dev *dev, int resource); |
98 | extern int rpaphp_enable_pci_slot(struct slot *slot); | 97 | extern int rpaphp_enable_pci_slot(struct slot *slot); |
99 | extern int register_pci_slot(struct slot *slot); | 98 | extern int register_pci_slot(struct slot *slot); |
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 54fff5fb0094..30a892ca4b37 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c | |||
@@ -30,22 +30,7 @@ | |||
30 | 30 | ||
31 | #include "rpaphp.h" | 31 | #include "rpaphp.h" |
32 | 32 | ||
33 | struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn) | 33 | static struct pci_bus *find_bus_among_children(struct pci_bus *bus, |
34 | { | ||
35 | struct pci_dev *dev = NULL; | ||
36 | char bus_id[BUS_ID_SIZE]; | ||
37 | |||
38 | sprintf(bus_id, "%04x:%02x:%02x.%d", dn->phb->global_number, | ||
39 | dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn)); | ||
40 | for_each_pci_dev(dev) { | ||
41 | if (!strcmp(pci_name(dev), bus_id)) { | ||
42 | break; | ||
43 | } | ||
44 | } | ||
45 | return dev; | ||
46 | } | ||
47 | |||
48 | struct pci_bus *find_bus_among_children(struct pci_bus *bus, | ||
49 | struct device_node *dn) | 34 | struct device_node *dn) |
50 | { | 35 | { |
51 | struct pci_bus *child = NULL; | 36 | struct pci_bus *child = NULL; |
@@ -64,15 +49,14 @@ struct pci_bus *find_bus_among_children(struct pci_bus *bus, | |||
64 | return child; | 49 | return child; |
65 | } | 50 | } |
66 | 51 | ||
67 | struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) | 52 | static struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) |
68 | { | 53 | { |
69 | BUG_ON(!dn->phb || !dn->phb->bus); | 54 | if (!dn->phb || !dn->phb->bus) |
55 | return NULL; | ||
70 | 56 | ||
71 | return find_bus_among_children(dn->phb->bus, dn); | 57 | return find_bus_among_children(dn->phb->bus, dn); |
72 | } | 58 | } |
73 | 59 | ||
74 | EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev); | ||
75 | |||
76 | int rpaphp_claim_resource(struct pci_dev *dev, int resource) | 60 | int rpaphp_claim_resource(struct pci_dev *dev, int resource) |
77 | { | 61 | { |
78 | struct resource *res = &dev->resource[resource]; | 62 | struct resource *res = &dev->resource[resource]; |
@@ -137,9 +121,8 @@ static int rpaphp_get_sensor_state(struct slot *slot, int *state) | |||
137 | */ | 121 | */ |
138 | int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) | 122 | int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) |
139 | { | 123 | { |
124 | struct pci_bus *bus; | ||
140 | int state, rc; | 125 | int state, rc; |
141 | struct device_node *child_dn; | ||
142 | struct pci_dev *child_dev = NULL; | ||
143 | 126 | ||
144 | *value = NOT_VALID; | 127 | *value = NOT_VALID; |
145 | rc = rpaphp_get_sensor_state(slot, &state); | 128 | rc = rpaphp_get_sensor_state(slot, &state); |
@@ -156,20 +139,11 @@ int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) | |||
156 | /* config/unconfig adapter */ | 139 | /* config/unconfig adapter */ |
157 | *value = slot->state; | 140 | *value = slot->state; |
158 | } else { | 141 | } else { |
159 | child_dn = slot->dn->child; | 142 | bus = rpaphp_find_pci_bus(slot->dn); |
160 | if (child_dn) | 143 | if (bus && !list_empty(&bus->devices)) |
161 | child_dev = rpaphp_find_pci_dev(child_dn); | 144 | *value = CONFIGURED; |
162 | 145 | else | |
163 | if (child_dev) | ||
164 | *value = CONFIGURED; | ||
165 | else if (!child_dn) | ||
166 | dbg("%s: %s is not valid OFDT node\n", | ||
167 | __FUNCTION__, slot->dn->full_name); | ||
168 | else { | ||
169 | err("%s: can't find pdev of adapter in slot[%s]\n", | ||
170 | __FUNCTION__, slot->dn->full_name); | ||
171 | *value = NOT_CONFIGURED; | 146 | *value = NOT_CONFIGURED; |
172 | } | ||
173 | } | 147 | } |
174 | } | 148 | } |
175 | exit: | 149 | exit: |
@@ -252,24 +226,26 @@ rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus) | |||
252 | int num; | 226 | int num; |
253 | 227 | ||
254 | dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); | 228 | dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); |
229 | if (!dn->child) | ||
230 | return NULL; | ||
255 | 231 | ||
256 | if (dn->child) { | 232 | slotno = PCI_SLOT(dn->child->devfn); |
257 | slotno = PCI_SLOT(dn->child->devfn); | ||
258 | 233 | ||
259 | /* pci_scan_slot should find all children */ | 234 | /* pci_scan_slot should find all children */ |
260 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); | 235 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); |
261 | if (num) { | 236 | if (num) { |
262 | rpaphp_fixup_new_pci_devices(bus, 1); | 237 | rpaphp_fixup_new_pci_devices(bus, 1); |
263 | pci_bus_add_devices(bus); | 238 | pci_bus_add_devices(bus); |
264 | } | 239 | } |
265 | dev = rpaphp_find_pci_dev(dn->child); | 240 | if (list_empty(&bus->devices)) { |
266 | if (!dev) { | 241 | err("%s: No new device found\n", __FUNCTION__); |
267 | err("No new device found\n"); | 242 | return NULL; |
268 | return NULL; | 243 | } |
269 | } | 244 | list_for_each_entry(dev, &bus->devices, bus_list) { |
270 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | 245 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) |
271 | rpaphp_pci_config_bridge(dev); | 246 | rpaphp_pci_config_bridge(dev); |
272 | } | 247 | } |
248 | |||
273 | return dev; | 249 | return dev; |
274 | } | 250 | } |
275 | 251 | ||