wdc.c revision 1.7 1 /* $NetBSD: wdc.c,v 1.7 1997/10/27 14:09:23 bouyer Exp $ */
2
3 /*
4 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
5 *
6 * DMA and multi-sector PIO handling are derived from code contributed by
7 * Onno van der Linden.
8 *
9 * Atapi support added by Manuel Bouyer.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Charles M. Hannum.
22 * 4. The name of the author may not be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #undef ATAPI_DEBUG_WDC
38 #define WDDEBUG
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/conf.h>
44 #include <sys/file.h>
45 #include <sys/stat.h>
46 #include <sys/ioctl.h>
47 #include <sys/buf.h>
48 #include <sys/uio.h>
49 #include <sys/malloc.h>
50 #include <sys/device.h>
51 #include <sys/disklabel.h>
52 #include <sys/disk.h>
53 #include <sys/syslog.h>
54 #include <sys/proc.h>
55
56 #include <vm/vm.h>
57
58 #include <machine/cpu.h>
59 #include <machine/intr.h>
60 #include <machine/bus.h>
61 #include <machine/pio.h>
62
63 #include <dev/isa/isavar.h>
64 #include <dev/isa/isadmavar.h>
65 #include <dev/isa/wdreg.h>
66 #include <dev/isa/wdlink.h>
67 #include "atapibus.h"
68 #include "wd.h"
69
70 #if NATAPIBUS > 0
71 #include <dev/scsipi/scsipi_all.h>
72 #include <dev/scsipi/atapiconf.h>
73 #endif
74
75 #define WAITTIME (10 * hz) /* time to wait for a completion */
76 /* this is a lot for hard drives, but not for cdroms */
77 #define RECOVERYTIME hz/2
78 #define WDCDELAY 100
79 #define WDCNDELAY 100000 /* delay = 100us; so 10s for a controller state change */
80 #if 0
81 /* If you enable this, it will report any delays more than 100us * N long. */
82 #define WDCNDELAY_DEBUG 50
83 #endif
84
85 #define WDIORETRIES 5 /* number of retries before giving up */
86
87 #define WDPART(dev) DISKPART(dev)
88
89 LIST_HEAD(xfer_free_list, wdc_xfer) xfer_free_list;
90
91 int wdcprobe __P((struct device *, void *, void *));
92 void wdcattach __P((struct device *, struct device *, void *));
93 int wdcintr __P((void *));
94
95 struct cfattach wdc_ca = {
96 sizeof(struct wdc_softc), wdcprobe, wdcattach
97 };
98
99 struct cfdriver wdc_cd = {
100 NULL, "wdc", DV_DULL
101 };
102
103 void wdcstart __P((struct wdc_softc *));
104 int wdcreset __P((struct wdc_softc *, int));
105 #define VERBOSE 1
106 #define SILENT 0
107 void wdcrestart __P((void *arg));
108 void wdcunwedge __P((struct wdc_softc *));
109 void wdctimeout __P((void *arg));
110 int wdccontrol __P((struct wdc_softc*, struct wd_link *));
111 void wdc_free_xfer __P((struct wdc_xfer *));
112 void wdcerror __P((struct wdc_softc*, char *));
113 void wdcbit_bucket __P(( struct wdc_softc *, int));
114 #if NWD > 0
115 int wdprint __P((void *, const char *));
116 int wdsetctlr __P((struct wd_link *));
117 int wdc_ata_intr __P((struct wdc_softc *,struct wdc_xfer *));
118 void wdc_ata_start __P((struct wdc_softc *,struct wdc_xfer *));
119 void wdc_ata_done __P((struct wdc_softc *, struct wdc_xfer *));
120 #endif /* NWD > 0 */
121 #if NATAPIBUS > 0
122 void wdc_atapi_minphys __P((struct buf *bp));
123 void wdc_atapi_start __P((struct wdc_softc *,struct wdc_xfer *));
124 int wdc_atapi_intr __P((struct wdc_softc *, struct wdc_xfer *));
125 void wdc_atapi_done __P((struct wdc_softc *, struct wdc_xfer *));
126 int wdc_atapi_send_command_packet __P((struct scsipi_xfer *sc_xfer));
127 #define MAX_SIZE MAXPHYS /* XXX */
128 #endif
129
130 #ifdef ATAPI_DEBUG
131 static int wdc_nxfer;
132 #endif
133
134 #ifdef WDDEBUG
135 #define WDDEBUG_PRINT(args) printf args
136 #else
137 #define WDDEBUG_PRINT(args)
138 #endif
139
140 #if NATAPIBUS > 0
141 static struct scsipi_adapter wdc_switch = {
142 wdc_atapi_send_command_packet,
143 wdc_atapi_minphys,
144 0,
145 0
146 };
147 #endif
148
149 int
150 wdcprobe(parent, match, aux)
151 struct device *parent;
152 void *match, *aux;
153 {
154 struct wdc_softc *wdc = match;
155 struct isa_attach_args *ia = aux;
156 int iobase;
157
158 wdc->sc_iobase = iobase = ia->ia_iobase;
159
160 if (wdcreset(wdc, SILENT) != 0) {
161 /*
162 * if the reset failed, there is no master. test for ATAPI signature
163 * on the slave device. If no ATAPI slave, wait 5s and retry a reset.
164 */
165 outb(iobase+wd_sdh, WDSD_IBM | 0x10); /* slave */
166 if (inb(iobase + wd_cyl_lo) == 0x14 &&
167 inb(iobase + wd_cyl_hi) == 0xeb) {
168 wdc->sc_flags |= WDCF_ONESLAVE;
169 goto drivefound;
170 } else {
171 delay(500000);
172 if (wdcreset(wdc, SILENT) != 0)
173 return 0;
174 }
175 }
176 /* reset succeeded. Test registers */
177 if (inb(iobase + wd_cyl_lo) == 0x14 &&
178 inb(iobase + wd_cyl_hi) == 0xeb)
179 goto drivefound;
180 /* not ATAPI. Test registers */
181 outb(iobase+wd_error, 0x58); /* Error register not writable, */
182 outb(iobase+wd_cyl_lo, 0xa5); /* but all of cyllo are. */
183 if (inb(iobase+wd_error) != 0x58 && inb(iobase+wd_cyl_lo) == 0xa5)
184 goto drivefound;
185 /* No master. Test atapi signature on slave */
186 outb(iobase+wd_sdh, WDSD_IBM | 0x10);
187 if (inb(iobase + wd_cyl_lo) == 0x14 &&
188 inb(iobase + wd_cyl_hi) == 0xeb) {
189 wdc->sc_flags |= WDCF_ONESLAVE;
190 goto drivefound;
191 }
192 return 0;
193 drivefound:
194 /* Select drive 0 or ATAPI slave device */
195 if (wdc->sc_flags & WDCF_ONESLAVE)
196 outb(iobase+wd_sdh, WDSD_IBM | 0x10);
197 else
198 outb(iobase+wd_sdh, WDSD_IBM);
199
200 /* Wait for controller to become ready. */
201 if (wait_for_unbusy(wdc) < 0)
202 return 0;
203
204 /* Start drive diagnostics. */
205 outb(iobase+wd_command, WDCC_DIAGNOSE);
206
207 /* Wait for command to complete. */
208 if (wait_for_unbusy(wdc) < 0)
209 return 0;
210
211 ia->ia_iosize = 8;
212 ia->ia_msize = 0;
213 return 1;
214 }
215
216 void
217 wdcattach(parent, self, aux)
218 struct device *parent, *self;
219 void *aux;
220 {
221 struct wdc_softc *wdc = (void *)self;
222 struct isa_attach_args *ia = aux;
223 #if NWD > 0
224 int drive;
225 #endif
226
227 TAILQ_INIT(&wdc->sc_xfer);
228 wdc->sc_drq = ia->ia_drq;
229
230 printf("\n");
231 if (wdc->sc_drq != -1) {
232 if (isa_dmamap_create(parent, wdc->sc_drq, MAXPHYS,
233 BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
234 printf("%s: can't create map for drq %d\n",
235 wdc->sc_dev.dv_xname, wdc->sc_drq);
236 wdc->sc_drq = -1;
237 }
238 }
239
240 wdc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
241 IPL_BIO, wdcintr, wdc);
242
243 #ifdef ATAPI_DEBUG
244 wdc_nxfer = 0;
245 #endif
246
247 #if NATAPIBUS > 0
248 /*
249 * Attach an ATAPI bus, if configured.
250 */
251 wdc->ab_link = malloc(sizeof(struct scsipi_link), M_DEVBUF, M_NOWAIT);
252 if (wdc->ab_link == NULL) {
253 printf("%s: can't allocate ATAPI link\n", self->dv_xname);
254 return;
255 }
256 bzero(wdc->ab_link,sizeof(struct scsipi_link));
257 wdc->ab_link->type = BUS_ATAPI;
258 wdc->ab_link->openings = 1;
259 wdc->ab_link->scsipi_atapi.type = ATAPI;
260 wdc->ab_link->scsipi_atapi.channel = 0;
261 wdc->ab_link->adapter_softc = (caddr_t)wdc;
262 wdc->ab_link->adapter = &wdc_switch;
263 (void)config_found(self, (void *)wdc->ab_link, NULL);
264 #endif /* NATAPIBUS > 0 */
265 #if NWD > 0
266 /*
267 * Attach standard IDE/ESDI/etc. disks to the controller.
268 */
269 for (drive = 0; drive < 2; drive++) {
270 /* if a disk is already present, skip */
271 if ((wdc->sc_drives_mask & (1 << drive)) != 0) {
272 continue;
273 }
274 /* test for ATAPI signature on this drive */
275 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM | (drive << 4));
276 if (inb(wdc->sc_iobase+ wd_cyl_lo) == 0x14 &&
277 inb(wdc->sc_iobase + wd_cyl_hi) == 0xeb) {
278 continue;
279 }
280 /* controller active while autoconf */
281 wdc->sc_flags |= WDCF_ACTIVE;
282
283 if (wdccommandshort(wdc, drive, WDCC_RECAL) != 0 ||
284 wait_for_ready(wdc) != 0) {
285 wdc->d_link[drive] = NULL;
286 wdc->sc_flags &= ~WDCF_ACTIVE;
287 } else {
288 wdc->sc_flags &= ~WDCF_ACTIVE;
289 wdc->d_link[drive] = malloc(sizeof(struct wd_link),
290 M_DEVBUF, M_NOWAIT);
291 if (wdc->d_link[drive] == NULL) {
292 printf("%s: can't allocate link for drive %d\n",
293 self->dv_xname, drive);
294 continue;
295 }
296 bzero(wdc->d_link[drive],sizeof(struct wd_link));
297 wdc->d_link[drive]->type = ATA;
298 wdc->d_link[drive]->wdc_softc =(caddr_t) wdc;
299 wdc->d_link[drive]->drive = drive;
300 if (wdc->sc_drq != DRQUNK)
301 wdc->d_link[drive]->sc_mode = WDM_DMA;
302 else
303 wdc->d_link[drive]->sc_mode = 0;
304
305 wdc->sc_drives_mask |= (1 << drive);
306 (void)config_found(self, (void *)wdc->d_link[drive],
307 wdprint);
308 }
309 }
310 #endif /* NWD > 0 */
311 /* explicitely select an existing drive, to avoid spurious interrupts */
312 if (wdc->sc_flags & WDCF_ONESLAVE)
313 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM | 0x10); /* slave */
314 else
315 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM); /* master */
316 }
317
318 /*
319 * Start I/O on a controller. This does the calculation, and starts a read or
320 * write operation. Called to from wdstart() to start a transfer, from
321 * wdcintr() to continue a multi-sector transfer or start the next transfer, or
322 * wdcrestart() after recovering from an error.
323 */
324 void
325 wdcstart(wdc)
326 struct wdc_softc *wdc;
327 {
328 struct wdc_xfer *xfer;
329
330 if ((wdc->sc_flags & WDCF_ACTIVE) != 0 ) {
331 WDDEBUG_PRINT(("wdcstart: already active\n"));
332 return; /* controller aleady active */
333 }
334 #ifdef DIAGNOSTIC
335 if ((wdc->sc_flags & WDCF_IRQ_WAIT) != 0)
336 panic("wdcstart: controller waiting for irq\n");
337 #endif
338 /* is there a xfer ? */
339 xfer = wdc->sc_xfer.tqh_first;
340 if (xfer == NULL) {
341 #ifdef ATAPI_DEBUG2
342 printf("wdcstart: null xfer\n");
343 #endif
344 /*
345 * XXX
346 * This is a kluge. See comments in wd_get_parms().
347 */
348 if ((wdc->sc_flags & WDCF_WANTED) != 0) {
349 #ifdef ATAPI_DEBUG_WDC
350 printf("WDCF_WANTED\n");
351 #endif
352 wdc->sc_flags &= ~WDCF_WANTED;
353 wakeup(wdc);
354 }
355 return;
356 }
357 wdc->sc_flags |= WDCF_ACTIVE;
358 #ifdef ATAPI_DEBUG2
359 printf("wdcstart: drive %d\n", (int)xfer->d_link->drive);
360 #endif
361 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM | xfer->d_link->drive << 4);
362 #if NATAPIBUS > 0 && NWD > 0
363 if (xfer->c_flags & C_ATAPI) {
364 #ifdef ATAPI_DEBUG_WDC
365 printf("wdcstart: atapi\n");
366 #endif
367 wdc_atapi_start(wdc,xfer);
368 } else
369 wdc_ata_start(wdc,xfer);
370 #else /* NATAPIBUS > 0 && NWD > 0 */
371 #if NATAPIBUS > 0
372 #ifdef ATAPI_DEBUG_WDC
373 printf("wdcstart: atapi\n");
374 #endif
375 wdc_atapi_start(wdc,xfer);
376 #endif /* NATAPIBUS > */
377 #if NWD > 0
378 wdc_ata_start(wdc,xfer);
379 #endif /* NWD > 0 */
380 #endif /* NATAPIBUS > 0 && NWD > 0 */
381 }
382
383 #if NWD > 0
384 int
385 wdprint(aux, wdc)
386 void *aux;
387 const char *wdc;
388 {
389 struct wd_link *d_link = aux;
390
391 if (!wdc)
392 printf(" drive %d", d_link->drive);
393 return QUIET;
394 }
395
396 void
397 wdc_ata_start(wdc, xfer)
398 struct wdc_softc *wdc;
399 struct wdc_xfer *xfer;
400 {
401 struct wd_link *d_link;
402 struct buf *bp = xfer->c_bp;
403 int nblks;
404
405 d_link=xfer->d_link;
406
407 if (wdc->sc_errors >= WDIORETRIES) {
408 wderror(d_link, bp, "wdc_ata_start hard error");
409 xfer->c_flags |= C_ERROR;
410 wdc_ata_done(wdc, xfer);
411 return;
412 }
413
414 /* Do control operations specially. */
415 if (d_link->sc_state < READY) {
416 /*
417 * Actually, we want to be careful not to mess with the control
418 * state if the device is currently busy, but we can assume
419 * that we never get to this point if that's the case.
420 */
421 if (wdccontrol(wdc, d_link) == 0) {
422 /* The drive is busy. Wait. */
423 return;
424 }
425 }
426
427 /*
428 * WDCF_ERROR is set by wdcunwedge() and wdcintr() when an error is
429 * encountered. If we are in multi-sector mode, then we switch to
430 * single-sector mode and retry the operation from the start.
431 */
432 if (wdc->sc_flags & WDCF_ERROR) {
433 wdc->sc_flags &= ~WDCF_ERROR;
434 if ((wdc->sc_flags & WDCF_SINGLE) == 0) {
435 wdc->sc_flags |= WDCF_SINGLE;
436 xfer->c_skip = 0;
437 }
438 }
439
440
441 /* When starting a transfer... */
442 if (xfer->c_skip == 0) {
443 daddr_t blkno;
444
445 WDDEBUG_PRINT(("\n%s: wdc_ata_start %s %d@%d; map ",
446 wdc->sc_dev.dv_xname,
447 (xfer->c_flags & B_READ) ? "read" : "write",
448 xfer->c_bcount, xfer->c_blkno));
449
450 blkno = xfer->c_blkno+xfer->c_p_offset;
451 xfer->c_blkno = blkno / (d_link->sc_lp->d_secsize / DEV_BSIZE);
452 } else {
453 WDDEBUG_PRINT((" %d)%x", xfer->c_skip,
454 inb(wdc->sc_iobase + wd_altsts)));
455 }
456
457 /*
458 * When starting a multi-sector transfer, or doing single-sector
459 * transfers...
460 */
461 if (xfer->c_skip == 0 || (wdc->sc_flags & WDCF_SINGLE) != 0 ||
462 d_link->sc_mode == WDM_DMA) {
463 daddr_t blkno = xfer->c_blkno;
464 long cylin, head, sector;
465 int command;
466
467 if ((wdc->sc_flags & WDCF_SINGLE) != 0)
468 nblks = 1;
469 else if (d_link->sc_mode != WDM_DMA)
470 nblks = xfer->c_bcount / d_link->sc_lp->d_secsize;
471 else
472 nblks =
473 min(xfer->c_bcount / d_link->sc_lp->d_secsize, 8);
474
475 /* Check for bad sectors and adjust transfer, if necessary. */
476 if ((d_link->sc_lp->d_flags & D_BADSECT) != 0
477 #ifdef B_FORMAT
478 && (bp->b_flags & B_FORMAT) == 0
479 #endif
480 ) {
481 long blkdiff;
482 int i;
483
484 for (i = 0;
485 (blkdiff = d_link->sc_badsect[i]) != -1; i++) {
486 blkdiff -= blkno;
487 if (blkdiff < 0)
488 continue;
489 if (blkdiff == 0) {
490 /* Replace current block of transfer. */
491 blkno =
492 d_link->sc_lp->d_secperunit -
493 d_link->sc_lp->d_nsectors - i - 1;
494 }
495 if (blkdiff < nblks) {
496 /* Bad block inside transfer. */
497 wdc->sc_flags |= WDCF_SINGLE;
498 nblks = 1;
499 }
500 break;
501 }
502 /* Tranfer is okay now. */
503 }
504
505 if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) {
506 sector = (blkno >> 0) & 0xff;
507 cylin = (blkno >> 8) & 0xffff;
508 head = (blkno >> 24) & 0xf;
509 head |= WDSD_LBA;
510 } else {
511 sector = blkno % d_link->sc_lp->d_nsectors;
512 sector++; /* Sectors begin with 1, not 0. */
513 blkno /= d_link->sc_lp->d_nsectors;
514 head = blkno % d_link->sc_lp->d_ntracks;
515 blkno /= d_link->sc_lp->d_ntracks;
516 cylin = blkno;
517 head |= WDSD_CHS;
518 }
519
520 if (d_link->sc_mode == WDM_PIOSINGLE ||
521 (wdc->sc_flags & WDCF_SINGLE) != 0)
522 xfer->c_nblks = 1;
523 else if (d_link->sc_mode == WDM_PIOMULTI)
524 xfer->c_nblks = min(nblks, d_link->sc_multiple);
525 else
526 xfer->c_nblks = nblks;
527 xfer->c_nbytes = xfer->c_nblks * d_link->sc_lp->d_secsize;
528
529 #ifdef B_FORMAT
530 if (bp->b_flags & B_FORMAT) {
531 sector = d_link->sc_lp->d_gap3;
532 nblks = d_link->sc_lp->d_nsectors;
533 command = WDCC_FORMAT;
534 } else
535 #endif
536 switch (d_link->sc_mode) {
537 case WDM_DMA:
538 command = (xfer->c_flags & B_READ) ?
539 WDCC_READDMA : WDCC_WRITEDMA;
540 /* Start the DMA channel. */
541 isa_dmastart(wdc->sc_dev.dv_parent, wdc->sc_drq,
542 xfer->databuf + xfer->c_skip, xfer->c_nbytes,
543 NULL,
544 xfer->c_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE,
545 BUS_DMA_NOWAIT);
546 break;
547
548 case WDM_PIOMULTI:
549 command = (xfer->c_flags & B_READ) ?
550 WDCC_READMULTI : WDCC_WRITEMULTI;
551 break;
552
553 case WDM_PIOSINGLE:
554 command = (xfer->c_flags & B_READ) ?
555 WDCC_READ : WDCC_WRITE;
556 break;
557
558 default:
559 #ifdef DIAGNOSTIC
560 panic("bad wd mode");
561 #endif
562 return;
563 }
564
565 /* Initiate command! */
566 if (wdccommand(wdc, d_link, command, d_link->drive,
567 cylin, head, sector, nblks) != 0) {
568 wderror(d_link, NULL,
569 "wdc_ata_start: timeout waiting for unbusy");
570 wdcunwedge(wdc);
571 return;
572 }
573
574 WDDEBUG_PRINT(("sector %d cylin %d head %d addr %x sts %x\n",
575 sector, cylin, head, xfer->databuf,
576 inb(wdc->sc_iobase + wd_altsts)));
577
578 } else if (xfer->c_nblks > 1) {
579 /* The number of blocks in the last stretch may be smaller. */
580 nblks = xfer->c_bcount / d_link->sc_lp->d_secsize;
581 if (xfer->c_nblks > nblks) {
582 xfer->c_nblks = nblks;
583 xfer->c_nbytes = xfer->c_bcount;
584 }
585 }
586
587 /* If this was a write and not using DMA, push the data. */
588 if (d_link->sc_mode != WDM_DMA &&
589 (xfer->c_flags & (B_READ|B_WRITE)) == B_WRITE) {
590 if (wait_for_drq(wdc) < 0) {
591 wderror(d_link, NULL,
592 "wdc_ata_start: timeout waiting for drq");
593 wdcunwedge(wdc);
594 return;
595 }
596
597 /* Push out data. */
598 if ((d_link->sc_flags & WDF_32BIT) == 0)
599 outsw(wdc->sc_iobase + wd_data,
600 xfer->databuf + xfer->c_skip,
601 xfer->c_nbytes >> 1);
602 else
603 outsl(wdc->sc_iobase + wd_data,
604 xfer->databuf + xfer->c_skip,
605 xfer->c_nbytes >> 2);
606 }
607
608 wdc->sc_flags |= WDCF_IRQ_WAIT;
609 WDDEBUG_PRINT(("wdc_ata_start: timeout "));
610 timeout(wdctimeout, wdc, WAITTIME);
611 WDDEBUG_PRINT(("done\n"));
612 }
613
614 int
615 wdc_ata_intr(wdc,xfer)
616 struct wdc_softc *wdc;
617 struct wdc_xfer *xfer;
618 {
619 struct wd_link *d_link;
620
621 d_link = xfer->d_link;
622
623 if (wait_for_unbusy(wdc) < 0) {
624 wdcerror(wdc, "wdcintr: timeout waiting for unbusy");
625 return 0;
626 }
627
628 untimeout(wdctimeout, wdc);
629
630 /* Is it not a transfer, but a control operation? */
631 if (d_link->sc_state < READY) {
632 if (wdccontrol(wdc, d_link) == 0) {
633 /* The drive is busy. Wait. */
634 return 1;
635 }
636 WDDEBUG_PRINT(("wdc_ata_start from wdc_ata_intr(open) flags 0x%x\n",
637 dc->sc_flags));
638 wdc_ata_start(wdc,xfer);
639 return 1;
640 }
641
642 /* Turn off the DMA channel. */
643 if (d_link->sc_mode == WDM_DMA)
644 isa_dmadone(wdc->sc_dev.dv_parent, wdc->sc_drq);
645
646 /* Have we an error? */
647 if (wdc->sc_status & WDCS_ERR) {
648 #ifdef WDDEBUG
649 wderror(d_link, NULL, "wdc_ata_start");
650 #endif
651 if ((wdc->sc_flags & WDCF_SINGLE) == 0) {
652 wdc->sc_flags |= WDCF_ERROR;
653 goto restart;
654 }
655
656 #ifdef B_FORMAT
657 if (bp->b_flags & B_FORMAT)
658 goto bad;
659 #endif
660
661 if (++wdc->sc_errors < WDIORETRIES) {
662 if (wdc->sc_errors == (WDIORETRIES + 1) / 2) {
663 #if 0
664 wderror(wd, NULL, "wedgie");
665 #endif
666 wdcunwedge(wdc);
667 return 1;
668 }
669 goto restart;
670 }
671 wderror(d_link, xfer->c_bp, "wdc_ata_intr hard error");
672
673 #ifdef B_FORMAT
674 bad:
675 #endif
676 xfer->c_flags |= C_ERROR;
677 goto done;
678 }
679
680 /* If this was a read and not using DMA, fetch the data. */
681 if (d_link->sc_mode != WDM_DMA &&
682 (xfer->c_flags & (B_READ|B_WRITE)) == B_READ) {
683 if ((wdc->sc_status & (WDCS_DRDY | WDCS_DSC | WDCS_DRQ))
684 != (WDCS_DRDY | WDCS_DSC | WDCS_DRQ)) {
685 wderror(d_link, NULL, "wdcintr: read intr before drq");
686 wdcunwedge(wdc);
687 return 1;
688 }
689
690 /* Pull in data. */
691 if ((d_link->sc_flags & WDF_32BIT) == 0)
692 insw(wdc->sc_iobase+wd_data,
693 xfer->databuf + xfer->c_skip, xfer->c_nbytes >> 1);
694 else
695 insl(wdc->sc_iobase+wd_data,
696 xfer->databuf + xfer->c_skip, xfer->c_nbytes >> 2);
697 }
698
699 /* If we encountered any abnormalities, flag it as a soft error. */
700 if (wdc->sc_errors > 0 ||
701 (wdc->sc_status & WDCS_CORR) != 0) {
702 wderror(d_link, xfer->c_bp, "soft error (corrected)");
703 wdc->sc_errors = 0;
704 }
705
706 /* Adjust pointers for the next block, if any. */
707 xfer->c_blkno += xfer->c_nblks;
708 xfer->c_skip += xfer->c_nbytes;
709 xfer->c_bcount -= xfer->c_nbytes;
710
711 /* See if this transfer is complete. */
712 if (xfer->c_bcount > 0)
713 goto restart;
714
715 done:
716 /* Done with this transfer, with or without error. */
717 wdc_ata_done(wdc, xfer);
718 return 1;
719
720 restart:
721 /* Start the next operation */
722 WDDEBUG_PRINT(("wdc_ata_start from wdcintr flags 0x%x\n",
723 wdc->sc_flags));
724 wdc_ata_start(wdc, xfer);
725
726 return 1;
727 }
728
729 void
730 wdc_ata_done(wdc, xfer)
731 struct wdc_softc *wdc;
732 struct wdc_xfer *xfer;
733 {
734 struct buf *bp = xfer->c_bp;
735 struct wd_link *d_link = xfer->d_link;
736 int s;
737
738 WDDEBUG_PRINT(("wdc_ata_done\n"));
739
740 /* remove this command from xfer queue */
741 s = splbio();
742 TAILQ_REMOVE(&wdc->sc_xfer, xfer, c_xferchain);
743 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
744 wdc->sc_errors = 0;
745 if (bp) {
746 if (xfer->c_flags & C_ERROR) {
747 bp->b_flags |= B_ERROR;
748 bp->b_error = EIO;
749 }
750 bp->b_resid = xfer->c_bcount;
751 wddone(d_link, bp);
752 biodone(bp);
753 } else {
754 wakeup(xfer->databuf);
755 }
756 xfer->c_skip = 0;
757 wdc_free_xfer(xfer);
758 d_link->openings++;
759 wdstart((void*)d_link->wd_softc);
760 WDDEBUG_PRINT(("wdcstart from wdc_ata_done, flags 0x%x\n",
761 wdc->sc_flags));
762 wdcstart(wdc);
763 splx(s);
764 }
765
766 /*
767 * Get the drive parameters, if ESDI or ATA, or create fake ones for ST506.
768 */
769 int
770 wdc_get_parms(wdc, d_link)
771 struct wdc_softc * wdc;
772 struct wd_link *d_link;
773 {
774 int i;
775 char tb[DEV_BSIZE];
776 int s, error;
777
778 /*
779 * XXX
780 * The locking done here, and the length of time this may keep the rest
781 * of the system suspended, is a kluge. This should be rewritten to
782 * set up a transfer and queue it through wdstart(), but it's called
783 * infrequently enough that this isn't a pressing matter.
784 */
785
786 s = splbio();
787
788 while ((wdc->sc_flags & WDCF_ACTIVE) != 0) {
789 wdc->sc_flags |= WDCF_WANTED;
790 if ((error = tsleep(wdc, PRIBIO | PCATCH, "wdprm", 0)) != 0) {
791 splx(s);
792 return error;
793 }
794 }
795
796 wdc->sc_flags |= WDCF_ACTIVE;
797
798 if (wdccommandshort(wdc, d_link->drive, WDCC_IDENTIFY) != 0 ||
799 wait_for_drq(wdc) != 0) {
800 /*
801 * We `know' there's a drive here; just assume it's old.
802 * This geometry is only used to read the MBR and print a
803 * (false) attach message.
804 */
805 strncpy(d_link->sc_lp->d_typename, "ST506",
806 sizeof d_link->sc_lp->d_typename);
807 d_link->sc_lp->d_type = DTYPE_ST506;
808
809 strncpy(d_link->sc_params.wdp_model, "unknown",
810 sizeof d_link->sc_params.wdp_model);
811 d_link->sc_params.wdp_config = WD_CFG_FIXED;
812 d_link->sc_params.wdp_cylinders = 1024;
813 d_link->sc_params.wdp_heads = 8;
814 d_link->sc_params.wdp_sectors = 17;
815 d_link->sc_params.wdp_maxmulti = 0;
816 d_link->sc_params.wdp_usedmovsd = 0;
817 d_link->sc_params.wdp_capabilities = 0;
818 } else {
819 strncpy(d_link->sc_lp->d_typename, "ESDI/IDE",
820 sizeof d_link->sc_lp->d_typename);
821 d_link->sc_lp->d_type = DTYPE_ESDI;
822
823 /* Read in parameter block. */
824 insw(wdc->sc_iobase + wd_data, tb, sizeof(tb) / sizeof(short));
825 bcopy(tb, &d_link->sc_params, sizeof(struct wdparams));
826
827 /* Shuffle string byte order. */
828 for (i = 0; i < sizeof(d_link->sc_params.wdp_model); i += 2) {
829 u_short *p;
830 p = (u_short *)(d_link->sc_params.wdp_model + i);
831 *p = ntohs(*p);
832 }
833 }
834
835 /* Clear any leftover interrupt. */
836 (void) inb(wdc->sc_iobase + wd_status);
837
838 /* Restart the queue. */
839 WDDEBUG_PRINT(("wdcstart from wdc_get_parms flags 0x%x\n",
840 wdc->sc_flags));
841 wdc->sc_flags &= ~WDCF_ACTIVE;
842 wdcstart(wdc);
843
844 splx(s);
845 return 0;
846 }
847
848 /*
849 * Implement operations needed before read/write.
850 * Returns 0 if operation still in progress, 1 if completed.
851 */
852 int
853 wdccontrol(wdc, d_link)
854 struct wdc_softc *wdc;
855 struct wd_link *d_link;
856 {
857 WDDEBUG_PRINT(("wdccontrol\n"));
858
859 switch (d_link->sc_state) {
860 case RECAL: /* Set SDH, step rate, do recal. */
861 if (wdccommandshort(wdc, d_link->drive, WDCC_RECAL) != 0) {
862 wderror(d_link, NULL, "wdccontrol: recal failed (1)");
863 goto bad;
864 }
865 d_link->sc_state = RECAL_WAIT;
866 break;
867
868 case RECAL_WAIT:
869 if (wdc->sc_status & WDCS_ERR) {
870 wderror(d_link, NULL, "wdccontrol: recal failed (2)");
871 goto bad;
872 }
873 /* fall through */
874
875 case GEOMETRY:
876 if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0)
877 goto multimode;
878 if (wdsetctlr(d_link) != 0) {
879 /* Already printed a message. */
880 goto bad;
881 }
882 d_link->sc_state = GEOMETRY_WAIT;
883 break;
884
885 case GEOMETRY_WAIT:
886 if (wdc->sc_status & WDCS_ERR) {
887 wderror(d_link, NULL, "wdccontrol: geometry failed");
888 goto bad;
889 }
890 /* fall through */
891
892 case MULTIMODE:
893 multimode:
894 if (d_link->sc_mode != WDM_PIOMULTI)
895 goto ready;
896 outb(wdc->sc_iobase + wd_seccnt, d_link->sc_multiple);
897 if (wdccommandshort(wdc, d_link->drive,
898 WDCC_SETMULTI) != 0) {
899 wderror(d_link, NULL,
900 "wdccontrol: setmulti failed (1)");
901 goto bad;
902 }
903 d_link->sc_state = MULTIMODE_WAIT;
904 break;
905
906 case MULTIMODE_WAIT:
907 if (wdc->sc_status & WDCS_ERR) {
908 wderror(d_link, NULL,
909 "wdccontrol: setmulti failed (2)");
910 goto bad;
911 }
912 /* fall through */
913
914 case READY:
915 ready:
916 wdc->sc_errors = 0;
917 d_link->sc_state = READY;
918 /*
919 * The rest of the initialization can be done by normal means.
920 */
921 return 1;
922
923 bad:
924 wdcunwedge(wdc);
925 return 0;
926 }
927
928 wdc->sc_flags |= WDCF_IRQ_WAIT;
929 timeout(wdctimeout, wdc, WAITTIME);
930 return 0;
931 }
932
933 #endif /* NWD > 0 */
934
935
936 /*
937 * Interrupt routine for the controller. Acknowledge the interrupt, check for
938 * errors on the current operation, mark it done if necessary, and start the
939 * next request. Also check for a partially done transfer, and continue with
940 * the next chunk if so.
941 */
942 int
943 wdcintr(arg)
944 void *arg;
945 {
946 struct wdc_softc *wdc = arg;
947 struct wdc_xfer *xfer;
948
949 if ((wdc->sc_flags & WDCF_IRQ_WAIT) == 0) {
950 /* Clear the pending interrupt and abort. */
951 u_char s = inb(wdc->sc_iobase+wd_status);
952
953 #ifdef ATAPI_DEBUG_WDC
954 u_char e = inb(wdc->sc_iobase+wd_error);
955 u_char i = inb(wdc->sc_iobase+wd_seccnt);
956 printf("wdcintr: inactive controller, "
957 "punting st=%02x er=%02x irr=%02x\n", s, e, i);
958 #else
959 inb(wdc->sc_iobase+wd_error);
960 inb(wdc->sc_iobase+wd_seccnt);
961 #endif
962
963 if (s & WDCS_DRQ) {
964 int len = inb (wdc->sc_iobase + wd_cyl_lo) +
965 256 * inb (wdc->sc_iobase + wd_cyl_hi);
966 #ifdef ATAPI_DEBUG_WDC
967 printf ("wdcintr: clearing up %d bytes\n", len);
968 #endif
969 wdcbit_bucket (wdc, len);
970 }
971 return 0;
972 }
973
974 WDDEBUG_PRINT(("wdcintr\n"));
975
976 wdc->sc_flags &= ~WDCF_IRQ_WAIT;
977 xfer = wdc->sc_xfer.tqh_first;
978 #if NATAPIBUS > 0 && NWD > 0
979 if (xfer->c_flags & C_ATAPI) {
980 return wdc_atapi_intr(wdc,xfer);
981 } else
982 return wdc_ata_intr(wdc,xfer);
983 #else /* NATAPIBUS > 0 && NWD > 0 */
984 #if NATAPIBUS > 0
985 return wdc_atapi_intr(wdc,xfer);
986 #endif /* NATAPIBUS > 0 */
987 #if NWD > 0
988 return wdc_ata_intr(wdc,xfer);
989 #endif /* NWD > 0 */
990 #endif /* NATAPIBUS > 0 && NWD > 0 */
991 }
992
993 int
994 wdcreset(wdc, verb)
995 struct wdc_softc *wdc;
996 int verb;
997 {
998 int iobase = wdc->sc_iobase;
999
1000 /* Reset the device. */
1001 outb(iobase+wd_ctlr, WDCTL_RST | WDCTL_IDS);
1002 delay(1000);
1003 outb(iobase+wd_ctlr, WDCTL_IDS);
1004 delay(1000);
1005 (void) inb(iobase+wd_error);
1006 outb(iobase+wd_ctlr, WDCTL_4BIT);
1007
1008 if (wait_for_unbusy(wdc) < 0) {
1009 if (verb)
1010 printf("%s: reset failed\n", wdc->sc_dev.dv_xname);
1011 return 1;
1012 }
1013
1014 return 0;
1015 }
1016
1017 void
1018 wdcrestart(arg)
1019 void *arg;
1020 {
1021 struct wdc_softc *wdc = arg;
1022 int s;
1023
1024 s = splbio();
1025 wdcstart(wdc);
1026 splx(s);
1027 }
1028
1029 /*
1030 * Unwedge the controller after an unexpected error. We do this by resetting
1031 * it, marking all drives for recalibration, and stalling the queue for a short
1032 * period to give the reset time to finish.
1033 * NOTE: We use a timeout here, so this routine must not be called during
1034 * autoconfig or dump.
1035 */
1036 void
1037 wdcunwedge(wdc)
1038 struct wdc_softc *wdc;
1039 {
1040 int unit;
1041
1042 #ifdef ATAPI_DEBUG
1043 printf("wdcunwedge\n");
1044 #endif
1045
1046 untimeout(wdctimeout, wdc);
1047 wdc->sc_flags &= ~WDCF_IRQ_WAIT;
1048 (void) wdcreset(wdc, VERBOSE);
1049
1050 /* Schedule recalibrate for all drives on this controller. */
1051 for (unit = 0; unit < 2; unit++) {
1052 if (!wdc->d_link[unit]) continue;
1053 if (wdc->d_link[unit]->sc_state > RECAL)
1054 wdc->d_link[unit]->sc_state = RECAL;
1055 }
1056
1057 wdc->sc_flags |= WDCF_ERROR;
1058 ++wdc->sc_errors;
1059
1060 /* Wake up in a little bit and restart the operation. */
1061 WDDEBUG_PRINT(("wdcrestart from wdcunwedge\n"));
1062 wdc->sc_flags &= ~WDCF_ACTIVE;
1063 timeout(wdcrestart, wdc, RECOVERYTIME);
1064 }
1065
1066 int
1067 wdcwait(wdc, mask)
1068 struct wdc_softc *wdc;
1069 int mask;
1070 {
1071 int iobase = wdc->sc_iobase;
1072 int timeout = 0;
1073 u_char status;
1074 #ifdef WDCNDELAY_DEBUG
1075 extern int cold;
1076 #endif
1077
1078 WDDEBUG_PRINT(("wdcwait iobase %x\n", iobase));
1079
1080 for (;;) {
1081 wdc->sc_status = status = inb(iobase+wd_status);
1082 /*
1083 * XXX
1084 * If a single slave ATAPI device is attached, it may
1085 * have released the bus. Select it and try again.
1086 */
1087 if (status == 0xff && wdc->sc_flags & WDCF_ONESLAVE) {
1088 outb(iobase+wd_sdh, WDSD_IBM | 0x10);
1089 wdc->sc_status = status = inb(iobase+wd_status);
1090 }
1091 if ((status & WDCS_BSY) == 0 && (status & mask) == mask)
1092 break;
1093 if (++timeout > WDCNDELAY) {
1094 #ifdef ATAPI_DEBUG
1095 printf("wdcwait: timeout, status %x error %x\n", status, inb(iobase+wd_error));
1096 #endif
1097 return -1;
1098 }
1099 delay(WDCDELAY);
1100 }
1101 if (status & WDCS_ERR) {
1102 wdc->sc_error = inb(iobase+wd_error);
1103 return WDCS_ERR;
1104 }
1105 #ifdef WDCNDELAY_DEBUG
1106 /* After autoconfig, there should be no long delays. */
1107 if (!cold && timeout > WDCNDELAY_DEBUG) {
1108 struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first;
1109 if (xfer == NULL)
1110 printf("%s: warning: busy-wait took %dus\n",
1111 wdc->sc_dev.dv_xname, WDCDELAY * timeout);
1112 else
1113 printf("%s(%s): warning: busy-wait took %dus\n",
1114 wdc->sc_dev.dv_xname,
1115 ((struct device*)xfer->d_link->wd_softc)->dv_xname,
1116 WDCDELAY * timeout);
1117 }
1118 #endif
1119 return 0;
1120 }
1121
1122 void
1123 wdctimeout(arg)
1124 void *arg;
1125 {
1126 struct wdc_softc *wdc = (struct wdc_softc *)arg;
1127 int s;
1128
1129 WDDEBUG_PRINT(("wdctimeout\n"));
1130
1131 s = splbio();
1132 if ((wdc->sc_flags & WDCF_IRQ_WAIT) != 0) {
1133 wdc->sc_flags &= ~WDCF_IRQ_WAIT;
1134 wdcerror(wdc, "lost interrupt");
1135 wdcunwedge(wdc);
1136 } else
1137 wdcerror(wdc, "missing untimeout");
1138 splx(s);
1139 }
1140
1141 /*
1142 * Wait for the drive to become ready and send a command.
1143 * Return -1 if busy for too long or 0 otherwise.
1144 * Assumes interrupts are blocked.
1145 */
1146 int
1147 wdccommand(wdc, d_link, command, drive, cylin, head, sector, count)
1148 struct wdc_softc *wdc;
1149 struct wd_link *d_link;
1150 int command;
1151 int drive, cylin, head, sector, count;
1152 {
1153 int iobase = wdc->sc_iobase;
1154 int stat;
1155
1156 WDDEBUG_PRINT(("wdccommand drive %d\n", drive));
1157
1158 #if defined(DIAGNOSTIC) && defined(WDCDEBUG)
1159 if ((wdc->sc_flags & WDCF_ACTIVE) == 0)
1160 printf("wdccommand: controler not active (drive %d)\n", drive);
1161 #endif
1162
1163 /* Select drive, head, and addressing mode. */
1164 outb(iobase+wd_sdh, WDSD_IBM | (drive << 4) | head);
1165
1166 /* Wait for it to become ready to accept a command. */
1167 if (command == WDCC_IDP || d_link->type == ATAPI)
1168 stat = wait_for_unbusy(wdc);
1169 else
1170 stat = wdcwait(wdc, WDCS_DRDY);
1171
1172 if (stat < 0) {
1173 #ifdef ATAPI_DEBUG
1174 printf("wdcommand: xfer failed (wait_for_unbusy) status %d\n",
1175 stat);
1176 #endif
1177 return -1;
1178 }
1179
1180 /* Load parameters. */
1181 if (d_link->type == ATA && d_link->sc_lp->d_type == DTYPE_ST506)
1182 outb(iobase + wd_precomp, d_link->sc_lp->d_precompcyl / 4);
1183 else
1184 outb(iobase + wd_features, 0);
1185 outb(iobase + wd_cyl_lo, cylin);
1186 outb(iobase + wd_cyl_hi, cylin >> 8);
1187 outb(iobase + wd_sector, sector);
1188 outb(iobase + wd_seccnt, count);
1189
1190 /* Send command. */
1191 outb(iobase + wd_command, command);
1192
1193 return 0;
1194 }
1195
1196 /*
1197 * Simplified version of wdccommand().
1198 */
1199 int
1200 wdccommandshort(wdc, drive, command)
1201 struct wdc_softc *wdc;
1202 int drive;
1203 int command;
1204 {
1205 int iobase = wdc->sc_iobase;
1206
1207 WDDEBUG_PRINT(("wdccommandshort\n"));
1208
1209 #if defined(DIAGNOSTIC) && defined(WDCDEBUG)
1210 if ((wdc->sc_flags & WDCF_ACTIVE) == 0)
1211 printf("wdccommandshort: controler not active (drive %d)\n",
1212 drive);
1213 #endif
1214
1215 /* Select drive. */
1216 outb(iobase + wd_sdh, WDSD_IBM | (drive << 4));
1217
1218 if (wdcwait(wdc, WDCS_DRDY) < 0)
1219 return -1;
1220
1221 outb(iobase + wd_command, command);
1222
1223 return 0;
1224 }
1225
1226 void
1227 wdc_exec_xfer(wdc, d_link, xfer)
1228 struct wdc_softc *wdc;
1229 struct wd_link *d_link;
1230 struct wdc_xfer *xfer;
1231 {
1232 int s;
1233
1234 WDDEBUG_PRINT(("wdc_exec_xfer\n"));
1235
1236 s = splbio();
1237
1238 /* insert at the end of command list */
1239 TAILQ_INSERT_TAIL(&wdc->sc_xfer,xfer , c_xferchain)
1240 WDDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
1241 wdc->sc_flags));
1242 wdcstart(wdc);
1243 xfer->c_flags |= C_NEEDDONE; /* we can now call upper level done() */
1244 splx(s);
1245 }
1246
1247 struct wdc_xfer *
1248 wdc_get_xfer(flags)
1249 int flags;
1250 {
1251 struct wdc_xfer *xfer;
1252 int s;
1253
1254 s = splbio();
1255 if ((xfer = xfer_free_list.lh_first) != NULL) {
1256 LIST_REMOVE(xfer, free_list);
1257 splx(s);
1258 #ifdef DIAGNOSTIC
1259 if ((xfer->c_flags & C_INUSE) != 0)
1260 panic("wdc_get_xfer: xfer already in use\n");
1261 #endif
1262 } else {
1263 splx(s);
1264 #ifdef ATAPI_DEBUG
1265 printf("wdc:making xfer %d\n",wdc_nxfer);
1266 #endif
1267 xfer = malloc(sizeof(*xfer), M_DEVBUF,
1268 ((flags & IDE_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK));
1269 if (xfer == NULL)
1270 return 0;
1271
1272 #ifdef DIAGNOSTIC
1273 xfer->c_flags &= ~C_INUSE;
1274 #endif
1275 #ifdef ATAPI_DEBUG
1276 wdc_nxfer++;
1277 #endif
1278 }
1279 #ifdef DIAGNOSTIC
1280 if ((xfer->c_flags & C_INUSE) != 0)
1281 panic("wdc_get_xfer: xfer already in use\n");
1282 #endif
1283 bzero(xfer,sizeof(struct wdc_xfer));
1284 xfer->c_flags = C_INUSE;
1285 return xfer;
1286 }
1287
1288 void
1289 wdc_free_xfer(xfer)
1290 struct wdc_xfer *xfer;
1291 {
1292 int s;
1293
1294 s = splbio();
1295 xfer->c_flags &= ~C_INUSE;
1296 LIST_INSERT_HEAD(&xfer_free_list, xfer, free_list);
1297 splx(s);
1298 }
1299
1300 void
1301 wdcerror(wdc, msg)
1302 struct wdc_softc *wdc;
1303 char *msg;
1304 {
1305 struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first;
1306 if (xfer == NULL)
1307 printf("%s: %s\n", wdc->sc_dev.dv_xname, msg);
1308 else
1309 printf("%s(%d): %s\n", wdc->sc_dev.dv_xname,
1310 xfer->d_link->drive, msg);
1311 }
1312
1313 /*
1314 * the bit bucket
1315 */
1316 void
1317 wdcbit_bucket(wdc, size)
1318 struct wdc_softc *wdc;
1319 int size;
1320 {
1321 int iobase = wdc->sc_iobase;
1322 int i;
1323
1324 for (i = 0 ; i < size / 2 ; i++) {
1325 short null;
1326 (void)insw(iobase + wd_data, &null, 1);
1327 }
1328
1329 if (size % 2)
1330 (void)inb(iobase + wd_data);
1331 }
1332
1333
1334 #if NATAPIBUS > 0
1335
1336 void
1337 wdc_atapi_minphys (struct buf *bp)
1338 {
1339 if(bp->b_bcount > MAX_SIZE)
1340 bp->b_bcount = MAX_SIZE;
1341 minphys(bp);
1342 }
1343
1344
1345 void
1346 wdc_atapi_start(wdc, xfer)
1347 struct wdc_softc *wdc;
1348 struct wdc_xfer *xfer;
1349 {
1350 struct scsipi_xfer *sc_xfer = xfer->atapi_cmd;
1351
1352 #ifdef ATAPI_DEBUG_WDC
1353 printf("wdc_atapi_start, acp flags %x \n",sc_xfer->flags);
1354 #endif
1355 if (wdc->sc_errors >= WDIORETRIES) {
1356 if ((wdc->sc_status & WDCS_ERR) == 0) {
1357 sc_xfer->error = XS_DRIVER_STUFFUP; /* XXX do we know more ? */
1358 } else {
1359 sc_xfer->error = XS_SENSE;
1360 sc_xfer->sense.atapi_sense = inb (wdc->sc_iobase + wd_error);
1361 }
1362 wdc_atapi_done(wdc, xfer);
1363 return;
1364 }
1365 if (wait_for_unbusy(wdc) != 0) {
1366 if ((wdc->sc_status & WDCS_ERR) == 0) {
1367 printf("wdc_atapi_start: not ready, st = %02x\n",
1368 wdc->sc_status);
1369 sc_xfer->error = XS_SELTIMEOUT;
1370 }
1371 #if 0 /* don't get the sense yet, as this may be just UNIT ATTENTION */
1372 else {
1373 #ifdef ATAPI_DEBUG_WDC
1374 printf("wdc_atapi_start: sense %02x\n", wdc->sc_error);
1375 #endif
1376 sc_xfer->error = XS_SENSE;
1377 sc_xfer->sense.atapi_sense = wdc->sc_error;
1378 }
1379 wdc_atapi_done(wdc, xfer);
1380 return;
1381 #endif
1382 }
1383
1384 if (wdccommand(wdc, (struct wd_link*)xfer->d_link, ATAPI_PACKET_COMMAND,
1385 sc_xfer->sc_link->scsipi_atapi.drive, sc_xfer->datalen,
1386 0, 0, 0) != 0) {
1387 printf("wdc_atapi_start: can't send atapi paket command\n");
1388 sc_xfer->error = XS_DRIVER_STUFFUP;
1389 wdc->sc_flags |= WDCF_IRQ_WAIT;
1390 wdc_atapi_done(wdc, xfer);
1391 return;
1392 }
1393 if ((sc_xfer->sc_link->scsipi_atapi.cap & 0x0300) != ACAP_DRQ_INTR) {
1394 int i, phase;
1395 for (i=20000; i>0; --i) {
1396 phase = (inb(wdc->sc_iobase + wd_ireason) &
1397 (WDCI_CMD | WDCI_IN)) |
1398 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
1399 if (phase == PHASE_CMDOUT)
1400 break;
1401 delay(10);
1402 }
1403 if (phase != PHASE_CMDOUT ) {
1404 printf("wdc_atapi_start: timout waiting PHASE_CMDOUT");
1405 sc_xfer->error = XS_SELTIMEOUT;
1406 wdc_atapi_done(wdc, xfer);
1407 return;
1408 }
1409 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd,
1410 sc_xfer->cmdlen / sizeof(short));
1411 }
1412 wdc->sc_flags |= WDCF_IRQ_WAIT;
1413
1414 #ifdef ATAPI_DEBUG2
1415 printf("wdc_atapi_start: timeout\n");
1416 #endif
1417 timeout(wdctimeout, wdc, WAITTIME);
1418 return;
1419 }
1420
1421
1422 int
1423 wdc_atapi_get_params(ab_link, drive, id)
1424 struct scsipi_link *ab_link;
1425 u_int8_t drive;
1426 struct atapi_identify *id;
1427 {
1428 struct wdc_softc *wdc = (void*)ab_link->adapter_softc;
1429 int status, len, excess = 0;
1430 int s, error;
1431
1432 /* if a disk is already present, skip */
1433 if ((wdc->sc_drives_mask & (1 << drive)) != 0) {
1434 #ifdef ATAPI_DEBUG_PROBE
1435 printf("wdc_atapi_get_params: drive %d present\n", drive);
1436 #endif
1437 return 0;
1438 }
1439
1440 /*
1441 * If there is only one ATAPI slave on the bus,don't probe
1442 * drive 0 (master)
1443 */
1444
1445 if (wdc->sc_flags & WDCF_ONESLAVE && drive != 1)
1446 return 0;
1447
1448 #ifdef ATAPI_DEBUG_PROBE
1449 printf("wdc_atapi_get_params: probing drive %d\n", drive);
1450 #endif
1451
1452 /*
1453 * XXX
1454 * The locking done here, and the length of time this may keep the rest
1455 * of the system suspended, is a kluge. This should be rewritten to
1456 * set up a transfer and queue it through wdstart(), but it's called
1457 * infrequently enough that this isn't a pressing matter.
1458 */
1459
1460 s = splbio();
1461
1462 while ((wdc->sc_flags & WDCF_ACTIVE) != 0) {
1463 wdc->sc_flags |= WDCF_WANTED;
1464 if ((error = tsleep(wdc, PRIBIO | PCATCH, "atprm", 0)) != 0) {
1465 splx(s);
1466 return error;
1467 }
1468 }
1469
1470 wdc->sc_flags |= WDCF_ACTIVE;
1471 error = 1;
1472 (void)wdcreset(wdc, VERBOSE);
1473 if ((status = wdccommand(wdc, (struct wd_link*)(&(ab_link->scsipi_atapi)),
1474 ATAPI_SOFT_RESET, drive, 0, 0, 0, 0)) != 0) {
1475 #ifdef ATAPI_DEBUG
1476 printf("wdc_atapi_get_params: ATAPI_SOFT_RESET"
1477 "failed for drive %d: status %d error %d\n",
1478 drive, status, wdc->sc_error);
1479 #endif
1480 error = 0;
1481 goto end;
1482 }
1483 if ((status = wait_for_unbusy(wdc)) != 0) {
1484 #ifdef ATAPI_DEBUG
1485 printf("wdc_atapi_get_params: wait_for_unbusy failed "
1486 "for drive %d: status %d error %d\n",
1487 drive, status, wdc->sc_error);
1488 #endif
1489 error = 0;
1490 goto end;
1491 }
1492
1493 if (wdccommand(wdc, (struct wd_link*)(&(ab_link->scsipi_atapi)),
1494 ATAPI_IDENTIFY_DEVICE, drive, sizeof(struct atapi_identify),
1495 0, 0, 0) != 0 ||
1496 atapi_ready(wdc) != 0) {
1497 #ifdef ATAPI_DEBUG_PROBE
1498 printf("ATAPI_IDENTIFY_DEVICE failed for drive %d\n", drive);
1499 #endif
1500 error = 0;
1501 goto end;
1502 }
1503 len = inb(wdc->sc_iobase + wd_cyl_lo) + 256 *
1504 inb(wdc->sc_iobase + wd_cyl_hi);
1505 if (len != sizeof(struct atapi_identify)) {
1506 printf("Warning drive %d returned %d/%d of "
1507 "indentify device data\n", drive, len,
1508 sizeof(struct atapi_identify));
1509 excess = len - sizeof(struct atapi_identify);
1510 if (excess < 0)
1511 excess = 0;
1512 }
1513 insw(wdc->sc_iobase + wd_data, id,
1514 sizeof(struct atapi_identify)/sizeof(short));
1515 wdcbit_bucket(wdc, excess);
1516 wdc->sc_drives_mask |= (1 << drive);
1517
1518 end: /* Restart the queue. */
1519 WDDEBUG_PRINT(("wdcstart from wdc_atapi_get_parms flags 0x%x\n",
1520 wdc->sc_flags));
1521 wdc->sc_flags &= ~WDCF_ACTIVE;
1522 wdcstart(wdc);
1523 splx(s);
1524 return error;
1525 }
1526
1527 int
1528 wdc_atapi_send_command_packet(sc_xfer)
1529 struct scsipi_xfer *sc_xfer;
1530 {
1531 struct scsipi_link *sc_link = sc_xfer->sc_link;
1532 struct wdc_softc *wdc = (void*)sc_link->adapter_softc;
1533 struct wdc_xfer *xfer;
1534 int flags = sc_xfer->flags;
1535
1536 if (flags & SCSI_POLL) { /* should use the queue and wdc_atapi_start */
1537 struct wdc_xfer xfer_s;
1538 int i, s;
1539
1540 s = splbio();
1541 #ifdef ATAPI_DEBUG_WDC
1542 printf("wdc_atapi_send_cmd: "
1543 "flags 0x%x drive %d cmdlen %d datalen %d",
1544 sc_xfer->flags, sc_link->scsipi_atapi.drive, sc_xfer->cmdlen,
1545 sc_xfer->datalen);
1546 #endif
1547 xfer = &xfer_s;
1548 bzero(xfer, sizeof(xfer_s));
1549 xfer->c_flags = C_INUSE|C_ATAPI|flags;
1550 xfer->d_link = (struct wd_link *)(&sc_link->scsipi_atapi);
1551 xfer->c_bp = sc_xfer->bp;
1552 xfer->atapi_cmd = sc_xfer;
1553 xfer->c_blkno = 0;
1554 xfer->databuf = sc_xfer->data;
1555 xfer->c_bcount = sc_xfer->datalen;
1556 if (wait_for_unbusy (wdc) != 0) {
1557 if ((wdc->sc_status & WDCS_ERR) == 0) {
1558 printf("wdc_atapi_send_command: not ready, "
1559 "st = %02x\n", wdc->sc_status);
1560 sc_xfer->error = XS_SELTIMEOUT;
1561 } else {
1562 sc_xfer->error = XS_SENSE;
1563 sc_xfer->sense.atapi_sense = wdc->sc_error;
1564 }
1565 splx(s);
1566 return COMPLETE;
1567 }
1568
1569 if (wdccommand(wdc, (struct wd_link*)(&sc_link->scsipi_atapi),
1570 ATAPI_PACKET_COMMAND, sc_link->scsipi_atapi.drive, sc_xfer->datalen,
1571 0, 0, 0) != 0) {
1572 printf("can't send atapi paket command\n");
1573 sc_xfer->error = XS_DRIVER_STUFFUP;
1574 splx(s);
1575 return COMPLETE;
1576 }
1577
1578 /* Wait for cmd i/o phase. */
1579 for (i = 20000; i > 0; --i) {
1580 int phase;
1581 phase = (inb(wdc->sc_iobase + wd_ireason) &
1582 (WDCI_CMD | WDCI_IN)) |
1583 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
1584 if (phase == PHASE_CMDOUT)
1585 break;
1586 delay(10);
1587 }
1588 #ifdef ATAPI_DEBUG_WDC
1589 printf("Wait for cmd i/o phase: i = %d\n", i);
1590 #endif
1591
1592 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd,
1593 sc_xfer->cmdlen/ sizeof (short));
1594
1595 /* Wait for data i/o phase. */
1596 for ( i= 20000; i > 0; --i) {
1597 int phase;
1598 phase = (inb(wdc->sc_iobase + wd_ireason) &
1599 (WDCI_CMD | WDCI_IN)) |
1600 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
1601 if (phase != PHASE_CMDOUT)
1602 break;
1603 delay(10);
1604 }
1605
1606 #ifdef ATAPI_DEBUG_WDC
1607 printf("Wait for data i/o phase: i = %d\n", i);
1608 #endif
1609 while ((sc_xfer->flags & ITSDONE) == 0) {
1610 wdc_atapi_intr(wdc, xfer);
1611 for (i = 2000; i > 0; --i)
1612 if ((inb(wdc->sc_iobase + wd_status)
1613 & WDCS_DRQ) == 0)
1614 break;
1615 #ifdef ATAPI_DEBUG_WDC
1616 printf("wdc_atapi_intr: i = %d\n", i);
1617 #endif
1618 }
1619 wdc->sc_flags &= ~(WDCF_IRQ_WAIT | WDCF_SINGLE | WDCF_ERROR);
1620 wdc->sc_errors = 0;
1621 xfer->c_skip = 0;
1622 splx(s);
1623 return COMPLETE;
1624 } else { /* POLLED */
1625 xfer = wdc_get_xfer(flags & SCSI_NOSLEEP ? IDE_NOSLEEP : 0);
1626 if (xfer == NULL) {
1627 return TRY_AGAIN_LATER;
1628 }
1629 xfer->c_flags |= C_ATAPI|sc_xfer->flags;
1630 xfer->d_link = (struct wd_link*)(&sc_link->scsipi_atapi);
1631 xfer->c_bp = sc_xfer->bp;
1632 xfer->atapi_cmd = sc_xfer;
1633 xfer->c_blkno = 0;
1634 xfer->databuf = sc_xfer->data;
1635 xfer->c_bcount = sc_xfer->datalen;
1636 wdc_exec_xfer(wdc, xfer->d_link, xfer);
1637 #ifdef ATAPI_DEBUG_WDC
1638 printf("wdc_atapi_send_command_packet: wdc_exec_xfer, flags 0x%x\n",
1639 sc_xfer->flags);
1640 #endif
1641 return (sc_xfer->flags & ITSDONE) ? COMPLETE : SUCCESSFULLY_QUEUED;
1642 }
1643 }
1644
1645 int
1646 wdc_atapi_intr(wdc, xfer)
1647 struct wdc_softc *wdc;
1648 struct wdc_xfer *xfer;
1649 {
1650 struct scsipi_xfer *sc_xfer = xfer->atapi_cmd;
1651 int len, phase, i, retries=0;
1652 int err, st, ire;
1653
1654 #ifdef ATAPI_DEBUG2
1655 printf("wdc_atapi_intr: %s\n", wdc->sc_dev.dv_xname);
1656 #endif
1657
1658 if (wait_for_unbusy(wdc) < 0) {
1659 if ((wdc->sc_status & WDCS_ERR) == 0) {
1660 printf("wdc_atapi_intr: controller busy\n");
1661 return 0;
1662 } else {
1663 sc_xfer->error = XS_SENSE;
1664 sc_xfer->sense.atapi_sense = wdc->sc_error;
1665 }
1666 #ifdef ATAPI_DEBUG_WDC
1667 printf("wdc_atapi_intr: wdc_atapi_done(), error %d\n",
1668 sc_xfer->error);
1669 #endif
1670 wdc_atapi_done(wdc, xfer);
1671 return 0;
1672 }
1673
1674
1675 again:
1676 len = inb(wdc->sc_iobase + wd_cyl_lo) +
1677 256 * inb(wdc->sc_iobase + wd_cyl_hi);
1678
1679 st = inb(wdc->sc_iobase + wd_status);
1680 err = inb(wdc->sc_iobase + wd_error);
1681 ire = inb(wdc->sc_iobase + wd_ireason);
1682
1683 phase = (ire & (WDCI_CMD | WDCI_IN)) | (st & WDCS_DRQ);
1684 #ifdef ATAPI_DEBUG_WDC
1685 printf("wdc_atapi_intr: len %d st %d err %d ire %d :",
1686 len, st, err, ire);
1687 #endif
1688 switch (phase) {
1689 case PHASE_CMDOUT:
1690 /* send packet command */
1691 #ifdef ATAPI_DEBUG_WDC
1692 printf("PHASE_CMDOUT\n");
1693 #endif
1694
1695 #ifdef ATAPI_DEBUG_WDC
1696 {
1697 int i;
1698 char *c = (char *)sc_xfer->cmd;
1699 printf("wdc_atapi_intr: cmd ");
1700 for (i = 0; i < sc_xfer->cmdlen; i++)
1701 printf("%x ", c[i]);
1702 printf("\n");
1703 }
1704 #endif
1705
1706 wdc->sc_flags |= WDCF_IRQ_WAIT;
1707 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd,
1708 sc_xfer->cmdlen/ sizeof (short));
1709 return 1;
1710
1711 case PHASE_DATAOUT:
1712 /* write data */
1713 #ifdef ATAPI_DEBUG_WDC
1714 printf("PHASE_DATAOUT\n");
1715 #endif
1716 if ((sc_xfer->flags & SCSI_DATA_OUT) == 0) {
1717 printf("wdc_atapi_intr: bad data phase\n");
1718 sc_xfer->error = XS_DRIVER_STUFFUP;
1719 return 0;
1720 }
1721 wdc->sc_flags |= WDCF_IRQ_WAIT;
1722 if (xfer->c_bcount < len) {
1723 printf("wdc_atapi_intr: warning: write only "
1724 "%d of %d requested bytes\n", xfer->c_bcount, len);
1725 outsw(wdc->sc_iobase + wd_data,
1726 xfer->databuf + xfer->c_skip,
1727 xfer->c_bcount / sizeof(short));
1728 for (i = xfer->c_bcount; i < len; i += sizeof(short))
1729 outw(wdc->sc_iobase + wd_data, 0);
1730 xfer->c_bcount = 0;
1731 return 1;
1732 } else {
1733 outsw(wdc->sc_iobase + wd_data,
1734 xfer->databuf + xfer->c_skip, len / sizeof(short));
1735 xfer->c_skip += len;
1736 xfer->c_bcount -= len;
1737 return 1;
1738 }
1739
1740 case PHASE_DATAIN:
1741 /* Read data */
1742 #ifdef ATAPI_DEBUG_WDC
1743 printf("PHASE_DATAIN\n");
1744 #endif
1745 if ((sc_xfer->flags & SCSI_DATA_IN) == 0) {
1746 printf("wdc_atapi_intr: bad data phase\n");
1747 sc_xfer->error = XS_DRIVER_STUFFUP;
1748 return 0;
1749 }
1750 wdc->sc_flags |= WDCF_IRQ_WAIT;
1751 if (xfer->c_bcount < len) {
1752 printf("wdc_atapi_intr: warning: reading only "
1753 "%d of %d bytes\n", xfer->c_bcount, len);
1754 insw(wdc->sc_iobase + wd_data,
1755 xfer->databuf + xfer->c_skip,
1756 xfer->c_bcount / sizeof(short));
1757 wdcbit_bucket(wdc, len - xfer->c_bcount);
1758 xfer->c_bcount = 0;
1759 return 1;
1760 } else {
1761 insw(wdc->sc_iobase + wd_data,
1762 xfer->databuf + xfer->c_skip, len / sizeof(short));
1763 xfer->c_skip += len;
1764 xfer->c_bcount -=len;
1765 return 1;
1766 }
1767
1768 case PHASE_ABORTED:
1769 case PHASE_COMPLETED:
1770 #ifdef ATAPI_DEBUG_WDC
1771 printf("PHASE_COMPLETED\n");
1772 #endif
1773 if (st & WDCS_ERR) {
1774 sc_xfer->error = XS_SENSE;
1775 sc_xfer->sense.atapi_sense = inb (wdc->sc_iobase + wd_error);
1776 }
1777 #ifdef ATAPI_DEBUG_WDC
1778 if (xfer->c_bcount != 0) {
1779 printf("wdc_atapi_intr warning: bcount value "
1780 "is %d after io\n", xfer->c_bcount);
1781 }
1782 #endif
1783 break;
1784
1785 default:
1786 if (++retries<500) {
1787 DELAY(100);
1788 goto again;
1789 }
1790 printf("wdc_atapi_intr: unknown phase %d\n", phase);
1791 if (st & WDCS_ERR) {
1792 sc_xfer->error = XS_SENSE;
1793 sc_xfer->sense.atapi_sense = inb (wdc->sc_iobase + wd_error);
1794 } else {
1795 sc_xfer->error = XS_DRIVER_STUFFUP;
1796 }
1797 }
1798
1799 #ifdef ATAPI_DEBUG_WDC
1800 printf("wdc_atapi_intr: wdc_atapi_done() (end), error %d\n",
1801 sc_xfer->error);
1802 #endif
1803 wdc_atapi_done(wdc, xfer);
1804 return (1);
1805 }
1806
1807
1808 void
1809 wdc_atapi_done(wdc, xfer)
1810 struct wdc_softc *wdc;
1811 struct wdc_xfer *xfer;
1812 {
1813 struct scsipi_xfer *sc_xfer = xfer->atapi_cmd;
1814 int s;
1815 int need_done = xfer->c_flags & C_NEEDDONE;
1816
1817 #ifdef ATAPI_DEBUG
1818 printf("wdc_atapi_done: flags 0x%x\n", (u_int)xfer->c_flags);
1819 #endif
1820 sc_xfer->resid = xfer->c_bcount;
1821
1822 /* remove this command from xfer queue */
1823 wdc->sc_errors = 0;
1824 xfer->c_skip = 0;
1825 if ((xfer->c_flags & SCSI_POLL) == 0) {
1826 s = splbio();
1827 untimeout(wdctimeout, wdc);
1828 TAILQ_REMOVE(&wdc->sc_xfer, xfer, c_xferchain);
1829 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
1830 wdc_free_xfer(xfer);
1831 sc_xfer->flags |= ITSDONE;
1832 if (need_done) {
1833 #ifdef ATAPI_DEBUG
1834 printf("wdc_atapi_done: scsipi_done\n");
1835 #endif
1836 scsipi_done(sc_xfer);
1837 }
1838 #ifdef WDDEBUG
1839 printf("wdcstart from wdc_atapi_intr, flags 0x%x\n",
1840 wdc->sc_flags);
1841 #endif
1842 wdcstart(wdc);
1843 splx(s);
1844 } else
1845 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
1846
1847 }
1848
1849 #endif /* NATAPIBUS > 0 */
1850