[COMMIT] [vioserial] use buffered mode for data transfer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 6ae78d9f9c49fc22120d1a96f9012f2aa69ed485 Mon Sep 17 00:00:00 2001
From: Vadim Rozenfeld <vrozenfe@xxxxxxxxxx>
Date: Mon, 16 May 2011 14:32:37 +0300
Subject: [COMMIT] [vioserial] use buffered mode for data transfer

---
 vioserial/sys/Control.c |    1 +
 vioserial/sys/Device.c  |   19 ---
 vioserial/sys/IsrDpc.c  |   54 +++-----
 vioserial/sys/Port.c    |  328
+++++++++++++++++++----------------------------
 vioserial/sys/vioser.h  |   20 +---
 5 files changed, 160 insertions(+), 262 deletions(-)

diff --git a/vioserial/sys/Control.c b/vioserial/sys/Control.c
index 1d0a849..329feb4 100644
--- a/vioserial/sys/Control.c
+++ b/vioserial/sys/Control.c
@@ -1,5 +1,6 @@
 #include "precomp.h"
 #include "vioser.h"
+#include "public.h"
 
 #if defined(EVENT_TRACING)
 #include "Control.tmh"
diff --git a/vioserial/sys/Device.c b/vioserial/sys/Device.c
index cd262fd..27769b6 100644
--- a/vioserial/sys/Device.c
+++ b/vioserial/sys/Device.c
@@ -176,7 +176,6 @@ VIOSerialEvtDevicePrepareHardware(
     PPORTS_DEVICE pContext = GetPortsDevice(Device);
     bool bPortFound = FALSE;
     NTSTATUS status = STATUS_SUCCESS;
-    WDF_DMA_ENABLER_CONFIG dmaConfig;
     UINT nr_ports;
     PAGED_CODE();
 
@@ -249,24 +248,6 @@ VIOSerialEvtDevicePrepareHardware(
                                 "VirtIOConsoleConfig->max_nr_ports %d
\n", pContext->consoleConfig.max_nr_ports);
     }
 
-    pContext->MaximumTransferLength = PORT_MAXIMUM_TRANSFER_LENGTH;
-    WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
-                                 WdfDmaProfileScatterGather64Duplex,
-                                 pContext->MaximumTransferLength );
-
-    status = WdfDmaEnablerCreate(Device,
-                                 &dmaConfig,
-                                 WDF_NO_OBJECT_ATTRIBUTES,
-                                 &pContext->DmaEnabler
-                                 );
-
-    if (!NT_SUCCESS (status))
-    {
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
-                        "WdfDmaEnablerCreate failed: 0x%x\n", status);
-        return status;
-    }
-
     if(pContext->isHostMultiport)
     {
         WDF_OBJECT_ATTRIBUTES  attributes;
diff --git a/vioserial/sys/IsrDpc.c b/vioserial/sys/IsrDpc.c
index 6dfadf6..fe78658 100644
--- a/vioserial/sys/IsrDpc.c
+++ b/vioserial/sys/IsrDpc.c
@@ -33,7 +33,6 @@ VIOSerialInterruptDpc(
     PPORTS_DEVICE    pContext;
     PVIOSERIAL_PORT  port;
     WDFDEVICE        Device;
-    WDFDMATRANSACTION dmaTransaction;
 
 
     ULONG            information;
@@ -41,7 +40,6 @@ VIOSerialInterruptDpc(
     PUCHAR           systemBuffer;
     size_t           Length;
     WDFREQUEST       request;
-    BOOLEAN          nonBlock;
 
     TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, "--> %s\n",
__FUNCTION__);
 
@@ -61,50 +59,40 @@ VIOSerialInterruptDpc(
         {
            struct virtqueue    *out_vq = GetOutQueue(port);
            WdfSpinLockAcquire(port->InBufLock);
-           if (!port->GuestConnected)
-           {
-              VIOSerialDiscardPortData(port);
-           }
            if (!port->InBuf)
            {
               port->InBuf = VIOSerialGetInBuf(port);
               TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "%s::%d
port->InBuf = %p\n", __FUNCTION__, __LINE__, port->InBuf);
            }
+           if (!port->GuestConnected)
+           {
+              VIOSerialDiscardPortData(port);
+           }
            WdfSpinLockRelease(port->InBufLock);
 
-           if (!VIOSerialWillReadBlock(port))
+           if (port->InBuf)
            {
-              status =
WdfIoQueueRetrieveNextRequest(port->PendingReadQueue, &request);
-              if (NT_SUCCESS(status))
+              if (port->PendingReadRequest)
               {
-                 TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,"Got
available read request\n");
-                 status = WdfRequestRetrieveOutputBuffer(request, 0,
&systemBuffer, &Length);
-                 if (NT_SUCCESS(status))
+                 request = port->PendingReadRequest;
+                 status = WdfRequestUnmarkCancelable(request);
+                 if (status != STATUS_CANCELLED)
                  {
-                    information = (ULONG)VIOSerialFillReadBuf(port,
systemBuffer, Length);
-                    WdfRequestCompleteWithInformation(request,
STATUS_SUCCESS, information);
+                    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,"Got
available read request\n");
+                    status = WdfRequestRetrieveOutputBuffer(request, 0,
&systemBuffer, &Length);
+                    if (NT_SUCCESS(status))
+                    {
+                       port->PendingReadRequest = NULL;
+                       information = (ULONG)VIOSerialFillReadBuf(port,
systemBuffer, Length);
+                       WdfRequestCompleteWithInformation(request,
STATUS_SUCCESS, information);
+                    }
+                 }
+                 else
+                 {
+                    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,
"Request = %p was cancelled\n", request);
                  }
               }
            }
-
-           if(out_vq && out_vq->vq_ops->get_buf(out_vq, &len))
-           {
-              BOOLEAN transactionComplete;
-              dmaTransaction = port->WriteDmaTransaction;
-              transactionComplete =
WdfDmaTransactionDmaCompleted( dmaTransaction,
-                                                         &status );
-
-              if (transactionComplete)
-              {
-                 WdfSpinLockAcquire(port->OutVqLock);
-                 VIOSerialReclaimConsumedBuffers(port);
-                 WdfSpinLockRelease(port->OutVqLock);
-                 TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,
-                                     "Completing Write request in the
DpcForIsr");
-                 VIOSerialPortWriteRequestComplete( dmaTransaction,
status );
-              }
-           }
-
         }
     }
     TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, "<-- %s\n",
__FUNCTION__);
diff --git a/vioserial/sys/Port.c b/vioserial/sys/Port.c
index ec55da1..719bc10 100644
--- a/vioserial/sys/Port.c
+++ b/vioserial/sys/Port.c
@@ -6,8 +6,10 @@
 #include "Port.tmh"
 #endif
 
-EVT_WDF_WORKITEM VIOSerialPortSendPortReady;
-EVT_WDF_WORKITEM VIOSerialPortCreateSymbolicName;
+EVT_WDF_WORKITEM VIOSerialPortPortReadyWork;
+EVT_WDF_WORKITEM VIOSerialPortSymbolicNameWork;
+EVT_WDF_WORKITEM VIOSerialPortPnpNotifyWork;
+EVT_WDF_REQUEST_CANCEL VIOSerialRequestCancel;
 
 #ifdef ALLOC_PRAGMA
 #pragma alloc_text(PAGE, VIOSerialDeviceListCreatePdo)
@@ -458,7 +460,7 @@ VIOSerialWillWriteBlock(
 }
 
 VOID
-VIOSerialPortSendPortReady(
+VIOSerialPortPortReadyWork(
     IN WDFWORKITEM  WorkItem
     )
 {
@@ -517,7 +519,7 @@ VIOSerialDeviceListCreatePdo(
                                  );
 
     WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_SERIAL_PORT);
-    WdfDeviceInitSetIoType(ChildInit, WdfDeviceIoDirect);
+    WdfDeviceInitSetIoType(ChildInit, WdfDeviceIoBuffered);
 
     do
     {
@@ -525,7 +527,7 @@ VIOSerialDeviceListCreatePdo(
                                  &buffer,
                                  L"%ws%vport%up%u",
                                  L"\\Device\\",
-                                 0,
+                                 pport->DeviceId,
                                  pport->PortId
                                  );
 
@@ -726,21 +728,6 @@ VIOSerialDeviceListCreatePdo(
         }
 
         WDF_IO_QUEUE_CONFIG_INIT(&queueConfig,
-                                 WdfIoQueueDispatchManual);
-
-        status = WdfIoQueueCreate(hChild,
-                                 &queueConfig,
-                                 WDF_NO_OBJECT_ATTRIBUTES,
-                                 &pport->PendingReadQueue
-                                 );
-        if (!NT_SUCCESS(status))
-        {
-           TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
-                    "WdfIoQueueCreate (Pending Read Queue) failed 0x%x
\n", status);
-           break;
-        }
-
-        WDF_IO_QUEUE_CONFIG_INIT(&queueConfig,
                                  WdfIoQueueDispatchSequential);
 
         queueConfig.EvtIoWrite  =  VIOSerialPortWrite;
@@ -824,54 +811,6 @@ VIOSerialDeviceListCreatePdo(
 
         pContext = GetPortsDevice(pport->BusDevice);
 
-        pport->WriteTransferElements =  BYTES_TO_PAGES((ULONG)
ROUND_TO_PAGES(
-                                    pContext->MaximumTransferLength) +
PAGE_SIZE) + 2;
-
-        pport->WriteCommonBufferSize =  sizeof(struct
VirtIOBufferDescriptor) * pport->WriteTransferElements;
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
-                    "pport->WriteCommonBufferSize = %d\n",
(int)pport->WriteCommonBufferSize);
-
-        status = WdfCommonBufferCreate(
-                                 pContext->DmaEnabler,
-                                 pport->WriteCommonBufferSize,
-                                 WDF_NO_OBJECT_ATTRIBUTES,
-                                 &pport->WriteCommonBuffer
-                                 );
-        if (!NT_SUCCESS(status))
-        {
-           TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
-                    "WdfCommonBufferCreate (write) failed: 0x%x\n",
status);
-           break;
-        }
-
-        pport->WriteCommonBufferBase =
-
WdfCommonBufferGetAlignedVirtualAddress(pport->WriteCommonBuffer);
-
-        pport->WriteCommonBufferBaseLA =
-
WdfCommonBufferGetAlignedLogicalAddress(pport->WriteCommonBuffer);
-
-        RtlZeroMemory( pport->WriteCommonBufferBase,
-                       pport->WriteCommonBufferSize);
-
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
-                                 "WriteCommonBuffer 0x%p   %08I64X,
length %d\n",
-                                 pport->WriteCommonBufferBase,
-
pport->WriteCommonBufferBaseLA.QuadPart,
-
(int)WdfCommonBufferGetLength(pport->WriteCommonBuffer) );
-
-        WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes,
TRANSACTION_CONTEXT);
-        status = WdfDmaTransactionCreate(pContext->DmaEnabler,
-                                 &attributes,
-                                 &pport->WriteDmaTransaction
-                                 );
-
-        if (!NT_SUCCESS(status))
-        {
-           TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
-                    "WdfDmaTransactionCreate failed: 0x%x\n", status);
-           break;
-        }
-
         status = VIOSerialFillQueue(GetInQueue(pport),
pport->InBufLock);
         if(!NT_SUCCESS(status))
         {
@@ -886,7 +825,7 @@ VIOSerialDeviceListCreatePdo(
         WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
         WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes,
RAWPDO_VIOSERIAL_PORT);
         attributes.ParentObject = hChild;
-        WDF_WORKITEM_CONFIG_INIT(&workitemConfig,
VIOSerialPortSendPortReady);
+        WDF_WORKITEM_CONFIG_INIT(&workitemConfig,
VIOSerialPortPortReadyWork);
 
         status = WdfWorkItemCreate( &workitemConfig,
                                  &attributes,
@@ -927,11 +866,14 @@ VIOSerialPortRead(
     SIZE_T             length;
     NTSTATUS           status;
     PUCHAR             systemBuffer;
+    BOOLEAN            nonBlock;
 
     PAGED_CODE();
 
     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))
     {
@@ -941,23 +883,15 @@ VIOSerialPortRead(
 
     if (!VIOSerialPortHasData(pdoData->port))
     {
-        if (!pdoData->port->HostConnected)
+        if (!pdoData->port->HostConnected && !nonBlock)
         {
            WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES);
            return;
         }
-
-        status = WdfRequestForwardToIoQueue(Request,
pdoData->port->PendingReadQueue);
-        if (NT_SUCCESS(status)) 
-        {
-            return;
-        } 
-        else 
-        {
-           TraceEvents(TRACE_LEVEL_ERROR, DBG_READ,
"WdfRequestForwardToIoQueue failed: %x\n", status);
-           WdfRequestComplete(Request, status);
-           return;
-        }
+        ASSERT (pdoData->port->PendingReadRequest == NULL);
+        WdfRequestMarkCancelableEx(Request, VIOSerialRequestCancel);
+        pdoData->port->PendingReadRequest = Request;
+        return;
     }
 
     length = (ULONG)VIOSerialFillReadBuf(pdoData->port, systemBuffer,
length);
@@ -982,134 +916,60 @@ VIOSerialPortWrite(
     PRAWPDO_VIOSERIAL_PORT  pdoData =
RawPdoSerialPortGetData(WdfIoQueueGetDevice(Queue));
     NTSTATUS           status = STATUS_SUCCESS;
     SIZE_T             length;
-    WDFREQUEST         readRequest;
     PUCHAR             systemBuffer;
     PVIOSERIAL_PORT    pport = pdoData->port;
-
+    BOOLEAN            nonBlock;
     PAGED_CODE();
 
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "-->%s length = %d
\n", __FUNCTION__, Length);
+    TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "-->%s length = %d\n",
__FUNCTION__, Length);
 
-    if (Length > PORT_MAXIMUM_TRANSFER_LENGTH)
+    if (Length == 0)
     {
         status = STATUS_INVALID_BUFFER_SIZE;
-        WdfDmaTransactionRelease(pport->WriteDmaTransaction);
         WdfRequestComplete(Request, status);
         TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "<--%s::%d\n",
__FUNCTION__, __LINE__);
         return;
     }
-
-    status = WdfDmaTransactionInitializeUsingRequest(
-                                 pport->WriteDmaTransaction,
-                                 Request,
-                                 VIOSerialPortProgramWriteDma,
-                                 WdfDmaDirectionWriteToDevice
-                                 );
-
-    if(!NT_SUCCESS(status))
+    status = WdfRequestRetrieveInputBuffer(Request, Length,
&systemBuffer, &length);
+    if (!NT_SUCCESS(status))
     {
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
-
"WdfDmaTransactionInitializeUsingRequest failed: 0x%x\n",
-                                 status
-                                 );
-        WdfDmaTransactionRelease(pport->WriteDmaTransaction);
         WdfRequestComplete(Request, status);
         return;
     }
-
-    status = WdfDmaTransactionExecute( pport->WriteDmaTransaction,
-                                       pport);
-
-    if(!NT_SUCCESS(status))
+    nonBlock = FALSE;
+    if (VIOSerialWillWriteBlock(pport))
     {
-        TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
-                    "WdfDmaTransactionExecute failed: 0x%x\n", status);
-        WdfDmaTransactionRelease(pport->WriteDmaTransaction);
-        WdfRequestComplete(Request, status);
+        if (nonBlock)
+        {
+           status = STATUS_INSUFFICIENT_RESOURCES;
+           WdfRequestComplete(Request, status);
+           TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "<--%s::%d\n",
__FUNCTION__, __LINE__);
+           return;
+        }
     }
+    length = VIOSerialSendBuffers(pport, systemBuffer, length,
nonBlock);
+    WdfRequestCompleteWithInformation( Request, status, length);
 }
 
-BOOLEAN
-VIOSerialPortProgramWriteDma(
-    IN  WDFDMATRANSACTION       Transaction,
-    IN  WDFDEVICE               Device,
-    IN  PVOID                   Context,
-    IN  WDF_DMA_DIRECTION       Direction,
-    IN  PSCATTER_GATHER_LIST    SgList
-    )
-{
-    UINT len;
-    SSIZE_T ret;
-    struct VirtIOBufferDescriptor* sg;
-    PVIOSERIAL_PORT port = (PVIOSERIAL_PORT)Context;
-    struct virtqueue *vq = GetOutQueue(port);
-    ULONG i;
-
-    UNREFERENCED_PARAMETER(Device);
-
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_QUEUEING, "--> %s
port->OutVqFull = %d\n", __FUNCTION__, port->OutVqFull);
-
-    WdfSpinLockAcquire(port->OutVqLock);
-    VIOSerialReclaimConsumedBuffers(port);
-
-    sg = (struct VirtIOBufferDescriptor*) port->WriteCommonBufferBase;
-
-    for (i=0; i < SgList->NumberOfElements; i++)
-    {
-        sg[i].physAddr = SgList->Elements[i].Address;
-        sg[i].ulSize   = SgList->Elements[i].Length;
-    }
-
-    ret = vq->vq_ops->add_buf(vq, sg, i, 0, Context);
-    if (ret < 0)
-    {
-        NTSTATUS status;
-        port->OutVqFull = TRUE;
-        WdfSpinLockRelease(port->OutVqLock);
-        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_QUEUEING, "<--> %s::%d
port->OutVqFull = %d\n", __FUNCTION__, __LINE__, port->OutVqFull);
-
-        (VOID) WdfDmaTransactionDmaCompletedFinal(Transaction, 0,
&status);
-        ASSERT(NT_SUCCESS(status));
-        VIOSerialPortWriteRequestComplete( Transaction,
STATUS_INVALID_DEVICE_STATE );
-        return FALSE;
-    }
-
-    vq->vq_ops->kick(vq);
-    WdfSpinLockRelease(port->OutVqLock);
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "<-- %s
port->OutVqFull = %d\n", __FUNCTION__, port->OutVqFull);
-    return TRUE;
-}
 
 VOID
-VIOSerialPortWriteRequestComplete(
-    IN WDFDMATRANSACTION  DmaTransaction,
-    IN NTSTATUS           Status
+VIOSerialRequestCancel(
+    IN WDFREQUEST Request
     )
 {
-    WDFDEVICE          device=
WdfDmaTransactionGetDevice(DmaTransaction);
-    PRAWPDO_VIOSERIAL_PORT   pdoData = RawPdoSerialPortGetData(device);
-    WDFREQUEST         request;
-    size_t             bytesTransferred;
-
-    request = WdfDmaTransactionGetRequest(DmaTransaction);
-
-    bytesTransferred =
WdfDmaTransactionGetBytesTransferred( DmaTransaction );
-
-    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,
-                                "%s:  Request %p, Status 0x%x, "
-                                "bytes transferred %d\n",
-                                 __FUNCTION__,
-                                 request,
-                                 Status,
-                                 (int)bytesTransferred
-                                 );
+    PRAWPDO_VIOSERIAL_PORT  pdoData =
RawPdoSerialPortGetData(WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)));
 
-    WdfDmaTransactionRelease(DmaTransaction);
+    TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "-->%s called on request
0x%p\n", __FUNCTION__, Request);
 
-    WdfRequestCompleteWithInformation( request, Status,
bytesTransferred);
+    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);
 
+    ASSERT(pdoData->port->PendingReadRequest == Request);
+    pdoData->port->PendingReadRequest = NULL;
+
+    return;
 }
 
+
 VOID
 VIOSerialPortDeviceControl(
     IN WDFQUEUE   Queue,
@@ -1292,7 +1152,7 @@ VIOSerialPortCreateName(
         WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
         WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes,
RAWPDO_VIOSERIAL_PORT);
         attributes.ParentObject = WdfDevice;
-        WDF_WORKITEM_CONFIG_INIT(&workitemConfig,
VIOSerialPortCreateSymbolicName);
+        WDF_WORKITEM_CONFIG_INIT(&workitemConfig,
VIOSerialPortSymbolicNameWork);
 
         status = WdfWorkItemCreate( &workitemConfig,
                                  &attributes,
@@ -1316,9 +1176,45 @@ VIOSerialPortCreateName(
     }
 }
 
+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;
+
+    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);
+}
 
 VOID
-VIOSerialPortCreateSymbolicName(
+VIOSerialPortSymbolicNameWork(
     IN WDFWORKITEM  WorkItem
     )
 {
@@ -1380,6 +1276,60 @@ VIOSerialPortCreateSymbolicName(
     WdfObjectDelete(WorkItem);
 }
 
+VOID
+VIOSerialPortPnpNotifyWork(
+    IN WDFWORKITEM  WorkItem
+    )
+{
+    PRAWPDO_VIOSERIAL_PORT  pdoData =
RawPdoSerialPortGetData(WorkItem);
+    PVIOSERIAL_PORT         pport = pdoData->port;
+    PTARGET_DEVICE_CUSTOM_NOTIFICATION  notification;
+    ULONG                               requiredSize;
+    NTSTATUS                            status;
+    VIRTIO_PORT_STATUS_CHANGE           portStatus = {0};
+
+    portStatus.Version = 1;
+    portStatus.Reason = pport->HostConnected;
+
+    status = RtlULongAdd((sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION) -
sizeof(UCHAR)),
+                                 sizeof(VIRTIO_PORT_STATUS_CHANGE),
+                                 &requiredSize);
+
+    if (NT_SUCCESS(status))
+    {
+        notification = ExAllocatePoolWithTag(NonPagedPool,
+                                 requiredSize,
+                                 VIOSERIAL_DRIVER_MEMORY_TAG);
+
+        if (notification != NULL)
+        {
+            RtlZeroMemory(notification, requiredSize);
+            notification->Version = 1;
+            notification->Size = (USHORT)(requiredSize);
+            notification->FileObject = NULL;
+            notification->NameBufferOffset = -1;
+            notification->Event = GUID_VIOSERIAL_PORT_CHANGE_STATUS;
+            RtlCopyMemory(notification->CustomDataBuffer, &portStatus,
sizeof(VIRTIO_PORT_STATUS_CHANGE));
+            //FIXME
+            if(WdfDeviceGetDevicePnpState(pport->Device) ==
WdfDevStatePnpStarted)
+            {
+               status = IoReportTargetDeviceChangeAsynchronous(
+
WdfDeviceWdmGetPhysicalDevice(pport->Device),
+                                 notification,
+                                 NULL,
+                                 NULL);
+               if (!NT_SUCCESS(status))
+               {
+                    TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
+
"IoReportTargetDeviceChangeAsynchronous Failed! status = 0x%x\n",
status);   
+               }
+            }
+            ExFreePoolWithTag(notification,
VIOSERIAL_DRIVER_MEMORY_TAG);
+        }
+    }
+    WdfObjectDelete(WorkItem);
+}
+
 NTSTATUS
 VIOSerialEvtChildListIdentificationDescriptionDuplicate(
     WDFCHILDLIST DeviceList,
@@ -1436,16 +1386,8 @@
VIOSerialEvtChildListIdentificationDescriptionDuplicate(
     dst->GuestConnected = src->GuestConnected;
 
     dst->ReadQueue = src->ReadQueue;
-    dst->PendingReadQueue = src->PendingReadQueue;
-
+    dst->PendingReadRequest = src->PendingReadRequest;
     dst->WriteQueue = src->WriteQueue;
-    dst->WriteCommonBuffer = src->WriteCommonBuffer;
-    dst->WriteDmaTransaction = src->WriteDmaTransaction;
-    dst->WriteTransferElements = src->WriteTransferElements;
-    dst->WriteCommonBufferSize = src->WriteCommonBufferSize;
-    dst->WriteCommonBufferBase = src->WriteCommonBufferBase;
-    dst->WriteCommonBufferBaseLA = src->WriteCommonBufferBaseLA;
-
     dst->IoctlQueue = src->IoctlQueue;
 
     return STATUS_SUCCESS;
diff --git a/vioserial/sys/vioser.h b/vioserial/sys/vioser.h
index 5caabc6..2712a0f 100644
--- a/vioserial/sys/vioser.h
+++ b/vioserial/sys/vioser.h
@@ -14,7 +14,7 @@
 **********************************************************************/
 #if !defined(VIOSERIAL_H)
 #define VIOSERIAL_H
-
+#include "public.h"
 
 EVT_WDF_DRIVER_DEVICE_ADD VIOSerialEvtDeviceAdd;
 
@@ -47,9 +47,6 @@ EVT_WDF_INTERRUPT_DISABLE
VIOSerialInterruptDisable;
 #define VIRTIO_CONSOLE_PORT_NAME        7
 
 
-#define PORT_MAXIMUM_TRANSFER_LENGTH    (32*1024)
-
-
 #pragma pack (push)
 #pragma pack (1)
 
@@ -92,9 +89,6 @@ typedef struct _tagPortDevice
     struct virtqueue    **in_vqs, **out_vqs;
     WDFSPINLOCK         CVqLock;
 
-    WDFDMAENABLER       DmaEnabler;
-    ULONG               MaximumTransferLength;
-
     BOOLEAN             DeviceOK;
     UINT                DeviceId;
 } PORTS_DEVICE, *PPORTS_DEVICE;
@@ -144,16 +138,9 @@ typedef struct _tagVioSerialPort
     BOOLEAN             GuestConnected;
 
     WDFQUEUE            ReadQueue;
-    WDFQUEUE            PendingReadQueue;
+    WDFREQUEST          PendingReadRequest;
 
     WDFQUEUE            WriteQueue;
-    WDFCOMMONBUFFER     WriteCommonBuffer;
-    WDFDMATRANSACTION   WriteDmaTransaction;
-    ULONG               WriteTransferElements;
-    size_t              WriteCommonBufferSize;
-    PUCHAR              WriteCommonBufferBase;
-    PHYSICAL_ADDRESS    WriteCommonBufferBaseLA;
-
     WDFQUEUE            IoctlQueue;
 } VIOSERIAL_PORT, *PVIOSERIAL_PORT;
 
@@ -175,7 +162,7 @@ typedef struct _tagTransactionContext {
 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(TRANSACTION_CONTEXT,
RawPdoSerialPortGetTransactionContext)
 
 
-NTSTATUS 
+NTSTATUS
 VIOSerialFillQueue(
     IN struct virtqueue *vq,
     IN WDFSPINLOCK Lock
@@ -297,7 +284,6 @@ EVT_WDF_IO_QUEUE_IO_WRITE VIOSerialPortWrite;
 EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL VIOSerialPortDeviceControl;
 EVT_WDF_DEVICE_FILE_CREATE VIOSerialPortCreate;
 EVT_WDF_FILE_CLOSE VIOSerialPortClose;
-EVT_WDF_PROGRAM_DMA VIOSerialPortProgramWriteDma;
 
 VOID
 VIOSerialPortWriteRequestComplete(
-- 


--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM Development]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Walks]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux