1 /* $NetBSD: wt.c,v 1.81 2009/05/12 08:44:20 cegger Exp $ */
4 * Streamer tape driver.
5 * Supports Archive and Wangtek compatible QIC-02/QIC-36 boards.
7 * Copyright (C) 1993 by:
8 * Sergey Ryzhkov <sir@kiae.su>
9 * Serge Vakulenko <vak@zebub.msk.su>
11 * This software is distributed with NO WARRANTIES, not even the implied
12 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * Authors grant any other persons or organisations permission to use
15 * or modify this software as long as this message is kept with the software,
16 * all derivative works or modified versions.
18 * This driver is derived from the old 386bsd Wangtek streamer tape driver,
19 * made by Robert Baron at CMU, based on Intel sources.
23 * Copyright (c) 1989 Carnegie-Mellon University.
24 * All rights reserved.
26 * Authors: Robert Baron
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.
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.
38 * Carnegie Mellon requests users of this software to return to
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
45 * any improvements or extensions that they make and grant Carnegie the
46 * rights to redistribute these changes.
50 * Copyright 1988, 1989 by Intel Corporation
53 #include <sys/cdefs.h>
54 __KERNEL_RCSID(0, "$NetBSD: wt.c,v 1.81 2009/05/12 08:44:20 cegger Exp $");
56 #include <sys/param.h>
57 #include <sys/systm.h>
58 #include <sys/callout.h>
59 #include <sys/kernel.h>
61 #include <sys/fcntl.h>
62 #include <sys/malloc.h>
63 #include <sys/ioctl.h>
65 #include <sys/device.h>
72 #include <machine/pio.h>
74 #include <dev/isa/isavar.h>
75 #include <dev/isa/isadmavar.h>
76 #include <dev/isa/wtreg.h>
79 * Uncomment this to enable internal device tracing.
81 #define WTDBPRINT(x) /* printf x */
83 #define WTPRI (PZERO+10) /* sleep priority */
85 #define WT_NPORT 2 /* 2 i/o ports */
86 #define AV_NPORT 4 /* 4 i/o ports */
89 UNKNOWN
= 0, /* unknown type, driver disabled */
90 ARCHIVE
, /* Archive Viper SC499, SC402 etc */
91 WANGTEK
, /* Wangtek */
94 static struct wtregs
{
95 /* controller ports */
96 int DATAPORT
, /* data, read only */
97 CMDPORT
, /* command, write only */
98 STATPORT
, /* status, read only */
99 CTLPORT
, /* control, write only */
100 SDMAPORT
, /* start DMA */
101 RDMAPORT
; /* reset DMA */
102 /* status port bits */
103 u_char BUSY
, /* not ready bit define */
104 NOEXCEP
, /* no exception bit define */
105 RESETMASK
, /* to check after reset */
106 RESETVAL
, /* state after reset */
107 /* control port bits */
108 ONLINE
, /* device selected */
109 RESET
, /* reset command */
110 REQUEST
, /* request command */
111 IEN
; /* enable interrupts */
114 0x01, 0x02, 0x07, 0x05,
115 0x01, 0x02, 0x04, 0x08
118 0x40, 0x20, 0xf8, 0x50,
123 struct device sc_dev
;
126 bus_space_tag_t sc_iot
;
127 bus_space_handle_t sc_ioh
;
128 isa_chipset_tag_t sc_ic
;
130 callout_t sc_timer_ch
;
132 enum wttype type
; /* type of controller */
133 int chan
; /* DMA channel number, 1..3 */
134 int flags
; /* state of tape drive */
135 unsigned dens
; /* tape density */
136 int bsize
; /* tape block size */
137 void *buf
; /* internal i/o buffer */
139 void *dmavaddr
; /* virtual address of DMA i/o buffer */
140 size_t dmatotal
; /* size of i/o buffer */
141 int dmaflags
; /* i/o direction */
142 size_t dmacount
; /* resulting length of DMA i/o */
144 u_short error
; /* code for error encountered */
145 u_short ercnt
; /* number of error blocks */
146 u_short urcnt
; /* number of underruns */
151 static dev_type_open(wtopen
);
152 static dev_type_close(wtclose
);
153 static dev_type_read(wtread
);
154 static dev_type_write(wtwrite
);
155 static dev_type_ioctl(wtioctl
);
156 static dev_type_strategy(wtstrategy
);
157 static dev_type_dump(wtdump
);
158 static dev_type_size(wtsize
);
160 const struct bdevsw wt_bdevsw
= {
161 wtopen
, wtclose
, wtstrategy
, wtioctl
, wtdump
, wtsize
, D_TAPE
164 const struct cdevsw wt_cdevsw
= {
165 wtopen
, wtclose
, wtread
, wtwrite
, wtioctl
,
166 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_TAPE
169 static int wtwait(struct wt_softc
*sc
, int catch, const char *msg
);
170 static int wtcmd(struct wt_softc
*sc
, int cmd
);
171 static int wtstart(struct wt_softc
*sc
, int flag
, void *vaddr
, size_t len
);
172 static void wtdma(struct wt_softc
*sc
);
173 static void wttimer(void *arg
);
174 static void wtclock(struct wt_softc
*sc
);
175 static int wtreset(bus_space_tag_t
, bus_space_handle_t
, struct wtregs
*);
176 static int wtsense(struct wt_softc
*sc
, int verbose
, int ignore
);
177 static int wtstatus(struct wt_softc
*sc
);
178 static void wtrewind(struct wt_softc
*sc
);
179 static int wtreadfm(struct wt_softc
*sc
);
180 static int wtwritefm(struct wt_softc
*sc
);
181 static u_char
wtsoft(struct wt_softc
*sc
, int mask
, int bits
);
182 static int wtintr(void *sc
);
184 int wtprobe(device_t
, cfdata_t
, void *);
185 void wtattach(device_t
, device_t
, void *);
187 CFATTACH_DECL(wt
, sizeof(struct wt_softc
),
188 wtprobe
, wtattach
, NULL
, NULL
);
190 extern struct cfdriver wt_cd
;
193 * Probe for the presence of the device.
196 wtprobe(device_t parent
, cfdata_t match
, void *aux
)
198 struct isa_attach_args
*ia
= aux
;
199 bus_space_tag_t iot
= ia
->ia_iot
;
200 bus_space_handle_t ioh
;
210 /* Disallow wildcarded i/o address. */
211 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
213 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
)
216 if (ia
->ia_drq
[0].ir_drq
< 1 || ia
->ia_drq
[0].ir_drq
> 3) {
217 printf("wtprobe: Bad drq=%d, should be 1..3\n",
218 ia
->ia_drq
[0].ir_drq
);
225 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
, iosize
, 0, &ioh
))
229 if (wtreset(iot
, ioh
, &wtregs
)) {
230 iosize
= WT_NPORT
; /* XXX misleading */
236 if (wtreset(iot
, ioh
, &avregs
)) {
245 ia
->ia_io
[0].ir_size
= iosize
;
252 bus_space_unmap(iot
, ioh
, AV_NPORT
);
257 * Device is found, configure it.
260 wtattach(device_t parent
, device_t self
, void *aux
)
262 struct wt_softc
*sc
= (void *)self
;
263 struct isa_attach_args
*ia
= aux
;
264 bus_space_tag_t iot
= ia
->ia_iot
;
265 bus_space_handle_t ioh
;
269 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
, AV_NPORT
, 0, &ioh
)) {
270 printf(": can't map i/o space\n");
276 sc
->sc_ic
= ia
->ia_ic
;
278 callout_init(&sc
->sc_timer_ch
, 0);
281 if (wtreset(iot
, ioh
, &wtregs
)) {
283 memcpy(&sc
->regs
, &wtregs
, sizeof(sc
->regs
));
284 printf(": type <Wangtek>\n");
289 if (wtreset(iot
, ioh
, &avregs
)) {
291 memcpy(&sc
->regs
, &avregs
, sizeof(sc
->regs
));
292 printf(": type <Archive>\n");
294 bus_space_write_1(iot
, ioh
, sc
->regs
.RDMAPORT
, 0);
299 aprint_error_dev(self
, "lost controller\n");
303 sc
->flags
= TPSTART
; /* tape is rewound */
304 sc
->dens
= -1; /* unknown density */
306 sc
->chan
= ia
->ia_drq
[0].ir_drq
;
308 if ((maxsize
= isa_dmamaxsize(sc
->sc_ic
, sc
->chan
)) < MAXPHYS
) {
309 aprint_error_dev(&sc
->sc_dev
, "max DMA size %lu is less than required %d\n",
310 (u_long
)maxsize
, MAXPHYS
);
314 if (isa_drq_alloc(sc
->sc_ic
, sc
->chan
) != 0) {
315 aprint_error_dev(&sc
->sc_dev
, "can't reserve drq %d\n",
320 if (isa_dmamap_create(sc
->sc_ic
, sc
->chan
, MAXPHYS
,
321 BUS_DMA_NOWAIT
|BUS_DMA_ALLOCNOW
)) {
322 aprint_error_dev(&sc
->sc_dev
, "can't set up ISA DMA map\n");
326 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, ia
->ia_irq
[0].ir_irq
,
327 IST_EDGE
, IPL_BIO
, wtintr
, sc
);
331 wtdump(dev_t dev
, daddr_t blkno
, void *va
,
335 /* Not implemented. */
343 /* Not implemented. */
348 * Open routine, called on every device open.
351 wtopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
353 int unit
= minor(dev
) & T_UNIT
;
357 sc
= device_lookup_private(&wt_cd
, unit
);
361 /* Check that device is not in use */
362 if (sc
->flags
& TPINUSE
)
365 /* If the tape is in rewound state, check the status and set density. */
366 if (sc
->flags
& TPSTART
) {
367 /* If rewind is going on, wait */
368 if ((error
= wtwait(sc
, PCATCH
, "wtrew")) != 0)
371 /* Check the controller status */
372 if (!wtsense(sc
, 0, (flag
& FWRITE
) ? 0 : TP_WRP
)) {
373 /* Bad status, reset the controller. */
374 if (!wtreset(sc
->sc_iot
, sc
->sc_ioh
, &sc
->regs
))
376 if (!wtsense(sc
, 1, (flag
& FWRITE
) ? 0 : TP_WRP
))
380 /* Set up tape density. */
381 if (sc
->dens
!= (minor(dev
) & WT_DENSEL
)) {
384 switch (minor(dev
) & WT_DENSEL
) {
387 break; /* default density */
389 d
= QIC_FMT11
; break; /* minor 010 */
391 d
= QIC_FMT24
; break; /* minor 020 */
393 d
= QIC_FMT120
; break; /* minor 030 */
395 d
= QIC_FMT150
; break; /* minor 040 */
397 d
= QIC_FMT300
; break; /* minor 050 */
399 d
= QIC_FMT600
; break; /* minor 060 */
402 /* Change tape density. */
405 if (!wtsense(sc
, 1, TP_WRP
| TP_ILL
))
408 /* Check the status of the controller. */
409 if (sc
->error
& TP_ILL
) {
410 aprint_error_dev(&sc
->sc_dev
, "invalid tape density\n");
414 sc
->dens
= minor(dev
) & WT_DENSEL
;
416 sc
->flags
&= ~TPSTART
;
417 } else if (sc
->dens
!= (minor(dev
) & WT_DENSEL
))
420 sc
->bsize
= (minor(dev
) & WT_BSIZE
) ? 1024 : 512;
421 sc
->buf
= malloc(sc
->bsize
, M_TEMP
, M_WAITOK
);
427 sc
->flags
|= TPWRITE
;
432 * Close routine, called on last device close.
435 wtclose(dev_t dev
, int flags
, int mode
,
440 sc
= device_lookup_private(&wt_cd
, minor(dev
) & T_UNIT
);
442 /* If rewind is pending, do nothing */
443 if (sc
->flags
& TPREW
)
446 /* If seek forward is pending and no rewind on close, do nothing */
447 if (sc
->flags
& TPRMARK
) {
448 if (minor(dev
) & T_NOREWIND
)
451 /* If read file mark is going on, wait */
452 wtwait(sc
, 0, "wtrfm");
455 if (sc
->flags
& TPWANY
) {
456 /* Tape was written. Write file mark. */
460 if ((minor(dev
) & T_NOREWIND
) == 0) {
461 /* Rewind to beginning of tape. */
462 /* Don't wait until rewind, though. */
466 if ((sc
->flags
& TPRANY
) && (sc
->flags
& (TPVOL
| TPWANY
)) == 0) {
467 /* Space forward to after next file mark if no writing done. */
468 /* Don't wait for completion. */
473 sc
->flags
&= TPREW
| TPRMARK
| TPSTART
| TPTIMER
;
474 free(sc
->buf
, M_TEMP
);
479 * Ioctl routine. Compatible with BSD ioctls.
480 * Direct QIC-02 commands ERASE and RETENSION added.
481 * There are three possible ioctls:
482 * ioctl(int fd, MTIOCGET, struct mtget *buf) -- get status
483 * ioctl(int fd, MTIOCTOP, struct mtop *buf) -- do BSD-like op
484 * ioctl(int fd, WTQICMD, int qicop) -- do QIC op
487 wtioctl(dev_t dev
, unsigned long cmd
, void *addr
, int flag
,
491 int error
, count
, op
;
493 sc
= device_lookup_private(&wt_cd
, minor(dev
) & T_UNIT
);
498 case WTQICMD
: /* direct QIC command */
503 case QIC_ERASE
: /* erase the whole tape */
504 if ((sc
->flags
& TPWRITE
) == 0 || (sc
->flags
& TPWP
))
506 if ((error
= wtwait(sc
, PCATCH
, "wterase")) != 0)
509 case QIC_RETENS
: /* retension the tape */
510 if ((error
= wtwait(sc
, PCATCH
, "wtretens")) != 0)
514 /* Both ERASE and RETENS operations work like REWIND. */
515 /* Simulate the rewind operation here. */
516 sc
->flags
&= ~(TPRO
| TPWO
| TPVOL
);
519 sc
->flags
|= TPSTART
| TPREW
;
524 case MTIOCIEOT
: /* ignore EOT errors */
525 case MTIOCEEOT
: /* enable EOT errors */
528 ((struct mtget
*)addr
)->mt_type
=
529 sc
->type
== ARCHIVE
? MT_ISVIPER1
: 0x11;
530 ((struct mtget
*)addr
)->mt_dsreg
= sc
->flags
; /* status */
531 ((struct mtget
*)addr
)->mt_erreg
= sc
->error
; /* errors */
532 ((struct mtget
*)addr
)->mt_resid
= 0;
533 ((struct mtget
*)addr
)->mt_fileno
= 0; /* file */
534 ((struct mtget
*)addr
)->mt_blkno
= 0; /* block */
540 switch ((short)((struct mtop
*)addr
)->mt_op
) {
543 case MTFSR
: /* forward space record */
544 case MTBSR
: /* backward space record */
545 case MTBSF
: /* backward space file */
548 case MTNOP
: /* no operation, sets status only */
549 case MTCACHE
: /* enable controller cache */
550 case MTNOCACHE
: /* disable controller cache */
552 case MTREW
: /* rewind */
553 case MTOFFL
: /* rewind and put the drive offline */
554 if (sc
->flags
& TPREW
) /* rewind is running */
556 if ((error
= wtwait(sc
, PCATCH
, "wtorew")) != 0)
560 case MTFSF
: /* forward space file */
561 for (count
= ((struct mtop
*)addr
)->mt_count
; count
> 0;
563 if ((error
= wtwait(sc
, PCATCH
, "wtorfm")) != 0)
565 if ((error
= wtreadfm(sc
)) != 0)
569 case MTWEOF
: /* write an end-of-file record */
570 if ((sc
->flags
& TPWRITE
) == 0 || (sc
->flags
& TPWP
))
572 if ((error
= wtwait(sc
, PCATCH
, "wtowfm")) != 0)
574 if ((error
= wtwritefm(sc
)) != 0)
580 panic("wtioctl: impossible");
588 wtstrategy(struct buf
*bp
)
593 sc
= device_lookup_private(&wt_cd
, minor(bp
->b_dev
) & T_UNIT
);
595 bp
->b_resid
= bp
->b_bcount
;
597 /* at file marks and end of tape, we just return '0 bytes available' */
598 if (sc
->flags
& TPVOL
)
601 if (bp
->b_flags
& B_READ
) {
602 /* Check read access and no previous write to this tape. */
603 if ((sc
->flags
& TPREAD
) == 0 || (sc
->flags
& TPWANY
))
606 /* For now, we assume that all data will be copied out */
607 /* If read command outstanding, just skip down */
608 if ((sc
->flags
& TPRO
) == 0) {
609 if (!wtsense(sc
, 1, TP_WRP
)) {
613 if (!wtcmd(sc
, QIC_RDDATA
)) {
615 wtsense(sc
, 1, TP_WRP
);
618 sc
->flags
|= TPRO
| TPRANY
;
621 /* Check write access and write protection. */
622 /* No previous read from this tape allowed. */
623 if ((sc
->flags
& TPWRITE
) == 0 || (sc
->flags
& (TPWP
| TPRANY
)))
626 /* If write command outstanding, just skip down */
627 if ((sc
->flags
& TPWO
) == 0) {
628 if (!wtsense(sc
, 1, 0)) {
632 if (!wtcmd(sc
, QIC_WRTDATA
)) {
633 /* Set write mode. */
637 sc
->flags
|= TPWO
| TPWANY
;
641 if (bp
->b_bcount
== 0)
644 sc
->flags
&= ~TPEXCEP
;
646 if (wtstart(sc
, bp
->b_flags
, bp
->b_data
, bp
->b_bcount
)) {
647 wtwait(sc
, 0, (bp
->b_flags
& B_READ
) ? "wtread" : "wtwrite");
648 bp
->b_resid
-= sc
->dmacount
;
652 if (sc
->flags
& TPEXCEP
) {
662 wtread(dev_t dev
, struct uio
*uio
, int flags
)
665 return (physio(wtstrategy
, NULL
, dev
, B_READ
, minphys
, uio
));
669 wtwrite(dev_t dev
, struct uio
*uio
, int flags
)
672 return (physio(wtstrategy
, NULL
, dev
, B_WRITE
, minphys
, uio
));
681 struct wt_softc
*sc
= arg
;
685 x
= bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, sc
->regs
.STATPORT
);
686 WTDBPRINT(("wtintr() status=0x%x -- ", x
));
687 if ((x
& (sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
))
688 == (sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
)) {
689 WTDBPRINT(("busy\n"));
690 return 0; /* device is busy */
694 * Check if rewind finished.
696 if (sc
->flags
& TPREW
) {
697 WTDBPRINT(((x
& (sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
))
698 == (sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
) ?
699 "rewind busy?\n" : "rewind finished\n"));
700 sc
->flags
&= ~TPREW
; /* rewind finished */
701 wtsense(sc
, 1, TP_WRP
);
707 * Check if writing/reading of file mark finished.
709 if (sc
->flags
& (TPRMARK
| TPWMARK
)) {
710 WTDBPRINT(((x
& (sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
))
711 == (sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
) ?
712 "marker r/w busy?\n" : "marker r/w finished\n"));
713 if ((x
& sc
->regs
.NOEXCEP
) == 0) /* operation failed */
714 wtsense(sc
, 1, (sc
->flags
& TPRMARK
) ? TP_WRP
: 0);
715 sc
->flags
&= ~(TPRMARK
| TPWMARK
); /* operation finished */
721 * Do we started any i/o? If no, just return.
723 if ((sc
->flags
& TPACTIVE
) == 0) {
724 WTDBPRINT(("unexpected interrupt\n"));
727 sc
->flags
&= ~TPACTIVE
;
728 sc
->dmacount
+= sc
->bsize
; /* increment counter */
733 if ((sc
->dmaflags
& DMAMODE_READ
) &&
734 (sc
->dmatotal
- sc
->dmacount
) < sc
->bsize
) {
735 /* If reading short block, copy the internal buffer
736 * to the user memory. */
737 isa_dmadone(sc
->sc_ic
, sc
->chan
);
738 memcpy(sc
->dmavaddr
, sc
->buf
, sc
->dmatotal
- sc
->dmacount
);
740 isa_dmadone(sc
->sc_ic
, sc
->chan
);
743 * On exception, check for end of file and end of volume.
745 if ((x
& sc
->regs
.NOEXCEP
) == 0) {
746 WTDBPRINT(("i/o exception\n"));
747 wtsense(sc
, 1, (sc
->dmaflags
& DMAMODE_READ
) ? TP_WRP
: 0);
748 if (sc
->error
& (TP_EOM
| TP_FIL
))
749 sc
->flags
|= TPVOL
; /* end of file */
751 sc
->flags
|= TPEXCEP
; /* i/o error */
756 if (sc
->dmacount
< sc
->dmatotal
) {
758 sc
->dmavaddr
= (char *)sc
->dmavaddr
+ sc
->bsize
;
760 WTDBPRINT(("continue i/o, %d\n", sc
->dmacount
));
763 if (sc
->dmacount
> sc
->dmatotal
) /* short last block */
764 sc
->dmacount
= sc
->dmatotal
;
765 /* Wake up user level. */
767 WTDBPRINT(("i/o finished, %d\n", sc
->dmacount
));
771 /* start the rewind operation */
773 wtrewind(struct wt_softc
*sc
)
775 int rwmode
= sc
->flags
& (TPRO
| TPWO
);
777 sc
->flags
&= ~(TPRO
| TPWO
| TPVOL
);
779 * Wangtek strictly follows QIC-02 standard:
780 * clearing ONLINE in read/write modes causes rewind.
781 * REWIND command is not allowed in read/write mode
782 * and gives `illegal command' error.
784 if (sc
->type
== WANGTEK
&& rwmode
) {
785 bus_space_write_1(sc
->sc_iot
, sc
->sc_ioh
, sc
->regs
.CTLPORT
, 0);
786 } else if (!wtcmd(sc
, QIC_REWIND
))
788 sc
->flags
|= TPSTART
| TPREW
;
793 * Start the `read marker' operation.
796 wtreadfm(struct wt_softc
*sc
)
799 sc
->flags
&= ~(TPRO
| TPWO
| TPVOL
);
800 if (!wtcmd(sc
, QIC_READFM
)) {
801 wtsense(sc
, 1, TP_WRP
);
804 sc
->flags
|= TPRMARK
| TPRANY
;
806 /* Don't wait for completion here. */
811 * Write marker to the tape.
814 wtwritefm(struct wt_softc
*sc
)
817 tsleep((void *)wtwritefm
, WTPRI
, "wtwfm", hz
);
818 sc
->flags
&= ~(TPRO
| TPWO
);
819 if (!wtcmd(sc
, QIC_WRITEFM
)) {
823 sc
->flags
|= TPWMARK
| TPWANY
;
825 return wtwait(sc
, 0, "wtwfm");
829 * While controller status & mask == bits continue waiting.
832 wtsoft(struct wt_softc
*sc
, int mask
, int bits
)
834 bus_space_tag_t iot
= sc
->sc_iot
;
835 bus_space_handle_t ioh
= sc
->sc_ioh
;
840 /* Poll status port, waiting for specified bits. */
841 for (i
= 0; i
< 1000; ++i
) { /* up to 1 msec */
842 x
= bus_space_read_1(iot
, ioh
, sc
->regs
.STATPORT
);
843 if ((x
& mask
) != bits
)
847 for (i
= 0; i
< 100; ++i
) { /* up to 10 msec */
848 x
= bus_space_read_1(iot
, ioh
, sc
->regs
.STATPORT
);
849 if ((x
& mask
) != bits
)
853 for (;;) { /* forever */
854 x
= bus_space_read_1(iot
, ioh
, sc
->regs
.STATPORT
);
855 if ((x
& mask
) != bits
)
857 tsleep((void *)wtsoft
, WTPRI
, "wtsoft", 1);
862 * Execute QIC command.
865 wtcmd(struct wt_softc
*sc
, int cmd
)
867 bus_space_tag_t iot
= sc
->sc_iot
;
868 bus_space_handle_t ioh
= sc
->sc_ioh
;
872 WTDBPRINT(("wtcmd() cmd=0x%x\n", cmd
));
874 x
= wtsoft(sc
, sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
,
875 sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
); /* ready? */
876 if ((x
& sc
->regs
.NOEXCEP
) == 0) { /* error */
881 /* output the command */
882 bus_space_write_1(iot
, ioh
, sc
->regs
.CMDPORT
, cmd
);
885 bus_space_write_1(iot
, ioh
, sc
->regs
.CTLPORT
,
886 sc
->regs
.REQUEST
| sc
->regs
.ONLINE
);
889 wtsoft(sc
, sc
->regs
.BUSY
, sc
->regs
.BUSY
);
892 bus_space_write_1(iot
, ioh
, sc
->regs
.CTLPORT
,
893 sc
->regs
.IEN
| sc
->regs
.ONLINE
);
895 /* wait for not ready */
896 wtsoft(sc
, sc
->regs
.BUSY
, 0);
901 /* wait for the end of i/o, seeking marker or rewind operation */
903 wtwait(struct wt_softc
*sc
, int catch, const char *msg
)
907 WTDBPRINT(("wtwait() `%s'\n", msg
));
908 while (sc
->flags
& (TPACTIVE
| TPREW
| TPRMARK
| TPWMARK
))
909 if ((error
= tsleep((void *)sc
, WTPRI
| catch, msg
, 0)) != 0)
914 /* initialize DMA for the i/o operation */
916 wtdma(struct wt_softc
*sc
)
918 bus_space_tag_t iot
= sc
->sc_iot
;
919 bus_space_handle_t ioh
= sc
->sc_ioh
;
921 sc
->flags
|= TPACTIVE
;
924 if (sc
->type
== ARCHIVE
) {
926 bus_space_write_1(iot
, ioh
, sc
->regs
.SDMAPORT
, 0);
929 if ((sc
->dmaflags
& DMAMODE_READ
) &&
930 (sc
->dmatotal
- sc
->dmacount
) < sc
->bsize
) {
931 /* Reading short block; do it through the internal buffer. */
932 isa_dmastart(sc
->sc_ic
, sc
->chan
, sc
->buf
,
933 sc
->bsize
, NULL
, sc
->dmaflags
, BUS_DMA_NOWAIT
);
935 isa_dmastart(sc
->sc_ic
, sc
->chan
, sc
->dmavaddr
,
936 sc
->bsize
, NULL
, sc
->dmaflags
, BUS_DMA_NOWAIT
);
939 /* start i/o operation */
941 wtstart(struct wt_softc
*sc
, int flag
, void *vaddr
, size_t len
)
945 WTDBPRINT(("wtstart()\n"));
946 x
= wtsoft(sc
, sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
,
947 sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
); /* ready? */
948 if ((x
& sc
->regs
.NOEXCEP
) == 0) {
949 sc
->flags
|= TPEXCEP
; /* error */
952 sc
->flags
&= ~TPEXCEP
; /* clear exception flag */
953 sc
->dmavaddr
= vaddr
;
956 sc
->dmaflags
= flag
& B_READ
? DMAMODE_READ
: DMAMODE_WRITE
;
965 wtclock(struct wt_softc
*sc
)
968 if (sc
->flags
& TPTIMER
)
970 sc
->flags
|= TPTIMER
;
972 * Some controllers seem to lose DMA interrupts too often. To make the
973 * tape stream we need 1 tick timeout.
975 callout_reset(&sc
->sc_timer_ch
, (sc
->flags
& TPACTIVE
) ? 1 : hz
,
980 * Simulate an interrupt periodically while i/o is going.
981 * This is necessary in case interrupts get eaten due to
982 * multiple devices on a single IRQ line.
987 register struct wt_softc
*sc
= (struct wt_softc
*)arg
;
991 sc
->flags
&= ~TPTIMER
;
992 if ((sc
->flags
& (TPACTIVE
| TPREW
| TPRMARK
| TPWMARK
)) == 0)
995 /* If i/o going, simulate interrupt. */
997 status
= bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, sc
->regs
.STATPORT
);
998 if ((status
& (sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
))
999 != (sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
)) {
1000 WTDBPRINT(("wttimer() -- "));
1005 /* Restart timer if i/o pending. */
1006 if (sc
->flags
& (TPACTIVE
| TPREW
| TPRMARK
| TPWMARK
))
1011 * Perform QIC-02 and QIC-36 compatible reset sequence.
1014 wtreset(bus_space_tag_t iot
, bus_space_handle_t ioh
, struct wtregs
*regs
)
1020 bus_space_write_1(iot
, ioh
, regs
->CTLPORT
, regs
->RESET
| regs
->ONLINE
);
1022 /* turn off reset */
1023 bus_space_write_1(iot
, ioh
, regs
->CTLPORT
, regs
->ONLINE
);
1026 /* Read the controller status. */
1027 x
= bus_space_read_1(iot
, ioh
, regs
->STATPORT
);
1028 if (x
== 0xff) /* no port at this address? */
1031 /* Wait 3 sec for reset to complete. Needed for QIC-36 boards? */
1032 for (i
= 0; i
< 3000; ++i
) {
1033 if ((x
& regs
->BUSY
) == 0 || (x
& regs
->NOEXCEP
) == 0)
1036 x
= bus_space_read_1(iot
, ioh
, regs
->STATPORT
);
1038 return (x
& regs
->RESETMASK
) == regs
->RESETVAL
;
1042 * Get controller status information. Return 0 if user i/o request should
1043 * receive an i/o error code.
1046 wtsense(struct wt_softc
*sc
, int verbose
, int ignore
)
1048 const char *msg
= 0;
1051 WTDBPRINT(("wtsense() ignore=0x%x\n", ignore
));
1052 sc
->flags
&= ~(TPRO
| TPWO
);
1055 if ((sc
->error
& TP_ST0
) == 0)
1056 sc
->error
&= ~TP_ST0MASK
;
1057 if ((sc
->error
& TP_ST1
) == 0)
1058 sc
->error
&= ~TP_ST1MASK
;
1059 sc
->error
&= ~ignore
; /* ignore certain errors */
1060 error
= sc
->error
& (TP_FIL
| TP_BNL
| TP_UDA
| TP_EOM
| TP_WRP
|
1061 TP_USL
| TP_CNI
| TP_MBD
| TP_NDT
| TP_ILL
);
1067 /* lifted from tdriver.c from Wangtek */
1069 msg
= "Drive not online";
1070 else if (error
& TP_CNI
)
1071 msg
= "No cartridge";
1072 else if ((error
& TP_WRP
) && (sc
->flags
& TPWP
) == 0) {
1073 msg
= "Tape is write protected";
1075 } else if (error
& TP_FIL
)
1076 msg
= 0 /*"Filemark detected"*/;
1077 else if (error
& TP_EOM
)
1078 msg
= 0 /*"End of tape"*/;
1079 else if (error
& TP_BNL
)
1080 msg
= "Block not located";
1081 else if (error
& TP_UDA
)
1082 msg
= "Unrecoverable data error";
1083 else if (error
& TP_NDT
)
1084 msg
= "No data detected";
1085 else if (error
& TP_ILL
)
1086 msg
= "Illegal command";
1088 printf("%s: %s\n", device_xname(&sc
->sc_dev
), msg
);
1093 * Get controller status information.
1096 wtstatus(struct wt_softc
*sc
)
1098 bus_space_tag_t iot
= sc
->sc_iot
;
1099 bus_space_handle_t ioh
= sc
->sc_ioh
;
1104 wtsoft(sc
, sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
,
1105 sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
); /* ready? */
1106 /* send `read status' command */
1107 bus_space_write_1(iot
, ioh
, sc
->regs
.CMDPORT
, QIC_RDSTAT
);
1110 bus_space_write_1(iot
, ioh
, sc
->regs
.CTLPORT
,
1111 sc
->regs
.REQUEST
| sc
->regs
.ONLINE
);
1113 /* wait for ready */
1114 wtsoft(sc
, sc
->regs
.BUSY
, sc
->regs
.BUSY
);
1116 bus_space_write_1(iot
, ioh
, sc
->regs
.CTLPORT
, sc
->regs
.ONLINE
);
1118 /* wait for not ready */
1119 wtsoft(sc
, sc
->regs
.BUSY
, 0);
1121 p
= (char *)&sc
->error
;
1122 while (p
< (char *)&sc
->error
+ 6) {
1123 u_char x
= wtsoft(sc
, sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
,
1124 sc
->regs
.BUSY
| sc
->regs
.NOEXCEP
);
1126 if ((x
& sc
->regs
.NOEXCEP
) == 0) { /* error */
1131 /* read status byte */
1132 *p
++ = bus_space_read_1(iot
, ioh
, sc
->regs
.DATAPORT
);
1135 bus_space_write_1(iot
, ioh
, sc
->regs
.CTLPORT
,
1136 sc
->regs
.REQUEST
| sc
->regs
.ONLINE
);
1138 /* wait for not ready */
1139 wtsoft(sc
, sc
->regs
.BUSY
, 0);
1142 bus_space_write_1(iot
, ioh
, sc
->regs
.CTLPORT
, sc
->regs
.ONLINE
);