Blame view

drivers/ata/libata-acpi.c 24.7 KB
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
1
2
3
4
5
6
7
  /*
   * libata-acpi.c
   * Provides ACPI support for PATA/SATA.
   *
   * Copyright (C) 2006 Intel Corp.
   * Copyright (C) 2006 Randy Dunlap
   */
3264a8d8f   Tejun Heo   libata-acpi: impl...
8
  #include <linux/module.h>
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
9
10
11
12
13
14
15
16
  #include <linux/ata.h>
  #include <linux/delay.h>
  #include <linux/device.h>
  #include <linux/errno.h>
  #include <linux/kernel.h>
  #include <linux/acpi.h>
  #include <linux/libata.h>
  #include <linux/pci.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
17
  #include <linux/slab.h>
237d8440c   Matthew Garrett   libata: Integrate...
18
  #include <scsi/scsi_device.h>
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
19
20
21
  #include "libata.h"
  
  #include <acpi/acpi_bus.h>
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
22

110f66d25   Tejun Heo   libata: make gtf_...
23
  unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
3264a8d8f   Tejun Heo   libata-acpi: impl...
24
  module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644);
fa5b561c4   Tejun Heo   libata: implement...
25
  MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM, 0x8=FPDMA non-zero offset, 0x10=FPDMA DMA Setup FIS auto-activate)");
3264a8d8f   Tejun Heo   libata-acpi: impl...
26

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
27
  #define NO_PORT_MULT		0xffff
2dcb407e6   Jeff Garzik   [libata] checkpat...
28
  #define SATA_ADR(root, pmp)	(((root) << 16) | (pmp))
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
29
30
  
  #define REGS_PER_GTF		7
4700c4bc9   Tejun Heo   libata-acpi: clea...
31
32
33
  struct ata_acpi_gtf {
  	u8	tf[REGS_PER_GTF];	/* regs. 0x1f1 - 0x1f7 */
  } __packed;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
34

ca4266359   Alan Cox   [PATCH] libata-ac...
35
36
37
38
39
40
41
  /*
   *	Helper - belongs in the PCI layer somewhere eventually
   */
  static int is_pci_dev(struct device *dev)
  {
  	return (dev->bus == &pci_bus_type);
  }
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
42

398e07826   Tejun Heo   libata-acpi: impl...
43
44
45
46
47
  static void ata_acpi_clear_gtf(struct ata_device *dev)
  {
  	kfree(dev->gtf_cache);
  	dev->gtf_cache = NULL;
  }
d0df8b5d0   Tejun Heo   libata-pmp: exten...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  /**
   * ata_acpi_associate_sata_port - associate SATA port with ACPI objects
   * @ap: target SATA port
   *
   * Look up ACPI objects associated with @ap and initialize acpi_handle
   * fields of @ap, the port and devices accordingly.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * 0 on success, -errno on failure.
   */
  void ata_acpi_associate_sata_port(struct ata_port *ap)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
62
  {
d0df8b5d0   Tejun Heo   libata-pmp: exten...
63
  	WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA));
071f44b1d   Tejun Heo   libata: implement...
64
  	if (!sata_pmp_attached(ap)) {
439913fff   Lin Ming   ACPI: replace acp...
65
  		u64 adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
d0df8b5d0   Tejun Heo   libata-pmp: exten...
66
67
68
69
70
71
72
  
  		ap->link.device->acpi_handle =
  			acpi_get_child(ap->host->acpi_handle, adr);
  	} else {
  		struct ata_link *link;
  
  		ap->link.device->acpi_handle = NULL;
1eca4365b   Tejun Heo   libata: beef up i...
73
  		ata_for_each_link(link, ap, EDGE) {
439913fff   Lin Ming   ACPI: replace acp...
74
  			u64 adr = SATA_ADR(ap->port_no, link->pmp);
fafbae87d   Tejun Heo   libata-acpi: impl...
75

d0df8b5d0   Tejun Heo   libata-pmp: exten...
76
77
78
79
  			link->device->acpi_handle =
  				acpi_get_child(ap->host->acpi_handle, adr);
  		}
  	}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
80
  }
fafbae87d   Tejun Heo   libata-acpi: impl...
81
  static void ata_acpi_associate_ide_port(struct ata_port *ap)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
82
  {
fafbae87d   Tejun Heo   libata-acpi: impl...
83
  	int max_devices, i;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
84

fafbae87d   Tejun Heo   libata-acpi: impl...
85
86
87
  	ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no);
  	if (!ap->acpi_handle)
  		return;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
88

fafbae87d   Tejun Heo   libata-acpi: impl...
89
90
91
  	max_devices = 1;
  	if (ap->flags & ATA_FLAG_SLAVE_POSS)
  		max_devices++;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
92

fafbae87d   Tejun Heo   libata-acpi: impl...
93
  	for (i = 0; i < max_devices; i++) {
9af5c9c97   Tejun Heo   libata-link: intr...
94
  		struct ata_device *dev = &ap->link.device[i];
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
95

fafbae87d   Tejun Heo   libata-acpi: impl...
96
  		dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
97
  	}
c05e6ff03   Tejun Heo   libata-acpi: impl...
98
99
100
  
  	if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
  		ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
101
  }
664d080c4   Holger Macht   [libata] ACPI: Pr...
102
103
104
105
106
107
108
109
  /* @ap and @dev are the same as ata_acpi_handle_hotplug() */
  static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
  {
  	if (dev)
  		dev->flags |= ATA_DFLAG_DETACH;
  	else {
  		struct ata_link *tlink;
  		struct ata_device *tdev;
1eca4365b   Tejun Heo   libata: beef up i...
110
111
  		ata_for_each_link(tlink, ap, EDGE)
  			ata_for_each_dev(tdev, tlink, ALL)
664d080c4   Holger Macht   [libata] ACPI: Pr...
112
113
114
115
116
117
118
119
120
121
122
  				tdev->flags |= ATA_DFLAG_DETACH;
  	}
  
  	ata_port_schedule_eh(ap);
  }
  
  /**
   * ata_acpi_handle_hotplug - ACPI event handler backend
   * @ap: ATA port ACPI event occurred
   * @dev: ATA device ACPI event occurred (can be NULL)
   * @event: ACPI event which occurred
664d080c4   Holger Macht   [libata] ACPI: Pr...
123
124
125
126
127
128
129
130
131
132
133
134
135
   *
   * All ACPI bay / device realted events end up in this function.  If
   * the event is port-wide @dev is NULL.  If the event is specific to a
   * device, @dev points to it.
   *
   * Hotplug (as opposed to unplug) notification is always handled as
   * port-wide while unplug only kills the target device on device-wide
   * event.
   *
   * LOCKING:
   * ACPI notify handler context.  May sleep.
   */
  static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
f730ae183   Shaohua Li   libata: remove fu...
136
  				    u32 event)
237d8440c   Matthew Garrett   libata: Integrate...
137
  {
664d080c4   Holger Macht   [libata] ACPI: Pr...
138
  	struct ata_eh_info *ehi = &ap->link.eh_info;
233f11204   Tejun Heo   libata-acpi: impr...
139
140
  	int wait = 0;
  	unsigned long flags;
3c1e38963   Zhang Rui   libata-acpi: don'...
141

664d080c4   Holger Macht   [libata] ACPI: Pr...
142
  	spin_lock_irqsave(ap->lock, flags);
f730ae183   Shaohua Li   libata: remove fu...
143
144
145
146
147
  	/*
  	 * When dock driver calls into the routine, it will always use
  	 * ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
  	 * ACPI_NOTIFY_EJECT_REQUEST for remove
  	 */
233f11204   Tejun Heo   libata-acpi: impr...
148
149
150
151
  	switch (event) {
  	case ACPI_NOTIFY_BUS_CHECK:
  	case ACPI_NOTIFY_DEVICE_CHECK:
  		ata_ehi_push_desc(ehi, "ACPI event");
664d080c4   Holger Macht   [libata] ACPI: Pr...
152

f730ae183   Shaohua Li   libata: remove fu...
153
154
  		ata_ehi_hotplugged(ehi);
  		ata_port_freeze(ap);
664d080c4   Holger Macht   [libata] ACPI: Pr...
155
156
157
  		break;
  	case ACPI_NOTIFY_EJECT_REQUEST:
  		ata_ehi_push_desc(ehi, "ACPI event");
664d080c4   Holger Macht   [libata] ACPI: Pr...
158
159
160
  		ata_acpi_detach_device(ap, dev);
  		wait = 1;
  		break;
237d8440c   Matthew Garrett   libata: Integrate...
161
  	}
ae6c23c4e   Matthew Garrett   Fixups to ATA ACP...
162
  	spin_unlock_irqrestore(ap->lock, flags);
f730ae183   Shaohua Li   libata: remove fu...
163
  	if (wait)
ae6c23c4e   Matthew Garrett   Fixups to ATA ACP...
164
  		ata_port_wait_eh(ap);
664d080c4   Holger Macht   [libata] ACPI: Pr...
165
166
167
168
169
  }
  
  static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
  {
  	struct ata_device *dev = data;
f730ae183   Shaohua Li   libata: remove fu...
170
  	ata_acpi_handle_hotplug(dev->link->ap, dev, event);
664d080c4   Holger Macht   [libata] ACPI: Pr...
171
172
173
174
175
  }
  
  static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
  {
  	struct ata_port *ap = data;
f730ae183   Shaohua Li   libata: remove fu...
176
  	ata_acpi_handle_hotplug(ap, NULL, event);
237d8440c   Matthew Garrett   libata: Integrate...
177
  }
1253f7aab   Shaohua Li   dock: introduce ....
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
  static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
  	u32 event)
  {
  	struct kobject *kobj = NULL;
  	char event_string[20];
  	char *envp[] = { event_string, NULL };
  
  	if (dev) {
  		if (dev->sdev)
  			kobj = &dev->sdev->sdev_gendev.kobj;
  	} else
  		kobj = &ap->dev->kobj;
  
  	if (kobj) {
  		snprintf(event_string, 20, "BAY_EVENT=%d", event);
  		kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
  	}
  }
  
  static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data)
  {
  	ata_acpi_uevent(data, NULL, event);
  }
  
  static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data)
  {
  	struct ata_device *dev = data;
  	ata_acpi_uevent(dev->link->ap, dev, event);
  }
9c8b04be4   Vasiliy Kulikov   ACPI: constify op...
207
  static const struct acpi_dock_ops ata_acpi_dev_dock_ops = {
1253f7aab   Shaohua Li   dock: introduce ....
208
209
210
  	.handler = ata_acpi_dev_notify_dock,
  	.uevent = ata_acpi_dev_uevent,
  };
9c8b04be4   Vasiliy Kulikov   ACPI: constify op...
211
  static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
1253f7aab   Shaohua Li   dock: introduce ....
212
213
214
  	.handler = ata_acpi_ap_notify_dock,
  	.uevent = ata_acpi_ap_uevent,
  };
fafbae87d   Tejun Heo   libata-acpi: impl...
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  /**
   * ata_acpi_associate - associate ATA host with ACPI objects
   * @host: target ATA host
   *
   * Look up ACPI objects associated with @host and initialize
   * acpi_handle fields of @host, its ports and devices accordingly.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * 0 on success, -errno on failure.
   */
  void ata_acpi_associate(struct ata_host *host)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
229
  {
237d8440c   Matthew Garrett   libata: Integrate...
230
  	int i, j;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
231

fafbae87d   Tejun Heo   libata-acpi: impl...
232
233
  	if (!is_pci_dev(host->dev) || libata_noacpi)
  		return;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
234

fafbae87d   Tejun Heo   libata-acpi: impl...
235
236
237
  	host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev);
  	if (!host->acpi_handle)
  		return;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
238

fafbae87d   Tejun Heo   libata-acpi: impl...
239
240
241
242
243
244
245
  	for (i = 0; i < host->n_ports; i++) {
  		struct ata_port *ap = host->ports[i];
  
  		if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA)
  			ata_acpi_associate_sata_port(ap);
  		else
  			ata_acpi_associate_ide_port(ap);
237d8440c   Matthew Garrett   libata: Integrate...
246

233f11204   Tejun Heo   libata-acpi: impr...
247
  		if (ap->acpi_handle) {
233f11204   Tejun Heo   libata-acpi: impr...
248
249
  			/* we might be on a docking station */
  			register_hotplug_dock_device(ap->acpi_handle,
1253f7aab   Shaohua Li   dock: introduce ....
250
  					     &ata_acpi_ap_dock_ops, ap);
233f11204   Tejun Heo   libata-acpi: impr...
251
  		}
237d8440c   Matthew Garrett   libata: Integrate...
252
253
254
  
  		for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
  			struct ata_device *dev = &ap->link.device[j];
233f11204   Tejun Heo   libata-acpi: impr...
255
  			if (dev->acpi_handle) {
233f11204   Tejun Heo   libata-acpi: impr...
256
257
  				/* we might be on a docking station */
  				register_hotplug_dock_device(dev->acpi_handle,
1253f7aab   Shaohua Li   dock: introduce ....
258
  					     &ata_acpi_dev_dock_ops, dev);
233f11204   Tejun Heo   libata-acpi: impr...
259
  			}
237d8440c   Matthew Garrett   libata: Integrate...
260
  		}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
261
  	}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
262
263
264
  }
  
  /**
562f0c2d7   Tejun Heo   libata-acpi: add ...
265
266
267
268
269
270
271
272
273
274
275
   * ata_acpi_dissociate - dissociate ATA host from ACPI objects
   * @host: target ATA host
   *
   * This function is called during driver detach after the whole host
   * is shut down.
   *
   * LOCKING:
   * EH context.
   */
  void ata_acpi_dissociate(struct ata_host *host)
  {
c05e6ff03   Tejun Heo   libata-acpi: impl...
276
277
278
279
280
281
282
283
284
285
286
287
  	int i;
  
  	/* Restore initial _GTM values so that driver which attaches
  	 * afterward can use them too.
  	 */
  	for (i = 0; i < host->n_ports; i++) {
  		struct ata_port *ap = host->ports[i];
  		const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
  
  		if (ap->acpi_handle && gtm)
  			ata_acpi_stm(ap, gtm);
  	}
562f0c2d7   Tejun Heo   libata-acpi: add ...
288
289
290
  }
  
  /**
64578a3de   Tejun Heo   libata-acpi: impl...
291
292
293
294
295
296
297
298
299
300
301
302
   * ata_acpi_gtm - execute _GTM
   * @ap: target ATA port
   * @gtm: out parameter for _GTM result
   *
   * Evaluate _GTM and store the result in @gtm.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
   */
0d02f0b22   Tejun Heo   libata-acpi: adju...
303
  int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
64578a3de   Tejun Heo   libata-acpi: impl...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
  {
  	struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
  	union acpi_object *out_obj;
  	acpi_status status;
  	int rc = 0;
  
  	status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output);
  
  	rc = -ENOENT;
  	if (status == AE_NOT_FOUND)
  		goto out_free;
  
  	rc = -EINVAL;
  	if (ACPI_FAILURE(status)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
318
319
320
  		ata_port_err(ap, "ACPI get timing mode failed (AE 0x%x)
  ",
  			     status);
64578a3de   Tejun Heo   libata-acpi: impl...
321
322
323
324
325
  		goto out_free;
  	}
  
  	out_obj = output.pointer;
  	if (out_obj->type != ACPI_TYPE_BUFFER) {
a9a79dfec   Joe Perches   ata: Convert ata_...
326
327
328
  		ata_port_warn(ap, "_GTM returned unexpected object type 0x%x
  ",
  			      out_obj->type);
64578a3de   Tejun Heo   libata-acpi: impl...
329
330
331
332
333
  
  		goto out_free;
  	}
  
  	if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
334
335
336
  		ata_port_err(ap, "_GTM returned invalid length %d
  ",
  			     out_obj->buffer.length);
64578a3de   Tejun Heo   libata-acpi: impl...
337
338
339
340
341
342
343
344
345
  		goto out_free;
  	}
  
  	memcpy(gtm, out_obj->buffer.pointer, sizeof(struct ata_acpi_gtm));
  	rc = 0;
   out_free:
  	kfree(output.pointer);
  	return rc;
  }
badff03df   Alan Cox   libata-core: Expo...
346
  EXPORT_SYMBOL_GPL(ata_acpi_gtm);
64578a3de   Tejun Heo   libata-acpi: impl...
347
348
349
350
351
352
353
354
355
356
357
358
359
  /**
   * ata_acpi_stm - execute _STM
   * @ap: target ATA port
   * @stm: timing parameter to _STM
   *
   * Evaluate _STM with timing parameter @stm.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure.
   */
0d02f0b22   Tejun Heo   libata-acpi: adju...
360
  int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
64578a3de   Tejun Heo   libata-acpi: impl...
361
362
  {
  	acpi_status status;
0d02f0b22   Tejun Heo   libata-acpi: adju...
363
  	struct ata_acpi_gtm		stm_buf = *stm;
64578a3de   Tejun Heo   libata-acpi: impl...
364
365
366
367
368
  	struct acpi_object_list         input;
  	union acpi_object               in_params[3];
  
  	in_params[0].type = ACPI_TYPE_BUFFER;
  	in_params[0].buffer.length = sizeof(struct ata_acpi_gtm);
0d02f0b22   Tejun Heo   libata-acpi: adju...
369
  	in_params[0].buffer.pointer = (u8 *)&stm_buf;
64578a3de   Tejun Heo   libata-acpi: impl...
370
371
372
  	/* Buffers for id may need byteswapping ? */
  	in_params[1].type = ACPI_TYPE_BUFFER;
  	in_params[1].buffer.length = 512;
9af5c9c97   Tejun Heo   libata-link: intr...
373
  	in_params[1].buffer.pointer = (u8 *)ap->link.device[0].id;
64578a3de   Tejun Heo   libata-acpi: impl...
374
375
  	in_params[2].type = ACPI_TYPE_BUFFER;
  	in_params[2].buffer.length = 512;
9af5c9c97   Tejun Heo   libata-link: intr...
376
  	in_params[2].buffer.pointer = (u8 *)ap->link.device[1].id;
64578a3de   Tejun Heo   libata-acpi: impl...
377
378
379
380
381
382
383
384
385
  
  	input.count = 3;
  	input.pointer = in_params;
  
  	status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL);
  
  	if (status == AE_NOT_FOUND)
  		return -ENOENT;
  	if (ACPI_FAILURE(status)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
386
387
388
  		ata_port_err(ap, "ACPI set timing mode failed (status=0x%x)
  ",
  			     status);
64578a3de   Tejun Heo   libata-acpi: impl...
389
390
391
392
  		return -EINVAL;
  	}
  	return 0;
  }
badff03df   Alan Cox   libata-core: Expo...
393
  EXPORT_SYMBOL_GPL(ata_acpi_stm);
64578a3de   Tejun Heo   libata-acpi: impl...
394
  /**
4700c4bc9   Tejun Heo   libata-acpi: clea...
395
   * ata_dev_get_GTF - get the drive bootup default taskfile settings
3a32a8e96   Tejun Heo   libata-acpi: clea...
396
   * @dev: target ATA device
4700c4bc9   Tejun Heo   libata-acpi: clea...
397
   * @gtf: output parameter for buffer containing _GTF taskfile arrays
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
398
399
400
401
402
403
404
405
406
   *
   * This applies to both PATA and SATA drives.
   *
   * The _GTF method has no input parameters.
   * It returns a variable number of register set values (registers
   * hex 1F1..1F7, taskfiles).
   * The <variable number> is not known in advance, so have ACPI-CA
   * allocate the buffer as needed and return it, then free it later.
   *
4700c4bc9   Tejun Heo   libata-acpi: clea...
407
408
409
410
   * LOCKING:
   * EH context.
   *
   * RETURNS:
66fa7f215   Tejun Heo   libata-acpi: impr...
411
412
   * Number of taskfiles on success, 0 if _GTF doesn't exist.  -EINVAL
   * if _GTF is invalid.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
413
   */
398e07826   Tejun Heo   libata-acpi: impl...
414
  static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
415
  {
9af5c9c97   Tejun Heo   libata-link: intr...
416
  	struct ata_port *ap = dev->link->ap;
3a32a8e96   Tejun Heo   libata-acpi: clea...
417
  	acpi_status status;
3a32a8e96   Tejun Heo   libata-acpi: clea...
418
419
  	struct acpi_buffer output;
  	union acpi_object *out_obj;
4700c4bc9   Tejun Heo   libata-acpi: clea...
420
  	int rc = 0;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
421

398e07826   Tejun Heo   libata-acpi: impl...
422
423
424
425
426
  	/* if _GTF is cached, use the cached value */
  	if (dev->gtf_cache) {
  		out_obj = dev->gtf_cache;
  		goto done;
  	}
4700c4bc9   Tejun Heo   libata-acpi: clea...
427
428
429
  	/* set up output buffer */
  	output.length = ACPI_ALLOCATE_BUFFER;
  	output.pointer = NULL;	/* ACPI-CA sets this; save/free it later */
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
430

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
431
  	if (ata_msg_probe(ap))
a9a79dfec   Joe Perches   ata: Convert ata_...
432
433
434
  		ata_dev_dbg(dev, "%s: ENTER: port#: %d
  ",
  			    __func__, ap->port_no);
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
435

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
436
  	/* _GTF has no input parameters */
4700c4bc9   Tejun Heo   libata-acpi: clea...
437
  	status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
398e07826   Tejun Heo   libata-acpi: impl...
438
  	out_obj = dev->gtf_cache = output.pointer;
4700c4bc9   Tejun Heo   libata-acpi: clea...
439

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
440
  	if (ACPI_FAILURE(status)) {
4700c4bc9   Tejun Heo   libata-acpi: clea...
441
  		if (status != AE_NOT_FOUND) {
a9a79dfec   Joe Perches   ata: Convert ata_...
442
443
444
  			ata_dev_warn(dev, "_GTF evaluation failed (AE 0x%x)
  ",
  				     status);
66fa7f215   Tejun Heo   libata-acpi: impr...
445
  			rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
446
447
  		}
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
448
449
450
451
  	}
  
  	if (!output.length || !output.pointer) {
  		if (ata_msg_probe(ap))
a9a79dfec   Joe Perches   ata: Convert ata_...
452
453
454
455
456
  			ata_dev_dbg(dev, "%s: Run _GTF: length or ptr is NULL (0x%llx, 0x%p)
  ",
  				    __func__,
  				    (unsigned long long)output.length,
  				    output.pointer);
66fa7f215   Tejun Heo   libata-acpi: impr...
457
  		rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
458
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
459
  	}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
460
  	if (out_obj->type != ACPI_TYPE_BUFFER) {
a9a79dfec   Joe Perches   ata: Convert ata_...
461
462
463
  		ata_dev_warn(dev, "_GTF unexpected object type 0x%x
  ",
  			     out_obj->type);
66fa7f215   Tejun Heo   libata-acpi: impr...
464
  		rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
465
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
466
  	}
4700c4bc9   Tejun Heo   libata-acpi: clea...
467
  	if (out_obj->buffer.length % REGS_PER_GTF) {
a9a79dfec   Joe Perches   ata: Convert ata_...
468
469
470
  		ata_dev_warn(dev, "unexpected _GTF length (%d)
  ",
  			     out_obj->buffer.length);
66fa7f215   Tejun Heo   libata-acpi: impr...
471
  		rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
472
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
473
  	}
398e07826   Tejun Heo   libata-acpi: impl...
474
   done:
4700c4bc9   Tejun Heo   libata-acpi: clea...
475
  	rc = out_obj->buffer.length / REGS_PER_GTF;
398e07826   Tejun Heo   libata-acpi: impl...
476
477
478
  	if (gtf) {
  		*gtf = (void *)out_obj->buffer.pointer;
  		if (ata_msg_probe(ap))
a9a79dfec   Joe Perches   ata: Convert ata_...
479
480
481
  			ata_dev_dbg(dev, "%s: returning gtf=%p, gtf_count=%d
  ",
  				    __func__, *gtf, rc);
398e07826   Tejun Heo   libata-acpi: impl...
482
  	}
4700c4bc9   Tejun Heo   libata-acpi: clea...
483
484
485
  	return rc;
  
   out_free:
398e07826   Tejun Heo   libata-acpi: impl...
486
  	ata_acpi_clear_gtf(dev);
4700c4bc9   Tejun Heo   libata-acpi: clea...
487
  	return rc;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
488
  }
7c77fa4d5   Tejun Heo   libata: separate ...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
  /**
   * ata_acpi_gtm_xfermode - determine xfermode from GTM parameter
   * @dev: target device
   * @gtm: GTM parameter to use
   *
   * Determine xfermask for @dev from @gtm.
   *
   * LOCKING:
   * None.
   *
   * RETURNS:
   * Determined xfermask.
   */
  unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev,
  				    const struct ata_acpi_gtm *gtm)
  {
a0f79b929   Tejun Heo   libata: implement...
505
506
507
508
  	unsigned long xfer_mask = 0;
  	unsigned int type;
  	int unit;
  	u8 mode;
7c77fa4d5   Tejun Heo   libata: separate ...
509
510
511
512
513
  
  	/* we always use the 0 slot for crap hardware */
  	unit = dev->devno;
  	if (!(gtm->flags & 0x10))
  		unit = 0;
a0f79b929   Tejun Heo   libata: implement...
514
515
516
  	/* PIO */
  	mode = ata_timing_cycle2mode(ATA_SHIFT_PIO, gtm->drive[unit].pio);
  	xfer_mask |= ata_xfer_mode2mask(mode);
7c77fa4d5   Tejun Heo   libata: separate ...
517
518
519
520
521
  
  	/* See if we have MWDMA or UDMA data. We don't bother with
  	 * MWDMA if UDMA is available as this means the BIOS set UDMA
  	 * and our error changedown if it works is UDMA to PIO anyway.
  	 */
a0f79b929   Tejun Heo   libata: implement...
522
523
524
525
526
527
528
  	if (!(gtm->flags & (1 << (2 * unit))))
  		type = ATA_SHIFT_MWDMA;
  	else
  		type = ATA_SHIFT_UDMA;
  
  	mode = ata_timing_cycle2mode(type, gtm->drive[unit].dma);
  	xfer_mask |= ata_xfer_mode2mask(mode);
7c77fa4d5   Tejun Heo   libata: separate ...
529

a0f79b929   Tejun Heo   libata: implement...
530
  	return xfer_mask;
7c77fa4d5   Tejun Heo   libata: separate ...
531
532
  }
  EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask);
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
533
  /**
e1ddb4b6a   Alan Cox   [libata] add ACPI...
534
535
   * ata_acpi_cbl_80wire		-	Check for 80 wire cable
   * @ap: Port to check
021ee9a6d   Tejun Heo   libata: reimpleme...
536
   * @gtm: GTM data to use
e1ddb4b6a   Alan Cox   [libata] add ACPI...
537
   *
021ee9a6d   Tejun Heo   libata: reimpleme...
538
   * Return 1 if the @gtm indicates the BIOS selected an 80wire mode.
e1ddb4b6a   Alan Cox   [libata] add ACPI...
539
   */
021ee9a6d   Tejun Heo   libata: reimpleme...
540
  int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm)
e1ddb4b6a   Alan Cox   [libata] add ACPI...
541
  {
021ee9a6d   Tejun Heo   libata: reimpleme...
542
  	struct ata_device *dev;
1eca4365b   Tejun Heo   libata: beef up i...
543
  	ata_for_each_dev(dev, &ap->link, ENABLED) {
021ee9a6d   Tejun Heo   libata: reimpleme...
544
  		unsigned long xfer_mask, udma_mask;
021ee9a6d   Tejun Heo   libata: reimpleme...
545
546
547
548
549
550
  		xfer_mask = ata_acpi_gtm_xfermask(dev, gtm);
  		ata_unpack_xfermask(xfer_mask, NULL, NULL, &udma_mask);
  
  		if (udma_mask & ~ATA_UDMA_MASK_40C)
  			return 1;
  	}
e1ddb4b6a   Alan Cox   [libata] add ACPI...
551
552
  	return 0;
  }
e1ddb4b6a   Alan Cox   [libata] add ACPI...
553
  EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
3264a8d8f   Tejun Heo   libata-acpi: impl...
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
  static void ata_acpi_gtf_to_tf(struct ata_device *dev,
  			       const struct ata_acpi_gtf *gtf,
  			       struct ata_taskfile *tf)
  {
  	ata_tf_init(dev, tf);
  
  	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
  	tf->protocol = ATA_PROT_NODATA;
  	tf->feature = gtf->tf[0];	/* 0x1f1 */
  	tf->nsect   = gtf->tf[1];	/* 0x1f2 */
  	tf->lbal    = gtf->tf[2];	/* 0x1f3 */
  	tf->lbam    = gtf->tf[3];	/* 0x1f4 */
  	tf->lbah    = gtf->tf[4];	/* 0x1f5 */
  	tf->device  = gtf->tf[5];	/* 0x1f6 */
  	tf->command = gtf->tf[6];	/* 0x1f7 */
  }
110f66d25   Tejun Heo   libata: make gtf_...
570
571
  static int ata_acpi_filter_tf(struct ata_device *dev,
  			      const struct ata_taskfile *tf,
3264a8d8f   Tejun Heo   libata-acpi: impl...
572
573
  			      const struct ata_taskfile *ptf)
  {
110f66d25   Tejun Heo   libata: make gtf_...
574
  	if (dev->gtf_filter & ATA_ACPI_FILTER_SETXFER) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
575
576
577
578
579
580
581
  		/* libata doesn't use ACPI to configure transfer mode.
  		 * It will only confuse device configuration.  Skip.
  		 */
  		if (tf->command == ATA_CMD_SET_FEATURES &&
  		    tf->feature == SETFEATURES_XFER)
  			return 1;
  	}
110f66d25   Tejun Heo   libata: make gtf_...
582
  	if (dev->gtf_filter & ATA_ACPI_FILTER_LOCK) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
  		/* BIOS writers, sorry but we don't wanna lock
  		 * features unless the user explicitly said so.
  		 */
  
  		/* DEVICE CONFIGURATION FREEZE LOCK */
  		if (tf->command == ATA_CMD_CONF_OVERLAY &&
  		    tf->feature == ATA_DCO_FREEZE_LOCK)
  			return 1;
  
  		/* SECURITY FREEZE LOCK */
  		if (tf->command == ATA_CMD_SEC_FREEZE_LOCK)
  			return 1;
  
  		/* SET MAX LOCK and SET MAX FREEZE LOCK */
  		if ((!ptf || ptf->command != ATA_CMD_READ_NATIVE_MAX) &&
  		    tf->command == ATA_CMD_SET_MAX &&
  		    (tf->feature == ATA_SET_MAX_LOCK ||
  		     tf->feature == ATA_SET_MAX_FREEZE_LOCK))
  			return 1;
  	}
fa5b561c4   Tejun Heo   libata: implement...
603
604
  	if (tf->command == ATA_CMD_SET_FEATURES &&
  	    tf->feature == SETFEATURES_SATA_ENABLE) {
b344991ac   Tejun Heo   libata-acpi: filt...
605
  		/* inhibit enabling DIPM */
110f66d25   Tejun Heo   libata: make gtf_...
606
  		if (dev->gtf_filter & ATA_ACPI_FILTER_DIPM &&
b344991ac   Tejun Heo   libata-acpi: filt...
607
608
  		    tf->nsect == SATA_DIPM)
  			return 1;
fa5b561c4   Tejun Heo   libata: implement...
609
610
  
  		/* inhibit FPDMA non-zero offset */
110f66d25   Tejun Heo   libata: make gtf_...
611
  		if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_OFFSET &&
fa5b561c4   Tejun Heo   libata: implement...
612
613
614
615
616
  		    (tf->nsect == SATA_FPDMA_OFFSET ||
  		     tf->nsect == SATA_FPDMA_IN_ORDER))
  			return 1;
  
  		/* inhibit FPDMA auto activation */
110f66d25   Tejun Heo   libata: make gtf_...
617
  		if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_AA &&
fa5b561c4   Tejun Heo   libata: implement...
618
619
  		    tf->nsect == SATA_FPDMA_AA)
  			return 1;
b344991ac   Tejun Heo   libata-acpi: filt...
620
  	}
3264a8d8f   Tejun Heo   libata-acpi: impl...
621
622
  	return 0;
  }
e1ddb4b6a   Alan Cox   [libata] add ACPI...
623
  /**
0e8634bf8   Tejun Heo   libata-acpi: impr...
624
   * ata_acpi_run_tf - send taskfile registers to host controller
3a32a8e96   Tejun Heo   libata-acpi: clea...
625
   * @dev: target ATA device
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
626
627
   * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
   *
3696df309   Sergei Shtylyov   libata: remove AT...
628
   * Outputs ATA taskfile to standard ATA host controller.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
629
630
631
632
633
634
635
636
637
   * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
   * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
   * hob_lbal, hob_lbam, and hob_lbah.
   *
   * This function waits for idle (!BUSY and !DRQ) after writing
   * registers.  If the control register has a new value, this
   * function also waits for idle after writing control and before
   * writing the remaining registers.
   *
4700c4bc9   Tejun Heo   libata-acpi: clea...
638
639
640
641
   * LOCKING:
   * EH context.
   *
   * RETURNS:
3264a8d8f   Tejun Heo   libata-acpi: impl...
642
643
   * 1 if command is executed successfully.  0 if ignored, rejected or
   * filtered out, -errno on other errors.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
644
   */
0e8634bf8   Tejun Heo   libata-acpi: impr...
645
  static int ata_acpi_run_tf(struct ata_device *dev,
3264a8d8f   Tejun Heo   libata-acpi: impl...
646
647
  			   const struct ata_acpi_gtf *gtf,
  			   const struct ata_acpi_gtf *prev_gtf)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
648
  {
3264a8d8f   Tejun Heo   libata-acpi: impl...
649
650
  	struct ata_taskfile *pptf = NULL;
  	struct ata_taskfile tf, ptf, rtf;
4700c4bc9   Tejun Heo   libata-acpi: clea...
651
  	unsigned int err_mask;
0e8634bf8   Tejun Heo   libata-acpi: impr...
652
  	const char *level;
6521148c6   Robert Hancock   libata: add comma...
653
  	const char *descr;
0e8634bf8   Tejun Heo   libata-acpi: impr...
654
655
  	char msg[60];
  	int rc;
fc16c25ff   Jeff Garzik   [libata] ACPI: re...
656

4700c4bc9   Tejun Heo   libata-acpi: clea...
657
658
659
660
  	if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0)
  	    && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
  	    && (gtf->tf[6] == 0))
  		return 0;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
661

3264a8d8f   Tejun Heo   libata-acpi: impl...
662
663
664
665
666
  	ata_acpi_gtf_to_tf(dev, gtf, &tf);
  	if (prev_gtf) {
  		ata_acpi_gtf_to_tf(dev, prev_gtf, &ptf);
  		pptf = &ptf;
  	}
110f66d25   Tejun Heo   libata: make gtf_...
667
  	if (!ata_acpi_filter_tf(dev, &tf, pptf)) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  		rtf = tf;
  		err_mask = ata_exec_internal(dev, &rtf, NULL,
  					     DMA_NONE, NULL, 0, 0);
  
  		switch (err_mask) {
  		case 0:
  			level = KERN_DEBUG;
  			snprintf(msg, sizeof(msg), "succeeded");
  			rc = 1;
  			break;
  
  		case AC_ERR_DEV:
  			level = KERN_INFO;
  			snprintf(msg, sizeof(msg),
  				 "rejected by device (Stat=0x%02x Err=0x%02x)",
  				 rtf.command, rtf.feature);
  			rc = 0;
  			break;
  
  		default:
  			level = KERN_ERR;
  			snprintf(msg, sizeof(msg),
  				 "failed (Emask=0x%x Stat=0x%02x Err=0x%02x)",
  				 err_mask, rtf.command, rtf.feature);
  			rc = -EIO;
  			break;
  		}
  	} else {
0e8634bf8   Tejun Heo   libata-acpi: impr...
696
  		level = KERN_INFO;
3264a8d8f   Tejun Heo   libata-acpi: impl...
697
  		snprintf(msg, sizeof(msg), "filtered out");
0e8634bf8   Tejun Heo   libata-acpi: impr...
698
  		rc = 0;
4700c4bc9   Tejun Heo   libata-acpi: clea...
699
  	}
6521148c6   Robert Hancock   libata: add comma...
700
  	descr = ata_get_cmd_descript(tf.command);
4700c4bc9   Tejun Heo   libata-acpi: clea...
701

0e8634bf8   Tejun Heo   libata-acpi: impr...
702
  	ata_dev_printk(dev, level,
6521148c6   Robert Hancock   libata: add comma...
703
704
  		       "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x (%s) %s
  ",
0e8634bf8   Tejun Heo   libata-acpi: impr...
705
  		       tf.command, tf.feature, tf.nsect, tf.lbal,
6521148c6   Robert Hancock   libata: add comma...
706
707
  		       tf.lbam, tf.lbah, tf.device,
  		       (descr ? descr : "unknown"), msg);
0e8634bf8   Tejun Heo   libata-acpi: impr...
708
709
  
  	return rc;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
710
711
712
  }
  
  /**
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
713
   * ata_acpi_exec_tfs - get then write drive taskfile settings
6746544c3   Tejun Heo   libata: reimpleme...
714
   * @dev: target ATA device
98a1708de   Martin Olsson   trivial: fix typo...
715
   * @nr_executed: out parameter for the number of executed commands
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
716
   *
98a1708de   Martin Olsson   trivial: fix typo...
717
   * Evaluate _GTF and execute returned taskfiles.
69b16a5f4   Tejun Heo   libata-acpi: misc...
718
719
720
721
722
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
66fa7f215   Tejun Heo   libata-acpi: impr...
723
724
   * Number of executed taskfiles on success, 0 if _GTF doesn't exist.
   * -errno on other errors.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
725
   */
66fa7f215   Tejun Heo   libata-acpi: impr...
726
  static int ata_acpi_exec_tfs(struct ata_device *dev, int *nr_executed)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
727
  {
3264a8d8f   Tejun Heo   libata-acpi: impl...
728
  	struct ata_acpi_gtf *gtf = NULL, *pgtf = NULL;
6746544c3   Tejun Heo   libata: reimpleme...
729
730
731
  	int gtf_count, i, rc;
  
  	/* get taskfiles */
66fa7f215   Tejun Heo   libata-acpi: impr...
732
733
734
735
  	rc = ata_dev_get_GTF(dev, &gtf);
  	if (rc < 0)
  		return rc;
  	gtf_count = rc;
6746544c3   Tejun Heo   libata: reimpleme...
736
737
  
  	/* execute them */
3264a8d8f   Tejun Heo   libata-acpi: impl...
738
739
  	for (i = 0; i < gtf_count; i++, gtf++) {
  		rc = ata_acpi_run_tf(dev, gtf, pgtf);
0e8634bf8   Tejun Heo   libata-acpi: impr...
740
741
  		if (rc < 0)
  			break;
3264a8d8f   Tejun Heo   libata-acpi: impl...
742
  		if (rc) {
0e8634bf8   Tejun Heo   libata-acpi: impr...
743
  			(*nr_executed)++;
3264a8d8f   Tejun Heo   libata-acpi: impl...
744
745
  			pgtf = gtf;
  		}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
746
  	}
398e07826   Tejun Heo   libata-acpi: impl...
747
  	ata_acpi_clear_gtf(dev);
6746544c3   Tejun Heo   libata: reimpleme...
748

0e8634bf8   Tejun Heo   libata-acpi: impr...
749
750
751
  	if (rc < 0)
  		return rc;
  	return 0;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
752
  }
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
753
754
  /**
   * ata_acpi_push_id - send Identify data to drive
3a32a8e96   Tejun Heo   libata-acpi: clea...
755
   * @dev: target ATA device
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
756
757
758
759
760
761
   *
   * _SDD ACPI object: for SATA mode only
   * Must be after Identify (Packet) Device -- uses its data
   * ATM this function never returns a failure.  It is an optional
   * method and if it fails for whatever reason, we should still
   * just keep going.
69b16a5f4   Tejun Heo   libata-acpi: misc...
762
763
764
765
766
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
f2406770a   Tejun Heo   libata-acpi: miss...
767
   * 0 on success, -ENOENT if _SDD doesn't exist, -errno on failure.
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
768
   */
6746544c3   Tejun Heo   libata: reimpleme...
769
  static int ata_acpi_push_id(struct ata_device *dev)
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
770
  {
9af5c9c97   Tejun Heo   libata-link: intr...
771
  	struct ata_port *ap = dev->link->ap;
3a32a8e96   Tejun Heo   libata-acpi: clea...
772
773
774
  	acpi_status status;
  	struct acpi_object_list input;
  	union acpi_object in_params[1];
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
775

7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
776
  	if (ata_msg_probe(ap))
a9a79dfec   Joe Perches   ata: Convert ata_...
777
778
779
  		ata_dev_dbg(dev, "%s: ix = %d, port#: %d
  ",
  			    __func__, dev->devno, ap->port_no);
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
780

7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
781
782
783
784
785
  	/* Give the drive Identify data to the drive via the _SDD method */
  	/* _SDD: set up input parameters */
  	input.count = 1;
  	input.pointer = in_params;
  	in_params[0].type = ACPI_TYPE_BUFFER;
3a32a8e96   Tejun Heo   libata-acpi: clea...
786
787
  	in_params[0].buffer.length = sizeof(dev->id[0]) * ATA_ID_WORDS;
  	in_params[0].buffer.pointer = (u8 *)dev->id;
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
788
789
790
  	/* Output buffer: _SDD has no output */
  
  	/* It's OK for _SDD to be missing too. */
3a32a8e96   Tejun Heo   libata-acpi: clea...
791
  	swap_buf_le16(dev->id, ATA_ID_WORDS);
fafbae87d   Tejun Heo   libata-acpi: impl...
792
  	status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
3a32a8e96   Tejun Heo   libata-acpi: clea...
793
  	swap_buf_le16(dev->id, ATA_ID_WORDS);
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
794

f2406770a   Tejun Heo   libata-acpi: miss...
795
796
797
798
  	if (status == AE_NOT_FOUND)
  		return -ENOENT;
  
  	if (ACPI_FAILURE(status)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
799
800
  		ata_dev_warn(dev, "ACPI _SDD failed (AE 0x%x)
  ", status);
f2406770a   Tejun Heo   libata-acpi: miss...
801
802
  		return -EIO;
  	}
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
803

f2406770a   Tejun Heo   libata-acpi: miss...
804
  	return 0;
6746544c3   Tejun Heo   libata: reimpleme...
805
806
807
  }
  
  /**
64578a3de   Tejun Heo   libata-acpi: impl...
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
   * ata_acpi_on_suspend - ATA ACPI hook called on suspend
   * @ap: target ATA port
   *
   * This function is called when @ap is about to be suspended.  All
   * devices are already put to sleep but the port_suspend() callback
   * hasn't been executed yet.  Error return from this function aborts
   * suspend.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * 0 on success, -errno on failure.
   */
  int ata_acpi_on_suspend(struct ata_port *ap)
  {
c05e6ff03   Tejun Heo   libata-acpi: impl...
824
825
  	/* nada */
  	return 0;
64578a3de   Tejun Heo   libata-acpi: impl...
826
827
828
  }
  
  /**
6746544c3   Tejun Heo   libata: reimpleme...
829
830
831
832
833
834
835
836
837
838
839
   * ata_acpi_on_resume - ATA ACPI hook called on resume
   * @ap: target ATA port
   *
   * This function is called when @ap is resumed - right after port
   * itself is resumed but before any EH action is taken.
   *
   * LOCKING:
   * EH context.
   */
  void ata_acpi_on_resume(struct ata_port *ap)
  {
c05e6ff03   Tejun Heo   libata-acpi: impl...
840
  	const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
f58229f80   Tejun Heo   libata-link: impl...
841
  	struct ata_device *dev;
6746544c3   Tejun Heo   libata: reimpleme...
842

398e07826   Tejun Heo   libata-acpi: impl...
843
844
845
846
  	if (ap->acpi_handle && gtm) {
  		/* _GTM valid */
  
  		/* restore timing parameters */
c05e6ff03   Tejun Heo   libata-acpi: impl...
847
  		ata_acpi_stm(ap, gtm);
64578a3de   Tejun Heo   libata-acpi: impl...
848

398e07826   Tejun Heo   libata-acpi: impl...
849
850
851
852
  		/* _GTF should immediately follow _STM so that it can
  		 * use values set by _STM.  Cache _GTF result and
  		 * schedule _GTF.
  		 */
1eca4365b   Tejun Heo   libata: beef up i...
853
  		ata_for_each_dev(dev, &ap->link, ALL) {
398e07826   Tejun Heo   libata-acpi: impl...
854
  			ata_acpi_clear_gtf(dev);
48feb3c41   Shaohua Li   ata-acpi: don't c...
855
856
  			if (ata_dev_enabled(dev) &&
  			    ata_dev_get_GTF(dev, NULL) >= 0)
398e07826   Tejun Heo   libata-acpi: impl...
857
858
859
860
861
862
863
  				dev->flags |= ATA_DFLAG_ACPI_PENDING;
  		}
  	} else {
  		/* SATA _GTF needs to be evaulated after _SDD and
  		 * there's no reason to evaluate IDE _GTF early
  		 * without _STM.  Clear cache and schedule _GTF.
  		 */
1eca4365b   Tejun Heo   libata: beef up i...
864
  		ata_for_each_dev(dev, &ap->link, ALL) {
398e07826   Tejun Heo   libata-acpi: impl...
865
  			ata_acpi_clear_gtf(dev);
48feb3c41   Shaohua Li   ata-acpi: don't c...
866
867
  			if (ata_dev_enabled(dev))
  				dev->flags |= ATA_DFLAG_ACPI_PENDING;
398e07826   Tejun Heo   libata-acpi: impl...
868
869
  		}
  	}
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
870
  }
6746544c3   Tejun Heo   libata: reimpleme...
871
  /**
bd3adca52   Shaohua Li   libata-acpi: add ...
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
   * ata_acpi_set_state - set the port power state
   * @ap: target ATA port
   * @state: state, on/off
   *
   * This function executes the _PS0/_PS3 ACPI method to set the power state.
   * ACPI spec requires _PS0 when IDE power on and _PS3 when power off
   */
  void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
  {
  	struct ata_device *dev;
  
  	if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA))
  		return;
  
  	/* channel first and then drives for power on and vica versa
  	   for power off */
  	if (state.event == PM_EVENT_ON)
  		acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0);
1eca4365b   Tejun Heo   libata: beef up i...
890
891
  	ata_for_each_dev(dev, &ap->link, ENABLED) {
  		if (dev->acpi_handle)
bd3adca52   Shaohua Li   libata-acpi: add ...
892
893
894
895
896
897
898
899
900
  			acpi_bus_set_power(dev->acpi_handle,
  				state.event == PM_EVENT_ON ?
  					ACPI_STATE_D0 : ACPI_STATE_D3);
  	}
  	if (state.event != PM_EVENT_ON)
  		acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3);
  }
  
  /**
6746544c3   Tejun Heo   libata: reimpleme...
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
   * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration
   * @dev: target ATA device
   *
   * This function is called when @dev is about to be configured.
   * IDENTIFY data might have been modified after this hook is run.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * Positive number if IDENTIFY data needs to be refreshed, 0 if not,
   * -errno on failure.
   */
  int ata_acpi_on_devcfg(struct ata_device *dev)
  {
9af5c9c97   Tejun Heo   libata-link: intr...
916
917
  	struct ata_port *ap = dev->link->ap;
  	struct ata_eh_context *ehc = &ap->link.eh_context;
6746544c3   Tejun Heo   libata: reimpleme...
918
  	int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
66fa7f215   Tejun Heo   libata-acpi: impr...
919
  	int nr_executed = 0;
6746544c3   Tejun Heo   libata: reimpleme...
920
  	int rc;
6746544c3   Tejun Heo   libata: reimpleme...
921
922
923
924
925
926
927
928
929
930
931
  	if (!dev->acpi_handle)
  		return 0;
  
  	/* do we need to do _GTF? */
  	if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) &&
  	    !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET)))
  		return 0;
  
  	/* do _SDD if SATA */
  	if (acpi_sata) {
  		rc = ata_acpi_push_id(dev);
f2406770a   Tejun Heo   libata-acpi: miss...
932
  		if (rc && rc != -ENOENT)
6746544c3   Tejun Heo   libata: reimpleme...
933
934
935
936
  			goto acpi_err;
  	}
  
  	/* do _GTF */
66fa7f215   Tejun Heo   libata-acpi: impr...
937
938
  	rc = ata_acpi_exec_tfs(dev, &nr_executed);
  	if (rc)
6746544c3   Tejun Heo   libata: reimpleme...
939
940
941
942
943
  		goto acpi_err;
  
  	dev->flags &= ~ATA_DFLAG_ACPI_PENDING;
  
  	/* refresh IDENTIFY page if any _GTF command has been executed */
66fa7f215   Tejun Heo   libata-acpi: impr...
944
  	if (nr_executed) {
6746544c3   Tejun Heo   libata: reimpleme...
945
946
  		rc = ata_dev_reread_id(dev, 0);
  		if (rc < 0) {
a9a79dfec   Joe Perches   ata: Convert ata_...
947
948
949
  			ata_dev_err(dev,
  				    "failed to IDENTIFY after ACPI commands
  ");
6746544c3   Tejun Heo   libata: reimpleme...
950
951
952
953
954
955
956
  			return rc;
  		}
  	}
  
  	return 0;
  
   acpi_err:
66fa7f215   Tejun Heo   libata-acpi: impr...
957
958
959
  	/* ignore evaluation failure if we can continue safely */
  	if (rc == -EINVAL && !nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN))
  		return 0;
6746544c3   Tejun Heo   libata: reimpleme...
960

66fa7f215   Tejun Heo   libata-acpi: impr...
961
962
963
964
  	/* fail and let EH retry once more for unknown IO errors */
  	if (!(dev->flags & ATA_DFLAG_ACPI_FAILED)) {
  		dev->flags |= ATA_DFLAG_ACPI_FAILED;
  		return rc;
6746544c3   Tejun Heo   libata: reimpleme...
965
  	}
66fa7f215   Tejun Heo   libata-acpi: impr...
966

a9a79dfec   Joe Perches   ata: Convert ata_...
967
968
  	ata_dev_warn(dev, "ACPI: failed the second time, disabled
  ");
66fa7f215   Tejun Heo   libata-acpi: impr...
969
970
971
972
973
974
975
  	dev->acpi_handle = NULL;
  
  	/* We can safely continue if no _GTF command has been executed
  	 * and port is not frozen.
  	 */
  	if (!nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN))
  		return 0;
6746544c3   Tejun Heo   libata: reimpleme...
976
977
  	return rc;
  }
562f0c2d7   Tejun Heo   libata-acpi: add ...
978
979
980
981
982
983
984
985
986
987
988
989
  
  /**
   * ata_acpi_on_disable - ATA ACPI hook called when a device is disabled
   * @dev: target ATA device
   *
   * This function is called when @dev is about to be disabled.
   *
   * LOCKING:
   * EH context.
   */
  void ata_acpi_on_disable(struct ata_device *dev)
  {
398e07826   Tejun Heo   libata-acpi: impl...
990
  	ata_acpi_clear_gtf(dev);
562f0c2d7   Tejun Heo   libata-acpi: add ...
991
  }