]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/pci/hotplug/acpiphp_glue.c
PCI hotplug: move IOAPIC support from acpiphp to ioapic driver
[net-next-2.6.git] / drivers / pci / hotplug / acpiphp_glue.c
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 }