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:
26: Noinit(EXPORT FastMLock knl_DevMgrLock);
27:
28:
29: Noinit(EXPORT T_IDEV knl_DefaultIDev);
30:
31:
32: 33: 34:
35:
36: Noinit(EXPORT DevCB knl_DevCBtbl[MAX_REGDEV]);
37: Noinit(EXPORT QUEUE knl_UsedDevCB);
38: Noinit(EXPORT QUEUE knl_FreeDevCB);
39:
40:
41: 42: 43:
44: EXPORT DevCB* knl_searchDevCB( CONST UB *devnm )
45: {
46: QUEUE *q;
47: DevCB *devcb;
48:
49: for ( q = knl_UsedDevCB.next; q != &knl_UsedDevCB; q = q->next ) {
50: devcb = (DevCB*)q;
51:
52: if ( devcb->devnm[0] == devnm[0] && knl_strcmp((char*)devcb->devnm, (char*)devnm) == 0 ) {
53: return devcb;
54: }
55: }
56:
57: return NULL;
58: }
59:
60: 61: 62:
63: LOCAL DevCB* newDevCB( CONST UB *devnm )
64: {
65: DevCB *devcb;
66:
67: devcb = (DevCB*)QueRemoveNext(&knl_FreeDevCB);
68: if ( devcb == NULL ) {
69: return NULL;
70: }
71:
72: knl_strncpy((char*)devcb->devnm, (char*)devnm, L_DEVNM+1);
73: QueInit(&devcb->openq);
74:
75: QueInsert(&devcb->q, &knl_UsedDevCB);
76:
77: return devcb;
78: }
79:
80: 81: 82:
83: LOCAL void delDevCB( DevCB *devcb )
84: {
85: QueRemove(&devcb->q);
86: QueInsert(&devcb->q, &knl_FreeDevCB);
87: devcb->devnm[0] = '\0';
88: }
89:
90: 91: 92:
93: SYSCALL ID tk_def_dev( CONST UB *devnm, CONST T_DDEV *pk_ddev, T_IDEV *pk_idev )
94: {
95: DevCB *devcb;
96: INT len;
97: ER ercd;
98:
99: LockREG();
100:
101: len = knl_strlen((char*)devnm);
102: if ( len == 0 || len > L_DEVNM ) {
103: ercd = E_PAR;
104: goto err_ret1;
105: }
106:
107: if ( pk_ddev != NULL ) {
108: if ( pk_ddev->nsub < 0 || pk_ddev->nsub > MAX_UNIT ) {
109: ercd = E_PAR;
110: goto err_ret1;
111: }
112:
113: 114:
115: if ( pk_ddev->nsub > 0 ) {
116: ++len;
117: }
118: if ( pk_ddev->nsub > 10 ) {
119: ++len;
120: }
121: if ( pk_ddev->nsub > 100 ) {
122: ++len;
123: }
124: if ( len > L_DEVNM ) {
125: ercd = E_PAR;
126: goto err_ret1;
127: }
128: }
129:
130: LockDM();
131:
132:
133: devcb = knl_searchDevCB(devnm);
134: if ( devcb == NULL ) {
135: if ( pk_ddev == NULL ) {
136: ercd = E_NOEXS;
137: goto err_ret2;
138: }
139:
140: 141:
142: devcb = newDevCB(devnm);
143: if ( devcb == NULL ) {
144: ercd = E_LIMIT;
145: goto err_ret2;
146: }
147: }
148:
149: if ( pk_ddev != NULL ) {
150:
151: devcb->ddev = *pk_ddev;
152:
153: if ( pk_idev != NULL ) {
154:
155: *pk_idev = knl_DefaultIDev;
156: }
157: } else {
158: if ( !isQueEmpty(&devcb->openq) ) {
159:
160: ercd = E_BUSY;
161: goto err_ret2;
162: }
163:
164:
165: delDevCB(devcb);
166: }
167:
168: UnlockDM();
169: UnlockREG();
170:
171: return DID(devcb);
172:
173: err_ret2:
174: UnlockDM();
175: err_ret1:
176: UnlockREG();
177: return ercd;
178: }
179:
180: 181: 182:
183: SYSCALL ER tk_ref_idv( T_IDEV *pk_idev )
184: {
185: LockDM();
186: *pk_idev = knl_DefaultIDev;
187: UnlockDM();
188:
189: return E_OK;
190: }
191:
192:
193:
194: 195: 196: 197: 198: 199:
200: EXPORT INT knl_phydevnm( UB *pdevnm, CONST UB *ldevnm )
201: {
202: UB c;
203: INT unitno;
204:
205: while ( (c = *ldevnm) != '\0' ) {
206: if ( c >= '0' && c <= '9' ) {
207: break;
208: }
209: *pdevnm++ = c;
210: ldevnm++;
211: }
212: *pdevnm = '\0';
213:
214: unitno = 0;
215: if (c != '\0') {
216: while ( (c = *ldevnm) != '\0' ) {
217: unitno = unitno * 10 + (c - '0');
218: ldevnm++;
219: }
220: ++unitno;
221: }
222:
223: return unitno;
224: }
225:
226: 227: 228: 229: 230:
231: LOCAL void logdevnm( UB *ldevnm, UB *pdevnm, INT unitno )
232: {
233: UB unostr[12], *cp;
234:
235: knl_strcpy((char*)ldevnm, (char*)pdevnm);
236: if ( unitno > 0 ) {
237: cp = &unostr[11];
238: *cp = '\0';
239: while (*ldevnm != '\0') {
240: ++ldevnm;
241: }
242: --unitno;
243: do {
244: *(--cp) = (UB)('0' + (unitno % 10));
245: unitno /= 10;
246: } while (unitno);
247: knl_strcat((char*)ldevnm, (char*)cp);
248: }
249: }
250:
251: 252: 253:
254: SYSCALL ID tk_get_dev( ID devid, UB *devnm )
255: {
256: DevCB *devcb;
257: ER ercd;
258:
259: ercd = knl_check_devid(devid);
260: if ( ercd < E_OK ) {
261: goto err_ret1;
262: }
263:
264: LockDM();
265:
266: devcb = DEVCB(devid);
267: if ( (devcb->devnm[0] == '\0')||(UNITNO(devid) > devcb->ddev.nsub) ) {
268: ercd = E_NOEXS;
269: goto err_ret2;
270: }
271:
272: logdevnm(devnm, devcb->devnm, UNITNO(devid));
273:
274: UnlockDM();
275:
276: return DID(devcb);
277:
278: err_ret2:
279: UnlockDM();
280: err_ret1:
281: return ercd;
282: }
283:
284: 285: 286:
287: SYSCALL ID tk_ref_dev( CONST UB *devnm, T_RDEV *pk_rdev )
288: {
289: UB pdevnm[L_DEVNM + 1];
290: DevCB *devcb;
291: INT unitno;
292: ER ercd;
293:
294: unitno = knl_phydevnm(pdevnm, devnm);
295:
296: LockDM();
297:
298: devcb = knl_searchDevCB(pdevnm);
299: if ( devcb == NULL || unitno > devcb->ddev.nsub ) {
300: ercd = E_NOEXS;
301: goto err_ret2;
302: }
303:
304: if ( pk_rdev != NULL ) {
305: pk_rdev->devatr = devcb->ddev.devatr;
306: pk_rdev->blksz = devcb->ddev.blksz;
307: pk_rdev->nsub = devcb->ddev.nsub;
308: pk_rdev->subno = unitno;
309: }
310:
311: UnlockDM();
312:
313: return DEVID(devcb, unitno);
314:
315: err_ret2:
316: UnlockDM();
317: return ercd;
318: }
319:
320: 321: 322:
323: SYSCALL ID tk_oref_dev( ID dd, T_RDEV *pk_rdev )
324: {
325: OpnCB *opncb;
326: DevCB *devcb;
327: INT unitno;
328: ER ercd;
329:
330: LockDM();
331:
332: ercd = knl_check_devdesc(dd, 0, &opncb);
333: if ( ercd < E_OK ) {
334: goto err_ret2;
335: }
336:
337: devcb = opncb->devcb;
338: unitno = opncb->unitno;
339:
340: if ( pk_rdev != NULL ) {
341: pk_rdev->devatr = devcb->ddev.devatr;
342: pk_rdev->blksz = devcb->ddev.blksz;
343: pk_rdev->nsub = devcb->ddev.nsub;
344: pk_rdev->subno = unitno;
345: }
346:
347: UnlockDM();
348:
349: return DEVID(devcb, unitno);
350:
351: err_ret2:
352: UnlockDM();
353: return ercd;
354: }
355:
356: 357: 358:
359: SYSCALL INT tk_lst_dev( T_LDEV *pk_ldev, INT start, INT ndev )
360: {
361: DevCB *devcb;
362: QUEUE *q;
363: INT n, end;
364: ER ercd;
365:
366: if ( start < 0 || ndev < 0 ) {
367: ercd = E_PAR;
368: goto err_ret;
369: }
370: LockDM();
371:
372: end = start + ndev;
373: n = 0;
374: for ( q = knl_UsedDevCB.next; q != &knl_UsedDevCB; q = q->next ) {
375: if ( n >= start && n < end ) {
376: devcb = (DevCB*)q;
377: pk_ldev->devatr = devcb->ddev.devatr;
378: pk_ldev->blksz = devcb->ddev.blksz;
379: pk_ldev->nsub = devcb->ddev.nsub;
380: knl_strncpy((char*)pk_ldev->devnm, (char*)devcb->devnm, L_DEVNM);
381: pk_ldev++;
382: }
383: n++;
384: }
385:
386: UnlockDM();
387:
388: if ( start >= n ) {
389: ercd = E_NOEXS;
390: goto err_ret;
391: }
392:
393: return n - start;
394:
395: err_ret:
396: return ercd;
397: }
398:
399:
400:
401: 402: 403:
404: SYSCALL INT tk_evt_dev( ID devid, INT evttyp, void *evtinf )
405: {
406: DevCB *devcb;
407: EVTFN eventfn;
408: void *exinf;
409: ER ercd;
410:
411: ercd = knl_check_devid(devid);
412: if ( ercd < E_OK ) {
413: goto err_ret1;
414: }
415: if ( evttyp < 0 ) {
416: ercd = E_PAR;
417: goto err_ret1;
418: }
419:
420: LockDM();
421:
422: devcb = DEVCB(devid);
423: if ( (devcb->devnm[0] == '\0')||(UNITNO(devid) > devcb->ddev.nsub) ) {
424: ercd = E_NOEXS;
425: goto err_ret2;
426: }
427:
428: eventfn = (EVTFN)devcb->ddev.eventfn;
429: exinf = devcb->ddev.exinf;
430:
431: UnlockDM();
432:
433:
434: DISABLE_INTERRUPT;
435: knl_ctxtsk->sysmode++;
436: ENABLE_INTERRUPT;
437: ercd = (*eventfn)(evttyp, evtinf, exinf);
438: DISABLE_INTERRUPT;
439: knl_ctxtsk->sysmode--;
440: ENABLE_INTERRUPT;
441:
442: return ercd;
443:
444: err_ret2:
445: UnlockDM();
446: err_ret1:
447: return ercd;
448: }
449:
450:
451:
452: 453: 454:
455: LOCAL ER initDevCB( void )
456: {
457: DevCB *devcb;
458: INT num = MAX_REGDEV;
459:
460: QueInit(&knl_UsedDevCB);
461: QueInit(&knl_FreeDevCB);
462:
463: devcb = knl_DevCBtbl;
464: while ( num-- > 0 ) {
465: QueInsert(&devcb->q, &knl_FreeDevCB);
466: devcb->devnm[0] = '\0';
467: devcb++;
468: }
469:
470: return E_OK;
471: }
472:
473: 474: 475:
476: LOCAL ER initIDev( void )
477: {
478: ER ercd;
479:
480: #if DEVT_MBFSZ0 >= 0
481: T_CMBF cmbf;
482:
483:
484: knl_strncpy((char*)&cmbf.exinf, (char*)OBJNAME_DMMBF, sizeof(cmbf.exinf));
485: cmbf.mbfatr = TA_TFIFO;
486: cmbf.bufsz = DEVT_MBFSZ0;
487: cmbf.maxmsz = DEVT_MBFSZ1;
488: ercd = tk_cre_mbf(&cmbf);
489: if ( ercd < E_OK ) {
490: knl_DefaultIDev.evtmbfid = 0;
491: goto err_ret;
492: }
493: #else
494: ercd = E_OK;
495: #endif
496: knl_DefaultIDev.evtmbfid = ercd;
497:
498: #if DEVT_MBFSZ0 >= 0
499: err_ret:
500: #endif
501: return ercd;
502: }
503:
504: 505: 506:
507: EXPORT ER knl_initialize_devmgr( void )
508: {
509: ER ercd;
510:
511:
512: ercd = CreateMLock(&knl_DevMgrLock, (UB*)OBJNAME_DMLOCK);
513: if ( ercd < E_OK ) {
514: goto err_ret;
515: }
516:
517:
518: ercd = initDevCB();
519: if ( ercd < E_OK ) {
520: goto err_ret;
521: }
522:
523:
524: ercd = knl_initDevIO();
525: if ( ercd < E_OK ) {
526: goto err_ret;
527: }
528:
529:
530: ercd = initIDev();
531: if ( ercd < E_OK ) {
532: goto err_ret;
533: }
534:
535: knl_devmgr_startup();
536:
537: return E_OK;
538:
539: err_ret:
540: knl_finish_devmgr();
541: return ercd;
542: }
543:
544: 545: 546:
547: LOCAL ER delIDev( void )
548: {
549: ER ercd = E_OK;
550:
551: #if DEVT_MBFSZ0 >= 0
552:
553: if ( knl_DefaultIDev.evtmbfid > 0 ) {
554: ercd = tk_del_mbf(knl_DefaultIDev.evtmbfid);
555: knl_DefaultIDev.evtmbfid = 0;
556: }
557:
558:
559: #endif
560:
561: return ercd;
562: }
563:
564: 565: 566:
567: EXPORT ER knl_finish_devmgr( void )
568: {
569: ER ercd;
570:
571: knl_devmgr_cleanup();
572:
573:
574: ercd = delIDev();
575:
576:
577: ercd = knl_finishDevIO();
578:
579:
580: DeleteMLock(&knl_DevMgrLock);
581:
582: return ercd;
583: }
584:
585: #endif