wt.c revision 1.12 1 /*
2 * Streamer tape driver.
3 * Supports Archive and Wangtek compatible QIC-02/QIC-36 boards.
4 *
5 * Copyright (C) 1993 by:
6 * Sergey Ryzhkov <sir (at) kiae.su>
7 * Serge Vakulenko <vak (at) zebub.msk.su>
8 *
9 * This software is distributed with NO WARRANTIES, not even the implied
10 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Authors grant any other persons or organisations permission to use
13 * or modify this software as long as this message is kept with the software,
14 * all derivative works or modified versions.
15 *
16 * This driver is derived from the old 386bsd Wangtek streamer tape driver,
17 * made by Robert Baron at CMU, based on Intel sources.
18 *
19 * $Id: wt.c,v 1.12 1994/04/21 00:41:52 mycroft Exp $
20 */
21
22 /*
23 * Copyright (c) 1989 Carnegie-Mellon University.
24 * All rights reserved.
25 *
26 * Authors: Robert Baron
27 *
28 * Permission to use, copy, modify and distribute this software and
29 * its documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
33 *
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
36 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
37 *
38 * Carnegie Mellon requests users of this software to return to
39 *
40 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
44 *
45 * any improvements or extensions that they make and grant Carnegie the
46 * rights to redistribute these changes.
47 */
48
49 /*
50 * Copyright 1988, 1989 by Intel Corporation
51 */
52
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/kernel.h>
56 #include <sys/buf.h>
57 #include <sys/fcntl.h>
58 #include <sys/malloc.h>
59 #include <sys/ioctl.h>
60 #include <sys/mtio.h>
61 #include <sys/device.h>
62
63 #include <vm/vm_param.h>
64
65 #include <machine/pio.h>
66
67 #include <i386/isa/isavar.h>
68 #include <i386/isa/wtreg.h>
69
70 /*
71 * Uncomment this to enable internal device tracing.
72 */
73 #define DEBUG(s) /* printf s */
74
75 #define WTPRI (PZERO+10) /* sleep priority */
76
77 /*
78 * Wangtek controller ports
79 */
80 #define WT_CTLPORT(base) ((base)+0) /* control, write only */
81 #define WT_STATPORT(base) ((base)+0) /* status, read only */
82 #define WT_CMDPORT(base) ((base)+1) /* command, write only */
83 #define WT_DATAPORT(base) ((base)+1) /* data, read only */
84 #define WT_NPORT 2 /* 2 i/o ports */
85
86 /* status port bits */
87 #define WT_BUSY 0x01 /* not ready bit define */
88 #define WT_NOEXCEP 0x02 /* no exception bit define */
89 #define WT_RESETMASK 0x07 /* to check after reset */
90 #define WT_RESETVAL 0x05 /* state after reset */
91
92 /* control port bits */
93 #define WT_ONLINE 0x01 /* device selected */
94 #define WT_RESET 0x02 /* reset command */
95 #define WT_REQUEST 0x04 /* request command */
96 #define WT_IEN 0x08 /* enable dma */
97
98 /*
99 * Archive controller ports
100 */
101 #define AV_DATAPORT(base) ((base)+0) /* data, read only */
102 #define AV_CMDPORT(base) ((base)+0) /* command, write only */
103 #define AV_STATPORT(base) ((base)+1) /* status, read only */
104 #define AV_CTLPORT(base) ((base)+1) /* control, write only */
105 #define AV_SDMAPORT(base) ((base)+2) /* start dma */
106 #define AV_RDMAPORT(base) ((base)+3) /* reset dma */
107 #define AV_NPORT 4 /* 4 i/o ports */
108
109 /* status port bits */
110 #define AV_BUSY 0x40 /* not ready bit define */
111 #define AV_NOEXCEP 0x20 /* no exception bit define */
112 #define AV_RESETMASK 0xf8 /* to check after reset */
113 #define AV_RESETVAL 0x50 /* state after reset */
114
115 /* control port bits */
116 #define AV_RESET 0x80 /* reset command */
117 #define AV_REQUEST 0x40 /* request command */
118 #define AV_IEN 0x20 /* enable interrupts */
119
120 enum wttype {
121 UNKNOWN = 0, /* unknown type, driver disabled */
122 ARCHIVE, /* Archive Viper SC499, SC402 etc */
123 WANGTEK, /* Wangtek */
124 };
125
126 struct wt_softc {
127 struct device sc_dev;
128 struct intrhand sc_ih;
129
130 enum wttype type; /* type of controller */
131 u_short sc_iobase; /* base i/o port */
132 unsigned chan; /* dma channel number, 1..3 */
133 int flags; /* state of tape drive */
134 unsigned dens; /* tape density */
135 int bsize; /* tape block size */
136 void *buf; /* internal i/o buffer */
137
138 void *dmavaddr; /* virtual address of dma i/o buffer */
139 size_t dmatotal; /* size of i/o buffer */
140 int dmaflags; /* i/o direction, B_READ or B_WRITE */
141 size_t dmacount; /* resulting length of dma i/o */
142
143 u_short error; /* code for error encountered */
144 u_short ercnt; /* number of error blocks */
145 u_short urcnt; /* number of underruns */
146
147 u_short DATAPORT, CMDPORT, STATPORT, CTLPORT, SDMAPORT, RDMAPORT;
148 u_char BUSY, NOEXCEP, RESETMASK, RESETVAL, ONLINE, RESET, REQUEST, IEN;
149 };
150
151 int wtwait __P((struct wt_softc *sc, int catch, char *msg));
152 int wtcmd __P((struct wt_softc *sc, int cmd));
153 int wtstart __P((struct wt_softc *sc, int flag, void *vaddr, size_t len));
154 void wtdma __P((struct wt_softc *sc));
155 void wttimer __P((struct wt_softc *sc));
156 void wtclock __P((struct wt_softc *sc));
157 int wtreset __P((struct wt_softc *sc));
158 int wtsense __P((struct wt_softc *sc, int verbose, int ignore));
159 int wtstatus __P((struct wt_softc *sc));
160 void wtrewind __P((struct wt_softc *sc));
161 int wtreadfm __P((struct wt_softc *sc));
162 int wtwritefm __P((struct wt_softc *sc));
163 u_char wtpoll __P((struct wt_softc *sc, int mask, int bits));
164
165 int wtprobe();
166 void wtattach();
167 int wtintr __P((struct wt_softc *sc));
168
169 struct cfdriver wtcd = {
170 NULL, "wt", wtprobe, wtattach, DV_TAPE, sizeof(struct wt_softc)
171 };
172
173 /*
174 * Probe for the presence of the device.
175 */
176 int
177 wtprobe(parent, self, aux)
178 struct device *parent, *self;
179 void *aux;
180 {
181 struct wt_softc *sc = (void *)self;
182 struct isa_attach_args *ia = aux;
183 u_short iobase;
184
185 sc->chan = ia->ia_drq;
186 sc->sc_iobase = iobase = ia->ia_iobase;
187 if (sc->chan < 1 || sc->chan > 3) {
188 printf("%s: Bad drq=%d, should be 1..3\n", sc->sc_dev.dv_xname,
189 sc->chan);
190 return 0;
191 }
192
193 /* Try Wangtek. */
194 sc->type = WANGTEK;
195 sc->CTLPORT = WT_CTLPORT(iobase);
196 sc->STATPORT = WT_STATPORT(iobase);
197 sc->CMDPORT = WT_CMDPORT(iobase);
198 sc->DATAPORT = WT_DATAPORT(iobase);
199 sc->SDMAPORT = sc->RDMAPORT = 0;
200 sc->BUSY = WT_BUSY; sc->NOEXCEP = WT_NOEXCEP;
201 sc->RESETMASK = WT_RESETMASK; sc->RESETVAL = WT_RESETVAL;
202 sc->ONLINE = WT_ONLINE; sc->RESET = WT_RESET;
203 sc->REQUEST = WT_REQUEST; sc->IEN = WT_IEN;
204 if (wtreset(sc)) {
205 ia->ia_iosize = WT_NPORT;
206 return 1;
207 }
208
209 /* Try Archive. */
210 sc->type = ARCHIVE;
211 sc->CTLPORT = AV_CTLPORT(iobase);
212 sc->STATPORT = AV_STATPORT(iobase);
213 sc->CMDPORT = AV_CMDPORT(iobase);
214 sc->DATAPORT = AV_DATAPORT(iobase);
215 sc->SDMAPORT = AV_SDMAPORT(iobase);
216 sc->RDMAPORT = AV_RDMAPORT(iobase);
217 sc->BUSY = AV_BUSY; sc->NOEXCEP = AV_NOEXCEP;
218 sc->RESETMASK = AV_RESETMASK; sc->RESETVAL = AV_RESETVAL;
219 sc->ONLINE = 0; sc->RESET = AV_RESET;
220 sc->REQUEST = AV_REQUEST; sc->IEN = AV_IEN;
221 if (wtreset(sc)) {
222 ia->ia_iosize = AV_NPORT;
223 return 1;
224 }
225
226 /* Tape controller not found. */
227 sc->type = UNKNOWN;
228 return 0;
229 }
230
231 /*
232 * Device is found, configure it.
233 */
234 void
235 wtattach(parent, self, aux)
236 struct device *parent, *self;
237 void *aux;
238 {
239 struct wt_softc *sc = (void *)self;
240 struct isa_attach_args *ia = aux;
241
242 if (sc->type == ARCHIVE) {
243 printf(": type <Archive>\n");
244 /* Reset DMA. */
245 outb(sc->RDMAPORT, 0);
246 } else
247 printf(": type <Wangtek>\n");
248 sc->flags = TPSTART; /* tape is rewound */
249 sc->dens = -1; /* unknown density */
250
251 sc->sc_ih.ih_fun = wtintr;
252 sc->sc_ih.ih_arg = sc;
253 sc->sc_ih.ih_level = IPL_BIO;
254 intr_establish(ia->ia_irq, &sc->sc_ih);
255 }
256
257 int
258 wtdump(dev)
259 dev_t dev;
260 {
261
262 /* Not implemented. */
263 return EINVAL;
264 }
265
266 int
267 wtsize(dev)
268 dev_t dev;
269 {
270
271 /* Not implemented. */
272 return -1;
273 }
274
275 /*
276 * Open routine, called on every device open.
277 */
278 int
279 wtopen(dev, flag)
280 dev_t dev;
281 int flag;
282 {
283 int unit = minor(dev) & T_UNIT;
284 struct wt_softc *sc;
285 int error;
286
287 if (unit >= wtcd.cd_ndevs)
288 return ENXIO;
289 sc = wtcd.cd_devs[unit];
290 if (!sc)
291 return ENXIO;
292
293 /* Check that device is not in use */
294 if (sc->flags & TPINUSE)
295 return EBUSY;
296
297 /* If the tape is in rewound state, check the status and set density. */
298 if (sc->flags & TPSTART) {
299 /* If rewind is going on, wait */
300 if (error = wtwait(sc, PCATCH, "wtrew"))
301 return error;
302
303 /* Check the controller status */
304 if (!wtsense(sc, 0, (flag & FWRITE) ? 0 : TP_WRP)) {
305 /* Bad status, reset the controller. */
306 if (!wtreset(sc))
307 return EIO;
308 if (!wtsense(sc, 1, (flag & FWRITE) ? 0 : TP_WRP))
309 return EIO;
310 }
311
312 /* Set up tape density. */
313 if (sc->dens != (minor(dev) & WT_DENSEL)) {
314 int d = 0;
315
316 switch (minor(dev) & WT_DENSEL) {
317 case WT_DENSDFLT:
318 default:
319 break; /* default density */
320 case WT_QIC11:
321 d = QIC_FMT11; break; /* minor 010 */
322 case WT_QIC24:
323 d = QIC_FMT24; break; /* minor 020 */
324 case WT_QIC120:
325 d = QIC_FMT120; break; /* minor 030 */
326 case WT_QIC150:
327 d = QIC_FMT150; break; /* minor 040 */
328 case WT_QIC300:
329 d = QIC_FMT300; break; /* minor 050 */
330 case WT_QIC600:
331 d = QIC_FMT600; break; /* minor 060 */
332 }
333 if (d) {
334 /* Change tape density. */
335 if (!wtcmd(sc, d))
336 return EIO;
337 if (!wtsense(sc, 1, TP_WRP | TP_ILL))
338 return EIO;
339
340 /* Check the status of the controller. */
341 if (sc->error & TP_ILL) {
342 printf("%s: invalid tape density\n",
343 sc->sc_dev.dv_xname);
344 return ENODEV;
345 }
346 }
347 sc->dens = minor(dev) & WT_DENSEL;
348 }
349 sc->flags &= ~TPSTART;
350 } else if (sc->dens != (minor(dev) & WT_DENSEL))
351 return ENXIO;
352
353 sc->bsize = (minor(dev) & WT_BSIZE) ? 1024 : 512;
354 sc->buf = malloc(sc->bsize, M_TEMP, M_WAITOK);
355
356 sc->flags = TPINUSE;
357 if (flag & FREAD)
358 sc->flags |= TPREAD;
359 if (flag & FWRITE)
360 sc->flags |= TPWRITE;
361 return 0;
362 }
363
364 /*
365 * Close routine, called on last device close.
366 */
367 int
368 wtclose(dev)
369 dev_t dev;
370 {
371 int unit = minor(dev) & T_UNIT;
372 struct wt_softc *sc = wtcd.cd_devs[unit];
373
374 /* If rewind is pending, do nothing */
375 if (sc->flags & TPREW)
376 goto done;
377
378 /* If seek forward is pending and no rewind on close, do nothing */
379 if (sc->flags & TPRMARK) {
380 if (minor(dev) & T_NOREWIND)
381 goto done;
382
383 /* If read file mark is going on, wait */
384 wtwait(sc, 0, "wtrfm");
385 }
386
387 if (sc->flags & TPWANY) {
388 /* Tape was written. Write file mark. */
389 wtwritefm(sc);
390 }
391
392 if ((minor(dev) & T_NOREWIND) == 0) {
393 /* Rewind to beginning of tape. */
394 /* Don't wait until rewind, though. */
395 wtrewind(sc);
396 goto done;
397 }
398 if ((sc->flags & TPRANY) && (sc->flags & (TPVOL | TPWANY)) == 0) {
399 /* Space forward to after next file mark if no writing done. */
400 /* Don't wait for completion. */
401 wtreadfm(sc);
402 }
403
404 done:
405 sc->flags &= TPREW | TPRMARK | TPSTART | TPTIMER;
406 free(sc->buf, M_TEMP);
407 return 0;
408 }
409
410 /*
411 * Ioctl routine. Compatible with BSD ioctls.
412 * Direct QIC-02 commands ERASE and RETENSION added.
413 * There are three possible ioctls:
414 * ioctl(int fd, MTIOCGET, struct mtget *buf) -- get status
415 * ioctl(int fd, MTIOCTOP, struct mtop *buf) -- do BSD-like op
416 * ioctl(int fd, WTQICMD, int qicop) -- do QIC op
417 */
418 int
419 wtioctl(dev, cmd, addr, flag)
420 dev_t dev;
421 int cmd;
422 void *addr;
423 int flag;
424 {
425 int unit = minor(dev) & T_UNIT;
426 struct wt_softc *sc = wtcd.cd_devs[unit];
427 int error, count, op;
428
429 switch (cmd) {
430 default:
431 return EINVAL;
432 case WTQICMD: /* direct QIC command */
433 op = *(int *)addr;
434 switch (op) {
435 default:
436 return EINVAL;
437 case QIC_ERASE: /* erase the whole tape */
438 if ((sc->flags & TPWRITE) == 0 || (sc->flags & TPWP))
439 return EACCES;
440 if (error = wtwait(sc, PCATCH, "wterase"))
441 return error;
442 break;
443 case QIC_RETENS: /* retension the tape */
444 if (error = wtwait(sc, PCATCH, "wtretens"))
445 return error;
446 break;
447 }
448 /* Both ERASE and RETENS operations work like REWIND. */
449 /* Simulate the rewind operation here. */
450 sc->flags &= ~(TPRO | TPWO | TPVOL);
451 if (!wtcmd(sc, op))
452 return EIO;
453 sc->flags |= TPSTART | TPREW;
454 if (op == QIC_ERASE)
455 sc->flags |= TPWANY;
456 wtclock(sc);
457 return 0;
458 case MTIOCIEOT: /* ignore EOT errors */
459 case MTIOCEEOT: /* enable EOT errors */
460 return 0;
461 case MTIOCGET:
462 ((struct mtget*)addr)->mt_type =
463 sc->type == ARCHIVE ? MT_ISVIPER1 : 0x11;
464 ((struct mtget*)addr)->mt_dsreg = sc->flags; /* status */
465 ((struct mtget*)addr)->mt_erreg = sc->error; /* errors */
466 ((struct mtget*)addr)->mt_resid = 0;
467 ((struct mtget*)addr)->mt_fileno = 0; /* file */
468 ((struct mtget*)addr)->mt_blkno = 0; /* block */
469 return 0;
470 case MTIOCTOP:
471 break;
472 }
473
474 switch ((short)((struct mtop*)addr)->mt_op) {
475 default:
476 #if 0
477 case MTFSR: /* forward space record */
478 case MTBSR: /* backward space record */
479 case MTBSF: /* backward space file */
480 #endif
481 return EINVAL;
482 case MTNOP: /* no operation, sets status only */
483 case MTCACHE: /* enable controller cache */
484 case MTNOCACHE: /* disable controller cache */
485 return 0;
486 case MTREW: /* rewind */
487 case MTOFFL: /* rewind and put the drive offline */
488 if (sc->flags & TPREW) /* rewind is running */
489 return 0;
490 if (error = wtwait(sc, PCATCH, "wtorew"))
491 return error;
492 wtrewind(sc);
493 return 0;
494 case MTFSF: /* forward space file */
495 for (count = ((struct mtop*)addr)->mt_count; count > 0;
496 --count) {
497 if (error = wtwait(sc, PCATCH, "wtorfm"))
498 return error;
499 if (error = wtreadfm(sc))
500 return error;
501 }
502 return 0;
503 case MTWEOF: /* write an end-of-file record */
504 if ((sc->flags & TPWRITE) == 0 || (sc->flags & TPWP))
505 return EACCES;
506 if (error = wtwait(sc, PCATCH, "wtowfm"))
507 return error;
508 if (error = wtwritefm(sc))
509 return error;
510 return 0;
511 }
512
513 #ifdef DIAGNOSTIC
514 panic("wtioctl: impossible");
515 #endif
516 }
517
518 /*
519 * Strategy routine.
520 */
521 void
522 wtstrategy(bp)
523 struct buf *bp;
524 {
525 int unit = minor(bp->b_dev) & T_UNIT;
526 struct wt_softc *sc = wtcd.cd_devs[unit];
527 int s;
528
529 bp->b_resid = bp->b_bcount;
530
531 /* at file marks and end of tape, we just return '0 bytes available' */
532 if (sc->flags & TPVOL)
533 goto xit;
534
535 if (bp->b_flags & B_READ) {
536 /* Check read access and no previous write to this tape. */
537 if ((sc->flags & TPREAD) == 0 || (sc->flags & TPWANY))
538 goto errxit;
539
540 /* For now, we assume that all data will be copied out */
541 /* If read command outstanding, just skip down */
542 if ((sc->flags & TPRO) == 0) {
543 if (!wtsense(sc, 1, TP_WRP)) {
544 /* Clear status. */
545 goto errxit;
546 }
547 if (!wtcmd(sc, QIC_RDDATA)) {
548 /* Set read mode. */
549 wtsense(sc, 1, TP_WRP);
550 goto errxit;
551 }
552 sc->flags |= TPRO | TPRANY;
553 }
554 } else {
555 /* Check write access and write protection. */
556 /* No previous read from this tape allowed. */
557 if ((sc->flags & TPWRITE) == 0 || (sc->flags & (TPWP | TPRANY)))
558 goto errxit;
559
560 /* If write command outstanding, just skip down */
561 if ((sc->flags & TPWO) == 0) {
562 if (!wtsense(sc, 1, 0)) {
563 /* Clear status. */
564 goto errxit;
565 }
566 if (!wtcmd(sc, QIC_WRTDATA)) {
567 /* Set write mode. */
568 wtsense(sc, 1, 0);
569 goto errxit;
570 }
571 sc->flags |= TPWO | TPWANY;
572 }
573 }
574
575 if (bp->b_bcount == 0)
576 goto xit;
577
578 sc->flags &= ~TPEXCEP;
579 s = splbio();
580 if (wtstart(sc, bp->b_flags, bp->b_un.b_addr, bp->b_bcount)) {
581 wtwait(sc, 0, (bp->b_flags & B_READ) ? "wtread" : "wtwrite");
582 bp->b_resid -= sc->dmacount;
583 }
584 splx(s);
585
586 if (sc->flags & TPEXCEP) {
587 errxit:
588 bp->b_flags |= B_ERROR;
589 bp->b_error = EIO;
590 }
591 xit:
592 biodone(bp);
593 return;
594 }
595
596 /*
597 * Interrupt routine.
598 */
599 int
600 wtintr(sc)
601 struct wt_softc *sc;
602 {
603 u_char s;
604
605 s = inb(sc->STATPORT); /* get status */
606 DEBUG(("wtintr() status=0x%x -- ", s));
607 if ((s & (sc->BUSY | sc->NOEXCEP)) == (sc->BUSY | sc->NOEXCEP)) {
608 DEBUG(("busy\n"));
609 return 0; /* device is busy */
610 }
611
612 /*
613 * Check if rewind finished.
614 */
615 if (sc->flags & TPREW) {
616 DEBUG(((s & (sc->BUSY | sc->NOEXCEP)) == (sc->BUSY | sc->NOEXCEP) ?
617 "rewind busy?\n" : "rewind finished\n"));
618 sc->flags &= ~TPREW; /* rewind finished */
619 wtsense(sc, 1, TP_WRP);
620 wakeup((caddr_t)sc);
621 return 1;
622 }
623
624 /*
625 * Check if writing/reading of file mark finished.
626 */
627 if (sc->flags & (TPRMARK | TPWMARK)) {
628 DEBUG(((s & (sc->BUSY | sc->NOEXCEP)) == (sc->BUSY | sc->NOEXCEP) ?
629 "marker r/w busy?\n" : "marker r/w finished\n"));
630 if ((s & sc->NOEXCEP) == 0) /* operation failed */
631 wtsense(sc, 1, (sc->flags & TPRMARK) ? TP_WRP : 0);
632 sc->flags &= ~(TPRMARK | TPWMARK); /* operation finished */
633 wakeup((caddr_t)sc);
634 return 1;
635 }
636
637 /*
638 * Do we started any i/o? If no, just return.
639 */
640 if ((sc->flags & TPACTIVE) == 0) {
641 DEBUG(("unexpected interrupt\n"));
642 return 0;
643 }
644 sc->flags &= ~TPACTIVE;
645 sc->dmacount += sc->bsize; /* increment counter */
646
647 /*
648 * Clean up dma.
649 */
650 if ((sc->dmaflags & B_READ) &&
651 (sc->dmatotal - sc->dmacount) < sc->bsize) {
652 /* If reading short block, copy the internal buffer
653 * to the user memory. */
654 isa_dmadone(sc->dmaflags, sc->buf, sc->bsize, sc->chan);
655 bcopy(sc->buf, sc->dmavaddr, sc->dmatotal - sc->dmacount);
656 } else
657 isa_dmadone(sc->dmaflags, sc->dmavaddr, sc->bsize, sc->chan);
658
659 /*
660 * On exception, check for end of file and end of volume.
661 */
662 if ((s & sc->NOEXCEP) == 0) {
663 DEBUG(("i/o exception\n"));
664 wtsense(sc, 1, (sc->dmaflags & B_READ) ? TP_WRP : 0);
665 if (sc->error & (TP_EOM | TP_FIL))
666 sc->flags |= TPVOL; /* end of file */
667 else
668 sc->flags |= TPEXCEP; /* i/o error */
669 wakeup((caddr_t)sc);
670 return 1;
671 }
672
673 if (sc->dmacount < sc->dmatotal) {
674 /* Continue I/O. */
675 sc->dmavaddr += sc->bsize;
676 wtdma(sc);
677 DEBUG(("continue i/o, %d\n", sc->dmacount));
678 return 1;
679 }
680 if (sc->dmacount > sc->dmatotal) /* short last block */
681 sc->dmacount = sc->dmatotal;
682 /* Wake up user level. */
683 wakeup((caddr_t)sc);
684 DEBUG(("i/o finished, %d\n", sc->dmacount));
685 return 1;
686 }
687
688 /* start the rewind operation */
689 void
690 wtrewind(sc)
691 struct wt_softc *sc;
692 {
693 int rwmode = sc->flags & (TPRO | TPWO);
694
695 sc->flags &= ~(TPRO | TPWO | TPVOL);
696 /*
697 * Wangtek strictly follows QIC-02 standard:
698 * clearing ONLINE in read/write modes causes rewind.
699 * REWIND command is not allowed in read/write mode
700 * and gives `illegal command' error.
701 */
702 if (sc->type == WANGTEK && rwmode) {
703 outb(sc->CTLPORT, 0);
704 } else if (!wtcmd(sc, QIC_REWIND))
705 return;
706 sc->flags |= TPSTART | TPREW;
707 wtclock(sc);
708 }
709
710 /*
711 * Start the `read marker' operation.
712 */
713 int
714 wtreadfm(sc)
715 struct wt_softc *sc;
716 {
717
718 sc->flags &= ~(TPRO | TPWO | TPVOL);
719 if (!wtcmd(sc, QIC_READFM)) {
720 wtsense(sc, 1, TP_WRP);
721 return EIO;
722 }
723 sc->flags |= TPRMARK | TPRANY;
724 wtclock(sc);
725 /* Don't wait for completion here. */
726 return 0;
727 }
728
729 /*
730 * Write marker to the tape.
731 */
732 int
733 wtwritefm(sc)
734 struct wt_softc *sc;
735 {
736
737 tsleep((caddr_t)wtwritefm, WTPRI, "wtwfm", hz);
738 sc->flags &= ~(TPRO | TPWO);
739 if (!wtcmd(sc, QIC_WRITEFM)) {
740 wtsense(sc, 1, 0);
741 return EIO;
742 }
743 sc->flags |= TPWMARK | TPWANY;
744 wtclock(sc);
745 return wtwait(sc, 0, "wtwfm");
746 }
747
748 /*
749 * While controller status & mask == bits continue waiting.
750 */
751 u_char
752 wtpoll(sc, mask, bits)
753 struct wt_softc *sc;
754 int mask, bits;
755 {
756 u_char s;
757 int i;
758
759 /* Poll status port, waiting for specified bits. */
760 for (i = 0; i < 1000; ++i) { /* up to 1 msec */
761 s = inb(sc->STATPORT);
762 if ((s & mask) != bits)
763 return s;
764 delay(1);
765 }
766 for (i = 0; i < 100; ++i) { /* up to 10 msec */
767 s = inb(sc->STATPORT);
768 if ((s & mask) != bits)
769 return s;
770 delay(100);
771 }
772 for (;;) { /* forever */
773 s = inb(sc->STATPORT);
774 if ((s & mask) != bits)
775 return s;
776 tsleep((caddr_t)wtpoll, WTPRI, "wtpoll", 1);
777 }
778 }
779
780 /*
781 * Execute QIC command.
782 */
783 int
784 wtcmd(sc, cmd)
785 struct wt_softc *sc;
786 int cmd;
787 {
788 u_char s;
789
790 DEBUG(("wtcmd() cmd=0x%x\n", cmd));
791 s = wtpoll(sc, sc->BUSY | sc->NOEXCEP, sc->BUSY | sc->NOEXCEP); /* ready? */
792 if ((s & sc->NOEXCEP) == 0) /* error */
793 return 0;
794
795 outb(sc->CMDPORT, cmd); /* output the command */
796
797 outb(sc->CTLPORT, sc->REQUEST | sc->ONLINE); /* set request */
798 wtpoll(sc, sc->BUSY, sc->BUSY); /* wait for ready */
799 outb(sc->CTLPORT, sc->IEN | sc->ONLINE); /* reset request */
800 wtpoll(sc, sc->BUSY, 0); /* wait for not ready */
801 return 1;
802 }
803
804 /* wait for the end of i/o, seeking marker or rewind operation */
805 int
806 wtwait(sc, catch, msg)
807 struct wt_softc *sc;
808 int catch;
809 char *msg;
810 {
811 int error;
812
813 DEBUG(("wtwait() `%s'\n", msg));
814 while (sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK))
815 if (error = tsleep((caddr_t)sc, WTPRI | catch, msg, 0))
816 return error;
817 return 0;
818 }
819
820 /* initialize dma for the i/o operation */
821 void
822 wtdma(sc)
823 struct wt_softc *sc;
824 {
825
826 sc->flags |= TPACTIVE;
827 wtclock(sc);
828
829 if (sc->type == ARCHIVE) {
830 /* Set DMA. */
831 outb(sc->SDMAPORT, 0);
832 }
833
834 if ((sc->dmaflags & B_READ) &&
835 (sc->dmatotal - sc->dmacount) < sc->bsize) {
836 /* Reading short block; do it through the internal buffer. */
837 isa_dmastart(sc->dmaflags, sc->buf, sc->bsize, sc->chan);
838 } else
839 isa_dmastart(sc->dmaflags, sc->dmavaddr, sc->bsize, sc->chan);
840 }
841
842 /* start i/o operation */
843 int
844 wtstart(sc, flag, vaddr, len)
845 struct wt_softc *sc;
846 int flag;
847 void *vaddr;
848 size_t len;
849 {
850 u_char s;
851
852 DEBUG(("wtstart()\n"));
853 s = wtpoll(sc, sc->BUSY | sc->NOEXCEP, sc->BUSY | sc->NOEXCEP); /* ready? */
854 if ((s & sc->NOEXCEP) == 0) {
855 sc->flags |= TPEXCEP; /* error */
856 return 0;
857 }
858 sc->flags &= ~TPEXCEP; /* clear exception flag */
859 sc->dmavaddr = vaddr;
860 sc->dmatotal = len;
861 sc->dmacount = 0;
862 sc->dmaflags = flag;
863 wtdma(sc);
864 return 1;
865 }
866
867 /*
868 * Start timer.
869 */
870 void
871 wtclock(sc)
872 struct wt_softc *sc;
873 {
874
875 if (sc->flags & TPTIMER)
876 return;
877 sc->flags |= TPTIMER;
878 /*
879 * Some controllers seem to lose dma interrupts too often. To make the
880 * tape stream we need 1 tick timeout.
881 */
882 timeout((timeout_t)wttimer, (caddr_t)sc, (sc->flags & TPACTIVE) ? 1 : hz);
883 }
884
885 /*
886 * Simulate an interrupt periodically while i/o is going.
887 * This is necessary in case interrupts get eaten due to
888 * multiple devices on a single IRQ line.
889 */
890 void
891 wttimer(sc)
892 struct wt_softc *sc;
893 {
894 int s;
895
896 sc->flags &= ~TPTIMER;
897 if ((sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK)) == 0)
898 return;
899
900 /* If i/o going, simulate interrupt. */
901 s = splbio();
902 if ((inb(sc->STATPORT) & (sc->BUSY | sc->NOEXCEP)) != (sc->BUSY | sc->NOEXCEP)) {
903 DEBUG(("wttimer() -- "));
904 wtintr(sc);
905 }
906 splx(s);
907
908 /* Restart timer if i/o pending. */
909 if (sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK))
910 wtclock(sc);
911 }
912
913 /*
914 * Perform QIC-02 and QIC-36 compatible reset sequence.
915 */
916 int
917 wtreset(sc)
918 struct wt_softc *sc;
919 {
920 u_char s;
921 int i;
922
923 outb(sc->CTLPORT, sc->RESET | sc->ONLINE); /* send reset */
924 delay(30);
925 outb(sc->CTLPORT, sc->ONLINE); /* turn off reset */
926 delay(30);
927
928 /* Read the controller status. */
929 s = inb(sc->STATPORT);
930 if (s == 0xff) /* no port at this address? */
931 return 0;
932
933 /* Wait 3 sec for reset to complete. Needed for QIC-36 boards? */
934 for (i = 0; i < 3000; ++i) {
935 if ((s & sc->BUSY) == 0 || (s & sc->NOEXCEP) == 0)
936 break;
937 delay(1000);
938 s = inb(sc->STATPORT);
939 }
940 return (s & sc->RESETMASK) == sc->RESETVAL;
941 }
942
943 /*
944 * Get controller status information. Return 0 if user i/o request should
945 * receive an i/o error code.
946 */
947 int
948 wtsense(sc, verbose, ignore)
949 struct wt_softc *sc;
950 int verbose, ignore;
951 {
952 char *msg = 0;
953 int error;
954
955 DEBUG(("wtsense() ignore=0x%x\n", ignore));
956 sc->flags &= ~(TPRO | TPWO);
957 if (!wtstatus(sc))
958 return 0;
959 if ((sc->error & TP_ST0) == 0)
960 sc->error &= ~TP_ST0MASK;
961 if ((sc->error & TP_ST1) == 0)
962 sc->error &= ~TP_ST1MASK;
963 sc->error &= ~ignore; /* ignore certain errors */
964 error = sc->error & (TP_FIL | TP_BNL | TP_UDA | TP_EOM | TP_WRP |
965 TP_USL | TP_CNI | TP_MBD | TP_NDT | TP_ILL);
966 if (!error)
967 return 1;
968 if (!verbose)
969 return 0;
970
971 /* lifted from tdriver.c from Wangtek */
972 if (error & TP_USL)
973 msg = "Drive not online";
974 else if (error & TP_CNI)
975 msg = "No cartridge";
976 else if ((error & TP_WRP) && (sc->flags & TPWP) == 0) {
977 msg = "Tape is write protected";
978 sc->flags |= TPWP;
979 } else if (error & TP_FIL)
980 msg = 0 /*"Filemark detected"*/;
981 else if (error & TP_EOM)
982 msg = 0 /*"End of tape"*/;
983 else if (error & TP_BNL)
984 msg = "Block not located";
985 else if (error & TP_UDA)
986 msg = "Unrecoverable data error";
987 else if (error & TP_NDT)
988 msg = "No data detected";
989 else if (error & TP_ILL)
990 msg = "Illegal command";
991 if (msg)
992 printf("%s: %s\n", sc->sc_dev.dv_xname, msg);
993 return 0;
994 }
995
996 /*
997 * Get controller status information.
998 */
999 int
1000 wtstatus(sc)
1001 struct wt_softc *sc;
1002 {
1003 char *p;
1004
1005 wtpoll(sc, sc->BUSY | sc->NOEXCEP, sc->BUSY | sc->NOEXCEP); /* ready? */
1006 outb(sc->CMDPORT, QIC_RDSTAT); /* send `read status' command */
1007
1008 outb(sc->CTLPORT, sc->REQUEST | sc->ONLINE); /* set request */
1009 wtpoll(sc, sc->BUSY, sc->BUSY); /* wait for ready */
1010 outb(sc->CTLPORT, sc->ONLINE); /* reset request */
1011 wtpoll(sc, sc->BUSY, 0); /* wait for not ready */
1012
1013 p = (char *)&sc->error;
1014 while (p < (char *)&sc->error + 6) {
1015 u_char s = wtpoll(sc, sc->BUSY | sc->NOEXCEP, sc->BUSY | sc->NOEXCEP);
1016 if ((s & sc->NOEXCEP) == 0) /* error */
1017 return 0;
1018
1019 *p++ = inb(sc->DATAPORT); /* read status byte */
1020
1021 outb(sc->CTLPORT, sc->REQUEST | sc->ONLINE); /* set request */
1022 wtpoll(sc, sc->BUSY, 0); /* wait for not ready */
1023 outb(sc->CTLPORT, sc->ONLINE); /* unset request */
1024 }
1025 return 1;
1026 }
1027