1 /* $NetBSD: ct.c,v 1.21 2009/05/12 14:21:58 cegger 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 * CS/80 cartridge tape driver (HP9144, HP88140, HP9145)
113 * C_CC bit (character count option) when used in the CS/80 command
114 * 'set options' will cause the tape not to stream.
117 * make filesystem compatible
118 * make block mode work according to mtio(4) spec. (if possible)
119 * merge with CS/80 disk driver
120 * finish support of HP9145
123 #include <sys/cdefs.h>
124 __KERNEL_RCSID(0, "$NetBSD: ct.c,v 1.21 2009/05/12 14:21:58 cegger Exp $");
126 #include <sys/param.h>
127 #include <sys/systm.h>
129 #include <sys/bufq.h>
130 #include <sys/conf.h>
131 #include <sys/device.h>
132 #include <sys/ioctl.h>
133 #include <sys/mtio.h>
134 #include <sys/proc.h>
135 #include <sys/tprintf.h>
137 #include <dev/gpib/ctreg.h> /* XXX must be before cs80busvar.h ATM */
139 #include <dev/gpib/gpibvar.h>
140 #include <dev/gpib/cs80busvar.h>
142 /* number of eof marks to remember */
147 #define CDB_FILES 0x01
149 #define CDB_IDENT 0x04
150 #define CDB_FAIL 0x08
151 #define CDB_FOLLOW 0x10
152 #define DPRINTF(mask, str) if (ctdebug & (mask)) printf str
154 #define DPRINTF(mask, str) /* nothing */
158 struct device sc_dev
;
160 gpib_chipset_tag_t sc_ic
;
161 gpib_handle_t sc_hdl
;
163 int sc_slave
; /* GPIB slave ID */
164 int sc_punit
; /* physical unit */
165 struct ct_iocmd sc_ioc
;
166 struct ct_rscmd sc_rsc
;
167 struct cs80_stat sc_stat
;
168 struct bufq_state
*sc_tab
;
171 struct buf sc_bufstore
; /* XXX */
177 #define CTF_OPEN 0x01
178 #define CTF_ALIVE 0x02
182 #define CTF_BEOF 0x20
183 #define CTF_AEOF 0x40
185 #define CTF_STATWAIT 0x100
186 #define CTF_CANSTREAM 0x200
187 #define CTF_WRTTN 0x400
194 int ctmatch(device_t
, cfdata_t
, void *);
195 void ctattach(device_t
, device_t
, void *);
197 CFATTACH_DECL(ct
, sizeof(struct ct_softc
),
198 ctmatch
, ctattach
, NULL
, NULL
);
200 int ctident(device_t
, struct ct_softc
*,
201 struct cs80bus_attach_args
*);
203 int ctlookup(int, int, int);
204 void ctaddeof(struct ct_softc
*);
205 void ctustart(struct ct_softc
*);
206 void cteof(struct ct_softc
*, struct buf
*);
207 void ctdone(struct ct_softc
*, struct buf
*);
209 void ctcallback(void *, int);
210 void ctstart(struct ct_softc
*);
211 void ctintr(struct ct_softc
*);
213 void ctcommand(dev_t
, int, int);
215 dev_type_open(ctopen
);
216 dev_type_close(ctclose
);
217 dev_type_read(ctread
);
218 dev_type_write(ctwrite
);
219 dev_type_ioctl(ctioctl
);
220 dev_type_strategy(ctstrategy
);
222 const struct bdevsw ct_bdevsw
= {
223 ctopen
, ctclose
, ctstrategy
, ctioctl
, nodump
, nosize
, D_TAPE
226 const struct cdevsw ct_cdevsw
= {
227 ctopen
, ctclose
, ctread
, ctwrite
, ctioctl
,
228 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_TAPE
231 extern struct cfdriver ct_cd
;
238 { CT7946ID
, 1, "7946A" },
239 { CT7912PID
, 1, "7912P" },
240 { CT7914PID
, 1, "7914P" },
241 { CT9144ID
, 0, "9144" },
242 { CT9145ID
, 0, "9145" },
243 { CT35401ID
, 0, "35401A"},
245 int nctinfo
= sizeof(ctinfo
) / sizeof(ctinfo
[0]);
249 #define CTUNIT(x) (minor(x) & 0x03)
252 ctlookup(int id
, int slave
, int punit
)
256 for (i
= 0; i
< nctinfo
; i
++)
257 if (ctinfo
[i
].hwid
== id
)
265 ctmatch(device_t parent
, cfdata_t match
, void *aux
)
267 struct cs80bus_attach_args
*ca
= aux
;
270 if ((i
= ctlookup(ca
->ca_id
, ca
->ca_slave
, ca
->ca_punit
)) < 0)
272 ca
->ca_punit
= ctinfo
[i
].punit
;
277 ctattach(device_t parent
, device_t self
, void *aux
)
279 struct ct_softc
*sc
= device_private(self
);
280 struct cs80bus_attach_args
*ca
= aux
;
281 struct cs80_description csd
;
283 int type
, i
, n
, canstream
= 0;
285 sc
->sc_ic
= ca
->ca_ic
;
286 sc
->sc_slave
= ca
->ca_slave
;
287 sc
->sc_punit
= ca
->ca_punit
;
289 if ((type
= ctlookup(ca
->ca_id
, ca
->ca_slave
, ca
->ca_punit
)) < 0)
292 if (cs80reset(parent
, sc
->sc_slave
, sc
->sc_punit
)) {
294 aprint_error_dev(&sc
->sc_dev
, "can't reset device\n");
298 if (cs80describe(parent
, sc
->sc_slave
, sc
->sc_punit
, &csd
)) {
300 aprint_error_dev(&sc
->sc_dev
, "didn't respond to describe command\n");
303 memset(name
, 0, sizeof(name
));
304 for (i
=0, n
=0; i
<3; i
++) {
305 name
[n
++] = (csd
.d_name
[i
] >> 4) + '0';
306 name
[n
++] = (csd
.d_name
[i
] & 0x0f) + '0';
310 if (ctdebug
& CDB_IDENT
) {
311 printf("\n%s: name: ('%s')\n",
312 device_xname(&sc
->sc_dev
),name
);
313 printf(" iuw %x, maxxfr %d, ctype %d\n",
314 csd
.d_iuw
, csd
.d_cmaxxfr
, csd
.d_ctype
);
315 printf(" utype %d, bps %d, blkbuf %d, burst %d, blktime %d\n",
316 csd
.d_utype
, csd
.d_sectsize
,
317 csd
.d_blkbuf
, csd
.d_burstsize
, csd
.d_blocktime
);
318 printf(" avxfr %d, ort %d, atp %d, maxint %d, fv %x, rv %x\n",
319 csd
.d_uavexfr
, csd
.d_retry
, csd
.d_access
,
320 csd
.d_maxint
, csd
.d_fvbyte
, csd
.d_rvbyte
);
321 printf(" maxcyl/head/sect %d/%d/%d, maxvsect %d, inter %d\n",
322 csd
.d_maxcylhead
>> 8 , csd
.d_maxcylhead
& 0xff,
323 csd
.d_maxsect
, csd
.d_maxvsectl
, csd
.d_interleave
);
324 printf("%s", device_xname(&sc
->sc_dev
));
330 if (memcmp(name
, "079450", 6) == 0)
331 return; /* not really a 7946 */
336 sc
->sc_type
= CT9144
;
342 sc
->sc_type
= CT88140
;
350 sc
->sc_flags
= canstream
? CTF_CANSTREAM
: 0;
351 printf(": %s %stape\n", ctinfo
[type
].desc
,
352 canstream
? "streaming " : "");
354 bufq_alloc(&sc
->sc_tab
, "fcfs", 0);
356 if (gpibregister(sc
->sc_ic
, sc
->sc_slave
, ctcallback
, sc
,
358 aprint_error_dev(&sc
->sc_dev
, "can't register callback\n");
362 sc
->sc_flags
|= CTF_ALIVE
;
367 ctopen(dev_t dev
, int flag
, int type
, struct lwp
*l
)
372 sc
= device_lookup_private(&ct_cd
, CTUNIT(dev
));
373 if (sc
== NULL
|| (sc
->sc_flags
& CTF_ALIVE
) == 0)
376 if (sc
->sc_flags
& CTF_OPEN
)
379 if ((dev
& CT_STREAM
) && (sc
->sc_flags
& CTF_CANSTREAM
))
380 opt
= C_SPAR
| C_IMRPT
;
384 if (cs80setoptions(device_parent(&sc
->sc_dev
), sc
->sc_slave
,
388 sc
->sc_tpr
= tprintf_open(l
->l_proc
);
389 sc
->sc_flags
|= CTF_OPEN
;
396 ctclose(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
400 sc
= device_lookup_private(&ct_cd
, CTUNIT(dev
));
404 if ((sc
->sc_flags
& (CTF_WRT
|CTF_WRTTN
)) == (CTF_WRT
|CTF_WRTTN
) &&
405 (sc
->sc_flags
& CTF_EOT
) == 0 ) { /* XXX return error if EOT ?? */
406 ctcommand(dev
, MTWEOF
, 2);
407 ctcommand(dev
, MTBSR
, 1);
408 if (sc
->sc_eofp
== EOFS
- 1)
409 sc
->sc_eofs
[EOFS
- 1]--;
412 DPRINTF(CDB_BSF
, ("%s: ctclose backup eofs prt %d blk %d\n",
413 device_xname(&sc
->sc_dev
), sc
->sc_eofp
,
414 sc
->sc_eofs
[sc
->sc_eofp
]));
417 if ((minor(dev
) & CT_NOREW
) == 0)
418 ctcommand(dev
, MTREW
, 1);
419 sc
->sc_flags
&= ~(CTF_OPEN
| CTF_WRT
| CTF_WRTTN
);
420 tprintf_close(sc
->sc_tpr
);
421 DPRINTF(CDB_FILES
, ("ctclose: flags %x\n", sc
->sc_flags
));
423 return (0); /* XXX */
427 ctcommand(dev_t dev
, int cmd
, int cnt
)
433 sc
= device_lookup_private(&ct_cd
, CTUNIT(dev
));
434 bp
= &sc
->sc_bufstore
;
436 DPRINTF(CDB_FOLLOW
, ("ctcommand: called\n"));
438 if (cmd
== MTBSF
&& sc
->sc_eofp
== EOFS
- 1) {
439 cnt
= sc
->sc_eofs
[EOFS
- 1] - cnt
;
440 ctcommand(dev
, MTREW
, 1);
441 ctcommand(dev
, MTFSF
, cnt
);
446 if (cmd
== MTBSF
&& sc
->sc_eofp
- cnt
< 0) {
451 sc
->sc_flags
|= CTF_CMD
;
455 bp
->b_objlock
= &buffer_lock
;
457 nbp
= (struct buf
*)geteblk(MAXBSIZE
);
458 bp
->b_data
= nbp
->b_data
;
459 bp
->b_bcount
= MAXBSIZE
;
464 bp
->b_cflags
= BC_BUSY
;
467 sc
->sc_blkno
= sc
->sc_eofs
[sc
->sc_eofp
];
469 DPRINTF(CDB_BSF
, ("%s: backup eof pos %d blk %d\n",
470 device_xname(&sc
->sc_dev
), sc
->sc_eofp
,
471 sc
->sc_eofs
[sc
->sc_eofp
]));
477 sc
->sc_flags
&= ~CTF_CMD
;
483 ctstrategy(struct buf
*bp
)
488 DPRINTF(CDB_FOLLOW
, ("cdstrategy(%p): dev %" PRIx64
", bn %" PRIx64
490 bp
, bp
->b_dev
, bp
->b_blkno
, bp
->b_bcount
,
491 (bp
->b_flags
& B_READ
) ? 'R' : 'W'));
493 sc
= device_lookup_private(&ct_cd
, CTUNIT(bp
->b_dev
));
496 bufq_put(sc
->sc_tab
, bp
);
497 if (sc
->sc_active
== 0) {
505 ctustart(struct ct_softc
*sc
)
509 bp
= bufq_peek(sc
->sc_tab
);
510 sc
->sc_addr
= bp
->b_data
;
511 sc
->sc_resid
= bp
->b_bcount
;
512 if (gpibrequest(sc
->sc_ic
, sc
->sc_hdl
))
517 ctstart(struct ct_softc
*sc
)
521 struct ct_wfmcmd wfm
;
524 slave
= sc
->sc_slave
;
525 punit
= sc
->sc_punit
;
527 bp
= bufq_peek(sc
->sc_tab
);
528 if ((sc
->sc_flags
& CTF_CMD
) && sc
->sc_bp
== bp
) {
531 bp
->b_flags
|= B_READ
;
539 ul
.unit
= CS80CMD_SUNIT(punit
);
540 ul
.cmd
= CS80CMD_UNLOAD
;
541 (void) cs80send(device_parent(&sc
->sc_dev
), slave
,
542 punit
, CS80CMD_SCMD
, &ul
, sizeof(ul
));
547 sc
->sc_flags
|= CTF_WRT
;
548 wfm
.unit
= CS80CMD_SUNIT(sc
->sc_punit
);
549 wfm
.cmd
= CS80CMD_WFM
;
550 (void) cs80send(device_parent(&sc
->sc_dev
), slave
,
551 punit
, CS80CMD_SCMD
, &wfm
, sizeof(wfm
));
565 DPRINTF(CDB_BSF
, ("%s: clearing eofs\n",
566 device_xname(&sc
->sc_dev
)));
567 for (i
=0; i
<EOFS
; i
++)
572 sc
->sc_ioc
.unit
= CS80CMD_SUNIT(sc
->sc_punit
);
573 sc
->sc_ioc
.saddr
= CS80CMD_SADDR
;
574 sc
->sc_ioc
.addr0
= 0;
575 sc
->sc_ioc
.addr
= htobe32(sc
->sc_blkno
);
576 sc
->sc_ioc
.nop2
= CS80CMD_NOP
;
577 sc
->sc_ioc
.slen
= CS80CMD_SLEN
;
578 sc
->sc_ioc
.len
= htobe32(0);
579 sc
->sc_ioc
.nop3
= CS80CMD_NOP
;
580 sc
->sc_ioc
.cmd
= CS80CMD_READ
;
581 (void) cs80send(device_parent(&sc
->sc_dev
), slave
,
582 punit
, CS80CMD_SCMD
, &sc
->sc_ioc
,
588 if ((bp
->b_flags
& B_READ
) &&
589 sc
->sc_flags
& (CTF_BEOF
|CTF_EOT
)) {
590 DPRINTF(CDB_FILES
, ("ctstart: before %x\n",
592 if (sc
->sc_flags
& CTF_BEOF
) {
593 sc
->sc_flags
&= ~CTF_BEOF
;
594 sc
->sc_flags
|= CTF_AEOF
;
595 DPRINTF(CDB_FILES
, ("ctstart: after %x\n",
598 bp
->b_resid
= bp
->b_bcount
;
602 sc
->sc_flags
|= CTF_IO
;
603 sc
->sc_ioc
.unit
= CS80CMD_SUNIT(sc
->sc_punit
);
604 sc
->sc_ioc
.saddr
= CS80CMD_SADDR
;
605 sc
->sc_ioc
.addr0
= 0;
606 sc
->sc_ioc
.addr
= htobe32(sc
->sc_blkno
);
607 sc
->sc_ioc
.nop2
= CS80CMD_NOP
;
608 sc
->sc_ioc
.slen
= CS80CMD_SLEN
;
609 sc
->sc_ioc
.len
= htobe32(sc
->sc_resid
);
610 sc
->sc_ioc
.nop3
= CS80CMD_NOP
;
611 if (bp
->b_flags
& B_READ
)
612 sc
->sc_ioc
.cmd
= CS80CMD_READ
;
614 sc
->sc_ioc
.cmd
= CS80CMD_WRITE
;
615 sc
->sc_flags
|= (CTF_WRT
| CTF_WRTTN
);
617 (void) cs80send(device_parent(&sc
->sc_dev
), slave
, punit
,
618 CS80CMD_SCMD
, &sc
->sc_ioc
, sizeof(sc
->sc_ioc
));
620 gpibawait(sc
->sc_ic
);
624 * Hideous grue to handle EOF/EOT (mostly for reads)
627 cteof(struct ct_softc
*sc
, struct buf
*bp
)
632 * EOT on a write is an error.
634 if ((bp
->b_flags
& B_READ
) == 0) {
635 bp
->b_resid
= bp
->b_bcount
;
636 bp
->b_error
= ENOSPC
;
637 sc
->sc_flags
|= CTF_EOT
;
641 * Use returned block position to determine how many blocks
642 * we really read and update b_resid.
644 blks
= sc
->sc_stat
.c_blk
- sc
->sc_blkno
- 1;
645 DPRINTF(CDB_FILES
, ("cteof: bc %d oblk %d nblk %d read %ld, resid %ld\n",
646 bp
->b_bcount
, sc
->sc_blkno
, sc
->sc_stat
.c_blk
,
647 blks
, bp
->b_bcount
- CTKTOB(blks
)));
648 if (blks
== -1) { /* 9145 on EOF does not change sc_stat.c_blk */
653 sc
->sc_blkno
= sc
->sc_stat
.c_blk
;
655 bp
->b_resid
= bp
->b_bcount
- CTKTOB(blks
);
657 * If we are at physical EOV or were after an EOF,
658 * we are now at logical EOT.
660 if ((sc
->sc_stat
.c_aef
& AEF_EOV
) ||
661 (sc
->sc_flags
& CTF_AEOF
)) {
662 sc
->sc_flags
|= CTF_EOT
;
663 sc
->sc_flags
&= ~(CTF_AEOF
|CTF_BEOF
);
666 * If we were before an EOF or we have just completed a FSF,
667 * we are now after EOF.
669 else if ((sc
->sc_flags
& CTF_BEOF
) ||
670 ((sc
->sc_flags
& CTF_CMD
) && sc
->sc_cmd
== MTFSF
)) {
671 sc
->sc_flags
|= CTF_AEOF
;
672 sc
->sc_flags
&= ~CTF_BEOF
;
675 * Otherwise if we read something we are now before EOF
676 * (and no longer after EOF).
679 sc
->sc_flags
|= CTF_BEOF
;
680 sc
->sc_flags
&= ~CTF_AEOF
;
683 * Finally, if we didn't read anything we just passed an EOF
686 sc
->sc_flags
|= CTF_AEOF
;
687 DPRINTF(CDB_FILES
, ("cteof: leaving flags %x\n", sc
->sc_flags
));
692 ctcallback(void *v
, int action
)
694 struct ct_softc
*sc
= v
;
696 DPRINTF(CDB_FOLLOW
, ("ctcallback: v=%p, action=%d\n", v
, action
));
707 DPRINTF(CDB_FAIL
, ("ctcallback: unknown action %d\n", action
));
714 ctintr(struct ct_softc
*sc
)
721 slave
= sc
->sc_slave
;
722 punit
= sc
->sc_punit
;
724 bp
= bufq_peek(sc
->sc_tab
);
726 aprint_error_dev(&sc
->sc_dev
, "bp == NULL\n");
729 if (sc
->sc_flags
& CTF_IO
) {
730 sc
->sc_flags
&= ~CTF_IO
;
731 dir
= (bp
->b_flags
& B_READ
? GPIB_READ
: GPIB_WRITE
);
732 gpibxfer(sc
->sc_ic
, slave
, CS80CMD_EXEC
, sc
->sc_addr
,
733 sc
->sc_resid
, dir
, dir
== GPIB_READ
);
736 if ((sc
->sc_flags
& CTF_STATWAIT
) == 0) {
737 if (gpibpptest(sc
->sc_ic
, slave
) == 0) {
738 sc
->sc_flags
|= CTF_STATWAIT
;
739 gpibawait(sc
->sc_ic
);
743 sc
->sc_flags
&= ~CTF_STATWAIT
;
744 (void) gpibrecv(sc
->sc_ic
, slave
, CS80CMD_QSTAT
, &stat
, 1);
745 DPRINTF(CDB_FILES
, ("ctintr: before flags %x\n", sc
->sc_flags
));
747 sc
->sc_rsc
.unit
= CS80CMD_SUNIT(punit
);
748 sc
->sc_rsc
.cmd
= CS80CMD_STATUS
;
749 (void) gpibsend(sc
->sc_ic
, slave
, CS80CMD_SCMD
, &sc
->sc_rsc
,
751 (void) gpibrecv(sc
->sc_ic
, slave
, CS80CMD_EXEC
, &sc
->sc_stat
,
752 sizeof(sc
->sc_stat
));
753 (void) gpibrecv(sc
->sc_ic
, slave
, CS80CMD_QSTAT
, &stat
, 1);
754 DPRINTF(CDB_FILES
, ("ctintr: return stat 0x%x, A%x F%x blk %d\n",
755 stat
, sc
->sc_stat
.c_aef
,
756 sc
->sc_stat
.c_fef
, sc
->sc_stat
.c_blk
));
758 if (sc
->sc_stat
.c_aef
& (AEF_EOF
| AEF_EOV
)) {
763 if (sc
->sc_stat
.c_fef
& FEF_PF
) {
764 cs80reset(sc
, slave
, punit
);
768 if (sc
->sc_stat
.c_fef
& FEF_REXMT
) {
772 if (sc
->sc_stat
.c_aef
& 0x5800) {
773 if (sc
->sc_stat
.c_aef
& 0x4000)
775 "%s: uninitialized media\n",
776 device_xname(&sc
->sc_dev
));
777 if (sc
->sc_stat
.c_aef
& 0x1000)
780 device_xname(&sc
->sc_dev
));
781 if (sc
->sc_stat
.c_aef
& 0x0800)
783 "%s: write protect\n",
784 device_xname(&sc
->sc_dev
));
786 printf("%s err: v%d u%d ru%d bn%d, ",
787 device_xname(&sc
->sc_dev
),
788 (sc
->sc_stat
.c_vu
>>4)&0xF,
789 sc
->sc_stat
.c_vu
&0xF,
792 printf("R0x%x F0x%x A0x%x I0x%x\n",
799 aprint_error_dev(&sc
->sc_dev
, "request status failed\n");
804 if (sc
->sc_flags
& CTF_CMD
) {
805 switch (sc
->sc_cmd
) {
807 sc
->sc_flags
&= ~(CTF_BEOF
|CTF_AEOF
);
808 sc
->sc_blkno
+= CTBTOK(sc
->sc_resid
);
812 sc
->sc_flags
&= ~(CTF_AEOF
|CTF_BEOF
|CTF_EOT
);
815 sc
->sc_flags
&= ~CTF_BEOF
;
816 if (sc
->sc_flags
& CTF_EOT
) {
817 sc
->sc_flags
|= CTF_AEOF
;
818 sc
->sc_flags
&= ~CTF_EOT
;
819 } else if (sc
->sc_flags
& CTF_AEOF
) {
820 sc
->sc_flags
|= CTF_BEOF
;
821 sc
->sc_flags
&= ~CTF_AEOF
;
825 sc
->sc_flags
&= ~CTF_BEOF
;
826 if (sc
->sc_flags
& (CTF_AEOF
|CTF_EOT
)) {
827 sc
->sc_flags
|= CTF_EOT
;
828 sc
->sc_flags
&= ~CTF_AEOF
;
830 sc
->sc_flags
|= CTF_AEOF
;
834 sc
->sc_flags
&= ~(CTF_BEOF
|CTF_AEOF
|CTF_EOT
);
838 sc
->sc_flags
&= ~CTF_AEOF
;
839 sc
->sc_blkno
+= CTBTOK(sc
->sc_resid
);
842 DPRINTF(CDB_FILES
, ("ctintr: after flags %x\n", sc
->sc_flags
));
847 ctdone(struct ct_softc
*sc
, struct buf
*bp
)
850 (void)bufq_get(sc
->sc_tab
);
852 gpibrelease(sc
->sc_ic
, sc
->sc_hdl
);
853 if (bufq_peek(sc
->sc_tab
) == NULL
) {
861 ctread(dev_t dev
, struct uio
*uio
, int flags
)
863 return (physio(ctstrategy
, NULL
, dev
, B_READ
, minphys
, uio
));
867 ctwrite(dev_t dev
, struct uio
*uio
, int flags
)
869 /* XXX: check for hardware write-protect? */
870 return (physio(ctstrategy
, NULL
, dev
, B_WRITE
, minphys
, uio
));
875 ctioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
883 op
= (struct mtop
*)data
;
902 ctcommand(dev
, op
->mt_op
, cnt
);
915 ctaddeof(struct ct_softc
*sc
)
918 if (sc
->sc_eofp
== EOFS
- 1)
919 sc
->sc_eofs
[EOFS
- 1]++;
922 if (sc
->sc_eofp
== EOFS
- 1)
923 sc
->sc_eofs
[EOFS
- 1] = EOFS
;
926 sc
->sc_eofs
[sc
->sc_eofp
] = sc
->sc_blkno
- 1;
928 DPRINTF(CDB_BSF
, ("%s: add eof pos %d blk %d\n",
929 device_xname(&sc
->sc_dev
), sc
->sc_eofp
,
930 sc
->sc_eofs
[sc
->sc_eofp
]));