VOID
SerialTimeoutImmediate(
    IN WDFTIMER Timer
    )
{

    PSERIAL_DEVICE_EXTENSION Extension = NULL;

    Extension = SerialGetDeviceExtension(WdfTimerGetParentObject(Timer));

    SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_IOCTLS, ">SerialTimeoutImmediate(%p)\n",
                     Extension);

    SerialTryToCompleteCurrent(
        Extension,
        SerialGrabImmediateFromIsr,
        STATUS_TIMEOUT,
        &Extension->CurrentImmediateRequest,
        NULL,
        NULL,
        Extension->ImmediateTotalTimer,
        NULL,
        SerialGetNextImmediate,
        SERIAL_REF_TOTAL_TIMER
        );

    SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_IOCTLS, "<SerialTimeoutImmediate\n");
}
Example #2
0
File: write.c Project: ms-iot/bsp
/*++

Routine Description:

    This routine is merely used to truely complete an xoff counter request.  It
    assumes that the status and the information fields of the request are
    already correctly filled in.

Arguments:

    Dpc - Not Used.

    DeferredContext - Really points to the device extension.

    SystemContext1 - Not Used.

    SystemContext2 - Not Used.

Return Value:

    None.

--*/
_Use_decl_annotations_
VOID
SerialCompleteXoff(
    WDFDPC Dpc
    )
{

    PSERIAL_DEVICE_EXTENSION extension = NULL;

    extension = SerialGetDeviceExtension(WdfDpcGetParentObject(Dpc));

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "++SerialCompleteXoff(%p)\r\n",
                     extension);

    SerialTryToCompleteCurrent(extension,
                                NULL,
                                STATUS_SUCCESS,
                                &extension->CurrentXoffRequest,
                                NULL, NULL,
                                extension->XoffCountTimer,
                                NULL, NULL,
                                SERIAL_REF_ISR);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "--SerialCompleteXoff\r\n");
}
VOID
SerialCompleteImmediate(
    IN WDFDPC Dpc
    )

{

    PSERIAL_DEVICE_EXTENSION Extension = NULL;

    Extension = SerialGetDeviceExtension(WdfDpcGetParentObject(Dpc));

    SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_IOCTLS, ">SerialCompleteImmediate(%p)\n",
                     Extension);

    SerialTryToCompleteCurrent(
        Extension,
        NULL,
        STATUS_SUCCESS,
        &Extension->CurrentImmediateRequest,
        NULL,
        NULL,
        Extension->ImmediateTotalTimer,
        NULL,
        SerialGetNextImmediate,
        SERIAL_REF_ISR
        );

    SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_IOCTLS, "<SerialCompleteImmediate\n");

}
Example #4
0
File: write.c Project: ms-iot/bsp
/*++

Routine Description:

    This routine will try to timeout the current write.

Arguments:

Return Value:

    None.

--*/
_Use_decl_annotations_
VOID
SerialWriteTimeout(
    WDFTIMER Timer
    )
{
    PSERIAL_DEVICE_EXTENSION extension = NULL;

    extension = SerialGetDeviceExtension(WdfTimerGetParentObject(Timer));

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "++SerialWriteTimeout(%p)\r\n",
                     extension);

    SerialTryToCompleteCurrent(extension,
                                SerialGrabWriteFromIsr,
                                STATUS_TIMEOUT,
                                &extension->CurrentWriteRequest,
                                extension->WriteQueue,
                                NULL,
                                extension->WriteRequestTotalTimer,
                                SerialStartWrite,
                                SerialGetNextWrite,
                                SERIAL_REF_TOTAL_TIMER);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "--SerialWriteTimeout\r\n");
}
Example #5
0
File: write.c Project: ms-iot/bsp
/*++

Routine Description:

    This routine is merely used to complete any write.  It
    assumes that the status and the information fields of
    the request are already correctly filled in.

Arguments:

    Dpc - Not Used.

    DeferredContext - Really points to the device extension.

    SystemContext1 - Not Used.

    SystemContext2 - Not Used.

Return Value:

    None.

--*/
_Use_decl_annotations_
VOID
SerialCompleteWrite(
    WDFDPC Dpc
    )
{
    PSERIAL_DEVICE_EXTENSION Extension = NULL;

    Extension = SerialGetDeviceExtension(WdfDpcGetParentObject(Dpc));

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "++SerialCompleteWrite(%p) DPC\r\n",
                     Extension);

    SerialTryToCompleteCurrent(Extension,
                               NULL,
                               STATUS_SUCCESS,
                               &Extension->CurrentWriteRequest,
                               Extension->WriteQueue,
                               NULL,
                               Extension->WriteRequestTotalTimer,
                               SerialStartWrite,
                               SerialGetNextWrite,
                               SERIAL_REF_ISR);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "--SerialCompleteWrite DPC\r\n");
}
VOID
SerialCancelImmediate(
    IN WDFREQUEST Request
    )

/*++

Routine Description:

    This routine is used to cancel a request that is waiting on
    a comm event.

Arguments:

    Request - Pointer to the WDFREQUEST for the current request

Return Value:

    None.

--*/

{
    PSERIAL_DEVICE_EXTENSION Extension = NULL;
    WDFDEVICE  device = WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request));

    UNREFERENCED_PARAMETER(Request);

    Extension = SerialGetDeviceExtension(device);

    SerialTryToCompleteCurrent(
        Extension,
        SerialGrabImmediateFromIsr,
        STATUS_CANCELLED,
        &Extension->CurrentImmediateRequest,
        NULL,
        NULL,
        Extension->ImmediateTotalTimer,
        NULL,
        SerialGetNextImmediate,
        SERIAL_REF_CANCEL
        );

}
Example #7
0
File: write.c Project: ms-iot/bsp
/*++

Routine Description:

    This routine is merely used to truely complete an xoff counter request,
    if its timer has run out.

Arguments:


Return Value:

    None.

--*/
_Use_decl_annotations_
VOID
SerialTimeoutXoff(
    WDFTIMER Timer
    )
{

    PSERIAL_DEVICE_EXTENSION extension = NULL;

    extension = SerialGetDeviceExtension(WdfTimerGetParentObject(Timer));

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "++SerialTimeoutXoff(%p)\r\n", extension);

    SerialTryToCompleteCurrent(extension,
                                SerialGrabXoffFromIsr,
                                STATUS_SERIAL_COUNTER_TIMEOUT,
                                &extension->CurrentXoffRequest,
                                NULL, NULL, NULL,
                                NULL, NULL,
                                SERIAL_REF_TOTAL_TIMER);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "--SerialTimeoutXoff\r\n");
}
Example #8
0
File: write.c Project: ms-iot/bsp
/*++

Routine Description:

    This routine is used to cancel the current write.

Arguments:

    Device - Wdf handle for the device

    Request - Pointer to the WDFREQUEST to be canceled.

Return Value:

    None.

--*/
_Use_decl_annotations_
VOID
SerialCancelCurrentXoff(
    WDFREQUEST Request
    )
{
    PSERIAL_DEVICE_EXTENSION extension;
    WDFDEVICE device = WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request));

    UNREFERENCED_PARAMETER(Request);

    extension = SerialGetDeviceExtension(device);

    SerialTryToCompleteCurrent(extension,
                                SerialGrabXoffFromIsr,
                                STATUS_CANCELLED,
                                &extension->CurrentXoffRequest,
                                NULL,
                                NULL,
                                extension->XoffCountTimer,
                                NULL,
                                NULL,
                                SERIAL_REF_CANCEL);
}
Example #9
0
File: write.c Project: ms-iot/bsp
/*++

Routine Description:

    This routine is used to start off any write.  It initializes
    the Iostatus fields of the request.  It will set up any timers
    that are used to control the write.

Arguments:

    Extension - Points to the serial device extension

Return Value:

--*/
_Use_decl_annotations_
VOID
SerialStartWrite(
    PSERIAL_DEVICE_EXTENSION Extension
    )
{

    LARGE_INTEGER    totalTime;
    BOOLEAN          useAtimer;
    SERIAL_TIMEOUTS  timeouts;
    PREQUEST_CONTEXT reqContext;
    PREQUEST_CONTEXT reqContextXoff;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE,
                     "++SerialStartWrite(%p)\r\n", Extension);

    totalTime.QuadPart = 0;

    do {

        reqContext = SerialGetRequestContext(Extension->CurrentWriteRequest);

        // If there is an xoff counter then complete it.

        // We see if there is a actually an Xoff counter request.
        //
        // If there is, we put the write request back on the head
        // of the write list.  We then complete the xoff counter.
        // The xoff counter completing code will actually make the
        // xoff counter back into the current write request, and
        // in the course of completing the xoff (which is now
        // the current write) we will restart this request.

        if (Extension->CurrentXoffRequest) {

            reqContextXoff =
                SerialGetRequestContext(Extension->CurrentXoffRequest);

            if (SERIAL_REFERENCE_COUNT(reqContextXoff)) {

                // The reference count is non-zero.  This implies that
                // the xoff request has not made it through the completion
                // path yet.  We will increment the reference count
                // and attempt to complete it ourseleves.

                SERIAL_SET_REFERENCE(reqContextXoff, SERIAL_REF_XOFF_REF);

                reqContextXoff->Information = 0;

                // The following call will actually release the
                // cancel spin lock.

                SerialTryToCompleteCurrent(Extension,
                                            SerialGrabXoffFromIsr,
                                            STATUS_SERIAL_MORE_WRITES,
                                            &Extension->CurrentXoffRequest,
                                            NULL,
                                            NULL,
                                            Extension->XoffCountTimer,
                                            NULL,
                                            NULL,
                                            SERIAL_REF_XOFF_REF);

            } else {

                // The request is well on its way to being finished.
                // We can let the regular completion code do the
                // work.  Just release the spin lock.

            }

        }

        useAtimer = FALSE;

        // Calculate the timeout value needed for the
        // request.  Note that the values stored in the
        // timeout record are in milliseconds.  Note that
        // if the timeout values are zero then we won't start
        // the timer.

        timeouts = Extension->timeouts;

        if (timeouts.WriteTotalTimeoutConstant ||
            timeouts.WriteTotalTimeoutMultiplier) {

            useAtimer = TRUE;

            // We have some timer values to calculate.
            //
            // Take care, we might have an xoff counter masquerading
            // as a write.

            totalTime.QuadPart =((LONGLONG)((UInt32x32To64((reqContext->MajorFunction == IRP_MJ_WRITE)?
                                                    (reqContext->Length) : (1),
                                                    timeouts.WriteTotalTimeoutMultiplier)
                                                    + timeouts.WriteTotalTimeoutConstant)))
                                                    * -10000;
        }

        // The request may be going to the isr shortly.  Now
        // is a good time to initialize its reference counts.

        SERIAL_INIT_REFERENCE(reqContext);

         // We give the request to to the isr to write out.
         // We set a cancel routine that knows how to
         // grab the current write away from the isr.

         SerialSetCancelRoutine(Extension->CurrentWriteRequest,
                                 SerialCancelCurrentWrite);

        if (useAtimer) {
            BOOLEAN result;

            result = SerialSetTimer(Extension->WriteRequestTotalTimer,
                                    totalTime);

            if(result == FALSE) {
                
                // This timer now has a reference to the request.

                SERIAL_SET_REFERENCE(reqContext, SERIAL_REF_TOTAL_TIMER );
            }
        }

        WdfInterruptSynchronize(Extension->WdfInterrupt,
                                SerialGiveWriteToIsr,
                                Extension);

    } while (FALSE);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "--SerialStartWrite\r\n");
    return;
}