From fa9395add2f8657775949185fb04c37c6154bc34 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 3 Oct 2007 01:24:16 +0100 Subject: [PATCH] --- yaml --- r: 68148 b: refs/heads/master c: 237d8440cb2b104a3b97fc971a9bce67960bb616 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/ata/libata-acpi.c | 60 ++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 568bc6d47511..e1c68205cbd1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b3a706014e56b1356e7b275fd25b833c63175bf0 +refs/heads/master: 237d8440cb2b104a3b97fc971a9bce67960bb616 diff --git a/trunk/drivers/ata/libata-acpi.c b/trunk/drivers/ata/libata-acpi.c index a276c06dda95..5ebbf16f3af1 100644 --- a/trunk/drivers/ata/libata-acpi.c +++ b/trunk/drivers/ata/libata-acpi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "libata.h" #include @@ -95,6 +96,47 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) } } +static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj, + u32 event) +{ + char event_string[12]; + char *envp[] = { event_string, NULL }; + struct ata_eh_info *ehi = &ap->link.eh_info; + + if (event == 0 || event == 1) { + unsigned long flags; + spin_lock_irqsave(ap->lock, flags); + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "ACPI event"); + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); + spin_unlock_irqrestore(ap->lock, flags); + } + + if (kobj) { + sprintf(event_string, "BAY_EVENT=%d", event); + kobject_uevent_env(kobj, KOBJ_CHANGE, envp); + } +} + +static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_device *dev = data; + struct kobject *kobj = NULL; + + if (dev->sdev) + kobj = &dev->sdev->sdev_gendev.kobj; + + ata_acpi_handle_hotplug (dev->link->ap, kobj, event); +} + +static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_port *ap = data; + + ata_acpi_handle_hotplug (ap, &ap->dev->kobj, event); +} + /** * ata_acpi_associate - associate ATA host with ACPI objects * @host: target ATA host @@ -110,7 +152,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) */ void ata_acpi_associate(struct ata_host *host) { - int i; + int i, j; if (!is_pci_dev(host->dev) || libata_noacpi) return; @@ -126,6 +168,22 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_associate_sata_port(ap); else ata_acpi_associate_ide_port(ap); + + if (ap->acpi_handle) + acpi_install_notify_handler (ap->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_ap_notify, + ap); + + for (j = 0; j < ata_link_max_devices(&ap->link); j++) { + struct ata_device *dev = &ap->link.device[j]; + + if (dev->acpi_handle) + acpi_install_notify_handler (dev->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_dev_notify, + dev); + } } }