gonzui


Format: Advanced Search

tkernel_2/kernel/sysmgr/src/device.cbare sourcepermlink (0.05 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by T-Engine Forum at 2011/09/08.
   11:  *    Modified by T-Engine Forum at 2014/09/10.
   12:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   13:  *
   14:  *----------------------------------------------------------------------
   15:  */
   16: 
   17: /*
   18:  *      device.c (T-Kernel/SM)
   19:  *      Device Management Function
   20:  */
   21: 
   22: #include "sysmgr.h"
   23: #include <sys/rominfo.h>
   24: #include <sys/svc/ifdevmgr.h>
   25: 
   26: /* Lock for device management exclusive control */
   27: EXPORT  FastMLock        DevMgrLock;
   28: /* Semaphore for device management synchronous control */
   29: EXPORT  ID               DevMgrSync;
   30: /* Device initial setting information */
   31: LOCAL   T_IDEV            DefaultIDev;
   32: 
   33: /* Set Object Name in .exinf for DEBUG */
   34: #define OBJNAME_DMMBF   "DEvt"            /* Event notification mbf */
   35: #define OBJNAME_DMSEM   "DMSy"            /* semaphore of synchronous control */
   36: #define OBJNAME_DMLOCK  "DMLk"           /* Multi-lock for Dev.Mgr. */
   37: 
   38: /*
   39:  * Initialization of device initial setting information
   40:  */
   41: LOCAL ER initIDev( void )
   42: {
   43:         T_CMBF cmbf;
   44:         INT    val[2];
   45:         ER     ercd;
   46: 
   47:         /* Get system information */
   48:         ercd = _tk_get_cfn(SCTAG_TDEVTMBFSZ, val, 2);
   49: 
   50:         if ( ercd >= 2 && val[0] >= 0 ) {
   51:                 /* Generate message buffer for event notification */
   52:                 SetOBJNAME(cmbf.exinf, OBJNAME_DMMBF);
   53:                 cmbf.mbfatr = TA_TFIFO;
   54:                 cmbf.bufsz  = val[0];
   55:                 cmbf.maxmsz = val[1];
   56:                 ercd = tk_cre_mbf(&cmbf);
   57:                 if ( ercd < E_OK ) {
   58:                         DefaultIDev.evtmbfid = 0;
   59:                         goto err_ret;
   60:                 }
   61:                 DefaultIDev.evtmbfid = ercd;
   62:         } else {
   63:                 /* Do not use message buffer for event notification */
   64:                 DefaultIDev.evtmbfid = 0;
   65:         }
   66: 
   67:         return E_OK;
   68: 
   69: err_ret:
   70:         DEBUG_PRINT(("initIDev ercd = %d\n", ercd));
   71:         return ercd;
   72: }
   73: 
   74: /*
   75:  * Unregister device initial setting information
   76:  */
   77: LOCAL ER delIDev( void )
   78: {
   79:         ER     ercd = E_OK;
   80: 
   81:         /* Delete message buffer for event notification */
   82:         if ( DefaultIDev.evtmbfid > 0 ) {
   83:                 ercd = tk_del_mbf(DefaultIDev.evtmbfid);
   84:                 DefaultIDev.evtmbfid = 0;
   85:         }
   86: 
   87:         ERCD_PRINT(("delIDev ercd = %d\n", ercd));
   88:         return ercd;
   89: }
   90: 
   91: /* ------------------------------------------------------------------------ */
   92: /*
   93:  *      Device registration management
   94:  */
   95: 
   96: EXPORT  DevCB    *DevCBtbl; /* Device registration information table */
   97: EXPORT  QUEUE    UsedDevCB; /* In-use queue */
   98: LOCAL   QUEUE     FreeDevCB;  /* Unused queue */
   99: LOCAL   INT       MaxRegDev;    /* Maximum number of device registrations */
  100: 
  101: #define MAX_UNIT        255    /* Maximum number of subunits */
  102: 
  103: /*
  104:  * Verify validity of device ID
  105:  */
  106: Inline ER check_devid( ID devid )
  107: {
  108:         devid >>= 8;
  109:         if ( devid < 1 || devid > MaxRegDev ) {
  110:                 return E_ID;
  111:         }
  112:         return E_OK;
  113: }
  114: 
  115: /*
  116:  * Initialization of device registration information table
  117:  */
  118: LOCAL ER initDevCB( void )
  119: {
  120:         DevCB  *devcb;
  121:         INT    num;
  122:         ER     ercd;
  123: 
  124:         /* Get system information */
  125:         ercd = _tk_get_cfn(SCTAG_TMAXREGDEV, &MaxRegDev, 1);
  126:         if ( ercd < 1 ) {
  127:                 ercd = E_SYS;
  128:                 goto err_ret;
  129:         }
  130:         num = MaxRegDev;
  131: 
  132:         /* Generate device registration information table */
  133:         DevCBtbl = Imalloc((UINT)num * sizeof(DevCB));
  134:         if ( DevCBtbl == NULL ) {
  135:                 ercd = E_NOMEM;
  136:                 goto err_ret;
  137:         }
  138: 
  139:         QueInit(&UsedDevCB);
  140:         QueInit(&FreeDevCB);
  141: 
  142:         devcb = DevCBtbl;
  143:         while ( num-- > 0 ) {
  144:                 QueInsert(&devcb->q, &FreeDevCB);
  145:                 devcb->devnm[0] = '\0';
  146:                 devcb++;
  147:         }
  148: 
  149:         return E_OK;
  150: 
  151: err_ret:
  152:         DEBUG_PRINT(("initDevCB ercd = %d\n", ercd));
  153:         return ercd;
  154: }
  155: 
  156: /*
  157:  * Search registration device
  158:  */
  159: EXPORT DevCB* searchDevCB( CONST UB *devnm )
  160: {
  161:         QUEUE  *q;
  162:         DevCB  *devcb;
  163: 
  164:         for ( q = UsedDevCB.next; q != &UsedDevCB; q = q->next ) {
  165:                 devcb = (DevCB*)q;
  166:                 if ( devcb->devnm[0] == devnm[0] &&
  167:                         STRCMP((char*)devcb->devnm, (char*)devnm) == 0 ) {
  168:                         return devcb; /* Found */
  169:                 }
  170:         }
  171: 
  172:         return NULL;
  173: }
  174: 
  175: /*
  176:  * Get DevCB for new registration
  177:  */
  178: LOCAL DevCB* newDevCB( CONST UB *devnm )
  179: {
  180:         DevCB  *devcb;
  181: 
  182:         devcb = (DevCB*)QueRemoveNext(&FreeDevCB);
  183:         if ( devcb == NULL ) {
  184:                 return NULL;  /* No space */
  185:         }
  186: 
  187:         STRNCPY((char*)devcb->devnm, (char*)devnm, L_DEVNM + 1);
  188:         QueInit(&devcb->openq);
  189:         QueInit(&devcb->syncq);
  190: 
  191:         QueInsert(&devcb->q, &UsedDevCB);
  192: 
  193:         return devcb;
  194: }
  195: 
  196: /*
  197:  * Free DevCB
  198:  */
  199: LOCAL void delDevCB( DevCB *devcb )
  200: {
  201:         QueRemove(&devcb->q);
  202:         QueInsert(&devcb->q, &FreeDevCB);
  203:         devcb->devnm[0] = '\0';
  204: }
  205: 
  206: /*
  207:  * Device registration
  208:  */
  209: LOCAL ID _tk_def_dev( CONST UB *devnm, CONST T_DDEV *ddev,
  210:                                         T_IDEV *idev, void *caller_gp )
  211: {
  212:         DevCB  *devcb;
  213:         INT    len, evttyp;
  214:         ER     ercd;
  215: 
  216:         LockREG();
  217: 
  218:         len = ChkSpaceBstrR(devnm, 0);
  219:         if ( len < E_OK ) {
  220:                 ercd = len;
  221:                 goto err_ret1;
  222:         }
  223:         if ( len <= 0 || len > L_DEVNM ) {
  224:                 ercd = E_PAR;
  225:                 goto err_ret1;
  226:         }
  227: 
  228:         if ( ddev != NULL ) {
  229:                 ercd = ChkSpaceR(ddev, sizeof(T_DDEV));
  230:                 if ( ercd < E_OK ) {
  231:                         goto err_ret1;
  232:                 }
  233:                 if ( ddev->nsub < 0 || ddev->nsub > MAX_UNIT ) {
  234:                         ercd = E_PAR;
  235:                         goto err_ret1;
  236:                 }
  237: 
  238:                 /* Make sure that the length of the logical device name
  239:                    does not exceed the character limit */
  240:                 if ( ddev->nsub > 0   ) {
  241:                         ++len;
  242:                 }
  243:                 if ( ddev->nsub > 10  ) {
  244:                         ++len;
  245:                 }
  246:                 if ( ddev->nsub > 100 ) {
  247:                         ++len;
  248:                 }
  249:                 if ( len > L_DEVNM ) {
  250:                         ercd = E_PAR;
  251:                         goto err_ret1;
  252:                 }
  253:         }
  254: 
  255:         if ( idev != NULL ) {
  256:                 ercd = ChkSpaceRW(idev, sizeof(T_IDEV));
  257:                 if ( ercd < E_OK ) {
  258:                         goto err_ret1;
  259:                 }
  260:         }
  261: 
  262:         LockDM();
  263: 
  264:         /* Search whether 'devnm' device is registered */
  265:         devcb = searchDevCB(devnm);
  266:         if ( devcb == NULL ) {
  267:                 if ( ddev == NULL ) {
  268:                         ercd = E_NOEXS;
  269:                         goto err_ret2;
  270:                 }
  271: 
  272:                 /* Get 'devcb' for new registration because it is not
  273:                    registered */
  274:                 devcb = newDevCB(devnm);
  275:                 if ( devcb == NULL ) {
  276:                         ercd = E_LIMIT;
  277:                         goto err_ret2;
  278:                 }
  279:         }
  280: 
  281:         if ( ddev != NULL ) {
  282:                 /* Set/update device registration information */
  283:                 devcb->ddev = *ddev;
  284: #if TA_GP
  285:                 if ( (ddev->drvatr & TA_GP) == 0 ) {
  286:                         /* Apply caller 'gp' if TA_GP is not specified */
  287:                         devcb->ddev.gp = caller_gp;
  288:                 }
  289: #endif
  290: 
  291:                 if ( idev != NULL ) {
  292:                         /* Device initial setting information */
  293:                         *idev = DefaultIDev;
  294:                 }
  295:                 evttyp = TSEVT_DEVICE_REGIST;
  296:         } else {
  297:                 if ( !isQueEmpty(&devcb->openq) ) {
  298:                         /* In use (open) */
  299:                         ercd = E_BUSY;
  300:                         goto err_ret2;
  301:                 }
  302: 
  303:                 /* Device unregistration */
  304:                 delDevCB(devcb);
  305:                 evttyp = TSEVT_DEVICE_DELETE;
  306:         }
  307: 
  308:         UnlockDM();
  309:         UnlockREG();
  310: 
  311:         /* Device registration/unregistration notification */
  312:         tk_evt_ssy(0, evttyp, 0, DID(devcb));
  313: 
  314:         return DID(devcb);
  315: 
  316: err_ret2:
  317:         UnlockDM();
  318: err_ret1:
  319:         UnlockREG();
  320:         DEBUG_PRINT(("_tk_def_dev ercd = %d\n", ercd));
  321:         return ercd;
  322: }
  323: 
  324: /*
  325:  * Check device initial information
  326:  */
  327: LOCAL ER _tk_ref_idv( T_IDEV *idev )
  328: {
  329:         ER     ercd;
  330: 
  331:         ercd = ChkSpaceRW(idev, sizeof(T_IDEV));
  332:         if ( ercd < E_OK ) {
  333:                 goto err_ret;
  334:         }
  335: 
  336:         LockDM();
  337:         *idev = DefaultIDev;
  338:         UnlockDM();
  339: 
  340:         return E_OK;
  341: 
  342: err_ret:
  343:         DEBUG_PRINT(("_tk_ref_idv ercd = %d\n", ercd));
  344:         return ercd;
  345: }
  346: 
  347: /* ------------------------------------------------------------------------ */
  348: 
  349: /*
  350:  * Get logical device name
  351:  *      Get the logical device name from
  352:  *      the physical device name (pdevnm) and the subunit number (unitno).
  353:  */
  354: LOCAL void logdevnm( UB *ldevnm, UB *pdevnm, INT unitno )
  355: {
  356:         UB     unostr[12], *cp;
  357: 
  358:         STRCPY((char*)ldevnm, (char*)pdevnm);
  359:         if ( unitno > 0 ) {
  360:                 cp = &unostr[11];
  361:                 *cp = '\0';
  362:                 while (*ldevnm != '\0') {
  363:                         ++ldevnm;
  364:                 }
  365:                 --unitno;
  366:                 do {
  367:                         *(--cp) = (UB)('0' + (unitno % 10));
  368:                         unitno /= 10;
  369:                 } while (unitno);
  370:                 STRCAT((char*)ldevnm, (char*)cp);
  371:         }
  372: }
  373: 
  374: /*
  375:  * Get physical device name
  376:  *      Get the subunit number (return value)
  377:  *      from the logical device name (ldevnm) and the physical
  378:  *      device name (pdevnm).
  379:  */
  380: EXPORT INT phydevnm( UB *pdevnm, CONST UB *ldevnm )
  381: {
  382:         UB     c;
  383:         INT    unitno;
  384: 
  385:         while ( (c = *ldevnm) != '\0' ) {
  386:                 if ( c >= '0' && c <= '9' ) {
  387:                         break;
  388:                 }
  389:                 *pdevnm++ = c;
  390:                 ldevnm++;
  391:         }
  392:         *pdevnm = '\0';
  393: 
  394:         unitno = 0;
  395:         if (c != '\0') {
  396:                 while ( (c = *ldevnm) != '\0' ) {
  397:                         unitno = unitno * 10 + (c - '0');
  398:                         ldevnm++;
  399:                 }
  400:                 ++unitno;
  401:         }
  402: 
  403:         return unitno;
  404: }
  405: 
  406: /*
  407:  * Get device name
  408:  */
  409: LOCAL ID _tk_get_dev( ID devid, UB *devnm )
  410: {
  411:         DevCB  *devcb;
  412:         ER     ercd;
  413: 
  414:         ercd = ChkSpaceRW(devnm, (L_DEVNM + 1) * sizeof(UB));
  415:         if ( ercd < E_OK ) {
  416:                 goto err_ret1;
  417:         }
  418:         ercd = check_devid(devid);
  419:         if ( ercd < E_OK ) {
  420:                 goto err_ret1;
  421:         }
  422: 
  423:         LockDM();
  424: 
  425:         devcb = DEVCB(devid);
  426:         if ( (devcb->devnm[0] == '\0')||(UNITNO(devid) > devcb->ddev.nsub) ) {
  427:                 ercd = E_NOEXS;
  428:                 goto err_ret2;
  429:         }
  430: 
  431:         logdevnm(devnm, devcb->devnm, UNITNO(devid));
  432: 
  433:         UnlockDM();
  434: 
  435:         return DID(devcb);
  436: 
  437: err_ret2:
  438:         UnlockDM();
  439: err_ret1:
  440:         DEBUG_PRINT(("_tk_get_dev ercd = %d\n", ercd));
  441:         return ercd;
  442: }
  443: 
  444: /*
  445:  * Get device information
  446:  */
  447: LOCAL ID _tk_ref_dev( CONST UB *devnm, T_RDEV *rdev )
  448: {
  449:         UB     pdevnm[L_DEVNM + 1];
  450:         DevCB  *devcb;
  451:         INT    unitno;
  452:         ER     ercd;
  453: 
  454:         ercd = ChkSpaceBstrR(devnm, 0);
  455:         if ( ercd < E_OK ) {
  456:                 goto err_ret1;
  457:         }
  458:         if ( rdev != NULL ) {
  459:                 ercd = ChkSpaceRW(rdev, sizeof(T_RDEV));
  460:                 if ( ercd < E_OK ) {
  461:                         goto err_ret1;
  462:                 }
  463:         }
  464: 
  465:         unitno = phydevnm(pdevnm, devnm);
  466: 
  467:         LockDM();
  468: 
  469:         devcb = searchDevCB(pdevnm);
  470:         if ( devcb == NULL || unitno > devcb->ddev.nsub ) {
  471:                 ercd = E_NOEXS;
  472:                 goto err_ret2;
  473:         }
  474: 
  475:         if ( rdev != NULL ) {
  476:                 rdev->devatr = devcb->ddev.devatr;
  477:                 rdev->blksz  = devcb->ddev.blksz;
  478:                 rdev->nsub   = devcb->ddev.nsub;
  479:                 rdev->subno  = unitno;
  480:         }
  481: 
  482:         UnlockDM();
  483: 
  484:         return DEVID(devcb, unitno);
  485: 
  486: err_ret2:
  487:         UnlockDM();
  488: err_ret1:
  489:         DEBUG_PRINT(("_tk_ref_dev ercd = %d\n", ercd));
  490:         return ercd;
  491: }
  492: 
  493: /*
  494:  * Get device information
  495:  */
  496: LOCAL ID _tk_oref_dev( ID dd, T_RDEV *rdev )
  497: {
  498:         OpnCB  *opncb;
  499:         DevCB  *devcb;
  500:         INT    unitno;
  501:         ER     ercd;
  502: 
  503:         if ( rdev != NULL ) {
  504:                 ercd = ChkSpaceRW(rdev, sizeof(T_RDEV));
  505:                 if ( ercd < E_OK ) {
  506:                         goto err_ret1;
  507:                 }
  508:         }
  509: 
  510:         LockDM();
  511: 
  512:         ercd = check_devdesc(dd, 0, &opncb);
  513:         if ( ercd < E_OK ) {
  514:                 goto err_ret2;
  515:         }
  516: 
  517:         devcb  = opncb->devcb;
  518:         unitno = opncb->unitno;
  519: 
  520:         if ( rdev != NULL ) {
  521:                 rdev->devatr = devcb->ddev.devatr;
  522:                 rdev->blksz  = devcb->ddev.blksz;
  523:                 rdev->nsub   = devcb->ddev.nsub;
  524:                 rdev->subno  = unitno;
  525:         }
  526: 
  527:         UnlockDM();
  528: 
  529:         return DEVID(devcb, unitno);
  530: 
  531: err_ret2:
  532:         UnlockDM();
  533: err_ret1:
  534:         DEBUG_PRINT(("_tk_oref_dev ercd = %d\n", ercd));
  535:         return ercd;
  536: }
  537: 
  538: /*
  539:  * Get registration device list
  540:  */
  541: LOCAL INT _tk_lst_dev( T_LDEV *ldev, INT start, INT ndev )
  542: {
  543:         DevCB  *devcb;
  544:         QUEUE  *q;
  545:         INT    n, end;
  546:         ER     ercd;
  547: 
  548:         if ( start < 0 || ndev < 0 ) {
  549:                 ercd = E_PAR;
  550:                 goto err_ret;
  551:         }
  552:         ercd = ChkSpaceRW(ldev, ndev * (INT)sizeof(T_LDEV));
  553:         if ( ercd < E_OK ) {
  554:                 goto err_ret;
  555:         }
  556: 
  557:         LockDM();
  558: 
  559:         end = start + ndev;
  560:         n = 0;
  561:         for ( q = UsedDevCB.next; q != &UsedDevCB; q = q->next ) {
  562:                 if ( n >= start && n < end ) {
  563:                         devcb = (DevCB*)q;
  564:                         ldev->devatr = devcb->ddev.devatr;
  565:                         ldev->blksz  = devcb->ddev.blksz;
  566:                         ldev->nsub   = devcb->ddev.nsub;
  567:                         STRNCPY((char*)ldev->devnm,
  568:                                         (char*)devcb->devnm, L_DEVNM);
  569:                         ldev++;
  570:                 }
  571:                 n++;
  572:         }
  573: 
  574:         UnlockDM();
  575: 
  576:         if ( start >= n ) {
  577:                 ercd = E_NOEXS;
  578:                 goto err_ret;
  579:         }
  580: 
  581:         return n - start;
  582: 
  583: err_ret:
  584:         DEBUG_PRINT(("_tk_lst_dev ercd = %d\n", ercd));
  585:         return ercd;
  586: }
  587: 
  588: /* ------------------------------------------------------------------------ */
  589: 
  590: /*
  591:  * Send driver request event
  592:  */
  593: LOCAL INT _tk_evt_dev( ID devid, INT evttyp, void *evtinf )
  594: {
  595:         DevCB  *devcb;
  596:         ER     ercd;
  597: 
  598:         ercd = check_devid(devid);
  599:         if ( ercd < E_OK ) {
  600:                 goto err_ret1;
  601:         }
  602:         if ( evttyp < 0 ) {
  603:                 ercd = E_PAR;
  604:                 goto err_ret1;
  605:         }
  606: 
  607:         LockDM();
  608: 
  609:         devcb = DEVCB(devid);
  610:         if ( (devcb->devnm[0] == '\0')||(UNITNO(devid) > devcb->ddev.nsub) ) {
  611:                 ercd = E_NOEXS;
  612:                 goto err_ret2;
  613:         }
  614: 
  615:         UnlockDM();
  616: 
  617:         /* Device driver call */
  618:         ercd = call_eventfn(devcb, evttyp, evtinf);
  619: 
  620:         return ercd;
  621: 
  622: err_ret2:
  623:         UnlockDM();
  624: err_ret1:
  625:         DEBUG_PRINT(("_tk_evt_dev ercd = %d\n", ercd));
  626:         return ercd;
  627: }
  628: 
  629: /* ------------------------------------------------------------------------ */
  630: 
  631: /*
  632:  * Extension SVC entry
  633:  */
  634: LOCAL INT devmgr_svcentry( void *pk_para, FN fncd, void *caller_gp )
  635: {
  636:         ER     ercd;
  637: 
  638:         /* Test call protection level */
  639:         ercd = ChkCallPLevel();
  640:         if ( ercd < E_OK ) {
  641:                 goto err_ret;
  642:         }
  643: 
  644:         switch ( fncd ) {
  645:           case DEVICE_TK_OPN_DEV_FN:
  646:                 { DEVICE_TK_OPN_DEV_PARA *p = pk_para;
  647:                 return _tk_opn_dev(p->devnm, p->omode); }
  648:           case DEVICE_TK_CLS_DEV_FN:
  649:                 { DEVICE_TK_CLS_DEV_PARA *p = pk_para;
  650:                 return _tk_cls_dev(p->dd, p->option); }
  651:           case DEVICE_TK_REA_DEV_FN:
  652:                 { DEVICE_TK_REA_DEV_PARA *p = pk_para;
  653:                 return _tk_rea_dev(p->dd, p->start, p->buf, p->size,
  654:                                                         p->tmout); }
  655:           case DEVICE_TK_SREA_DEV_FN:
  656:                 { DEVICE_TK_SREA_DEV_PARA *p = pk_para;
  657:                 return _tk_srea_dev(p->dd, p->start, p->buf, p->size,
  658:                                                         p->asize); }
  659:           case DEVICE_TK_WRI_DEV_FN:
  660:                 { DEVICE_TK_WRI_DEV_PARA *p = pk_para;
  661:                 return _tk_wri_dev(p->dd, p->start, p->buf, p->size,
  662:                                                         p->tmout); }
  663:           case DEVICE_TK_SWRI_DEV_FN:
  664:                 { DEVICE_TK_SWRI_DEV_PARA *p = pk_para;
  665:                 return _tk_swri_dev(p->dd, p->start, p->buf, p->size,
  666:                                                         p->asize); }
  667:           case DEVICE_TK_WAI_DEV_FN:
  668:                 { DEVICE_TK_WAI_DEV_PARA *p = pk_para;
  669:                 return _tk_wai_dev(p->dd, p->reqid, p->asize, p->ioer,
  670:                                                         p->tmout); }
  671:           case DEVICE_TK_SUS_DEV_FN:
  672:                 { DEVICE_TK_SUS_DEV_PARA *p = pk_para;
  673:                 return _tk_sus_dev(p->mode); }
  674:           case DEVICE_TK_GET_DEV_FN:
  675:                 { DEVICE_TK_GET_DEV_PARA *p = pk_para;
  676:                 return _tk_get_dev(p->devid, p->devnm); }
  677:           case DEVICE_TK_REF_DEV_FN:
  678:                 { DEVICE_TK_REF_DEV_PARA *p = pk_para;
  679:                 return _tk_ref_dev(p->devnm, p->rdev); }
  680:           case DEVICE_TK_OREF_DEV_FN:
  681:                 { DEVICE_TK_OREF_DEV_PARA *p = pk_para;
  682:                 return _tk_oref_dev(p->dd, p->rdev); }
  683:           case DEVICE_TK_LST_DEV_FN:
  684:                 { DEVICE_TK_LST_DEV_PARA *p = pk_para;
  685:                 return _tk_lst_dev(p->ldev, p->start, p->ndev); }
  686:           case DEVICE_TK_EVT_DEV_FN:
  687:                 { DEVICE_TK_EVT_DEV_PARA *p = pk_para;
  688:                 return _tk_evt_dev(p->devid, p->evttyp, p->evtinf); }
  689:           case DEVICE_TK_DEF_DEV_FN:
  690:                 { DEVICE_TK_DEF_DEV_PARA *p = pk_para;
  691:                 return _tk_def_dev(p->devnm, p->ddev, p->idev, caller_gp); }
  692:           case DEVICE_TK_REF_IDV_FN:
  693:                 { DEVICE_TK_REF_IDV_PARA *p = pk_para;
  694:                 return _tk_ref_idv(p->idev); }
  695: 
  696:           /* T-Kernel 2.0 */
  697:           case DEVICE_TK_REA_DEV_DU_FN:
  698:                 { DEVICE_TK_REA_DEV_DU_PARA *p = pk_para;
  699:                 return _tk_rea_dev_du(p->dd, p->start_d, p->buf, p->size,
  700:                                       p->tmout_u); }
  701:           case DEVICE_TK_SREA_DEV_D_FN:
  702:                 { DEVICE_TK_SREA_DEV_D_PARA *p = pk_para;
  703:                 return _tk_srea_dev_d(p->dd, p->start_d, p->buf, p->size,
  704:                                       p->asize); }
  705:           case DEVICE_TK_WRI_DEV_DU_FN:
  706:                 { DEVICE_TK_WRI_DEV_DU_PARA *p = pk_para;
  707:                 return _tk_wri_dev_du(p->dd, p->start_d, p->buf, p->size,
  708:                                       p->tmout_u); }
  709:           case DEVICE_TK_SWRI_DEV_D_FN:
  710:                 { DEVICE_TK_SWRI_DEV_D_PARA *p = pk_para;
  711:                 return _tk_swri_dev_d(p->dd, p->start_d, p->buf, p->size,
  712:                                       p->asize); }
  713:           case DEVICE_TK_WAI_DEV_U_FN:
  714:                 { DEVICE_TK_WAI_DEV_U_PARA *p = pk_para;
  715:                 return _tk_wai_dev_u(p->dd, p->reqid, p->asize, p->ioer,
  716:                                      p->tmout_u); }
  717: 
  718:           default:
  719:                 ercd = E_RSFN;
  720:         }
  721: err_ret:
  722:         DEBUG_PRINT(("devmgr_svcentry ercd = %d\n", ercd));
  723:         return ercd;
  724: }
  725: 
  726: /*
  727:  * Initialization of system management
  728:  */
  729: EXPORT ER initialize_devmgr( void )
  730: {
  731:         T_DSSY dssy;
  732:         T_CSEM csem;
  733:         ER     ercd;
  734: 
  735:         /* Generate lock for device management exclusive control */
  736:         ercd = CreateMLock(&DevMgrLock, (UB*)OBJNAME_DMLOCK);
  737:         if ( ercd < E_OK ) {
  738:                 goto err_ret;
  739:         }
  740: 
  741:         /* Generate semaphore for device management synchronous control */
  742:         SetOBJNAME(csem.exinf, OBJNAME_DMSEM);
  743:         csem.sematr  = TA_TFIFO | TA_FIRST;
  744:         csem.isemcnt = 0;
  745:         csem.maxsem  = 1;
  746:         ercd = tk_cre_sem(&csem);
  747:         if ( ercd < E_OK ) {
  748:                 goto err_ret;
  749:         }
  750:         DevMgrSync = ercd;
  751: 
  752:         /* Generate device registration information table */
  753:         ercd = initDevCB();
  754:         if ( ercd < E_OK ) {
  755:                 goto err_ret;
  756:         }
  757: 
  758:         /* Initialization of device input/output-related */
  759:         ercd = initDevIO();
  760:         if ( ercd < E_OK ) {
  761:                 goto err_ret;
  762:         }
  763: 
  764:         /* Initialization of device initial setting information */
  765:         ercd = initIDev();
  766:         if ( ercd < E_OK ) {
  767:                 goto err_ret;
  768:         }
  769: 
  770:         /* Subsystem registration */
  771:         dssy.ssyatr    = TA_NULL;
  772:         dssy.ssypri    = DEVICE_PRI;
  773:         dssy.svchdr    = (FP)&devmgr_svcentry;
  774:         dssy.breakfn   = (FP)&devmgr_break;
  775:         dssy.startupfn = (FP)&devmgr_startup;
  776:         dssy.cleanupfn = (FP)&devmgr_cleanup;
  777:         dssy.eventfn   = NULL;
  778:         dssy.resblksz  = sizeof(ResCB);
  779:         ercd = tk_def_ssy(DEVICE_SVC, &dssy);
  780:         if ( ercd < E_OK ) {
  781:                 goto err_ret;
  782:         }
  783: 
  784:         return E_OK;
  785: 
  786: err_ret:
  787:         DEBUG_PRINT(("initialize_devmgr ercd = %d\n", ercd));
  788:         finish_devmgr();
  789:         return ercd;
  790: }
  791: 
  792: /*
  793:  * Finalization sequence of system management
  794:  */
  795: EXPORT ER finish_devmgr( void )
  796: {
  797:         ER     ercd;
  798: 
  799:         /* Unregister subsystem */
  800:         ercd = tk_def_ssy(DEVICE_SVC, NULL);
  801:         ERCD_PRINT(("1. finish_devmgr -> tk_def_ssy ercd = %d\n", ercd));
  802: 
  803:         /* Unregister device initial setting information */
  804:         ercd = delIDev();
  805:         ERCD_PRINT(("2. finish_devmgr -> delIDev ercd = %d\n", ercd));
  806: 
  807:         /* Finalization sequence of device input/output-related */
  808:         ercd = finishDevIO();
  809:         ERCD_PRINT(("3. finish_devmgr -> finishDevIO ercd = %d\n", ercd));
  810: 
  811:         /* Delete device registration information table */
  812:         if ( DevCBtbl != NULL ) {
  813:                 Ifree(DevCBtbl);
  814:                 DevCBtbl = NULL;
  815:         }
  816: 
  817:         /* Delete semaphore for device management synchronous control */
  818:         if ( DevMgrSync > 0 ) {
  819:                 tk_del_sem(DevMgrSync);
  820:                 DevMgrSync = 0;
  821:         }
  822: 
  823:         /* Delete lock for device management exclusive control */
  824:         DeleteMLock(&DevMgrLock);
  825: 
  826:         return ercd;
  827: }