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