Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[sfrench/cifs-2.6.git] / drivers / acpi / pci_bind.c
index 388300de005d37df692f142649e0e1a1ab75d9c0..bc46de3d967f62904962e06bf9beef26095a9a78 100644 (file)
@@ -44,6 +44,8 @@ struct acpi_pci_data {
        struct pci_dev *dev;
 };
 
+static int acpi_pci_unbind(struct acpi_device *device);
+
 static void acpi_pci_data_handler(acpi_handle handle, u32 function,
                                  void *context)
 {
@@ -97,7 +99,7 @@ acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id)
         */
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                         "Device %s has PCI address %02x:%02x:%02x.%02x\n",
+                         "Device %s has PCI address %04x:%02x:%02x.%d\n",
                          acpi_device_bid(device), id->segment, id->bus,
                          id->device, id->function));
 
@@ -109,34 +111,27 @@ EXPORT_SYMBOL(acpi_get_pci_id);
 int acpi_pci_bind(struct acpi_device *device)
 {
        int result = 0;
-       acpi_status status = AE_OK;
-       struct acpi_pci_data *data = NULL;
-       struct acpi_pci_data *pdata = NULL;
-       char *pathname = NULL;
-       struct acpi_buffer buffer = { 0, NULL };
-       acpi_handle handle = NULL;
-       struct pci_dev *dev;
-       struct pci_bus *bus;
-
+       acpi_status status;
+       struct acpi_pci_data *data;
+       struct acpi_pci_data *pdata;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       acpi_handle handle;
 
        if (!device || !device->parent)
                return -EINVAL;
 
-       pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
-       if (!pathname)
-               return -ENOMEM;
-       buffer.length = ACPI_PATHNAME_MAX;
-       buffer.pointer = pathname;
-
        data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
-       if (!data) {
-               kfree(pathname);
+       if (!data)
                return -ENOMEM;
+
+       status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+       if (ACPI_FAILURE(status)) {
+               kfree(data);
+               return -ENODEV;
        }
 
-       acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
-                         pathname));
+                         (char *)buffer.pointer));
 
        /* 
         * Segment & Bus
@@ -164,7 +159,7 @@ int acpi_pci_bind(struct acpi_device *device)
        data->id.device = device->pnp.bus_address >> 16;
        data->id.function = device->pnp.bus_address & 0xFFFF;
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n",
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n",
                          data->id.segment, data->id.bus, data->id.device,
                          data->id.function));
 
@@ -178,23 +173,12 @@ int acpi_pci_bind(struct acpi_device *device)
         * Locate matching device in PCI namespace.  If it doesn't exist
         * this typically means that the device isn't currently inserted
         * (e.g. docking station, port replicator, etc.).
-        * We cannot simply search the global pci device list, since
-        * PCI devices are added to the global pci list when the root
-        * bridge start ops are run, which may not have happened yet.
         */
-       bus = pci_find_bus(data->id.segment, data->id.bus);
-       if (bus) {
-               list_for_each_entry(dev, &bus->devices, bus_list) {
-                       if (dev->devfn == PCI_DEVFN(data->id.device,
-                                                   data->id.function)) {
-                               data->dev = dev;
-                               break;
-                       }
-               }
-       }
+       data->dev = pci_get_slot(pdata->bus,
+                               PCI_DEVFN(data->id.device, data->id.function));
        if (!data->dev) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
+                                 "Device %04x:%02x:%02x.%d not present in PCI namespace\n",
                                  data->id.segment, data->id.bus,
                                  data->id.device, data->id.function));
                result = -ENODEV;
@@ -202,7 +186,7 @@ int acpi_pci_bind(struct acpi_device *device)
        }
        if (!data->dev->bus) {
                printk(KERN_ERR PREFIX
-                           "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n",
+                           "Device %04x:%02x:%02x.%d has invalid 'bus' field\n",
                            data->id.segment, data->id.bus,
                            data->id.device, data->id.function);
                result = -ENODEV;
@@ -217,7 +201,7 @@ int acpi_pci_bind(struct acpi_device *device)
         */
        if (data->dev->subordinate) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Device %02x:%02x:%02x.%02x is a PCI bridge\n",
+                                 "Device %04x:%02x:%02x.%d is a PCI bridge\n",
                                  data->id.segment, data->id.bus,
                                  data->id.device, data->id.function));
                data->bus = data->dev->subordinate;
@@ -260,35 +244,32 @@ int acpi_pci_bind(struct acpi_device *device)
        }
 
       end:
-       kfree(pathname);
-       if (result)
+       kfree(buffer.pointer);
+       if (result) {
+               pci_dev_put(data->dev);
                kfree(data);
-
+       }
        return result;
 }
 
-int acpi_pci_unbind(struct acpi_device *device)
+static int acpi_pci_unbind(struct acpi_device *device)
 {
        int result = 0;
-       acpi_status status = AE_OK;
-       struct acpi_pci_data *data = NULL;
-       char *pathname = NULL;
-       struct acpi_buffer buffer = { 0, NULL };
+       acpi_status status;
+       struct acpi_pci_data *data;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
 
        if (!device || !device->parent)
                return -EINVAL;
 
-       pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
-       if (!pathname)
-               return -ENOMEM;
+       status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
 
-       buffer.length = ACPI_PATHNAME_MAX;
-       buffer.pointer = pathname;
-       acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n",
-                         pathname));
-       kfree(pathname);
+                         (char *) buffer.pointer));
+       kfree(buffer.pointer);
 
        status =
            acpi_get_data(device->handle, acpi_pci_data_handler,
@@ -309,6 +290,7 @@ int acpi_pci_unbind(struct acpi_device *device)
        if (data->dev->subordinate) {
                acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
        }
+       pci_dev_put(data->dev);
        kfree(data);
 
       end:
@@ -320,50 +302,44 @@ acpi_pci_bind_root(struct acpi_device *device,
                   struct acpi_pci_id *id, struct pci_bus *bus)
 {
        int result = 0;
-       acpi_status status = AE_OK;
+       acpi_status status;
        struct acpi_pci_data *data = NULL;
-       char *pathname = NULL;
-       struct acpi_buffer buffer = { 0, NULL };
-
-       pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
-       if (!pathname)
-               return -ENOMEM;
-
-       buffer.length = ACPI_PATHNAME_MAX;
-       buffer.pointer = pathname;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
        if (!device || !id || !bus) {
-               kfree(pathname);
                return -EINVAL;
        }
 
        data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
-       if (!data) {
-               kfree(pathname);
+       if (!data)
                return -ENOMEM;
-       }
 
        data->id = *id;
        data->bus = bus;
        device->ops.bind = acpi_pci_bind;
        device->ops.unbind = acpi_pci_unbind;
 
-       acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+       status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+       if (ACPI_FAILURE(status)) {
+               kfree (data);
+               return -ENODEV;
+       }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to "
-                         "%02x:%02x\n", pathname, id->segment, id->bus));
+                       "%04x:%02x\n", (char *)buffer.pointer,
+                       id->segment, id->bus));
 
        status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status,
                                "Unable to attach ACPI-PCI context to device %s",
-                               pathname));
+                               (char *)buffer.pointer));
                result = -ENODEV;
                goto end;
        }
 
       end:
-       kfree(pathname);
+       kfree(buffer.pointer);
        if (result != 0)
                kfree(data);