//*************************************************************************** // // Module Name: // // pciprobe.c // // Abstract: // // Probe PCI and get access range // // Environment: // // Kernel mode // // // Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved. // Copyright (c) 1995-1999 Microsoft Corporation. All Rights Reserved. // //*************************************************************************** #include "permedia.h" #if defined(ALLOC_PRAGMA) #pragma alloc_text(PAGE, Permedia2AssignResources) #pragma alloc_text(PAGE, Permedia2AssignResourcesNT4) #endif #define CreativeSubVendorID 0x1102 #define PiccasoSubVendorID 0x148C #define PiccasoSubSystemID 0x0100 #define SynergyA8SubVendorID 0x1048 #define SynergyA8SubSystemID 0x0A32 BOOLEAN Permedia2AssignResources( PVOID HwDeviceExtension, PVIDEO_PORT_CONFIG_INFO ConfigInfo, ULONG NumRegions, PVIDEO_ACCESS_RANGE AccessRange ) /*++ Routine Description: // // Look for a Permedia2 adapter and return the address regions for // that adapter. // --*/ { PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; PCI_COMMON_CONFIG PCIFunctionConfig; PPCI_COMMON_CONFIG PciData = &PCIFunctionConfig; BOOLEAN bRet; USHORT VendorID; USHORT DeviceID; VP_STATUS status; ULONG i; ULONG VgaStatus; // // assume we fail to catch all errors. // bRet = FALSE; #if DBG DEBUG_PRINT((2, "Permedia2AssignResources: read PCI config space (bus %d):-\n", (int)ConfigInfo->SystemIoBusNumber)); DumpPCIConfigSpace(HwDeviceExtension, ConfigInfo->SystemIoBusNumber, 0); #endif VideoPortGetBusData( HwDeviceExtension, PCIConfiguration, 0, PciData, 0, PCI_COMMON_HDR_LENGTH ); hwDeviceExtension->bDMAEnabled = PciData->Command & PCI_ENABLE_BUS_MASTER; if (!hwDeviceExtension->bDMAEnabled) { DEBUG_PRINT((1, "PERM2: enabling DMA for VGA card\n")); PciData->Command |= PCI_ENABLE_BUS_MASTER; VideoPortSetBusData( HwDeviceExtension, PCIConfiguration, 0, PciData, 0, PCI_COMMON_HDR_LENGTH ); } VendorID = PciData->VendorID; DeviceID = PciData->DeviceID; hwDeviceExtension->deviceInfo.VendorId = VendorID; hwDeviceExtension->deviceInfo.DeviceId = DeviceID; hwDeviceExtension->deviceInfo.RevisionId = PciData->RevisionID; hwDeviceExtension->deviceInfo.SubsystemVendorId = PciData->u.type0.SubVendorID; hwDeviceExtension->deviceInfo.SubsystemId = PciData->u.type0.SubSystemID; if( ( PciData->u.type0.SubVendorID == PiccasoSubVendorID ) && ( PciData->u.type0.SubSystemID == PiccasoSubSystemID ) ) { return(FALSE); } if( ( PciData->u.type0.SubVendorID == SynergyA8SubVendorID ) && ( PciData->u.type0.SubSystemID == SynergyA8SubSystemID ) ) { return(FALSE); } // // check if SubSystemID/SubVendorID bits are read only // if( PciData->u.type0.SubVendorID == CreativeSubVendorID ) { hwDeviceExtension->HardwiredSubSystemId = FALSE; } else { hwDeviceExtension->HardwiredSubSystemId = TRUE; } hwDeviceExtension->pciBus = ConfigInfo->SystemIoBusNumber; hwDeviceExtension->deviceInfo.DeltaRevId = 0; // // in multi-adapter systems we need to check if the VGA on this device // is active // VideoPortGetVgaStatus( HwDeviceExtension, &VgaStatus ); hwDeviceExtension->bVGAEnabled = (VgaStatus & DEVICE_VGA_ENABLED) ? TRUE : FALSE; if(!hwDeviceExtension->bVGAEnabled) { // // in a multi-adapter system we'll need to turn on the memory // space for the secondary adapters // DEBUG_PRINT((1, "PERM2: enabling memory space access for the secondary card\n")); PciData->Command |= PCI_ENABLE_MEMORY_SPACE; VideoPortSetBusData( HwDeviceExtension, PCIConfiguration, 0, PciData, 0, PCI_COMMON_HDR_LENGTH ); } hwDeviceExtension->PciSpeed = (PciData->Status & PCI_STATUS_66MHZ_CAPABLE) ? 66 : 33; DEBUG_PRINT((2, "VGAEnabled = %d. Pci Speed = %d\n", hwDeviceExtension->bVGAEnabled, hwDeviceExtension->PciSpeed)); VideoPortZeroMemory((PVOID)AccessRange, NumRegions * sizeof(VIDEO_ACCESS_RANGE)); // // these should be zero but just in case // ConfigInfo->BusInterruptLevel = 0; ConfigInfo->BusInterruptVector = 0; i = 0; status = VideoPortGetAccessRanges(HwDeviceExtension, 0, NULL, NumRegions, AccessRange, &VendorID, &DeviceID, &i); if (status == NO_ERROR) { DEBUG_PRINT((2, "VideoPortGetAccessRanges succeeded\n")); } else { DEBUG_PRINT((2, "VideoPortGetAccessRanges failed. error 0x%x\n", status)); goto ReturnValue; } // // get an updated copy of the config space // VideoPortGetBusData(HwDeviceExtension, PCIConfiguration, 0, PciData, 0, PCI_COMMON_HDR_LENGTH); #if DBG DEBUG_PRINT((2, "Final set of base addresses\n")); for (i = 0; i < NumRegions; ++i) { if (AccessRange[i].RangeLength == 0) break; DEBUG_PRINT((2, "%d: Addr 0x%x.0x%08x, Length 0x%08x, InIo %d, visible %d, share %d\n", i, AccessRange[i].RangeStart.HighPart, AccessRange[i].RangeStart.LowPart, AccessRange[i].RangeLength, AccessRange[i].RangeInIoSpace, AccessRange[i].RangeVisible, AccessRange[i].RangeShareable)); } #endif // // try to enable for DMA transfers // ConfigInfo->Master=1; bRet = TRUE; ReturnValue: return(bRet); } BOOLEAN Permedia2AssignResourcesNT4( PVOID HwDeviceExtension, PVIDEO_PORT_CONFIG_INFO ConfigInfo, ULONG NumRegions, PVIDEO_ACCESS_RANGE AccessRange ) /*++ Routine Description: // // Look for a Permedia2 adapter and return the address regions for // that adapter. // --*/ { PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; BOOLEAN bRet; USHORT VendorID, DeviceID; USHORT *pVenID, *pDevID; VP_STATUS status; ULONG i; USHORT VenID[] = { VENDOR_ID_3DLABS, VENDOR_ID_TI, 0 }; USHORT DevID[] = { PERMEDIA2_ID, PERMEDIA_P2_ID, PERMEDIA_P2S_ID, 0 }; if( hwDeviceExtension->NtVersion != NT4) { DEBUG_PRINT((0, "Permedia2AssignResourcesNT4: This function can only be called on NT 4\n")); return (FALSE); } else { bRet = FALSE; // // Since we do not support multi-mon on NT 4, we // assume this is the only video card in the system. // hwDeviceExtension->bVGAEnabled = 1; VideoPortZeroMemory((PVOID)AccessRange, NumRegions * sizeof(VIDEO_ACCESS_RANGE)); for( pVenID = &(VenID[0]); *pVenID != 0; pVenID++) { for( pDevID = &(DevID[0]); *pDevID != 0; pDevID++) { i = 0; status = VideoPortGetAccessRanges(HwDeviceExtension, 0, NULL, NumRegions, (PVIDEO_ACCESS_RANGE) AccessRange, pVenID, pDevID, &i); if (status == NO_ERROR) { DEBUG_PRINT((2, "VideoPortGetAccessRanges succeeded\n")); bRet = TRUE; return(bRet); } } } return(bRet); } }