|
@@ -800,20 +800,10 @@ static int __ref enable_device(struct acpiphp_slot *slot)
|
|
|
if (slot->flags & SLOT_ENABLED)
|
|
|
goto err_exit;
|
|
|
|
|
|
- /* sanity check: dev should be NULL when hot-plugged in */
|
|
|
- dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
|
|
|
- if (dev) {
|
|
|
- /* This case shouldn't happen */
|
|
|
- err("pci_dev structure already exists.\n");
|
|
|
- pci_dev_put(dev);
|
|
|
- retval = -1;
|
|
|
- goto err_exit;
|
|
|
- }
|
|
|
-
|
|
|
num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
|
|
|
if (num == 0) {
|
|
|
- err("No new device found\n");
|
|
|
- retval = -1;
|
|
|
+ /* Maybe only part of funcs are added. */
|
|
|
+ dbg("No new device found\n");
|
|
|
goto err_exit;
|
|
|
}
|
|
|
|
|
@@ -848,11 +838,16 @@ static int __ref enable_device(struct acpiphp_slot *slot)
|
|
|
|
|
|
pci_bus_add_devices(bus);
|
|
|
|
|
|
+ slot->flags |= SLOT_ENABLED;
|
|
|
list_for_each_entry(func, &slot->funcs, sibling) {
|
|
|
dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
|
|
|
func->function));
|
|
|
- if (!dev)
|
|
|
+ if (!dev) {
|
|
|
+ /* Do not set SLOT_ENABLED flag if some funcs
|
|
|
+ are not added. */
|
|
|
+ slot->flags &= (~SLOT_ENABLED);
|
|
|
continue;
|
|
|
+ }
|
|
|
|
|
|
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
|
|
|
dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) {
|
|
@@ -867,7 +862,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
|
|
|
pci_dev_put(dev);
|
|
|
}
|
|
|
|
|
|
- slot->flags |= SLOT_ENABLED;
|
|
|
|
|
|
err_exit:
|
|
|
return retval;
|
|
@@ -892,9 +886,12 @@ static int disable_device(struct acpiphp_slot *slot)
|
|
|
{
|
|
|
struct acpiphp_func *func;
|
|
|
struct pci_dev *pdev;
|
|
|
+ struct pci_bus *bus = slot->bridge->pci_bus;
|
|
|
|
|
|
- /* is this slot already disabled? */
|
|
|
- if (!(slot->flags & SLOT_ENABLED))
|
|
|
+ /* The slot will be enabled when func 0 is added, so check
|
|
|
+ func 0 before disable the slot. */
|
|
|
+ pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
|
|
|
+ if (!pdev)
|
|
|
goto err_exit;
|
|
|
|
|
|
list_for_each_entry(func, &slot->funcs, sibling) {
|