1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16:
17: 18: 19: 20: 21:
22:
23: #include <basic.h>
24: #include <device/gdrvif.h>
25: #include <tk/tkernel.h>
26: #include <tk/util.h>
27: #include <sys/queue.h>
28: #include <libstr.h>
29: #include <sys/debug.h>
30:
31: typedef enum {
32: NotDone = 0,
33: Abort = 1,
34: Done = 2
35: } DONE;
36:
37: 38: 39:
40: typedef struct DeviceRequestQueue {
41: QUEUE q;
42: T_DEVREQ *req;
43: INT memsz;
44: ID wtid;
45: DONE done;
46: } DRQ;
47:
48: 49: 50:
51: struct GeneralDriverInterface {
52: FastMLock lock;
53: GDefDev def;
54: ID devid;
55:
56: DRQ *drq;
57: QUEUE freeq;
58: QUEUE acpq;
59: ID flgid;
60:
61: INT limit;
62: INT preq[2];
63:
64: INT acpd[2];
65: INT acpa[2];
66: };
67:
68:
69: #define cntacpq(req, gdi, ope) \
70: if ( (req)->cmd == TDC_READ ) { \
71: if ( (req)->start < 0 ) (gdi)->acpa[0] ope; \
72: else (gdi)->acpd[0] ope; \
73: } else { \
74: if ( (req)->start < 0 ) (gdi)->acpa[1] ope; \
75: else (gdi)->acpd[1] ope; \
76: }
77:
78:
79: #define validDRQ(q, gdi) \
80: ( (q) >= (gdi)->drq && (q) < (gdi)->drq + (gdi)->def.maxreqq )
81:
82: 83: 84: 85:
86: #define FREEQ_RD 0x40000000
87: #define FREEQ_WR 0x80000000
88:
89: 90: 91:
92: #define LockGDI(gdi) MLock(&(gdi)->lock, 0)
93: #define UnlockGDI(gdi) MUnlock(&(gdi)->lock, 0)
94:
95: 96: 97:
98: #define LockCALL(gdi) MLock(&(gdi)->lock, 1)
99: #define UnlockCALL(gdi) MUnlock(&(gdi)->lock, 1)
100:
101: 102: 103:
104: #define LockDRQ(gdi, rw, tmo) MLockTmo(&(gdi)->lock, 2 + (rw), (tmo))
105: #define UnlockDRQ(gdi, rw) MUnlock(&(gdi)->lock, 2 + (rw))
106:
107: 108: 109:
110: LOCAL INT GDI_TEV;
111:
112: #define TEVPTN(tev) ( 1 << ((tev) - 1) )
113: #define TTWTEV(tev) ( TTW_EV1 << ((tev) - 1) )
114:
115:
116: 117: 118: 119: 120:
121:
122: 123: 124:
125: EXPORT ID GDI_devid( GDI gdi )
126: {
127: return gdi->devid;
128: }
129:
130: 131: 132:
133: EXPORT void* GDI_exinf( GDI gdi )
134: {
135: return gdi->def.exinf;
136: }
137:
138: 139: 140:
141: EXPORT const GDefDev* GDI_ddev( GDI gdi )
142: {
143: return &gdi->def;
144: }
145:
146:
147: 148: 149:
150:
151: 152: 153: 154:
155: LOCAL ER gdi_getDRQ( DRQ **p_drq, T_DEVREQ *req, TMO tmout, GDI gdi )
156: {
157: DRQ *drq;
158: SYSTIM stime, ctime;
159: TMO tmo = tmout;
160: INT rw;
161: UINT ptn, waiptn;
162: ER err;
163:
164: rw = ( req->cmd == TDC_READ )? 0 : 1;
165: waiptn = ( rw == 0 )? FREEQ_RD: FREEQ_WR;
166:
167: if ( tmout != TMO_FEVR ) {
168: err = tk_get_otm(&stime);
169: if ( err < E_OK ) goto err_ret1;
170: }
171:
172: 173:
174: err = LockDRQ(gdi, rw, tmo);
175: if ( err < E_OK ) goto err_ret1;
176:
177: for ( ;; ) {
178:
179: LockGDI(gdi);
180: if ( gdi->preq[rw] < gdi->limit ) {
181: drq = (DRQ*)QueRemoveNext(&gdi->freeq);
182: if ( drq != NULL ) break;
183: }
184: UnlockGDI(gdi);
185:
186:
187: if ( tmout != TMO_FEVR ) {
188: err = tk_get_otm(&ctime);
189: if ( err < E_OK ) goto err_ret2;
190:
191: tmo = tmout - (ctime.lo - stime.lo);
192: if ( tmo <= 0 ) { err = E_TMOUT; goto err_ret2; }
193: }
194:
195: err = tk_wai_flg(gdi->flgid, waiptn, TWF_ORW | TWF_BITCLR,
196: &ptn, tmo);
197: if ( err < E_OK ) {
198: if ( err == E_DISWAI ) err = E_ABORT;
199: goto err_ret2;
200: }
201: }
202:
203:
204: UnlockDRQ(gdi, rw);
205:
206: gdi->preq[rw]++;
207:
208:
209: drq->req = req;
210: if ( req->exinf != NULL ) {
211:
212: drq->wtid = *(ID*)req->exinf;
213: }
214: req->exinf = drq;
215:
216: *p_drq = drq;
217: return E_OK;
218:
219: err_ret2:
220: UnlockDRQ(gdi, rw);
221: err_ret1:
222: DEBUG_PRINT(("gdi_getDRQ err = %d\n", err));
223: return err;
224: }
225:
226: 227: 228: 229:
230: LOCAL void gdi_relDRQ( DRQ *drq, GDI gdi )
231: {
232: UINT ptn = isQueEmpty(&gdi->freeq)? (FREEQ_RD|FREEQ_WR): 0;
233:
234: if ( drq->req->cmd == TDC_READ ) {
235: if ( gdi->preq[0]-- == gdi->limit ) ptn |= FREEQ_RD;
236: } else {
237: if ( gdi->preq[1]-- == gdi->limit ) ptn |= FREEQ_WR;
238: }
239:
240: if ( ptn != 0 ) {
241: tk_set_flg(gdi->flgid, ptn);
242: }
243:
244: QueInsert((QUEUE*)drq, &gdi->freeq);
245:
246: drq->req = NULL;
247: drq->wtid = 0;
248: drq->done = NotDone;
249: }
250:
251: 252: 253: 254:
255: LOCAL ER gdi_sndreq( DRQ *drq, GDI gdi )
256: {
257: T_DEVREQ *req = drq->req;
258: UINT setptn;
259: ER err;
260:
261: if ( req->abort ) { err = E_ABORT; goto err_ret1; }
262:
263:
264: setptn = 0;
265: if ( req->cmd == TDC_READ ) {
266: if ( req->start < 0 ) {
267: if ( gdi->acpa[0]++ == 0 ) setptn |= DRP_AREAD;
268: } else {
269: if ( gdi->acpd[0]++ == 0 ) setptn |= DRP_DREAD;
270: }
271: } else {
272: if ( req->start < 0 ) {
273: if ( gdi->acpa[1]++ == 0 ) setptn |= DRP_AWRITE;
274: } else {
275: if ( gdi->acpd[1]++ == 0 ) setptn |= DRP_DWRITE;
276: }
277: }
278: QueInsert((QUEUE*)drq, &gdi->acpq);
279:
280: if ( setptn != 0 ) {
281:
282: err = tk_set_flg(gdi->flgid, setptn);
283: if ( err < E_OK ) goto err_ret2;
284: }
285:
286: return E_OK;
287:
288: err_ret2:
289: cntacpq(req, gdi, --);
290: QueRemove((QUEUE*)drq);
291: err_ret1:
292: DEBUG_PRINT(("gdi_sndreq err = %d\n", err));
293: return err;
294: }
295:
296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356:
357: EXPORT INT GDI_Accept( T_DEVREQ **devreq, INT _acpptn, TMO tmout, GDI gdi )
358: {
359: DRQ *drq;
360: T_DEVREQ *req;
361: QUEUE *q;
362: INT reqptn, rptn;
363: UINT acpptn, aptn;
364: SYSTIM stime, ctime;
365: TMO tmo;
366: ER err;
367:
368: if ( (_acpptn & DRP_ADSEL) == 0 ) {
369:
370: if ( (_acpptn & ~(DRP_NORMREQ|DRP_USERCMD)) != 0 )
371: { err = E_PAR; goto err_ret; }
372: acpptn = ((_acpptn & DRP_NORMREQ) << 8) | _acpptn;
373: } else {
374:
375: if ( (_acpptn & ~(DRP_REQMASK|DRP_USERCMD)) != 0 )
376: { err = E_PAR; goto err_ret; }
377: acpptn = _acpptn & ~DRP_ADSEL;
378: }
379:
380: aptn = 0;
381: tmo = TMO_FEVR;
382: stime.lo = 0;
383:
384: for ( ;; ) {
385:
386: LockGDI(gdi);
387: drq = NULL;
388: req = NULL; rptn = 0;
389: for ( q = gdi->acpq.next; q != &gdi->acpq; q = q->next ) {
390: req = ((DRQ*)q)->req;
391: rptn = DEVREQ_ACPPTN(req->cmd);
392: if ( req->start < 0 ) rptn <<= 8;
393: if ( (rptn & acpptn) == 0 ) continue;
394:
395: drq = (DRQ*)q;
396: cntacpq(req, gdi, --);
397: QueRemove(q);
398: QueInit(q);
399: break;
400: }
401: UnlockGDI(gdi);
402: reqptn = aptn & DRP_USERCMD;
403: if ( drq != NULL ) {
404: if ( req->abort ) {
405:
406: req->error = E_ABORT;
407: GDI_Reply(req, gdi);
408: continue;
409: }
410:
411:
412: *devreq = req;
413: reqptn |= rptn;
414:
415: if ( (aptn &= ~rptn & DRP_REQMASK) != 0 ) {
416:
417: tk_set_flg(gdi->flgid, aptn);
418: }
419: break;
420: }
421: if ( reqptn != 0 ) {
422:
423: *devreq = NULL;
424: break;
425: }
426:
427:
428: if ( tmout != TMO_FEVR ) {
429: err = tk_get_otm(&ctime);
430: if ( err < E_OK ) goto err_ret;
431: if ( tmo < 0 ) {
432: stime = ctime;
433: tmo = tmout;
434: } else {
435: tmo = tmout - (ctime.lo - stime.lo);
436: if ( tmo < 0 ) tmo = 0;
437: }
438: }
439:
440:
441: err = tk_wai_flg(gdi->flgid, acpptn, TWF_ORW | TWF_BITCLR,
442: &aptn, tmo);
443: if ( err < E_OK ) goto err_ret;
444: aptn &= acpptn;
445: }
446:
447: if ( (reqptn & DRP_REQMASK) != 0 ) {
448: if ( (_acpptn & DRP_ADSEL) == 0 ) {
449:
450: reqptn |= (reqptn & (DRP_NORMREQ << 8)) >> 8;
451: reqptn &= ~(DRP_NORMREQ << 8);
452: } else {
453:
454: reqptn |= DRP_ADSEL;
455: }
456: }
457:
458: return reqptn;
459:
460: err_ret:
461: DEBUG_PRINT(("GDI_Accept err = %d\n", err));
462: return err;
463: }
464:
465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479:
480: EXPORT ER GDI_SendCmd( INT cmd, GDI gdi )
481: {
482: ER err;
483:
484: if ( cmd < 16 || cmd > 23 ) { err = E_PAR; goto err_ret; }
485:
486: err = tk_set_flg(gdi->flgid, DEVREQ_ACPPTN(cmd));
487: if ( err < E_OK ) goto err_ret;
488:
489: return E_OK;
490:
491: err_ret:
492: DEBUG_PRINT(("GDI_SendCmd err = %d\n", err));
493: return err;
494: }
495:
496: 497: 498: 499: 500: 501:
502: EXPORT void GDI_Reply( T_DEVREQ *req, GDI gdi )
503: {
504: DRQ *drq = req->exinf;
505:
506: LockGDI(gdi);
507: drq->done = Done;
508:
509: if ( drq->wtid > 0 ) {
510:
511: tk_sig_tev(drq->wtid, GDI_TEV);
512: }
513: UnlockGDI(gdi);
514: }
515:
516:
517: 518: 519:
520:
521: 522: 523:
524: LOCAL ER gdi_openfn( ID devid, UINT omode, GDI gdi )
525: {
526: ER err;
527:
528: if ( gdi->def.open == NULL ) return E_OK;
529:
530: LockCALL(gdi);
531: err = (*gdi->def.open)(devid, omode, gdi);
532: UnlockCALL(gdi);
533:
534: return err;
535: }
536:
537: 538: 539:
540: LOCAL ER gdi_closefn( ID devid, UINT option, GDI gdi )
541: {
542: ER err;
543:
544: if ( gdi->def.close == NULL ) return E_OK;
545:
546: LockCALL(gdi);
547: err = (*gdi->def.close)(devid, option, gdi);
548: UnlockCALL(gdi);
549:
550: return err;
551: }
552:
553: 554: 555:
556: LOCAL ER gdi_execfn( T_DEVREQ *req, TMO tmout, GDI gdi )
557: {
558: DRQ *drq;
559: INT memsz;
560: ER err;
561:
562:
563: if ( req->start < 0 ) {
564:
565: memsz = req->size;
566: } else {
567:
568: if ( gdi->def.blksz <= 0 ) { err = E_PAR; goto err_ret1; }
569: memsz = req->size * gdi->def.blksz;
570: }
571: if ( memsz < 0 ) { err = E_PAR; goto err_ret1; }
572:
573: if ( memsz > 0 ) {
574:
575: if ( req->cmd == TDC_READ ) {
576: err = ChkSpaceRW(req->buf, memsz);
577: } else {
578: err = ChkSpaceR(req->buf, memsz);
579: }
580: if ( err < E_OK ) goto err_ret1;
581:
582: if ( (gdi->def.drvatr & TDA_LOCKREQ) != 0 && !req->nolock ) {
583:
584: err = LockSpace(req->buf, memsz);
585: if ( err < E_OK ) goto err_ret1;
586: }
587: }
588:
589:
590: err = gdi_getDRQ(&drq, req, tmout, gdi);
591: if ( err < E_OK ) goto err_ret2;
592:
593:
594: drq->memsz = memsz;
595:
596:
597: err = gdi_sndreq(drq, gdi);
598: if ( err < E_OK ) goto err_ret3;
599:
600: UnlockGDI(gdi);
601:
602: return E_OK;
603:
604: err_ret3:
605: gdi_relDRQ(drq, gdi);
606: UnlockGDI(gdi);
607: err_ret2:
608: if ( (gdi->def.drvatr & TDA_LOCKREQ) != 0 && !req->nolock ) {
609: if ( memsz > 0 ) UnlockSpace(req->buf, memsz);
610: }
611: err_ret1:
612: DEBUG_PRINT(("gdi_execfn err = %d\n", err));
613: return err;
614: }
615:
616: 617: 618: 619: 620:
621: LOCAL INT gdi_waitfn_abort( DRQ *drq, GDI gdi )
622: {
623: T_DEVREQ *req = drq->req;
624: INT done;
625:
626: if ( !isQueEmpty(&drq->q) ) {
627:
628: cntacpq(req, gdi, --);
629: QueRemove(&drq->q);
630: QueInit(&drq->q);
631: req->error = E_ABORT;
632: drq->done = Done;
633: done = 1;
634: } else {
635:
636: drq->done = Abort;
637: if ( gdi->def.abort != NULL ) {
638: (*gdi->def.abort)(req, gdi);
639: }
640: done = 0;
641: }
642:
643: return done;
644: }
645:
646: 647: 648:
649: LOCAL INT gdi_waitfn( T_DEVREQ *devreq, INT nreq, TMO tmout, GDI gdi )
650: {
651: T_DEVREQ *req;
652: DRQ *drq, *complete = NULL;
653: ID mytid;
654: INT i, n, abort = 0;
655: INT memsz;
656: void *buf;
657: ER err;
658:
659: mytid = tk_get_tid();
660:
661: LockGDI(gdi);
662:
663:
664: req = devreq;
665: for ( n = 0; n < nreq; ++n ) {
666: drq = req->exinf;
667: if ( drq != NULL && drq->done == Done ) {
668: complete = drq;
669: break;
670: }
671: req = req->next;
672: }
673: if ( complete == NULL ) {
674:
675: req = devreq;
676: for ( i = 0; i < nreq; ++i ) {
677: drq = req->exinf;
678: if ( drq == NULL ) {
679:
680: req->exinf = &mytid;
681: } else {
682:
683: if ( req->abort && drq->done == NotDone ) {
684:
685: abort |= gdi_waitfn_abort(drq, gdi);
686: }
687: drq->wtid = mytid;
688: }
689: req = req->next;
690: }
691: }
692:
693: UnlockGDI(gdi);
694:
695: if ( complete == NULL ) {
696:
697: if ( abort == 0 ) {
698: err = tk_wai_tev(TEVPTN(GDI_TEV), tmout);
699: } else {
700: err = E_ABORT;
701: }
702:
703:
704: req = devreq;
705: LockGDI(gdi);
706: for ( i = 0; i < nreq; ++i ) {
707: drq = req->exinf;
708: if ( validDRQ(drq, gdi) ) {
709: drq->wtid = 0;
710: if ( complete == NULL && drq->done == Done ) {
711: complete = drq;
712: n = i;
713: }
714: } else {
715: req->exinf = NULL;
716: }
717: req = req->next;
718: }
719: UnlockGDI(gdi);
720:
721:
722: tk_wai_tev(TEVPTN(GDI_TEV), TMO_POL);
723:
724: if ( complete == NULL ) {
725: if ( err == E_DISWAI ) err = E_ABORT;
726: if ( err >= E_OK ) err = E_SYS;
727: goto err_ret;
728: }
729: }
730:
731:
732: memsz = ( (gdi->def.drvatr & TDA_LOCKREQ) != 0
733: && !complete->req->nolock )? complete->memsz: 0;
734: buf = complete->req->buf;
735:
736:
737: LockGDI(gdi);
738: gdi_relDRQ(complete, gdi);
739: UnlockGDI(gdi);
740:
741:
742: if ( memsz > 0 ) UnlockSpace(buf, memsz);
743:
744: return n;
745:
746: err_ret:
747: DEBUG_PRINT(("gdi_waitfn err = %d\n", err));
748: return err;
749: }
750:
751: 752: 753: 754:
755: LOCAL ER gdi_abortreq( ID tskid, T_DEVREQ *req, GDI gdi )
756: {
757: DRQ *drq = req->exinf;
758: ER err;
759:
760: if ( drq == NULL ) {
761:
762: tk_dis_wai(tskid, TTW_FLG);
763: return E_OK;
764: }
765:
766: if ( drq->req == NULL ) {
767:
768: return E_OK;
769: }
770:
771: if ( !isQueEmpty(&drq->q) ) {
772:
773: cntacpq(req, gdi, --);
774: QueRemove(&drq->q);
775: QueInit(&drq->q);
776: req->error = E_ABORT;
777: drq->done = Done;
778: }
779:
780: if ( drq->done == Done ) {
781:
782: tk_dis_wai(tskid, TTWTEV(GDI_TEV));
783: return E_OK;
784: }
785:
786:
787: if ( drq->done != Abort ) {
788: drq->done = Abort;
789: if ( gdi->def.abort != NULL ) {
790: err = (*gdi->def.abort)(req, gdi);
791: if ( err < E_OK ) goto err_ret;
792: }
793: }
794:
795: return E_OK;
796:
797: err_ret:
798: DEBUG_PRINT(("gdi_abortreq err = %d\n", err));
799: return err;
800: }
801:
802: 803: 804:
805: LOCAL ER gdi_abortfn( ID tskid, T_DEVREQ *req, INT nreq, GDI gdi )
806: {
807: LockGDI(gdi);
808: if ( nreq == 1 ) {
809:
810: gdi_abortreq(tskid, req, gdi);
811: } else {
812:
813: tk_dis_wai(tskid, TTWTEV(GDI_TEV));
814: }
815: UnlockGDI(gdi);
816:
817: return E_OK;
818: }
819:
820: 821: 822:
823: LOCAL INT gdi_eventfn( INT evttyp, void *evtinf, GDI gdi )
824: {
825: INT ret;
826:
827: if ( gdi->def.event == NULL ) return E_OK;
828:
829: LockCALL(gdi);
830: ret = (*gdi->def.event)(evttyp, evtinf, gdi);
831: UnlockCALL(gdi);
832:
833: return ret;
834: }
835:
836:
837: 838: 839:
840:
841: 842: 843:
844: LOCAL ER gdi_defdevice( GDI gdi, T_IDEV *idev )
845: {
846: T_DDEV ddev;
847: ER err;
848:
849: ddev.exinf = gdi;
850: ddev.drvatr = gdi->def.drvatr & ~(TDA_LOCKREQ|TDA_LIMITEDREQ);
851: ddev.devatr = gdi->def.devatr;
852: ddev.nsub = gdi->def.nsub;
853: ddev.blksz = gdi->def.blksz;
854: ddev.openfn = (FP)gdi_openfn;
855: ddev.closefn = (FP)gdi_closefn;
856: ddev.execfn = (FP)gdi_execfn;
857: ddev.waitfn = (FP)gdi_waitfn;
858: ddev.abortfn = (FP)gdi_abortfn;
859: ddev.eventfn = (FP)gdi_eventfn;
860:
861: err = tk_def_dev(gdi->def.devnm, &ddev, idev);
862: if ( err < E_OK ) goto err_ret;
863:
864: gdi->devid = (ID)err;
865:
866: return E_OK;
867:
868: err_ret:
869: DEBUG_PRINT(("gdi_defdevice err = %d\n", err));
870: return err;
871: }
872:
873: 874: 875: 876: 877: 878: 879:
880: EXPORT ER GDefDevice( const GDefDev *ddev, T_IDEV *idev, GDI *p_gdi )
881: {
882: GDI gdi;
883: DRQ *drq;
884: T_CFLG cflg;
885: INT n;
886: ER err;
887:
888: if ( ddev->maxreqq < 1 ) { err = E_PAR; goto err_ret1; }
889:
890: if ( GDI_TEV == 0 ) {
891:
892: n = tk_get_cfn((UB*)"TEV_GDI", &GDI_TEV, 1);
893: if ( n < 1 ) { err = ( n < E_OK )? n: E_SYS; goto err_ret1; }
894: }
895:
896:
897: gdi = Kmalloc(sizeof(*gdi));
898: if ( gdi == NULL ) { err = E_NOMEM; goto err_ret1; }
899:
900: gdi->def = *ddev;
901: QueInit(&gdi->freeq);
902: QueInit(&gdi->acpq);
903:
904: gdi->limit = ddev->maxreqq + 1;
905: if ( (ddev->drvatr & TDA_LIMITEDREQ) != 0 ) gdi->limit /= 2;
906: gdi->preq[0] = gdi->preq[1] = 0;
907: gdi->acpd[0] = gdi->acpd[1] = 0;
908: gdi->acpa[0] = gdi->acpa[1] = 0;
909:
910:
911: n = ddev->maxreqq;
912: drq = Kcalloc(n, sizeof(DRQ));
913: if ( drq == NULL ) { err = E_NOMEM; goto err_ret2; }
914: gdi->drq = drq;
915: while ( n-- > 0 ) {
916: QueInsert((QUEUE*)drq, &gdi->freeq);
917: drq++;
918: }
919:
920:
921: STRNCPY((B*)&cflg.exinf, (B*)gdi->def.devnm, sizeof(void*));
922: cflg.flgatr = TA_TPRI | TA_WMUL;
923: cflg.iflgptn = 0;
924: err = tk_cre_flg(&cflg);
925: if ( err < E_OK ) goto err_ret3;
926: gdi->flgid = (ID)err;
927:
928:
929: err = CreateMLock(&gdi->lock, gdi->def.devnm);
930: if ( err < E_OK ) goto err_ret4;
931:
932:
933: err = gdi_defdevice(gdi, idev);
934: if ( err < E_OK ) goto err_ret5;
935:
936: *p_gdi = gdi;
937: return E_OK;
938:
939: err_ret5:
940: DeleteMLock(&gdi->lock);
941: err_ret4:
942: tk_del_flg(gdi->flgid);
943: err_ret3:
944: Kfree(gdi->drq);
945: err_ret2:
946: Kfree(gdi);
947: err_ret1:
948: DEBUG_PRINT(("GDefDevice err = %d\n", err));
949: return err;
950: }
951:
952: 953: 954: 955: 956: 957: 958: 959: 960: 961: 962:
963: EXPORT ER GRedefDevice( const GDefDev *ddev, GDI gdi )
964: {
965: DRQ *drq;
966: ER err;
967:
968: LockGDI(gdi);
969: gdi->def = *ddev;
970: UnlockGDI(gdi);
971:
972:
973: err = gdi_defdevice(gdi, NULL);
974: if ( err < E_OK ) goto err_ret;
975:
976:
977: LockGDI(gdi);
978: while ( (drq = (DRQ*)QueRemoveNext(&gdi->acpq)) != NULL ) {
979: QueInit(&drq->q);
980: drq->req->error = E_ABORT;
981: drq->done = Done;
982: if ( drq->wtid > 0 ) {
983: tk_dis_wai(drq->wtid, TTWTEV(GDI_TEV));
984: }
985: }
986: gdi->acpd[0] = gdi->acpd[1] = 0;
987: gdi->acpa[0] = gdi->acpa[1] = 0;
988: UnlockGDI(gdi);
989:
990: return E_OK;
991:
992: err_ret:
993: DEBUG_PRINT(("GRedefDevice err = %d\n", err));
994: return err;
995: }
996:
997: 998: 999: 1000:
1001: EXPORT ER GDelDevice( GDI gdi )
1002: {
1003: ER err, error = E_OK;
1004:
1005:
1006: err = tk_def_dev(gdi->def.devnm, NULL, NULL);
1007: if ( err < E_OK ) {
1008: error = err;
1009: if ( err == E_BUSY ) goto err_ret;
1010: }
1011:
1012:
1013: DeleteMLock(&gdi->lock);
1014:
1015:
1016: err = tk_del_flg(gdi->flgid);
1017: if ( err < E_OK ) error = err;
1018:
1019:
1020: Kfree(gdi->drq);
1021:
1022:
1023: Kfree(gdi);
1024:
1025: err_ret:
1026: #ifdef DEBUG
1027: if ( error < E_OK ) DEBUG_PRINT(("GDelDevice err = %d\n", error));
1028: #endif
1029: return error;
1030: }
1031:
1032: