xref: /csrg-svn/sys/vax/stand/uda.c (revision 27075)
123247Smckusick /*
223247Smckusick  * Copyright (c) 1982 Regents of the University of California.
323247Smckusick  * All rights reserved.  The Berkeley software License Agreement
423247Smckusick  * specifies the terms and conditions for redistribution.
523247Smckusick  *
6*27075Skarels  *	@(#)uda.c	6.4 (Berkeley) 04/14/86
723247Smckusick  */
85153Ssam 
95153Ssam /*
105153Ssam  * UDA50/RAxx disk device driver
115153Ssam  */
129806Ssam #include "../machine/pte.h"
135153Ssam 
145153Ssam #include "../h/param.h"
155153Ssam #include "../h/inode.h"
167447Sroot #include "../h/fs.h"
179186Ssam 
185153Ssam #include "saio.h"
195153Ssam #include "savax.h"
205153Ssam 
21*27075Skarels #define	NRA	4
225153Ssam /*
235153Ssam  * Parameters for the communications area
245153Ssam  */
255153Ssam #define	NRSPL2	0
265153Ssam #define	NCMDL2	0
275153Ssam #define	NRSP	(1<<NRSPL2)
285153Ssam #define	NCMD	(1<<NCMDL2)
295153Ssam 
309186Ssam #include "../vaxuba/udareg.h"
319186Ssam #include "../vaxuba/ubareg.h"
329186Ssam #include "../vax/mscp.h"
335153Ssam 
3411181Ssam u_short udastd[] = { 0772150 };
355153Ssam 
365153Ssam struct iob	cudbuf;
375153Ssam 
385153Ssam struct udadevice *udaddr = 0;
395153Ssam 
405153Ssam struct uda {
415153Ssam 	struct udaca	uda_ca;
425153Ssam 	struct mscp	uda_rsp;
435153Ssam 	struct mscp	uda_cmd;
445153Ssam } uda;
455153Ssam 
465153Ssam struct uda *ud_ubaddr;			/* Unibus address of uda structure */
475153Ssam 
48*27075Skarels int ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
49*27075Skarels int ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
50*27075Skarels int ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
51*27075Skarels #ifndef	UCBRA
52*27075Skarels #ifdef RA_COMPAT
53*27075Skarels int ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
54*27075Skarels #else
55*27075Skarels int ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
56*27075Skarels #endif
57*27075Skarels #else
58*27075Skarels int ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
59*27075Skarels #endif
605153Ssam 
615153Ssam struct mscp *udcmd();
62*27075Skarels static int ratype[NRA];
635153Ssam 
6411111Ssam raopen(io)
655153Ssam 	register struct iob *io;
665153Ssam {
675153Ssam 	register struct mscp *mp;
68*27075Skarels 	static int udainit, udadriveinit[NRA];
695153Ssam 	int i;
70*27075Skarels 	daddr_t off;
715153Ssam 
725153Ssam 	if (udaddr == 0)
735153Ssam 		udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]);
745153Ssam 	if (ud_ubaddr == 0) {
7517231Smckusick 		/*
7617231Smckusick 		 * Initialise cudbuf.i_unit so that controllers
7717231Smckusick 		 * on UNIBUSes other than 0 can be used.
7817231Smckusick 		 */
7917231Smckusick 		cudbuf.i_unit = io->i_unit;
805153Ssam 		cudbuf.i_ma = (caddr_t)&uda;
815153Ssam 		cudbuf.i_cc = sizeof(uda);
825153Ssam 		ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2);
835153Ssam 	}
8417231Smckusick 	if (udainit == 0) {
8517231Smckusick 		udaddr->udaip = 0;
8617231Smckusick 		while ((udaddr->udasa & UDA_STEP1) == 0)
8717231Smckusick 			;
8817231Smckusick 		udaddr->udasa = UDA_ERR;
8917231Smckusick 		while ((udaddr->udasa & UDA_STEP2) == 0)
9017231Smckusick 			;
9117231Smckusick 		udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase;
9217231Smckusick 		while ((udaddr->udasa & UDA_STEP3) == 0)
9317231Smckusick 			;
9417231Smckusick 		udaddr->udasa =
9517231Smckusick 			(short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16);
9617231Smckusick 		while ((udaddr->udasa & UDA_STEP4) == 0)
9717231Smckusick 			;
9817231Smckusick 		udaddr->udasa = UDA_GO;
9917231Smckusick 		uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref;
10017231Smckusick 		uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref;
10117231Smckusick 		uda.uda_cmd.mscp_cntflgs = 0;
10217231Smckusick 		if (udcmd(M_OP_STCON) == 0) {
10317231Smckusick 			_stop("ra: open error, STCON");
10417231Smckusick 			return;
10517231Smckusick 		}
106*27075Skarels 	}
107*27075Skarels 	i = io->i_unit & 7;
108*27075Skarels 	if (udadriveinit[i] == 0) {
109*27075Skarels 		uda.uda_cmd.mscp_unit = i;
11017231Smckusick 		if (udcmd(M_OP_ONLIN) == 0) {
11117231Smckusick 			_stop("ra: open error, ONLIN");
11217231Smckusick 			return;
11317231Smckusick 		}
11417231Smckusick 		udainit = 1;
1155153Ssam 	}
116*27075Skarels 	if (io->i_boff < 0 || io->i_boff > 7)
1175153Ssam 		_stop("ra: bad unit");
118*27075Skarels 
119*27075Skarels 	switch (ratype[i]) {
120*27075Skarels 	case    25:
121*27075Skarels 		off = ra25_off[io->i_boff];
122*27075Skarels 		break;
123*27075Skarels 	case    60:
124*27075Skarels 		off = ra60_off[io->i_boff];
125*27075Skarels 		break;
126*27075Skarels 	case    80:
127*27075Skarels 		off = ra80_off[io->i_boff];
128*27075Skarels 		break;
129*27075Skarels 	case    81:
130*27075Skarels 		off = ra81_off[io->i_boff];
131*27075Skarels 		break;
132*27075Skarels 	default:
133*27075Skarels 		printf("uda%d: don't support ra%d's\n", i, ratype[i]);
134*27075Skarels 		off = -1;
135*27075Skarels 		break;
136*27075Skarels 	}
137*27075Skarels 	if (off == -1)
138*27075Skarels 		_stop("ra: bad partition");
139*27075Skarels 	io->i_boff = off;
1405153Ssam }
1415153Ssam 
1425153Ssam struct mscp *
1435153Ssam udcmd(op)
1445153Ssam 	int op;
1455153Ssam {
1465153Ssam 	struct mscp *mp;
1475153Ssam 	int i;
1485153Ssam 
1495153Ssam 	uda.uda_cmd.mscp_opcode = op;
1505153Ssam 	uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp);
1515153Ssam 	uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp);
1525153Ssam 	uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT;
1535153Ssam 	uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT;
1545153Ssam 	i = udaddr->udaip;
1555153Ssam 	for (;;) {
1565153Ssam 		if (uda.uda_ca.ca_cmdint)
1575153Ssam 			uda.uda_ca.ca_cmdint = 0;
1585153Ssam 		if (uda.uda_ca.ca_rspint)
1595153Ssam 			break;
1605153Ssam 	}
1615153Ssam 	uda.uda_ca.ca_rspint = 0;
1625153Ssam 	mp = &uda.uda_rsp;
1635153Ssam 	if (mp->mscp_opcode != (op|M_OP_END) ||
1645153Ssam 	    (mp->mscp_status&M_ST_MASK) != M_ST_SUCC)
1655153Ssam 		return(0);
166*27075Skarels 	if (mp->mscp_opcode == (M_OP_ONLIN|M_OP_END))
167*27075Skarels 		ratype[uda.uda_cmd.mscp_unit] = mp->mscp_mediaid & 0x7f;
1685153Ssam 	return(mp);
1695153Ssam }
1705153Ssam 
17111111Ssam rastrategy(io, func)
1725153Ssam 	register struct iob *io;
1735153Ssam {
1745153Ssam 	register struct mscp *mp;
1755153Ssam 	int ubinfo;
1765153Ssam 
1775153Ssam 	ubinfo = ubasetup(io, 1);
1785153Ssam 	mp = &uda.uda_cmd;
1795153Ssam 	mp->mscp_lbn = io->i_bn;
1805153Ssam 	mp->mscp_unit = io->i_unit&7;
1815153Ssam 	mp->mscp_bytecnt = io->i_cc;
1825153Ssam 	mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
1835153Ssam 	if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) {
1845153Ssam 		printf("ra: I/O error\n");
1855153Ssam 		ubafree(io, ubinfo);
1865153Ssam 		return(-1);
1875153Ssam 	}
1885153Ssam 	ubafree(io, ubinfo);
1895153Ssam 	return(io->i_cc);
1905153Ssam }
19110024Ssam 
19210024Ssam /*ARGSUSED*/
19311111Ssam raioctl(io, cmd, arg)
19410024Ssam 	struct iob *io;
19510024Ssam 	int cmd;
19610024Ssam 	caddr_t arg;
19710024Ssam {
19810024Ssam 
19910024Ssam 	return (ECMD);
20010024Ssam }
201