1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42#define pr_fmt(fmt) "acpiphp_glue: " fmt
43
44#include <linux/module.h>
45
46#include <linux/kernel.h>
47#include <linux/pci.h>
48#include <linux/pci_hotplug.h>
49#include <linux/pci-acpi.h>
50#include <linux/pm_runtime.h>
51#include <linux/mutex.h>
52#include <linux/slab.h>
53#include <linux/acpi.h>
54
55#include "../pci.h"
56#include "acpiphp.h"
57
58static LIST_HEAD(bridge_list);
59static DEFINE_MUTEX(bridge_mutex);
60
61static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type);
62static void acpiphp_post_dock_fixup(struct acpi_device *adev);
63static void acpiphp_sanitize_bus(struct pci_bus *bus);
64static void hotplug_event(u32 type, struct acpiphp_context *context);
65static void free_bridge(struct kref *kref);
66
67
68
69
70
71
72
73static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
74{
75 struct acpiphp_context *context;
76
77 context = kzalloc(sizeof(*context), GFP_KERNEL);
78 if (!context)
79 return NULL;
80
81 context->refcount = 1;
82 context->hp.notify = acpiphp_hotplug_notify;
83 context->hp.fixup = acpiphp_post_dock_fixup;
84 acpi_set_hp_context(adev, &context->hp);
85 return context;
86}
87
88
89
90
91
92
93
94static struct acpiphp_context *acpiphp_get_context(struct acpi_device *adev)
95{
96 struct acpiphp_context *context;
97
98 if (!adev->hp)
99 return NULL;
100
101 context = to_acpiphp_context(adev->hp);
102 context->refcount++;
103 return context;
104}
105
106
107
108
109
110
111
112
113
114static void acpiphp_put_context(struct acpiphp_context *context)
115{
116 if (--context->refcount)
117 return;
118
119 WARN_ON(context->bridge);
120 context->hp.self->hp = NULL;
121 kfree(context);
122}
123
124static inline void get_bridge(struct acpiphp_bridge *bridge)
125{
126 kref_get(&bridge->ref);
127}
128
129static inline void put_bridge(struct acpiphp_bridge *bridge)
130{
131 kref_put(&bridge->ref, free_bridge);
132}
133
134static struct acpiphp_context *acpiphp_grab_context(struct acpi_device *adev)
135{
136 struct acpiphp_context *context;
137
138 acpi_lock_hp_context();
139 context = acpiphp_get_context(adev);
140 if (!context || context->func.parent->is_going_away) {
141 acpi_unlock_hp_context();
142 return NULL;
143 }
144 get_bridge(context->func.parent);
145 acpiphp_put_context(context);
146 acpi_unlock_hp_context();
147 return context;
148}
149
150static void acpiphp_let_context_go(struct acpiphp_context *context)
151{
152 put_bridge(context->func.parent);
153}
154
155static void free_bridge(struct kref *kref)
156{
157 struct acpiphp_context *context;
158 struct acpiphp_bridge *bridge;
159 struct acpiphp_slot *slot, *next;
160 struct acpiphp_func *func, *tmp;
161
162 acpi_lock_hp_context();
163
164 bridge = container_of(kref, struct acpiphp_bridge, ref);
165
166 list_for_each_entry_safe(slot, next, &bridge->slots, node) {
167 list_for_each_entry_safe(func, tmp, &slot->funcs, sibling)
168 acpiphp_put_context(func_to_context(func));
169
170 kfree(slot);
171 }
172
173 context = bridge->context;
174
175 if (context) {
176
177 put_bridge(context->func.parent);
178 context->bridge = NULL;
179 acpiphp_put_context(context);
180 }
181
182 put_device(&bridge->pci_bus->dev);
183 pci_dev_put(bridge->pci_dev);
184 kfree(bridge);
185
186 acpi_unlock_hp_context();
187}
188
189
190
191
192
193
194
195static void acpiphp_post_dock_fixup(struct acpi_device *adev)
196{
197 struct acpiphp_context *context = acpiphp_grab_context(adev);
198 struct pci_bus *bus;
199 u32 buses;
200
201 if (!context)
202 return;
203
204 bus = context->func.slot->bus;
205 if (!bus->self)
206 goto out;
207
208
209
210
211 pci_read_config_dword(bus->self, PCI_PRIMARY_BUS, &buses);
212
213 if (((buses >> 8) & 0xff) != bus->busn_res.start) {
214 buses = (buses & 0xff000000)
215 | ((unsigned int)(bus->primary) << 0)
216 | ((unsigned int)(bus->busn_res.start) << 8)
217 | ((unsigned int)(bus->busn_res.end) << 16);
218 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);
219 }
220
221 out:
222 acpiphp_let_context_go(context);
223}
224
225
226
227
228
229
230
231
232static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
233 void **rv)
234{
235 struct acpiphp_bridge *bridge = data;
236 struct acpiphp_context *context;
237 struct acpi_device *adev;
238 struct acpiphp_slot *slot;
239 struct acpiphp_func *newfunc;
240 acpi_status status = AE_OK;
241 unsigned long long adr;
242 int device, function;
243 struct pci_bus *pbus = bridge->pci_bus;
244 struct pci_dev *pdev = bridge->pci_dev;
245 u32 val;
246
247 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
248 if (ACPI_FAILURE(status)) {
249 if (status != AE_NOT_FOUND)
250 acpi_handle_warn(handle,
251 "can't evaluate _ADR (%#x)\n", status);
252 return AE_OK;
253 }
254 if (acpi_bus_get_device(handle, &adev))
255 return AE_OK;
256
257 device = (adr >> 16) & 0xffff;
258 function = adr & 0xffff;
259
260 acpi_lock_hp_context();
261 context = acpiphp_init_context(adev);
262 if (!context) {
263 acpi_unlock_hp_context();
264 acpi_handle_err(handle, "No hotplug context\n");
265 return AE_NOT_EXIST;
266 }
267 newfunc = &context->func;
268 newfunc->function = function;
269 newfunc->parent = bridge;
270 acpi_unlock_hp_context();
271
272
273
274
275
276 if (!is_dock_device(adev) && acpi_has_method(handle, "_EJ0"))
277 newfunc->flags = FUNC_HAS_EJ0;
278
279 if (acpi_has_method(handle, "_STA"))
280 newfunc->flags |= FUNC_HAS_STA;
281
282
283 list_for_each_entry(slot, &bridge->slots, node)
284 if (slot->device == device)
285 goto slot_found;
286
287 slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
288 if (!slot) {
289 acpi_lock_hp_context();
290 acpiphp_put_context(context);
291 acpi_unlock_hp_context();
292 return AE_NO_MEMORY;
293 }
294
295 slot->bus = bridge->pci_bus;
296 slot->device = device;
297 INIT_LIST_HEAD(&slot->funcs);
298
299 list_add_tail(&slot->node, &bridge->slots);
300
301
302
303
304
305
306
307 if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev))
308 && !(pdev && pdev->is_hotplug_bridge && pciehp_is_native(pdev))) {
309 unsigned long long sun;
310 int retval;
311
312 bridge->nr_slots++;
313 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
314 if (ACPI_FAILURE(status))
315 sun = bridge->nr_slots;
316
317 pr_debug("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",
318 sun, pci_domain_nr(pbus), pbus->number, device);
319
320 retval = acpiphp_register_hotplug_slot(slot, sun);
321 if (retval) {
322 slot->slot = NULL;
323 bridge->nr_slots--;
324 if (retval == -EBUSY)
325 pr_warn("Slot %llu already registered by another hotplug driver\n", sun);
326 else
327 pr_warn("acpiphp_register_hotplug_slot failed (err code = 0x%x)\n", retval);
328 }
329
330 }
331
332 slot_found:
333 newfunc->slot = slot;
334 list_add_tail(&newfunc->sibling, &slot->funcs);
335
336 if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function),
337 &val, 60*1000))
338 slot->flags |= SLOT_ENABLED;
339
340 return AE_OK;
341}
342
343static void cleanup_bridge(struct acpiphp_bridge *bridge)
344{
345 struct acpiphp_slot *slot;
346 struct acpiphp_func *func;
347
348 list_for_each_entry(slot, &bridge->slots, node) {
349 list_for_each_entry(func, &slot->funcs, sibling) {
350 struct acpi_device *adev = func_to_acpi_device(func);
351
352 acpi_lock_hp_context();
353 adev->hp->notify = NULL;
354 adev->hp->fixup = NULL;
355 acpi_unlock_hp_context();
356 }
357 slot->flags |= SLOT_IS_GOING_AWAY;
358 if (slot->slot)
359 acpiphp_unregister_hotplug_slot(slot);
360 }
361
362 mutex_lock(&bridge_mutex);
363 list_del(&bridge->list);
364 mutex_unlock(&bridge_mutex);
365
366 acpi_lock_hp_context();
367 bridge->is_going_away = true;
368 acpi_unlock_hp_context();
369}
370
371
372
373
374
375static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
376{
377 struct pci_bus *tmp;
378 unsigned char max, n;
379
380
381
382
383
384
385
386
387
388 max = bus->busn_res.start;
389
390 list_for_each_entry(tmp, &bus->children, node) {
391 n = pci_bus_max_busnr(tmp);
392 if (n > max)
393 max = n;
394 }
395 return max;
396}
397
398static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
399{
400 struct acpiphp_func *func;
401 union acpi_object params[2];
402 struct acpi_object_list arg_list;
403
404 list_for_each_entry(func, &slot->funcs, sibling) {
405 arg_list.count = 2;
406 arg_list.pointer = params;
407 params[0].type = ACPI_TYPE_INTEGER;
408 params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG;
409 params[1].type = ACPI_TYPE_INTEGER;
410 params[1].integer.value = 1;
411
412 acpi_evaluate_object(func_to_handle(func), "_REG", &arg_list,
413 NULL);
414 }
415}
416
417static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
418{
419 struct acpiphp_func *func;
420
421
422 if (dev->is_hotplug_bridge)
423 return;
424
425 list_for_each_entry(func, &slot->funcs, sibling) {
426 if (PCI_FUNC(dev->devfn) == func->function) {
427 dev->is_hotplug_bridge = 1;
428 break;
429 }
430 }
431}
432
433static int acpiphp_rescan_slot(struct acpiphp_slot *slot)
434{
435 struct acpiphp_func *func;
436
437 list_for_each_entry(func, &slot->funcs, sibling) {
438 struct acpi_device *adev = func_to_acpi_device(func);
439
440 acpi_bus_scan(adev->handle);
441 if (acpi_device_enumerated(adev))
442 acpi_device_set_power(adev, ACPI_STATE_D0);
443 }
444 return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0));
445}
446
447
448
449
450
451
452
453
454static void enable_slot(struct acpiphp_slot *slot)
455{
456 struct pci_dev *dev;
457 struct pci_bus *bus = slot->bus;
458 struct acpiphp_func *func;
459 int max, pass;
460 LIST_HEAD(add_list);
461
462 acpiphp_rescan_slot(slot);
463 max = acpiphp_max_busnr(bus);
464 for (pass = 0; pass < 2; pass++) {
465 list_for_each_entry(dev, &bus->devices, bus_list) {
466 if (PCI_SLOT(dev->devfn) != slot->device)
467 continue;
468
469 if (pci_is_bridge(dev)) {
470 max = pci_scan_bridge(bus, dev, max, pass);
471 if (pass && dev->subordinate) {
472 check_hotplug_bridge(slot, dev);
473 pcibios_resource_survey_bus(dev->subordinate);
474 __pci_bus_size_bridges(dev->subordinate,
475 &add_list);
476 }
477 }
478 }
479 }
480 __pci_bus_assign_resources(bus, &add_list, NULL);
481
482 acpiphp_sanitize_bus(bus);
483 pcie_bus_configure_settings(bus);
484 acpiphp_set_acpi_region(slot);
485
486 list_for_each_entry(dev, &bus->devices, bus_list) {
487
488 if (!dev->is_added)
489 dev->current_state = PCI_D0;
490 }
491
492 pci_bus_add_devices(bus);
493
494 slot->flags |= SLOT_ENABLED;
495 list_for_each_entry(func, &slot->funcs, sibling) {
496 dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
497 func->function));
498 if (!dev) {
499
500
501 slot->flags &= (~SLOT_ENABLED);
502 continue;
503 }
504 }
505}
506
507
508
509
510
511static void disable_slot(struct acpiphp_slot *slot)
512{
513 struct pci_bus *bus = slot->bus;
514 struct pci_dev *dev, *prev;
515 struct acpiphp_func *func;
516
517
518
519
520
521
522
523 list_for_each_entry_safe_reverse(dev, prev, &bus->devices, bus_list)
524 if (PCI_SLOT(dev->devfn) == slot->device)
525 pci_stop_and_remove_bus_device(dev);
526
527 list_for_each_entry(func, &slot->funcs, sibling)
528 acpi_bus_trim(func_to_acpi_device(func));
529
530 slot->flags &= (~SLOT_ENABLED);
531}
532
533static bool slot_no_hotplug(struct acpiphp_slot *slot)
534{
535 struct pci_bus *bus = slot->bus;
536 struct pci_dev *dev;
537
538 list_for_each_entry(dev, &bus->devices, bus_list) {
539 if (PCI_SLOT(dev->devfn) == slot->device && dev->ignore_hotplug)
540 return true;
541 }
542 return false;
543}
544
545
546
547
548
549
550
551
552
553
554
555
556
557static unsigned int get_slot_status(struct acpiphp_slot *slot)
558{
559 unsigned long long sta = 0;
560 struct acpiphp_func *func;
561
562 list_for_each_entry(func, &slot->funcs, sibling) {
563 if (func->flags & FUNC_HAS_STA) {
564 acpi_status status;
565
566 status = acpi_evaluate_integer(func_to_handle(func),
567 "_STA", NULL, &sta);
568 if (ACPI_SUCCESS(status) && sta)
569 break;
570 } else {
571 u32 dvid;
572
573 pci_bus_read_config_dword(slot->bus,
574 PCI_DEVFN(slot->device,
575 func->function),
576 PCI_VENDOR_ID, &dvid);
577 if (dvid != 0xffffffff) {
578 sta = ACPI_STA_ALL;
579 break;
580 }
581 }
582 }
583
584 return (unsigned int)sta;
585}
586
587static inline bool device_status_valid(unsigned int sta)
588{
589
590
591
592
593
594 unsigned int mask = ACPI_STA_DEVICE_ENABLED | ACPI_STA_DEVICE_FUNCTIONING;
595 return (sta & mask) == mask;
596}
597
598
599
600
601
602static void trim_stale_devices(struct pci_dev *dev)
603{
604 struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
605 struct pci_bus *bus = dev->subordinate;
606 bool alive = dev->ignore_hotplug;
607
608 if (adev) {
609 acpi_status status;
610 unsigned long long sta;
611
612 status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
613 alive = alive || (ACPI_SUCCESS(status) && device_status_valid(sta));
614 }
615 if (!alive)
616 alive = pci_device_is_present(dev);
617
618 if (!alive) {
619 pci_stop_and_remove_bus_device(dev);
620 if (adev)
621 acpi_bus_trim(adev);
622 } else if (bus) {
623 struct pci_dev *child, *tmp;
624
625
626 pm_runtime_get_sync(&dev->dev);
627 list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list)
628 trim_stale_devices(child);
629
630 pm_runtime_put(&dev->dev);
631 }
632}
633
634
635
636
637
638
639
640
641static void acpiphp_check_bridge(struct acpiphp_bridge *bridge)
642{
643 struct acpiphp_slot *slot;
644
645
646 if (bridge->is_going_away)
647 return;
648
649 if (bridge->pci_dev)
650 pm_runtime_get_sync(&bridge->pci_dev->dev);
651
652 list_for_each_entry(slot, &bridge->slots, node) {
653 struct pci_bus *bus = slot->bus;
654 struct pci_dev *dev, *tmp;
655
656 if (slot_no_hotplug(slot)) {
657 ;
658 } else if (device_status_valid(get_slot_status(slot))) {
659
660 list_for_each_entry_safe_reverse(dev, tmp,
661 &bus->devices, bus_list)
662 if (PCI_SLOT(dev->devfn) == slot->device)
663 trim_stale_devices(dev);
664
665
666 enable_slot(slot);
667 } else {
668 disable_slot(slot);
669 }
670 }
671
672 if (bridge->pci_dev)
673 pm_runtime_put(&bridge->pci_dev->dev);
674}
675
676
677
678
679
680static void acpiphp_sanitize_bus(struct pci_bus *bus)
681{
682 struct pci_dev *dev, *tmp;
683 int i;
684 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
685
686 list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
687 for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
688 struct resource *res = &dev->resource[i];
689 if ((res->flags & type_mask) && !res->start &&
690 res->end) {
691
692
693 pci_stop_and_remove_bus_device(dev);
694 break;
695 }
696 }
697 }
698}
699
700
701
702
703
704void acpiphp_check_host_bridge(struct acpi_device *adev)
705{
706 struct acpiphp_bridge *bridge = NULL;
707
708 acpi_lock_hp_context();
709 if (adev->hp) {
710 bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
711 if (bridge)
712 get_bridge(bridge);
713 }
714 acpi_unlock_hp_context();
715 if (bridge) {
716 pci_lock_rescan_remove();
717
718 acpiphp_check_bridge(bridge);
719
720 pci_unlock_rescan_remove();
721 put_bridge(bridge);
722 }
723}
724
725static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot);
726
727static void hotplug_event(u32 type, struct acpiphp_context *context)
728{
729 acpi_handle handle = context->hp.self->handle;
730 struct acpiphp_func *func = &context->func;
731 struct acpiphp_slot *slot = func->slot;
732 struct acpiphp_bridge *bridge;
733
734 acpi_lock_hp_context();
735 bridge = context->bridge;
736 if (bridge)
737 get_bridge(bridge);
738
739 acpi_unlock_hp_context();
740
741 pci_lock_rescan_remove();
742
743 switch (type) {
744 case ACPI_NOTIFY_BUS_CHECK:
745
746 acpi_handle_debug(handle, "Bus check in %s()\n", __func__);
747 if (bridge)
748 acpiphp_check_bridge(bridge);
749 else if (!(slot->flags & SLOT_IS_GOING_AWAY))
750 enable_slot(slot);
751
752 break;
753
754 case ACPI_NOTIFY_DEVICE_CHECK:
755
756 acpi_handle_debug(handle, "Device check in %s()\n", __func__);
757 if (bridge) {
758 acpiphp_check_bridge(bridge);
759 } else if (!(slot->flags & SLOT_IS_GOING_AWAY)) {
760
761
762
763
764 if (acpiphp_rescan_slot(slot))
765 acpiphp_check_bridge(func->parent);
766 }
767 break;
768
769 case ACPI_NOTIFY_EJECT_REQUEST:
770
771 acpi_handle_debug(handle, "Eject request in %s()\n", __func__);
772 acpiphp_disable_and_eject_slot(slot);
773 break;
774 }
775
776 pci_unlock_rescan_remove();
777 if (bridge)
778 put_bridge(bridge);
779}
780
781static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type)
782{
783 struct acpiphp_context *context;
784
785 context = acpiphp_grab_context(adev);
786 if (!context)
787 return -ENODATA;
788
789 hotplug_event(type, context);
790 acpiphp_let_context_go(context);
791 return 0;
792}
793
794
795
796
797
798
799
800
801void acpiphp_enumerate_slots(struct pci_bus *bus)
802{
803 struct acpiphp_bridge *bridge;
804 struct acpi_device *adev;
805 acpi_handle handle;
806 acpi_status status;
807
808 if (acpiphp_disabled)
809 return;
810
811 adev = ACPI_COMPANION(bus->bridge);
812 if (!adev)
813 return;
814
815 handle = adev->handle;
816 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
817 if (!bridge) {
818 acpi_handle_err(handle, "No memory for bridge object\n");
819 return;
820 }
821
822 INIT_LIST_HEAD(&bridge->slots);
823 kref_init(&bridge->ref);
824 bridge->pci_dev = pci_dev_get(bus->self);
825 bridge->pci_bus = bus;
826
827
828
829
830
831
832 get_device(&bus->dev);
833
834 acpi_lock_hp_context();
835 if (pci_is_root_bus(bridge->pci_bus)) {
836 struct acpiphp_root_context *root_context;
837
838 root_context = kzalloc(sizeof(*root_context), GFP_KERNEL);
839 if (!root_context)
840 goto err;
841
842 root_context->root_bridge = bridge;
843 acpi_set_hp_context(adev, &root_context->hp);
844 } else {
845 struct acpiphp_context *context;
846
847
848
849
850
851
852
853 context = acpiphp_get_context(adev);
854 if (!context)
855 goto err;
856
857 bridge->context = context;
858 context->bridge = bridge;
859
860 get_bridge(context->func.parent);
861 }
862 acpi_unlock_hp_context();
863
864
865 mutex_lock(&bridge_mutex);
866 list_add(&bridge->list, &bridge_list);
867 mutex_unlock(&bridge_mutex);
868
869
870 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
871 acpiphp_add_context, NULL, bridge, NULL);
872 if (ACPI_FAILURE(status)) {
873 acpi_handle_err(handle, "failed to register slots\n");
874 cleanup_bridge(bridge);
875 put_bridge(bridge);
876 }
877 return;
878
879 err:
880 acpi_unlock_hp_context();
881 put_device(&bus->dev);
882 pci_dev_put(bridge->pci_dev);
883 kfree(bridge);
884}
885
886static void acpiphp_drop_bridge(struct acpiphp_bridge *bridge)
887{
888 if (pci_is_root_bus(bridge->pci_bus)) {
889 struct acpiphp_root_context *root_context;
890 struct acpi_device *adev;
891
892 acpi_lock_hp_context();
893 adev = ACPI_COMPANION(bridge->pci_bus->bridge);
894 root_context = to_acpiphp_root_context(adev->hp);
895 adev->hp = NULL;
896 acpi_unlock_hp_context();
897 kfree(root_context);
898 }
899 cleanup_bridge(bridge);
900 put_bridge(bridge);
901}
902
903
904
905
906
907void acpiphp_remove_slots(struct pci_bus *bus)
908{
909 struct acpiphp_bridge *bridge;
910
911 if (acpiphp_disabled)
912 return;
913
914 mutex_lock(&bridge_mutex);
915 list_for_each_entry(bridge, &bridge_list, list)
916 if (bridge->pci_bus == bus) {
917 mutex_unlock(&bridge_mutex);
918 acpiphp_drop_bridge(bridge);
919 return;
920 }
921
922 mutex_unlock(&bridge_mutex);
923}
924
925
926
927
928
929int acpiphp_enable_slot(struct acpiphp_slot *slot)
930{
931 pci_lock_rescan_remove();
932
933 if (slot->flags & SLOT_IS_GOING_AWAY) {
934 pci_unlock_rescan_remove();
935 return -ENODEV;
936 }
937
938
939 if (!(slot->flags & SLOT_ENABLED))
940 enable_slot(slot);
941
942 pci_unlock_rescan_remove();
943 return 0;
944}
945
946
947
948
949
950static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot)
951{
952 struct acpiphp_func *func;
953
954 if (slot->flags & SLOT_IS_GOING_AWAY)
955 return -ENODEV;
956
957
958 disable_slot(slot);
959
960 list_for_each_entry(func, &slot->funcs, sibling)
961 if (func->flags & FUNC_HAS_EJ0) {
962 acpi_handle handle = func_to_handle(func);
963
964 if (ACPI_FAILURE(acpi_evaluate_ej0(handle)))
965 acpi_handle_err(handle, "_EJ0 failed\n");
966
967 break;
968 }
969
970 return 0;
971}
972
973int acpiphp_disable_slot(struct acpiphp_slot *slot)
974{
975 int ret;
976
977
978
979
980
981 acpi_scan_lock_acquire();
982 pci_lock_rescan_remove();
983 ret = acpiphp_disable_and_eject_slot(slot);
984 pci_unlock_rescan_remove();
985 acpi_scan_lock_release();
986 return ret;
987}
988
989
990
991
992
993u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
994{
995 return (slot->flags & SLOT_ENABLED);
996}
997
998
999
1000
1001
1002u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
1003{
1004 return !(get_slot_status(slot) & ACPI_STA_DEVICE_UI);
1005}
1006
1007
1008
1009
1010
1011u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot)
1012{
1013 return !!get_slot_status(slot);
1014}
1015