[PATCHv2 7/8] acpi: Prevent duplicate hotplug device registration on dock stations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <holger@xxxxxxxx>
---
 drivers/acpi/dock.c         |   20 ++++++++++++++++++++
 drivers/ata/libata-acpi.c   |    6 ++++--
 include/acpi/acpi_drivers.h |    1 +
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 98cecaf..b5e4142 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -720,6 +720,26 @@ void unregister_hotplug_dock_device(acpi_handle handle)
 }
 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
  *
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 3595ef4..a39f9b3 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -1001,7 +1001,8 @@ static int ata_acpi_bind_host(struct device *dev, int host, acpi_handle *handle)
 	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 device *dev, int channel, int id,
 	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;
 }
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 43f7817..3c4e381 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -131,6 +131,7 @@ extern int register_hotplug_dock_device(acpi_handle handle,
 					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
-- 
1.7.8

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux