gonzui


Format: Advanced Search

tkernel_2/lib/libdrvif/src/sdrvif.cbare sourcepermlink (0.02 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 2013/03/11.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: 
   16: 
   17: /*
   18:  *      sdrvif.c
   19:  *
   20:  *      Simple device driver I/F layer
   21:  */
   22: 
   23: #include <basic.h>
   24: #include <device/sdrvif.h>
   25: #include <tk/tkernel.h>
   26: #include <tk/util.h>
   27: #include <sys/debug.h>
   28: 
   29: /*
   30:  * Driver I/F access handle (SDI)
   31:  */
   32: struct SimpleDriverInterface {
   33:         FastLock       lock; /* Lock for exclusive access control */
   34:         SDefDev                def;  /* Device registration information */
   35:         ID             devid;     /* Device ID*/
   36: };
   37: 
   38: #define LockSDI(sdi)    Lock(&(sdi)->lock)
   39: #define UnlockSDI(sdi)  Unlock(&(sdi)->lock)
   40: 
   41: /* ------------------------------------------------------------------------ */
   42: /*
   43:  *      Get information from "SDI"
   44:  *      These functions shall be call-ready even at the task independent part,
   45:  *      during disabling the dispatch, and during disabling the interrupt.
   46:  */
   47: 
   48: /*
   49:  * Get physical device ID
   50:  */
   51: EXPORT ID SDI_devid( SDI sdi )
   52: {
   53:         return sdi->devid;
   54: }
   55: 
   56: /*
   57:  * Get the extended information (SDefDev.exinf)
   58:  */
   59: EXPORT void* SDI_exinf( SDI sdi )
   60: {
   61:         return sdi->def.exinf;
   62: }
   63: 
   64: /*
   65:  * Get the registration information
   66:  */
   67: EXPORT const SDefDev* SDI_ddev( SDI sdi )
   68: {
   69:         return &sdi->def;
   70: }
   71: 
   72: /* ------------------------------------------------------------------------ */
   73: /*
   74:  *      Processing function
   75:  */
   76: 
   77: /*
   78:  * Open function
   79:  */
   80: LOCAL ER sdi_openfn( ID devid, UINT omode, SDI sdi )
   81: {
   82:         ER     err;
   83: 
   84:         if ( sdi->def.open == NULL ) return E_OK;
   85: 
   86:         LockSDI(sdi);
   87:         err = (*sdi->def.open)(devid, omode, sdi);
   88:         UnlockSDI(sdi);
   89: 
   90:         return err;
   91: }
   92: 
   93: /*
   94:  * Close cunction
   95:  */
   96: LOCAL ER sdi_closefn( ID devid, UINT option, SDI sdi )
   97: {
   98:         ER     err;
   99: 
  100:         if ( sdi->def.close == NULL ) return E_OK;
  101: 
  102:         LockSDI(sdi);
  103:         err = (*sdi->def.close)(devid, option, sdi);
  104:         UnlockSDI(sdi);
  105: 
  106:         return err;
  107: }
  108: 
  109: /*
  110:  * Processing start function
  111:  */
  112: LOCAL ER sdi_execfn( T_DEVREQ *req, TMO tmout, SDI sdi )
  113: {
  114:         INT    (*fp)( ID devid, INT start, INT size, void *buf, SDI );
  115:         INT    memsz;
  116:         ER     err;
  117: 
  118:         fp = ( req->cmd == TDC_READ )? sdi->def.read: sdi->def.write;
  119:         if ( fp == NULL ) { err = E_NOSPT; goto err_ret; }
  120: 
  121:         /* I/O size */
  122:         if ( req->start < 0 ) {
  123:                 /* Attribute data */
  124:                 memsz = req->size;
  125:         } else {
  126:                 /* Specific data */
  127:                 if ( sdi->def.blksz <= 0 ) { err = E_PAR; goto err_ret; }
  128:                 memsz = req->size * sdi->def.blksz;
  129:         }
  130:         if ( memsz < 0 ) { err = E_PAR; goto err_ret; }
  131: 
  132:         if ( memsz > 0 ) {
  133:                 /* Check the "buf" space */
  134:                 if ( req->cmd == TDC_READ ) {
  135:                         err = ChkSpaceRW(req->buf, memsz);
  136:                 } else {
  137:                         err = ChkSpaceR(req->buf, memsz);
  138:                 }
  139:                 if ( err < E_OK ) goto err_ret;
  140:         }
  141: 
  142:         /* I/O processing */
  143:         LockSDI(sdi);
  144:         err = (*fp)(req->devid, req->start, req->size, req->buf, sdi);
  145:         UnlockSDI(sdi);
  146:         if ( err < E_OK ) goto err_ret;
  147: 
  148:         req->asize = (INT)err;
  149:         req->error = E_OK;
  150: 
  151:         return E_OK;
  152: 
  153: err_ret:
  154:         req->error = err;
  155:         return E_OK;
  156: }
  157: 
  158: /*
  159:  * Wait-for-completion function
  160:  */
  161: LOCAL INT sdi_waitfn( T_DEVREQ *req, INT nreq, TMO tmout, SDI sdi )
  162: {
  163:         return 0;
  164: }
  165: 
  166: /*
  167:  * Abort processing function
  168:  */
  169: LOCAL ER sdi_abortfn( ID tskid, T_DEVREQ *req, INT nreq, SDI sdi )
  170: {
  171:         return E_OK;
  172: }
  173: 
  174: /*
  175:  * Event function
  176:  */
  177: LOCAL INT sdi_eventfn( INT evttyp, void *evtinf, SDI sdi )
  178: {
  179:         INT    ret;
  180: 
  181:         if ( sdi->def.event == NULL ) return E_OK;
  182: 
  183:         LockSDI(sdi);
  184:         ret = (*sdi->def.event)(evttyp, evtinf, sdi);
  185:         UnlockSDI(sdi);
  186: 
  187:         return ret;
  188: }
  189: 
  190: /* ------------------------------------------------------------------------ */
  191: /*
  192:  *      Device registration
  193:  */
  194: 
  195: /*
  196:  * Device registration processing
  197:  */
  198: LOCAL ER sdi_defdevice( SDI sdi, T_IDEV *idev )
  199: {
  200:         T_DDEV ddev;
  201:         ER     err;
  202: 
  203:         ddev.exinf   = sdi;
  204:         ddev.drvatr  = sdi->def.drvatr;
  205:         ddev.devatr  = sdi->def.devatr;
  206:         ddev.nsub    = sdi->def.nsub;
  207:         ddev.blksz   = sdi->def.blksz;
  208:         ddev.openfn  = (FP)sdi_openfn;
  209:         ddev.closefn = (FP)sdi_closefn;
  210:         ddev.execfn  = (FP)sdi_execfn;
  211:         ddev.waitfn  = (FP)sdi_waitfn;
  212:         ddev.abortfn = (FP)sdi_abortfn;
  213:         ddev.eventfn = (FP)sdi_eventfn;
  214: 
  215:         err = tk_def_dev(sdi->def.devnm, &ddev, idev);
  216:         if ( err < E_OK ) goto err_ret;
  217: 
  218:         sdi->devid = (ID)err;
  219: 
  220:         return E_OK;
  221: 
  222: err_ret:
  223:         DEBUG_PRINT(("sdi_defdevice err = %d\n", err));
  224:         return err;
  225: }
  226: 
  227: /*
  228:  * Device registration
  229:  *      Device shall be registered in accordance with "ddev" registration information.
  230:  *      Device initialization information is returned to "idev".
  231:  *      It is not returned when "idev = NULL"
  232:  *      Driver I/F access handle shall be returned to "SDI".
  233:  */
  234: EXPORT ER SDefDevice( const SDefDev *ddev, T_IDEV *idev, SDI *p_sdi )
  235: {
  236:         SDI    sdi;
  237:         ER     err;
  238: 
  239:         /* Create "SDI"*/
  240:         sdi = Kmalloc(sizeof(*sdi));
  241:         if ( sdi == NULL ) { err = E_NOMEM; goto err_ret1; }
  242: 
  243:         sdi->def = *ddev;
  244: 
  245:         /* Create the lock for exclusive access control */
  246:         err = CreateLock(&sdi->lock, sdi->def.devnm);
  247:         if ( err < E_OK ) goto err_ret2;
  248: 
  249:         /* Device registration */
  250:         err = sdi_defdevice(sdi, idev);
  251:         if ( err < E_OK ) goto err_ret3;
  252: 
  253:         *p_sdi = sdi;
  254:         return E_OK;
  255: 
  256: err_ret3:
  257:         DeleteLock(&sdi->lock);
  258: err_ret2:
  259:         Kfree(sdi);
  260: err_ret1:
  261:         DEBUG_PRINT(("SDefDevice err = %d\n", err));
  262:         return err;
  263: }
  264: 
  265: /*
  266:  * Update
  267:  *      SDI device registration shall be updated in accordance with "ddev" registration information.
  268:  *      Device name (devnm) cannot be changed (must not be changed).
  269:  *      Device ID is not changed when updated.
  270:  */
  271: EXPORT ER SRedefDevice( const SDefDev *ddev, SDI sdi )
  272: {
  273:         ER     err;
  274: 
  275:         sdi->def = *ddev;
  276: 
  277:         /* Update the device registration */
  278:         err = sdi_defdevice(sdi, NULL);
  279:         if ( err < E_OK ) goto err_ret;
  280: 
  281:         return E_OK;
  282: 
  283: err_ret:
  284:         DEBUG_PRINT(("SRedefDevice err = %d\n", err));
  285:         return err;
  286: }
  287: 
  288: /*
  289:  * Deregistration
  290:  *      Deregister "SDI" device
  291:  */
  292: EXPORT ER SDelDevice( SDI sdi )
  293: {
  294:         ER     err, error = E_OK;
  295: 
  296:         /* Deregister device */
  297:         err = tk_def_dev(sdi->def.devnm, NULL, NULL);
  298:         if ( err < E_OK ) error = err;
  299: 
  300:         /* Delete the lock for exclusive access control */
  301:         DeleteLock(&sdi->lock);
  302: 
  303:         /* Delete "SDI" */
  304:         Kfree(sdi);
  305: 
  306: #ifdef DEBUG
  307:         if ( error < E_OK ) DEBUG_PRINT(("SDelDevice err = %d\n", error));
  308: #endif
  309:         return error;
  310: }
  311: 
  312: /* ------------------------------------------------------------------------ */