Commit | Line | Data |
---|---|---|
da7c5cc6 KM |
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) %G% | |
7 | */ | |
788aa549 SL |
8 | |
9 | /* | |
10 | * UDA50/RAxx disk device driver | |
11 | */ | |
faeec66d | 12 | #include "../machine/pte.h" |
788aa549 SL |
13 | |
14 | #include "../h/param.h" | |
15 | #include "../h/inode.h" | |
b5d17f4d | 16 | #include "../h/fs.h" |
a031a31b | 17 | |
788aa549 SL |
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 | ||
a031a31b SL |
29 | #include "../vaxuba/udareg.h" |
30 | #include "../vaxuba/ubareg.h" | |
31 | #include "../vax/mscp.h" | |
788aa549 | 32 | |
840c0e98 | 33 | u_short udastd[] = { 0772150 }; |
788aa549 SL |
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 | ||
76780d43 | 51 | raopen(io) |
788aa549 SL |
52 | register struct iob *io; |
53 | { | |
54 | register struct mscp *mp; | |
e0fcb4e0 | 55 | static int udainit; |
788aa549 SL |
56 | int i; |
57 | ||
58 | if (udaddr == 0) | |
59 | udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]); | |
60 | if (ud_ubaddr == 0) { | |
e0fcb4e0 KM |
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; | |
788aa549 SL |
66 | cudbuf.i_ma = (caddr_t)&uda; |
67 | cudbuf.i_cc = sizeof(uda); | |
68 | ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2); | |
69 | } | |
e0fcb4e0 KM |
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; | |
788aa549 SL |
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 | ||
76780d43 | 131 | rastrategy(io, func) |
788aa549 SL |
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 | } | |
75f313ad SL |
151 | |
152 | /*ARGSUSED*/ | |
76780d43 | 153 | raioctl(io, cmd, arg) |
75f313ad SL |
154 | struct iob *io; |
155 | int cmd; | |
156 | caddr_t arg; | |
157 | { | |
158 | ||
159 | return (ECMD); | |
160 | } |