-#endif
-
-static int init_slot_pci_funcs(struct slot *slot)
-{
- struct device_node *child;
-
- for (child = slot->dn->child; child != NULL; child = child->sibling) {
- struct pci_dev *pdev = rpaphp_find_pci_dev(child);
-
- if (pdev) {
- struct rpaphp_pci_func *func;
- func = kmalloc(sizeof(struct rpaphp_pci_func), GFP_KERNEL);
- if (!func)
- return -ENOMEM;
- memset(func, 0, sizeof(struct rpaphp_pci_func));
- INIT_LIST_HEAD(&func->sibling);
- func->pci_dev = pdev;
- list_add_tail(&func->sibling, &slot->dev.pci_funcs);
- print_slot_pci_funcs(slot);
- } else {
- err("%s: dn=%s has no pci_dev\n",
- __FUNCTION__, child->full_name);
- return -EIO;
- }
- }
- return 0;
-}
-
-static int rpaphp_config_pci_adapter(struct slot *slot)
-{
- struct pci_bus *pci_bus;
- struct pci_dev *dev;
- int rc = -ENODEV;
-
- dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
-
- if (slot->bridge) {
-
- pci_bus = slot->bridge->subordinate;
- if (!pci_bus) {
- err("%s: can't find bus structure\n", __FUNCTION__);
- goto exit;
- }
- enable_eeh(slot->dn);
- dev = rpaphp_pci_config_slot(slot->dn, pci_bus);
- if (!dev) {
- err("%s: can't find any devices.\n", __FUNCTION__);
- goto exit;
- }
- /* associate corresponding pci_dev */
- rc = init_slot_pci_funcs(slot);
- if (rc)
- goto exit;
- print_slot_pci_funcs(slot);
- if (!list_empty(&slot->dev.pci_funcs))
- rc = 0;
- } else {
- /* slot is not enabled */
- err("slot doesn't have pci_dev structure\n");
- }
-exit:
- dbg("Exit %s: rc=%d\n", __FUNCTION__, rc);
- return rc;
-}
-
-
-static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
-{
- eeh_remove_device(dev);
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- struct pci_bus *bus = dev->subordinate;
- struct list_head *ln;
- if (!bus)
- return;
- for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
- struct pci_dev *pdev = pci_dev_b(ln);
- if (pdev)
- rpaphp_eeh_remove_bus_device(pdev);
- }
-
- }
- return;
-}
-
-int rpaphp_unconfig_pci_adapter(struct slot *slot)
-{
- int retval = 0;
- struct list_head *ln;
-
- dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
- if (list_empty(&slot->dev.pci_funcs)) {
- err("%s: slot[%s] doesn't have any devices.\n", __FUNCTION__,
- slot->name);
-
- retval = -EINVAL;
- goto exit;
- }
- /* remove the devices from the pci core */
- list_for_each (ln, &slot->dev.pci_funcs) {
- struct rpaphp_pci_func *func;
-
- func = list_entry(ln, struct rpaphp_pci_func, sibling);
- if (func->pci_dev) {
- pci_remove_bus_device(func->pci_dev);
- rpaphp_eeh_remove_bus_device(func->pci_dev);
- }
- kfree(func);
- }
- INIT_LIST_HEAD(&slot->dev.pci_funcs);
- slot->state = NOT_CONFIGURED;
- info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
- slot->name);
-exit:
- dbg("Exit %s, rc=0x%x\n", __FUNCTION__, retval);
- return retval;
-}