VOID
VIOSerialCtrlWorkHandler(
    IN WDFDEVICE Device
)
{
    struct virtqueue *vq;
    PPORT_BUFFER buf;
    UINT len;
    NTSTATUS  status = STATUS_SUCCESS;
    PPORTS_DEVICE pContext = GetPortsDevice(Device);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> %s\n", __FUNCTION__);

    vq = pContext->c_ivq;
    ASSERT(vq);

    WdfSpinLockAcquire(pContext->CInVqLock);
    while ((buf = virtqueue_get_buf(vq, &len)))
    {
        WdfSpinLockRelease(pContext->CInVqLock);
        buf->len = len;
        buf->offset = 0;
        VIOSerialHandleCtrlMsg(Device, buf);

        WdfSpinLockAcquire(pContext->CInVqLock);
        status = VIOSerialAddInBuf(vq, buf);
        if (!NT_SUCCESS(status))
        {
           TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "%s::%d Error adding buffer to queue\n", __FUNCTION__, __LINE__);
           VIOSerialFreeBuffer(buf);
        }
    }
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s\n", __FUNCTION__);
    WdfSpinLockRelease(pContext->CInVqLock);
}
VOID
VIOSerialPortClose(
    IN WDFFILEOBJECT FileObject
    )
{
    PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData(
        WdfFileObjectGetDevice(FileObject));

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

    if (!pdoData->port->Removed && pdoData->port->GuestConnected)
    {
        VIOSerialSendCtrlMsg(pdoData->port->BusDevice, pdoData->port->PortId,
            VIRTIO_CONSOLE_PORT_OPEN, 0);
    }
    pdoData->port->GuestConnected = FALSE;

    WdfSpinLockAcquire(pdoData->port->InBufLock);
    VIOSerialDiscardPortDataLocked(pdoData->port);
    WdfSpinLockRelease(pdoData->port->InBufLock);

    WdfSpinLockAcquire(pdoData->port->OutVqLock);
    VIOSerialReclaimConsumedBuffers(pdoData->port);
    WdfSpinLockRelease(pdoData->port->OutVqLock);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE,
        "<-- %s\n", __FUNCTION__);
}
NTSTATUS
VIOSerialFillQueue(
    IN struct virtqueue *vq,
    IN WDFSPINLOCK Lock
)
{
    NTSTATUS     status = STATUS_SUCCESS;
    PPORT_BUFFER buf = NULL;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "--> %s\n", __FUNCTION__);

    for (;;)
    {
        buf = VIOSerialAllocateBuffer(PAGE_SIZE);
        if(buf == NULL)
        {
           TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "VIOSerialAllocateBuffer failed\n");
           return STATUS_INSUFFICIENT_RESOURCES;
        }

        WdfSpinLockAcquire(Lock);
        status = VIOSerialAddInBuf(vq, buf);
        if(!NT_SUCCESS(status))
        {
           VIOSerialFreeBuffer(buf);
           WdfSpinLockRelease(Lock);
           break;
        }
        WdfSpinLockRelease(Lock);
    }
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "<-- %s\n", __FUNCTION__);
    return STATUS_SUCCESS;
}
/* Source: WDK/src_5239/kmdf/1394/isochapi.c, line 1178. */
void
t1394_IsochTimeout(
    PDEVICE_EXTENSION   DeviceExtension, /* added for SLAyer */
/*     IN PKDPC                Dpc, */
    /* IN */ PISOCH_DETACH_DATA   IsochDetachData/* , */
/*     IN PVOID                SystemArgument1, */
/*     IN PVOID                SystemArgument2 */
    )
{
/*     PDEVICE_EXTENSION   DeviceExtension; */

/*     UNREFERENCED_PARAMETER(Dpc); */
/*     UNREFERENCED_PARAMETER(SystemArgument1); */
/*     UNREFERENCED_PARAMETER(SystemArgument2); */

/*     ENTER("t1394_IsochTimeout"); */
/*     TRACE(TL_WARNING, ("Isoch Timeout!\n")); */

    //
    // ISSUE: the device extension we are referencing comes from the IsochDetachData
    // but it is possible this memory has been freed before we enter this function.
    // The only way to check is to validate against our DeviceExtension->IsochDetachList
    // but if the IsochDetachData has been freed then that won't be accessible
    //
/*     DeviceExtension = IsochDetachData->DeviceExtension; */
    if (DeviceExtension)
    {
        // make sure nobody else has already handled this request yet

		WdfSpinLockAcquire(DeviceExtension->IsochSpinLock);
        if (t1394_IsOnList(&IsochDetachData->IsochDetachList, &DeviceExtension->IsochDetachData))
        {
            RemoveEntryList(&IsochDetachData->IsochDetachList);

			WdfSpinLockRelease(DeviceExtension->IsochSpinLock);


/*             if(KeCancelTimer(&IsochDetachData->Timer)) */
            {

/*                 TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData = 0x%x\n", IsochDetachData)); */
/*                 TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData->Irp = 0x%x\n", IsochDetachData->Request)); */
/*                 TRACE(TL_TRACE, ("IsochTimeout: IsochDetachData->newIrp = 0x%x\n", IsochDetachData->newIrp)); */

                // need to save the status of the attach
                // we'll clean up in the same spot for success's and timeout's
/*                 IsochDetachData->AttachStatus = STATUS_TIMEOUT; */
                t1394_IsochCleanup(IsochDetachData);
            }
        }
        else
        {

			WdfSpinLockRelease(DeviceExtension->IsochSpinLock);

        }
    }

/*     EXIT("t1394_IsochTimeout", 0); */
} // t1394_IsochTimeout
NTSTATUS
VIOSerialPortEvtDeviceD0Exit(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE TargetState
    )
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(Device)->port;
    PPORT_BUFFER buf;
    PSINGLE_LIST_ENTRY iter;

    UNREFERENCED_PARAMETER(TargetState);

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

    WdfIoQueuePurge(Port->ReadQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);
    WdfIoQueuePurge(Port->WriteQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);
    WdfIoQueuePurge(Port->IoctlQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);

    VIOSerialDisableInterruptQueue(GetInQueue(Port));

    WdfSpinLockAcquire(Port->InBufLock);
    VIOSerialDiscardPortDataLocked(Port);
    Port->InBuf = NULL;
    WdfSpinLockRelease(Port->InBufLock);

    WdfSpinLockAcquire(Port->OutVqLock);
    VIOSerialReclaimConsumedBuffers(Port);
    WdfSpinLockRelease(Port->OutVqLock);

    while (buf = (PPORT_BUFFER)VirtIODeviceDetachUnusedBuf(GetInQueue(Port)))
    {
        VIOSerialFreeBuffer(buf);
    }

    iter = PopEntryList(&Port->WriteBuffersList);
    while (iter != NULL)
    {
        PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter,
            WRITE_BUFFER_ENTRY, ListEntry);

        ExFreePoolWithTag(entry->Buffer, VIOSERIAL_DRIVER_MEMORY_TAG);
        ExFreePoolWithTag(entry, VIOSERIAL_DRIVER_MEMORY_TAG);

        iter = PopEntryList(&Port->WriteBuffersList);
    };

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__);

    return STATUS_SUCCESS;
}
VOID
VIOSerialPortIoStop(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN ULONG      ActionFlags
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(Queue));
    PVIOSERIAL_PORT    pport = pdoData->port;

    ASSERT(pport->PendingReadRequest == Request);
    TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "-->%s\n", __FUNCTION__);

    WdfSpinLockAcquire(pport->InBufLock);
    if (ActionFlags &  WdfRequestStopActionSuspend )
    {
        WdfRequestStopAcknowledge(Request, FALSE);
    }
    else if(ActionFlags &  WdfRequestStopActionPurge)
    {
        if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED)
        {
           pport->PendingReadRequest = NULL;
           WdfRequestCompleteWithInformation(Request , STATUS_CANCELLED, 0L);
        }
    }
    WdfSpinLockRelease(pport->InBufLock);
    return;
}
VOID VIOSerialPortWriteRequestCancel(IN WDFREQUEST Request)
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(
        WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)))->port;
    PSINGLE_LIST_ENTRY iter;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s Request: 0x%p\n",
        __FUNCTION__, Request);

    // synchronize with VIOSerialReclaimConsumedBuffers because the pending
    // request is not guaranteed to be alive after we return from this callback
    WdfSpinLockAcquire(Port->OutVqLock);
    iter = &Port->WriteBuffersList;
    while ((iter = iter->Next) != NULL)
    {
        PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter, WRITE_BUFFER_ENTRY, ListEntry);
        if (entry->Request == Request)
        {
            entry->Request = NULL;
            break;
        }
    }
    WdfSpinLockRelease(Port->OutVqLock);

    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
VOID
VIOSerialPortReadRequestCancel(
    IN WDFREQUEST Request
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)));
    BOOLEAN reqComplete = FALSE;

    TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "-->%s called on request 0x%p\n", __FUNCTION__, Request);

    WdfSpinLockAcquire(pdoData->port->InBufLock);
    ASSERT(pdoData->port->PendingReadRequest == Request);
    if (pdoData->port->PendingReadRequest)
    {
        pdoData->port->PendingReadRequest = NULL;
        reqComplete = TRUE;
    }
    WdfSpinLockRelease(pdoData->port->InBufLock);

    if (reqComplete)
    {
        WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);
    }
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE,"<-- %s\n", __FUNCTION__);
    return;
}
Example #9
0
VOID
BusDogTraceFifoCleanUp(
    VOID
    )
{
    ULONG i;

    PAGED_CODE ();

    //
    // Clean up anything in the trace fifo
    //

    WdfSpinLockAcquire(BusDogTraceFifoLock);

    for (i = 0; i < BUSDOG_FILTER_TRACE_FIFO_LENGTH; i++)
    {
        if (BusDogTraceFifo.TraceItems[i] != NULL)
        {
            ExFreePool(BusDogTraceFifo.TraceItems[i]);

            BusDogTraceFifo.TraceItems[i] = NULL;
        }
    }

    BusDogTraceFifo.WriteIndex = 0;

    BusDogTraceFifo.ReadIndex = 0;

    WdfSpinLockRelease(BusDogTraceFifoLock);
}
Example #10
0
VOID VIOSerialPortWriteIoStop(IN WDFQUEUE Queue,
                              IN WDFREQUEST Request,
                              IN ULONG ActionFlags)
{
   PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData(
      WdfIoQueueGetDevice(Queue));
   PVIOSERIAL_PORT pport = pdoData->port;

   TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "--> %s\n", __FUNCTION__);

   WdfSpinLockAcquire(pport->OutVqLock);
   if (ActionFlags & WdfRequestStopActionSuspend)
   {
      WdfRequestStopAcknowledge(Request, FALSE);
   }
   else if (ActionFlags & WdfRequestStopActionPurge)
   {
      if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED)
      {
         pport->PendingWriteRequest = NULL;
         WdfRequestComplete(Request, STATUS_OBJECT_NO_LONGER_EXISTS);
      }
   }
   WdfSpinLockRelease(pport->OutVqLock);

   TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
static NTSTATUS
HIDKeyboardSendStatus(
    PINPUT_DEVICE pContext,
    USHORT uType,
    USHORT uCode,
    ULONG uValue,
    WDFREQUEST Request)
{
    PVIRTIO_INPUT_EVENT_WITH_REQUEST pEvent;
    NTSTATUS status;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s\n", __FUNCTION__);

    pEvent = VIOInputAlloc(sizeof(VIRTIO_INPUT_EVENT_WITH_REQUEST));
    if (pEvent == NULL)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        pEvent->Event.type = uType;
        pEvent->Event.code = uCode;
        pEvent->Event.value = uValue;
        pEvent->Request = Request;

        WdfSpinLockAcquire(pContext->StatusQLock);
        status = VIOInputAddOutBuf(pContext->StatusQ, &pEvent->Event);
        WdfSpinLockRelease(pContext->StatusQLock);
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);
    return status;
}
Example #12
0
VOID
NICFreeQueuedSendPackets(
    IN  PFDO_DATA  FdoData
    )
/*++
Routine Description:

    Free and complete the pended sends on SendQueueHead

    Assumption: This function is called with the Send SPINLOCK held.

Arguments:

    FdoData     Pointer to our FdoData

Return Value:

     None

--*/
{
    WDFREQUEST   request;
    NTSTATUS     status;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> NICFreeQueuedSendPackets\n");

    do {
        status = WdfIoQueueRetrieveNextRequest(
                     FdoData->PendingWriteQueue,
                     &request
                     );

        if(!NT_SUCCESS(status) ) {
            if(STATUS_NO_MORE_ENTRIES != status){
                TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                    "WdfIoQueueRetrieveNextRequest failed %x\n", status);
            }
            break;
        }

        FdoData->nWaitSend--;

        WdfSpinLockRelease(FdoData->SendLock);

        WdfRequestCompleteWithInformation(request, status, 0);

        WdfSpinLockAcquire(FdoData->SendLock);

    } WHILE (TRUE);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "<-- NICFreeQueuedSendPackets\n");

}
Example #13
0
__inline
VOID
MP_FREE_SEND_PACKET(
    IN  PFDO_DATA   FdoData,
    IN  PMP_TCB     pMpTcb,
    IN  NTSTATUS    Status
    )
/*++
Routine Description:

    Recycle a MP_TCB and complete the packet if necessary

    Assumption: This function is called with the Send SPINLOCK held.

Arguments:

    FdoData     Pointer to our FdoData
    pMpTcb      Pointer to MP_TCB

Return Value:

    None

--*/
{

    WDFREQUEST          request;
    WDFDMATRANSACTION   dmaTransaction;
    size_t              length;

    ASSERT(MP_TEST_FLAG(pMpTcb, fMP_TCB_IN_USE));

    dmaTransaction = pMpTcb->DmaTransaction;
    pMpTcb->DmaTransaction = NULL;

    MP_CLEAR_FLAGS(pMpTcb);

    FdoData->CurrSendHead = FdoData->CurrSendHead->Next;
    FdoData->nBusySend--;

    request = WdfDmaTransactionGetRequest(dmaTransaction);
    length  = WdfDmaTransactionGetBytesTransferred(dmaTransaction);

    WdfObjectDelete( dmaTransaction );

    if (request)
    {
        WdfSpinLockRelease(FdoData->SendLock);
        WdfRequestCompleteWithInformation(request, Status, length);
        FdoData->BytesTransmitted += length;

        WdfSpinLockAcquire(FdoData->SendLock);
    }
}
Example #14
0
VOID
PepPendWorkRequest (
    _In_ PPEP_WORK_CONTEXT WorkRequest
    )

/*++

Routine Description:

    This routine adds the given work request to the pending queue.

Arguments:

    WorkRequest - Supplies a pointer to the work request.

Return Value:

    None.

--*/

{

    //
    // Ensure that the request is not already on some other queue.
    //

    NT_ASSERT(IsListEmpty(&WorkRequest->ListEntry) != FALSE);

    TraceEvents(INFO,
                DBG_PEP,
                "%s: Insert pending work request. "
                "Device=%p, WorkType=%d, NotificationId=%d.\n",
                __FUNCTION__,
                (PVOID)WorkRequest->PepInternalDevice,
                (ULONG)WorkRequest->WorkType,
                (ULONG)WorkRequest->NotificationId);

    //
    // Add the new request to the end of tail of the pending work queue.
    //

    WdfSpinLockAcquire(PepWorkListLock);
    InsertTailList(&PepPendingWorkList, &WorkRequest->ListEntry);
    WdfSpinLockRelease(PepWorkListLock);

    //
    // Schedule a worker to pick up the new work.
    //

    PepScheduleWorker(WorkRequest);
    return;
}
Example #15
0
VOID
UfxDeviceSetRunStop (
    _In_ UFXDEVICE UfxDevice,
    _In_ BOOLEAN Set
    )
/*++

Routine Description:

    Function that sets or clears the run/stop state on the controller.  Setting the
    run state will initiate a connect to the host.

Arguments:

    UfxDevice - Wdf object representing the UFXDEVICE

    Set - TRUE if setting the run state, FALSE if clearing the run state.

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;
    PUFXDEVICE_CONTEXT DeviceContext;
    BOOLEAN EventComplete;


    TraceEntry();

    DeviceContext = UfxDeviceGetContext(UfxDevice);
    ControllerContext = DeviceGetControllerContext(DeviceContext->FdoWdfDevice);

    EventComplete = TRUE;

    WdfSpinLockAcquire(ControllerContext->DpcLock);

    if (Set) {
        //
        // #### TODO: Insert code to set the run state on the controller ####
        //
    } else {
        //
        // #### TODO: Insert code to clear the run state on the controller ####
        //
    }

    WdfSpinLockRelease(ControllerContext->DpcLock);

    if (EventComplete) {
        UfxDeviceEventComplete(UfxDevice, STATUS_SUCCESS);
    }

    TraceExit();
}
size_t VIOSerialSendBuffers(IN PVIOSERIAL_PORT Port,
                            IN PVOID Buffer,
                            IN size_t Length)
{
    struct virtqueue *vq = GetOutQueue(Port);
    struct VirtIOBufferDescriptor sg[QUEUE_DESCRIPTORS];
    PVOID buffer = Buffer;
    size_t length = Length;
    int out = 0;
    int ret;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> %s Buffer: %p Length: %d\n", __FUNCTION__, Buffer, Length);

    if (BYTES_TO_PAGES(Length) > QUEUE_DESCRIPTORS)
    {
        return 0;
    }

    while (length > 0)
    {
        sg[out].physAddr = MmGetPhysicalAddress(buffer);
        sg[out].length = min(length, PAGE_SIZE);

        buffer = (PVOID)((LONG_PTR)buffer + sg[out].length);
        length -= sg[out].length;
        out += 1;
    }

    WdfSpinLockAcquire(Port->OutVqLock);

    ret = virtqueue_add_buf(vq, sg, out, 0, Buffer, NULL, 0);
    virtqueue_kick(vq);

    if (ret >= 0)
    {
        Port->OutVqFull = (ret == 0);
    }
    else
    {
        Length = 0;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                    "Error adding buffer to queue (ret = %d)\n", ret);
    }

    WdfSpinLockRelease(Port->OutVqLock);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);

    return Length;
}
Example #17
0
VOID
VIOSerialSendCtrlMsg(
    IN WDFDEVICE Device,
    IN ULONG id,
    IN USHORT event,
    IN USHORT value
)
{
    struct VirtIOBufferDescriptor sg;
    struct virtqueue *vq;
    UINT len;
    PPORTS_DEVICE pContext = GetPortsDevice(Device);
    VIRTIO_CONSOLE_CONTROL cpkt;
    int cnt = 0;
    if (!pContext->isHostMultiport)
    {
        return;
    }

    vq = pContext->c_ovq;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s vq = %p\n", __FUNCTION__, vq);

    cpkt.id = id;
    cpkt.event = event;
    cpkt.value = value;

    sg.physAddr = MmGetPhysicalAddress(&cpkt);
    sg.ulSize = sizeof(cpkt);

    WdfSpinLockAcquire(pContext->CVqLock);
    if(0 <= vq->vq_ops->add_buf(vq, &sg, 1, 0, &cpkt, NULL, 0))
    {
        vq->vq_ops->kick(vq);
        while(!vq->vq_ops->get_buf(vq, &len))
        {
           KeStallExecutionProcessor(50);
           if(++cnt > RETRY_THRESHOLD)
           {
              TraceEvents(TRACE_LEVEL_FATAL, DBG_PNP, "<-> %s retries = %d\n", __FUNCTION__, cnt);
              break;
           }
        }
    }
    WdfSpinLockRelease(pContext->CVqLock);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s cnt = %d\n", __FUNCTION__, cnt);
}
Example #18
0
NTSTATUS 
BusDogFufillRequestWithTraces(
    IN WDFREQUEST Request,
    OUT size_t* bytesWritten
    )
{
    NTSTATUS status;    

    WdfSpinLockAcquire(BusDogTraceFifoLock);

    status = __BusDogFufillRequestWithTraces(Request, bytesWritten);

    WdfSpinLockRelease(BusDogTraceFifoLock);

    return status;
}
void
BthEchoConnectionObjectDisconnectCompletion(
    _In_ WDFREQUEST  Request,
    _In_ WDFIOTARGET  Target,
    _In_ PWDF_REQUEST_COMPLETION_PARAMS  Params,
    _In_ WDFCONTEXT  Context
    )
/*++

Description:

    Completion routine for disconnect BRB completion

    In this routine we set the connection to disconnect
    and set the DisconnectEvent.

Arguments:

    Request - Request completed
    Target - Target to which request was sent
    Params - Completion parameters
    Context - We receive connection as the context

--*/
{
    PBTHECHO_CONNECTION connection = (PBTHECHO_CONNECTION) Context;

    UNREFERENCED_PARAMETER(Request);
    UNREFERENCED_PARAMETER(Target);
    UNREFERENCED_PARAMETER(Params);

    WdfSpinLockAcquire(connection->ConnectionLock);
    connection->ConnectionState = ConnectionStateDisconnected;
    WdfSpinLockRelease(connection->ConnectionLock);

    //
    // Disconnect complete, set the event
    //

    KeSetEvent(
        &connection->DisconnectEvent,
        0,
        FALSE
        );    
}
Example #20
0
NTSTATUS
VIOSerialPortEvtDeviceD0Exit(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE TargetState
    )
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(Device)->port;
    PPORT_BUFFER buf;
    PSINGLE_LIST_ENTRY iter;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s TargetState: %d\n",
        __FUNCTION__, TargetState);

    Port->Removed = TRUE;

    VIOSerialDisableInterruptQueue(GetInQueue(Port));

    WdfSpinLockAcquire(Port->InBufLock);
    VIOSerialDiscardPortDataLocked(Port);
    Port->InBuf = NULL;
    WdfSpinLockRelease(Port->InBufLock);

    VIOSerialReclaimConsumedBuffers(Port);

    while (buf = (PPORT_BUFFER)virtqueue_detach_unused_buf(GetInQueue(Port)))
    {
        VIOSerialFreeBuffer(buf);
    }

    iter = PopEntryList(&Port->WriteBuffersList);
    while (iter != NULL)
    {
        PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter,
            WRITE_BUFFER_ENTRY, ListEntry);

        ExFreePoolWithTag(entry->Buffer, VIOSERIAL_DRIVER_MEMORY_TAG);
        WdfObjectDelete(entry->EntryHandle);

        iter = PopEntryList(&Port->WriteBuffersList);
    };

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__);

    return STATUS_SUCCESS;
}
Example #21
0
VOID VIOSerialPortWriteRequestCancel(IN WDFREQUEST Request)
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(
        WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)))->port;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s Request: 0x%p\n",
        __FUNCTION__, Request);

    // synchronize with VIOSerialReclaimConsumedBuffers because the pending
    // request is not guaranteed to be alive after we return from this callback
    WdfSpinLockAcquire(Port->OutVqLock);
    Port->PendingWriteRequest = NULL;
    WdfSpinLockRelease(Port->OutVqLock);

    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
VOID
VIOSerialPortCreate(
    IN WDFDEVICE WdfDevice,
    IN WDFREQUEST Request,
    IN WDFFILEOBJECT FileObject
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfDevice);
    NTSTATUS                status  = STATUS_SUCCESS;

    UNREFERENCED_PARAMETER(FileObject);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE,
        "%s Port id = %d\n", __FUNCTION__, pdoData->port->PortId);

    if (pdoData->port->Removed)
    {
        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE,
            "Connect request on removed port id %d\n", pdoData->port->PortId);
        status = STATUS_OBJECT_NO_LONGER_EXISTS;
    }
    else if (pdoData->port->GuestConnected == TRUE)
    {
        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE,
            "Guest already connected to port id %d\n", pdoData->port->PortId);
        status = STATUS_OBJECT_NAME_EXISTS;
    }
    else
    {
        pdoData->port->GuestConnected = TRUE;

        WdfSpinLockAcquire(pdoData->port->OutVqLock);
        VIOSerialReclaimConsumedBuffers(pdoData->port);
        WdfSpinLockRelease(pdoData->port->OutVqLock);

        VIOSerialSendCtrlMsg(pdoData->port->BusDevice, pdoData->port->PortId,
            VIRTIO_CONSOLE_PORT_OPEN, 1);
    }

    WdfRequestComplete(Request, status);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CREATE_CLOSE,
        "<-- %s\n", __FUNCTION__);
}
Example #23
0
VOID
VIOSerialPortReadRequestCancel(
    IN WDFREQUEST Request
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)));

    TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "-->%s called on request 0x%p\n", __FUNCTION__, Request);

    // synchronize with VIOSerialQueuesInterruptDpc because the pending
    // request is not guaranteed to be alive after we return from this callback
    WdfSpinLockAcquire(pdoData->port->InBufLock);
    pdoData->port->PendingReadRequest = NULL;
    WdfSpinLockRelease(pdoData->port->InBufLock);

    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
BOOLEAN
VIOSerialWillWriteBlock(
    IN PVIOSERIAL_PORT port
)
{
    BOOLEAN ret = FALSE;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"--> %s\n", __FUNCTION__);
    if (!port->HostConnected)
    {
        return TRUE;
    }

    WdfSpinLockAcquire(port->OutVqLock);
    VIOSerialReclaimConsumedBuffers(port);
    ret = port->OutVqFull;
    WdfSpinLockRelease(port->OutVqLock);
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"<-- %s\n", __FUNCTION__);
    return ret;
}
Example #25
0
VOID VirtRngEvtRequestCancel(IN WDFREQUEST Request)
{
    PDEVICE_CONTEXT context = GetDeviceContext(WdfIoQueueGetDevice(
        WdfRequestGetIoQueue(Request)));
    PSINGLE_LIST_ENTRY iter;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ,
        "--> %!FUNC! Cancelled Request: %p", Request);

    WdfSpinLockAcquire(context->VirtQueueLock);

    WdfRequestComplete(Request, STATUS_CANCELLED);

    iter = &context->ReadBuffersList;
    while (iter->Next != NULL)
    {
        PREAD_BUFFER_ENTRY entry = CONTAINING_RECORD(iter->Next,
            READ_BUFFER_ENTRY, ListEntry);

        if (Request == entry->Request)
        {
            TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ,
                "Clear entry %p request.", entry);

            entry->Request = NULL;
            break;
        }
        else
        {
            iter = iter->Next;
        }
    };

    WdfSpinLockRelease(context->VirtQueueLock);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "<-- %!FUNC!");
}
Example #26
0
VOID VIOSerialPortWriteIoStop(IN WDFQUEUE Queue,
                              IN WDFREQUEST Request,
                              IN ULONG ActionFlags)
{
   PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData(
      WdfIoQueueGetDevice(Queue));
   PVIOSERIAL_PORT pport = pdoData->port;

   TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "--> %s\n", __FUNCTION__);

   WdfSpinLockAcquire(pport->OutVqLock);
   if (ActionFlags & WdfRequestStopActionSuspend)
   {
      WdfRequestStopAcknowledge(Request, FALSE);
   }
   else if (ActionFlags & WdfRequestStopActionPurge)
   {
      if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED)
      {
         PSINGLE_LIST_ENTRY iter = &pport->WriteBuffersList;
         while ((iter = iter->Next) != NULL)
         {
            PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter, WRITE_BUFFER_ENTRY, ListEntry);
            if (entry->Request == Request)
            {
               entry->Request = NULL;
               break;
            }
         }
         WdfRequestComplete(Request, STATUS_OBJECT_NO_LONGER_EXISTS);
      }
   }
   WdfSpinLockRelease(pport->OutVqLock);

   TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
Example #27
0
VOID
BusDogAddTraceToFifo(
    WDFDEVICE device,
    ULONG DeviceId,
    BUSDOG_REQUEST_TYPE Type,
    BUSDOG_REQUEST_PARAMS Params,
    PVOID TraceBuffer,
    ULONG BufferLength
    )
{
    PBUSDOG_FILTER_TRACE_FIFO_ITEM pTraceItem = NULL; 
    WDFREQUEST request;
    NTSTATUS status;

    WdfSpinLockAcquire(BusDogTraceFifoLock);

    //
    // First add trace to the fifo
    //

    pTraceItem = BusDogTraceFifo.TraceItems[BusDogTraceFifo.WriteIndex];

    pTraceItem = 
        __BusDogCreateTrace(
            pTraceItem,
            DeviceId,
            Type,
            Params,
            TraceBuffer,
            BufferLength);

    BusDogTraceFifo.TraceItems[BusDogTraceFifo.WriteIndex] = 
        pTraceItem;

    BusDogTraceFifo.WriteIndex++;

    if (BusDogTraceFifo.WriteIndex >= BUSDOG_FILTER_TRACE_FIFO_LENGTH)
        BusDogTraceFifo.WriteIndex = 0;

    if (BusDogTraceFifo.WriteIndex == BusDogTraceFifo.ReadIndex)
    {
        BusDogPrint(BUSDOG_DEBUG_ERROR, "On noes! We have overflow\n");
    }

    //
    // Now see if we can complete a request from the manual queue
    //
    
    status = WdfIoQueueRetrieveNextRequest(
            BufferRequestQueue,
            &request);

    if (NT_SUCCESS(status))
    {
        size_t bytesWritten;

        status = __BusDogFufillRequestWithTraces(request, &bytesWritten);

        //
        // Ok for better or worse we finally completed this request
        //

        WdfRequestCompleteWithInformation(request, status, bytesWritten);
    }
    else
    {
        if (status != STATUS_NO_MORE_ENTRIES)
        {
            BusDogPrint(BUSDOG_DEBUG_ERROR, "WdfIoQueueRetrieveNextRequest failed - 0x%x\n",
                status);
        }
    }

    WdfSpinLockRelease(BusDogTraceFifoLock);
}
Example #28
0
BOOLEAN
NICEvtProgramDmaFunction(
    IN  WDFDMATRANSACTION       Transaction,
    IN  WDFDEVICE               Device,
    IN  PVOID                   Context,
    IN  WDF_DMA_DIRECTION       Direction,
    IN  PSCATTER_GATHER_LIST    ScatterGather
    )
/*++

Routine Description:

Arguments:

Return Value:

--*/
{
    PFDO_DATA           fdoData;
    WDFREQUEST          request;
    NTSTATUS            status;

    UNREFERENCED_PARAMETER( Context );
    UNREFERENCED_PARAMETER( Direction );

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> NICEvtProgramDmaFunction\n");

    fdoData = FdoGetData(Device);
    request = WdfDmaTransactionGetRequest(Transaction);


    WdfSpinLockAcquire(fdoData->SendLock);

    //
    // If tcb or link is not available, queue the request
    //
    if (!MP_TCB_RESOURCES_AVAIABLE(fdoData))
    {
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "Resource is not available: queue Request %p\n", request);

        //
        // Must abort the transaction before deleting.
        //
        (VOID) WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
        ASSERT(NT_SUCCESS(status));
        WdfObjectDelete( Transaction );

        //
        // Queue the request for later processing.
        //
        status = WdfRequestForwardToIoQueue(request,
                                           fdoData->PendingWriteQueue);

        if(!NT_SUCCESS(status)) {
            ASSERTMSG(" WdfRequestForwardToIoQueue failed ", FALSE);
            WdfSpinLockRelease(fdoData->SendLock);
            WdfRequestCompleteWithInformation(request, STATUS_UNSUCCESSFUL, 0);
            return FALSE;
        }
        fdoData->nWaitSend++;

    } else {

        status = NICWritePacket(fdoData, Transaction, ScatterGather);

        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                        "<-- NICEvtProgramDmaFunction returning %!STATUS!\n",
                        status);
            //
            // Must abort the transaction before deleting.
            //
            (VOID )WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
            ASSERT(NT_SUCCESS(status));
            WdfObjectDelete( Transaction );

            WdfSpinLockRelease(fdoData->SendLock);
            WdfRequestCompleteWithInformation(request, STATUS_UNSUCCESSFUL, 0);
            return FALSE;
        }
    }


    WdfSpinLockRelease(fdoData->SendLock);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "<-- NICEvtProgramDmaFunction\n");

    return TRUE;
}
Example #29
0
/* Source: WDK/src_5239/kmdf/1394/pnp.c, line 634. */
VOID
t1394_EvtDeviceSelfManagedIoCleanup(
/*     IN  WDFDEVICE Device */
    PDEVICE_EXTENSION   deviceExtension /* added for SLAyer */
    )
{
     PLIST_ENTRY         listEntry;

    //
    // Remove any isoch resource data
    //
    WHILE (TRUE) {

        WdfSpinLockAcquire(deviceExtension->IsochResourceSpinLock);

        if (!IsListEmpty(&deviceExtension->IsochResourceData)) {

            PISOCH_RESOURCE_DATA    IsochResourceData = NULL;

/* SLAyer: memory unsafety in original code. Reported as Windows 8 Bug #59410. Fixed by Patrick Maninger 9/Aug/2010.  */
	    listEntry = RemoveHeadList(&deviceExtension->CromData);

            IsochResourceData = CONTAINING_RECORD(listEntry,
						  ISOCH_RESOURCE_DATA,
						  IsochResourceList);

            WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock);

/*             TRACE(TL_TRACE, ("Surprise Removal: IsochResourceData = 0x%x\n", */
/*                              IsochResourceData)); */

            if (IsochResourceData) {

                PIRB          pIrb;
                WDFREQUEST    request;
	         NTSTATUS status;

/*                 TRACE(TL_TRACE, ("Surprise Removal: Freeing hResource = 0x%x\n", */
/*                                  IsochResourceData->hResource)); */

                status = WdfRequestCreate(
                    WDF_NO_OBJECT_ATTRIBUTES,
                    deviceExtension->StackIoTarget,
                    &request);

                if (!NT_SUCCESS(status)) {
/*                     TRACE(TL_ERROR, ("Failed to allocate request %x\n", status)); */
			free(IsochResourceData); /* SLAyer: added */
                }
                else {

                    pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_1394);

                    if (!pIrb) {

                        WdfObjectDelete(request);

/*                         TRACE(TL_ERROR, ("Failed to allocate pIrb!\n")); */
			free(IsochResourceData); /* SLAyer: added */
                    }
                    else {

                        RtlZeroMemory (pIrb, sizeof (IRB));
                        pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
                        pIrb->Flags = 0;
                        pIrb->u.IsochFreeResources.hResource = IsochResourceData->hResource;

                        status = t1394_SubmitIrpSynch(deviceExtension->StackIoTarget, request, pIrb);
			free(IsochResourceData); /* SLAyer: added */

                        if (!NT_SUCCESS(status)) {

/*                             TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", status)); */
                        }

                        ExFreePool(pIrb);
                        WdfObjectDelete(request);
                    }
                }
            }
        }
        else {


            WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock);
            break;
        }
    }

/*     EXIT("t1394_PnpRemoveDevice", STATUS_SUCCESS); */

}
VOID
VIOSerialPortRead(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN size_t     Length
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(Queue));
    size_t             length;
    NTSTATUS           status;
    PVOID              systemBuffer;
    BOOLEAN            nonBlock;

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

    nonBlock = ((WdfFileObjectGetFlags(WdfRequestGetFileObject(Request)) & FO_SYNCHRONOUS_IO) != FO_SYNCHRONOUS_IO);

    status = WdfRequestRetrieveOutputBuffer(Request, Length, &systemBuffer, &length);
    if (!NT_SUCCESS(status))
    {
        WdfRequestComplete(Request, status);
        return;
    }

	WdfSpinLockAcquire(pdoData->port->InBufLock);

	if (!VIOSerialPortHasDataLocked(pdoData->port))
    {
        if (!pdoData->port->HostConnected)
        {
           WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES);
        }
		else
		{
			ASSERT (pdoData->port->PendingReadRequest == NULL);
			status = WdfRequestMarkCancelableEx(Request,
				VIOSerialPortReadRequestCancel);
			if (!NT_SUCCESS(status))
			{
				WdfRequestComplete(Request, status);
			}
			else
			{
				pdoData->port->PendingReadRequest = Request;
			}
		}
    }
    else
    {
        length = (ULONG)VIOSerialFillReadBufLocked(pdoData->port, systemBuffer, length);
        if (length)
        {
           WdfRequestCompleteWithInformation(Request, status, (ULONG_PTR)length);
        }
        else
        {
           WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES);
        }
    }
    WdfSpinLockRelease(pdoData->port->InBufLock);
    
	TraceEvents(TRACE_LEVEL_INFORMATION, DBG_READ,"<-- %s\n", __FUNCTION__);
    return;
}