pci.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 928 行 · 第 1/3 页
C
928 行
NewBridge.bParentFuncNo = pCurDevice->bFuncNo;
NewBridge.bBusNo = bSecondaryBusNo;
NewBridge.bDevNo = 0xFF;
if (FindNextPCIDevice( pPCIDevID, &NewBridge ))
return 1;
/* If the target was found behind this bridge, the PCI address record */
/* will now be filled out. */
if (NewBridge.bDevNo != 0xFF) {
*pCurDevice = NewBridge;
return 0;
}
}
}
/* Find the next PCI device on this segment */
if (ScanNextPCIDevice( pCurDevice )) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Call To ScanNextPCIDevice() Failed\n" );
return 1;
}
/* If there is another device on this segment, compare it to the target */
/* ID's and see if we've found it. */
if (pCurDevice->bDevNo != 0xFF) {
/* Determine whether or not this is a bridge */
OEM_ReadConfigByte( pCurDevice->bBusNo, pCurDevice->bDevNo, 0x00, 0x0E, &bHeaderType );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Configuration Header Type Read Failed\n" );
ClearPCIBridgeStatus( pCurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* Read the Vendor ID */
OEM_ReadConfigWord( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo, 0x00, &wVendorID );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
ClearPCIBridgeStatus( pCurDevice );
DbgPrintf( "FindNextPCIDevice() - ERROR: Vendor ID Read Failed\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* Read the Device ID */
OEM_ReadConfigWord( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo, 0x02, &wDeviceID );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
ClearPCIBridgeStatus( pCurDevice );
DbgPrintf( "FindNextPCIDevice() - ERROR: Device ID Read Failed\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* The header type determines where to get the Subsystem ID and Subsystem Vendor ID. */
/* Read the Subsystem Vendor ID */
OEM_ReadConfigWord( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo,
((bHeaderType & 0x7F) == 0x01) ? 0x34 : 0x2C, &wSubsystemVendorID );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
ClearPCIBridgeStatus( pCurDevice );
DbgPrintf( "FindNextPCIDevice() - ERROR: Subsystem Vendor ID Read Failed\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* Read the Subsystem ID */
OEM_ReadConfigWord( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo,
((bHeaderType & 0x7F) == 0x01) ? 0x36 : 0x2E, &wSubsystemID );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
ClearPCIBridgeStatus( pCurDevice );
DbgPrintf( "FindNextPCIDevice() - ERROR: Subsystem ID Read Failed\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* If it's the target device, then return the address. */
/* Note that the lower nibble of the Subsystem ID is the RIO */
/* revision number. */
if (pPCIDevID->wVendorID == 0 || wVendorID == pPCIDevID->wVendorID) {
if (pPCIDevID->wDeviceID == 0 || wDeviceID == pPCIDevID->wDeviceID) {
if (pPCIDevID->wSubsystemVendorID == 0 || wSubsystemVendorID == pPCIDevID->wSubsystemVendorID) {
if (pPCIDevID->wSubsystemID == 0 || wSubsystemID == pPCIDevID->wSubsystemID)
return 0;
}
}
}
}
}
while( pCurDevice->bDevNo != 0xFF );
return 0;
} /* FindNextPCIDevice() */
int FindNextPCIDevice( PCIDevIDRec *pPCIDevID, PCIDevAddrRec *pCurDevice ) {
WORD wVendorID, wDeviceID, wSubsystemVendorID, wSubsystemID;
WORD wPCIStatus;
BYTE bHeaderType, bSecondaryBusNo;
/* If the device to start at is a PCI-PCI bridge, I need to start the */
/* search at the first device behind it. */
if (pCurDevice->bDevNo != 0xFF) {
/* Determine whether or not this is a bridge */
OEM_ReadConfigByte( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo, 0x0E, &bHeaderType );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Configuration Header Type Read Failed\n" );
ClearPCIBridgeStatus( pCurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* If this is a PCI-PCI bridge we need to look behind it */
if ((bHeaderType & 0x7F) == 0x01) {
/* Read the secondary bus number. This will be the bus */
/* number that is searched next. */
OEM_ReadConfigByte( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo, 0x19, &bSecondaryBusNo );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Secondary Bus Number Read Failed\n" );
ClearPCIBridgeStatus( pCurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* Go look for the target device on the secondary side of the bridge */
pCurDevice->bParentBusNo = pCurDevice->bBusNo;
pCurDevice->bParentDevNo = pCurDevice->bDevNo;
pCurDevice->bParentFuncNo = pCurDevice->bFuncNo;
pCurDevice->bBusNo = bSecondaryBusNo;
pCurDevice->bDevNo = 0xFF;
}
}
do {
/* Find the next PCI device on this segment */
if (ScanNextPCIDevice( pCurDevice )) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Call To ScanNextPCIDevice() Failed\n" );
return 1;
}
/* If there is another device on this segment, compare it to the target */
/* ID's and see if we've found it. */
if (pCurDevice->bDevNo != 0xFF) {
/* Determine whether or not this is a bridge */
OEM_ReadConfigByte( pCurDevice->bBusNo, pCurDevice->bDevNo, 0x00, 0x0E, &bHeaderType );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Configuration Header Type Read Failed\n" );
ClearPCIBridgeStatus( pCurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* Read the Vendor ID */
OEM_ReadConfigWord( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo, 0x00, &wVendorID );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
ClearPCIBridgeStatus( pCurDevice );
DbgPrintf( "FindNextPCIDevice() - ERROR: Vendor ID Read Failed\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* Read the Device ID */
OEM_ReadConfigWord( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo, 0x02, &wDeviceID );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
ClearPCIBridgeStatus( pCurDevice );
DbgPrintf( "FindNextPCIDevice() - ERROR: Device ID Read Failed\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* The header type determines where to get the Subsystem ID and Subsystem Vendor ID. */
/* Read the Subsystem Vendor ID */
OEM_ReadConfigWord( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo,
((bHeaderType & 0x7F) == 0x01) ? 0x34 : 0x2C, &wSubsystemVendorID );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
ClearPCIBridgeStatus( pCurDevice );
DbgPrintf( "FindNextPCIDevice() - ERROR: Subsystem Vendor ID Read Failed\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* Read the Subsystem ID */
OEM_ReadConfigWord( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo,
((bHeaderType & 0x7F) == 0x01) ? 0x36 : 0x2E, &wSubsystemID );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
ClearPCIBridgeStatus( pCurDevice );
DbgPrintf( "FindNextPCIDevice() - ERROR: Subsystem ID Read Failed\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* If it's the target device, then return the address. */
/* Note that the lower nibble of the Subsystem ID is the RIO */
/* revision number. */
if (pPCIDevID->wVendorID == 0 || wVendorID == pPCIDevID->wVendorID) {
if (pPCIDevID->wDeviceID == 0 || wDeviceID == pPCIDevID->wDeviceID) {
if (pPCIDevID->wSubsystemVendorID == 0 || wSubsystemVendorID == pPCIDevID->wSubsystemVendorID) {
if (pPCIDevID->wSubsystemID == 0 || wSubsystemID == pPCIDevID->wSubsystemID)
return 0;
}
}
}
/* Determine whether or not this is a bridge */
OEM_ReadConfigByte( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo, 0x0E, &bHeaderType );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Configuration Header Type Read Failed\n" );
ClearPCIBridgeStatus( pCurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* If this is a PCI-PCI bridge we need to look behind it */
if ((bHeaderType & 0x7F) == 0x01) {
/* Read the secondary bus number. This will be the bus */
/* number that is searched next. */
OEM_ReadConfigByte( pCurDevice->bBusNo, pCurDevice->bDevNo, pCurDevice->bFuncNo, 0x19, &bSecondaryBusNo );
if ((wPCIStatus = GetPCIBridgeStatus( pCurDevice )) != 0) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Secondary Bus Number Read Failed\n" );
ClearPCIBridgeStatus( pCurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* Go look for the target device on the secondary side of the bridge */
pCurDevice->bParentBusNo = pCurDevice->bBusNo;
pCurDevice->bParentDevNo = pCurDevice->bDevNo;
pCurDevice->bParentFuncNo = pCurDevice->bFuncNo;
pCurDevice->bBusNo = bSecondaryBusNo;
pCurDevice->bDevNo = 0xFF;
}
}
/* If there are no more devices on this segment, try to go back up to the */
/* parent segment and continue the search. If we are already at the top */
/* level segment, then don't bother. */
else if (pCurDevice->bParentDevNo != 0xFF) {
/* Go look for the target device on the secondary side of the bridge */
pCurDevice->bBusNo = pCurDevice->bParentBusNo;
pCurDevice->bDevNo = pCurDevice->bParentDevNo;
pCurDevice->bFuncNo = pCurDevice->bParentFuncNo;
if (FindPCIParentDevice( pCurDevice )) {
DbgPrintf( "FindNextPCIDevice() - ERROR: Call To FindNextPCIDevice() Failed\n" );
return 1;
}
continue;
}
}
while( pCurDevice->bDevNo != 0xFF );
return 0;
} /* FindNextPCIDevice() */
/* This function takes a target device specified in terms of bus and device number and */
/* fills in the parent bus and parent device. It returns non-zero if an error occurs. */
int FindPCIParentDevice( PCIDevAddrRec *pTargetDevice ) {
PCIDevAddrRec CurDevice;
WORD wPCIStatus;
BYTE bHeaderType, bSecondaryBusNo, bSubordinateBusNo;
CurDevice.bParentBusNo = CurDevice.bParentDevNo = CurDevice.bBusNo = CurDevice.bDevNo = 0xFF;
do {
/* Find the next PCI device on this segment */
if (ScanNextPCIDevice( &CurDevice )) {
DbgPrintf( "FindPCIParentDevice() - ERROR: Call To ScanNextPCIDevice() Failed\n" );
return 1;
}
/* If we've found the target device, return it */
if (CurDevice.bBusNo == pTargetDevice->bBusNo && CurDevice.bDevNo == pTargetDevice->bDevNo
&& CurDevice.bFuncNo == pTargetDevice->bFuncNo) {
pTargetDevice->bParentBusNo = CurDevice.bParentBusNo;
pTargetDevice->bParentDevNo = CurDevice.bParentDevNo;
pTargetDevice->bParentFuncNo = CurDevice.bParentFuncNo;
return 0;
}
/* Determine whether or not this is a bridge */
OEM_ReadConfigByte( CurDevice.bBusNo, CurDevice.bDevNo, 0x00, 0x0E, &bHeaderType );
if ((wPCIStatus = GetPCIBridgeStatus( &CurDevice )) != 0) {
DbgPrintf( "FindPCIParentDevice() - ERROR: Configuration Header Type Read Failed\n" );
ClearPCIBridgeStatus( &CurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* If this is a PCI-PCI bridge we need to check to see if the target device is behind it */
if ((bHeaderType & 0x7F) == 0x01) {
/* Read the secondary bus number */
OEM_ReadConfigByte( CurDevice.bBusNo, CurDevice.bDevNo, CurDevice.bFuncNo, 0x19, &bSecondaryBusNo );
if ((wPCIStatus = GetPCIBridgeStatus( &CurDevice )) != 0) {
DbgPrintf( "FindPCIParentDevice() - ERROR: Secondary Bus Number Read Failed\n" );
ClearPCIBridgeStatus( &CurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* Read the subordinate bus number */
OEM_ReadConfigByte( CurDevice.bBusNo, CurDevice.bDevNo, CurDevice.bFuncNo, 0x1A, &bSubordinateBusNo );
if ((wPCIStatus = GetPCIBridgeStatus( &CurDevice )) != 0) {
DbgPrintf( "FindPCIParentDevice() - ERROR: Subordinate Bus Number Read Failed\n" );
ClearPCIBridgeStatus( &CurDevice );
PrintPCIError( wPCIStatus );
return 1;
}
/* If the bus number for the target device is within the range for this bridge, then the */
/* device is behind this bridge and we should look there. */
if (bSecondaryBusNo <= pTargetDevice->bBusNo && bSubordinateBusNo >= pTargetDevice->bBusNo) {
CurDevice.bParentBusNo = CurDevice.bBusNo;
CurDevice.bParentDevNo = CurDevice.bDevNo;
CurDevice.bBusNo = bSecondaryBusNo;
CurDevice.bDevNo = 0xFF;
continue;
}
}
}
while(CurDevice.bDevNo != 0xFF);
DbgPrintf( "FindPCIParentDevice() - ERROR: Failed To Find Target Device\n" );
return 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?