diff options
Diffstat (limited to 'drivers/pci/hotplug/fakephp.c')
| -rw-r--r-- | drivers/pci/hotplug/fakephp.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index b0e7de9e536d..d8649e127298 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
| @@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work) | |||
| 195 | * Tries hard not to re-enable already existing devices; | 195 | * Tries hard not to re-enable already existing devices; |
| 196 | * also handles scanning of subfunctions. | 196 | * also handles scanning of subfunctions. |
| 197 | */ | 197 | */ |
| 198 | static void pci_rescan_slot(struct pci_dev *temp) | 198 | static int pci_rescan_slot(struct pci_dev *temp) |
| 199 | { | 199 | { |
| 200 | struct pci_bus *bus = temp->bus; | 200 | struct pci_bus *bus = temp->bus; |
| 201 | struct pci_dev *dev; | 201 | struct pci_dev *dev; |
| 202 | int func; | 202 | int func; |
| 203 | int retval; | ||
| 204 | u8 hdr_type; | 203 | u8 hdr_type; |
| 204 | int count = 0; | ||
| 205 | 205 | ||
| 206 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { | 206 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { |
| 207 | temp->hdr_type = hdr_type & 0x7f; | 207 | temp->hdr_type = hdr_type & 0x7f; |
| @@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
| 213 | dbg("New device on %s function %x:%x\n", | 213 | dbg("New device on %s function %x:%x\n", |
| 214 | bus->name, temp->devfn >> 3, | 214 | bus->name, temp->devfn >> 3, |
| 215 | temp->devfn & 7); | 215 | temp->devfn & 7); |
| 216 | retval = pci_bus_add_device(dev); | 216 | count++; |
| 217 | if (retval) | ||
| 218 | dev_err(&dev->dev, "error adding " | ||
| 219 | "device, continuing.\n"); | ||
| 220 | else | ||
| 221 | add_slot(dev); | ||
| 222 | } | 217 | } |
| 223 | } | 218 | } |
| 224 | /* multifunction device? */ | 219 | /* multifunction device? */ |
| 225 | if (!(hdr_type & 0x80)) | 220 | if (!(hdr_type & 0x80)) |
| 226 | return; | 221 | return count; |
| 227 | 222 | ||
| 228 | /* continue scanning for other functions */ | 223 | /* continue scanning for other functions */ |
| 229 | for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) { | 224 | for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) { |
| @@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
| 239 | dbg("New device on %s function %x:%x\n", | 234 | dbg("New device on %s function %x:%x\n", |
| 240 | bus->name, temp->devfn >> 3, | 235 | bus->name, temp->devfn >> 3, |
| 241 | temp->devfn & 7); | 236 | temp->devfn & 7); |
| 242 | retval = pci_bus_add_device(dev); | 237 | count++; |
| 243 | if (retval) | ||
| 244 | dev_err(&dev->dev, "error adding " | ||
| 245 | "device, continuing.\n"); | ||
| 246 | else | ||
| 247 | add_slot(dev); | ||
| 248 | } | 238 | } |
| 249 | } | 239 | } |
| 250 | } | 240 | } |
| 251 | } | 241 | } |
| 242 | |||
| 243 | return count; | ||
| 252 | } | 244 | } |
| 253 | 245 | ||
| 254 | 246 | ||
| @@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus) | |||
| 262 | { | 254 | { |
| 263 | unsigned int devfn; | 255 | unsigned int devfn; |
| 264 | struct pci_dev *dev; | 256 | struct pci_dev *dev; |
| 257 | int retval; | ||
| 258 | int found = 0; | ||
| 265 | dev = alloc_pci_dev(); | 259 | dev = alloc_pci_dev(); |
| 266 | if (!dev) | 260 | if (!dev) |
| 267 | return; | 261 | return; |
| @@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus) | |||
| 270 | dev->sysdata = bus->sysdata; | 264 | dev->sysdata = bus->sysdata; |
| 271 | for (devfn = 0; devfn < 0x100; devfn += 8) { | 265 | for (devfn = 0; devfn < 0x100; devfn += 8) { |
| 272 | dev->devfn = devfn; | 266 | dev->devfn = devfn; |
| 273 | pci_rescan_slot(dev); | 267 | found += pci_rescan_slot(dev); |
| 268 | } | ||
| 269 | |||
| 270 | if (found) { | ||
| 271 | pci_bus_assign_resources(bus); | ||
| 272 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 273 | /* Skip already-added devices */ | ||
| 274 | if (dev->is_added) | ||
| 275 | continue; | ||
| 276 | retval = pci_bus_add_device(dev); | ||
| 277 | if (retval) | ||
| 278 | dev_err(&dev->dev, | ||
| 279 | "Error adding device, continuing\n"); | ||
| 280 | else | ||
| 281 | add_slot(dev); | ||
| 282 | } | ||
| 283 | pci_bus_add_devices(bus); | ||
| 274 | } | 284 | } |
| 275 | kfree(dev); | 285 | kfree(dev); |
| 276 | } | 286 | } |
