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