blob: a276c06dda95a8b5c71efa80e2a243283aaa59bf [file] [log] [blame]
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -07001/*
2 * libata-acpi.c
3 * Provides ACPI support for PATA/SATA.
4 *
5 * Copyright (C) 2006 Intel Corp.
6 * Copyright (C) 2006 Randy Dunlap
7 */
8
9#include <linux/ata.h>
10#include <linux/delay.h>
11#include <linux/device.h>
12#include <linux/errno.h>
13#include <linux/kernel.h>
14#include <linux/acpi.h>
15#include <linux/libata.h>
16#include <linux/pci.h>
17#include "libata.h"
18
19#include <acpi/acpi_bus.h>
20#include <acpi/acnames.h>
21#include <acpi/acnamesp.h>
22#include <acpi/acparser.h>
23#include <acpi/acexcep.h>
24#include <acpi/acmacros.h>
25#include <acpi/actypes.h>
26
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -070027#define NO_PORT_MULT 0xffff
Tejun Heofafbae82007-05-15 03:28:16 +090028#define SATA_ADR(root,pmp) (((root) << 16) | (pmp))
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -070029
30#define REGS_PER_GTF 7
Tejun Heo4700c4b2007-05-15 03:28:16 +090031struct ata_acpi_gtf {
32 u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
33} __packed;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -070034
Alan Coxca426632007-03-08 23:13:50 +000035/*
36 * Helper - belongs in the PCI layer somewhere eventually
37 */
38static int is_pci_dev(struct device *dev)
39{
40 return (dev->bus == &pci_bus_type);
41}
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -070042
Tejun Heod0df8b5d2007-09-23 13:19:54 +090043/**
44 * ata_acpi_associate_sata_port - associate SATA port with ACPI objects
45 * @ap: target SATA port
46 *
47 * Look up ACPI objects associated with @ap and initialize acpi_handle
48 * fields of @ap, the port and devices accordingly.
49 *
50 * LOCKING:
51 * EH context.
52 *
53 * RETURNS:
54 * 0 on success, -errno on failure.
55 */
56void ata_acpi_associate_sata_port(struct ata_port *ap)
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -070057{
Tejun Heod0df8b5d2007-09-23 13:19:54 +090058 WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA));
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -070059
Tejun Heod0df8b5d2007-09-23 13:19:54 +090060 if (!ap->nr_pmp_links) {
61 acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
62
63 ap->link.device->acpi_handle =
64 acpi_get_child(ap->host->acpi_handle, adr);
65 } else {
66 struct ata_link *link;
67
68 ap->link.device->acpi_handle = NULL;
69
70 ata_port_for_each_link(link, ap) {
71 acpi_integer adr = SATA_ADR(ap->port_no, link->pmp);
72
73 link->device->acpi_handle =
74 acpi_get_child(ap->host->acpi_handle, adr);
75 }
76 }
Tejun Heofafbae82007-05-15 03:28:16 +090077}
Alan Coxca426632007-03-08 23:13:50 +000078
Tejun Heofafbae82007-05-15 03:28:16 +090079static void ata_acpi_associate_ide_port(struct ata_port *ap)
80{
81 int max_devices, i;
82
83 ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no);
84 if (!ap->acpi_handle)
85 return;
86
87 max_devices = 1;
88 if (ap->flags & ATA_FLAG_SLAVE_POSS)
89 max_devices++;
90
91 for (i = 0; i < max_devices; i++) {
Tejun Heo9af5c9c2007-08-06 18:36:22 +090092 struct ata_device *dev = &ap->link.device[i];
Tejun Heofafbae82007-05-15 03:28:16 +090093
94 dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
95 }
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -070096}
97
98/**
Tejun Heofafbae82007-05-15 03:28:16 +090099 * ata_acpi_associate - associate ATA host with ACPI objects
100 * @host: target ATA host
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700101 *
Tejun Heofafbae82007-05-15 03:28:16 +0900102 * Look up ACPI objects associated with @host and initialize
103 * acpi_handle fields of @host, its ports and devices accordingly.
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700104 *
Tejun Heofafbae82007-05-15 03:28:16 +0900105 * LOCKING:
106 * EH context.
107 *
108 * RETURNS:
109 * 0 on success, -errno on failure.
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700110 */
Tejun Heofafbae82007-05-15 03:28:16 +0900111void ata_acpi_associate(struct ata_host *host)
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700112{
Tejun Heofafbae82007-05-15 03:28:16 +0900113 int i;
Alan Coxca426632007-03-08 23:13:50 +0000114
Tejun Heofafbae82007-05-15 03:28:16 +0900115 if (!is_pci_dev(host->dev) || libata_noacpi)
116 return;
Alan Coxca426632007-03-08 23:13:50 +0000117
Tejun Heofafbae82007-05-15 03:28:16 +0900118 host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev);
119 if (!host->acpi_handle)
120 return;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700121
Tejun Heofafbae82007-05-15 03:28:16 +0900122 for (i = 0; i < host->n_ports; i++) {
123 struct ata_port *ap = host->ports[i];
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700124
Tejun Heofafbae82007-05-15 03:28:16 +0900125 if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA)
126 ata_acpi_associate_sata_port(ap);
127 else
128 ata_acpi_associate_ide_port(ap);
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700129 }
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700130}
131
132/**
Tejun Heo64578a32007-05-15 03:28:16 +0900133 * ata_acpi_gtm - execute _GTM
134 * @ap: target ATA port
135 * @gtm: out parameter for _GTM result
136 *
137 * Evaluate _GTM and store the result in @gtm.
138 *
139 * LOCKING:
140 * EH context.
141 *
142 * RETURNS:
143 * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
144 */
145static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm)
146{
147 struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
148 union acpi_object *out_obj;
149 acpi_status status;
150 int rc = 0;
151
152 status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output);
153
154 rc = -ENOENT;
155 if (status == AE_NOT_FOUND)
156 goto out_free;
157
158 rc = -EINVAL;
159 if (ACPI_FAILURE(status)) {
160 ata_port_printk(ap, KERN_ERR,
161 "ACPI get timing mode failed (AE 0x%x)\n",
162 status);
163 goto out_free;
164 }
165
166 out_obj = output.pointer;
167 if (out_obj->type != ACPI_TYPE_BUFFER) {
168 ata_port_printk(ap, KERN_WARNING,
169 "_GTM returned unexpected object type 0x%x\n",
170 out_obj->type);
171
172 goto out_free;
173 }
174
175 if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) {
176 ata_port_printk(ap, KERN_ERR,
177 "_GTM returned invalid length %d\n",
178 out_obj->buffer.length);
179 goto out_free;
180 }
181
182 memcpy(gtm, out_obj->buffer.pointer, sizeof(struct ata_acpi_gtm));
183 rc = 0;
184 out_free:
185 kfree(output.pointer);
186 return rc;
187}
188
189/**
190 * ata_acpi_stm - execute _STM
191 * @ap: target ATA port
192 * @stm: timing parameter to _STM
193 *
194 * Evaluate _STM with timing parameter @stm.
195 *
196 * LOCKING:
197 * EH context.
198 *
199 * RETURNS:
200 * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure.
201 */
202static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
203{
204 acpi_status status;
205 struct acpi_object_list input;
206 union acpi_object in_params[3];
207
208 in_params[0].type = ACPI_TYPE_BUFFER;
209 in_params[0].buffer.length = sizeof(struct ata_acpi_gtm);
210 in_params[0].buffer.pointer = (u8 *)stm;
211 /* Buffers for id may need byteswapping ? */
212 in_params[1].type = ACPI_TYPE_BUFFER;
213 in_params[1].buffer.length = 512;
Tejun Heo9af5c9c2007-08-06 18:36:22 +0900214 in_params[1].buffer.pointer = (u8 *)ap->link.device[0].id;
Tejun Heo64578a32007-05-15 03:28:16 +0900215 in_params[2].type = ACPI_TYPE_BUFFER;
216 in_params[2].buffer.length = 512;
Tejun Heo9af5c9c2007-08-06 18:36:22 +0900217 in_params[2].buffer.pointer = (u8 *)ap->link.device[1].id;
Tejun Heo64578a32007-05-15 03:28:16 +0900218
219 input.count = 3;
220 input.pointer = in_params;
221
222 status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL);
223
224 if (status == AE_NOT_FOUND)
225 return -ENOENT;
226 if (ACPI_FAILURE(status)) {
227 ata_port_printk(ap, KERN_ERR,
228 "ACPI set timing mode failed (status=0x%x)\n", status);
229 return -EINVAL;
230 }
231 return 0;
232}
233
234/**
Tejun Heo4700c4b2007-05-15 03:28:16 +0900235 * ata_dev_get_GTF - get the drive bootup default taskfile settings
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900236 * @dev: target ATA device
Tejun Heo4700c4b2007-05-15 03:28:16 +0900237 * @gtf: output parameter for buffer containing _GTF taskfile arrays
238 * @ptr_to_free: pointer which should be freed
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700239 *
240 * This applies to both PATA and SATA drives.
241 *
242 * The _GTF method has no input parameters.
243 * It returns a variable number of register set values (registers
244 * hex 1F1..1F7, taskfiles).
245 * The <variable number> is not known in advance, so have ACPI-CA
246 * allocate the buffer as needed and return it, then free it later.
247 *
Tejun Heo4700c4b2007-05-15 03:28:16 +0900248 * LOCKING:
249 * EH context.
250 *
251 * RETURNS:
252 * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
253 * contain valid data. -errno on other errors.
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700254 */
Tejun Heo4700c4b2007-05-15 03:28:16 +0900255static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
256 void **ptr_to_free)
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700257{
Tejun Heo9af5c9c2007-08-06 18:36:22 +0900258 struct ata_port *ap = dev->link->ap;
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900259 acpi_status status;
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900260 struct acpi_buffer output;
261 union acpi_object *out_obj;
Tejun Heo4700c4b2007-05-15 03:28:16 +0900262 int rc = 0;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700263
Tejun Heo4700c4b2007-05-15 03:28:16 +0900264 /* set up output buffer */
265 output.length = ACPI_ALLOCATE_BUFFER;
266 output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700267
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700268 if (ata_msg_probe(ap))
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900269 ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
Tejun Heo878d4fe2007-02-21 16:36:33 +0900270 __FUNCTION__, ap->port_no);
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700271
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700272 /* _GTF has no input parameters */
Tejun Heo4700c4b2007-05-15 03:28:16 +0900273 status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
274
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700275 if (ACPI_FAILURE(status)) {
Tejun Heo4700c4b2007-05-15 03:28:16 +0900276 if (status != AE_NOT_FOUND) {
277 ata_dev_printk(dev, KERN_WARNING,
278 "_GTF evaluation failed (AE 0x%x)\n",
279 status);
280 rc = -EIO;
281 }
282 goto out_free;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700283 }
284
285 if (!output.length || !output.pointer) {
286 if (ata_msg_probe(ap))
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900287 ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: "
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700288 "length or ptr is NULL (0x%llx, 0x%p)\n",
289 __FUNCTION__,
290 (unsigned long long)output.length,
291 output.pointer);
Tejun Heo4700c4b2007-05-15 03:28:16 +0900292 goto out_free;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700293 }
294
295 out_obj = output.pointer;
296 if (out_obj->type != ACPI_TYPE_BUFFER) {
Tejun Heo69b16a52007-05-15 03:28:16 +0900297 ata_dev_printk(dev, KERN_WARNING,
298 "_GTF unexpected object type 0x%x\n",
299 out_obj->type);
Tejun Heo4700c4b2007-05-15 03:28:16 +0900300 rc = -EINVAL;
301 goto out_free;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700302 }
303
Tejun Heo4700c4b2007-05-15 03:28:16 +0900304 if (out_obj->buffer.length % REGS_PER_GTF) {
Tejun Heo69b16a52007-05-15 03:28:16 +0900305 ata_dev_printk(dev, KERN_WARNING,
306 "unexpected _GTF length (%d)\n",
307 out_obj->buffer.length);
Tejun Heo4700c4b2007-05-15 03:28:16 +0900308 rc = -EINVAL;
309 goto out_free;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700310 }
311
Tejun Heo4700c4b2007-05-15 03:28:16 +0900312 *ptr_to_free = out_obj;
313 *gtf = (void *)out_obj->buffer.pointer;
314 rc = out_obj->buffer.length / REGS_PER_GTF;
315
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700316 if (ata_msg_probe(ap))
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900317 ata_dev_printk(dev, KERN_DEBUG, "%s: returning "
Tejun Heo4700c4b2007-05-15 03:28:16 +0900318 "gtf=%p, gtf_count=%d, ptr_to_free=%p\n",
319 __FUNCTION__, *gtf, rc, *ptr_to_free);
320 return rc;
321
322 out_free:
323 kfree(output.pointer);
324 return rc;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700325}
326
327/**
Alan Coxe1ddb4b2007-08-16 02:33:36 -0400328 * ata_acpi_cbl_80wire - Check for 80 wire cable
329 * @ap: Port to check
330 *
331 * Return 1 if the ACPI mode data for this port indicates the BIOS selected
332 * an 80wire mode.
333 */
334
335int ata_acpi_cbl_80wire(struct ata_port *ap)
336{
337 struct ata_acpi_gtm gtm;
338 int valid = 0;
339
340 /* No _GTM data, no information */
341 if (ata_acpi_gtm(ap, &gtm) < 0)
342 return 0;
343
344 /* Split timing, DMA enabled */
345 if ((gtm.flags & 0x11) == 0x11 && gtm.drive[0].dma < 55)
346 valid |= 1;
347 if ((gtm.flags & 0x14) == 0x14 && gtm.drive[1].dma < 55)
348 valid |= 2;
349 /* Shared timing, DMA enabled */
350 if ((gtm.flags & 0x11) == 0x01 && gtm.drive[0].dma < 55)
351 valid |= 1;
352 if ((gtm.flags & 0x14) == 0x04 && gtm.drive[0].dma < 55)
353 valid |= 2;
354
355 /* Drive check */
356 if ((valid & 1) && ata_dev_enabled(&ap->link.device[0]))
357 return 1;
358 if ((valid & 2) && ata_dev_enabled(&ap->link.device[1]))
359 return 1;
360 return 0;
361}
362
363EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
364
365/**
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700366 * taskfile_load_raw - send taskfile registers to host controller
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900367 * @dev: target ATA device
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700368 * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
369 *
370 * Outputs ATA taskfile to standard ATA host controller using MMIO
371 * or PIO as indicated by the ATA_FLAG_MMIO flag.
372 * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
373 * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
374 * hob_lbal, hob_lbam, and hob_lbah.
375 *
376 * This function waits for idle (!BUSY and !DRQ) after writing
377 * registers. If the control register has a new value, this
378 * function also waits for idle after writing control and before
379 * writing the remaining registers.
380 *
Tejun Heo4700c4b2007-05-15 03:28:16 +0900381 * LOCKING:
382 * EH context.
383 *
384 * RETURNS:
385 * 0 on success, -errno on failure.
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700386 */
Tejun Heo4700c4b2007-05-15 03:28:16 +0900387static int taskfile_load_raw(struct ata_device *dev,
388 const struct ata_acpi_gtf *gtf)
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700389{
Tejun Heo9af5c9c2007-08-06 18:36:22 +0900390 struct ata_port *ap = dev->link->ap;
Tejun Heo4700c4b2007-05-15 03:28:16 +0900391 struct ata_taskfile tf, rtf;
392 unsigned int err_mask;
Jeff Garzikfc16c252007-02-24 21:05:01 -0500393
Tejun Heo4700c4b2007-05-15 03:28:16 +0900394 if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0)
395 && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
396 && (gtf->tf[6] == 0))
397 return 0;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700398
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900399 ata_tf_init(dev, &tf);
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700400
Jeff Garzikfc16c252007-02-24 21:05:01 -0500401 /* convert gtf to tf */
402 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
Tejun Heo48be6b12007-04-23 02:06:46 +0900403 tf.protocol = ATA_PROT_NODATA;
Tejun Heo4700c4b2007-05-15 03:28:16 +0900404 tf.feature = gtf->tf[0]; /* 0x1f1 */
405 tf.nsect = gtf->tf[1]; /* 0x1f2 */
406 tf.lbal = gtf->tf[2]; /* 0x1f3 */
407 tf.lbam = gtf->tf[3]; /* 0x1f4 */
408 tf.lbah = gtf->tf[4]; /* 0x1f5 */
409 tf.device = gtf->tf[5]; /* 0x1f6 */
410 tf.command = gtf->tf[6]; /* 0x1f7 */
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700411
Tejun Heo4700c4b2007-05-15 03:28:16 +0900412 if (ata_msg_probe(ap))
413 ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd "
414 "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n",
415 tf.command, tf.feature, tf.nsect,
416 tf.lbal, tf.lbam, tf.lbah, tf.device);
417
418 rtf = tf;
419 err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0);
420 if (err_mask) {
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900421 ata_dev_printk(dev, KERN_ERR,
Tejun Heo4700c4b2007-05-15 03:28:16 +0900422 "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed "
423 "(Emask=0x%x Stat=0x%02x Err=0x%02x)\n",
424 tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam,
425 tf.lbah, tf.device, err_mask, rtf.command, rtf.feature);
426 return -EIO;
427 }
428
429 return 0;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700430}
431
432/**
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700433 * ata_acpi_exec_tfs - get then write drive taskfile settings
Tejun Heo67465442007-05-15 03:28:16 +0900434 * @dev: target ATA device
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700435 *
Tejun Heo67465442007-05-15 03:28:16 +0900436 * Evaluate _GTF and excute returned taskfiles.
Tejun Heo69b16a52007-05-15 03:28:16 +0900437 *
438 * LOCKING:
439 * EH context.
440 *
441 * RETURNS:
Tejun Heo67465442007-05-15 03:28:16 +0900442 * Number of executed taskfiles on success, 0 if _GTF doesn't exist or
443 * doesn't contain valid data. -errno on other errors.
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700444 */
Tejun Heo67465442007-05-15 03:28:16 +0900445static int ata_acpi_exec_tfs(struct ata_device *dev)
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700446{
Tejun Heo67465442007-05-15 03:28:16 +0900447 struct ata_acpi_gtf *gtf = NULL;
448 void *ptr_to_free = NULL;
449 int gtf_count, i, rc;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700450
Tejun Heo67465442007-05-15 03:28:16 +0900451 /* get taskfiles */
452 rc = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
453 if (rc < 0)
454 return rc;
455 gtf_count = rc;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700456
Tejun Heo67465442007-05-15 03:28:16 +0900457 /* execute them */
458 for (i = 0, rc = 0; i < gtf_count; i++) {
459 int tmp;
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900460
Tejun Heo67465442007-05-15 03:28:16 +0900461 /* ACPI errors are eventually ignored. Run till the
462 * end even after errors.
463 */
464 tmp = taskfile_load_raw(dev, gtf++);
465 if (!rc)
466 rc = tmp;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700467 }
468
Tejun Heo67465442007-05-15 03:28:16 +0900469 kfree(ptr_to_free);
470
471 if (rc == 0)
472 return gtf_count;
473 return rc;
Kristen Carlson Accardi11ef6972006-09-28 11:29:01 -0700474}
475
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700476/**
477 * ata_acpi_push_id - send Identify data to drive
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900478 * @dev: target ATA device
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700479 *
480 * _SDD ACPI object: for SATA mode only
481 * Must be after Identify (Packet) Device -- uses its data
482 * ATM this function never returns a failure. It is an optional
483 * method and if it fails for whatever reason, we should still
484 * just keep going.
Tejun Heo69b16a52007-05-15 03:28:16 +0900485 *
486 * LOCKING:
487 * EH context.
488 *
489 * RETURNS:
490 * 0 on success, -errno on failure.
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700491 */
Tejun Heo67465442007-05-15 03:28:16 +0900492static int ata_acpi_push_id(struct ata_device *dev)
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700493{
Tejun Heo9af5c9c2007-08-06 18:36:22 +0900494 struct ata_port *ap = dev->link->ap;
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900495 int err;
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900496 acpi_status status;
497 struct acpi_object_list input;
498 union acpi_object in_params[1];
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700499
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700500 if (ata_msg_probe(ap))
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900501 ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
502 __FUNCTION__, dev->devno, ap->port_no);
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700503
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700504 /* Give the drive Identify data to the drive via the _SDD method */
505 /* _SDD: set up input parameters */
506 input.count = 1;
507 input.pointer = in_params;
508 in_params[0].type = ACPI_TYPE_BUFFER;
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900509 in_params[0].buffer.length = sizeof(dev->id[0]) * ATA_ID_WORDS;
510 in_params[0].buffer.pointer = (u8 *)dev->id;
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700511 /* Output buffer: _SDD has no output */
512
513 /* It's OK for _SDD to be missing too. */
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900514 swap_buf_le16(dev->id, ATA_ID_WORDS);
Tejun Heofafbae82007-05-15 03:28:16 +0900515 status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
Tejun Heo3a32a8e2007-05-05 23:50:38 +0900516 swap_buf_le16(dev->id, ATA_ID_WORDS);
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700517
518 err = ACPI_FAILURE(status) ? -EIO : 0;
Tejun Heo69b16a52007-05-15 03:28:16 +0900519 if (err < 0)
520 ata_dev_printk(dev, KERN_WARNING,
521 "ACPI _SDD failed (AE 0x%x)\n", status);
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700522
Tejun Heo67465442007-05-15 03:28:16 +0900523 return err;
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700524}
525
Tejun Heo67465442007-05-15 03:28:16 +0900526/**
Tejun Heo64578a32007-05-15 03:28:16 +0900527 * ata_acpi_on_suspend - ATA ACPI hook called on suspend
528 * @ap: target ATA port
529 *
530 * This function is called when @ap is about to be suspended. All
531 * devices are already put to sleep but the port_suspend() callback
532 * hasn't been executed yet. Error return from this function aborts
533 * suspend.
534 *
535 * LOCKING:
536 * EH context.
537 *
538 * RETURNS:
539 * 0 on success, -errno on failure.
540 */
541int ata_acpi_on_suspend(struct ata_port *ap)
542{
543 unsigned long flags;
544 int rc;
545
546 /* proceed iff per-port acpi_handle is valid */
547 if (!ap->acpi_handle)
548 return 0;
549 BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
550
551 /* store timing parameters */
552 rc = ata_acpi_gtm(ap, &ap->acpi_gtm);
553
554 spin_lock_irqsave(ap->lock, flags);
555 if (rc == 0)
556 ap->pflags |= ATA_PFLAG_GTM_VALID;
557 else
558 ap->pflags &= ~ATA_PFLAG_GTM_VALID;
559 spin_unlock_irqrestore(ap->lock, flags);
560
561 if (rc == -ENOENT)
562 rc = 0;
563 return rc;
564}
565
566/**
Tejun Heo67465442007-05-15 03:28:16 +0900567 * ata_acpi_on_resume - ATA ACPI hook called on resume
568 * @ap: target ATA port
569 *
570 * This function is called when @ap is resumed - right after port
571 * itself is resumed but before any EH action is taken.
572 *
573 * LOCKING:
574 * EH context.
575 */
576void ata_acpi_on_resume(struct ata_port *ap)
577{
Tejun Heof58229f2007-08-06 18:36:23 +0900578 struct ata_device *dev;
Kristen Carlson Accardi7ea1fbc2006-09-28 11:29:12 -0700579
Tejun Heo64578a32007-05-15 03:28:16 +0900580 if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) {
581 BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
582
583 /* restore timing parameters */
584 ata_acpi_stm(ap, &ap->acpi_gtm);
585 }
586
Tejun Heo67465442007-05-15 03:28:16 +0900587 /* schedule _GTF */
Tejun Heof58229f2007-08-06 18:36:23 +0900588 ata_link_for_each_dev(dev, &ap->link)
589 dev->flags |= ATA_DFLAG_ACPI_PENDING;
Tejun Heo67465442007-05-15 03:28:16 +0900590}
591
592/**
593 * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration
594 * @dev: target ATA device
595 *
596 * This function is called when @dev is about to be configured.
597 * IDENTIFY data might have been modified after this hook is run.
598 *
599 * LOCKING:
600 * EH context.
601 *
602 * RETURNS:
603 * Positive number if IDENTIFY data needs to be refreshed, 0 if not,
604 * -errno on failure.
605 */
606int ata_acpi_on_devcfg(struct ata_device *dev)
607{
Tejun Heo9af5c9c2007-08-06 18:36:22 +0900608 struct ata_port *ap = dev->link->ap;
609 struct ata_eh_context *ehc = &ap->link.eh_context;
Tejun Heo67465442007-05-15 03:28:16 +0900610 int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
611 int rc;
612
Tejun Heo67465442007-05-15 03:28:16 +0900613 if (!dev->acpi_handle)
614 return 0;
615
616 /* do we need to do _GTF? */
617 if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) &&
618 !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET)))
619 return 0;
620
621 /* do _SDD if SATA */
622 if (acpi_sata) {
623 rc = ata_acpi_push_id(dev);
624 if (rc)
625 goto acpi_err;
626 }
627
628 /* do _GTF */
629 rc = ata_acpi_exec_tfs(dev);
630 if (rc < 0)
631 goto acpi_err;
632
633 dev->flags &= ~ATA_DFLAG_ACPI_PENDING;
634
635 /* refresh IDENTIFY page if any _GTF command has been executed */
636 if (rc > 0) {
637 rc = ata_dev_reread_id(dev, 0);
638 if (rc < 0) {
639 ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY "
640 "after ACPI commands\n");
641 return rc;
642 }
643 }
644
645 return 0;
646
647 acpi_err:
648 /* let EH retry on the first failure, disable ACPI on the second */
649 if (dev->flags & ATA_DFLAG_ACPI_FAILED) {
650 ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the "
651 "second time, disabling (errno=%d)\n", rc);
652
653 dev->acpi_handle = NULL;
654
655 /* if port is working, request IDENTIFY reload and continue */
656 if (!(ap->pflags & ATA_PFLAG_FROZEN))
657 rc = 1;
658 }
659 dev->flags |= ATA_DFLAG_ACPI_FAILED;
660 return rc;
661}