xref: /csrg-svn/sys/vax/stand/uda.c (revision 17231)
1 /*	uda.c	6.2	84/10/04	*/
2 
3 /*
4  * UDA50/RAxx disk device driver
5  */
6 #include "../machine/pte.h"
7 
8 #include "../h/param.h"
9 #include "../h/inode.h"
10 #include "../h/fs.h"
11 
12 #include "saio.h"
13 #include "savax.h"
14 
15 /*
16  * Parameters for the communications area
17  */
18 #define	NRSPL2	0
19 #define	NCMDL2	0
20 #define	NRSP	(1<<NRSPL2)
21 #define	NCMD	(1<<NCMDL2)
22 
23 #include "../vaxuba/udareg.h"
24 #include "../vaxuba/ubareg.h"
25 #include "../vax/mscp.h"
26 
27 u_short udastd[] = { 0772150 };
28 
29 struct iob	cudbuf;
30 
31 struct udadevice *udaddr = 0;
32 
33 struct uda {
34 	struct udaca	uda_ca;
35 	struct mscp	uda_rsp;
36 	struct mscp	uda_cmd;
37 } uda;
38 
39 struct uda *ud_ubaddr;			/* Unibus address of uda structure */
40 
41 int uda_off[] = { 0, 15884, 0, -1, -1, -1, 49324, 131404 };
42 
43 struct mscp *udcmd();
44 
45 raopen(io)
46 	register struct iob *io;
47 {
48 	register struct mscp *mp;
49 	static int udainit;
50 	int i;
51 
52 	if (udaddr == 0)
53 		udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]);
54 	if (ud_ubaddr == 0) {
55 		/*
56 		 * Initialise cudbuf.i_unit so that controllers
57 		 * on UNIBUSes other than 0 can be used.
58 		 */
59 		cudbuf.i_unit = io->i_unit;
60 		cudbuf.i_ma = (caddr_t)&uda;
61 		cudbuf.i_cc = sizeof(uda);
62 		ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2);
63 	}
64 	if (udainit == 0) {
65 		udaddr->udaip = 0;
66 		while ((udaddr->udasa & UDA_STEP1) == 0)
67 			;
68 		udaddr->udasa = UDA_ERR;
69 		while ((udaddr->udasa & UDA_STEP2) == 0)
70 			;
71 		udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase;
72 		while ((udaddr->udasa & UDA_STEP3) == 0)
73 			;
74 		udaddr->udasa =
75 			(short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16);
76 		while ((udaddr->udasa & UDA_STEP4) == 0)
77 			;
78 		udaddr->udasa = UDA_GO;
79 		uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref;
80 		uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref;
81 		uda.uda_cmd.mscp_cntflgs = 0;
82 		if (udcmd(M_OP_STCON) == 0) {
83 			_stop("ra: open error, STCON");
84 			return;
85 		}
86 		uda.uda_cmd.mscp_unit = io->i_unit&7;
87 		if (udcmd(M_OP_ONLIN) == 0) {
88 			_stop("ra: open error, ONLIN");
89 			return;
90 		}
91 		udainit = 1;
92 	}
93 	if (io->i_boff < 0 || io->i_boff > 7 || uda_off[io->i_boff] == -1)
94 		_stop("ra: bad unit");
95 	io->i_boff = uda_off[io->i_boff];
96 }
97 
98 struct mscp *
99 udcmd(op)
100 	int op;
101 {
102 	struct mscp *mp;
103 	int i;
104 
105 	uda.uda_cmd.mscp_opcode = op;
106 	uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp);
107 	uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp);
108 	uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT;
109 	uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT;
110 	i = udaddr->udaip;
111 	for (;;) {
112 		if (uda.uda_ca.ca_cmdint)
113 			uda.uda_ca.ca_cmdint = 0;
114 		if (uda.uda_ca.ca_rspint)
115 			break;
116 	}
117 	uda.uda_ca.ca_rspint = 0;
118 	mp = &uda.uda_rsp;
119 	if (mp->mscp_opcode != (op|M_OP_END) ||
120 	    (mp->mscp_status&M_ST_MASK) != M_ST_SUCC)
121 		return(0);
122 	return(mp);
123 }
124 
125 rastrategy(io, func)
126 	register struct iob *io;
127 {
128 	register struct mscp *mp;
129 	int ubinfo;
130 
131 	ubinfo = ubasetup(io, 1);
132 	mp = &uda.uda_cmd;
133 	mp->mscp_lbn = io->i_bn;
134 	mp->mscp_unit = io->i_unit&7;
135 	mp->mscp_bytecnt = io->i_cc;
136 	mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
137 	if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) {
138 		printf("ra: I/O error\n");
139 		ubafree(io, ubinfo);
140 		return(-1);
141 	}
142 	ubafree(io, ubinfo);
143 	return(io->i_cc);
144 }
145 
146 /*ARGSUSED*/
147 raioctl(io, cmd, arg)
148 	struct iob *io;
149 	int cmd;
150 	caddr_t arg;
151 {
152 
153 	return (ECMD);
154 }
155