View | Details | Raw Unified | Return to bug 390822
Collapse All | Expand All

(-)a/drivers/ata/libata-acpi.c (-31 / +73 lines)
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
	}

Return to bug 390822