|
@@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work)
|
|
|
* Tries hard not to re-enable already existing devices;
|
|
|
* also handles scanning of subfunctions.
|
|
|
*/
|
|
|
-static void pci_rescan_slot(struct pci_dev *temp)
|
|
|
+static int pci_rescan_slot(struct pci_dev *temp)
|
|
|
{
|
|
|
struct pci_bus *bus = temp->bus;
|
|
|
struct pci_dev *dev;
|
|
|
int func;
|
|
|
- int retval;
|
|
|
u8 hdr_type;
|
|
|
+ int count = 0;
|
|
|
|
|
|
if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
|
|
|
temp->hdr_type = hdr_type & 0x7f;
|
|
@@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp)
|
|
|
dbg("New device on %s function %x:%x\n",
|
|
|
bus->name, temp->devfn >> 3,
|
|
|
temp->devfn & 7);
|
|
|
- retval = pci_bus_add_device(dev);
|
|
|
- if (retval)
|
|
|
- dev_err(&dev->dev, "error adding "
|
|
|
- "device, continuing.\n");
|
|
|
- else
|
|
|
- add_slot(dev);
|
|
|
+ count++;
|
|
|
}
|
|
|
}
|
|
|
/* multifunction device? */
|
|
|
if (!(hdr_type & 0x80))
|
|
|
- return;
|
|
|
+ return count;
|
|
|
|
|
|
/* continue scanning for other functions */
|
|
|
for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
|
|
@@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp)
|
|
|
dbg("New device on %s function %x:%x\n",
|
|
|
bus->name, temp->devfn >> 3,
|
|
|
temp->devfn & 7);
|
|
|
- retval = pci_bus_add_device(dev);
|
|
|
- if (retval)
|
|
|
- dev_err(&dev->dev, "error adding "
|
|
|
- "device, continuing.\n");
|
|
|
- else
|
|
|
- add_slot(dev);
|
|
|
+ count++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ return count;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus)
|
|
|
{
|
|
|
unsigned int devfn;
|
|
|
struct pci_dev *dev;
|
|
|
+ int retval;
|
|
|
+ int found = 0;
|
|
|
dev = alloc_pci_dev();
|
|
|
if (!dev)
|
|
|
return;
|
|
@@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus)
|
|
|
dev->sysdata = bus->sysdata;
|
|
|
for (devfn = 0; devfn < 0x100; devfn += 8) {
|
|
|
dev->devfn = devfn;
|
|
|
- pci_rescan_slot(dev);
|
|
|
+ found += pci_rescan_slot(dev);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (found) {
|
|
|
+ pci_bus_assign_resources(bus);
|
|
|
+ list_for_each_entry(dev, &bus->devices, bus_list) {
|
|
|
+ /* Skip already-added devices */
|
|
|
+ if (dev->is_added)
|
|
|
+ continue;
|
|
|
+ retval = pci_bus_add_device(dev);
|
|
|
+ if (retval)
|
|
|
+ dev_err(&dev->dev,
|
|
|
+ "Error adding device, continuing\n");
|
|
|
+ else
|
|
|
+ add_slot(dev);
|
|
|
+ }
|
|
|
+ pci_bus_add_devices(bus);
|
|
|
}
|
|
|
kfree(dev);
|
|
|
}
|