You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
9.2 KiB
341 lines
9.2 KiB
//***************************************************************************
|
|
//
|
|
// 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);
|
|
}
|
|
}
|