重要的两个数据结构分别是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; }