summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajib Dutta <[email protected]>2017-06-08 15:55:25 -0700
committerRajib Dutta <[email protected]>2017-06-08 15:55:25 -0700
commit19fa751dea92ced9c834a6a168dc151c68d8e060 (patch)
tree7ed310f1da4643c85f5db7ed4cb31df4e3abea03
parented1df9a8b80b154b71b79635e40af75f4f19001c (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.cpp103
-rw-r--r--usb/UcmCxUcsi/Fdo.h1
-rw-r--r--usb/UcmCxUcsi/Ppm.cpp9
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: