Esempio n. 1
0
NTSTATUS
WaitWakeCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

    This is the IoSet completion routine for the wait wake irp.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
{
    BulkUsb_DbgPrint(3, ("WaitWakeCompletionRoutine - begins\n"));

    if(Irp->PendingReturned) {

        IoMarkIrpPending(Irp);
    }

    //
    // Nullify the WaitWakeIrp pointer-the Irp is released 
    // as part of the completion process. If it's already NULL, 
    // avoid race with the CancelWaitWake routine.
    //

    if(InterlockedExchangePointer(&DeviceExtension->WaitWakeIrp, NULL)) {

        PoStartNextPowerIrp(Irp);

        return STATUS_SUCCESS;
    }

    //
    // CancelWaitWake has run. 
    // If FlagWWCancel != 0, complete the Irp.
    // If FlagWWCancel == 0, CancelWaitWake completes it.
    //
    if(InterlockedExchange(&DeviceExtension->FlagWWCancel, 1)) {

        PoStartNextPowerIrp(Irp);

        return STATUS_CANCELLED;
    }

    BulkUsb_DbgPrint(3, ("WaitWakeCompletionRoutine - ends\n"));

    return STATUS_MORE_PROCESSING_REQUIRED;
}
Esempio n. 2
0
VOID CancelSelectSuspend(IN PTDeviceExtension DeviceExtension)
{
    PIRP  irp;
    KIRQL oldIrql;

    irp = NULL;
    BulkUsb_DbgPrint(3, ("file bulkdev: CancelSelectSuspend - begins\n"));
    KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
    if(!CanDeviceSuspend(DeviceExtension))
    {
        BulkUsb_DbgPrint(3, ("file bulkdev: Device is not idle\n"));
        irp = (PIRP)InterlockedExchangePointer(&DeviceExtension->PendingIdleIrp, NULL);
    }

    KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
    if(irp) 
	{
		IoCancelIrp(irp);
        if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount)) 
		{
            BulkUsb_DbgPrint(3, ("file bulkdev: CancelSelectSuspend frees the irp\n"));
            IoFreeIrp(irp);
            KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
        }
    }

    BulkUsb_DbgPrint(3, ("file bulkdev: CancelSelectSuspend - ends\n"));
    return;
}
Esempio n. 3
0
NTSTATUS
HandleSystemSetPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
 
Routine Description:

    This routine services irps of minor type IRP_MN_SET_POWER
    for the system power state

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet sent by the power manager

Return Value:

    NT status value:

--*/
{
    NTSTATUS           ntStatus;
    PDEVICE_EXTENSION  deviceExtension;
    SYSTEM_POWER_STATE systemState;
    PIO_STACK_LOCATION irpStack;
    
    BulkUsb_DbgPrint(3, ("HandleSystemSetPower - begins\n"));

    //
    // initialize variables
    //

    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    systemState = irpStack->Parameters.Power.State.SystemState;

    BulkUsb_DbgPrint(3, ("Set request for system power state S%X\n"
                         "Current system power state S%X\n",
                         systemState - 1,
                         deviceExtension->SysPower - 1));

    IoCopyCurrentIrpStackLocationToNext(Irp);

    IoSetCompletionRoutine(
            Irp, 
            (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
            deviceExtension, 
            TRUE, 
            TRUE, 
            TRUE);

    ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

    BulkUsb_DbgPrint(3, ("HandleSystemSetPower - ends\n"));

    return STATUS_PENDING;
}
Esempio n. 4
0
NTSTATUS
FinishDevPoDnIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

    This routine is the completion routine for device power DOWN irp.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
{
    NTSTATUS           ntStatus;
    POWER_STATE        newState;
    PIO_STACK_LOCATION irpStack;

    //
    // initialize variables
    //
    ntStatus = Irp->IoStatus.Status;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    newState = irpStack->Parameters.Power.State;

    BulkUsb_DbgPrint(3, ("FinishDevPoDnIrp - begins\n"));

    if(NT_SUCCESS(ntStatus) && irpStack->MinorFunction == IRP_MN_SET_POWER) {

        //
        // update the cache;
        //

        BulkUsb_DbgPrint(3, ("updating cache..\n"));

        DeviceExtension->DevPower = newState.DeviceState;

        PoSetPowerState(DeviceObject, DevicePowerState, newState);
    }

    PoStartNextPowerIrp(Irp);

    BulkUsb_DbgPrint(3, ("FinishDevPoDnIrp::"));
    BulkUsb_IoDecrement(DeviceExtension);

    BulkUsb_DbgPrint(3, ("FinishDevPoDnIrp - ends\n"));

    return STATUS_SUCCESS;
}
Esempio n. 5
0
NTSTATUS
FinishDevPoUpIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

    completion routine for the device power UP irp with minor function
    IRP_MN_SET_POWER.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
{
    NTSTATUS           ntStatus;
                        
    //
    // initialize variables
    //

    ntStatus = Irp->IoStatus.Status;

    BulkUsb_DbgPrint(3, ("FinishDevPoUpIrp - begins\n"));

    if(Irp->PendingReturned) {

        IoMarkIrpPending(Irp);
    }

    if(!NT_SUCCESS(ntStatus)) {

        PoStartNextPowerIrp(Irp);

        BulkUsb_DbgPrint(3, ("FinishDevPoUpIrp::"));
        BulkUsb_IoDecrement(DeviceExtension);

        return STATUS_SUCCESS;
    }

    SetDeviceFunctional(DeviceObject, Irp, DeviceExtension);

    BulkUsb_DbgPrint(3, ("FinishDevPoUpIrp - ends\n"));

    return STATUS_MORE_PROCESSING_REQUIRED;
}
Esempio n. 6
0
NTSTATUS
IssueWaitWake(
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

    This routine will PoRequest a WAIT WAKE irp for the device

Arguments:

    DeviceExtension - pointer to device extension

Return Value:

    NT status value.

--*/
{
    POWER_STATE poState;
    NTSTATUS    ntStatus;

    BulkUsb_DbgPrint(3, ("IssueWaitWake - begins\n"));

    if(InterlockedExchange(&DeviceExtension->FlagWWOutstanding, 1)) {

        return STATUS_DEVICE_BUSY;
    }

    InterlockedExchange(&DeviceExtension->FlagWWCancel, 0);

    //
    // lowest state from which this Irp will wake the system
    //

    poState.SystemState = DeviceExtension->DeviceCapabilities.SystemWake;

    ntStatus = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject, 
                                 IRP_MN_WAIT_WAKE,
                                 poState, 
                                 (PREQUEST_POWER_COMPLETE) WaitWakeCallback,
                                 DeviceExtension, 
                                 &DeviceExtension->WaitWakeIrp);

    if(!NT_SUCCESS(ntStatus)) {

        InterlockedExchange(&DeviceExtension->FlagWWOutstanding, 0);
    }

    BulkUsb_DbgPrint(3, ("IssueWaitWake - ends\n"));

    return ntStatus;
}
Esempio n. 7
0
NTSTATUS
QueueRequest(
    IN OUT PDEVICE_EXTENSION DeviceExtension,
    IN PIRP Irp
    )
/*++
 
Routine Description:

    Queue the Irp in the device queue

Arguments:

    DeviceExtension - pointer to device extension
    Irp - I/O request packet.

Return Value:

    NT status value

--*/
{
    KIRQL    oldIrql;
    NTSTATUS ntStatus;

    //
    // initialize variables
    //
    ntStatus = STATUS_PENDING;

    BulkUsb_DbgPrint(3, ("QueueRequests - begins\n"));

    ASSERT(HoldRequests == DeviceExtension->QueueState);

    KeAcquireSpinLock(&DeviceExtension->QueueLock, &oldIrql);

    InsertTailList(&DeviceExtension->NewRequestsQueue, 
                   &Irp->Tail.Overlay.ListEntry);

    IoMarkIrpPending(Irp);

    //
    // Set the cancel routine
    //

    IoSetCancelRoutine(Irp, CancelQueued);

    KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql);

    BulkUsb_DbgPrint(3, ("QueueRequests - ends\n"));

    return ntStatus;
}
Esempio n. 8
0
NTSTATUS BulkUsb_DispatchSysCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PTDeviceExtension       deviceExtension;
    SYSCTL_IRP_DISPOSITION  disposition;
    NTSTATUS                ntStatus;
    PIO_STACK_LOCATION      irpStack;
    
    PAGED_CODE();
    irpStack = IoGetCurrentIrpStackLocation (Irp);
    deviceExtension = (PTDeviceExtension) DeviceObject->DeviceExtension;
    if(REMOVED == deviceExtension->DeviceState) 
	{
        ntStatus = STATUS_DELETE_PENDING;
        Irp->IoStatus.Status = ntStatus;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return ntStatus;
    }

	BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_DispatchSysCtrl::\n"));
    BulkUsb_IoIncrement(deviceExtension);
    ntStatus = WmiSystemControl(&deviceExtension->WmiLibInfo, 
                                DeviceObject, 
                                Irp,
                                &disposition);

    switch(disposition) 
	{
        case IrpProcessed: 
            break;
        
        case IrpNotCompleted:
            IoCompleteRequest(Irp, IO_NO_INCREMENT);                
            break;
      
        case IrpForward:
        case IrpNotWmi:
            IoSkipCurrentIrpStackLocation (Irp);
            ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
            break;
                                    
        default:
            IoSkipCurrentIrpStackLocation (Irp);
            ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
            break;
    }
    BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_DispatchSysCtrl::\n"));
    BulkUsb_IoDecrement(deviceExtension);

    return ntStatus;
}
Esempio n. 9
0
static VOID IdleNotificationCallback(IN PTDeviceExtension DeviceExtension)
{
	NTSTATUS                ntStatus;
	POWER_STATE             powerState;
	KEVENT                  irpCompletionEvent;
	PTIrpCompletionContext	irpContext;

	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationCallback - process\n"));
	if(DeviceExtension->DeviceState != WORKING) 
		return;

	if(DeviceExtension->WaitWakeEnable) 
		IssueWaitWake(DeviceExtension);
	irpContext = (PTIrpCompletionContext)ExAllocatePool(NonPagedPool, sizeof(TIrpCompletionContext));
	if(!irpContext) 
	{
		BulkUsb_DbgPrint(1, ("file bulkdev: Failed to alloc memory for irpContext\n"));
		//ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		return;
	}
	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationCallback::"));
	BulkUsb_IoIncrement(DeviceExtension);
	powerState.DeviceState = DeviceExtension->PowerDownLevel;
	KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE);
	irpContext->DeviceExtension = DeviceExtension;
	irpContext->Event = &irpCompletionEvent;
	ntStatus = PoRequestPowerIrp(
				DeviceExtension->PhysicalDeviceObject, 
				IRP_MN_SET_POWER, 
				powerState, 
				(PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc,
				irpContext, 
				NULL);

	if(STATUS_PENDING == ntStatus) 
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationCallback::"
						"waiting for the power irp to complete\n"));
		KeWaitForSingleObject(&irpCompletionEvent,
					Executive,
					KernelMode,
					FALSE,
					NULL);
	}
	ExFreePool(irpContext);
	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationCallback - ends\n"));
}
Esempio n. 10
0
NTSTATUS BulkUsb_QueryWmiDataBlock(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex,
								   IN ULONG InstanceIndex, IN ULONG InstanceCount, 
								   IN OUT PULONG InstanceLengthArray, IN ULONG OutBufferSize,
								   OUT PUCHAR Buffer)
{
    PTDeviceExtension deviceExtension;
    NTSTATUS          ntStatus;
    ULONG             size;
    WCHAR             modelName[] = L"Aishverya\0\0";
    USHORT            modelNameLen;

    PAGED_CODE();
    BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_QueryWmiDataBlock - begins\n"));
    size = 0;
    modelNameLen = (wcslen(modelName) + 1) * sizeof(WCHAR);

    ASSERT((InstanceIndex == 0) && (InstanceCount == 1));
    
    deviceExtension = (PTDeviceExtension) DeviceObject->DeviceExtension;
    switch (GuidIndex) 
	{
    case WMI_BULKUSB_DRIVER_INFORMATION:
        size = sizeof(ULONG) + modelNameLen + sizeof(USHORT);
        if (OutBufferSize < size ) 
		{
            BulkUsb_DbgPrint(3, ("file bulkwmi: OutBuffer too small\n"));
            ntStatus = STATUS_BUFFER_TOO_SMALL;
            break;
        }
        * (PULONG) Buffer = DebugLevel;
        Buffer += sizeof(ULONG);
        *((PUSHORT)Buffer) = modelNameLen;
        Buffer = (PUCHAR)Buffer + sizeof(USHORT);
        RtlCopyBytes((PVOID)Buffer, (PVOID)modelName, modelNameLen);
        *InstanceLengthArray = size ;
        ntStatus = STATUS_SUCCESS;
        break;

    default:
        ntStatus = STATUS_WMI_GUID_NOT_FOUND;
		break;
    }
    ntStatus = WmiCompleteRequest(DeviceObject, Irp, ntStatus, size, IO_NO_INCREMENT);
    BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_QueryWmiDataBlock - ends\n"));
    return ntStatus;
}
Esempio n. 11
0
static NTSTATUS BulkUsb_QueryWmiRegInfo(IN  PDEVICE_OBJECT  DeviceObject, OUT ULONG *RegFlags,
										OUT PUNICODE_STRING InstanceName, 
										OUT PUNICODE_STRING *RegistryPath,
										OUT PUNICODE_STRING MofResourceName, OUT PDEVICE_OBJECT *Pdo)
{
    PTDeviceExtension deviceExtension;

    PAGED_CODE();
    BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_QueryWmiRegInfo - begins\n"));
    deviceExtension = DeviceObject->DeviceExtension;
    *RegFlags     = WMIREG_FLAG_INSTANCE_PDO;
    *RegistryPath = &gUsbdContext.BulkUsb_RegistryPath;
    *Pdo          = deviceExtension->PhysicalDeviceObject;
    RtlInitUnicodeString(MofResourceName, MOFRESOURCENAME);
    BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_QueryWmiRegInfo - ends\n"));
    return STATUS_SUCCESS;
}
Esempio n. 12
0
NTSTATUS BulkUsb_ResetDevice(IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS ntStatus;
    ULONG    portStatus;

    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_ResetDevice - begins\n"));
    ntStatus = BulkUsb_GetPortStatus(DeviceObject, &portStatus);
    if((NT_SUCCESS(ntStatus)) && 
		(!(portStatus & USBD_PORT_ENABLED)) &&
       (portStatus & USBD_PORT_CONNECTED)) 
	{
        ntStatus = BulkUsb_ResetParentPort(DeviceObject);
    }
    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_ResetDevice - ends\n"));

    return ntStatus;
}
Esempio n. 13
0
//============================================
static NTSTATUS BulkUsb_GetPortStatus(IN PDEVICE_OBJECT DeviceObject, IN OUT PULONG PortStatus)
{
    NTSTATUS           ntStatus;
    KEVENT             event;
    PIRP               irp;
    IO_STATUS_BLOCK    ioStatus;
    PIO_STACK_LOCATION nextStack;
    PTDeviceExtension  deviceExtension;

    deviceExtension = (PTDeviceExtension) DeviceObject->DeviceExtension;
    *PortStatus = 0;
    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_GetPortStatus - begins\n"));
    KeInitializeEvent(&event, NotificationEvent, FALSE);
    irp = IoBuildDeviceIoControlRequest(
                    IOCTL_INTERNAL_USB_GET_PORT_STATUS,
                    deviceExtension->TopOfStackDeviceObject,
                    NULL,
                    0,
                    NULL,
                    0,
                    TRUE,
                    &event,
                    &ioStatus);

    if(NULL == irp) 
	{
        BulkUsb_DbgPrint(1, ("file bulkdev: memory alloc for irp failed\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    nextStack = IoGetNextIrpStackLocation(irp);
    ASSERT(nextStack != NULL);
    nextStack->Parameters.Others.Argument1 = PortStatus;
    ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
    if(STATUS_PENDING == ntStatus) 
	{
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
    }
    else 
        ioStatus.Status = ntStatus;

    ntStatus = ioStatus.Status;
    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_GetPortStatus - ends\n"));
    return ntStatus;
}
Esempio n. 14
0
NTSTATUS BulkUsb_SetWmiDataItem(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex,
								IN ULONG InstanceIndex, IN ULONG DataItemId, IN ULONG BufferSize,
								IN PUCHAR Buffer)
{
    PTDeviceExtension deviceExtension;
    NTSTATUS          ntStatus;
    ULONG             info;
    
    PAGED_CODE();
    BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_SetWmiDataItem - begins\n"));
    deviceExtension = (PTDeviceExtension) DeviceObject->DeviceExtension;
    info = 0;
    switch(GuidIndex) 
	{
    case WMI_BULKUSB_DRIVER_INFORMATION:
        if(DataItemId == 1) 
		{
            if(BufferSize == sizeof(ULONG)) 
			{
                DebugLevel = *((PULONG)Buffer);
                ntStatus = STATUS_SUCCESS;
                info = sizeof(ULONG);
            }
            else 
                ntStatus = STATUS_INFO_LENGTH_MISMATCH;
        }
        else 
            ntStatus = STATUS_WMI_READ_ONLY;
        break;

    default:
        ntStatus = STATUS_WMI_GUID_NOT_FOUND;
		break;
    }

    ntStatus = WmiCompleteRequest(DeviceObject,
                                Irp,
                                ntStatus,
                                info,
                                IO_NO_INCREMENT);

    BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_SetWmiDataItem - ends\n"));
    return ntStatus;
}
Esempio n. 15
0
VOID
CancelWaitWake(
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

    This routine cancels the Wait Wake request.

Arguments:

    DeviceExtension - pointer to the device extension

Return Value:

    None.

--*/
{
    PIRP Irp;

    BulkUsb_DbgPrint(3, ("CancelWaitWake - begins\n"));

    Irp = (PIRP) InterlockedExchangePointer(&DeviceExtension->WaitWakeIrp, 
                                            NULL);

    if(Irp) {

        IoCancelIrp(Irp);

        if(InterlockedExchange(&DeviceExtension->FlagWWCancel, 1)) {

            PoStartNextPowerIrp(Irp);

            Irp->IoStatus.Status = STATUS_CANCELLED;
            Irp->IoStatus.Information = 0;

            IoCompleteRequest(Irp, IO_NO_INCREMENT);
        }    
    }

    BulkUsb_DbgPrint(3, ("CancelWaitWake - ends\n"));
}
Esempio n. 16
0
VOID
PoIrpCompletionFunc(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Context,
    IN PIO_STATUS_BLOCK IoStatus
    )
/*++
 
Routine Description:

    Completion routine for power irp PoRequested in 
    IdleNotificationCallback.

Arguments:

    DeviceObject - pointer to device object
    MinorFunciton - minor function for the irp.
    PowerState - irp power state
    Context - context passed to the completion function
    IoStatus - status block.

Return Value:

    None

--*/
{
    PIRP_COMPLETION_CONTEXT irpContext;
    
    //
    // initialize variables
    //

    if(Context) {

        irpContext = (PIRP_COMPLETION_CONTEXT) Context;
    }

    //
    // all we do is set the event and decrement the count
    //

    if(irpContext) {

        KeSetEvent(irpContext->Event, 0, FALSE);

        BulkUsb_DbgPrint(3, ("PoIrpCompletionFunc::"));
        BulkUsb_IoDecrement(irpContext->DeviceExtension);

        ExFreePool(irpContext);
    }

    return;
}
Esempio n. 17
0
static VOID PoIrpAsyncCompletionFunc(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction,
    IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus)
{
    PTDeviceExtension DeviceExtension;
    
    DeviceExtension = (PTDeviceExtension) Context;
	if(DeviceExtension)
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: PoIrpAsyncCompletionFunc::"));
		BulkUsb_IoDecrement(DeviceExtension);
	}
}
Esempio n. 18
0
NTSTATUS
BulkUsb_ResetDevice(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++
 
Routine Description:

    This routine invokes BulkUsb_ResetParentPort to reset the device

Arguments:

    DeviceObject - pointer to device object

Return Value:

    NT status value

--*/
{
    NTSTATUS ntStatus;
    ULONG    portStatus;

    BulkUsb_DbgPrint(3, ("BulkUsb_ResetDevice - begins\n"));

    ntStatus = BulkUsb_GetPortStatus(DeviceObject, &portStatus);

    if((NT_SUCCESS(ntStatus))                 &&
       (!(portStatus & USBD_PORT_ENABLED))    &&
       (portStatus & USBD_PORT_CONNECTED)) {

        ntStatus = BulkUsb_ResetParentPort(DeviceObject);
    }

    BulkUsb_DbgPrint(3, ("BulkUsb_ResetDevice - ends\n"));

    return ntStatus;
}
Esempio n. 19
0
NTSTATUS BulkUsb_DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS				ntStatus;
    PFILE_OBJECT			fileObject;
    PTDeviceExtension		deviceExtension;
    PIO_STACK_LOCATION		irpStack;
    PTPipeContext			pipeContext;
    PUSBD_PIPE_INFORMATION pipeInformation;
    
    PAGED_CODE();

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    fileObject = irpStack->FileObject;
    pipeContext = NULL;
    pipeInformation = NULL;
    deviceExtension = (PTDeviceExtension) DeviceObject->DeviceExtension;
    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_DispatchClose - begins\n"));
    if(fileObject && fileObject->FsContext) 
	{
        pipeInformation = fileObject->FsContext;
        if(0 != fileObject->FileName.Length) 
		{
            pipeContext = BulkUsb_PipeWithName(DeviceObject, &fileObject->FileName);
        }

        if(pipeContext && pipeContext->PipeOpen) 
            pipeContext->PipeOpen = FALSE;
    }
    ntStatus = STATUS_SUCCESS;
    Irp->IoStatus.Status = ntStatus;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    InterlockedDecrement(&deviceExtension->OpenHandleCount);
    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_DispatchClose - ends\n"));
    return ntStatus;
}
Esempio n. 20
0
static VOID PoIrpCompletionFunc(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction,
    IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus)
{
	PTIrpCompletionContext irpContext;

	//irpContext = NULL;
	//if(Context) 
		irpContext = (PTIrpCompletionContext) Context;
	if(irpContext) 
	{
		KeSetEvent(irpContext->Event, 0, FALSE);
		BulkUsb_DbgPrint(3, ("file bulkdev: PoIrpCompletionFunc::"));
		BulkUsb_IoDecrement(irpContext->DeviceExtension);
		ExFreePool(irpContext);
	}
}
Esempio n. 21
0
VOID
PoIrpAsyncCompletionFunc(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Context,
    IN PIO_STATUS_BLOCK IoStatus
    )
/*++
 
Routine Description:

    Completion routine for power irp PoRequested in IdleNotification
    RequestComplete routine.

Arguments:

    DeviceObject - pointer to device object
    MinorFunciton - minor function for the irp.
    PowerState - irp power state
    Context - context passed to the completion function
    IoStatus - status block.

Return Value:

    None

--*/
{
    PDEVICE_EXTENSION DeviceExtension;
    
    //
    // initialize variables
    //
    DeviceExtension = (PDEVICE_EXTENSION) Context;

    //
    // all we do is decrement the count
    //
    
    BulkUsb_DbgPrint(3, ("PoIrpAsyncCompletionFunc::"));
    BulkUsb_IoDecrement(DeviceExtension);

    return;
}
Esempio n. 22
0
VOID
SendDeviceIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP SIrp
    )
/*++
 
Routine Description:

    This routine is invoked from the completion routine of the system power
    irp. This routine will PoRequest a device power irp. The system irp is 
    passed as a context to the the device power irp.

Arguments:

    DeviceObject - pointer to device object
    SIrp - system power irp.

Return Value:

    None

--*/
{
    NTSTATUS                  ntStatus;
    POWER_STATE               powState;
    PDEVICE_EXTENSION         deviceExtension;
    PIO_STACK_LOCATION        irpStack;
    SYSTEM_POWER_STATE        systemState;
    DEVICE_POWER_STATE        devState;
    PPOWER_COMPLETION_CONTEXT powerContext;
    
    //
    // initialize variables
    //

    irpStack = IoGetCurrentIrpStackLocation(SIrp);
    systemState = irpStack->Parameters.Power.State.SystemState;
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    BulkUsb_DbgPrint(3, ("SendDeviceIrp - begins\n"));

    //
    // Read out the D-IRP out of the S->D mapping array captured in QueryCap's.
    // we can choose deeper sleep states than our mapping but never choose
    // lighter ones.
    //

    devState = deviceExtension->DeviceCapabilities.DeviceState[systemState];
    powState.DeviceState = devState;
    
    powerContext = (PPOWER_COMPLETION_CONTEXT) 
                   ExAllocatePool(NonPagedPool,
                                  sizeof(POWER_COMPLETION_CONTEXT));

    if(!powerContext) {

        BulkUsb_DbgPrint(1, ("Failed to alloc memory for powerContext\n"));

        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }
    else {

        powerContext->DeviceObject = DeviceObject;
        powerContext->SIrp = SIrp;
   
        //
        // in win2k PoRequestPowerIrp can take fdo or pdo.
        //

        ntStatus = PoRequestPowerIrp(
                            deviceExtension->PhysicalDeviceObject, 
                            irpStack->MinorFunction,
                            powState,
                            (PREQUEST_POWER_COMPLETE)DevPoCompletionRoutine,
                            powerContext, 
                            NULL);
    }

    if(!NT_SUCCESS(ntStatus)) {

        if(powerContext) {

            ExFreePool(powerContext);
        }

        PoStartNextPowerIrp(SIrp);

        SIrp->IoStatus.Status = ntStatus;
        SIrp->IoStatus.Information = 0;
        
        IoCompleteRequest(SIrp, IO_NO_INCREMENT);

        BulkUsb_DbgPrint(3, ("SendDeviceIrp::"));
        BulkUsb_IoDecrement(deviceExtension);

    }

    BulkUsb_DbgPrint(3, ("SendDeviceIrp - ends\n"));
}
Esempio n. 23
0
NTSTATUS
HandleDeviceSetPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
 
Routine Description:

    This routine services irps of minor type IRP_MN_SET_POWER
    for the device power state

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet sent by the power manager

Return Value:

    NT status value

--*/
{
    KIRQL              oldIrql;
    NTSTATUS           ntStatus;
    POWER_STATE        newState;    
    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION  deviceExtension;
    DEVICE_POWER_STATE newDevState,
                       oldDevState;

    BulkUsb_DbgPrint(3, ("HandleDeviceSetPower - begins\n"));
	
    //
    // initialize variables
    //

    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    oldDevState = deviceExtension->DevPower;
    newState = irpStack->Parameters.Power.State;
    newDevState = newState.DeviceState;

    BulkUsb_DbgPrint(3, ("Set request for device power state D%X\n"
                         "Current device power state D%X\n",
                         newDevState - 1,
                         deviceExtension->DevPower - 1));

    if(newDevState < oldDevState) {

        //
        // adding power
        //
        BulkUsb_DbgPrint(3, ("Adding power to the device\n"));

        //
        // send the power IRP to the next driver in the stack
        //
        IoCopyCurrentIrpStackLocationToNext(Irp);

        IoSetCompletionRoutine(
                Irp, 
                (PIO_COMPLETION_ROUTINE)FinishDevPoUpIrp,
                deviceExtension, 
                TRUE, 
                TRUE, 
                TRUE);

        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

	}
    else {

        //
        // newDevState >= oldDevState 
        //
        // hold I/O if transition from D0 -> DX (X = 1, 2, 3)
        // if transition from D1 or D2 to deeper sleep states, 
        // I/O queue is already on hold.
        //

        if(PowerDeviceD0 == oldDevState && newDevState > oldDevState) {

            //
            // D0 -> DX transition
            //

            BulkUsb_DbgPrint(3, ("Removing power from the device\n"));

            ntStatus = HoldIoRequests(DeviceObject, Irp);

            if(!NT_SUCCESS(ntStatus)) {

                PoStartNextPowerIrp(Irp);

                Irp->IoStatus.Status = ntStatus;
                Irp->IoStatus.Information = 0;

                IoCompleteRequest(Irp, IO_NO_INCREMENT);

                BulkUsb_DbgPrint(3, ("HandleDeviceSetPower::"));
                BulkUsb_IoDecrement(deviceExtension);

                return ntStatus;
            }
            else {

                goto HandleDeviceSetPower_Exit;
            }

        }
        else if(PowerDeviceD0 == oldDevState && PowerDeviceD0 == newDevState) {

            //
            // D0 -> D0
            // unblock the queue which may have been blocked processing
            // query irp
            //

            BulkUsb_DbgPrint(3, ("A SetD0 request\n"));

            KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
              
            deviceExtension->QueueState = AllowRequests;

            KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);

            ProcessQueuedRequests(deviceExtension);
        }   

        IoCopyCurrentIrpStackLocationToNext(Irp);

        IoSetCompletionRoutine(
                Irp, 
                (PIO_COMPLETION_ROUTINE) FinishDevPoDnIrp,
                deviceExtension, 
                TRUE, 
                TRUE, 
                TRUE);

        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

        if(!NT_SUCCESS(ntStatus)) {

            BulkUsb_DbgPrint(1, ("Lower drivers failed a power Irp\n"));
        }

    }

HandleDeviceSetPower_Exit:

    BulkUsb_DbgPrint(3, ("HandleDeviceSetPower - ends\n"));

    return STATUS_PENDING;
}
Esempio n. 24
0
NTSTATUS
SysPoCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

    This is the completion routine for the system power irps of minor
    function types IRP_MN_QUERY_POWER and IRP_MN_SET_POWER.
    This completion routine sends the corresponding device power irp and
    returns STATUS_MORE_PROCESSING_REQUIRED. The system irp is passed as a
    context to the device power irp completion routine and is completed in
    the device power irp completion routine.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
{
    NTSTATUS           ntStatus;
 	PIO_STACK_LOCATION irpStack;

    //
    // initialize variables
    //
    ntStatus = Irp->IoStatus.Status;
    irpStack = IoGetCurrentIrpStackLocation(Irp);


    BulkUsb_DbgPrint(3, ("SysPoCompletionRoutine - begins\n"));

    //
    // lower drivers failed this Irp
    //

    if(!NT_SUCCESS(ntStatus)) {

        PoStartNextPowerIrp(Irp);

        BulkUsb_DbgPrint(3, ("SysPoCompletionRoutine::"));
        BulkUsb_IoDecrement(DeviceExtension);

        return STATUS_SUCCESS;
    }

    //
    // ..otherwise update the cached system power state (IRP_MN_SET_POWER)
    //

    if(irpStack->MinorFunction == IRP_MN_SET_POWER) {

        DeviceExtension->SysPower = irpStack->Parameters.Power.State.SystemState;
    }

    //
    // queue device irp and return STATUS_MORE_PROCESSING_REQUIRED
    //
	
    SendDeviceIrp(DeviceObject, Irp);

    BulkUsb_DbgPrint(3, ("SysPoCompletionRoutine - ends\n"));

    return STATUS_MORE_PROCESSING_REQUIRED;
}
Esempio n. 25
0
//====================
NTSTATUS BulkUsb_DispatchDevCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    ULONG              code;
    PVOID              ioBuffer;
    ULONG              inputBufferLength;
    ULONG              outputBufferLength;
    ULONG              info;
    NTSTATUS           ntStatus;
    PTDeviceExtension  deviceExtension;
    PIO_STACK_LOCATION irpStack;

    info = 0;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    code = irpStack->Parameters.DeviceIoControl.IoControlCode;
    deviceExtension = (PTDeviceExtension) DeviceObject->DeviceExtension;
    ioBuffer           = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    if(deviceExtension->DeviceState != WORKING) 
	{
        BulkUsb_DbgPrint(1, ("file bulkdev: Invalid device state\n"));
        Irp->IoStatus.Status = ntStatus = STATUS_INVALID_DEVICE_STATE;
        Irp->IoStatus.Information = info;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return ntStatus;
    }
    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_DispatchDevCtrl::"));
    BulkUsb_IoIncrement(deviceExtension);
    BulkUsb_DbgPrint(3, ("file bulkdev: Waiting on the IdleReqPendEvent\n"));
    
    if(deviceExtension->SSEnable) 
	{
        KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, 
                              Executive, 
                              KernelMode, 
                              FALSE, 
                              NULL);
    }

    switch(code) 
	{
    case IOCTL_BULKUSB_RESET_PIPE:
    {
        PFILE_OBJECT           fileObject;
        PUSBD_PIPE_INFORMATION pipe;

        pipe = NULL;
        fileObject = irpStack->FileObject;
        if(fileObject == NULL) 
		{
            ntStatus = STATUS_INVALID_PARAMETER;
            break;
        }

        pipe = (PUSBD_PIPE_INFORMATION) fileObject->FsContext;
        if(pipe == NULL) 
            ntStatus = STATUS_INVALID_PARAMETER;
        else 
            ntStatus = BulkUsb_ResetPipe(DeviceObject, pipe);
        break;
    }

    case IOCTL_BULKUSB_GET_CONFIG_DESCRIPTOR:
    {
        ULONG length;

        if(deviceExtension->UsbConfigurationDescriptor) 
		{
            length = deviceExtension->UsbConfigurationDescriptor->wTotalLength;
            if(outputBufferLength >= length) 
			{
                RtlCopyMemory(ioBuffer, deviceExtension->UsbConfigurationDescriptor, length);
                info = length;
                ntStatus = STATUS_SUCCESS;
            }
            else 
                ntStatus = STATUS_BUFFER_TOO_SMALL;
        }
        else 
            ntStatus = STATUS_UNSUCCESSFUL;
        break;
    }

    case IOCTL_BULKUSB_RESET_DEVICE:
        ntStatus = BulkUsb_ResetDevice(DeviceObject);
        break;

    default :
        ntStatus = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    Irp->IoStatus.Status = ntStatus;
    Irp->IoStatus.Information = info;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_DispatchDevCtrl::"));
    BulkUsb_IoDecrement(deviceExtension);
    return ntStatus;
}
Esempio n. 26
0
static NTSTATUS IdleNotificationRequestComplete(IN PDEVICE_OBJECT DeviceObject,
												IN PIRP Irp, IN PTDeviceExtension DeviceExtension)
{
	NTSTATUS                ntStatus;
	POWER_STATE             powerState;
	KIRQL                   oldIrql;
	LARGE_INTEGER           dueTime;
	PIRP                    idleIrp;
	PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;

	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestCompete - begins\n"));
	idleIrp = NULL;
	ntStatus = Irp->IoStatus.Status;
	if(!NT_SUCCESS(ntStatus) && ntStatus != STATUS_NOT_SUPPORTED) 
	{
		BulkUsb_DbgPrint(1, ("file bulkdev: Idle irp completes with error::"));
		switch(ntStatus) 
		{
		case STATUS_INVALID_DEVICE_REQUEST:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_INVALID_DEVICE_REQUEST\n"));
			break;

		case STATUS_CANCELLED:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_CANCELLED\n"));
			break;

		case STATUS_POWER_STATE_INVALID:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_POWER_STATE_INVALID\n"));
			goto IdleNotificationRequestComplete_Exit;

		case STATUS_DEVICE_BUSY:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_DEVICE_BUSY\n"));
			break;

		default:
			BulkUsb_DbgPrint(1, ("file bulkdev: default: status = %X\n", ntStatus));
			break;
		}

		if(PowerDeviceD0 != DeviceExtension->DevPower) 
		{
			BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestComplete::"));
			BulkUsb_IoIncrement(DeviceExtension);
			powerState.DeviceState = PowerDeviceD0;
			ntStatus = PoRequestPowerIrp(
						DeviceExtension->PhysicalDeviceObject, 
						IRP_MN_SET_POWER, 
						powerState, 
						(PREQUEST_POWER_COMPLETE) PoIrpAsyncCompletionFunc, 
						DeviceExtension, 
						NULL);

			if(!NT_SUCCESS(ntStatus)) 
			{
				BulkUsb_DbgPrint(1, ("file bulkdev: PoRequestPowerIrp failed\n"));
			}
		}
	}

IdleNotificationRequestComplete_Exit:

	KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
	idleCallbackInfo = DeviceExtension->IdleCallbackInfo;
	DeviceExtension->IdleCallbackInfo = NULL;
	idleIrp = (PIRP) InterlockedExchangePointer(&DeviceExtension->PendingIdleIrp, NULL);
	InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
	KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
	if(idleCallbackInfo) 
	{
		ExFreePool(idleCallbackInfo);
	}
	if(idleIrp) 
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: completion routine has a valid irp and frees it\n"));
		IoFreeIrp(Irp);
		KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
	}
	else 
	{
		if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount)) 
		{
			BulkUsb_DbgPrint(3, ("file bulkdev: completion routine frees the irp\n"));
			IoFreeIrp(Irp);
			KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
		}
	}
	if(DeviceExtension->SSEnable) 
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: Set the timer to fire DPCs\n"));
		dueTime.QuadPart = -10000 * IDLE_INTERVAL;               // 5000 ms
		KeSetTimerEx(&DeviceExtension->Timer, 
			dueTime,
			IDLE_INTERVAL,                              // 5000 ms
			&DeviceExtension->DeferredProcCall);

		BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestCompete - ends\n"));
	}
	return STATUS_MORE_PROCESSING_REQUIRED;
}
Esempio n. 27
0
NTSTATUS BulkUsb_DispatchCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    ULONG                       i;
    NTSTATUS                    ntStatus;
    PFILE_OBJECT                fileObject;
    PTDeviceExtension           deviceExtension;
    PIO_STACK_LOCATION          irpStack;
    PTPipeContext				pipeContext;
    PUSBD_INTERFACE_INFORMATION Interface;

    PAGED_CODE();
	BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_DispatchCreate - begins\n"));
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    fileObject = irpStack->FileObject;
    deviceExtension = (PTDeviceExtension) DeviceObject->DeviceExtension;
    if(deviceExtension->DeviceState != WORKING) 
	{
        ntStatus = STATUS_INVALID_DEVICE_STATE;
        goto BulkUsb_DispatchCreate_Exit;
    }

    if(deviceExtension->UsbInterface) 
        Interface = deviceExtension->UsbInterface;
    else 
	{
        BulkUsb_DbgPrint(1, ("file bulkdev: UsbInterface not found\n"));
        ntStatus = STATUS_INVALID_DEVICE_STATE;
        goto BulkUsb_DispatchCreate_Exit;
    }

    if(fileObject) 
        fileObject->FsContext = NULL; 
    else 
	{
        ntStatus = STATUS_INVALID_PARAMETER;
        goto BulkUsb_DispatchCreate_Exit;
    }

    if(0 == fileObject->FileName.Length) 
	{
        ntStatus = STATUS_SUCCESS;
        InterlockedIncrement(&deviceExtension->OpenHandleCount);
        if(deviceExtension->SSEnable) 
		{
            CancelSelectSuspend(deviceExtension);
        }
        goto BulkUsb_DispatchCreate_Exit;
    }
    
    pipeContext = BulkUsb_PipeWithName(DeviceObject, &fileObject->FileName);
    if(pipeContext == NULL) 
	{
        ntStatus = STATUS_INVALID_PARAMETER;
        goto BulkUsb_DispatchCreate_Exit;
    }

    ntStatus = STATUS_INVALID_PARAMETER;
    for(i = 0; i < Interface->NumberOfPipes; i++) 
	{
        if(pipeContext == &deviceExtension->PipeContext[i]) 
		{
            BulkUsb_DbgPrint(3, ("file bulkdev: open pipe %d\n", i));
            fileObject->FsContext = &Interface->Pipes[i];
            ASSERT(fileObject->FsContext);
            pipeContext->PipeOpen = TRUE;
            ntStatus = STATUS_SUCCESS;
            InterlockedIncrement(&deviceExtension->OpenHandleCount);
            if(deviceExtension->SSEnable) 
			{
                CancelSelectSuspend(deviceExtension);
            }
        }
    }

BulkUsb_DispatchCreate_Exit:

    Irp->IoStatus.Status = ntStatus;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    BulkUsb_DbgPrint(3, ("file bulkdev: BulkUsb_DispatchCreate - ends\n"));
    return ntStatus;
}
Esempio n. 28
0
VOID
DevPoCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject, 
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Context,
    IN PIO_STATUS_BLOCK IoStatus
    )
/*++
 
Routine Description:

    This is the PoRequest - completion routine for the device power irp.
    This routine is responsible for completing the system power irp, 
    received as a context.

Arguments:

    DeviceObject - pointer to device object
    MinorFunction - minor function of the irp.
    PowerState - power state of the irp.
    Context - context passed to the completion routine.
    IoStatus - status of the device power irp.

Return Value:

    None

--*/
{
    PIRP                      sIrp;
    PDEVICE_EXTENSION         deviceExtension;
    PPOWER_COMPLETION_CONTEXT powerContext;
    
    //
    // initialize variables
    //

    powerContext = (PPOWER_COMPLETION_CONTEXT) Context;
    sIrp = powerContext->SIrp;
    deviceExtension = powerContext->DeviceObject->DeviceExtension;

    BulkUsb_DbgPrint(3, ("DevPoCompletionRoutine - begins\n"));

    //
    // copy the D-Irp status into S-Irp
    //

    sIrp->IoStatus.Status = IoStatus->Status;

    //
    // complete the system Irp
    //
    
    PoStartNextPowerIrp(sIrp);

    sIrp->IoStatus.Information = 0;

    IoCompleteRequest(sIrp, IO_NO_INCREMENT);

    //
    // cleanup
    //
    
    BulkUsb_DbgPrint(3, ("DevPoCompletionRoutine::"));
    BulkUsb_IoDecrement(deviceExtension);

    ExFreePool(powerContext);

    BulkUsb_DbgPrint(3, ("DevPoCompletionRoutine - ends\n"));

}
Esempio n. 29
0
NTSTATUS
SetDeviceFunctional(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

    This routine processes queue of pending irps.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
{
    KIRQL              oldIrql;
    NTSTATUS           ntStatus;
    POWER_STATE        newState;
    PIO_STACK_LOCATION irpStack;
    DEVICE_POWER_STATE newDevState,
                       oldDevState;

    //
    // initialize variables
    //

    ntStatus = Irp->IoStatus.Status;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    newState = irpStack->Parameters.Power.State;
    newDevState = newState.DeviceState;
    oldDevState = DeviceExtension->DevPower;

    BulkUsb_DbgPrint(3, ("SetDeviceFunctional - begins\n"));

    //
    // update the cached state
    //
    DeviceExtension->DevPower = newDevState;

    //
    // restore appropriate amount of state to our h/w
    // this driver does not implement partial context
    // save/restore.
    //

    PoSetPowerState(DeviceObject, DevicePowerState, newState);

    if(PowerDeviceD0 == newDevState) {

    //
    // empty existing queue of all pending irps.
    //

        KeAcquireSpinLock(&DeviceExtension->DevStateLock, &oldIrql);

        DeviceExtension->QueueState = AllowRequests;
        
        KeReleaseSpinLock(&DeviceExtension->DevStateLock, oldIrql);

        ProcessQueuedRequests(DeviceExtension);
    }

    PoStartNextPowerIrp(Irp);

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    BulkUsb_DbgPrint(3, ("SetDeviceFunctional::"));
    BulkUsb_IoDecrement(DeviceExtension);

    BulkUsb_DbgPrint(3, ("SetDeviceFunctional - ends\n"));

    return STATUS_SUCCESS;
}
Esempio n. 30
0
NTSTATUS SubmitIdleRequestIrp(IN PTDeviceExtension DeviceExtension)
{
	PIRP                    irp;
	NTSTATUS                ntStatus;
	KIRQL                   oldIrql;
	PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;
	PIO_STACK_LOCATION      nextStack;

	irp = NULL;
	idleCallbackInfo = NULL;
	BulkUsb_DbgPrint(3, ("file bulkdev: SubmitIdleRequest - process\n"));
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
	if(PowerDeviceD0 != DeviceExtension->DevPower) 
	{
//		ntStatus = STATUS_POWER_STATE_INVALID;
//		goto SubmitIdleRequestIrp_Exit;
		return STATUS_POWER_STATE_INVALID;
	}

	KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
	if(InterlockedExchange(&DeviceExtension->IdleReqPend, 1)) 
	{
		BulkUsb_DbgPrint(1, ("file bulkdev: Idle request pending..\n"));
		KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
//		ntStatus = STATUS_DEVICE_BUSY;
//		goto SubmitIdleRequestIrp_Exit;
		return STATUS_DEVICE_BUSY;
	}

	KeClearEvent(&DeviceExtension->NoIdleReqPendEvent);
	idleCallbackInfo = ExAllocatePool(NonPagedPool, sizeof(struct _USB_IDLE_CALLBACK_INFO));
	if(idleCallbackInfo) 
	{
		idleCallbackInfo->IdleCallback = IdleNotificationCallback;
		idleCallbackInfo->IdleContext = (PVOID)DeviceExtension;
		ASSERT(DeviceExtension->IdleCallbackInfo == NULL);
		DeviceExtension->IdleCallbackInfo = idleCallbackInfo;
		irp = IoAllocateIrp(DeviceExtension->TopOfStackDeviceObject->StackSize, FALSE);
		if(irp == NULL) 
		{
			BulkUsb_DbgPrint(1, ("file bulkdev: cannot build idle request irp\n"));
			KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
			InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
			KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
			ExFreePool(idleCallbackInfo);
//			ntStatus = STATUS_INSUFFICIENT_RESOURCES;
//			goto SubmitIdleRequestIrp_Exit;
			return STATUS_INSUFFICIENT_RESOURCES;
		}

		nextStack = IoGetNextIrpStackLocation(irp);
		nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
		nextStack->Parameters.DeviceIoControl.IoControlCode = 
					IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
		nextStack->Parameters.DeviceIoControl.Type3InputBuffer = idleCallbackInfo;
		nextStack->Parameters.DeviceIoControl.InputBufferLength = 
					sizeof(struct _USB_IDLE_CALLBACK_INFO);
		IoSetCompletionRoutine(irp, 
					IdleNotificationRequestComplete, 
					DeviceExtension, 
					TRUE, 
					TRUE, 
					TRUE);

		DeviceExtension->PendingIdleIrp = irp;
		DeviceExtension->FreeIdleIrpCount = 2;
		KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
		if(!CanDeviceSuspend(DeviceExtension) || PowerDeviceD0 != DeviceExtension->DevPower) 
		{
			BulkUsb_DbgPrint(1, ("file bulkdev: Device is not idle\n"));
			KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
			DeviceExtension->IdleCallbackInfo = NULL;
			DeviceExtension->PendingIdleIrp = NULL;
			KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
			InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
			KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
			if(idleCallbackInfo) 
			{
				ExFreePool(idleCallbackInfo);
			}
			if(irp) 
			{
				IoFreeIrp(irp);
			}
//			ntStatus = STATUS_UNSUCCESSFUL;
//			goto SubmitIdleRequestIrp_Exit;
			return STATUS_UNSUCCESSFUL;
		}

		BulkUsb_DbgPrint(3, ("file bulkdev: Cancel the timers\n"));
		KeCancelTimer(&DeviceExtension->Timer);
		ntStatus = IoCallDriver(DeviceExtension->TopOfStackDeviceObject, irp);
		if(!NT_SUCCESS(ntStatus)) 
		{
//			BulkUsb_DbgPrint(1, ("file bulkdev: IoCallDriver failed\n"));
//			goto SubmitIdleRequestIrp_Exit;
			return ntStatus;
		}
	}
	else 
	{
		BulkUsb_DbgPrint(1, ("file bulkdev: Memory allocation for idleCallbackInfo failed\n"));
		KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
		InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
		KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	}

//SubmitIdleRequestIrp_Exit:
	BulkUsb_DbgPrint(3, ("file bulkdev: SubmitIdleRequest - ends\n"));
	return ntStatus;
}