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

(-)linux-2.6.25.orig/drivers/ata/libata-acpi.c (-27 / +97 lines)
Lines 118-125 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_eject_device(acpi_handle handle)
122
{
123
	struct acpi_object_list arg_list;
124
	union acpi_object arg;
125
126
	arg_list.count = 1;
127
	arg_list.pointer = &arg;
128
	arg.type = ACPI_TYPE_INTEGER;
129
	arg.integer.value = 1;
130
131
	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0",
132
					      &arg_list, NULL)))
133
		printk(KERN_ERR "Failed to evaluate _EJ0!\n");
134
}
135
136
static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
137
{
138
	if (dev)
139
		dev->flags |= ATA_DFLAG_DETACH;
140
	else {
141
		struct ata_link *tlink;
142
		struct ata_device *tdev;
143
144
		ata_port_for_each_link(tlink, ap)
145
			ata_link_for_each_dev(tdev, tlink)
146
				tdev->flags |= ATA_DFLAG_DETACH;
147
	}
148
149
	ata_port_freeze(ap);
150
	ata_port_schedule_eh(ap);
151
}
152
121
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
153
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
122
				    u32 event)
154
				    u32 event, int is_dock_event)
123
{
155
{
124
	char event_string[12];
156
	char event_string[12];
125
	char *envp[] = { event_string, NULL };
157
	char *envp[] = { event_string, NULL };
Lines 127-194 Link Here
127
	struct kobject *kobj = NULL;
159
	struct kobject *kobj = NULL;
128
	int wait = 0;
160
	int wait = 0;
129
	unsigned long flags;
161
	unsigned long flags;
162
	acpi_handle handle, tmphandle;
163
	unsigned long sta;
164
	acpi_status status;
130
165
131
	if (!ap)
166
	if (!ap)
132
		ap = dev->link->ap;
167
		ap = dev->link->ap;
133
	ehi = &ap->link.eh_info;
168
	ehi = &ap->link.eh_info;
134
169
170
	if (dev) {
171
		if (dev->sdev)
172
			kobj = &dev->sdev->sdev_gendev.kobj;
173
		handle = dev->acpi_handle;
174
	} else {
175
		kobj = &ap->dev->kobj;
176
		handle = ap->acpi_handle;
177
	}
178
179
	status = acpi_get_handle(handle, "_EJ0", &tmphandle);
180
	if (ACPI_FAILURE(status))
181
		/* This device does not support hotplug */
182
		return;
183
135
	spin_lock_irqsave(ap->lock, flags);
184
	spin_lock_irqsave(ap->lock, flags);
136
185
137
	switch (event) {
186
	switch (event) {
138
	case ACPI_NOTIFY_BUS_CHECK:
187
	case ACPI_NOTIFY_BUS_CHECK:
139
	case ACPI_NOTIFY_DEVICE_CHECK:
188
	case ACPI_NOTIFY_DEVICE_CHECK:
140
		ata_ehi_push_desc(ehi, "ACPI event");
189
		ata_ehi_push_desc(ehi, "ACPI event");
141
		ata_ehi_hotplugged(ehi);
142
		ata_port_freeze(ap);
143
		break;
144
190
191
		status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
192
		if (ACPI_FAILURE(status)) {
193
			printk(KERN_ERR "Unable to determine bay status\n");
194
			break;
195
		}
196
197
		if (sta) {
198
			ata_ehi_hotplugged(ehi);
199
			ata_port_freeze(ap);
200
		} else {
201
			/* The device has gone - unplug it */
202
			ata_acpi_detach_device(ap, dev);
203
			wait = 1;
204
		}
205
		break;
145
	case ACPI_NOTIFY_EJECT_REQUEST:
206
	case ACPI_NOTIFY_EJECT_REQUEST:
146
		ata_ehi_push_desc(ehi, "ACPI event");
207
		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
208
158
		ata_port_schedule_eh(ap);
209
		if (!is_dock_event)
210
			break;
211
212
		/* undock event - immediate unplug */
213
		ata_acpi_detach_device(ap, dev);
159
		wait = 1;
214
		wait = 1;
160
		break;
215
		break;
161
	}
216
	}
162
217
163
	if (dev) {
218
	/* make sure kobj doesn't go away while ap->lock is released */
164
		if (dev->sdev)
219
	kobject_get(kobj);
165
			kobj = &dev->sdev->sdev_gendev.kobj;
166
	} else
167
		kobj = &ap->dev->kobj;
168
220
169
	if (kobj) {
221
	spin_unlock_irqrestore(ap->lock, flags);
222
223
	if (kobj && !is_dock_event) {
170
		sprintf(event_string, "BAY_EVENT=%d", event);
224
		sprintf(event_string, "BAY_EVENT=%d", event);
171
		kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
225
		kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
172
	}
226
	}
173
227
174
	spin_unlock_irqrestore(ap->lock, flags);
228
	kobject_put(kobj);
175
229
176
	if (wait)
230
	if (wait) {
177
		ata_port_wait_eh(ap);
231
		ata_port_wait_eh(ap);
232
		ata_acpi_eject_device(handle);
233
	}
234
}
235
236
static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
237
{
238
	struct ata_device *dev = data;
239
240
	ata_acpi_handle_hotplug(NULL, dev, event, 1);
241
}
242
243
static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
244
{
245
	struct ata_port *ap = data;
246
247
	ata_acpi_handle_hotplug(ap, NULL, event, 1);
178
}
248
}
179
249
180
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
250
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
181
{
251
{
182
	struct ata_device *dev = data;
252
	struct ata_device *dev = data;
183
253
184
	ata_acpi_handle_hotplug(NULL, dev, event);
254
	ata_acpi_handle_hotplug(NULL, dev, event, 0);
185
}
255
}
186
256
187
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
257
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
188
{
258
{
189
	struct ata_port *ap = data;
259
	struct ata_port *ap = data;
190
260
191
	ata_acpi_handle_hotplug(ap, NULL, event);
261
	ata_acpi_handle_hotplug(ap, NULL, event, 0);
192
}
262
}
193
263
194
/**
264
/**
Lines 230-236 Link Here
230
#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
300
#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
231
			/* we might be on a docking station */
301
			/* we might be on a docking station */
232
			register_hotplug_dock_device(ap->acpi_handle,
302
			register_hotplug_dock_device(ap->acpi_handle,
233
						     ata_acpi_ap_notify, ap);
303
					     ata_acpi_ap_notify_dock, ap);
234
#endif
304
#endif
235
		}
305
		}
236
306
Lines 244-250 Link Here
244
#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
314
#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
245
				/* we might be on a docking station */
315
				/* we might be on a docking station */
246
				register_hotplug_dock_device(dev->acpi_handle,
316
				register_hotplug_dock_device(dev->acpi_handle,
247
						ata_acpi_dev_notify, dev);
317
						ata_acpi_dev_notify_dock, dev);
248
#endif
318
#endif
249
			}
319
			}
250
		}
320
		}

Return to bug 395082