From b918c62e086b2130a7bae44110ca516ef10bfe5a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:11 -0700 Subject: PCI: replace struct pci_bus secondary/subordinate with busn_res Replace the struct pci_bus secondary/subordinate members with the struct resource busn_res. Later we'll build a resource tree of these bus numbers. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp_glue.c | 8 ++++---- drivers/pci/hotplug/cpci_hotplug_pci.c | 6 +++--- drivers/pci/hotplug/pciehp_pci.c | 4 ++-- drivers/pci/hotplug/shpchp_pci.c | 6 +++--- drivers/pci/hotplug/shpchp_sysfs.c | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 806c44fa645a..62d0ae4dfcad 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, PCI_PRIMARY_BUS, &buses); - if (((buses >> 8) & 0xff) != bus->secondary) { + if (((buses >> 8) & 0xff) != bus->busn_res.start) { buses = (buses & 0xff000000) | ((unsigned int)(bus->primary) << 0) - | ((unsigned int)(bus->secondary) << 8) - | ((unsigned int)(bus->subordinate) << 16); + | ((unsigned int)(bus->busn_res.start) << 8) + | ((unsigned int)(bus->busn_res.end) << 16); pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); } return NOTIFY_OK; @@ -692,7 +692,7 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) * bus->subordinate value because it could have * padding in it. */ - max = bus->secondary; + max = bus->busn_res.start; list_for_each(tmp, &bus->children) { n = pci_bus_max_busnr(pci_bus_b(tmp)); diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index ae853ccd0cd5..42f3a61db87c 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -292,8 +292,8 @@ int __ref cpci_configure_slot(struct slot *slot) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { /* Find an unused bus number for the new bridge */ struct pci_bus *child; - unsigned char busnr, start = parent->secondary; - unsigned char end = parent->subordinate; + unsigned char busnr, start = parent->busn_res.start; + unsigned char end = parent->busn_res.end; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), @@ -312,7 +312,7 @@ int __ref cpci_configure_slot(struct slot *slot) pci_dev_put(dev); continue; } - child->subordinate = pci_do_scan_bus(child); + child->busn_res.end = pci_do_scan_bus(child); pci_bus_size_bridges(child); } pci_dev_put(dev); diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 47d9dc06b109..b898f06b588d 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -37,8 +37,8 @@ static int __ref pciehp_add_bridge(struct pci_dev *dev) { struct pci_bus *parent = dev->bus; - int pass, busnr, start = parent->secondary; - int end = parent->subordinate; + int pass, busnr, start = parent->busn_res.start; + int end = parent->busn_res.end; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), busnr)) diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index df7e4bfadae3..d021eb031b3c 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -64,8 +64,8 @@ int __ref shpchp_configure_device(struct slot *p_slot) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { /* Find an unused bus number for the new bridge */ struct pci_bus *child; - unsigned char busnr, start = parent->secondary; - unsigned char end = parent->subordinate; + unsigned char busnr, start = parent->busn_res.start; + unsigned char end = parent->busn_res.end; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), busnr)) @@ -84,7 +84,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) pci_dev_put(dev); continue; } - child->subordinate = pci_do_scan_bus(child); + child->busn_res.end = pci_do_scan_bus(child); pci_bus_size_bridges(child); } pci_configure_slot(dev); 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 } } out += sprintf(out, "Free resources: bus numbers\n"); - for (busnr = bus->secondary; busnr <= bus->subordinate; busnr++) { + for (busnr = bus->busn_res.start; busnr <= bus->busn_res.end; busnr++) { if (!pci_find_bus(pci_domain_nr(bus), busnr)) break; } - if (busnr < bus->subordinate) + if (busnr < bus->busn_res.end) out += sprintf(out, "start = %8.8x, length = %8.8x\n", - busnr, (bus->subordinate - busnr)); + busnr, (int)(bus->busn_res.end - busnr)); return out - buf; } -- cgit v1.2.3 From f406384628e97618955e17e8d61e59d5ecdc9ca0 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: PCI: cpci_hotplug: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpci_hotplug_pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 42f3a61db87c..111b7d94c9a9 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -294,6 +294,7 @@ int __ref cpci_configure_slot(struct slot *slot) struct pci_bus *child; unsigned char busnr, start = parent->busn_res.start; unsigned char end = parent->busn_res.end; + int max; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), @@ -312,7 +313,8 @@ int __ref cpci_configure_slot(struct slot *slot) pci_dev_put(dev); continue; } - child->busn_res.end = pci_do_scan_bus(child); + max = pci_do_scan_bus(child); + pci_bus_update_busn_res_end(child, max); pci_bus_size_bridges(child); } pci_dev_put(dev); -- cgit v1.2.3 From 6cda0fcf26df18f0e5476fbff12845cc46e1f41b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: PCI: shpchp: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/shpchp_pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index d021eb031b3c..13069802b8c8 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -66,6 +66,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) struct pci_bus *child; unsigned char busnr, start = parent->busn_res.start; unsigned char end = parent->busn_res.end; + int max; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), busnr)) @@ -84,7 +85,8 @@ int __ref shpchp_configure_device(struct slot *p_slot) pci_dev_put(dev); continue; } - child->busn_res.end = pci_do_scan_bus(child); + max = pci_do_scan_bus(child); + pci_bus_update_busn_res_end(child, max); pci_bus_size_bridges(child); } pci_configure_slot(dev); -- cgit v1.2.3 From 450878759aa10c6d172a0cafd5922b23a3b4547a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: PCI: cpqhp: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpqphp_pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 1c8494021a42..24716725263f 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c @@ -106,9 +106,11 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) } if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + int max; pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); - pci_do_scan_bus(child); + max = pci_do_scan_bus(child); + pci_bus_update_busn_res_end(child, max); } pci_dev_put(func->pci_dev); -- cgit v1.2.3 From d0a350fe57c0a4014a8eccf8166d7dc2e599ce5c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: PCI: ibmhp: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/ibmphp_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 4fda7e6a86a7..a62f296e8b0d 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -805,9 +805,11 @@ static int ibm_configure_device(struct pci_func *func) } } if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { + int max; pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus); child = pci_add_new_bus(func->dev->bus, func->dev, bus); - pci_do_scan_bus(child); + max = pci_do_scan_bus(child); + pci_bus_update_busn_res_end(child, max); } return 0; -- cgit v1.2.3 From 85019faf4a88477cc72f56b6e371955ea0bb7a2a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: PCI: sgihp: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/sgi_hotplug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index de573113c102..b0bb3b537bb0 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -398,11 +398,13 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) sn_io_slot_fixup(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { unsigned char sec_bus; + int max; pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_bus); new_bus = pci_add_new_bus(dev->bus, dev, sec_bus); - pci_scan_child_bus(new_bus); + max = pci_scan_child_bus(new_bus); + pci_bus_update_busn_res_end(new_bus, max); new_ppb = 1; } pci_dev_put(dev); -- cgit v1.2.3 From c6da81a4d3cb8d461f77c5f61843fcc9c18b6c2c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: PCI: pciehp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: split "add generic pci_hp_add_bridge()" into a separate patch] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/pciehp_pci.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index b898f06b588d..09cecaf450c5 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -34,29 +34,6 @@ #include "../pci.h" #include "pciehp.h" -static int __ref pciehp_add_bridge(struct pci_dev *dev) -{ - struct pci_bus *parent = dev->bus; - int pass, busnr, start = parent->busn_res.start; - int end = parent->busn_res.end; - - for (busnr = start; busnr <= end; busnr++) { - if (!pci_find_bus(pci_domain_nr(parent), busnr)) - break; - } - if (busnr-- > end) { - err("No bus number available for hot-added bridge %s\n", - pci_name(dev)); - return -1; - } - for (pass = 0; pass < 2; pass++) - busnr = pci_scan_bridge(parent, dev, busnr, pass); - if (!dev->subordinate) - return -1; - - return 0; -} - int pciehp_configure_device(struct slot *p_slot) { struct pci_dev *dev; @@ -85,9 +62,8 @@ int pciehp_configure_device(struct slot *p_slot) if (!dev) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || - (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { - pciehp_add_bridge(dev); - } + (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) + pci_hp_add_bridge(dev); pci_dev_put(dev); } -- cgit v1.2.3 From 073ae10c0f8284b6c6dd9708656802507349ef91 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: PCI: cpci_hotplug: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpci_hotplug_pci.c | 37 ++++++---------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 111b7d94c9a9..dcc75c785443 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -285,44 +285,19 @@ int __ref cpci_configure_slot(struct slot *slot) for (fn = 0; fn < 8; fn++) { struct pci_dev *dev; - dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); + dev = pci_get_slot(parent, + PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); if (!dev) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || - (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { - /* Find an unused bus number for the new bridge */ - struct pci_bus *child; - unsigned char busnr, start = parent->busn_res.start; - unsigned char end = parent->busn_res.end; - int max; - - for (busnr = start; busnr <= end; busnr++) { - if (!pci_find_bus(pci_domain_nr(parent), - busnr)) - break; - } - if (busnr >= end) { - err("No free bus for hot-added bridge\n"); - pci_dev_put(dev); - continue; - } - child = pci_add_new_bus(parent, dev, busnr); - if (!child) { - err("Cannot add new bus for %s\n", - pci_name(dev)); - pci_dev_put(dev); - continue; - } - max = pci_do_scan_bus(child); - pci_bus_update_busn_res_end(child, max); - pci_bus_size_bridges(child); - } + (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) + pci_hp_add_bridge(dev); pci_dev_put(dev); } - pci_bus_assign_resources(parent); + pci_assign_unassigned_bridge_resources(parent->self); + pci_bus_add_devices(parent); - pci_enable_bridges(parent); dbg("%s - exit", __func__); return 0; -- cgit v1.2.3 From 7d01f70ac6f48733d595f1a54aa7c4d2ae3fef0d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: PCI: shpchp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/shpchp_pci.c | 47 +++++++++++++--------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 13069802b8c8..c627ed9957d1 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -37,9 +37,10 @@ int __ref shpchp_configure_device(struct slot *p_slot) { struct pci_dev *dev; - struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; - int num, fn; struct controller *ctrl = p_slot->ctrl; + struct pci_dev *bridge = ctrl->pci_dev; + struct pci_bus *parent = bridge->subordinate; + int num, fn; dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); if (dev) { @@ -61,41 +62,23 @@ int __ref shpchp_configure_device(struct slot *p_slot) if (!dev) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || - (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { - /* Find an unused bus number for the new bridge */ - struct pci_bus *child; - unsigned char busnr, start = parent->busn_res.start; - unsigned char end = parent->busn_res.end; - int max; - for (busnr = start; busnr <= end; busnr++) { - if (!pci_find_bus(pci_domain_nr(parent), - busnr)) - break; - } - if (busnr > end) { - ctrl_err(ctrl, - "No free bus for hot-added bridge\n"); - pci_dev_put(dev); - continue; - } - child = pci_add_new_bus(parent, dev, busnr); - if (!child) { - ctrl_err(ctrl, "Cannot add new bus for %s\n", - pci_name(dev)); - pci_dev_put(dev); - continue; - } - max = pci_do_scan_bus(child); - pci_bus_update_busn_res_end(child, max); - pci_bus_size_bridges(child); - } + (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) + pci_hp_add_bridge(dev); + pci_dev_put(dev); + } + + pci_assign_unassigned_bridge_resources(bridge); + + for (fn = 0; fn < 8; fn++) { + dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); + if (!dev) + continue; pci_configure_slot(dev); pci_dev_put(dev); } - pci_bus_assign_resources(parent); pci_bus_add_devices(parent); - pci_enable_bridges(parent); + return 0; } -- cgit v1.2.3 From 04de975e7840e6d9da3ef44ab414f3ee1b98d611 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: PCI: cpqhp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpqphp_pci.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 24716725263f..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 int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) { - unsigned char bus; struct pci_bus *child; int num; @@ -106,11 +105,10 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) } if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - int max; - pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); - child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); - max = pci_do_scan_bus(child); - pci_bus_update_busn_res_end(child, max); + pci_hp_add_bridge(func->pci_dev); + child = func->pci_dev->subordinate; + if (child) + pci_bus_add_devices(child); } pci_dev_put(func->pci_dev); -- cgit v1.2.3 From 2d7abf32925f1a8aeeb37234c8ea7590ebbe62be Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: PCI: ibmhp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/ibmphp_core.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index a62f296e8b0d..7dccad5fc891 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) static int ibm_configure_device(struct pci_func *func) { - unsigned char bus; struct pci_bus *child; int num; int flag = 0; /* this is to make sure we don't double scan the bus, @@ -805,11 +804,10 @@ static int ibm_configure_device(struct pci_func *func) } } if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { - int max; - pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus); - child = pci_add_new_bus(func->dev->bus, func->dev, bus); - max = pci_do_scan_bus(child); - pci_bus_update_busn_res_end(child, max); + pci_hp_add_bridge(func->dev); + child = func->dev->subordinate; + if (child) + pci_bus_add_devices(child); } return 0; -- cgit v1.2.3 From 69ba29b9f91317b0cb8a4891c0cc6270a6f77ec9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: PCI: sgihp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/sgi_hotplug.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index b0bb3b537bb0..f64ca92253da 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -397,15 +397,11 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) else sn_io_slot_fixup(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - unsigned char sec_bus; - int max; - pci_read_config_byte(dev, PCI_SECONDARY_BUS, - &sec_bus); - new_bus = pci_add_new_bus(dev->bus, dev, - sec_bus); - max = pci_scan_child_bus(new_bus); - pci_bus_update_busn_res_end(new_bus, max); - new_ppb = 1; + pci_hp_add_bridge(dev); + if (dev->subordinate) { + new_bus = dev->subordinate; + new_ppb = 1; + } } pci_dev_put(dev); } -- cgit v1.2.3 From 638f293307b5787b69bf0a0bc915aed491efbec9 Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Tue, 22 May 2012 21:58:40 -0600 Subject: PCI: acpiphp: fix function 0 leak when disabling a slot Previously, we acquired two references to function 0, but only released one. [bhelgaas: split this out from "remove all functions" fix] Signed-off-by: Amos Kong Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp_glue.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 62d0ae4dfcad..c8f999102765 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -893,6 +893,7 @@ static int disable_device(struct acpiphp_slot *slot) pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); if (!pdev) goto err_exit; + pci_dev_put(pdev); list_for_each_entry(func, &slot->funcs, sibling) { if (func->bridge) { -- cgit v1.2.3 From ce29ca3ea40744f24c2b5d88431e8ac566d257cc Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Wed, 23 May 2012 10:20:35 -0600 Subject: PCI: acpiphp: remove all functions in slot, even without ACPI _EJx When we add a device with acpiphp, we enumerate all functions in the slot with pci_scan_slot(), regardless of whether they have associated ACPI methods such as _EJ0. When removing the device, we previously removed only the functions with those ACPI methods. This patch makes the remove symmetric with the add: we remove all functions in the slot, whether they have associated ACPI methods or not. With qemu-kvm and SeaBIOS, we can build a multi-function device where only function 0 has _EJ0 and _ADR (see bugzilla below). Removing and re-adding that slot (including all functions of the device) works correctly with Windows guests. This patch makes it also work in Linux guests. [bhelgaas: restructure loop iteration, pull out of slot->funcs loop] Reference: https://bugzilla.kernel.org/show_bug.cgi?id=43219 Signed-off-by: Amos Kong Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp_glue.c | 42 +++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index c8f999102765..73af3374e915 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -878,6 +878,24 @@ static void disable_bridges(struct pci_bus *bus) } } +/* return first device in slot, acquiring a reference on it */ +static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) +{ + struct pci_bus *bus = slot->bridge->pci_bus; + struct pci_dev *dev; + struct pci_dev *ret = NULL; + + down_read(&pci_bus_sem); + list_for_each_entry(dev, &bus->devices, bus_list) + if (PCI_SLOT(dev->devfn) == slot->device) { + ret = pci_dev_get(dev); + break; + } + up_read(&pci_bus_sem); + + return ret; +} + /** * disable_device - disable a slot * @slot: ACPI PHP slot @@ -902,18 +920,22 @@ static int disable_device(struct acpiphp_slot *slot) (u32)1, NULL, NULL); func->bridge = NULL; } + } - pdev = pci_get_slot(slot->bridge->pci_bus, - PCI_DEVFN(slot->device, func->function)); - if (pdev) { - pci_stop_bus_device(pdev); - if (pdev->subordinate) { - disable_bridges(pdev->subordinate); - pci_disable_device(pdev); - } - __pci_remove_bus_device(pdev); - pci_dev_put(pdev); + /* + * enable_device() enumerates all functions in this device via + * pci_scan_slot(), whether they have associated ACPI hotplug + * methods (_EJ0, etc.) or not. Therefore, we remove all functions + * here. + */ + while ((pdev = dev_in_slot(slot))) { + pci_stop_bus_device(pdev); + if (pdev->subordinate) { + disable_bridges(pdev->subordinate); + pci_disable_device(pdev); } + __pci_remove_bus_device(pdev); + pci_dev_put(pdev); } list_for_each_entry(func, &slot->funcs, sibling) { -- cgit v1.2.3 From 67454b6602c3519d15193630e6765a5f02f39160 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 20 Jun 2012 16:11:45 -0600 Subject: PCI: shpchp: remove dead code "slots_not_empty" is initialized to zero and can't be set again before reaching this point, so this return statement is dead. Remove it. Found by Coverity (CID 114324). Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/shpchp_ctrl.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/pci/hotplug') 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) } if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { - if (slots_not_empty) - return WRONG_BUS_FREQUENCY; - if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { ctrl_err(ctrl, "%s: Issue of set bus speed mode command" " failed\n", __func__); -- cgit v1.2.3 From dfb117b3e50c52c7b3416db4a4569224b8db80bb Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 20 Jun 2012 16:18:29 -0600 Subject: PCI: acpiphp: check whether _ADR evaluation succeeded Check whether we evaluated _ADR successfully. Previously we ignored failure, so we would have used garbage data from the stack as the device and function number. We return AE_OK so that we ignore only this slot and continue looking for other slots. Found by Coverity (CID 113981). Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp_glue.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 806c44fa645a..09bf37721842 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -132,6 +132,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) return AE_OK; + status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); + if (ACPI_FAILURE(status)) { + warn("can't evaluate _ADR (%#x)\n", status); + return AE_OK; + } + + device = (adr >> 16) & 0xffff; + function = adr & 0xffff; + pdev = pbus->self; if (pdev && pci_is_pcie(pdev)) { tmp = acpi_find_root_bridge_handle(pdev); @@ -144,10 +153,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) } } - acpi_evaluate_integer(handle, "_ADR", NULL, &adr); - device = (adr >> 16) & 0xffff; - function = adr & 0xffff; - newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); if (!newfunc) return AE_NO_MEMORY; -- cgit v1.2.3 From e735a80bd57d6b04e1c8f30da762ed0c6af5ee6a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 23 Jun 2012 00:42:01 -0700 Subject: PCI: acpiphp: remove unused res_lock res_lock is never used, so remove it. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp.h | 2 -- drivers/pci/hotplug/acpiphp_glue.c | 3 --- 2 files changed, 5 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 7722108e78df..6b58ed0432e9 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -89,8 +89,6 @@ struct acpiphp_bridge { /* PCI-to-PCI bridge device */ struct pci_dev *pci_dev; - - spinlock_t res_lock; }; diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 806c44fa645a..7dc8dd00135a 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -391,8 +391,6 @@ static void add_host_bridge(acpi_handle *handle) bridge->pci_bus = root->bus; - spin_lock_init(&bridge->res_lock); - init_bridge_misc(bridge); } @@ -425,7 +423,6 @@ static void add_p2p_bridge(acpi_handle *handle) * (which we access during module unload). */ get_device(&bridge->pci_bus->dev); - spin_lock_init(&bridge->res_lock); init_bridge_misc(bridge); return; -- cgit v1.2.3 From 2ac45f28b8eeef576c48579833b40b572f3f9790 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 23 Jun 2012 00:42:03 -0700 Subject: PCI: acpiphp: merge acpiphp_debug and debug Should not have two, just remove debug, and use module_param_named instead. Also change acpiphp_debug to bool. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp.h | 2 +- drivers/pci/hotplug/acpiphp_core.c | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 6b58ed0432e9..a1afb5b39ad4 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -205,6 +205,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); /* variables */ -extern int acpiphp_debug; +extern bool acpiphp_debug; #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 @@ /* name size which is used for entries in pcihpfs */ #define SLOT_NAME_SIZE 21 /* {_SUN} */ -static bool debug; -int acpiphp_debug; +bool acpiphp_debug; /* local variables */ static int num_slots; @@ -62,7 +61,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); -module_param(debug, bool, 0644); +module_param_named(debug, acpiphp_debug, bool, 0644); /* export the attention callback registration methods */ EXPORT_SYMBOL_GPL(acpiphp_register_attention); @@ -379,8 +378,6 @@ static int __init acpiphp_init(void) if (acpi_pci_disabled) return 0; - acpiphp_debug = debug; - /* read all the ACPI info from the system */ return init_acpi(); } -- cgit v1.2.3 From e73cfecdfca900098f807f9523f45573a1155429 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 11 Jul 2012 15:08:16 -0700 Subject: PCI: pciehp: remove unused pciehp_get_max_lnk_width(), pciehp_get_cur_lnk_width() Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas Cc: Kenji Kaneshige --- drivers/pci/hotplug/pciehp.h | 4 -- drivers/pci/hotplug/pciehp_hpc.c | 101 --------------------------------------- 2 files changed, 105 deletions(-) (limited to 'drivers/pci/hotplug') 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); int pciehp_set_attention_status(struct slot *slot, u8 status); int pciehp_get_latch_status(struct slot *slot, u8 *status); int pciehp_get_adapter_status(struct slot *slot, u8 *status); -int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *speed); -int pciehp_get_max_link_width(struct slot *slot, enum pcie_link_width *val); -int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *speed); -int pciehp_get_cur_link_width(struct slot *slot, enum pcie_link_width *val); int pciehp_query_power_fault(struct slot *slot); void pciehp_green_led_on(struct slot *slot); void 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) return IRQ_HANDLED; } -int pciehp_get_max_lnk_width(struct slot *slot, - enum pcie_link_width *value) -{ - struct controller *ctrl = slot->ctrl; - enum pcie_link_width lnk_wdth; - u32 lnk_cap; - int retval = 0; - - retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap); - if (retval) { - ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); - return retval; - } - - switch ((lnk_cap & PCI_EXP_LNKSTA_NLW) >> 4){ - case 0: - lnk_wdth = PCIE_LNK_WIDTH_RESRV; - break; - case 1: - lnk_wdth = PCIE_LNK_X1; - break; - case 2: - lnk_wdth = PCIE_LNK_X2; - break; - case 4: - lnk_wdth = PCIE_LNK_X4; - break; - case 8: - lnk_wdth = PCIE_LNK_X8; - break; - case 12: - lnk_wdth = PCIE_LNK_X12; - break; - case 16: - lnk_wdth = PCIE_LNK_X16; - break; - case 32: - lnk_wdth = PCIE_LNK_X32; - break; - default: - lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN; - break; - } - - *value = lnk_wdth; - ctrl_dbg(ctrl, "Max link width = %d\n", lnk_wdth); - - return retval; -} - -int pciehp_get_cur_lnk_width(struct slot *slot, - enum pcie_link_width *value) -{ - struct controller *ctrl = slot->ctrl; - enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN; - int retval = 0; - u16 lnk_status; - - retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); - if (retval) { - ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", - __func__); - return retval; - } - - switch ((lnk_status & PCI_EXP_LNKSTA_NLW) >> 4){ - case 0: - lnk_wdth = PCIE_LNK_WIDTH_RESRV; - break; - case 1: - lnk_wdth = PCIE_LNK_X1; - break; - case 2: - lnk_wdth = PCIE_LNK_X2; - break; - case 4: - lnk_wdth = PCIE_LNK_X4; - break; - case 8: - lnk_wdth = PCIE_LNK_X8; - break; - case 12: - lnk_wdth = PCIE_LNK_X12; - break; - case 16: - lnk_wdth = PCIE_LNK_X16; - break; - case 32: - lnk_wdth = PCIE_LNK_X32; - break; - default: - lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN; - break; - } - - *value = lnk_wdth; - ctrl_dbg(ctrl, "Current link width = %d\n", lnk_wdth); - - return retval; -} - int pcie_enable_notification(struct controller *ctrl) { u16 cmd, mask; -- cgit v1.2.3 From 83d057107382b74a4b15c59971631aa3542599a5 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 16 Jul 2012 09:25:56 -0600 Subject: PCI: hotplug: ensure a consistent return value in error case Typically, the return value desired for the failure of a function with an integer return value is a negative integer. In these cases, the return value is sometimes a negative integer and sometimes 0, due to a subsequent initialization of the return variable within the loop. A simplified version of the semantic match that finds this problem is: (http://coccinelle.lip6.fr/) // @r exists@ identifier ret; position p; constant C; expression e1,e3,e4; statement S; @@ ret = -C ... when != ret = e3 when any if@p (...) S ... when any if (\(ret != 0\|ret < 0\|ret > 0\) || ...) { ... return ...; } ... when != ret = e3 when any *if@p (...) { ... when != ret = e4 return ret; } // [bhelgaas: squashed into one patch] Signed-off-by: Julia Lawall Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpci_hotplug_core.c | 14 ++++++++++---- drivers/pci/hotplug/cpqphp_core.c | 14 ++++++++++---- drivers/pci/hotplug/pcihp_skeleton.c | 14 ++++++++++---- drivers/pci/hotplug/shpchp_core.c | 14 ++++++++++---- 4 files changed, 40 insertions(+), 16 deletions(-) (limited to 'drivers/pci/hotplug') 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) struct hotplug_slot *hotplug_slot; struct hotplug_slot_info *info; char name[SLOT_NAME_SIZE]; - int status = -ENOMEM; + int status; int i; if (!(controller && bus)) @@ -237,18 +237,24 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) */ for (i = first; i <= last; ++i) { slot = kzalloc(sizeof (struct slot), GFP_KERNEL); - if (!slot) + if (!slot) { + status = -ENOMEM; goto error; + } hotplug_slot = kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL); - if (!hotplug_slot) + if (!hotplug_slot) { + status = -ENOMEM; goto error_slot; + } slot->hotplug_slot = hotplug_slot; info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL); - if (!info) + if (!info) { + status = -ENOMEM; goto error_hpslot; + } hotplug_slot->info = info; slot->bus = bus; 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, u32 tempdword; char name[SLOT_NAME_SIZE]; void __iomem *slot_entry= NULL; - int result = -ENOMEM; + int result; dbg("%s\n", __func__); @@ -623,19 +623,25 @@ static int ctrl_slot_setup(struct controller *ctrl, while (number_of_slots) { slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) + if (!slot) { + result = -ENOMEM; goto error; + } slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)), GFP_KERNEL); - if (!slot->hotplug_slot) + if (!slot->hotplug_slot) { + result = -ENOMEM; goto error_slot; + } hotplug_slot = slot->hotplug_slot; hotplug_slot->info = kzalloc(sizeof(*(hotplug_slot->info)), GFP_KERNEL); - if (!hotplug_slot->info) + if (!hotplug_slot->info) { + result = -ENOMEM; goto error_hpslot; + } hotplug_slot_info = hotplug_slot->info; slot->ctrl = ctrl; 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) struct slot *slot; struct hotplug_slot *hotplug_slot; struct hotplug_slot_info *info; - int retval = -ENOMEM; + int retval; int i; /* @@ -261,17 +261,23 @@ static int __init init_slots(void) */ for (i = 0; i < num_slots; ++i) { slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) + if (!slot) { + retval = -ENOMEM; goto error; + } hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); - if (!hotplug_slot) + if (!hotplug_slot) { + retval = -ENOMEM; goto error_slot; + } slot->hotplug_slot = hotplug_slot; info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) + if (!info) { + retval = -ENOMEM; goto error_hpslot; + } hotplug_slot->info = info; slot->number = i; 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) struct hotplug_slot *hotplug_slot; struct hotplug_slot_info *info; char name[SLOT_NAME_SIZE]; - int retval = -ENOMEM; + int retval; int i; for (i = 0; i < ctrl->num_slots; i++) { slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) + if (!slot) { + retval = -ENOMEM; goto error; + } hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); - if (!hotplug_slot) + if (!hotplug_slot) { + retval = -ENOMEM; goto error_slot; + } slot->hotplug_slot = hotplug_slot; info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) + if (!info) { + retval = -ENOMEM; goto error_hpslot; + } hotplug_slot->info = info; slot->hp_slot = i; -- cgit v1.2.3