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