diff options
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index fd48b201eb53..6a0a82f0508b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -374,8 +374,11 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de | |||
374 | struct pci_bus *child; | 374 | struct pci_bus *child; |
375 | 375 | ||
376 | child = pci_alloc_child_bus(parent, dev, busnr); | 376 | child = pci_alloc_child_bus(parent, dev, busnr); |
377 | if (child) | 377 | if (child) { |
378 | spin_lock(&pci_bus_lock); | ||
378 | list_add_tail(&child->node, &parent->children); | 379 | list_add_tail(&child->node, &parent->children); |
380 | spin_unlock(&pci_bus_lock); | ||
381 | } | ||
379 | return child; | 382 | return child; |
380 | } | 383 | } |
381 | 384 | ||
@@ -411,7 +414,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
411 | { | 414 | { |
412 | struct pci_bus *child; | 415 | struct pci_bus *child; |
413 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); | 416 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); |
414 | u32 buses; | 417 | u32 buses, i; |
415 | u16 bctl; | 418 | u16 bctl; |
416 | 419 | ||
417 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); | 420 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); |
@@ -447,7 +450,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
447 | return max; | 450 | return max; |
448 | } | 451 | } |
449 | 452 | ||
450 | child = pci_alloc_child_bus(bus, dev, busnr); | 453 | child = pci_add_new_bus(bus, dev, busnr); |
451 | if (!child) | 454 | if (!child) |
452 | return max; | 455 | return max; |
453 | child->primary = buses & 0xFF; | 456 | child->primary = buses & 0xFF; |
@@ -470,7 +473,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
470 | /* Clear errors */ | 473 | /* Clear errors */ |
471 | pci_write_config_word(dev, PCI_STATUS, 0xffff); | 474 | pci_write_config_word(dev, PCI_STATUS, 0xffff); |
472 | 475 | ||
473 | child = pci_alloc_child_bus(bus, dev, ++max); | 476 | /* Prevent assigning a bus number that already exists. |
477 | * This can happen when a bridge is hot-plugged */ | ||
478 | if (pci_find_bus(pci_domain_nr(bus), max+1)) | ||
479 | return max; | ||
480 | child = pci_add_new_bus(bus, dev, ++max); | ||
474 | buses = (buses & 0xff000000) | 481 | buses = (buses & 0xff000000) |
475 | | ((unsigned int)(child->primary) << 0) | 482 | | ((unsigned int)(child->primary) << 0) |
476 | | ((unsigned int)(child->secondary) << 8) | 483 | | ((unsigned int)(child->secondary) << 8) |
@@ -501,7 +508,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
501 | * as cards with a PCI-to-PCI bridge can be | 508 | * as cards with a PCI-to-PCI bridge can be |
502 | * inserted later. | 509 | * inserted later. |
503 | */ | 510 | */ |
504 | max += CARDBUS_RESERVE_BUSNR; | 511 | for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) |
512 | if (pci_find_bus(pci_domain_nr(bus), | ||
513 | max+i+1)) | ||
514 | break; | ||
515 | max += i; | ||
505 | } | 516 | } |
506 | /* | 517 | /* |
507 | * Set the subordinate bus number to its real value. | 518 | * Set the subordinate bus number to its real value. |
@@ -757,7 +768,9 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) | |||
757 | * and the bus list for fixup functions, etc. | 768 | * and the bus list for fixup functions, etc. |
758 | */ | 769 | */ |
759 | INIT_LIST_HEAD(&dev->global_list); | 770 | INIT_LIST_HEAD(&dev->global_list); |
771 | spin_lock(&pci_bus_lock); | ||
760 | list_add_tail(&dev->bus_list, &bus->devices); | 772 | list_add_tail(&dev->bus_list, &bus->devices); |
773 | spin_unlock(&pci_bus_lock); | ||
761 | 774 | ||
762 | return dev; | 775 | return dev; |
763 | } | 776 | } |
@@ -878,7 +891,9 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, | |||
878 | pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); | 891 | pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); |
879 | goto err_out; | 892 | goto err_out; |
880 | } | 893 | } |
894 | spin_lock(&pci_bus_lock); | ||
881 | list_add_tail(&b->node, &pci_root_buses); | 895 | list_add_tail(&b->node, &pci_root_buses); |
896 | spin_unlock(&pci_bus_lock); | ||
882 | 897 | ||
883 | memset(dev, 0, sizeof(*dev)); | 898 | memset(dev, 0, sizeof(*dev)); |
884 | dev->parent = parent; | 899 | dev->parent = parent; |
@@ -911,8 +926,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, | |||
911 | 926 | ||
912 | b->subordinate = pci_scan_child_bus(b); | 927 | b->subordinate = pci_scan_child_bus(b); |
913 | 928 | ||
914 | pci_bus_add_devices(b); | ||
915 | |||
916 | return b; | 929 | return b; |
917 | 930 | ||
918 | sys_create_link_err: | 931 | sys_create_link_err: |
@@ -922,7 +935,9 @@ class_dev_create_file_err: | |||
922 | class_dev_reg_err: | 935 | class_dev_reg_err: |
923 | device_unregister(dev); | 936 | device_unregister(dev); |
924 | dev_reg_err: | 937 | dev_reg_err: |
938 | spin_lock(&pci_bus_lock); | ||
925 | list_del(&b->node); | 939 | list_del(&b->node); |
940 | spin_unlock(&pci_bus_lock); | ||
926 | err_out: | 941 | err_out: |
927 | kfree(dev); | 942 | kfree(dev); |
928 | kfree(b); | 943 | kfree(b); |