1/*	$NetBSD: wt.c,v 1.81 2009/05/12 08:44:20 cegger Exp $	*/
2
3/*
4 * Streamer tape driver.
5 * Supports Archive and Wangtek compatible QIC-02/QIC-36 boards.
6 *
7 * Copyright (C) 1993 by:
8 *	Sergey Ryzhkov <sir@kiae.su>
9 *	Serge Vakulenko <vak@zebub.msk.su>
10 *
11 * This software is distributed with NO WARRANTIES, not even the implied
12 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
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.
17 *
18 * This driver is derived from the old 386bsd Wangtek streamer tape driver,
19 * made by Robert Baron at CMU, based on Intel sources.
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@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/cdefs.h>
54__KERNEL_RCSID(0, "$NetBSD: wt.c,v 1.81 2009/05/12 08:44:20 cegger Exp $");
55
56#include <sys/param.h>
57#include <sys/systm.h>
58#include <sys/callout.h>
59#include <sys/kernel.h>
60#include <sys/buf.h>
61#include <sys/fcntl.h>
62#include <sys/malloc.h>
63#include <sys/ioctl.h>
64#include <sys/mtio.h>
65#include <sys/device.h>
66#include <sys/proc.h>
67#include <sys/lwp.h>
68#include <sys/conf.h>
69
70#include <sys/intr.h>
71#include <sys/bus.h>
72#include <machine/pio.h>
73
74#include <dev/isa/isavar.h>
75#include <dev/isa/isadmavar.h>
76#include <dev/isa/wtreg.h>
77
78/*
79 * Uncomment this to enable internal device tracing.
80 */
81#define WTDBPRINT(x)		/* printf x */
82
83#define WTPRI			(PZERO+10)	/* sleep priority */
84
85#define WT_NPORT		2		/* 2 i/o ports */
86#define AV_NPORT		4		/* 4 i/o ports */
87
88enum wttype {
89	UNKNOWN = 0,	/* unknown type, driver disabled */
90	ARCHIVE,	/* Archive Viper SC499, SC402 etc */
91	WANGTEK,	/* Wangtek */
92};
93
94static 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 */
112} wtregs = {
113	1, 1, 0, 0, 0, 0,
114	0x01, 0x02, 0x07, 0x05,
115	0x01, 0x02, 0x04, 0x08
116}, avregs = {
117	0, 0, 1, 1, 2, 3,
118	0x40, 0x20, 0xf8, 0x50,
119	0, 0x80, 0x40, 0x20
120};
121
122struct wt_softc {
123	struct device sc_dev;
124	void *sc_ih;
125
126	bus_space_tag_t		sc_iot;
127	bus_space_handle_t	sc_ioh;
128	isa_chipset_tag_t	sc_ic;
129
130	callout_t		sc_timer_ch;
131
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 */
138
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 */
143
144	u_short error;		/* code for error encountered */
145	u_short ercnt;		/* number of error blocks */
146	u_short urcnt;		/* number of underruns */
147
148	struct wtregs regs;
149};
150
151static dev_type_open(wtopen);
152static dev_type_close(wtclose);
153static dev_type_read(wtread);
154static dev_type_write(wtwrite);
155static dev_type_ioctl(wtioctl);
156static dev_type_strategy(wtstrategy);
157static dev_type_dump(wtdump);
158static dev_type_size(wtsize);
159
160const struct bdevsw wt_bdevsw = {
161	wtopen, wtclose, wtstrategy, wtioctl, wtdump, wtsize, D_TAPE
162};
163
164const struct cdevsw wt_cdevsw = {
165	wtopen, wtclose, wtread, wtwrite, wtioctl,
166	nostop, notty, nopoll, nommap, nokqfilter, D_TAPE
167};
168
169static int	wtwait(struct wt_softc *sc, int catch, const char *msg);
170static int	wtcmd(struct wt_softc *sc, int cmd);
171static int	wtstart(struct wt_softc *sc, int flag, void *vaddr, size_t len);
172static void	wtdma(struct wt_softc *sc);
173static void	wttimer(void *arg);
174static void	wtclock(struct wt_softc *sc);
175static int	wtreset(bus_space_tag_t, bus_space_handle_t, struct wtregs *);
176static int	wtsense(struct wt_softc *sc, int verbose, int ignore);
177static int	wtstatus(struct wt_softc *sc);
178static void	wtrewind(struct wt_softc *sc);
179static int	wtreadfm(struct wt_softc *sc);
180static int	wtwritefm(struct wt_softc *sc);
181static u_char	wtsoft(struct wt_softc *sc, int mask, int bits);
182static int	wtintr(void *sc);
183
184int	wtprobe(device_t, cfdata_t, void *);
185void	wtattach(device_t, device_t, void *);
186
187CFATTACH_DECL(wt, sizeof(struct wt_softc),
188    wtprobe, wtattach, NULL, NULL);
189
190extern struct cfdriver wt_cd;
191
192/*
193 * Probe for the presence of the device.
194 */
195int
196wtprobe(device_t parent, cfdata_t match, void *aux)
197{
198	struct isa_attach_args *ia = aux;
199	bus_space_tag_t iot = ia->ia_iot;
200	bus_space_handle_t ioh;
201	int rv = 0, iosize;
202
203	if (ia->ia_nio < 1)
204		return (0);
205	if (ia->ia_nirq < 1)
206		return (0);
207	if (ia->ia_ndrq < 1)
208		return (0);
209
210	/* Disallow wildcarded i/o address. */
211	if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
212		return (0);
213	if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ)
214		return (0);
215
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);
219		return (0);
220	}
221
222	iosize = AV_NPORT;
223
224	/* Map i/o space */
225	if (bus_space_map(iot, ia->ia_io[0].ir_addr, iosize, 0, &ioh))
226		return 0;
227
228	/* Try Wangtek. */
229	if (wtreset(iot, ioh, &wtregs)) {
230		iosize = WT_NPORT; /* XXX misleading */
231		rv = 1;
232		goto done;
233	}
234
235	/* Try Archive. */
236	if (wtreset(iot, ioh, &avregs)) {
237		iosize = AV_NPORT;
238		rv = 1;
239		goto done;
240	}
241
242done:
243	if (rv) {
244		ia->ia_nio = 1;
245		ia->ia_io[0].ir_size = iosize;
246
247		ia->ia_nirq = 1;
248		ia->ia_ndrq = 1;
249
250		ia->ia_niomem = 0;
251	}
252	bus_space_unmap(iot, ioh, AV_NPORT);
253	return rv;
254}
255
256/*
257 * Device is found, configure it.
258 */
259void
260wtattach(device_t parent, device_t self, void *aux)
261{
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;
266	bus_size_t maxsize;
267
268	/* Map i/o space */
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");
271		return;
272	}
273
274	sc->sc_iot = iot;
275	sc->sc_ioh = ioh;
276	sc->sc_ic = ia->ia_ic;
277
278	callout_init(&sc->sc_timer_ch, 0);
279
280	/* Try Wangtek. */
281	if (wtreset(iot, ioh, &wtregs)) {
282		sc->type = WANGTEK;
283		memcpy(&sc->regs, &wtregs, sizeof(sc->regs));
284		printf(": type <Wangtek>\n");
285		goto ok;
286	}
287
288	/* Try Archive. */
289	if (wtreset(iot, ioh, &avregs)) {
290		sc->type = ARCHIVE;
291		memcpy(&sc->regs, &avregs, sizeof(sc->regs));
292		printf(": type <Archive>\n");
293		/* Reset DMA. */
294		bus_space_write_1(iot, ioh, sc->regs.RDMAPORT, 0);
295		goto ok;
296	}
297
298	/* what happened? */
299	aprint_error_dev(self, "lost controller\n");
300	return;
301
302ok:
303	sc->flags = TPSTART;		/* tape is rewound */
304	sc->dens = -1;			/* unknown density */
305
306	sc->chan = ia->ia_drq[0].ir_drq;
307
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);
311		return;
312	}
313
314	if (isa_drq_alloc(sc->sc_ic, sc->chan) != 0) {
315		aprint_error_dev(&sc->sc_dev, "can't reserve drq %d\n",
316		    sc->chan);
317		return;
318	}
319
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");
323		return;
324	}
325
326	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
327	    IST_EDGE, IPL_BIO, wtintr, sc);
328}
329
330static int
331wtdump(dev_t dev, daddr_t blkno, void *va,
332    size_t size)
333{
334
335	/* Not implemented. */
336	return ENXIO;
337}
338
339static int
340wtsize(dev_t dev)
341{
342
343	/* Not implemented. */
344	return -1;
345}
346
347/*
348 * Open routine, called on every device open.
349 */
350static int
351wtopen(dev_t dev, int flag, int mode, struct lwp *l)
352{
353	int unit = minor(dev) & T_UNIT;
354	struct wt_softc *sc;
355	int error;
356
357	sc = device_lookup_private(&wt_cd, unit);
358	if (sc == NULL)
359		return (ENXIO);
360
361	/* Check that device is not in use */
362	if (sc->flags & TPINUSE)
363		return EBUSY;
364
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)
369			return error;
370
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))
375				return EIO;
376			if (!wtsense(sc, 1, (flag & FWRITE) ? 0 : TP_WRP))
377				return EIO;
378		}
379
380		/* Set up tape density. */
381		if (sc->dens != (minor(dev) & WT_DENSEL)) {
382			int d = 0;
383
384			switch (minor(dev) & WT_DENSEL) {
385			case WT_DENSDFLT:
386			default:
387				break;			/* default density */
388			case WT_QIC11:
389				d = QIC_FMT11;  break;	/* minor 010 */
390			case WT_QIC24:
391				d = QIC_FMT24;  break;	/* minor 020 */
392			case WT_QIC120:
393				d = QIC_FMT120; break;	/* minor 030 */
394			case WT_QIC150:
395				d = QIC_FMT150; break;	/* minor 040 */
396			case WT_QIC300:
397				d = QIC_FMT300; break;	/* minor 050 */
398			case WT_QIC600:
399				d = QIC_FMT600; break;	/* minor 060 */
400			}
401			if (d) {
402				/* Change tape density. */
403				if (!wtcmd(sc, d))
404					return EIO;
405				if (!wtsense(sc, 1, TP_WRP | TP_ILL))
406					return EIO;
407
408				/* Check the status of the controller. */
409				if (sc->error & TP_ILL) {
410					aprint_error_dev(&sc->sc_dev, "invalid tape density\n");
411					return ENODEV;
412				}
413			}
414			sc->dens = minor(dev) & WT_DENSEL;
415		}
416		sc->flags &= ~TPSTART;
417	} else if (sc->dens != (minor(dev) & WT_DENSEL))
418		return ENXIO;
419
420	sc->bsize = (minor(dev) & WT_BSIZE) ? 1024 : 512;
421	sc->buf = malloc(sc->bsize, M_TEMP, M_WAITOK);
422
423	sc->flags = TPINUSE;
424	if (flag & FREAD)
425		sc->flags |= TPREAD;
426	if (flag & FWRITE)
427		sc->flags |= TPWRITE;
428	return 0;
429}
430
431/*
432 * Close routine, called on last device close.
433 */
434static int
435wtclose(dev_t dev, int flags, int mode,
436    struct lwp *l)
437{
438	struct wt_softc *sc;
439
440	sc = device_lookup_private(&wt_cd, minor(dev) & T_UNIT);
441
442	/* If rewind is pending, do nothing */
443	if (sc->flags & TPREW)
444		goto done;
445
446	/* If seek forward is pending and no rewind on close, do nothing */
447	if (sc->flags & TPRMARK) {
448		if (minor(dev) & T_NOREWIND)
449			goto done;
450
451		/* If read file mark is going on, wait */
452		wtwait(sc, 0, "wtrfm");
453	}
454
455	if (sc->flags & TPWANY) {
456		/* Tape was written.  Write file mark. */
457		wtwritefm(sc);
458	}
459
460	if ((minor(dev) & T_NOREWIND) == 0) {
461		/* Rewind to beginning of tape. */
462		/* Don't wait until rewind, though. */
463		wtrewind(sc);
464		goto done;
465	}
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. */
469		wtreadfm(sc);
470	}
471
472done:
473	sc->flags &= TPREW | TPRMARK | TPSTART | TPTIMER;
474	free(sc->buf, M_TEMP);
475	return 0;
476}
477
478/*
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
485 */
486static int
487wtioctl(dev_t dev, unsigned long cmd, void *addr, int flag,
488    struct lwp *l)
489{
490	struct wt_softc *sc;
491	int error, count, op;
492
493	sc = device_lookup_private(&wt_cd, minor(dev) & T_UNIT);
494
495	switch (cmd) {
496	default:
497		return EINVAL;
498	case WTQICMD:	/* direct QIC command */
499		op = *(int *)addr;
500		switch (op) {
501		default:
502			return EINVAL;
503		case QIC_ERASE:		/* erase the whole tape */
504			if ((sc->flags & TPWRITE) == 0 || (sc->flags & TPWP))
505				return EACCES;
506			if ((error = wtwait(sc, PCATCH, "wterase")) != 0)
507				return error;
508			break;
509		case QIC_RETENS:	/* retension the tape */
510			if ((error = wtwait(sc, PCATCH, "wtretens")) != 0)
511				return error;
512			break;
513		}
514		/* Both ERASE and RETENS operations work like REWIND. */
515		/* Simulate the rewind operation here. */
516		sc->flags &= ~(TPRO | TPWO | TPVOL);
517		if (!wtcmd(sc, op))
518			return EIO;
519		sc->flags |= TPSTART | TPREW;
520		if (op == QIC_ERASE)
521			sc->flags |= TPWANY;
522		wtclock(sc);
523		return 0;
524	case MTIOCIEOT:	/* ignore EOT errors */
525	case MTIOCEEOT:	/* enable EOT errors */
526		return 0;
527	case MTIOCGET:
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 */
535		return 0;
536	case MTIOCTOP:
537		break;
538	}
539
540	switch ((short)((struct mtop*)addr)->mt_op) {
541	default:
542#if 0
543	case MTFSR:	/* forward space record */
544	case MTBSR:	/* backward space record */
545	case MTBSF:	/* backward space file */
546#endif
547		return EINVAL;
548	case MTNOP:	/* no operation, sets status only */
549	case MTCACHE:	/* enable controller cache */
550	case MTNOCACHE:	/* disable controller cache */
551		return 0;
552	case MTREW:	/* rewind */
553	case MTOFFL:	/* rewind and put the drive offline */
554		if (sc->flags & TPREW)   /* rewind is running */
555			return 0;
556		if ((error = wtwait(sc, PCATCH, "wtorew")) != 0)
557			return error;
558		wtrewind(sc);
559		return 0;
560	case MTFSF:	/* forward space file */
561		for (count = ((struct mtop*)addr)->mt_count; count > 0;
562		    --count) {
563			if ((error = wtwait(sc, PCATCH, "wtorfm")) != 0)
564				return error;
565			if ((error = wtreadfm(sc)) != 0)
566				return error;
567		}
568		return 0;
569	case MTWEOF:	/* write an end-of-file record */
570		if ((sc->flags & TPWRITE) == 0 || (sc->flags & TPWP))
571			return EACCES;
572		if ((error = wtwait(sc, PCATCH, "wtowfm")) != 0)
573			return error;
574		if ((error = wtwritefm(sc)) != 0)
575			return error;
576		return 0;
577	}
578
579#ifdef DIAGNOSTIC
580	panic("wtioctl: impossible");
581#endif
582}
583
584/*
585 * Strategy routine.
586 */
587static void
588wtstrategy(struct buf *bp)
589{
590	struct wt_softc *sc;
591	int s;
592
593	sc = device_lookup_private(&wt_cd, minor(bp->b_dev) & T_UNIT);
594
595	bp->b_resid = bp->b_bcount;
596
597	/* at file marks and end of tape, we just return '0 bytes available' */
598	if (sc->flags & TPVOL)
599		goto xit;
600
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))
604			goto errxit;
605
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)) {
610				/* Clear status. */
611				goto errxit;
612			}
613			if (!wtcmd(sc, QIC_RDDATA)) {
614				/* Set read mode. */
615				wtsense(sc, 1, TP_WRP);
616				goto errxit;
617			}
618			sc->flags |= TPRO | TPRANY;
619		}
620	} else {
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)))
624			goto errxit;
625
626		/* If write command outstanding, just skip down */
627		if ((sc->flags & TPWO) == 0) {
628			if (!wtsense(sc, 1, 0)) {
629				/* Clear status. */
630				goto errxit;
631			}
632			if (!wtcmd(sc, QIC_WRTDATA)) {
633				/* Set write mode. */
634				wtsense(sc, 1, 0);
635				goto errxit;
636			}
637			sc->flags |= TPWO | TPWANY;
638		}
639	}
640
641	if (bp->b_bcount == 0)
642		goto xit;
643
644	sc->flags &= ~TPEXCEP;
645	s = splbio();
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;
649	}
650	splx(s);
651
652	if (sc->flags & TPEXCEP) {
653errxit:
654		bp->b_error = EIO;
655	}
656xit:
657	biodone(bp);
658	return;
659}
660
661static int
662wtread(dev_t dev, struct uio *uio, int flags)
663{
664
665	return (physio(wtstrategy, NULL, dev, B_READ, minphys, uio));
666}
667
668static int
669wtwrite(dev_t dev, struct uio *uio, int flags)
670{
671
672	return (physio(wtstrategy, NULL, dev, B_WRITE, minphys, uio));
673}
674
675/*
676 * Interrupt routine.
677 */
678static int
679wtintr(void *arg)
680{
681	struct wt_softc *sc = arg;
682	u_char x;
683
684	/* get status */
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 */
691	}
692
693	/*
694	 * Check if rewind finished.
695	 */
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);
702		wakeup((void *)sc);
703		return 1;
704	}
705
706	/*
707	 * Check if writing/reading of file mark finished.
708	 */
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 */
716		wakeup((void *)sc);
717		return 1;
718	}
719
720	/*
721	 * Do we started any i/o?  If no, just return.
722	 */
723	if ((sc->flags & TPACTIVE) == 0) {
724		WTDBPRINT(("unexpected interrupt\n"));
725		return 0;
726	}
727	sc->flags &= ~TPACTIVE;
728	sc->dmacount += sc->bsize;		/* increment counter */
729
730	/*
731	 * Clean up DMA.
732	 */
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);
739	} else
740		isa_dmadone(sc->sc_ic, sc->chan);
741
742	/*
743	 * On exception, check for end of file and end of volume.
744	 */
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 */
750		else
751			sc->flags |= TPEXCEP;	/* i/o error */
752		wakeup((void *)sc);
753		return 1;
754	}
755
756	if (sc->dmacount < sc->dmatotal) {
757		/* Continue I/O. */
758		sc->dmavaddr = (char *)sc->dmavaddr + sc->bsize;
759		wtdma(sc);
760		WTDBPRINT(("continue i/o, %d\n", sc->dmacount));
761		return 1;
762	}
763	if (sc->dmacount > sc->dmatotal)	/* short last block */
764		sc->dmacount = sc->dmatotal;
765	/* Wake up user level. */
766	wakeup((void *)sc);
767	WTDBPRINT(("i/o finished, %d\n", sc->dmacount));
768	return 1;
769}
770
771/* start the rewind operation */
772static void
773wtrewind(struct wt_softc *sc)
774{
775	int rwmode = sc->flags & (TPRO | TPWO);
776
777	sc->flags &= ~(TPRO | TPWO | TPVOL);
778	/*
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.
783	 */
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))
787		return;
788	sc->flags |= TPSTART | TPREW;
789	wtclock(sc);
790}
791
792/*
793 * Start the `read marker' operation.
794 */
795static int
796wtreadfm(struct wt_softc *sc)
797{
798
799	sc->flags &= ~(TPRO | TPWO | TPVOL);
800	if (!wtcmd(sc, QIC_READFM)) {
801		wtsense(sc, 1, TP_WRP);
802		return EIO;
803	}
804	sc->flags |= TPRMARK | TPRANY;
805	wtclock(sc);
806	/* Don't wait for completion here. */
807	return 0;
808}
809
810/*
811 * Write marker to the tape.
812 */
813static int
814wtwritefm(struct wt_softc *sc)
815{
816
817	tsleep((void *)wtwritefm, WTPRI, "wtwfm", hz);
818	sc->flags &= ~(TPRO | TPWO);
819	if (!wtcmd(sc, QIC_WRITEFM)) {
820		wtsense(sc, 1, 0);
821		return EIO;
822	}
823	sc->flags |= TPWMARK | TPWANY;
824	wtclock(sc);
825	return wtwait(sc, 0, "wtwfm");
826}
827
828/*
829 * While controller status & mask == bits continue waiting.
830 */
831static u_char
832wtsoft(struct wt_softc *sc, int mask, int bits)
833{
834	bus_space_tag_t iot = sc->sc_iot;
835	bus_space_handle_t ioh = sc->sc_ioh;
836	u_char x;
837	int i;
838
839
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)
844			return x;
845		delay(1);
846	}
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)
850			return x;
851		delay(100);
852	}
853	for (;;) {			/* forever */
854		x = bus_space_read_1(iot, ioh, sc->regs.STATPORT);
855		if ((x & mask) != bits)
856			return x;
857		tsleep((void *)wtsoft, WTPRI, "wtsoft", 1);
858	}
859}
860
861/*
862 * Execute QIC command.
863 */
864static int
865wtcmd(struct wt_softc *sc, int cmd)
866{
867	bus_space_tag_t iot = sc->sc_iot;
868	bus_space_handle_t ioh = sc->sc_ioh;
869	u_char x;
870	int s;
871
872	WTDBPRINT(("wtcmd() cmd=0x%x\n", cmd));
873	s = splbio();
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 */
877		splx(s);
878		return 0;
879	}
880
881	/* output the command */
882	bus_space_write_1(iot, ioh, sc->regs.CMDPORT, cmd);
883
884	/* set request */
885	bus_space_write_1(iot, ioh, sc->regs.CTLPORT,
886			  sc->regs.REQUEST | sc->regs.ONLINE);
887
888	/* wait for ready */
889	wtsoft(sc, sc->regs.BUSY, sc->regs.BUSY);
890
891	/* reset request */
892	bus_space_write_1(iot, ioh, sc->regs.CTLPORT,
893			  sc->regs.IEN | sc->regs.ONLINE);
894
895	/* wait for not ready */
896	wtsoft(sc, sc->regs.BUSY, 0);
897	splx(s);
898	return 1;
899}
900
901/* wait for the end of i/o, seeking marker or rewind operation */
902static int
903wtwait(struct wt_softc *sc, int catch, const char *msg)
904{
905	int error;
906
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)
910			return error;
911	return 0;
912}
913
914/* initialize DMA for the i/o operation */
915static void
916wtdma(struct wt_softc *sc)
917{
918	bus_space_tag_t iot = sc->sc_iot;
919	bus_space_handle_t ioh = sc->sc_ioh;
920
921	sc->flags |= TPACTIVE;
922	wtclock(sc);
923
924	if (sc->type == ARCHIVE) {
925		/* Set DMA. */
926		bus_space_write_1(iot, ioh, sc->regs.SDMAPORT, 0);
927	}
928
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);
934	} else
935		isa_dmastart(sc->sc_ic, sc->chan, sc->dmavaddr,
936		    sc->bsize, NULL, sc->dmaflags, BUS_DMA_NOWAIT);
937}
938
939/* start i/o operation */
940static int
941wtstart(struct wt_softc *sc, int flag, void *vaddr, size_t len)
942{
943	u_char x;
944
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 */
950		return 0;
951	}
952	sc->flags &= ~TPEXCEP;		/* clear exception flag */
953	sc->dmavaddr = vaddr;
954	sc->dmatotal = len;
955	sc->dmacount = 0;
956	sc->dmaflags = flag & B_READ ? DMAMODE_READ : DMAMODE_WRITE;
957	wtdma(sc);
958	return 1;
959}
960
961/*
962 * Start timer.
963 */
964static void
965wtclock(struct wt_softc *sc)
966{
967
968	if (sc->flags & TPTIMER)
969		return;
970	sc->flags |= TPTIMER;
971	/*
972	 * Some controllers seem to lose DMA interrupts too often.  To make the
973	 * tape stream we need 1 tick timeout.
974	 */
975	callout_reset(&sc->sc_timer_ch, (sc->flags & TPACTIVE) ? 1 : hz,
976	    wttimer, sc);
977}
978
979/*
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.
983 */
984static void
985wttimer(void *arg)
986{
987	register struct wt_softc *sc = (struct wt_softc *)arg;
988	int s;
989	u_char status;
990
991	sc->flags &= ~TPTIMER;
992	if ((sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK)) == 0)
993		return;
994
995	/* If i/o going, simulate interrupt. */
996	s = splbio();
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() -- "));
1001		wtintr(sc);
1002	}
1003	splx(s);
1004
1005	/* Restart timer if i/o pending. */
1006	if (sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK))
1007		wtclock(sc);
1008}
1009
1010/*
1011 * Perform QIC-02 and QIC-36 compatible reset sequence.
1012 */
1013static int
1014wtreset(bus_space_tag_t iot, bus_space_handle_t ioh, struct wtregs *regs)
1015{
1016	u_char x;
1017	int i;
1018
1019	/* send reset */
1020	bus_space_write_1(iot, ioh, regs->CTLPORT, regs->RESET | regs->ONLINE);
1021	delay(30);
1022	/* turn off reset */
1023	bus_space_write_1(iot, ioh, regs->CTLPORT, regs->ONLINE);
1024	delay(30);
1025
1026	/* Read the controller status. */
1027	x = bus_space_read_1(iot, ioh, regs->STATPORT);
1028	if (x == 0xff)			/* no port at this address? */
1029		return 0;
1030
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)
1034			break;
1035		delay(1000);
1036		x = bus_space_read_1(iot, ioh, regs->STATPORT);
1037	}
1038	return (x & regs->RESETMASK) == regs->RESETVAL;
1039}
1040
1041/*
1042 * Get controller status information.  Return 0 if user i/o request should
1043 * receive an i/o error code.
1044 */
1045static int
1046wtsense(struct wt_softc *sc, int verbose, int ignore)
1047{
1048	const char *msg = 0;
1049	int error;
1050
1051	WTDBPRINT(("wtsense() ignore=0x%x\n", ignore));
1052	sc->flags &= ~(TPRO | TPWO);
1053	if (!wtstatus(sc))
1054		return 0;
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);
1062	if (!error)
1063		return 1;
1064	if (!verbose)
1065		return 0;
1066
1067	/* lifted from tdriver.c from Wangtek */
1068	if (error & TP_USL)
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";
1074		sc->flags |= TPWP;
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";
1087	if (msg)
1088		printf("%s: %s\n", device_xname(&sc->sc_dev), msg);
1089	return 0;
1090}
1091
1092/*
1093 * Get controller status information.
1094 */
1095static int
1096wtstatus(struct wt_softc *sc)
1097{
1098	bus_space_tag_t iot = sc->sc_iot;
1099	bus_space_handle_t ioh = sc->sc_ioh;
1100	char *p;
1101	int s;
1102
1103	s = splbio();
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);
1108
1109	/* set request */
1110	bus_space_write_1(iot, ioh, sc->regs.CTLPORT,
1111			  sc->regs.REQUEST | sc->regs.ONLINE);
1112
1113	/* wait for ready */
1114	wtsoft(sc, sc->regs.BUSY, sc->regs.BUSY);
1115	/* reset request */
1116	bus_space_write_1(iot, ioh, sc->regs.CTLPORT, sc->regs.ONLINE);
1117
1118	/* wait for not ready */
1119	wtsoft(sc, sc->regs.BUSY, 0);
1120
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);
1125
1126		if ((x & sc->regs.NOEXCEP) == 0) {	/* error */
1127			splx(s);
1128			return 0;
1129		}
1130
1131		/* read status byte */
1132		*p++ = bus_space_read_1(iot, ioh, sc->regs.DATAPORT);
1133
1134		/* set request */
1135		bus_space_write_1(iot, ioh, sc->regs.CTLPORT,
1136		    sc->regs.REQUEST | sc->regs.ONLINE);
1137
1138		/* wait for not ready */
1139		wtsoft(sc, sc->regs.BUSY, 0);
1140
1141		/* unset request */
1142		bus_space_write_1(iot, ioh, sc->regs.CTLPORT, sc->regs.ONLINE);
1143	}
1144	splx(s);
1145	return 1;
1146}
1147