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