fe091aae9edaa54bb93706a34ae6a342313f62ab
[dragonfly.git] / sys / dev / disk / ahci / ahci_pm.c
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 #include "ahci.h"
36
37 static void ahci_pm_dummy_done(struct ata_xfer *xa);
38 static void ahci_pm_empty_done(struct ahci_ccb *ccb);
39
40 /*
41  * Identify the port multiplier
42  */
43 int
44 ahci_pm_identify(struct ahci_port *ap)
45 {
46         u_int32_t chipid;
47         u_int32_t rev;
48         u_int32_t nports;
49         u_int32_t data1;
50         u_int32_t data2;
51
52         ap->ap_pmcount = 0;
53         ap->ap_probe = ATA_PROBE_FAILED;
54         if (ahci_pm_read(ap, 15, 0, &chipid))
55                 goto err;
56         if (ahci_pm_read(ap, 15, 1, &rev))
57                 goto err;
58         if (ahci_pm_read(ap, 15, 2, &nports))
59                 goto err;
60         nports &= 0x0000000F;   /* only the low 4 bits */
61         ap->ap_probe = ATA_PROBE_GOOD;
62         kprintf("%s: Port multiplier: chip=%08x rev=0x%b nports=%d\n",
63                 PORTNAME(ap),
64                 chipid,
65                 rev, AHCI_PFMT_PM_REV,
66                 nports);
67         ap->ap_pmcount = nports;
68
69         if (ahci_pm_read(ap, 15, AHCI_PMREG_FEA, &data1)) {
70                 kprintf("%s: Port multiplier: Warning, "
71                         "cannot read feature register\n", PORTNAME(ap));
72         } else {
73                 kprintf("%s: Port multiplier features: 0x%b\n",
74                         PORTNAME(ap),
75                         data1,
76                         AHCI_PFMT_PM_FEA);
77         }
78         if (ahci_pm_read(ap, 15, AHCI_PMREG_FEAEN, &data2) == 0) {
79                 kprintf("%s: Port multiplier defaults: 0x%b\n",
80                         PORTNAME(ap),
81                         data2,
82                         AHCI_PFMT_PM_FEA);
83         }
84
85         /*
86          * Turn on async notification if we support and the PM supports it.
87          * This allows the PM to forward async notification events to us and
88          * it will also generate an event for target 15 for hot-plug events
89          * (or is supposed to anyway).
90          */
91         if ((ap->ap_sc->sc_cap & AHCI_REG_CAP_SSNTF) &&
92             (data1 & AHCI_PMFEA_ASYNCNOTIFY)) {
93                 u_int32_t serr_bits = AHCI_PREG_SERR_DIAG_N |
94                                       AHCI_PREG_SERR_DIAG_X;
95                 data2 |= AHCI_PMFEA_ASYNCNOTIFY;
96                 if (ahci_pm_write(ap, 15, AHCI_PMREG_FEAEN, data2)) {
97                         kprintf("%s: Port multiplier: AsyncNotify cannot be "
98                                 "enabled\n", PORTNAME(ap));
99                 } else if (ahci_pm_write(ap, 15, AHCI_PMREG_EEENA, serr_bits)) {
100                         kprintf("%s: Port mulltiplier: AsyncNotify unable "
101                                 "to enable error info bits\n", PORTNAME(ap));
102                 } else {
103                         kprintf("%s: Port multiplier: AsyncNotify enabled\n",
104                                 PORTNAME(ap));
105                 }
106         }
107
108         return (0);
109 err:
110         kprintf("%s: Port multiplier cannot be identified\n", PORTNAME(ap));
111         return (EIO);
112 }
113
114 /*
115  * Do a COMRESET sequence on the target behind a port multiplier.
116  *
117  * If hard is 2 we also cycle the phy on the target.
118  *
119  * This must be done prior to any softreset or probe attempts on
120  * targets behind the port multiplier.
121  *
122  * Returns 0 on success or an error.
123  */
124 int
125 ahci_pm_hardreset(struct ahci_port *ap, int target, int hard)
126 {
127         struct ata_port *at;
128         u_int32_t data;
129         int loop;
130         int error = EIO;
131
132         kprintf("%s.%d: ahci_pm_hardreset hard=%d\n",
133                 PORTNAME(ap), target, hard);
134
135         at = &ap->ap_ata[target];
136
137         /*
138          * Turn off power management and kill the phy on the target
139          * if requested.  Hold state for 10ms.
140          */
141         data = AHCI_PREG_SCTL_IPM_DISABLED;
142         if (hard == 2)
143                 data |= AHCI_PREG_SCTL_DET_DISABLE;
144         if (ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1))
145                 goto err;
146         if (ahci_pm_write(ap, target, AHCI_PMREG_SCTL, data))
147                 goto err;
148         ahci_os_sleep(10);
149
150         /*
151          * Start transmitting COMRESET.  COMRESET must be sent for at
152          * least 1ms.
153          */
154         at->at_probe = ATA_PROBE_FAILED;
155         at->at_type = ATA_PORT_T_NONE;
156         data = AHCI_PREG_SCTL_IPM_DISABLED | AHCI_PREG_SCTL_DET_INIT;
157         if (AhciForceGen1 & (1 << ap->ap_num)) {
158                 kprintf("%s.%d: Force 1.5GBits\n", PORTNAME(ap), target);
159                 data |= AHCI_PREG_SCTL_SPD_GEN1;
160         } else {
161                 data |= AHCI_PREG_SCTL_SPD_ANY;
162         }
163         if (ahci_pm_write(ap, target, AHCI_PMREG_SCTL, data))
164                 goto err;
165         ahci_os_sleep(2);
166
167 #if 0
168         if (ahci_pm_phy_status(ap, target, &data)) {
169                 kprintf("%s: Cannot clear phy status\n",
170                         ATANAME(ap ,at));
171         }
172 #endif
173
174         /*
175          * Flush any status, then clear DET to initiate negotiation.
176          */
177         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
178         data = AHCI_PREG_SCTL_IPM_DISABLED | AHCI_PREG_SCTL_DET_NONE;
179         if (ahci_pm_write(ap, target, AHCI_PMREG_SCTL, data))
180                 goto err;
181
182         /*
183          * Try to determine if there is a device on the port.
184          *
185          * Give the device 3/10 second to at least be detected.
186          * If we fail clear any pending status since we may have
187          * cycled the phy and probably caused another PRCS interrupt.
188          */
189         for (loop = 3; loop; --loop) {
190                 if (ahci_pm_read(ap, target, AHCI_PMREG_SSTS, &data))
191                         goto err;
192                 if (data & AHCI_PREG_SSTS_DET)
193                         break;
194                 ahci_os_sleep(100);
195         }
196         if (loop == 0) {
197                 kprintf("%s.%d: Port appears to be unplugged\n",
198                         PORTNAME(ap), target);
199                 error = ENODEV;
200                 goto err;
201         }
202
203         /*
204          * There is something on the port.  Give the device 3 seconds
205          * to fully negotiate.
206          */
207         for (loop = 30; loop; --loop) {
208                 if (ahci_pm_read(ap, target, AHCI_PMREG_SSTS, &data))
209                         goto err;
210                 if ((data & AHCI_PREG_SSTS_DET) == AHCI_PREG_SSTS_DET_DEV)
211                         break;
212                 ahci_os_sleep(100);
213         }
214
215         /*
216          * Clear SERR on the target so we get a new NOTIFY event if a hot-plug
217          * or hot-unplug occurs.
218          */
219         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
220
221         /*
222          * Device not detected
223          */
224         if (loop == 0) {
225                 kprintf("%s: Device may be powered down\n",
226                         PORTNAME(ap));
227                 error = ENODEV;
228                 goto err;
229         }
230
231         /*
232          * Device detected
233          */
234         kprintf("%s.%d: Device detected data=%08x\n",
235                 PORTNAME(ap), target, data);
236         ahci_os_sleep(100);
237         error = 0;
238 err:
239         at->at_probe = error ? ATA_PROBE_FAILED : ATA_PROBE_NEED_SOFT_RESET;
240         return (EIO);
241 }
242
243 /*
244  * AHCI soft reset through port multiplier.
245  *
246  * This function keeps port communications intact and attempts to generate
247  * a reset to the connected device using device commands.  Unlike
248  * hard-port operations we can't do fancy stop/starts or stuff like
249  * that without messing up other commands that might be running or
250  * queued.
251  */
252 int
253 ahci_pm_softreset(struct ahci_port *ap, int target)
254 {
255         struct ata_port         *at;
256         struct ahci_ccb         *ccb = NULL;
257         struct ahci_cmd_hdr     *cmd_slot;
258         u_int8_t                *fis;
259         int                     count;
260         int                     error;
261         u_int32_t               data;
262         int                     tried_longer;
263
264         error = EIO;
265         at = &ap->ap_ata[target];
266
267         DPRINTF(AHCI_D_VERBOSE, "%s: soft reset\n", PORTNAME(ap));
268
269         kprintf("%s: ahci_pm_softreset\n", ATANAME(ap, at));
270         count = 2;
271         tried_longer = 0;
272 retry:
273         /*
274          * Try to clear the phy so we get a good signature, otherwise
275          * the PM may not latch a new signature.
276          *
277          * NOTE: This cannot be safely done between the first and second
278          *       softreset FISs.  It's now or never.
279          */
280 #if 1
281         if (ahci_pm_phy_status(ap, target, &data)) {
282                 kprintf("%s: Cannot clear phy status\n",
283                         ATANAME(ap ,at));
284         }
285 #endif
286
287         /*
288          * Prep first D2H command with SRST feature & clear busy/reset flags
289          *
290          * It is unclear which other fields in the FIS are used.  Just zero
291          * everything.
292          *
293          * When soft-resetting a port behind a multiplier at will be
294          * non-NULL, assigning it to the ccb prevents the port interrupt
295          * from hard-resetting the port if a problem crops up.
296          */
297         ccb = ahci_get_ccb(ap);
298         ccb->ccb_done = ahci_pm_empty_done;
299         ccb->ccb_xa.flags = ATA_F_READ | ATA_F_POLL;
300         ccb->ccb_xa.complete = ahci_pm_dummy_done;
301         ccb->ccb_xa.at = at;
302
303         fis = ccb->ccb_cmd_table->cfis;
304         bzero(fis, sizeof(ccb->ccb_cmd_table->cfis));
305         fis[0] = ATA_FIS_TYPE_H2D;
306         fis[1] = at->at_target;
307         fis[15] = ATA_FIS_CONTROL_SRST|ATA_FIS_CONTROL_4BIT;
308
309         cmd_slot = ccb->ccb_cmd_hdr;
310         cmd_slot->prdtl = 0;
311         cmd_slot->flags = htole16(5);   /* FIS length: 5 DWORDS */
312         cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_C); /* Clear busy on OK */
313         cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_R); /* Reset */
314         cmd_slot->flags |= htole16(at->at_target <<
315                                    AHCI_CMD_LIST_FLAG_PMP_SHIFT);
316
317         ccb->ccb_xa.state = ATA_S_PENDING;
318         ccb->ccb_xa.flags = 0;
319
320         /*
321          * XXX hack to ignore IFS errors which can occur during the target
322          *     device's reset.
323          *
324          *     If an IFS error occurs the target is probably powering up,
325          *     so we try for a longer period of time.
326          */
327         ap->ap_flags |= AP_F_IGNORE_IFS;
328         ap->ap_flags &= ~(AP_F_IFS_IGNORED | AP_F_IFS_OCCURED);
329
330         if (ahci_poll(ccb, 1000, ahci_ata_cmd_timeout) != 0 ||
331             ccb->ccb_xa.state != ATA_S_COMPLETE) {
332                 kprintf("%s: First FIS failed\n", ATANAME(ap, at));
333                 if (tried_longer == 0 && (ap->ap_flags & AP_F_IFS_OCCURED)) {
334                         tried_longer = 1;
335                         count += 4;
336                 }
337                 if (--count) {
338                         fis[15] = 0;
339                         ahci_put_ccb(ccb);
340                         goto retry;
341                 }
342                 goto err;
343         }
344
345         /*
346          * The device may muff the PHY up.
347          */
348         ahci_os_sleep(100);     /* XXX 3ms should do it? */
349
350         /*
351          * Prep second D2H command to read status and complete reset sequence
352          * AHCI 10.4.1 and "Serial ATA Revision 2.6".  I can't find the ATA
353          * Rev 2.6 and it is unclear how the second FIS should be set up
354          * from the AHCI document.
355          *
356          * Give the device 3ms before sending the second FIS.
357          *
358          * It is unclear which other fields in the FIS are used.  Just zero
359          * everything.
360          */
361         bzero(fis, sizeof(ccb->ccb_cmd_table->cfis));
362         fis[0] = ATA_FIS_TYPE_H2D;
363         fis[1] = at->at_target;
364         fis[15] = ATA_FIS_CONTROL_4BIT;
365
366         cmd_slot->prdtl = 0;
367         cmd_slot->flags = htole16(5);   /* FIS length: 5 DWORDS */
368         cmd_slot->flags |= htole16(at->at_target <<
369                                    AHCI_CMD_LIST_FLAG_PMP_SHIFT);
370
371         ccb->ccb_xa.state = ATA_S_PENDING;
372         ccb->ccb_xa.flags = 0;
373
374         if (ahci_poll(ccb, 1000, ahci_ata_cmd_timeout) != 0 ||
375             ccb->ccb_xa.state != ATA_S_COMPLETE) {
376                 kprintf("%s: Second FIS failed\n", ATANAME(ap, at));
377                 if (--count) {
378                         fis[15] = 0;
379                         ahci_put_ccb(ccb);
380                         goto retry;
381                 }
382                 goto err;
383         }
384
385         ahci_os_sleep(10);
386
387         /*
388          * Do it again, even if we think we got a good result
389          */
390         if (--count) {
391                 fis[15] = 0;
392                 ahci_put_ccb(ccb);
393                 goto retry;
394         }
395
396         /*
397          * If the softreset is trying to clear a BSY condition after a
398          * normal portreset we assign the port type.
399          *
400          * If the softreset is being run first as part of the ccb error
401          * processing code then report if the device signature changed
402          * unexpectedly.
403          */
404         if (at->at_type == ATA_PORT_T_NONE) {
405                 at->at_type = ahci_port_signature_detect(ap, at);
406         } else {
407                 if (ahci_port_signature_detect(ap, at) != at->at_type) {
408                         kprintf("%s: device signature unexpectedly "
409                                 "changed\n", ATANAME(ap, at));
410                         error = EBUSY; /* XXX */
411                 }
412         }
413         error = 0;
414
415         ahci_os_sleep(100);
416 err:
417         /*
418          * Clean up the CCB.  If the command failed it already went through
419          * the standard timeout handling and should no longer be active.
420          */
421         if (ccb) {
422                 KKASSERT((ap->ap_active & (1 << ccb->ccb_slot)) == 0);
423                 fis[15] = 0;
424                 ahci_put_ccb(ccb);
425         }
426
427         /*
428          * If we failed to softreset make the port quiescent, otherwise
429          * make sure the port's start/stop state matches what it was on
430          * entry.
431          *
432          * Don't kill the port if the softreset is on a port multiplier
433          * target, that would kill all the targets!
434          */
435
436         ap->ap_flags &= ~AP_F_IGNORE_IFS;
437
438         /*
439          * Clear error status so we can detect removal
440          */
441         if (ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1)) {
442                 kprintf("%s: ahci_pm_softreset unable to clear SERR\n",
443                         ATANAME(ap, at));
444         }
445
446         kprintf("%s: ahci_pm_softreset done %d\n", ATANAME(ap, at), error);
447
448         at->at_probe = error ? ATA_PROBE_FAILED : ATA_PROBE_NEED_IDENT;
449         return (error);
450 }
451
452
453 /*
454  * Return the phy status for a target behind a port multiplier and
455  * reset AHCI_PMREG_SERR.
456  *
457  * Returned bits follow AHCI_PREG_SSTS bits.  The AHCI_PREG_SSTS_SPD
458  * bits can be used to determine the link speed and will be 0 if there
459  * is no link.
460  *
461  * 0 is returned if any communications error occurs.
462  */
463 int
464 ahci_pm_phy_status(struct ahci_port *ap, int target, u_int32_t *datap)
465 {
466         int error;
467
468         error = ahci_pm_read(ap, target, AHCI_PMREG_SSTS, datap);
469         if (error == 0)
470                 error = ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
471         if (error)
472                 *datap = 0;
473         return(error);
474 }
475
476 int
477 ahci_pm_set_feature(struct ahci_port *ap, int feature, int enable)
478 {
479         struct ata_xfer *xa;
480         int status;
481         int error;
482
483         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
484
485         bzero(xa->fis, sizeof(*xa->fis));
486         xa->fis->type = ATA_FIS_TYPE_H2D;
487         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
488         xa->fis->command = enable ? ATA_C_SATA_FEATURE_ENA :
489                                     ATA_C_SATA_FEATURE_DIS;
490         xa->fis->sector_count = feature;
491         xa->fis->control = ATA_FIS_CONTROL_4BIT;
492
493         xa->complete = ahci_pm_dummy_done;
494         xa->datalen = 0;
495         xa->flags = ATA_F_READ | ATA_F_POLL;
496         xa->timeout = 1000;
497
498         status = ahci_ata_cmd(xa);
499         error = (status == ATA_COMPLETE && xa->state == ATA_S_COMPLETE) ?
500                 0 : EIO;
501         ahci_ata_put_xfer(xa);
502         return(error);
503 }
504
505 /*
506  * Check that a target is still good.
507  */
508 void
509 ahci_pm_check_good(struct ahci_port *ap, int target)
510 {
511         struct ata_port *at;
512         u_int32_t data;
513
514         /*
515          * It looks like we might have to read the EINFO register
516          * to allow the PM to generate a new event.
517          */
518         if (ahci_pm_read(ap, 15, AHCI_PMREG_EINFO, &data)) {
519                 kprintf("%s: Port multiplier EINFO could not be read\n",
520                         PORTNAME(ap));
521         }
522         if (ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1)) {
523                 kprintf("%s: Port multiplier: SERR could not be cleared\n",
524                         PORTNAME(ap));
525         }
526
527         if (target == CAM_TARGET_WILDCARD)
528                 return;
529
530         at = &ap->ap_ata[target];
531         if (ahci_pm_read(ap, target, AHCI_PMREG_SSTS, &data)) {
532                 kprintf("%s: Unable to access PM SSTS register target %d\n",
533                         PORTNAME(ap), target);
534                 return;
535         }
536         if ((data & AHCI_PREG_SSTS_DET) != AHCI_PREG_SSTS_DET_DEV) {
537                 if (at->at_probe != ATA_PROBE_FAILED) {
538                         at->at_probe = ATA_PROBE_FAILED;
539                         at->at_type = ATA_PORT_T_NONE;
540                         at->at_features |= ATA_PORT_F_RESCAN;
541                         kprintf("%s: HOTPLUG - Device removed\n",
542                                 ATANAME(ap, at));
543                 }
544         } else {
545                 if (at->at_probe == ATA_PROBE_FAILED) {
546                         at->at_probe = ATA_PROBE_NEED_HARD_RESET;
547                         at->at_features |= ATA_PORT_F_RESCAN;
548                         kprintf("%s: HOTPLUG - Device inserted\n",
549                                 ATANAME(ap, at));
550                 }
551         }
552 }
553
554 /*
555  * Read a PM register
556  */
557 int
558 ahci_pm_read(struct ahci_port *ap, int target, int which, u_int32_t *datap)
559 {
560         struct ata_xfer *xa;
561         int status;
562         int error;
563
564         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
565
566         bzero(xa->fis, sizeof(*xa->fis));
567         xa->fis->type = ATA_FIS_TYPE_H2D;
568         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
569         xa->fis->command = ATA_C_READ_PM;
570         xa->fis->features = which;
571         xa->fis->device = target | ATA_H2D_DEVICE_LBA;
572         xa->fis->control = ATA_FIS_CONTROL_4BIT;
573
574         xa->complete = ahci_pm_dummy_done;
575         xa->datalen = 0;
576         xa->flags = ATA_F_READ | ATA_F_POLL;
577         xa->timeout = 1000;
578
579         status = ahci_ata_cmd(xa);
580         if (status == ATA_COMPLETE && xa->state == ATA_S_COMPLETE) {
581                 *datap = xa->rfis.sector_count | (xa->rfis.lba_low << 8) |
582                        (xa->rfis.lba_mid << 16) | (xa->rfis.lba_high << 24);
583                 error = 0;
584         } else {
585                 kprintf("pm_read status %d xa->state %d\n", status, xa->state);
586                 *datap = 0;
587                 error = EIO;
588         }
589         ahci_ata_put_xfer(xa);
590         return (error);
591 }
592
593 /*
594  * Write a PM register
595  */
596 int
597 ahci_pm_write(struct ahci_port *ap, int target, int which, u_int32_t data)
598 {
599         struct ata_xfer *xa;
600         int status;
601         int error;
602
603         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
604
605         bzero(xa->fis, sizeof(*xa->fis));
606         xa->fis->type = ATA_FIS_TYPE_H2D;
607         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
608         xa->fis->command = ATA_C_WRITE_PM;
609         xa->fis->features = which;
610         xa->fis->device = target | ATA_H2D_DEVICE_LBA;
611         xa->fis->sector_count = (u_int8_t)data;
612         xa->fis->lba_low = (u_int8_t)(data >> 8);
613         xa->fis->lba_mid = (u_int8_t)(data >> 16);
614         xa->fis->lba_high = (u_int8_t)(data >> 24);
615         xa->fis->control = ATA_FIS_CONTROL_4BIT;
616
617         xa->complete = ahci_pm_dummy_done;
618         xa->datalen = 0;
619         xa->flags = ATA_F_READ | ATA_F_POLL;
620         xa->timeout = 1000;
621
622         status = ahci_ata_cmd(xa);
623         error = (status == ATA_COMPLETE && xa->state == ATA_S_COMPLETE) ?
624                 0 : EIO;
625         ahci_ata_put_xfer(xa);
626         return(error);
627 }
628
629 /*
630  * Dummy done callback for xa.
631  */
632 static void
633 ahci_pm_dummy_done(struct ata_xfer *xa)
634 {
635 }
636
637 static void
638 ahci_pm_empty_done(struct ahci_ccb *ccb)
639 {
640         ccb->ccb_xa.state = ATA_S_COMPLETE;
641 }