1 /*      $OpenBSD: ata_wdc.c,v 1.27 2004/06/02 18:55:08 grange Exp $	*/
2 /*	$NetBSD: ata_wdc.c,v 1.21 1999/08/09 09:43:11 bouyer Exp $	*/
3 
4 /*
5  * Copyright (c) 1998, 2001 Manuel Bouyer.
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  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Manuel Bouyer.
18  * 4. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 
35 /*-
36  * Copyright (c) 1998 The NetBSD Foundation, Inc.
37  * All rights reserved.
38  *
39  * This code is derived from software contributed to The NetBSD Foundation
40  * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that the following conditions
44  * are met:
45  * 1. Redistributions of source code must retain the above copyright
46  *    notice, this list of conditions and the following disclaimer.
47  * 2. Redistributions in binary form must reproduce the above copyright
48  *    notice, this list of conditions and the following disclaimer in the
49  *    documentation and/or other materials provided with the distribution.
50  * 3. All advertising materials mentioning features or use of this software
51  *    must display the following acknowledgement:
52  *        This product includes software developed by the NetBSD
53  *        Foundation, Inc. and its contributors.
54  * 4. Neither the name of The NetBSD Foundation nor the names of its
55  *    contributors may be used to endorse or promote products derived
56  *    from this software without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
59  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
60  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
61  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
62  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
63  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
64  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
66  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
67  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68  * POSSIBILITY OF SUCH DAMAGE.
69  */
70 
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/kernel.h>
74 #include <sys/file.h>
75 #include <sys/stat.h>
76 #include <sys/buf.h>
77 #include <sys/malloc.h>
78 #include <sys/device.h>
79 #include <sys/disklabel.h>
80 #include <sys/syslog.h>
81 #include <sys/proc.h>
82 
83 #include <machine/intr.h>
84 #include <machine/bus.h>
85 
86 #include <dev/ata/atareg.h>
87 #include <dev/ata/atavar.h>
88 #include <dev/ic/wdcreg.h>
89 #include <dev/ic/wdcvar.h>
90 #include <dev/ata/wdvar.h>
91 
92 #define DEBUG_INTR   0x01
93 #define DEBUG_XFERS  0x02
94 #define DEBUG_STATUS 0x04
95 #define DEBUG_FUNCS  0x08
96 #define DEBUG_PROBE  0x10
97 
98 #ifdef WDCDEBUG
99 #ifndef WDCDEBUG_WD_MASK
100 #define WDCDEBUG_WD_MASK 0x00
101 #endif
102 int wdcdebug_wd_mask = WDCDEBUG_WD_MASK;
103 #define WDCDEBUG_PRINT(args, level) do {	\
104 	if ((wdcdebug_wd_mask & (level)) != 0)	\
105 		printf args;			\
106 } while (0)
107 #else
108 #define WDCDEBUG_PRINT(args, level)
109 #endif
110 
111 #define ATA_DELAY 10000 /* 10s for a drive I/O */
112 
113 #ifdef __OpenBSD__
114 struct cfdriver wdc_cd = {
115 	NULL, "wdc", DV_DULL
116 };
117 #endif
118 
119 void  wdc_ata_bio_start(struct channel_softc *, struct wdc_xfer *);
120 void  _wdc_ata_bio_start(struct channel_softc *, struct wdc_xfer *);
121 int   wdc_ata_bio_intr(struct channel_softc *, struct wdc_xfer *, int);
122 void  wdc_ata_bio_kill_xfer(struct channel_softc *, struct wdc_xfer *);
123 void  wdc_ata_bio_done(struct channel_softc *, struct wdc_xfer *);
124 int   wdc_ata_ctrl_intr(struct channel_softc *, struct wdc_xfer *, int);
125 int   wdc_ata_err(struct ata_drive_datas *, struct ata_bio *);
126 #define WDC_ATA_NOERR 0x00 /* Drive doesn't report an error */
127 #define WDC_ATA_RECOV 0x01 /* There was a recovered error */
128 #define WDC_ATA_ERR   0x02 /* Drive reports an error */
129 
130 /*
131  * Handle block I/O operation. Return WDC_COMPLETE, WDC_QUEUED, or
132  * WDC_TRY_AGAIN. Must be called at splbio().
133  */
134 int
wdc_ata_bio(struct ata_drive_datas * drvp,struct ata_bio * ata_bio)135 wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
136 {
137 	struct wdc_xfer *xfer;
138 	struct channel_softc *chp = drvp->chnl_softc;
139 
140 	xfer = wdc_get_xfer(WDC_NOSLEEP);
141 	if (xfer == NULL)
142 		return WDC_TRY_AGAIN;
143 	if (ata_bio->flags & ATA_POLL)
144 		xfer->c_flags |= C_POLL;
145 	if (!(ata_bio->flags & ATA_POLL) &&
146 	    (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
147 	    (ata_bio->flags & ATA_SINGLE) == 0 &&
148 	    (ata_bio->bcount > 512 ||
149 	    (chp->wdc->quirks & WDC_QUIRK_NOSHORTDMA) == 0))
150 		xfer->c_flags |= C_DMA;
151 	xfer->drive = drvp->drive;
152 	xfer->cmd = ata_bio;
153 	xfer->databuf = ata_bio->databuf;
154 	xfer->c_bcount = ata_bio->bcount;
155 	xfer->c_start = wdc_ata_bio_start;
156 	xfer->c_intr = wdc_ata_bio_intr;
157 	xfer->c_kill_xfer = wdc_ata_bio_kill_xfer;
158 	wdc_exec_xfer(chp, xfer);
159 	return (ata_bio->flags & ATA_ITSDONE) ? WDC_COMPLETE : WDC_QUEUED;
160 }
161 
162 void
wdc_ata_bio_start(struct channel_softc * chp,struct wdc_xfer * xfer)163 wdc_ata_bio_start(struct channel_softc *chp, struct wdc_xfer *xfer)
164 {
165 	struct ata_bio *ata_bio = xfer->cmd;
166 	WDCDEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n",
167 	    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
168 	    DEBUG_XFERS);
169 
170 	/* start timeout machinery */
171 	if ((ata_bio->flags & ATA_POLL) == 0)
172 		timeout_add(&chp->ch_timo, ATA_DELAY / 1000 * hz);
173 	_wdc_ata_bio_start(chp, xfer);
174 }
175 
176 void
_wdc_ata_bio_start(struct channel_softc * chp,struct wdc_xfer * xfer)177 _wdc_ata_bio_start(struct channel_softc *chp, struct wdc_xfer *xfer)
178 {
179 	struct ata_bio *ata_bio = xfer->cmd;
180 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
181 	u_int16_t cyl;
182 	u_int8_t head, sect, cmd = 0;
183 	int nblks;
184 	int ata_delay;
185 	int dma_flags = 0;
186 
187 	WDCDEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",
188 	    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
189 	    DEBUG_INTR | DEBUG_XFERS);
190 	/* Do control operations specially. */
191 	if (drvp->state < READY) {
192 		/*
193 		 * Actually, we want to be careful not to mess with the control
194 		 * state if the device is currently busy, but we can assume
195 		 * that we never get to this point if that's the case.
196 		 */
197 		/* at this point, we should only be in RECAL state */
198 		if (drvp->state != RECAL) {
199 			printf("%s:%d:%d: bad state %d in _wdc_ata_bio_start\n",
200 			    chp->wdc->sc_dev.dv_xname, chp->channel,
201 			    xfer->drive, drvp->state);
202 			panic("_wdc_ata_bio_start: bad state");
203 		}
204 		xfer->c_intr = wdc_ata_ctrl_intr;
205 		wdc_set_drive(chp, xfer->drive);
206 		if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY) != 0)
207 			goto timeout;
208 		wdccommandshort(chp, xfer->drive, WDCC_RECAL);
209 		drvp->state = RECAL_WAIT;
210 		if ((ata_bio->flags & ATA_POLL) == 0) {
211 			chp->ch_flags |= WDCF_IRQ_WAIT;
212 		} else {
213 			/* Wait for at last 400ns for status bit to be valid */
214 			DELAY(1);
215 			wdc_ata_ctrl_intr(chp, xfer, 0);
216 		}
217 		return;
218 	}
219 
220 	if (xfer->c_flags & C_DMA) {
221 		if (drvp->n_xfers <= NXFER)
222 			drvp->n_xfers++;
223 		dma_flags = (ata_bio->flags & ATA_READ) ?  WDC_DMA_READ : 0;
224 		if (ata_bio->flags & ATA_LBA48)
225 			dma_flags |= WDC_DMA_LBA48;
226 	}
227 	if (ata_bio->flags & ATA_SINGLE)
228 		ata_delay = ATA_DELAY;
229 	else
230 		ata_delay = ATA_DELAY;
231 again:
232 	/*
233 	 *
234 	 * When starting a multi-sector transfer, or doing single-sector
235 	 * transfers...
236 	 */
237 	if (xfer->c_skip == 0 || (ata_bio->flags & ATA_SINGLE) != 0) {
238 		if (ata_bio->flags & ATA_SINGLE)
239 			nblks = 1;
240 		else
241 			nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
242 		/* Check for bad sectors and adjust transfer, if necessary. */
243 		if ((ata_bio->lp->d_flags & D_BADSECT) != 0) {
244 			long blkdiff;
245 			int i;
246 			for (i = 0; (blkdiff = ata_bio->badsect[i]) != -1;
247 			     i++) {
248 				blkdiff -= ata_bio->blkno;
249 				if (blkdiff < 0)
250 					continue;
251 				if (blkdiff == 0) {
252 					/* Replace current block of transfer. */
253 					ata_bio->blkno =
254 					    ata_bio->lp->d_secperunit -
255 					    ata_bio->lp->d_nsectors - i - 1;
256 				}
257 				if (blkdiff < nblks) {
258 					/* Bad block inside transfer. */
259 					ata_bio->flags |= ATA_SINGLE;
260 					nblks = 1;
261 				}
262 				break;
263 			}
264 			/* Transfer is okay now. */
265 		}
266 		if (ata_bio->flags & ATA_LBA) {
267 			sect = (ata_bio->blkno >> 0) & 0xff;
268 			cyl = (ata_bio->blkno >> 8) & 0xffff;
269 			head = (ata_bio->blkno >> 24) & 0x0f;
270 			head |= WDSD_LBA;
271 		} else {
272 			int blkno = ata_bio->blkno;
273 			sect = blkno % ata_bio->lp->d_nsectors;
274 			sect++;    /* Sectors begin with 1, not 0. */
275 			blkno /= ata_bio->lp->d_nsectors;
276 			head = blkno % ata_bio->lp->d_ntracks;
277 			blkno /= ata_bio->lp->d_ntracks;
278 			cyl = blkno;
279 			head |= WDSD_CHS;
280 		}
281 		if (xfer->c_flags & C_DMA) {
282 			ata_bio->nblks = nblks;
283 			ata_bio->nbytes = xfer->c_bcount;
284 			if (ata_bio->flags & ATA_LBA48)
285 				cmd = (ata_bio->flags & ATA_READ) ?
286 				    WDCC_READDMA_EXT : WDCC_WRITEDMA_EXT;
287 			else
288 				cmd = (ata_bio->flags & ATA_READ) ?
289 				    WDCC_READDMA : WDCC_WRITEDMA;
290 	    		/* Init the DMA channel. */
291 			if ((*chp->wdc->dma_init)(chp->wdc->dma_arg,
292 			    chp->channel, xfer->drive,
293 			    (char *)xfer->databuf + xfer->c_skip,
294 			    ata_bio->nbytes, dma_flags) != 0) {
295 				ata_bio->error = ERR_DMA;
296 				ata_bio->r_error = 0;
297 				wdc_ata_bio_done(chp, xfer);
298 				return;
299 			}
300 			/* Initiate command */
301 			wdc_set_drive(chp, xfer->drive);
302 			if (wait_for_ready(chp, ata_delay) < 0)
303 				goto timeout;
304 			if (ata_bio->flags & ATA_LBA48) {
305 				wdccommandext(chp, xfer->drive, cmd,
306 				    (u_int64_t)ata_bio->blkno, nblks);
307 			} else {
308 				wdccommand(chp, xfer->drive, cmd, cyl,
309 				    head, sect, nblks, 0);
310 			}
311 			/* start the DMA channel */
312 			(*chp->wdc->dma_start)(chp->wdc->dma_arg,
313 			    chp->channel, xfer->drive);
314 			chp->ch_flags |= WDCF_DMA_WAIT;
315 			/* wait for irq */
316 			goto intr;
317 		} /* else not DMA */
318 		ata_bio->nblks = min(nblks, ata_bio->multi);
319 		ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize;
320 		if (ata_bio->nblks > 1 && (ata_bio->flags & ATA_SINGLE) == 0) {
321 			if (ata_bio->flags & ATA_LBA48)
322 				cmd = (ata_bio->flags & ATA_READ) ?
323 				    WDCC_READMULTI_EXT : WDCC_WRITEMULTI_EXT;
324 			else
325 				cmd = (ata_bio->flags & ATA_READ) ?
326 				    WDCC_READMULTI : WDCC_WRITEMULTI;
327 		} else {
328 			if (ata_bio->flags & ATA_LBA48)
329 				cmd = (ata_bio->flags & ATA_READ) ?
330 				    WDCC_READ_EXT : WDCC_WRITE_EXT;
331 			else
332 				cmd = (ata_bio->flags & ATA_READ) ?
333 				    WDCC_READ : WDCC_WRITE;
334 		}
335 		/* Initiate command! */
336 		wdc_set_drive(chp, xfer->drive);
337 		if (wait_for_ready(chp, ata_delay) < 0)
338 			goto timeout;
339 		if (ata_bio->flags & ATA_LBA48) {
340 			wdccommandext(chp, xfer->drive, cmd,
341 			    (u_int64_t)ata_bio->blkno, nblks);
342 		} else {
343 			wdccommand(chp, xfer->drive, cmd, cyl,
344 			    head, sect, nblks,
345 			    (ata_bio->lp->d_type == DTYPE_ST506) ?
346 			    ata_bio->lp->d_precompcyl / 4 : 0);
347 		}
348 	} else if (ata_bio->nblks > 1) {
349 		/* The number of blocks in the last stretch may be smaller. */
350 		nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
351 		if (ata_bio->nblks > nblks) {
352 			ata_bio->nblks = nblks;
353 			ata_bio->nbytes = xfer->c_bcount;
354 		}
355 	}
356 	/* If this was a write and not using DMA, push the data. */
357 	if ((ata_bio->flags & ATA_READ) == 0) {
358 		if (wait_for_drq(chp, ata_delay) != 0) {
359 			printf("%s:%d:%d: timeout waiting for DRQ, "
360 			    "st=0x%b, err=0x%02x\n",
361 			    chp->wdc->sc_dev.dv_xname, chp->channel,
362 			    xfer->drive, chp->ch_status, WDCS_BITS,
363 			    chp->ch_error);
364 			if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR)
365 				ata_bio->error = TIMEOUT;
366 			wdc_ata_bio_done(chp, xfer);
367 			return;
368 		}
369 		if (wdc_ata_err(drvp, ata_bio) == WDC_ATA_ERR) {
370 			wdc_ata_bio_done(chp, xfer);
371 			return;
372 		}
373 		wdc_output_bytes(drvp, (char *)xfer->databuf + xfer->c_skip,
374 		    ata_bio->nbytes);
375 	}
376 
377 intr:	/* Wait for IRQ (either real or polled) */
378 	if ((ata_bio->flags & ATA_POLL) == 0) {
379 		chp->ch_flags |= WDCF_IRQ_WAIT;
380 	} else {
381 		/* Wait for at last 400ns for status bit to be valid */
382 		delay(1);
383 		if (chp->ch_flags & WDCF_DMA_WAIT) {
384 			wdc_dmawait(chp, xfer, ATA_DELAY);
385 			chp->ch_flags &= ~WDCF_DMA_WAIT;
386 		}
387 		wdc_ata_bio_intr(chp, xfer, 0);
388 		if ((ata_bio->flags & ATA_ITSDONE) == 0)
389 			goto again;
390 	}
391 	return;
392 timeout:
393 	printf("%s:%d:%d: not ready, st=0x%b, err=0x%02x\n",
394 	    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
395 	    chp->ch_status, WDCS_BITS, chp->ch_error);
396 	if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR)
397 		ata_bio->error = TIMEOUT;
398 	wdc_ata_bio_done(chp, xfer);
399 	return;
400 }
401 
402 int
wdc_ata_bio_intr(struct channel_softc * chp,struct wdc_xfer * xfer,int irq)403 wdc_ata_bio_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
404 {
405 	struct ata_bio *ata_bio = xfer->cmd;
406 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
407 	int drv_err;
408 
409 	WDCDEBUG_PRINT(("wdc_ata_bio_intr %s:%d:%d\n",
410 	    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
411 	    DEBUG_INTR | DEBUG_XFERS);
412 
413 
414 	/* Is it not a transfer, but a control operation? */
415 	if (drvp->state < READY) {
416 		printf("%s:%d:%d: bad state %d in wdc_ata_bio_intr\n",
417 		    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
418 		    drvp->state);
419 		panic("wdc_ata_bio_intr: bad state");
420 	}
421 
422 	/*
423 	 * reset on timeout. This will cause extra resets in the case
424 	 * of occasional lost interrupts
425 	 */
426 	if (xfer->c_flags & C_TIMEOU)
427 		goto timeout;
428 
429 	/* Ack interrupt done by wait_for_unbusy */
430 	if (wait_for_unbusy(chp,
431 	    (irq == 0) ? ATA_DELAY : 0) < 0) {
432 		if (irq)
433 			return 0; /* IRQ was not for us */
434 		printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
435 		    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
436 		    xfer->c_bcount, xfer->c_skip);
437 
438 		goto timeout;
439 	}
440 	if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
441 		chp->wdc->irqack(chp);
442 
443 	drv_err = wdc_ata_err(drvp, ata_bio);
444 
445 	if (xfer->c_flags & C_DMA) {
446 		if (chp->wdc->dma_status != 0) {
447 			if (drv_err != WDC_ATA_ERR) {
448 				ata_bio->error = ERR_DMA;
449 				drv_err = WDC_ATA_ERR;
450 			}
451 		}
452 		if (chp->ch_status & WDCS_DRQ) {
453 			if (drv_err != WDC_ATA_ERR) {
454 				printf("%s:%d:%d: intr with DRQ (st=0x%b)\n",
455 				    chp->wdc->sc_dev.dv_xname, chp->channel,
456 				    xfer->drive, chp->ch_status, WDCS_BITS);
457 				ata_bio->error = TIMEOUT;
458 				drv_err = WDC_ATA_ERR;
459 			}
460 		}
461 		if (drv_err != WDC_ATA_ERR)
462 			goto end;
463 		ata_dmaerr(drvp);
464 	}
465 
466 	/* if we had an error, end */
467 	if (drv_err == WDC_ATA_ERR) {
468 		wdc_ata_bio_done(chp, xfer);
469 		return 1;
470 	}
471 
472 	/* If this was a read and not using DMA, fetch the data. */
473 	if ((ata_bio->flags & ATA_READ) != 0) {
474 		if ((chp->ch_status & WDCS_DRQ) != WDCS_DRQ) {
475 			printf("%s:%d:%d: read intr before drq\n",
476 			    chp->wdc->sc_dev.dv_xname, chp->channel,
477 			    xfer->drive);
478 			ata_bio->error = TIMEOUT;
479 			wdc_ata_bio_done(chp, xfer);
480 			return 1;
481 		}
482 		wdc_input_bytes(drvp, (char *)xfer->databuf + xfer->c_skip,
483 		    ata_bio->nbytes);
484 	}
485 end:
486 	ata_bio->blkno += ata_bio->nblks;
487 	ata_bio->blkdone += ata_bio->nblks;
488 	xfer->c_skip += ata_bio->nbytes;
489 	xfer->c_bcount -= ata_bio->nbytes;
490 	/* See if this transfer is complete. */
491 	if (xfer->c_bcount > 0) {
492 		if ((ata_bio->flags & ATA_POLL) == 0) {
493 			/* Start the next operation */
494 			_wdc_ata_bio_start(chp, xfer);
495 		} else {
496 			/* Let _wdc_ata_bio_start do the loop */
497 			return 1;
498 		}
499 	} else { /* Done with this transfer */
500 		ata_bio->error = NOERROR;
501 		wdc_ata_bio_done(chp, xfer);
502 	}
503 	return 1;
504 
505 timeout:
506 	if (xfer->c_flags & C_DMA)
507 		ata_dmaerr(drvp);
508 
509 	ata_bio->error = TIMEOUT;
510 	wdc_ata_bio_done(chp, xfer);
511 	return 1;
512 }
513 
514 void
wdc_ata_bio_kill_xfer(struct channel_softc * chp,struct wdc_xfer * xfer)515 wdc_ata_bio_kill_xfer(struct channel_softc *chp, struct wdc_xfer *xfer)
516 {
517 	struct ata_bio *ata_bio = xfer->cmd;
518 
519 	timeout_del(&chp->ch_timo);
520 	/* remove this command from xfer queue */
521 	wdc_free_xfer(chp, xfer);
522 
523 	ata_bio->flags |= ATA_ITSDONE;
524 	ata_bio->error = ERR_NODEV;
525 	ata_bio->r_error = WDCE_ABRT;
526 	if ((ata_bio->flags & ATA_POLL) == 0) {
527 		WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS);
528 		wddone(ata_bio->wd);
529 	}
530 }
531 
532 void
wdc_ata_bio_done(struct channel_softc * chp,struct wdc_xfer * xfer)533 wdc_ata_bio_done(struct channel_softc *chp, struct wdc_xfer *xfer)
534 {
535 	struct ata_bio *ata_bio = xfer->cmd;
536 
537 	WDCDEBUG_PRINT(("wdc_ata_bio_done %s:%d:%d: flags 0x%x\n",
538 	    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
539 	    (u_int)xfer->c_flags),
540 	    DEBUG_XFERS);
541 
542 	timeout_del(&chp->ch_timo);
543 
544 	/* feed back residual bcount to our caller */
545 	ata_bio->bcount = xfer->c_bcount;
546 
547 	/* remove this command from xfer queue */
548 	wdc_free_xfer(chp, xfer);
549 
550 	ata_bio->flags |= ATA_ITSDONE;
551 	if ((ata_bio->flags & ATA_POLL) == 0) {
552 		WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS);
553 		wddone(ata_bio->wd);
554 	}
555 	WDCDEBUG_PRINT(("wdcstart from wdc_ata_done, flags 0x%x\n",
556 	    chp->ch_flags), DEBUG_XFERS);
557 	wdcstart(chp);
558 }
559 
560 /*
561  * Implement operations needed before read/write.
562  */
563 int
wdc_ata_ctrl_intr(struct channel_softc * chp,struct wdc_xfer * xfer,int irq)564 wdc_ata_ctrl_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
565 {
566 	struct ata_bio *ata_bio = xfer->cmd;
567 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
568 	char *errstring = NULL;
569 	int delay = (irq == 0) ? ATA_DELAY : 0;
570 
571 	WDCDEBUG_PRINT(("wdc_ata_ctrl_intr: state %d\n", drvp->state),
572 	    DEBUG_FUNCS);
573 
574 again:
575 	switch (drvp->state) {
576 	case RECAL:    /* Should not be in this state here */
577 		panic("wdc_ata_ctrl_intr: state==RECAL");
578 		break;
579 
580 	case RECAL_WAIT:
581 		errstring = "recal";
582 		if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
583 			goto timeout;
584 		if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
585 			chp->wdc->irqack(chp);
586 		if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
587 			goto error;
588 	/* fall through */
589 
590 	case PIOMODE:
591 		/* Don't try to set modes if controller can't be adjusted */
592 		if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0)
593 			goto geometry;
594 		/* Also don't try if the drive didn't report its mode */
595 		if ((drvp->drive_flags & DRIVE_MODE) == 0)
596 			goto geometry;
597 		/* SET FEATURES 0x08 is only for PIO mode > 2 */
598 		if (drvp->PIO_mode <= 2)
599 			goto geometry;
600 		wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
601 		    0x08 | drvp->PIO_mode, WDSF_SET_MODE);
602 		drvp->state = PIOMODE_WAIT;
603 		break;
604 
605 	case PIOMODE_WAIT:
606 		errstring = "piomode";
607 		if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
608 			goto timeout;
609 		if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
610 			chp->wdc->irqack(chp);
611 		if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
612 			goto error;
613 	/* fall through */
614 
615 	case DMAMODE:
616 		if (drvp->drive_flags & DRIVE_UDMA) {
617 			wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
618 			    0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
619 		} else if (drvp->drive_flags & DRIVE_DMA) {
620 			wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
621 			    0x20 | drvp->DMA_mode, WDSF_SET_MODE);
622 		} else {
623 			goto geometry;
624 		}
625 		drvp->state = DMAMODE_WAIT;
626 		break;
627 	case DMAMODE_WAIT:
628 		errstring = "dmamode";
629 		if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
630 			goto timeout;
631 		if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
632 			chp->wdc->irqack(chp);
633 		if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
634 			goto error;
635 	/* fall through */
636 
637 	case GEOMETRY:
638 	geometry:
639 		if (ata_bio->flags & ATA_LBA)
640 			goto multimode;
641 		wdccommand(chp, xfer->drive, WDCC_IDP,
642 		    ata_bio->lp->d_ncylinders,
643 		    ata_bio->lp->d_ntracks - 1, 0, ata_bio->lp->d_nsectors,
644 		    (ata_bio->lp->d_type == DTYPE_ST506) ?
645 			ata_bio->lp->d_precompcyl / 4 : 0);
646 		drvp->state = GEOMETRY_WAIT;
647 		break;
648 
649 	case GEOMETRY_WAIT:
650 		errstring = "geometry";
651 		if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
652 			goto timeout;
653 		if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
654 			chp->wdc->irqack(chp);
655 		if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
656 			goto error;
657 		/* fall through */
658 
659 	case MULTIMODE:
660 	multimode:
661 		if (ata_bio->multi == 1)
662 			goto ready;
663 		wdccommand(chp, xfer->drive, WDCC_SETMULTI, 0, 0, 0,
664 		    ata_bio->multi, 0);
665 		drvp->state = MULTIMODE_WAIT;
666 		break;
667 
668 	case MULTIMODE_WAIT:
669 		errstring = "setmulti";
670 		if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
671 			goto timeout;
672 		if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
673 			chp->wdc->irqack(chp);
674 		if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
675 			goto error;
676 		/* fall through */
677 
678 	case READY:
679 	ready:
680 		drvp->state = READY;
681 		/*
682 		 * The drive is usable now
683 		 */
684 		xfer->c_intr = wdc_ata_bio_intr;
685 		_wdc_ata_bio_start(chp, xfer);
686 		return 1;
687 	}
688 
689 	if ((ata_bio->flags & ATA_POLL) == 0) {
690 		chp->ch_flags |= WDCF_IRQ_WAIT;
691 	} else {
692 		goto again;
693 	}
694 	return 1;
695 
696 timeout:
697 	if (irq && (xfer->c_flags & C_TIMEOU) == 0) {
698 		return 0; /* IRQ was not for us */
699 	}
700 	printf("%s:%d:%d: %s timed out\n",
701 	    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
702 	ata_bio->error = TIMEOUT;
703 	drvp->state = 0;
704 	wdc_ata_bio_done(chp, xfer);
705 	return 0;
706 error:
707 	printf("%s:%d:%d: %s ",
708 	    chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
709 	    errstring);
710 	if (chp->ch_status & WDCS_DWF) {
711 		printf("drive fault\n");
712 		ata_bio->error = ERR_DF;
713 	} else {
714 		printf("error (%x)\n", chp->ch_error);
715 		ata_bio->r_error = chp->ch_error;
716 		ata_bio->error = ERROR;
717 	}
718 	drvp->state = 0;
719 	wdc_ata_bio_done(chp, xfer);
720 	return 1;
721 }
722 
723 int
wdc_ata_err(struct ata_drive_datas * drvp,struct ata_bio * ata_bio)724 wdc_ata_err(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
725 {
726 	struct channel_softc *chp = drvp->chnl_softc;
727 	ata_bio->error = 0;
728 	if (chp->ch_status & WDCS_BSY) {
729 		ata_bio->error = TIMEOUT;
730 		return WDC_ATA_ERR;
731 	}
732 
733 	if (chp->ch_status & WDCS_DWF) {
734 		ata_bio->error = ERR_DF;
735 		return WDC_ATA_ERR;
736 	}
737 
738 	if (chp->ch_status & WDCS_ERR) {
739 		ata_bio->error = ERROR;
740 		ata_bio->r_error = chp->ch_error;
741 		if (drvp->drive_flags & DRIVE_UDMA &&
742 		    (ata_bio->r_error & WDCE_CRC)) {
743 			/*
744 			 * Record the CRC error, to avoid downgrading to
745 			 * multiword DMA
746 			 */
747 			drvp->drive_flags |= DRIVE_DMAERR;
748 		}
749 		if (ata_bio->r_error & (WDCE_BBK | WDCE_UNC | WDCE_IDNF |
750 		    WDCE_ABRT | WDCE_TK0NF | WDCE_AMNF))
751 			return WDC_ATA_ERR;
752 		return WDC_ATA_NOERR;
753 	}
754 
755 	if (chp->ch_status & WDCS_CORR)
756 		ata_bio->flags |= ATA_CORR;
757 	return WDC_ATA_NOERR;
758 }
759 
760 #if 0
761 int
762 wdc_ata_addref(drvp)
763 	struct ata_drive_datas *drvp;
764 {
765 	struct channel_softc *chp = drvp->chnl_softc;
766 
767 	return (wdc_addref(chp));
768 }
769 
770 void
771 wdc_ata_delref(drvp)
772 	struct ata_drive_datas *drvp;
773 {
774 	struct channel_softc *chp = drvp->chnl_softc;
775 
776 	wdc_delref(chp);
777 }
778 #endif
779