xref: /csrg-svn/sys/vax/stand/uda.c (revision 10024)
1*10024Ssam /*	uda.c	4.5	82/12/30	*/
25153Ssam 
35153Ssam /*
45153Ssam  * UDA50/RAxx disk device driver
55153Ssam  */
69806Ssam #include "../machine/pte.h"
75153Ssam 
85153Ssam #include "../h/param.h"
95153Ssam #include "../h/inode.h"
107447Sroot #include "../h/fs.h"
119186Ssam 
125153Ssam #include "saio.h"
135153Ssam #include "savax.h"
145153Ssam 
155153Ssam /*
165153Ssam  * Parameters for the communications area
175153Ssam  */
185153Ssam #define	NRSPL2	0
195153Ssam #define	NCMDL2	0
205153Ssam #define	NRSP	(1<<NRSPL2)
215153Ssam #define	NCMD	(1<<NCMDL2)
225153Ssam 
239186Ssam #include "../vaxuba/udareg.h"
249186Ssam #include "../vaxuba/ubareg.h"
259186Ssam #include "../vax/mscp.h"
265153Ssam 
275153Ssam u_short udastd[] = { 0777550 };
285153Ssam 
295153Ssam struct iob	cudbuf;
305153Ssam 
315153Ssam struct udadevice *udaddr = 0;
325153Ssam 
335153Ssam struct uda {
345153Ssam 	struct udaca	uda_ca;
355153Ssam 	struct mscp	uda_rsp;
365153Ssam 	struct mscp	uda_cmd;
375153Ssam } uda;
385153Ssam 
395153Ssam struct uda *ud_ubaddr;			/* Unibus address of uda structure */
405153Ssam 
415153Ssam int uda_off[] = { 0, 15884, 0, -1, -1, -1, 49324, 131404 };
425153Ssam 
435153Ssam struct mscp *udcmd();
445153Ssam 
455153Ssam udopen(io)
465153Ssam 	register struct iob *io;
475153Ssam {
485153Ssam 	register struct mscp *mp;
495153Ssam 	int i;
505153Ssam 
515153Ssam 	if (udaddr == 0)
525153Ssam 		udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]);
535153Ssam 	if (ud_ubaddr == 0) {
545153Ssam 		cudbuf.i_ma = (caddr_t)&uda;
555153Ssam 		cudbuf.i_cc = sizeof(uda);
565153Ssam 		ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2);
575153Ssam 	}
585153Ssam 	udaddr->udaip = 0;
595153Ssam 	while ((udaddr->udasa & UDA_STEP1) == 0)
605153Ssam 		;
615153Ssam 	udaddr->udasa = UDA_ERR;
625153Ssam 	while ((udaddr->udasa & UDA_STEP2) == 0)
635153Ssam 		;
645153Ssam 	udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase;
655153Ssam 	while ((udaddr->udasa & UDA_STEP3) == 0)
665153Ssam 		;
675153Ssam 	udaddr->udasa = (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16);
685153Ssam 	while ((udaddr->udasa & UDA_STEP4) == 0)
695153Ssam 		;
705153Ssam 	udaddr->udasa = UDA_GO;
715153Ssam 	uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref;
725153Ssam 	uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref;
735153Ssam 	uda.uda_cmd.mscp_cntflgs = 0;
745153Ssam 	if (udcmd(M_OP_STCON) == 0) {
755153Ssam 		_stop("ra: open error, STCON");
765153Ssam 		return;
775153Ssam 	}
785153Ssam 	uda.uda_cmd.mscp_unit = io->i_unit&7;
795153Ssam 	if (udcmd(M_OP_ONLIN) == 0) {
805153Ssam 		_stop("ra: open error, ONLIN");
815153Ssam 		return;
825153Ssam 	}
835153Ssam 	if (io->i_boff < 0 || io->i_boff > 7 || uda_off[io->i_boff] == -1)
845153Ssam 		_stop("ra: bad unit");
855153Ssam 	io->i_boff = uda_off[io->i_boff];
865153Ssam }
875153Ssam 
885153Ssam struct mscp *
895153Ssam udcmd(op)
905153Ssam 	int op;
915153Ssam {
925153Ssam 	struct mscp *mp;
935153Ssam 	int i;
945153Ssam 
955153Ssam 	uda.uda_cmd.mscp_opcode = op;
965153Ssam 	uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp);
975153Ssam 	uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp);
985153Ssam 	uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT;
995153Ssam 	uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT;
1005153Ssam 	i = udaddr->udaip;
1015153Ssam 	for (;;) {
1025153Ssam 		if (uda.uda_ca.ca_cmdint)
1035153Ssam 			uda.uda_ca.ca_cmdint = 0;
1045153Ssam 		if (uda.uda_ca.ca_rspint)
1055153Ssam 			break;
1065153Ssam 	}
1075153Ssam 	uda.uda_ca.ca_rspint = 0;
1085153Ssam 	mp = &uda.uda_rsp;
1095153Ssam 	if (mp->mscp_opcode != (op|M_OP_END) ||
1105153Ssam 	    (mp->mscp_status&M_ST_MASK) != M_ST_SUCC)
1115153Ssam 		return(0);
1125153Ssam 	return(mp);
1135153Ssam }
1145153Ssam 
1155153Ssam udstrategy(io, func)
1165153Ssam 	register struct iob *io;
1175153Ssam {
1185153Ssam 	register struct mscp *mp;
1195153Ssam 	int ubinfo;
1205153Ssam 
1215153Ssam 	ubinfo = ubasetup(io, 1);
1225153Ssam 	mp = &uda.uda_cmd;
1235153Ssam 	mp->mscp_lbn = io->i_bn;
1245153Ssam 	mp->mscp_unit = io->i_unit&7;
1255153Ssam 	mp->mscp_bytecnt = io->i_cc;
1265153Ssam 	mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
1275153Ssam 	if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) {
1285153Ssam 		printf("ra: I/O error\n");
1295153Ssam 		ubafree(io, ubinfo);
1305153Ssam 		return(-1);
1315153Ssam 	}
1325153Ssam 	ubafree(io, ubinfo);
1335153Ssam 	return(io->i_cc);
1345153Ssam }
135*10024Ssam 
136*10024Ssam /*ARGSUSED*/
137*10024Ssam udioctl(io, cmd, arg)
138*10024Ssam 	struct iob *io;
139*10024Ssam 	int cmd;
140*10024Ssam 	caddr_t arg;
141*10024Ssam {
142*10024Ssam 
143*10024Ssam 	return (ECMD);
144*10024Ssam }
145