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