ahcisata_core.c revision 1.4 1 /* $NetBSD: ahcisata_core.c,v 1.4 2007/07/09 21:00:34 ad Exp $ */
2
3 /*
4 * Copyright (c) 2006 Manuel Bouyer.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Manuel Bouyer.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.4 2007/07/09 21:00:34 ad Exp $");
35
36 #include <sys/types.h>
37 #include <sys/malloc.h>
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/systm.h>
41 #include <sys/disklabel.h>
42 #include <sys/proc.h>
43
44 #include <uvm/uvm_extern.h>
45
46 #include <dev/ic/wdcreg.h>
47 #include <dev/ata/atareg.h>
48 #include <dev/ata/satavar.h>
49 #include <dev/ata/satareg.h>
50 #include <dev/ic/ahcisatavar.h>
51
52 #ifdef AHCI_DEBUG
53 int ahcidebug_mask = 0x0;
54 #endif
55
56 void ahci_probe_drive(struct ata_channel *);
57 void ahci_setup_channel(struct ata_channel *);
58
59 int ahci_ata_bio(struct ata_drive_datas *, struct ata_bio *);
60 void ahci_reset_drive(struct ata_drive_datas *, int);
61 void ahci_reset_channel(struct ata_channel *, int);
62 int ahci_exec_command(struct ata_drive_datas *, struct ata_command *);
63 int ahci_ata_addref(struct ata_drive_datas *);
64 void ahci_ata_delref(struct ata_drive_datas *);
65 void ahci_killpending(struct ata_drive_datas *);
66
67 void ahci_cmd_start(struct ata_channel *, struct ata_xfer *);
68 int ahci_cmd_complete(struct ata_channel *, struct ata_xfer *, int);
69 void ahci_cmd_done(struct ata_channel *, struct ata_xfer *, int);
70 void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ;
71 void ahci_bio_start(struct ata_channel *, struct ata_xfer *);
72 int ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int);
73 void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ;
74 void ahci_channel_start(struct ahci_softc *, struct ata_channel *);
75 void ahci_timeout(void *);
76 int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int);
77
78 #define ATA_DELAY 10000 /* 10s for a drive I/O */
79
80 const struct ata_bustype ahci_ata_bustype = {
81 SCSIPI_BUSTYPE_ATA,
82 ahci_ata_bio,
83 ahci_reset_drive,
84 ahci_reset_channel,
85 ahci_exec_command,
86 ata_get_params,
87 ahci_ata_addref,
88 ahci_ata_delref,
89 ahci_killpending
90 };
91
92 void ahci_intr_port(struct ahci_softc *, struct ahci_channel *);
93
94 void
95 ahci_attach(struct ahci_softc *sc)
96 {
97 u_int32_t ahci_cap, ahci_rev, ahci_ports;
98 int i, j, port;
99 struct ahci_channel *achp;
100 struct ata_channel *chp;
101 int error;
102 bus_dma_segment_t seg;
103 int rseg;
104 int dmasize;
105 void *cmdhp;
106 void *cmdtblp;
107
108 /* reset controller */
109 AHCI_WRITE(sc, AHCI_GHC, AHCI_GHC_HR);
110 delay(1000);
111 /* wait up to 1s for reset to complete */
112 for (i = 0; i < 1000; i++) {
113 if ((AHCI_READ(sc, AHCI_GHC) & AHCI_GHC_HR) == 0)
114 break;
115 }
116 if ((AHCI_READ(sc, AHCI_GHC) & AHCI_GHC_HR)) {
117 aprint_error("%s: reset failed\n", AHCINAME(sc));
118 return;
119 }
120 /* enable ahci mode */
121 AHCI_WRITE(sc, AHCI_GHC, AHCI_GHC_AE);
122
123
124 ahci_cap = AHCI_READ(sc, AHCI_CAP);
125 sc->sc_atac.atac_nchannels = (ahci_cap & AHCI_CAP_NPMASK) + 1;
126 sc->sc_ncmds = ((ahci_cap & AHCI_CAP_NCS) >> 8) + 1;
127 ahci_rev = AHCI_READ(sc, AHCI_VS);
128 aprint_normal("%s: AHCI revision ", AHCINAME(sc));
129 switch(ahci_rev) {
130 case AHCI_VS_10:
131 aprint_normal("1.0");
132 break;
133 case AHCI_VS_11:
134 aprint_normal("1.1");
135 break;
136 default:
137 aprint_normal("0x%x", ahci_rev);
138 break;
139 }
140
141 aprint_normal(", %d ports, %d command slots, features 0x%x\n",
142 sc->sc_atac.atac_nchannels, sc->sc_ncmds,
143 ahci_cap & ~(AHCI_CAP_NPMASK|AHCI_CAP_NCS));
144 sc->sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DMA | ATAC_CAP_UDMA;
145 sc->sc_atac.atac_pio_cap = 4;
146 sc->sc_atac.atac_dma_cap = 2;
147 sc->sc_atac.atac_udma_cap = 6;
148 sc->sc_atac.atac_channels = sc->sc_chanarray;
149 sc->sc_atac.atac_atapibus_attach = NULL; /* XXX */
150 sc->sc_atac.atac_probe = ahci_probe_drive;
151 sc->sc_atac.atac_bustype_ata = &ahci_ata_bustype;
152 sc->sc_atac.atac_set_modes = ahci_setup_channel;
153
154 dmasize =
155 (AHCI_RFIS_SIZE + AHCI_CMDH_SIZE) * sc->sc_atac.atac_nchannels;
156 error = bus_dmamem_alloc(sc->sc_dmat, dmasize, PAGE_SIZE, 0,
157 &seg, 1, &rseg, BUS_DMA_NOWAIT);
158 if (error) {
159 aprint_error("%s: unable to allocate command header memory"
160 ", error=%d\n", AHCINAME(sc), error);
161 return;
162 }
163 error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, dmasize,
164 &cmdhp, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
165 if (error) {
166 aprint_error("%s: unable to map command header memory"
167 ", error=%d\n", AHCINAME(sc), error);
168 return;
169 }
170 error = bus_dmamap_create(sc->sc_dmat, dmasize, 1, dmasize, 0,
171 BUS_DMA_NOWAIT, &sc->sc_cmd_hdrd);
172 if (error) {
173 aprint_error("%s: unable to create command header map"
174 ", error=%d\n", AHCINAME(sc), error);
175 return;
176 }
177 error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_hdrd,
178 cmdhp, dmasize, NULL, BUS_DMA_NOWAIT);
179 if (error) {
180 aprint_error("%s: unable to load command header map"
181 ", error=%d\n", AHCINAME(sc), error);
182 return;
183 }
184 sc->sc_cmd_hdr = cmdhp;
185
186 /* clear interrupts */
187 AHCI_WRITE(sc, AHCI_IS, AHCI_READ(sc, AHCI_IS));
188 /* enable interrupts */
189 AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
190
191 ahci_ports = AHCI_READ(sc, AHCI_PI);
192 for (i = 0, port = 0; i < AHCI_MAX_PORTS; i++) {
193 if ((ahci_ports & (1 << i)) == 0)
194 continue;
195 if (port >= sc->sc_atac.atac_nchannels) {
196 aprint_error("%s: more ports than announced\n",
197 AHCINAME(sc));
198 break;
199 }
200 achp = &sc->sc_channels[i];
201 chp = (struct ata_channel *)achp;
202 sc->sc_chanarray[i] = chp;
203 chp->ch_channel = i;
204 chp->ch_atac = &sc->sc_atac;
205 chp->ch_queue = malloc(sizeof(struct ata_queue),
206 M_DEVBUF, M_NOWAIT);
207 if (chp->ch_queue == NULL) {
208 aprint_error("%s port %d: can't allocate memory for "
209 "command queue", AHCINAME(sc), i);
210 break;
211 }
212 dmasize = AHCI_CMDTBL_SIZE * sc->sc_ncmds;
213 error = bus_dmamem_alloc(sc->sc_dmat, dmasize, PAGE_SIZE, 0,
214 &seg, 1, &rseg, BUS_DMA_NOWAIT);
215 if (error) {
216 aprint_error("%s: unable to allocate command table "
217 "memory, error=%d\n", AHCINAME(sc), error);
218 break;
219 }
220 error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, dmasize,
221 &cmdtblp, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
222 if (error) {
223 aprint_error("%s: unable to map command table memory"
224 ", error=%d\n", AHCINAME(sc), error);
225 break;
226 }
227 error = bus_dmamap_create(sc->sc_dmat, dmasize, 1, dmasize, 0,
228 BUS_DMA_NOWAIT, &achp->ahcic_cmd_tbld);
229 if (error) {
230 aprint_error("%s: unable to create command table map"
231 ", error=%d\n", AHCINAME(sc), error);
232 break;
233 }
234 error = bus_dmamap_load(sc->sc_dmat, achp->ahcic_cmd_tbld,
235 cmdtblp, dmasize, NULL, BUS_DMA_NOWAIT);
236 if (error) {
237 aprint_error("%s: unable to load command table map"
238 ", error=%d\n", AHCINAME(sc), error);
239 break;
240 }
241 achp->ahcic_cmdh = (struct ahci_cmd_header *)
242 ((char *)cmdhp + AHCI_CMDH_SIZE * port);
243 achp->ahcic_bus_cmdh = sc->sc_cmd_hdrd->dm_segs[0].ds_addr +
244 AHCI_CMDH_SIZE * port;
245 achp->ahcic_rfis = (struct ahci_r_fis *)
246 ((char *)cmdhp +
247 AHCI_CMDH_SIZE * sc->sc_atac.atac_nchannels +
248 AHCI_RFIS_SIZE * port);
249 achp->ahcic_bus_rfis = sc->sc_cmd_hdrd->dm_segs[0].ds_addr +
250 AHCI_CMDH_SIZE * sc->sc_atac.atac_nchannels +
251 AHCI_RFIS_SIZE * port;
252 AHCIDEBUG_PRINT(("port %d cmdh %p (0x%x) rfis %p (0x%x)\n", i,
253 achp->ahcic_cmdh, (u_int)achp->ahcic_bus_cmdh,
254 achp->ahcic_rfis, (u_int)achp->ahcic_bus_rfis),
255 DEBUG_PROBE);
256
257 for (j = 0; j < sc->sc_ncmds; j++) {
258 achp->ahcic_cmd_tbl[j] = (struct ahci_cmd_tbl *)
259 ((char *)cmdtblp + AHCI_CMDTBL_SIZE * j);
260 achp->ahcic_bus_cmd_tbl[j] =
261 achp->ahcic_cmd_tbld->dm_segs[0].ds_addr +
262 AHCI_CMDTBL_SIZE * j;
263 achp->ahcic_cmdh[j].cmdh_cmdtba =
264 htole32(achp->ahcic_bus_cmd_tbl[j]);
265 achp->ahcic_cmdh[j].cmdh_cmdtbau = htole32(0);
266 AHCIDEBUG_PRINT(("port %d/%d tbl %p (0x%x)\n", i, j,
267 achp->ahcic_cmd_tbl[j],
268 (u_int)achp->ahcic_bus_cmd_tbl[j]), DEBUG_PROBE);
269 /* The xfer DMA map */
270 error = bus_dmamap_create(sc->sc_dmat, MAXPHYS,
271 AHCI_NPRD, 0x400000 /* 4MB */, 0,
272 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
273 &achp->ahcic_datad[j]);
274 if (error) {
275 aprint_error("%s: couldn't alloc xfer DMA map, "
276 "error=%d\n", AHCINAME(sc), error);
277 goto end;
278 }
279 }
280 AHCI_WRITE(sc, AHCI_P_CLB(i), achp->ahcic_bus_cmdh);
281 AHCI_WRITE(sc, AHCI_P_CLBU(i), 0);
282 AHCI_WRITE(sc, AHCI_P_FB(i), achp->ahcic_bus_rfis);
283 AHCI_WRITE(sc, AHCI_P_FBU(i), 0);
284 chp->ch_ndrive = 1;
285 if (bus_space_subregion(sc->sc_ahcit, sc->sc_ahcih,
286 AHCI_P_SSTS(i), 1, &achp->ahcic_sstatus) != 0) {
287 aprint_error("%s: couldn't map channel %d "
288 "sata_status regs\n", AHCINAME(sc), i);
289 break;
290 }
291 if (bus_space_subregion(sc->sc_ahcit, sc->sc_ahcih,
292 AHCI_P_SCTL(i), 1, &achp->ahcic_scontrol) != 0) {
293 aprint_error("%s: couldn't map channel %d "
294 "sata_control regs\n", AHCINAME(sc), i);
295 break;
296 }
297 if (bus_space_subregion(sc->sc_ahcit, sc->sc_ahcih,
298 AHCI_P_SERR(i), 1, &achp->ahcic_serror) != 0) {
299 aprint_error("%s: couldn't map channel %d "
300 "sata_error regs\n", AHCINAME(sc), i);
301 break;
302 }
303 ata_channel_attach(chp);
304 port++;
305 end:
306 continue;
307 }
308 }
309
310 int
311 ahci_intr(void *v)
312 {
313 struct ahci_softc *sc = v;
314 u_int32_t is;
315 int i, r = 0;
316
317 while ((is = AHCI_READ(sc, AHCI_IS))) {
318 AHCIDEBUG_PRINT(("%s ahci_intr 0x%x\n", AHCINAME(sc), is),
319 DEBUG_INTR);
320 r = 1;
321 AHCI_WRITE(sc, AHCI_IS, is);
322 for (i = 0; i < AHCI_MAX_PORTS; i++)
323 if (is & (1 << i))
324 ahci_intr_port(sc, &sc->sc_channels[i]);
325 }
326 return r;
327 }
328
329 void
330 ahci_intr_port(struct ahci_softc *sc, struct ahci_channel *achp)
331 {
332 u_int32_t is, tfd;
333 struct ata_channel *chp = &achp->ata_channel;
334 struct ata_xfer *xfer = chp->ch_queue->active_xfer;
335 int slot;
336
337 is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
338 AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is);
339 AHCIDEBUG_PRINT(("ahci_intr_port %s port %d is 0x%x CI 0x%x\n", AHCINAME(sc),
340 chp->ch_channel, is, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
341 DEBUG_INTR);
342
343 if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_IFS |
344 AHCI_P_IX_OFS | AHCI_P_IX_UFS)) {
345 slot = (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))
346 & AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT;
347 if ((achp->ahcic_cmds_active & (1 << slot)) == 0)
348 return;
349 /* stop channel */
350 AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
351 AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & ~AHCI_P_CMD_ST);
352 if (slot != 0) {
353 printf("ahci_intr_port: slot %d\n", slot);
354 panic("ahci_intr_port");
355 }
356 if (is & AHCI_P_IX_TFES) {
357 tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
358 chp->ch_error =
359 (tfd & AHCI_P_TFD_ERR_MASK) >> AHCI_P_TFD_ERR_SHIFT;
360 chp->ch_status = (tfd & 0xff);
361 } else {
362 /* emulate a CRC error */
363 chp->ch_error = WDCE_CRC;
364 chp->ch_status = WDCS_ERR;
365 }
366 xfer->c_intr(chp, xfer, is);
367 } else {
368 slot = 0; /* XXX */
369 is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
370 AHCIDEBUG_PRINT(("ahci_intr_port port %d is 0x%x act 0x%x CI 0x%x\n",
371 chp->ch_channel, is, achp->ahcic_cmds_active,
372 AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_INTR);
373 if ((achp->ahcic_cmds_active & (1 << slot)) == 0)
374 return;
375 if ((AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) & (1 << slot))
376 == 0) {
377 xfer->c_intr(chp, xfer, 0);
378 }
379 }
380 }
381
382 void
383 ahci_reset_drive(struct ata_drive_datas *drvp, int flags)
384 {
385 struct ata_channel *chp = drvp->chnl_softc;
386 ata_reset_channel(chp, flags);
387 return;
388 }
389
390 void
391 ahci_reset_channel(struct ata_channel *chp, int flags)
392 {
393 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
394 struct ahci_channel *achp = (struct ahci_channel *)chp;
395 int i;
396
397 /* stop channel */
398 AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
399 AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & ~AHCI_P_CMD_ST);
400 /* wait 1s for channel to stop */
401 for (i = 0; i <100; i++) {
402 if ((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR)
403 == 0)
404 break;
405 if (flags & AT_WAIT)
406 tsleep(&sc, PRIBIO, "ahcirst", mstohz(10));
407 else
408 delay(10000);
409 }
410 if (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR) {
411 printf("%s: channel wouldn't stop\n", AHCINAME(sc));
412 /* XXX controller reset ? */
413 return;
414 }
415 if (sata_reset_interface(chp, sc->sc_ahcit, achp->ahcic_scontrol,
416 achp->ahcic_sstatus) != SStatus_DET_DEV) {
417 printf("%s: port reset failed\n", AHCINAME(sc));
418 /* XXX and then ? */
419 }
420 AHCI_WRITE(sc, AHCI_P_SERR(chp->ch_channel),
421 AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel)));
422 if (chp->ch_queue->active_xfer) {
423 chp->ch_queue->active_xfer->c_kill_xfer(chp,
424 chp->ch_queue->active_xfer, KILL_RESET);
425 }
426 ahci_channel_start(sc, chp);
427 return;
428 }
429
430 int
431 ahci_ata_addref(struct ata_drive_datas *drvp)
432 {
433 return 0;
434 }
435
436 void
437 ahci_ata_delref(struct ata_drive_datas *drvp)
438 {
439 return;
440 }
441
442 void
443 ahci_killpending(struct ata_drive_datas *drvp)
444 {
445 return;
446 }
447
448 void
449 ahci_probe_drive(struct ata_channel *chp)
450 {
451 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
452 struct ahci_channel *achp = (struct ahci_channel *)chp;
453 int i, s;
454 u_int32_t sig;
455
456 /* XXX This should be done by other code. */
457 for (i = 0; i < chp->ch_ndrive; i++) {
458 chp->ch_drive[i].chnl_softc = chp;
459 chp->ch_drive[i].drive = i;
460 }
461
462 /* bring interface up, power up and spin up device */
463 AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
464 AHCI_P_CMD_ICC_AC | AHCI_P_CMD_POD | AHCI_P_CMD_SUD);
465 /* reset the PHY and bring online */
466 switch (sata_reset_interface(chp, sc->sc_ahcit, achp->ahcic_scontrol,
467 achp->ahcic_sstatus)) {
468 case SStatus_DET_DEV:
469 AHCI_WRITE(sc, AHCI_P_SERR(chp->ch_channel),
470 AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel)));
471 sig = AHCI_READ(sc, AHCI_P_SIG(chp->ch_channel));
472 AHCIDEBUG_PRINT(("%s: port %d: sig=0x%x CMD=0x%x\n",
473 AHCINAME(sc), chp->ch_channel, sig,
474 AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))), DEBUG_PROBE);
475 /*
476 * scnt and sn are supposed to be 0x1 for ATAPI, but in some
477 * cases we get wrong values here, so ignore it.
478 */
479 s = splbio();
480 if ((sig & 0xffff0000) == 0xeb140000) {
481 aprint_error("%s port %d: ATAPI device ignored\n",
482 AHCINAME(sc), chp->ch_channel);
483 chp->ch_drive[0].drive_flags |= 0 /* DRIVE_ATAPI XXX */;
484 } else
485 chp->ch_drive[0].drive_flags |= DRIVE_ATA;
486 splx(s);
487 /* enable interrupts */
488 AHCI_WRITE(sc, AHCI_P_IE(chp->ch_channel),
489 AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_IFS |
490 AHCI_P_IX_OFS | AHCI_P_IX_DPS | AHCI_P_IX_UFS |
491 AHCI_P_IX_DHRS);
492 /* and start operations */
493 ahci_channel_start(sc, chp);
494 break;
495
496 default:
497 break;
498 }
499 }
500
501 void
502 ahci_setup_channel(struct ata_channel *chp)
503 {
504 return;
505 }
506
507 int
508 ahci_exec_command(struct ata_drive_datas *drvp, struct ata_command *ata_c)
509 {
510 struct ata_channel *chp = drvp->chnl_softc;
511 struct ata_xfer *xfer;
512 int ret;
513 int s;
514
515 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
516 AHCIDEBUG_PRINT(("ahci_exec_command port %d CI 0x%x\n",
517 chp->ch_channel, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
518 DEBUG_XFERS);
519 xfer = ata_get_xfer(ata_c->flags & AT_WAIT ? ATAXF_CANSLEEP :
520 ATAXF_NOSLEEP);
521 if (xfer == NULL) {
522 return ATACMD_TRY_AGAIN;
523 }
524 if (ata_c->flags & AT_POLL)
525 xfer->c_flags |= C_POLL;
526 if (ata_c->flags & AT_WAIT)
527 xfer->c_flags |= C_WAIT;
528 xfer->c_drive = drvp->drive;
529 xfer->c_databuf = ata_c->data;
530 xfer->c_bcount = ata_c->bcount;
531 xfer->c_cmd = ata_c;
532 xfer->c_start = ahci_cmd_start;
533 xfer->c_intr = ahci_cmd_complete;
534 xfer->c_kill_xfer = ahci_cmd_kill_xfer;
535 s = splbio();
536 ata_exec_xfer(chp, xfer);
537 #ifdef DIAGNOSTIC
538 if ((ata_c->flags & AT_POLL) != 0 &&
539 (ata_c->flags & AT_DONE) == 0)
540 panic("ahci_exec_command: polled command not done");
541 #endif
542 if (ata_c->flags & AT_DONE) {
543 ret = ATACMD_COMPLETE;
544 } else {
545 if (ata_c->flags & AT_WAIT) {
546 while ((ata_c->flags & AT_DONE) == 0) {
547 tsleep(ata_c, PRIBIO, "ahcicmd", 0);
548 }
549 ret = ATACMD_COMPLETE;
550 } else {
551 ret = ATACMD_QUEUED;
552 }
553 }
554 splx(s);
555 return ret;
556 }
557
558 void
559 ahci_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer)
560 {
561 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
562 struct ahci_channel *achp = (struct ahci_channel *)chp;
563 struct ata_command *ata_c = xfer->c_cmd;
564 int slot = 0 /* XXX slot */;
565 struct ahci_cmd_tbl *cmd_tbl;
566 struct ahci_cmd_header *cmd_h;
567 u_int8_t *fis;
568 int i;
569 int channel = chp->ch_channel;
570
571 AHCIDEBUG_PRINT(("ahci_cmd_start CI 0x%x\n",
572 AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS);
573
574 cmd_tbl = achp->ahcic_cmd_tbl[slot];
575 AHCIDEBUG_PRINT(("%s port %d tbl %p\n", AHCINAME(sc), chp->ch_channel,
576 cmd_tbl), DEBUG_XFERS);
577 fis = cmd_tbl->cmdt_cfis;
578
579 fis[0] = 0x27; /* host to device */
580 fis[1] = 0x80; /* command FIS */
581 fis[2] = ata_c->r_command;
582 fis[3] = ata_c->r_features;
583 fis[4] = ata_c->r_sector;
584 fis[5] = ata_c->r_cyl & 0xff;
585 fis[6] = (ata_c->r_cyl >> 8) & 0xff;
586 fis[7] = ata_c->r_head & 0x0f;
587 fis[8] = 0;
588 fis[9] = 0;
589 fis[10] = 0;
590 fis[11] = 0;
591 fis[12] = ata_c->r_count;
592 fis[13] = 0;
593 fis[14] = 0;
594 fis[15] = WDCTL_4BIT;
595 fis[16] = 0;
596 fis[17] = 0;
597 fis[18] = 0;
598 fis[19] = 0;
599
600 cmd_h = &achp->ahcic_cmdh[slot];
601 AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc),
602 chp->ch_channel, cmd_h), DEBUG_XFERS);
603 if (ahci_dma_setup(chp, slot,
604 (ata_c->flags & (AT_READ|AT_WRITE)) ? ata_c->data : NULL,
605 ata_c->bcount,
606 (ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) {
607 ata_c->flags |= AT_DF;
608 ahci_cmd_complete(chp, xfer, slot);
609 return;
610 }
611 cmd_h->cmdh_flags = htole16(
612 ((ata_c->flags & AT_WRITE) ? AHCI_CMDH_F_WR : 0) |
613 20 /* fis lenght */ / 4);
614 cmd_h->cmdh_prdbc = 0;
615 AHCI_CMDH_SYNC(sc, achp, slot,
616 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
617
618 if (ata_c->flags & AT_POLL) {
619 /* polled command, disable interrupts */
620 AHCI_WRITE(sc, AHCI_GHC,
621 AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE);
622 }
623 chp->ch_flags |= ATACH_IRQ_WAIT;
624 /* start command */
625 AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1 << slot);
626 /* and says we started this command */
627 achp->ahcic_cmds_active |= 1 << slot;
628
629 if ((ata_c->flags & AT_POLL) == 0) {
630 chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */
631 callout_reset(&chp->ch_callout, mstohz(ata_c->timeout),
632 ahci_timeout, chp);
633 return;
634 }
635 /*
636 * Polled command.
637 */
638 for (i = 0; i < ata_c->timeout / 10; i++) {
639 if (ata_c->flags & AT_DONE)
640 break;
641 ahci_intr_port(sc, achp);
642 if (ata_c->flags & AT_WAIT)
643 tsleep(&xfer, PRIBIO, "ahcipl", mstohz(10));
644 else
645 delay(10000);
646 }
647 AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), channel,
648 AHCI_READ(sc, AHCI_GHC), AHCI_READ(sc, AHCI_IS),
649 AHCI_READ(sc, AHCI_P_CLBU(channel)), AHCI_READ(sc, AHCI_P_CLB(channel)),
650 AHCI_READ(sc, AHCI_P_FBU(channel)), AHCI_READ(sc, AHCI_P_FB(channel)),
651 AHCI_READ(sc, AHCI_P_CMD(channel)), AHCI_READ(sc, AHCI_P_CI(channel))),
652 DEBUG_XFERS);
653 if ((ata_c->flags & AT_DONE) == 0) {
654 ata_c->flags |= AT_TIMEOU;
655 ahci_cmd_complete(chp, xfer, slot);
656 }
657 /* reenable interrupts */
658 AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
659 }
660
661 void
662 ahci_cmd_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
663 {
664 struct ata_command *ata_c = xfer->c_cmd;
665 AHCIDEBUG_PRINT(("ahci_cmd_kill_xfer channel %d\n", chp->ch_channel),
666 DEBUG_FUNCS);
667
668 switch (reason) {
669 case KILL_GONE:
670 ata_c->flags |= AT_GONE;
671 break;
672 case KILL_RESET:
673 ata_c->flags |= AT_RESET;
674 break;
675 default:
676 printf("ahci_cmd_kill_xfer: unknown reason %d\n", reason);
677 panic("ahci_cmd_kill_xfer");
678 }
679 ahci_cmd_done(chp, xfer, 0 /* XXX slot */);
680 }
681
682 int
683 ahci_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is)
684 {
685 int slot = 0; /* XXX slot */
686 struct ata_command *ata_c = xfer->c_cmd;
687 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
688
689 AHCIDEBUG_PRINT(("ahci_cmd_complete channel %d CMD 0x%x CI 0x%x\n",
690 chp->ch_channel, AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)),
691 AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
692 DEBUG_FUNCS);
693 chp->ch_flags &= ~ATACH_IRQ_WAIT;
694 if (xfer->c_flags & C_TIMEOU) {
695 ata_c->flags |= AT_TIMEOU;
696 } else
697 callout_stop(&chp->ch_callout);
698
699 chp->ch_queue->active_xfer = NULL;
700
701 if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) {
702 ahci_cmd_kill_xfer(chp, xfer, KILL_GONE);
703 chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN;
704 wakeup(&chp->ch_queue->active_xfer);
705 return 0;
706 }
707 if (is) {
708 ata_c->r_head = 0;
709 ata_c->r_count = 0;
710 ata_c->r_sector = 0;
711 ata_c->r_cyl = 0;
712 if (chp->ch_status & WDCS_BSY) {
713 ata_c->flags |= AT_TIMEOU;
714 } else if (chp->ch_status & WDCS_ERR) {
715 ata_c->r_error = chp->ch_error;
716 ata_c->flags |= AT_ERROR;
717 }
718 }
719 ahci_cmd_done(chp, xfer, slot);
720 return 0;
721 }
722
723 void
724 ahci_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer, int slot)
725 {
726 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
727 struct ahci_channel *achp = (struct ahci_channel *)chp;
728 struct ata_command *ata_c = xfer->c_cmd;
729
730 AHCIDEBUG_PRINT(("ahci_cmd_done channel %d\n", chp->ch_channel),
731 DEBUG_FUNCS);
732
733 /* this comamnd is not active any more */
734 achp->ahcic_cmds_active &= ~(1 << slot);
735
736 if (ata_c->flags & (AT_READ|AT_WRITE)) {
737 bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[slot], 0,
738 achp->ahcic_datad[slot]->dm_mapsize,
739 (ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD :
740 BUS_DMASYNC_POSTWRITE);
741 bus_dmamap_unload(sc->sc_dmat, achp->ahcic_datad[slot]);
742 }
743
744 AHCI_CMDH_SYNC(sc, achp, slot,
745 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
746
747 ata_c->flags |= AT_DONE;
748 if (achp->ahcic_cmdh[slot].cmdh_prdbc)
749 ata_c->flags |= AT_XFDONE;
750
751 ata_free_xfer(chp, xfer);
752 if (ata_c->flags & AT_WAIT)
753 wakeup(ata_c);
754 else if (ata_c->callback)
755 ata_c->callback(ata_c->callback_arg);
756 atastart(chp);
757 return;
758 }
759
760 int
761 ahci_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
762 {
763 struct ata_channel *chp = drvp->chnl_softc;
764 struct ata_xfer *xfer;
765
766 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
767 AHCIDEBUG_PRINT(("ahci_ata_bio port %d CI 0x%x\n",
768 chp->ch_channel, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
769 DEBUG_XFERS);
770 xfer = ata_get_xfer(ATAXF_NOSLEEP);
771 if (xfer == NULL) {
772 return ATACMD_TRY_AGAIN;
773 }
774 if (ata_bio->flags & ATA_POLL)
775 xfer->c_flags |= C_POLL;
776 xfer->c_drive = drvp->drive;
777 xfer->c_cmd = ata_bio;
778 xfer->c_databuf = ata_bio->databuf;
779 xfer->c_bcount = ata_bio->bcount;
780 xfer->c_start = ahci_bio_start;
781 xfer->c_intr = ahci_bio_complete;
782 xfer->c_kill_xfer = ahci_bio_kill_xfer;
783 ata_exec_xfer(chp, xfer);
784 return (ata_bio->flags & ATA_ITSDONE) ? ATACMD_COMPLETE : ATACMD_QUEUED;
785 }
786
787 void
788 ahci_bio_start(struct ata_channel *chp, struct ata_xfer *xfer)
789 {
790 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
791 struct ahci_channel *achp = (struct ahci_channel *)chp;
792 struct ata_bio *ata_bio = xfer->c_cmd;
793 int slot = 0 /* XXX slot */;
794 struct ahci_cmd_tbl *cmd_tbl;
795 struct ahci_cmd_header *cmd_h;
796 u_int8_t *fis;
797 int i, nblks;
798 int channel = chp->ch_channel;
799
800 AHCIDEBUG_PRINT(("ahci_bio_start CI 0x%x\n",
801 AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS);
802
803 nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
804
805 cmd_tbl = achp->ahcic_cmd_tbl[slot];
806 AHCIDEBUG_PRINT(("%s port %d tbl %p\n", AHCINAME(sc), chp->ch_channel,
807 cmd_tbl), DEBUG_XFERS);
808 fis = cmd_tbl->cmdt_cfis;
809
810 fis[0] = 0x27; /* host to device */
811 fis[1] = 0x80; /* command FIS */
812 if (ata_bio->flags & ATA_LBA48) {
813 fis[2] = (ata_bio->flags & ATA_READ) ?
814 WDCC_READDMA_EXT : WDCC_WRITEDMA_EXT;
815 } else {
816 fis[2] =
817 (ata_bio->flags & ATA_READ) ? WDCC_READDMA : WDCC_WRITEDMA;
818 }
819 fis[3] = 0; /* features */
820 fis[4] = ata_bio->blkno & 0xff;
821 fis[5] = (ata_bio->blkno >> 8) & 0xff;
822 fis[6] = (ata_bio->blkno >> 16) & 0xff;
823 if (ata_bio->flags & ATA_LBA48) {
824 fis[7] = WDSD_LBA;
825 fis[8] = (ata_bio->blkno >> 24) & 0xff;
826 fis[9] = (ata_bio->blkno >> 32) & 0xff;
827 fis[10] = (ata_bio->blkno >> 40) & 0xff;
828 } else {
829 fis[7] = ((ata_bio->blkno >> 24) & 0x0f) | WDSD_LBA;
830 fis[8] = 0;
831 fis[9] = 0;
832 fis[10] = 0;
833 }
834 fis[11] = 0; /* ext features */
835 fis[12] = nblks & 0xff;
836 fis[13] = (ata_bio->flags & ATA_LBA48) ?
837 ((nblks >> 8) & 0xff) : 0;
838 fis[14] = 0;
839 fis[15] = WDCTL_4BIT;
840 fis[16] = 0;
841 fis[17] = 0;
842 fis[18] = 0;
843 fis[19] = 0;
844
845 cmd_h = &achp->ahcic_cmdh[slot];
846 AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc),
847 chp->ch_channel, cmd_h), DEBUG_XFERS);
848 if (ahci_dma_setup(chp, slot, ata_bio->databuf, ata_bio->bcount,
849 (ata_bio->flags & ATA_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) {
850 ata_bio->error = ERR_DMA;
851 ata_bio->r_error = 0;
852 ahci_bio_complete(chp, xfer, slot);
853 return;
854 }
855 cmd_h->cmdh_flags = htole16(
856 ((ata_bio->flags & ATA_READ) ? 0 : AHCI_CMDH_F_WR) |
857 20 /* fis lenght */ / 4);
858 cmd_h->cmdh_prdbc = 0;
859 AHCI_CMDH_SYNC(sc, achp, slot,
860 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
861
862 if (xfer->c_flags & C_POLL) {
863 /* polled command, disable interrupts */
864 AHCI_WRITE(sc, AHCI_GHC,
865 AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE);
866 }
867 chp->ch_flags |= ATACH_IRQ_WAIT;
868 /* start command */
869 AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1 << slot);
870 /* and says we started this command */
871 achp->ahcic_cmds_active |= 1 << slot;
872
873 if ((xfer->c_flags & C_POLL) == 0) {
874 chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */
875 callout_reset(&chp->ch_callout, mstohz(ATA_DELAY),
876 ahci_timeout, chp);
877 return;
878 }
879 /*
880 * Polled command.
881 */
882 for (i = 0; i < ATA_DELAY / 10; i++) {
883 if (ata_bio->flags & ATA_ITSDONE)
884 break;
885 ahci_intr_port(sc, achp);
886 if (ata_bio->flags & ATA_NOSLEEP)
887 delay(10000);
888 else
889 tsleep(&xfer, PRIBIO, "ahcipl", mstohz(10));
890 }
891 AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), channel,
892 AHCI_READ(sc, AHCI_GHC), AHCI_READ(sc, AHCI_IS),
893 AHCI_READ(sc, AHCI_P_CLBU(channel)), AHCI_READ(sc, AHCI_P_CLB(channel)),
894 AHCI_READ(sc, AHCI_P_FBU(channel)), AHCI_READ(sc, AHCI_P_FB(channel)),
895 AHCI_READ(sc, AHCI_P_CMD(channel)), AHCI_READ(sc, AHCI_P_CI(channel))),
896 DEBUG_XFERS);
897 if ((ata_bio->flags & ATA_ITSDONE) == 0) {
898 ata_bio->error = TIMEOUT;
899 ahci_bio_complete(chp, xfer, slot);
900 }
901 /* reenable interrupts */
902 AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
903 }
904
905 void
906 ahci_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
907 {
908 int slot = 0; /* XXX slot */
909 int drive = xfer->c_drive;
910 struct ata_bio *ata_bio = xfer->c_cmd;
911 struct ahci_channel *achp = (struct ahci_channel *)chp;
912 AHCIDEBUG_PRINT(("ahci_bio_kill_xfer channel %d\n", chp->ch_channel),
913 DEBUG_FUNCS);
914
915 achp->ahcic_cmds_active &= ~(1 << slot);
916 ata_free_xfer(chp, xfer);
917 ata_bio->flags |= ATA_ITSDONE;
918 switch (reason) {
919 case KILL_GONE:
920 ata_bio->error = ERR_NODEV;
921 break;
922 case KILL_RESET:
923 ata_bio->error = ERR_RESET;
924 break;
925 default:
926 printf("ahci_bio_kill_xfer: unknown reason %d\n", reason);
927 panic("ahci_bio_kill_xfer");
928 }
929 ata_bio->r_error = WDCE_ABRT;
930 (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc);
931 }
932
933 int
934 ahci_bio_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is)
935 {
936 int slot = 0; /* XXX slot */
937 struct ata_bio *ata_bio = xfer->c_cmd;
938 int drive = xfer->c_drive;
939 struct ahci_channel *achp = (struct ahci_channel *)chp;
940 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
941
942 AHCIDEBUG_PRINT(("ahci_bio_complete channel %d\n", chp->ch_channel),
943 DEBUG_FUNCS);
944
945 achp->ahcic_cmds_active &= ~(1 << slot);
946 chp->ch_flags &= ~ATACH_IRQ_WAIT;
947 callout_stop(&chp->ch_callout);
948
949 chp->ch_queue->active_xfer = NULL;
950 bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[slot], 0,
951 achp->ahcic_datad[slot]->dm_mapsize,
952 (ata_bio->flags & ATA_READ) ? BUS_DMASYNC_POSTREAD :
953 BUS_DMASYNC_POSTWRITE);
954 bus_dmamap_unload(sc->sc_dmat, achp->ahcic_datad[slot]);
955
956 if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) {
957 ahci_bio_kill_xfer(chp, xfer, KILL_GONE);
958 chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN;
959 wakeup(&chp->ch_queue->active_xfer);
960 return 0;
961 }
962 ata_free_xfer(chp, xfer);
963 ata_bio->flags |= ATA_ITSDONE;
964 if (chp->ch_status & WDCS_DWF) {
965 ata_bio->error = ERR_DF;
966 } else if (chp->ch_status & WDCS_ERR) {
967 ata_bio->error = ERROR;
968 ata_bio->r_error = chp->ch_error;
969 } else if (chp->ch_status & WDCS_CORR)
970 ata_bio->flags |= ATA_CORR;
971
972 AHCI_CMDH_SYNC(sc, achp, slot,
973 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
974 AHCIDEBUG_PRINT(("ahci_bio_complete bcount %ld",
975 ata_bio->bcount), DEBUG_XFERS);
976 ata_bio->bcount -= le32toh(achp->ahcic_cmdh[slot].cmdh_prdbc);
977 AHCIDEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS);
978 (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc);
979 atastart(chp);
980 return 0;
981 }
982
983 void
984 ahci_channel_start(struct ahci_softc *sc, struct ata_channel *chp)
985 {
986 /* clear error */
987 AHCI_WRITE(sc, AHCI_P_SERR(chp->ch_channel), 0);
988
989 /* and start controller */
990 AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
991 AHCI_P_CMD_ICC_AC | AHCI_P_CMD_POD | AHCI_P_CMD_SUD |
992 AHCI_P_CMD_FRE | AHCI_P_CMD_ST);
993 }
994
995 void
996 ahci_timeout(void *v)
997 {
998 struct ata_channel *chp = (struct ata_channel *)v;
999 struct ata_xfer *xfer = chp->ch_queue->active_xfer;
1000 int s = splbio();
1001 AHCIDEBUG_PRINT(("ahci_timeout xfer %p\n", xfer), DEBUG_INTR);
1002 if ((chp->ch_flags & ATACH_IRQ_WAIT) != 0) {
1003 xfer->c_flags |= C_TIMEOU;
1004 xfer->c_intr(chp, xfer, 0);
1005 }
1006 splx(s);
1007 }
1008
1009 int
1010 ahci_dma_setup(struct ata_channel *chp, int slot, void *data,
1011 size_t count, int op)
1012 {
1013 int error, seg;
1014 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
1015 struct ahci_channel *achp = (struct ahci_channel *)chp;
1016 struct ahci_cmd_tbl *cmd_tbl;
1017 struct ahci_cmd_header *cmd_h;
1018
1019 cmd_h = &achp->ahcic_cmdh[slot];
1020 cmd_tbl = achp->ahcic_cmd_tbl[slot];
1021
1022 if (data == NULL) {
1023 cmd_h->cmdh_prdtl = 0;
1024 goto end;
1025 }
1026
1027 error = bus_dmamap_load(sc->sc_dmat, achp->ahcic_datad[slot],
1028 data, count, NULL,
1029 BUS_DMA_NOWAIT | BUS_DMA_STREAMING | op);
1030 if (error) {
1031 printf("%s port %d: failed to load xfer: %d\n",
1032 AHCINAME(sc), chp->ch_channel, error);
1033 return error;
1034 }
1035 bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[slot], 0,
1036 achp->ahcic_datad[slot]->dm_mapsize,
1037 (op == BUS_DMA_READ) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
1038 for (seg = 0; seg < achp->ahcic_datad[slot]->dm_nsegs; seg++) {
1039 cmd_tbl->cmdt_prd[seg].prd_dba = htole32(
1040 achp->ahcic_datad[slot]->dm_segs[seg].ds_addr);
1041 cmd_tbl->cmdt_prd[seg].prd_dbau = 0;
1042 cmd_tbl->cmdt_prd[seg].prd_dbc = htole32(
1043 achp->ahcic_datad[slot]->dm_segs[seg].ds_len - 1);
1044 }
1045 cmd_tbl->cmdt_prd[seg - 1].prd_dbc |= htole32(AHCI_PRD_DBC_IPC);
1046 cmd_h->cmdh_prdtl = htole16(achp->ahcic_datad[slot]->dm_nsegs);
1047 end:
1048 AHCI_CMDTBL_SYNC(sc, achp, slot, BUS_DMASYNC_PREWRITE);
1049 return 0;
1050 }
1051