X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpci%2Fhotplug%2Frpaphp_pci.c;h=9e81bdedca5a2efbfb511ce70badc3529b4c565f;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=76d722f34a9c59296e54778a9ab2968e31e5eec1;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 76d722f34..9e81bdedc 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -25,24 +25,24 @@ #include #include #include +#include #include "../pci.h" /* for pci_add_new_bus */ #include "rpaphp.h" struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn) { - struct pci_dev *retval_dev = NULL, *dev = NULL; + struct pci_dev *dev = NULL; char bus_id[BUS_ID_SIZE]; - sprintf(bus_id, "%04x:%02x:%02x.%d",dn->phb->global_number, + sprintf(bus_id, "%04x:%02x:%02x.%d", dn->phb->global_number, dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn)); - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + for_each_pci_dev(dev) { if (!strcmp(pci_name(dev), bus_id)) { - retval_dev = dev; break; } } - return retval_dev; + return dev; } EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev); @@ -117,33 +117,40 @@ static int rpaphp_get_sensor_state(struct slot *slot, int *state) int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) { int state, rc; - *value = NOT_VALID; + struct device_node *child_dn; + struct pci_dev *child_dev = NULL; + *value = NOT_VALID; rc = rpaphp_get_sensor_state(slot, &state); if (rc) goto exit; - if (state == PRESENT) { + + if ((state == EMPTY) || (slot->type == PHB)) { + dbg("slot is empty\n"); + *value = EMPTY; + } + else if (state == PRESENT) { if (!is_init) /* at run-time slot->state can be changed by */ /* config/unconfig adapter */ *value = slot->state; else { - if (!slot->dn->child) + child_dn = slot->dn->child; + if (child_dn) + child_dev = rpaphp_find_pci_dev(child_dn); + + if (child_dev) + *value = CONFIGURED; + else if (!child_dn) dbg("%s: %s is not valid OFDT node\n", __FUNCTION__, slot->dn->full_name); - else if (rpaphp_find_pci_dev(slot->dn->child)) - *value = CONFIGURED; else { err("%s: can't find pdev of adapter in slot[%s]\n", __FUNCTION__, slot->dn->full_name); *value = NOT_CONFIGURED; } } - } else if (state == EMPTY) { - dbg("slot is empty\n"); - *value = state; } - exit: return rc; } @@ -162,6 +169,9 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) if (list_empty(&dev->global_list)) { int i; + /* Need to setup IOMMU tables */ + ppc_md.iommu_dev_setup(dev); + if(fix_bus) pcibios_fixup_device_resources(dev, bus); pci_read_irq_line(dev); @@ -408,15 +418,52 @@ static int setup_pci_hotplug_slot_info(struct slot *slot) return 0; } +static int set_phb_slot_name(struct slot *slot) +{ + struct device_node *dn; + struct pci_controller *phb; + struct pci_bus *bus; + + dn = slot->dn; + if (!dn) { + return 1; + } + phb = dn->phb; + if (!phb) { + return 1; + } + bus = phb->bus; + if (!bus) { + return 1; + } + + sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus), + bus->number, 0, 0); + return 0; +} + static int setup_pci_slot(struct slot *slot) { - slot->bridge = rpaphp_find_bridge_pdev(slot); - if (!slot->bridge) { /* slot being added doesn't have pci_dev yet */ - err("%s: no pci_dev for bridge dn %s\n", __FUNCTION__, slot->name); - goto exit_rc; + int rc; + + if (slot->type == PHB) { + rc = set_phb_slot_name(slot); + if (rc) { + err("%s: failed to set phb slot name\n", __FUNCTION__); + goto exit_rc; + } + } else { + slot->bridge = rpaphp_find_bridge_pdev(slot); + if (!slot->bridge) { + /* slot being added doesn't have pci_dev yet */ + err("%s: no pci_dev for bridge dn %s\n", + __FUNCTION__, slot->name); + goto exit_rc; + } + dbg("%s set slot->name to %s\n", __FUNCTION__, + pci_name(slot->bridge)); + strcpy(slot->name, pci_name(slot->bridge)); } - dbg("%s set slot->name to %s\n", __FUNCTION__, pci_name(slot->bridge)); - strcpy(slot->name, pci_name(slot->bridge)); /* find slot's pci_dev if it's not empty */ if (slot->hotplug_slot->info->adapter_status == EMPTY) { @@ -470,10 +517,10 @@ int register_pci_slot(struct slot *slot) int rc = 1; slot->dev_type = PCI_DEV; - if (slot->type == EMBEDDED) - slot->removable = EMBEDDED; + if ((slot->type == EMBEDDED) || (slot->type == PHB)) + slot->removable = 0; else - slot->removable = HOTPLUG; + slot->removable = 1; INIT_LIST_HEAD(&slot->dev.pci_funcs); if (setup_pci_hotplug_slot_info(slot)) goto exit_rc;