1 /* $NetBSD: mt.c,v 1.22 2009/09/12 18:44:36 tsutsui Exp $ */
4 * Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1982, 1990, 1993
34 * The Regents of the University of California. All rights reserved.
36 * This code is derived from software contributed to Berkeley by
37 * the Systems Programming Group of the University of Utah Computer
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * from: Utah $Hdr: rd.c 1.44 92/12/26$
66 * @(#)rd.c 8.2 (Berkeley) 5/19/94
70 * Copyright (c) 1988 University of Utah.
72 * This code is derived from software contributed to Berkeley by
73 * the Systems Programming Group of the University of Utah Computer
76 * Redistribution and use in source and binary forms, with or without
77 * modification, are permitted provided that the following conditions
79 * 1. Redistributions of source code must retain the above copyright
80 * notice, this list of conditions and the following disclaimer.
81 * 2. Redistributions in binary form must reproduce the above copyright
82 * notice, this list of conditions and the following disclaimer in the
83 * documentation and/or other materials provided with the distribution.
84 * 3. All advertising materials mentioning features or use of this software
85 * must display the following acknowledgement:
86 * This product includes software developed by the University of
87 * California, Berkeley and its contributors.
88 * 4. Neither the name of the University nor the names of its contributors
89 * may be used to endorse or promote products derived from this software
90 * without specific prior written permission.
92 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
93 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
95 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
96 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
97 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
98 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
100 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
101 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
104 * from: Utah $Hdr: rd.c 1.44 92/12/26$
106 * @(#)rd.c 8.2 (Berkeley) 5/19/94
110 * Magnetic tape driver (HP7974a, HP7978a/b, HP7979a, HP7980a, HP7980xc)
111 * Original version contributed by Mt. Xinu.
112 * Modified for 4.4BSD by Mark Davies and Andrew Vignaux, Department of
113 * Computer Science, Victoria University of Wellington
116 #include <sys/cdefs.h>
117 __KERNEL_RCSID(0, "$NetBSD: mt.c,v 1.22 2009/09/12 18:44:36 tsutsui Exp $");
119 #include <sys/param.h>
120 #include <sys/systm.h>
121 #include <sys/callout.h>
123 #include <sys/bufq.h>
124 #include <sys/ioctl.h>
125 #include <sys/mtio.h>
126 #include <sys/file.h>
127 #include <sys/proc.h>
129 #include <sys/kernel.h>
130 #include <sys/tprintf.h>
131 #include <sys/device.h>
132 #include <sys/conf.h>
134 #include <dev/gpib/gpibvar.h>
135 #include <dev/gpib/cs80busvar.h>
137 #include <dev/gpib/mtreg.h>
142 #define MDB_FOLLOW 0x01
143 #define DPRINTF(mask, str) if (mtdebug & (mask)) printf str
145 #define DPRINTF(mask, str) /* nothing */
149 struct device sc_dev
;
151 gpib_chipset_tag_t sc_ic
;
152 gpib_handle_t sc_hdl
;
154 int sc_slave
; /* GPIB slave address (0-6) */
155 short sc_flags
; /* see below */
156 u_char sc_lastdsj
; /* place for DSJ in mtreaddsj() */
157 u_char sc_lastecmd
; /* place for End Command in mtreaddsj() */
158 short sc_recvtimeo
; /* count of gpibsend timeouts to prevent hang */
159 short sc_statindex
; /* index for next sc_stat when MTF_STATTIMEO */
160 struct mt_stat sc_stat
;/* status bytes last read from device */
161 short sc_density
; /* current density of tape (mtio.h format) */
162 short sc_type
; /* tape drive model (hardware IDs) */
164 struct bufq_state
*sc_tab
;/* buf queue */
166 struct buf sc_bufstore
; /* XXX buffer storage */
168 struct callout sc_start_ch
;
169 struct callout sc_intr_ch
;
172 #define MTUNIT(x) (minor(x) & 0x03)
174 #define B_CMD B_DEVPRIVATE /* command buf instead of data */
175 #define b_cmd b_blkno /* blkno holds cmd when B_CMD */
177 int mtmatch(device_t
, cfdata_t
, void *);
178 void mtattach(device_t
, device_t
, void *);
180 CFATTACH_DECL(mt
, sizeof(struct mt_softc
),
181 mtmatch
, mtattach
, NULL
, NULL
);
183 int mtlookup(int, int, int);
184 void mtustart(struct mt_softc
*);
185 int mtreaddsj(struct mt_softc
*, int);
186 int mtcommand(dev_t
, int, int);
188 void mtintr_callout(void *);
189 void mtstart_callout(void *);
191 void mtcallback(void *, int);
192 void mtstart(struct mt_softc
*);
193 void mtintr(struct mt_softc
*);
195 dev_type_open(mtopen
);
196 dev_type_close(mtclose
);
197 dev_type_read(mtread
);
198 dev_type_write(mtwrite
);
199 dev_type_ioctl(mtioctl
);
200 dev_type_strategy(mtstrategy
);
202 const struct bdevsw mt_bdevsw
= {
203 mtopen
, mtclose
, mtstrategy
, mtioctl
, nodump
, nosize
, D_TAPE
206 const struct cdevsw mt_cdevsw
= {
207 mtopen
, mtclose
, mtread
, mtwrite
, mtioctl
,
208 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_TAPE
212 extern struct cfdriver mt_cd
;
218 { MT7978ID
, "7978" },
219 { MT7979AID
, "7979A" },
220 { MT7980ID
, "7980" },
221 { MT7974AID
, "7974A" },
223 int nmtinfo
= sizeof(mtinfo
) / sizeof(mtinfo
[0]);
227 mtlookup(int id
, int slave
, int punit
)
231 for (i
= 0; i
< nmtinfo
; i
++)
232 if (mtinfo
[i
].hwid
== id
)
240 mtmatch(device_t parent
, cfdata_t match
, void *aux
)
242 struct cs80bus_attach_args
*ca
= aux
;
245 return (mtlookup(ca
->ca_id
, ca
->ca_slave
, ca
->ca_punit
) == 0);
249 mtattach(device_t parent
, device_t self
, void *aux
)
251 struct mt_softc
*sc
= device_private(self
);
252 struct cs80bus_attach_args
*ca
= aux
;
255 sc
->sc_ic
= ca
->ca_ic
;
256 sc
->sc_slave
= ca
->ca_slave
;
258 if ((type
= mtlookup(ca
->ca_id
, ca
->ca_slave
, ca
->ca_punit
)) < 0)
261 printf(": %s tape\n", mtinfo
[type
].desc
);
264 sc
->sc_flags
= MTF_EXISTS
;
266 bufq_alloc(&sc
->sc_tab
, "fcfs", 0);
267 callout_init(&sc
->sc_start_ch
, 0);
268 callout_init(&sc
->sc_intr_ch
, 0);
270 if (gpibregister(sc
->sc_ic
, sc
->sc_slave
, mtcallback
, sc
,
272 aprint_error_dev(&sc
->sc_dev
, "can't register callback\n");
278 * Perform a read of "Device Status Jump" register and update the
279 * status if necessary. If status is read, the given "ecmd" is also
280 * performed, unless "ecmd" is zero. Returns DSJ value, -1 on failure
281 * and -2 on "temporary" failure.
284 mtreaddsj(struct mt_softc
*sc
, int ecmd
)
288 if (sc
->sc_flags
& MTF_STATTIMEO
)
290 retval
= gpibrecv(sc
->sc_ic
,
291 (sc
->sc_flags
& MTF_DSJTIMEO
) ? -1 : sc
->sc_slave
,
292 MTT_DSJ
, &(sc
->sc_lastdsj
), 1);
293 sc
->sc_flags
&= ~MTF_DSJTIMEO
;
295 DPRINTF(MDB_ANY
, ("%s can't gpibrecv DSJ",
296 device_xname(&sc
->sc_dev
)));
297 if (sc
->sc_recvtimeo
== 0)
298 sc
->sc_recvtimeo
= hz
;
299 if (--sc
->sc_recvtimeo
== 0)
302 sc
->sc_flags
|= MTF_DSJTIMEO
;
305 sc
->sc_recvtimeo
= 0;
306 sc
->sc_statindex
= 0;
307 DPRINTF(MDB_ANY
, ("%s readdsj: 0x%x", device_xname(&sc
->sc_dev
),
309 sc
->sc_lastecmd
= ecmd
;
310 switch (sc
->sc_lastdsj
) {
312 if (ecmd
& MTE_DSJ_FORCE
)
317 sc
->sc_lastecmd
= MTE_COMPLETE
;
322 printf("%s readdsj: DSJ 0x%x\n", device_xname(&sc
->sc_dev
),
328 retval
= gpibrecv(sc
->sc_ic
,
329 (sc
->sc_flags
& MTF_STATCONT
) ? -1 : sc
->sc_slave
, MTT_STAT
,
330 ((char *)&(sc
->sc_stat
)) + sc
->sc_statindex
,
331 sizeof(sc
->sc_stat
) - sc
->sc_statindex
);
332 sc
->sc_flags
&= ~(MTF_STATTIMEO
| MTF_STATCONT
);
333 if (retval
!= sizeof(sc
->sc_stat
) - sc
->sc_statindex
) {
334 if (sc
->sc_recvtimeo
== 0)
335 sc
->sc_recvtimeo
= hz
;
336 if (--sc
->sc_recvtimeo
!= 0) {
338 sc
->sc_statindex
+= retval
;
339 sc
->sc_flags
|= MTF_STATCONT
;
341 sc
->sc_flags
|= MTF_STATTIMEO
;
344 printf("%s readdsj: can't read status", device_xname(&sc
->sc_dev
));
347 sc
->sc_recvtimeo
= 0;
348 sc
->sc_statindex
= 0;
349 DPRINTF(MDB_ANY
, ("%s readdsj: status is %x %x %x %x %x %x",
350 device_xname(&sc
->sc_dev
),
351 sc
->sc_stat1
, sc
->sc_stat2
, sc
->sc_stat3
,
352 sc
->sc_stat4
, sc
->sc_stat5
, sc
->sc_stat6
));
354 (void) gpibsend(sc
->sc_ic
, sc
->sc_slave
,
355 MTL_ECMD
, &(sc
->sc_lastecmd
), 1);
356 return ((int) sc
->sc_lastdsj
);
360 mtopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
366 sc
= device_lookup_private(&mt_cd
, MTUNIT(dev
));
367 if (sc
== NULL
|| (sc
->sc_flags
& MTF_EXISTS
) == 0)
370 if (sc
->sc_flags
& MTF_OPEN
)
373 DPRINTF(MDB_ANY
, ("%s open: flags 0x%x", device_xname(&sc
->sc_dev
),
376 sc
->sc_flags
|= MTF_OPEN
;
377 sc
->sc_ttyp
= tprintf_open(l
->l_proc
);
378 if ((sc
->sc_flags
& MTF_ALIVE
) == 0) {
379 error
= mtcommand(dev
, MTRESET
, 0);
380 if (error
!= 0 || (sc
->sc_flags
& MTF_ALIVE
) == 0)
382 if ((sc
->sc_stat1
& (SR1_BOT
| SR1_ONLINE
)) == SR1_ONLINE
)
383 (void) mtcommand(dev
, MTREW
, 0);
386 if ((error
= mtcommand(dev
, MTNOP
, 0)) != 0)
388 if (!(sc
->sc_flags
& MTF_REW
))
390 error
= kpause("mt", true, hz
, NULL
);
391 if (error
!= 0 && error
!= EWOULDBLOCK
) {
396 if ((flag
& FWRITE
) && (sc
->sc_stat1
& SR1_RO
)) {
400 if (!(sc
->sc_stat1
& SR1_ONLINE
)) {
401 uprintf("%s: not online\n", device_xname(&sc
->sc_dev
));
407 * - find out what density the drive is set to
408 * (i.e. the density of the current tape)
409 * - if we are going to write
410 * - if we're not at the beginning of the tape
411 * - complain if we want to change densities
412 * - otherwise, select the mtcommand to set the density
414 * If the drive doesn't support it then don't change the recorded
417 * The original MOREbsd code had these additional conditions
418 * for the mid-tape change
420 * req_den != T_BADBPI &&
421 * sc->sc_density != T_6250BPI
423 * which suggests that it would be possible to write multiple
424 * densities if req_den == T_BAD_BPI or the current tape
425 * density was 6250. Testing of our 7980 suggests that the
426 * device cannot change densities mid-tape.
430 sc
->sc_density
= (sc
->sc_stat2
& SR2_6250
) ? T_6250BPI
: (
431 (sc
->sc_stat3
& SR3_1600
) ? T_1600BPI
: (
432 (sc
->sc_stat3
& SR3_800
) ? T_800BPI
: -1));
433 req_den
= (dev
& T_DENSEL
);
436 if (!(sc
->sc_stat1
& SR1_BOT
)) {
437 if (sc
->sc_density
!= req_den
) {
438 uprintf("%s: can't change density mid-tape\n",
439 device_xname(&sc
->sc_dev
));
446 (req_den
== T_800BPI
? MTSET800BPI
: (
447 req_den
== T_1600BPI
? MTSET1600BPI
: (
448 req_den
== T_6250BPI
? MTSET6250BPI
: (
449 sc
->sc_type
== MT7980ID
452 if (mtcommand(dev
, mtset_density
, 0) == 0)
453 sc
->sc_density
= req_den
;
458 sc
->sc_flags
&= ~MTF_OPEN
;
463 mtclose(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
467 sc
= device_lookup_private(&mt_cd
, MTUNIT(dev
));
471 if (sc
->sc_flags
& MTF_WRT
) {
472 (void) mtcommand(dev
, MTWEOF
, 2);
473 (void) mtcommand(dev
, MTBSF
, 0);
475 if ((minor(dev
) & T_NOREWIND
) == 0)
476 (void) mtcommand(dev
, MTREW
, 0);
477 sc
->sc_flags
&= ~MTF_OPEN
;
478 tprintf_close(sc
->sc_ttyp
);
483 mtcommand(dev_t dev
, int cmd
, int cnt
)
489 sc
= device_lookup_private(&mt_cd
, MTUNIT(dev
));
490 bp
= &sc
->sc_bufstore
;
492 if (bp
->b_cflags
& BC_BUSY
)
497 bp
->b_objlock
= &buffer_lock
;
499 bp
->b_cflags
= BC_BUSY
;
504 if (bp
->b_error
!= 0) {
505 error
= (int) (unsigned) bp
->b_error
;
510 bp
->b_cflags
= 0 /*&= ~BC_BUSY*/;
512 bp
->b_cflags
&= ~BC_BUSY
;
518 * Only thing to check here is for legal record lengths (writes only).
521 mtstrategy(struct buf
*bp
)
526 sc
= device_lookup_private(&mt_cd
, MTUNIT(bp
->b_dev
));
528 DPRINTF(MDB_ANY
, ("%s strategy", device_xname(&sc
->sc_dev
)));
530 if ((bp
->b_flags
& (B_CMD
| B_READ
)) == 0) {
531 #define WRITE_BITS_IGNORED 8
533 if (bp
->b_bcount
& ((1 << WRITE_BITS_IGNORED
) - 1)) {
535 "%s: write record must be multiple of %d\n",
536 device_xname(&sc
->sc_dev
), 1 << WRITE_BITS_IGNORED
);
541 if (sc
->sc_stat2
& SR2_LONGREC
) {
542 switch (sc
->sc_density
) {
553 if (bp
->b_bcount
> s
) {
555 "%s: write record (%d) too big: limit (%d)\n",
556 device_xname(&sc
->sc_dev
), bp
->b_bcount
, s
);
557 #if 0 /* XXX see above */
566 bufq_put(sc
->sc_tab
, bp
);
567 if (sc
->sc_active
== 0) {
575 mtustart(struct mt_softc
*sc
)
578 DPRINTF(MDB_ANY
, ("%s ustart", device_xname(&sc
->sc_dev
)));
579 if (gpibrequest(sc
->sc_ic
, sc
->sc_hdl
))
584 mtcallback(void *v
, int action
)
586 struct mt_softc
*sc
= v
;
588 DPRINTF(MDB_FOLLOW
, ("mtcallback: v=%p, action=%d\n", v
, action
));
599 printf("mtcallback: unknown action %d\n", action
);
606 mtintr_callout(void *arg
)
608 struct mt_softc
*sc
= arg
;
611 gpibppclear(sc
->sc_ic
);
617 mtstart_callout(void *arg
)
621 mtstart((struct mt_softc
*)arg
);
626 mtstart(struct mt_softc
*sc
)
632 DPRINTF(MDB_ANY
, ("%s start", device_xname(&sc
->sc_dev
)));
633 sc
->sc_flags
&= ~MTF_WRT
;
634 bp
= bufq_peek(sc
->sc_tab
);
635 if ((sc
->sc_flags
& MTF_ALIVE
) == 0 &&
636 ((bp
->b_flags
& B_CMD
) == 0 || bp
->b_cmd
!= MTRESET
))
639 if (sc
->sc_flags
& MTF_REW
) {
640 if (!gpibpptest(sc
->sc_ic
, sc
->sc_slave
))
642 switch (mtreaddsj(sc
, MTE_DSJ_FORCE
|MTE_COMPLETE
|MTE_IDLE
)) {
646 if ((sc
->sc_stat1
& SR1_BOT
) ||
647 !(sc
->sc_stat1
& SR1_ONLINE
)) {
648 sc
->sc_flags
&= ~MTF_REW
;
653 * -2 means "timeout" reading DSJ, which is probably
654 * temporary. This is considered OK when doing a NOP,
657 if (sc
->sc_flags
& (MTF_DSJTIMEO
| MTF_STATTIMEO
)) {
658 callout_reset(&sc
->sc_start_ch
, hz
>> 5,
659 mtstart_callout
, sc
);
663 if (bp
->b_cmd
!= MTNOP
|| !(bp
->b_flags
& B_CMD
)) {
673 if (bp
->b_flags
& B_CMD
) {
674 if (sc
->sc_flags
& MTF_PASTEOT
) {
679 bp
->b_error
= ENOSPC
;
686 sc
->sc_flags
&= ~(MTF_PASTEOT
| MTF_ATEOT
);
692 if (sc
->sc_flags
& MTF_HITEOF
)
694 cmdbuf
[0] = MTTC_FSF
;
698 if (sc
->sc_flags
& MTF_HITBOF
)
700 cmdbuf
[0] = MTTC_BSF
;
704 sc
->sc_flags
|= MTF_REW
;
705 cmdbuf
[0] = MTTC_REWOFF
;
709 cmdbuf
[0] = MTTC_WFM
;
713 cmdbuf
[0] = MTTC_BSR
;
717 cmdbuf
[0] = MTTC_FSR
;
721 sc
->sc_flags
|= MTF_REW
;
722 cmdbuf
[0] = MTTC_REW
;
727 * NOP is supposed to set status bits.
728 * Force readdsj to do it.
730 switch (mtreaddsj(sc
,
731 MTE_DSJ_FORCE
| MTE_COMPLETE
| MTE_IDLE
)) {
737 * If this fails, perform a device clear
738 * to fix any protocol problems and (most
739 * likely) get the status.
745 callout_reset(&sc
->sc_start_ch
, hz
>> 5,
746 mtstart_callout
, sc
);
752 * 1) selected device clear (send with "-2" secondary)
753 * 2) set timeout, then wait for "service request"
754 * 3) interrupt will read DSJ (and END COMPLETE-IDLE)
756 if (gpibsend(sc
->sc_ic
, sc
->sc_slave
, -2, NULL
, 0)){
757 aprint_error_dev(&sc
->sc_dev
, "can't reset");
760 callout_reset(&sc
->sc_intr_ch
, 4*hz
, mtintr_callout
,
762 gpibawait(sc
->sc_ic
);
766 cmdbuf
[0] = MTTC_800
;
770 cmdbuf
[0] = MTTC_1600
;
774 cmdbuf
[0] = MTTC_6250
;
778 cmdbuf
[0] = MTTC_DC6250
;
782 if (sc
->sc_flags
& MTF_PASTEOT
) {
783 bp
->b_error
= ENOSPC
;
786 if (bp
->b_flags
& B_READ
) {
787 sc
->sc_flags
|= MTF_IO
;
788 cmdbuf
[0] = MTTC_READ
;
790 sc
->sc_flags
|= MTF_WRT
| MTF_IO
;
791 cmdbuf
[0] = MTTC_WRITE
;
792 cmdbuf
[1] = (bp
->b_bcount
+((1 << WRITE_BITS_IGNORED
) - 1)) >> WRITE_BITS_IGNORED
;
796 if (gpibsend(sc
->sc_ic
, sc
->sc_slave
, MTL_TCMD
, cmdbuf
, cmdcount
)
798 if (sc
->sc_flags
& MTF_REW
)
800 gpibawait(sc
->sc_ic
);
805 * If anything fails, the drive is probably hosed, so mark it not
806 * "ALIVE" (but it EXISTS and is OPEN or we wouldn't be here, and
807 * if, last we heard, it was REWinding, remember that).
809 sc
->sc_flags
&= MTF_EXISTS
| MTF_OPEN
| MTF_REW
;
812 sc
->sc_flags
&= ~(MTF_HITEOF
| MTF_HITBOF
);
813 (void)bufq_get(sc
->sc_tab
);
815 gpibrelease(sc
->sc_ic
, sc
->sc_hdl
);
816 if ((bp
= bufq_peek(sc
->sc_tab
)) == NULL
)
823 mtintr(struct mt_softc
*sc
)
829 slave
= sc
->sc_slave
;
831 bp
= bufq_peek(sc
->sc_tab
);
833 printf("%s intr: bp == NULL", device_xname(&sc
->sc_dev
));
837 DPRINTF(MDB_ANY
, ("%s intr", device_xname(&sc
->sc_dev
)));
840 * Some operation completed. Read status bytes and report errors.
841 * Clear EOF flags here `cause they're set once on specific conditions
842 * below when a command succeeds.
843 * A DSJ of 2 always means keep waiting. If the command was READ
844 * (and we're in data DMA phase) stop data transfer first.
846 sc
->sc_flags
&= ~(MTF_HITEOF
| MTF_HITBOF
);
847 if ((bp
->b_flags
& (B_CMD
|B_READ
)) == B_READ
&&
848 !(sc
->sc_flags
& (MTF_IO
| MTF_STATTIMEO
| MTF_DSJTIMEO
))){
849 cmdbuf
[0] = MTE_STOP
;
850 (void) gpibsend(sc
->sc_ic
, slave
, MTL_ECMD
,cmdbuf
,1);
852 switch (mtreaddsj(sc
, 0)) {
858 * If we're in the middle of a READ/WRITE and have yet to
859 * start the data transfer, a DSJ of one should terminate it.
861 sc
->sc_flags
&= ~MTF_IO
;
865 (void) gpibawait(sc
->sc_ic
);
870 * -2 means that the drive failed to respond quickly enough
871 * to the request for DSJ. It's probably just "busy" figuring
872 * it out and will know in a little bit...
874 callout_reset(&sc
->sc_intr_ch
, hz
>> 5, mtintr_callout
, sc
);
878 printf("%s intr: can't get drive stat", device_xname(&sc
->sc_dev
));
881 if (sc
->sc_stat1
& (SR1_ERR
| SR1_REJECT
)) {
882 i
= sc
->sc_stat4
& SR4_ERCLMASK
;
883 printf("%s: %s error, retry %d, SR2/3 %x/%x, code %d",
884 device_xname(&sc
->sc_dev
), i
== SR4_DEVICE
? "device" :
885 (i
== SR4_PROTOCOL
? "protocol" :
886 (i
== SR4_SELFTEST
? "selftest" : "unknown")),
887 sc
->sc_stat4
& SR4_RETRYMASK
, sc
->sc_stat2
,
888 sc
->sc_stat3
, sc
->sc_stat5
);
890 if ((bp
->b_flags
& B_CMD
) && bp
->b_cmd
== MTRESET
)
891 callout_stop(&sc
->sc_intr_ch
);
892 if (sc
->sc_stat3
& SR3_POWERUP
)
893 sc
->sc_flags
&= MTF_OPEN
| MTF_EXISTS
;
897 * Report and clear any soft errors.
899 if (sc
->sc_stat1
& SR1_SOFTERR
) {
900 printf("%s: soft error, retry %d\n", device_xname(&sc
->sc_dev
),
901 sc
->sc_stat4
& SR4_RETRYMASK
);
902 sc
->sc_stat1
&= ~SR1_SOFTERR
;
905 * We've initiated a read or write, but haven't actually started to
906 * DMA the data yet. At this point, the drive's ready.
908 if (sc
->sc_flags
& MTF_IO
) {
909 sc
->sc_flags
&= ~MTF_IO
;
910 dir
= (bp
->b_flags
& B_READ
? GPIB_READ
: GPIB_WRITE
);
911 gpibxfer(sc
->sc_ic
, slave
,
912 dir
== GPIB_READ
? MTT_READ
: MTL_WRITE
,
913 bp
->b_data
, bp
->b_bcount
, dir
, dir
== GPIB_READ
);
917 * Check for End Of Tape - we're allowed to hit EOT and then write (or
918 * read) one more record. If we get here and have not already hit EOT,
919 * return ENOSPC to inform the process that it's hit it. If we get
920 * here and HAVE already hit EOT, don't allow any more operations that
921 * move the tape forward.
923 if (sc
->sc_stat1
& SR1_EOT
) {
924 if (sc
->sc_flags
& MTF_ATEOT
)
925 sc
->sc_flags
|= MTF_PASTEOT
;
927 bp
->b_error
= ENOSPC
;
928 sc
->sc_flags
|= MTF_ATEOT
;
932 * If a motion command was being executed, check for Tape Marks.
933 * If we were doing data, make sure we got the right amount, and
934 * check for hitting tape marks on reads.
936 if (bp
->b_flags
& B_CMD
) {
937 if (sc
->sc_stat1
& SR1_EOF
) {
938 if (bp
->b_cmd
== MTFSR
)
939 sc
->sc_flags
|= MTF_HITEOF
;
940 if (bp
->b_cmd
== MTBSR
)
941 sc
->sc_flags
|= MTF_HITBOF
;
943 if (bp
->b_cmd
== MTRESET
) {
944 callout_stop(&sc
->sc_intr_ch
);
945 sc
->sc_flags
|= MTF_ALIVE
;
948 i
= gpibrecv(sc
->sc_ic
, slave
, MTT_BCNT
, cmdbuf
, 2);
950 aprint_error_dev(&sc
->sc_dev
, "intr: can't get xfer length\n");
953 i
= (int) *((u_short
*) cmdbuf
);
954 if (i
<= bp
->b_bcount
) {
956 sc
->sc_flags
|= MTF_HITEOF
;
957 bp
->b_resid
= bp
->b_bcount
- i
;
958 DPRINTF(MDB_ANY
, ("%s intr: bcount %d, resid %d",
959 device_xname(&sc
->sc_dev
),
960 bp
->b_bcount
, bp
->b_resid
));
963 "%s: record (%d) larger than wanted (%d)\n",
964 device_xname(&sc
->sc_dev
), i
, bp
->b_bcount
);
966 sc
->sc_flags
&= ~MTF_IO
;
971 * The operation is completely done.
972 * Let the drive know with an END command.
974 cmdbuf
[0] = MTE_COMPLETE
| MTE_IDLE
;
975 (void) gpibsend(sc
->sc_ic
, slave
, MTL_ECMD
, cmdbuf
, 1);
976 bp
->b_flags
&= ~B_CMD
;
977 (void)bufq_get(sc
->sc_tab
);
979 gpibrelease(sc
->sc_ic
, sc
->sc_hdl
);
980 if (bufq_peek(sc
->sc_tab
) == NULL
)
987 mtread(dev_t dev
, struct uio
*uio
, int flags
)
991 sc
= device_lookup_private(&mt_cd
, MTUNIT(dev
));
993 return (physio(mtstrategy
, NULL
, dev
, B_READ
, minphys
, uio
));
997 mtwrite(dev_t dev
, struct uio
*uio
, int flags
)
1001 sc
= device_lookup_private(&mt_cd
, MTUNIT(dev
));
1003 return (physio(mtstrategy
, NULL
, dev
, B_WRITE
, minphys
, uio
));
1007 mtioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
1014 op
= (struct mtop
*)data
;
1033 return (mtcommand(dev
, op
->mt_op
, cnt
));