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

📄 devinfo.c

📁 T-kernel 的extension源代码
💻 C
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	devinfo.c (device) * *	Device information */#include "devmgr.h"/* * Access mode management table *	It is a simple array of ACCENT. Arrange devid in ascending order. */typedef struct {	ID	devid;		/* Device ID of physical device */	H	nsub;		/* Subunit count (0= No subunit) */	UH	mode[1];	/* [0]:Physical device. [1 to nsub]: Logical device */} ACCENT;LOCAL ACCENT	*AccTbl;	/* Access mode management table */LOCAL W		AccTblSz;	/* Valid size of AccTbl (Bytes) */#define	ACCTBL_BLKSZ	256	/* Extension steps of AccTbl (Bytes) */Inline UW ACCENT_SZ( W nsub );Inline UW ACCTBL_SZ( UW s );LOCAL ER resizeAccTbl( W diff );LOCAL ACCENT* searchAccEnt( ID devid );LOCAL ER registAccEnt( ID devid, W nsub );LOCAL UW GetAccessMode( ID devid );#define TSD_RAE_MOD_0X0FFF	0x0fffU#define TSD_GAM_MOD_0X0FFF	0x0fffU#define TSD_TCD_MSK_0X0FFF	0x0fffU#define TSD_UAM_NSB_M1		(-1)#define TSD_ACS_VAL_3		3#define TSD_ACS_VAL_4		4#define TSD_CAM_MSK_0XF		0xfU#define TSD_CAM_SFT_4		4#define TSD_CAM_SFT_8		8Inline UW ACCENT_SZ( W nsub ){	/* To avoid misalignment access, it is defined as 4 bytes steps. */	return (((offsetof(ACCENT, mode[nsub + 1]) + (UW)TSD_ACS_VAL_3) / (UW)TSD_ACS_VAL_4) * (UW)TSD_ACS_VAL_4);}Inline UW ACCTBL_SZ( UW s ){	return ((s + (UW)(ACCTBL_BLKSZ - 1)) / (UW)ACCTBL_BLKSZ) * (UW)ACCTBL_BLKSZ;}/* * Change the size of the access mode management table. */LOCAL ER resizeAccTbl( W diff ){	W	cursz, newsz;	ACCENT	*p;	cursz = (W)ACCTBL_SZ((UW)AccTblSz);	newsz = (W)ACCTBL_SZ((UW)(AccTblSz + diff));	if ( cursz != newsz ) {		p = (ACCENT *)Vrealloc(AccTbl, (size_t)newsz);		if ( (p == NULL) && (newsz > 0) ) {			goto err_ret;		}		AccTbl = p;	}	return E_OK;err_ret:	DEBUG_PRINT(("resizeAccTbl err = %d\n", E_NOMEM));	return E_NOMEM;}/* * Retrieve the access mode entry. */LOCAL ACCENT* searchAccEnt( ID devid ){	ACCENT	*ent, *ep;	UW	sz;	ep = (ACCENT*)((B*)AccTbl + AccTblSz);	sz = (UW)0;	for ( ent = AccTbl; ent < ep; ent = (ACCENT*)((B*)ent + sz) ) {		if ( devid < ent->devid ) {			break;		}		sz = ACCENT_SZ(ent->nsub);	}	if ( sz == (UW)0 ) {		return NULL;	}	ent = (ACCENT*)((B*)ent - sz);	if ( devid > (ent->devid + ent->nsub) ) {		return NULL;	}	return ent;}/* * Register/Change/Deregister the access mode entry. *	nsub >= 0	Register (Registered subunit count) *	nsub <  0	Deregister */LOCAL ER registAccEnt( ID devid, W nsub ){	ACCENT	*ent, *ep;	W	sz, i;	ER	err;	/* Current registration information */	ent = searchAccEnt(devid);	/* The size of the change of the access mode management table. */	sz = ( nsub < 0 )? 0: (W)ACCENT_SZ(nsub);			/* New size */	sz -= ( ent == NULL )? 0: (W)ACCENT_SZ(ent->nsub);		/* Current size */	/* Retrieve the registered position. */	ep = (ACCENT*)((B*)AccTbl + AccTblSz);	for ( ent = AccTbl; ent < ep; ent = (ACCENT*)((B*)ent + ACCENT_SZ(ent->nsub)) ) {		if ( ent->devid > devid ) {			break;		}	}	if ( sz != 0 ) {		i = (B*)ent - (B*)AccTbl;		if ( sz > 0 ) {			err = resizeAccTbl(sz);			if ( err < E_OK ) {				goto err_ret;			}		}		if ( ent != NULL ) {			/* Move the size of the change. */			ent = (ACCENT*)((B*)AccTbl + i);			memmove((B*)ent + sz, ent, (size_t)(AccTblSz - i));		}		if ( sz < 0 ) {			err = resizeAccTbl(sz);			if ( err < E_OK ) {				goto err_ret;			}		}		AccTblSz += sz;		ent = (ACCENT*)((B*)AccTbl + i);	}	if ( nsub < 0 ) {		/* In the case of deletion, here is the end. */		return E_OK;	} 	/* Update the registration information. */	ent = (ACCENT*)((B*)ent + sz - ACCENT_SZ(nsub));	if ( sz > 0 ) {		i = ( sz == (W)ACCENT_SZ(nsub) )?	0:		/* New */						(ent->nsub + 1);	/* Addition */		while ( i <= nsub ) {			ent->mode[i++] = (UH)TSD_RAE_MOD_0X0FFF;		}	}	ent->devid = devid;	ent->nsub  = (H)nsub;	return E_OK;err_ret:	DEBUG_PRINT(("registAccEnt err = %d\n", err));	return err;}/* * Obtain the access mode. */LOCAL UW GetAccessMode( ID devid ){	ACCENT	*ent;	W	unitno;	UW	mode = TSD_GAM_MOD_0X0FFF;	LockDM();	/* Retrieve the access mode information. */	ent = searchAccEnt(devid);	if ( ent == NULL ) {		goto err_ret;	}	unitno = devid - ent->devid;	mode = ent->mode[unitno];err_ret:	UnlockDM();	return mode;}/* * Check the access mode. */EXPORT ER CheckAccessMode( UB *devnm, W omode ){	ID	devid;	UW	mode, level;	ER	err;	devid = tk_ref_dev(devnm, NULL);	if ( devid < E_OK ) {		err = ERtoERR(devid);		goto err_ret;	}	/* Obtain the access mode. */	mode = GetAccessMode(devid);	/* Obtain the user level. */	level = (UW)GetUserLevel(TSK_SELF);	if ( ((UW)omode & D_READ) != 0 ) {		if ( ((mode >> TSD_CAM_SFT_8) & TSD_CAM_MSK_0XF) < level ) {			return E_OACV;		}	}	if ( ((UW)omode & D_WRITE) != 0 ) {		if ( ((mode >> TSD_CAM_SFT_4) & TSD_CAM_MSK_0XF) < level ) {			return E_OACV;		}	}	return E_OK;err_ret:	DEBUG_PRINT(("CheckAccessMode err = %d\n", err));	return err;}/* * Check the access mode. (for T-Kernel I/F SystemCall) */EXPORT ER tkCheckAccessMode( UB *devnm, UINT omode ){	ID	devid;	UW	mode, level;	ER	err;	devid = tk_ref_dev(devnm, NULL);	if ( devid < E_OK ) {		err = devid;		goto err_ret;	}	/* Obtain the access mode. */	mode = (UW)GetAccessMode(devid);	/* Obtain the user level. */	level = (UW)GetUserLevel(TSK_SELF);	if ( (omode & TD_READ) != 0 ) {		if ( ((mode >> TSD_CAM_SFT_8) & TSD_CAM_MSK_0XF) < level ) {			return E_OACV;		}	}	if ( (omode & TD_WRITE) != 0 ) {		if ( ((mode >> TSD_CAM_SFT_4) & TSD_CAM_MSK_0XF) < level ) {			return E_OACV;		}	}	return E_OK;err_ret:	DEBUG_PRINT(("tkCheckAccessMode err = %d\n", err));	return err;}/* * Update the access mode by device registration/deregistration. *	reg =	TRUE	Registration/Change *		FALSE	Deregistration */EXPORT ER UpdateAccessMode( ID devid, BOOL reg ){	UB	devnm[L_DEVNM + 1];	T_RDEV	rdev;	ER	err;	if ( reg != 0 ) {		/* Obtain the registration information. */		err = tk_get_dev(devid, devnm);		if ( err < E_OK ) {			err = ERtoERR(err);			goto err_ret1;		}		err = tk_ref_dev(devnm, &rdev);		if ( err < E_OK ) {			err = ERtoERR(err);			goto err_ret1;		}	} else {		rdev.nsub = TSD_UAM_NSB_M1;	}	LockDM();	/* Registration/Change/Deregistration */	err = registAccEnt(devid, rdev.nsub);	if ( err < E_OK ) {		goto err_ret2;	}	UnlockDM();	return E_OK;err_ret2:	UnlockDM();err_ret1:	DEBUG_PRINT(("UpdateAccessMode err = %d\n", err));	return err;}/* * Change the device access mode. */EXPORT ER _tkse_chg_dmd( TC *dev, W mode ){	UB	devnm[L_DEVNM + 1];	ID	devid;	ACCENT	*ent;	W	unitno;	ER	err;	err = CheckStrSpaceR(dev, 0);	if ( err < E_OK ) {		goto err_ret1;	}	if ( ((UW)mode & ~TSD_TCD_MSK_0X0FFF) != 0 ) {		err = E_PAR;		goto err_ret1;	}	/* Check the user level. */	if ( GetUserLevel(TSK_SELF) != 0 ) {		err = E_OACV;		goto err_ret1;	}	/* Convert the device name. */	err = ubdevnm(devnm, dev);	if ( err < E_OK ) {		goto err_ret1;	}	devid = tk_ref_dev(devnm, NULL);	if ( devid < E_OK ) {		err = ERtoERR(devid);		goto err_ret1;	}	LockDM();	/* Retrieve the access mode information. */	ent = searchAccEnt(devid);	if ( ent == NULL ) {		err = E_SYS;		goto err_ret2;	}	unitno = devid - ent->devid;	/* Set the access mode. */	ent->mode[unitno] = (UH)mode;	UnlockDM();	return E_OK;err_ret2:	UnlockDM();err_ret1:	DEBUG_PRINT(("_tkse_chg_dmd err = %d\n", err));	return err;}/* ------------------------------------------------------------------------ *//* * Obtain the device management information. */EXPORT ER _tkse_dev_sts( TC *dev, DEV_STATE *buf ){	UB	devnm[L_DEVNM + 1];	T_RDEV	rdev;	ID	devid;	ER	err;	err = CheckSpaceRW(buf, sizeof(DEV_STATE));	if ( err < E_OK ) {		goto err_ret;	}	err = CheckStrSpaceR(dev, 0);	if ( err < E_OK ) {		goto err_ret;	}	/* Convert the device name. */	err = ubdevnm(devnm, dev);	if ( err < E_OK ) {		goto err_ret;	}	/* Obtain the device information. */	devid = tk_ref_dev(devnm, &rdev);	if ( devid < E_OK ) {		err = ERtoERR(devid);		goto err_ret;	}	buf->attr  = rdev.devatr;	buf->blksz = rdev.blksz;	buf->wprt  = ( (rdev.devatr & TD_PROTECT) != 0 )? 1: 0;	buf->mode  = GetAccessMode(devid);	return E_OK;err_ret:	DEBUG_PRINT(("_tkse_dev_sts err = %d\n", err));	return err;}/* * Obtain the device name. */EXPORT WER _tkse_get_dev2( TC *dev, W num ){	UB	devnm[L_DEVNM + 1];	T_RDEV	rdev;	ER	err;	err = CheckSpaceRW(dev, (L_DEVNM + 1) * sizeof(TC));	if ( err < E_OK ) {		goto err_ret;	}	/* Obtain the device name. */	err = tk_get_dev(num, devnm);	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret;	}	/* Obtain the device information. */	err = tk_ref_dev(devnm, &rdev);	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret;	}	/* Convert the device name. */	tcdevnm(dev, devnm, L_DEVNM + 1);	return rdev.nsub;err_ret:	DEBUG_PRINT(("_tkse_get_dev err = %d\n", err));	return err;}/* * Obtain the registered device. */EXPORT WER _tkse_lst_dev2( DEV_INFO *dev, W ndev ){	T_LDEV	*ldev = NULL;	W	total, i;	ER	err;	if ( ndev < 0 ) {		err = E_PAR;		goto err_ret1;	}	if ( dev == NULL ) {		ndev = 0;	}	if ( ndev > 0 ) {		err = CheckSpaceRW(dev, (W)sizeof(DEV_INFO) * ndev);		if ( err < E_OK ) {			goto err_ret1;		}		ldev = Vmalloc((size_t)((W)sizeof(T_LDEV) * ndev));		if ( ldev == NULL ) {			err = E_NOMEM;			goto err_ret1;		}	}	/* Obtain the registered device. */	total = tk_lst_dev(ldev, 0, ndev);	if ( total < E_OK ) {		err = ERtoERR(total);		goto err_ret2;	}	/* Convert the device name and store it. */	if ( ndev > total ) {		ndev = total;	}	for ( i = 0; i < ndev; ++i ) {		dev[i].attr = ldev[i].devatr;		dev[i].nsub = ldev[i].nsub;		tcdevnm(dev[i].name, ldev[i].devnm, L_DEVNM);	}	if ( ldev != NULL ) {		Vfree(ldev);	}	return total;err_ret2:	if ( ldev != NULL ) {		Vfree(ldev);	}err_ret1:	DEBUG_PRINT(("_tkse_lst_dev err = %d\n", err));	return err;}

⌨️ 快捷键说明

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