xref: /csrg-svn/sys/vax/stand/uda.c (revision 23247)
1*23247Smckusick /*
2*23247Smckusick  * Copyright (c) 1982 Regents of the University of California.
3*23247Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*23247Smckusick  * specifies the terms and conditions for redistribution.
5*23247Smckusick  *
6*23247Smckusick  *	@(#)uda.c	6.3 (Berkeley) 06/08/85
7*23247Smckusick  */
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 
215153Ssam /*
225153Ssam  * Parameters for the communications area
235153Ssam  */
245153Ssam #define	NRSPL2	0
255153Ssam #define	NCMDL2	0
265153Ssam #define	NRSP	(1<<NRSPL2)
275153Ssam #define	NCMD	(1<<NCMDL2)
285153Ssam 
299186Ssam #include "../vaxuba/udareg.h"
309186Ssam #include "../vaxuba/ubareg.h"
319186Ssam #include "../vax/mscp.h"
325153Ssam 
3311181Ssam u_short udastd[] = { 0772150 };
345153Ssam 
355153Ssam struct iob	cudbuf;
365153Ssam 
375153Ssam struct udadevice *udaddr = 0;
385153Ssam 
395153Ssam struct uda {
405153Ssam 	struct udaca	uda_ca;
415153Ssam 	struct mscp	uda_rsp;
425153Ssam 	struct mscp	uda_cmd;
435153Ssam } uda;
445153Ssam 
455153Ssam struct uda *ud_ubaddr;			/* Unibus address of uda structure */
465153Ssam 
475153Ssam int uda_off[] = { 0, 15884, 0, -1, -1, -1, 49324, 131404 };
485153Ssam 
495153Ssam struct mscp *udcmd();
505153Ssam 
5111111Ssam raopen(io)
525153Ssam 	register struct iob *io;
535153Ssam {
545153Ssam 	register struct mscp *mp;
5517231Smckusick 	static int udainit;
565153Ssam 	int i;
575153Ssam 
585153Ssam 	if (udaddr == 0)
595153Ssam 		udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]);
605153Ssam 	if (ud_ubaddr == 0) {
6117231Smckusick 		/*
6217231Smckusick 		 * Initialise cudbuf.i_unit so that controllers
6317231Smckusick 		 * on UNIBUSes other than 0 can be used.
6417231Smckusick 		 */
6517231Smckusick 		cudbuf.i_unit = io->i_unit;
665153Ssam 		cudbuf.i_ma = (caddr_t)&uda;
675153Ssam 		cudbuf.i_cc = sizeof(uda);
685153Ssam 		ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2);
695153Ssam 	}
7017231Smckusick 	if (udainit == 0) {
7117231Smckusick 		udaddr->udaip = 0;
7217231Smckusick 		while ((udaddr->udasa & UDA_STEP1) == 0)
7317231Smckusick 			;
7417231Smckusick 		udaddr->udasa = UDA_ERR;
7517231Smckusick 		while ((udaddr->udasa & UDA_STEP2) == 0)
7617231Smckusick 			;
7717231Smckusick 		udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase;
7817231Smckusick 		while ((udaddr->udasa & UDA_STEP3) == 0)
7917231Smckusick 			;
8017231Smckusick 		udaddr->udasa =
8117231Smckusick 			(short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16);
8217231Smckusick 		while ((udaddr->udasa & UDA_STEP4) == 0)
8317231Smckusick 			;
8417231Smckusick 		udaddr->udasa = UDA_GO;
8517231Smckusick 		uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref;
8617231Smckusick 		uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref;
8717231Smckusick 		uda.uda_cmd.mscp_cntflgs = 0;
8817231Smckusick 		if (udcmd(M_OP_STCON) == 0) {
8917231Smckusick 			_stop("ra: open error, STCON");
9017231Smckusick 			return;
9117231Smckusick 		}
9217231Smckusick 		uda.uda_cmd.mscp_unit = io->i_unit&7;
9317231Smckusick 		if (udcmd(M_OP_ONLIN) == 0) {
9417231Smckusick 			_stop("ra: open error, ONLIN");
9517231Smckusick 			return;
9617231Smckusick 		}
9717231Smckusick 		udainit = 1;
985153Ssam 	}
995153Ssam 	if (io->i_boff < 0 || io->i_boff > 7 || uda_off[io->i_boff] == -1)
1005153Ssam 		_stop("ra: bad unit");
1015153Ssam 	io->i_boff = uda_off[io->i_boff];
1025153Ssam }
1035153Ssam 
1045153Ssam struct mscp *
1055153Ssam udcmd(op)
1065153Ssam 	int op;
1075153Ssam {
1085153Ssam 	struct mscp *mp;
1095153Ssam 	int i;
1105153Ssam 
1115153Ssam 	uda.uda_cmd.mscp_opcode = op;
1125153Ssam 	uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp);
1135153Ssam 	uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp);
1145153Ssam 	uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT;
1155153Ssam 	uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT;
1165153Ssam 	i = udaddr->udaip;
1175153Ssam 	for (;;) {
1185153Ssam 		if (uda.uda_ca.ca_cmdint)
1195153Ssam 			uda.uda_ca.ca_cmdint = 0;
1205153Ssam 		if (uda.uda_ca.ca_rspint)
1215153Ssam 			break;
1225153Ssam 	}
1235153Ssam 	uda.uda_ca.ca_rspint = 0;
1245153Ssam 	mp = &uda.uda_rsp;
1255153Ssam 	if (mp->mscp_opcode != (op|M_OP_END) ||
1265153Ssam 	    (mp->mscp_status&M_ST_MASK) != M_ST_SUCC)
1275153Ssam 		return(0);
1285153Ssam 	return(mp);
1295153Ssam }
1305153Ssam 
13111111Ssam rastrategy(io, func)
1325153Ssam 	register struct iob *io;
1335153Ssam {
1345153Ssam 	register struct mscp *mp;
1355153Ssam 	int ubinfo;
1365153Ssam 
1375153Ssam 	ubinfo = ubasetup(io, 1);
1385153Ssam 	mp = &uda.uda_cmd;
1395153Ssam 	mp->mscp_lbn = io->i_bn;
1405153Ssam 	mp->mscp_unit = io->i_unit&7;
1415153Ssam 	mp->mscp_bytecnt = io->i_cc;
1425153Ssam 	mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
1435153Ssam 	if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) {
1445153Ssam 		printf("ra: I/O error\n");
1455153Ssam 		ubafree(io, ubinfo);
1465153Ssam 		return(-1);
1475153Ssam 	}
1485153Ssam 	ubafree(io, ubinfo);
1495153Ssam 	return(io->i_cc);
1505153Ssam }
15110024Ssam 
15210024Ssam /*ARGSUSED*/
15311111Ssam raioctl(io, cmd, arg)
15410024Ssam 	struct iob *io;
15510024Ssam 	int cmd;
15610024Ssam 	caddr_t arg;
15710024Ssam {
15810024Ssam 
15910024Ssam 	return (ECMD);
16010024Ssam }
161