aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-acpi.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index a276c06dda95..5ebbf16f3af1 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -14,6 +14,7 @@
14#include <linux/acpi.h> 14#include <linux/acpi.h>
15#include <linux/libata.h> 15#include <linux/libata.h>
16#include <linux/pci.h> 16#include <linux/pci.h>
17#include <scsi/scsi_device.h>
17#include "libata.h" 18#include "libata.h"
18 19
19#include <acpi/acpi_bus.h> 20#include <acpi/acpi_bus.h>
@@ -95,6 +96,47 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
95 } 96 }
96} 97}
97 98
99static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj,
100 u32 event)
101{
102 char event_string[12];
103 char *envp[] = { event_string, NULL };
104 struct ata_eh_info *ehi = &ap->link.eh_info;
105
106 if (event == 0 || event == 1) {
107 unsigned long flags;
108 spin_lock_irqsave(ap->lock, flags);
109 ata_ehi_clear_desc(ehi);
110 ata_ehi_push_desc(ehi, "ACPI event");
111 ata_ehi_hotplugged(ehi);
112 ata_port_freeze(ap);
113 spin_unlock_irqrestore(ap->lock, flags);
114 }
115
116 if (kobj) {
117 sprintf(event_string, "BAY_EVENT=%d", event);
118 kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
119 }
120}
121
122static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
123{
124 struct ata_device *dev = data;
125 struct kobject *kobj = NULL;
126
127 if (dev->sdev)
128 kobj = &dev->sdev->sdev_gendev.kobj;
129
130 ata_acpi_handle_hotplug (dev->link->ap, kobj, event);
131}
132
133static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
134{
135 struct ata_port *ap = data;
136
137 ata_acpi_handle_hotplug (ap, &ap->dev->kobj, event);
138}
139
98/** 140/**
99 * ata_acpi_associate - associate ATA host with ACPI objects 141 * ata_acpi_associate - associate ATA host with ACPI objects
100 * @host: target ATA host 142 * @host: target ATA host
@@ -110,7 +152,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
110 */ 152 */
111void ata_acpi_associate(struct ata_host *host) 153void ata_acpi_associate(struct ata_host *host)
112{ 154{
113 int i; 155 int i, j;
114 156
115 if (!is_pci_dev(host->dev) || libata_noacpi) 157 if (!is_pci_dev(host->dev) || libata_noacpi)
116 return; 158 return;
@@ -126,6 +168,22 @@ void ata_acpi_associate(struct ata_host *host)
126 ata_acpi_associate_sata_port(ap); 168 ata_acpi_associate_sata_port(ap);
127 else 169 else
128 ata_acpi_associate_ide_port(ap); 170 ata_acpi_associate_ide_port(ap);
171
172 if (ap->acpi_handle)
173 acpi_install_notify_handler (ap->acpi_handle,
174 ACPI_SYSTEM_NOTIFY,
175 ata_acpi_ap_notify,
176 ap);
177
178 for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
179 struct ata_device *dev = &ap->link.device[j];
180
181 if (dev->acpi_handle)
182 acpi_install_notify_handler (dev->acpi_handle,
183 ACPI_SYSTEM_NOTIFY,
184 ata_acpi_dev_notify,
185 dev);
186 }
129 } 187 }
130} 188}
131 189