diff options
Diffstat (limited to 'drivers/pci/hotplug/cpci_hotplug_pci.c')
| -rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index dcc75c78544..7d48ecae669 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -39,14 +39,14 @@ extern int cpci_debug; do { \ if (cpci_debug) \ printk (KERN_DEBUG "%s: " format "\n", \ - MY_NAME , ## arg); \ + MY_NAME , ## arg); \ } while (0) #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) -u8 cpci_get_attention_status(struct slot* slot) +u8 cpci_get_attention_status(struct slot *slot) { int hs_cap; u16 hs_csr; @@ -66,7 +66,7 @@ u8 cpci_get_attention_status(struct slot* slot) return hs_csr & 0x0008 ? 1 : 0; } -int cpci_set_attention_status(struct slot* slot, int status) +int cpci_set_attention_status(struct slot *slot, int status) { int hs_cap; u16 hs_csr; @@ -93,7 +93,7 @@ int cpci_set_attention_status(struct slot* slot, int status) return 1; } -u16 cpci_get_hs_csr(struct slot* slot) +u16 cpci_get_hs_csr(struct slot *slot) { int hs_cap; u16 hs_csr; @@ -111,7 +111,7 @@ u16 cpci_get_hs_csr(struct slot* slot) return hs_csr; } -int cpci_check_and_clear_ins(struct slot* slot) +int cpci_check_and_clear_ins(struct slot *slot) { int hs_cap; u16 hs_csr; @@ -140,7 +140,7 @@ int cpci_check_and_clear_ins(struct slot* slot) return ins; } -int cpci_check_ext(struct slot* slot) +int cpci_check_ext(struct slot *slot) { int hs_cap; u16 hs_csr; @@ -161,7 +161,7 @@ int cpci_check_ext(struct slot* slot) return ext; } -int cpci_clear_ext(struct slot* slot) +int cpci_clear_ext(struct slot *slot) { int hs_cap; u16 hs_csr; @@ -187,7 +187,7 @@ int cpci_clear_ext(struct slot* slot) return 0; } -int cpci_led_on(struct slot* slot) +int cpci_led_on(struct slot *slot) { int hs_cap; u16 hs_csr; @@ -216,7 +216,7 @@ int cpci_led_on(struct slot* slot) return 0; } -int cpci_led_off(struct slot* slot) +int cpci_led_off(struct slot *slot) { int hs_cap; u16 hs_csr; @@ -250,13 +250,16 @@ int cpci_led_off(struct slot* slot) * Device configuration functions */ -int __ref cpci_configure_slot(struct slot *slot) +int cpci_configure_slot(struct slot *slot) { + struct pci_dev *dev; struct pci_bus *parent; - int fn; + int ret = 0; dbg("%s - enter", __func__); + pci_lock_rescan_remove(); + if (slot->dev == NULL) { dbg("pci_dev null, finding %02x:%02x:%x", slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); @@ -277,36 +280,32 @@ int __ref cpci_configure_slot(struct slot *slot) slot->dev = pci_get_slot(slot->bus, slot->devfn); if (slot->dev == NULL) { err("Could not find PCI device for slot %02x", slot->number); - return -ENODEV; + ret = -ENODEV; + goto out; } } parent = slot->dev->bus; - for (fn = 0; fn < 8; fn++) { - struct pci_dev *dev; - - dev = pci_get_slot(parent, - PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); - if (!dev) + list_for_each_entry(dev, &parent->devices, bus_list) + if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) continue; - if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || - (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) + if (pci_is_bridge(dev)) pci_hp_add_bridge(dev); - pci_dev_put(dev); - } + pci_assign_unassigned_bridge_resources(parent->self); pci_bus_add_devices(parent); + out: + pci_unlock_rescan_remove(); dbg("%s - exit", __func__); - return 0; + return ret; } -int cpci_unconfigure_slot(struct slot* slot) +int cpci_unconfigure_slot(struct slot *slot) { - int i; - struct pci_dev *dev; + struct pci_dev *dev, *temp; dbg("%s - enter", __func__); if (!slot->dev) { @@ -314,17 +313,20 @@ int cpci_unconfigure_slot(struct slot* slot) return -ENODEV; } - for (i = 0; i < 8; i++) { - dev = pci_get_slot(slot->bus, - PCI_DEVFN(PCI_SLOT(slot->devfn), i)); - if (dev) { - pci_stop_and_remove_bus_device(dev); - pci_dev_put(dev); - } + pci_lock_rescan_remove(); + + list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) + continue; + pci_dev_get(dev); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); } pci_dev_put(slot->dev); slot->dev = NULL; + pci_unlock_rescan_remove(); + dbg("%s - exit", __func__); return 0; } |
