AHCI - Port Multiplier bug fixes
[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         at = &ap->ap_ata[target];
133
134         /*
135          * Turn off power management and kill the phy on the target
136          * if requested.  Hold state for 10ms.
137          */
138         data = AHCI_PREG_SCTL_IPM_DISABLED;
139         if (hard == 2)
140                 data |= AHCI_PREG_SCTL_DET_DISABLE;
141         if (ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1))
142                 goto err;
143         if (ahci_pm_write(ap, target, AHCI_PMREG_SCTL, data))
144                 goto err;
145         ahci_os_sleep(10);
146
147         /*
148          * Start transmitting COMRESET.  COMRESET must be sent for at
149          * least 1ms.
150          */
151         at->at_probe = ATA_PROBE_FAILED;
152         at->at_type = ATA_PORT_T_NONE;
153         data = AHCI_PREG_SCTL_IPM_DISABLED | AHCI_PREG_SCTL_DET_INIT;
154         if (AhciForceGen1 & (1 << ap->ap_num)) {
155                 kprintf("%s.%d: Force 1.5GBits\n", PORTNAME(ap), target);
156                 data |= AHCI_PREG_SCTL_SPD_GEN1;
157         } else {
158                 data |= AHCI_PREG_SCTL_SPD_ANY;
159         }
160         if (ahci_pm_write(ap, target, AHCI_PMREG_SCTL, data))
161                 goto err;
162
163         /*
164          * It takes about 100ms for the DET logic to settle down,
165          * from trial and error testing.  If this is too short
166          * the softreset code will fail.
167          */
168         ahci_os_sleep(100);
169
170         if (ahci_pm_phy_status(ap, target, &data)) {
171                 kprintf("%s: (A)Cannot clear phy status\n",
172                         ATANAME(ap ,at));
173         }
174
175         /*
176          * Flush any status, then clear DET to initiate negotiation.
177          */
178         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
179         data = AHCI_PREG_SCTL_IPM_DISABLED | AHCI_PREG_SCTL_DET_NONE;
180         if (ahci_pm_write(ap, target, AHCI_PMREG_SCTL, data))
181                 goto err;
182
183         /*
184          * Try to determine if there is a device on the port.
185          *
186          * Give the device 3/10 second to at least be detected.
187          * If we fail clear any pending status since we may have
188          * cycled the phy and probably caused another PRCS interrupt.
189          */
190         for (loop = 3; loop; --loop) {
191                 if (ahci_pm_read(ap, target, AHCI_PMREG_SSTS, &data))
192                         goto err;
193                 if (data & AHCI_PREG_SSTS_DET)
194                         break;
195                 ahci_os_sleep(100);
196         }
197         if (loop == 0) {
198                 kprintf("%s.%d: Port appears to be unplugged\n",
199                         PORTNAME(ap), target);
200                 error = ENODEV;
201                 goto err;
202         }
203
204         /*
205          * There is something on the port.  Give the device 3 seconds
206          * to fully negotiate.
207          */
208         for (loop = 30; loop; --loop) {
209                 if (ahci_pm_read(ap, target, AHCI_PMREG_SSTS, &data))
210                         goto err;
211                 if ((data & AHCI_PREG_SSTS_DET) == AHCI_PREG_SSTS_DET_DEV)
212                         break;
213                 ahci_os_sleep(100);
214         }
215
216         /*
217          * Device not detected
218          */
219         if (loop == 0) {
220                 kprintf("%s: Device may be powered down\n",
221                         PORTNAME(ap));
222                 error = ENODEV;
223                 goto err;
224         }
225
226         /*
227          * Device detected
228          */
229         kprintf("%s.%d: Device detected data=%08x\n",
230                 PORTNAME(ap), target, data);
231         /*
232          * Clear SERR on the target so we get a new NOTIFY event if a hot-plug
233          * or hot-unplug occurs.
234          */
235         ahci_os_sleep(100);
236
237         error = 0;
238 err:
239         at->at_probe = error ? ATA_PROBE_FAILED : ATA_PROBE_NEED_SOFT_RESET;
240         return (error);
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;
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         count = 2;
270         tried_longer = 0;
271 retry:
272         /*
273          * Try to clear the phy so we get a good signature, otherwise
274          * the PM may not latch a new signature.
275          *
276          * NOTE: This cannot be safely done between the first and second
277          *       softreset FISs.  It's now or never.
278          */
279 #if 1
280         if (ahci_pm_phy_status(ap, target, &data)) {
281                 kprintf("%s: (B)Cannot clear phy status\n",
282                         ATANAME(ap ,at));
283         }
284         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
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_err_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) != ATA_S_COMPLETE) {
331                 kprintf("%s: (PM) First FIS failed\n", ATANAME(ap, at));
332                 if (ap->ap_flags & AP_F_IFS_OCCURED) {
333                         if (tried_longer == 0)
334                                 count += 4;
335                         ++tried_longer;
336                 }
337                 ahci_put_err_ccb(ccb);
338                 if (--count)
339                         goto retry;
340                 goto err;
341         }
342
343         /*
344          * WARNING!  SENSITIVE TIME PERIOD!  WARNING!
345          *
346          * The first and second FISes are supposed to be back-to-back,
347          * I think the idea is to get the second sent and then after
348          * the device resets it will send a signature.  Do not delay
349          * here and most definitely do not issue any commands to other
350          * targets!
351          */
352
353         /*
354          * Prep second D2H command to read status and complete reset sequence
355          * AHCI 10.4.1 and "Serial ATA Revision 2.6".  I can't find the ATA
356          * Rev 2.6 and it is unclear how the second FIS should be set up
357          * from the AHCI document.
358          *
359          * Give the device 3ms before sending the second FIS.
360          *
361          * It is unclear which other fields in the FIS are used.  Just zero
362          * everything.
363          */
364         bzero(fis, sizeof(ccb->ccb_cmd_table->cfis));
365         fis[0] = ATA_FIS_TYPE_H2D;
366         fis[1] = at->at_target;
367         fis[15] = ATA_FIS_CONTROL_4BIT;
368
369         cmd_slot->prdtl = 0;
370         cmd_slot->flags = htole16(5);   /* FIS length: 5 DWORDS */
371         cmd_slot->flags |= htole16(at->at_target <<
372                                    AHCI_CMD_LIST_FLAG_PMP_SHIFT);
373
374         ccb->ccb_xa.state = ATA_S_PENDING;
375         ccb->ccb_xa.flags = 0;
376
377         if (ahci_poll(ccb, 1000, ahci_ata_cmd_timeout) != ATA_S_COMPLETE) {
378                 kprintf("%s: (PM) Second FIS failed\n", ATANAME(ap, at));
379                 ahci_put_err_ccb(ccb);
380 #if 1
381                 if (--count)
382                         goto retry;
383 #endif
384                 goto err;
385         }
386
387         ahci_put_err_ccb(ccb);
388         ahci_os_sleep(100);
389         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
390         if (ahci_pm_phy_status(ap, target, &data)) {
391                 kprintf("%s: (C)Cannot clear phy status\n",
392                         ATANAME(ap ,at));
393         }
394         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
395
396         /*
397          * Do it again, even if we think we got a good result
398          */
399         if (--count) {
400                 fis[15] = 0;
401                 goto retry;
402         }
403
404         /*
405          * If the softreset is trying to clear a BSY condition after a
406          * normal portreset we assign the port type.
407          *
408          * If the softreset is being run first as part of the ccb error
409          * processing code then report if the device signature changed
410          * unexpectedly.
411          */
412         if (at->at_type == ATA_PORT_T_NONE) {
413                 at->at_type = ahci_port_signature_detect(ap, at);
414         } else {
415                 if (ahci_port_signature_detect(ap, at) != at->at_type) {
416                         kprintf("%s: device signature unexpectedly "
417                                 "changed\n", ATANAME(ap, at));
418                         error = EBUSY; /* XXX */
419                 }
420         }
421         error = 0;
422
423         /*
424          * Who knows what kind of mess occured.  We have exclusive access
425          * to the port so try to clean up potential problems.
426          */
427         ahci_os_sleep(100);
428 err:
429         /*
430          * Clear error status so we can detect removal.
431          */
432         if (ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1)) {
433                 kprintf("%s: ahci_pm_softreset unable to clear SERR\n",
434                         ATANAME(ap, at));
435                 ap->ap_flags &= ~AP_F_IGNORE_IFS;
436         }
437         ahci_pwrite(ap, AHCI_PREG_SERR, -1);
438
439         at->at_probe = error ? ATA_PROBE_FAILED : ATA_PROBE_NEED_IDENT;
440         return (error);
441 }
442
443
444 /*
445  * Return the phy status for a target behind a port multiplier and
446  * reset AHCI_PMREG_SERR.
447  *
448  * Returned bits follow AHCI_PREG_SSTS bits.  The AHCI_PREG_SSTS_SPD
449  * bits can be used to determine the link speed and will be 0 if there
450  * is no link.
451  *
452  * 0 is returned if any communications error occurs.
453  */
454 int
455 ahci_pm_phy_status(struct ahci_port *ap, int target, u_int32_t *datap)
456 {
457         int error;
458
459         error = ahci_pm_read(ap, target, AHCI_PMREG_SSTS, datap);
460         if (error == 0)
461                 error = ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
462         if (error)
463                 *datap = 0;
464         return(error);
465 }
466
467 int
468 ahci_pm_set_feature(struct ahci_port *ap, int feature, int enable)
469 {
470         struct ata_xfer *xa;
471         int error;
472
473         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
474
475         bzero(xa->fis, sizeof(*xa->fis));
476         xa->fis->type = ATA_FIS_TYPE_H2D;
477         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
478         xa->fis->command = enable ? ATA_C_SATA_FEATURE_ENA :
479                                     ATA_C_SATA_FEATURE_DIS;
480         xa->fis->sector_count = feature;
481         xa->fis->control = ATA_FIS_CONTROL_4BIT;
482
483         xa->complete = ahci_pm_dummy_done;
484         xa->datalen = 0;
485         xa->flags = ATA_F_READ | ATA_F_POLL;
486         xa->timeout = 1000;
487
488         if (ahci_ata_cmd(xa) == ATA_S_COMPLETE)
489                 error = 0;
490         else
491                 error = EIO;
492         ahci_ata_put_xfer(xa);
493         return(error);
494 }
495
496 /*
497  * Check that a target is still good.
498  */
499 void
500 ahci_pm_check_good(struct ahci_port *ap, int target)
501 {
502         struct ata_port *at;
503         u_int32_t data;
504
505 #if 0
506         /*
507          * It looks like we might have to read the EINFO register
508          * to allow the PM to generate a new event.
509          */
510         if (ahci_pm_read(ap, 15, AHCI_PMREG_EINFO, &data)) {
511                 kprintf("%s: Port multiplier EINFO could not be read\n",
512                         PORTNAME(ap));
513         }
514 #endif
515         if (ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1)) {
516                 kprintf("%s: Port multiplier: SERR could not be cleared\n",
517                         PORTNAME(ap));
518         }
519
520         if (target == CAM_TARGET_WILDCARD)
521                 return;
522         at = &ap->ap_ata[target];
523
524         /*
525          * If the device needs an init or hard reset also make sure the
526          * PHY is turned on.
527          */
528         if (at->at_probe <= ATA_PROBE_NEED_HARD_RESET) {
529                 /*kprintf("%s DOHARD\n", ATANAME(ap, at));*/
530                 ahci_pm_hardreset(ap, target, 1);
531         }
532
533         /*
534          * Read the detect status
535          */
536         if (ahci_pm_read(ap, target, AHCI_PMREG_SSTS, &data)) {
537                 kprintf("%s: Unable to access PM SSTS register target %d\n",
538                         PORTNAME(ap), target);
539                 return;
540         }
541         if ((data & AHCI_PREG_SSTS_DET) != AHCI_PREG_SSTS_DET_DEV) {
542                 /*kprintf("%s: DETECT %08x\n", ATANAME(ap, at), data);*/
543                 if (at->at_probe != ATA_PROBE_FAILED) {
544                         at->at_probe = ATA_PROBE_FAILED;
545                         at->at_type = ATA_PORT_T_NONE;
546                         at->at_features |= ATA_PORT_F_RESCAN;
547                         kprintf("%s: HOTPLUG (PM) - Device removed\n",
548                                 ATANAME(ap, at));
549                 }
550         } else {
551                 if (at->at_probe == ATA_PROBE_FAILED) {
552                         at->at_probe = ATA_PROBE_NEED_HARD_RESET;
553                         at->at_features |= ATA_PORT_F_RESCAN;
554                         kprintf("%s: HOTPLUG (PM) - Device inserted\n",
555                                 ATANAME(ap, at));
556                 }
557         }
558 }
559
560 /*
561  * Read a PM register
562  */
563 int
564 ahci_pm_read(struct ahci_port *ap, int target, int which, u_int32_t *datap)
565 {
566         struct ata_xfer *xa;
567         int error;
568
569         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
570
571         bzero(xa->fis, sizeof(*xa->fis));
572         xa->fis->type = ATA_FIS_TYPE_H2D;
573         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
574         xa->fis->command = ATA_C_READ_PM;
575         xa->fis->features = which;
576         xa->fis->device = target | ATA_H2D_DEVICE_LBA;
577         xa->fis->control = ATA_FIS_CONTROL_4BIT;
578
579         xa->complete = ahci_pm_dummy_done;
580         xa->datalen = 0;
581         xa->flags = ATA_F_READ | ATA_F_POLL;
582         xa->timeout = 1000;
583
584         if (ahci_ata_cmd(xa) == ATA_S_COMPLETE) {
585                 *datap = xa->rfis.sector_count | (xa->rfis.lba_low << 8) |
586                        (xa->rfis.lba_mid << 16) | (xa->rfis.lba_high << 24);
587                 error = 0;
588         } else {
589                 kprintf("%s.%d pm_read SCA[%d] failed\n",
590                         PORTNAME(ap), target, which);
591                 *datap = 0;
592                 error = EIO;
593         }
594         ahci_ata_put_xfer(xa);
595         return (error);
596 }
597
598 /*
599  * Write a PM register
600  */
601 int
602 ahci_pm_write(struct ahci_port *ap, int target, int which, u_int32_t data)
603 {
604         struct ata_xfer *xa;
605         int error;
606
607         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
608
609         bzero(xa->fis, sizeof(*xa->fis));
610         xa->fis->type = ATA_FIS_TYPE_H2D;
611         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
612         xa->fis->command = ATA_C_WRITE_PM;
613         xa->fis->features = which;
614         xa->fis->device = target | ATA_H2D_DEVICE_LBA;
615         xa->fis->sector_count = (u_int8_t)data;
616         xa->fis->lba_low = (u_int8_t)(data >> 8);
617         xa->fis->lba_mid = (u_int8_t)(data >> 16);
618         xa->fis->lba_high = (u_int8_t)(data >> 24);
619         xa->fis->control = ATA_FIS_CONTROL_4BIT;
620
621         xa->complete = ahci_pm_dummy_done;
622         xa->datalen = 0;
623         xa->flags = ATA_F_READ | ATA_F_POLL;
624         xa->timeout = 1000;
625
626         if (ahci_ata_cmd(xa) == ATA_S_COMPLETE)
627                 error = 0;
628         else
629                 error = EIO;
630         ahci_ata_put_xfer(xa);
631         return(error);
632 }
633
634 /*
635  * Dummy done callback for xa.
636  */
637 static void
638 ahci_pm_dummy_done(struct ata_xfer *xa)
639 {
640 }
641
642 static void
643 ahci_pm_empty_done(struct ahci_ccb *ccb)
644 {
645         if (ccb->ccb_xa.state == ATA_S_ONCHIP)
646                 ccb->ccb_xa.state = ATA_S_COMPLETE;
647 }