xref: /original-bsd/sys/vax/stand/uda.c (revision d6141097)
1 /*	uda.c	4.2	82/07/15	*/
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 "../h/fs.h"
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 "../h/udareg.h"
24 #include "../h/mscp.h"
25 
26 
27 u_short udastd[] = { 0777550 };
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 udopen(io)
46 	register struct iob *io;
47 {
48 	register struct mscp *mp;
49 	int i;
50 
51 	if (udaddr == 0)
52 		udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]);
53 	if (ud_ubaddr == 0) {
54 		cudbuf.i_ma = (caddr_t)&uda;
55 		cudbuf.i_cc = sizeof(uda);
56 		ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2);
57 	}
58 	udaddr->udaip = 0;
59 	while ((udaddr->udasa & UDA_STEP1) == 0)
60 		;
61 	udaddr->udasa = UDA_ERR;
62 	while ((udaddr->udasa & UDA_STEP2) == 0)
63 		;
64 	udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase;
65 	while ((udaddr->udasa & UDA_STEP3) == 0)
66 		;
67 	udaddr->udasa = (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16);
68 	while ((udaddr->udasa & UDA_STEP4) == 0)
69 		;
70 	udaddr->udasa = UDA_GO;
71 	uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref;
72 	uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref;
73 	uda.uda_cmd.mscp_cntflgs = 0;
74 	if (udcmd(M_OP_STCON) == 0) {
75 		_stop("ra: open error, STCON");
76 		return;
77 	}
78 	uda.uda_cmd.mscp_unit = io->i_unit&7;
79 	if (udcmd(M_OP_ONLIN) == 0) {
80 		_stop("ra: open error, ONLIN");
81 		return;
82 	}
83 	if (io->i_boff < 0 || io->i_boff > 7 || uda_off[io->i_boff] == -1)
84 		_stop("ra: bad unit");
85 	io->i_boff = uda_off[io->i_boff];
86 }
87 
88 struct mscp *
89 udcmd(op)
90 	int op;
91 {
92 	struct mscp *mp;
93 	int i;
94 
95 	uda.uda_cmd.mscp_opcode = op;
96 	uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp);
97 	uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp);
98 	uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT;
99 	uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT;
100 	i = udaddr->udaip;
101 	for (;;) {
102 		if (uda.uda_ca.ca_cmdint)
103 			uda.uda_ca.ca_cmdint = 0;
104 		if (uda.uda_ca.ca_rspint)
105 			break;
106 	}
107 	uda.uda_ca.ca_rspint = 0;
108 	mp = &uda.uda_rsp;
109 	if (mp->mscp_opcode != (op|M_OP_END) ||
110 	    (mp->mscp_status&M_ST_MASK) != M_ST_SUCC)
111 		return(0);
112 	return(mp);
113 }
114 
115 udstrategy(io, func)
116 	register struct iob *io;
117 {
118 	register struct mscp *mp;
119 	int ubinfo;
120 
121 	ubinfo = ubasetup(io, 1);
122 	mp = &uda.uda_cmd;
123 	mp->mscp_lbn = io->i_bn;
124 	mp->mscp_unit = io->i_unit&7;
125 	mp->mscp_bytecnt = io->i_cc;
126 	mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
127 	if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) {
128 		printf("ra: I/O error\n");
129 		ubafree(io, ubinfo);
130 		return(-1);
131 	}
132 	ubafree(io, ubinfo);
133 	return(io->i_cc);
134 }
135