0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #define pr_fmt(fmt) "acpiphp_glue: " fmt
0029
0030 #include <linux/module.h>
0031
0032 #include <linux/kernel.h>
0033 #include <linux/pci.h>
0034 #include <linux/pci_hotplug.h>
0035 #include <linux/pci-acpi.h>
0036 #include <linux/pm_runtime.h>
0037 #include <linux/mutex.h>
0038 #include <linux/slab.h>
0039 #include <linux/acpi.h>
0040
0041 #include "../pci.h"
0042 #include "acpiphp.h"
0043
0044 static LIST_HEAD(bridge_list);
0045 static DEFINE_MUTEX(bridge_mutex);
0046
0047 static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type);
0048 static void acpiphp_post_dock_fixup(struct acpi_device *adev);
0049 static void acpiphp_sanitize_bus(struct pci_bus *bus);
0050 static void hotplug_event(u32 type, struct acpiphp_context *context);
0051 static void free_bridge(struct kref *kref);
0052
0053
0054
0055
0056
0057
0058
0059 static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
0060 {
0061 struct acpiphp_context *context;
0062
0063 context = kzalloc(sizeof(*context), GFP_KERNEL);
0064 if (!context)
0065 return NULL;
0066
0067 context->refcount = 1;
0068 context->hp.notify = acpiphp_hotplug_notify;
0069 context->hp.fixup = acpiphp_post_dock_fixup;
0070 acpi_set_hp_context(adev, &context->hp);
0071 return context;
0072 }
0073
0074
0075
0076
0077
0078
0079
0080 static struct acpiphp_context *acpiphp_get_context(struct acpi_device *adev)
0081 {
0082 struct acpiphp_context *context;
0083
0084 if (!adev->hp)
0085 return NULL;
0086
0087 context = to_acpiphp_context(adev->hp);
0088 context->refcount++;
0089 return context;
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 static void acpiphp_put_context(struct acpiphp_context *context)
0101 {
0102 if (--context->refcount)
0103 return;
0104
0105 WARN_ON(context->bridge);
0106 context->hp.self->hp = NULL;
0107 kfree(context);
0108 }
0109
0110 static inline void get_bridge(struct acpiphp_bridge *bridge)
0111 {
0112 kref_get(&bridge->ref);
0113 }
0114
0115 static inline void put_bridge(struct acpiphp_bridge *bridge)
0116 {
0117 kref_put(&bridge->ref, free_bridge);
0118 }
0119
0120 static struct acpiphp_context *acpiphp_grab_context(struct acpi_device *adev)
0121 {
0122 struct acpiphp_context *context;
0123
0124 acpi_lock_hp_context();
0125
0126 context = acpiphp_get_context(adev);
0127 if (!context)
0128 goto unlock;
0129
0130 if (context->func.parent->is_going_away) {
0131 acpiphp_put_context(context);
0132 context = NULL;
0133 goto unlock;
0134 }
0135
0136 get_bridge(context->func.parent);
0137 acpiphp_put_context(context);
0138
0139 unlock:
0140 acpi_unlock_hp_context();
0141 return context;
0142 }
0143
0144 static void acpiphp_let_context_go(struct acpiphp_context *context)
0145 {
0146 put_bridge(context->func.parent);
0147 }
0148
0149 static void free_bridge(struct kref *kref)
0150 {
0151 struct acpiphp_context *context;
0152 struct acpiphp_bridge *bridge;
0153 struct acpiphp_slot *slot, *next;
0154 struct acpiphp_func *func, *tmp;
0155
0156 acpi_lock_hp_context();
0157
0158 bridge = container_of(kref, struct acpiphp_bridge, ref);
0159
0160 list_for_each_entry_safe(slot, next, &bridge->slots, node) {
0161 list_for_each_entry_safe(func, tmp, &slot->funcs, sibling)
0162 acpiphp_put_context(func_to_context(func));
0163
0164 kfree(slot);
0165 }
0166
0167 context = bridge->context;
0168
0169 if (context) {
0170
0171 put_bridge(context->func.parent);
0172 context->bridge = NULL;
0173 acpiphp_put_context(context);
0174 }
0175
0176 put_device(&bridge->pci_bus->dev);
0177 pci_dev_put(bridge->pci_dev);
0178 kfree(bridge);
0179
0180 acpi_unlock_hp_context();
0181 }
0182
0183
0184
0185
0186
0187
0188
0189 static void acpiphp_post_dock_fixup(struct acpi_device *adev)
0190 {
0191 struct acpiphp_context *context = acpiphp_grab_context(adev);
0192 struct pci_bus *bus;
0193 u32 buses;
0194
0195 if (!context)
0196 return;
0197
0198 bus = context->func.slot->bus;
0199 if (!bus->self)
0200 goto out;
0201
0202
0203
0204
0205 pci_read_config_dword(bus->self, PCI_PRIMARY_BUS, &buses);
0206
0207 if (((buses >> 8) & 0xff) != bus->busn_res.start) {
0208 buses = (buses & 0xff000000)
0209 | ((unsigned int)(bus->primary) << 0)
0210 | ((unsigned int)(bus->busn_res.start) << 8)
0211 | ((unsigned int)(bus->busn_res.end) << 16);
0212 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);
0213 }
0214
0215 out:
0216 acpiphp_let_context_go(context);
0217 }
0218
0219
0220
0221
0222
0223
0224
0225
0226 static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
0227 void **rv)
0228 {
0229 struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
0230 struct acpiphp_bridge *bridge = data;
0231 struct acpiphp_context *context;
0232 struct acpiphp_slot *slot;
0233 struct acpiphp_func *newfunc;
0234 acpi_status status = AE_OK;
0235 unsigned long long adr;
0236 int device, function;
0237 struct pci_bus *pbus = bridge->pci_bus;
0238 struct pci_dev *pdev = bridge->pci_dev;
0239 u32 val;
0240
0241 if (!adev)
0242 return AE_OK;
0243
0244 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
0245 if (ACPI_FAILURE(status)) {
0246 if (status != AE_NOT_FOUND)
0247 acpi_handle_warn(handle,
0248 "can't evaluate _ADR (%#x)\n", status);
0249 return AE_OK;
0250 }
0251
0252 device = (adr >> 16) & 0xffff;
0253 function = adr & 0xffff;
0254
0255 acpi_lock_hp_context();
0256 context = acpiphp_init_context(adev);
0257 if (!context) {
0258 acpi_unlock_hp_context();
0259 acpi_handle_err(handle, "No hotplug context\n");
0260 return AE_NOT_EXIST;
0261 }
0262 newfunc = &context->func;
0263 newfunc->function = function;
0264 newfunc->parent = bridge;
0265 acpi_unlock_hp_context();
0266
0267
0268
0269
0270
0271 if (!is_dock_device(adev) && acpi_has_method(handle, "_EJ0"))
0272 newfunc->flags = FUNC_HAS_EJ0;
0273
0274 if (acpi_has_method(handle, "_STA"))
0275 newfunc->flags |= FUNC_HAS_STA;
0276
0277
0278 list_for_each_entry(slot, &bridge->slots, node)
0279 if (slot->device == device)
0280 goto slot_found;
0281
0282 slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
0283 if (!slot) {
0284 acpi_lock_hp_context();
0285 acpiphp_put_context(context);
0286 acpi_unlock_hp_context();
0287 return AE_NO_MEMORY;
0288 }
0289
0290 slot->bus = bridge->pci_bus;
0291 slot->device = device;
0292 INIT_LIST_HEAD(&slot->funcs);
0293
0294 list_add_tail(&slot->node, &bridge->slots);
0295
0296
0297
0298
0299
0300
0301
0302
0303 if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev))
0304 && !(pdev && hotplug_is_native(pdev))) {
0305 unsigned long long sun;
0306 int retval;
0307
0308 bridge->nr_slots++;
0309 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
0310 if (ACPI_FAILURE(status))
0311 sun = bridge->nr_slots;
0312
0313 pr_debug("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",
0314 sun, pci_domain_nr(pbus), pbus->number, device);
0315
0316 retval = acpiphp_register_hotplug_slot(slot, sun);
0317 if (retval) {
0318 slot->slot = NULL;
0319 bridge->nr_slots--;
0320 if (retval == -EBUSY)
0321 pr_warn("Slot %llu already registered by another hotplug driver\n", sun);
0322 else
0323 pr_warn("acpiphp_register_hotplug_slot failed (err code = 0x%x)\n", retval);
0324 }
0325
0326 }
0327
0328 slot_found:
0329 newfunc->slot = slot;
0330 list_add_tail(&newfunc->sibling, &slot->funcs);
0331
0332 if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function),
0333 &val, 60*1000))
0334 slot->flags |= SLOT_ENABLED;
0335
0336 return AE_OK;
0337 }
0338
0339 static void cleanup_bridge(struct acpiphp_bridge *bridge)
0340 {
0341 struct acpiphp_slot *slot;
0342 struct acpiphp_func *func;
0343
0344 list_for_each_entry(slot, &bridge->slots, node) {
0345 list_for_each_entry(func, &slot->funcs, sibling) {
0346 struct acpi_device *adev = func_to_acpi_device(func);
0347
0348 acpi_lock_hp_context();
0349 adev->hp->notify = NULL;
0350 adev->hp->fixup = NULL;
0351 acpi_unlock_hp_context();
0352 }
0353 slot->flags |= SLOT_IS_GOING_AWAY;
0354 if (slot->slot)
0355 acpiphp_unregister_hotplug_slot(slot);
0356 }
0357
0358 mutex_lock(&bridge_mutex);
0359 list_del(&bridge->list);
0360 mutex_unlock(&bridge_mutex);
0361
0362 acpi_lock_hp_context();
0363 bridge->is_going_away = true;
0364 acpi_unlock_hp_context();
0365 }
0366
0367
0368
0369
0370
0371 static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
0372 {
0373 struct pci_bus *tmp;
0374 unsigned char max, n;
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384 max = bus->busn_res.start;
0385
0386 list_for_each_entry(tmp, &bus->children, node) {
0387 n = pci_bus_max_busnr(tmp);
0388 if (n > max)
0389 max = n;
0390 }
0391 return max;
0392 }
0393
0394 static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
0395 {
0396 struct acpiphp_func *func;
0397
0398 list_for_each_entry(func, &slot->funcs, sibling) {
0399
0400 acpi_evaluate_reg(func_to_handle(func),
0401 ACPI_ADR_SPACE_PCI_CONFIG,
0402 ACPI_REG_CONNECT);
0403 }
0404 }
0405
0406 static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
0407 {
0408 struct acpiphp_func *func;
0409
0410
0411 if (dev->is_hotplug_bridge)
0412 return;
0413
0414 list_for_each_entry(func, &slot->funcs, sibling) {
0415 if (PCI_FUNC(dev->devfn) == func->function) {
0416 dev->is_hotplug_bridge = 1;
0417 break;
0418 }
0419 }
0420 }
0421
0422 static int acpiphp_rescan_slot(struct acpiphp_slot *slot)
0423 {
0424 struct acpiphp_func *func;
0425
0426 list_for_each_entry(func, &slot->funcs, sibling) {
0427 struct acpi_device *adev = func_to_acpi_device(func);
0428
0429 acpi_bus_scan(adev->handle);
0430 if (acpi_device_enumerated(adev))
0431 acpi_device_set_power(adev, ACPI_STATE_D0);
0432 }
0433 return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0));
0434 }
0435
0436 static void acpiphp_native_scan_bridge(struct pci_dev *bridge)
0437 {
0438 struct pci_bus *bus = bridge->subordinate;
0439 struct pci_dev *dev;
0440 int max;
0441
0442 if (!bus)
0443 return;
0444
0445 max = bus->busn_res.start;
0446
0447 for_each_pci_bridge(dev, bus) {
0448 if (!hotplug_is_native(dev))
0449 max = pci_scan_bridge(bus, dev, max, 0);
0450 }
0451
0452
0453 for_each_pci_bridge(dev, bus) {
0454 if (hotplug_is_native(dev))
0455 continue;
0456
0457 max = pci_scan_bridge(bus, dev, max, 1);
0458 if (dev->subordinate) {
0459 pcibios_resource_survey_bus(dev->subordinate);
0460 pci_bus_size_bridges(dev->subordinate);
0461 pci_bus_assign_resources(dev->subordinate);
0462 }
0463 }
0464 }
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474 static void enable_slot(struct acpiphp_slot *slot, bool bridge)
0475 {
0476 struct pci_dev *dev;
0477 struct pci_bus *bus = slot->bus;
0478 struct acpiphp_func *func;
0479
0480 if (bridge && bus->self && hotplug_is_native(bus->self)) {
0481
0482
0483
0484
0485
0486
0487
0488 for_each_pci_bridge(dev, bus) {
0489 if (PCI_SLOT(dev->devfn) == slot->device)
0490 acpiphp_native_scan_bridge(dev);
0491 }
0492 } else {
0493 LIST_HEAD(add_list);
0494 int max, pass;
0495
0496 acpiphp_rescan_slot(slot);
0497 max = acpiphp_max_busnr(bus);
0498 for (pass = 0; pass < 2; pass++) {
0499 for_each_pci_bridge(dev, bus) {
0500 if (PCI_SLOT(dev->devfn) != slot->device)
0501 continue;
0502
0503 max = pci_scan_bridge(bus, dev, max, pass);
0504 if (pass && dev->subordinate) {
0505 check_hotplug_bridge(slot, dev);
0506 pcibios_resource_survey_bus(dev->subordinate);
0507 __pci_bus_size_bridges(dev->subordinate,
0508 &add_list);
0509 }
0510 }
0511 }
0512 __pci_bus_assign_resources(bus, &add_list, NULL);
0513 }
0514
0515 acpiphp_sanitize_bus(bus);
0516 pcie_bus_configure_settings(bus);
0517 acpiphp_set_acpi_region(slot);
0518
0519 list_for_each_entry(dev, &bus->devices, bus_list) {
0520
0521 if (!pci_dev_is_added(dev))
0522 dev->current_state = PCI_D0;
0523 }
0524
0525 pci_bus_add_devices(bus);
0526
0527 slot->flags |= SLOT_ENABLED;
0528 list_for_each_entry(func, &slot->funcs, sibling) {
0529 dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
0530 func->function));
0531 if (!dev) {
0532
0533
0534 slot->flags &= ~SLOT_ENABLED;
0535 continue;
0536 }
0537 pci_dev_put(dev);
0538 }
0539 }
0540
0541
0542
0543
0544
0545 static void disable_slot(struct acpiphp_slot *slot)
0546 {
0547 struct pci_bus *bus = slot->bus;
0548 struct pci_dev *dev, *prev;
0549 struct acpiphp_func *func;
0550
0551
0552
0553
0554
0555
0556
0557 list_for_each_entry_safe_reverse(dev, prev, &bus->devices, bus_list)
0558 if (PCI_SLOT(dev->devfn) == slot->device)
0559 pci_stop_and_remove_bus_device(dev);
0560
0561 list_for_each_entry(func, &slot->funcs, sibling)
0562 acpi_bus_trim(func_to_acpi_device(func));
0563
0564 slot->flags &= ~SLOT_ENABLED;
0565 }
0566
0567 static bool slot_no_hotplug(struct acpiphp_slot *slot)
0568 {
0569 struct pci_bus *bus = slot->bus;
0570 struct pci_dev *dev;
0571
0572 list_for_each_entry(dev, &bus->devices, bus_list) {
0573 if (PCI_SLOT(dev->devfn) == slot->device && dev->ignore_hotplug)
0574 return true;
0575 }
0576 return false;
0577 }
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591 static unsigned int get_slot_status(struct acpiphp_slot *slot)
0592 {
0593 unsigned long long sta = 0;
0594 struct acpiphp_func *func;
0595 u32 dvid;
0596
0597 list_for_each_entry(func, &slot->funcs, sibling) {
0598 if (func->flags & FUNC_HAS_STA) {
0599 acpi_status status;
0600
0601 status = acpi_evaluate_integer(func_to_handle(func),
0602 "_STA", NULL, &sta);
0603 if (ACPI_SUCCESS(status) && sta)
0604 break;
0605 } else {
0606 if (pci_bus_read_dev_vendor_id(slot->bus,
0607 PCI_DEVFN(slot->device, func->function),
0608 &dvid, 0)) {
0609 sta = ACPI_STA_ALL;
0610 break;
0611 }
0612 }
0613 }
0614
0615 if (!sta) {
0616
0617
0618
0619
0620
0621 if (pci_bus_read_dev_vendor_id(slot->bus,
0622 PCI_DEVFN(slot->device, 0), &dvid, 0)) {
0623 sta = ACPI_STA_ALL;
0624 }
0625 }
0626
0627 return (unsigned int)sta;
0628 }
0629
0630 static inline bool device_status_valid(unsigned int sta)
0631 {
0632
0633
0634
0635
0636
0637 unsigned int mask = ACPI_STA_DEVICE_ENABLED | ACPI_STA_DEVICE_FUNCTIONING;
0638 return (sta & mask) == mask;
0639 }
0640
0641
0642
0643
0644
0645 static void trim_stale_devices(struct pci_dev *dev)
0646 {
0647 struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
0648 struct pci_bus *bus = dev->subordinate;
0649 bool alive = dev->ignore_hotplug;
0650
0651 if (adev) {
0652 acpi_status status;
0653 unsigned long long sta;
0654
0655 status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
0656 alive = alive || (ACPI_SUCCESS(status) && device_status_valid(sta));
0657 }
0658 if (!alive)
0659 alive = pci_device_is_present(dev);
0660
0661 if (!alive) {
0662 pci_dev_set_disconnected(dev, NULL);
0663 if (pci_has_subordinate(dev))
0664 pci_walk_bus(dev->subordinate, pci_dev_set_disconnected,
0665 NULL);
0666
0667 pci_stop_and_remove_bus_device(dev);
0668 if (adev)
0669 acpi_bus_trim(adev);
0670 } else if (bus) {
0671 struct pci_dev *child, *tmp;
0672
0673
0674 pm_runtime_get_sync(&dev->dev);
0675 list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list)
0676 trim_stale_devices(child);
0677
0678 pm_runtime_put(&dev->dev);
0679 }
0680 }
0681
0682
0683
0684
0685
0686
0687
0688
0689 static void acpiphp_check_bridge(struct acpiphp_bridge *bridge)
0690 {
0691 struct acpiphp_slot *slot;
0692
0693
0694 if (bridge->is_going_away)
0695 return;
0696
0697 if (bridge->pci_dev)
0698 pm_runtime_get_sync(&bridge->pci_dev->dev);
0699
0700 list_for_each_entry(slot, &bridge->slots, node) {
0701 struct pci_bus *bus = slot->bus;
0702 struct pci_dev *dev, *tmp;
0703
0704 if (slot_no_hotplug(slot)) {
0705 ;
0706 } else if (device_status_valid(get_slot_status(slot))) {
0707
0708 list_for_each_entry_safe_reverse(dev, tmp,
0709 &bus->devices, bus_list)
0710 if (PCI_SLOT(dev->devfn) == slot->device)
0711 trim_stale_devices(dev);
0712
0713
0714 enable_slot(slot, true);
0715 } else {
0716 disable_slot(slot);
0717 }
0718 }
0719
0720 if (bridge->pci_dev)
0721 pm_runtime_put(&bridge->pci_dev->dev);
0722 }
0723
0724
0725
0726
0727
0728 static void acpiphp_sanitize_bus(struct pci_bus *bus)
0729 {
0730 struct pci_dev *dev, *tmp;
0731 int i;
0732 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
0733
0734 list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
0735 for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
0736 struct resource *res = &dev->resource[i];
0737 if ((res->flags & type_mask) && !res->start &&
0738 res->end) {
0739
0740
0741 pci_stop_and_remove_bus_device(dev);
0742 break;
0743 }
0744 }
0745 }
0746 }
0747
0748
0749
0750
0751
0752 void acpiphp_check_host_bridge(struct acpi_device *adev)
0753 {
0754 struct acpiphp_bridge *bridge = NULL;
0755
0756 acpi_lock_hp_context();
0757 if (adev->hp) {
0758 bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
0759 if (bridge)
0760 get_bridge(bridge);
0761 }
0762 acpi_unlock_hp_context();
0763 if (bridge) {
0764 pci_lock_rescan_remove();
0765
0766 acpiphp_check_bridge(bridge);
0767
0768 pci_unlock_rescan_remove();
0769 put_bridge(bridge);
0770 }
0771 }
0772
0773 static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot);
0774
0775 static void hotplug_event(u32 type, struct acpiphp_context *context)
0776 {
0777 acpi_handle handle = context->hp.self->handle;
0778 struct acpiphp_func *func = &context->func;
0779 struct acpiphp_slot *slot = func->slot;
0780 struct acpiphp_bridge *bridge;
0781
0782 acpi_lock_hp_context();
0783 bridge = context->bridge;
0784 if (bridge)
0785 get_bridge(bridge);
0786
0787 acpi_unlock_hp_context();
0788
0789 pci_lock_rescan_remove();
0790
0791 switch (type) {
0792 case ACPI_NOTIFY_BUS_CHECK:
0793
0794 acpi_handle_debug(handle, "Bus check in %s()\n", __func__);
0795 if (bridge)
0796 acpiphp_check_bridge(bridge);
0797 else if (!(slot->flags & SLOT_IS_GOING_AWAY))
0798 enable_slot(slot, false);
0799
0800 break;
0801
0802 case ACPI_NOTIFY_DEVICE_CHECK:
0803
0804 acpi_handle_debug(handle, "Device check in %s()\n", __func__);
0805 if (bridge) {
0806 acpiphp_check_bridge(bridge);
0807 } else if (!(slot->flags & SLOT_IS_GOING_AWAY)) {
0808
0809
0810
0811
0812 if (acpiphp_rescan_slot(slot))
0813 acpiphp_check_bridge(func->parent);
0814 }
0815 break;
0816
0817 case ACPI_NOTIFY_EJECT_REQUEST:
0818
0819 acpi_handle_debug(handle, "Eject request in %s()\n", __func__);
0820 acpiphp_disable_and_eject_slot(slot);
0821 break;
0822 }
0823
0824 pci_unlock_rescan_remove();
0825 if (bridge)
0826 put_bridge(bridge);
0827 }
0828
0829 static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type)
0830 {
0831 struct acpiphp_context *context;
0832
0833 context = acpiphp_grab_context(adev);
0834 if (!context)
0835 return -ENODATA;
0836
0837 hotplug_event(type, context);
0838 acpiphp_let_context_go(context);
0839 return 0;
0840 }
0841
0842
0843
0844
0845
0846
0847
0848
0849 void acpiphp_enumerate_slots(struct pci_bus *bus)
0850 {
0851 struct acpiphp_bridge *bridge;
0852 struct acpi_device *adev;
0853 acpi_handle handle;
0854 acpi_status status;
0855
0856 if (acpiphp_disabled)
0857 return;
0858
0859 adev = ACPI_COMPANION(bus->bridge);
0860 if (!adev)
0861 return;
0862
0863 handle = adev->handle;
0864 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
0865 if (!bridge)
0866 return;
0867
0868 INIT_LIST_HEAD(&bridge->slots);
0869 kref_init(&bridge->ref);
0870 bridge->pci_dev = pci_dev_get(bus->self);
0871 bridge->pci_bus = bus;
0872
0873
0874
0875
0876
0877
0878 get_device(&bus->dev);
0879
0880 acpi_lock_hp_context();
0881 if (pci_is_root_bus(bridge->pci_bus)) {
0882 struct acpiphp_root_context *root_context;
0883
0884 root_context = kzalloc(sizeof(*root_context), GFP_KERNEL);
0885 if (!root_context)
0886 goto err;
0887
0888 root_context->root_bridge = bridge;
0889 acpi_set_hp_context(adev, &root_context->hp);
0890 } else {
0891 struct acpiphp_context *context;
0892
0893
0894
0895
0896
0897
0898
0899 context = acpiphp_get_context(adev);
0900 if (!context)
0901 goto err;
0902
0903 bridge->context = context;
0904 context->bridge = bridge;
0905
0906 get_bridge(context->func.parent);
0907 }
0908 acpi_unlock_hp_context();
0909
0910
0911 mutex_lock(&bridge_mutex);
0912 list_add(&bridge->list, &bridge_list);
0913 mutex_unlock(&bridge_mutex);
0914
0915
0916 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
0917 acpiphp_add_context, NULL, bridge, NULL);
0918 if (ACPI_FAILURE(status)) {
0919 acpi_handle_err(handle, "failed to register slots\n");
0920 cleanup_bridge(bridge);
0921 put_bridge(bridge);
0922 }
0923 return;
0924
0925 err:
0926 acpi_unlock_hp_context();
0927 put_device(&bus->dev);
0928 pci_dev_put(bridge->pci_dev);
0929 kfree(bridge);
0930 }
0931
0932 static void acpiphp_drop_bridge(struct acpiphp_bridge *bridge)
0933 {
0934 if (pci_is_root_bus(bridge->pci_bus)) {
0935 struct acpiphp_root_context *root_context;
0936 struct acpi_device *adev;
0937
0938 acpi_lock_hp_context();
0939 adev = ACPI_COMPANION(bridge->pci_bus->bridge);
0940 root_context = to_acpiphp_root_context(adev->hp);
0941 adev->hp = NULL;
0942 acpi_unlock_hp_context();
0943 kfree(root_context);
0944 }
0945 cleanup_bridge(bridge);
0946 put_bridge(bridge);
0947 }
0948
0949
0950
0951
0952
0953 void acpiphp_remove_slots(struct pci_bus *bus)
0954 {
0955 struct acpiphp_bridge *bridge;
0956
0957 if (acpiphp_disabled)
0958 return;
0959
0960 mutex_lock(&bridge_mutex);
0961 list_for_each_entry(bridge, &bridge_list, list)
0962 if (bridge->pci_bus == bus) {
0963 mutex_unlock(&bridge_mutex);
0964 acpiphp_drop_bridge(bridge);
0965 return;
0966 }
0967
0968 mutex_unlock(&bridge_mutex);
0969 }
0970
0971
0972
0973
0974
0975 int acpiphp_enable_slot(struct acpiphp_slot *slot)
0976 {
0977 pci_lock_rescan_remove();
0978
0979 if (slot->flags & SLOT_IS_GOING_AWAY) {
0980 pci_unlock_rescan_remove();
0981 return -ENODEV;
0982 }
0983
0984
0985 if (!(slot->flags & SLOT_ENABLED))
0986 enable_slot(slot, false);
0987
0988 pci_unlock_rescan_remove();
0989 return 0;
0990 }
0991
0992
0993
0994
0995
0996 static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot)
0997 {
0998 struct acpiphp_func *func;
0999
1000 if (slot->flags & SLOT_IS_GOING_AWAY)
1001 return -ENODEV;
1002
1003
1004 disable_slot(slot);
1005
1006 list_for_each_entry(func, &slot->funcs, sibling)
1007 if (func->flags & FUNC_HAS_EJ0) {
1008 acpi_handle handle = func_to_handle(func);
1009
1010 if (ACPI_FAILURE(acpi_evaluate_ej0(handle)))
1011 acpi_handle_err(handle, "_EJ0 failed\n");
1012
1013 break;
1014 }
1015
1016 return 0;
1017 }
1018
1019 int acpiphp_disable_slot(struct acpiphp_slot *slot)
1020 {
1021 int ret;
1022
1023
1024
1025
1026
1027 acpi_scan_lock_acquire();
1028 pci_lock_rescan_remove();
1029 ret = acpiphp_disable_and_eject_slot(slot);
1030 pci_unlock_rescan_remove();
1031 acpi_scan_lock_release();
1032 return ret;
1033 }
1034
1035
1036
1037
1038
1039 u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
1040 {
1041 return (slot->flags & SLOT_ENABLED);
1042 }
1043
1044
1045
1046
1047
1048 u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
1049 {
1050 return !(get_slot_status(slot) & ACPI_STA_DEVICE_UI);
1051 }
1052
1053
1054
1055
1056
1057 u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot)
1058 {
1059 return !!get_slot_status(slot);
1060 }