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