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