[PATCH] PCI Hotplug: PCI panic on dlpar add (add pci slot to running partition)
[linux-2.6] / drivers / pci / hotplug / rpaphp_pci.c
1 /*
2  * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
3  * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
4  *
5  * All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or (at
10  * your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15  * NON INFRINGEMENT.  See the GNU General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * Send feedback to <lxie@us.ibm.com>
23  *
24  */
25 #include <linux/pci.h>
26 #include <linux/string.h>
27
28 #include <asm/pci-bridge.h>
29 #include <asm/rtas.h>
30 #include <asm/machdep.h>
31
32 #include "../pci.h"             /* for pci_add_new_bus */
33 #include "rpaphp.h"
34
35 static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
36                                         struct device_node *dn)
37 {
38         struct pci_bus *child = NULL;
39         struct list_head *tmp;
40         struct device_node *busdn;
41
42         busdn = pci_bus_to_OF_node(bus);
43         if (busdn == dn)
44                 return bus;
45
46         list_for_each(tmp, &bus->children) {
47                 child = find_bus_among_children(pci_bus_b(tmp), dn);
48                 if (child)
49                         break;
50         }
51         return child;
52 }
53
54 struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn)
55 {
56         struct pci_dn *pdn = dn->data;
57
58         if (!pdn  || !pdn->phb || !pdn->phb->bus)
59                 return NULL;
60
61         return find_bus_among_children(pdn->phb->bus, dn);
62 }
63 EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);
64
65 static int rpaphp_get_sensor_state(struct slot *slot, int *state)
66 {
67         int rc;
68         int setlevel;
69
70         rc = rtas_get_sensor(DR_ENTITY_SENSE, slot->index, state);
71
72         if (rc < 0) {
73                 if (rc == -EFAULT || rc == -EEXIST) {
74                         dbg("%s: slot must be power up to get sensor-state\n",
75                             __FUNCTION__);
76
77                         /* some slots have to be powered up 
78                          * before get-sensor will succeed.
79                          */
80                         rc = rtas_set_power_level(slot->power_domain, POWER_ON,
81                                                   &setlevel);
82                         if (rc < 0) {
83                                 dbg("%s: power on slot[%s] failed rc=%d.\n",
84                                     __FUNCTION__, slot->name, rc);
85                         } else {
86                                 rc = rtas_get_sensor(DR_ENTITY_SENSE,
87                                                      slot->index, state);
88                         }
89                 } else if (rc == -ENODEV)
90                         info("%s: slot is unusable\n", __FUNCTION__);
91                 else
92                         err("%s failed to get sensor state\n", __FUNCTION__);
93         }
94         return rc;
95 }
96
97 /**
98  * get_pci_adapter_status - get the status of a slot
99  * 
100  * 0-- slot is empty
101  * 1-- adapter is configured
102  * 2-- adapter is not configured
103  * 3-- not valid
104  */
105 int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
106 {
107         struct pci_bus *bus;
108         int state, rc;
109
110         *value = NOT_VALID;
111         rc = rpaphp_get_sensor_state(slot, &state);
112         if (rc)
113                 goto exit;
114
115         if (state == EMPTY)
116                 *value = EMPTY;
117         else if (state == PRESENT) {
118                 if (!is_init) {
119                         /* at run-time slot->state can be changed by */
120                         /* config/unconfig adapter */
121                         *value = slot->state;
122                 } else {
123                         bus = rpaphp_find_pci_bus(slot->dn);
124                         if (bus && !list_empty(&bus->devices))
125                                 *value = CONFIGURED;
126                         else
127                                 *value = NOT_CONFIGURED;
128                 }
129         }
130 exit:
131         return rc;
132 }
133
134 /* Must be called before pci_bus_add_devices */
135 void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
136 {
137         struct pci_dev *dev;
138
139         list_for_each_entry(dev, &bus->devices, bus_list) {
140                 /*
141                  * Skip already-present devices (which are on the
142                  * global device list.)
143                  */
144                 if (list_empty(&dev->global_list)) {
145                         int i;
146                         
147                         /* Need to setup IOMMU tables */
148                         ppc_md.iommu_dev_setup(dev);
149
150                         if(fix_bus)
151                                 pcibios_fixup_device_resources(dev, bus);
152                         pci_read_irq_line(dev);
153                         for (i = 0; i < PCI_NUM_RESOURCES; i++) {
154                                 struct resource *r = &dev->resource[i];
155
156                                 if (r->parent || !r->start || !r->flags)
157                                         continue;
158                                 pci_claim_resource(dev, i);
159                         }
160                 }
161         }
162 }
163
164 static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
165 {
166         struct pci_dev *dev;
167
168         list_for_each_entry(dev, &bus->devices, bus_list) {
169                 eeh_add_device_late(dev);
170                 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
171                         struct pci_bus *subbus = dev->subordinate;
172                         if (subbus)
173                                 rpaphp_eeh_add_bus_device (subbus);
174                 }
175         }
176 }
177
178 static int rpaphp_pci_config_bridge(struct pci_dev *dev)
179 {
180         u8 sec_busno;
181         struct pci_bus *child_bus;
182         struct pci_dev *child_dev;
183
184         dbg("Enter %s:  BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev));
185
186         /* get busno of downstream bus */
187         pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
188                 
189         /* add to children of PCI bridge dev->bus */
190         child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
191         if (!child_bus) {
192                 err("%s: could not add second bus\n", __FUNCTION__);
193                 return -EIO;
194         }
195         sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
196         /* do pci_scan_child_bus */
197         pci_scan_child_bus(child_bus);
198
199         list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
200                 eeh_add_device_late(child_dev);
201         }
202
203          /* fixup new pci devices without touching bus struct */
204         rpaphp_fixup_new_pci_devices(child_bus, 0);
205
206         /* Make the discovered devices available */
207         pci_bus_add_devices(child_bus);
208         return 0;
209 }
210
211 void rpaphp_init_new_devs(struct pci_bus *bus)
212 {
213         rpaphp_fixup_new_pci_devices(bus, 0);
214         rpaphp_eeh_add_bus_device(bus);
215 }
216 EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
217
218 /*****************************************************************************
219  rpaphp_pci_config_slot() will  configure all devices under the
220  given slot->dn and return the the first pci_dev.
221  *****************************************************************************/
222 static struct pci_dev *
223 rpaphp_pci_config_slot(struct pci_bus *bus)
224 {
225         struct device_node *dn = pci_bus_to_OF_node(bus);
226         struct pci_dev *dev = NULL;
227         int slotno;
228         int num;
229
230         dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
231         if (!dn || !dn->child)
232                 return NULL;
233
234         if (_machine == PLATFORM_PSERIES_LPAR) {
235                 of_scan_bus(dn, bus);
236                 if (list_empty(&bus->devices)) {
237                         err("%s: No new device found\n", __FUNCTION__);
238                         return NULL;
239                 }
240
241                 rpaphp_init_new_devs(bus);
242                 pci_bus_add_devices(bus);
243                 dev = list_entry(&bus->devices, struct pci_dev, bus_list);
244         } else {
245                 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
246
247                 /* pci_scan_slot should find all children */
248                 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
249                 if (num) {
250                         rpaphp_fixup_new_pci_devices(bus, 1);
251                         pci_bus_add_devices(bus);
252                 }
253                 if (list_empty(&bus->devices)) {
254                         err("%s: No new device found\n", __FUNCTION__);
255                         return NULL;
256                 }
257                 list_for_each_entry(dev, &bus->devices, bus_list) {
258                         if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
259                                 rpaphp_pci_config_bridge(dev);
260
261                         rpaphp_eeh_add_bus_device(bus);
262                 }
263         }
264
265         return dev;
266 }
267
268 static void print_slot_pci_funcs(struct pci_bus *bus)
269 {
270         struct device_node *dn;
271         struct pci_dev *dev;
272
273         dn = pci_bus_to_OF_node(bus);
274         if (!dn)
275                 return;
276
277         dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name);
278         list_for_each_entry (dev, &bus->devices, bus_list)
279                 dbg("\t%s\n", pci_name(dev));
280         return;
281 }
282
283 int rpaphp_config_pci_adapter(struct pci_bus *bus)
284 {
285         struct device_node *dn = pci_bus_to_OF_node(bus);
286         struct pci_dev *dev;
287         int rc = -ENODEV;
288
289         dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name);
290         if (!dn)
291                 goto exit;
292
293         eeh_add_device_tree_early(dn);
294         dev = rpaphp_pci_config_slot(bus);
295         if (!dev) {
296                 err("%s: can't find any devices.\n", __FUNCTION__);
297                 goto exit;
298         }
299         print_slot_pci_funcs(bus);
300         rc = 0;
301 exit:
302         dbg("Exit %s:  rc=%d\n", __FUNCTION__, rc);
303         return rc;
304 }
305 EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter);
306
307 static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
308 {
309         eeh_remove_device(dev);
310         if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
311                 struct pci_bus *bus = dev->subordinate;
312                 struct list_head *ln;
313                 if (!bus)
314                         return; 
315                 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
316                         struct pci_dev *pdev = pci_dev_b(ln);
317                         if (pdev)
318                                 rpaphp_eeh_remove_bus_device(pdev);
319                 }
320
321         }
322         return;
323 }
324
325 int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
326 {
327         struct pci_dev *dev, *tmp;
328
329         list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
330                 rpaphp_eeh_remove_bus_device(dev);
331                 pci_remove_bus_device(dev);
332         }
333         return 0;
334 }
335 EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
336
337 static int setup_pci_hotplug_slot_info(struct slot *slot)
338 {
339         struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info;
340
341         dbg("%s Initilize the PCI slot's hotplug->info structure ...\n",
342             __FUNCTION__);
343         rpaphp_get_power_status(slot, &hotplug_slot_info->power_status);
344         rpaphp_get_pci_adapter_status(slot, 1,
345                                       &hotplug_slot_info->adapter_status);
346         if (hotplug_slot_info->adapter_status == NOT_VALID) {
347                 err("%s: NOT_VALID: skip dn->full_name=%s\n",
348                     __FUNCTION__, slot->dn->full_name);
349                 return -EINVAL;
350         }
351         return 0;
352 }
353
354 static void set_slot_name(struct slot *slot)
355 {
356         struct pci_bus *bus = slot->bus;
357         struct pci_dev *bridge;
358
359         bridge = bus->self;
360         if (bridge)
361                 strcpy(slot->name, pci_name(bridge));
362         else
363                 sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus),
364                         bus->number);
365 }
366
367 static int setup_pci_slot(struct slot *slot)
368 {
369         struct device_node *dn = slot->dn;
370         struct pci_bus *bus;
371
372         BUG_ON(!dn);
373         bus = rpaphp_find_pci_bus(dn);
374         if (!bus) {
375                 err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name);
376                 goto exit_rc;
377         }
378
379         slot->bus = bus;
380         slot->pci_devs = &bus->devices;
381         set_slot_name(slot);
382
383         /* find slot's pci_dev if it's not empty */
384         if (slot->hotplug_slot->info->adapter_status == EMPTY) {
385                 slot->state = EMPTY;    /* slot is empty */
386         } else {
387                 /* slot is occupied */
388                 if (!dn->child) {
389                         /* non-empty slot has to have child */
390                         err("%s: slot[%s]'s device_node doesn't have child for adapter\n", 
391                                 __FUNCTION__, slot->name);
392                         goto exit_rc;
393                 }
394
395                 if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
396                         dbg("%s CONFIGURING pci adapter in slot[%s]\n",  
397                                 __FUNCTION__, slot->name);
398                         if (rpaphp_config_pci_adapter(slot->bus)) {
399                                 err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
400                                 goto exit_rc;           
401                         }
402
403                 } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) {
404                         err("%s: slot[%s]'s adapter_status is NOT_VALID.\n",
405                                 __FUNCTION__, slot->name);
406                         goto exit_rc;
407                 }
408                 print_slot_pci_funcs(slot->bus);
409                 if (!list_empty(slot->pci_devs)) {
410                         slot->state = CONFIGURED;
411                 } else {
412                         /* DLPAR add as opposed to 
413                          * boot time */
414                         slot->state = NOT_CONFIGURED;
415                 }
416         }
417         return 0;
418 exit_rc:
419         dealloc_slot_struct(slot);
420         return -EINVAL;
421 }
422
423 int register_pci_slot(struct slot *slot)
424 {
425         int rc = -EINVAL;
426
427         if (setup_pci_hotplug_slot_info(slot))
428                 goto exit_rc;
429         if (setup_pci_slot(slot))
430                 goto exit_rc;
431         rc = register_slot(slot);
432 exit_rc:
433         return rc;
434 }
435
436 int rpaphp_enable_pci_slot(struct slot *slot)
437 {
438         int retval = 0, state;
439
440         retval = rpaphp_get_sensor_state(slot, &state);
441         if (retval)
442                 goto exit;
443         dbg("%s: sensor state[%d]\n", __FUNCTION__, state);
444         /* if slot is not empty, enable the adapter */
445         if (state == PRESENT) {
446                 dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name);
447                 retval = rpaphp_config_pci_adapter(slot->bus);
448                 if (!retval) {
449                         slot->state = CONFIGURED;
450                         info("%s: devices in slot[%s] configured\n",
451                                         __FUNCTION__, slot->name);
452                 } else {
453                         slot->state = NOT_CONFIGURED;
454                         dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
455                             __FUNCTION__, slot->name);
456                 }
457         } else if (state == EMPTY) {
458                 dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name);
459                 slot->state = EMPTY;
460         } else {
461                 err("%s: slot[%s] is in invalid state\n", __FUNCTION__,
462                     slot->name);
463                 slot->state = NOT_VALID;
464                 retval = -EINVAL;
465         }
466 exit:
467         dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
468         return retval;
469 }