1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 ioi_set:
33 procedure;
34
35 dcl p_channel fixed bin (7) parameter;
36 dcl p_code fixed bin (35) parameter;
37 dcl p_devx fixed bin parameter;
38 dcl p_evchn fixed bin (71) parameter;
39 dcl p_iom fixed bin (3) parameter;
40 dcl p_count fixed bin parameter;
41 dcl p_offset fixed bin (18) parameter;
42 dcl p_ring fixed bin (3) parameter;
43 dcl p_time fixed bin (71) parameter;
44 dcl p_workspace_ptr ptr parameter;
45 dcl p_workspace_size fixed bin (19) parameter;
46
47 dcl chanid char (8) aligned;
48 dcl channel fixed bin (7);
49 dcl code fixed bin (35);
50 dcl devx fixed bin;
51 dcl evchn fixed bin (71);
52 dcl iom fixed bin (3);
53 dcl n_entries fixed bin;
54 dcl offset fixed bin (18);
55 dcl ring fixed bin (3);
56 dcl time fixed bin (71);
57 dcl workspace_ptr ptr;
58 dcl workspace_size fixed bin (19);
59
60 dcl error_table_$bad_channel
61 fixed bin (35) ext static;
62 dcl error_table_$bad_ring_brackets
63 fixed bin (35) ext static;
64 dcl error_table_$buffer_big
65 fixed bin (35) ext static;
66 dcl error_table_$chnl_already_deleted
67 fixed bin (35) ext static;
68 dcl error_table_$chnl_being_deleted
69 fixed bin (35) ext static;
70 dcl error_table_$dev_offset_out_of_bounds
71 fixed bin (35) ext static;
72 dcl error_table_$device_active
73 fixed bin (35) ext static;
74 dcl error_table_$no_operation
75 fixed bin (35) ext static;
76 dcl error_table_$time_too_long
77 fixed bin (35) ext static;
78
79 dcl pds$validation_level fixed bin (3) external;
80 dcl sys_info$page_size fixed bin external;
81 dcl sys_info$seg_size_256K fixed bin external;
82
83 dcl ioi_page_table$get entry (fixed bin (19), fixed bin, fixed bin (35));
84 dcl ioi_page_table$ptx_to_ptp
85 entry (fixed bin) returns (ptr);
86 dcl ioi_page_table$put entry (fixed bin, fixed bin (35));
87 dcl ioi_device$get_dtep entry (fixed bin, ptr, fixed bin (35));
88 dcl ioi_device$unlock entry (ptr);
89 dcl ioi_usurp_channels$required
90 entry (ptr, fixed bin (35));
91 dcl ioi_wire$unwire entry (ptr);
92 dcl ioi_workspace$set_rb entry (ptr, fixed bin (35));
93 dcl ioi_workspace$set_max_size
94 entry (ptr, fixed bin (35));
95
96 dcl (divide, null, ptr, rel, size)
97 builtin;
98 ^L
99 return;
100
101
102
103
104
105
106 timeout:
107 entry (p_devx, p_time, p_code);
108
109 time = p_time;
110 call check_devx;
111
112 if dte.direct then do;
113 call unlock;
114 p_code = error_table_$no_operation;
115 return;
116 end;
117
118 if (time > dte.max_timeout) & ^dte.priv then do;
119 call unlock;
120 p_code = error_table_$time_too_long;
121 return;
122 end;
123
124 dte.timeout = time;
125 call unlock;
126 p_code = code;
127 return;
128
129
130
131
132
133 max_timeout:
134 entry (p_devx, p_time, p_code);
135
136 time = p_time;
137 call check_devx;
138
139 dte.max_timeout = time;
140 call unlock;
141 p_code = code;
142 return;
143
144
145
146
147
148 event:
149 entry (p_devx, p_evchn, p_code);
150
151 evchn = p_evchn;
152 call check_devx;
153
154 dte.ev_chn = evchn;
155 call unlock;
156 p_code = code;
157 return;
158
159
160
161
162
163 workspace:
164 entry (p_devx, p_workspace_ptr, p_workspace_size, p_code);
165
166 workspace_size =
167 divide (p_workspace_size + sys_info$page_size - 1, sys_info$page_size, 17) * sys_info$page_size;
168 p_workspace_ptr, workspace_ptr = null ();
169 call check_devx;
170
171 if dte.active then do;
172 call unlock;
173 p_code = error_table_$device_active;
174 return;
175 end;
176
177 if (workspace_size <= 0) | (workspace_size > dte.max_bound) then do;
178 call unlock;
179 p_code = error_table_$buffer_big;
180 return;
181 end;
182
183 if workspace_size < dte.status_offset + dte.status_entries * size (istat) then do;
184 call unlock;
185 p_code = error_table_$dev_offset_out_of_bounds;
186 return;
187 end;
188
189
190 if dte.workspace_wired then
191 call ioi_wire$unwire (dtep);
192
193 dte.bound = workspace_size;
194 if dte.ptx ^= 0 then do;
195 call ioi_page_table$put (dte.ptx, code);
196 dte.ptx = 0;
197 call quit_if_error;
198 end;
199
200 if dte.direct then
201 call ioi_page_table$get ((sys_info$seg_size_256K), dte.ptx, code);
202 else call ioi_page_table$get (dte.bound, dte.ptx, code);
203 call quit_if_error;
204 dte.ptp = ioi_page_table$ptx_to_ptp (dte.ptx);
205 workspace_ptr = dte.workspace_ptr;
206 call unlock;
207
208 p_workspace_ptr = workspace_ptr;
209 p_code = code;
210 return;
211
212
213
214
215
216 max_workspace:
217 entry (p_devx, p_workspace_size, p_code);
218
219 workspace_size =
220 divide (p_workspace_size + sys_info$page_size - 1, sys_info$page_size, 17) * sys_info$page_size;
221 call check_devx;
222
223 dte.max_bound = workspace_size;
224 call ioi_workspace$set_max_size (dtep, code);
225 call quit_if_error;
226 call unlock;
227 p_code = code;
228 return;
229
230
231
232
233
234 level:
235 entry (p_devx, p_ring, p_code);
236
237 ring = p_ring;
238 call check_devx;
239
240 if ring < pds$validation_level then do;
241 call unlock;
242 p_code = error_table_$bad_ring_brackets;
243 return;
244 end;
245
246 dte.ring = ring;
247 call ioi_workspace$set_rb (dtep, code);
248 call quit_if_error;
249 call unlock;
250 p_code = code;
251 return;
252
253
254
255
256
257
258 channel_required:
259 entry (p_devx, p_iom, p_channel, p_code);
260
261 iom = p_iom;
262 channel = p_channel;
263 call check_devx;
264
265 if ^dte.priv then do;
266 call unlock;
267 p_code = error_table_$no_operation;
268 return;
269 end;
270
271 if (iom = 0) & (channel = 0) then do;
272 dte.channel_required = "";
273 call unlock;
274 p_code = code;
275 return;
276 end;
277
278 call io_chnl_util$iom_to_name (iom, channel, chanid, code);
279 if code ^= 0 then do;
280 call unlock;
281 p_code = error_table_$bad_channel;
282 return;
283 end;
284
285 if dte.active then do;
286 call unlock;
287 p_code = error_table_$device_active;
288 return;
289 end;
290
291 gtep = ptr (dtep, dte.gtep);
292 do ctep = ptr (gtep, gte.ctep) repeat ptr (ctep, cte.next_ctep) while (rel (ctep) ^= ""b);
293 if cte.chanid = chanid then do;
294
295 if cte.deleted then do;
296 call unlock;
297 p_code = error_table_$chnl_already_deleted;
298 return;
299 end;
300
301 if cte.deleting then do;
302 call unlock;
303 p_code = error_table_$chnl_being_deleted;
304 return;
305 end;
306
307 if (gte.disk_data_subsystem_idx ^= 0) & ^cte.ioi_use then
308
309 if ^gte.suspend_devices then do;
310 call ioi_usurp_channels$required (ctep, code);
311 if code ^= 0 then do;
312 call unlock;
313 p_code = code;
314 return;
315 end;
316 end;
317 else do;
318 call unlock;
319 p_code = error_table_$no_operation;
320 return;
321 end;
322
323 dte.channel_required = chanid;
324 call unlock;
325 p_code = code;
326 return;
327 end;
328 end;
329
330 call unlock;
331 p_code = error_table_$bad_channel;
332 return;
333
334
335
336
337
338 status:
339 entry (p_devx, p_offset, p_count, p_code);
340
341 offset = p_offset;
342 n_entries = p_count;
343 call check_devx;
344
345 if (offset < 0) | (n_entries < 0) | (offset + (n_entries * size (istat)) > dte.bound) then do;
346 call unlock;
347 p_code = error_table_$dev_offset_out_of_bounds;
348 return;
349 end;
350
351 dte.status_control.status_offset = offset;
352 dte.status_control.status_entries = n_entries;
353 dte.status_control.status_entry_idx = 0;
354 call unlock;
355 p_code = code;
356 return;
357 ^L
358
359
360
361 check_devx:
362 procedure;
363
364 p_code, code = 0;
365 devx = p_devx;
366 call ioi_device$get_dtep (devx, dtep, code);
367 if code ^= 0 then
368 goto QUIT;
369
370 end check_devx;
371
372
373
374 unlock:
375 procedure;
376
377 call ioi_device$unlock (dtep);
378
379 end unlock;
380
381 quit_if_error:
382 proc;
383
384 if code ^= 0 then do;
385 call unlock;
386 goto QUIT;
387 end;
388
389 end quit_if_error;
390
391 QUIT:
392 p_code = code;
393 return;
394 ^L
395 %include ioi_data;
396 %page;
397 %include ioi_stat;
398 %page;
399 %include io_chnl_util_dcls;
400
401 end ioi_set;