Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=237d8440cb2b104a3b97fc971a9bce67960bb616
Commit:     237d8440cb2b104a3b97fc971a9bce67960bb616
Parent:     b3a706014e56b1356e7b275fd25b833c63175bf0
Author:     Matthew Garrett <[EMAIL PROTECTED]>
AuthorDate: Wed Oct 3 01:24:16 2007 +0100
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Fri Oct 12 14:55:45 2007 -0400

    libata: Integrate ACPI-based PATA/SATA hotplug - version 5
    
    Modern laptops with hotswap bays still tend to utilise a PATA interface
    on a SATA bridge, generally with the host controller in some legacy
    emulation mode rather than AHCI. This means that the existing hotplug
    code in libata is unable to work. The ACPI specification states that
    these devices can send notifications when hotswapped, which avoids the
    need to obtain notification from the controller. This patch uses the
    existing libata-acpi code and simply registers a notification in order
    to trigger a rescan whenever the firmware signals an event.
    
    Signed-off-by: Matthew Garrett <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/ata/libata-acpi.c |   60 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index a276c06..5ebbf16 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -14,6 +14,7 @@
 #include <linux/acpi.h>
 #include <linux/libata.h>
 #include <linux/pci.h>
+#include <scsi/scsi_device.h>
 #include "libata.h"
 
 #include <acpi/acpi_bus.h>
@@ -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);
+               }
        }
 }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to