VXBUS源码分析
作者:互联网
重要的两个数据结构分别是VXB_DEV和VXB_DRV
typedef struct vxbDev
{
SL_NODE vxbNode; /* must always be first element */
SL_NODE vxbAttachNode;
UINT32 vxbUnit; /* unit number */
VXB_BUSTYPE_ID vxbClass;
/* device name */
char * pName;//设备名称
void * pVxbIvars;
/* per-driver info */
void * pVxbSoftc;
void * pVxbDrvData;
SL_LIST vxbList;
SEM_ID pVxbDevSem;
struct vxbDev * pVxbParent;
int vxbToggle;
//标志信息,如vxbDevCreate会添加 VXB_FLAG_DYNAMIC标志,在释放后清除;主要是动态申请和回收一些标志信息。
UINT32 vxbFlags;
int vxbRefCnt;
VXB_DRV * pVxbDriver; //匹配驱动是 挂载这个
VXB_KEY vxbSerial;
void * pVxbParams;
UINT32 level;
char * pNameAddr; /* Unit-address specification */
char * pNameOrphan;/* Original orphan name */
} VXB_DEV;
typedef struct vxbDrvMethod
{
VXB_METHOD_ID drvMethodId;// typedef UINT32 VXB_METHOD_ID;
FUNCPTR handler;
} VXB_DRV_METHOD;
typedef struct vxbDrv
{
SL_NODE vxbNode; /* must always be first element */
char * pVxbName;//驱动名称
char * pVxbDesc;
VXB_BUSTYPE_ID vxbClass;
UINT32 vxbFlags;
int vxbRefCnt;
VXB_DRV_METHOD * pVxbMethods;//驱动操作方法,也就是提供驱动函数
void * pVxbParamDefaults;
} VXB_DRV;
#define VXB_DEVMETHOD_CALL(METHOD) ((VXB_METHOD_ID)(&METHOD##_desc[0]))
vxbLibInit函数
STATUS vxbLibInit (void)
{
VXB_DEV_ID pRoot;
………. /* req: VX7-13783 */
/* 创建 root nexus 节点 */
pRoot = &vxbRoot;
(void) vxbDevCreate (&pRoot);
//创建设备为mainbus0 节点
vxbDevNameSet (pRoot, "mainbus", FALSE);
vxbDevNameAddrSet (pRoot, "0", FALSE);
vxbDevClassSet (pRoot, VXB_BUSID_ROOT);
/*创建完成后,添加bus,vxbDevAdd第一个参数是一个NULL,
表示从根节点开始,也是唯一个调用第一个参数为NULL的地方了。*/
if (vxbDevAdd (NULL, pRoot) != OK)
{
/* req: VX7-13784 */
return (ERROR);
}
return (OK);
}
vxbDevClassGet 和 vxbDevClassSet函数
//主要实现获取和填充VXB_DEV结构中的 vxbClass成员
vxbClass 参数可以归类设备属于哪一类
VXB_BUSID_FDT //设备树类
VXB_BUSID_ROOT //root 类
VXB_BUSID_IEEE1588 //IEEE1588类
VXB_BUSID_USBTGT_SERSIO
VXB_BUSID_USB //USB类
VXB_BUSID_MII //MII 类
在驱动里可以经常看到
if (VXB_BUSID_MATCH (vxbDevClassGet (pChild), VXB_BUSID_MII) == FALSE)
vxbDevNameSet (pRoot, "mainbus", FALSE); //填充VXB_DEV pName数据
//填充VXB_DEV vxbClass与之对应的vxbDevClassGet
vxbDevClassSet (pRoot, VXB_BUSID_ROOT);
//填充VXB_DEV pVxbIvars 与之对应的vxbDevIvarsGet
vxbDevIvarsSet(pCur, (void *) pI2cDevInfo);
vxbDevSoftcSet (pDev, pDrvCtrl); //填充VXB_DEV pVxbSoftc
//填充VXB_DEV pVxbDrvData 与之对应的vxbDevDrvDataGet
vxbDevDrvDataSet (pDev, (void *)pMatch->data);
//这个函数主要比较VXB_DEV成员 pName 和 vxbDev 成员pVxbName 是否匹配
vxbDevMatch(pDev);
vxbDevUnitSet();//填充VXB_DEV vxbUnit
pI2cRtcCtrlInfo = (I2C_RTC_CTRL_INFO *)vxbDevDrvDataGet(pDev); //获取VXB_DEV 中的pVxbDrvData
vxbDevCreate函数
STATUS vxbDevCreate
(
VXB_DEV_ID * pDev /* pointer to device ID, or NULL */
)
{
BOOL isDynamic = FALSE;
if (*pDev == NULL)
{
/*申请内存 */
*pDev = (VXB_DEV_ID) vxbMemAlloc (sizeof (struct vxbDev));
isDynamic = TRUE;
}
/*设置CLASS */
(*pDev)->vxbClass = VXB_BUSID_NONE;
SLL_INIT(&(*pDev)->vxbList);
if (isDynamic)
{
/* 申请内存后置标志,释放是主要判断此标志 */
(*pDev)->vxbFlags = VXB_FLAG_DYNAMIC;
}
vxbSerial++;
(*pDev)->vxbSerial = vxbSerial;
return (OK);
}
LOCAL STATUS vxbDevProbe
(
VXB_DEV_ID pDev /* identifier of device to probe */
)
r = VXB_DEV_PROBE(pDev); //执行Probe函数
if (pCandidate != NULL &&
(((pDev->vxbFlags & VXB_FLAG_RESETTING) == 0) ||
((pDev->vxbFlags & VXB_FLAG_RESETTING) == VXB_FLAG_RESETTING &&
(pCandidate->vxbFlags & VXB_DRVFLAG_RESET) == VXB_DRVFLAG_RESET)))
{
/* req: VX7-13843 */
//匹配成功后,把驱动名称复制到设备名称
vxbDevNameSet (pDev, pCandidate->pVxbName, TRUE);
vxbDevUnitAssign (pDev);
pDev->vxbFlags |= VXB_FLAG_PROBED;
//把驱动设备赋值到VXB_DEV结构 pVxbDriver 内中
pDev->pVxbDriver = pCandidate;
if (_func_vxbParamTableCreateFunc != NULL)
(void) _func_vxbParamTableCreateFunc (pDev);
return (OK);
}
STATUS VXB_DEV_PROBE (VXB_DEV_ID pDev)
{
vxbDevProbe_t * func = (vxbDevProbe_t *) vxbDevMethodFind (pDev, VXB_DEVMETHOD_CALL(vxbDevProbe));
if (func == NULL)
return (STATUS)ERROR;
return func (pDev);
}
FUNCPTR vxbDevMethodFind
(
VXB_DEV_ID pDev, /* Device information */
VXB_METHOD_ID method /* Specified method */
)
{
VXB_DRV * pDriver;
VXB_DRV_METHOD * pMethod;
if (pDev == NULL)
{
return NULL; /* req: VX7-13833 */
}
pDriver = pDev->pVxbDriver;
if (pDriver == NULL)
{
return NULL; /* req: VX7-13833 */
}
/* req: VX7-13834 */
pMethod = pDriver->pVxbMethods;
//寻找具体方法
while (pMethod != NULL && pMethod->drvMethodId)
{
if (pMethod->drvMethodId == method)
{
return (pMethod->handler);
}
pMethod++;
}
/* req: VX7-13835 */
return NULL;
}
标签:分析,BUSID,VXBUS,DEV,VXB,源码,pDev,NULL,ID 来源: https://blog.csdn.net/u011996698/article/details/118582119