Exemplo n.º 1
0
/*
 *	Set the wait-for-interrupt
 */
EXPORT	void	sdSetIntWait(DrvTab *drv)
{
	/* Get the task number that waits for interrupt */
	drv->WaitTskId = tk_get_tid();

	/* Clear the previous wakeup request */
	tk_can_wup(drv->WaitTskId);
}
Exemplo n.º 2
0
lwp_t*
tkn_curlwp(void)
{
	ID tskid = tk_get_tid();

	lwp_t* re = get_lwp(tskid);

	return re;
}
Exemplo n.º 3
0
/*
 * Enter Synchronization Queue
 *	entry is registered as the task that has entered synchronization queue
 *	return value
 *	FALSE	entry is the first task that has entered the synchronization
 *		queue
 *	TRUE	there were other tasks in the synchronization queue
 */
LOCAL BOOL enterSyncWait( QUEUE *syncq, WaitQ *entry )
{
	BOOL	wait;

	wait = !isQueEmpty(syncq);

	entry->tskid = tk_get_tid();
	QueInsert(&entry->q, syncq);

	return wait;
}
/* |------------------+---------------------------------------------------------| */
StatusType GetTaskID ( TaskRefType pxTask )
{
	*pxTask = tk_get_tid();
	return E_OK;
}
Exemplo n.º 5
0
/*
 * wait for I/O completion for a device
 */
LOCAL ID waitcomplete( ID dd, ID reqid, W *asize, ER *ioer,
					TMO_U tmout, enum ReqType syncreq )
{
	ATR	drvatr;
	OpnCB	*opncb;
	DevCB	*devcb;
	ReqCB	*reqcb;
	DEVREQ	*devreq;
	INT	reqno, nreq;
	ID	tskid;
	BOOL	abort;
	ER	ercd;

	tskid = tk_get_tid();

	LockDM();

	ercd = check_devdesc(dd, 0, &opncb);
	if ( ercd < E_OK ) {
		goto err_ret1;
	}

	/* Check whether there is a break request */
	abort = FALSE;
	ercd = check_break();
	if ( ercd < E_OK ) {
		if ( syncreq == AsyncReq ) goto err_ret1;
		abort = TRUE;
	}

	devcb = opncb->devcb;
	drvatr = devcb->ddev.drvatr;

	if ( reqid == 0 ) {
		/* When waiting for completion of any of requests for 'dd' */
		if ( opncb->nwaireq > 0 || opncb->waitone > 0
		     || opncb->syncreq > 0 ) {
			ercd = E_OBJ;
			goto err_ret1;
		}
		if ( isQueEmpty(&opncb->requestq) ) {
			ercd = E_NOEXS;
			goto err_ret1;
		}

		/* Create wait request list */
		reqcb = (ReqCB*)opncb->requestq.next;
		for ( nreq = 1;; nreq++ ) {
			reqcb->tskid = tskid;
			devreq = &reqcb->req;
			reqcb = (ReqCB*)reqcb->q.next;
			if ( reqcb == (ReqCB*)&opncb->requestq ) {
				break;
			}
			devreq->c.next = &reqcb->req;
		}
		devreq->c.next = NULL;
		devreq = &((ReqCB*)opncb->requestq.next)->req;
		opncb->waireqlst = devreq;
		opncb->nwaireq = nreq;
	} else {
		/* Wait for completion of abort request processing */
		reqcb = check_reqid(reqid, opncb);
		if ( reqcb == NULL ) {
			ercd = E_ID;
			goto err_ret1;
		}
		if ( opncb->nwaireq > 0 || reqcb->tskid > 0 ) {
			ercd = E_OBJ;
			goto err_ret1;
		}

		/* Create waiting request list */
		reqcb->tskid = tskid;
		devreq = &reqcb->req;
		devreq->c.next = NULL;
		if ( abort ) devreq->c.abort = TRUE;
		nreq = 1;
		opncb->waitone++;
	}

	/* Device driver call */
	UnlockDM();
	reqno = call_waitfn(devcb, devreq, nreq, tmout);
	LockDM();
	if ( reqno <  E_OK ) {
		ercd = reqno;
	} else if ( reqno >= nreq ) {
		ercd = E_SYS;
	}

	LockDAbort();

	/* Free wait processing */
	if ( reqid == 0 ) {
		opncb->nwaireq = 0;
	} else {
		opncb->waitone--;
	}

	/* If there is an abort completion wait task,
	   notify abort completion */
	if ( opncb->abort_tskid > 0 && --opncb->abort_cnt == 0 ) {
		SyncSignalDM(opncb->abort_tskid);
	}

	/* Get processing result */
	while ( devreq != NULL ) {
		reqcb = DEVREQ_REQCB(devreq);
		if ( reqno-- == 0 ) {
			reqid = REQID(reqcb);
			if ( (drvatr & TDA_DEV_D) == 0 ) {
				*asize = devreq->s.asize;
				*ioer  = devreq->s.error;
			} else {
				*asize = devreq->l.asize;
				*ioer  = devreq->l.error;
			}
		}
		reqcb->tskid = 0;
		devreq = devreq->c.next;
	}
	UnlockDAbort();

	if ( ercd < E_OK ) {
		goto err_ret1;
	}

	if ( syncreq == SyncReq ) {
		opncb->syncreq--;
	}

	/* Unregister completed request */
	delReqCB(REQCB(reqid));

	UnlockDM();

	return reqid;

err_ret1:
	if ( syncreq == SyncReq ) {
		opncb->syncreq--;
	}
	UnlockDM();
	DEBUG_PRINT(("waitcomplete ercd = %d\n", ercd));
	return ercd;
}
Exemplo n.º 6
0
/*
 * Request for starting input/output to device
 */
LOCAL ID request( ID dd, D start, void *buf, INT size, TMO_U tmout,
					INT cmd, enum ReqType syncreq )
{
	ATR	drvatr;
	OpnCB	*opncb;
	DevCB	*devcb;
	ReqCB	*reqcb;
	UINT	m;
	ER	ercd;

	LockDM();

	/* Check whether there is a break request */
	ercd = check_break();
	if ( ercd < E_OK ) {
		goto err_ret1;
	}

	m = ( cmd == TDC_READ )? TD_READ: TD_WRITE;
	ercd = check_devdesc(dd, m, &opncb);
	if ( ercd < E_OK ) {
		goto err_ret1;
	}

	if ( syncreq == SyncReq ) {
		/* synchronous I/O is prohibited while there are
					pending I/O requests for completion */
		if ( opncb->nwaireq > 0 ) { ercd = E_OBJ; goto err_ret1; }
		opncb->syncreq++;
	}

	devcb = opncb->devcb;
	drvatr = devcb->ddev.drvatr;

	/* check the range of parameter value */
	if ( (drvatr & TDA_DEV_D) == 0 ) {
		if ( start > 0x7fffffff || start < (-0x7fffffff-1) ) {
			ercd = E_PAR; goto err_ret2;
		}
	}

	/* Get request management block */
	reqcb = newReqCB(opncb);
	if ( reqcb == NULL ) {
		ercd = E_LIMIT;
		goto err_ret2;
	}

	/* Set request packet */
	MEMSET(&reqcb->req, 0, sizeof(DEVREQ));
	reqcb->req.c.devid  = DEVID(devcb, opncb->unitno);
	reqcb->req.c.cmd    = cmd;
	if ( (opncb->omode & TD_NOLOCK) != 0 ) {
		reqcb->req.c.nolock = TRUE;
	}
	if ( (drvatr & TDA_DEV_D) == 0 ) {
		reqcb->req.s.start   = start;
		reqcb->req.s.size    = size;
		reqcb->req.s.buf     = buf;
	} else {
		reqcb->req.l.start_d = start;
		reqcb->req.l.size    = size;
		reqcb->req.l.buf     = buf;
	}
	ercd = tk_get_tsp(TSK_SELF, &reqcb->req.c.tskspc);
	if ( ercd < E_OK ) {
		goto err_ret3;
	}

	/* Indicate that it is during processing */
	reqcb->tskid = tk_get_tid();

	/* Device driver call */
	UnlockDM();
	ercd = call_execfn(devcb, &reqcb->req, tmout);
	LockDM();

	LockDAbort();

	/* Indicate that it is not during processing */
	reqcb->tskid = 0;

	/* If there is an abort completion wait task,
	   notify abort completion */
	if ( opncb->abort_tskid > 0 && --opncb->abort_cnt == 0 ) {
		SyncSignalDM(opncb->abort_tskid);
	}
	UnlockDAbort();

	if ( ercd < E_OK ) {
		goto err_ret3;
	}

	UnlockDM();

	return REQID(reqcb);

err_ret3:
	delReqCB(reqcb);
err_ret2:
	if ( syncreq == SyncReq ) {
		opncb->syncreq--;
	}
err_ret1:
	UnlockDM();
	DEBUG_PRINT(("request ercd = %d\n", ercd));
	return ercd;
}
Exemplo n.º 7
0
/*
 * Abort all requests
 */
LOCAL void abort_allrequest( OpnCB *opncb )
{
	DevCB	*devcb;
	ReqCB	*reqcb;
	QUEUE	*q;

	/* If 'execfn' and 'waitfn' are called, execute abort request. */
	LockDM();

	devcb = opncb->devcb;
	opncb->abort_tskid = tk_get_tid();
	opncb->abort_cnt = 0;

	LockDAbort();
	UnlockDM();

	if ( opncb->nwaireq > 0 ) {
		/* Multiple requests wait */
		reqcb = DEVREQ_REQCB(opncb->waireqlst);

		/* Device driver call */
		call_abortfn(devcb, reqcb->tskid, opncb->waireqlst,
							opncb->nwaireq);
		opncb->abort_cnt++;
	} else {
		/* Start request or single request wait */
		for ( q = opncb->requestq.next;
					q != &opncb->requestq; q = q->next ) {
			reqcb = (ReqCB*)q;
			if ( reqcb->tskid == 0 ) {
				continue;
			}
			reqcb->req.c.abort = TRUE;

			/* Device driver call */
			call_abortfn(devcb, reqcb->tskid, &reqcb->req, 1);
			opncb->abort_cnt++;
		}
	}
	UnlockDAbort();

	if ( opncb->abort_cnt > 0 ) {
		/* Wait for completion of abort request processing */
		SyncWaitDM();
	}
	opncb->abort_tskid = 0;

	/* Abort remaining requests and wait for completion */
	LockDM();
	while ( !isQueEmpty(&opncb->requestq) ) {
		reqcb = (ReqCB*)opncb->requestq.next;
		reqcb->req.c.abort = TRUE;

		/* Device driver waitfn call */
		UnlockDM();
		call_waitfn(devcb, &reqcb->req, 1, TMO_FEVR);
		LockDM();

		/* Unregister completed request */
		delReqCB(reqcb);
	}
	UnlockDM();
}