|
Lines 118-194
static void ata_acpi_associate_ide_port(struct ata_port *ap)
Link Here
|
| 118 |
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; |
118 |
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; |
| 119 |
} |
119 |
} |
| 120 |
|
120 |
|
|
|
121 |
static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) |
| 122 |
{ |
| 123 |
if (dev) |
| 124 |
dev->flags |= ATA_DFLAG_DETACH; |
| 125 |
else { |
| 126 |
struct ata_link *tlink; |
| 127 |
struct ata_device *tdev; |
| 128 |
|
| 129 |
ata_port_for_each_link(tlink, ap) |
| 130 |
ata_link_for_each_dev(tdev, tlink) |
| 131 |
tdev->flags |= ATA_DFLAG_DETACH; |
| 132 |
} |
| 133 |
|
| 134 |
ata_port_freeze(ap); |
| 135 |
ata_port_schedule_eh(ap); |
| 136 |
} |
| 137 |
|
| 121 |
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, |
138 |
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, |
| 122 |
u32 event) |
139 |
u32 event, int is_dock_event) |
| 123 |
{ |
140 |
{ |
| 124 |
char event_string[12]; |
141 |
char event_string[12]; |
| 125 |
char *envp[] = { event_string, NULL }; |
142 |
char *envp[] = { event_string, NULL }; |
| 126 |
struct ata_eh_info *ehi; |
143 |
struct ata_eh_info *ehi; |
| 127 |
struct kobject *kobj = NULL; |
144 |
struct kobject *kobj = NULL; |
| 128 |
int wait = 0; |
145 |
int wait = 0; |
| 129 |
unsigned long flags; |
146 |
unsigned long flags, sta; |
|
|
147 |
acpi_status status; |
| 148 |
acpi_handle handle; |
| 130 |
|
149 |
|
| 131 |
if (!ap) |
150 |
if (!ap) |
| 132 |
ap = dev->link->ap; |
151 |
ap = dev->link->ap; |
| 133 |
ehi = &ap->link.eh_info; |
152 |
ehi = &ap->link.eh_info; |
| 134 |
|
153 |
|
|
|
154 |
if (dev) { |
| 155 |
if (dev->sdev) |
| 156 |
kobj = &dev->sdev->sdev_gendev.kobj; |
| 157 |
handle = dev->acpi_handle; |
| 158 |
} else { |
| 159 |
kobj = &ap->dev->kobj; |
| 160 |
handle = ap->acpi_handle; |
| 161 |
} |
| 162 |
|
| 163 |
if (kobj) { |
| 164 |
sprintf(event_string, "BAY_EVENT=%d", event); |
| 165 |
kobject_uevent_env(kobj, KOBJ_CHANGE, envp); |
| 166 |
} |
| 167 |
|
| 135 |
spin_lock_irqsave(ap->lock, flags); |
168 |
spin_lock_irqsave(ap->lock, flags); |
| 136 |
|
169 |
|
| 137 |
switch (event) { |
170 |
switch (event) { |
| 138 |
case ACPI_NOTIFY_BUS_CHECK: |
171 |
case ACPI_NOTIFY_BUS_CHECK: |
| 139 |
case ACPI_NOTIFY_DEVICE_CHECK: |
172 |
case ACPI_NOTIFY_DEVICE_CHECK: |
|
|
173 |
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
| 174 |
if (!ACPI_SUCCESS(status)) { |
| 175 |
printk(KERN_INFO "Unable to evaluate bay status\n"); |
| 176 |
break; |
| 177 |
} |
| 178 |
|
| 140 |
ata_ehi_push_desc(ehi, "ACPI event"); |
179 |
ata_ehi_push_desc(ehi, "ACPI event"); |
| 141 |
ata_ehi_hotplugged(ehi); |
|
|
| 142 |
ata_port_freeze(ap); |
| 143 |
break; |
| 144 |
|
180 |
|
|
|
181 |
if (sta) { |
| 182 |
ata_ehi_hotplugged(ehi); |
| 183 |
ata_port_freeze(ap); |
| 184 |
} else { |
| 185 |
/* The device has gone - unplug it */ |
| 186 |
ata_acpi_detach_device(ap, dev); |
| 187 |
wait = 1; |
| 188 |
} |
| 189 |
break; |
| 145 |
case ACPI_NOTIFY_EJECT_REQUEST: |
190 |
case ACPI_NOTIFY_EJECT_REQUEST: |
| 146 |
ata_ehi_push_desc(ehi, "ACPI event"); |
191 |
ata_ehi_push_desc(ehi, "ACPI event"); |
| 147 |
if (dev) |
|
|
| 148 |
dev->flags |= ATA_DFLAG_DETACH; |
| 149 |
else { |
| 150 |
struct ata_link *tlink; |
| 151 |
struct ata_device *tdev; |
| 152 |
|
| 153 |
ata_port_for_each_link(tlink, ap) |
| 154 |
ata_link_for_each_dev(tdev, tlink) |
| 155 |
tdev->flags |= ATA_DFLAG_DETACH; |
| 156 |
} |
| 157 |
|
192 |
|
| 158 |
ata_port_schedule_eh(ap); |
193 |
if (!is_dock_event) |
|
|
194 |
break; |
| 195 |
|
| 196 |
/* undock event - immediate unplug */ |
| 197 |
ata_acpi_detach_device(ap, dev); |
| 159 |
wait = 1; |
198 |
wait = 1; |
| 160 |
break; |
199 |
break; |
| 161 |
} |
200 |
} |
| 162 |
|
201 |
|
| 163 |
if (dev) { |
|
|
| 164 |
if (dev->sdev) |
| 165 |
kobj = &dev->sdev->sdev_gendev.kobj; |
| 166 |
} else |
| 167 |
kobj = &ap->dev->kobj; |
| 168 |
|
| 169 |
if (kobj) { |
| 170 |
sprintf(event_string, "BAY_EVENT=%d", event); |
| 171 |
kobject_uevent_env(kobj, KOBJ_CHANGE, envp); |
| 172 |
} |
| 173 |
|
| 174 |
spin_unlock_irqrestore(ap->lock, flags); |
202 |
spin_unlock_irqrestore(ap->lock, flags); |
| 175 |
|
203 |
|
| 176 |
if (wait) |
204 |
if (wait) |
| 177 |
ata_port_wait_eh(ap); |
205 |
ata_port_wait_eh(ap); |
| 178 |
} |
206 |
} |
| 179 |
|
207 |
|
|
|
208 |
static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) |
| 209 |
{ |
| 210 |
struct ata_device *dev = data; |
| 211 |
|
| 212 |
ata_acpi_handle_hotplug(NULL, dev, event, 1); |
| 213 |
} |
| 214 |
|
| 215 |
static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) |
| 216 |
{ |
| 217 |
struct ata_port *ap = data; |
| 218 |
|
| 219 |
ata_acpi_handle_hotplug(ap, NULL, event, 1); |
| 220 |
} |
| 221 |
|
| 180 |
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) |
222 |
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) |
| 181 |
{ |
223 |
{ |
| 182 |
struct ata_device *dev = data; |
224 |
struct ata_device *dev = data; |
| 183 |
|
225 |
|
| 184 |
ata_acpi_handle_hotplug(NULL, dev, event); |
226 |
ata_acpi_handle_hotplug(NULL, dev, event, 0); |
| 185 |
} |
227 |
} |
| 186 |
|
228 |
|
| 187 |
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) |
229 |
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) |
| 188 |
{ |
230 |
{ |
| 189 |
struct ata_port *ap = data; |
231 |
struct ata_port *ap = data; |
| 190 |
|
232 |
|
| 191 |
ata_acpi_handle_hotplug(ap, NULL, event); |
233 |
ata_acpi_handle_hotplug(ap, NULL, event, 0); |
| 192 |
} |
234 |
} |
| 193 |
|
235 |
|
| 194 |
/** |
236 |
/** |
|
Lines 229-235
void ata_acpi_associate(struct ata_host *host)
Link Here
|
| 229 |
ata_acpi_ap_notify, ap); |
271 |
ata_acpi_ap_notify, ap); |
| 230 |
/* we might be on a docking station */ |
272 |
/* we might be on a docking station */ |
| 231 |
register_hotplug_dock_device(ap->acpi_handle, |
273 |
register_hotplug_dock_device(ap->acpi_handle, |
| 232 |
ata_acpi_ap_notify, ap); |
274 |
ata_acpi_ap_notify_dock, ap); |
| 233 |
} |
275 |
} |
| 234 |
|
276 |
|
| 235 |
for (j = 0; j < ata_link_max_devices(&ap->link); j++) { |
277 |
for (j = 0; j < ata_link_max_devices(&ap->link); j++) { |
|
Lines 241-247
void ata_acpi_associate(struct ata_host *host)
Link Here
|
| 241 |
ata_acpi_dev_notify, dev); |
283 |
ata_acpi_dev_notify, dev); |
| 242 |
/* we might be on a docking station */ |
284 |
/* we might be on a docking station */ |
| 243 |
register_hotplug_dock_device(dev->acpi_handle, |
285 |
register_hotplug_dock_device(dev->acpi_handle, |
| 244 |
ata_acpi_dev_notify, dev); |
286 |
ata_acpi_dev_notify_dock, dev); |
| 245 |
} |
287 |
} |
| 246 |
} |
288 |
} |
| 247 |
} |
289 |
} |