* to resolve PCI information for ACPI-PCI devices defined in the namespace.
* This typically occurs when resolving PCI operation region information.
*/
+#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_os_get_pci_id (
acpi_handle handle,
return_ACPI_STATUS(AE_OK);
}
+#endif /* ACPI_FUTURE_USAGE */
int
acpi_status status = AE_OK;
struct acpi_pci_data *data = NULL;
struct acpi_pci_data *pdata = NULL;
- char pathname[ACPI_PATHNAME_MAX] = {0};
- struct acpi_buffer buffer = {ACPI_PATHNAME_MAX, pathname};
+ char *pathname = NULL;
+ struct acpi_buffer buffer = {0, NULL};
acpi_handle handle = NULL;
ACPI_FUNCTION_TRACE("acpi_pci_bind");
if (!device || !device->parent)
return_VALUE(-EINVAL);
+ pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ if(!pathname)
+ return_VALUE(-ENOMEM);
+ memset(pathname, 0, ACPI_PATHNAME_MAX);
+ buffer.length = ACPI_PATHNAME_MAX;
+ buffer.pointer = pathname;
+
data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
- if (!data)
+ if (!data){
+ kfree (pathname);
return_VALUE(-ENOMEM);
+ }
memset(data, 0, sizeof(struct acpi_pci_data));
acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
data->id.device, data->id.function));
data->bus = data->dev->subordinate;
device->ops.bind = acpi_pci_bind;
+ device->ops.unbind = acpi_pci_unbind;
}
/*
}
end:
+ kfree(pathname);
if (result)
kfree(data);
return_VALUE(result);
}
+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_FUNCTION_TRACE("acpi_pci_unbind");
+
+ if (!device || !device->parent)
+ return_VALUE(-EINVAL);
+
+ pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ if(!pathname)
+ return_VALUE(-ENOMEM);
+ memset(pathname, 0, ACPI_PATHNAME_MAX);
+
+ 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);
+
+ status = acpi_get_data(device->handle, acpi_pci_data_handler, (void**)&data);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to get data from device %s\n",
+ acpi_device_bid(device)));
+ result = -ENODEV;
+ goto end;
+ }
+
+ status = acpi_detach_data(device->handle, acpi_pci_data_handler);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to detach data from device %s\n",
+ acpi_device_bid(device)));
+ result = -ENODEV;
+ goto end;
+ }
+ if (data->dev->subordinate) {
+ acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
+ }
+ kfree(data);
+
+end:
+ return_VALUE(result);
+}
int
acpi_pci_bind_root (
int result = 0;
acpi_status status = AE_OK;
struct acpi_pci_data *data = NULL;
- char pathname[ACPI_PATHNAME_MAX] = {0};
- struct acpi_buffer buffer = {ACPI_PATHNAME_MAX, pathname};
+ char *pathname = NULL;
+ struct acpi_buffer buffer = {0, NULL};
ACPI_FUNCTION_TRACE("acpi_pci_bind_root");
- if (!device || !id || !bus)
+ pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ if(!pathname)
+ return_VALUE(-ENOMEM);
+ memset(pathname, 0, ACPI_PATHNAME_MAX);
+
+ buffer.length = ACPI_PATHNAME_MAX;
+ buffer.pointer = pathname;
+
+ if (!device || !id || !bus){
+ kfree(pathname);
return_VALUE(-EINVAL);
+ }
data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
- if (!data)
+ if (!data){
+ kfree(pathname);
return_VALUE(-ENOMEM);
+ }
memset(data, 0, sizeof(struct acpi_pci_data));
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);
}
end:
+ kfree(pathname);
if (result != 0)
kfree(data);