Merge branch 'master' of ssh://crater.dragonflybsd.org/repository/git/dragonfly
[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 = 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         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 (ahci_pm_phy_status(ap, target, &data)) {
280                 kprintf("%s: (B)Cannot clear phy status\n",
281                         ATANAME(ap ,at));
282         }
283         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
284
285         /*
286          * Prep first D2H command with SRST feature & clear busy/reset flags
287          *
288          * It is unclear which other fields in the FIS are used.  Just zero
289          * everything.
290          *
291          * When soft-resetting a port behind a multiplier at will be
292          * non-NULL, assigning it to the ccb prevents the port interrupt
293          * from hard-resetting the port if a problem crops up.
294          */
295         ccb = ahci_get_ccb(ap);
296         ccb->ccb_done = ahci_pm_empty_done;
297         ccb->ccb_xa.flags = ATA_F_READ | ATA_F_POLL;
298         ccb->ccb_xa.complete = ahci_pm_dummy_done;
299         ccb->ccb_xa.at = at;
300
301         fis = ccb->ccb_cmd_table->cfis;
302         bzero(fis, sizeof(ccb->ccb_cmd_table->cfis));
303         fis[0] = ATA_FIS_TYPE_H2D;
304         fis[1] = at->at_target;
305         fis[15] = ATA_FIS_CONTROL_SRST|ATA_FIS_CONTROL_4BIT;
306
307         cmd_slot = ccb->ccb_cmd_hdr;
308         cmd_slot->prdtl = 0;
309         cmd_slot->flags = htole16(5);   /* FIS length: 5 DWORDS */
310         cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_C); /* Clear busy on OK */
311         cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_R); /* Reset */
312         cmd_slot->flags |= htole16(at->at_target <<
313                                    AHCI_CMD_LIST_FLAG_PMP_SHIFT);
314
315         ccb->ccb_xa.state = ATA_S_PENDING;
316         ccb->ccb_xa.flags = 0;
317
318         /*
319          * XXX hack to ignore IFS errors which can occur during the target
320          *     device's reset.
321          *
322          *     If an IFS error occurs the target is probably powering up,
323          *     so we try for a longer period of time.
324          */
325         ap->ap_flags |= AP_F_IGNORE_IFS;
326         ap->ap_flags &= ~(AP_F_IFS_IGNORED | AP_F_IFS_OCCURED);
327
328         if (ahci_poll(ccb, 1000, ahci_ata_cmd_timeout) != ATA_S_COMPLETE) {
329                 kprintf("%s: (PM) First FIS failed\n", ATANAME(ap, at));
330                 if (ap->ap_flags & AP_F_IFS_OCCURED) {
331                         if (tried_longer == 0)
332                                 count += 4;
333                         ++tried_longer;
334                 }
335                 if (--count) {
336                         ahci_put_ccb(ccb);
337                         goto retry;
338                 }
339                 goto err;
340         }
341
342         /*
343          * WARNING!  SENSITIVE TIME PERIOD!  WARNING!
344          *
345          * The first and second FISes are supposed to be back-to-back,
346          * I think the idea is to get the second sent and then after
347          * the device resets it will send a signature.  Do not delay
348          * here and most definitely do not issue any commands to other
349          * targets!
350          */
351
352         /*
353          * Prep second D2H command to read status and complete reset sequence
354          * AHCI 10.4.1 and "Serial ATA Revision 2.6".  I can't find the ATA
355          * Rev 2.6 and it is unclear how the second FIS should be set up
356          * from the AHCI document.
357          *
358          * Give the device 3ms before sending the second FIS.
359          *
360          * It is unclear which other fields in the FIS are used.  Just zero
361          * everything.
362          */
363         bzero(fis, sizeof(ccb->ccb_cmd_table->cfis));
364         fis[0] = ATA_FIS_TYPE_H2D;
365         fis[1] = at->at_target;
366         fis[15] = ATA_FIS_CONTROL_4BIT;
367
368         cmd_slot->prdtl = 0;
369         cmd_slot->flags = htole16(5);   /* FIS length: 5 DWORDS */
370         cmd_slot->flags |= htole16(at->at_target <<
371                                    AHCI_CMD_LIST_FLAG_PMP_SHIFT);
372
373         ccb->ccb_xa.state = ATA_S_PENDING;
374         ccb->ccb_xa.flags = 0;
375
376         if (ahci_poll(ccb, 1000, ahci_ata_cmd_timeout) != ATA_S_COMPLETE) {
377                 kprintf("%s: (PM) Second FIS failed\n", ATANAME(ap, at));
378                 if (--count) {
379                         ahci_put_ccb(ccb);
380                         goto retry;
381                 }
382                 goto err;
383         }
384
385         ahci_os_sleep(100);
386         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
387         if (ahci_pm_phy_status(ap, target, &data)) {
388                 kprintf("%s: (C)Cannot clear phy status\n",
389                         ATANAME(ap ,at));
390         }
391         ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
392
393         /*
394          * Do it again, even if we think we got a good result
395          */
396         if (--count) {
397                 fis[15] = 0;
398                 ahci_put_ccb(ccb);
399                 goto retry;
400         }
401
402         /*
403          * If the softreset is trying to clear a BSY condition after a
404          * normal portreset we assign the port type.
405          *
406          * If the softreset is being run first as part of the ccb error
407          * processing code then report if the device signature changed
408          * unexpectedly.
409          */
410         if (at->at_type == ATA_PORT_T_NONE) {
411                 at->at_type = ahci_port_signature_detect(ap, at);
412         } else {
413                 if (ahci_port_signature_detect(ap, at) != at->at_type) {
414                         kprintf("%s: device signature unexpectedly "
415                                 "changed\n", ATANAME(ap, at));
416                         error = EBUSY; /* XXX */
417                 }
418         }
419         error = 0;
420
421         /*
422          * Who knows what kind of mess occured.  We have exclusive access
423          * to the port so try to clean up potential problems.
424          */
425         ahci_os_sleep(100);
426 err:
427         /*
428          * Clean up the CCB.  If the command failed it already went through
429          * the standard timeout handling and should no longer be active.
430          */
431         if (ccb) {
432                 KKASSERT((ap->ap_active & (1 << ccb->ccb_slot)) == 0);
433                 ahci_put_ccb(ccb);
434         }
435
436         /*
437          * Clear error status so we can detect removal.
438          */
439         if (ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1)) {
440                 kprintf("%s: ahci_pm_softreset unable to clear SERR\n",
441                         ATANAME(ap, at));
442                 ap->ap_flags &= ~AP_F_IGNORE_IFS;
443         }
444         ahci_pwrite(ap, AHCI_PREG_SERR, -1);
445
446
447         at->at_probe = error ? ATA_PROBE_FAILED : ATA_PROBE_NEED_IDENT;
448         return (error);
449 }
450
451
452 /*
453  * Return the phy status for a target behind a port multiplier and
454  * reset AHCI_PMREG_SERR.
455  *
456  * Returned bits follow AHCI_PREG_SSTS bits.  The AHCI_PREG_SSTS_SPD
457  * bits can be used to determine the link speed and will be 0 if there
458  * is no link.
459  *
460  * 0 is returned if any communications error occurs.
461  */
462 int
463 ahci_pm_phy_status(struct ahci_port *ap, int target, u_int32_t *datap)
464 {
465         int error;
466
467         error = ahci_pm_read(ap, target, AHCI_PMREG_SSTS, datap);
468         if (error == 0)
469                 error = ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1);
470         if (error)
471                 *datap = 0;
472         return(error);
473 }
474
475 int
476 ahci_pm_set_feature(struct ahci_port *ap, int feature, int enable)
477 {
478         struct ata_xfer *xa;
479         int error;
480
481         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
482
483         bzero(xa->fis, sizeof(*xa->fis));
484         xa->fis->type = ATA_FIS_TYPE_H2D;
485         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
486         xa->fis->command = enable ? ATA_C_SATA_FEATURE_ENA :
487                                     ATA_C_SATA_FEATURE_DIS;
488         xa->fis->sector_count = feature;
489         xa->fis->control = ATA_FIS_CONTROL_4BIT;
490
491         xa->complete = ahci_pm_dummy_done;
492         xa->datalen = 0;
493         xa->flags = ATA_F_READ | ATA_F_POLL;
494         xa->timeout = 1000;
495
496         if (ahci_ata_cmd(xa) == ATA_S_COMPLETE)
497                 error = 0;
498         else
499                 error = EIO;
500         ahci_ata_put_xfer(xa);
501         return(error);
502 }
503
504 /*
505  * Check that a target is still good.
506  */
507 void
508 ahci_pm_check_good(struct ahci_port *ap, int target)
509 {
510         struct ata_port *at;
511         u_int32_t data;
512
513 #if 0
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 #endif
523         if (ahci_pm_write(ap, target, AHCI_PMREG_SERR, -1)) {
524                 kprintf("%s: Port multiplier: SERR could not be cleared\n",
525                         PORTNAME(ap));
526         }
527
528         if (target == CAM_TARGET_WILDCARD)
529                 return;
530         at = &ap->ap_ata[target];
531
532         /*
533          * If the device needs an init or hard reset also make sure the
534          * PHY is turned on.
535          */
536         if (at->at_probe <= ATA_PROBE_NEED_HARD_RESET) {
537                 /*kprintf("%s DOHARD\n", ATANAME(ap, at));*/
538                 ahci_pm_hardreset(ap, target, 1);
539         }
540
541         /*
542          * Read the detect status
543          */
544         if (ahci_pm_read(ap, target, AHCI_PMREG_SSTS, &data)) {
545                 kprintf("%s: Unable to access PM SSTS register target %d\n",
546                         PORTNAME(ap), target);
547                 return;
548         }
549         if ((data & AHCI_PREG_SSTS_DET) != AHCI_PREG_SSTS_DET_DEV) {
550                 /*kprintf("%s: DETECT %08x\n", ATANAME(ap, at), data);*/
551                 if (at->at_probe != ATA_PROBE_FAILED) {
552                         at->at_probe = ATA_PROBE_FAILED;
553                         at->at_type = ATA_PORT_T_NONE;
554                         at->at_features |= ATA_PORT_F_RESCAN;
555                         kprintf("%s: HOTPLUG (PM) - Device removed\n",
556                                 ATANAME(ap, at));
557                 }
558         } else {
559                 if (at->at_probe == ATA_PROBE_FAILED) {
560                         at->at_probe = ATA_PROBE_NEED_HARD_RESET;
561                         at->at_features |= ATA_PORT_F_RESCAN;
562                         kprintf("%s: HOTPLUG (PM) - Device inserted\n",
563                                 ATANAME(ap, at));
564                 }
565         }
566 }
567
568 /*
569  * Read a PM register
570  */
571 int
572 ahci_pm_read(struct ahci_port *ap, int target, int which, u_int32_t *datap)
573 {
574         struct ata_xfer *xa;
575         int error;
576
577         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
578
579         bzero(xa->fis, sizeof(*xa->fis));
580         xa->fis->type = ATA_FIS_TYPE_H2D;
581         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
582         xa->fis->command = ATA_C_READ_PM;
583         xa->fis->features = which;
584         xa->fis->device = target | ATA_H2D_DEVICE_LBA;
585         xa->fis->control = ATA_FIS_CONTROL_4BIT;
586
587         xa->complete = ahci_pm_dummy_done;
588         xa->datalen = 0;
589         xa->flags = ATA_F_READ | ATA_F_POLL;
590         xa->timeout = 1000;
591
592         if (ahci_ata_cmd(xa) == ATA_S_COMPLETE) {
593                 *datap = xa->rfis.sector_count | (xa->rfis.lba_low << 8) |
594                        (xa->rfis.lba_mid << 16) | (xa->rfis.lba_high << 24);
595                 error = 0;
596         } else {
597                 kprintf("%s.%d pm_read SCA[%d] failed\n",
598                         PORTNAME(ap), target, which);
599                 *datap = 0;
600                 error = EIO;
601         }
602         ahci_ata_put_xfer(xa);
603         return (error);
604 }
605
606 /*
607  * Write a PM register
608  */
609 int
610 ahci_pm_write(struct ahci_port *ap, int target, int which, u_int32_t data)
611 {
612         struct ata_xfer *xa;
613         int error;
614
615         xa = ahci_ata_get_xfer(ap, &ap->ap_ata[15]);
616
617         bzero(xa->fis, sizeof(*xa->fis));
618         xa->fis->type = ATA_FIS_TYPE_H2D;
619         xa->fis->flags = ATA_H2D_FLAGS_CMD | 15;
620         xa->fis->command = ATA_C_WRITE_PM;
621         xa->fis->features = which;
622         xa->fis->device = target | ATA_H2D_DEVICE_LBA;
623         xa->fis->sector_count = (u_int8_t)data;
624         xa->fis->lba_low = (u_int8_t)(data >> 8);
625         xa->fis->lba_mid = (u_int8_t)(data >> 16);
626         xa->fis->lba_high = (u_int8_t)(data >> 24);
627         xa->fis->control = ATA_FIS_CONTROL_4BIT;
628
629         xa->complete = ahci_pm_dummy_done;
630         xa->datalen = 0;
631         xa->flags = ATA_F_READ | ATA_F_POLL;
632         xa->timeout = 1000;
633
634         if (ahci_ata_cmd(xa) == ATA_S_COMPLETE)
635                 error = 0;
636         else
637                 error = EIO;
638         ahci_ata_put_xfer(xa);
639         return(error);
640 }
641
642 /*
643  * Dummy done callback for xa.
644  */
645 static void
646 ahci_pm_dummy_done(struct ata_xfer *xa)
647 {
648 }
649
650 static void
651 ahci_pm_empty_done(struct ahci_ccb *ccb)
652 {
653         if (ccb->ccb_xa.state == ATA_S_ONCHIP)
654                 ccb->ccb_xa.state = ATA_S_COMPLETE;
655 }