1 /* $NetBSD: ct.c,v 1.56 2008/06/17 19:46:23 he Exp $ */
4 * Copyright (c) 1996, 1997 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 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)ct.c 8.2 (Berkeley) 1/12/94
64 * CS80 cartridge tape driver (9144, 88140, 9145)
67 * C_CC bit (character count option) when used in the CS/80 command
68 * 'set options' will cause the tape not to stream.
71 * make filesystem compatible
72 * make block mode work according to mtio(4) spec. (if possible)
73 * merge with cs80 disk driver
74 * finish support of 9145
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: ct.c,v 1.56 2008/06/17 19:46:23 he Exp $");
80 #include <sys/param.h>
81 #include <sys/systm.h>
85 #include <sys/device.h>
86 #include <sys/ioctl.h>
89 #include <sys/tprintf.h>
91 #include <hp300/dev/hpibvar.h>
93 #include <hp300/dev/ctreg.h>
97 /* number of eof marks to remember */
102 int sc_slave
; /* HP-IB slave ID */
103 int sc_punit
; /* physical unit */
104 struct ct_iocmd sc_ioc
;
105 struct ct_rscmd sc_rsc
;
106 struct ct_stat sc_stat
;
107 struct ct_ssmcmd sc_ssmc
;
108 struct ct_srcmd sc_src
;
109 struct ct_soptcmd sc_soptc
;
110 struct ct_ulcmd sc_ul
;
111 struct ct_wfmcmd sc_wfm
;
112 struct ct_clearcmd sc_clear
;
113 struct bufq_state
*sc_tab
;
116 struct buf sc_bufstore
; /* XXX */
124 struct hpibqueue sc_hq
; /* entry on hpib job queue */
130 #define CTF_OPEN 0x01
131 #define CTF_ALIVE 0x02
135 #define CTF_BEOF 0x20
136 #define CTF_AEOF 0x40
138 #define CTF_STATWAIT 0x100
139 #define CTF_CANSTREAM 0x200
140 #define CTF_WRTTN 0x400
142 static int ctmatch(device_t
, cfdata_t
, void *);
143 static void ctattach(device_t
, device_t
, void *);
145 CFATTACH_DECL_NEW(ct
, sizeof(struct ct_softc
),
146 ctmatch
, ctattach
, NULL
, NULL
);
148 static dev_type_open(ctopen
);
149 static dev_type_close(ctclose
);
150 static dev_type_read(ctread
);
151 static dev_type_write(ctwrite
);
152 static dev_type_ioctl(ctioctl
);
153 static dev_type_strategy(ctstrategy
);
155 const struct bdevsw ct_bdevsw
= {
156 ctopen
, ctclose
, ctstrategy
, ctioctl
, nodump
, nosize
, D_TAPE
159 const struct cdevsw ct_cdevsw
= {
160 ctopen
, ctclose
, ctread
, ctwrite
, ctioctl
,
161 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_TAPE
164 static int ctident(device_t
, struct ct_softc
*,
165 struct hpibbus_attach_args
*);
167 static void ctreset(struct ct_softc
*);
168 static void ctaddeof(struct ct_softc
*);
169 static void ctustart(struct ct_softc
*);
170 static void cteof(struct ct_softc
*, struct buf
*);
171 static void ctdone(struct ct_softc
*, struct buf
*);
173 static void ctstart(void *);
174 static void ctgo(void *);
175 static void ctintr(void *);
177 static void ctcommand(dev_t
, int, int);
179 static const struct ctinfo
{
184 { CT7946ID
, 1, "7946A" },
185 { CT7912PID
, 1, "7912P" },
186 { CT7914PID
, 1, "7914P" },
187 { CT9144ID
, 0, "9144" },
188 { CT9145ID
, 0, "9145" },
189 { CT35401ID
, 0, "35401A"},
191 static const int nctinfo
= __arraycount(ctinfo
);
195 #define UNIT(x) (minor(x) & 3)
196 #define ctpunit(x) ((x) & 7)
200 #define CDB_FILES 0x01
205 ctmatch(device_t parent
, cfdata_t cf
, void *aux
)
207 struct hpibbus_attach_args
*ha
= aux
;
209 return ctident(parent
, NULL
, ha
);
213 ctattach(device_t parent
, device_t self
, void *aux
)
215 struct ct_softc
*sc
= device_private(self
);
216 struct hpibbus_attach_args
*ha
= aux
;
219 if (ctident(parent
, sc
, ha
) == 0) {
220 aprint_error(": didn't respond to describe command!\n");
224 sc
->sc_slave
= ha
->ha_slave
;
225 sc
->sc_punit
= ha
->ha_punit
;
227 bufq_alloc(&sc
->sc_tab
, "fcfs", 0);
229 /* Initialize hpib job queue entry. */
230 sc
->sc_hq
.hq_softc
= sc
;
231 sc
->sc_hq
.hq_slave
= sc
->sc_slave
;
232 sc
->sc_hq
.hq_start
= ctstart
;
233 sc
->sc_hq
.hq_go
= ctgo
;
234 sc
->sc_hq
.hq_intr
= ctintr
;
237 sc
->sc_flags
|= CTF_ALIVE
;
241 ctident(device_t parent
, struct ct_softc
*sc
, struct hpibbus_attach_args
*ha
)
243 struct ct_describe desc
;
246 int i
, id
, n
, type
, canstream
;
248 type
= canstream
= 0;
250 /* Verify that we have a CS80 device. */
251 if ((ha
->ha_id
& 0x200) == 0)
254 /* Is it one of the tapes we support? */
255 for (id
= 0; id
< nctinfo
; id
++)
256 if (ha
->ha_id
== ctinfo
[id
].hwid
)
261 ha
->ha_punit
= ctinfo
[id
].punit
;
264 * So far, so good. Get drive parameters. Note command
265 * is always issued to unit 0.
270 hpibsend(device_unit(parent
), ha
->ha_slave
, C_CMD
, cmd
, sizeof(cmd
));
271 hpibrecv(device_unit(parent
), ha
->ha_slave
, C_EXEC
, &desc
, 37);
272 hpibrecv(device_unit(parent
), ha
->ha_slave
, C_QSTAT
, &stat
,
275 memset(name
, 0, sizeof(name
));
278 for (i
= 5; i
>= 0; i
--) {
279 name
[i
] = (n
& 0xf) + '0';
286 if (memcmp(name
, "079450", 6) == 0)
287 return 0; /* not really a 7946 */
304 sc
->sc_flags
= canstream
? CTF_CANSTREAM
: 0;
305 aprint_normal(": %s %stape\n", ctinfo
[id
].desc
,
306 canstream
? "streaming " : "");
313 ctreset(struct ct_softc
*sc
)
318 ctlr
= device_unit(device_parent(sc
->sc_dev
));
319 slave
= sc
->sc_slave
;
321 sc
->sc_clear
.unit
= C_SUNIT(sc
->sc_punit
);
322 sc
->sc_clear
.cmd
= C_CLEAR
;
323 hpibsend(ctlr
, slave
, C_TCMD
, &sc
->sc_clear
, sizeof(sc
->sc_clear
));
324 hpibswait(ctlr
, slave
);
325 hpibrecv(ctlr
, slave
, C_QSTAT
, &stat
, sizeof(stat
));
327 sc
->sc_src
.unit
= C_SUNIT(CTCTLR
);
328 sc
->sc_src
.nop
= C_NOP
;
329 sc
->sc_src
.cmd
= C_SREL
;
330 sc
->sc_src
.param
= C_REL
;
331 hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_src
, sizeof(sc
->sc_src
));
332 hpibswait(ctlr
, slave
);
333 hpibrecv(ctlr
, slave
, C_QSTAT
, &stat
, sizeof(stat
));
335 sc
->sc_ssmc
.unit
= C_SUNIT(sc
->sc_punit
);
336 sc
->sc_ssmc
.cmd
= C_SSM
;
337 sc
->sc_ssmc
.refm
= REF_MASK
;
338 sc
->sc_ssmc
.fefm
= FEF_MASK
;
339 sc
->sc_ssmc
.aefm
= AEF_MASK
;
340 sc
->sc_ssmc
.iefm
= IEF_MASK
;
341 hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_ssmc
, sizeof(sc
->sc_ssmc
));
342 hpibswait(ctlr
, slave
);
343 hpibrecv(ctlr
, slave
, C_QSTAT
, &stat
, sizeof(stat
));
345 sc
->sc_soptc
.unit
= C_SUNIT(sc
->sc_punit
);
346 sc
->sc_soptc
.nop
= C_NOP
;
347 sc
->sc_soptc
.cmd
= C_SOPT
;
348 sc
->sc_soptc
.opt
= C_SPAR
;
349 hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_soptc
, sizeof(sc
->sc_soptc
));
350 hpibswait(ctlr
, slave
);
351 hpibrecv(ctlr
, slave
, C_QSTAT
, &stat
, sizeof(stat
));
356 ctopen(dev_t dev
, int flag
, int type
, struct lwp
*l
)
362 sc
= device_lookup_private(&ct_cd
, UNIT(dev
));
366 if ((sc
->sc_flags
& CTF_ALIVE
) == 0)
369 if (sc
->sc_flags
& CTF_OPEN
)
372 ctlr
= device_unit(device_parent(sc
->sc_dev
));
373 slave
= sc
->sc_slave
;
375 sc
->sc_soptc
.unit
= C_SUNIT(sc
->sc_punit
);
376 sc
->sc_soptc
.nop
= C_NOP
;
377 sc
->sc_soptc
.cmd
= C_SOPT
;
378 if ((dev
& CT_STREAM
) && (sc
->sc_flags
& CTF_CANSTREAM
))
379 sc
->sc_soptc
.opt
= C_SPAR
| C_IMRPT
;
381 sc
->sc_soptc
.opt
= C_SPAR
;
384 * Check the return of hpibsend() and hpibswait().
385 * Drive could be loading/unloading a tape. If not checked,
388 cc
= hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_soptc
, sizeof(sc
->sc_soptc
));
389 if (cc
!= sizeof(sc
->sc_soptc
))
392 hpibswait(ctlr
, slave
);
393 cc
= hpibrecv(ctlr
, slave
, C_QSTAT
, &stat
, sizeof(stat
));
394 if (cc
!= sizeof(stat
))
397 sc
->sc_tpr
= tprintf_open(l
->l_proc
);
398 sc
->sc_flags
|= CTF_OPEN
;
404 ctclose(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
406 struct ct_softc
*sc
= device_lookup_private(&ct_cd
,UNIT(dev
));
408 if ((sc
->sc_flags
& (CTF_WRT
|CTF_WRTTN
)) == (CTF_WRT
|CTF_WRTTN
) &&
409 (sc
->sc_flags
& CTF_EOT
) == 0 ) { /* XXX return error if EOT ?? */
410 ctcommand(dev
, MTWEOF
, 2);
411 ctcommand(dev
, MTBSR
, 1);
412 if (sc
->sc_eofp
== EOFS
- 1)
413 sc
->sc_eofs
[EOFS
- 1]--;
418 printf("%s: ctclose backup eofs prt %d blk %d\n",
419 device_xname(sc
->sc_dev
), sc
->sc_eofp
,
420 sc
->sc_eofs
[sc
->sc_eofp
]);
423 if ((minor(dev
) & CT_NOREW
) == 0)
424 ctcommand(dev
, MTREW
, 1);
425 sc
->sc_flags
&= ~(CTF_OPEN
| CTF_WRT
| CTF_WRTTN
);
426 tprintf_close(sc
->sc_tpr
);
428 if (ctdebug
& CDB_FILES
)
429 printf("ctclose: flags %x\n", sc
->sc_flags
);
435 ctcommand(dev_t dev
, int cmd
, int cnt
)
437 struct ct_softc
*sc
= device_lookup_private(&ct_cd
,UNIT(dev
));
438 struct buf
*bp
= &sc
->sc_bufstore
;
441 if (cmd
== MTBSF
&& sc
->sc_eofp
== EOFS
- 1) {
442 cnt
= sc
->sc_eofs
[EOFS
- 1] - cnt
;
443 ctcommand(dev
, MTREW
, 1);
444 ctcommand(dev
, MTFSF
, cnt
);
449 if (cmd
== MTBSF
&& sc
->sc_eofp
- cnt
< 0) {
454 sc
->sc_flags
|= CTF_CMD
;
459 nbp
= (struct buf
*)geteblk(MAXBSIZE
);
460 bp
->b_data
= nbp
->b_data
;
461 bp
->b_bcount
= MAXBSIZE
;
465 bp
->b_cflags
= BC_BUSY
;
467 sc
->sc_blkno
= sc
->sc_eofs
[sc
->sc_eofp
];
470 if (ctdebug
& CT_BSF
)
471 printf("%s: backup eof pos %d blk %d\n",
472 device_xname(sc
->sc_dev
), sc
->sc_eofp
,
473 sc
->sc_eofs
[sc
->sc_eofp
]);
480 sc
->sc_flags
&= ~CTF_CMD
;
486 ctstrategy(struct buf
*bp
)
491 sc
= device_lookup_private(&ct_cd
, UNIT(bp
->b_dev
));
494 bufq_put(sc
->sc_tab
, bp
);
495 if (sc
->sc_active
== 0) {
503 ctustart(struct ct_softc
*sc
)
507 bp
= bufq_peek(sc
->sc_tab
);
508 sc
->sc_addr
= bp
->b_data
;
509 sc
->sc_resid
= bp
->b_bcount
;
510 if (hpibreq(device_parent(sc
->sc_dev
), &sc
->sc_hq
))
517 struct ct_softc
*sc
= arg
;
521 ctlr
= device_unit(device_parent(sc
->sc_dev
));
522 slave
= sc
->sc_slave
;
524 bp
= bufq_peek(sc
->sc_tab
);
525 if ((sc
->sc_flags
& CTF_CMD
) && sc
->sc_bp
== bp
) {
528 bp
->b_flags
|= B_READ
;
536 sc
->sc_ul
.unit
= C_SUNIT(sc
->sc_punit
);
537 sc
->sc_ul
.cmd
= C_UNLOAD
;
538 hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_ul
,
544 sc
->sc_flags
|= CTF_WRT
;
545 sc
->sc_wfm
.unit
= C_SUNIT(sc
->sc_punit
);
546 sc
->sc_wfm
.cmd
= C_WFM
;
547 hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_wfm
,
564 printf("%s: clearing eofs\n",
565 device_xname(sc
->sc_dev
));
567 for (i
=0; i
<EOFS
; i
++)
572 sc
->sc_ioc
.saddr
= C_SADDR
;
573 sc
->sc_ioc
.addr0
= 0;
574 sc
->sc_ioc
.addr
= sc
->sc_blkno
;
575 sc
->sc_ioc
.unit
= C_SUNIT(sc
->sc_punit
);
576 sc
->sc_ioc
.nop2
= C_NOP
;
577 sc
->sc_ioc
.slen
= C_SLEN
;
579 sc
->sc_ioc
.nop3
= C_NOP
;
580 sc
->sc_ioc
.cmd
= C_READ
;
581 hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_ioc
,
587 if ((bp
->b_flags
& B_READ
) &&
588 sc
->sc_flags
& (CTF_BEOF
|CTF_EOT
)) {
590 if (ctdebug
& CDB_FILES
)
591 printf("ctstart: before flags %x\n",
594 if (sc
->sc_flags
& CTF_BEOF
) {
595 sc
->sc_flags
&= ~CTF_BEOF
;
596 sc
->sc_flags
|= CTF_AEOF
;
598 if (ctdebug
& CDB_FILES
)
599 printf("ctstart: after flags %x\n",
603 bp
->b_resid
= bp
->b_bcount
;
607 sc
->sc_flags
|= CTF_IO
;
608 sc
->sc_ioc
.unit
= C_SUNIT(sc
->sc_punit
);
609 sc
->sc_ioc
.saddr
= C_SADDR
;
610 sc
->sc_ioc
.addr0
= 0;
611 sc
->sc_ioc
.addr
= sc
->sc_blkno
;
612 sc
->sc_ioc
.nop2
= C_NOP
;
613 sc
->sc_ioc
.slen
= C_SLEN
;
614 sc
->sc_ioc
.len
= sc
->sc_resid
;
615 sc
->sc_ioc
.nop3
= C_NOP
;
616 if (bp
->b_flags
& B_READ
)
617 sc
->sc_ioc
.cmd
= C_READ
;
619 sc
->sc_ioc
.cmd
= C_WRITE
;
620 sc
->sc_flags
|= (CTF_WRT
| CTF_WRTTN
);
622 hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_ioc
, sizeof(sc
->sc_ioc
));
630 struct ct_softc
*sc
= arg
;
634 bp
= bufq_peek(sc
->sc_tab
);
635 rw
= bp
->b_flags
& B_READ
;
636 hpibgo(device_unit(device_parent(sc
->sc_dev
)), sc
->sc_slave
, C_EXEC
,
637 sc
->sc_addr
, sc
->sc_resid
, rw
, rw
!= 0);
641 * Hideous grue to handle EOF/EOT (mostly for reads)
644 cteof(struct ct_softc
*sc
, struct buf
*bp
)
649 * EOT on a write is an error.
651 if ((bp
->b_flags
& B_READ
) == 0) {
652 bp
->b_resid
= bp
->b_bcount
;
653 bp
->b_error
= ENOSPC
;
654 sc
->sc_flags
|= CTF_EOT
;
658 * Use returned block position to determine how many blocks
659 * we really read and update b_resid.
661 blks
= sc
->sc_stat
.c_blk
- sc
->sc_blkno
- 1;
663 if (ctdebug
& CDB_FILES
)
664 printf("cteof: bc %d oblk %d nblk %ld read %ld, resid %ld\n",
665 bp
->b_bcount
, sc
->sc_blkno
, sc
->sc_stat
.c_blk
,
666 blks
, bp
->b_bcount
- CTKTOB(blks
));
668 if (blks
== -1) { /* 9145 on EOF does not change sc_stat.c_blk */
673 sc
->sc_blkno
= sc
->sc_stat
.c_blk
;
675 bp
->b_resid
= bp
->b_bcount
- CTKTOB(blks
);
677 * If we are at physical EOV or were after an EOF,
678 * we are now at logical EOT.
680 if ((sc
->sc_stat
.c_aef
& AEF_EOV
) ||
681 (sc
->sc_flags
& CTF_AEOF
)) {
682 sc
->sc_flags
|= CTF_EOT
;
683 sc
->sc_flags
&= ~(CTF_AEOF
|CTF_BEOF
);
686 * If we were before an EOF or we have just completed a FSF,
687 * we are now after EOF.
689 else if ((sc
->sc_flags
& CTF_BEOF
) ||
690 ((sc
->sc_flags
& CTF_CMD
) && sc
->sc_cmd
== MTFSF
)) {
691 sc
->sc_flags
|= CTF_AEOF
;
692 sc
->sc_flags
&= ~CTF_BEOF
;
695 * Otherwise if we read something we are now before EOF
696 * (and no longer after EOF).
699 sc
->sc_flags
|= CTF_BEOF
;
700 sc
->sc_flags
&= ~CTF_AEOF
;
703 * Finally, if we didn't read anything we just passed an EOF
706 sc
->sc_flags
|= CTF_AEOF
;
708 if (ctdebug
& CDB_FILES
)
709 printf("cteof: leaving flags %x\n", sc
->sc_flags
);
717 struct ct_softc
*sc
= arg
;
720 int ctlr
, slave
, unit
;
722 ctlr
= device_unit(device_parent(sc
->sc_dev
));
723 slave
= sc
->sc_slave
;
724 unit
= device_unit(sc
->sc_dev
);
726 bp
= bufq_peek(sc
->sc_tab
);
728 printf("%s: bp == NULL\n", device_xname(sc
->sc_dev
));
731 if (sc
->sc_flags
& CTF_IO
) {
732 sc
->sc_flags
&= ~CTF_IO
;
733 if (hpibustart(ctlr
))
737 if ((sc
->sc_flags
& CTF_STATWAIT
) == 0) {
738 if (hpibpptest(ctlr
, slave
) == 0) {
739 sc
->sc_flags
|= CTF_STATWAIT
;
744 sc
->sc_flags
&= ~CTF_STATWAIT
;
745 hpibrecv(ctlr
, slave
, C_QSTAT
, &stat
, 1);
747 if (ctdebug
& CDB_FILES
)
748 printf("ctintr: before flags %x\n", sc
->sc_flags
);
751 sc
->sc_rsc
.unit
= C_SUNIT(sc
->sc_punit
);
752 sc
->sc_rsc
.cmd
= C_STATUS
;
753 hpibsend(ctlr
, slave
, C_CMD
, &sc
->sc_rsc
, sizeof(sc
->sc_rsc
));
754 hpibrecv(ctlr
, slave
, C_EXEC
, &sc
->sc_stat
,
755 sizeof(sc
->sc_stat
));
756 hpibrecv(ctlr
, slave
, C_QSTAT
, &stat
, 1);
758 if (ctdebug
& CDB_FILES
)
759 printf("ctintr: return stat 0x%x, A%x F%x blk %ld\n",
760 stat
, sc
->sc_stat
.c_aef
,
761 sc
->sc_stat
.c_fef
, sc
->sc_stat
.c_blk
);
764 if (sc
->sc_stat
.c_aef
& (AEF_EOF
| AEF_EOV
)) {
769 if (sc
->sc_stat
.c_fef
& FEF_PF
) {
774 if (sc
->sc_stat
.c_fef
& FEF_REXMT
) {
778 if (sc
->sc_stat
.c_aef
& 0x5800) {
779 if (sc
->sc_stat
.c_aef
& 0x4000)
781 "%s: uninitialized media\n",
782 device_xname(sc
->sc_dev
));
783 if (sc
->sc_stat
.c_aef
& 0x1000)
786 device_xname(sc
->sc_dev
));
787 if (sc
->sc_stat
.c_aef
& 0x0800)
789 "%s: write protect\n",
790 device_xname(sc
->sc_dev
));
792 printf("%s err: v%d u%d ru%d bn%ld, ",
793 device_xname(sc
->sc_dev
),
794 (sc
->sc_stat
.c_vu
>> 4) & 0xF,
795 sc
->sc_stat
.c_vu
& 0xF,
798 printf("R0x%x F0x%x A0x%x I0x%x\n",
805 printf("%s: request status failed\n",
806 device_xname(sc
->sc_dev
));
811 if (sc
->sc_flags
& CTF_CMD
) {
812 switch (sc
->sc_cmd
) {
814 sc
->sc_flags
&= ~(CTF_BEOF
|CTF_AEOF
);
815 sc
->sc_blkno
+= CTBTOK(sc
->sc_resid
);
819 sc
->sc_flags
&= ~(CTF_AEOF
|CTF_BEOF
|CTF_EOT
);
822 sc
->sc_flags
&= ~CTF_BEOF
;
823 if (sc
->sc_flags
& CTF_EOT
) {
824 sc
->sc_flags
|= CTF_AEOF
;
825 sc
->sc_flags
&= ~CTF_EOT
;
826 } else if (sc
->sc_flags
& CTF_AEOF
) {
827 sc
->sc_flags
|= CTF_BEOF
;
828 sc
->sc_flags
&= ~CTF_AEOF
;
832 sc
->sc_flags
&= ~CTF_BEOF
;
833 if (sc
->sc_flags
& (CTF_AEOF
|CTF_EOT
)) {
834 sc
->sc_flags
|= CTF_EOT
;
835 sc
->sc_flags
&= ~CTF_AEOF
;
837 sc
->sc_flags
|= CTF_AEOF
;
841 sc
->sc_flags
&= ~(CTF_BEOF
|CTF_AEOF
|CTF_EOT
);
845 sc
->sc_flags
&= ~CTF_AEOF
;
846 sc
->sc_blkno
+= CTBTOK(sc
->sc_resid
);
850 if (ctdebug
& CDB_FILES
)
851 printf("ctintr: after flags %x\n", sc
->sc_flags
);
857 ctdone(struct ct_softc
*sc
, struct buf
*bp
)
860 (void)bufq_get(sc
->sc_tab
);
862 hpibfree(device_parent(sc
->sc_dev
), &sc
->sc_hq
);
863 if (bufq_peek(sc
->sc_tab
) == NULL
) {
871 ctread(dev_t dev
, struct uio
*uio
, int flags
)
874 return physio(ctstrategy
, NULL
, dev
, B_READ
, minphys
, uio
);
878 ctwrite(dev_t dev
, struct uio
*uio
, int flags
)
881 /* XXX: check for hardware write-protect? */
882 return physio(ctstrategy
, NULL
, dev
, B_WRITE
, minphys
, uio
);
887 ctioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
895 op
= (struct mtop
*)data
;
914 ctcommand(dev
, op
->mt_op
, cnt
);
927 ctaddeof(struct ct_softc
*sc
)
930 if (sc
->sc_eofp
== EOFS
- 1)
931 sc
->sc_eofs
[EOFS
- 1]++;
934 if (sc
->sc_eofp
== EOFS
- 1)
935 sc
->sc_eofs
[EOFS
- 1] = EOFS
;
938 sc
->sc_eofs
[sc
->sc_eofp
] = sc
->sc_blkno
- 1;
941 if (ctdebug
& CT_BSF
)
942 printf("%s: add eof pos %d blk %d\n",
943 device_xname(sc
->sc_dev
), sc
->sc_eofp
,
944 sc
->sc_eofs
[sc
->sc_eofp
]);