⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 driver wdk
💻 C
📖 第 1 页 / 共 4 页
字号:
#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 + -