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