1 /* $NetBSD: ct.c,v 1.5 2005/12/11 12:17:19 christos Exp $ */
4 * Copyright (c) 1982, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * @(#)ct.c 8.1 (Berkeley) 7/15/93
37 #include <sys/param.h>
39 #include <machine/stdarg.h>
41 #include <hp300/dev/ctreg.h>
43 #include <lib/libsa/stand.h>
44 #include <hp300/stand/common/conf.h>
45 #include <hp300/stand/common/hpibvar.h>
46 #include <hp300/stand/common/samachdep.h>
48 struct ct_iocmd ct_ioc
;
49 struct ct_rscmd ct_rsc
;
50 struct ct_stat ct_stat
;
51 struct ct_ssmcmd ct_ssmc
;
60 } ct_softc
[NHPIB
][NCT
];
66 char ctio_buf
[MAXBSIZE
];
78 int nctinfo
= sizeof(ctinfo
) / sizeof(ctinfo
[0]);
80 static int ctinit(int, int);
81 static int ctident(int, int);
82 static int cterror(int, int);
85 ctinit(int ctlr
, int unit
)
87 struct ct_softc
*rs
= &ct_softc
[ctlr
][unit
];
90 if (hpibrecv(ctlr
, unit
, C_QSTAT
, &stat
, 1) != 1 || stat
)
92 if (ctident(ctlr
, unit
) < 0)
94 memset(&ct_ssmc
, 0, sizeof(ct_ssmc
));
95 ct_ssmc
.unit
= C_SUNIT(rs
->sc_punit
);
97 ct_ssmc
.fefm
= FEF_MASK
;
98 ct_ssmc
.refm
= REF_MASK
;
99 ct_ssmc
.aefm
= AEF_MASK
;
100 ct_ssmc
.iefm
= IEF_MASK
;
101 hpibsend(ctlr
, unit
, C_CMD
, (uint8_t *)&ct_ssmc
, sizeof(ct_ssmc
));
102 hpibswait(ctlr
, unit
);
103 hpibrecv(ctlr
, unit
, C_QSTAT
, &stat
, 1);
109 ctident(int ctlr
, int unit
)
111 struct ct_describe desc
;
112 uint8_t stat
, cmd
[3];
116 id
= hpibid(ctlr
, unit
);
117 if ((id
& 0x200) == 0)
119 for (i
= 0; i
< nctinfo
; i
++)
120 if (id
== ctinfo
[i
].hwid
)
124 ct_softc
[ctlr
][unit
].sc_punit
= ctinfo
[i
].punit
;
128 * Collect device description.
129 * Right now we only need this to differentiate 7945 from 7946.
130 * Note that we always issue the describe command to unit 0.
135 hpibsend(ctlr
, unit
, C_CMD
, cmd
, sizeof(cmd
));
136 hpibrecv(ctlr
, unit
, C_EXEC
, (uint8_t *)&desc
, 37);
137 hpibrecv(ctlr
, unit
, C_QSTAT
, &stat
, sizeof(stat
));
138 memset(name
, 0, sizeof(name
));
141 for (i
= 5; i
>= 0; i
--) {
142 name
[i
] = (n
& 0xf) + '0';
146 switch (ctinfo
[id
].hwid
) {
148 if (memcmp(name
, "079450", 6) == 0)
149 id
= -1; /* not really a 7946 */
158 ctpunit(int ctlr
, int slave
, int *punit
)
162 if (ctlr
>= NHPIB
|| hpibalive(ctlr
) == 0)
166 rs
= &ct_softc
[ctlr
][slave
];
168 if (rs
->sc_alive
== 0)
171 *punit
= rs
->sc_punit
;
176 ctopen(struct open_file
*f
, ...)
179 int ctlr
, unit
, part
;
185 ctlr
= va_arg(ap
, int);
186 unit
= va_arg(ap
, int);
187 part
= va_arg(ap
, int);
190 if (ctlr
>= NHPIB
|| hpibalive(ctlr
) == 0)
194 rs
= &ct_softc
[ctlr
][unit
];
198 if (rs
->sc_alive
== 0)
199 if (ctinit(ctlr
, unit
) == 0)
201 f
->f_devdata
= (void *)rs
;
202 ctstrategy(f
->f_devdata
, MTREW
, 0, 0, ctio_buf
, &resid
);
205 ctstrategy(f
->f_devdata
, MTFSF
, 0, 0, ctio_buf
, &resid
);
210 ctclose(struct open_file
*f
)
214 ctstrategy(f
->f_devdata
, MTREW
, 0, 0, ctio_buf
, &resid
);
219 ctstrategy(void *devdata
, int func
, daddr_t dblk
, size_t size
, void *v_buf
,
222 struct ct_softc
*rs
= devdata
;
223 uint8_t *buf
= v_buf
;
224 int ctlr
= rs
->sc_ctlr
;
225 int unit
= rs
->sc_unit
;
228 if (size
== 0 && (func
== F_READ
|| func
== F_WRITE
))
232 memset(&ct_ioc
, 0, sizeof(ct_ioc
));
233 ct_ioc
.unit
= C_SUNIT(rs
->sc_punit
);
234 ct_ioc
.saddr
= C_SADDR
;
236 ct_ioc
.slen
= C_SLEN
;
239 if (func
== F_READ
) {
241 ct_ioc
.addr
= rs
->sc_blkno
;
244 else if (func
== F_WRITE
) {
245 ct_ioc
.cmd
= C_WRITE
;
246 ct_ioc
.addr
= rs
->sc_blkno
;
249 else if (func
== MTFSF
) {
251 ct_ioc
.addr
= rs
->sc_blkno
;
252 ct_ioc
.len
= size
= MAXBSIZE
;
262 hpibsend(ctlr
, unit
, C_CMD
, (uint8_t *)&ct_ioc
, sizeof(ct_ioc
));
264 hpibswait(ctlr
, unit
);
265 hpibgo(ctlr
, unit
, C_EXEC
, buf
, size
,
266 func
!= F_WRITE
? F_READ
: F_WRITE
);
267 hpibswait(ctlr
, unit
);
269 while (hpibswait(ctlr
, unit
) < 0)
272 hpibrecv(ctlr
, unit
, C_QSTAT
, &stat
, 1);
274 stat
= cterror(ctlr
, unit
);
279 if (++rs
->sc_retry
> CTRETRY
)
283 rs
->sc_blkno
+= CTBTOK(size
);
292 cterror(int ctlr
, int unit
)
294 struct ct_softc
*rs
= &ct_softc
[ctlr
][unit
];
297 memset(&ct_rsc
, 0, sizeof(ct_rsc
));
298 memset(&ct_stat
, 0, sizeof(ct_stat
));
299 ct_rsc
.unit
= C_SUNIT(rs
->sc_punit
);
300 ct_rsc
.cmd
= C_STATUS
;
301 hpibsend(ctlr
, unit
, C_CMD
, (uint8_t *)&ct_rsc
, sizeof(ct_rsc
));
302 hpibrecv(ctlr
, unit
, C_EXEC
, (uint8_t *)&ct_stat
, sizeof(ct_stat
));
303 hpibrecv(ctlr
, unit
, C_QSTAT
, &stat
, 1);
305 printf("ct%d: request status fail %d\n", unit
, stat
);
308 if (ct_stat
.c_aef
& AEF_EOF
) {
309 /* 9145 drives don't increment block number at EOF */
310 if ((ct_stat
.c_blk
- rs
->sc_blkno
) == 0)
313 rs
->sc_blkno
= ct_stat
.c_blk
;
316 printf("ct%d err: vu 0x%x, pend 0x%x, bn%ld", unit
,
317 ct_stat
.c_vu
, ct_stat
.c_pend
, ct_stat
.c_blk
);
318 printf(", R 0x%x F 0x%x A 0x%x I 0x%x\n", ct_stat
.c_ref
,
319 ct_stat
.c_fef
, ct_stat
.c_aef
, ct_stat
.c_ief
);