*
* @param temp Device template. Should be set: bus and devfn.
*/
-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;
u8 hdr_type;
+ int count = 0;
+
if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
temp->hdr_type = hdr_type & 0x7f;
if (!pci_find_slot(bus->number, temp->devfn)) {
dbg("New device on %s function %x:%x\n",
bus->name, temp->devfn >> 3,
temp->devfn & 7);
- pci_bus_add_device(dev);
- 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++) {
dbg("New device on %s function %x:%x\n",
bus->name, temp->devfn >> 3,
temp->devfn & 7);
- pci_bus_add_device(dev);
- add_slot(dev);
+ count++;
}
}
}
}
+ return count;
}
*
* @param bus
*/
-static void pci_rescan_bus(const struct pci_bus *bus)
+static void pci_rescan_bus(struct pci_bus *bus)
{
unsigned int devfn;
struct pci_dev *dev;
+ int found = 0;
dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
if (!dev)
return;
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) {
+ struct pci_dev *tmp;
+ pci_bus_assign_resources(bus);
+ list_for_each_entry(tmp, &bus->devices, bus_list) {
+ /* Skip already-added devices */
+ if (!list_empty(&tmp->global_list))
+ continue;
+ pci_bus_add_device(tmp);
+ add_slot(tmp);
+ }
+ pci_bus_add_devices(bus);
}
kfree(dev);
}
{
const struct list_head *l;
list_for_each(l,list) {
- const struct pci_bus *b = pci_bus_b(l);
+ struct pci_bus *b = pci_bus_b(l);
pci_rescan_bus(b);
pci_rescan_buses(&b->children);
}