wdc.c revision 1.8 1 /* $NetBSD: wdc.c,v 1.8 1997/11/05 22:19:07 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 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/conf.h>
41 #include <sys/file.h>
42 #include <sys/stat.h>
43 #include <sys/ioctl.h>
44 #include <sys/buf.h>
45 #include <sys/uio.h>
46 #include <sys/malloc.h>
47 #include <sys/device.h>
48 #include <sys/disklabel.h>
49 #include <sys/disk.h>
50 #include <sys/syslog.h>
51 #include <sys/proc.h>
52
53 #include <vm/vm.h>
54
55 #include <machine/cpu.h>
56 #include <machine/intr.h>
57 #include <machine/bus.h>
58 #include <machine/pio.h>
59
60 #include <dev/isa/isavar.h>
61 #include <dev/isa/isadmavar.h>
62 #include <dev/isa/wdreg.h>
63 #include <dev/isa/wdlink.h>
64 #include "atapibus.h"
65 #include "wd.h"
66
67 #if NATAPIBUS > 0
68 #include <dev/scsipi/scsipi_all.h>
69 #include <dev/scsipi/atapiconf.h>
70 #endif
71
72 #define WAITTIME (10 * hz) /* time to wait for a completion */
73 /* this is a lot for hard drives, but not for cdroms */
74 #define RECOVERYTIME hz/2
75 #define WDCDELAY 100
76 #define WDCNDELAY 100000 /* delay = 100us; so 10s for a controller state change */
77 #if 0
78 /* If you enable this, it will report any delays more than 100us * N long. */
79 #define WDCNDELAY_DEBUG 50
80 #endif
81
82 #define WDIORETRIES 5 /* number of retries before giving up */
83
84 #define WDPART(dev) DISKPART(dev)
85
86 LIST_HEAD(xfer_free_list, wdc_xfer) xfer_free_list;
87
88 int wdcprobe __P((struct device *, void *, void *));
89 void wdcattach __P((struct device *, struct device *, void *));
90 int wdcintr __P((void *));
91
92 struct cfattach wdc_ca = {
93 sizeof(struct wdc_softc), wdcprobe, wdcattach
94 };
95
96 struct cfdriver wdc_cd = {
97 NULL, "wdc", DV_DULL
98 };
99
100 void wdcstart __P((struct wdc_softc *));
101 int wdcreset __P((struct wdc_softc *, int));
102 #define VERBOSE 1
103 #define SILENT 0
104 void wdcrestart __P((void *arg));
105 void wdcunwedge __P((struct wdc_softc *));
106 void wdctimeout __P((void *arg));
107 int wdccontrol __P((struct wdc_softc*, struct wd_link *));
108 void wdc_free_xfer __P((struct wdc_xfer *));
109 void wdcerror __P((struct wdc_softc*, char *));
110 void wdcbit_bucket __P(( struct wdc_softc *, int));
111 #if NWD > 0
112 int wdprint __P((void *, const char *));
113 int wdsetctlr __P((struct wd_link *));
114 int wdc_ata_intr __P((struct wdc_softc *,struct wdc_xfer *));
115 void wdc_ata_start __P((struct wdc_softc *,struct wdc_xfer *));
116 void wdc_ata_done __P((struct wdc_softc *, struct wdc_xfer *));
117 #endif /* NWD > 0 */
118 #if NATAPIBUS > 0
119 void wdc_atapi_minphys __P((struct buf *bp));
120 void wdc_atapi_start __P((struct wdc_softc *,struct wdc_xfer *));
121 int wdc_atapi_intr __P((struct wdc_softc *, struct wdc_xfer *));
122 void wdc_atapi_done __P((struct wdc_softc *, struct wdc_xfer *));
123 int wdc_atapi_send_command_packet __P((struct scsipi_xfer *sc_xfer));
124 #define MAX_SIZE MAXPHYS /* XXX */
125 #endif
126
127 #ifdef ATAPI_DEBUG2
128 static int wdc_nxfer;
129 #endif
130
131 #ifdef WDDEBUG
132 #define WDDEBUG_PRINT(args) printf args
133 #else
134 #define WDDEBUG_PRINT(args)
135 #endif
136
137 #if NATAPIBUS > 0
138 static struct scsipi_adapter wdc_switch = {
139 wdc_atapi_send_command_packet,
140 wdc_atapi_minphys,
141 0,
142 0
143 };
144 #endif
145
146 int
147 wdcprobe(parent, match, aux)
148 struct device *parent;
149 void *match, *aux;
150 {
151 struct wdc_softc *wdc = match;
152 struct isa_attach_args *ia = aux;
153 int iobase;
154
155 wdc->sc_iobase = iobase = ia->ia_iobase;
156
157 if (wdcreset(wdc, SILENT) != 0) {
158 /*
159 * if the reset failed, there is no master. test for ATAPI signature
160 * on the slave device. If no ATAPI slave, wait 5s and retry a reset.
161 */
162 outb(iobase+wd_sdh, WDSD_IBM | 0x10); /* slave */
163 if (inb(iobase + wd_cyl_lo) == 0x14 &&
164 inb(iobase + wd_cyl_hi) == 0xeb) {
165 wdc->sc_flags |= WDCF_ONESLAVE;
166 goto drivefound;
167 } else {
168 delay(500000);
169 if (wdcreset(wdc, SILENT) != 0)
170 return 0;
171 }
172 }
173 /* reset succeeded. Test registers */
174 if (inb(iobase + wd_cyl_lo) == 0x14 &&
175 inb(iobase + wd_cyl_hi) == 0xeb)
176 goto drivefound;
177 /* not ATAPI. Test registers */
178 outb(iobase+wd_error, 0x58); /* Error register not writable, */
179 outb(iobase+wd_cyl_lo, 0xa5); /* but all of cyllo are. */
180 if (inb(iobase+wd_error) != 0x58 && inb(iobase+wd_cyl_lo) == 0xa5)
181 goto drivefound;
182 /* No master. Test atapi signature on slave */
183 outb(iobase+wd_sdh, WDSD_IBM | 0x10);
184 if (inb(iobase + wd_cyl_lo) == 0x14 &&
185 inb(iobase + wd_cyl_hi) == 0xeb) {
186 wdc->sc_flags |= WDCF_ONESLAVE;
187 goto drivefound;
188 }
189 return 0;
190 drivefound:
191 /* Select drive 0 or ATAPI slave device */
192 if (wdc->sc_flags & WDCF_ONESLAVE)
193 outb(iobase+wd_sdh, WDSD_IBM | 0x10);
194 else
195 outb(iobase+wd_sdh, WDSD_IBM);
196
197 /* Wait for controller to become ready. */
198 if (wait_for_unbusy(wdc) < 0)
199 return 0;
200
201 /* Start drive diagnostics. */
202 outb(iobase+wd_command, WDCC_DIAGNOSE);
203
204 /* Wait for command to complete. */
205 if (wait_for_unbusy(wdc) < 0)
206 return 0;
207
208 ia->ia_iosize = 8;
209 ia->ia_msize = 0;
210 return 1;
211 }
212
213 void
214 wdcattach(parent, self, aux)
215 struct device *parent, *self;
216 void *aux;
217 {
218 struct wdc_softc *wdc = (void *)self;
219 struct isa_attach_args *ia = aux;
220 #if NWD > 0
221 int drive;
222 #endif
223
224 TAILQ_INIT(&wdc->sc_xfer);
225 wdc->sc_drq = ia->ia_drq;
226
227 printf("\n");
228 if (wdc->sc_drq != -1) {
229 if (isa_dmamap_create(parent, wdc->sc_drq, MAXPHYS,
230 BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
231 printf("%s: can't create map for drq %d\n",
232 wdc->sc_dev.dv_xname, wdc->sc_drq);
233 wdc->sc_drq = -1;
234 }
235 }
236
237 wdc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
238 IPL_BIO, wdcintr, wdc);
239
240 #ifdef ATAPI_DEBUG2
241 wdc_nxfer = 0;
242 #endif
243
244 #if NATAPIBUS > 0
245 /*
246 * Attach an ATAPI bus, if configured.
247 */
248 wdc->ab_link = malloc(sizeof(struct scsipi_link), M_DEVBUF, M_NOWAIT);
249 if (wdc->ab_link == NULL) {
250 printf("%s: can't allocate ATAPI link\n", self->dv_xname);
251 return;
252 }
253 bzero(wdc->ab_link,sizeof(struct scsipi_link));
254 wdc->ab_link->type = BUS_ATAPI;
255 wdc->ab_link->openings = 1;
256 wdc->ab_link->scsipi_atapi.type = ATAPI;
257 wdc->ab_link->scsipi_atapi.channel = 0;
258 wdc->ab_link->adapter_softc = (caddr_t)wdc;
259 wdc->ab_link->adapter = &wdc_switch;
260 (void)config_found(self, (void *)wdc->ab_link, NULL);
261 #endif /* NATAPIBUS > 0 */
262 #if NWD > 0
263 /*
264 * Attach standard IDE/ESDI/etc. disks to the controller.
265 */
266 for (drive = 0; drive < 2; drive++) {
267 /* if a disk is already present, skip */
268 if ((wdc->sc_drives_mask & (1 << drive)) != 0) {
269 continue;
270 }
271 /* controller active while autoconf */
272 wdc->sc_flags |= WDCF_ACTIVE;
273
274 if (wdccommandshort(wdc, drive, WDCC_RECAL) != 0 ||
275 wait_for_ready(wdc) != 0) {
276 wdc->d_link[drive] = NULL;
277 wdc->sc_flags &= ~WDCF_ACTIVE;
278 } else {
279 wdc->sc_flags &= ~WDCF_ACTIVE;
280 wdc->d_link[drive] = malloc(sizeof(struct wd_link),
281 M_DEVBUF, M_NOWAIT);
282 if (wdc->d_link[drive] == NULL) {
283 printf("%s: can't allocate link for drive %d\n",
284 self->dv_xname, drive);
285 continue;
286 }
287 bzero(wdc->d_link[drive],sizeof(struct wd_link));
288 wdc->d_link[drive]->type = ATA;
289 wdc->d_link[drive]->wdc_softc =(caddr_t) wdc;
290 wdc->d_link[drive]->drive = drive;
291 if (wdc->sc_drq != DRQUNK)
292 wdc->d_link[drive]->sc_mode = WDM_DMA;
293 else
294 wdc->d_link[drive]->sc_mode = 0;
295
296 wdc->sc_drives_mask |= (1 << drive);
297 (void)config_found(self, (void *)wdc->d_link[drive],
298 wdprint);
299 }
300 }
301 #endif /* NWD > 0 */
302 /* explicitely select an existing drive, to avoid spurious interrupts */
303 if (wdc->sc_flags & WDCF_ONESLAVE)
304 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM | 0x10); /* slave */
305 else
306 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM); /* master */
307 /*
308 * Reset controller. The probe, with some combinations of ATA/ATAPI
309 * device keep it in a mostly working, but strange state (with busy
310 * led on)
311 */
312 wdcreset(wdc, VERBOSE);
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_DEBUG2
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 wdc->sc_flags &= ~WDCF_IRQ_WAIT;
626 untimeout(wdctimeout, wdc);
627
628 /* Is it not a transfer, but a control operation? */
629 if (d_link->sc_state < READY) {
630 if (wdccontrol(wdc, d_link) == 0) {
631 /* The drive is busy. Wait. */
632 return 1;
633 }
634 WDDEBUG_PRINT(("wdc_ata_start from wdc_ata_intr(open) flags 0x%x\n",
635 dc->sc_flags));
636 wdc_ata_start(wdc,xfer);
637 return 1;
638 }
639
640 /* Turn off the DMA channel. */
641 if (d_link->sc_mode == WDM_DMA)
642 isa_dmadone(wdc->sc_dev.dv_parent, wdc->sc_drq);
643
644 /* Have we an error? */
645 if (wdc->sc_status & WDCS_ERR) {
646 #ifdef WDDEBUG
647 wderror(d_link, NULL, "wdc_ata_start");
648 #endif
649 if ((wdc->sc_flags & WDCF_SINGLE) == 0) {
650 wdc->sc_flags |= WDCF_ERROR;
651 goto restart;
652 }
653
654 #ifdef B_FORMAT
655 if (bp->b_flags & B_FORMAT)
656 goto bad;
657 #endif
658
659 if (++wdc->sc_errors < WDIORETRIES) {
660 if (wdc->sc_errors == (WDIORETRIES + 1) / 2) {
661 #if 0
662 wderror(wd, NULL, "wedgie");
663 #endif
664 wdcunwedge(wdc);
665 return 1;
666 }
667 goto restart;
668 }
669 wderror(d_link, xfer->c_bp, "wdc_ata_intr hard error");
670
671 #ifdef B_FORMAT
672 bad:
673 #endif
674 xfer->c_flags |= C_ERROR;
675 goto done;
676 }
677
678 /* If this was a read and not using DMA, fetch the data. */
679 if (d_link->sc_mode != WDM_DMA &&
680 (xfer->c_flags & (B_READ|B_WRITE)) == B_READ) {
681 if ((wdc->sc_status & (WDCS_DRDY | WDCS_DSC | WDCS_DRQ))
682 != (WDCS_DRDY | WDCS_DSC | WDCS_DRQ)) {
683 wderror(d_link, NULL, "wdcintr: read intr before drq");
684 wdcunwedge(wdc);
685 return 1;
686 }
687
688 /* Pull in data. */
689 if ((d_link->sc_flags & WDF_32BIT) == 0)
690 insw(wdc->sc_iobase+wd_data,
691 xfer->databuf + xfer->c_skip, xfer->c_nbytes >> 1);
692 else
693 insl(wdc->sc_iobase+wd_data,
694 xfer->databuf + xfer->c_skip, xfer->c_nbytes >> 2);
695 }
696
697 /* If we encountered any abnormalities, flag it as a soft error. */
698 if (wdc->sc_errors > 0 ||
699 (wdc->sc_status & WDCS_CORR) != 0) {
700 wderror(d_link, xfer->c_bp, "soft error (corrected)");
701 wdc->sc_errors = 0;
702 }
703
704 /* Adjust pointers for the next block, if any. */
705 xfer->c_blkno += xfer->c_nblks;
706 xfer->c_skip += xfer->c_nbytes;
707 xfer->c_bcount -= xfer->c_nbytes;
708
709 /* See if this transfer is complete. */
710 if (xfer->c_bcount > 0)
711 goto restart;
712
713 done:
714 /* Done with this transfer, with or without error. */
715 wdc_ata_done(wdc, xfer);
716 return 1;
717
718 restart:
719 /* Start the next operation */
720 WDDEBUG_PRINT(("wdc_ata_start from wdcintr flags 0x%x\n",
721 wdc->sc_flags));
722 wdc_ata_start(wdc, xfer);
723
724 return 1;
725 }
726
727 void
728 wdc_ata_done(wdc, xfer)
729 struct wdc_softc *wdc;
730 struct wdc_xfer *xfer;
731 {
732 struct buf *bp = xfer->c_bp;
733 struct wd_link *d_link = xfer->d_link;
734 int s;
735
736 WDDEBUG_PRINT(("wdc_ata_done\n"));
737
738 /* remove this command from xfer queue */
739 s = splbio();
740 TAILQ_REMOVE(&wdc->sc_xfer, xfer, c_xferchain);
741 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
742 wdc->sc_errors = 0;
743 if (bp) {
744 if (xfer->c_flags & C_ERROR) {
745 bp->b_flags |= B_ERROR;
746 bp->b_error = EIO;
747 }
748 bp->b_resid = xfer->c_bcount;
749 wddone(d_link, bp);
750 biodone(bp);
751 } else {
752 wakeup(xfer->databuf);
753 }
754 xfer->c_skip = 0;
755 wdc_free_xfer(xfer);
756 d_link->openings++;
757 wdstart((void*)d_link->wd_softc);
758 WDDEBUG_PRINT(("wdcstart from wdc_ata_done, flags 0x%x\n",
759 wdc->sc_flags));
760 wdcstart(wdc);
761 splx(s);
762 }
763
764 /*
765 * Get the drive parameters, if ESDI or ATA, or create fake ones for ST506.
766 */
767 int
768 wdc_get_parms(wdc, d_link)
769 struct wdc_softc * wdc;
770 struct wd_link *d_link;
771 {
772 int i;
773 char tb[DEV_BSIZE];
774 int s, error;
775
776 /*
777 * XXX
778 * The locking done here, and the length of time this may keep the rest
779 * of the system suspended, is a kluge. This should be rewritten to
780 * set up a transfer and queue it through wdstart(), but it's called
781 * infrequently enough that this isn't a pressing matter.
782 */
783
784 s = splbio();
785
786 while ((wdc->sc_flags & WDCF_ACTIVE) != 0) {
787 wdc->sc_flags |= WDCF_WANTED;
788 if ((error = tsleep(wdc, PRIBIO | PCATCH, "wdprm", 0)) != 0) {
789 splx(s);
790 return error;
791 }
792 }
793
794 wdc->sc_flags |= WDCF_ACTIVE;
795
796 if (wdccommandshort(wdc, d_link->drive, WDCC_IDENTIFY) != 0 ||
797 wait_for_drq(wdc) != 0) {
798 /*
799 * We `know' there's a drive here; just assume it's old.
800 * This geometry is only used to read the MBR and print a
801 * (false) attach message.
802 */
803 strncpy(d_link->sc_lp->d_typename, "ST506",
804 sizeof d_link->sc_lp->d_typename);
805 d_link->sc_lp->d_type = DTYPE_ST506;
806
807 strncpy(d_link->sc_params.wdp_model, "unknown",
808 sizeof d_link->sc_params.wdp_model);
809 d_link->sc_params.wdp_config = WD_CFG_FIXED;
810 d_link->sc_params.wdp_cylinders = 1024;
811 d_link->sc_params.wdp_heads = 8;
812 d_link->sc_params.wdp_sectors = 17;
813 d_link->sc_params.wdp_maxmulti = 0;
814 d_link->sc_params.wdp_usedmovsd = 0;
815 d_link->sc_params.wdp_capabilities = 0;
816 } else {
817 strncpy(d_link->sc_lp->d_typename, "ESDI/IDE",
818 sizeof d_link->sc_lp->d_typename);
819 d_link->sc_lp->d_type = DTYPE_ESDI;
820
821 /* Read in parameter block. */
822 insw(wdc->sc_iobase + wd_data, tb, sizeof(tb) / sizeof(short));
823 bcopy(tb, &d_link->sc_params, sizeof(struct wdparams));
824
825 /* Shuffle string byte order. */
826 for (i = 0; i < sizeof(d_link->sc_params.wdp_model); i += 2) {
827 u_short *p;
828 p = (u_short *)(d_link->sc_params.wdp_model + i);
829 *p = ntohs(*p);
830 }
831 }
832
833 /* Clear any leftover interrupt. */
834 (void) inb(wdc->sc_iobase + wd_status);
835
836 /* Restart the queue. */
837 WDDEBUG_PRINT(("wdcstart from wdc_get_parms flags 0x%x\n",
838 wdc->sc_flags));
839 wdc->sc_flags &= ~WDCF_ACTIVE;
840 wdcstart(wdc);
841
842 splx(s);
843 return 0;
844 }
845
846 /*
847 * Implement operations needed before read/write.
848 * Returns 0 if operation still in progress, 1 if completed.
849 */
850 int
851 wdccontrol(wdc, d_link)
852 struct wdc_softc *wdc;
853 struct wd_link *d_link;
854 {
855 WDDEBUG_PRINT(("wdccontrol\n"));
856
857 switch (d_link->sc_state) {
858 case RECAL: /* Set SDH, step rate, do recal. */
859 if (wdccommandshort(wdc, d_link->drive, WDCC_RECAL) != 0) {
860 wderror(d_link, NULL, "wdccontrol: recal failed (1)");
861 goto bad;
862 }
863 d_link->sc_state = RECAL_WAIT;
864 break;
865
866 case RECAL_WAIT:
867 if (wdc->sc_status & WDCS_ERR) {
868 wderror(d_link, NULL, "wdccontrol: recal failed (2)");
869 goto bad;
870 }
871 /* fall through */
872
873 case GEOMETRY:
874 if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0)
875 goto multimode;
876 if (wdsetctlr(d_link) != 0) {
877 /* Already printed a message. */
878 goto bad;
879 }
880 d_link->sc_state = GEOMETRY_WAIT;
881 break;
882
883 case GEOMETRY_WAIT:
884 if (wdc->sc_status & WDCS_ERR) {
885 wderror(d_link, NULL, "wdccontrol: geometry failed");
886 goto bad;
887 }
888 /* fall through */
889
890 case MULTIMODE:
891 multimode:
892 if (d_link->sc_mode != WDM_PIOMULTI)
893 goto ready;
894 outb(wdc->sc_iobase + wd_seccnt, d_link->sc_multiple);
895 if (wdccommandshort(wdc, d_link->drive,
896 WDCC_SETMULTI) != 0) {
897 wderror(d_link, NULL,
898 "wdccontrol: setmulti failed (1)");
899 goto bad;
900 }
901 d_link->sc_state = MULTIMODE_WAIT;
902 break;
903
904 case MULTIMODE_WAIT:
905 if (wdc->sc_status & WDCS_ERR) {
906 wderror(d_link, NULL,
907 "wdccontrol: setmulti failed (2)");
908 goto bad;
909 }
910 /* fall through */
911
912 case READY:
913 ready:
914 wdc->sc_errors = 0;
915 d_link->sc_state = READY;
916 /*
917 * The rest of the initialization can be done by normal means.
918 */
919 return 1;
920
921 bad:
922 wdcunwedge(wdc);
923 return 0;
924 }
925
926 wdc->sc_flags |= WDCF_IRQ_WAIT;
927 timeout(wdctimeout, wdc, WAITTIME);
928 return 0;
929 }
930
931 #endif /* NWD > 0 */
932
933
934 /*
935 * Interrupt routine for the controller. Acknowledge the interrupt, check for
936 * errors on the current operation, mark it done if necessary, and start the
937 * next request. Also check for a partially done transfer, and continue with
938 * the next chunk if so.
939 */
940 int
941 wdcintr(arg)
942 void *arg;
943 {
944 struct wdc_softc *wdc = arg;
945 struct wdc_xfer *xfer;
946
947 if ((wdc->sc_flags & WDCF_IRQ_WAIT) == 0) {
948 /* Clear the pending interrupt and abort. */
949 u_char s = inb(wdc->sc_iobase+wd_status);
950
951 #ifdef ATAPI_DEBUG_WDC
952 u_char e = inb(wdc->sc_iobase+wd_error);
953 u_char i = inb(wdc->sc_iobase+wd_seccnt);
954 printf("wdcintr: inactive controller, "
955 "punting st=%02x er=%02x irr=%02x\n", s, e, i);
956 #else
957 inb(wdc->sc_iobase+wd_error);
958 inb(wdc->sc_iobase+wd_seccnt);
959 #endif
960
961 if (s & WDCS_DRQ) {
962 int len = inb (wdc->sc_iobase + wd_cyl_lo) +
963 256 * inb (wdc->sc_iobase + wd_cyl_hi);
964 #ifdef ATAPI_DEBUG_WDC
965 printf ("wdcintr: clearing up %d bytes\n", len);
966 #endif
967 wdcbit_bucket (wdc, len);
968 }
969 return 0;
970 }
971
972 WDDEBUG_PRINT(("wdcintr\n"));
973
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])
1050 wdccommandshort(wdc, unit, ATAPI_SOFT_RESET);
1051 else if (wdc->d_link[unit]->sc_state > RECAL)
1052 wdc->d_link[unit]->sc_state = RECAL;
1053 }
1054
1055 wdc->sc_flags |= WDCF_ERROR;
1056 ++wdc->sc_errors;
1057
1058 /* Wake up in a little bit and restart the operation. */
1059 WDDEBUG_PRINT(("wdcrestart from wdcunwedge\n"));
1060 wdc->sc_flags &= ~WDCF_ACTIVE;
1061 timeout(wdcrestart, wdc, RECOVERYTIME);
1062 }
1063
1064 int
1065 wdcwait(wdc, mask)
1066 struct wdc_softc *wdc;
1067 int mask;
1068 {
1069 int iobase = wdc->sc_iobase;
1070 int timeout = 0;
1071 u_char status;
1072 #ifdef WDCNDELAY_DEBUG
1073 extern int cold;
1074 #endif
1075
1076 WDDEBUG_PRINT(("wdcwait iobase %x\n", iobase));
1077
1078 for (;;) {
1079 wdc->sc_status = status = inb(iobase+wd_status);
1080 /*
1081 * XXX
1082 * If a single slave ATAPI device is attached, it may
1083 * have released the bus. Select it and try again.
1084 */
1085 if (status == 0xff && wdc->sc_flags & WDCF_ONESLAVE) {
1086 outb(iobase+wd_sdh, WDSD_IBM | 0x10);
1087 wdc->sc_status = status = inb(iobase+wd_status);
1088 }
1089 if ((status & WDCS_BSY) == 0 && (status & mask) == mask)
1090 break;
1091 if (++timeout > WDCNDELAY) {
1092 #ifdef ATAPI_DEBUG
1093 printf("wdcwait: timeout, status %x error %x\n", status, inb(iobase+wd_error));
1094 #endif
1095 return -1;
1096 }
1097 delay(WDCDELAY);
1098 }
1099 if (status & WDCS_ERR) {
1100 wdc->sc_error = inb(iobase+wd_error);
1101 return WDCS_ERR;
1102 }
1103 #ifdef WDCNDELAY_DEBUG
1104 /* After autoconfig, there should be no long delays. */
1105 if (!cold && timeout > WDCNDELAY_DEBUG) {
1106 struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first;
1107 if (xfer == NULL)
1108 printf("%s: warning: busy-wait took %dus\n",
1109 wdc->sc_dev.dv_xname, WDCDELAY * timeout);
1110 else
1111 printf("%s(%s): warning: busy-wait took %dus\n",
1112 wdc->sc_dev.dv_xname,
1113 ((struct device*)xfer->d_link->wd_softc)->dv_xname,
1114 WDCDELAY * timeout);
1115 }
1116 #endif
1117 return 0;
1118 }
1119
1120 void
1121 wdctimeout(arg)
1122 void *arg;
1123 {
1124 struct wdc_softc *wdc = (struct wdc_softc *)arg;
1125 struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first;
1126 int s;
1127
1128 WDDEBUG_PRINT(("wdctimeout\n"));
1129
1130 s = splbio();
1131 if ((wdc->sc_flags & WDCF_IRQ_WAIT) != 0) {
1132 wdcerror(wdc, "lost interrupt");
1133 printf("\ttype: %s\n", (xfer->c_flags & C_ATAPI) ? "atapi":"ata");
1134 printf("\tc_bcount: %d\n", xfer->c_bcount);
1135 printf("\tc_skip: %d\n", xfer->c_skip);
1136 wdcintr(wdc);
1137 wdc->sc_flags &= ~WDCF_IRQ_WAIT;
1138 wdcunwedge(wdc);
1139 } else
1140 wdcerror(wdc, "missing untimeout");
1141 splx(s);
1142 }
1143
1144 /*
1145 * Wait for the drive to become ready and send a command.
1146 * Return -1 if busy for too long or 0 otherwise.
1147 * Assumes interrupts are blocked.
1148 */
1149 int
1150 wdccommand(wdc, d_link, command, drive, cylin, head, sector, count)
1151 struct wdc_softc *wdc;
1152 struct wd_link *d_link;
1153 int command;
1154 int drive, cylin, head, sector, count;
1155 {
1156 int iobase = wdc->sc_iobase;
1157 int stat;
1158
1159 WDDEBUG_PRINT(("wdccommand drive %d\n", drive));
1160
1161 #if defined(DIAGNOSTIC) && defined(WDCDEBUG)
1162 if ((wdc->sc_flags & WDCF_ACTIVE) == 0)
1163 printf("wdccommand: controler not active (drive %d)\n", drive);
1164 #endif
1165
1166 /* Select drive, head, and addressing mode. */
1167 outb(iobase+wd_sdh, WDSD_IBM | (drive << 4) | head);
1168
1169 /* Wait for it to become ready to accept a command. */
1170 if (command == WDCC_IDP || d_link->type == ATAPI)
1171 stat = wait_for_unbusy(wdc);
1172 else
1173 stat = wdcwait(wdc, WDCS_DRDY);
1174
1175 if (stat < 0) {
1176 #ifdef ATAPI_DEBUG
1177 printf("wdcommand: xfer failed (wait_for_unbusy) status %d\n",
1178 stat);
1179 #endif
1180 return -1;
1181 }
1182
1183 /* Load parameters. */
1184 if (d_link->type == ATA && d_link->sc_lp->d_type == DTYPE_ST506)
1185 outb(iobase + wd_precomp, d_link->sc_lp->d_precompcyl / 4);
1186 else
1187 outb(iobase + wd_features, 0);
1188 outb(iobase + wd_cyl_lo, cylin);
1189 outb(iobase + wd_cyl_hi, cylin >> 8);
1190 outb(iobase + wd_sector, sector);
1191 outb(iobase + wd_seccnt, count);
1192
1193 /* Send command. */
1194 outb(iobase + wd_command, command);
1195
1196 return 0;
1197 }
1198
1199 /*
1200 * Simplified version of wdccommand().
1201 */
1202 int
1203 wdccommandshort(wdc, drive, command)
1204 struct wdc_softc *wdc;
1205 int drive;
1206 int command;
1207 {
1208 int iobase = wdc->sc_iobase;
1209
1210 WDDEBUG_PRINT(("wdccommandshort\n"));
1211
1212 #if defined(DIAGNOSTIC) && defined(WDCDEBUG)
1213 if ((wdc->sc_flags & WDCF_ACTIVE) == 0)
1214 printf("wdccommandshort: controler not active (drive %d)\n",
1215 drive);
1216 #endif
1217
1218 /* Select drive. */
1219 outb(iobase + wd_sdh, WDSD_IBM | (drive << 4));
1220
1221 if (wdcwait(wdc, WDCS_DRDY) < 0)
1222 return -1;
1223
1224 outb(iobase + wd_command, command);
1225
1226 return 0;
1227 }
1228
1229 void
1230 wdc_exec_xfer(wdc, d_link, xfer)
1231 struct wdc_softc *wdc;
1232 struct wd_link *d_link;
1233 struct wdc_xfer *xfer;
1234 {
1235 int s;
1236
1237 WDDEBUG_PRINT(("wdc_exec_xfer\n"));
1238
1239 s = splbio();
1240
1241 /* insert at the end of command list */
1242 TAILQ_INSERT_TAIL(&wdc->sc_xfer,xfer , c_xferchain)
1243 WDDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
1244 wdc->sc_flags));
1245 wdcstart(wdc);
1246 xfer->c_flags |= C_NEEDDONE; /* we can now call upper level done() */
1247 splx(s);
1248 }
1249
1250 struct wdc_xfer *
1251 wdc_get_xfer(flags)
1252 int flags;
1253 {
1254 struct wdc_xfer *xfer;
1255 int s;
1256
1257 s = splbio();
1258 if ((xfer = xfer_free_list.lh_first) != NULL) {
1259 LIST_REMOVE(xfer, free_list);
1260 splx(s);
1261 #ifdef DIAGNOSTIC
1262 if ((xfer->c_flags & C_INUSE) != 0)
1263 panic("wdc_get_xfer: xfer already in use\n");
1264 #endif
1265 } else {
1266 splx(s);
1267 #ifdef ATAPI_DEBUG2
1268 printf("wdc:making xfer %d\n",wdc_nxfer);
1269 #endif
1270 xfer = malloc(sizeof(*xfer), M_DEVBUF,
1271 ((flags & IDE_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK));
1272 if (xfer == NULL)
1273 return 0;
1274
1275 #ifdef DIAGNOSTIC
1276 xfer->c_flags &= ~C_INUSE;
1277 #endif
1278 #ifdef ATAPI_DEBUG2
1279 wdc_nxfer++;
1280 #endif
1281 }
1282 #ifdef DIAGNOSTIC
1283 if ((xfer->c_flags & C_INUSE) != 0)
1284 panic("wdc_get_xfer: xfer already in use\n");
1285 #endif
1286 bzero(xfer,sizeof(struct wdc_xfer));
1287 xfer->c_flags = C_INUSE;
1288 return xfer;
1289 }
1290
1291 void
1292 wdc_free_xfer(xfer)
1293 struct wdc_xfer *xfer;
1294 {
1295 int s;
1296
1297 s = splbio();
1298 xfer->c_flags &= ~C_INUSE;
1299 LIST_INSERT_HEAD(&xfer_free_list, xfer, free_list);
1300 splx(s);
1301 }
1302
1303 void
1304 wdcerror(wdc, msg)
1305 struct wdc_softc *wdc;
1306 char *msg;
1307 {
1308 struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first;
1309 if (xfer == NULL)
1310 printf("%s: %s\n", wdc->sc_dev.dv_xname, msg);
1311 else
1312 printf("%s(%d): %s\n", wdc->sc_dev.dv_xname,
1313 xfer->d_link->drive, msg);
1314 }
1315
1316 /*
1317 * the bit bucket
1318 */
1319 void
1320 wdcbit_bucket(wdc, size)
1321 struct wdc_softc *wdc;
1322 int size;
1323 {
1324 int iobase = wdc->sc_iobase;
1325 int i;
1326
1327 for (i = 0 ; i < size / 2 ; i++) {
1328 short null;
1329 (void)insw(iobase + wd_data, &null, 1);
1330 }
1331
1332 if (size % 2)
1333 (void)inb(iobase + wd_data);
1334 }
1335
1336
1337 #if NATAPIBUS > 0
1338
1339 void
1340 wdc_atapi_minphys (struct buf *bp)
1341 {
1342 if(bp->b_bcount > MAX_SIZE)
1343 bp->b_bcount = MAX_SIZE;
1344 minphys(bp);
1345 }
1346
1347
1348 void
1349 wdc_atapi_start(wdc, xfer)
1350 struct wdc_softc *wdc;
1351 struct wdc_xfer *xfer;
1352 {
1353 struct scsipi_xfer *sc_xfer = xfer->atapi_cmd;
1354
1355 #ifdef ATAPI_DEBUG_WDC
1356 printf("wdc_atapi_start, acp flags %x \n",sc_xfer->flags);
1357 #endif
1358 if (wdc->sc_errors >= WDIORETRIES) {
1359 if ((wdc->sc_status & WDCS_ERR) == 0) {
1360 sc_xfer->error = XS_DRIVER_STUFFUP; /* XXX do we know more ? */
1361 } else {
1362 sc_xfer->error = XS_SENSE;
1363 sc_xfer->sense.atapi_sense = inb (wdc->sc_iobase + wd_error);
1364 }
1365 wdc_atapi_done(wdc, xfer);
1366 return;
1367 }
1368 if (wait_for_unbusy(wdc) != 0) {
1369 if ((wdc->sc_status & WDCS_ERR) == 0) {
1370 printf("wdc_atapi_start: not ready, st = %02x\n",
1371 wdc->sc_status);
1372 sc_xfer->error = XS_SELTIMEOUT;
1373 }
1374 #if 0 /* don't get the sense yet, as this may be just UNIT ATTENTION */
1375 else {
1376 #ifdef ATAPI_DEBUG_WDC
1377 printf("wdc_atapi_start: sense %02x\n", wdc->sc_error);
1378 #endif
1379 sc_xfer->error = XS_SENSE;
1380 sc_xfer->sense.atapi_sense = wdc->sc_error;
1381 }
1382 wdc_atapi_done(wdc, xfer);
1383 return;
1384 #endif
1385 }
1386
1387 if (wdccommand(wdc, (struct wd_link*)xfer->d_link, ATAPI_PACKET_COMMAND,
1388 sc_xfer->sc_link->scsipi_atapi.drive, sc_xfer->datalen,
1389 0, 0, 0) != 0) {
1390 printf("wdc_atapi_start: can't send atapi paket command\n");
1391 sc_xfer->error = XS_DRIVER_STUFFUP;
1392 wdc_atapi_done(wdc, xfer);
1393 return;
1394 }
1395 if ((sc_xfer->sc_link->scsipi_atapi.cap & 0x0300) != ACAP_DRQ_INTR) {
1396 int i, phase;
1397 for (i=20000; i>0; --i) {
1398 phase = (inb(wdc->sc_iobase + wd_ireason) &
1399 (WDCI_CMD | WDCI_IN)) |
1400 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
1401 if (phase == PHASE_CMDOUT)
1402 break;
1403 delay(10);
1404 }
1405 if (phase != PHASE_CMDOUT ) {
1406 printf("wdc_atapi_start: timout waiting PHASE_CMDOUT");
1407 sc_xfer->error = XS_SELTIMEOUT;
1408 wdc_atapi_done(wdc, xfer);
1409 return;
1410 }
1411 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd,
1412 sc_xfer->cmdlen / sizeof(short));
1413 }
1414 wdc->sc_flags |= WDCF_IRQ_WAIT;
1415
1416 #ifdef ATAPI_DEBUG2
1417 printf("wdc_atapi_start: timeout\n");
1418 #endif
1419 timeout(wdctimeout, wdc, WAITTIME);
1420 return;
1421 }
1422
1423
1424 int
1425 wdc_atapi_get_params(ab_link, drive, id)
1426 struct scsipi_link *ab_link;
1427 u_int8_t drive;
1428 struct atapi_identify *id;
1429 {
1430 struct wdc_softc *wdc = (void*)ab_link->adapter_softc;
1431 int status, len, excess = 0;
1432 int s, error;
1433
1434 /* if a disk is already present, skip */
1435 if ((wdc->sc_drives_mask & (1 << drive)) != 0) {
1436 #ifdef ATAPI_DEBUG_PROBE
1437 printf("wdc_atapi_get_params: drive %d present\n", drive);
1438 #endif
1439 return 0;
1440 }
1441
1442 /*
1443 * If there is only one ATAPI slave on the bus,don't probe
1444 * drive 0 (master)
1445 */
1446
1447 if (wdc->sc_flags & WDCF_ONESLAVE && drive != 1)
1448 return 0;
1449
1450 #ifdef ATAPI_DEBUG_PROBE
1451 printf("wdc_atapi_get_params: probing drive %d\n", drive);
1452 #endif
1453
1454 /*
1455 * XXX
1456 * The locking done here, and the length of time this may keep the rest
1457 * of the system suspended, is a kluge. This should be rewritten to
1458 * set up a transfer and queue it through wdstart(), but it's called
1459 * infrequently enough that this isn't a pressing matter.
1460 */
1461
1462 s = splbio();
1463
1464 while ((wdc->sc_flags & WDCF_ACTIVE) != 0) {
1465 wdc->sc_flags |= WDCF_WANTED;
1466 if ((error = tsleep(wdc, PRIBIO | PCATCH, "atprm", 0)) != 0) {
1467 splx(s);
1468 return error;
1469 }
1470 }
1471
1472 wdc->sc_flags |= WDCF_ACTIVE;
1473 error = 1;
1474 (void)wdcreset(wdc, VERBOSE);
1475 if ((status = wdccommand(wdc, (struct wd_link*)(&(ab_link->scsipi_atapi)),
1476 ATAPI_SOFT_RESET, drive, 0, 0, 0, 0)) != 0) {
1477 #ifdef ATAPI_DEBUG
1478 printf("wdc_atapi_get_params: ATAPI_SOFT_RESET"
1479 "failed for drive %d: status %d error %d\n",
1480 drive, status, wdc->sc_error);
1481 #endif
1482 error = 0;
1483 goto end;
1484 }
1485 if ((status = wait_for_unbusy(wdc)) != 0) {
1486 #ifdef ATAPI_DEBUG
1487 printf("wdc_atapi_get_params: wait_for_unbusy failed "
1488 "for drive %d: status %d error %d\n",
1489 drive, status, wdc->sc_error);
1490 #endif
1491 error = 0;
1492 goto end;
1493 }
1494
1495 if (wdccommand(wdc, (struct wd_link*)(&(ab_link->scsipi_atapi)),
1496 ATAPI_IDENTIFY_DEVICE, drive, sizeof(struct atapi_identify),
1497 0, 0, 0) != 0 ||
1498 atapi_ready(wdc) != 0) {
1499 #ifdef ATAPI_DEBUG_PROBE
1500 printf("ATAPI_IDENTIFY_DEVICE failed for drive %d\n", drive);
1501 #endif
1502 error = 0;
1503 goto end;
1504 }
1505 len = inb(wdc->sc_iobase + wd_cyl_lo) + 256 *
1506 inb(wdc->sc_iobase + wd_cyl_hi);
1507 if (len != sizeof(struct atapi_identify)) {
1508 printf("Warning drive %d returned %d/%d of "
1509 "indentify device data\n", drive, len,
1510 sizeof(struct atapi_identify));
1511 excess = len - sizeof(struct atapi_identify);
1512 if (excess < 0)
1513 excess = 0;
1514 }
1515 insw(wdc->sc_iobase + wd_data, id,
1516 sizeof(struct atapi_identify)/sizeof(short));
1517 wdcbit_bucket(wdc, excess);
1518 wdc->sc_drives_mask |= (1 << drive);
1519
1520 end: /* Restart the queue. */
1521 WDDEBUG_PRINT(("wdcstart from wdc_atapi_get_parms flags 0x%x\n",
1522 wdc->sc_flags));
1523 wdc->sc_flags &= ~WDCF_ACTIVE;
1524 wdcstart(wdc);
1525 splx(s);
1526 return error;
1527 }
1528
1529 int
1530 wdc_atapi_send_command_packet(sc_xfer)
1531 struct scsipi_xfer *sc_xfer;
1532 {
1533 struct scsipi_link *sc_link = sc_xfer->sc_link;
1534 struct wdc_softc *wdc = (void*)sc_link->adapter_softc;
1535 struct wdc_xfer *xfer;
1536 int flags = sc_xfer->flags;
1537
1538 if (flags & SCSI_POLL) { /* should use the queue and wdc_atapi_start */
1539 struct wdc_xfer xfer_s;
1540 int i, s;
1541
1542 s = splbio();
1543 #ifdef ATAPI_DEBUG_WDC
1544 printf("wdc_atapi_send_cmd: "
1545 "flags 0x%x drive %d cmdlen %d datalen %d",
1546 sc_xfer->flags, sc_link->scsipi_atapi.drive, sc_xfer->cmdlen,
1547 sc_xfer->datalen);
1548 #endif
1549 xfer = &xfer_s;
1550 bzero(xfer, sizeof(xfer_s));
1551 xfer->c_flags = C_INUSE|C_ATAPI|flags;
1552 xfer->d_link = (struct wd_link *)(&sc_link->scsipi_atapi);
1553 xfer->c_bp = sc_xfer->bp;
1554 xfer->atapi_cmd = sc_xfer;
1555 xfer->c_blkno = 0;
1556 xfer->databuf = sc_xfer->data;
1557 xfer->c_bcount = sc_xfer->datalen;
1558 if (wait_for_unbusy (wdc) != 0) {
1559 if ((wdc->sc_status & WDCS_ERR) == 0) {
1560 printf("wdc_atapi_send_command: not ready, "
1561 "st = %02x\n", wdc->sc_status);
1562 sc_xfer->error = XS_SELTIMEOUT;
1563 } else {
1564 sc_xfer->error = XS_SENSE;
1565 sc_xfer->sense.atapi_sense = wdc->sc_error;
1566 }
1567 splx(s);
1568 return COMPLETE;
1569 }
1570
1571 if (wdccommand(wdc, (struct wd_link*)(&sc_link->scsipi_atapi),
1572 ATAPI_PACKET_COMMAND, sc_link->scsipi_atapi.drive, sc_xfer->datalen,
1573 0, 0, 0) != 0) {
1574 printf("can't send atapi paket command\n");
1575 sc_xfer->error = XS_DRIVER_STUFFUP;
1576 splx(s);
1577 return COMPLETE;
1578 }
1579
1580 /* Wait for cmd i/o phase. */
1581 for (i = 20000; i > 0; --i) {
1582 int phase;
1583 phase = (inb(wdc->sc_iobase + wd_ireason) &
1584 (WDCI_CMD | WDCI_IN)) |
1585 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
1586 if (phase == PHASE_CMDOUT)
1587 break;
1588 delay(10);
1589 }
1590 #ifdef ATAPI_DEBUG_WDC
1591 printf("Wait for cmd i/o phase: i = %d\n", i);
1592 #endif
1593
1594 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd,
1595 sc_xfer->cmdlen/ sizeof (short));
1596
1597 /* Wait for data i/o phase. */
1598 for ( i= 20000; i > 0; --i) {
1599 int phase;
1600 phase = (inb(wdc->sc_iobase + wd_ireason) &
1601 (WDCI_CMD | WDCI_IN)) |
1602 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
1603 if (phase != PHASE_CMDOUT)
1604 break;
1605 delay(10);
1606 }
1607
1608 #ifdef ATAPI_DEBUG_WDC
1609 printf("Wait for data i/o phase: i = %d\n", i);
1610 #endif
1611 wdc->sc_flags |= WDCF_IRQ_WAIT;
1612 while ((sc_xfer->flags & ITSDONE) == 0) {
1613 wdc_atapi_intr(wdc, xfer);
1614 for (i = 2000; i > 0; --i)
1615 if ((inb(wdc->sc_iobase + wd_status)
1616 & WDCS_DRQ) == 0)
1617 break;
1618 #ifdef ATAPI_DEBUG_WDC
1619 printf("wdc_atapi_intr: i = %d\n", i);
1620 #endif
1621 }
1622 wdc->sc_flags &= ~(WDCF_IRQ_WAIT | WDCF_SINGLE | WDCF_ERROR);
1623 wdc->sc_errors = 0;
1624 xfer->c_skip = 0;
1625 splx(s);
1626 return COMPLETE;
1627 } else { /* POLLED */
1628 xfer = wdc_get_xfer(flags & SCSI_NOSLEEP ? IDE_NOSLEEP : 0);
1629 if (xfer == NULL) {
1630 return TRY_AGAIN_LATER;
1631 }
1632 xfer->c_flags |= C_ATAPI|sc_xfer->flags;
1633 xfer->d_link = (struct wd_link*)(&sc_link->scsipi_atapi);
1634 xfer->c_bp = sc_xfer->bp;
1635 xfer->atapi_cmd = sc_xfer;
1636 xfer->c_blkno = 0;
1637 xfer->databuf = sc_xfer->data;
1638 xfer->c_bcount = sc_xfer->datalen;
1639 wdc_exec_xfer(wdc, xfer->d_link, xfer);
1640 #ifdef ATAPI_DEBUG_WDC
1641 printf("wdc_atapi_send_command_packet: wdc_exec_xfer, flags 0x%x\n",
1642 sc_xfer->flags);
1643 #endif
1644 return (sc_xfer->flags & ITSDONE) ? COMPLETE : SUCCESSFULLY_QUEUED;
1645 }
1646 }
1647
1648 int
1649 wdc_atapi_intr(wdc, xfer)
1650 struct wdc_softc *wdc;
1651 struct wdc_xfer *xfer;
1652 {
1653 struct scsipi_xfer *sc_xfer = xfer->atapi_cmd;
1654 int len, phase, i, retries=0;
1655 int err, st, ire;
1656
1657 #ifdef ATAPI_DEBUG2
1658 printf("wdc_atapi_intr: %s\n", wdc->sc_dev.dv_xname);
1659 #endif
1660
1661 if (wait_for_unbusy(wdc) < 0) {
1662 if ((wdc->sc_status & WDCS_ERR) == 0) {
1663 printf("wdc_atapi_intr: controller busy\n");
1664 return 0;
1665 } else {
1666 sc_xfer->error = XS_SENSE;
1667 sc_xfer->sense.atapi_sense = wdc->sc_error;
1668 }
1669 #ifdef ATAPI_DEBUG_WDC
1670 printf("wdc_atapi_intr: wdc_atapi_done(), error %d\n",
1671 sc_xfer->error);
1672 #endif
1673 wdc_atapi_done(wdc, xfer);
1674 return 0;
1675 }
1676
1677
1678 again:
1679 len = inb(wdc->sc_iobase + wd_cyl_lo) +
1680 256 * inb(wdc->sc_iobase + wd_cyl_hi);
1681
1682 st = inb(wdc->sc_iobase + wd_status);
1683 err = inb(wdc->sc_iobase + wd_error);
1684 ire = inb(wdc->sc_iobase + wd_ireason);
1685
1686 phase = (ire & (WDCI_CMD | WDCI_IN)) | (st & WDCS_DRQ);
1687 #ifdef ATAPI_DEBUG_WDC
1688 printf("wdc_atapi_intr: len %d st %d err %d ire %d :",
1689 len, st, err, ire);
1690 #endif
1691 switch (phase) {
1692 case PHASE_CMDOUT:
1693 /* send packet command */
1694 #ifdef ATAPI_DEBUG_WDC
1695 printf("PHASE_CMDOUT\n");
1696 #endif
1697
1698 #ifdef ATAPI_DEBUG_WDC
1699 {
1700 int i;
1701 char *c = (char *)sc_xfer->cmd;
1702 printf("wdc_atapi_intr: cmd ");
1703 for (i = 0; i < sc_xfer->cmdlen; i++)
1704 printf("%x ", c[i]);
1705 printf("\n");
1706 }
1707 #endif
1708
1709 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd,
1710 sc_xfer->cmdlen/ sizeof (short));
1711 return 1;
1712
1713 case PHASE_DATAOUT:
1714 /* write data */
1715 #ifdef ATAPI_DEBUG_WDC
1716 printf("PHASE_DATAOUT\n");
1717 #endif
1718 if ((sc_xfer->flags & SCSI_DATA_OUT) == 0) {
1719 printf("wdc_atapi_intr: bad data phase\n");
1720 sc_xfer->error = XS_DRIVER_STUFFUP;
1721 return 0;
1722 }
1723 if (xfer->c_bcount < len) {
1724 printf("wdc_atapi_intr: warning: write only "
1725 "%d of %d requested bytes\n", xfer->c_bcount, len);
1726 outsw(wdc->sc_iobase + wd_data,
1727 xfer->databuf + xfer->c_skip,
1728 xfer->c_bcount / sizeof(short));
1729 for (i = xfer->c_bcount; i < len; i += sizeof(short))
1730 outw(wdc->sc_iobase + wd_data, 0);
1731 xfer->c_skip += xfer->c_bcount;
1732 xfer->c_bcount = 0;
1733 } else {
1734 outsw(wdc->sc_iobase + wd_data,
1735 xfer->databuf + xfer->c_skip, len / sizeof(short));
1736 xfer->c_skip += len;
1737 xfer->c_bcount -= len;
1738 }
1739 return 1;
1740
1741 case PHASE_DATAIN:
1742 /* Read data */
1743 #ifdef ATAPI_DEBUG_WDC
1744 printf("PHASE_DATAIN\n");
1745 #endif
1746 if ((sc_xfer->flags & SCSI_DATA_IN) == 0) {
1747 printf("wdc_atapi_intr: bad data phase\n");
1748 sc_xfer->error = XS_DRIVER_STUFFUP;
1749 return 0;
1750 }
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_skip += xfer->c_bcount;
1759 xfer->c_bcount = 0;
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 }
1766 return 1;
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 wdc->sc_flags &= ~WDCF_IRQ_WAIT;
1822
1823 /* remove this command from xfer queue */
1824 wdc->sc_errors = 0;
1825 xfer->c_skip = 0;
1826 if ((xfer->c_flags & SCSI_POLL) == 0) {
1827 s = splbio();
1828 untimeout(wdctimeout, wdc);
1829 TAILQ_REMOVE(&wdc->sc_xfer, xfer, c_xferchain);
1830 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
1831 wdc_free_xfer(xfer);
1832 sc_xfer->flags |= ITSDONE;
1833 if (need_done) {
1834 #ifdef ATAPI_DEBUG
1835 printf("wdc_atapi_done: scsipi_done\n");
1836 #endif
1837 scsipi_done(sc_xfer);
1838 }
1839 #ifdef WDDEBUG
1840 printf("wdcstart from wdc_atapi_intr, flags 0x%x\n",
1841 wdc->sc_flags);
1842 #endif
1843 wdcstart(wdc);
1844 splx(s);
1845 } else {
1846 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
1847 sc_xfer->flags |= ITSDONE;
1848 }
1849 }
1850
1851 #endif /* NATAPIBUS > 0 */
1852