]> err.no Git - linux-2.6/blob - drivers/pci/hotplug/rpaphp_pci.c
f16d0f9240ee70d11488c125f302c909edeb555e
[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 int rpaphp_get_sensor_state(struct slot *slot, int *state)
36 {
37         int rc;
38         int setlevel;
39
40         rc = rtas_get_sensor(DR_ENTITY_SENSE, slot->index, state);
41
42         if (rc < 0) {
43                 if (rc == -EFAULT || rc == -EEXIST) {
44                         dbg("%s: slot must be power up to get sensor-state\n",
45                             __FUNCTION__);
46
47                         /* some slots have to be powered up 
48                          * before get-sensor will succeed.
49                          */
50                         rc = rtas_set_power_level(slot->power_domain, POWER_ON,
51                                                   &setlevel);
52                         if (rc < 0) {
53                                 dbg("%s: power on slot[%s] failed rc=%d.\n",
54                                     __FUNCTION__, slot->name, rc);
55                         } else {
56                                 rc = rtas_get_sensor(DR_ENTITY_SENSE,
57                                                      slot->index, state);
58                         }
59                 } else if (rc == -ENODEV)
60                         info("%s: slot is unusable\n", __FUNCTION__);
61                 else
62                         err("%s failed to get sensor state\n", __FUNCTION__);
63         }
64         return rc;
65 }
66
67 /**
68  * get_pci_adapter_status - get the status of a slot
69  * 
70  * 0-- slot is empty
71  * 1-- adapter is configured
72  * 2-- adapter is not configured
73  * 3-- not valid
74  */
75 int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
76 {
77         struct pci_bus *bus;
78         int state, rc;
79
80         *value = NOT_VALID;
81         rc = rpaphp_get_sensor_state(slot, &state);
82         if (rc)
83                 goto exit;
84
85         if (state == EMPTY)
86                 *value = EMPTY;
87         else if (state == PRESENT) {
88                 if (!is_init) {
89                         /* at run-time slot->state can be changed by */
90                         /* config/unconfig adapter */
91                         *value = slot->state;
92                 } else {
93                         bus = pcibios_find_pci_bus(slot->dn);
94                         if (bus && !list_empty(&bus->devices))
95                                 *value = CONFIGURED;
96                         else
97                                 *value = NOT_CONFIGURED;
98                 }
99         }
100 exit:
101         return rc;
102 }
103
104 /* Must be called before pci_bus_add_devices */
105 void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
106 {
107         struct pci_dev *dev;
108
109         list_for_each_entry(dev, &bus->devices, bus_list) {
110                 /*
111                  * Skip already-present devices (which are on the
112                  * global device list.)
113                  */
114                 if (list_empty(&dev->global_list)) {
115                         int i;
116                         
117                         /* Need to setup IOMMU tables */
118                         ppc_md.iommu_dev_setup(dev);
119
120                         if(fix_bus)
121                                 pcibios_fixup_device_resources(dev, bus);
122                         pci_read_irq_line(dev);
123                         for (i = 0; i < PCI_NUM_RESOURCES; i++) {
124                                 struct resource *r = &dev->resource[i];
125
126                                 if (r->parent || !r->start || !r->flags)
127                                         continue;
128                                 pci_claim_resource(dev, i);
129                         }
130                 }
131         }
132 }
133
134 static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
135 {
136         struct pci_dev *dev;
137
138         list_for_each_entry(dev, &bus->devices, bus_list) {
139                 eeh_add_device_late(dev);
140                 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
141                         struct pci_bus *subbus = dev->subordinate;
142                         if (subbus)
143                                 rpaphp_eeh_add_bus_device (subbus);
144                 }
145         }
146 }
147
148 static int rpaphp_pci_config_bridge(struct pci_dev *dev)
149 {
150         u8 sec_busno;
151         struct pci_bus *child_bus;
152         struct pci_dev *child_dev;
153
154         dbg("Enter %s:  BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev));
155
156         /* get busno of downstream bus */
157         pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
158                 
159         /* add to children of PCI bridge dev->bus */
160         child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
161         if (!child_bus) {
162                 err("%s: could not add second bus\n", __FUNCTION__);
163                 return -EIO;
164         }
165         sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
166         /* do pci_scan_child_bus */
167         pci_scan_child_bus(child_bus);
168
169         list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
170                 eeh_add_device_late(child_dev);
171         }
172
173          /* fixup new pci devices without touching bus struct */
174         rpaphp_fixup_new_pci_devices(child_bus, 0);
175
176         /* Make the discovered devices available */
177         pci_bus_add_devices(child_bus);
178         return 0;
179 }
180
181 void rpaphp_init_new_devs(struct pci_bus *bus)
182 {
183         rpaphp_fixup_new_pci_devices(bus, 0);
184         rpaphp_eeh_add_bus_device(bus);
185 }
186 EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
187
188 /*****************************************************************************
189  rpaphp_pci_config_slot() will  configure all devices under the
190  given slot->dn and return the the first pci_dev.
191  *****************************************************************************/
192 static struct pci_dev *
193 rpaphp_pci_config_slot(struct pci_bus *bus)
194 {
195         struct device_node *dn = pci_bus_to_OF_node(bus);
196         struct pci_dev *dev = NULL;
197         int slotno;
198         int num;
199
200         dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
201         if (!dn || !dn->child)
202                 return NULL;
203
204         if (_machine == PLATFORM_PSERIES_LPAR) {
205                 of_scan_bus(dn, bus);
206                 if (list_empty(&bus->devices)) {
207                         err("%s: No new device found\n", __FUNCTION__);
208                         return NULL;
209                 }
210
211                 rpaphp_init_new_devs(bus);
212                 pci_bus_add_devices(bus);
213                 dev = list_entry(&bus->devices, struct pci_dev, bus_list);
214         } else {
215                 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
216
217                 /* pci_scan_slot should find all children */
218                 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
219                 if (num) {
220                         rpaphp_fixup_new_pci_devices(bus, 1);
221                         pci_bus_add_devices(bus);
222                 }
223                 if (list_empty(&bus->devices)) {
224                         err("%s: No new device found\n", __FUNCTION__);
225                         return NULL;
226                 }
227                 list_for_each_entry(dev, &bus->devices, bus_list) {
228                         if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
229                                 rpaphp_pci_config_bridge(dev);
230
231                         rpaphp_eeh_add_bus_device(bus);
232                 }
233         }
234
235         return dev;
236 }
237
238 static void print_slot_pci_funcs(struct pci_bus *bus)
239 {
240         struct device_node *dn;
241         struct pci_dev *dev;
242
243         dn = pci_bus_to_OF_node(bus);
244         if (!dn)
245                 return;
246
247         dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name);
248         list_for_each_entry (dev, &bus->devices, bus_list)
249                 dbg("\t%s\n", pci_name(dev));
250         return;
251 }
252
253 int rpaphp_config_pci_adapter(struct pci_bus *bus)
254 {
255         struct device_node *dn = pci_bus_to_OF_node(bus);
256         struct pci_dev *dev;
257         int rc = -ENODEV;
258
259         dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name);
260         if (!dn)
261                 goto exit;
262
263         eeh_add_device_tree_early(dn);
264         dev = rpaphp_pci_config_slot(bus);
265         if (!dev) {
266                 err("%s: can't find any devices.\n", __FUNCTION__);
267                 goto exit;
268         }
269         print_slot_pci_funcs(bus);
270         rc = 0;
271 exit:
272         dbg("Exit %s:  rc=%d\n", __FUNCTION__, rc);
273         return rc;
274 }
275 EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter);
276
277 static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
278 {
279         eeh_remove_device(dev);
280         if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
281                 struct pci_bus *bus = dev->subordinate;
282                 struct list_head *ln;
283                 if (!bus)
284                         return; 
285                 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
286                         struct pci_dev *pdev = pci_dev_b(ln);
287                         if (pdev)
288                                 rpaphp_eeh_remove_bus_device(pdev);
289                 }
290
291         }
292         return;
293 }
294
295 int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
296 {
297         struct pci_dev *dev, *tmp;
298
299         list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
300                 rpaphp_eeh_remove_bus_device(dev);
301                 pci_remove_bus_device(dev);
302         }
303         return 0;
304 }
305 EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
306
307 static int setup_pci_hotplug_slot_info(struct slot *slot)
308 {
309         struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info;
310
311         dbg("%s Initilize the PCI slot's hotplug->info structure ...\n",
312             __FUNCTION__);
313         rpaphp_get_power_status(slot, &hotplug_slot_info->power_status);
314         rpaphp_get_pci_adapter_status(slot, 1,
315                                       &hotplug_slot_info->adapter_status);
316         if (hotplug_slot_info->adapter_status == NOT_VALID) {
317                 err("%s: NOT_VALID: skip dn->full_name=%s\n",
318                     __FUNCTION__, slot->dn->full_name);
319                 return -EINVAL;
320         }
321         return 0;
322 }
323
324 static void set_slot_name(struct slot *slot)
325 {
326         struct pci_bus *bus = slot->bus;
327         struct pci_dev *bridge;
328
329         bridge = bus->self;
330         if (bridge)
331                 strcpy(slot->name, pci_name(bridge));
332         else
333                 sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus),
334                         bus->number);
335 }
336
337 static int setup_pci_slot(struct slot *slot)
338 {
339         struct device_node *dn = slot->dn;
340         struct pci_bus *bus;
341
342         BUG_ON(!dn);
343         bus = pcibios_find_pci_bus(dn);
344         if (!bus) {
345                 err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name);
346                 goto exit_rc;
347         }
348
349         slot->bus = bus;
350         slot->pci_devs = &bus->devices;
351         set_slot_name(slot);
352
353         /* find slot's pci_dev if it's not empty */
354         if (slot->hotplug_slot->info->adapter_status == EMPTY) {
355                 slot->state = EMPTY;    /* slot is empty */
356         } else {
357                 /* slot is occupied */
358                 if (!dn->child) {
359                         /* non-empty slot has to have child */
360                         err("%s: slot[%s]'s device_node doesn't have child for adapter\n", 
361                                 __FUNCTION__, slot->name);
362                         goto exit_rc;
363                 }
364
365                 if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
366                         dbg("%s CONFIGURING pci adapter in slot[%s]\n",  
367                                 __FUNCTION__, slot->name);
368                         if (rpaphp_config_pci_adapter(slot->bus)) {
369                                 err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
370                                 goto exit_rc;           
371                         }
372
373                 } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) {
374                         err("%s: slot[%s]'s adapter_status is NOT_VALID.\n",
375                                 __FUNCTION__, slot->name);
376                         goto exit_rc;
377                 }
378                 print_slot_pci_funcs(slot->bus);
379                 if (!list_empty(slot->pci_devs)) {
380                         slot->state = CONFIGURED;
381                 } else {
382                         /* DLPAR add as opposed to 
383                          * boot time */
384                         slot->state = NOT_CONFIGURED;
385                 }
386         }
387         return 0;
388 exit_rc:
389         dealloc_slot_struct(slot);
390         return -EINVAL;
391 }
392
393 int register_pci_slot(struct slot *slot)
394 {
395         int rc = -EINVAL;
396
397         if (setup_pci_hotplug_slot_info(slot))
398                 goto exit_rc;
399         if (setup_pci_slot(slot))
400                 goto exit_rc;
401         rc = register_slot(slot);
402 exit_rc:
403         return rc;
404 }
405
406 int rpaphp_enable_pci_slot(struct slot *slot)
407 {
408         int retval = 0, state;
409
410         retval = rpaphp_get_sensor_state(slot, &state);
411         if (retval)
412                 goto exit;
413         dbg("%s: sensor state[%d]\n", __FUNCTION__, state);
414         /* if slot is not empty, enable the adapter */
415         if (state == PRESENT) {
416                 dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name);
417                 retval = rpaphp_config_pci_adapter(slot->bus);
418                 if (!retval) {
419                         slot->state = CONFIGURED;
420                         info("%s: devices in slot[%s] configured\n",
421                                         __FUNCTION__, slot->name);
422                 } else {
423                         slot->state = NOT_CONFIGURED;
424                         dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
425                             __FUNCTION__, slot->name);
426                 }
427         } else if (state == EMPTY) {
428                 dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name);
429                 slot->state = EMPTY;
430         } else {
431                 err("%s: slot[%s] is in invalid state\n", __FUNCTION__,
432                     slot->name);
433                 slot->state = NOT_VALID;
434                 retval = -EINVAL;
435         }
436 exit:
437         dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
438         return retval;
439 }