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