xref: /netbsd-src/sys/dev/gpib/mt.c (revision d710132b4b8ce7f7cccaaf660cb16aa16b4077a0)
1 /*	$NetBSD: mt.c,v 1.1 2003/06/02 03:52:24 gmcgarry Exp $ */
2 
3 /*-
4  * Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the NetBSD
21  *	Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Copyright (c) 1988 University of Utah.
41  * Copyright (c) 1982, 1990, 1993
42  *	The Regents of the University of California.  All rights reserved.
43  *
44  * This code is derived from software contributed to Berkeley by
45  * the Systems Programming Group of the University of Utah Computer
46  * Science Department.
47  *
48  * Redistribution and use in source and binary forms, with or without
49  * modification, are permitted provided that the following conditions
50  * are met:
51  * 1. Redistributions of source code must retain the above copyright
52  *    notice, this list of conditions and the following disclaimer.
53  * 2. Redistributions in binary form must reproduce the above copyright
54  *    notice, this list of conditions and the following disclaimer in the
55  *    documentation and/or other materials provided with the distribution.
56  * 3. All advertising materials mentioning features or use of this software
57  *    must display the following acknowledgement:
58  *	This product includes software developed by the University of
59  *	California, Berkeley and its contributors.
60  * 4. Neither the name of the University nor the names of its contributors
61  *    may be used to endorse or promote products derived from this software
62  *    without specific prior written permission.
63  *
64  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74  * SUCH DAMAGE.
75  *
76  * from: Utah $Hdr: rd.c 1.44 92/12/26$
77  *
78  *	@(#)rd.c	8.2 (Berkeley) 5/19/94
79  */
80 
81 /*
82  * Magnetic tape driver (HP7974a, HP7978a/b, HP7979a, HP7980a, HP7980xc)
83  * Original version contributed by Mt. Xinu.
84  * Modified for 4.4BSD by Mark Davies and Andrew Vignaux, Department of
85  * Computer Science, Victoria University of Wellington
86  */
87 
88 #include <sys/cdefs.h>
89 __KERNEL_RCSID(0, "$NetBSD: mt.c,v 1.1 2003/06/02 03:52:24 gmcgarry Exp $");
90 
91 #include <sys/param.h>
92 #include <sys/systm.h>
93 #include <sys/callout.h>
94 #include <sys/buf.h>
95 #include <sys/ioctl.h>
96 #include <sys/mtio.h>
97 #include <sys/file.h>
98 #include <sys/proc.h>
99 #include <sys/tty.h>
100 #include <sys/kernel.h>
101 #include <sys/tprintf.h>
102 #include <sys/device.h>
103 #include <sys/conf.h>
104 
105 #include <dev/gpib/gpibvar.h>
106 #include <dev/gpib/cs80busvar.h>
107 
108 #include <dev/gpib/mtreg.h>
109 
110 #ifdef DEBUG
111 int	mtdebug = 0;
112 #define MDB_ANY		0xff
113 #define MDB_FOLLOW	0x01
114 #define	DPRINTF(mask, str)	if (mtdebug & (mask)) printf str
115 #else
116 #define	DPRINTF(mask, str)	/* nothing */
117 #endif
118 
119 struct	mt_softc {
120 	struct	device sc_dev;
121 
122 	gpib_chipset_tag_t sc_ic;
123 	gpib_handle_t sc_hdl;
124 
125 	int	sc_slave;	/* GPIB slave address (0-6) */
126 	short	sc_flags;	/* see below */
127 	u_char	sc_lastdsj;	/* place for DSJ in mtreaddsj() */
128 	u_char	sc_lastecmd;	/* place for End Command in mtreaddsj() */
129 	short	sc_recvtimeo;	/* count of gpibsend timeouts to prevent hang */
130 	short	sc_statindex;	/* index for next sc_stat when MTF_STATTIMEO */
131 	struct	mt_stat sc_stat;/* status bytes last read from device */
132 	short	sc_density;	/* current density of tape (mtio.h format) */
133 	short	sc_type;	/* tape drive model (hardware IDs) */
134 	tpr_t	sc_ttyp;
135 	struct bufq_state sc_tab;/* buf queue */
136 	int	sc_active;
137 	struct buf sc_bufstore;	/* XXX buffer storage */
138 
139 	struct	callout sc_start_ch;
140 	struct	callout sc_intr_ch;
141 };
142 
143 #define	MTUNIT(x)	(minor(x) & 0x03)
144 
145 #define B_CMD		B_XXX		/* command buf instead of data */
146 #define	b_cmd		b_blkno		/* blkno holds cmd when B_CMD */
147 
148 int	mtmatch(struct device *, struct cfdata *, void *);
149 void	mtattach(struct device *, struct device *, void *);
150 
151 CFATTACH_DECL(mt, sizeof(struct mt_softc),
152 	mtmatch, mtattach, NULL, NULL);
153 
154 int	mtlookup(int, int, int);
155 void	mtustart(struct mt_softc *);
156 int	mtreaddsj(struct mt_softc *, int);
157 int	mtcommand(dev_t, int, int);
158 
159 void	mtintr_callout(void *);
160 void	mtstart_callout(void *);
161 
162 void	mtcallback(void *, int);
163 void	mtstart(struct mt_softc *);
164 void	mtintr(struct mt_softc  *);
165 
166 dev_type_open(mtopen);
167 dev_type_close(mtclose);
168 dev_type_read(mtread);
169 dev_type_write(mtwrite);
170 dev_type_ioctl(mtioctl);
171 dev_type_strategy(mtstrategy);
172 
173 const struct bdevsw mt_bdevsw = {
174 	mtopen, mtclose, mtstrategy, mtioctl, nodump, nosize, D_TAPE
175 };
176 
177 const struct cdevsw mt_cdevsw = {
178 	mtopen, mtclose, mtread, mtwrite, mtioctl,
179 	nostop, notty, nopoll, nommap, nokqfilter, D_TAPE
180 };
181 
182 
183 extern struct cfdriver mt_cd;
184 
185 struct	mtinfo {
186 	u_short	hwid;
187 	char	*desc;
188 } mtinfo[] = {
189 	{ MT7978ID,	"7978"	},
190 	{ MT7979AID,	"7979A"	},
191 	{ MT7980ID,	"7980"	},
192 	{ MT7974AID,	"7974A"	},
193 };
194 int	nmtinfo = sizeof(mtinfo) / sizeof(mtinfo[0]);
195 
196 
197 int
198 mtlookup(id, slave, punit)
199 	int id;
200 	int slave;
201 	int punit;
202 {
203 	int i;
204 
205 	for (i = 0; i < nmtinfo; i++)
206 		if (mtinfo[i].hwid == id)
207 			break;
208 	if (i == nmtinfo)
209 		return (-1);
210 	return (0);
211 }
212 
213 int
214 mtmatch(parent, match, aux)
215 	struct device *parent;
216 	struct cfdata *match;
217 	void *aux;
218 {
219 	struct cs80bus_attach_args *ca = aux;
220 
221 	ca->ca_punit = 0;
222 	return (mtlookup(ca->ca_id, ca->ca_slave, ca->ca_punit) == 0);
223 }
224 
225 void
226 mtattach(parent, self, aux)
227 	struct device *parent, *self;
228 	void *aux;
229 {
230 	struct mt_softc *sc = (struct mt_softc *)self;
231 	struct cs80bus_attach_args *ca = aux;
232 	int type;
233 
234 	sc->sc_ic = ca->ca_ic;
235 	sc->sc_slave = ca->ca_slave;
236 
237 	if ((type = mtlookup(ca->ca_id, ca->ca_slave, ca->ca_punit)) < 0)
238 		return;
239 
240 	printf(": %s tape\n", mtinfo[type].desc);
241 
242 	sc->sc_type = type;
243 	sc->sc_flags = MTF_EXISTS;
244 
245 	bufq_alloc(&sc->sc_tab, BUFQ_FCFS);
246 	callout_init(&sc->sc_start_ch);
247 	callout_init(&sc->sc_intr_ch);
248 
249 	if (gpibregister(sc->sc_ic, sc->sc_slave, mtcallback, sc,
250 	    &sc->sc_hdl)) {
251 		printf("%s: can't register callback\n", sc->sc_dev.dv_xname);
252 		return;
253 	}
254 }
255 
256 /*
257  * Perform a read of "Device Status Jump" register and update the
258  * status if necessary.  If status is read, the given "ecmd" is also
259  * performed, unless "ecmd" is zero.  Returns DSJ value, -1 on failure
260  * and -2 on "temporary" failure.
261  */
262 int
263 mtreaddsj(sc, ecmd)
264 	struct mt_softc *sc;
265 	int ecmd;
266 {
267 	int retval;
268 
269 	if (sc->sc_flags & MTF_STATTIMEO)
270 		goto getstats;
271 	retval = gpibrecv(sc->sc_ic,
272 	    (sc->sc_flags & MTF_DSJTIMEO) ? -1 : sc->sc_slave,
273 	    MTT_DSJ, &(sc->sc_lastdsj), 1);
274 	sc->sc_flags &= ~MTF_DSJTIMEO;
275 	if (retval != 1) {
276 		DPRINTF(MDB_ANY, ("%s can't gpibrecv DSJ",
277 		    sc->sc_dev.dv_xname));
278 		if (sc->sc_recvtimeo == 0)
279 			sc->sc_recvtimeo = hz;
280 		if (--sc->sc_recvtimeo == 0)
281 			return (-1);
282 		if (retval == 0)
283 			sc->sc_flags |= MTF_DSJTIMEO;
284 		return (-2);
285 	}
286 	sc->sc_recvtimeo = 0;
287 	sc->sc_statindex = 0;
288 	DPRINTF(MDB_ANY, ("%s readdsj: 0x%x", sc->sc_dev.dv_xname,
289 	    sc->sc_lastdsj));
290 	sc->sc_lastecmd = ecmd;
291 	switch (sc->sc_lastdsj) {
292 	    case 0:
293 		if (ecmd & MTE_DSJ_FORCE)
294 			break;
295 		return (0);
296 
297 	    case 2:
298 		sc->sc_lastecmd = MTE_COMPLETE;
299 	    case 1:
300 		break;
301 
302 	    default:
303 		printf("%s readdsj: DSJ 0x%x\n", sc->sc_dev.dv_xname,
304 		    sc->sc_lastdsj);
305 		return (-1);
306 	}
307 
308 getstats:
309 	retval = gpibrecv(sc->sc_ic,
310 	    (sc->sc_flags & MTF_STATCONT) ? -1 : sc->sc_slave, MTT_STAT,
311 	     ((char *)&(sc->sc_stat)) + sc->sc_statindex,
312 	    sizeof(sc->sc_stat) - sc->sc_statindex);
313 	sc->sc_flags &= ~(MTF_STATTIMEO | MTF_STATCONT);
314 	if (retval != sizeof(sc->sc_stat) - sc->sc_statindex) {
315 		if (sc->sc_recvtimeo == 0)
316 			sc->sc_recvtimeo = hz;
317 		if (--sc->sc_recvtimeo != 0) {
318 			if (retval >= 0) {
319 				sc->sc_statindex += retval;
320 				sc->sc_flags |= MTF_STATCONT;
321 			}
322 			sc->sc_flags |= MTF_STATTIMEO;
323 			return (-2);
324 		}
325 		printf("%s readdsj: can't read status", sc->sc_dev.dv_xname);
326 		return (-1);
327 	}
328 	sc->sc_recvtimeo = 0;
329 	sc->sc_statindex = 0;
330 	DPRINTF(MDB_ANY, ("%s readdsj: status is %x %x %x %x %x %x",
331 	    sc->sc_dev.dv_xname,
332 	    sc->sc_stat1, sc->sc_stat2, sc->sc_stat3,
333 	    sc->sc_stat4, sc->sc_stat5, sc->sc_stat6));
334 	if (sc->sc_lastecmd)
335 		(void) gpibsend(sc->sc_ic, sc->sc_slave,
336 		    MTL_ECMD, &(sc->sc_lastecmd), 1);
337 	return ((int) sc->sc_lastdsj);
338 }
339 
340 int
341 mtopen(dev, flag, mode, p)
342 	dev_t dev;
343 	int flag, mode;
344 	struct proc *p;
345 {
346 	struct mt_softc *sc;
347 	int req_den;
348 	int error;
349 
350 	sc = device_lookup(&mt_cd, MTUNIT(dev));
351 	if (sc == NULL || (sc->sc_flags & MTF_EXISTS) == 0)
352 		return (ENXIO);
353 
354 	if (sc->sc_flags & MTF_OPEN)
355 		return (EBUSY);
356 
357 	DPRINTF(MDB_ANY, ("%s open: flags 0x%x", sc->sc_dev.dv_xname,
358 	    sc->sc_flags));
359 
360 	sc->sc_flags |= MTF_OPEN;
361 	sc->sc_ttyp = tprintf_open(p);
362 	if ((sc->sc_flags & MTF_ALIVE) == 0) {
363 		error = mtcommand(dev, MTRESET, 0);
364 		if (error != 0 || (sc->sc_flags & MTF_ALIVE) == 0)
365 			goto errout;
366 		if ((sc->sc_stat1 & (SR1_BOT | SR1_ONLINE)) == SR1_ONLINE)
367 			(void) mtcommand(dev, MTREW, 0);
368 	}
369 	for (;;) {
370 		if ((error = mtcommand(dev, MTNOP, 0)) != 0)
371 			goto errout;
372 		if (!(sc->sc_flags & MTF_REW))
373 			break;
374 		if (tsleep((caddr_t) &lbolt, PCATCH | (PZERO + 1),
375 		    "mt", 0) != 0) {
376 			error = EINTR;
377 			goto errout;
378 		}
379 	}
380 	if ((flag & FWRITE) && (sc->sc_stat1 & SR1_RO)) {
381 		error = EROFS;
382 		goto errout;
383 	}
384 	if (!(sc->sc_stat1 & SR1_ONLINE)) {
385 		uprintf("%s: not online\n", sc->sc_dev.dv_xname);
386 		error = EIO;
387 		goto errout;
388 	}
389 	/*
390 	 * Select density:
391 	 *  - find out what density the drive is set to
392 	 *	(i.e. the density of the current tape)
393 	 *  - if we are going to write
394 	 *    - if we're not at the beginning of the tape
395 	 *      - complain if we want to change densities
396 	 *    - otherwise, select the mtcommand to set the density
397 	 *
398 	 * If the drive doesn't support it then don't change the recorded
399 	 * density.
400 	 *
401 	 * The original MOREbsd code had these additional conditions
402 	 * for the mid-tape change
403 	 *
404 	 *	req_den != T_BADBPI &&
405 	 *	sc->sc_density != T_6250BPI
406 	 *
407 	 * which suggests that it would be possible to write multiple
408 	 * densities if req_den == T_BAD_BPI or the current tape
409 	 * density was 6250.  Testing of our 7980 suggests that the
410 	 * device cannot change densities mid-tape.
411 	 *
412 	 * ajv@comp.vuw.ac.nz
413 	 */
414 	sc->sc_density = (sc->sc_stat2 & SR2_6250) ? T_6250BPI : (
415 			 (sc->sc_stat3 & SR3_1600) ? T_1600BPI : (
416 			 (sc->sc_stat3 & SR3_800) ? T_800BPI : -1));
417 	req_den = (dev & T_DENSEL);
418 
419 	if (flag & FWRITE) {
420 		if (!(sc->sc_stat1 & SR1_BOT)) {
421 			if (sc->sc_density != req_den) {
422 				uprintf("%s: can't change density mid-tape\n",
423 				    sc->sc_dev.dv_xname);
424 				error = EIO;
425 				goto errout;
426 			}
427 		}
428 		else {
429 			int mtset_density =
430 			    (req_den == T_800BPI  ? MTSET800BPI : (
431 			     req_den == T_1600BPI ? MTSET1600BPI : (
432 			     req_den == T_6250BPI ? MTSET6250BPI : (
433 			     sc->sc_type == MT7980ID
434 						  ? MTSET6250DC
435 						  : MTSET6250BPI))));
436 			if (mtcommand(dev, mtset_density, 0) == 0)
437 				sc->sc_density = req_den;
438 		}
439 	}
440 	return (0);
441 errout:
442 	sc->sc_flags &= ~MTF_OPEN;
443 	return (error);
444 }
445 
446 int
447 mtclose(dev, flag, fmt, p)
448 	dev_t dev;
449 	int flag, fmt;
450 	struct proc *p;
451 {
452 	struct mt_softc *sc;
453 
454 	sc = device_lookup(&mt_cd, MTUNIT(dev));
455 	if (sc == NULL)
456 		return (ENXIO);
457 
458 	if (sc->sc_flags & MTF_WRT) {
459 		(void) mtcommand(dev, MTWEOF, 2);
460 		(void) mtcommand(dev, MTBSF, 0);
461 	}
462 	if ((minor(dev) & T_NOREWIND) == 0)
463 		(void) mtcommand(dev, MTREW, 0);
464 	sc->sc_flags &= ~MTF_OPEN;
465 	tprintf_close(sc->sc_ttyp);
466 	return (0);
467 }
468 
469 int
470 mtcommand(dev, cmd, cnt)
471 	dev_t dev;
472 	int cmd;
473 	int cnt;
474 {
475 	struct mt_softc *sc;
476 	struct buf *bp;
477 	int error = 0;
478 
479 	sc = device_lookup(&mt_cd, MTUNIT(dev));
480 	bp = &sc->sc_bufstore;
481 
482 	if (bp->b_flags & B_BUSY)
483 		return (EBUSY);
484 
485 	bp->b_cmd = cmd;
486 	bp->b_dev = dev;
487 	do {
488 		bp->b_flags = B_BUSY | B_CMD;
489 		mtstrategy(bp);
490 		biowait(bp);
491 		if (bp->b_flags & B_ERROR) {
492 			error = (int) (unsigned) bp->b_error;
493 			break;
494 		}
495 	} while (--cnt > 0);
496 #if 0
497 	bp->b_flags = 0 /*&= ~B_BUSY*/;
498 #else
499 	bp->b_flags &= ~B_BUSY;
500 #endif
501 	return (error);
502 }
503 
504 /*
505  * Only thing to check here is for legal record lengths (writes only).
506  */
507 void
508 mtstrategy(bp)
509 	struct buf *bp;
510 {
511 	struct mt_softc *sc;
512 	int s;
513 
514 	sc = device_lookup(&mt_cd, MTUNIT(bp->b_dev));
515 
516 	DPRINTF(MDB_ANY, ("%s strategy", sc->sc_dev.dv_xname));
517 
518 	if ((bp->b_flags & (B_CMD | B_READ)) == 0) {
519 #define WRITE_BITS_IGNORED	8
520 #if 0
521 		if (bp->b_bcount & ((1 << WRITE_BITS_IGNORED) - 1)) {
522 			tprintf(sc->sc_ttyp,
523 				"%s: write record must be multiple of %d\n",
524 				sc->sc_dev.dv_xname, 1 << WRITE_BITS_IGNORED);
525 			goto error;
526 		}
527 #endif
528 		s = 16 * 1024;
529 		if (sc->sc_stat2 & SR2_LONGREC) {
530 			switch (sc->sc_density) {
531 			    case T_1600BPI:
532 				s = 32 * 1024;
533 				break;
534 
535 			    case T_6250BPI:
536 			    case T_BADBPI:
537 				s = 60 * 1024;
538 				break;
539 			}
540 		}
541 		if (bp->b_bcount > s) {
542 			tprintf(sc->sc_ttyp,
543 				"%s: write record (%ld) too big: limit (%d)\n",
544 				sc->sc_dev.dv_xname, bp->b_bcount, s);
545 #if 0 /* XXX see above */
546 	    error:
547 #endif
548 			bp->b_flags |= B_ERROR;
549 			bp->b_error = EIO;
550 			biodone(bp);
551 			return;
552 		}
553 	}
554 	s = splbio();
555 	BUFQ_PUT(&sc->sc_tab, bp);
556 	if (sc->sc_active == 0) {
557 		sc->sc_active = 1;
558 		mtustart(sc);
559 	}
560 	splx(s);
561 }
562 
563 void
564 mtustart(sc)
565 	struct mt_softc *sc;
566 {
567 
568 	DPRINTF(MDB_ANY, ("%s ustart", sc->sc_dev.dv_xname));
569 	if (gpibrequest(sc->sc_ic, sc->sc_hdl))
570 		mtstart(sc);
571 }
572 
573 void
574 mtcallback(v, action)
575 	void *v;
576 	int action;
577 {
578 	struct mt_softc *sc = v;
579 
580 	DPRINTF(MDB_FOLLOW, ("mtcallback: v=%p, action=%d\n", v, action));
581 
582 	switch (action) {
583 	case GPIBCBF_START:
584 		mtstart(sc);
585 		break;
586 	case GPIBCBF_INTR:
587 		mtintr(sc);
588 		break;
589 #ifdef DEBUG
590 	default:
591 		printf("mtcallback: unknown action %d\n", action);
592 		break;
593 #endif
594 	}
595 }
596 
597 void
598 mtintr_callout(arg)
599 	void *arg;
600 {
601 	struct mt_softc *sc = arg;
602 	int s = splbio();
603 
604 	gpibppclear(sc->sc_ic);
605 	mtintr(sc);
606 	splx(s);
607 }
608 
609 void
610 mtstart_callout(arg)
611 	void *arg;
612 {
613 	int s = splbio();
614 
615 	mtstart((struct mt_softc *)arg);
616 	splx(s);
617 }
618 
619 void
620 mtstart(sc)
621 	struct mt_softc *sc;
622 {
623 	struct buf *bp;
624 	short	cmdcount = 1;
625 	u_char	cmdbuf[2];
626 
627 	DPRINTF(MDB_ANY, ("%s start", sc->sc_dev.dv_xname));
628 	sc->sc_flags &= ~MTF_WRT;
629 	bp = BUFQ_PEEK(&sc->sc_tab);
630 	if ((sc->sc_flags & MTF_ALIVE) == 0 &&
631 	    ((bp->b_flags & B_CMD) == 0 || bp->b_cmd != MTRESET))
632 		goto fatalerror;
633 
634 	if (sc->sc_flags & MTF_REW) {
635 		if (!gpibpptest(sc->sc_ic, sc->sc_slave))
636 			goto stillrew;
637 		switch (mtreaddsj(sc, MTE_DSJ_FORCE|MTE_COMPLETE|MTE_IDLE)) {
638 		    case 0:
639 		    case 1:
640 		stillrew:
641 			if ((sc->sc_stat1 & SR1_BOT) ||
642 			    !(sc->sc_stat1 & SR1_ONLINE)) {
643 				sc->sc_flags &= ~MTF_REW;
644 				break;
645 			}
646 		    case -2:
647 			/*
648 			 * -2 means "timeout" reading DSJ, which is probably
649 			 * temporary.  This is considered OK when doing a NOP,
650 			 * but not otherwise.
651 			 */
652 			if (sc->sc_flags & (MTF_DSJTIMEO | MTF_STATTIMEO)) {
653 				callout_reset(&sc->sc_start_ch, hz >> 5,
654 				    mtstart_callout, sc);
655 				return;
656 			}
657 		    case 2:
658 			if (bp->b_cmd != MTNOP || !(bp->b_flags & B_CMD)) {
659 				bp->b_error = EBUSY;
660 				goto errdone;
661 			}
662 			goto done;
663 
664 		    default:
665 			goto fatalerror;
666 		}
667 	}
668 	if (bp->b_flags & B_CMD) {
669 		if (sc->sc_flags & MTF_PASTEOT) {
670 			switch(bp->b_cmd) {
671 			    case MTFSF:
672 			    case MTWEOF:
673 			    case MTFSR:
674 				bp->b_error = ENOSPC;
675 				goto errdone;
676 
677 			    case MTBSF:
678 			    case MTOFFL:
679 			    case MTBSR:
680 			    case MTREW:
681 				sc->sc_flags &= ~(MTF_PASTEOT | MTF_ATEOT);
682 				break;
683 			}
684 		}
685 		switch(bp->b_cmd) {
686 		    case MTFSF:
687 			if (sc->sc_flags & MTF_HITEOF)
688 				goto done;
689 			cmdbuf[0] = MTTC_FSF;
690 			break;
691 
692 		    case MTBSF:
693 			if (sc->sc_flags & MTF_HITBOF)
694 				goto done;
695 			cmdbuf[0] = MTTC_BSF;
696 			break;
697 
698 		    case MTOFFL:
699 			sc->sc_flags |= MTF_REW;
700 			cmdbuf[0] = MTTC_REWOFF;
701 			break;
702 
703 		    case MTWEOF:
704 			cmdbuf[0] = MTTC_WFM;
705 			break;
706 
707 		    case MTBSR:
708 			cmdbuf[0] = MTTC_BSR;
709 			break;
710 
711 		    case MTFSR:
712 			cmdbuf[0] = MTTC_FSR;
713 			break;
714 
715 		    case MTREW:
716 			sc->sc_flags |= MTF_REW;
717 			cmdbuf[0] = MTTC_REW;
718 			break;
719 
720 		    case MTNOP:
721 			/*
722 			 * NOP is supposed to set status bits.
723 			 * Force readdsj to do it.
724 			 */
725 			switch (mtreaddsj(sc,
726 			  MTE_DSJ_FORCE | MTE_COMPLETE | MTE_IDLE)) {
727 			    default:
728 				goto done;
729 
730 			    case -1:
731 				/*
732 				 * If this fails, perform a device clear
733 				 * to fix any protocol problems and (most
734 				 * likely) get the status.
735 				 */
736 				bp->b_cmd = MTRESET;
737 				break;
738 
739 			    case -2:
740 				callout_reset(&sc->sc_start_ch, hz >> 5,
741 				    mtstart_callout, sc);
742 				return;
743 			}
744 
745 		    case MTRESET:
746 			/*
747 			 * 1) selected device clear (send with "-2" secondary)
748 			 * 2) set timeout, then wait for "service request"
749 			 * 3) interrupt will read DSJ (and END COMPLETE-IDLE)
750 			 */
751 			if (gpibsend(sc->sc_ic, sc->sc_slave, -2, NULL, 0)){
752 				printf("%s can't reset", sc->sc_dev.dv_xname);
753 				goto fatalerror;
754 			}
755 			callout_reset(&sc->sc_intr_ch, 4*hz, mtintr_callout,
756 			    sc);
757 			gpibawait(sc->sc_ic);
758 			return;
759 
760 		    case MTSET800BPI:
761 			cmdbuf[0] = MTTC_800;
762 			break;
763 
764 		    case MTSET1600BPI:
765 			cmdbuf[0] = MTTC_1600;
766 			break;
767 
768 		    case MTSET6250BPI:
769 			cmdbuf[0] = MTTC_6250;
770 			break;
771 
772 		    case MTSET6250DC:
773 			cmdbuf[0] = MTTC_DC6250;
774 			break;
775 		}
776 	} else {
777 		if (sc->sc_flags & MTF_PASTEOT) {
778 			bp->b_error = ENOSPC;
779 			goto errdone;
780 		}
781 		if (bp->b_flags & B_READ) {
782 			sc->sc_flags |= MTF_IO;
783 			cmdbuf[0] = MTTC_READ;
784 		} else {
785 			sc->sc_flags |= MTF_WRT | MTF_IO;
786 			cmdbuf[0] = MTTC_WRITE;
787 			cmdbuf[1] = (bp->b_bcount +((1 << WRITE_BITS_IGNORED) - 1)) >> WRITE_BITS_IGNORED;
788 			cmdcount = 2;
789 		}
790 	}
791 	if (gpibsend(sc->sc_ic, sc->sc_slave, MTL_TCMD, cmdbuf, cmdcount)
792 	    == cmdcount) {
793 		if (sc->sc_flags & MTF_REW)
794 			goto done;
795 		gpibawait(sc->sc_ic);
796 		return;
797 	}
798 fatalerror:
799 	/*
800 	 * If anything fails, the drive is probably hosed, so mark it not
801 	 * "ALIVE" (but it EXISTS and is OPEN or we wouldn't be here, and
802 	 * if, last we heard, it was REWinding, remember that).
803 	 */
804 	sc->sc_flags &= MTF_EXISTS | MTF_OPEN | MTF_REW;
805 	bp->b_error = EIO;
806 errdone:
807 	bp->b_flags |= B_ERROR;
808 done:
809 	sc->sc_flags &= ~(MTF_HITEOF | MTF_HITBOF);
810 	(void)BUFQ_GET(&sc->sc_tab);
811 	biodone(bp);
812 	gpibrelease(sc->sc_ic, sc->sc_hdl);
813 	if ((bp = BUFQ_PEEK(&sc->sc_tab)) == NULL)
814 		sc->sc_active = 0;
815 	else
816 		mtustart(sc);
817 }
818 
819 void
820 mtintr(sc)
821 	struct mt_softc *sc;
822 {
823 	struct buf *bp;
824 	int slave, dir, i;
825 	u_char cmdbuf[4];
826 
827 	slave = sc->sc_slave;
828 
829 	bp = BUFQ_PEEK(&sc->sc_tab);
830 	if (bp == NULL) {
831 		printf("%s intr: bp == NULL", sc->sc_dev.dv_xname);
832 		return;
833 	}
834 
835 	DPRINTF(MDB_ANY, ("%s intr", sc->sc_dev.dv_xname));
836 
837 	/*
838 	 * Some operation completed.  Read status bytes and report errors.
839 	 * Clear EOF flags here `cause they're set once on specific conditions
840 	 * below when a command succeeds.
841 	 * A DSJ of 2 always means keep waiting.  If the command was READ
842 	 * (and we're in data DMA phase) stop data transfer first.
843 	 */
844 	sc->sc_flags &= ~(MTF_HITEOF | MTF_HITBOF);
845 	if ((bp->b_flags & (B_CMD|B_READ)) == B_READ &&
846 	    !(sc->sc_flags & (MTF_IO | MTF_STATTIMEO | MTF_DSJTIMEO))){
847 		cmdbuf[0] = MTE_STOP;
848 		(void) gpibsend(sc->sc_ic, slave, MTL_ECMD,cmdbuf,1);
849 	}
850 	switch (mtreaddsj(sc, 0)) {
851 	    case 0:
852 		break;
853 
854 	    case 1:
855 		/*
856 		 * If we're in the middle of a READ/WRITE and have yet to
857 		 * start the data transfer, a DSJ of one should terminate it.
858 		 */
859 		sc->sc_flags &= ~MTF_IO;
860 		break;
861 
862 	    case 2:
863 		(void) gpibawait(sc->sc_ic);
864 		return;
865 
866 	    case -2:
867 		/*
868 		 * -2 means that the drive failed to respond quickly enough
869 		 * to the request for DSJ.  It's probably just "busy" figuring
870 		 * it out and will know in a little bit...
871 		 */
872 		callout_reset(&sc->sc_intr_ch, hz >> 5, mtintr_callout, sc);
873 		return;
874 
875 	    default:
876 		printf("%s intr: can't get drive stat", sc->sc_dev.dv_xname);
877 		goto error;
878 	}
879 	if (sc->sc_stat1 & (SR1_ERR | SR1_REJECT)) {
880 		i = sc->sc_stat4 & SR4_ERCLMASK;
881 		printf("%s: %s error, retry %d, SR2/3 %x/%x, code %d",
882 			sc->sc_dev.dv_xname, i == SR4_DEVICE ? "device" :
883 			(i == SR4_PROTOCOL ? "protocol" :
884 			(i == SR4_SELFTEST ? "selftest" : "unknown")),
885 			sc->sc_stat4 & SR4_RETRYMASK, sc->sc_stat2,
886 			sc->sc_stat3, sc->sc_stat5);
887 
888 		if ((bp->b_flags & B_CMD) && bp->b_cmd == MTRESET)
889 			callout_stop(&sc->sc_intr_ch);
890 		if (sc->sc_stat3 & SR3_POWERUP)
891 			sc->sc_flags &= MTF_OPEN | MTF_EXISTS;
892 		goto error;
893 	}
894 	/*
895 	 * Report and clear any soft errors.
896 	 */
897 	if (sc->sc_stat1 & SR1_SOFTERR) {
898 		printf("%s: soft error, retry %d\n", sc->sc_dev.dv_xname,
899 		    sc->sc_stat4 & SR4_RETRYMASK);
900 		sc->sc_stat1 &= ~SR1_SOFTERR;
901 	}
902 	/*
903 	 * We've initiated a read or write, but haven't actually started to
904 	 * DMA the data yet.  At this point, the drive's ready.
905 	 */
906 	if (sc->sc_flags & MTF_IO) {
907 		sc->sc_flags &= ~MTF_IO;
908 		dir = (bp->b_flags & B_READ ? GPIB_READ : GPIB_WRITE);
909 		gpibxfer(sc->sc_ic, slave,
910 		    dir == GPIB_READ ? MTT_READ : MTL_WRITE,
911 		    bp->b_data, bp->b_bcount, dir, dir == GPIB_READ);
912 		return;
913 	}
914 	/*
915 	 * Check for End Of Tape - we're allowed to hit EOT and then write (or
916 	 * read) one more record.  If we get here and have not already hit EOT,
917 	 * return ENOSPC to inform the process that it's hit it.  If we get
918 	 * here and HAVE already hit EOT, don't allow any more operations that
919 	 * move the tape forward.
920 	 */
921 	if (sc->sc_stat1 & SR1_EOT) {
922 		if (sc->sc_flags & MTF_ATEOT)
923 			sc->sc_flags |= MTF_PASTEOT;
924 		else {
925 			bp->b_flags |= B_ERROR;
926 			bp->b_error = ENOSPC;
927 			sc->sc_flags |= MTF_ATEOT;
928 		}
929 	}
930 	/*
931 	 * If a motion command was being executed, check for Tape Marks.
932 	 * If we were doing data, make sure we got the right amount, and
933 	 * check for hitting tape marks on reads.
934 	 */
935 	if (bp->b_flags & B_CMD) {
936 		if (sc->sc_stat1 & SR1_EOF) {
937 			if (bp->b_cmd == MTFSR)
938 				sc->sc_flags |= MTF_HITEOF;
939 			if (bp->b_cmd == MTBSR)
940 				sc->sc_flags |= MTF_HITBOF;
941 		}
942 		if (bp->b_cmd == MTRESET) {
943 			callout_stop(&sc->sc_intr_ch);
944 			sc->sc_flags |= MTF_ALIVE;
945 		}
946 	} else {
947 		i = gpibrecv(sc->sc_ic, slave, MTT_BCNT, cmdbuf, 2);
948 		if (i != 2) {
949 			printf("%s intr: can't get xfer length\n",
950 			    sc->sc_dev.dv_xname);
951 			goto error;
952 		}
953 		i = (int) *((u_short *) cmdbuf);
954 		if (i <= bp->b_bcount) {
955 			if (i == 0)
956 				sc->sc_flags |= MTF_HITEOF;
957 			bp->b_resid = bp->b_bcount - i;
958 			DPRINTF(MDB_ANY, ("%s intr: bcount %ld, resid %ld",
959 			    sc->sc_dev.dv_xname, bp->b_bcount, bp->b_resid));
960 		} else {
961 			tprintf(sc->sc_ttyp,
962 				"%s: record (%d) larger than wanted (%ld)\n",
963 				sc->sc_dev.dv_xname, i, bp->b_bcount);
964 error:
965 			sc->sc_flags &= ~MTF_IO;
966 			bp->b_error = EIO;
967 			bp->b_flags |= B_ERROR;
968 		}
969 	}
970 	/*
971 	 * The operation is completely done.
972 	 * Let the drive know with an END command.
973 	 */
974 	cmdbuf[0] = MTE_COMPLETE | MTE_IDLE;
975 	(void) gpibsend(sc->sc_ic, slave, MTL_ECMD, cmdbuf, 1);
976 	bp->b_flags &= ~B_CMD;
977 	(void)BUFQ_GET(&sc->sc_tab);
978 	biodone(bp);
979 	gpibrelease(sc->sc_ic, sc->sc_hdl);
980 	if (BUFQ_PEEK(&sc->sc_tab) == NULL)
981 		sc->sc_active = 0;
982 	else
983 		mtustart(sc);
984 }
985 
986 int
987 mtread(dev, uio, flags)
988 	dev_t dev;
989 	struct uio *uio;
990 	int flags;
991 {
992 	struct mt_softc *sc;
993 
994 	sc = device_lookup(&mt_cd, MTUNIT(dev));
995 
996 	return (physio(mtstrategy, &sc->sc_bufstore,
997 	    dev, B_READ, minphys, uio));
998 }
999 
1000 int
1001 mtwrite(dev, uio, flags)
1002 	dev_t dev;
1003 	struct uio *uio;
1004 	int flags;
1005 {
1006 	struct mt_softc *sc;
1007 
1008 	sc = device_lookup(&mt_cd, MTUNIT(dev));
1009 
1010 	return (physio(mtstrategy, &sc->sc_bufstore,
1011 	    dev, B_WRITE, minphys, uio));
1012 }
1013 
1014 int
1015 mtioctl(dev, cmd, data, flag, p)
1016 	dev_t dev;
1017 	u_long cmd;
1018 	caddr_t data;
1019 	int flag;
1020 	struct proc *p;
1021 {
1022 	struct mtop *op;
1023 	int cnt;
1024 
1025 	switch (cmd) {
1026 	    case MTIOCTOP:
1027 		op = (struct mtop *)data;
1028 		switch(op->mt_op) {
1029 		    case MTWEOF:
1030 		    case MTFSF:
1031 		    case MTBSR:
1032 		    case MTBSF:
1033 		    case MTFSR:
1034 			cnt = op->mt_count;
1035 			break;
1036 
1037 		    case MTOFFL:
1038 		    case MTREW:
1039 		    case MTNOP:
1040 			cnt = 0;
1041 			break;
1042 
1043 		    default:
1044 			return (EINVAL);
1045 		}
1046 		return (mtcommand(dev, op->mt_op, cnt));
1047 
1048 	    case MTIOCGET:
1049 		break;
1050 
1051 	    default:
1052 		return (EINVAL);
1053 	}
1054 	return (0);
1055 }
1056