aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/acpiphp_glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/acpiphp_glue.c')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 22d0f1cf1362..dbfdac63cb49 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -128,8 +128,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
128 acpi_handle tmp; 128 acpi_handle tmp;
129 acpi_status status = AE_OK; 129 acpi_status status = AE_OK;
130 unsigned long adr, sun; 130 unsigned long adr, sun;
131 int device, function; 131 int device, function, retval;
132 static int num_slots = 0; /* XXX if we support I/O node hotplug... */
133 132
134 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); 133 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
135 134
@@ -198,7 +197,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
198 197
199 memset(slot, 0, sizeof(struct acpiphp_slot)); 198 memset(slot, 0, sizeof(struct acpiphp_slot));
200 slot->bridge = bridge; 199 slot->bridge = bridge;
201 slot->id = num_slots++;
202 slot->device = device; 200 slot->device = device;
203 slot->sun = sun; 201 slot->sun = sun;
204 INIT_LIST_HEAD(&slot->funcs); 202 INIT_LIST_HEAD(&slot->funcs);
@@ -212,6 +210,11 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
212 dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n", 210 dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",
213 slot->sun, pci_domain_nr(bridge->pci_bus), 211 slot->sun, pci_domain_nr(bridge->pci_bus),
214 bridge->pci_bus->number, slot->device); 212 bridge->pci_bus->number, slot->device);
213 retval = acpiphp_register_hotplug_slot(slot);
214 if (retval) {
215 warn("acpiphp_register_hotplug_slot failed(err code = 0x%x)\n", retval);
216 goto err_exit;
217 }
215 } 218 }
216 219
217 newfunc->slot = slot; 220 newfunc->slot = slot;
@@ -253,6 +256,14 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
253 status = AE_OK; 256 status = AE_OK;
254 257
255 return status; 258 return status;
259
260 err_exit:
261 bridge->nr_slots--;
262 bridge->slots = slot->next;
263 kfree(slot);
264 kfree(newfunc);
265
266 return AE_OK;
256} 267}
257 268
258 269
@@ -335,9 +346,16 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
335 /* decode ACPI 2.0 _HPP (hot plug parameters) */ 346 /* decode ACPI 2.0 _HPP (hot plug parameters) */
336 decode_hpp(bridge); 347 decode_hpp(bridge);
337 348
349 /* must be added to the list prior to calling register_slot */
350 list_add(&bridge->list, &bridge_list);
351
338 /* register all slot objects under this bridge */ 352 /* register all slot objects under this bridge */
339 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, 353 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
340 register_slot, bridge, NULL); 354 register_slot, bridge, NULL);
355 if (ACPI_FAILURE(status)) {
356 list_del(&bridge->list);
357 return;
358 }
341 359
342 /* install notify handler */ 360 /* install notify handler */
343 if (bridge->type != BRIDGE_TYPE_HOST) { 361 if (bridge->type != BRIDGE_TYPE_HOST) {
@@ -350,8 +368,6 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
350 err("failed to register interrupt notify handler\n"); 368 err("failed to register interrupt notify handler\n");
351 } 369 }
352 } 370 }
353
354 list_add(&bridge->list, &bridge_list);
355} 371}
356 372
357 373
@@ -555,6 +571,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
555 list_del(list); 571 list_del(list);
556 kfree(func); 572 kfree(func);
557 } 573 }
574 acpiphp_unregister_hotplug_slot(slot);
575 list_del(&slot->funcs);
558 kfree(slot); 576 kfree(slot);
559 slot = next; 577 slot = next;
560 } 578 }
@@ -1521,26 +1539,6 @@ static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
1521} 1539}
1522#endif 1540#endif
1523 1541
1524/* search matching slot from id */
1525struct acpiphp_slot *get_slot_from_id(int id)
1526{
1527 struct list_head *node;
1528 struct acpiphp_bridge *bridge;
1529 struct acpiphp_slot *slot;
1530
1531 list_for_each (node, &bridge_list) {
1532 bridge = (struct acpiphp_bridge *)node;
1533 for (slot = bridge->slots; slot; slot = slot->next)
1534 if (slot->id == id)
1535 return slot;
1536 }
1537
1538 /* should never happen! */
1539 err("%s: no object for id %d\n", __FUNCTION__, id);
1540 WARN_ON(1);
1541 return NULL;
1542}
1543
1544 1542
1545/** 1543/**
1546 * acpiphp_enable_slot - power on slot 1544 * acpiphp_enable_slot - power on slot