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