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.c242
1 files changed, 179 insertions, 63 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 053ee843863c..d370f999782e 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -286,13 +286,19 @@ static void decode_hpp(struct acpiphp_bridge *bridge)
286{ 286{
287 acpi_status status; 287 acpi_status status;
288 288
289 status = acpi_get_hp_params_from_firmware(bridge->pci_dev, &bridge->hpp); 289 status = acpi_get_hp_params_from_firmware(bridge->pci_bus, &bridge->hpp);
290 if (ACPI_FAILURE(status)) { 290 if (ACPI_FAILURE(status) ||
291 !bridge->hpp.t0 || (bridge->hpp.t0->revision > 1)) {
291 /* use default numbers */ 292 /* use default numbers */
292 bridge->hpp.cache_line_size = 0x10; 293 printk(KERN_WARNING
293 bridge->hpp.latency_timer = 0x40; 294 "%s: Could not get hotplug parameters. Use defaults\n",
294 bridge->hpp.enable_serr = 0; 295 __FUNCTION__);
295 bridge->hpp.enable_perr = 0; 296 bridge->hpp.t0 = &bridge->hpp.type0_data;
297 bridge->hpp.t0->revision = 0;
298 bridge->hpp.t0->cache_line_size = 0x10;
299 bridge->hpp.t0->latency_timer = 0x40;
300 bridge->hpp.t0->enable_serr = 0;
301 bridge->hpp.t0->enable_perr = 0;
296 } 302 }
297} 303}
298 304
@@ -319,6 +325,13 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
319 325
320 /* install notify handler */ 326 /* install notify handler */
321 if (bridge->type != BRIDGE_TYPE_HOST) { 327 if (bridge->type != BRIDGE_TYPE_HOST) {
328 if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) {
329 status = acpi_remove_notify_handler(bridge->func->handle,
330 ACPI_SYSTEM_NOTIFY,
331 handle_hotplug_event_func);
332 if (ACPI_FAILURE(status))
333 err("failed to remove notify handler\n");
334 }
322 status = acpi_install_notify_handler(bridge->handle, 335 status = acpi_install_notify_handler(bridge->handle,
323 ACPI_SYSTEM_NOTIFY, 336 ACPI_SYSTEM_NOTIFY,
324 handle_hotplug_event_bridge, 337 handle_hotplug_event_bridge,
@@ -331,6 +344,66 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
331} 344}
332 345
333 346
347/* find acpiphp_func from acpiphp_bridge */
348static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle)
349{
350 struct list_head *node, *l;
351 struct acpiphp_bridge *bridge;
352 struct acpiphp_slot *slot;
353 struct acpiphp_func *func;
354
355 list_for_each(node, &bridge_list) {
356 bridge = list_entry(node, struct acpiphp_bridge, list);
357 for (slot = bridge->slots; slot; slot = slot->next) {
358 list_for_each(l, &slot->funcs) {
359 func = list_entry(l, struct acpiphp_func,
360 sibling);
361 if (func->handle == handle)
362 return func;
363 }
364 }
365 }
366
367 return NULL;
368}
369
370
371static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
372{
373 acpi_handle dummy_handle;
374
375 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
376 "_STA", &dummy_handle)))
377 bridge->flags |= BRIDGE_HAS_STA;
378
379 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
380 "_EJ0", &dummy_handle)))
381 bridge->flags |= BRIDGE_HAS_EJ0;
382
383 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
384 "_PS0", &dummy_handle)))
385 bridge->flags |= BRIDGE_HAS_PS0;
386
387 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
388 "_PS3", &dummy_handle)))
389 bridge->flags |= BRIDGE_HAS_PS3;
390
391 /* is this ejectable p2p bridge? */
392 if (bridge->flags & BRIDGE_HAS_EJ0) {
393 struct acpiphp_func *func;
394
395 dbg("found ejectable p2p bridge\n");
396
397 /* make link between PCI bridge and PCI function */
398 func = acpiphp_bridge_handle_to_function(bridge->handle);
399 if (!func)
400 return;
401 bridge->func = func;
402 func->bridge = bridge;
403 }
404}
405
406
334/* allocate and initialize host bridge data structure */ 407/* allocate and initialize host bridge data structure */
335static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) 408static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
336{ 409{
@@ -364,6 +437,7 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
364 437
365 bridge->type = BRIDGE_TYPE_P2P; 438 bridge->type = BRIDGE_TYPE_P2P;
366 bridge->handle = handle; 439 bridge->handle = handle;
440 config_p2p_bridge_flags(bridge);
367 441
368 bridge->pci_dev = pci_dev_get(pci_dev); 442 bridge->pci_dev = pci_dev_get(pci_dev);
369 bridge->pci_bus = pci_dev->subordinate; 443 bridge->pci_bus = pci_dev->subordinate;
@@ -423,7 +497,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
423 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 497 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
424 find_p2p_bridge, dev->subordinate, NULL); 498 find_p2p_bridge, dev->subordinate, NULL);
425 if (ACPI_FAILURE(status)) 499 if (ACPI_FAILURE(status))
426 warn("find_p2p_bridge faied (error code = 0x%x)\n", status); 500 warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
427 501
428 out: 502 out:
429 pci_dev_put(dev); 503 pci_dev_put(dev);
@@ -478,7 +552,6 @@ static int add_bridge(acpi_handle handle)
478 if (detect_ejectable_slots(handle) > 0) { 552 if (detect_ejectable_slots(handle) > 0) {
479 dbg("found PCI host-bus bridge with hot-pluggable slots\n"); 553 dbg("found PCI host-bus bridge with hot-pluggable slots\n");
480 add_host_bridge(handle, pci_bus); 554 add_host_bridge(handle, pci_bus);
481 return 0;
482 } 555 }
483 556
484 /* search P2P bridges under this host bridge */ 557 /* search P2P bridges under this host bridge */
@@ -486,7 +559,7 @@ static int add_bridge(acpi_handle handle)
486 find_p2p_bridge, pci_bus, NULL); 559 find_p2p_bridge, pci_bus, NULL);
487 560
488 if (ACPI_FAILURE(status)) 561 if (ACPI_FAILURE(status))
489 warn("find_p2p_bridge faied (error code = 0x%x)\n",status); 562 warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
490 563
491 return 0; 564 return 0;
492} 565}
@@ -516,6 +589,16 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
516 if (ACPI_FAILURE(status)) 589 if (ACPI_FAILURE(status))
517 err("failed to remove notify handler\n"); 590 err("failed to remove notify handler\n");
518 591
592 if ((bridge->type != BRIDGE_TYPE_HOST) &&
593 ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) {
594 status = acpi_install_notify_handler(bridge->func->handle,
595 ACPI_SYSTEM_NOTIFY,
596 handle_hotplug_event_func,
597 bridge->func);
598 if (ACPI_FAILURE(status))
599 err("failed to install interrupt notify handler\n");
600 }
601
519 slot = bridge->slots; 602 slot = bridge->slots;
520 while (slot) { 603 while (slot) {
521 struct acpiphp_slot *next = slot->next; 604 struct acpiphp_slot *next = slot->next;
@@ -549,6 +632,11 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
549{ 632{
550 struct acpiphp_bridge *bridge; 633 struct acpiphp_bridge *bridge;
551 634
635 /* cleanup p2p bridges under this P2P bridge
636 in a depth-first manner */
637 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
638 cleanup_p2p_bridge, NULL, NULL);
639
552 if (!(bridge = acpiphp_handle_to_bridge(handle))) 640 if (!(bridge = acpiphp_handle_to_bridge(handle)))
553 return AE_OK; 641 return AE_OK;
554 cleanup_bridge(bridge); 642 cleanup_bridge(bridge);
@@ -559,15 +647,14 @@ static void remove_bridge(acpi_handle handle)
559{ 647{
560 struct acpiphp_bridge *bridge; 648 struct acpiphp_bridge *bridge;
561 649
650 /* cleanup p2p bridges under this host bridge
651 in a depth-first manner */
652 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
653 (u32)1, cleanup_p2p_bridge, NULL, NULL);
654
562 bridge = acpiphp_handle_to_bridge(handle); 655 bridge = acpiphp_handle_to_bridge(handle);
563 if (bridge) { 656 if (bridge)
564 cleanup_bridge(bridge); 657 cleanup_bridge(bridge);
565 } else {
566 /* clean-up p2p bridges under this host bridge */
567 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
568 ACPI_UINT32_MAX, cleanup_p2p_bridge,
569 NULL, NULL);
570 }
571} 658}
572 659
573static struct pci_dev * get_apic_pci_info(acpi_handle handle) 660static struct pci_dev * get_apic_pci_info(acpi_handle handle)
@@ -634,7 +721,7 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
634 break; 721 break;
635 } 722 }
636 out: 723 out:
637 acpi_os_free(buffer.pointer); 724 kfree(buffer.pointer);
638 return result; 725 return result;
639} 726}
640 727
@@ -797,36 +884,6 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
797} 884}
798 885
799 886
800
801/**
802 * get_func - get a pointer to acpiphp_func given a slot, device
803 * @slot: slot to search
804 * @dev: pci_dev struct to match.
805 *
806 * This function will increase the reference count of pci_dev,
807 * so callers should call pci_dev_put when complete.
808 *
809 */
810static struct acpiphp_func *
811get_func(struct acpiphp_slot *slot, struct pci_dev *dev)
812{
813 struct acpiphp_func *func = NULL;
814 struct pci_bus *bus = slot->bridge->pci_bus;
815 struct pci_dev *pdev;
816
817 list_for_each_entry(func, &slot->funcs, sibling) {
818 pdev = pci_get_slot(bus, PCI_DEVFN(slot->device,
819 func->function));
820 if (pdev) {
821 if (pdev == dev)
822 break;
823 pci_dev_put(pdev);
824 }
825 }
826 return func;
827}
828
829
830/** 887/**
831 * acpiphp_bus_add - add a new bus to acpi subsystem 888 * acpiphp_bus_add - add a new bus to acpi subsystem
832 * @func: acpiphp_func of the bridge 889 * @func: acpiphp_func of the bridge
@@ -872,6 +929,28 @@ acpiphp_bus_add_out:
872} 929}
873 930
874 931
932/**
933 * acpiphp_bus_trim - trim a bus from acpi subsystem
934 * @handle: handle to acpi namespace
935 *
936 */
937int acpiphp_bus_trim(acpi_handle handle)
938{
939 struct acpi_device *device;
940 int retval;
941
942 retval = acpi_bus_get_device(handle, &device);
943 if (retval) {
944 dbg("acpi_device not found\n");
945 return retval;
946 }
947
948 retval = acpi_bus_trim(device, 1);
949 if (retval)
950 err("cannot remove from acpi list\n");
951
952 return retval;
953}
875 954
876/** 955/**
877 * enable_device - enable, configure a slot 956 * enable_device - enable, configure a slot
@@ -889,6 +968,7 @@ static int enable_device(struct acpiphp_slot *slot)
889 struct acpiphp_func *func; 968 struct acpiphp_func *func;
890 int retval = 0; 969 int retval = 0;
891 int num, max, pass; 970 int num, max, pass;
971 acpi_status status;
892 972
893 if (slot->flags & SLOT_ENABLED) 973 if (slot->flags & SLOT_ENABLED)
894 goto err_exit; 974 goto err_exit;
@@ -918,19 +998,17 @@ static int enable_device(struct acpiphp_slot *slot)
918 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 998 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
919 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { 999 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
920 max = pci_scan_bridge(bus, dev, max, pass); 1000 max = pci_scan_bridge(bus, dev, max, pass);
921 if (pass && dev->subordinate) { 1001 if (pass && dev->subordinate)
922 pci_bus_size_bridges(dev->subordinate); 1002 pci_bus_size_bridges(dev->subordinate);
923 func = get_func(slot, dev);
924 if (func) {
925 acpiphp_bus_add(func);
926 /* side effect of get_func */
927 pci_dev_put(dev);
928 }
929 }
930 } 1003 }
931 } 1004 }
932 } 1005 }
933 1006
1007 list_for_each (l, &slot->funcs) {
1008 func = list_entry(l, struct acpiphp_func, sibling);
1009 acpiphp_bus_add(func);
1010 }
1011
934 pci_bus_assign_resources(bus); 1012 pci_bus_assign_resources(bus);
935 acpiphp_sanitize_bus(bus); 1013 acpiphp_sanitize_bus(bus);
936 pci_enable_bridges(bus); 1014 pci_enable_bridges(bus);
@@ -943,6 +1021,17 @@ static int enable_device(struct acpiphp_slot *slot)
943 func = list_entry(l, struct acpiphp_func, sibling); 1021 func = list_entry(l, struct acpiphp_func, sibling);
944 func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 1022 func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
945 func->function)); 1023 func->function));
1024 if (!func->pci_dev)
1025 continue;
1026
1027 if (func->pci_dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
1028 func->pci_dev->hdr_type != PCI_HEADER_TYPE_CARDBUS)
1029 continue;
1030
1031 status = find_p2p_bridge(func->handle, (u32)1, bus, NULL);
1032 if (ACPI_FAILURE(status))
1033 warn("find_p2p_bridge failed (error code = 0x%x)\n",
1034 status);
946 } 1035 }
947 1036
948 slot->flags |= SLOT_ENABLED; 1037 slot->flags |= SLOT_ENABLED;
@@ -967,6 +1056,18 @@ static int disable_device(struct acpiphp_slot *slot)
967 1056
968 list_for_each (l, &slot->funcs) { 1057 list_for_each (l, &slot->funcs) {
969 func = list_entry(l, struct acpiphp_func, sibling); 1058 func = list_entry(l, struct acpiphp_func, sibling);
1059
1060 if (func->bridge) {
1061 /* cleanup p2p bridges under this P2P bridge */
1062 cleanup_p2p_bridge(func->bridge->handle,
1063 (u32)1, NULL, NULL);
1064 func->bridge = NULL;
1065 }
1066
1067 acpiphp_bus_trim(func->handle);
1068 /* try to remove anyway.
1069 * acpiphp_bus_add might have been failed */
1070
970 if (!func->pci_dev) 1071 if (!func->pci_dev)
971 continue; 1072 continue;
972 1073
@@ -1111,16 +1212,17 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
1111 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && 1212 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
1112 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) 1213 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
1113 return; 1214 return;
1215
1114 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 1216 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
1115 bridge->hpp.cache_line_size); 1217 bridge->hpp.t0->cache_line_size);
1116 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 1218 pci_write_config_byte(dev, PCI_LATENCY_TIMER,
1117 bridge->hpp.latency_timer); 1219 bridge->hpp.t0->latency_timer);
1118 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); 1220 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
1119 if (bridge->hpp.enable_serr) 1221 if (bridge->hpp.t0->enable_serr)
1120 pci_cmd |= PCI_COMMAND_SERR; 1222 pci_cmd |= PCI_COMMAND_SERR;
1121 else 1223 else
1122 pci_cmd &= ~PCI_COMMAND_SERR; 1224 pci_cmd &= ~PCI_COMMAND_SERR;
1123 if (bridge->hpp.enable_perr) 1225 if (bridge->hpp.t0->enable_perr)
1124 pci_cmd |= PCI_COMMAND_PARITY; 1226 pci_cmd |= PCI_COMMAND_PARITY;
1125 else 1227 else
1126 pci_cmd &= ~PCI_COMMAND_PARITY; 1228 pci_cmd &= ~PCI_COMMAND_PARITY;
@@ -1129,13 +1231,13 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
1129 /* Program bridge control value and child devices */ 1231 /* Program bridge control value and child devices */
1130 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 1232 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
1131 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 1233 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
1132 bridge->hpp.latency_timer); 1234 bridge->hpp.t0->latency_timer);
1133 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); 1235 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
1134 if (bridge->hpp.enable_serr) 1236 if (bridge->hpp.t0->enable_serr)
1135 pci_bctl |= PCI_BRIDGE_CTL_SERR; 1237 pci_bctl |= PCI_BRIDGE_CTL_SERR;
1136 else 1238 else
1137 pci_bctl &= ~PCI_BRIDGE_CTL_SERR; 1239 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
1138 if (bridge->hpp.enable_perr) 1240 if (bridge->hpp.t0->enable_perr)
1139 pci_bctl |= PCI_BRIDGE_CTL_PARITY; 1241 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
1140 else 1242 else
1141 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; 1243 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
@@ -1155,6 +1257,7 @@ static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
1155 1257
1156 memset(&bridge, 0, sizeof(bridge)); 1258 memset(&bridge, 0, sizeof(bridge));
1157 bridge.handle = handle; 1259 bridge.handle = handle;
1260 bridge.pci_bus = bus;
1158 bridge.pci_dev = bus->self; 1261 bridge.pci_dev = bus->self;
1159 decode_hpp(&bridge); 1262 decode_hpp(&bridge);
1160 list_for_each_entry(dev, &bus->devices, bus_list) 1263 list_for_each_entry(dev, &bus->devices, bus_list)
@@ -1297,6 +1400,13 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
1297 case ACPI_NOTIFY_EJECT_REQUEST: 1400 case ACPI_NOTIFY_EJECT_REQUEST:
1298 /* request device eject */ 1401 /* request device eject */
1299 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); 1402 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1403 if ((bridge->type != BRIDGE_TYPE_HOST) &&
1404 (bridge->flags & BRIDGE_HAS_EJ0)) {
1405 struct acpiphp_slot *slot;
1406 slot = bridge->func->slot;
1407 if (!acpiphp_disable_slot(slot))
1408 acpiphp_eject_slot(slot);
1409 }
1300 break; 1410 break;
1301 1411
1302 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 1412 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
@@ -1490,9 +1600,15 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
1490 if (retval) 1600 if (retval)
1491 goto err_exit; 1601 goto err_exit;
1492 1602
1493 if (get_slot_status(slot) == ACPI_STA_ALL) 1603 if (get_slot_status(slot) == ACPI_STA_ALL) {
1494 /* configure all functions */ 1604 /* configure all functions */
1495 retval = enable_device(slot); 1605 retval = enable_device(slot);
1606 if (retval)
1607 power_off_slot(slot);
1608 } else {
1609 dbg("%s: Slot status is not ACPI_STA_ALL\n", __FUNCTION__);
1610 power_off_slot(slot);
1611 }
1496 1612
1497 err_exit: 1613 err_exit:
1498 mutex_unlock(&slot->crit_sect); 1614 mutex_unlock(&slot->crit_sect);