From linux-scsi Tue Dec 06 16:38:10 2011 From: Holger Macht Date: Tue, 06 Dec 2011 16:38:10 +0000 To: linux-scsi Subject: [PATCH 7/7] acpi: Prevent duplicate hotplug device registration on Message-Id: <20111206163810.GH3629 () homac ! suse ! de> X-MARC-Message: https://marc.info/?l=linux-scsi&m=132318958332269 register_hotplug_dock_device() must only be called once per ACPI handle. However, ACPI glue infrastructure does not allow to prevent multiple find_device() invocations when a scsi bus or device appears or disappears. So export a function from the dock driver to check if a specific hotplug dock device is already registered and call this before registering. Signed-off-by: Holger Macht --- drivers/acpi/dock.c | 20 ++++++++++++++++++++ drivers/ata/libata-acpi.c | 6 ++++-- include/acpi/acpi_drivers.h | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) Index: linux/drivers/acpi/dock.c =================================================================== --- linux.orig/drivers/acpi/dock.c +++ linux/drivers/acpi/dock.c @@ -720,6 +720,26 @@ void unregister_hotplug_dock_device(acpi } EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); +int is_registered_hotplug_dock_device(const struct acpi_dock_ops *ops) +{ + struct dock_dependent_device *dd; + struct dock_station *ds; + + list_for_each_entry(ds, &dock_stations, sibling) { + mutex_lock(&ds->hp_lock); + list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) { + if (ops == dd->ops) { + mutex_unlock(&ds->hp_lock); + return 1; + } + } + mutex_unlock(&ds->hp_lock); + } + + return 0; +} +EXPORT_SYMBOL(is_registered_hotplug_dock_device); + /** * handle_eject_request - handle an undock request checking for error conditions * Index: linux/drivers/ata/libata-acpi.c =================================================================== --- linux.orig/drivers/ata/libata-acpi.c +++ linux/drivers/ata/libata-acpi.c @@ -1001,7 +1001,8 @@ static int ata_acpi_bind_host(struct dev if (!*handle) return -ENODEV; - register_hotplug_dock_device(*handle, &ata_acpi_ap_dock_ops, ap); + if (!is_registered_hotplug_dock_device(&ata_acpi_ap_dock_ops)) + register_hotplug_dock_device(*handle, &ata_acpi_ap_dock_ops, ap); return 0; } @@ -1024,7 +1025,8 @@ static int ata_acpi_bind_device(struct d if (!*handle) return -ENODEV; - register_hotplug_dock_device(*handle, &ata_acpi_dev_dock_ops, ata_dev); + if (!is_registered_hotplug_dock_device(&ata_acpi_dev_dock_ops)) + register_hotplug_dock_device(*handle, &ata_acpi_dev_dock_ops, ata_dev); return 0; } Index: linux/include/acpi/acpi_drivers.h =================================================================== --- linux.orig/include/acpi/acpi_drivers.h +++ linux/include/acpi/acpi_drivers.h @@ -131,6 +131,7 @@ extern int register_hotplug_dock_device( const struct acpi_dock_ops *ops, void *context); extern void unregister_hotplug_dock_device(acpi_handle handle); +extern int is_registered_hotplug_dock_device(const struct acpi_dock_ops *ops); extern struct device **dock_link_device(acpi_handle handle); extern struct device **dock_unlink_device(acpi_handle handle); #else -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html