📄 init.c
字号:
#if _WIN32_WINNT==0x0400
//++
// Function:
// Ave2kReleaseHardwareInfo
//
// Description:
// This function deallocates space used to
// hold hardware info gathered by the driver
//
// Arguments:
// Pointer to linked-list of Config arrays
//
// Return Value:
// (None)
//
//--
VOID
Ave2kReleaseHardwareInfo(
IN PDEVICE_CONFIG ConfigList
)
{
ASSERT(NULL != ConfigList);
ExFreePool(ConfigList);
}
//++
// Function:
// Ave2kReportHardwareUsage
//
// Description:
// This function allocates any hardware used
// by the driver
//
// Arguments:
// Pointer to the Driver object
// Pointer to linked-list of Config arrays,
// one for each bus-type/bus-number
// combination containing our hardware
//
// Return Value:
// This function returns STATUS_SUCCESS, or
// STATUS_INSUFFICIENT_RESOURCES.
//
//--
NTSTATUS
Ave2kReportHardwareUsage(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_CONFIG ConfigList
)
{
return STATUS_SUCCESS;
}
#endif
#if _WIN32_WINNT==0x0400
//++
// Function:
// Ave2kGetHardwareInfo
//
// Description:
// This function extracts auto-detected information
// about a device from the Registry.
//
// Arguments:
// Registry path of driver's service key
// Pointer to variable that receives address
// of list of Config Array blocks.
//
// Return Value:
// STATUS_SUCCESS
// STATUS_INSUFFICIENT_RESOURCES
// STATUS_NO_SUCH_DEVICE
//--
NTSTATUS
Ave2kGetHardwareInfo(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath,
OUT PDEVICE_CONFIG ConfigList
)
{
//Local Variables for finding devices
PPCI_COMMON_CONFIG pPciCfg;
PDEVICE_BLOCK pDevice;
ULONG BusDataLen;
ULONG BusNumber;
ULONG SlotNumber;
//Local variables for HalAssignSlotResources
ULONG DeviceNo;
PCM_RESOURCE_LIST pAllocatedResourceList;
PCM_PARTIAL_RESOURCE_LIST pParticalResourceList;
ULONG ParticalResourceIndex;
NTSTATUS Status;
//PCI configuration's base address
ULONG BaseAddrIndex;
ULONG BaseAddr;
ULONG SubVendorID;
ULONG SubSystemID;
ULONG bSkip;
//For HalTranslateBusAddress
ConfigList->Count =0;
RtlWriteRegistryValue(
RTL_REGISTRY_SERVICES,
L"ave2k\\",
L"TotalCard",
REG_DWORD,
&(ConfigList->Count),
4);
RtlWriteRegistryValue(
RTL_REGISTRY_SERVICES,
L"ave2k\\Enum",
L"Count",
REG_DWORD,
&(ConfigList->Count),
4);
pPciCfg=(PPCI_COMMON_CONFIG)ExAllocatePool(PagedPool,sizeof(PCI_COMMON_CONFIG));
ASSERT(pPciCfg!=NULL);
for(BusNumber=0; BusNumber < 32;BusNumber ++){
for(SlotNumber=0;SlotNumber < 32; SlotNumber ++){
BusDataLen=HalGetBusData(
PCIConfiguration,
BusNumber,
SlotNumber,
pPciCfg,
sizeof(*pPciCfg));
if(BusDataLen == 0) /*The specified PCI bus does not exist*/
goto Ave2kGetHardwareInfo_Found;
if(BusDataLen !=2 && pPciCfg->BaseClass==0x3 && //If it's display adapter
(pPciCfg->Command&PCI_ENABLE_MEMORY_SPACE)){ //and it's enabled
for(BaseAddrIndex=0; BaseAddrIndex < PCI_TYPE0_ADDRESSES; BaseAddrIndex ++){
BaseAddr = pPciCfg->u.type0.BaseAddresses[BaseAddrIndex];
if(BaseAddr != 0 && (BaseAddr&0x7) ==0 ){
VGAAddress= BaseAddr&0xfffffff0;
KdPrint(("Display card base address:%x\n",BaseAddr&0xfffffff0));
break;
}
}
continue;
}
if(BusDataLen != 2 &&
SAA7146A_PCI_DEVICEID == pPciCfg->DeviceID &&
SAA7146A_PCI_VENDORID == pPciCfg->VendorID){ /*SAA7146A is found*/
pDevice = &(ConfigList->Device[ConfigList->Count]);
pDevice -> BusNumber = BusNumber;
pDevice -> SlotNumber = SlotNumber;
SubVendorID = pPciCfg->u.type0.SubVendorID;
SubSystemID = pPciCfg->u.type0.SubSystemID;
bSkip=0;
//if(0xffff == SubVendorID)
// pDevice -> BoardVersion = REVA0;
if(SUBVENDOR_THAKRAL == SubVendorID){
switch(SubSystemID){
#if(TARGET_DEVICE==TD_AVE2K || TARGET_DEVICE==TD_TEST)
case SUBSYS_AVE2KREVA1:
pDevice -> BoardVersion = REVA1;
break;
case SUBSYS_AVE2KREVA2:
#endif
#if(TARGET_DEVICE==TD_AVEIII || TARGET_DEVICE==TD_TEST)
case SUBSYS_AVE2KREVA21:
#endif
pDevice -> BoardVersion = REVA2;
break;
#if(TARGET_DEVICE==TD_AVE2K || TARGET_DEVICE==TD_TEST)
case SUBSYS_AVE2KDREVB2:
pDevice -> BoardVersion = REVB2;
break;
case SUBSYS_AVE2KMREVC2:
pDevice -> BoardVersion = REVC2;
break;
case SUBSYS_AVE2KREVD1Q:
case SUBSYS_AVE2KREVD1D:
case SUBSYS_AVE2KREVD1S:
pDevice -> BoardVersion = REVD1;
break;
#endif
default:
#if(TARGET_DEVICE==TD_TEST)
pDevice -> BoardVersion = REVA2;
#else
bSkip=1;
#endif
}
}
else
#if(TARGET_DEVICE==TD_TEST)
pDevice -> BoardVersion = REVA2;
#else
bSkip=1;
#endif
if(!bSkip)
ConfigList->Count++;
#if(TARGET_DEVICE==TD_AVEIII)
if(ConfigList->Count == 4)//AVEIII only allow 1 device
#else
if(ConfigList->Count == AVE2K_MAXIMUM_DEVICES) //Reach maximum number of devices
#endif
goto Ave2kGetHardwareInfo_Found;
}
}
}
Ave2kGetHardwareInfo_Found:
ExFreePool(pPciCfg);
RtlWriteRegistryValue(
RTL_REGISTRY_SERVICES,
L"ave2k\\",
L"TotalCard",
REG_DWORD,
&(ConfigList->Count),
4);
RtlWriteRegistryValue(
RTL_REGISTRY_SERVICES,
L"ave2k\\Enum",
L"Count",
REG_DWORD,
&(ConfigList->Count),
4);
if(0 == ConfigList->Count){
KdPrint(("No card is found!\n"));
return STATUS_NO_SUCH_DEVICE;
}
//Allocate resource for devices
for(DeviceNo =0; DeviceNo< ConfigList->Count; DeviceNo ++){
pDevice = &(ConfigList->Device[DeviceNo]);
Status =HalAssignSlotResources(
RegistryPath,
NULL, /*IN PUNICODE_STRING DriverClassName, optional */
DriverObject,
NULL, /*IN PDEVICE_OBJECT DeviceObject, optional */
PCIBus, /*IN INTERFACE_TYPE BusType*/
pDevice -> BusNumber,
pDevice -> SlotNumber,
&pAllocatedResourceList
);
if(NT_SUCCESS(Status)){
pParticalResourceList=&((*pAllocatedResourceList).List[0].PartialResourceList);
for(ParticalResourceIndex=0;ParticalResourceIndex < pParticalResourceList->Count;
ParticalResourceIndex++){
if(CmResourceTypeInterrupt == pParticalResourceList -> PartialDescriptors[ParticalResourceIndex].Type){
pDevice -> Level = pParticalResourceList ->
PartialDescriptors[ParticalResourceIndex].u.Interrupt.Level;
pDevice -> Affinity = pParticalResourceList ->
PartialDescriptors[ParticalResourceIndex].u.Interrupt.Affinity;
pDevice -> OriginalVector = pParticalResourceList ->
PartialDescriptors[ParticalResourceIndex].u.Interrupt.Vector;
//Get interrupt mode
if( CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE == pParticalResourceList ->
PartialDescriptors[ParticalResourceIndex].Flags)
pDevice ->InterruptMode = LevelSensitive;
else
pDevice -> InterruptMode = Latched;
//HalGetInterruptVector
pDevice-> SystemVector =
HalGetInterruptVector(
PCIBus,
pDevice -> BusNumber,
pDevice -> Level,
pDevice -> OriginalVector,
&pDevice->Dirql,
&pDevice->Affinity);
}
else if(CmResourceTypeMemory == pParticalResourceList -> PartialDescriptors[ParticalResourceIndex].Type){
pDevice -> OriginalPortBase = pParticalResourceList ->
PartialDescriptors[ParticalResourceIndex].u.Memory.Start;
pDevice -> PortSpan = pParticalResourceList ->
PartialDescriptors[ParticalResourceIndex].u.Memory.Length;
//Map the SAA7146A's register to virtual address
pDevice -> PortBase =
MmMapIoSpace(
pDevice -> OriginalPortBase,
pDevice -> PortSpan,
FALSE //IN BOOLEAN CacheEnable
);
}
}
ExFreePool(pAllocatedResourceList);
}
}
return STATUS_SUCCESS;
}
#else
//++
// Function:
// Ave2kGetVGAHardwareInfo
//
// Description:
// This function find device's Board Version and VGA Address
//
// Arguments:
//
// Return Value:
// STATUS_SUCCESS
// STATUS_INSUFFICIENT_RESOURCES
// STATUS_NO_SUCH_DEVICE
//--
NTSTATUS
Ave2kGetVGAHardwareInfo()
{
//Local Variables for finding devices
PPCI_COMMON_CONFIG pPciCfg;
ULONG BusDataLen;
ULONG BusNumber;
ULONG SlotNumber;
//PCI configuration's base address
ULONG BaseAddrIndex;
ULONG BaseAddr;
ULONG SubVendorID;
ULONG SubSystemID;
ULONG Count=0;
//For HalTranslateBusAddress
pPciCfg=(PPCI_COMMON_CONFIG)ExAllocatePool(PagedPool,sizeof(PCI_COMMON_CONFIG));
if(pPciCfg==NULL)
{
DebugPrintMsg("pPciCfg:No paged pool left!");
return STATUS_INSUFFICIENT_RESOURCES;
}
for(BusNumber=0; BusNumber < 4;BusNumber ++){
for(SlotNumber=0;SlotNumber < 32; SlotNumber ++){
BusDataLen=HalGetBusData(
PCIConfiguration,
BusNumber,
SlotNumber,
pPciCfg,
sizeof(*pPciCfg));
if(BusDataLen == 0) //The specified PCI bus does not exist
{
DebugPrintMsg("No PCI Bus");
goto Ave2kGetHardwareInfo_Found;
}
if(BusDataLen !=2 && pPciCfg->BaseClass==0x3 && //If it's display adapter
(pPciCfg->Command&PCI_ENABLE_MEMORY_SPACE)){ //and it's enabled
for(BaseAddrIndex=0; BaseAddrIndex < PCI_TYPE0_ADDRESSES; BaseAddrIndex ++){
BaseAddr = pPciCfg->u.type0.BaseAddresses[BaseAddrIndex];
if(BaseAddr != 0 && (BaseAddr&0x7) ==0 ){
VGAAddress= BaseAddr&0xfffffff0;
DebugPrint("Display card base address:%x\n",BaseAddr&0xfffffff0);
goto Ave2kGetHardwareInfo_Found;
}
}
}
}
}
Ave2kGetHardwareInfo_Found:
ExFreePool(pPciCfg);
return STATUS_SUCCESS;
}
#endif
//++
// Function:
// Ave2kIsr
//
// Description:
// This function processes interrupts from
// the SAA7146
//
// Arguments:
// Pointer to the Interrupt object
// Pointer to the Device Extension
//
// Return Value:
// TRUE if we handled the interrupt
//--
BOOLEAN
Ave2kIsr(
IN PKINTERRUPT Interrupt,
IN PVOID ServiceContext
)
{
ULONG CurDMAAddress;
PDEVICE_EXTENSION pDE = (PDEVICE_EXTENSION)ServiceContext;
PDEVICE_OBJECT pDevice = pDE->DeviceObject;
//Write ISR to clean the event
ULONG ISRValue = Ave2kReadRegister(pDE, ISR);
Ave2kWriteRegister(pDE, ISR, ISRValue);
if(0xffffffff == ISRValue){
return TRUE;
}
if(0 == ISRValue) //Not by this board
return FALSE;
if(0 != (ISRValue&0x2010)){ //Is not DSP 2 interrupt
if(FALSE == pDE->DataReceiving[1])
pDE->DataReceiving[1]=TRUE;
KeInsertQueueDpc(
&pDE->AlternateDpc,
NULL,
NULL
);
}
if(0 != (ISRValue&0x8008)){ //Is not DSP 1 interrupt
//SyncAudioWrite(pDE);
if(FALSE == pDE->DataReceiving[0])
pDE->DataReceiving[0]=TRUE;
IoRequestDpc(pDevice,
pDevice->CurrentIrp,
NULL
);
}
if(0 != (ISRValue&MASK_28)){
pDE->bBitmapOK=TRUE;
IoRequestDpc(pDevice,
pDevice->CurrentIrp,
NULL
);
//KeSetEvent(&pDE->EventVDone,(KPRIORITY)0, FALSE);
}
return TRUE;
}
//++
// Function:
// Ave2kDpcForIsr
//
// Description:
// This function performs the low-IRQL
// post-processing of I/O requests
//
// Arguments:
// Pointer to a DPC object
// Pointer to the Device object
// Pointer to the IRP for this request
// Pointer to the Device Extension
//
// Return Value:
// (None)
//--
VOID
Ave2kDpcForIsr(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
)
{
PIO_STACK_LOCATION IrpStack;
PDEVICE_OBJECT DeviceObject = DeferredContext;
PDEVICE_EXTENSION pDE = DeviceObject->DeviceExtension;
PIRP Irp = DeviceObject->CurrentIrp;
KIRQL OldIrql;
ULONG BufLen;
ULONG FbBuffer;
signed char cAudio;
int i;
FbBuffer=Ave2kReadRegister(pDE, FEEDBACKBUF1);
for(i=0; i<4; i++){
cAudio=(signed char)(FbBuffer&0xff);
if(cAudio<0)
cAudio=~cAudio;//use inverse instead of neg to trans FF to 0
if(cAudio>pDE->nMaxAudio)
pDE->nMaxAudio=cAudio;
FbBuffer>>=8;
}
if(pDE->bBitmapOK){
KeSetEvent(&pDE->EventVDone,(KPRIORITY)0, FALSE);
pDE->bBitmapOK=FALSE;
}
KeAcquireSpinLock(&pDE->ReadLock, &OldIrql);
/* KeSynchronizeExecution(
pDE->pInterrupt,
SyncAudioWrite,
(PVOID)pDE);*/
SyncAudioWrite((PVOID)pDE);
KeReleaseSpinLock(&pDE->ReadLock,OldIrql);
if(Irp == NULL)
return ;
IoAcquireCancelSpinLock( &OldIrql );
//
// Check the state of the Cancel flag. If
// it's set, release the spin lock and return
// immediately. The IRP has already been
// processed by the Cancel routine.
//
if( Irp->Cancel )
{
IoReleaseCancelSpinLock( OldIrql );
return;
}
IoReleaseCancelSpinLock( OldIrql );
KeAcquireSpinLock(&pDE->ReadLock, &OldIrql);
if(pDE->ReadIrpDataBuffer==NULL){
KeReleaseSpinLock(&pDE->ReadLock,OldIrql);
return;
}
Irp = DeviceObject->CurrentIrp;
ASSERT(Irp!=NULL);
IrpStack =IoGetCurrentIrpStackLocation( Irp );
ASSERT(IrpStack!=NULL);
//if(KeSynchronizeExecution(
// pDE->pInterrupt,
// SyncAudioRead,
// (PVOID)pDE))
BufLen=IrpStack->Parameters.Read.Length;
if(AudioDespListRead(pDE, BufLen, 0))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = IrpStack->Parameters.Read.Length; /*sizeof(AUDIOSTREAMSECTOR)*/;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
pDE->ReadIrpDataBuffer=NULL;
IoStartNextPacket(DeviceObject,TRUE);
}
KeReleaseSpinLock(&pDE->ReadLock,OldIrql);
OldIrql=KeGetCurrentIrql();
ErrorRecover(pDE, 0);
}
BOOLEAN InitializeData(PDEVICE_EXTENSION pDE)
{
//
// Prepare a DPC object for later use
//
IoInitializeDpcRequest(
pDE->DeviceObject,
Ave2kDpcForIsr );
//Do necessary initialization for DMA
{
DEVICE_DESCRIPTION DeviceDescription;
ULONG NumberOfMapRegisters=0;
RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION1;
DeviceDescription.Master=TRUE;
DeviceDescription.ScatterGather=FALSE;
DeviceDescription.Dma32BitAddresses=TRUE;
#ifdef WIN_NT
DeviceDescription.BusNumber=TRUE;
#endif
DeviceDescription.DmaWidth=Width32Bits; // 8-bit, 16-bit, etc.
DeviceDescription.DmaSpeed=Compatible;
DeviceDescription.InterfaceType=PCIBus;
#ifdef WIN_2K
DeviceDescription.Reserved1= FALSE;
#endif
#ifdef WIN_NT
pDE->pAdapter = HalGetAdapter(
&DeviceDescription,
&NumberOfMapRegisters
);
ASSERT(pDE->pAdapter != NULL);
#else
pDE->pAdapter =IoGetDmaAdapter(pDE->PDO,
&DeviceDescription,
&NumberOfMapRegisters
);
if(pDE->pAdapter != NULL)
{
DebugPrint("Get Dma Adapter:%d mparegister",NumberOfMapRegisters);
}
else
{
DebugPrintMsg("error to get dma adapter!");
return FALSE;
}
#endif
}
//DMA buffer init
if(pDE->Compress){
//Allocate common buffer for DMA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -