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

📄 pnpmanagement.c

📁 此驱动程序是SATA功能的PCI卡为例
💻 C
📖 第 1 页 / 共 2 页
字号:
    deviceDescription.IgnoreCount = FALSE;
    deviceDescription.InterfaceType = PCIBus ;
    deviceDescription.DmaWidth = Width32Bits ; //PCI default width
    deviceDescription.DmaSpeed = Compatible ;
    deviceDescription.MaximumLength = MAX_DMA_LENGTH ;
    //get adapter object
	pdx->AdapterObject = IoGetDmaAdapter(pdx->pPhysicalDeviceObject,&deviceDescription,
	    &pdx->MaximumMapRegisters) ;
	DebugPrint("the # of map register system provide is:%u\n",pdx->MaximumMapRegisters);

	 // If IoGetDmaAdapter fails, it is mostly likely that one of the parameters
    // supplied in the DEVICE_DESCRIPTION structure is not valid. It can also fail because of insufficient
    // resource, but not very likely.
    if (pdx->AdapterObject == NULL) {
	DebugPrint ("Sil3124: IoGetDmaAdapter failed.\n") ;
	status = STATUS_DEVICE_CONFIGURATION_ERROR ;
	return status;
    }

	DebugPrint("Start Device Start.");
	DebugPrint("the ResourceListRaw->count is %x\n",ResourceListRaw->Count);

    for (i = 0,m = 0; i < ResourceListRaw->Count; ++i, ++Resource, ++ResourceRaw)
    {
        switch (ResourceRaw->Type)
        {
		case CmResourceTypePort:        //IO Port Resource
			DebugPrint("ResourceType:Registers that provide indirect access to the registers of sil3124");
				pdx->BaseAddress_Indirect_Access = Resource->u.Port.Start;
				pdx->IORangeBytes = Resource->u.Port.Length;
				DebugPrint("Indirect Access Register base address : 0x%x\n",pdx->BaseAddress_Indirect_Access);
				DebugPrint("Indirect Access register's length :%ubytes\n",pdx->IORangeBytes);
				if(ResourceRaw->Flags & CM_RESOURCE_PORT_IO)
				{
					DebugPrint("The TaskFile register of channel#0 is accessed in IO address space");
				}
				else 
				{
                    DebugPrint("The TaskFile register of channel#0 is accessed in Memory address space");
				}
		
			break;
		case CmResourceTypeMemory:        //Memory Resources
            DebugPrint("ResourceType:Memory Registers that provide access for Global Register and 4 PCI Ports ");
			switch(m)
			{
			case 0:                    //Base Address 0  Global register base address 
				pdx->BaseAddress_GlobalRegister = Resource->u.Memory.Start;
				pdx->GlobalRegisterBytes = Resource->u.Memory.Length;
				DebugPrint("Global register base address  : 0x%x\n",pdx->BaseAddress_GlobalRegister);
				DebugPrint("Global register's length :%ubytes\n",pdx->GlobalRegisterBytes);
				if(ResourceRaw->Flags == CM_RESOURCE_MEMORY_READ_WRITE)
				{
					DebugPrint("the global registers could be read & write");
				}
				else 
				{
                    DebugPrint("the global registers could be read OR write");
				}
				pdx->Map_GlobalRegister = NULL;
			
				break;
			case 1:                    //Base Address 1  Port register and LRAM base address for 4 ports
				pdx->BaseAddress_PortRegister = Resource->u.Memory.Start;
				pdx->PortRegisterBytes = Resource->u.Memory.Length;
				DebugPrint("Port register base address  : 0x%x\n",pdx->BaseAddress_PortRegister);
				DebugPrint("Port register's length :%ubytes\n",pdx->PortRegisterBytes);
				if(ResourceRaw->Flags & CM_RESOURCE_MEMORY_READ_WRITE)
				{
					DebugPrint("the Port registers could be read & write");
				}
				else 
				{
                    DebugPrint("the Port registers could be read OR write");
				}
				pdx->Map_PortRegister = NULL;
			
				break;
			}
			m++;
			break;
         
		case CmResourceTypeInterrupt:	//Interrupt Resources
			    pdx->GotInterrupt = TRUE;
                pdx->IrqL       = (KIRQL) Resource->u.Interrupt.Level;
                pdx->vector     = Resource->u.Interrupt.Vector;
                pdx->affinity   = Resource->u.Interrupt.Affinity;
				DebugPrint("the Interrupt Flags:%x\n",ResourceRaw->Flags);
                if (ResourceRaw->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
                {
                    pdx->mode = Latched;
                }
                else
                {
                    pdx->mode = LevelSensitive;
                }
				pdx->irqshare = Resource->ShareDisposition == CmResourceShareShared;

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

			default:
				DebugPrint("Type: ?Unknown Resource Type?");
				break;
        }
    }

		//connect to interrupt

    if (pdx->GotInterrupt)
    {
		DebugPrint("Get Interrupt.");
        // firstly,Disable the PCI interrupt
       //DisablePciInterrupt(pdx);
		//connect interrupt
		status = IoConnectInterrupt(&pdx->InterruptObject,(PKSERVICE_ROUTINE)OnInterrupt,
						(PVOID)pdx,NULL,pdx->vector,pdx->IrqL,pdx->IrqL,pdx->mode,pdx->irqshare,pdx->affinity,FALSE);
		
		if (!NT_SUCCESS(status))
		{
			pdx->InterruptObject = NULL;
			return status;
		}
     DebugPrint("OK, I haved Connect Interruput!");
    }
    else
    {
        DebugPrint("Sil3124: No interrupt found.");
        pdx->InterruptObject = NULL;
    }


	// Initialize DPC object
	IoInitializeDpcRequest(fdo, DpcForIsr);

	pdx->NeedToHandle =FALSE;
	DebugPrint("Start Device end.");
	pdx->GotResource = TRUE;

    return STATUS_SUCCESS;
}	
											//StartDevice
/******************************************************************************
 *
 * Function   :  OnRequestComplete
 *
 * Description:  Set an event when a lower driver complete an IRP.
 *
 ******************************************************************************/
NTSTATUS OnRequestComplete(IN PDEVICE_OBJECT fdo,
						   IN PIRP pIrp,
						   IN PKEVENT pKEvent)
{												//OnRequestComplete
    KeSetEvent(pKEvent,(KPRIORITY)0,FALSE);

    return(STATUS_MORE_PROCESSING_REQUIRED);
}												//OnRequestComplete

/******************************************************************************
 *
 * Function   :  HandleStopDevice
 *
 * Description:  Handle the IRP_MN_STOP_DEVICE PnP request
 *
 ******************************************************************************/
NTSTATUS PnpStopDevice(IN PDEVICE_OBJECT fdo,
					   IN PIRP pIrp)
{	
    DebugPrintMsg("PnpStopDeviceHandler");
	
	// Wait for I/O to complete and stop device
    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;

	pdx->bStopping = TRUE;
	DebugPrintMsg("StopDevice");

	if( !pdx->GotResource)
		return;
	pdx->GotResource = FALSE;
}												//StopDevice

/////////////////////////////////////////////////////////////////////////////
//	PnpQueryRemoveDeviceHandler:	Handle PnP query remove device

NTSTATUS PnpQueryRemoveDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;
	DebugPrintMsg("PnpQueryRemoveDeviceHandler");
	if( pdx->OpenHandleCount>0)
	{
		DebugPrint("PnpQueryRemoveDeviceHandler: %d handles still open",pdx->OpenHandleCount);
		return CompleteRequestInfo( Irp, STATUS_UNSUCCESSFUL, 0);
	}
	
	return DefaultPnpHandler(fdo,Irp);
}

/******************************************************************************
 *
 * Function   :  PnpRemoveDevice
 *
 * Description:  Handle the IRP_MN_REMOVE_DEVICE PnP request
 *
 ******************************************************************************/

NTSTATUS PnpRemoveDevice(IN PDEVICE_OBJECT fdo,
							IN PIRP pIrp)
{												//HandleRemoveDevice
    NTSTATUS          status;
    DEVICE_EXTENSION  *pdx;

    // Wait for any pending I/O operations to complete

    pdx			   = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	pIrp->IoStatus.Status = STATUS_SUCCESS;			// flag that we handled this IRP

	DebugPrintMsg("call StopDevice");
	StopDevice(fdo);

// disconnect the interrupt							
	if (pdx->InterruptObject != NULL)
    {
  //      KeSynchronizeExecution(pdx->pInterruptObject,
    //        (PKSYNCHRONIZE_ROUTINE)DisablePciInterrupt,(PVOID)pdx);

        IoDisconnectInterrupt(pdx->InterruptObject);
        pdx->InterruptObject = NULL;
    }

	// free the adapter object
	if(pdx->AdapterObject!=NULL)
	{
		(pdx->AdapterObject->DmaOperations->PutDmaAdapter)(pdx->AdapterObject);
        pdx->AdapterObject = NULL;
	}
	
    // Let lower-level drivers handle this request & ignore the result
    status = DefaultPnpHandler(fdo,pIrp);

	IoSetDeviceInterfaceState(&pdx->InterfaceName, FALSE);
	RtlFreeUnicodeString(&pdx->InterfaceName);
	DebugPrint("the InterfaceName has been free");

    // Detach device from the device object stack
    if (pdx->pLowerDeviceObject)
    {
        IoDetachDevice(pdx->pLowerDeviceObject);
    }

    DebugPrint("Sil3124: Deleting device object...");

    // Delete the functional device object
    IoDeleteDevice(fdo);

	DebugPrint("Sil3124 is removed.");

    return status;
}												//HandleRemoveDevice
/////////////////////////////////////////////////////////////////////////////
//	PnpQueryCapabilitiesHandler:	Print pdo device capabilities

#define SetMostPoweredState( SystemState, OurDeviceState)	\
	dps = deviceCapabilities->DeviceState[SystemState];		\
	if( dps==PowerDeviceUnspecified || dps>OurDeviceState)	\
		deviceCapabilities->DeviceState[SystemState] = OurDeviceState


NTSTATUS PnpQueryCapabilitiesHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	NTSTATUS status = ForwardAndWait( fdo, Irp);
	int ds;
	DEVICE_POWER_STATE dps;
	if( NT_SUCCESS(status))
	{
		PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
		PDEVICE_CAPABILITIES deviceCapabilities;
		deviceCapabilities = IrpStack->Parameters.DeviceCapabilities.Capabilities;
#if DBG
		for(ds=PowerSystemWorking;ds<PowerSystemMaximum;ds++)
			DebugPrint("Capabilities from bus: DeviceState[%d]=%d", ds, deviceCapabilities->DeviceState[ds]);
#endif
		

		SetMostPoweredState( PowerSystemWorking, PowerDeviceD0);
		SetMostPoweredState( PowerSystemSleeping1, PowerDeviceD3);
		SetMostPoweredState( PowerSystemSleeping2, PowerDeviceD3);
		SetMostPoweredState( PowerSystemSleeping3, PowerDeviceD3);
		SetMostPoweredState( PowerSystemHibernate, PowerDeviceD3);
		SetMostPoweredState( PowerSystemShutdown, PowerDeviceD3);

#if DBG
		for(ds=PowerSystemWorking;ds<PowerSystemMaximum;ds++)
			DebugPrint("Capabilities now: DeviceState[%d]=%d", ds, deviceCapabilities->DeviceState[ds]);
#endif
	}
	return CompleteRequestInfo( Irp, status, Irp->IoStatus.Information);
}

/******************************************************************************
 *
 * Function   :  ForwardAndWait
 *
 * Description:  Forward request to lower level and await completion, used
 *               in PnP's IRP_MN_START_DEVICE
 *
 ******************************************************************************/
#pragma code_seg()	// end PAGE section
NTSTATUS ForwardAndWait(PDEVICE_OBJECT fdo,PIRP pIrp)
{												// ForwardAndWait
    KEVENT    event;
    NTSTATUS  status;

    // Initialize a kernel event object to use in waiting for the lower-level
    // driver to finish processing the object. 
    KeInitializeEvent(&event,NotificationEvent,FALSE);

	DebugPrint("ForwardAndWait Start.");

    IoCopyCurrentIrpStackLocationToNext(pIrp);

    IoSetCompletionRoutine(pIrp,(PIO_COMPLETION_ROUTINE) OnRequestComplete,
							(PVOID) &event,TRUE,TRUE,TRUE);

    status = IoCallDriver(
					((DEVICE_EXTENSION *) fdo->DeviceExtension)->pLowerDeviceObject,
					pIrp);

    if (status == STATUS_PENDING)
    {
        // Wait for completion
		DebugPrintMsg("ForwardIrpAndWait: waiting for completion");
        KeWaitForSingleObject((PVOID)&event,Executive,KernelMode,FALSE,NULL);

        return pIrp->IoStatus.Status;
    }
	DebugPrint("ForwardAndWait End.");
    return(pIrp->IoStatus.Status);	//status;
}													// ForwardAndWait

⌨️ 快捷键说明

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