⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deviceio.c

📁 uT Kernel os source code for AT91
💻 C
📖 第 1 页 / 共 2 页
字号:
	devcb = opncb->devcb;	execfn = (EXCFN)devcb->ddev.execfn;	exinf = devcb->ddev.exinf;#if TA_GP	gp = devcb->ddev.gp;#endif	/* Get request management block */	reqcb = newReqCB(opncb);	if ( reqcb == NULL ) {		ercd = E_LIMIT;		goto err_ret1;	}	/* Set request packet */	reqcb->req.next   = NULL;	reqcb->req.exinf  = NULL;	reqcb->req.devid  = DEVID(devcb, opncb->unitno);	reqcb->req.cmd    = cmd;	reqcb->req.abort  = FALSE;	reqcb->req.start  = start;	reqcb->req.size   = size;	reqcb->req.buf    = buf;	reqcb->req.asize  = 0;	reqcb->req.error  = 0;	/* Indicate that it is during processing */	reqcb->tskid = tk_get_tid_impl();	UnlockDM();	/* Device driver call */	DISABLE_INTERRUPT;	knl_ctxtsk->sysmode++;	ENABLE_INTERRUPT;#if TA_GP	ercd = CallDeviceDriver(&reqcb->req, tmout, exinf, 0, (FP)execfn, gp);#else	ercd = (*execfn)(&reqcb->req, tmout, exinf);#endif	DISABLE_INTERRUPT;	knl_ctxtsk->sysmode--;	ENABLE_INTERRUPT;	LockDM();	/* 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 ) {		tk_sig_sem_impl(opncb->abort_semid, 1);	}	if ( ercd < E_OK ) {		goto err_ret2;	}	UnlockDM();	return REQID(reqcb);err_ret2:	knl_delReqCB(reqcb);err_ret1:	UnlockDM();	DEBUG_PRINT(("knl_request ercd = %d\n", ercd));	return ercd;}#endif /* USE_FUNC_REQUEST */#ifdef USE_FUNC_TK_REA_DEV/* * Start reading from device */SYSCALL ID tk_rea_dev_impl( ID dd, W start, VP buf, W size, TMO tmout ){	ER	ercd;	ercd = knl_request(dd, start, buf, size, tmout, TDC_READ);#ifdef DEBUG	if ( ercd < E_OK ) {		DEBUG_PRINT(("tk_rea_dev_impl ercd = %d\n", ercd));	}#endif	return ercd;}#endif /* USE_FUNC_TK_REA_DEV */#ifdef USE_FUNC_TK_SREA_DEV/* * Synchronous reading from device */SYSCALL ER tk_srea_dev_impl( ID dd, W start, VP buf, W size, W *asize ){	ER	ercd, ioercd;	ercd = tk_rea_dev_impl(dd, start, buf, size, TMO_FEVR);	if ( ercd < E_OK ) {		goto err_ret;	}	ercd = tk_wai_dev_impl(dd, ercd, asize, &ioercd, TMO_FEVR);	if ( ercd < E_OK ) {		goto err_ret;	}	return ioercd;err_ret:	DEBUG_PRINT(("tk_srea_dev_impl ercd = %d\n", ercd));	return ercd;}#endif /* USE_FUNC_TK_SREA_DEV */#ifdef USE_FUNC_TK_WRI_DEV/* * Start writing to device */SYSCALL ID tk_wri_dev_impl( ID dd, W start, VP buf, W size, TMO tmout ){	ER	ercd;	ercd = knl_request(dd, start, buf, size, tmout, TDC_WRITE);#ifdef DEBUG	if ( ercd < E_OK ) {		DEBUG_PRINT(("tk_wri_dev_impl ercd = %d\n", ercd));	}#endif	return ercd;}#endif /* USE_FUNC_TK_WRI_DEV */#ifdef USE_FUNC_TK_SWRI_DEV/* * Synchronous writing to device */SYSCALL ER tk_swri_dev_impl( ID dd, W start, VP buf, W size, W *asize ){	ER	ercd, ioercd;	ercd = tk_wri_dev_impl(dd, start, buf, size, TMO_FEVR);	if ( ercd < E_OK ) {		goto err_ret;	}	ercd = tk_wai_dev_impl(dd, ercd, asize, &ioercd, TMO_FEVR);	if ( ercd < E_OK ) {		goto err_ret;	}	return ioercd;err_ret:	DEBUG_PRINT(("tk_swri_dev_impl ercd = %d\n", ercd));	return ercd;}#endif /* USE_FUNC_TK_SWRI_DEV */#ifdef USE_FUNC_TK_WAI_DEV/* * Verify validity of request ID */LOCAL ReqCB* knl_check_reqid( ID reqid, OpnCB *opncb ){	ReqCB	*reqcb;	if ( reqid < 1 || reqid > CFN_MAX_REQDEV ) {		return NULL;	}	reqcb = REQCB(reqid);	if ( reqcb->opncb != opncb ) {		return NULL;	}	return reqcb;}/* * Request completion wait */SYSCALL ID tk_wai_dev_impl( ID dd, ID reqid, W *asize, ER *ioer, TMO tmout ){	WAIFN	waitfn;	VP	exinf;#if TA_GP	VP	gp;#endif	OpnCB	*opncb;	DevCB	*devcb;	ReqCB	*reqcb;	T_DEVREQ *devreq;	INT	reqno, nreq;	ID	tskid;	ER	ercd;	tskid = tk_get_tid_impl();	LockDM();	ercd = knl_check_devdesc(dd, 0, &opncb);	if ( ercd < E_OK ) {		goto err_ret2;	}	devcb = opncb->devcb;	waitfn = (WAIFN)devcb->ddev.waitfn;	exinf = devcb->ddev.exinf;#if TA_GP	gp = devcb->ddev.gp;#endif	if ( reqid == 0 ) {		/* When waiting for completion of any of requests for 'dd' */		if ( opncb->nwaireq > 0 || opncb->waitone > 0 ) {			ercd = E_OBJ;			goto err_ret2;		}		if ( isQueEmpty(&opncb->requestq) ) {			ercd = E_NOEXS;			goto err_ret2;		}		/* 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->next = &reqcb->req;		}		devreq->next = NULL;		devreq = &((ReqCB*)opncb->requestq.next)->req;		opncb->waireqlst = devreq;		opncb->nwaireq = nreq;	} else {		/* Wait for completion of abort request processing */		reqcb = knl_check_reqid(reqid, opncb);		if ( reqcb == NULL ) {			ercd = E_ID;			goto err_ret2;		}		if ( opncb->nwaireq > 0 || reqcb->tskid > 0 ) {			ercd = E_OBJ;			goto err_ret2;		}		/* Create waiting request list */		reqcb->tskid = tskid;		devreq = &reqcb->req;		devreq->next = NULL;		nreq = 1;		opncb->waitone++;	}	UnlockDM();	/* Device driver call */	DISABLE_INTERRUPT;	knl_ctxtsk->sysmode++;	ENABLE_INTERRUPT;#if TA_GP	reqno = CallDeviceDriver(devreq, nreq, tmout, exinf, (FP)waitfn, gp);#else	reqno = (*waitfn)(devreq, nreq, tmout, exinf);#endif	DISABLE_INTERRUPT;	knl_ctxtsk->sysmode--;	ENABLE_INTERRUPT;	if ( reqno <  E_OK ) {		ercd = reqno;	}	if ( reqno >= nreq ) {		ercd = E_SYS;	}	LockDM();	/* 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 ) {		tk_sig_sem_impl(opncb->abort_semid, 1);	}	/* Get processing result */	while ( devreq != NULL ) {		reqcb = DEVREQ_REQCB(devreq);		if ( reqno-- == 0 ) {			reqid = REQID(reqcb);			*asize = devreq->asize;			*ioer  = devreq->error;		}		reqcb->tskid = 0;		devreq = devreq->next;	}	if ( ercd < E_OK ) {		goto err_ret2;	}	/* Unregister completed request */	knl_delReqCB(REQCB(reqid));	UnlockDM();	return reqid;err_ret2:	UnlockDM();	DEBUG_PRINT(("tk_wai_dev_impl ercd = %d\n", ercd));	return ercd;}#endif /* USE_FUNC_TK_WAI_DEV *//* ------------------------------------------------------------------------ */#ifdef USE_FUNC_DISSUSCNT/* Suspend disable request count */EXPORT INT	knl_DisSusCnt = 0;#endif /* USE_FUNC_DISSUSCNT */#ifdef USE_FUNC_TK_SUS_DEV/* * Send driver request event to each device */LOCAL ER sendevt_alldevice( INT evttyp, BOOL disk ){	EVTFN	eventfn;	QUEUE	*q;	DevCB	*devcb;	BOOL	d;	ER	ercd = E_OK;	for ( q = knl_UsedDevCB.next; q != &knl_UsedDevCB; q = q->next ) {		devcb = (DevCB*)q;		d = ( (devcb->ddev.devatr & TD_DEVTYPE) == TDK_DISK )?							TRUE: FALSE;		if ( disk != d ) {			continue;		}		/* Device driver call */		eventfn = (EVTFN)devcb->ddev.eventfn;		DISABLE_INTERRUPT;		knl_ctxtsk->sysmode++;		ENABLE_INTERRUPT;#if TA_GP		ercd = CallDeviceDriver(evttyp, NULL, devcb->ddev.exinf, 0,						(FP)eventfn, devcb->ddev.gp);#else		ercd = (*eventfn)(evttyp, NULL, devcb->ddev.exinf);#endif		DISABLE_INTERRUPT;		knl_ctxtsk->sysmode--;		ENABLE_INTERRUPT;	}#ifdef DEBUG	if ( ercd < E_OK ) {		DEBUG_PRINT(("sendevt_alldevice ercd = %d\n", ercd));	}#endif	return ercd;}/* * Suspend */LOCAL ER do_suspend( void ){	ER	ercd;	/* Stop accepting device registration/unregistration */	LockREG();	/* Suspend processing of device except for disks */	ercd = sendevt_alldevice(TDV_SUSPEND, FALSE);#ifdef DEBUG	if ( ercd < E_OK ) {		DEBUG_PRINT(("2. do_suspend -> sendevt_alldevice ercd = %d\n", ercd));	}#endif	/* Suspend processing of disk device */	ercd = sendevt_alldevice(TDV_SUSPEND, TRUE);#ifdef DEBUG	if ( ercd < E_OK ) {		DEBUG_PRINT(("3. do_suspend -> sendevt_alldevice ercd = %d\n", ercd));	}#endif	/* Stop accepting new requests */	LockDM();	/*	 * Insert code to transit to suspend state here	 */	/*	 * Insert code executed on returning from suspend state	 */	/* Resume accepting requests */	UnlockDM();	/* Resume processing of disk device */	ercd = sendevt_alldevice(TDV_RESUME, TRUE);#ifdef DEBUG	if ( ercd < E_OK ) {		DEBUG_PRINT(("7. do_suspend -> sendevt_alldevice ercd = %d\n", ercd));	}#endif	/* Resume processing of device except for disks */	ercd = sendevt_alldevice(TDV_RESUME, FALSE);#ifdef DEBUG	if ( ercd < E_OK ) {		DEBUG_PRINT(("8. do_suspend -> sendevt_alldevice ercd = %d\n", ercd));	}#endif	/* Resume accepting device registration/unregistration */	UnlockREG();	return ercd;}/* * Suspend processing */SYSCALL INT tk_sus_dev_impl( UINT mode ){	ResCB	*rescb;	BOOL	suspend = FALSE;	ER	ercd;	/* Get resource management information */	rescb = knl_GetResCB();	if ( rescb == NULL ) {		ercd = E_CTX;		goto err_ret1;	}	LockDM();	switch ( mode & 0xf ) {	  case TD_SUSPEND:	/* Suspend */		if ( knl_DisSusCnt > 0 && (mode & TD_FORCE) == 0 ) {			ercd = E_BUSY;			goto err_ret2;		}		suspend = TRUE;		break;	  case TD_DISSUS:	/* Disable suspend */		if ( knl_DisSusCnt >= MAX_DISSUS ) {			ercd = E_QOVR;			goto err_ret2;		}		knl_DisSusCnt++;		rescb->dissus++;		break;	  case TD_ENASUS:	/* Enable suspend */		if ( rescb->dissus > 0 ) {			rescb->dissus--;			knl_DisSusCnt--;		}		break;	  case TD_CHECK:	/* Get suspend disable request count */		break;	  default:		ercd = E_PAR;		goto err_ret2;	}	UnlockDM();	if ( suspend ) {		/* Suspend */		ercd = do_suspend();		if ( ercd < E_OK ) {			goto err_ret1;		}	}	return knl_DisSusCnt;err_ret2:	UnlockDM();err_ret1:	DEBUG_PRINT(("tk_sus_dev_impl ercd = %d\n", ercd));	return ercd;}#endif /* USE_FUNC_TK_SUS_DEV *//* ------------------------------------------------------------------------ */#ifdef USE_FUNC_DEVMGR_STARTUP/* * Device management startup function */EXPORT void knl_devmgr_startup( void ){	LockDM();	/* Initialization of open device management queue */	QueInit(&(knl_resource_control_block.openq));	UnlockDM();	return;}#endif /* USE_FUNC_DEVMGR_STARTUP */#ifdef USE_FUNC_DEVMGR_CLEANUP/* * Device management cleanup function */EXPORT void knl_devmgr_cleanup( void ){	OpnCB	*opncb;	/* Do nothing if it is not used even once */	if ( knl_resource_control_block.openq.next == NULL ) {		return;	}	LockDM();	/* Free suspend disable request */	knl_DisSusCnt -= knl_resource_control_block.dissus;	knl_resource_control_block.dissus = 0;	/* Close all open devices */	while ( !isQueEmpty(&(knl_resource_control_block.openq)) ) {		opncb = RESQ_OPNCB(knl_resource_control_block.openq.next);		/* Indicate that it is during close processing */		opncb->resid = 0;		UnlockDM();		/* Device close processing */		knl_close_device(opncb, 0);		LockDM();	}	UnlockDM();	return;}#endif /* USE_FUNC_DEVMGR_CLEANUP */#ifdef USE_FUNC_INITDEVIO/* * Initialization sequence of device input/output-related */EXPORT ER knl_initDevIO( void ){	INT	i;	QueInit(&knl_FreeOpnCB);	for ( i = 0; i < CFN_MAX_OPNDEV; ++i ) {		knl_OpnCBtbl[i].resid = 0;		QueInsert(&knl_OpnCBtbl[i].q, &knl_FreeOpnCB);	}	QueInit(&knl_FreeReqCB);	for ( i = 0; i < CFN_MAX_REQDEV; ++i ) {		knl_ReqCBtbl[i].opncb = NULL;		QueInsert(&knl_ReqCBtbl[i].q, &knl_FreeReqCB);	}	return E_OK;}#endif /* USE_FUNC_INITDEVIO */#ifdef USE_FUNC_FINISHDEVIO/* * Finalization sequence of device input/output-related */EXPORT ER knl_finishDevIO( void ){	return E_OK;}#endif /* USE_FUNC_FINISHDEVIO */#endif /* CFN_MAX_REGDEV */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -