diff options
| author | Rajib Dutta <[email protected]> | 2017-06-08 15:55:25 -0700 |
|---|---|---|
| committer | Rajib Dutta <[email protected]> | 2017-06-08 15:55:25 -0700 |
| commit | 19fa751dea92ced9c834a6a168dc151c68d8e060 (patch) | |
| tree | 7ed310f1da4643c85f5db7ed4cb31df4e3abea03 | |
| parent | ed1df9a8b80b154b71b79635e40af75f4f19001c (diff) | |
Changes in the way UcmInitializeDevice and Ppm_CreateConnectors calls are made.
UcmInitializeDevice needs to be called from EvtDeviceAdd callbcack otherwise connect APIs may not work. Hence moving the function call to Ppm_Initialize which is called from EvtDeviceAdd callback.
Creating a work item to create connectors and enable UCSI notifications so as to not block D0 Entry and thereby boot sequence during startup.
| -rw-r--r-- | usb/UcmCxUcsi/Fdo.cpp | 103 | ||||
| -rw-r--r-- | usb/UcmCxUcsi/Fdo.h | 1 | ||||
| -rw-r--r-- | usb/UcmCxUcsi/Ppm.cpp | 9 |
3 files changed, 79 insertions, 34 deletions
diff --git a/usb/UcmCxUcsi/Fdo.cpp b/usb/UcmCxUcsi/Fdo.cpp index 88aa9129..29f19279 100644 --- a/usb/UcmCxUcsi/Fdo.cpp +++ b/usb/UcmCxUcsi/Fdo.cpp @@ -27,6 +27,7 @@ EVT_WDF_DEVICE_D0_ENTRY Fdo_EvtDeviceD0Entry; EVT_WDF_DEVICE_D0_EXIT Fdo_EvtDeviceD0Exit; EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT Fdo_EvtDeviceSelfManagedIoInit; EVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART Fdo_EvtDeviceSelfManagedIoRestart; +EVT_WDF_WORKITEM Fdo_ConnectorAndNotificationWorkItem; _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS @@ -112,8 +113,11 @@ Fdo_Initialize ( _In_ PFDO_CONTEXT FdoCtx ) { + NTSTATUS status; WDFDEVICE device; WDF_DEVICE_STATE deviceState; + WDF_WORKITEM_CONFIG workItemConfig; + WDF_OBJECT_ATTRIBUTES attributes; PAGED_CODE(); @@ -130,8 +134,27 @@ Fdo_Initialize ( deviceState.NotDisableable = WdfFalse; WdfDeviceSetDeviceState(device, &deviceState); + // + // Create a workitem that will create connectors and enable notifications + // so that we don't block D0 Entry and thereby boot sequence of the system. + // + + WDF_WORKITEM_CONFIG_INIT(&workItemConfig, Fdo_ConnectorAndNotificationWorkItem); + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = device; + + status = WdfWorkItemCreate(&workItemConfig, &attributes, &FdoCtx->ConnectorAndNotificationWorkItem); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_FDO, "[Device: 0x%p] WdfWorkItemCreate for ConnectorAndNotificationWorkItem failed - %!STATUS!", device, status); + goto Exit; + } + TRACE_INFO(TRACE_FLAG_FDO, "[Device: 0x%p] FDO initialized", device); +Exit: + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); return STATUS_SUCCESS; @@ -304,44 +327,35 @@ Fdo_EvtDeviceSelfManagedIoInit ( _In_ WDFDEVICE Device ) { - NTSTATUS status; - PPPM_CONTEXT ppmCtx; - UCM_MANAGER_CONFIG ucmConfig; + PFDO_CONTEXT fdoCtx; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); - ppmCtx = &Fdo_GetContext(Device)->PpmCtx; + fdoCtx = Fdo_GetContext(Device); - // - // Since the PPM uses a power-managed queue to handle command requests, self-managed I/O init - // is when we can start processing commands. - // + WdfWorkItemEnqueue(fdoCtx->ConnectorAndNotificationWorkItem); - UCM_MANAGER_CONFIG_INIT(&ucmConfig); + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); - // - // Initialize our device with UCM. - // + return STATUS_SUCCESS; +} - status = UcmInitializeDevice(Device, &ucmConfig); - if (!NT_SUCCESS(status)) - { - TRACE_ERROR(TRACE_FLAG_FDO, "[Device: 0x%p] UcmInitializeDevice failed - %!STATUS!", Device, status); - goto Exit; - } +NTSTATUS +Fdo_EvtDeviceSelfManagedIoRestart ( + _In_ WDFDEVICE Device + ) +{ + NTSTATUS status; + PPPM_CONTEXT ppmCtx; - status = Ucm_CreateConnectors(ppmCtx); - if (!NT_SUCCESS(status)) - { - goto Exit; - } + PAGED_CODE(); - // - // Connector objects are ready. Now we can enable all notifications. - // + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + ppmCtx = &Fdo_GetContext(Device)->PpmCtx; status = Ppm_EnableNotifications(ppmCtx); if (!NT_SUCCESS(status)) @@ -356,21 +370,33 @@ Exit: return status; } - -NTSTATUS -Fdo_EvtDeviceSelfManagedIoRestart ( - _In_ WDFDEVICE Device - ) +VOID +Fdo_ConnectorAndNotificationWorkItem( + _In_ WDFWORKITEM WorkItem +) { NTSTATUS status; PPPM_CONTEXT ppmCtx; + PFDO_CONTEXT fdoCtx; + WDFDEVICE device; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); - ppmCtx = &Fdo_GetContext(Device)->PpmCtx; + device = (WDFDEVICE)WdfWorkItemGetParentObject(WorkItem); + fdoCtx = Fdo_GetContext(device); + ppmCtx = &fdoCtx->PpmCtx; + status = Ucm_CreateConnectors(ppmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + // + // Connector objects are ready. Now we can enable all notifications. + // status = Ppm_EnableNotifications(ppmCtx); if (!NT_SUCCESS(status)) { @@ -378,8 +404,17 @@ Fdo_EvtDeviceSelfManagedIoRestart ( } Exit: + // + // Failing to create the connectors or enable notifications are both + // unrecoverable failures. Attempt to have WDF reload the driver. + // + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_FDO, "[Device: 0x%p] Failed to initialize PPM connectors - attempting to restart device.", device); + WdfDeviceSetFailed(fdoCtx->WdfDevice, WdfDeviceFailedAttemptRestart); + } - TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + TRACE_INFO(TRACE_FLAG_FDO, "[Device: 0x%p] Work item complete.", device); - return status; + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); } diff --git a/usb/UcmCxUcsi/Fdo.h b/usb/UcmCxUcsi/Fdo.h index c6f2c921..2266df26 100644 --- a/usb/UcmCxUcsi/Fdo.h +++ b/usb/UcmCxUcsi/Fdo.h @@ -26,6 +26,7 @@ typedef struct _FDO_CONTEXT ACPI_CONTEXT AcpiCtx; PPM_CONTEXT PpmCtx; + WDFWORKITEM ConnectorAndNotificationWorkItem; } FDO_CONTEXT, *PFDO_CONTEXT; diff --git a/usb/UcmCxUcsi/Ppm.cpp b/usb/UcmCxUcsi/Ppm.cpp index 522adf27..33be0be9 100644 --- a/usb/UcmCxUcsi/Ppm.cpp +++ b/usb/UcmCxUcsi/Ppm.cpp @@ -54,6 +54,7 @@ Ppm_Initialize ( WDF_IO_QUEUE_CONFIG queueConfig; WDF_IO_TARGET_OPEN_PARAMS openParams; WDF_WORKITEM_CONFIG workItemConfig; + UCM_MANAGER_CONFIG ucmConfig; PAGED_CODE(); @@ -132,6 +133,14 @@ Ppm_Initialize ( goto Exit; } + UCM_MANAGER_CONFIG_INIT(&ucmConfig); + status = UcmInitializeDevice(device, &ucmConfig); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] UcmInitializeDevice failed - %!STATUS!", device, status); + goto Exit; + } + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM initialized", device); Exit: |
