/***********************************************
PCI设备查找程序
vendorId:设备厂商号;
deviceId:设备号;
index:索引号;
*pBusNo:返回的总线号;
*pDeviceNo;返回的设备号;
*pFuncNo:返回的功能号;
************************************************/
STATUS pciFindDevice
(
int vendorId, /* vendor ID */
int deviceId, /* device ID */
int index, /* desired instance of device */
int * pBusNo, /* bus number */
int * pDeviceNo, /* device number */
int * pFuncNo /* function number */
)
{
STATUS status = ERROR;/*初始化状态为error*/
BOOL cont = TRUE;/*定义cont为TRUE*/
int busNo;
int deviceNo;
int funcNo;
UINT32 device;
UINT32 vendor;
UINT8 header;
if (pciLibInitStatus != OK) /* sanity check 检查初始化状态*/
cont = FALSE;
for (busNo = 0; cont == TRUE && busNo <= pciMaxBus; busNo++)/*查找总线号*/
for (deviceNo = 0;
((cont == TRUE) && (deviceNo < PCI_MAX_DEV));
++deviceNo) /*查找设备号*/
for (funcNo = 0; cont == TRUE && funcNo < PCI_MAX_FUNC; funcNo++)/*查找功能号*/
{
/* avoid a special bus cycle 避免一个特殊的总线循环*/
if ((deviceNo == 0x1f) && (funcNo == 0x07))
continue;/*结束当前循环开始下一个循环*/
pciConfigInLong (busNo, deviceNo, funcNo, PCI_CFG_VENDOR_ID,
&vendor);
/*
* If nonexistent device, skip to next, only look at
* vendor ID field for existence check
*/
if (((vendor & 0x0000ffff) == 0x0000FFFF) && (funcNo == 0))
break;
device = vendor >> 16;/*右移16位得到设备名*/
device &= 0x0000FFFF;
vendor &= 0x0000FFFF;/*厂商名等于低16位*/
if ((vendor == (UINT32)vendorId) &&
(device == (UINT32)deviceId) &&
(index-- == 0))
{
*pBusNo = busNo;
*pDeviceNo = deviceNo;
*pFuncNo = funcNo;
status = OK;
cont = FALSE; /* terminate all loops */
continue;
}
/* goto next if current device is single function */
pciConfigInByte (busNo, deviceNo, funcNo, PCI_CFG_HEADER_TYPE,
&header);
if ((header & PCI_HEADER_MULTI_FUNC) != PCI_HEADER_MULTI_FUNC &&
funcNo == 0)
break;
}
return (status);
}
/*************************************************
PCI读取函数
busNo:总线号;
deviceNo:设备号;
funcNo:功能号;
offset:偏移量;
*pData:返回的数据;
**************************************************/
STATUS pciConfigInLong
(
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT32 * pData /* data read from the offset */
)
{
int key;
STATUS retStat = ERROR;
UINT32 retval = 0;
/* check for library initialization or unaligned access */
#ifdef PCI_CONFIG_OFFSET_NOCHECK
if (pciLibInitStatus != OK)
{
return (retStat);
}
#else
if ((pciLibInitStatus != OK) || ((offset & (int)0x3) > 0) )
{
return (retStat);
}
#endif
key = intLock (); /* mutual exclusion start 屏蔽中断互斥开始*/
switch (pciConfigMech)
{
case PCI_MECHANISM_0:
if (pciConfigRead (busNo, deviceNo, funcNo, offset, 4,
(void *)&retval) == ERROR)
{
retval = 0xffffffff;
}
else
{
retStat = OK;
}
break;
case PCI_MECHANISM_1:
PCI_OUT_LONG (pciConfigAddr0,
pciConfigBdfPack (busNo, deviceNo, funcNo) |
(offset & 0xfc) | 0x80000000);
retval = PCI_IN_LONG (pciConfigAddr1);
retStat = OK;
break;
case PCI_MECHANISM_2:
PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1));
PCI_OUT_BYTE (pciConfigAddr1, busNo);
retval = PCI_IN_LONG (pciConfigAddr2 | ((deviceNo & 0x000f) << 8) |
(offset & 0xfc));
PCI_OUT_BYTE (pciConfigAddr0, 0);
retStat = OK;
break;
default:
break;
}
intUnlock (key); /* mutual exclusion stop 解除中断锁*/
*pData = retval;
return (retStat);
}