Home | History | Annotate | Line # | Download | only in common
ct.c revision 1.1.60.1
      1  1.1.60.1    skrll /*	$NetBSD: ct.c,v 1.1.60.1 2004/08/03 10:34:37 skrll Exp $	*/
      2       1.1  thorpej 
      3       1.1  thorpej /*
      4       1.1  thorpej  * Copyright (c) 1982, 1990, 1993
      5       1.1  thorpej  *	The Regents of the University of California.  All rights reserved.
      6       1.1  thorpej  *
      7       1.1  thorpej  * Redistribution and use in source and binary forms, with or without
      8       1.1  thorpej  * modification, are permitted provided that the following conditions
      9       1.1  thorpej  * are met:
     10       1.1  thorpej  * 1. Redistributions of source code must retain the above copyright
     11       1.1  thorpej  *    notice, this list of conditions and the following disclaimer.
     12       1.1  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  thorpej  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  thorpej  *    documentation and/or other materials provided with the distribution.
     15  1.1.60.1    skrll  * 3. Neither the name of the University nor the names of its contributors
     16       1.1  thorpej  *    may be used to endorse or promote products derived from this software
     17       1.1  thorpej  *    without specific prior written permission.
     18       1.1  thorpej  *
     19       1.1  thorpej  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20       1.1  thorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21       1.1  thorpej  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22       1.1  thorpej  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23       1.1  thorpej  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24       1.1  thorpej  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25       1.1  thorpej  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26       1.1  thorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27       1.1  thorpej  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28       1.1  thorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29       1.1  thorpej  * SUCH DAMAGE.
     30       1.1  thorpej  *
     31       1.1  thorpej  *	@(#)ct.c	8.1 (Berkeley) 7/15/93
     32       1.1  thorpej  */
     33       1.1  thorpej 
     34       1.1  thorpej /*
     35       1.1  thorpej  * CS80 tape driver
     36       1.1  thorpej  */
     37       1.1  thorpej #include <sys/param.h>
     38       1.1  thorpej 
     39  1.1.60.1    skrll #include <machine/stdarg.h>
     40  1.1.60.1    skrll 
     41       1.1  thorpej #include <hp300/dev/ctreg.h>
     42       1.1  thorpej 
     43       1.1  thorpej #include <lib/libsa/stand.h>
     44  1.1.60.1    skrll #include <hp300/stand/common/conf.h>
     45  1.1.60.1    skrll #include <hp300/stand/common/hpibvar.h>
     46       1.1  thorpej #include <hp300/stand/common/samachdep.h>
     47       1.1  thorpej 
     48       1.1  thorpej struct	ct_iocmd ct_ioc;
     49       1.1  thorpej struct	ct_rscmd ct_rsc;
     50       1.1  thorpej struct	ct_stat ct_stat;
     51       1.1  thorpej struct	ct_ssmcmd ct_ssmc;
     52       1.1  thorpej 
     53       1.1  thorpej struct	ct_softc {
     54       1.1  thorpej 	int	sc_ctlr;
     55       1.1  thorpej 	int	sc_unit;
     56       1.1  thorpej 	char	sc_retry;
     57       1.1  thorpej 	char	sc_alive;
     58       1.1  thorpej 	short	sc_punit;
     59       1.1  thorpej 	int	sc_blkno;
     60       1.1  thorpej } ct_softc[NHPIB][NCT];
     61       1.1  thorpej 
     62       1.1  thorpej #define	CTRETRY		5
     63       1.1  thorpej #define	MTFSF		10
     64       1.1  thorpej #define	MTREW		11
     65       1.1  thorpej 
     66       1.1  thorpej char ctio_buf[MAXBSIZE];
     67       1.1  thorpej 
     68       1.1  thorpej struct	ctinfo {
     69       1.1  thorpej 	short	hwid;
     70       1.1  thorpej 	short	punit;
     71       1.1  thorpej } ctinfo[] = {
     72  1.1.60.1    skrll 	{ CT7946ID,	1 },
     73  1.1.60.1    skrll 	{ CT7912PID,	1 },
     74  1.1.60.1    skrll 	{ CT7914PID,	1 },
     75  1.1.60.1    skrll 	{ CT9144ID,	0 },
     76  1.1.60.1    skrll 	{ CT9145ID,	0 },
     77       1.1  thorpej };
     78       1.1  thorpej int	nctinfo = sizeof(ctinfo) / sizeof(ctinfo[0]);
     79       1.1  thorpej 
     80  1.1.60.1    skrll static int ctinit(int, int);
     81  1.1.60.1    skrll static int ctident(int, int);
     82  1.1.60.1    skrll static int cterror(int, int);
     83  1.1.60.1    skrll 
     84  1.1.60.1    skrll int
     85       1.1  thorpej ctinit(ctlr, unit)
     86  1.1.60.1    skrll 	int ctlr, unit;
     87       1.1  thorpej {
     88  1.1.60.1    skrll 	struct ct_softc *rs = &ct_softc[ctlr][unit];
     89       1.1  thorpej 	u_char stat;
     90       1.1  thorpej 
     91       1.1  thorpej 	if (hpibrecv(ctlr, unit, C_QSTAT, &stat, 1) != 1 || stat)
     92  1.1.60.1    skrll 		return 0;
     93       1.1  thorpej 	if (ctident(ctlr, unit) < 0)
     94  1.1.60.1    skrll 		return 0;
     95  1.1.60.1    skrll 	memset(&ct_ssmc, 0, sizeof(ct_ssmc));
     96       1.1  thorpej 	ct_ssmc.unit = C_SUNIT(rs->sc_punit);
     97       1.1  thorpej 	ct_ssmc.cmd = C_SSM;
     98       1.1  thorpej 	ct_ssmc.fefm = FEF_MASK;
     99       1.1  thorpej 	ct_ssmc.refm = REF_MASK;
    100       1.1  thorpej 	ct_ssmc.aefm = AEF_MASK;
    101       1.1  thorpej 	ct_ssmc.iefm = IEF_MASK;
    102  1.1.60.1    skrll 	hpibsend(ctlr, unit, C_CMD, (char *)&ct_ssmc, sizeof(ct_ssmc));
    103       1.1  thorpej 	hpibswait(ctlr, unit);
    104       1.1  thorpej 	hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
    105       1.1  thorpej 	rs->sc_alive = 1;
    106  1.1.60.1    skrll 	return 1;
    107       1.1  thorpej }
    108       1.1  thorpej 
    109  1.1.60.1    skrll int
    110       1.1  thorpej ctident(ctlr, unit)
    111       1.1  thorpej 	int ctlr, unit;
    112       1.1  thorpej {
    113       1.1  thorpej 	struct ct_describe desc;
    114       1.1  thorpej 	u_char stat, cmd[3];
    115       1.1  thorpej 	char name[7];
    116       1.1  thorpej 	int id, i;
    117       1.1  thorpej 
    118       1.1  thorpej 	id = hpibid(ctlr, unit);
    119       1.1  thorpej 	if ((id & 0x200) == 0)
    120  1.1.60.1    skrll 		return -1;
    121       1.1  thorpej 	for (i = 0; i < nctinfo; i++)
    122       1.1  thorpej 		if (id == ctinfo[i].hwid)
    123       1.1  thorpej 			break;
    124       1.1  thorpej 	if (i == nctinfo)
    125  1.1.60.1    skrll 		return -1;
    126       1.1  thorpej 	ct_softc[ctlr][unit].sc_punit = ctinfo[i].punit;
    127       1.1  thorpej 	id = i;
    128       1.1  thorpej 
    129       1.1  thorpej 	/*
    130       1.1  thorpej 	 * Collect device description.
    131       1.1  thorpej 	 * Right now we only need this to differentiate 7945 from 7946.
    132       1.1  thorpej 	 * Note that we always issue the describe command to unit 0.
    133       1.1  thorpej 	 */
    134       1.1  thorpej 	cmd[0] = C_SUNIT(0);
    135       1.1  thorpej 	cmd[1] = C_SVOL(0);
    136       1.1  thorpej 	cmd[2] = C_DESC;
    137       1.1  thorpej 	hpibsend(ctlr, unit, C_CMD, cmd, sizeof(cmd));
    138  1.1.60.1    skrll 	hpibrecv(ctlr, unit, C_EXEC, (char *)&desc, 37);
    139       1.1  thorpej 	hpibrecv(ctlr, unit, C_QSTAT, &stat, sizeof(stat));
    140  1.1.60.1    skrll 	memset(name, 0, sizeof(name));
    141       1.1  thorpej 	if (!stat) {
    142  1.1.60.1    skrll 		int n = desc.d_name;
    143       1.1  thorpej 		for (i = 5; i >= 0; i--) {
    144       1.1  thorpej 			name[i] = (n & 0xf) + '0';
    145       1.1  thorpej 			n >>= 4;
    146       1.1  thorpej 		}
    147       1.1  thorpej 	}
    148       1.1  thorpej 	switch (ctinfo[id].hwid) {
    149       1.1  thorpej 	case CT7946ID:
    150  1.1.60.1    skrll 		if (memcmp(name, "079450", 6) == 0)
    151       1.1  thorpej 			id = -1;		/* not really a 7946 */
    152       1.1  thorpej 		break;
    153       1.1  thorpej 	default:
    154       1.1  thorpej 		break;
    155       1.1  thorpej 	}
    156  1.1.60.1    skrll 	return id;
    157       1.1  thorpej }
    158       1.1  thorpej 
    159       1.1  thorpej int
    160       1.1  thorpej ctpunit(ctlr, slave, punit)
    161       1.1  thorpej 	int ctlr, slave, *punit;
    162       1.1  thorpej {
    163  1.1.60.1    skrll 	struct ct_softc *rs;
    164       1.1  thorpej 
    165       1.1  thorpej 	if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
    166  1.1.60.1    skrll 		return EADAPT;
    167       1.1  thorpej 	if (slave >= NCT)
    168  1.1.60.1    skrll 		return ECTLR;
    169       1.1  thorpej 	rs = &ct_softc[ctlr][slave];
    170       1.1  thorpej 
    171       1.1  thorpej 	if (rs->sc_alive == 0)
    172  1.1.60.1    skrll 		return ENXIO;
    173       1.1  thorpej 
    174       1.1  thorpej 	*punit = rs->sc_punit;
    175  1.1.60.1    skrll 	return 0;
    176       1.1  thorpej }
    177       1.1  thorpej 
    178  1.1.60.1    skrll int
    179  1.1.60.1    skrll ctopen(struct open_file *f, ...)
    180       1.1  thorpej {
    181  1.1.60.1    skrll 	va_list ap;
    182  1.1.60.1    skrll 	int ctlr, unit, part;
    183  1.1.60.1    skrll 	struct ct_softc *rs;
    184  1.1.60.1    skrll 	int skip;
    185       1.1  thorpej 	size_t resid;
    186       1.1  thorpej 
    187  1.1.60.1    skrll 	va_start(ap, f);
    188  1.1.60.1    skrll 	ctlr = va_arg(ap, int);
    189  1.1.60.1    skrll 	unit = va_arg(ap, int);
    190  1.1.60.1    skrll 	part = va_arg(ap, int);
    191  1.1.60.1    skrll 	va_end(ap);
    192  1.1.60.1    skrll 
    193       1.1  thorpej 	if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
    194  1.1.60.1    skrll 		return EADAPT;
    195       1.1  thorpej 	if (unit >= NCT)
    196  1.1.60.1    skrll 		return ECTLR;
    197       1.1  thorpej 	rs = &ct_softc[ctlr][unit];
    198       1.1  thorpej 	rs->sc_blkno = 0;
    199       1.1  thorpej 	rs->sc_unit = unit;
    200       1.1  thorpej 	rs->sc_ctlr = ctlr;
    201       1.1  thorpej 	if (rs->sc_alive == 0)
    202       1.1  thorpej 		if (ctinit(ctlr, unit) == 0)
    203  1.1.60.1    skrll 			return ENXIO;
    204       1.1  thorpej 	f->f_devdata = (void *)rs;
    205       1.1  thorpej 	ctstrategy(f->f_devdata, MTREW, 0, 0, ctio_buf, &resid);
    206       1.1  thorpej 	skip = part;
    207       1.1  thorpej 	while (skip--)
    208       1.1  thorpej 		ctstrategy(f->f_devdata, MTFSF, 0, 0, ctio_buf, &resid);
    209  1.1.60.1    skrll 	return 0;
    210       1.1  thorpej }
    211       1.1  thorpej 
    212  1.1.60.1    skrll int
    213       1.1  thorpej ctclose(f)
    214       1.1  thorpej 	struct open_file *f;
    215       1.1  thorpej {
    216       1.1  thorpej 	size_t resid;
    217       1.1  thorpej 
    218       1.1  thorpej 	ctstrategy(f->f_devdata, MTREW, 0, 0, ctio_buf, &resid);
    219  1.1.60.1    skrll 	return 0;
    220       1.1  thorpej }
    221       1.1  thorpej 
    222  1.1.60.1    skrll int
    223       1.1  thorpej ctstrategy(devdata, func, dblk, size, v_buf, rsize)
    224       1.1  thorpej 	void *devdata;
    225       1.1  thorpej 	int func;
    226       1.1  thorpej 	daddr_t dblk;
    227       1.1  thorpej 	size_t size;
    228       1.1  thorpej 	void *v_buf;
    229       1.1  thorpej 	size_t *rsize;
    230       1.1  thorpej {
    231       1.1  thorpej 	struct ct_softc *rs = devdata;
    232       1.1  thorpej 	char *buf = v_buf;
    233       1.1  thorpej 	int ctlr = rs->sc_ctlr;
    234       1.1  thorpej 	int unit = rs->sc_unit;
    235       1.1  thorpej 	char stat;
    236       1.1  thorpej 
    237       1.1  thorpej 	if (size == 0 && (func == F_READ || func == F_WRITE))
    238  1.1.60.1    skrll 		return 0;
    239       1.1  thorpej 
    240       1.1  thorpej 	rs->sc_retry = 0;
    241  1.1.60.1    skrll 	memset(&ct_ioc, 0, sizeof(ct_ioc));
    242       1.1  thorpej 	ct_ioc.unit = C_SUNIT(rs->sc_punit);
    243       1.1  thorpej 	ct_ioc.saddr = C_SADDR;
    244       1.1  thorpej 	ct_ioc.nop2 = C_NOP;
    245       1.1  thorpej 	ct_ioc.slen = C_SLEN;
    246       1.1  thorpej 	ct_ioc.nop3 = C_NOP;
    247       1.1  thorpej top:
    248       1.1  thorpej 	if (func == F_READ) {
    249       1.1  thorpej 		ct_ioc.cmd = C_READ;
    250       1.1  thorpej 		ct_ioc.addr = rs->sc_blkno;
    251       1.1  thorpej 		ct_ioc.len = size;
    252       1.1  thorpej 	}
    253       1.1  thorpej 	else if (func == F_WRITE) {
    254       1.1  thorpej 		ct_ioc.cmd = C_WRITE;
    255       1.1  thorpej 		ct_ioc.addr = rs->sc_blkno;
    256       1.1  thorpej 		ct_ioc.len = size;
    257       1.1  thorpej 	}
    258       1.1  thorpej 	else if (func == MTFSF) {
    259       1.1  thorpej 		ct_ioc.cmd = C_READ;
    260       1.1  thorpej 		ct_ioc.addr = rs->sc_blkno;
    261       1.1  thorpej 		ct_ioc.len = size = MAXBSIZE;
    262       1.1  thorpej 	}
    263       1.1  thorpej 	else {
    264       1.1  thorpej 		ct_ioc.cmd = C_READ;
    265       1.1  thorpej 		ct_ioc.addr = 0;
    266       1.1  thorpej 		ct_ioc.len = 0;
    267       1.1  thorpej 		rs->sc_blkno = 0;
    268       1.1  thorpej 		size = 0;
    269       1.1  thorpej 	}
    270       1.1  thorpej retry:
    271  1.1.60.1    skrll 	hpibsend(ctlr, unit, C_CMD, (char *)&ct_ioc, sizeof(ct_ioc));
    272       1.1  thorpej 	if (func != MTREW) {
    273       1.1  thorpej 		hpibswait(ctlr, unit);
    274       1.1  thorpej 		hpibgo(ctlr, unit, C_EXEC, buf, size,
    275       1.1  thorpej 			func != F_WRITE ? F_READ : F_WRITE);
    276       1.1  thorpej 		hpibswait(ctlr, unit);
    277       1.1  thorpej 	} else {
    278       1.1  thorpej 		while (hpibswait(ctlr, unit) < 0)
    279       1.1  thorpej 			;
    280       1.1  thorpej 	}
    281       1.1  thorpej 	hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
    282       1.1  thorpej 	if (stat) {
    283       1.1  thorpej 		stat = cterror(ctlr, unit);
    284       1.1  thorpej 		if (stat == 0)
    285  1.1.60.1    skrll 			return -1;
    286       1.1  thorpej 		if (stat == 2)
    287  1.1.60.1    skrll 			return 0;
    288       1.1  thorpej 		if (++rs->sc_retry > CTRETRY)
    289  1.1.60.1    skrll 			return -1;
    290       1.1  thorpej 		goto retry;
    291       1.1  thorpej 	}
    292       1.1  thorpej 	rs->sc_blkno += CTBTOK(size);
    293       1.1  thorpej 	if (func == MTFSF)
    294       1.1  thorpej 		goto top;
    295       1.1  thorpej 	*rsize = size;
    296       1.1  thorpej 
    297  1.1.60.1    skrll 	return 0;
    298       1.1  thorpej }
    299       1.1  thorpej 
    300  1.1.60.1    skrll int
    301       1.1  thorpej cterror(ctlr, unit)
    302  1.1.60.1    skrll 	int ctlr, unit;
    303       1.1  thorpej {
    304  1.1.60.1    skrll 	struct ct_softc *rs = &ct_softc[ctlr][unit];
    305       1.1  thorpej 	char stat;
    306       1.1  thorpej 
    307  1.1.60.1    skrll 	memset(&ct_rsc, 0, sizeof(ct_rsc));
    308  1.1.60.1    skrll 	memset(&ct_stat, 0, sizeof(ct_stat));
    309       1.1  thorpej 	ct_rsc.unit = C_SUNIT(rs->sc_punit);
    310       1.1  thorpej 	ct_rsc.cmd = C_STATUS;
    311  1.1.60.1    skrll 	hpibsend(ctlr, unit, C_CMD, (char *)&ct_rsc, sizeof(ct_rsc));
    312  1.1.60.1    skrll 	hpibrecv(ctlr, unit, C_EXEC, (char *)&ct_stat, sizeof(ct_stat));
    313       1.1  thorpej 	hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
    314       1.1  thorpej 	if (stat) {
    315       1.1  thorpej 		printf("ct%d: request status fail %d\n", unit, stat);
    316  1.1.60.1    skrll 		return 0;
    317       1.1  thorpej 	}
    318       1.1  thorpej 	if (ct_stat.c_aef & AEF_EOF) {
    319       1.1  thorpej 		/* 9145 drives don't increment block number at EOF */
    320       1.1  thorpej 		if ((ct_stat.c_blk - rs->sc_blkno) == 0)
    321       1.1  thorpej 			rs->sc_blkno++;
    322       1.1  thorpej 		else
    323       1.1  thorpej 			rs->sc_blkno = ct_stat.c_blk;
    324  1.1.60.1    skrll 		return 2;
    325       1.1  thorpej 	}
    326  1.1.60.1    skrll 	printf("ct%d err: vu 0x%x, pend 0x%x, bn%ld", unit,
    327  1.1.60.1    skrll 	    ct_stat.c_vu, ct_stat.c_pend, ct_stat.c_blk);
    328       1.1  thorpej 	printf(", R 0x%x F 0x%x A 0x%x I 0x%x\n", ct_stat.c_ref,
    329  1.1.60.1    skrll 	    ct_stat.c_fef, ct_stat.c_aef, ct_stat.c_ief);
    330  1.1.60.1    skrll 	return 1;
    331       1.1  thorpej }
    332