VOID StopAllPipes( IN PDEVICE_CONTEXT DeviceContext ) { WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->InterruptPipe), WdfIoTargetCancelSentIo); WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkReadPipe), WdfIoTargetCancelSentIo); WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkWritePipe), WdfIoTargetCancelSentIo); }
NTSTATUS OsrFxEvtDeviceD0Exit( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE TargetState ) /*++ Routine Description: This routine undoes anything done in EvtDeviceD0Entry. It is called whenever the device leaves the D0 state, which happens when the device is stopped, when it is removed, and when it is powered off. The device is still in D0 when this callback is invoked, which means that the driver can still touch hardware in this routine. EvtDeviceD0Exit event callback must perform any operations that are necessary before the specified device is moved out of the D0 state. If the driver needs to save hardware state before the device is powered down, then that should be done here. This function runs at PASSIVE_LEVEL, though it is generally not paged. A driver can optionally make this function pageable if DO_POWER_PAGABLE is set. Even if DO_POWER_PAGABLE isn't set, this function still runs at PASSIVE_LEVEL. In this case, though, the function absolutely must not do anything that will cause a page fault. Arguments: Device - Handle to a framework device object. TargetState - Device power state which the device will be put in once this callback is complete. Return Value: Success implies that the device can be used. Failure will result in the device stack being torn down. --*/ { PDEVICE_CONTEXT pDeviceContext; PAGED_CODE(); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "-->OsrFxEvtDeviceD0Exit - moving to %s\n", DbgDevicePowerString(TargetState)); pDeviceContext = GetDeviceContext(Device); WdfIoTargetStop(WdfUsbTargetDeviceGetIoTarget(pDeviceContext->UsbDevice), WdfIoTargetCancelSentIo); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtDeviceD0Exit\n"); return STATUS_SUCCESS; }
NTSTATUS EvtDeviceD0Exit( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE TargetState ) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_CONTEXT devCtx = NULL; devCtx = GetDeviceContext(Device); KdPrint((__DRIVER_NAME "Device D0 Exit. Going to %s\n", PowerName(TargetState))); /*Save the state of the LED array if the device is waking up from a D3 power state.*/ if(TargetState == PowerDeviceD3) { status = llGetLightBar(devCtx, devCtx->WdfMemLEDArrayState); if(!NT_SUCCESS(status)) return status; } // Dung viec gui gui cac lenh dang pending qua ong interrupt WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(devCtx->UsbInterruptPipe), WdfIoTargetLeaveSentIoPending); return status; }
NTSTATUS AndroidUsbDeviceObject::OnEvtDeviceReleaseHardware( WDFCMRESLIST resources_translated) { ASSERT_IRQL_PASSIVE(); // It's possible that Preparehardware failed half way thru. So make // sure the target device exists. if (!IsTaretDeviceCreated()) return STATUS_SUCCESS; // Cancel all the currently queued I/O. This is better than sending an // explicit USB abort request down because release hardware gets // called even when the device surprise-removed. WdfIoTargetStop(WdfUsbTargetDeviceGetIoTarget(wdf_target_device()), WdfIoTargetCancelSentIo); // Unselect all selected configurations WDF_USB_DEVICE_SELECT_CONFIG_PARAMS config_params; WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_DECONFIG(&config_params); NTSTATUS status = WdfUsbTargetDeviceSelectConfig(wdf_target_device(), WDF_NO_OBJECT_ATTRIBUTES, &config_params); ASSERT(NT_SUCCESS(status) || (STATUS_DEVICE_NOT_CONNECTED == status)); return status; }
static VOID UsbChief_StopAllPipes(IN PDEVICE_CONTEXT DeviceContext) { UCHAR count,i; count = DeviceContext->NumberConfiguredPipes; for (i = 0; i < count; i++) { WDFUSBPIPE pipe; pipe = WdfUsbInterfaceGetConfiguredPipe(DeviceContext->UsbInterface, i, NULL); WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pipe), WdfIoTargetCancelSentIo); } }
/* This routine undoes anything done in EvtDeviceD0Entry. It is called whenever the device leaves the D0 state, which happens when the device is stopped, when it is removed, and when it is powered off. The device is still in D0 when this callback is invoked, which means that the driver can still touch hardware in this routine. EvtDeviceD0Exit event callback must perform any operations that are necessary before the specified device is moved out of the D0 state. If the driver needs to save hardware state before the device is powered down, then that should be done here. This function runs at PASSIVE_LEVEL, though it is generally not paged. A driver can optionally make this function pageable if DO_POWER_PAGABLE is set. Even if DO_POWER_PAGABLE isn't set, this function still runs at PASSIVE_LEVEL. In this case, though, the function absolutely must not do anything that will cause a page fault. */ NTSTATUS HidFx2EvtDeviceD0Exit(_In_ WDFDEVICE hDevice, _In_ WDF_POWER_DEVICE_STATE targetState) { PDEVICE_EXTENSION pDevContext; PAGED_CODE(); TraceVerbose(DBG_PNP, "(%!FUNC!) Enter- moving to %S\n", DbgDevicePowerString(targetState)); pDevContext = GetDeviceContext(hDevice); WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDevContext->hInterruptPipe), WdfIoTargetCancelSentIo); TraceVerbose(DBG_PNP, "(%!FUNC!) Exit\n"); return STATUS_SUCCESS; }
// 此函数类似于WDM中的PNP_MN_STOP_DEVICE函数,在设备移除时被调用。 // 当个函数被调用时候,设备仍处于工作状态。 NTSTATUS DrvClass::PnpReleaseHardware(IN WDFCMRESLIST ResourceListTranslated) { KDBG(DPFLTR_INFO_LEVEL, "[PnpReleaseHardware]"); // 如果PnpPrepareHardware调用失败,UsbDevice为空; // 这时候直接返回即可。 if (m_hUsbDevice == NULL) return STATUS_SUCCESS; // 取消USB设备的所有IO操作。它将连带取消所有Pipe的IO操作。 WdfIoTargetStop(WdfUsbTargetDeviceGetIoTarget(m_hUsbDevice), WdfIoTargetCancelSentIo); // Deconfiguration或者“反配置” WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_DECONFIG(&configParams); return WdfUsbTargetDeviceSelectConfig(m_hUsbDevice, WDF_NO_OBJECT_ATTRIBUTES, &configParams); }
/////////////////////////////////////////////////////////////////////////////// // // BasicUsbEvtDeviceD0Exit // // This routine is called by the framework when a device of // the type we support is leaving the D0 state // // INPUTS: // // Device - One of our WDFDEVICE objects // // PreviousState - The D-State we're entering // // OUTPUTS: // // None. // // RETURNS: // // STATUS_SUCCESS, otherwise an error indicating why the driver could not // load. // // IRQL: // // This routine is called at IRQL == PASSIVE_LEVEL. // // NOTES: // // /////////////////////////////////////////////////////////////////////////////// NTSTATUS BasicUsbEvtDeviceD0Exit( IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE TargetState ) { PBASICUSB_DEVICE_CONTEXT devContext; WDFIOTARGET interruptIoTarget; UNREFERENCED_PARAMETER(TargetState); #if DBG DbgPrint("BasicUsbEvtDeviceD0Exit\n"); #endif devContext = BasicUsbGetContextFromDevice(Device); // // It is our responsibility to stop the continous reader before // leaving D0. // // // First, ge the I/O target associated with our INT IN pipe. // interruptIoTarget = WdfUsbTargetPipeGetIoTarget(devContext->InterruptInPipe); // // And stop the I/O target, leaving any outstanding requests // pending. // // Note that if we're leaving D0 because we're being removed // the framework will cancel all the requests and clean up // the I/O target for us. // WdfIoTargetStop(interruptIoTarget, WdfIoTargetLeaveSentIoPending); return STATUS_SUCCESS; }
NTSTATUS OsrFxEvtDeviceD0Entry( WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState ) /*++ Routine Description: EvtDeviceD0Entry event callback must perform any operations that are necessary before the specified device is used. It will be called every time the hardware needs to be (re-)initialized. This function is not marked pageable because this function is in the device power up path. When a function is marked pagable and the code section is paged out, it will generate a page fault which could impact the fast resume behavior because the client driver will have to wait until the system drivers can service this page fault. This function runs at PASSIVE_LEVEL, even though it is not paged. A driver can optionally make this function pageable if DO_POWER_PAGABLE is set. Even if DO_POWER_PAGABLE isn't set, this function still runs at PASSIVE_LEVEL. In this case, though, the function absolutely must not do anything that will cause a page fault. Arguments: Device - Handle to a framework device object. PreviousState - Device power state which the device was in most recently. If the device is being newly started, this will be PowerDeviceUnspecified. Return Value: NTSTATUS --*/ { PDEVICE_CONTEXT pDeviceContext; NTSTATUS status; BOOLEAN isTargetStarted; pDeviceContext = GetDeviceContext(Device); isTargetStarted = FALSE; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "-->OsrFxEvtEvtDeviceD0Entry - coming from %s\n", DbgDevicePowerString(PreviousState)); // // Since continuous reader is configured for this interrupt-pipe, we must explicitly start // the I/O target to get the framework to post read requests. // status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe)); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_POWER, "Failed to start interrupt pipe %!STATUS!\n", status); goto End; } isTargetStarted = TRUE; End: if (!NT_SUCCESS(status)) { // // Failure in D0Entry will lead to device being removed. So let us stop the continuous // reader in preparation for the ensuing remove. // if (isTargetStarted) { WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo); } } TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtEvtDeviceD0Entry\n"); return status; }