aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 19:17:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 19:17:07 -0400
commit6dd53aa4563a2c69e80a24d2cc68d484b5ea2891 (patch)
tree0cca9f65984b524527910960d972fc6ef85fac88 /drivers/pci/hotplug
parentf14121ab35912e3d2e57ac9a4ce1f9d4b7baeffb (diff)
parent63b96f7baeba71966c723912c3f8f0274577f877 (diff)
Merge tag 'for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: "Host bridge hotplug: - Add MMCONFIG support for hot-added host bridges (Jiang Liu) Device hotplug: - Move fixups from __init to __devinit (Sebastian Andrzej Siewior) - Call FINAL fixups for hot-added devices, too (Myron Stowe) - Factor out generic code for P2P bridge hot-add (Yinghai Lu) - Remove all functions in a slot, not just those with _EJx (Amos Kong) Dynamic resource management: - Track bus number allocation (struct resource tree per domain) (Yinghai Lu) - Make P2P bridge 1K I/O windows work with resource reassignment (Bjorn Helgaas, Yinghai Lu) - Disable decoding while updating 64-bit BARs (Bjorn Helgaas) Power management: - Add PCIe runtime D3cold support (Huang Ying) Virtualization: - Add VFIO infrastructure (ACS, DMA source ID quirks) (Alex Williamson) - Add quirks for devices with broken INTx masking (Jan Kiszka) Miscellaneous: - Fix some PCI Express capability version issues (Myron Stowe) - Factor out some arch code with a weak, generic, pcibios_setup() (Myron Stowe)" * tag 'for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (122 commits) PCI: hotplug: ensure a consistent return value in error case PCI: fix undefined reference to 'pci_fixup_final_inited' PCI: build resource code for M68K architecture PCI: pciehp: remove unused pciehp_get_max_lnk_width(), pciehp_get_cur_lnk_width() PCI: reorder __pci_assign_resource() (no change) PCI: fix truncation of resource size to 32 bits PCI: acpiphp: merge acpiphp_debug and debug PCI: acpiphp: remove unused res_lock sparc/PCI: replace pci_cfg_fake_ranges() with pci_read_bridge_bases() PCI: call final fixups hot-added devices PCI: move final fixups from __init to __devinit x86/PCI: move final fixups from __init to __devinit MIPS/PCI: move final fixups from __init to __devinit PCI: support sizing P2P bridge I/O windows with 1K granularity PCI: reimplement P2P bridge 1K I/O windows (Intel P64H2) PCI: disable MEM decoding while updating 64-bit MEM BARs PCI: leave MEM and IO decoding disabled during 64-bit BAR sizing, too PCI: never discard enable/suspend/resume_early/resume fixups PCI: release temporary reference in __nv_msi_ht_cap_quirk() PCI: restructure 'pci_do_fixups()' ...
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpiphp.h4
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c7
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c67
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c14
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c35
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c14
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c8
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c8
-rw-r--r--drivers/pci/hotplug/pciehp.h4
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c101
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c28
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c14
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c12
-rw-r--r--drivers/pci/hotplug/shpchp_core.c14
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c3
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c45
-rw-r--r--drivers/pci/hotplug/shpchp_sysfs.c6
17 files changed, 128 insertions, 256 deletions
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 7722108e78df..a1afb5b39ad4 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -89,8 +89,6 @@ struct acpiphp_bridge {
89 89
90 /* PCI-to-PCI bridge device */ 90 /* PCI-to-PCI bridge device */
91 struct pci_dev *pci_dev; 91 struct pci_dev *pci_dev;
92
93 spinlock_t res_lock;
94}; 92};
95 93
96 94
@@ -207,6 +205,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
207extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); 205extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
208 206
209/* variables */ 207/* variables */
210extern int acpiphp_debug; 208extern bool acpiphp_debug;
211 209
212#endif /* _ACPIPHP_H */ 210#endif /* _ACPIPHP_H */
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index aa41631e9e02..96316b74969f 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -47,8 +47,7 @@
47/* name size which is used for entries in pcihpfs */ 47/* name size which is used for entries in pcihpfs */
48#define SLOT_NAME_SIZE 21 /* {_SUN} */ 48#define SLOT_NAME_SIZE 21 /* {_SUN} */
49 49
50static bool debug; 50bool acpiphp_debug;
51int acpiphp_debug;
52 51
53/* local variables */ 52/* local variables */
54static int num_slots; 53static int num_slots;
@@ -62,7 +61,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
62MODULE_DESCRIPTION(DRIVER_DESC); 61MODULE_DESCRIPTION(DRIVER_DESC);
63MODULE_LICENSE("GPL"); 62MODULE_LICENSE("GPL");
64MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); 63MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
65module_param(debug, bool, 0644); 64module_param_named(debug, acpiphp_debug, bool, 0644);
66 65
67/* export the attention callback registration methods */ 66/* export the attention callback registration methods */
68EXPORT_SYMBOL_GPL(acpiphp_register_attention); 67EXPORT_SYMBOL_GPL(acpiphp_register_attention);
@@ -379,8 +378,6 @@ static int __init acpiphp_init(void)
379 if (acpi_pci_disabled) 378 if (acpi_pci_disabled)
380 return 0; 379 return 0;
381 380
382 acpiphp_debug = debug;
383
384 /* read all the ACPI info from the system */ 381 /* read all the ACPI info from the system */
385 return init_acpi(); 382 return init_acpi();
386} 383}
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 806c44fa645a..ad6fd6695495 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -100,11 +100,11 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
100 PCI_PRIMARY_BUS, 100 PCI_PRIMARY_BUS,
101 &buses); 101 &buses);
102 102
103 if (((buses >> 8) & 0xff) != bus->secondary) { 103 if (((buses >> 8) & 0xff) != bus->busn_res.start) {
104 buses = (buses & 0xff000000) 104 buses = (buses & 0xff000000)
105 | ((unsigned int)(bus->primary) << 0) 105 | ((unsigned int)(bus->primary) << 0)
106 | ((unsigned int)(bus->secondary) << 8) 106 | ((unsigned int)(bus->busn_res.start) << 8)
107 | ((unsigned int)(bus->subordinate) << 16); 107 | ((unsigned int)(bus->busn_res.end) << 16);
108 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); 108 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);
109 } 109 }
110 return NOTIFY_OK; 110 return NOTIFY_OK;
@@ -132,6 +132,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
132 if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) 132 if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle))
133 return AE_OK; 133 return AE_OK;
134 134
135 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
136 if (ACPI_FAILURE(status)) {
137 warn("can't evaluate _ADR (%#x)\n", status);
138 return AE_OK;
139 }
140
141 device = (adr >> 16) & 0xffff;
142 function = adr & 0xffff;
143
135 pdev = pbus->self; 144 pdev = pbus->self;
136 if (pdev && pci_is_pcie(pdev)) { 145 if (pdev && pci_is_pcie(pdev)) {
137 tmp = acpi_find_root_bridge_handle(pdev); 146 tmp = acpi_find_root_bridge_handle(pdev);
@@ -144,10 +153,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
144 } 153 }
145 } 154 }
146 155
147 acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
148 device = (adr >> 16) & 0xffff;
149 function = adr & 0xffff;
150
151 newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); 156 newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
152 if (!newfunc) 157 if (!newfunc)
153 return AE_NO_MEMORY; 158 return AE_NO_MEMORY;
@@ -391,8 +396,6 @@ static void add_host_bridge(acpi_handle *handle)
391 396
392 bridge->pci_bus = root->bus; 397 bridge->pci_bus = root->bus;
393 398
394 spin_lock_init(&bridge->res_lock);
395
396 init_bridge_misc(bridge); 399 init_bridge_misc(bridge);
397} 400}
398 401
@@ -425,7 +428,6 @@ static void add_p2p_bridge(acpi_handle *handle)
425 * (which we access during module unload). 428 * (which we access during module unload).
426 */ 429 */
427 get_device(&bridge->pci_bus->dev); 430 get_device(&bridge->pci_bus->dev);
428 spin_lock_init(&bridge->res_lock);
429 431
430 init_bridge_misc(bridge); 432 init_bridge_misc(bridge);
431 return; 433 return;
@@ -692,7 +694,7 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
692 * bus->subordinate value because it could have 694 * bus->subordinate value because it could have
693 * padding in it. 695 * padding in it.
694 */ 696 */
695 max = bus->secondary; 697 max = bus->busn_res.start;
696 698
697 list_for_each(tmp, &bus->children) { 699 list_for_each(tmp, &bus->children) {
698 n = pci_bus_max_busnr(pci_bus_b(tmp)); 700 n = pci_bus_max_busnr(pci_bus_b(tmp));
@@ -878,6 +880,24 @@ static void disable_bridges(struct pci_bus *bus)
878 } 880 }
879} 881}
880 882
883/* return first device in slot, acquiring a reference on it */
884static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot)
885{
886 struct pci_bus *bus = slot->bridge->pci_bus;
887 struct pci_dev *dev;
888 struct pci_dev *ret = NULL;
889
890 down_read(&pci_bus_sem);
891 list_for_each_entry(dev, &bus->devices, bus_list)
892 if (PCI_SLOT(dev->devfn) == slot->device) {
893 ret = pci_dev_get(dev);
894 break;
895 }
896 up_read(&pci_bus_sem);
897
898 return ret;
899}
900
881/** 901/**
882 * disable_device - disable a slot 902 * disable_device - disable a slot
883 * @slot: ACPI PHP slot 903 * @slot: ACPI PHP slot
@@ -893,6 +913,7 @@ static int disable_device(struct acpiphp_slot *slot)
893 pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); 913 pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
894 if (!pdev) 914 if (!pdev)
895 goto err_exit; 915 goto err_exit;
916 pci_dev_put(pdev);
896 917
897 list_for_each_entry(func, &slot->funcs, sibling) { 918 list_for_each_entry(func, &slot->funcs, sibling) {
898 if (func->bridge) { 919 if (func->bridge) {
@@ -901,18 +922,22 @@ static int disable_device(struct acpiphp_slot *slot)
901 (u32)1, NULL, NULL); 922 (u32)1, NULL, NULL);
902 func->bridge = NULL; 923 func->bridge = NULL;
903 } 924 }
925 }
904 926
905 pdev = pci_get_slot(slot->bridge->pci_bus, 927 /*
906 PCI_DEVFN(slot->device, func->function)); 928 * enable_device() enumerates all functions in this device via
907 if (pdev) { 929 * pci_scan_slot(), whether they have associated ACPI hotplug
908 pci_stop_bus_device(pdev); 930 * methods (_EJ0, etc.) or not. Therefore, we remove all functions
909 if (pdev->subordinate) { 931 * here.
910 disable_bridges(pdev->subordinate); 932 */
911 pci_disable_device(pdev); 933 while ((pdev = dev_in_slot(slot))) {
912 } 934 pci_stop_bus_device(pdev);
913 __pci_remove_bus_device(pdev); 935 if (pdev->subordinate) {
914 pci_dev_put(pdev); 936 disable_bridges(pdev->subordinate);
937 pci_disable_device(pdev);
915 } 938 }
939 __pci_remove_bus_device(pdev);
940 pci_dev_put(pdev);
916 } 941 }
917 942
918 list_for_each_entry(func, &slot->funcs, sibling) { 943 list_for_each_entry(func, &slot->funcs, sibling) {
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 3fadf2f135e8..2b4c412f94c3 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -225,7 +225,7 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
225 struct hotplug_slot *hotplug_slot; 225 struct hotplug_slot *hotplug_slot;
226 struct hotplug_slot_info *info; 226 struct hotplug_slot_info *info;
227 char name[SLOT_NAME_SIZE]; 227 char name[SLOT_NAME_SIZE];
228 int status = -ENOMEM; 228 int status;
229 int i; 229 int i;
230 230
231 if (!(controller && bus)) 231 if (!(controller && bus))
@@ -237,18 +237,24 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
237 */ 237 */
238 for (i = first; i <= last; ++i) { 238 for (i = first; i <= last; ++i) {
239 slot = kzalloc(sizeof (struct slot), GFP_KERNEL); 239 slot = kzalloc(sizeof (struct slot), GFP_KERNEL);
240 if (!slot) 240 if (!slot) {
241 status = -ENOMEM;
241 goto error; 242 goto error;
243 }
242 244
243 hotplug_slot = 245 hotplug_slot =
244 kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL); 246 kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
245 if (!hotplug_slot) 247 if (!hotplug_slot) {
248 status = -ENOMEM;
246 goto error_slot; 249 goto error_slot;
250 }
247 slot->hotplug_slot = hotplug_slot; 251 slot->hotplug_slot = hotplug_slot;
248 252
249 info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL); 253 info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
250 if (!info) 254 if (!info) {
255 status = -ENOMEM;
251 goto error_hpslot; 256 goto error_hpslot;
257 }
252 hotplug_slot->info = info; 258 hotplug_slot->info = info;
253 259
254 slot->bus = bus; 260 slot->bus = bus;
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index ae853ccd0cd5..dcc75c785443 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -285,42 +285,19 @@ int __ref cpci_configure_slot(struct slot *slot)
285 for (fn = 0; fn < 8; fn++) { 285 for (fn = 0; fn < 8; fn++) {
286 struct pci_dev *dev; 286 struct pci_dev *dev;
287 287
288 dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); 288 dev = pci_get_slot(parent,
289 PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
289 if (!dev) 290 if (!dev)
290 continue; 291 continue;
291 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || 292 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
292 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { 293 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
293 /* Find an unused bus number for the new bridge */ 294 pci_hp_add_bridge(dev);
294 struct pci_bus *child;
295 unsigned char busnr, start = parent->secondary;
296 unsigned char end = parent->subordinate;
297
298 for (busnr = start; busnr <= end; busnr++) {
299 if (!pci_find_bus(pci_domain_nr(parent),
300 busnr))
301 break;
302 }
303 if (busnr >= end) {
304 err("No free bus for hot-added bridge\n");
305 pci_dev_put(dev);
306 continue;
307 }
308 child = pci_add_new_bus(parent, dev, busnr);
309 if (!child) {
310 err("Cannot add new bus for %s\n",
311 pci_name(dev));
312 pci_dev_put(dev);
313 continue;
314 }
315 child->subordinate = pci_do_scan_bus(child);
316 pci_bus_size_bridges(child);
317 }
318 pci_dev_put(dev); 295 pci_dev_put(dev);
319 } 296 }
320 297
321 pci_bus_assign_resources(parent); 298 pci_assign_unassigned_bridge_resources(parent->self);
299
322 pci_bus_add_devices(parent); 300 pci_bus_add_devices(parent);
323 pci_enable_bridges(parent);
324 301
325 dbg("%s - exit", __func__); 302 dbg("%s - exit", __func__);
326 return 0; 303 return 0;
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 187a199da93c..c8eaeb43fa5d 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -611,7 +611,7 @@ static int ctrl_slot_setup(struct controller *ctrl,
611 u32 tempdword; 611 u32 tempdword;
612 char name[SLOT_NAME_SIZE]; 612 char name[SLOT_NAME_SIZE];
613 void __iomem *slot_entry= NULL; 613 void __iomem *slot_entry= NULL;
614 int result = -ENOMEM; 614 int result;
615 615
616 dbg("%s\n", __func__); 616 dbg("%s\n", __func__);
617 617
@@ -623,19 +623,25 @@ static int ctrl_slot_setup(struct controller *ctrl,
623 623
624 while (number_of_slots) { 624 while (number_of_slots) {
625 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 625 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
626 if (!slot) 626 if (!slot) {
627 result = -ENOMEM;
627 goto error; 628 goto error;
629 }
628 630
629 slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)), 631 slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
630 GFP_KERNEL); 632 GFP_KERNEL);
631 if (!slot->hotplug_slot) 633 if (!slot->hotplug_slot) {
634 result = -ENOMEM;
632 goto error_slot; 635 goto error_slot;
636 }
633 hotplug_slot = slot->hotplug_slot; 637 hotplug_slot = slot->hotplug_slot;
634 638
635 hotplug_slot->info = kzalloc(sizeof(*(hotplug_slot->info)), 639 hotplug_slot->info = kzalloc(sizeof(*(hotplug_slot->info)),
636 GFP_KERNEL); 640 GFP_KERNEL);
637 if (!hotplug_slot->info) 641 if (!hotplug_slot->info) {
642 result = -ENOMEM;
638 goto error_hpslot; 643 goto error_hpslot;
644 }
639 hotplug_slot_info = hotplug_slot->info; 645 hotplug_slot_info = hotplug_slot->info;
640 646
641 slot->ctrl = ctrl; 647 slot->ctrl = ctrl;
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 1c8494021a42..09801c6945ce 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -83,7 +83,6 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom
83 83
84int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) 84int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
85{ 85{
86 unsigned char bus;
87 struct pci_bus *child; 86 struct pci_bus *child;
88 int num; 87 int num;
89 88
@@ -106,9 +105,10 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
106 } 105 }
107 106
108 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 107 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
109 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); 108 pci_hp_add_bridge(func->pci_dev);
110 child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); 109 child = func->pci_dev->subordinate;
111 pci_do_scan_bus(child); 110 if (child)
111 pci_bus_add_devices(child);
112 } 112 }
113 113
114 pci_dev_put(func->pci_dev); 114 pci_dev_put(func->pci_dev);
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 01cc054eb0d5..cbd72d81d253 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -775,7 +775,6 @@ static u8 bus_structure_fixup(u8 busno)
775 775
776static int ibm_configure_device(struct pci_func *func) 776static int ibm_configure_device(struct pci_func *func)
777{ 777{
778 unsigned char bus;
779 struct pci_bus *child; 778 struct pci_bus *child;
780 int num; 779 int num;
781 int flag = 0; /* this is to make sure we don't double scan the bus, 780 int flag = 0; /* this is to make sure we don't double scan the bus,
@@ -805,9 +804,10 @@ static int ibm_configure_device(struct pci_func *func)
805 } 804 }
806 } 805 }
807 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { 806 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
808 pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus); 807 pci_hp_add_bridge(func->dev);
809 child = pci_add_new_bus(func->dev->bus, func->dev, bus); 808 child = func->dev->subordinate;
810 pci_do_scan_bus(child); 809 if (child)
810 pci_bus_add_devices(child);
811 } 811 }
812 812
813 return 0; 813 return 0;
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 4b7cce1de6ec..26ffd3e3fb74 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -149,10 +149,6 @@ int pciehp_get_attention_status(struct slot *slot, u8 *status);
149int pciehp_set_attention_status(struct slot *slot, u8 status); 149int pciehp_set_attention_status(struct slot *slot, u8 status);
150int pciehp_get_latch_status(struct slot *slot, u8 *status); 150int pciehp_get_latch_status(struct slot *slot, u8 *status);
151int pciehp_get_adapter_status(struct slot *slot, u8 *status); 151int pciehp_get_adapter_status(struct slot *slot, u8 *status);
152int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *speed);
153int pciehp_get_max_link_width(struct slot *slot, enum pcie_link_width *val);
154int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *speed);
155int pciehp_get_cur_link_width(struct slot *slot, enum pcie_link_width *val);
156int pciehp_query_power_fault(struct slot *slot); 152int pciehp_query_power_fault(struct slot *slot);
157void pciehp_green_led_on(struct slot *slot); 153void pciehp_green_led_on(struct slot *slot);
158void pciehp_green_led_off(struct slot *slot); 154void pciehp_green_led_off(struct slot *slot);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index a960faec1021..302451e8289d 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -705,107 +705,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
705 return IRQ_HANDLED; 705 return IRQ_HANDLED;
706} 706}
707 707
708int pciehp_get_max_lnk_width(struct slot *slot,
709 enum pcie_link_width *value)
710{
711 struct controller *ctrl = slot->ctrl;
712 enum pcie_link_width lnk_wdth;
713 u32 lnk_cap;
714 int retval = 0;
715
716 retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap);
717 if (retval) {
718 ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
719 return retval;
720 }
721
722 switch ((lnk_cap & PCI_EXP_LNKSTA_NLW) >> 4){
723 case 0:
724 lnk_wdth = PCIE_LNK_WIDTH_RESRV;
725 break;
726 case 1:
727 lnk_wdth = PCIE_LNK_X1;
728 break;
729 case 2:
730 lnk_wdth = PCIE_LNK_X2;
731 break;
732 case 4:
733 lnk_wdth = PCIE_LNK_X4;
734 break;
735 case 8:
736 lnk_wdth = PCIE_LNK_X8;
737 break;
738 case 12:
739 lnk_wdth = PCIE_LNK_X12;
740 break;
741 case 16:
742 lnk_wdth = PCIE_LNK_X16;
743 break;
744 case 32:
745 lnk_wdth = PCIE_LNK_X32;
746 break;
747 default:
748 lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
749 break;
750 }
751
752 *value = lnk_wdth;
753 ctrl_dbg(ctrl, "Max link width = %d\n", lnk_wdth);
754
755 return retval;
756}
757
758int pciehp_get_cur_lnk_width(struct slot *slot,
759 enum pcie_link_width *value)
760{
761 struct controller *ctrl = slot->ctrl;
762 enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
763 int retval = 0;
764 u16 lnk_status;
765
766 retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
767 if (retval) {
768 ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
769 __func__);
770 return retval;
771 }
772
773 switch ((lnk_status & PCI_EXP_LNKSTA_NLW) >> 4){
774 case 0:
775 lnk_wdth = PCIE_LNK_WIDTH_RESRV;
776 break;
777 case 1:
778 lnk_wdth = PCIE_LNK_X1;
779 break;
780 case 2:
781 lnk_wdth = PCIE_LNK_X2;
782 break;
783 case 4:
784 lnk_wdth = PCIE_LNK_X4;
785 break;
786 case 8:
787 lnk_wdth = PCIE_LNK_X8;
788 break;
789 case 12:
790 lnk_wdth = PCIE_LNK_X12;
791 break;
792 case 16:
793 lnk_wdth = PCIE_LNK_X16;
794 break;
795 case 32:
796 lnk_wdth = PCIE_LNK_X32;
797 break;
798 default:
799 lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
800 break;
801 }
802
803 *value = lnk_wdth;
804 ctrl_dbg(ctrl, "Current link width = %d\n", lnk_wdth);
805
806 return retval;
807}
808
809int pcie_enable_notification(struct controller *ctrl) 708int pcie_enable_notification(struct controller *ctrl)
810{ 709{
811 u16 cmd, mask; 710 u16 cmd, mask;
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 47d9dc06b109..09cecaf450c5 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -34,29 +34,6 @@
34#include "../pci.h" 34#include "../pci.h"
35#include "pciehp.h" 35#include "pciehp.h"
36 36
37static int __ref pciehp_add_bridge(struct pci_dev *dev)
38{
39 struct pci_bus *parent = dev->bus;
40 int pass, busnr, start = parent->secondary;
41 int end = parent->subordinate;
42
43 for (busnr = start; busnr <= end; busnr++) {
44 if (!pci_find_bus(pci_domain_nr(parent), busnr))
45 break;
46 }
47 if (busnr-- > end) {
48 err("No bus number available for hot-added bridge %s\n",
49 pci_name(dev));
50 return -1;
51 }
52 for (pass = 0; pass < 2; pass++)
53 busnr = pci_scan_bridge(parent, dev, busnr, pass);
54 if (!dev->subordinate)
55 return -1;
56
57 return 0;
58}
59
60int pciehp_configure_device(struct slot *p_slot) 37int pciehp_configure_device(struct slot *p_slot)
61{ 38{
62 struct pci_dev *dev; 39 struct pci_dev *dev;
@@ -85,9 +62,8 @@ int pciehp_configure_device(struct slot *p_slot)
85 if (!dev) 62 if (!dev)
86 continue; 63 continue;
87 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || 64 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
88 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { 65 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
89 pciehp_add_bridge(dev); 66 pci_hp_add_bridge(dev);
90 }
91 pci_dev_put(dev); 67 pci_dev_put(dev);
92 } 68 }
93 69
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
index b20ceaaa31f4..1f00b937f721 100644
--- a/drivers/pci/hotplug/pcihp_skeleton.c
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -252,7 +252,7 @@ static int __init init_slots(void)
252 struct slot *slot; 252 struct slot *slot;
253 struct hotplug_slot *hotplug_slot; 253 struct hotplug_slot *hotplug_slot;
254 struct hotplug_slot_info *info; 254 struct hotplug_slot_info *info;
255 int retval = -ENOMEM; 255 int retval;
256 int i; 256 int i;
257 257
258 /* 258 /*
@@ -261,17 +261,23 @@ static int __init init_slots(void)
261 */ 261 */
262 for (i = 0; i < num_slots; ++i) { 262 for (i = 0; i < num_slots; ++i) {
263 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 263 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
264 if (!slot) 264 if (!slot) {
265 retval = -ENOMEM;
265 goto error; 266 goto error;
267 }
266 268
267 hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); 269 hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
268 if (!hotplug_slot) 270 if (!hotplug_slot) {
271 retval = -ENOMEM;
269 goto error_slot; 272 goto error_slot;
273 }
270 slot->hotplug_slot = hotplug_slot; 274 slot->hotplug_slot = hotplug_slot;
271 275
272 info = kzalloc(sizeof(*info), GFP_KERNEL); 276 info = kzalloc(sizeof(*info), GFP_KERNEL);
273 if (!info) 277 if (!info) {
278 retval = -ENOMEM;
274 goto error_hpslot; 279 goto error_hpslot;
280 }
275 hotplug_slot->info = info; 281 hotplug_slot->info = info;
276 282
277 slot->number = i; 283 slot->number = i;
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index de573113c102..f64ca92253da 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -397,13 +397,11 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
397 else 397 else
398 sn_io_slot_fixup(dev); 398 sn_io_slot_fixup(dev);
399 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 399 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
400 unsigned char sec_bus; 400 pci_hp_add_bridge(dev);
401 pci_read_config_byte(dev, PCI_SECONDARY_BUS, 401 if (dev->subordinate) {
402 &sec_bus); 402 new_bus = dev->subordinate;
403 new_bus = pci_add_new_bus(dev->bus, dev, 403 new_ppb = 1;
404 sec_bus); 404 }
405 pci_scan_child_bus(new_bus);
406 new_ppb = 1;
407 } 405 }
408 pci_dev_put(dev); 406 pci_dev_put(dev);
409 } 407 }
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 7414fd9ad1d2..b6de307248e4 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -99,22 +99,28 @@ static int init_slots(struct controller *ctrl)
99 struct hotplug_slot *hotplug_slot; 99 struct hotplug_slot *hotplug_slot;
100 struct hotplug_slot_info *info; 100 struct hotplug_slot_info *info;
101 char name[SLOT_NAME_SIZE]; 101 char name[SLOT_NAME_SIZE];
102 int retval = -ENOMEM; 102 int retval;
103 int i; 103 int i;
104 104
105 for (i = 0; i < ctrl->num_slots; i++) { 105 for (i = 0; i < ctrl->num_slots; i++) {
106 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 106 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
107 if (!slot) 107 if (!slot) {
108 retval = -ENOMEM;
108 goto error; 109 goto error;
110 }
109 111
110 hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); 112 hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
111 if (!hotplug_slot) 113 if (!hotplug_slot) {
114 retval = -ENOMEM;
112 goto error_slot; 115 goto error_slot;
116 }
113 slot->hotplug_slot = hotplug_slot; 117 slot->hotplug_slot = hotplug_slot;
114 118
115 info = kzalloc(sizeof(*info), GFP_KERNEL); 119 info = kzalloc(sizeof(*info), GFP_KERNEL);
116 if (!info) 120 if (!info) {
121 retval = -ENOMEM;
117 goto error_hpslot; 122 goto error_hpslot;
123 }
118 hotplug_slot->info = info; 124 hotplug_slot->info = info;
119 125
120 slot->hp_slot = i; 126 slot->hp_slot = i;
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index b00b09bdd38a..f9b5a52e4115 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -262,9 +262,6 @@ static int board_added(struct slot *p_slot)
262 } 262 }
263 263
264 if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { 264 if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
265 if (slots_not_empty)
266 return WRONG_BUS_FREQUENCY;
267
268 if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { 265 if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
269 ctrl_err(ctrl, "%s: Issue of set bus speed mode command" 266 ctrl_err(ctrl, "%s: Issue of set bus speed mode command"
270 " failed\n", __func__); 267 " failed\n", __func__);
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index df7e4bfadae3..c627ed9957d1 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -37,9 +37,10 @@
37int __ref shpchp_configure_device(struct slot *p_slot) 37int __ref shpchp_configure_device(struct slot *p_slot)
38{ 38{
39 struct pci_dev *dev; 39 struct pci_dev *dev;
40 struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
41 int num, fn;
42 struct controller *ctrl = p_slot->ctrl; 40 struct controller *ctrl = p_slot->ctrl;
41 struct pci_dev *bridge = ctrl->pci_dev;
42 struct pci_bus *parent = bridge->subordinate;
43 int num, fn;
43 44
44 dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); 45 dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
45 if (dev) { 46 if (dev) {
@@ -61,39 +62,23 @@ int __ref shpchp_configure_device(struct slot *p_slot)
61 if (!dev) 62 if (!dev)
62 continue; 63 continue;
63 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || 64 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
64 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { 65 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
65 /* Find an unused bus number for the new bridge */ 66 pci_hp_add_bridge(dev);
66 struct pci_bus *child; 67 pci_dev_put(dev);
67 unsigned char busnr, start = parent->secondary; 68 }
68 unsigned char end = parent->subordinate; 69
69 for (busnr = start; busnr <= end; busnr++) { 70 pci_assign_unassigned_bridge_resources(bridge);
70 if (!pci_find_bus(pci_domain_nr(parent), 71
71 busnr)) 72 for (fn = 0; fn < 8; fn++) {
72 break; 73 dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
73 } 74 if (!dev)
74 if (busnr > end) { 75 continue;
75 ctrl_err(ctrl,
76 "No free bus for hot-added bridge\n");
77 pci_dev_put(dev);
78 continue;
79 }
80 child = pci_add_new_bus(parent, dev, busnr);
81 if (!child) {
82 ctrl_err(ctrl, "Cannot add new bus for %s\n",
83 pci_name(dev));
84 pci_dev_put(dev);
85 continue;
86 }
87 child->subordinate = pci_do_scan_bus(child);
88 pci_bus_size_bridges(child);
89 }
90 pci_configure_slot(dev); 76 pci_configure_slot(dev);
91 pci_dev_put(dev); 77 pci_dev_put(dev);
92 } 78 }
93 79
94 pci_bus_assign_resources(parent);
95 pci_bus_add_devices(parent); 80 pci_bus_add_devices(parent);
96 pci_enable_bridges(parent); 81
97 return 0; 82 return 0;
98} 83}
99 84
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
index efa30da1ae8f..eeb23ceae4a8 100644
--- a/drivers/pci/hotplug/shpchp_sysfs.c
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -73,13 +73,13 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha
73 } 73 }
74 } 74 }
75 out += sprintf(out, "Free resources: bus numbers\n"); 75 out += sprintf(out, "Free resources: bus numbers\n");
76 for (busnr = bus->secondary; busnr <= bus->subordinate; busnr++) { 76 for (busnr = bus->busn_res.start; busnr <= bus->busn_res.end; busnr++) {
77 if (!pci_find_bus(pci_domain_nr(bus), busnr)) 77 if (!pci_find_bus(pci_domain_nr(bus), busnr))
78 break; 78 break;
79 } 79 }
80 if (busnr < bus->subordinate) 80 if (busnr < bus->busn_res.end)
81 out += sprintf(out, "start = %8.8x, length = %8.8x\n", 81 out += sprintf(out, "start = %8.8x, length = %8.8x\n",
82 busnr, (bus->subordinate - busnr)); 82 busnr, (int)(bus->busn_res.end - busnr));
83 83
84 return out - buf; 84 return out - buf;
85} 85}