1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17:
18:
19: #include "kernel.h"
20: #include "sysmgr.h"
21: #include "device.h"
22:
23: #if USE_DEVICE
24:
25: Noinit(EXPORT OpnCB knl_OpnCBtbl[MAX_OPNDEV]);
26: Noinit(EXPORT QUEUE knl_FreeOpnCB);
27:
28: Noinit(EXPORT ReqCB knl_ReqCBtbl[MAX_REQDEV]);
29: Noinit(EXPORT QUEUE knl_FreeReqCB);
30:
31: Noinit(EXPORT ResCB knl_resource_control_block);
32:
33:
34: 35: 36:
37: EXPORT ResCB* knl_GetResCB( void )
38: {
39: LockDM();
40:
41:
42: if ( knl_resource_control_block.openq.next == NULL ) {
43:
44: QueInit(&(knl_resource_control_block.openq));
45: }
46:
47: UnlockDM();
48:
49: return &knl_resource_control_block;
50: }
51:
52: 53: 54:
55: EXPORT ER knl_check_devdesc( ID dd, UINT mode, OpnCB **p_opncb )
56: {
57: OpnCB *opncb;
58:
59: if ( dd < 1 || dd > MAX_OPNDEV ) {
60: return E_ID;
61: }
62: opncb = OPNCB(dd);
63: if ( opncb->resid == 0 ) {
64: return E_ID;
65: }
66:
67: if ( mode != 0 ) {
68: if ( (opncb->omode & mode) == 0 ) {
69: return E_OACV;
70: }
71: }
72:
73: *p_opncb = opncb;
74: return E_OK;
75: }
76:
77: 78: 79:
80: EXPORT void knl_delOpnCB( OpnCB *opncb, BOOL free )
81: {
82: QueRemove(&opncb->q);
83: QueRemove(&opncb->resq);
84:
85: if ( free ) {
86: QueInsert(&opncb->q, &knl_FreeOpnCB);
87: }
88: opncb->resid = 0;
89: }
90:
91: 92: 93:
94: EXPORT void knl_delReqCB( ReqCB *reqcb )
95: {
96: QueRemove(&reqcb->q);
97:
98: QueInsert(&reqcb->q, &knl_FreeReqCB);
99: reqcb->opncb = NULL;
100: }
101:
102:
103:
104: 105: 106:
107: EXPORT BOOL knl_chkopen( DevCB *devcb, INT unitno )
108: {
109: QUEUE *q;
110:
111: for ( q = devcb->openq.next; q != &devcb->openq; q = q->next ) {
112: if ( ((OpnCB*)q)->unitno == unitno ) {
113: return TRUE;
114: }
115: }
116: return FALSE;
117: }
118:
119:
120: LOCAL CONST T_CSEM knl_pk_csem_DM = {
121: NULL,
122: TA_TFIFO | TA_FIRST,
123: 0,
124: 1,
125: };
126:
127: 128: 129:
130: LOCAL OpnCB* newOpnCB( DevCB *devcb, INT unitno, UINT omode, ResCB *rescb )
131: {
132: OpnCB *opncb;
133:
134:
135: opncb = (OpnCB*)QueRemoveNext(&knl_FreeOpnCB);
136: if ( opncb == NULL ) {
137: return NULL;
138: }
139:
140:
141: QueInsert(&opncb->q, &devcb->openq);
142: QueInsert(&opncb->resq, &rescb->openq);
143:
144: opncb->devcb = devcb;
145: opncb->unitno = unitno;
146: opncb->omode = omode;
147: QueInit(&opncb->requestq);
148: opncb->waitone = 0;
149: opncb->nwaireq = 0;
150: opncb->abort_tskid = 0;
151:
152: opncb->resid = 0;
153:
154: return opncb;
155: }
156:
157: 158: 159:
160: LOCAL ER chkopenmode( DevCB *devcb, INT unitno, UINT omode )
161: {
162: QUEUE *q;
163: OpnCB *opncb;
164: INT read, write, rexcl, wexcl;
165:
166: if ( (omode & TD_UPDATE) == 0 ) {
167: return E_PAR;
168: }
169:
170:
171: read = write = rexcl = wexcl = 0;
172: for ( q = devcb->openq.next; q != &devcb->openq; q = q->next ) {
173: opncb = (OpnCB*)q;
174:
175: if ( unitno == 0 || opncb->unitno == 0 || opncb->unitno == unitno ) {
176: if ( (opncb->omode & TD_READ) != 0 ) {
177: read++;
178: }
179: if ( (opncb->omode & TD_WRITE) != 0 ) {
180: write++;
181: }
182: if ( (opncb->omode & (TD_EXCL|TD_REXCL)) != 0) {
183: rexcl++;
184: }
185: if ( (opncb->omode & (TD_EXCL|TD_WEXCL)) != 0) {
186: wexcl++;
187: }
188: }
189: }
190:
191:
192: if ( (omode & (TD_EXCL|TD_REXCL)) != 0 && read > 0 ) {
193: return E_BUSY;
194: }
195: if ( (omode & (TD_EXCL|TD_WEXCL)) != 0 && write > 0 ) {
196: return E_BUSY;
197: }
198: if ( (omode & TD_READ) != 0 && rexcl > 0 ) {
199: return E_BUSY;
200: }
201: if ( (omode & TD_WRITE) != 0 && wexcl > 0 ) {
202: return E_BUSY;
203: }
204:
205: return E_OK;
206: }
207:
208: 209: 210:
211: SYSCALL ID tk_opn_dev( CONST UB *devnm, UINT omode )
212: {
213: OPNFN openfn;
214: void *exinf;
215: UB pdevnm[L_DEVNM + 1];
216: INT unitno;
217: ResCB *rescb;
218: DevCB *devcb;
219: OpnCB *opncb;
220: ER ercd;
221: ID semid;
222:
223: unitno = knl_phydevnm(pdevnm, devnm);
224:
225:
226: rescb = knl_GetResCB();
227: if ( rescb == NULL ) {
228: ercd = E_CTX;
229: goto err_ret1;
230: }
231:
232: LockDM();
233:
234:
235: devcb = knl_searchDevCB(pdevnm);
236: if ( devcb == NULL || unitno > devcb->ddev.nsub ) {
237: ercd = E_NOEXS;
238: goto err_ret2;
239: }
240:
241:
242: ercd = chkopenmode(devcb, unitno, omode);
243: if ( ercd < E_OK ) {
244: goto err_ret2;
245: }
246:
247: openfn = (OPNFN)devcb->ddev.openfn;
248: exinf = devcb->ddev.exinf;
249:
250:
251: if ( knl_chkopen(devcb, unitno) && (devcb->ddev.drvatr & TDA_OPENREQ) == 0 ) {
252: openfn = NULL;
253: }
254:
255:
256: opncb = newOpnCB(devcb, unitno, omode, rescb);
257: if ( opncb == NULL ) {
258: ercd = E_LIMIT;
259: goto err_ret2;
260: }
261:
262: semid = tk_cre_sem(&knl_pk_csem_DM);
263: if ( semid < E_OK ) {
264: ercd = E_SYS;
265: goto err_ret2_5;
266: }
267: opncb->abort_semid = semid;
268:
269: UnlockDM();
270:
271: if ( openfn != NULL ) {
272:
273: DISABLE_INTERRUPT;
274: knl_ctxtsk->sysmode++;
275: ENABLE_INTERRUPT;
276: ercd = (*openfn)(DEVID(devcb, unitno), omode, exinf);
277: DISABLE_INTERRUPT;
278: knl_ctxtsk->sysmode--;
279: ENABLE_INTERRUPT;
280:
281: if ( ercd < E_OK ) {
282: goto err_ret3;
283: }
284: }
285:
286: LockDM();
287: opncb->resid = 1;
288: UnlockDM();
289:
290: return DD(opncb);
291:
292: err_ret3:
293: LockDM();
294: tk_del_sem(opncb->abort_semid);
295: err_ret2_5:
296: knl_delOpnCB(opncb, TRUE);
297: err_ret2:
298: UnlockDM();
299: err_ret1:
300: return ercd;
301: }
302:
303: 304: 305:
306: LOCAL void abort_allrequest( OpnCB *opncb )
307: {
308: ABTFN abortfn;
309: WAIFN waitfn;
310: void *exinf;
311: DevCB *devcb;
312: ReqCB *reqcb;
313: QUEUE *q;
314:
315:
316: LockDM();
317:
318: devcb = opncb->devcb;
319: abortfn = (ABTFN)devcb->ddev.abortfn;
320: waitfn = (WAIFN)devcb->ddev.waitfn;
321: exinf = devcb->ddev.exinf;
322:
323: opncb->abort_tskid = tk_get_tid();
324: opncb->abort_cnt = 0;
325:
326: if ( opncb->nwaireq > 0 ) {
327:
328: reqcb = DEVREQ_REQCB(opncb->waireqlst);
329:
330:
331: DISABLE_INTERRUPT;
332: knl_ctxtsk->sysmode++;
333: ENABLE_INTERRUPT;
334: (*abortfn)(reqcb->tskid, opncb->waireqlst, opncb->nwaireq, exinf);
335: DISABLE_INTERRUPT;
336: knl_ctxtsk->sysmode--;
337: ENABLE_INTERRUPT;
338:
339: opncb->abort_cnt++;
340: } else {
341:
342: for ( q = opncb->requestq.next; q != &opncb->requestq; q = q->next ) {
343: reqcb = (ReqCB*)q;
344: if ( reqcb->tskid == 0 ) {
345: continue;
346: }
347:
348: reqcb->req.abort = TRUE;
349:
350:
351: DISABLE_INTERRUPT;
352: knl_ctxtsk->sysmode++;
353: ENABLE_INTERRUPT;
354: (*abortfn)(reqcb->tskid, &reqcb->req, 1, exinf);
355: DISABLE_INTERRUPT;
356: knl_ctxtsk->sysmode--;
357: ENABLE_INTERRUPT;
358:
359: opncb->abort_cnt++;
360: }
361: }
362:
363: UnlockDM();
364:
365: if ( opncb->abort_cnt > 0 ) {
366:
367: tk_wai_sem(opncb->abort_semid, 1, TMO_FEVR);
368: }
369: opncb->abort_tskid = 0;
370:
371:
372: LockDM();
373: while ( !isQueEmpty(&opncb->requestq) ) {
374: reqcb = (ReqCB*)opncb->requestq.next;
375: reqcb->req.abort = TRUE;
376:
377: UnlockDM();
378:
379:
380: DISABLE_INTERRUPT;
381: knl_ctxtsk->sysmode++;
382: ENABLE_INTERRUPT;
383: (*waitfn)(&reqcb->req, 1, TMO_FEVR, exinf);
384: DISABLE_INTERRUPT;
385: knl_ctxtsk->sysmode--;
386: ENABLE_INTERRUPT;
387:
388: LockDM();
389:
390:
391: knl_delReqCB(reqcb);
392: }
393: UnlockDM();
394: }
395:
396: 397: 398:
399: EXPORT ER knl_close_device( OpnCB *opncb, UINT option )
400: {
401: CLSFN closefn;
402: void *exinf;
403: ID devid;
404: DevCB *devcb;
405: INT unitno;
406: ER ercd = E_OK;
407:
408:
409: abort_allrequest(opncb);
410:
411: LockDM();
412:
413: devcb = opncb->devcb;
414: unitno = opncb->unitno;
415: closefn = (CLSFN)devcb->ddev.closefn;
416: exinf = devcb->ddev.exinf;
417: devid = DEVID(devcb, unitno);
418:
419:
420: tk_del_sem(opncb->abort_semid);
421:
422:
423: knl_delOpnCB(opncb, FALSE);
424:
425:
426: if ( knl_chkopen(devcb, unitno) ) {
427: option &= ~TD_EJECT;
428: if ( (devcb->ddev.drvatr & TDA_OPENREQ) == 0 ) {
429: closefn = NULL;
430: }
431: }
432:
433: UnlockDM();
434:
435: if ( closefn != NULL ) {
436:
437: DISABLE_INTERRUPT;
438: knl_ctxtsk->sysmode++;
439: ENABLE_INTERRUPT;
440: ercd = (*closefn)(devid, option, exinf);
441: DISABLE_INTERRUPT;
442: knl_ctxtsk->sysmode--;
443: ENABLE_INTERRUPT;
444: }
445:
446: LockDM();
447:
448: QueInsert(&opncb->q, &knl_FreeOpnCB);
449: UnlockDM();
450:
451: return ercd;
452: }
453:
454: 455: 456:
457: SYSCALL ER tk_cls_dev( ID dd, UINT option )
458: {
459: OpnCB *opncb;
460: ER ercd;
461:
462: LockDM();
463:
464: ercd = knl_check_devdesc(dd, 0, &opncb);
465: if ( ercd < E_OK ) {
466: UnlockDM();
467: goto err_ret;
468: }
469:
470: opncb->resid = 0;
471:
472: UnlockDM();
473:
474:
475: ercd = knl_close_device(opncb, option);
476:
477: err_ret:
478: return ercd;
479: }
480:
481:
482:
483: 484: 485:
486: LOCAL ReqCB* newReqCB( OpnCB *opncb )
487: {
488: ReqCB *reqcb;
489:
490:
491: reqcb = (ReqCB*)QueRemoveNext(&knl_FreeReqCB);
492: if ( reqcb == NULL ) {
493: return NULL;
494: }
495:
496:
497: QueInsert(&reqcb->q, &opncb->requestq);
498:
499: reqcb->opncb = opncb;
500:
501: return reqcb;
502: }
503:
504: 505: 506:
507: EXPORT ID knl_request( ID dd, W start, void *buf, W size, TMO tmout, INT cmd )
508: {
509: EXCFN execfn;
510: void *exinf;
511: OpnCB *opncb;
512: DevCB *devcb;
513: ReqCB *reqcb;
514: UINT m;
515: ER ercd;
516:
517: LockDM();
518:
519: if ( start <= -0x00010000 && start >= -0x7fffffff ) {
520: m = 0;
521: } else {
522: m = ( cmd == TDC_READ )? TD_READ: TD_WRITE;
523: }
524: ercd = knl_check_devdesc(dd, m, &opncb);
525: if ( ercd < E_OK ) {
526: goto err_ret1;
527: }
528:
529: devcb = opncb->devcb;
530: execfn = (EXCFN)devcb->ddev.execfn;
531: exinf = devcb->ddev.exinf;
532:
533:
534: reqcb = newReqCB(opncb);
535: if ( reqcb == NULL ) {
536: ercd = E_LIMIT;
537: goto err_ret1;
538: }
539:
540:
541: reqcb->req.next = NULL;
542: reqcb->req.exinf = NULL;
543: reqcb->req.devid = DEVID(devcb, opncb->unitno);
544: reqcb->req.cmd = cmd;
545: reqcb->req.abort = FALSE;
546: reqcb->req.start = start;
547: reqcb->req.size = size;
548: reqcb->req.buf = buf;
549: reqcb->req.asize = 0;
550: reqcb->req.error = 0;
551:
552:
553: reqcb->tskid = tk_get_tid();
554:
555: UnlockDM();
556:
557:
558: DISABLE_INTERRUPT;
559: knl_ctxtsk->sysmode++;
560: ENABLE_INTERRUPT;
561: ercd = (*execfn)(&reqcb->req, tmout, exinf);
562: DISABLE_INTERRUPT;
563: knl_ctxtsk->sysmode--;
564: ENABLE_INTERRUPT;
565:
566: LockDM();
567:
568:
569: reqcb->tskid = 0;
570:
571: 572:
573: if ( opncb->abort_tskid > 0 && --opncb->abort_cnt == 0 ) {
574: tk_sig_sem(opncb->abort_semid, 1);
575: }
576:
577: if ( ercd < E_OK ) {
578: goto err_ret2;
579: }
580:
581: UnlockDM();
582:
583: return REQID(reqcb);
584:
585: err_ret2:
586: knl_delReqCB(reqcb);
587: err_ret1:
588: UnlockDM();
589: return ercd;
590: }
591:
592: 593: 594:
595: SYSCALL ID tk_rea_dev( ID dd, W start, void *buf, SZ size, TMO tmout )
596: {
597: ER ercd;
598:
599: ercd = knl_request(dd, start, buf, size, tmout, TDC_READ);
600:
601: return ercd;
602: }
603:
604: 605: 606:
607: SYSCALL ER tk_srea_dev( ID dd, W start, void *buf, SZ size, SZ *asize )
608: {
609: ER ercd, ioercd;
610:
611: ercd = tk_rea_dev(dd, start, buf, size, TMO_FEVR);
612: if ( ercd < E_OK ) {
613: goto err_ret;
614: }
615:
616: ercd = tk_wai_dev(dd, ercd, asize, &ioercd, TMO_FEVR);
617: if ( ercd < E_OK ) {
618: goto err_ret;
619: }
620:
621: return ioercd;
622:
623: err_ret:
624: return ercd;
625: }
626:
627: 628: 629:
630: SYSCALL ID tk_wri_dev( ID dd, W start, CONST void *buf, SZ size, TMO tmout )
631: {
632: ER ercd;
633:
634: ercd = knl_request(dd, start, (void *)buf, size, tmout, TDC_WRITE);
635:
636: return ercd;
637: }
638:
639: 640: 641:
642: SYSCALL ER tk_swri_dev( ID dd, W start, CONST void *buf, SZ size, SZ *asize )
643: {
644: ER ercd, ioercd;
645:
646: ercd = tk_wri_dev(dd, start, buf, size, TMO_FEVR);
647: if ( ercd < E_OK ) {
648: goto err_ret;
649: }
650:
651: ercd = tk_wai_dev(dd, ercd, asize, &ioercd, TMO_FEVR);
652: if ( ercd < E_OK ) {
653: goto err_ret;
654: }
655:
656: return ioercd;
657:
658: err_ret:
659: return ercd;
660: }
661:
662: 663: 664:
665: LOCAL ReqCB* knl_check_reqid( ID reqid, OpnCB *opncb )
666: {
667: ReqCB *reqcb;
668:
669: if ( reqid < 1 || reqid > MAX_REQDEV ) {
670: return NULL;
671: }
672: reqcb = REQCB(reqid);
673: if ( reqcb->opncb != opncb ) {
674: return NULL;
675: }
676:
677: return reqcb;
678: }
679:
680: 681: 682:
683: SYSCALL ID tk_wai_dev( ID dd, ID reqid, SZ *asize, ER *ioer, TMO tmout )
684: {
685: WAIFN waitfn;
686: void *exinf;
687: OpnCB *opncb;
688: DevCB *devcb;
689: ReqCB *reqcb;
690: T_DEVREQ *devreq;
691: INT reqno, nreq;
692: ID tskid;
693: ER ercd;
694:
695: tskid = tk_get_tid();
696:
697: LockDM();
698:
699: ercd = knl_check_devdesc(dd, 0, &opncb);
700: if ( ercd < E_OK ) {
701: goto err_ret2;
702: }
703:
704: devcb = opncb->devcb;
705: waitfn = (WAIFN)devcb->ddev.waitfn;
706: exinf = devcb->ddev.exinf;
707:
708: if ( reqid == 0 ) {
709:
710: if ( opncb->nwaireq > 0 || opncb->waitone > 0 ) {
711: ercd = E_OBJ;
712: goto err_ret2;
713: }
714: if ( isQueEmpty(&opncb->requestq) ) {
715: ercd = E_NOEXS;
716: goto err_ret2;
717: }
718:
719:
720: reqcb = (ReqCB*)opncb->requestq.next;
721: for ( nreq = 1;; nreq++ ) {
722: reqcb->tskid = tskid;
723: devreq = &reqcb->req;
724: reqcb = (ReqCB*)reqcb->q.next;
725: if ( reqcb == (ReqCB*)&opncb->requestq ) {
726: break;
727: }
728: devreq->next = &reqcb->req;
729: }
730: devreq->next = NULL;
731: devreq = &((ReqCB*)opncb->requestq.next)->req;
732:
733: opncb->waireqlst = devreq;
734: opncb->nwaireq = nreq;
735: } else {
736:
737: reqcb = knl_check_reqid(reqid, opncb);
738: if ( reqcb == NULL ) {
739: ercd = E_ID;
740: goto err_ret2;
741: }
742: if ( opncb->nwaireq > 0 || reqcb->tskid > 0 ) {
743: ercd = E_OBJ;
744: goto err_ret2;
745: }
746:
747:
748: reqcb->tskid = tskid;
749: devreq = &reqcb->req;
750: devreq->next = NULL;
751: nreq = 1;
752:
753: opncb->waitone++;
754: }
755:
756: UnlockDM();
757:
758:
759: DISABLE_INTERRUPT;
760: knl_ctxtsk->sysmode++;
761: ENABLE_INTERRUPT;
762: reqno = (*waitfn)(devreq, nreq, tmout, exinf);
763: DISABLE_INTERRUPT;
764: knl_ctxtsk->sysmode--;
765: ENABLE_INTERRUPT;
766:
767: if ( reqno < E_OK ) {
768: ercd = reqno;
769: }
770: if ( reqno >= nreq ) {
771: ercd = E_SYS;
772: }
773:
774: LockDM();
775:
776:
777: if ( reqid == 0 ) {
778: opncb->nwaireq = 0;
779: } else {
780: opncb->waitone--;
781: }
782:
783: 784:
785: if ( opncb->abort_tskid > 0 && --opncb->abort_cnt == 0 ) {
786: tk_sig_sem(opncb->abort_semid, 1);
787: }
788:
789:
790: while ( devreq != NULL ) {
791: reqcb = DEVREQ_REQCB(devreq);
792: if ( reqno-- == 0 ) {
793: reqid = REQID(reqcb);
794: *asize = devreq->asize;
795: *ioer = devreq->error;
796: }
797: reqcb->tskid = 0;
798: devreq = devreq->next;
799: }
800:
801: if ( ercd < E_OK ) {
802: goto err_ret2;
803: }
804:
805:
806: knl_delReqCB(REQCB(reqid));
807:
808: UnlockDM();
809:
810: return reqid;
811:
812: err_ret2:
813: UnlockDM();
814: return ercd;
815: }
816:
817:
818:
819:
820: EXPORT INT knl_DisSusCnt = 0;
821:
822: 823: 824:
825: LOCAL ER sendevt_alldevice( INT evttyp, BOOL disk )
826: {
827: EVTFN eventfn;
828: QUEUE *q;
829: DevCB *devcb;
830: BOOL d;
831: ER ercd = E_OK;
832:
833: for ( q = knl_UsedDevCB.next; q != &knl_UsedDevCB; q = q->next ) {
834: devcb = (DevCB*)q;
835:
836: d = ( (devcb->ddev.devatr & TD_DEVTYPE) == TDK_DISK )?
837: TRUE: FALSE;
838: if ( disk != d ) {
839: continue;
840: }
841:
842:
843: eventfn = (EVTFN)devcb->ddev.eventfn;
844: DISABLE_INTERRUPT;
845: knl_ctxtsk->sysmode++;
846: ENABLE_INTERRUPT;
847: ercd = (*eventfn)(evttyp, NULL, devcb->ddev.exinf);
848: DISABLE_INTERRUPT;
849: knl_ctxtsk->sysmode--;
850: ENABLE_INTERRUPT;
851: }
852:
853: return ercd;
854: }
855:
856: 857: 858:
859: LOCAL ER do_suspend( void )
860: {
861: ER ercd;
862:
863:
864: LockREG();
865:
866:
867: ercd = sendevt_alldevice(TDV_SUSPEND, FALSE);
868:
869:
870: ercd = sendevt_alldevice(TDV_SUSPEND, TRUE);
871:
872:
873: LockDM();
874:
875: 876: 877:
878:
879: 880: 881:
882:
883:
884:
885: UnlockDM();
886:
887:
888: ercd = sendevt_alldevice(TDV_RESUME, TRUE);
889:
890:
891: ercd = sendevt_alldevice(TDV_RESUME, FALSE);
892:
893:
894: UnlockREG();
895:
896: return ercd;
897: }
898:
899: 900: 901:
902: SYSCALL INT tk_sus_dev( UINT mode )
903: {
904: ResCB *rescb;
905: BOOL suspend = FALSE;
906: ER ercd;
907:
908:
909: rescb = knl_GetResCB();
910: if ( rescb == NULL ) {
911: ercd = E_CTX;
912: goto err_ret1;
913: }
914:
915: LockDM();
916:
917: switch ( mode & 0xf ) {
918: case TD_SUSPEND:
919: if ( knl_DisSusCnt > 0 && (mode & TD_FORCE) == 0 ) {
920: ercd = E_BUSY;
921: goto err_ret2;
922: }
923: suspend = TRUE;
924: break;
925:
926: case TD_DISSUS:
927: if ( knl_DisSusCnt >= MAX_DISSUS ) {
928: ercd = E_QOVR;
929: goto err_ret2;
930: }
931: knl_DisSusCnt++;
932: rescb->dissus++;
933: break;
934: case TD_ENASUS:
935: if ( rescb->dissus > 0 ) {
936: rescb->dissus--;
937: knl_DisSusCnt--;
938: }
939: break;
940:
941: case TD_CHECK:
942: break;
943:
944: default:
945: ercd = E_PAR;
946: goto err_ret2;
947: }
948:
949: UnlockDM();
950:
951: if ( suspend ) {
952:
953: ercd = do_suspend();
954: if ( ercd < E_OK ) {
955: goto err_ret1;
956: }
957: }
958:
959: return knl_DisSusCnt;
960:
961: err_ret2:
962: UnlockDM();
963: err_ret1:
964: return ercd;
965: }
966:
967:
968:
969: 970: 971:
972: EXPORT void knl_devmgr_startup( void )
973: {
974: LockDM();
975:
976:
977: QueInit(&(knl_resource_control_block.openq));
978: knl_resource_control_block.dissus = 0;
979:
980: UnlockDM();
981:
982: return;
983: }
984:
985: 986: 987:
988: EXPORT void knl_devmgr_cleanup( void )
989: {
990: OpnCB *opncb;
991:
992:
993: if ( knl_resource_control_block.openq.next == NULL ) {
994: return;
995: }
996:
997: LockDM();
998:
999:
1000: knl_DisSusCnt -= knl_resource_control_block.dissus;
1001: knl_resource_control_block.dissus = 0;
1002:
1003:
1004: while ( !isQueEmpty(&(knl_resource_control_block.openq)) ) {
1005: opncb = RESQ_OPNCB(knl_resource_control_block.openq.next);
1006:
1007:
1008: opncb->resid = 0;
1009:
1010: UnlockDM();
1011:
1012:
1013: knl_close_device(opncb, 0);
1014:
1015: LockDM();
1016: }
1017: UnlockDM();
1018:
1019: return;
1020: }
1021:
1022: 1023: 1024:
1025: EXPORT ER knl_initDevIO( void )
1026: {
1027: INT i;
1028:
1029: QueInit(&knl_FreeOpnCB);
1030: for ( i = 0; i < MAX_OPNDEV; ++i ) {
1031: knl_OpnCBtbl[i].resid = 0;
1032: QueInsert(&knl_OpnCBtbl[i].q, &knl_FreeOpnCB);
1033: }
1034:
1035: QueInit(&knl_FreeReqCB);
1036: for ( i = 0; i < MAX_REQDEV; ++i ) {
1037: knl_ReqCBtbl[i].opncb = NULL;
1038: QueInsert(&knl_ReqCBtbl[i].q, &knl_FreeReqCB);
1039: }
1040:
1041: return E_OK;
1042: }
1043:
1044: 1045: 1046:
1047: EXPORT ER knl_finishDevIO( void )
1048: {
1049: return E_OK;
1050: }
1051:
1052: #endif