mt.c revision 1.13 1 /* $NetBSD: mt.c,v 1.13 2008/04/08 07:38:35 cegger 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.13 2008/04/08 07:38:35 cegger 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_DEVPRIVATE /* 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 const 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 = device_private(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, 0);
283 callout_init(&sc->sc_intr_ch, 0);
284
285 if (gpibregister(sc->sc_ic, sc->sc_slave, mtcallback, sc,
286 &sc->sc_hdl)) {
287 aprint_error_dev(&sc->sc_dev, "can't register callback\n");
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 device_xname(&sc->sc_dev)));
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", device_xname(&sc->sc_dev),
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", device_xname(&sc->sc_dev),
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", device_xname(&sc->sc_dev));
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 device_xname(&sc->sc_dev),
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, l)
378 dev_t dev;
379 int flag, mode;
380 struct lwp *l;
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", device_xname(&sc->sc_dev),
394 sc->sc_flags));
395
396 sc->sc_flags |= MTF_OPEN;
397 sc->sc_ttyp = tprintf_open(l->l_proc);
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((void *) &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", device_xname(&sc->sc_dev));
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 device_xname(&sc->sc_dev));
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, l)
484 dev_t dev;
485 int flag, fmt;
486 struct lwp *l;
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_cflags & BC_BUSY)
519 return (EBUSY);
520
521 bp->b_cmd = cmd;
522 bp->b_dev = dev;
523 bp->b_objlock = &buffer_lock;
524 do {
525 bp->b_cflags = BC_BUSY;
526 bp->b_flags = B_CMD;
527 bp->b_oflags = 0;
528 mtstrategy(bp);
529 biowait(bp);
530 if (bp->b_error != 0) {
531 error = (int) (unsigned) bp->b_error;
532 break;
533 }
534 } while (--cnt > 0);
535 #if 0
536 bp->b_cflags = 0 /*&= ~BC_BUSY*/;
537 #else
538 bp->b_cflags &= ~BC_BUSY;
539 #endif
540 return (error);
541 }
542
543 /*
544 * Only thing to check here is for legal record lengths (writes only).
545 */
546 void
547 mtstrategy(bp)
548 struct buf *bp;
549 {
550 struct mt_softc *sc;
551 int s;
552
553 sc = device_lookup(&mt_cd, MTUNIT(bp->b_dev));
554
555 DPRINTF(MDB_ANY, ("%s strategy", device_xname(&sc->sc_dev)));
556
557 if ((bp->b_flags & (B_CMD | B_READ)) == 0) {
558 #define WRITE_BITS_IGNORED 8
559 #if 0
560 if (bp->b_bcount & ((1 << WRITE_BITS_IGNORED) - 1)) {
561 tprintf(sc->sc_ttyp,
562 "%s: write record must be multiple of %d\n",
563 device_xname(&sc->sc_dev), 1 << WRITE_BITS_IGNORED);
564 goto error;
565 }
566 #endif
567 s = 16 * 1024;
568 if (sc->sc_stat2 & SR2_LONGREC) {
569 switch (sc->sc_density) {
570 case T_1600BPI:
571 s = 32 * 1024;
572 break;
573
574 case T_6250BPI:
575 case T_BADBPI:
576 s = 60 * 1024;
577 break;
578 }
579 }
580 if (bp->b_bcount > s) {
581 tprintf(sc->sc_ttyp,
582 "%s: write record (%d) too big: limit (%d)\n",
583 device_xname(&sc->sc_dev), bp->b_bcount, s);
584 #if 0 /* XXX see above */
585 error:
586 #endif
587 bp->b_error = EIO;
588 biodone(bp);
589 return;
590 }
591 }
592 s = splbio();
593 BUFQ_PUT(sc->sc_tab, bp);
594 if (sc->sc_active == 0) {
595 sc->sc_active = 1;
596 mtustart(sc);
597 }
598 splx(s);
599 }
600
601 void
602 mtustart(sc)
603 struct mt_softc *sc;
604 {
605
606 DPRINTF(MDB_ANY, ("%s ustart", device_xname(&sc->sc_dev)));
607 if (gpibrequest(sc->sc_ic, sc->sc_hdl))
608 mtstart(sc);
609 }
610
611 void
612 mtcallback(v, action)
613 void *v;
614 int action;
615 {
616 struct mt_softc *sc = v;
617
618 DPRINTF(MDB_FOLLOW, ("mtcallback: v=%p, action=%d\n", v, action));
619
620 switch (action) {
621 case GPIBCBF_START:
622 mtstart(sc);
623 break;
624 case GPIBCBF_INTR:
625 mtintr(sc);
626 break;
627 #ifdef DEBUG
628 default:
629 printf("mtcallback: unknown action %d\n", action);
630 break;
631 #endif
632 }
633 }
634
635 void
636 mtintr_callout(arg)
637 void *arg;
638 {
639 struct mt_softc *sc = arg;
640 int s = splbio();
641
642 gpibppclear(sc->sc_ic);
643 mtintr(sc);
644 splx(s);
645 }
646
647 void
648 mtstart_callout(arg)
649 void *arg;
650 {
651 int s = splbio();
652
653 mtstart((struct mt_softc *)arg);
654 splx(s);
655 }
656
657 void
658 mtstart(sc)
659 struct mt_softc *sc;
660 {
661 struct buf *bp;
662 short cmdcount = 1;
663 u_char cmdbuf[2];
664
665 DPRINTF(MDB_ANY, ("%s start", device_xname(&sc->sc_dev)));
666 sc->sc_flags &= ~MTF_WRT;
667 bp = BUFQ_PEEK(sc->sc_tab);
668 if ((sc->sc_flags & MTF_ALIVE) == 0 &&
669 ((bp->b_flags & B_CMD) == 0 || bp->b_cmd != MTRESET))
670 goto fatalerror;
671
672 if (sc->sc_flags & MTF_REW) {
673 if (!gpibpptest(sc->sc_ic, sc->sc_slave))
674 goto stillrew;
675 switch (mtreaddsj(sc, MTE_DSJ_FORCE|MTE_COMPLETE|MTE_IDLE)) {
676 case 0:
677 case 1:
678 stillrew:
679 if ((sc->sc_stat1 & SR1_BOT) ||
680 !(sc->sc_stat1 & SR1_ONLINE)) {
681 sc->sc_flags &= ~MTF_REW;
682 break;
683 }
684 case -2:
685 /*
686 * -2 means "timeout" reading DSJ, which is probably
687 * temporary. This is considered OK when doing a NOP,
688 * but not otherwise.
689 */
690 if (sc->sc_flags & (MTF_DSJTIMEO | MTF_STATTIMEO)) {
691 callout_reset(&sc->sc_start_ch, hz >> 5,
692 mtstart_callout, sc);
693 return;
694 }
695 case 2:
696 if (bp->b_cmd != MTNOP || !(bp->b_flags & B_CMD)) {
697 bp->b_error = EBUSY;
698 goto done;
699 }
700 goto done;
701
702 default:
703 goto fatalerror;
704 }
705 }
706 if (bp->b_flags & B_CMD) {
707 if (sc->sc_flags & MTF_PASTEOT) {
708 switch(bp->b_cmd) {
709 case MTFSF:
710 case MTWEOF:
711 case MTFSR:
712 bp->b_error = ENOSPC;
713 goto done;
714
715 case MTBSF:
716 case MTOFFL:
717 case MTBSR:
718 case MTREW:
719 sc->sc_flags &= ~(MTF_PASTEOT | MTF_ATEOT);
720 break;
721 }
722 }
723 switch(bp->b_cmd) {
724 case MTFSF:
725 if (sc->sc_flags & MTF_HITEOF)
726 goto done;
727 cmdbuf[0] = MTTC_FSF;
728 break;
729
730 case MTBSF:
731 if (sc->sc_flags & MTF_HITBOF)
732 goto done;
733 cmdbuf[0] = MTTC_BSF;
734 break;
735
736 case MTOFFL:
737 sc->sc_flags |= MTF_REW;
738 cmdbuf[0] = MTTC_REWOFF;
739 break;
740
741 case MTWEOF:
742 cmdbuf[0] = MTTC_WFM;
743 break;
744
745 case MTBSR:
746 cmdbuf[0] = MTTC_BSR;
747 break;
748
749 case MTFSR:
750 cmdbuf[0] = MTTC_FSR;
751 break;
752
753 case MTREW:
754 sc->sc_flags |= MTF_REW;
755 cmdbuf[0] = MTTC_REW;
756 break;
757
758 case MTNOP:
759 /*
760 * NOP is supposed to set status bits.
761 * Force readdsj to do it.
762 */
763 switch (mtreaddsj(sc,
764 MTE_DSJ_FORCE | MTE_COMPLETE | MTE_IDLE)) {
765 default:
766 goto done;
767
768 case -1:
769 /*
770 * If this fails, perform a device clear
771 * to fix any protocol problems and (most
772 * likely) get the status.
773 */
774 bp->b_cmd = MTRESET;
775 break;
776
777 case -2:
778 callout_reset(&sc->sc_start_ch, hz >> 5,
779 mtstart_callout, sc);
780 return;
781 }
782
783 case MTRESET:
784 /*
785 * 1) selected device clear (send with "-2" secondary)
786 * 2) set timeout, then wait for "service request"
787 * 3) interrupt will read DSJ (and END COMPLETE-IDLE)
788 */
789 if (gpibsend(sc->sc_ic, sc->sc_slave, -2, NULL, 0)){
790 aprint_error_dev(&sc->sc_dev, "can't reset");
791 goto fatalerror;
792 }
793 callout_reset(&sc->sc_intr_ch, 4*hz, mtintr_callout,
794 sc);
795 gpibawait(sc->sc_ic);
796 return;
797
798 case MTSET800BPI:
799 cmdbuf[0] = MTTC_800;
800 break;
801
802 case MTSET1600BPI:
803 cmdbuf[0] = MTTC_1600;
804 break;
805
806 case MTSET6250BPI:
807 cmdbuf[0] = MTTC_6250;
808 break;
809
810 case MTSET6250DC:
811 cmdbuf[0] = MTTC_DC6250;
812 break;
813 }
814 } else {
815 if (sc->sc_flags & MTF_PASTEOT) {
816 bp->b_error = ENOSPC;
817 goto done;
818 }
819 if (bp->b_flags & B_READ) {
820 sc->sc_flags |= MTF_IO;
821 cmdbuf[0] = MTTC_READ;
822 } else {
823 sc->sc_flags |= MTF_WRT | MTF_IO;
824 cmdbuf[0] = MTTC_WRITE;
825 cmdbuf[1] = (bp->b_bcount +((1 << WRITE_BITS_IGNORED) - 1)) >> WRITE_BITS_IGNORED;
826 cmdcount = 2;
827 }
828 }
829 if (gpibsend(sc->sc_ic, sc->sc_slave, MTL_TCMD, cmdbuf, cmdcount)
830 == cmdcount) {
831 if (sc->sc_flags & MTF_REW)
832 goto done;
833 gpibawait(sc->sc_ic);
834 return;
835 }
836 fatalerror:
837 /*
838 * If anything fails, the drive is probably hosed, so mark it not
839 * "ALIVE" (but it EXISTS and is OPEN or we wouldn't be here, and
840 * if, last we heard, it was REWinding, remember that).
841 */
842 sc->sc_flags &= MTF_EXISTS | MTF_OPEN | MTF_REW;
843 bp->b_error = EIO;
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", device_xname(&sc->sc_dev));
868 return;
869 }
870
871 DPRINTF(MDB_ANY, ("%s intr", device_xname(&sc->sc_dev)));
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", device_xname(&sc->sc_dev));
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 device_xname(&sc->sc_dev), 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", device_xname(&sc->sc_dev),
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_error = ENOSPC;
962 sc->sc_flags |= MTF_ATEOT;
963 }
964 }
965 /*
966 * If a motion command was being executed, check for Tape Marks.
967 * If we were doing data, make sure we got the right amount, and
968 * check for hitting tape marks on reads.
969 */
970 if (bp->b_flags & B_CMD) {
971 if (sc->sc_stat1 & SR1_EOF) {
972 if (bp->b_cmd == MTFSR)
973 sc->sc_flags |= MTF_HITEOF;
974 if (bp->b_cmd == MTBSR)
975 sc->sc_flags |= MTF_HITBOF;
976 }
977 if (bp->b_cmd == MTRESET) {
978 callout_stop(&sc->sc_intr_ch);
979 sc->sc_flags |= MTF_ALIVE;
980 }
981 } else {
982 i = gpibrecv(sc->sc_ic, slave, MTT_BCNT, cmdbuf, 2);
983 if (i != 2) {
984 aprint_error_dev(&sc->sc_dev, "intr: can't get xfer length\n");
985 goto error;
986 }
987 i = (int) *((u_short *) cmdbuf);
988 if (i <= bp->b_bcount) {
989 if (i == 0)
990 sc->sc_flags |= MTF_HITEOF;
991 bp->b_resid = bp->b_bcount - i;
992 DPRINTF(MDB_ANY, ("%s intr: bcount %ld, resid %ld",
993 device_xname(&sc->sc_dev), bp->b_bcount, bp->b_resid));
994 } else {
995 tprintf(sc->sc_ttyp,
996 "%s: record (%d) larger than wanted (%d)\n",
997 device_xname(&sc->sc_dev), i, bp->b_bcount);
998 error:
999 sc->sc_flags &= ~MTF_IO;
1000 bp->b_error = EIO;
1001 }
1002 }
1003 /*
1004 * The operation is completely done.
1005 * Let the drive know with an END command.
1006 */
1007 cmdbuf[0] = MTE_COMPLETE | MTE_IDLE;
1008 (void) gpibsend(sc->sc_ic, slave, MTL_ECMD, cmdbuf, 1);
1009 bp->b_flags &= ~B_CMD;
1010 (void)BUFQ_GET(sc->sc_tab);
1011 biodone(bp);
1012 gpibrelease(sc->sc_ic, sc->sc_hdl);
1013 if (BUFQ_PEEK(sc->sc_tab) == NULL)
1014 sc->sc_active = 0;
1015 else
1016 mtustart(sc);
1017 }
1018
1019 int
1020 mtread(dev, uio, flags)
1021 dev_t dev;
1022 struct uio *uio;
1023 int flags;
1024 {
1025 struct mt_softc *sc;
1026
1027 sc = device_lookup(&mt_cd, MTUNIT(dev));
1028
1029 return (physio(mtstrategy, &sc->sc_bufstore,
1030 dev, B_READ, minphys, uio));
1031 }
1032
1033 int
1034 mtwrite(dev, uio, flags)
1035 dev_t dev;
1036 struct uio *uio;
1037 int flags;
1038 {
1039 struct mt_softc *sc;
1040
1041 sc = device_lookup(&mt_cd, MTUNIT(dev));
1042
1043 return (physio(mtstrategy, &sc->sc_bufstore,
1044 dev, B_WRITE, minphys, uio));
1045 }
1046
1047 int
1048 mtioctl(dev, cmd, data, flag, l)
1049 dev_t dev;
1050 u_long cmd;
1051 void *data;
1052 int flag;
1053 struct lwp *l;
1054 {
1055 struct mtop *op;
1056 int cnt;
1057
1058 switch (cmd) {
1059 case MTIOCTOP:
1060 op = (struct mtop *)data;
1061 switch(op->mt_op) {
1062 case MTWEOF:
1063 case MTFSF:
1064 case MTBSR:
1065 case MTBSF:
1066 case MTFSR:
1067 cnt = op->mt_count;
1068 break;
1069
1070 case MTOFFL:
1071 case MTREW:
1072 case MTNOP:
1073 cnt = 0;
1074 break;
1075
1076 default:
1077 return (EINVAL);
1078 }
1079 return (mtcommand(dev, op->mt_op, cnt));
1080
1081 case MTIOCGET:
1082 break;
1083
1084 default:
1085 return (EINVAL);
1086 }
1087 return (0);
1088 }
1089