예제 #1
0
VOID
UfxDevice_Reset (
    _In_ UFXDEVICE Device
    )
/*++

Routine Description:

    Cancels all transfers and disables non-zero endpoints in
    response to USB reset.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

--*/
{
    PUFXDEVICE_CONTEXT DeviceContext;
    PREGISTERS_CONTEXT RegistersContext;
    ULONG EpIndex;

    TraceEntry();

    DeviceContext = UfxDeviceGetContext(Device);
    RegistersContext = DeviceGetRegistersContext(DeviceContext->FdoWdfDevice);

    //
    // Get EP0 back to setup stage.
    //
    TransferReset(WdfCollectionGetFirstItem(DeviceContext->Endpoints));

    //
    // Disable all non-default endpoints
    //

    // 
    // #### TODO: Insert code to disable non-default endpoints ####
    //

    //
    // End any transfers on non-default endpoints.
    //
    for (EpIndex = 1; EpIndex < WdfCollectionGetCount(DeviceContext->Endpoints); EpIndex++) {
        TransferReset(WdfCollectionGetItem(DeviceContext->Endpoints, EpIndex));
    }

    TraceExit();
}
예제 #2
0
파일: Device.cpp 프로젝트: OpenXT/xc-vusb
/**
 * @brief DPC callback.
 * Calls the Xen interface api to process the ringbuffer until the ringbuffer is empty,
 * then completes all requests provided by the Xen api.
 *
 * @todo consider completion within the XenDpc() loop. However this would release the device
 * lock.
 *
 * @param[in] Dpc The WDFDPC handle.
 *  
 */
VOID
FdoEvtDeviceDpcFunc(
    IN VOID *Context)
{
    // --XT-- FDO context passed directly now.
    PUSB_FDO_CONTEXT fdoContext = (PUSB_FDO_CONTEXT)Context;
    //
    // this stuff needs to be done at DPC level in order to complete irps.
    //
    ULONG passes = 0;
    AcquireFdoLock(fdoContext);

    if (fdoContext->InDpc)
    {
        fdoContext->DpcOverLapCount++;
        ReleaseFdoLock(fdoContext);
        return;
    }
    fdoContext->InDpc = TRUE;

    BOOLEAN moreWork;
    do
    {
        moreWork = XenDpc(fdoContext, fdoContext->RequestCollection);
        passes++;
        if (fdoContext->DpcOverLapCount)
        {
            fdoContext->totalDpcOverLapCount += fdoContext->DpcOverLapCount;
            fdoContext->DpcOverLapCount = 0;
            moreWork = TRUE;
        }
        if (moreWork & (passes >= KeQueryActiveProcessorCount(NULL)))
        {
            //
            // reschedule the dpc to prevent starvation.
            //
            // --XT-- WdfDpcEnqueue(fdoContext->WdfDpc);
            //
            // --XT-- Schedule through the Xen interface now.
            //
            XenScheduleDPC(fdoContext->Xen);
            TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DPC,
                __FUNCTION__": enqueue dpc at %d passes\n",
                passes);
            fdoContext->totalDpcReQueueCount++;
            break;
        }

    } while (moreWork);
 
    fdoContext->InDpc = FALSE; // allow another dpc instance to run and add to the collection.
    if (passes > fdoContext->maxDpcPasses)
    {
        fdoContext->maxDpcPasses = passes;
    }
    //
    // complete all queued Irps. Note that this section is re-entrant.
    // Note also that all of these requests have been "uncanceled" and ahve
    // been marked as completed in their request contexts and that the
    // additional reference on the request object has been removed.
    // The collection can be safely completed with no race conditions.
    //
    ULONG responseCount = 0;
    WDFREQUEST Request;
    while ((Request = (WDFREQUEST) WdfCollectionGetFirstItem(fdoContext->RequestCollection)) != NULL)
    {
        WdfCollectionRemoveItem(fdoContext->RequestCollection, 0);

        TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DPC,
            __FUNCTION__": complete Request %p Status %x\n",
            Request,
            WdfRequestWdmGetIrp(Request)->IoStatus.Status);
        
        ReleaseFdoLock(fdoContext);

        WdfRequestCompleteWithPriorityBoost(Request,
            WdfRequestWdmGetIrp(Request)->IoStatus.Status,
            IO_SOUND_INCREMENT);
        
        AcquireFdoLock(fdoContext);

        responseCount++;
    }

    if (responseCount > fdoContext->maxRequestsProcessed)
    {
        fdoContext->maxRequestsProcessed = responseCount;
    }
    //
    // fire up any queued requests
    //    
    DrainRequestQueue(fdoContext, FALSE);

    ReleaseFdoLock(fdoContext);

    // --XT-- this trace was way too noisy, made it verbose.
    TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DPC,
        __FUNCTION__": exit responses processed %d passes %d\n",
        responseCount,
        passes);
}
예제 #3
0
파일: Device.cpp 프로젝트: OpenXT/xc-vusb
/**
 * @brief Allocate a workitem from or for our collection of workitems.
 * Must be called with the device lock held.
 * 
 * @param[in] Device handle to the WDFDEVICE created by FdoEvtDeviceAdd.
 * @param[in] callback only optional if this is add device doing an allocation!
 * @param[in] Param0 arbitrary context data
 * @param[in] Param1 arbitrary context data
 * @param[in] Param2 arbitrary context data
 * @param[in] Param3 arbitrary context data
 * 
 * @returns a WDFWORKITEM handle or NULL on failure.
 * 
 */
WDFWORKITEM
NewWorkItem(
    IN PUSB_FDO_CONTEXT fdoContext,
    IN PFN_WDF_WORKITEM  callback, 
    IN ULONG_PTR Param0,
    IN ULONG_PTR Param1,
    IN ULONG_PTR Param2,
    IN ULONG_PTR Param3)
{
    //
    // First try to get a workitem from our collection of them.
    //    
    WDFWORKITEM  WorkItem = (WDFWORKITEM) WdfCollectionGetFirstItem(fdoContext->FreeWorkItems);
    if (WorkItem == NULL)
    {
        //
        // ok - allocate a new one.
        //
        TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DEVICE,
            __FUNCTION__": Device %p FreeWorkItems is empty, init count %d\n",
            fdoContext->WdfDevice,
            INIT_WORK_ITEM_COUNT);

        NTSTATUS  status = STATUS_SUCCESS;
        WDF_OBJECT_ATTRIBUTES  attributes;
        WDF_WORKITEM_CONFIG  workitemConfig;

        WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
        WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(
            &attributes,
            USB_FDO_WORK_ITEM_CONTEXT);

        attributes.ParentObject = fdoContext->WdfDevice;

        WDF_WORKITEM_CONFIG_INIT(
            &workitemConfig,
            EvtFdoDeviceGenericWorkItem);

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

        if (!NT_SUCCESS(status)) 
        {
            TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
                __FUNCTION__": WdfWorkItemCreate error %x\n",
                status);
            return NULL;
        }
    }
    else
    {
        // note that WdfCollectionGetFirstItem doesn't remove it from the collection.
        WdfCollectionRemove(fdoContext->FreeWorkItems, WorkItem);
    }
    if (WorkItem)
    {
        // initialize it.
        PUSB_FDO_WORK_ITEM_CONTEXT  context = WorkItemGetContext(WorkItem);
        context->FdoContext = fdoContext;
        context->CallBack = callback;
        context->Params[0] = Param0;
        context->Params[1] = Param1;
        context->Params[2] = Param2;
        context->Params[3] = Param3;
    }
    return WorkItem;
}