Exemple #1
0
static NTSTATUS UsbChief_QueuePassiveLevelCallback(IN WDFDEVICE    Device,
				   IN WDFUSBPIPE   Pipe)
{
	NTSTATUS                       status = STATUS_SUCCESS;
	PWORKITEM_CONTEXT               context;
	WDF_OBJECT_ATTRIBUTES           attributes;
	WDF_WORKITEM_CONFIG             workitemConfig;
	WDFWORKITEM                     hWorkItem;

	WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
	WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, WORKITEM_CONTEXT);
	attributes.ParentObject = Device;

	WDF_WORKITEM_CONFIG_INIT(&workitemConfig, UsbChief_ReadWriteWorkItem);

	status = WdfWorkItemCreate( &workitemConfig,
				    &attributes,
				    &hWorkItem);

	if (!NT_SUCCESS(status))
		return status;

	context = GetWorkItemContext(hWorkItem);

	context->Device = Device;
	context->Pipe = Pipe;

	WdfWorkItemEnqueue(hWorkItem);
	return STATUS_SUCCESS;
}
VOID
SimSensorTemperatureInterrupt (
    _In_ WDFDEVICE Device
    )


/*++

Routine Description:

    This routine is invoked to simulate an interrupt from the virtual sensor
    device. It performs all the work a normal ISR would perform.

Arguments:

    Device - Supplies a handle to the device.

Return Value:

    None.

--*/

{

    PFDO_DATA DevExt;

    DevExt = GetDeviceExtension(Device);
    WdfWorkItemEnqueue(DevExt->InterruptWorker);
    return;
}
Exemple #3
0
NTSTATUS
QueuePassiveLevelCallback(
  _In_ WDFDEVICE  Device,
  _In_ WDFUSBPIPE Pipe
)
/*++

Routine Description:

    This routine is used to queue workitems so that the callback
    functions can be executed at PASSIVE_LEVEL in the context of
    a system thread.

Arguments:

Return Value:

--*/
{
  NTSTATUS              status = STATUS_SUCCESS;
  PWORKITEM_CONTEXT     context;
  WDF_OBJECT_ATTRIBUTES attributes;
  WDF_WORKITEM_CONFIG   workitemConfig;
  WDFWORKITEM           hWorkItem;

  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
  WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, WORKITEM_CONTEXT);
  attributes.ParentObject = Device;

  WDF_WORKITEM_CONFIG_INIT(&workitemConfig, Rio500_EvtReadWriteWorkItem);

  status = WdfWorkItemCreate(
    &workitemConfig,
    &attributes,
    &hWorkItem
  );

  if (!NT_SUCCESS(status)) {
    return status;
  }

  context = GetWorkItemContext(hWorkItem);

  context->Device = Device;
  context->Pipe = Pipe;

  //
  // Execute this work item.
  //
  WdfWorkItemEnqueue(hWorkItem);

  return STATUS_SUCCESS;
}
Exemple #4
0
void CyapaBootTimer(_In_ WDFTIMER hTimer) {
	WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer);
	PDEVICE_CONTEXT pDevice = GetDeviceContext(Device);

	WDF_OBJECT_ATTRIBUTES attributes;
	WDF_WORKITEM_CONFIG workitemConfig;
	WDFWORKITEM hWorkItem;

	WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
	WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
	attributes.ParentObject = Device;
	WDF_WORKITEM_CONFIG_INIT(&workitemConfig, CyapaBootWorkItem);

	WdfWorkItemCreate(&workitemConfig,
		&attributes,
		&hWorkItem);

	WdfWorkItemEnqueue(hWorkItem);
	WdfTimerStop(hTimer, FALSE);
}
VOID
VIOSerialPortPnpNotify (
    IN WDFDEVICE WdfDevice,
    IN PVIOSERIAL_PORT port,
    IN BOOLEAN connected
)
{
    WDF_OBJECT_ATTRIBUTES attributes;
    WDF_WORKITEM_CONFIG   workitemConfig;
    WDFWORKITEM           hWorkItem;
    PRAWPDO_VIOSERIAL_PORT  pdoData = NULL;
    NTSTATUS              status = STATUS_SUCCESS;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);
    port->HostConnected = connected;

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, RAWPDO_VIOSERIAL_PORT);
    attributes.ParentObject = WdfDevice;
    WDF_WORKITEM_CONFIG_INIT(&workitemConfig, VIOSerialPortPnpNotifyWork);

    status = WdfWorkItemCreate( &workitemConfig,
                                 &attributes,
                                 &hWorkItem);

    if (!NT_SUCCESS(status))
    {
       TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "WdfWorkItemCreate failed with status = 0x%08x\n", status);
       return;
    }

    pdoData = RawPdoSerialPortGetData(hWorkItem);

    pdoData->port = port;

    WdfWorkItemEnqueue(hWorkItem);
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__);
}
NTSTATUS AndroidUsbPipeFileObject::QueueResetPipePassiveCallback() {
  ASSERT_IRQL_LOW_OR_DISPATCH();

  // Initialize workitem
  WDF_OBJECT_ATTRIBUTES attr;
  WDF_OBJECT_ATTRIBUTES_INIT(&attr);
  WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attr, AndroidUsbWorkitemContext);
  attr.ParentObject = wdf_device();

  WDFWORKITEM wdf_work_item = NULL;
  WDF_WORKITEM_CONFIG workitem_config;
  WDF_WORKITEM_CONFIG_INIT(&workitem_config, ResetPipePassiveCallbackEntry);
  NTSTATUS status = WdfWorkItemCreate(&workitem_config,
                                      &attr,
                                      &wdf_work_item);
  ASSERT(NT_SUCCESS(status) && (NULL != wdf_work_item));
  if (!NT_SUCCESS(status))
    return status;

  // Initialize our extension to work item
  AndroidUsbWorkitemContext* context =
    GetAndroidUsbWorkitemContext(wdf_work_item);
  ASSERT(NULL != context);
  if (NULL == context) {
    WdfObjectDelete(wdf_work_item);
    return STATUS_INTERNAL_ERROR;
  }

  context->object_type = AndroidUsbWdfObjectTypeWorkitem;
  context->pipe_file_ext = this;

  // Enqueue this work item.
  WdfWorkItemEnqueue(wdf_work_item);

  return STATUS_SUCCESS;
}
VOID
VIOSerialPortCreateName(
    IN WDFDEVICE WdfDevice,
    IN PVIOSERIAL_PORT port,
    IN PPORT_BUFFER buf
    )
{
    WDF_OBJECT_ATTRIBUTES attributes;
    WDF_WORKITEM_CONFIG   workitemConfig;
    WDFWORKITEM           hWorkItem;
    PRAWPDO_VIOSERIAL_PORT  pdoData = NULL;
    NTSTATUS              status = STATUS_SUCCESS;
    size_t                length;
    PVIRTIO_CONSOLE_CONTROL cpkt;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE, "--> %s\n", __FUNCTION__);
    cpkt = (PVIRTIO_CONSOLE_CONTROL)((ULONG_PTR)buf->va_buf + buf->offset);
    if (port && !port->NameString.Buffer)
    {
        length = buf->len - buf->offset - sizeof(VIRTIO_CONSOLE_CONTROL);
        port->NameString.Length = (USHORT)( length );
        port->NameString.MaximumLength = port->NameString.Length + 1;
        port->NameString.Buffer = (PCHAR)ExAllocatePoolWithTag(
                                 NonPagedPool,
                                 port->NameString.MaximumLength,
                                 VIOSERIAL_DRIVER_MEMORY_TAG
                                 );
        if (port->NameString.Buffer)
        {
           RtlCopyMemory(  port->NameString.Buffer,
                                 (PVOID)((LONG_PTR)buf->va_buf + buf->offset + sizeof(*cpkt)),
                                 length
                                 );
           port->NameString.Buffer[length] = '\0';
           TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "VIRTIO_CONSOLE_PORT_NAME name_size = %d %s\n", length, port->NameString.Buffer);
        }
        else
        {
           TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                                 "VIRTIO_CONSOLE_PORT_NAME: Unable to alloc string buffer\n"
                                 );
        }

        WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
        WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, RAWPDO_VIOSERIAL_PORT);
        attributes.ParentObject = WdfDevice;
        WDF_WORKITEM_CONFIG_INIT(&workitemConfig, VIOSerialPortSymbolicNameWork);

        status = WdfWorkItemCreate( &workitemConfig,
                                 &attributes,
                                 &hWorkItem);

        if (!NT_SUCCESS(status))
        {
           TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "WdfWorkItemCreate failed with status = 0x%08x\n", status);
           return;
        }

        pdoData = RawPdoSerialPortGetData(hWorkItem);

        pdoData->port = port;

        WdfWorkItemEnqueue(hWorkItem);
    }
    else
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "VIRTIO_CONSOLE_PORT_NAME invalid id = %d\n", cpkt->id);
    }
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE, "<-- %s\n", __FUNCTION__);
}
Exemple #8
0
NTSTATUS
PepScheduleWorker (
    _In_ PPEP_WORK_CONTEXT WorkContext
    )

/*++

Routine Description:

    This function schedules a worker thread to process pending work requests.

Arguments:

    WorkContext - Supplies the context of the work.

Return Value:

    NTSTATUS.

--*/

{

    WDF_OBJECT_ATTRIBUTES Attributes;
    NTSTATUS Status;
    BOOLEAN Synchronous;
    WDFWORKITEM WorkItem;
    WDF_WORKITEM_CONFIG WorkItemConfiguration;

    WorkItem = NULL;
    Synchronous = FALSE;

    //
    // Create a workitem to process events.
    //

    WDF_OBJECT_ATTRIBUTES_INIT(&Attributes);
    WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&Attributes,
                                           PEP_WORK_ITEM_CONTEXT);

    Attributes.ParentObject = PepGlobalWdfDevice;

    //
    // Initialize the handler routine and create a new workitem.
    //

    WDF_WORKITEM_CONFIG_INIT(&WorkItemConfiguration, PepWorkerWrapper);

    //
    // Disable automatic serialization by the framework for the worker thread.
    // The parent device object is being serialized at device level (i.e.,
    // WdfSynchronizationScopeDevice), and the framework requires it to be
    // passive level (i.e., WdfExecutionLevelPassive) if automatic
    // synchronization is desired.
    //

    WorkItemConfiguration.AutomaticSerialization = FALSE;

    //
    // Create the work item and queue it. If the workitem cannot be created
    // for some reason, just call the worker routine synchronously.
    //

    Status = WdfWorkItemCreate(&WorkItemConfiguration,
                               &Attributes,
                               &WorkItem);

    if (!NT_SUCCESS(Status)) {
        Synchronous = TRUE;
        TraceEvents(INFO,
                    DBG_PEP,
                    "%s: Failed to allocate work item to process pending"
                    "work! Status = %!STATUS!. Will synchronously process.\n",
                    __FUNCTION__,
                    Status);
    }

    //
    // If the operation is to be performed synchronously, then directly
    // invoke the worker routine. Otherwise, queue a workitem to run the
    // worker routine.
    //

    if (Synchronous != FALSE) {
        PepProcessPendingWorkRequests();

    } else {
        TraceEvents(INFO,
                    DBG_PEP,
                    "%s: Work request scheduled to run asynchronously. "
                    "Device=%p, WorkType=%d, NotificationId=%d.\n",
                    __FUNCTION__,
                    (PVOID)WorkContext->PepInternalDevice,
                    (ULONG)WorkContext->WorkType,
                    (ULONG)WorkContext->NotificationId);

        WdfWorkItemEnqueue(WorkItem);
    }

    return STATUS_SUCCESS;
}
VOID
BalloonInterruptDpc(
    IN WDFINTERRUPT WdfInterrupt,
    IN WDFOBJECT    WdfDevice
    )
{
    unsigned int          len;
    PDEVICE_CONTEXT       devCtx = GetDeviceContext(WdfDevice);
    PVOID                 buffer;

    BOOLEAN               bHostAck = FALSE;
    UNREFERENCED_PARAMETER( WdfInterrupt );

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "--> %s\n", __FUNCTION__);

    WdfSpinLockAcquire(devCtx->InfDefQueueLock);
    if (virtqueue_get_buf(devCtx->InfVirtQueue, &len))
    {
        bHostAck = TRUE;
    }
    if (virtqueue_get_buf(devCtx->DefVirtQueue, &len))
    {
        bHostAck = TRUE;
    }
    WdfSpinLockRelease(devCtx->InfDefQueueLock);

    if(bHostAck)
    {
        KeSetEvent (&devCtx->HostAckEvent, IO_NO_INCREMENT, FALSE);
    }

    if (devCtx->StatVirtQueue)
    {
        WdfSpinLockAcquire(devCtx->StatQueueLock);
        buffer = virtqueue_get_buf(devCtx->StatVirtQueue, &len);
        WdfSpinLockRelease(devCtx->StatQueueLock);

        if (buffer)
        {
            /*
             * According to MSDN 'Using Framework Work Items' article:
             * Create one or more work items that your driver requeues as necessary.
             * Subsequently, each time that the driver's EvtInterruptDpc callback
             * function is called it must determine if the EvtWorkItem callback
             * function has run. If the EvtWorkItem callback function has not run,
             * the EvtInterruptDpc callback function does not call WdfWorkItemEnqueue,
             * because the work item is still queued.
             * A few drivers might need to call WdfWorkItemFlush to flush their work
             * items from the work-item queue.
             *
             * For each dpc (i.e. interrupt) we'll push stats exactly that many times.
             */
            if (1==InterlockedIncrement(&devCtx->WorkCount))
            {
                WdfWorkItemEnqueue(devCtx->StatWorkItem);
            }
        }
    }

    if(devCtx->Thread)
    {
       KeSetEvent(&devCtx->WakeUpThread, 0, FALSE);
    }
}
Exemple #10
0
VOID
kmdf1394_BusResetRoutine(
                         IN PVOID    Context)
{
    WDFDEVICE device= Context;
    PDEVICE_EXTENSION deviceExtension = GetDeviceContext(device);
    NTSTATUS ntStatus    = STATUS_SUCCESS;
    WDFREQUEST request;
    WDF_WORKITEM_CONFIG workItemConfig;
    WDFWORKITEM workItem;
    WDF_OBJECT_ATTRIBUTES attributes;

    ENTER("kmdf1394_BusResetRoutine");

    TRACE(TL_TRACE, ("Context = 0x%x\n", Context));

    WDF_WORKITEM_CONFIG_INIT (&workItemConfig, kmdf1394_BusResetRoutineWorkItem);

    WDF_OBJECT_ATTRIBUTES_INIT (&attributes);
    attributes.ParentObject = device;

    ntStatus = WdfWorkItemCreate( &workItemConfig,
        &attributes,
        &workItem);
    if (!NT_SUCCESS (ntStatus)) 
    {
        TRACE(TL_ERROR, ("Failed to create workitem %x\n", ntStatus));
        return;
    }

    //
    // Execute this work item.
    //
    WdfWorkItemEnqueue (workItem);

    //
    // If we have any bus reset notify irps, then nows the
    // time to complete them.
    //
    WHILE (TRUE)
    {
        ntStatus = WdfIoQueueRetrieveNextRequest (
            deviceExtension->BusResetRequestsQueue,
            &request);
        if(NT_SUCCESS (ntStatus))
        {
            TRACE(TL_TRACE, ("Completing BusReset Request = 0x%p\n", request));
            WdfRequestCompleteWithInformation (request, STATUS_SUCCESS, 0);
            // continue;
        }
        else if (STATUS_NO_MORE_ENTRIES == ntStatus)
        {
            TRACE (TL_TRACE, ("Request Queue is empty.\n"));
            break;
        }
        else 
        {
            ASSERTMSG (
                "WdfIoQueueRetrieveNextRequest failed", 
                ntStatus);
            break;
        }
    }

    EXIT("kmdf1394_BusResetRoutine", ntStatus);
} // kmdf1394_BusResetRoutine