FreeCalypso > hg > freecalypso-sw
comparison nuc-fw/nucleus/ioc.c @ 79:947b1f473960
beginning of nuc-fw
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 11 Aug 2013 07:17:25 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
78:2c266d4339ff | 79:947b1f473960 |
---|---|
1 /*************************************************************************/ | |
2 /* */ | |
3 /* Copyright Mentor Graphics Corporation 2002 */ | |
4 /* All Rights Reserved. */ | |
5 /* */ | |
6 /* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */ | |
7 /* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */ | |
8 /* SUBJECT TO LICENSE TERMS. */ | |
9 /* */ | |
10 /*************************************************************************/ | |
11 | |
12 /*************************************************************************/ | |
13 /* */ | |
14 /* FILE NAME VERSION */ | |
15 /* */ | |
16 /* ioc.c Nucleus PLUS 1.14 */ | |
17 /* */ | |
18 /* COMPONENT */ | |
19 /* */ | |
20 /* IO - Input/Output Driver Management */ | |
21 /* */ | |
22 /* DESCRIPTION */ | |
23 /* */ | |
24 /* This file contains the core routines for the I/O Driver */ | |
25 /* Management component. */ | |
26 /* */ | |
27 /* DATA STRUCTURES */ | |
28 /* */ | |
29 /* None */ | |
30 /* */ | |
31 /* FUNCTIONS */ | |
32 /* */ | |
33 /* IOC_Create_Driver Create an I/O driver */ | |
34 /* IOC_Delete_Driver Delete an I/O driver */ | |
35 /* IOC_Request_Driver Make an I/O driver request */ | |
36 /* IOC_Resume_Driver Resume a task suspended in */ | |
37 /* an I/O driver */ | |
38 /* IOC_Suspend_Driver Suspend a task inside an I/O */ | |
39 /* driver */ | |
40 /* */ | |
41 /* DEPENDENCIES */ | |
42 /* */ | |
43 /* cs_extr.h Common Service functions */ | |
44 /* tc_extr.h Thread Control functions */ | |
45 /* io_extr.h I/O driver functions */ | |
46 /* hi_extr.h History functions */ | |
47 /* */ | |
48 /* HISTORY */ | |
49 /* */ | |
50 /* DATE REMARKS */ | |
51 /* */ | |
52 /* 03-01-1993 Created initial version 1.0 */ | |
53 /* 04-19-1993 Verified version 1.0 */ | |
54 /* 08-09-1993 Corrected pointer retrieval */ | |
55 /* loop, resulting in version 1.0a */ | |
56 /* 08-09-1993 Verified version 1.0a */ | |
57 /* 03-01-1994 Moved non-core functions into */ | |
58 /* supplemental files, changed */ | |
59 /* function interfaces to match */ | |
60 /* those in prototype, changed */ | |
61 /* protection logic to reduce */ | |
62 /* overhead, resulting in */ | |
63 /* version 1.1 */ | |
64 /* */ | |
65 /* 03-15-1994 Verified version 1.1 */ | |
66 /* 04-17-1996 updated to version 1.2 */ | |
67 /* 04-23-1996 Corrected SPR121. */ | |
68 /* 03-24-1998 Released version 1.3 */ | |
69 /* 03-26-1999 Released 1.11m (new release */ | |
70 /* numbering scheme) */ | |
71 /* 04-07-1999 Release 1.11mA */ | |
72 /* 04-17-2002 Released version 1.13m */ | |
73 /* 11-07-2002 Released version 1.14 */ | |
74 /*************************************************************************/ | |
75 #define NU_SOURCE_FILE | |
76 | |
77 | |
78 #include "cs_extr.h" /* Common service functions */ | |
79 #include "tc_extr.h" /* Thread control functions */ | |
80 #include "io_extr.h" /* I/O driver functions */ | |
81 #include "hi_extr.h" /* History functions */ | |
82 #include "profiler.h" /* ProView interface */ | |
83 | |
84 /* Define external inner-component global data references. */ | |
85 | |
86 extern CS_NODE *IOD_Created_Drivers_List; | |
87 extern UNSIGNED IOD_Total_Drivers; | |
88 extern TC_PROTECT IOD_List_Protect; | |
89 | |
90 | |
91 | |
92 /*************************************************************************/ | |
93 /* */ | |
94 /* FUNCTION */ | |
95 /* */ | |
96 /* IOC_Create_Driver */ | |
97 /* */ | |
98 /* DESCRIPTION */ | |
99 /* */ | |
100 /* This function creates an I/O driver and places it on the list of */ | |
101 /* created I/O drivers. Note that this function does not actually */ | |
102 /* invoke the driver. */ | |
103 /* */ | |
104 /* CALLED BY */ | |
105 /* */ | |
106 /* Application */ | |
107 /* IOCE_Create_Driver Error checking shell */ | |
108 /* */ | |
109 /* CALLS */ | |
110 /* */ | |
111 /* CSC_Place_On_List Add node to linked-list */ | |
112 /* [HIC_Make_History_Entry] Make entry in history log */ | |
113 /* [TCT_Check_Stack] Stack checking function */ | |
114 /* TCT_Protect Data structure protect */ | |
115 /* TCT_Unprotect Un-protect data structure */ | |
116 /* */ | |
117 /* INPUTS */ | |
118 /* */ | |
119 /* driver Driver control block pointer */ | |
120 /* name Driver's logical name */ | |
121 /* driver_entry Driver's point of entry */ | |
122 /* */ | |
123 /* OUTPUTS */ | |
124 /* */ | |
125 /* NU_SUCCESS */ | |
126 /* */ | |
127 /* HISTORY */ | |
128 /* */ | |
129 /* DATE REMARKS */ | |
130 /* */ | |
131 /* 03-01-1993 Created initial version 1.0 */ | |
132 /* 04-19-1993 Verified version 1.0 */ | |
133 /* */ | |
134 /*************************************************************************/ | |
135 STATUS IOC_Create_Driver(NU_DRIVER *driver, CHAR *name, | |
136 VOID (*driver_entry)(NU_DRIVER *, NU_DRIVER_REQUEST *)) | |
137 { | |
138 | |
139 INT i; /* Working index variable */ | |
140 NU_SUPERV_USER_VARIABLES | |
141 | |
142 /* Switch to supervisor mode */ | |
143 NU_SUPERVISOR_MODE(); | |
144 | |
145 #ifdef NU_ENABLE_STACK_CHECK | |
146 | |
147 /* Call stack checking function to check for an overflow condition. */ | |
148 TCT_Check_Stack(); | |
149 | |
150 #endif | |
151 | |
152 #ifdef NU_ENABLE_HISTORY | |
153 | |
154 /* Make an entry that corresponds to this function in the system history | |
155 log. */ | |
156 HIC_Make_History_Entry(NU_CREATE_DRIVER_ID, (UNSIGNED) driver, | |
157 (UNSIGNED) name, (UNSIGNED) driver_entry); | |
158 | |
159 #endif | |
160 | |
161 /* First, clear the driver ID just in case it is an old Driver | |
162 Control Block. */ | |
163 driver -> nu_driver_id = 0; | |
164 | |
165 /* Fill in the driver's name. */ | |
166 for (i = 0; i < NU_MAX_NAME; i++) | |
167 driver -> nu_driver_name[i] = name[i]; | |
168 | |
169 /* Save the driver's entry function in the control block. */ | |
170 driver -> nu_driver_entry = driver_entry; | |
171 | |
172 /* Protect against access to the list of created drivers. */ | |
173 TCT_Protect(&IOD_List_Protect); | |
174 | |
175 /* At this point the driver is completely built. The ID can now be | |
176 set and it can be linked into the created driver list. */ | |
177 driver -> nu_driver_id = IO_DRIVER_ID; | |
178 | |
179 /* Link the driver into the list of created I/O drivers and increment the | |
180 total number of drivers in the system. */ | |
181 CSC_Place_On_List(&IOD_Created_Drivers_List, (CS_NODE *) driver); | |
182 IOD_Total_Drivers++; | |
183 | |
184 #ifdef INCLUDE_PROVIEW | |
185 _RTProf_DumpDriver(RT_PROF_CREATE_DRIVER, driver, RT_PROF_OK); | |
186 #endif /*INCLUDE_PROVIEW*/ | |
187 /* Release protection against access to the list of created I/O drivers. */ | |
188 TCT_Unprotect(); | |
189 | |
190 /* Return to user mode */ | |
191 NU_USER_MODE(); | |
192 | |
193 /* Return successful completion. */ | |
194 return(NU_SUCCESS); | |
195 } | |
196 | |
197 | |
198 /*************************************************************************/ | |
199 /* */ | |
200 /* FUNCTION */ | |
201 /* */ | |
202 /* IOC_Delete_Driver */ | |
203 /* */ | |
204 /* DESCRIPTION */ | |
205 /* */ | |
206 /* This function deletes an I/O driver and removes it from the list */ | |
207 /* of created drivers. Note that this function does not actually */ | |
208 /* invoke the driver. */ | |
209 /* */ | |
210 /* CALLED BY */ | |
211 /* */ | |
212 /* Application */ | |
213 /* IOCE_Delete_Driver Error checking shell */ | |
214 /* */ | |
215 /* CALLS */ | |
216 /* */ | |
217 /* CSC_Remove_From_List Remove node from list */ | |
218 /* [HIC_Make_History_Entry] Make entry in history log */ | |
219 /* [TCT_Check_Stack] Stack checking function */ | |
220 /* TCT_Protect Protect created list */ | |
221 /* TCT_Unprotect Release protection */ | |
222 /* */ | |
223 /* INPUTS */ | |
224 /* */ | |
225 /* driver Driver control block pointer */ | |
226 /* */ | |
227 /* OUTPUTS */ | |
228 /* */ | |
229 /* NU_SUCCESS */ | |
230 /* */ | |
231 /* HISTORY */ | |
232 /* */ | |
233 /* DATE REMARKS */ | |
234 /* */ | |
235 /* 03-01-1993 Created initial version 1.0 */ | |
236 /* 04-19-1993 Verified version 1.0 */ | |
237 /* */ | |
238 /*************************************************************************/ | |
239 STATUS IOC_Delete_Driver(NU_DRIVER *driver) | |
240 { | |
241 NU_SUPERV_USER_VARIABLES | |
242 | |
243 /* Switch to supervisor mode */ | |
244 NU_SUPERVISOR_MODE(); | |
245 | |
246 #ifdef NU_ENABLE_STACK_CHECK | |
247 | |
248 /* Call stack checking function to check for an overflow condition. */ | |
249 TCT_Check_Stack(); | |
250 | |
251 #endif | |
252 | |
253 #ifdef NU_ENABLE_HISTORY | |
254 | |
255 /* Make an entry that corresponds to this function in the system history | |
256 log. */ | |
257 HIC_Make_History_Entry(NU_DELETE_DRIVER_ID, (UNSIGNED) driver , | |
258 (UNSIGNED) 0, (UNSIGNED) 0); | |
259 | |
260 #endif | |
261 | |
262 /* Protect against access to the list of created I/O drivers. */ | |
263 TCT_Protect(&IOD_List_Protect); | |
264 | |
265 #ifdef INCLUDE_PROVIEW | |
266 _RTProf_DumpDriver(RT_PROF_DELETE_DRIVER, driver, RT_PROF_OK); | |
267 #endif /*INCLUDE_PROVIEW*/ | |
268 /* Set the driver ID to 0. */ | |
269 driver -> nu_driver_id = 0; | |
270 | |
271 /* Remove the driver from the list of created I/O drivers. */ | |
272 CSC_Remove_From_List(&IOD_Created_Drivers_List, (CS_NODE *) driver); | |
273 | |
274 /* Decrement the total number of created I/O drivers. */ | |
275 IOD_Total_Drivers--; | |
276 | |
277 /* Release protection against access to the list of created I/O drivers. */ | |
278 TCT_Unprotect(); | |
279 | |
280 /* Return to user mode */ | |
281 NU_USER_MODE(); | |
282 | |
283 /* Return a successful completion. */ | |
284 return(NU_SUCCESS); | |
285 } | |
286 | |
287 | |
288 /*************************************************************************/ | |
289 /* */ | |
290 /* FUNCTION */ | |
291 /* */ | |
292 /* IOC_Request_Driver */ | |
293 /* */ | |
294 /* DESCRIPTION */ | |
295 /* */ | |
296 /* This function sends a user request to the specified I/O driver. */ | |
297 /* */ | |
298 /* CALLED BY */ | |
299 /* */ | |
300 /* Application */ | |
301 /* IOCE_Request_Driver Error checking shell */ | |
302 /* */ | |
303 /* CALLS */ | |
304 /* */ | |
305 /* [HIC_Make_History_Entry] Make entry in history log */ | |
306 /* [TCT_Check_Stack] Stack checking function */ | |
307 /* */ | |
308 /* INPUTS */ | |
309 /* */ | |
310 /* driver Driver control block pointer */ | |
311 /* request User's I/O request */ | |
312 /* */ | |
313 /* OUTPUTS */ | |
314 /* */ | |
315 /* NU_SUCCESS If service is successful */ | |
316 /* */ | |
317 /* HISTORY */ | |
318 /* */ | |
319 /* DATE REMARKS */ | |
320 /* */ | |
321 /* 03-01-1993 Created initial version 1.0 */ | |
322 /* 04-19-1993 Verified version 1.0 */ | |
323 /* */ | |
324 /*************************************************************************/ | |
325 STATUS IOC_Request_Driver(NU_DRIVER *driver , NU_DRIVER_REQUEST *request) | |
326 { | |
327 NU_SUPERV_USER_VARIABLES | |
328 | |
329 /* Switch to supervisor mode */ | |
330 NU_SUPERVISOR_MODE(); | |
331 | |
332 #ifdef NU_ENABLE_STACK_CHECK | |
333 | |
334 /* Call stack checking function to check for an overflow condition. */ | |
335 TCT_Check_Stack(); | |
336 | |
337 #endif | |
338 | |
339 #ifdef NU_ENABLE_HISTORY | |
340 | |
341 /* Make an entry that corresponds to this function in the system history | |
342 log. */ | |
343 HIC_Make_History_Entry(NU_REQUEST_DRIVER_ID, (UNSIGNED) driver, | |
344 (UNSIGNED) request, (UNSIGNED) 0); | |
345 | |
346 #endif | |
347 | |
348 #ifdef INCLUDE_PROVIEW | |
349 _RTProf_DumpDriver(RT_PROF_REQUEST_DRIVER, driver, RT_PROF_OK); | |
350 #endif /*INCLUDE_PROVIEW*/ | |
351 /* Call the specified I/O Driver. */ | |
352 (*(driver -> nu_driver_entry)) (driver, request); | |
353 | |
354 /* Return to user mode */ | |
355 NU_USER_MODE(); | |
356 | |
357 /* Return the completion status. */ | |
358 return(NU_SUCCESS); | |
359 } | |
360 | |
361 | |
362 /*************************************************************************/ | |
363 /* */ | |
364 /* FUNCTION */ | |
365 /* */ | |
366 /* IOC_Resume_Driver */ | |
367 /* */ | |
368 /* DESCRIPTION */ | |
369 /* */ | |
370 /* This function resumes a task previously suspended inside of an */ | |
371 /* I/O driver. Typically, this function is called from within an */ | |
372 /* I/O driver. */ | |
373 /* */ | |
374 /* CALLED BY */ | |
375 /* */ | |
376 /* Application */ | |
377 /* IOCE_Resume_Driver Error checking shell */ | |
378 /* */ | |
379 /* CALLS */ | |
380 /* */ | |
381 /* [HIC_Make_History_Entry] Make entry in history log */ | |
382 /* TCC_Resume_Task Resume a suspended task */ | |
383 /* TCT_Control_To_System Transfer control to higher */ | |
384 /* priority task */ | |
385 /* [TCT_Check_Stack] Stack checking function */ | |
386 /* TCT_Get_Current_Protect Pickup current protection */ | |
387 /* TCT_Set_Current_Protect Set current protection */ | |
388 /* TCT_System_Protect Protect against system access*/ | |
389 /* TCT_System_Unprotect Release system protection */ | |
390 /* TCT_Unprotect Release system protection */ | |
391 /* TCT_Unprotect_Specific Release specific protection */ | |
392 /* */ | |
393 /* INPUTS */ | |
394 /* */ | |
395 /* task Pointer of task to resume */ | |
396 /* */ | |
397 /* OUTPUTS */ | |
398 /* */ | |
399 /* NU_SUCCESS If service is successful */ | |
400 /* */ | |
401 /* HISTORY */ | |
402 /* */ | |
403 /* DATE REMARKS */ | |
404 /* */ | |
405 /* 03-01-1993 Created initial version 1.0 */ | |
406 /* 04-19-1993 Verified version 1.0 */ | |
407 /* 03-01-1994 Changed function interfaces to */ | |
408 /* match prototype, changed */ | |
409 /* protection logic, resulting in */ | |
410 /* version 1.1 */ | |
411 /* */ | |
412 /* 03-18-1994 Verified version 1.1 */ | |
413 /* 04-23-1996 Corrected SPR121 */ | |
414 /* */ | |
415 /*************************************************************************/ | |
416 STATUS IOC_Resume_Driver(NU_TASK *task) | |
417 { | |
418 | |
419 TC_PROTECT *save_protect; /* Saved protect pointer */ | |
420 NU_SUPERV_USER_VARIABLES | |
421 | |
422 | |
423 /* Switch to supervisor mode */ | |
424 NU_SUPERVISOR_MODE(); | |
425 | |
426 #ifdef NU_ENABLE_STACK_CHECK | |
427 | |
428 /* Call stack checking function to check for an overflow condition. */ | |
429 TCT_Check_Stack(); | |
430 | |
431 #endif | |
432 | |
433 #ifdef NU_ENABLE_HISTORY | |
434 | |
435 /* Make an entry that corresponds to this function in the system history | |
436 log. */ | |
437 HIC_Make_History_Entry(NU_RESUME_DRIVER_ID, (UNSIGNED) task, | |
438 (UNSIGNED) 0, (UNSIGNED) 0); | |
439 | |
440 #endif | |
441 | |
442 /* Pickup current protection. */ | |
443 save_protect = TCT_Get_Current_Protect(); | |
444 | |
445 /* Protect against system access. */ | |
446 TCT_System_Protect(); | |
447 | |
448 #ifdef INCLUDE_PROVIEW | |
449 _RTProf_DumpDriver(RT_PROF_RESUME_DRIVER, 0 , RT_PROF_OK); | |
450 #endif /*INCLUDE_PROVIEW*/ | |
451 /* Resume the specified task. */ | |
452 if (TCC_Resume_Task(task, NU_DRIVER_SUSPEND)) | |
453 { | |
454 /* Only unprotect if there is protection in place. */ | |
455 if (save_protect) | |
456 { | |
457 /* Release protection caller had. */ | |
458 TCT_Unprotect_Specific(save_protect); | |
459 } | |
460 | |
461 /* Transfer control to the system if the resumed task function | |
462 detects a preemption condition. */ | |
463 TCT_Control_To_System(); | |
464 } | |
465 else | |
466 { | |
467 | |
468 /* Determine if there was protection previously in force. */ | |
469 if (save_protect) | |
470 { | |
471 | |
472 /* Switch to original protection. */ | |
473 TCT_Set_Current_Protect(save_protect); | |
474 | |
475 /* Release system protection. */ | |
476 TCT_System_Unprotect(); | |
477 } | |
478 else | |
479 | |
480 /* Release system protection. */ | |
481 TCT_Unprotect(); | |
482 } | |
483 | |
484 /* Return to user mode */ | |
485 NU_USER_MODE(); | |
486 | |
487 /* Return the completion status. */ | |
488 return(NU_SUCCESS); | |
489 } | |
490 | |
491 | |
492 | |
493 /*************************************************************************/ | |
494 /* */ | |
495 /* FUNCTION */ | |
496 /* */ | |
497 /* IOC_Suspend_Driver */ | |
498 /* */ | |
499 /* DESCRIPTION */ | |
500 /* */ | |
501 /* This function suspends a task inside of an I/O driver. It is */ | |
502 /* the responsibility of the I/O driver to keep track of tasks */ | |
503 /* waiting inside of an I/O driver. */ | |
504 /* */ | |
505 /* CALLED BY */ | |
506 /* */ | |
507 /* Application */ | |
508 /* IOCE_Suspend_Driver Error checking shell */ | |
509 /* */ | |
510 /* CALLS */ | |
511 /* */ | |
512 /* [HIC_Make_History_Entry] Make entry in history log */ | |
513 /* TCC_Suspend_Task Suspend calling task */ | |
514 /* TCT_Current_Thread Current task thread */ | |
515 /* [TCT_Check_Stack] Stack checking function */ | |
516 /* TCT_Get_Current_Protect Pickup current protect ptr */ | |
517 /* TCT_Set_Suspend_Protect Setup suspend protect field */ | |
518 /* TCT_System_Protect Protect against system access*/ | |
519 /* TCT_Unprotect_Specific Release user protection */ | |
520 /* */ | |
521 /* INPUTS */ | |
522 /* */ | |
523 /* terminate_routine Termination/Timeout cleanup */ | |
524 /* routine */ | |
525 /* information Information pointer of the */ | |
526 /* cleanup routine */ | |
527 /* timeout Suspension timeout request */ | |
528 /* */ | |
529 /* OUTPUTS */ | |
530 /* */ | |
531 /* NU_SUCCESS If service is successful */ | |
532 /* */ | |
533 /* HISTORY */ | |
534 /* */ | |
535 /* DATE REMARKS */ | |
536 /* */ | |
537 /* 03-01-1993 Created initial version 1.0 */ | |
538 /* 04-19-1993 Verified version 1.0 */ | |
539 /* 03-01-1994 Changed protection logic, */ | |
540 /* resulting in version 1.1 */ | |
541 /* */ | |
542 /* 03-18-1994 Verified version 1.1 */ | |
543 /* 04-23-1996 Corrected SPR121. */ | |
544 /* */ | |
545 /*************************************************************************/ | |
546 STATUS IOC_Suspend_Driver(VOID (*terminate_routine)(VOID *), | |
547 VOID *information, UNSIGNED timeout) | |
548 { | |
549 | |
550 TC_PROTECT *suspend_protect; /* Current protection */ | |
551 NU_SUPERV_USER_VARIABLES | |
552 | |
553 /* Switch to supervisor mode */ | |
554 NU_SUPERVISOR_MODE(); | |
555 | |
556 #ifdef NU_ENABLE_STACK_CHECK | |
557 | |
558 /* Call stack checking function to check for an overflow condition. */ | |
559 TCT_Check_Stack(); | |
560 | |
561 #endif | |
562 | |
563 #ifdef NU_ENABLE_HISTORY | |
564 | |
565 /* Make an entry that corresponds to this function in the system history | |
566 log. */ | |
567 HIC_Make_History_Entry(NU_SUSPEND_DRIVER_ID, (UNSIGNED) terminate_routine, | |
568 (UNSIGNED) information, (UNSIGNED) timeout); | |
569 | |
570 #endif | |
571 | |
572 | |
573 /* Pickup current protect. */ | |
574 suspend_protect = TCT_Get_Current_Protect(); | |
575 | |
576 /* Setup system protection. */ | |
577 TCT_System_Protect(); | |
578 | |
579 #ifdef INCLUDE_PROVIEW | |
580 _RTProf_DumpDriver(RT_PROF_SUSPEND_DRIVER, 0 , RT_PROF_OK); | |
581 #endif /*INCLUDE_PROVIEW*/ | |
582 /* If no protection exists, don't unprotect. */ | |
583 if (suspend_protect) | |
584 { | |
585 /* Release initial protection. */ | |
586 TCT_Unprotect_Specific(suspend_protect); | |
587 | |
588 /* Save suspend protect for timeout and terminate. */ | |
589 TCT_Set_Suspend_Protect(suspend_protect); | |
590 } | |
591 | |
592 /* Suspend the calling task. */ | |
593 TCC_Suspend_Task((NU_TASK *) TCT_Current_Thread(), NU_DRIVER_SUSPEND, | |
594 terminate_routine, information, timeout); | |
595 | |
596 /* Return to user mode */ | |
597 NU_USER_MODE(); | |
598 | |
599 /* Return the completion status. */ | |
600 return(NU_SUCCESS); | |
601 } | |
602 | |
603 | |
604 | |
605 | |
606 |