/* * Return to the free queue * Call by executing "LockGDI()" */ LOCAL void gdi_relDRQ( DRQ *drq, GDI gdi ) { UINT ptn = isQueEmpty(&gdi->freeq)? (FREEQ_RD|FREEQ_WR): 0; if ( drq->req->cmd == TDC_READ ) { if ( gdi->preq[0]-- == gdi->limit ) ptn |= FREEQ_RD; } else { if ( gdi->preq[1]-- == gdi->limit ) ptn |= FREEQ_WR; } if ( ptn != 0 ) { tk_set_flg(gdi->flgid, ptn); } QueInsert((QUEUE*)drq, &gdi->freeq); drq->req = NULL; drq->wtid = 0; drq->done = NotDone; }
/* |------------------+----------------------------------------------------------| */ StatusType SetEvent ( TaskType xTaskID , EventMaskType xMask ) { StatusType ercd = E_OK; TCB* tcb=get_tcb(xTaskID); ID flgid=(ID)(tcb->exinf); if((xTaskID >= cfgOSEK_TASK_NUM+MIN_TSKID) || (xTaskID < MIN_TSKID)) { ercd = E_OS_ID; goto Error_Exit; } if(flgid == (ID)NULL) { ercd = E_OS_ACCESS; goto Error_Exit; } ercd = tk_set_flg(flgid,xMask); Error_Exit: return ercd; }
/* * An insertion into the queue that waits for accepting a request * Call by executing "LockGDI()" */ LOCAL ER gdi_sndreq( DRQ *drq, GDI gdi ) { T_DEVREQ *req = drq->req; UINT setptn; ER err; if ( req->abort ) { err = E_ABORT; goto err_ret1; } /* Insert into the queue that waits for accepting */ setptn = 0; if ( req->cmd == TDC_READ ) { if ( req->start < 0 ) { if ( gdi->acpa[0]++ == 0 ) setptn |= DRP_AREAD; } else { if ( gdi->acpd[0]++ == 0 ) setptn |= DRP_DREAD; } } else { if ( req->start < 0 ) { if ( gdi->acpa[1]++ == 0 ) setptn |= DRP_AWRITE; } else { if ( gdi->acpd[1]++ == 0 ) setptn |= DRP_DWRITE; } } QueInsert((QUEUE*)drq, &gdi->acpq); if ( setptn != 0 ) { /* Notify the insertion into the queue that waits for accepting */ err = tk_set_flg(gdi->flgid, setptn); if ( err < E_OK ) goto err_ret2; } return E_OK; err_ret2: cntacpq(req, gdi, --); QueRemove((QUEUE*)drq); err_ret1: DEBUG_PRINT(("gdi_sndreq err = %d\n", err)); return err; }
/* * 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 {