1 /* 2 * ACPI PCI HotPlug glue functions to ACPI CA subsystem 3 * 4 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) 5 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) 6 * Copyright (C) 2002,2003 NEC Corporation 7 * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) 8 * Copyright (C) 2003-2005 Hewlett Packard 9 * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com) 10 * Copyright (C) 2005 Intel Corporation 11 * 12 * All rights reserved. 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or (at 17 * your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, but 20 * WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 22 * NON INFRINGEMENT. See the GNU General Public License for more 23 * details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, write to the Free Software 27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 29 * Send feedback to <kristen.c.accardi@intel.com> 30 * 31 */ 32 33 /* 34 * Lifetime rules for pci_dev: 35 * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() 36 * when the bridge is scanned and it loses a refcount when the bridge 37 * is removed. 38 * - When a P2P bridge is present, we elevate the refcount on the subordinate 39 * bus. It loses the refcount when the the driver unloads. 40 */ 41 42 #include <linux/init.h> 43 #include <linux/module.h> 44 45 #include <linux/kernel.h> 46 #include <linux/pci.h> 47 #include <linux/pci_hotplug.h> 48 #include <linux/pci-acpi.h> 49 #include <linux/mutex.h> 50 51 #include "../pci.h" 52 #include "acpiphp.h" 53 54 static LIST_HEAD(bridge_list); 55 56 #define MY_NAME "acpiphp_glue" 57 58 static void handle_hotplug_event_bridge (acpi_handle, u32, void *); 59 static void acpiphp_sanitize_bus(struct pci_bus *bus); 60 static void acpiphp_set_hpp_values(struct pci_bus *bus); 61 static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); 62 63 /* callback routine to check for the existence of a pci dock device */ 64 static acpi_status 65 is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) 66 { 67 int *count = (int *)context; 68 69 if (is_dock_device(handle)) { 70 (*count)++; 71 return AE_CTRL_TERMINATE; 72 } else { 73 return AE_OK; 74 } 75 } 76 77 /* 78 * the _DCK method can do funny things... and sometimes not 79 * hah-hah funny. 80 * 81 * TBD - figure out a way to only call fixups for 82 * systems that require them. 83 */ 84 static int post_dock_fixups(struct notifier_block *nb, unsigned long val, 85 void *v) 86 { 87 struct acpiphp_func *func = container_of(nb, struct acpiphp_func, nb); 88 struct pci_bus *bus = func->slot->bridge->pci_bus; 89 u32 buses; 90 91 if (!bus->self) 92 return NOTIFY_OK; 93 94 /* fixup bad _DCK function that rewrites 95 * secondary bridge on slot 96 */ 97 pci_read_config_dword(bus->self, 98 PCI_PRIMARY_BUS, 99 &buses); 100 101 if (((buses >> 8) & 0xff) != bus->secondary) { 102 buses = (buses & 0xff000000) 103 | ((unsigned int)(bus->primary) << 0) 104 | ((unsigned int)(bus->secondary) << 8) 105 | ((unsigned int)(bus->subordinate) << 16); 106 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); 107 } 108 return NOTIFY_OK; 109 } 110 111 112 static struct acpi_dock_ops acpiphp_dock_ops = { 113 .handler = handle_hotplug_event_func, 114 }; 115 116 /* callback routine to register each ACPI PCI slot object */ 117 static acpi_status 118 register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) 119 { 120 struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context; 121 struct acpiphp_slot *slot; 122 struct acpiphp_func *newfunc; 123 acpi_handle tmp; 124 acpi_status status = AE_OK; 125 unsigned long long adr, sun; 126 int device, function, retval; 127 struct pci_bus *pbus = bridge->pci_bus; 128 struct pci_dev *pdev; 129 130 if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) 131 return AE_OK; 132 133 acpi_evaluate_integer(handle, "_ADR", NULL, &adr); 134 device = (adr >> 16) & 0xffff; 135 function = adr & 0xffff; 136 137 newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); 138 if (!newfunc) 139 return AE_NO_MEMORY; 140 141 INIT_LIST_HEAD(&newfunc->sibling); 142 newfunc->handle = handle; 143 newfunc->function = function; 144 145 if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp))) 146 newfunc->flags = FUNC_HAS_EJ0; 147 148 if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp))) 149 newfunc->flags |= FUNC_HAS_STA; 150 151 if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS0", &tmp))) 152 newfunc->flags |= FUNC_HAS_PS0; 153 154 if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp))) 155 newfunc->flags |= FUNC_HAS_PS3; 156 157 if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp))) 158 newfunc->flags |= FUNC_HAS_DCK; 159 160 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun); 161 if (ACPI_FAILURE(status)) { 162 /* 163 * use the count of the number of slots we've found 164 * for the number of the slot 165 */ 166 sun = bridge->nr_slots+1; 167 } 168 169 /* search for objects that share the same slot */ 170 for (slot = bridge->slots; slot; slot = slot->next) 171 if (slot->device == device) { 172 if (slot->sun != sun) 173 warn("sibling found, but _SUN doesn't match!\n"); 174 break; 175 } 176 177 if (!slot) { 178 slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); 179 if (!slot) { 180 kfree(newfunc); 181 return AE_NO_MEMORY; 182 } 183 184 slot->bridge = bridge; 185 slot->device = device; 186 slot->sun = sun; 187 INIT_LIST_HEAD(&slot->funcs); 188 mutex_init(&slot->crit_sect); 189 190 slot->next = bridge->slots; 191 bridge->slots = slot; 192 193 bridge->nr_slots++; 194 195 dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", 196 slot->sun, pci_domain_nr(pbus), pbus->number, device); 197 retval = acpiphp_register_hotplug_slot(slot); 198 if (retval) { 199 if (retval == -EBUSY) 200 warn("Slot %llu already registered by another " 201 "hotplug driver\n", slot->sun); 202 else 203 warn("acpiphp_register_hotplug_slot failed " 204 "(err code = 0x%x)\n", retval); 205 goto err_exit; 206 } 207 } 208 209 newfunc->slot = slot; 210 list_add_tail(&newfunc->sibling, &slot->funcs); 211 212 pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); 213 if (pdev) { 214 slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); 215 pci_dev_put(pdev); 216 } 217 218 if (is_dock_device(handle)) { 219 /* we don't want to call this device's _EJ0 220 * because we want the dock notify handler 221 * to call it after it calls _DCK 222 */ 223 newfunc->flags &= ~FUNC_HAS_EJ0; 224 if (register_hotplug_dock_device(handle, 225 &acpiphp_dock_ops, newfunc)) 226 dbg("failed to register dock device\n"); 227 228 /* we need to be notified when dock events happen 229 * outside of the hotplug operation, since we may 230 * need to do fixups before we can hotplug. 231 */ 232 newfunc->nb.notifier_call = post_dock_fixups; 233 if (register_dock_notifier(&newfunc->nb)) 234 dbg("failed to register a dock notifier"); 235 } 236 237 /* install notify handler */ 238 if (!(newfunc->flags & FUNC_HAS_DCK)) { 239 status = acpi_install_notify_handler(handle, 240 ACPI_SYSTEM_NOTIFY, 241 handle_hotplug_event_func, 242 newfunc); 243 244 if (ACPI_FAILURE(status)) 245 err("failed to register interrupt notify handler\n"); 246 } else 247 status = AE_OK; 248 249 return status; 250 251 err_exit: 252 bridge->nr_slots--; 253 bridge->slots = slot->next; 254 kfree(slot); 255 kfree(newfunc); 256 257 return AE_OK; 258 } 259 260 261 /* see if it's worth looking at this bridge */ 262 static int detect_ejectable_slots(acpi_handle handle) 263 { 264 int found = acpi_pci_detect_ejectable(handle); 265 if (!found) { 266 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 267 is_pci_dock_device, (void *)&found, NULL); 268 } 269 return found; 270 } 271 272 /* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */ 273 static void init_bridge_misc(struct acpiphp_bridge *bridge) 274 { 275 acpi_status status; 276 277 /* must be added to the list prior to calling register_slot */ 278 list_add(&bridge->list, &bridge_list); 279 280 /* register all slot objects under this bridge */ 281 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, 282 register_slot, bridge, NULL); 283 if (ACPI_FAILURE(status)) { 284 list_del(&bridge->list); 285 return; 286 } 287 288 /* install notify handler */ 289 if (bridge->type != BRIDGE_TYPE_HOST) { 290 if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { 291 status = acpi_remove_notify_handler(bridge->func->handle, 292 ACPI_SYSTEM_NOTIFY, 293 handle_hotplug_event_func); 294 if (ACPI_FAILURE(status)) 295 err("failed to remove notify handler\n"); 296 } 297 status = acpi_install_notify_handler(bridge->handle, 298 ACPI_SYSTEM_NOTIFY, 299 handle_hotplug_event_bridge, 300 bridge); 301 302 if (ACPI_FAILURE(status)) { 303 err("failed to register interrupt notify handler\n"); 304 } 305 } 306 } 307 308 309 /* find acpiphp_func from acpiphp_bridge */ 310 static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) 311 { 312 struct list_head *node, *l; 313 struct acpiphp_bridge *bridge; 314 struct acpiphp_slot *slot; 315 struct acpiphp_func *func; 316 317 list_for_each(node, &bridge_list) { 318 bridge = list_entry(node, struct acpiphp_bridge, list); 319 for (slot = bridge->slots; slot; slot = slot->next) { 320 list_for_each(l, &slot->funcs) { 321 func = list_entry(l, struct acpiphp_func, 322 sibling); 323 if (func->handle == handle) 324 return func; 325 } 326 } 327 } 328 329 return NULL; 330 } 331 332 333 static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) 334 { 335 acpi_handle dummy_handle; 336 337 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, 338 "_STA", &dummy_handle))) 339 bridge->flags |= BRIDGE_HAS_STA; 340 341 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, 342 "_EJ0", &dummy_handle))) 343 bridge->flags |= BRIDGE_HAS_EJ0; 344 345 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, 346 "_PS0", &dummy_handle))) 347 bridge->flags |= BRIDGE_HAS_PS0; 348 349 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, 350 "_PS3", &dummy_handle))) 351 bridge->flags |= BRIDGE_HAS_PS3; 352 353 /* is this ejectable p2p bridge? */ 354 if (bridge->flags & BRIDGE_HAS_EJ0) { 355 struct acpiphp_func *func; 356 357 dbg("found ejectable p2p bridge\n"); 358 359 /* make link between PCI bridge and PCI function */ 360 func = acpiphp_bridge_handle_to_function(bridge->handle); 361 if (!func) 362 return; 363 bridge->func = func; 364 func->bridge = bridge; 365 } 366 } 367 368 369 /* allocate and initialize host bridge data structure */ 370 static void add_host_bridge(acpi_handle *handle) 371 { 372 struct acpiphp_bridge *bridge; 373 struct acpi_pci_root *root = acpi_pci_find_root(handle); 374 375 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 376 if (bridge == NULL) 377 return; 378 379 bridge->type = BRIDGE_TYPE_HOST; 380 bridge->handle = handle; 381 382 bridge->pci_bus = root->bus; 383 384 spin_lock_init(&bridge->res_lock); 385 386 init_bridge_misc(bridge); 387 } 388 389 390 /* allocate and initialize PCI-to-PCI bridge data structure */ 391 static void add_p2p_bridge(acpi_handle *handle) 392 { 393 struct acpiphp_bridge *bridge; 394 395 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 396 if (bridge == NULL) { 397 err("out of memory\n"); 398 return; 399 } 400 401 bridge->type = BRIDGE_TYPE_P2P; 402 bridge->handle = handle; 403 config_p2p_bridge_flags(bridge); 404 405 bridge->pci_dev = acpi_get_pci_dev(handle); 406 bridge->pci_bus = bridge->pci_dev->subordinate; 407 if (!bridge->pci_bus) { 408 err("This is not a PCI-to-PCI bridge!\n"); 409 goto err; 410 } 411 412 /* 413 * Grab a ref to the subordinate PCI bus in case the bus is 414 * removed via PCI core logical hotplug. The ref pins the bus 415 * (which we access during module unload). 416 */ 417 get_device(&bridge->pci_bus->dev); 418 spin_lock_init(&bridge->res_lock); 419 420 init_bridge_misc(bridge); 421 return; 422 err: 423 pci_dev_put(bridge->pci_dev); 424 kfree(bridge); 425 return; 426 } 427 428 429 /* callback routine to find P2P bridges */ 430 static acpi_status 431 find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) 432 { 433 acpi_status status; 434 struct pci_dev *dev; 435 436 dev = acpi_get_pci_dev(handle); 437 if (!dev || !dev->subordinate) 438 goto out; 439 440 /* check if this bridge has ejectable slots */ 441 if ((detect_ejectable_slots(handle) > 0)) { 442 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); 443 add_p2p_bridge(handle); 444 } 445 446 /* search P2P bridges under this p2p bridge */ 447 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 448 find_p2p_bridge, NULL, NULL); 449 if (ACPI_FAILURE(status)) 450 warn("find_p2p_bridge failed (error code = 0x%x)\n", status); 451 452 out: 453 pci_dev_put(dev); 454 return AE_OK; 455 } 456 457 458 /* find hot-pluggable slots, and then find P2P bridge */ 459 static int add_bridge(acpi_handle handle) 460 { 461 acpi_status status; 462 unsigned long long tmp; 463 acpi_handle dummy_handle; 464 465 /* if the bridge doesn't have _STA, we assume it is always there */ 466 status = acpi_get_handle(handle, "_STA", &dummy_handle); 467 if (ACPI_SUCCESS(status)) { 468 status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp); 469 if (ACPI_FAILURE(status)) { 470 dbg("%s: _STA evaluation failure\n", __func__); 471 return 0; 472 } 473 if ((tmp & ACPI_STA_FUNCTIONING) == 0) 474 /* don't register this object */ 475 return 0; 476 } 477 478 /* check if this bridge has ejectable slots */ 479 if (detect_ejectable_slots(handle) > 0) { 480 dbg("found PCI host-bus bridge with hot-pluggable slots\n"); 481 add_host_bridge(handle); 482 } 483 484 /* search P2P bridges under this host bridge */ 485 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 486 find_p2p_bridge, NULL, NULL); 487 488 if (ACPI_FAILURE(status)) 489 warn("find_p2p_bridge failed (error code = 0x%x)\n", status); 490 491 return 0; 492 } 493 494 static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) 495 { 496 struct list_head *head; 497 list_for_each(head, &bridge_list) { 498 struct acpiphp_bridge *bridge = list_entry(head, 499 struct acpiphp_bridge, list); 500 if (bridge->handle == handle) 501 return bridge; 502 } 503 504 return NULL; 505 } 506 507 static void cleanup_bridge(struct acpiphp_bridge *bridge) 508 { 509 struct list_head *list, *tmp; 510 struct acpiphp_slot *slot; 511 acpi_status status; 512 acpi_handle handle = bridge->handle; 513 514 status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 515 handle_hotplug_event_bridge); 516 if (ACPI_FAILURE(status)) 517 err("failed to remove notify handler\n"); 518 519 if ((bridge->type != BRIDGE_TYPE_HOST) && 520 ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) { 521 status = acpi_install_notify_handler(bridge->func->handle, 522 ACPI_SYSTEM_NOTIFY, 523 handle_hotplug_event_func, 524 bridge->func); 525 if (ACPI_FAILURE(status)) 526 err("failed to install interrupt notify handler\n"); 527 } 528 529 slot = bridge->slots; 530 while (slot) { 531 struct acpiphp_slot *next = slot->next; 532 list_for_each_safe (list, tmp, &slot->funcs) { 533 struct acpiphp_func *func; 534 func = list_entry(list, struct acpiphp_func, sibling); 535 if (is_dock_device(func->handle)) { 536 unregister_hotplug_dock_device(func->handle); 537 unregister_dock_notifier(&func->nb); 538 } 539 if (!(func->flags & FUNC_HAS_DCK)) { 540 status = acpi_remove_notify_handler(func->handle, 541 ACPI_SYSTEM_NOTIFY, 542 handle_hotplug_event_func); 543 if (ACPI_FAILURE(status)) 544 err("failed to remove notify handler\n"); 545 } 546 list_del(list); 547 kfree(func); 548 } 549 acpiphp_unregister_hotplug_slot(slot); 550 list_del(&slot->funcs); 551 kfree(slot); 552 slot = next; 553 } 554 555 /* 556 * Only P2P bridges have a pci_dev 557 */ 558 if (bridge->pci_dev) 559 put_device(&bridge->pci_bus->dev); 560 561 pci_dev_put(bridge->pci_dev); 562 list_del(&bridge->list); 563 kfree(bridge); 564 } 565 566 static acpi_status 567 cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) 568 { 569 struct acpiphp_bridge *bridge; 570 571 /* cleanup p2p bridges under this P2P bridge 572 in a depth-first manner */ 573 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 574 cleanup_p2p_bridge, NULL, NULL); 575 576 bridge = acpiphp_handle_to_bridge(handle); 577 if (bridge) 578 cleanup_bridge(bridge); 579 580 return AE_OK; 581 } 582 583 static void remove_bridge(acpi_handle handle) 584 { 585 struct acpiphp_bridge *bridge; 586 587 /* cleanup p2p bridges under this host bridge 588 in a depth-first manner */ 589 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 590 (u32)1, cleanup_p2p_bridge, NULL, NULL); 591 592 /* 593 * On root bridges with hotplug slots directly underneath (ie, 594 * no p2p bridge inbetween), we call cleanup_bridge(). 595 * 596 * The else clause cleans up root bridges that either had no 597 * hotplug slots at all, or had a p2p bridge underneath. 598 */ 599 bridge = acpiphp_handle_to_bridge(handle); 600 if (bridge) 601 cleanup_bridge(bridge); 602 else 603 acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 604 handle_hotplug_event_bridge); 605 } 606 607 static int power_on_slot(struct acpiphp_slot *slot) 608 { 609 acpi_status status; 610 struct acpiphp_func *func; 611 struct list_head *l; 612 int retval = 0; 613 614 /* if already enabled, just skip */ 615 if (slot->flags & SLOT_POWEREDON) 616 goto err_exit; 617 618 list_for_each (l, &slot->funcs) { 619 func = list_entry(l, struct acpiphp_func, sibling); 620 621 if (func->flags & FUNC_HAS_PS0) { 622 dbg("%s: executing _PS0\n", __func__); 623 status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); 624 if (ACPI_FAILURE(status)) { 625 warn("%s: _PS0 failed\n", __func__); 626 retval = -1; 627 goto err_exit; 628 } else 629 break; 630 } 631 } 632 633 /* TBD: evaluate _STA to check if the slot is enabled */ 634 635 slot->flags |= SLOT_POWEREDON; 636 637 err_exit: 638 return retval; 639 } 640 641 642 static int power_off_slot(struct acpiphp_slot *slot) 643 { 644 acpi_status status; 645 struct acpiphp_func *func; 646 struct list_head *l; 647 648 int retval = 0; 649 650 /* if already disabled, just skip */ 651 if ((slot->flags & SLOT_POWEREDON) == 0) 652 goto err_exit; 653 654 list_for_each (l, &slot->funcs) { 655 func = list_entry(l, struct acpiphp_func, sibling); 656 657 if (func->flags & FUNC_HAS_PS3) { 658 status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); 659 if (ACPI_FAILURE(status)) { 660 warn("%s: _PS3 failed\n", __func__); 661 retval = -1; 662 goto err_exit; 663 } else 664 break; 665 } 666 } 667 668 /* TBD: evaluate _STA to check if the slot is disabled */ 669 670 slot->flags &= (~SLOT_POWEREDON); 671 672 err_exit: 673 return retval; 674 } 675 676 677 678 /** 679 * acpiphp_max_busnr - return the highest reserved bus number under the given bus. 680 * @bus: bus to start search with 681 */ 682 static unsigned char acpiphp_max_busnr(struct pci_bus *bus) 683 { 684 struct list_head *tmp; 685 unsigned char max, n; 686 687 /* 688 * pci_bus_max_busnr will return the highest 689 * reserved busnr for all these children. 690 * that is equivalent to the bus->subordinate 691 * value. We don't want to use the parent's 692 * bus->subordinate value because it could have 693 * padding in it. 694 */ 695 max = bus->secondary; 696 697 list_for_each(tmp, &bus->children) { 698 n = pci_bus_max_busnr(pci_bus_b(tmp)); 699 if (n > max) 700 max = n; 701 } 702 return max; 703 } 704 705 706 /** 707 * acpiphp_bus_add - add a new bus to acpi subsystem 708 * @func: acpiphp_func of the bridge 709 */ 710 static int acpiphp_bus_add(struct acpiphp_func *func) 711 { 712 acpi_handle phandle; 713 struct acpi_device *device, *pdevice; 714 int ret_val; 715 716 acpi_get_parent(func->handle, &phandle); 717 if (acpi_bus_get_device(phandle, &pdevice)) { 718 dbg("no parent device, assuming NULL\n"); 719 pdevice = NULL; 720 } 721 if (!acpi_bus_get_device(func->handle, &device)) { 722 dbg("bus exists... trim\n"); 723 /* this shouldn't be in here, so remove 724 * the bus then re-add it... 725 */ 726 ret_val = acpi_bus_trim(device, 1); 727 dbg("acpi_bus_trim return %x\n", ret_val); 728 } 729 730 ret_val = acpi_bus_add(&device, pdevice, func->handle, 731 ACPI_BUS_TYPE_DEVICE); 732 if (ret_val) { 733 dbg("error adding bus, %x\n", 734 -ret_val); 735 goto acpiphp_bus_add_out; 736 } 737 /* 738 * try to start anyway. We could have failed to add 739 * simply because this bus had previously been added 740 * on another add. Don't bother with the return value 741 * we just keep going. 742 */ 743 ret_val = acpi_bus_start(device); 744 745 acpiphp_bus_add_out: 746 return ret_val; 747 } 748 749 750 /** 751 * acpiphp_bus_trim - trim a bus from acpi subsystem 752 * @handle: handle to acpi namespace 753 */ 754 static int acpiphp_bus_trim(acpi_handle handle) 755 { 756 struct acpi_device *device; 757 int retval; 758 759 retval = acpi_bus_get_device(handle, &device); 760 if (retval) { 761 dbg("acpi_device not found\n"); 762 return retval; 763 } 764 765 retval = acpi_bus_trim(device, 1); 766 if (retval) 767 err("cannot remove from acpi list\n"); 768 769 return retval; 770 } 771 772 /** 773 * enable_device - enable, configure a slot 774 * @slot: slot to be enabled 775 * 776 * This function should be called per *physical slot*, 777 * not per each slot object in ACPI namespace. 778 */ 779 static int __ref enable_device(struct acpiphp_slot *slot) 780 { 781 struct pci_dev *dev; 782 struct pci_bus *bus = slot->bridge->pci_bus; 783 struct list_head *l; 784 struct acpiphp_func *func; 785 int retval = 0; 786 int num, max, pass; 787 acpi_status status; 788 789 if (slot->flags & SLOT_ENABLED) 790 goto err_exit; 791 792 /* sanity check: dev should be NULL when hot-plugged in */ 793 dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); 794 if (dev) { 795 /* This case shouldn't happen */ 796 err("pci_dev structure already exists.\n"); 797 pci_dev_put(dev); 798 retval = -1; 799 goto err_exit; 800 } 801 802 num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); 803 if (num == 0) { 804 err("No new device found\n"); 805 retval = -1; 806 goto err_exit; 807 } 808 809 max = acpiphp_max_busnr(bus); 810 for (pass = 0; pass < 2; pass++) { 811 list_for_each_entry(dev, &bus->devices, bus_list) { 812 if (PCI_SLOT(dev->devfn) != slot->device) 813 continue; 814 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 815 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { 816 max = pci_scan_bridge(bus, dev, max, pass); 817 if (pass && dev->subordinate) 818 pci_bus_size_bridges(dev->subordinate); 819 } 820 } 821 } 822 823 list_for_each (l, &slot->funcs) { 824 func = list_entry(l, struct acpiphp_func, sibling); 825 acpiphp_bus_add(func); 826 } 827 828 pci_bus_assign_resources(bus); 829 acpiphp_sanitize_bus(bus); 830 acpiphp_set_hpp_values(bus); 831 pci_enable_bridges(bus); 832 pci_bus_add_devices(bus); 833 834 list_for_each (l, &slot->funcs) { 835 func = list_entry(l, struct acpiphp_func, sibling); 836 dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 837 func->function)); 838 if (!dev) 839 continue; 840 841 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && 842 dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { 843 pci_dev_put(dev); 844 continue; 845 } 846 847 status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); 848 if (ACPI_FAILURE(status)) 849 warn("find_p2p_bridge failed (error code = 0x%x)\n", 850 status); 851 pci_dev_put(dev); 852 } 853 854 slot->flags |= SLOT_ENABLED; 855 856 err_exit: 857 return retval; 858 } 859 860 static void disable_bridges(struct pci_bus *bus) 861 { 862 struct pci_dev *dev; 863 list_for_each_entry(dev, &bus->devices, bus_list) { 864 if (dev->subordinate) { 865 disable_bridges(dev->subordinate); 866 pci_disable_device(dev); 867 } 868 } 869 } 870 871 /** 872 * disable_device - disable a slot 873 * @slot: ACPI PHP slot 874 */ 875 static int disable_device(struct acpiphp_slot *slot) 876 { 877 struct acpiphp_func *func; 878 struct pci_dev *pdev; 879 880 /* is this slot already disabled? */ 881 if (!(slot->flags & SLOT_ENABLED)) 882 goto err_exit; 883 884 list_for_each_entry(func, &slot->funcs, sibling) { 885 if (func->bridge) { 886 /* cleanup p2p bridges under this P2P bridge */ 887 cleanup_p2p_bridge(func->bridge->handle, 888 (u32)1, NULL, NULL); 889 func->bridge = NULL; 890 } 891 892 pdev = pci_get_slot(slot->bridge->pci_bus, 893 PCI_DEVFN(slot->device, func->function)); 894 if (pdev) { 895 pci_stop_bus_device(pdev); 896 if (pdev->subordinate) { 897 disable_bridges(pdev->subordinate); 898 pci_disable_device(pdev); 899 } 900 pci_remove_bus_device(pdev); 901 pci_dev_put(pdev); 902 } 903 } 904 905 list_for_each_entry(func, &slot->funcs, sibling) { 906 acpiphp_bus_trim(func->handle); 907 } 908 909 slot->flags &= (~SLOT_ENABLED); 910 911 err_exit: 912 return 0; 913 } 914 915 916 /** 917 * get_slot_status - get ACPI slot status 918 * @slot: ACPI PHP slot 919 * 920 * If a slot has _STA for each function and if any one of them 921 * returned non-zero status, return it. 922 * 923 * If a slot doesn't have _STA and if any one of its functions' 924 * configuration space is configured, return 0x0f as a _STA. 925 * 926 * Otherwise return 0. 927 */ 928 static unsigned int get_slot_status(struct acpiphp_slot *slot) 929 { 930 acpi_status status; 931 unsigned long long sta = 0; 932 u32 dvid; 933 struct list_head *l; 934 struct acpiphp_func *func; 935 936 list_for_each (l, &slot->funcs) { 937 func = list_entry(l, struct acpiphp_func, sibling); 938 939 if (func->flags & FUNC_HAS_STA) { 940 status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); 941 if (ACPI_SUCCESS(status) && sta) 942 break; 943 } else { 944 pci_bus_read_config_dword(slot->bridge->pci_bus, 945 PCI_DEVFN(slot->device, 946 func->function), 947 PCI_VENDOR_ID, &dvid); 948 if (dvid != 0xffffffff) { 949 sta = ACPI_STA_ALL; 950 break; 951 } 952 } 953 } 954 955 return (unsigned int)sta; 956 } 957 958 /** 959 * acpiphp_eject_slot - physically eject the slot 960 * @slot: ACPI PHP slot 961 */ 962 int acpiphp_eject_slot(struct acpiphp_slot *slot) 963 { 964 acpi_status status; 965 struct acpiphp_func *func; 966 struct list_head *l; 967 struct acpi_object_list arg_list; 968 union acpi_object arg; 969 970 list_for_each (l, &slot->funcs) { 971 func = list_entry(l, struct acpiphp_func, sibling); 972 973 /* We don't want to call _EJ0 on non-existing functions. */ 974 if ((func->flags & FUNC_HAS_EJ0)) { 975 /* _EJ0 method take one argument */ 976 arg_list.count = 1; 977 arg_list.pointer = &arg; 978 arg.type = ACPI_TYPE_INTEGER; 979 arg.integer.value = 1; 980 981 status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); 982 if (ACPI_FAILURE(status)) { 983 warn("%s: _EJ0 failed\n", __func__); 984 return -1; 985 } else 986 break; 987 } 988 } 989 return 0; 990 } 991 992 /** 993 * acpiphp_check_bridge - re-enumerate devices 994 * @bridge: where to begin re-enumeration 995 * 996 * Iterate over all slots under this bridge and make sure that if a 997 * card is present they are enabled, and if not they are disabled. 998 */ 999 static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) 1000 { 1001 struct acpiphp_slot *slot; 1002 int retval = 0; 1003 int enabled, disabled; 1004 1005 enabled = disabled = 0; 1006 1007 for (slot = bridge->slots; slot; slot = slot->next) { 1008 unsigned int status = get_slot_status(slot); 1009 if (slot->flags & SLOT_ENABLED) { 1010 if (status == ACPI_STA_ALL) 1011 continue; 1012 retval = acpiphp_disable_slot(slot); 1013 if (retval) { 1014 err("Error occurred in disabling\n"); 1015 goto err_exit; 1016 } else { 1017 acpiphp_eject_slot(slot); 1018 } 1019 disabled++; 1020 } else { 1021 if (status != ACPI_STA_ALL) 1022 continue; 1023 retval = acpiphp_enable_slot(slot); 1024 if (retval) { 1025 err("Error occurred in enabling\n"); 1026 goto err_exit; 1027 } 1028 enabled++; 1029 } 1030 } 1031 1032 dbg("%s: %d enabled, %d disabled\n", __func__, enabled, disabled); 1033 1034 err_exit: 1035 return retval; 1036 } 1037 1038 static void acpiphp_set_hpp_values(struct pci_bus *bus) 1039 { 1040 struct pci_dev *dev; 1041 1042 list_for_each_entry(dev, &bus->devices, bus_list) 1043 pci_configure_slot(dev); 1044 } 1045 1046 /* 1047 * Remove devices for which we could not assign resources, call 1048 * arch specific code to fix-up the bus 1049 */ 1050 static void acpiphp_sanitize_bus(struct pci_bus *bus) 1051 { 1052 struct pci_dev *dev; 1053 int i; 1054 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; 1055 1056 list_for_each_entry(dev, &bus->devices, bus_list) { 1057 for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { 1058 struct resource *res = &dev->resource[i]; 1059 if ((res->flags & type_mask) && !res->start && 1060 res->end) { 1061 /* Could not assign a required resources 1062 * for this device, remove it */ 1063 pci_remove_bus_device(dev); 1064 break; 1065 } 1066 } 1067 } 1068 } 1069 1070 /* Program resources in newly inserted bridge */ 1071 static int acpiphp_configure_bridge (acpi_handle handle) 1072 { 1073 struct pci_bus *bus; 1074 1075 if (acpi_is_root_bridge(handle)) { 1076 struct acpi_pci_root *root = acpi_pci_find_root(handle); 1077 bus = root->bus; 1078 } else { 1079 struct pci_dev *pdev = acpi_get_pci_dev(handle); 1080 bus = pdev->subordinate; 1081 pci_dev_put(pdev); 1082 } 1083 1084 pci_bus_size_bridges(bus); 1085 pci_bus_assign_resources(bus); 1086 acpiphp_sanitize_bus(bus); 1087 acpiphp_set_hpp_values(bus); 1088 pci_enable_bridges(bus); 1089 return 0; 1090 } 1091 1092 static void handle_bridge_insertion(acpi_handle handle, u32 type) 1093 { 1094 struct acpi_device *device, *pdevice; 1095 acpi_handle phandle; 1096 1097 if ((type != ACPI_NOTIFY_BUS_CHECK) && 1098 (type != ACPI_NOTIFY_DEVICE_CHECK)) { 1099 err("unexpected notification type %d\n", type); 1100 return; 1101 } 1102 1103 acpi_get_parent(handle, &phandle); 1104 if (acpi_bus_get_device(phandle, &pdevice)) { 1105 dbg("no parent device, assuming NULL\n"); 1106 pdevice = NULL; 1107 } 1108 if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) { 1109 err("cannot add bridge to acpi list\n"); 1110 return; 1111 } 1112 if (!acpiphp_configure_bridge(handle) && 1113 !acpi_bus_start(device)) 1114 add_bridge(handle); 1115 else 1116 err("cannot configure and start bridge\n"); 1117 1118 } 1119 1120 /* 1121 * ACPI event handlers 1122 */ 1123 1124 static acpi_status 1125 count_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) 1126 { 1127 int *count = (int *)context; 1128 struct acpiphp_bridge *bridge; 1129 1130 bridge = acpiphp_handle_to_bridge(handle); 1131 if (bridge) 1132 (*count)++; 1133 return AE_OK ; 1134 } 1135 1136 static acpi_status 1137 check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) 1138 { 1139 struct acpiphp_bridge *bridge; 1140 char objname[64]; 1141 struct acpi_buffer buffer = { .length = sizeof(objname), 1142 .pointer = objname }; 1143 1144 bridge = acpiphp_handle_to_bridge(handle); 1145 if (bridge) { 1146 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); 1147 dbg("%s: re-enumerating slots under %s\n", 1148 __func__, objname); 1149 acpiphp_check_bridge(bridge); 1150 } 1151 return AE_OK ; 1152 } 1153 1154 /** 1155 * handle_hotplug_event_bridge - handle ACPI event on bridges 1156 * @handle: Notify()'ed acpi_handle 1157 * @type: Notify code 1158 * @context: pointer to acpiphp_bridge structure 1159 * 1160 * Handles ACPI event notification on {host,p2p} bridges. 1161 */ 1162 static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *context) 1163 { 1164 struct acpiphp_bridge *bridge; 1165 char objname[64]; 1166 struct acpi_buffer buffer = { .length = sizeof(objname), 1167 .pointer = objname }; 1168 struct acpi_device *device; 1169 int num_sub_bridges = 0; 1170 1171 if (acpi_bus_get_device(handle, &device)) { 1172 /* This bridge must have just been physically inserted */ 1173 handle_bridge_insertion(handle, type); 1174 return; 1175 } 1176 1177 bridge = acpiphp_handle_to_bridge(handle); 1178 if (type == ACPI_NOTIFY_BUS_CHECK) { 1179 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX, 1180 count_sub_bridges, &num_sub_bridges, NULL); 1181 } 1182 1183 if (!bridge && !num_sub_bridges) { 1184 err("cannot get bridge info\n"); 1185 return; 1186 } 1187 1188 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); 1189 1190 switch (type) { 1191 case ACPI_NOTIFY_BUS_CHECK: 1192 /* bus re-enumerate */ 1193 dbg("%s: Bus check notify on %s\n", __func__, objname); 1194 if (bridge) { 1195 dbg("%s: re-enumerating slots under %s\n", 1196 __func__, objname); 1197 acpiphp_check_bridge(bridge); 1198 } 1199 if (num_sub_bridges) 1200 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1201 ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL); 1202 break; 1203 1204 case ACPI_NOTIFY_DEVICE_CHECK: 1205 /* device check */ 1206 dbg("%s: Device check notify on %s\n", __func__, objname); 1207 acpiphp_check_bridge(bridge); 1208 break; 1209 1210 case ACPI_NOTIFY_DEVICE_WAKE: 1211 /* wake event */ 1212 dbg("%s: Device wake notify on %s\n", __func__, objname); 1213 break; 1214 1215 case ACPI_NOTIFY_EJECT_REQUEST: 1216 /* request device eject */ 1217 dbg("%s: Device eject notify on %s\n", __func__, objname); 1218 if ((bridge->type != BRIDGE_TYPE_HOST) && 1219 (bridge->flags & BRIDGE_HAS_EJ0)) { 1220 struct acpiphp_slot *slot; 1221 slot = bridge->func->slot; 1222 if (!acpiphp_disable_slot(slot)) 1223 acpiphp_eject_slot(slot); 1224 } 1225 break; 1226 1227 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 1228 printk(KERN_ERR "Device %s cannot be configured due" 1229 " to a frequency mismatch\n", objname); 1230 break; 1231 1232 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 1233 printk(KERN_ERR "Device %s cannot be configured due" 1234 " to a bus mode mismatch\n", objname); 1235 break; 1236 1237 case ACPI_NOTIFY_POWER_FAULT: 1238 printk(KERN_ERR "Device %s has suffered a power fault\n", 1239 objname); 1240 break; 1241 1242 default: 1243 warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); 1244 break; 1245 } 1246 } 1247 1248 /** 1249 * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) 1250 * @handle: Notify()'ed acpi_handle 1251 * @type: Notify code 1252 * @context: pointer to acpiphp_func structure 1253 * 1254 * Handles ACPI event notification on slots. 1255 */ 1256 static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context) 1257 { 1258 struct acpiphp_func *func; 1259 char objname[64]; 1260 struct acpi_buffer buffer = { .length = sizeof(objname), 1261 .pointer = objname }; 1262 1263 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); 1264 1265 func = (struct acpiphp_func *)context; 1266 1267 switch (type) { 1268 case ACPI_NOTIFY_BUS_CHECK: 1269 /* bus re-enumerate */ 1270 dbg("%s: Bus check notify on %s\n", __func__, objname); 1271 acpiphp_enable_slot(func->slot); 1272 break; 1273 1274 case ACPI_NOTIFY_DEVICE_CHECK: 1275 /* device check : re-enumerate from parent bus */ 1276 dbg("%s: Device check notify on %s\n", __func__, objname); 1277 acpiphp_check_bridge(func->slot->bridge); 1278 break; 1279 1280 case ACPI_NOTIFY_DEVICE_WAKE: 1281 /* wake event */ 1282 dbg("%s: Device wake notify on %s\n", __func__, objname); 1283 break; 1284 1285 case ACPI_NOTIFY_EJECT_REQUEST: 1286 /* request device eject */ 1287 dbg("%s: Device eject notify on %s\n", __func__, objname); 1288 if (!(acpiphp_disable_slot(func->slot))) 1289 acpiphp_eject_slot(func->slot); 1290 break; 1291 1292 default: 1293 warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); 1294 break; 1295 } 1296 } 1297 1298 1299 static acpi_status 1300 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) 1301 { 1302 int *count = (int *)context; 1303 1304 if (acpi_is_root_bridge(handle)) { 1305 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 1306 handle_hotplug_event_bridge, NULL); 1307 (*count)++; 1308 } 1309 return AE_OK ; 1310 } 1311 1312 static struct acpi_pci_driver acpi_pci_hp_driver = { 1313 .add = add_bridge, 1314 .remove = remove_bridge, 1315 }; 1316 1317 /** 1318 * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures 1319 */ 1320 int __init acpiphp_glue_init(void) 1321 { 1322 int num = 0; 1323 1324 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1325 ACPI_UINT32_MAX, find_root_bridges, &num, NULL); 1326 1327 if (num <= 0) 1328 return -1; 1329 else 1330 acpi_pci_register_driver(&acpi_pci_hp_driver); 1331 1332 return 0; 1333 } 1334 1335 1336 /** 1337 * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures 1338 * 1339 * This function frees all data allocated in acpiphp_glue_init(). 1340 */ 1341 void acpiphp_glue_exit(void) 1342 { 1343 acpi_pci_unregister_driver(&acpi_pci_hp_driver); 1344 } 1345 1346 1347 /** 1348 * acpiphp_get_num_slots - count number of slots in a system 1349 */ 1350 int __init acpiphp_get_num_slots(void) 1351 { 1352 struct acpiphp_bridge *bridge; 1353 int num_slots = 0; 1354 1355 list_for_each_entry (bridge, &bridge_list, list) { 1356 dbg("Bus %04x:%02x has %d slot%s\n", 1357 pci_domain_nr(bridge->pci_bus), 1358 bridge->pci_bus->number, bridge->nr_slots, 1359 bridge->nr_slots == 1 ? "" : "s"); 1360 num_slots += bridge->nr_slots; 1361 } 1362 1363 dbg("Total %d slots\n", num_slots); 1364 return num_slots; 1365 } 1366 1367 1368 #if 0 1369 /** 1370 * acpiphp_for_each_slot - call function for each slot 1371 * @fn: callback function 1372 * @data: context to be passed to callback function 1373 */ 1374 static int acpiphp_for_each_slot(acpiphp_callback fn, void *data) 1375 { 1376 struct list_head *node; 1377 struct acpiphp_bridge *bridge; 1378 struct acpiphp_slot *slot; 1379 int retval = 0; 1380 1381 list_for_each (node, &bridge_list) { 1382 bridge = (struct acpiphp_bridge *)node; 1383 for (slot = bridge->slots; slot; slot = slot->next) { 1384 retval = fn(slot, data); 1385 if (!retval) 1386 goto err_exit; 1387 } 1388 } 1389 1390 err_exit: 1391 return retval; 1392 } 1393 #endif 1394 1395 1396 /** 1397 * acpiphp_enable_slot - power on slot 1398 * @slot: ACPI PHP slot 1399 */ 1400 int acpiphp_enable_slot(struct acpiphp_slot *slot) 1401 { 1402 int retval; 1403 1404 mutex_lock(&slot->crit_sect); 1405 1406 /* wake up all functions */ 1407 retval = power_on_slot(slot); 1408 if (retval) 1409 goto err_exit; 1410 1411 if (get_slot_status(slot) == ACPI_STA_ALL) { 1412 /* configure all functions */ 1413 retval = enable_device(slot); 1414 if (retval) 1415 power_off_slot(slot); 1416 } else { 1417 dbg("%s: Slot status is not ACPI_STA_ALL\n", __func__); 1418 power_off_slot(slot); 1419 } 1420 1421 err_exit: 1422 mutex_unlock(&slot->crit_sect); 1423 return retval; 1424 } 1425 1426 /** 1427 * acpiphp_disable_slot - power off slot 1428 * @slot: ACPI PHP slot 1429 */ 1430 int acpiphp_disable_slot(struct acpiphp_slot *slot) 1431 { 1432 int retval = 0; 1433 1434 mutex_lock(&slot->crit_sect); 1435 1436 /* unconfigure all functions */ 1437 retval = disable_device(slot); 1438 if (retval) 1439 goto err_exit; 1440 1441 /* power off all functions */ 1442 retval = power_off_slot(slot); 1443 if (retval) 1444 goto err_exit; 1445 1446 err_exit: 1447 mutex_unlock(&slot->crit_sect); 1448 return retval; 1449 } 1450 1451 1452 /* 1453 * slot enabled: 1 1454 * slot disabled: 0 1455 */ 1456 u8 acpiphp_get_power_status(struct acpiphp_slot *slot) 1457 { 1458 return (slot->flags & SLOT_POWEREDON); 1459 } 1460 1461 1462 /* 1463 * latch open: 1 1464 * latch closed: 0 1465 */ 1466 u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) 1467 { 1468 unsigned int sta; 1469 1470 sta = get_slot_status(slot); 1471 1472 return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; 1473 } 1474 1475 1476 /* 1477 * adapter presence : 1 1478 * absence : 0 1479 */ 1480 u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot) 1481 { 1482 unsigned int sta; 1483 1484 sta = get_slot_status(slot); 1485 1486 return (sta == 0) ? 0 : 1; 1487 } 1488