Blame view

drivers/ata/libata-acpi.c 25.1 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
207
208
209
210
211
212
213
214
215
216
  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);
  }
  
  static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
  	.handler = ata_acpi_dev_notify_dock,
  	.uevent = ata_acpi_dev_uevent,
  };
  
  static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
  	.handler = ata_acpi_ap_notify_dock,
  	.uevent = ata_acpi_ap_uevent,
  };
fafbae87d   Tejun Heo   libata-acpi: impl...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  /**
   * 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...
231
  {
237d8440c   Matthew Garrett   libata: Integrate...
232
  	int i, j;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
233

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

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

fafbae87d   Tejun Heo   libata-acpi: impl...
241
242
243
244
245
246
247
  	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...
248

233f11204   Tejun Heo   libata-acpi: impr...
249
  		if (ap->acpi_handle) {
233f11204   Tejun Heo   libata-acpi: impr...
250
251
  			/* we might be on a docking station */
  			register_hotplug_dock_device(ap->acpi_handle,
1253f7aab   Shaohua Li   dock: introduce ....
252
  					     &ata_acpi_ap_dock_ops, ap);
233f11204   Tejun Heo   libata-acpi: impr...
253
  		}
237d8440c   Matthew Garrett   libata: Integrate...
254
255
256
  
  		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...
257
  			if (dev->acpi_handle) {
233f11204   Tejun Heo   libata-acpi: impr...
258
259
  				/* we might be on a docking station */
  				register_hotplug_dock_device(dev->acpi_handle,
1253f7aab   Shaohua Li   dock: introduce ....
260
  					     &ata_acpi_dev_dock_ops, dev);
233f11204   Tejun Heo   libata-acpi: impr...
261
  			}
237d8440c   Matthew Garrett   libata: Integrate...
262
  		}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
263
  	}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
264
265
266
  }
  
  /**
562f0c2d7   Tejun Heo   libata-acpi: add ...
267
268
269
270
271
272
273
274
275
276
277
   * 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...
278
279
280
281
282
283
284
285
286
287
288
289
  	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 ...
290
291
292
  }
  
  /**
64578a3de   Tejun Heo   libata-acpi: impl...
293
294
295
296
297
298
299
300
301
302
303
304
   * 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...
305
  int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
64578a3de   Tejun Heo   libata-acpi: impl...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  {
  	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)) {
  		ata_port_printk(ap, KERN_ERR,
  				"ACPI get timing mode failed (AE 0x%x)
  ",
  				status);
  		goto out_free;
  	}
  
  	out_obj = output.pointer;
  	if (out_obj->type != ACPI_TYPE_BUFFER) {
  		ata_port_printk(ap, KERN_WARNING,
  				"_GTM returned unexpected object type 0x%x
  ",
  				out_obj->type);
  
  		goto out_free;
  	}
  
  	if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) {
  		ata_port_printk(ap, KERN_ERR,
  				"_GTM returned invalid length %d
  ",
  				out_obj->buffer.length);
  		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...
351
  EXPORT_SYMBOL_GPL(ata_acpi_gtm);
64578a3de   Tejun Heo   libata-acpi: impl...
352
353
354
355
356
357
358
359
360
361
362
363
364
  /**
   * 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...
365
  int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
64578a3de   Tejun Heo   libata-acpi: impl...
366
367
  {
  	acpi_status status;
0d02f0b22   Tejun Heo   libata-acpi: adju...
368
  	struct ata_acpi_gtm		stm_buf = *stm;
64578a3de   Tejun Heo   libata-acpi: impl...
369
370
371
372
373
  	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...
374
  	in_params[0].buffer.pointer = (u8 *)&stm_buf;
64578a3de   Tejun Heo   libata-acpi: impl...
375
376
377
  	/* 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...
378
  	in_params[1].buffer.pointer = (u8 *)ap->link.device[0].id;
64578a3de   Tejun Heo   libata-acpi: impl...
379
380
  	in_params[2].type = ACPI_TYPE_BUFFER;
  	in_params[2].buffer.length = 512;
9af5c9c97   Tejun Heo   libata-link: intr...
381
  	in_params[2].buffer.pointer = (u8 *)ap->link.device[1].id;
64578a3de   Tejun Heo   libata-acpi: impl...
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  
  	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)) {
  		ata_port_printk(ap, KERN_ERR,
  			"ACPI set timing mode failed (status=0x%x)
  ", status);
  		return -EINVAL;
  	}
  	return 0;
  }
badff03df   Alan Cox   libata-core: Expo...
398
  EXPORT_SYMBOL_GPL(ata_acpi_stm);
64578a3de   Tejun Heo   libata-acpi: impl...
399
  /**
4700c4bc9   Tejun Heo   libata-acpi: clea...
400
   * ata_dev_get_GTF - get the drive bootup default taskfile settings
3a32a8e96   Tejun Heo   libata-acpi: clea...
401
   * @dev: target ATA device
4700c4bc9   Tejun Heo   libata-acpi: clea...
402
   * @gtf: output parameter for buffer containing _GTF taskfile arrays
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
403
404
405
406
407
408
409
410
411
   *
   * 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...
412
413
414
415
   * LOCKING:
   * EH context.
   *
   * RETURNS:
66fa7f215   Tejun Heo   libata-acpi: impr...
416
417
   * Number of taskfiles on success, 0 if _GTF doesn't exist.  -EINVAL
   * if _GTF is invalid.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
418
   */
398e07826   Tejun Heo   libata-acpi: impl...
419
  static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
420
  {
9af5c9c97   Tejun Heo   libata-link: intr...
421
  	struct ata_port *ap = dev->link->ap;
3a32a8e96   Tejun Heo   libata-acpi: clea...
422
  	acpi_status status;
3a32a8e96   Tejun Heo   libata-acpi: clea...
423
424
  	struct acpi_buffer output;
  	union acpi_object *out_obj;
4700c4bc9   Tejun Heo   libata-acpi: clea...
425
  	int rc = 0;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
426

398e07826   Tejun Heo   libata-acpi: impl...
427
428
429
430
431
  	/* 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...
432
433
434
  	/* 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...
435

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
436
  	if (ata_msg_probe(ap))
3a32a8e96   Tejun Heo   libata-acpi: clea...
437
438
  		ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d
  ",
7f5e4e8d9   Harvey Harrison   ata: replace rema...
439
  			       __func__, ap->port_no);
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
440

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

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
445
  	if (ACPI_FAILURE(status)) {
4700c4bc9   Tejun Heo   libata-acpi: clea...
446
447
448
449
450
  		if (status != AE_NOT_FOUND) {
  			ata_dev_printk(dev, KERN_WARNING,
  				       "_GTF evaluation failed (AE 0x%x)
  ",
  				       status);
66fa7f215   Tejun Heo   libata-acpi: impr...
451
  			rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
452
453
  		}
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
454
455
456
457
  	}
  
  	if (!output.length || !output.pointer) {
  		if (ata_msg_probe(ap))
3a32a8e96   Tejun Heo   libata-acpi: clea...
458
  			ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: "
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
459
460
  				"length or ptr is NULL (0x%llx, 0x%p)
  ",
7f5e4e8d9   Harvey Harrison   ata: replace rema...
461
  				__func__,
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
462
463
  				(unsigned long long)output.length,
  				output.pointer);
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
  	}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
467
  	if (out_obj->type != ACPI_TYPE_BUFFER) {
69b16a5f4   Tejun Heo   libata-acpi: misc...
468
469
470
471
  		ata_dev_printk(dev, KERN_WARNING,
  			       "_GTF unexpected object type 0x%x
  ",
  			       out_obj->type);
66fa7f215   Tejun Heo   libata-acpi: impr...
472
  		rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
473
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
474
  	}
4700c4bc9   Tejun Heo   libata-acpi: clea...
475
  	if (out_obj->buffer.length % REGS_PER_GTF) {
69b16a5f4   Tejun Heo   libata-acpi: misc...
476
477
478
479
  		ata_dev_printk(dev, KERN_WARNING,
  			       "unexpected _GTF length (%d)
  ",
  			       out_obj->buffer.length);
66fa7f215   Tejun Heo   libata-acpi: impr...
480
  		rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
481
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
482
  	}
398e07826   Tejun Heo   libata-acpi: impl...
483
   done:
4700c4bc9   Tejun Heo   libata-acpi: clea...
484
  	rc = out_obj->buffer.length / REGS_PER_GTF;
398e07826   Tejun Heo   libata-acpi: impl...
485
486
487
488
489
490
  	if (gtf) {
  		*gtf = (void *)out_obj->buffer.pointer;
  		if (ata_msg_probe(ap))
  			ata_dev_printk(dev, KERN_DEBUG,
  				       "%s: returning gtf=%p, gtf_count=%d
  ",
7f5e4e8d9   Harvey Harrison   ata: replace rema...
491
  				       __func__, *gtf, rc);
398e07826   Tejun Heo   libata-acpi: impl...
492
  	}
4700c4bc9   Tejun Heo   libata-acpi: clea...
493
494
495
  	return rc;
  
   out_free:
398e07826   Tejun Heo   libata-acpi: impl...
496
  	ata_acpi_clear_gtf(dev);
4700c4bc9   Tejun Heo   libata-acpi: clea...
497
  	return rc;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
498
  }
7c77fa4d5   Tejun Heo   libata: separate ...
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
  /**
   * 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...
515
516
517
518
  	unsigned long xfer_mask = 0;
  	unsigned int type;
  	int unit;
  	u8 mode;
7c77fa4d5   Tejun Heo   libata: separate ...
519
520
521
522
523
  
  	/* we always use the 0 slot for crap hardware */
  	unit = dev->devno;
  	if (!(gtm->flags & 0x10))
  		unit = 0;
a0f79b929   Tejun Heo   libata: implement...
524
525
526
  	/* PIO */
  	mode = ata_timing_cycle2mode(ATA_SHIFT_PIO, gtm->drive[unit].pio);
  	xfer_mask |= ata_xfer_mode2mask(mode);
7c77fa4d5   Tejun Heo   libata: separate ...
527
528
529
530
531
  
  	/* 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...
532
533
534
535
536
537
538
  	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 ...
539

a0f79b929   Tejun Heo   libata: implement...
540
  	return xfer_mask;
7c77fa4d5   Tejun Heo   libata: separate ...
541
542
  }
  EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask);
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
543
  /**
e1ddb4b6a   Alan Cox   [libata] add ACPI...
544
545
   * ata_acpi_cbl_80wire		-	Check for 80 wire cable
   * @ap: Port to check
021ee9a6d   Tejun Heo   libata: reimpleme...
546
   * @gtm: GTM data to use
e1ddb4b6a   Alan Cox   [libata] add ACPI...
547
   *
021ee9a6d   Tejun Heo   libata: reimpleme...
548
   * Return 1 if the @gtm indicates the BIOS selected an 80wire mode.
e1ddb4b6a   Alan Cox   [libata] add ACPI...
549
   */
021ee9a6d   Tejun Heo   libata: reimpleme...
550
  int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm)
e1ddb4b6a   Alan Cox   [libata] add ACPI...
551
  {
021ee9a6d   Tejun Heo   libata: reimpleme...
552
  	struct ata_device *dev;
1eca4365b   Tejun Heo   libata: beef up i...
553
  	ata_for_each_dev(dev, &ap->link, ENABLED) {
021ee9a6d   Tejun Heo   libata: reimpleme...
554
  		unsigned long xfer_mask, udma_mask;
021ee9a6d   Tejun Heo   libata: reimpleme...
555
556
557
558
559
560
  		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...
561
562
  	return 0;
  }
e1ddb4b6a   Alan Cox   [libata] add ACPI...
563
  EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
3264a8d8f   Tejun Heo   libata-acpi: impl...
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
  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_...
580
581
  static int ata_acpi_filter_tf(struct ata_device *dev,
  			      const struct ata_taskfile *tf,
3264a8d8f   Tejun Heo   libata-acpi: impl...
582
583
  			      const struct ata_taskfile *ptf)
  {
110f66d25   Tejun Heo   libata: make gtf_...
584
  	if (dev->gtf_filter & ATA_ACPI_FILTER_SETXFER) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
585
586
587
588
589
590
591
  		/* 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_...
592
  	if (dev->gtf_filter & ATA_ACPI_FILTER_LOCK) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
  		/* 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...
613
614
  	if (tf->command == ATA_CMD_SET_FEATURES &&
  	    tf->feature == SETFEATURES_SATA_ENABLE) {
b344991ac   Tejun Heo   libata-acpi: filt...
615
  		/* inhibit enabling DIPM */
110f66d25   Tejun Heo   libata: make gtf_...
616
  		if (dev->gtf_filter & ATA_ACPI_FILTER_DIPM &&
b344991ac   Tejun Heo   libata-acpi: filt...
617
618
  		    tf->nsect == SATA_DIPM)
  			return 1;
fa5b561c4   Tejun Heo   libata: implement...
619
620
  
  		/* inhibit FPDMA non-zero offset */
110f66d25   Tejun Heo   libata: make gtf_...
621
  		if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_OFFSET &&
fa5b561c4   Tejun Heo   libata: implement...
622
623
624
625
626
  		    (tf->nsect == SATA_FPDMA_OFFSET ||
  		     tf->nsect == SATA_FPDMA_IN_ORDER))
  			return 1;
  
  		/* inhibit FPDMA auto activation */
110f66d25   Tejun Heo   libata: make gtf_...
627
  		if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_AA &&
fa5b561c4   Tejun Heo   libata: implement...
628
629
  		    tf->nsect == SATA_FPDMA_AA)
  			return 1;
b344991ac   Tejun Heo   libata-acpi: filt...
630
  	}
3264a8d8f   Tejun Heo   libata-acpi: impl...
631
632
  	return 0;
  }
e1ddb4b6a   Alan Cox   [libata] add ACPI...
633
  /**
0e8634bf8   Tejun Heo   libata-acpi: impr...
634
   * ata_acpi_run_tf - send taskfile registers to host controller
3a32a8e96   Tejun Heo   libata-acpi: clea...
635
   * @dev: target ATA device
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
636
637
638
639
640
641
642
643
644
645
646
647
648
   * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
   *
   * Outputs ATA taskfile to standard ATA host controller using MMIO
   * or PIO as indicated by the ATA_FLAG_MMIO flag.
   * 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...
649
650
651
652
   * LOCKING:
   * EH context.
   *
   * RETURNS:
3264a8d8f   Tejun Heo   libata-acpi: impl...
653
654
   * 1 if command is executed successfully.  0 if ignored, rejected or
   * filtered out, -errno on other errors.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
655
   */
0e8634bf8   Tejun Heo   libata-acpi: impr...
656
  static int ata_acpi_run_tf(struct ata_device *dev,
3264a8d8f   Tejun Heo   libata-acpi: impl...
657
658
  			   const struct ata_acpi_gtf *gtf,
  			   const struct ata_acpi_gtf *prev_gtf)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
659
  {
3264a8d8f   Tejun Heo   libata-acpi: impl...
660
661
  	struct ata_taskfile *pptf = NULL;
  	struct ata_taskfile tf, ptf, rtf;
4700c4bc9   Tejun Heo   libata-acpi: clea...
662
  	unsigned int err_mask;
0e8634bf8   Tejun Heo   libata-acpi: impr...
663
  	const char *level;
6521148c6   Robert Hancock   libata: add comma...
664
  	const char *descr;
0e8634bf8   Tejun Heo   libata-acpi: impr...
665
666
  	char msg[60];
  	int rc;
fc16c25ff   Jeff Garzik   [libata] ACPI: re...
667

4700c4bc9   Tejun Heo   libata-acpi: clea...
668
669
670
671
  	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...
672

3264a8d8f   Tejun Heo   libata-acpi: impl...
673
674
675
676
677
  	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_...
678
  	if (!ata_acpi_filter_tf(dev, &tf, pptf)) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
  		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...
707
  		level = KERN_INFO;
3264a8d8f   Tejun Heo   libata-acpi: impl...
708
  		snprintf(msg, sizeof(msg), "filtered out");
0e8634bf8   Tejun Heo   libata-acpi: impr...
709
  		rc = 0;
4700c4bc9   Tejun Heo   libata-acpi: clea...
710
  	}
6521148c6   Robert Hancock   libata: add comma...
711
  	descr = ata_get_cmd_descript(tf.command);
4700c4bc9   Tejun Heo   libata-acpi: clea...
712

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

0e8634bf8   Tejun Heo   libata-acpi: impr...
760
761
762
  	if (rc < 0)
  		return rc;
  	return 0;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
763
  }
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
764
765
  /**
   * ata_acpi_push_id - send Identify data to drive
3a32a8e96   Tejun Heo   libata-acpi: clea...
766
   * @dev: target ATA device
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
767
768
769
770
771
772
   *
   * _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...
773
774
775
776
777
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
f2406770a   Tejun Heo   libata-acpi: miss...
778
   * 0 on success, -ENOENT if _SDD doesn't exist, -errno on failure.
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
779
   */
6746544c3   Tejun Heo   libata: reimpleme...
780
  static int ata_acpi_push_id(struct ata_device *dev)
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
781
  {
9af5c9c97   Tejun Heo   libata-link: intr...
782
  	struct ata_port *ap = dev->link->ap;
3a32a8e96   Tejun Heo   libata-acpi: clea...
783
784
785
  	acpi_status status;
  	struct acpi_object_list input;
  	union acpi_object in_params[1];
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
786

7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
787
  	if (ata_msg_probe(ap))
3a32a8e96   Tejun Heo   libata-acpi: clea...
788
789
  		ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d
  ",
7f5e4e8d9   Harvey Harrison   ata: replace rema...
790
  			       __func__, dev->devno, ap->port_no);
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
791

7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
792
793
794
795
796
  	/* 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...
797
798
  	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...
799
800
801
  	/* Output buffer: _SDD has no output */
  
  	/* It's OK for _SDD to be missing too. */
3a32a8e96   Tejun Heo   libata-acpi: clea...
802
  	swap_buf_le16(dev->id, ATA_ID_WORDS);
fafbae87d   Tejun Heo   libata-acpi: impl...
803
  	status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
3a32a8e96   Tejun Heo   libata-acpi: clea...
804
  	swap_buf_le16(dev->id, ATA_ID_WORDS);
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
805

f2406770a   Tejun Heo   libata-acpi: miss...
806
807
808
809
  	if (status == AE_NOT_FOUND)
  		return -ENOENT;
  
  	if (ACPI_FAILURE(status)) {
69b16a5f4   Tejun Heo   libata-acpi: misc...
810
811
812
  		ata_dev_printk(dev, KERN_WARNING,
  			       "ACPI _SDD failed (AE 0x%x)
  ", status);
f2406770a   Tejun Heo   libata-acpi: miss...
813
814
  		return -EIO;
  	}
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
815

f2406770a   Tejun Heo   libata-acpi: miss...
816
  	return 0;
6746544c3   Tejun Heo   libata: reimpleme...
817
818
819
  }
  
  /**
64578a3de   Tejun Heo   libata-acpi: impl...
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
   * 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...
836
837
  	/* nada */
  	return 0;
64578a3de   Tejun Heo   libata-acpi: impl...
838
839
840
  }
  
  /**
6746544c3   Tejun Heo   libata: reimpleme...
841
842
843
844
845
846
847
848
849
850
851
   * 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...
852
  	const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
f58229f80   Tejun Heo   libata-link: impl...
853
  	struct ata_device *dev;
6746544c3   Tejun Heo   libata: reimpleme...
854

398e07826   Tejun Heo   libata-acpi: impl...
855
856
857
858
  	if (ap->acpi_handle && gtm) {
  		/* _GTM valid */
  
  		/* restore timing parameters */
c05e6ff03   Tejun Heo   libata-acpi: impl...
859
  		ata_acpi_stm(ap, gtm);
64578a3de   Tejun Heo   libata-acpi: impl...
860

398e07826   Tejun Heo   libata-acpi: impl...
861
862
863
864
  		/* _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...
865
  		ata_for_each_dev(dev, &ap->link, ALL) {
398e07826   Tejun Heo   libata-acpi: impl...
866
  			ata_acpi_clear_gtf(dev);
48feb3c41   Shaohua Li   ata-acpi: don't c...
867
868
  			if (ata_dev_enabled(dev) &&
  			    ata_dev_get_GTF(dev, NULL) >= 0)
398e07826   Tejun Heo   libata-acpi: impl...
869
870
871
872
873
874
875
  				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...
876
  		ata_for_each_dev(dev, &ap->link, ALL) {
398e07826   Tejun Heo   libata-acpi: impl...
877
  			ata_acpi_clear_gtf(dev);
48feb3c41   Shaohua Li   ata-acpi: don't c...
878
879
  			if (ata_dev_enabled(dev))
  				dev->flags |= ATA_DFLAG_ACPI_PENDING;
398e07826   Tejun Heo   libata-acpi: impl...
880
881
  		}
  	}
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
882
  }
6746544c3   Tejun Heo   libata: reimpleme...
883
  /**
bd3adca52   Shaohua Li   libata-acpi: add ...
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
   * 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...
902
903
  	ata_for_each_dev(dev, &ap->link, ENABLED) {
  		if (dev->acpi_handle)
bd3adca52   Shaohua Li   libata-acpi: add ...
904
905
906
907
908
909
910
911
912
  			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...
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
   * 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...
928
929
  	struct ata_port *ap = dev->link->ap;
  	struct ata_eh_context *ehc = &ap->link.eh_context;
6746544c3   Tejun Heo   libata: reimpleme...
930
  	int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
66fa7f215   Tejun Heo   libata-acpi: impr...
931
  	int nr_executed = 0;
6746544c3   Tejun Heo   libata: reimpleme...
932
  	int rc;
6746544c3   Tejun Heo   libata: reimpleme...
933
934
935
936
937
938
939
940
941
942
943
  	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...
944
  		if (rc && rc != -ENOENT)
6746544c3   Tejun Heo   libata: reimpleme...
945
946
947
948
  			goto acpi_err;
  	}
  
  	/* do _GTF */
66fa7f215   Tejun Heo   libata-acpi: impr...
949
950
  	rc = ata_acpi_exec_tfs(dev, &nr_executed);
  	if (rc)
6746544c3   Tejun Heo   libata: reimpleme...
951
952
953
954
955
  		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...
956
  	if (nr_executed) {
6746544c3   Tejun Heo   libata: reimpleme...
957
958
959
960
961
962
963
964
965
966
967
968
  		rc = ata_dev_reread_id(dev, 0);
  		if (rc < 0) {
  			ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY "
  				       "after ACPI commands
  ");
  			return rc;
  		}
  	}
  
  	return 0;
  
   acpi_err:
66fa7f215   Tejun Heo   libata-acpi: impr...
969
970
971
  	/* 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...
972

66fa7f215   Tejun Heo   libata-acpi: impr...
973
974
975
976
  	/* 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...
977
  	}
66fa7f215   Tejun Heo   libata-acpi: impr...
978
979
980
981
982
983
984
985
986
987
988
  
  	ata_dev_printk(dev, KERN_WARNING,
  		       "ACPI: failed the second time, disabled
  ");
  	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...
989
990
  	return rc;
  }
562f0c2d7   Tejun Heo   libata-acpi: add ...
991
992
993
994
995
996
997
998
999
1000
1001
1002
  
  /**
   * 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...
1003
  	ata_acpi_clear_gtf(dev);
562f0c2d7   Tejun Heo   libata-acpi: add ...
1004
  }