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

📄 pnp.cpp

📁 vc开发的PCI总线加密卡 PCI开发卡主要由PCI9054、93C56、16M晶振和相应的跳线、控制地址数据线等部分组成。PCI9054是PLX公司的PCI主模式桥芯片
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 *
 * Function   :  HandleStartDevice
 *
 * Description:  Handle the IRP_MN_START_DEVICE PnP request
 *
 ******************************************************************************/
NTSTATUS PnpStartDevice(IN PDEVICE_OBJECT fdo,
						   IN PIRP pIrp )
{												//HandleStartDevice
    NTSTATUS           status;
    PIO_STACK_LOCATION stack;

    
    //First let all lower-level drivers handle this request. In this
    //particular sample, the only lower-level driver should be the physical
    //device created by the bus driver, but there could theoretically be any
	//number of intervening bus filter devices. Those drivers may need to do
	//some setup at this point in time before they'll be ready to handle
	//non-PnP IRP's.

	pIrp->IoStatus.Status = STATUS_SUCCESS;
    status = ForwardAndWait(fdo,pIrp);			//Send IRP to lower driver and wait for finishing 
    if (!NT_SUCCESS(status))
    {
        return CompleteRequest(pIrp, status);
    }

    stack = IoGetCurrentIrpStackLocation(pIrp);

    // Assign resources to the devices
    status = StartDevice(fdo,
                 &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList,
                 &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList);

    return CompleteRequestInfo(pIrp,status,0);
}													//HandleStartDevice
/******************************************************************************
 *
 * Function   :  StartDevice
 *
 * Description:  Start a device
 *
 ******************************************************************************/
NTSTATUS StartDevice(IN PDEVICE_OBJECT fdo,
					 IN PCM_PARTIAL_RESOURCE_LIST ResourceListRaw,
					 IN PCM_PARTIAL_RESOURCE_LIST ResourceList)
{													//StartDevice
    ULONG							i;
    ULONG							vector;
    KIRQL							IrqL;
    BOOLEAN							GotInterrupt;
	BOOLEAN							GotPdcMem;
	BOOLEAN							GotBaseMem;
    NTSTATUS						status;
    KAFFINITY						affinity;
	BOOLEAN							irqshare;
    KINTERRUPT_MODE					mode;
    PDEVICE_EXTENSION				pdx;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR	ResourceRaw;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR	Resource;


    pdx         = (PDEVICE_EXTENSION)fdo->DeviceExtension;

	if (pdx->GotResource)
		return STATUS_SUCCESS;

    GotInterrupt= FALSE;
	GotPdcMem	= FALSE;
	GotBaseMem	= FALSE;
    ResourceRaw = ResourceListRaw->PartialDescriptors;
    Resource    = ResourceList->PartialDescriptors;

	KdPrint((DBG_NAME "Start Device Start.\n"));

    for (i = 0; i < ResourceListRaw->Count; ++i, ++Resource, ++ResourceRaw)
    {
        switch (ResourceRaw->Type)
        {
		case CmResourceTypeInterrupt://中断资源
            GotInterrupt = TRUE;
            IrqL       = (KIRQL) Resource->u.Interrupt.Level;
            vector     = Resource->u.Interrupt.Vector;
            affinity   = Resource->u.Interrupt.Affinity;

            if (ResourceRaw->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
            {
                mode = Latched;
            }
            else
            {
                mode = LevelSensitive;
            }
			irqshare = Resource->ShareDisposition == CmResourceShareShared;

			KdPrint((DBG_NAME "ResouceType: Interrupt:Vector:0x%x(Translated=0x%x)\n",
                     ResourceRaw->u.Interrupt.Vector, vector));
			KdPrint((DBG_NAME "                       IRQL:0x%x(Translated=0x%x)Affinity:0x%x(Translated=0x%x)\n",
						ResourceRaw->u.Interrupt.Level, IrqL,
						ResourceRaw->u.Interrupt.Affinity, affinity));
            break;

        case CmResourceTypePort:
			//PCI9052内部的寄存器占用一个IO资源和Mem资源,可以不用IO资源
			KdPrint((DBG_NAME "Port is reqired."));
			KdPrint((DBG_NAME "ResoureType: I/O Port:Address:0x%x(Translated=0x%x);Size:0x%x.\n",
                     ResourceRaw->u.Port.Start.LowPart,
                     Resource->u.Port.Start.LowPart,
                     ResourceRaw->u.Port.Length));
            break;

        case CmResourceTypeMemory:
			KdPrint((DBG_NAME "ResoureType: Memory Space:Address:0x%x(Translated=0x%x);Size: 0x%x.\n",
                     ResourceRaw->u.Memory.Start.LowPart,
                     Resource->u.Memory.Start.LowPart,
                     ResourceRaw->u.Memory.Length));
			//其实在对Mem资源进行读取时,按照PCI BAR0-5进行的,可以根据数量来判断各个BAR.
			if (ResourceRaw->u.Memory.Length == 0x100)
			{		//PCI Bar 0
				pdx->LocalRegisterPhysicalMemBase = ResourceRaw->u.Memory.Start;
				pdx->LocalRegisterMemCount = ResourceRaw->u.Memory.Length;
				pdx->LocalRegisterMemBase = (ULONG *)MmMapIoSpace(pdx->LocalRegisterPhysicalMemBase,
													pdx->LocalRegisterMemCount,MmNonCached);
				KdPrint((DBG_NAME "The MEM Base 0 is %x; Count is %x.\n",pdx->LocalRegisterMemBase, pdx->LocalRegisterMemCount));
				if (pdx->LocalRegisterMemBase == NULL)
				{
					// PCI BAR 0 is required for register access
					KdPrint((DBG_NAME "PDC4000: ERROR - BAR 0 mapping is required\n"));
					return STATUS_INSUFFICIENT_RESOURCES;
				}
				GotBaseMem = TRUE;
			}		//PCI Bar 0
			else
			{		//PCI Bar 2
				pdx->PdcPhysicalMemBase0 = ResourceRaw->u.Memory.Start;
				pdx->PdcMemCount0 = ResourceRaw->u.Memory.Length;
				pdx->PdcMemBase0 = (ULONG *)MmMapIoSpace(pdx->PdcPhysicalMemBase0,
												pdx->PdcMemCount0, MmNonCached);
				KdPrint((DBG_NAME "The MEM Base SJA1000 is %x;Count is %x.\n", pdx->PdcMemBase0, pdx->PdcMemCount0));
				if (pdx->PdcMemBase0 == NULL)
				{
					KdPrint((DBG_NAME "ERROR - Unable to map SJA1000.\n"));
					return STATUS_INSUFFICIENT_RESOURCES;
				}
				GotPdcMem = TRUE;
			}			//PCI Bar 2
			break;
		//其他资源一般没有,可默认处理
			case CmResourceTypeNull:
			KdPrint((DBG_NAME "Type: Null (unsupported)\n"));
			break;
		case CmResourceTypeDma:
			KdPrint((DBG_NAME "Type: DMA (unsupported)\n"));
			break;
		case CmResourceTypeDeviceSpecific:
			KdPrint((DBG_NAME "Type: Device Specific (unsupported)"));
			break;
		case CmResourceTypeBusNumber:
			KdPrint((DBG_NAME "Type: Bus Number (unsupported)\n"));
			break;
		// NonArbitrated & ConfigData are currently #defined as the same number
		case CmResourceTypeConfigData:
			KdPrint((DBG_NAME "Type: Non-Arbitrated or Config Data (unsupported)\n"));
			break;
		case CmResourceTypeDevicePrivate:
			KdPrint((DBG_NAME "Type: Device Private Data (unsupported)\n"));
			break;
		case CmResourceTypePcCardConfig:
			KdPrint((DBG_NAME "Type: PC Card Configuration (unsupported)\n"));
			break;
		case CmResourceTypeMfCardConfig:
			KdPrint((DBG_NAME "Type: Multi-function Card Configuration (unsupported)\n"));
			break;
		default:
			KdPrint((DBG_NAME "Type: ?Unknown Resource Type?\n"));
			break;
        }
    }

    // Make sure BAR 0 exists or the device can't be started
	if (!GotBaseMem)
	{
		KdPrint((DBG_NAME "PDC4000: ERROR - BAR 0 address not configured, unable to load driver."));
		return STATUS_INSUFFICIENT_RESOURCES;	
	}
	if (!GotPdcMem)
	{
		if(pdx->LocalRegisterMemBase)
		{
			MmUnmapIoSpace(pdx->LocalRegisterMemBase, pdx->LocalRegisterMemCount);		//Free Base Memory.
			KdPrint((DBG_NAME "PDC4000: ERROR - CanMemBase.\n"));
		}
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	//连接中断
    if (GotInterrupt)
    {
		KdPrint((DBG_NAME "Get Interrupt.\n"));
        // 首先Disable the PCI interrupt
		DisablePciInterrupt(pdx);
		//连接中断
		status = IoConnectInterrupt(&pdx->pInterruptObject,(PKSERVICE_ROUTINE)OnInterrupt,
						(PVOID)pdx,NULL,vector,IrqL,IrqL,mode,irqshare,affinity,FALSE);	//(PVOID)
		KdPrint((DBG_NAME "OK, I haved Connect Interruput!\n"));
		if (!NT_SUCCESS(status))
		{
			pdx->pInterruptObject = NULL;
			return status;
		}
		else
        {	// Re-enable the PCI Interrupt
			KdPrint((DBG_NAME "OK, Let's enable interrupt.\n"));
			if (pdx->pInterruptObject == NULL)
			{
				KdPrint((DBG_NAME "Interrupt object is NULL.\n"));
			}
			//同步Enable interrupt.
			KeSynchronizeExecution(pdx->pInterruptObject,(PKSYNCHRONIZE_ROUTINE)EnablePciInterrupt,pdx);
			KdPrint((DBG_NAME "Have Enabled Interrupt.\n"));
		}
    }
    else
    {
        KdPrint((DBG_NAME "No interrupt found.\n"));
		//Free haved mapped memories.
		MmUnmapIoSpace(pdx->LocalRegisterMemBase, pdx->LocalRegisterMemCount);
		MmUnmapIoSpace(pdx->PdcMemBase0, pdx->PdcMemCount0);
        pdx->pInterruptObject = NULL;
    }

	//Set DMA
	DEVICE_DESCRIPTION dd;
	RtlZeroMemory(&dd, sizeof(dd));
	dd.Version				= DEVICE_DESCRIPTION_VERSION;
	dd.Master				= TRUE;
	dd.InterfaceType		= InterfaceTypeUndefined;
	dd.MaximumLength		= MAX_DMA_LENGTH;
	dd.Dma32BitAddresses	= TRUE;
	dd.Dma64BitAddresses	= FALSE;
	dd.ScatterGather		= TRUE;

	pdx->DmaInfo[0].pDmaAdapterObject = IoGetDmaAdapter(pdx->pPhysicalDeviceObject, 
													&dd,	
													&pdx->DmaInfo[0].lNumberOfMapRegisters);
	if (pdx->DmaInfo[0].pDmaAdapterObject == NULL)
	{
		KdPrint((DBG_NAME "Fatal Error: DmaAdapterObject is NULL!!!!!!\n"));
	}
	pdx->DmaInfo[0].lCommonBufferSize = COMMON_BUFFER_SIZE;	//the length of the common buffer.
	pdx->DmaInfo[0].vaCommonBuffer =
		(*pdx->DmaInfo[0].pDmaAdapterObject->DmaOperations->AllocateCommonBuffer)
			(pdx->DmaInfo[0].pDmaAdapterObject,		//AdapterObject
			pdx->DmaInfo[0].lCommonBufferSize,	//Size
			&pdx->DmaInfo[0].paCommonBuffer,	//LogicalAddress
			FALSE);		//CacheEnabled

	if (pdx->DmaInfo[0].vaCommonBuffer == NULL)
	{
		KdPrint((DBG_NAME "Don't Allocate the Common Buffer.\n"));
	}
	KdPrint((DBG_NAME "Have Allocate the Common Buffer.\n"));
	//Use the common buffer as the SGL Descriptor buffer.
	pdx->DmaInfo[0].pSGE = (PPCI9054_SCATTER_GATHER_ELEMENT)(pdx->DmaInfo[0].vaCommonBuffer);
	pdx->DmaInfo[0].lMapRegisterCount = SGE_MAX_COUNT;
	
	pdx->GotResource = TRUE;

	KdPrint((DBG_NAME "Start Device end.\n"));
    return STATUS_SUCCESS;
}												//StartDevice

/******************************************************************************
 *
 * Function   :  HandleStopDevice
 *
 * Description:  Handle the IRP_MN_STOP_DEVICE PnP request
 *
 ******************************************************************************/
NTSTATUS PnpStopDevice(IN PDEVICE_OBJECT fdo,
					   IN PIRP pIrp)
{	

    StopDevice(fdo);
	
	return DefaultPnpHandler(fdo,pIrp);
}												//HandleStopDevice

/******************************************************************************
 *
 * Function   :  StopDevice
 *
 * Description:  Stop a device
 *
 ******************************************************************************/
VOID StopDevice(IN PDEVICE_OBJECT fdo)
{												//StopDevice
    DEVICE_EXTENSION *pdx;

    pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	if (!pdx->GotResource)
		return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -