1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 ioam_: proc;
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 dcl devx fixed bin,
36 handler entry,
37 code fixed bin (35),
38 pid bit (36) aligned;
39
40 dcl ioat_uidc char (4) int static init ("ioat") options (constant),
41 ioat_uid bit (36) based (addr (ioat_uidc));
42
43 dcl pds$processid bit (36) ext,
44 (error_table_$bad_index,
45 error_table_$dev_nt_assnd,
46 error_table_$already_assigned,
47 error_table_$ioat_err) fixed bin (35) ext;
48
49 dcl sys_info$service_system
50 bit (1) aligned external static;
51
52 dcl ignore fixed bin (35),
53 isize fixed bin,
54 i fixed bin;
55
56 dcl (addr, baseno, divide, fixed, hbound, rel, size) builtin;
57
58 dcl syserr_sw bit (1) int static init ("0"b);
59
60 dcl syserr entry options (variable),
61 lock$wait entry (ptr, bit (36), fixed bin (35)),
62 lock$unlock entry (ptr, bit (36));
63 ^L
64 dcl (ioatp, ioatep) ptr,
65 (dseg$, ioat$) fixed bin ext;
66
67 dcl 1 ioat aligned based (ioatp),
68 2 lock bit (36),
69 2 last_entry fixed bin,
70 2 max_entries fixed bin,
71 2 entries (2048) like ioate;
72
73 dcl 1 ioate aligned based (ioatep),
74 2 pid bit (36),
75 2 devx fixed bin,
76 2 handler entry (fixed bin, fixed bin (35));
77 ^L
78 %include sdw;
79 ^L
80 assign: entry (devx, handler, code);
81
82 call setup;
83
84 call find_device (code);
85 if code = 0 then
86 ioate.handler = handler;
87 else if code = error_table_$dev_nt_assnd then do;
88 call find_free;
89
90 ioate.pid = pds$processid;
91 ioate.devx = devx;
92 ioate.handler = handler;
93 code = 0;
94 end;
95
96 if sys_info$service_system then
97 call lock$unlock (ioatp, ioat_uid);
98 return;
99
100
101
102 unassign: entry (devx, code);
103
104 call setup;
105 call find_device (code);
106 if code = 0 then
107 ioate.pid = "0"b;
108
109 if sys_info$service_system then
110 call lock$unlock (ioatp, ioat_uid);
111 return;
112 ^L
113 preempt: entry (pid, devx, code);
114
115 call setup;
116 call find_device (code);
117 if code ^= error_table_$dev_nt_assnd then do;
118 call ioate.handler (ioate.devx, code);
119
120 ioate.pid = "0"b;
121 end;
122
123 if sys_info$service_system then
124 call lock$unlock (ioatp, ioat_uid);
125 return;
126
127
128
129 process_release: entry (pid);
130
131 ioatp = addr (ioat$);
132 if sys_info$service_system then do;
133 call lock$wait (ioatp, ioat_uid, ignore);
134 if ignore ^= 0 then return;
135 end;
136
137 do i = 1 to ioat.last_entry;
138 ioatep = addr (ioat.entries (i));
139
140 if (ioate.pid ^= "0"b) & (ioate.pid = pid) then do;
141 call ioate.handler (ioate.devx, ignore);
142 ioate.pid = "0"b;
143 end;
144 end;
145
146 if sys_info$service_system then
147 call lock$unlock (ioatp, ioat_uid);
148 return;
149 ^L
150 setup: proc;
151
152 if (devx < 0) | (devx > hbound (ioat.entries, 1)) then do;
153 code = error_table_$bad_index;
154 goto RETURN;
155 end;
156
157 code = 0;
158 ioatp = addr (ioat$);
159
160 if ioat.max_entries = 0 then do;
161 sdwp = addr (dseg$);
162 sdwp = addr (sdwa (fixed (baseno (ioatp), 17)));
163 isize = fixed (sdw.bound, 17) * 16;
164
165 isize = isize - fixed (rel (addr (ioat.entries)), 17);
166 ioat.max_entries = divide (isize, size (ioate), 17, 0);
167 end;
168
169 if sys_info$service_system then do;
170 call lock$wait (ioatp, ioat_uid, code);
171 if code ^= 0 then goto RETURN;
172 end;
173 return;
174
175 end;
176
177
178 RETURN: return;
179
180 ^L
181 find_device: proc (acode);
182
183 dcl acode fixed bin (35);
184
185 acode = 0;
186 do i = 1 to ioat.last_entry;
187 ioatep = addr (ioat.entries (i));
188
189 if ioate.devx = devx then
190 if ioate.pid = pds$processid then return;
191 else if ioate.pid = "0"b then do;
192 acode = error_table_$dev_nt_assnd;
193 return;
194 end;
195 else do;
196 acode = error_table_$already_assigned;
197 return;
198 end;
199 end;
200
201 acode = error_table_$dev_nt_assnd;
202 return;
203
204 end;
205
206
207
208 find_free: proc;
209
210 do i = 1 to ioat.last_entry;
211 ioatep = addr (ioat.entries (i));
212 if ioate.pid = "0"b then return;
213 end;
214
215 if ioat.last_entry < ioat.max_entries then do;
216 ioat.last_entry = ioat.last_entry + 1;
217 ioatep = addr (ioat.entries (ioat.last_entry));
218 return;
219 end;
220
221 if ^syserr_sw then
222 call syserr (3, "ioam_: The IOAT is too small, use TBLS config card to increase size.");
223 syserr_sw = "1"b;
224 code = error_table_$ioat_err;
225 goto RETURN;
226
227 end;
228
229 ^L
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248 end;