pciehp: use pci_pcie_cap()
[safe/jmp/linux-2.6] / drivers / pci / hotplug / pciehp_acpi.c
index 88a5c57..b09b083 100644 (file)
@@ -24,6 +24,8 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include "pciehp.h"
 
 #define PCIEHP_DETECT_PCIE     (0)
 #define PCIEHP_DETECT_AUTO     (2)
 #define PCIEHP_DETECT_DEFAULT  PCIEHP_DETECT_AUTO
 
+struct dummy_slot {
+       u32 number;
+       struct list_head list;
+};
+
 static int slot_detection_mode;
 static char *pciehp_detect_mode;
 module_param(pciehp_detect_mode, charp, 0444);
@@ -41,59 +48,11 @@ MODULE_PARM_DESC(pciehp_detect_mode,
         "  auto(default) - Auto select mode. Use acpi option if duplicate\n"
         "                  slot ids are found. Otherwise, use pcie option\n");
 
-static int is_ejectable(acpi_handle handle)
-{
-       acpi_status status;
-       acpi_handle tmp;
-       unsigned long long removable;
-       status = acpi_get_handle(handle, "_ADR", &tmp);
-       if (ACPI_FAILURE(status))
-               return 0;
-       status = acpi_get_handle(handle, "_EJ0", &tmp);
-       if (ACPI_SUCCESS(status))
-               return 1;
-       status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable);
-       if (ACPI_SUCCESS(status) && removable)
-               return 1;
-       return 0;
-}
-
-static acpi_status
-check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-       int *found = (int *)context;
-       if (is_ejectable(handle)) {
-               *found = 1;
-               return AE_CTRL_TERMINATE;
-       }
-       return AE_OK;
-}
-
-static int pciehp_detect_acpi_slot(struct pci_bus *pbus)
-{
-       acpi_handle handle;
-       struct pci_dev *pdev = pbus->self;
-       int found = 0;
-
-       if (!pdev){
-               int seg = pci_domain_nr(pbus), busnr = pbus->number;
-               handle = acpi_get_pci_rootbridge_handle(seg, busnr);
-       } else
-               handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
-
-       if (!handle)
-               return 0;
-
-       acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-                           check_hotplug, (void *)&found, NULL);
-       return found;
-}
-
 int pciehp_acpi_slot_detection_check(struct pci_dev *dev)
 {
        if (slot_detection_mode != PCIEHP_DETECT_ACPI)
                return 0;
-       if (pciehp_detect_acpi_slot(dev->subordinate))
+       if (acpi_pci_detect_ejectable(DEVICE_ACPI_HANDLE(&dev->dev)))
                return 0;
        return -ENODEV;
 }
@@ -113,60 +72,54 @@ static int __init parse_detect_mode(void)
        return PCIEHP_DETECT_DEFAULT;
 }
 
-static struct pcie_port_service_id __initdata port_pci_ids[] = {
-       {
-               .vendor = PCI_ANY_ID,
-               .device = PCI_ANY_ID,
-               .port_type = PCIE_ANY_PORT,
-               .service_type = PCIE_PORT_SERVICE_HP,
-               .driver_data =  0,
-        }, { /* end: all zeroes */ }
-};
-
 static int __initdata dup_slot_id;
 static int __initdata acpi_slot_detected;
 static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots);
 
 /* Dummy driver for dumplicate name detection */
-static int __init dummy_probe(struct pcie_device *dev,
-                             const struct pcie_port_service_id *id)
+static int __init dummy_probe(struct pcie_device *dev)
 {
        int pos;
        u32 slot_cap;
-       struct slot *slot, *tmp;
+       acpi_handle handle;
+       struct dummy_slot *slot, *tmp;
        struct pci_dev *pdev = dev->port;
-       if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL)))
-               return -ENOMEM;
        /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
        if (pciehp_get_hp_hw_control_from_firmware(pdev))
                return -ENODEV;
-       if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP)))
+       pos = pci_pcie_cap(pdev);
+       if (!pos)
                return -ENODEV;
        pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
+       slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+       if (!slot)
+               return -ENOMEM;
        slot->number = slot_cap >> 19;
-       list_for_each_entry(tmp, &dummy_slots, slot_list) {
+       list_for_each_entry(tmp, &dummy_slots, list) {
                if (tmp->number == slot->number)
                        dup_slot_id++;
        }
-       list_add_tail(&slot->slot_list, &dummy_slots);
-       if (!acpi_slot_detected && pciehp_detect_acpi_slot(pdev->subordinate))
+       list_add_tail(&slot->list, &dummy_slots);
+       handle = DEVICE_ACPI_HANDLE(&pdev->dev);
+       if (!acpi_slot_detected && acpi_pci_detect_ejectable(handle))
                acpi_slot_detected = 1;
        return -ENODEV;         /* dummy driver always returns error */
 }
 
 static struct pcie_port_service_driver __initdata dummy_driver = {
         .name           = "pciehp_dummy",
-        .id_table       = port_pci_ids,
+       .port_type      = PCIE_ANY_PORT,
+       .service        = PCIE_PORT_SERVICE_HP,
         .probe          = dummy_probe,
 };
 
 static int __init select_detection_mode(void)
 {
-       struct slot *slot, *tmp;
+       struct dummy_slot *slot, *tmp;
        pcie_port_service_register(&dummy_driver);
        pcie_port_service_unregister(&dummy_driver);
-       list_for_each_entry_safe(slot, tmp, &dummy_slots, slot_list) {
-               list_del(&slot->slot_list);
+       list_for_each_entry_safe(slot, tmp, &dummy_slots, list) {
+               list_del(&slot->list);
                kfree(slot);
        }
        if (acpi_slot_detected && dup_slot_id)