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 + -
显示快捷键?