示例#1
0
文件: common.c 项目: yuki74w/TRON
/*
 *	Fetch the current time (msec)
 */
EXPORT	UW	sdGetMsec(void)
{
	SYSTIM	ctm;
	UW	ct;

	tk_get_otm(&ctm);		/* Current time : monotone increasing	*/

	ct = ctm.lo;
	return (ct == 0) ? 1 : ct;	/* Avoid 0		*/
}
示例#2
0
/*
 * 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 {
示例#3
0
/*
 * 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;
}