include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / acpi / pci_slot.c
index b9ab030..07f7fea 100644 (file)
@@ -6,8 +6,8 @@
  *  Thanks to Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> for code
  *  review and fixes.
  *
- *  Copyright (C) 2007 Alex Chiang <achiang@hp.com>
- *  Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
+ *  Copyright (C) 2007-2008 Hewlett-Packard Development Company, L.P.
+ *     Alex Chiang <achiang@hp.com>
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms and conditions of the GNU General Public License,
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+#include <linux/dmi.h>
 
 static int debug;
 static int check_sta_before_sun;
@@ -57,7 +59,7 @@ ACPI_MODULE_NAME("pci_slot");
                                MY_NAME , ## arg);              \
        } while (0)
 
-#define SLOT_NAME_SIZE 20              /* Inspired by #define in acpiphp.h */
+#define SLOT_NAME_SIZE 21              /* Inspired by #define in acpiphp.h */
 
 struct acpi_pci_slot {
        acpi_handle root_handle;        /* handle of the root bridge */
@@ -76,10 +78,10 @@ static struct acpi_pci_driver acpi_pci_slot_driver = {
 };
 
 static int
-check_slot(acpi_handle handle, int *device, unsigned long *sun)
+check_slot(acpi_handle handle, unsigned long long *sun)
 {
-       int retval = 0;
-       unsigned long adr, sta;
+       int device = -1;
+       unsigned long long adr, sta;
        acpi_status status;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
@@ -89,32 +91,27 @@ check_slot(acpi_handle handle, int *device, unsigned long *sun)
        if (check_sta_before_sun) {
                /* If SxFy doesn't have _STA, we just assume it's there */
                status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-               if (ACPI_SUCCESS(status) && !(sta & ACPI_STA_DEVICE_PRESENT)) {
-                       retval = -1;
+               if (ACPI_SUCCESS(status) && !(sta & ACPI_STA_DEVICE_PRESENT))
                        goto out;
-               }
        }
 
        status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
        if (ACPI_FAILURE(status)) {
                dbg("_ADR returned %d on %s\n", status, (char *)buffer.pointer);
-               retval = -1;
                goto out;
        }
 
-       *device = (adr >> 16) & 0xffff;
-
        /* No _SUN == not a slot == bail */
        status = acpi_evaluate_integer(handle, "_SUN", NULL, sun);
        if (ACPI_FAILURE(status)) {
                dbg("_SUN returned %d on %s\n", status, (char *)buffer.pointer);
-               retval = -1;
                goto out;
        }
 
+       device = (adr >> 16) & 0xffff;
 out:
        kfree(buffer.pointer);
-       return retval;
+       return device;
 }
 
 struct callback_args {
@@ -137,14 +134,15 @@ static acpi_status
 register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        int device;
-       unsigned long sun;
+       unsigned long long sun;
        char name[SLOT_NAME_SIZE];
        struct acpi_pci_slot *slot;
        struct pci_slot *pci_slot;
        struct callback_args *parent_context = context;
        struct pci_bus *pci_bus = parent_context->pci_bus;
 
-       if (check_slot(handle, &device, &sun))
+       device = check_slot(handle, &sun);
+       if (device < 0)
                return AE_OK;
 
        slot = kmalloc(sizeof(*slot), GFP_KERNEL);
@@ -153,11 +151,12 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
                return AE_OK;
        }
 
-       snprintf(name, sizeof(name), "%u", (u32)sun);
-       pci_slot = pci_create_slot(pci_bus, device, name);
+       snprintf(name, sizeof(name), "%llu", sun);
+       pci_slot = pci_create_slot(pci_bus, device, name, NULL);
        if (IS_ERR(pci_slot)) {
                err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
                kfree(slot);
+               return AE_OK;
        }
 
        slot->root_handle = parent_context->root_handle;
@@ -167,6 +166,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
        list_add(&slot->list, &slot_list);
        mutex_unlock(&slot_list_lock);
 
+       get_device(&pci_bus->dev);
+
        dbg("pci_slot: %p, pci_bus: %x, device: %d, name: %s\n",
                pci_slot, pci_bus->number, device, name);
 
@@ -185,7 +186,7 @@ static acpi_status
 walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        int device, function;
-       unsigned long adr;
+       unsigned long long adr;
        acpi_status status;
        acpi_handle dummy_handle;
        acpi_walk_callback user_function;
@@ -219,12 +220,12 @@ walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 
        dbg("p2p bridge walk, pci_bus = %x\n", dev->subordinate->number);
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-                                    user_function, &child_context, NULL);
+                                    user_function, NULL, &child_context, NULL);
        if (ACPI_FAILURE(status))
                goto out;
 
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-                                    walk_p2p_bridge, &child_context, NULL);
+                                    walk_p2p_bridge, NULL, &child_context, NULL);
 out:
        pci_dev_put(dev);
        return AE_OK;
@@ -242,7 +243,7 @@ static int
 walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function)
 {
        int seg, bus;
-       unsigned long tmp;
+       unsigned long long tmp;
        acpi_status status;
        acpi_handle dummy_handle;
        struct pci_bus *pci_bus;
@@ -277,12 +278,12 @@ walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function)
 
        dbg("root bridge walk, pci_bus = %x\n", pci_bus->number);
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-                                    user_function, &context, NULL);
+                                    user_function, NULL, &context, NULL);
        if (ACPI_FAILURE(status))
                return status;
 
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-                                    walk_p2p_bridge, &context, NULL);
+                                    walk_p2p_bridge, NULL, &context, NULL);
        if (ACPI_FAILURE(status))
                err("%s: walk_p2p_bridge failure - %d\n", __func__, status);
 
@@ -313,12 +314,15 @@ static void
 acpi_pci_slot_remove(acpi_handle handle)
 {
        struct acpi_pci_slot *slot, *tmp;
+       struct pci_bus *pbus;
 
        mutex_lock(&slot_list_lock);
        list_for_each_entry_safe(slot, tmp, &slot_list, list) {
                if (slot->root_handle == handle) {
                        list_del(&slot->list);
+                       pbus = slot->pci_slot->bus;
                        pci_destroy_slot(slot->pci_slot);
+                       put_device(&pbus->dev);
                        kfree(slot);
                }
        }