aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_root.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2009-06-18 16:46:52 -0400
committerLen Brown <len.brown@intel.com>2009-06-20 00:01:52 -0400
commitf5eebbe119a861b5e4f5c67c886eab0937c686ed (patch)
tree9aa3e915a50d5d8155a21c76c447afa9911ed072 /drivers/acpi/pci_root.c
parentfbe2b31b4b6dfa790cbc88e00631f3112c4fc54e (diff)
ACPI: pci_root: simplify acpi_pci_root_add() control flow
By looking up the segment & bus number earlier, we don't have to worry about cleaning up if it fails. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r--drivers/acpi/pci_root.c100
1 files changed, 38 insertions, 62 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index a8b250783937..0d69c0348c58 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -161,19 +161,22 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
161 return AE_OK; 161 return AE_OK;
162} 162}
163 163
164static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) 164static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
165 unsigned long long *bus)
165{ 166{
166 acpi_status status; 167 acpi_status status;
168 int busnum;
167 169
168 *busnum = -1; 170 busnum = -1;
169 status = 171 status =
170 acpi_walk_resources(handle, METHOD_NAME__CRS, 172 acpi_walk_resources(handle, METHOD_NAME__CRS,
171 get_root_bridge_busnr_callback, busnum); 173 get_root_bridge_busnr_callback, &busnum);
172 if (ACPI_FAILURE(status)) 174 if (ACPI_FAILURE(status))
173 return status; 175 return status;
174 /* Check if we really get a bus number from _CRS */ 176 /* Check if we really get a bus number from _CRS */
175 if (*busnum == -1) 177 if (busnum == -1)
176 return AE_ERROR; 178 return AE_ERROR;
179 *bus = busnum;
177 return AE_OK; 180 return AE_OK;
178} 181}
179 182
@@ -363,24 +366,39 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set);
363 366
364static int __devinit acpi_pci_root_add(struct acpi_device *device) 367static int __devinit acpi_pci_root_add(struct acpi_device *device)
365{ 368{
366 int result = 0; 369 unsigned long long segment, bus;
367 struct acpi_pci_root *root = NULL; 370 acpi_status status;
368 acpi_status status = AE_OK; 371 int result;
369 unsigned long long value = 0; 372 struct acpi_pci_root *root;
370 acpi_handle handle = NULL; 373 acpi_handle handle;
371 struct acpi_device *child; 374 struct acpi_device *child;
372 u32 flags, base_flags; 375 u32 flags, base_flags;
373 int bus;
374 376
377 segment = 0;
378 status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
379 &segment);
380 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
381 printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
382 return -ENODEV;
383 }
375 384
376 if (!device) 385 /* Check _CRS first, then _BBN. If no _BBN, default to zero. */
377 return -EINVAL; 386 bus = 0;
387 status = try_get_root_bridge_busnr(device->handle, &bus);
388 if (ACPI_FAILURE(status)) {
389 status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus);
390 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
391 printk(KERN_ERR PREFIX
392 "no bus number in _CRS and can't evaluate _BBN\n");
393 return -ENODEV;
394 }
395 }
378 396
379 root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); 397 root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
380 if (!root) 398 if (!root)
381 return -ENOMEM; 399 return -ENOMEM;
382 INIT_LIST_HEAD(&root->node);
383 400
401 INIT_LIST_HEAD(&root->node);
384 root->device = device; 402 root->device = device;
385 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); 403 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
386 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); 404 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
@@ -395,54 +413,13 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
395 flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; 413 flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
396 acpi_pci_osc_support(root, flags); 414 acpi_pci_osc_support(root, flags);
397 415
398 /*
399 * Segment
400 * -------
401 * Obtained via _SEG, if exists, otherwise assumed to be zero (0).
402 */
403 status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
404 &value);
405 switch (status) {
406 case AE_OK:
407 root->id.segment = (u16) value;
408 break;
409 case AE_NOT_FOUND:
410 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
411 "Assuming segment 0 (no _SEG)\n"));
412 root->id.segment = 0;
413 break;
414 default:
415 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SEG"));
416 result = -ENODEV;
417 goto end;
418 }
419
420 /*
421 * Bus
422 * ---
423 * Check _CRS first, then _BBN. If no _BBN, default to zero.
424 */
425 status = try_get_root_bridge_busnr(device->handle, &bus);
426 if (ACPI_SUCCESS(status))
427 root->id.bus = bus;
428 else {
429 status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &value);
430 if (ACPI_SUCCESS(status))
431 root->id.bus = (u16) value;
432 else if (status == AE_NOT_FOUND)
433 root->id.bus = 0;
434 else {
435 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BBN"));
436 result = -ENODEV;
437 goto end;
438 }
439 }
440
441 /* 416 /*
442 * Device & Function 417 * Device & Function
443 * ----------------- 418 * -----------------
444 * Obtained from _ADR (which has already been evaluated for us). 419 * Obtained from _ADR (which has already been evaluated for us).
445 */ 420 */
421 root->id.segment = segment & 0xFFFF;
422 root->id.bus = bus & 0xFF;
446 root->id.device = device->pnp.bus_address >> 16; 423 root->id.device = device->pnp.bus_address >> 16;
447 root->id.function = device->pnp.bus_address & 0xFFFF; 424 root->id.function = device->pnp.bus_address & 0xFFFF;
448 425
@@ -509,13 +486,12 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
509 if (flags != base_flags) 486 if (flags != base_flags)
510 acpi_pci_osc_support(root, flags); 487 acpi_pci_osc_support(root, flags);
511 488
512 end: 489 return 0;
513 if (result) {
514 if (!list_empty(&root->node))
515 list_del(&root->node);
516 kfree(root);
517 }
518 490
491end:
492 if (!list_empty(&root->node))
493 list_del(&root->node);
494 kfree(root);
519 return result; 495 return result;
520} 496}
521 497