1
2
3
4
5
6
7
8
9
10
11 ioi_assignment:
12 proc;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 dcl p_dtx fixed bin parameter;
35 dcl p_name char (*) parameter;
36 dcl p_priv bit (1) aligned parameter;
37 dcl p_eventid fixed bin (71) parameter;
38 dcl p_code fixed bin (35) parameter;
39
40 dcl code fixed bin (35);
41 dcl controller bit (1) aligned;
42 dcl device bit (6) aligned;
43 dcl dtx fixed bin;
44 dcl eventid fixed bin (71);
45 dcl locked_for_reconfig bit (1) aligned;
46 dcl must_be_deleted bit (1) aligned;
47 dcl name char (32) var;
48 dcl no_path bit (1) aligned;
49 dcl priv bit (1) aligned;
50 dcl statusp ptr;
51 dcl subsys_name char (4) aligned;
52
53 dcl cleanup cond;
54
55 dcl error_table_$invalid_device
56 fixed bin (35) ext;
57 dcl error_table_$io_configured
58 fixed bin (35) ext static;
59 dcl error_table_$io_no_path
60 fixed bin (35) ext static;
61 dcl error_table_$io_not_configured
62 fixed bin (35) ext static;
63
64 dcl pds$process_id bit (36) aligned external;
65 dcl pds$validation_level fixed bin (3) external;
66
67 dcl sys_info$service_system
68 bit (1) aligned external static;
69
70 dcl ioi_device$assign entry (ptr, bit (6) aligned, bit (1) aligned, fixed bin, fixed bin (35));
71 dcl ioi_device$get_dtep entry (fixed bin, ptr, fixed bin (35));
72 dcl ioi_device$get_dtep_force
73 entry (fixed bin, ptr, fixed bin (35));
74 dcl ioi_device$unassign entry (ptr);
75 dcl ioi_device$unlock entry (ptr);
76 dcl ioi_masked$flush_status
77 entry (ptr);
78 dcl ioi_masked$interrupt entry (fixed bin (35), fixed bin (3), bit (36) aligned);
79 dcl ioi_masked$reset_device
80 entry (ptr);
81 dcl ioi_page_table$put entry (fixed bin, fixed bin (35));
82 dcl ioi_usurp_channels$assign
83 entry (ptr, fixed bin (35));
84 dcl ioi_usurp_channels$unassign
85 entry (ptr, fixed bin (35));
86 dcl ioi_wire$unwire entry (ptr);
87 dcl ioi_workspace$create entry (ptr, fixed bin (35));
88 dcl ioi_workspace$destroy entry (ptr, fixed bin (35));
89 dcl ioi_workspace$release_aste
90 entry (ptr);
91
92 dcl (addr, after, before, bin, bit, index, null, ptr, rel, rtrim)
93 builtin;
94 ^L
95 assign_deleted:
96 entry (p_dtx, p_name, p_eventid, p_priv, p_code);
97
98 must_be_deleted = "1"b;
99 goto ASSIGN_COMMON;
100
101 assign:
102 entry (p_dtx, p_name, p_eventid, p_priv, p_code);
103
104 must_be_deleted = "0"b;
105 ASSIGN_COMMON:
106 name = rtrim (p_name);
107 priv = p_priv;
108 eventid = p_eventid;
109
110 idp = addr (ioi_data$);
111 p_code = 0;
112 subsys_name = before (name, "_");
113
114 call find_gte (subsys_name);
115 if gtep = null () then do;
116 p_code = error_table_$invalid_device;
117 return;
118 end;
119
120 controller = "0"b;
121 if index (name, "_") = 0 then
122 if gte.fips then do;
123 device = "00"b3;
124 controller = "1"b;
125 end;
126 else device = "01"b3;
127 else device = bit (bin (after (name, "_"), 6, 0));
128 if device = "00"b3 & ^gte.fips then
129 controller = "1"b;
130
131 dtep = null ();
132 on cleanup call cleanup_assign;
133
134 call ioi_device$assign (gtep, device, controller, dtx, code);
135 if code ^= 0 then do;
136 p_code = code;
137 return;
138 end;
139 gte.n_devices = gte.n_devices + 1;
140 call ioi_device$get_dtep (dtx, dtep, code);
141 if code ^= 0 then do;
142 call cleanup_assign;
143 p_code = code;
144 return;
145 end;
146
147 if dte.deleted & ^must_be_deleted then do;
148 call cleanup_assign;
149 p_code = error_table_$io_not_configured;
150 return;
151 end;
152 if ^dte.deleted & must_be_deleted then do;
153 call cleanup_assign;
154 p_code = error_table_$io_configured;
155 return;
156 end;
157
158 if gte.disk_data_subsystem_idx ^= 0 then do;
159 call ioi_usurp_channels$assign (gtep, code);
160 if code ^= 0 then do;
161 call cleanup_assign;
162 p_code = code;
163 return;
164 end;
165 end;
166 else if ^gte.mplex then do;
167 ctep = ptr (gtep, gte.ctep);
168 if ^cte.ioi_use then do;
169 call io_manager$assign (cte.chx, cte.chanid, ioi_masked$interrupt, bin (rel (ctep)), statusp, code);
170 if code = 0 then do;
171 cte.ioi_use = "1"b;
172 cte.statusp = statusp;
173 end;
174 else do;
175 call cleanup_assign;
176 p_code = code;
177 return;
178 end;
179 end;
180 end;
181
182
183 dte.cur_ctep = ""b;
184 dte.channel_required = "";
185 dte.ev_chn = eventid;
186 dte.max_bound = IOI_DEFAULT_MAX_BOUND;
187 dte.max_timeout = IOI_DEFAULT_MAX_TIMEOUT;
188 dte.timeout = IOI_DEFAULT_TIMEOUT;
189 dte.unwire_time = 0;
190 dte.bound = 0;
191
192 dte.priv = priv;
193 dte.connected = "0"b;
194 dte.active = "0"b;
195 dte.workspace_wired = "0"b;
196 dte.special_interrupt = "0"b;
197 dte.log_status_cnt = "0"b;
198 dte.reading_detailed_status = "0"b;
199 dte.detailed_status_valid = "0"b;
200
201
202 dte.ring = pds$validation_level;
203 dte.ptx = 0;
204 dte.status_offset = 0;
205 dte.status_entries = 0;
206 dte.status_entry_idx = 0;
207 call ioi_workspace$create (dtep, code);
208 if code ^= 0 then do;
209 call cleanup_assign;
210 p_code = code;
211 return;
212 end;
213
214 call unlock;
215 p_dtx = dtx;
216 return;
217 ^L
218 unassign:
219 entry (p_dtx, p_code);
220
221 dtx = p_dtx;
222 p_code = 0;
223 call ioi_device$get_dtep_force (dtx, dtep, code);
224 if code ^= 0 then do;
225 p_code = code;
226 return;
227 end;
228
229 idp = addr (ioi_data$);
230 gtep = ptr (idp, dte.gtep);
231 if dte.active then do;
232 call ioi_masked$reset_device (dtep);
233 do while (dte.active);
234 end;
235 end;
236
237 if dte.ptx ^= 0 then do;
238 call ioi_page_table$put (dte.ptx, code);
239 dte.ptx = 0;
240 if code ^= 0 then do;
241 call unlock;
242 p_code = code;
243 return;
244 end;
245 end;
246
247
248
249
250
251
252 if dte.process_id = pds$process_id then
253 call ioi_workspace$destroy (dtep, code);
254 else do;
255 call ioi_wire$unwire (dtep);
256 call ioi_workspace$release_aste (dtep);
257 end;
258 if code ^= 0 then do;
259 call unlock;
260 p_code = code;
261 return;
262 end;
263
264 dte.ev_chn = 0;
265 dte.channel_required = "";
266 call ioi_masked$flush_status (dtep);
267 call channel_unassign;
268 call ioi_device$unassign (dtep);
269 call unlock;
270 p_code = 0;
271 return;
272 ^L
273 add_device:
274 entry (p_name, p_code);
275
276 dtx = 0;
277 locked_for_reconfig = "0"b;
278 on cleanup call cleanup_reconfigure;
279
280 call assign_deleted (dtx, p_name, 0, "0"b, code);
281 if code ^= 0 then do;
282 p_code = code;
283 return;
284 end;
285
286 call ioi_device$get_dtep (dtx, dtep, code);
287 if code ^= 0 then do;
288 call cleanup_reconfigure;
289 p_code = code;
290 return;
291 end;
292
293 call lock_for_reconfig_proc;
294 no_path = "1"b;
295 gtep = ptr (dtep, dte.gtep);
296 do ctep = ptr (gtep, gte.ctep) repeat ptr (ctep, cte.next_ctep) while (rel (ctep) ^= ""b & no_path);
297 no_path = cte.deleted | cte.deleting;
298 end;
299 if no_path then do;
300 call cleanup_reconfigure;
301 p_code = error_table_$io_no_path;
302 return;
303 end;
304
305 dte.deleted = "0"b;
306 io_config_data_ptr = addr (io_config_data$);
307 io_config_device_table_ptr = ptr (io_config_data_ptr, io_config_data.device_table_offset);
308 device_table.device_entry (dte.device_table_idx).configured = "1"b;
309 call cleanup_reconfigure;
310 p_code = 0;
311 return;
312 ^L
313 delete_device:
314 entry (p_name, p_code);
315
316 dtx = 0;
317 locked_for_reconfig = "0"b;
318 on cleanup call cleanup_reconfigure;
319
320 call assign (dtx, p_name, 0, "0"b, code);
321 if code ^= 0 then do;
322 p_code = code;
323 return;
324 end;
325
326 call ioi_device$get_dtep (dtx, dtep, code);
327 if code ^= 0 then do;
328 call cleanup_reconfigure;
329 p_code = code;
330 return;
331 end;
332
333 if dte.deleted then do;
334 call cleanup_reconfigure;
335 p_code = error_table_$io_not_configured;
336 return;
337 end;
338
339 dte.deleted = "1"b;
340 io_config_data_ptr = addr (io_config_data$);
341 io_config_device_table_ptr = ptr (io_config_data_ptr, io_config_data.device_table_offset);
342 device_table.device_entry (dte.device_table_idx).configured = "0"b;
343 call cleanup_reconfigure;
344 p_code = 0;
345 return;
346 ^L
347 lock_for_reconfig:
348 entry;
349
350 call lock_for_reconfig_proc;
351 return;
352
353 unlock_for_reconfig:
354 entry;
355
356 call unlock_for_reconfig_proc;
357 return;
358 ^L
359 cleanup_reconfigure:
360 proc;
361
362 if locked_for_reconfig then
363 call unlock_for_reconfig_proc;
364 if dtx ^= 0 then do;
365 call ioi_device$unlock (dtep);
366 call unassign (dtx, (0));
367 end;
368
369 end cleanup_reconfigure;
370
371 lock_for_reconfig_proc:
372 proc;
373
374 dcl lock$lock_fast entry (ptr);
375
376 idp = addr (ioi_data$);
377 if sys_info$service_system then
378 call lock$lock_fast (addr (ioi_data.reconfig_lock));
379 locked_for_reconfig = "1"b;
380
381 end lock_for_reconfig_proc;
382
383 unlock_for_reconfig_proc:
384 proc;
385
386 dcl lock$unlock_fast entry (ptr);
387
388 idp = addr (ioi_data$);
389 if sys_info$service_system then
390 call lock$unlock_fast (addr (ioi_data.reconfig_lock));
391 locked_for_reconfig = "0"b;
392
393 end unlock_for_reconfig_proc;
394 ^L
395 find_gte:
396 proc (name);
397
398 dcl name char (4) aligned parameter;
399
400 dcl gtx fixed bin;
401
402
403 do gtx = 1 to ioi_data.ngt;
404 gtep = addr (ioi_data.gt (gtx));
405 if gte.name = subsys_name then
406 return;
407 end;
408 gtep = null ();
409
410 end find_gte;
411
412 cleanup_assign:
413 proc;
414
415 if dtep ^= null () then do;
416 call unlock;
417 call channel_unassign;
418 call ioi_device$unassign (dtep);
419 end;
420
421 end cleanup_assign;
422
423 channel_unassign:
424 proc;
425
426 gte.n_devices = gte.n_devices - 1;
427 if gte.disk_data_subsystem_idx ^= 0 then
428 call ioi_usurp_channels$unassign (gtep, (0));
429 else if ^gte.mplex then do;
430 ctep = ptr (gtep, gte.ctep);
431 if cte.ioi_use then do;
432 call io_manager$unassign (cte.chx, code);
433 if code = 0 then
434 cte.ioi_use = "0"b;
435 end;
436 end;
437
438 end channel_unassign;
439
440 unlock:
441 proc;
442
443 call ioi_device$unlock (dtep);
444
445 end unlock;
446 ^L
447 %include ioi_data;
448 %page;
449 %include io_config_data;
450 %page;
451 %include io_manager_dcls;
452
453 end ioi_assignment;