/* |------------------+------------------------------------------------------------| */ StatusType WaitEvent( EventMaskType xMask ) { UINT flgptn; StatusType ercd = E_OK; ID flgid=(ID)(knl_ctxtsk->exinf); if(flgid == (ID)NULL) { ercd = E_OS_ACCESS; goto Error_Exit; } ercd = tk_wai_flg(flgid,xMask,TWF_ORW,&flgptn,TMO_FEVR); Error_Exit: return ercd; }
/* * Accept requests * Fetch one request from the request accept queue. * When there is no request in queue, the device driver shall enter into a wait status until request is made. * Specify "acpptn" by ORing the pattern of accepted request type (TDC_READ/TDC_WRITE) * or the value obtained in "DEVREQ_ACPPTN()" in the pattern of user command. * In addition, the request regarding specific data and attribute data can be individually accepted. * (Refer to the following descriptions of the accept-wait-extended function). * As for the acceptance of request, normal request (including the case of individual specification of "TDC_READ", "TDC_WRITE", "specific data", and "attribute data") * is prioritized over the user command. * However, normal request and user command may be simultaneously received. * Specify a time-out time in milli second for "tmout". * "TMO_POL" and "TMO_FEVR" also can be specified. * Return the received request pattern or error to the return value. * Return the pattern of the accepted request in the format specified for "acpptn". * Briefly, when the accept-wait-extended function is used, * the request for the specific data and the request for attribute are individually indicated. * In this case,"DRP_ADSEL" is also set. * * In the case of Normal request * Return the pattern, which indicates the type of the accepted request, to the return value. * Return the accepted request to "*devreq" * In the case of User command * Return the pattern, which indicates the accepted user command, to the return value. * When several kinds of user command are accumulated, * the pattern, in which all the user commands specified at "acpptn" are collectively accepted and ORed, shall be returned * * Return NULL to "*devreq" * In the case where normal request and user command are simultaneously accepted. * Return the pattern, which ORed both the accepted normal request and user command * , to the return value. * Return the accepted normal request to "*devreq". * In the case of time-out or error * Return the error code to the return value. "E_TMOUT" is returned in case of time out. * "*devreq" is indeterminate. * * "exinf" of the accepted request(T_DEVREQ) shall never be changed. * Checking of "buf" space (ChkSpace) is already executed in driver I/F * Reply to user command (GDI_Reply) is unnecessary. * * Generally, the next request is newly received after one request is accepted and processed * and the result is returned. * However, several requests may be received and simultaneously processed. * In the case of processing several requests simultaneously, the several request processing tasks may execute each "GDI_Accept()" to be processed in parallel. * Or one processing task may execute several "GDI_Accept()" to be processed simultaneously. * * It does not matter that the order of accepting request and the order of returning result are not necessarily the same. * *Accept-wait-extended function (Specify the accept-wait for specific data and attribute data individually) * DRP_DREAD Read the specific data * DRP_DWRITE Write the specific data * DRP_AREAD Read the attribute data * DRP_AWRITE Write the attribute data * These shall be specified by ORing these above. * * "DRP_DREAD |DRP_AREAD" is equivalent to "DRP_READ". * "DRP_DWRITE|DRP_AWRITE" is equivalent to "DRP_WRITE". * * These specific data and attribute data individual specification cannot be simultaneously combined * and used with "DRP_READ" and "DRP_WRITE" . */ EXPORT INT GDI_Accept( T_DEVREQ **devreq, INT _acpptn, TMO tmout, GDI gdi ) { DRQ *drq; T_DEVREQ *req; QUEUE *q; INT reqptn, rptn; UINT acpptn, aptn; SYSTIM stime, ctime; TMO tmo; ER err; if ( (_acpptn & DRP_ADSEL) == 0 ) { /* Normal specification */ if ( (_acpptn & ~(DRP_NORMREQ|DRP_USERCMD)) != 0 ) { err = E_PAR; goto err_ret; } acpptn = ((_acpptn & DRP_NORMREQ) << 8) | _acpptn; } else { /* Extended specification*/ if ( (_acpptn & ~(DRP_REQMASK|DRP_USERCMD)) != 0 ) { err = E_PAR; goto err_ret; } acpptn = _acpptn & ~DRP_ADSEL; } aptn = 0; tmo = TMO_FEVR; stime.lo = 0; for ( ;; ) { /* Fetch the request from queue */ LockGDI(gdi); drq = NULL; req = NULL; rptn = 0; /* "warning" measures */ for ( q = gdi->acpq.next; q != &gdi->acpq; q = q->next ) { req = ((DRQ*)q)->req; rptn = DEVREQ_ACPPTN(req->cmd); if ( req->start < 0 ) rptn <<= 8; if ( (rptn & acpptn) == 0 ) continue; drq = (DRQ*)q; cntacpq(req, gdi, --); QueRemove(q); QueInit(q); break; } UnlockGDI(gdi); reqptn = aptn & DRP_USERCMD; if ( drq != NULL ) { if ( req->abort ) { /* Abort processing */ req->error = E_ABORT; GDI_Reply(req, gdi); continue; } /* Normal request was accepted */ *devreq = req; reqptn |= rptn; if ( (aptn &= ~rptn & DRP_REQMASK) != 0 ) { /* Reset the unnecessarily cleared flag */ tk_set_flg(gdi->flgid, aptn); } break; } if ( reqptn != 0 ) { /* Only the user command is accepted */ *devreq = NULL; break; } /* Remaining waiting time */ if ( tmout != TMO_FEVR ) { err = tk_get_otm(&ctime); if ( err < E_OK ) goto err_ret; if ( tmo < 0 ) { stime = ctime; tmo = tmout; } else { tmo = tmout - (ctime.lo - stime.lo); if ( tmo < 0 ) tmo = 0; } } /* Wait for the request to come */ err = tk_wai_flg(gdi->flgid, acpptn, TWF_ORW | TWF_BITCLR, &aptn, tmo); if ( err < E_OK ) goto err_ret; aptn &= acpptn; } if ( (reqptn & DRP_REQMASK) != 0 ) { if ( (_acpptn & DRP_ADSEL) == 0 ) { /* Normal specification */ reqptn |= (reqptn & (DRP_NORMREQ << 8)) >> 8; reqptn &= ~(DRP_NORMREQ << 8); } else {
/* * Fetch from the free queue * When DRQ is obtained, execute a return in the state of executing "LockGDI()". */ LOCAL ER gdi_getDRQ( DRQ **p_drq, T_DEVREQ *req, TMO tmout, GDI gdi ) { DRQ *drq; SYSTIM stime, ctime; TMO tmo = tmout; INT rw; UINT ptn, waiptn; ER err; rw = ( req->cmd == TDC_READ )? 0 : 1; waiptn = ( rw == 0 )? FREEQ_RD: FREEQ_WR; if ( tmout != TMO_FEVR ) { err = tk_get_otm(&stime); if ( err < E_OK ) goto err_ret1; } /* Lock for DRQ : This required in order to ensure that only one task waits the event flag for the same pattern */ err = LockDRQ(gdi, rw, tmo); if ( err < E_OK ) goto err_ret1; for ( ;; ) { /* Fetch one from the free queue */ LockGDI(gdi); if ( gdi->preq[rw] < gdi->limit ) { drq = (DRQ*)QueRemoveNext(&gdi->freeq); if ( drq != NULL ) break; /* Obtained */ } UnlockGDI(gdi); /* Remaining waiting time */ if ( tmout != TMO_FEVR ) { err = tk_get_otm(&ctime); if ( err < E_OK ) goto err_ret2; tmo = tmout - (ctime.lo - stime.lo); if ( tmo <= 0 ) { err = E_TMOUT; goto err_ret2; } } /* Wait for DRQ to be returned to the free queue */ err = tk_wai_flg(gdi->flgid, waiptn, TWF_ORW | TWF_BITCLR, &ptn, tmo); if ( err < E_OK ) { if ( err == E_DISWAI ) err = E_ABORT; goto err_ret2; } } /* UnLock for DRQ */ UnlockDRQ(gdi, rw); gdi->preq[rw]++; /* Set the device request to DRQ */ drq->req = req; if ( req->exinf != NULL ) { /* There is the task that waits for completion (gdi_waitfn) */ drq->wtid = *(ID*)req->exinf; } req->exinf = drq; *p_drq = drq; return E_OK; /* Return while executing "LockGDI()" */ err_ret2: UnlockDRQ(gdi, rw); err_ret1: DEBUG_PRINT(("gdi_getDRQ err = %d\n", err)); return err; }