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

[win-pv-devel] [PATCH 5/6] Switch to VIF interface V2



Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 include/vif_interface.h  |  94 ++++++++-
 src/coinst/coinst.c      |   5 +-
 src/xennet.inf           |   6 +-
 src/xennet/adapter.c     |   7 +-
 src/xennet/driver.c      | 533 +++++++++++++++++++++++++++++++++++++++++++++++
 src/xennet/transmitter.c | 205 ++++++++++++------
 src/xennet/transmitter.h |   9 +-
 7 files changed, 780 insertions(+), 79 deletions(-)
 create mode 100644 src/xennet/driver.c

diff --git a/include/vif_interface.h b/include/vif_interface.h
index 498ed8f..d083fd1 100644
--- a/include/vif_interface.h
+++ b/include/vif_interface.h
@@ -257,7 +257,7 @@ struct _XENVIF_TRANSMITTER_PACKET_V1 {
     };
 };
 
-typedef struct _XENVIF_TRANSMITTER_PACKET_V1 XENVIF_TRANSMITTER_PACKET, 
*PXENVIF_TRANSMITTER_PACKET;
+typedef struct _XENVIF_TRANSMITTER_PACKET_V1 XENVIF_TRANSMITTER_PACKET_V1, 
*PXENVIF_TRANSMITTER_PACKET_V1;
 
 #pragma warning(pop)
 
@@ -265,6 +265,30 @@ typedef struct _XENVIF_TRANSMITTER_PACKET_V1 
XENVIF_TRANSMITTER_PACKET, *PXENVIF
 
 C_ASSERT(sizeof (struct _XENVIF_TRANSMITTER_PACKET_V1) <= (3 * sizeof 
(PVOID)));
 
+/*! \struct _XENVIF_TRANSMITTER_PACKET_V2
+    \brief Transmit-side packet structure (v2)
+*/
+struct _XENVIF_TRANSMITTER_PACKET_V2 {
+    /*! List entry used for chaining packets together */
+    LIST_ENTRY                                  ListEntry;
+    /*! Opaque cookie used to store context information for packet return */
+    PVOID                                       Cookie;
+    /*! Hash value set by subscriber */
+    ULONG                                       Value;
+    /*! Packet information passed from subscriber to provider */
+    XENVIF_TRANSMITTER_PACKET_SEND_INFO         Send;
+    /*! Packet information passed from provider to subscriber on packet return 
*/
+    XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO   Completion;
+    /*! Packet data MDL */
+    PMDL                                        Mdl;
+    /*! Offset into MDL to start of packet */
+    ULONG                                       Offset;
+    /*! Packet length */
+    ULONG                                       Length;
+};
+
+typedef struct _XENVIF_TRANSMITTER_PACKET_V2 XENVIF_TRANSMITTER_PACKET, 
*PXENVIF_TRANSMITTER_PACKET;
+
 /*! \enum _XENVIF_TRANSMITTER_PACKET_OFFSET
     \brief Offsets of packet metadata relative to
     XENVIF_TRANSMITTER_PACKET pointer
@@ -474,16 +498,44 @@ typedef NTSTATUS
     IN  LONG_PTR                            Value
     );
 
+/*! \typedef XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS
+    \brief Get the packet headers into supplied buffer
+
+    \param Interface The interface header
+    \param Packet The packet to acquire headers for.
+    \param Headers The buffer to receive headers.
+    \param Info The offsets into Headers for relevant headers
+*/
+typedef NTSTATUS
+(*XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENVIF_TRANSMITTER_PACKET  Packet,
+    OUT PVOID                       Headers,
+    OUT PXENVIF_PACKET_INFO         Info
+    );
+
 /*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS
     \brief Queue transmit side packets at the provider
 
     \param Interface The interface header
-    \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET
+    \param Head The head of a chain of _XENVIF_TRANSMITTER_PACKET_V1
 */
 typedef NTSTATUS
 (*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS)(
-    IN  PINTERFACE                  Interface,
-    IN  PXENVIF_TRANSMITTER_PACKET  Head
+    IN  PINTERFACE                      Interface,
+    IN  PXENVIF_TRANSMITTER_PACKET_V1   Head
+    );
+
+/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2
+    \brief Queue transmit side packets at the provider
+
+    \param Interface The interface header
+    \param List List of _XENVIF_TRANSMITTER_PACKET_V2
+*/
+typedef NTSTATUS
+(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2)(
+    IN  PINTERFACE  Interface,
+    IN  PLIST_ENTRY List
     );
 
 /*! \typedef XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS
@@ -708,7 +760,37 @@ struct _XENVIF_VIF_INTERFACE_V1 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-typedef struct _XENVIF_VIF_INTERFACE_V1 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
+
+/*! \struct _XENVIF_VIF_INTERFACE_V2
+    \brief VIF interface version 2
+    \ingroup interfaces
+*/
+struct _XENVIF_VIF_INTERFACE_V2 {
+    INTERFACE                                       Interface;
+    XENVIF_VIF_ACQUIRE                              Acquire;
+    XENVIF_VIF_RELEASE                              Release;
+    XENVIF_VIF_ENABLE                               Enable;
+    XENVIF_VIF_DISABLE                              Disable;
+    XENVIF_VIF_QUERY_STATISTIC                      QueryStatistic;
+    XENVIF_VIF_RECEIVER_RETURN_PACKETS              ReceiverReturnPackets;
+    XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS         ReceiverSetOffloadOptions;
+    XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
+    XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS       
TransmitterGetPacketHeaders;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2         TransmitterQueuePackets;
+    XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    
TransmitterQueryOffloadOptions;
+    XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  
TransmitterQueryLargePacketSize;
+    XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE          TransmitterQueryRingSize;
+    XENVIF_VIF_MAC_QUERY_STATE                      MacQueryState;
+    XENVIF_VIF_MAC_QUERY_MAXIMUM_FRAME_SIZE         MacQueryMaximumFrameSize;
+    XENVIF_VIF_MAC_QUERY_PERMANENT_ADDRESS          MacQueryPermanentAddress;
+    XENVIF_VIF_MAC_QUERY_CURRENT_ADDRESS            MacQueryCurrentAddress;
+    XENVIF_VIF_MAC_QUERY_MULTICAST_ADDRESSES        MacQueryMulticastAddresses;
+    XENVIF_VIF_MAC_SET_MULTICAST_ADDRESSES          MacSetMulticastAddresses;
+    XENVIF_VIF_MAC_SET_FILTER_LEVEL                 MacSetFilterLevel;
+    XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
+};
+
+typedef struct _XENVIF_VIF_INTERFACE_V2 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
 
 /*! \def XENVIF_VIF
     \brief Macro at assist in method invocation
@@ -719,6 +801,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V1 
XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER
 #endif  // _WINDLL
 
 #define XENVIF_VIF_INTERFACE_VERSION_MIN    1
-#define XENVIF_VIF_INTERFACE_VERSION_MAX    1
+#define XENVIF_VIF_INTERFACE_VERSION_MAX    2
 
 #endif  // _XENVIF_INTERFACE_H
diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c
index 265f348..540d51d 100644
--- a/src/coinst/coinst.c
+++ b/src/coinst/coinst.c
@@ -45,6 +45,7 @@
 #include <stdarg.h>
 #include <assert.h>
 #include <vif_interface.h>
+#include <cache_interface.h>
 
 #include <tcpip.h>
 #include <version.h>
@@ -2165,7 +2166,7 @@ RegisterInterface(
                           InterfaceName,
                           0,
                           REG_DWORD,
-                          (const BYTE *)InterfaceVersion,
+                          (const BYTE *)&InterfaceVersion,
                           sizeof(DWORD));
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
@@ -2335,6 +2336,7 @@ __DifInstallPostProcess(
         goto fail5;
 
     RegisterInterface("XENVIF", "VIF", XENVIF_VIF_INTERFACE_VERSION_MAX);
+    RegisterInterface("XENBUS", "CACHE", XENBUS_CACHE_INTERFACE_VERSION_MAX);
 
     if (SoftwareKeyName != NULL) {
         (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
@@ -2417,6 +2419,7 @@ __DifRemovePreProcess(
     Log("====>");
 
     (VOID) DeregisterAllInterfaces("XENVIF");
+    (VOID) DeregisterAllInterfaces("XENBUS");
     (VOID) RemoveUnplugService("NICS", "XENNET");
     (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
 
diff --git a/src/xennet.inf b/src/xennet.inf
index d99ffed..1adf079 100644
--- a/src/xennet.inf
+++ b/src/xennet.inf
@@ -61,9 +61,9 @@ 
xennet_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll
 ; DisplayName          Section         DeviceID
 ; -----------          -------         --------
 
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XSC000&DEV_NET&REV_00000001
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XS0001&DEV_NET&REV_00000001
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XS0002&DEV_NET&REV_00000001
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XSC000&DEV_NET&REV_00000002
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XS0001&DEV_NET&REV_00000002
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XS0002&DEV_NET&REV_00000002
 
 [XenNet_Inst] 
 Characteristics=0x84
diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c
index 2f10b35..24cf4a0 100644
--- a/src/xennet/adapter.c
+++ b/src/xennet/adapter.c
@@ -164,11 +164,11 @@ AdapterVifCallback(
 
     switch (Type) {
     case XENVIF_TRANSMITTER_RETURN_PACKETS: {
-        PXENVIF_TRANSMITTER_PACKET HeadPacket;
+        PLIST_ENTRY List;
 
-        HeadPacket = va_arg(Arguments, PXENVIF_TRANSMITTER_PACKET);
+        List = va_arg(Arguments, PLIST_ENTRY);
 
-        TransmitterCompletePackets(Adapter->Transmitter, HeadPacket);
+        TransmitterCompletePackets(Adapter->Transmitter, List);
         break;
     }
     case XENVIF_RECEIVER_QUEUE_PACKETS: {
@@ -964,7 +964,6 @@ AdapterEnable(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    TransmitterEnable(Adapter->Transmitter);
     Adapter->Enabled = TRUE;
 
     return NDIS_STATUS_SUCCESS;
diff --git a/src/xennet/driver.c b/src/xennet/driver.c
new file mode 100644
index 0000000..cfa5cdd
--- /dev/null
+++ b/src/xennet/driver.c
@@ -0,0 +1,533 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#define INITGUID 1
+
+#include <ndis.h>
+#include "adapter.h"
+#include <version.h>
+#include "dbg_print.h"
+#include "assert.h"
+
+typedef struct _XENNET_DRIVER {
+    NDIS_HANDLE             MiniportHandle;
+} XENNET_DRIVER;
+
+static XENNET_DRIVER Driver;
+
+extern PULONG InitSafeBootMode;
+
+MINIPORT_CANCEL_OID_REQUEST __AdapterCancelOidRequest;
+VOID
+__AdapterCancelOidRequest(
+    IN  NDIS_HANDLE     Handle,
+    IN  PVOID           Request
+    )
+{
+    UNREFERENCED_PARAMETER(Handle);
+    UNREFERENCED_PARAMETER(Request);
+}
+
+MINIPORT_CANCEL_SEND    __AdapterCancelSendNetBufferLists;
+VOID
+__AdapterCancelSendNetBufferLists(
+    IN  NDIS_HANDLE     Handle,
+    IN  PVOID           Cancel
+    )
+{
+    UNREFERENCED_PARAMETER(Handle);
+    UNREFERENCED_PARAMETER(Cancel);
+}
+
+MINIPORT_CHECK_FOR_HANG __AdapterCheckForHang;
+BOOLEAN
+__AdapterCheckForHang(
+    IN  NDIS_HANDLE     Handle
+    )
+{
+    UNREFERENCED_PARAMETER(Handle);
+    return FALSE;
+}
+
+MINIPORT_INITIALIZE __AdapterInitialize;
+NDIS_STATUS 
+__AdapterInitialize(
+    IN  NDIS_HANDLE     Handle,
+    IN  NDIS_HANDLE     DriverContext,
+    IN  PNDIS_MINIPORT_INIT_PARAMETERS  Params
+    )
+{
+    PXENNET_ADAPTER     Adapter;
+    NDIS_STATUS         ndisStatus;
+
+    UNREFERENCED_PARAMETER(DriverContext);
+    UNREFERENCED_PARAMETER(Params);
+
+    ndisStatus = AdapterInitialize(Handle, &Adapter);
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
+        goto fail1;
+
+    return ndisStatus;
+
+fail1:
+    Error("fail1\n");
+    return ndisStatus;
+}
+
+MINIPORT_HALT   __AdapterHalt;
+VOID 
+__AdapterHalt(
+    IN  NDIS_HANDLE     Handle,
+    IN  NDIS_HALT_ACTION    Action
+    )
+{
+    PXENNET_ADAPTER     Adapter = (PXENNET_ADAPTER)Handle;
+
+    UNREFERENCED_PARAMETER(Action);
+
+    if (Adapter == NULL)
+        return;
+
+    (VOID) AdapterDisable(Adapter);
+
+    AdapterTeardown(Adapter);
+}
+
+MINIPORT_OID_REQUEST    __AdapterOidRequest;
+NDIS_STATUS
+__AdapterOidRequest(
+    IN  NDIS_HANDLE         Handle,
+    IN  PNDIS_OID_REQUEST   Request
+    )
+{
+    PXENNET_ADAPTER     Adapter = (PXENNET_ADAPTER)Handle;
+    NDIS_STATUS         ndisStatus;
+
+    switch (Request->RequestType) {
+        case NdisRequestSetInformation:
+            ndisStatus = AdapterSetInformation(Adapter, Request);
+            break;
+
+        case NdisRequestQueryInformation:
+        case NdisRequestQueryStatistics:
+            ndisStatus = AdapterQueryInformation(Adapter, Request);
+            break;
+
+        default:
+            ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+            break;
+    };
+
+    return ndisStatus;
+}
+
+MINIPORT_PAUSE  __AdapterPause;
+NDIS_STATUS
+__AdapterPause(
+    IN  NDIS_HANDLE     Handle,
+    IN  PNDIS_MINIPORT_PAUSE_PARAMETERS Params
+    )
+{
+    PXENNET_ADAPTER     Adapter = (PXENNET_ADAPTER)Handle;
+
+    UNREFERENCED_PARAMETER(Params);
+
+    if (AdapterDisable(Adapter))
+        AdapterMediaStateChange(Adapter);
+
+    return NDIS_STATUS_SUCCESS;
+}
+
+MINIPORT_DEVICE_PNP_EVENT_NOTIFY    __AdapterPnPEventHandler;
+VOID
+__AdapterPnPEventHandler(
+    IN  NDIS_HANDLE     Handle,
+    IN  PNET_DEVICE_PNP_EVENT   Event
+    )
+{
+    UNREFERENCED_PARAMETER(Handle);
+    UNREFERENCED_PARAMETER(Event);
+}
+
+MINIPORT_RESET  __AdapterReset;
+NDIS_STATUS
+__AdapterReset(
+    IN  NDIS_HANDLE     Handle,
+    OUT PBOOLEAN        AddressingReset
+    )
+{
+    UNREFERENCED_PARAMETER(Handle);
+
+    *AddressingReset = FALSE;
+    return NDIS_STATUS_SUCCESS;
+}
+
+MINIPORT_RESTART    __AdapterRestart;
+NDIS_STATUS
+__AdapterRestart(
+    IN  NDIS_HANDLE             Handle,
+    IN  PNDIS_MINIPORT_RESTART_PARAMETERS   Params
+    )
+{
+    PXENNET_ADAPTER     Adapter = (PXENNET_ADAPTER)Handle;
+
+    UNREFERENCED_PARAMETER(Params);
+
+    return AdapterEnable(Adapter);
+}
+
+MINIPORT_RETURN_NET_BUFFER_LISTS    __AdapterReturnNetBufferLists;
+VOID
+__AdapterReturnNetBufferLists(
+    IN  NDIS_HANDLE             Handle,
+    IN  PNET_BUFFER_LIST        NetBufferLists,
+    IN  ULONG                   ReturnFlags
+    )
+{
+    PXENNET_ADAPTER     Adapter = (PXENNET_ADAPTER)Handle;
+    PXENNET_RECEIVER    Receiver = AdapterGetReceiver(Adapter);
+
+    ReceiverReturnNetBufferLists(Receiver,
+                                 NetBufferLists,
+                                 ReturnFlags);
+}
+
+MINIPORT_SEND_NET_BUFFER_LISTS  __AdapterSendNetBufferLists;
+VOID
+__AdapterSendNetBufferLists(
+    IN  NDIS_HANDLE             Handle,
+    IN  PNET_BUFFER_LIST        NetBufferList,
+    IN  NDIS_PORT_NUMBER        PortNumber,
+    IN  ULONG                   SendFlags
+    )
+{
+    PXENNET_ADAPTER     Adapter = (PXENNET_ADAPTER)Handle;
+    PXENNET_TRANSMITTER Transmitter = AdapterGetTransmitter(Adapter);
+
+    TransmitterSendNetBufferLists(Transmitter,
+                                  NetBufferList,
+                                  PortNumber,
+                                  SendFlags);
+}
+
+MINIPORT_SHUTDOWN   __AdapterShutdown;
+VOID
+__AdapterShutdown(
+    IN  NDIS_HANDLE             Handle,
+    IN  NDIS_SHUTDOWN_ACTION    Action
+    )
+{
+    PXENNET_ADAPTER Adapter = (PXENNET_ADAPTER)Handle;
+
+    if (Action != NdisShutdownBugCheck)
+        AdapterDisable(Adapter);
+}
+
+typedef struct _XENNET_CONTEXT {
+    PDEVICE_CAPABILITIES    Capabilities;
+    PIO_COMPLETION_ROUTINE  CompletionRoutine;
+    PVOID                   CompletionContext;
+    UCHAR                   CompletionControl;
+} XENNET_CONTEXT, *PXENNET_CONTEXT;
+
+static NTSTATUS (*NdisDispatchPnp)(PDEVICE_OBJECT, PIRP);
+
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+static NTSTATUS
+__QueryCapabilities(
+    IN  PDEVICE_OBJECT      DeviceObject,
+    IN  PIRP                Irp,
+    IN  PVOID               _Context
+    )
+{
+    PXENNET_CONTEXT         Context = _Context;
+    NTSTATUS                status;
+
+    Context->Capabilities->SurpriseRemovalOK = 1;
+
+    if (Context->CompletionRoutine != NULL &&
+        (Context->CompletionControl & SL_INVOKE_ON_SUCCESS))
+        status = Context->CompletionRoutine(DeviceObject, Irp, 
Context->CompletionContext);
+    else
+        status = STATUS_SUCCESS;
+
+    ExFreePool(Context);
+
+    return status;
+}
+
+NTSTATUS
+QueryCapabilities(
+    IN PDEVICE_OBJECT       DeviceObject,
+    IN PIRP                 Irp
+    )
+{
+    PIO_STACK_LOCATION      StackLocation;
+    PXENNET_CONTEXT         Context;
+    NTSTATUS                status;
+
+    Trace("====>\n");
+
+    Trace("%p\n", DeviceObject);
+
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+    Context = ExAllocatePoolWithTag(NonPagedPool, sizeof (XENNET_CONTEXT), ' 
TEN');
+    if (Context != NULL) {
+        Context->Capabilities = 
StackLocation->Parameters.DeviceCapabilities.Capabilities;
+        Context->CompletionRoutine = StackLocation->CompletionRoutine;
+        Context->CompletionContext = StackLocation->Context;
+        Context->CompletionControl = StackLocation->Control;
+
+        StackLocation->CompletionRoutine = __QueryCapabilities;
+        StackLocation->Context = Context;
+        StackLocation->Control = SL_INVOKE_ON_SUCCESS;
+    }
+
+    status = NdisDispatchPnp(DeviceObject, Irp);
+
+    Trace("<====\n");
+
+    return status;
+}
+
+DRIVER_DISPATCH DispatchPnp;
+
+NTSTATUS
+DispatchPnp(
+    IN PDEVICE_OBJECT   DeviceObject,
+    IN PIRP             Irp
+    )
+{
+    PIO_STACK_LOCATION  StackLocation;
+    UCHAR               MinorFunction;
+    NTSTATUS            status;
+
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    MinorFunction = StackLocation->MinorFunction;
+
+    switch (StackLocation->MinorFunction) {
+    case IRP_MN_QUERY_CAPABILITIES:
+        status = QueryCapabilities(DeviceObject, Irp);
+        break;
+
+    default:
+        status = NdisDispatchPnp(DeviceObject, Irp);
+        break;
+    }
+
+    return status;
+}
+
+DRIVER_DISPATCH DispatchFail;
+
+NTSTATUS
+DispatchFail(
+    IN PDEVICE_OBJECT   DeviceObject,
+    IN PIRP             Irp
+    )
+{
+    UNREFERENCED_PARAMETER(DeviceObject);
+
+    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+MINIPORT_UNLOAD DriverUnload;
+VOID
+DriverUnload(
+    IN  PDRIVER_OBJECT  DriverObject
+    )
+{
+    UNREFERENCED_PARAMETER(DriverObject);
+
+    Trace("====>\n");
+
+    if (*InitSafeBootMode > 0)
+        goto done;
+
+    if (Driver.MiniportHandle)
+        NdisMDeregisterMiniportDriver(Driver.MiniportHandle);
+    Driver.MiniportHandle = NULL;
+
+    Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
+
+done:
+    Trace("<====\n");
+}
+
+DRIVER_INITIALIZE       DriverEntry;
+
+NTSTATUS
+DriverEntry (
+    IN  PDRIVER_OBJECT  DriverObject,
+    IN  PUNICODE_STRING RegistryPath
+    )
+{
+    NDIS_STATUS ndisStatus;
+    NDIS_MINIPORT_DRIVER_CHARACTERISTICS mpChars;
+    NDIS_CONFIGURATION_OBJECT ConfigurationObject;
+    NDIS_HANDLE ConfigurationHandle;
+    NDIS_STRING ParameterName;
+    PNDIS_CONFIGURATION_PARAMETER ParameterValue;
+    ULONG FailCreateClose;
+    ULONG FailDeviceControl;
+
+    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
+
+    Trace("====>\n");
+
+    if (*InitSafeBootMode > 0)
+        return NDIS_STATUS_SUCCESS;
+
+    Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
+
+    //
+    // Register miniport with NDIS.
+    //
+
+    NdisZeroMemory(&mpChars, sizeof(mpChars));
+    mpChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS,
+    mpChars.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
+    mpChars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
+
+    mpChars.MajorNdisVersion = 6;
+    mpChars.MinorNdisVersion = 0;
+    mpChars.MajorDriverVersion = MAJOR_VERSION;
+    mpChars.MinorDriverVersion = MINOR_VERSION;
+
+    mpChars.CancelOidRequestHandler = __AdapterCancelOidRequest;
+    mpChars.CancelSendHandler = __AdapterCancelSendNetBufferLists;
+    mpChars.CheckForHangHandlerEx = __AdapterCheckForHang;
+    mpChars.InitializeHandlerEx = __AdapterInitialize;
+    mpChars.HaltHandlerEx = __AdapterHalt;
+    mpChars.OidRequestHandler = __AdapterOidRequest;
+    mpChars.PauseHandler = __AdapterPause;
+    mpChars.DevicePnPEventNotifyHandler  = __AdapterPnPEventHandler;
+    mpChars.ResetHandlerEx = __AdapterReset;
+    mpChars.RestartHandler = __AdapterRestart;
+    mpChars.ReturnNetBufferListsHandler = __AdapterReturnNetBufferLists;
+    mpChars.SendNetBufferListsHandler = __AdapterSendNetBufferLists;
+    mpChars.ShutdownHandlerEx = __AdapterShutdown;
+    mpChars.UnloadHandler = DriverUnload;
+
+    Driver.MiniportHandle = NULL;
+    ndisStatus = NdisMRegisterMiniportDriver(DriverObject,
+                                             RegistryPath,
+                                             NULL,
+                                             &mpChars,
+                                             &Driver.MiniportHandle);
+    if (ndisStatus != NDIS_STATUS_SUCCESS) {
+        Error("Failed (0x%08X) to register miniport.\n", ndisStatus);
+        goto fail;
+    }
+
+    ConfigurationObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
+    ConfigurationObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
+    ConfigurationObject.Header.Size = 
NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
+    ConfigurationObject.NdisHandle = Driver.MiniportHandle;
+    ConfigurationObject.Flags = 0;
+
+    ndisStatus = NdisOpenConfigurationEx(&ConfigurationObject, 
&ConfigurationHandle);
+    if (ndisStatus != NDIS_STATUS_SUCCESS) {
+        Error("Failed (0x%08X) to open driver configuration.\n", ndisStatus);
+        NdisMDeregisterMiniportDriver(Driver.MiniportHandle);
+        goto fail;
+    }
+
+    RtlInitUnicodeString(&ParameterName, L"FailCreateClose");
+
+    NdisReadConfiguration(&ndisStatus,
+                          &ParameterValue,
+                          ConfigurationHandle,
+                          &ParameterName,
+                          NdisParameterInteger);
+    if (ndisStatus == NDIS_STATUS_SUCCESS &&
+        ParameterValue->ParameterType == NdisParameterInteger)
+        FailCreateClose = ParameterValue->ParameterData.IntegerData;
+    else
+        FailCreateClose = 0;
+
+    RtlInitUnicodeString(&ParameterName, L"FailDeviceControl");
+
+    NdisReadConfiguration(&ndisStatus,
+                          &ParameterValue,
+                          ConfigurationHandle,
+                          &ParameterName,
+                          NdisParameterInteger);
+    if (ndisStatus == NDIS_STATUS_SUCCESS &&
+        ParameterValue->ParameterType == NdisParameterInteger)
+        FailDeviceControl = ParameterValue->ParameterData.IntegerData;
+    else
+        FailDeviceControl = 0;
+
+    NdisCloseConfiguration(ConfigurationHandle);
+    ndisStatus = NDIS_STATUS_SUCCESS;
+
+    NdisDispatchPnp = DriverObject->MajorFunction[IRP_MJ_PNP];
+#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation
+    DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
+
+    if (FailCreateClose != 0) {
+#pragma prefast(suppress:28168) // No matching__drv_dispatchType annotation
+        DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchFail;
+#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation
+        DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchFail;
+    }
+
+    if (FailDeviceControl != 0) {
+#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation
+        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFail;
+    }
+
+    Trace("<====\n");
+    return ndisStatus;
+
+fail:
+    Error("fail\n");
+    return ndisStatus;
+}
diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c
index 0c89f76..c64591d 100644
--- a/src/xennet/transmitter.c
+++ b/src/xennet/transmitter.c
@@ -33,22 +33,72 @@
 #include "transmitter.h"
 #include "adapter.h"
 #include <vif_interface.h>
+#include <cache_interface.h>
 #include "dbg_print.h"
 #include "assert.h"
 
 struct _XENNET_TRANSMITTER {
     PXENNET_ADAPTER             Adapter;
     XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
+    PXENBUS_CACHE               PacketCache;
+    KSPIN_LOCK                  PacketLock;
 };
 
+#define XENNET_PACKET_CACHE_MIN     32
 #define TRANSMITTER_POOL_TAG        'TteN'
 
+static NTSTATUS
+__TransmitterPacketCtor(
+    IN  PVOID       Argument,
+    IN  PVOID       Object
+    )
+{
+    UNREFERENCED_PARAMETER(Argument);
+    UNREFERENCED_PARAMETER(Object);
+    return STATUS_SUCCESS;
+}
+
+static VOID
+__TransmitterPacketDtor(
+    IN  PVOID       Argument,
+    IN  PVOID       Object
+    )
+{
+    UNREFERENCED_PARAMETER(Argument);
+    UNREFERENCED_PARAMETER(Object);
+}
+
+static VOID
+__TransmitterPacketAcquireLock(
+    IN  PVOID           Argument
+    )
+{
+    PXENNET_TRANSMITTER Transmitter = Argument;
+
+    KeAcquireSpinLockAtDpcLevel(&Transmitter->PacketLock);
+}
+
+static VOID
+__TransmitterPacketReleaseLock(
+    IN  PVOID           Argument
+    )
+{
+    PXENNET_TRANSMITTER Transmitter = Argument;
+
+    KeReleaseSpinLockFromDpcLevel(&Transmitter->PacketLock);
+}
+
 NDIS_STATUS
 TransmitterInitialize (
     IN  PXENNET_ADAPTER     Adapter,
     OUT PXENNET_TRANSMITTER *Transmitter
     )
 {
+    NTSTATUS                status;
+    PXENBUS_CACHE_INTERFACE CacheInterface; 
+    
+    CacheInterface = AdapterGetCacheInterface(Adapter);
+
     *Transmitter = ExAllocatePoolWithTag(NonPagedPool,
                                          sizeof(XENNET_TRANSMITTER),
                                          TRANSMITTER_POOL_TAG);
@@ -57,9 +107,28 @@ TransmitterInitialize (
 
     RtlZeroMemory(*Transmitter, sizeof(XENNET_TRANSMITTER));
     (*Transmitter)->Adapter = Adapter;
+    KeInitializeSpinLock(&(*Transmitter)->PacketLock);
+
+    status = XENBUS_CACHE(Create,
+                          CacheInterface,
+                          "packet_cache",
+                          sizeof(XENVIF_TRANSMITTER_PACKET),
+                          XENNET_PACKET_CACHE_MIN,
+                          __TransmitterPacketCtor,
+                          __TransmitterPacketDtor,
+                          __TransmitterPacketAcquireLock,
+                          __TransmitterPacketReleaseLock,
+                          *Transmitter,
+                          &(*Transmitter)->PacketCache);
+    if (!NT_SUCCESS(status))
+        goto fail2;
     
     return NDIS_STATUS_SUCCESS;
 
+fail2:
+    RtlZeroMemory(&(*Transmitter)->PacketLock, sizeof(KSPIN_LOCK));
+    ExFreePoolWithTag(*Transmitter, TRANSMITTER_POOL_TAG);
+    *Transmitter = NULL;
 fail1:
     return NDIS_STATUS_FAILURE;
 }
@@ -69,36 +138,54 @@ TransmitterTeardown(
     IN  PXENNET_TRANSMITTER Transmitter
     )
 {
+    PXENBUS_CACHE_INTERFACE CacheInterface; 
+    
+    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
+
     Transmitter->Adapter = NULL;
     Transmitter->OffloadOptions.Value = 0;
+    RtlZeroMemory(&Transmitter->PacketLock, sizeof(KSPIN_LOCK));
+
+    XENBUS_CACHE(Destroy,
+                 CacheInterface,
+                 Transmitter->PacketCache);
+    Transmitter->PacketCache = NULL;
 
     ExFreePoolWithTag(Transmitter, TRANSMITTER_POOL_TAG);
 }
 
-VOID
-TransmitterEnable(
+static FORCEINLINE PXENVIF_TRANSMITTER_PACKET
+__TransmitterGetPacket(
     IN  PXENNET_TRANSMITTER Transmitter
     )
 {
-    PXENVIF_VIF_INTERFACE   VifInterface = 
AdapterGetVifInterface(Transmitter->Adapter);
-
-    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
-                      VifInterface,
-                      XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET,
-                      
(LONG_PTR)&NET_BUFFER_CURRENT_MDL_OFFSET((PNET_BUFFER)NULL) -
-                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
-
-    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
-                      VifInterface,
-                      XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET,
-                      (LONG_PTR)&NET_BUFFER_DATA_LENGTH((PNET_BUFFER)NULL) -
-                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
-
-    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
-                      VifInterface,
-                      XENVIF_TRANSMITTER_PACKET_MDL_OFFSET,
-                      (LONG_PTR)&NET_BUFFER_CURRENT_MDL((PNET_BUFFER)NULL) -
-                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
+    PXENBUS_CACHE_INTERFACE CacheInterface; 
+    
+    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
+
+    return XENBUS_CACHE(Get,
+                        CacheInterface,
+                        Transmitter->PacketCache,
+                        FALSE);
+}
+
+static FORCEINLINE VOID
+__TransmitterPutPacket(
+    IN  PXENNET_TRANSMITTER         Transmitter,
+    IN  PXENVIF_TRANSMITTER_PACKET  Packet
+    )
+{
+    PXENBUS_CACHE_INTERFACE CacheInterface; 
+    
+    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
+
+    RtlZeroMemory(Packet, sizeof(XENVIF_TRANSMITTER_PACKET));
+
+    XENBUS_CACHE(Put,
+                 CacheInterface,
+                 Transmitter->PacketCache,
+                 Packet,
+                 FALSE);
 }
 
 typedef struct _NET_BUFFER_LIST_RESERVED {
@@ -107,13 +194,6 @@ typedef struct _NET_BUFFER_LIST_RESERVED {
 
 C_ASSERT(sizeof (NET_BUFFER_LIST_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER_LIST, 
MiniportReserved));
 
-typedef struct _NET_BUFFER_RESERVED {
-    XENVIF_TRANSMITTER_PACKET   Packet;
-    PNET_BUFFER_LIST            NetBufferList;
-} NET_BUFFER_RESERVED, *PNET_BUFFER_RESERVED;
-
-C_ASSERT(sizeof (NET_BUFFER_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER, 
MiniportReserved));
-
 static VOID
 __TransmitterCompleteNetBufferList(
     IN  PXENNET_TRANSMITTER     Transmitter,
@@ -140,26 +220,25 @@ __TransmitterCompleteNetBufferList(
                                     NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
 }
 
-
 static VOID
 __TransmitterCompletePackets(
-    IN  PXENNET_TRANSMITTER         Transmitter,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet,
-    IN  NDIS_STATUS                 Status
+    IN  PXENNET_TRANSMITTER Transmitter,
+    IN  PLIST_ENTRY         List,
+    IN  NDIS_STATUS         Status
     )
 {
-    while (Packet != NULL) {
-        PXENVIF_TRANSMITTER_PACKET  Next;
-        PNET_BUFFER_RESERVED        Reserved;
+    while (!IsListEmpty(List)) {
+        PLIST_ENTRY                 ListEntry;
+        PXENVIF_TRANSMITTER_PACKET  Packet;
         PNET_BUFFER_LIST            NetBufferList;
         PNET_BUFFER_LIST_RESERVED   ListReserved;
 
-        Next = Packet->Next;
-        Packet->Next = NULL;
+        ListEntry = RemoveHeadList(List);
+        ASSERT3P(ListEntry, !=, List);
 
-        Reserved = CONTAINING_RECORD(Packet, NET_BUFFER_RESERVED, Packet);
+        Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET, 
ListEntry);
 
-        NetBufferList = Reserved->NetBufferList;
+        NetBufferList = Packet->Cookie;
         ASSERT(NetBufferList != NULL);
 
         ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
@@ -168,7 +247,7 @@ __TransmitterCompletePackets(
         if (InterlockedDecrement(&ListReserved->Reference) == 0)
             __TransmitterCompleteNetBufferList(Transmitter, NetBufferList, 
Status);
 
-        Packet = Next;
+        __TransmitterPutPacket(Transmitter, Packet);
     }    
 }
 
@@ -246,14 +325,12 @@ TransmitterSendNetBufferLists(
     IN  ULONG                   SendFlags
     )
 {
-    PXENVIF_TRANSMITTER_PACKET  HeadPacket;
-    PXENVIF_TRANSMITTER_PACKET  *TailPacket;
+    LIST_ENTRY                  List;
     KIRQL                       Irql;
 
     UNREFERENCED_PARAMETER(PortNumber);
 
-    HeadPacket = NULL;
-    TailPacket = &HeadPacket;
+    InitializeListHead(&List);
 
     if (!NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags)) {
         ASSERT3U(NDIS_CURRENT_IRQL(), <=, DISPATCH_LEVEL);
@@ -283,23 +360,35 @@ TransmitterSendNetBufferLists(
 
         NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
         while (NetBuffer != NULL) {
-            PNET_BUFFER_RESERVED        Reserved;
             PXENVIF_TRANSMITTER_PACKET  Packet;
 
-            Reserved = 
(PNET_BUFFER_RESERVED)NET_BUFFER_MINIPORT_RESERVED(NetBuffer);
-            RtlZeroMemory(Reserved, sizeof (NET_BUFFER_RESERVED));
+            Packet = __TransmitterGetPacket(Transmitter);
+            if (Packet == NULL) {
+                while (ListReserved->Reference--) {
+                    PLIST_ENTRY     ListEntry;
+
+                    ListEntry = RemoveTailList(&List);
+                    ASSERT3P(ListEntry, !=, &List);
+
+                    Packet = CONTAINING_RECORD(ListEntry, 
XENVIF_TRANSMITTER_PACKET, ListEntry);
+                    
+                    __TransmitterPutPacket(Transmitter, Packet);
+                }
+                __TransmitterCompleteNetBufferList(Transmitter, NetBufferList, 
NDIS_STATUS_NOT_ACCEPTED);
+                break;
+            }
 
-            Reserved->NetBufferList = NetBufferList;
             ListReserved->Reference++;
 
-            Packet = &Reserved->Packet;
+            Packet->Cookie = NetBufferList;
             Packet->Send.OffloadOptions.Value = OffloadOptions.Value & 
Transmitter->OffloadOptions.Value;
             Packet->Send.MaximumSegmentSize = MaximumSegmentSize;
             Packet->Send.TagControlInformation = TagControlInformation;
+            Packet->Mdl = NET_BUFFER_CURRENT_MDL(NetBuffer);
+            Packet->Length = NET_BUFFER_DATA_LENGTH(NetBuffer);
+            Packet->Offset = NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer);
 
-            ASSERT3P(Packet->Next, ==, NULL);
-            *TailPacket = Packet;
-            TailPacket = &Packet->Next;
+            InsertTailList(&List, &Packet->ListEntry);
 
             NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer);
         }
@@ -307,14 +396,14 @@ TransmitterSendNetBufferLists(
         NetBufferList = ListNext;
     }
 
-    if (HeadPacket != NULL) {
+    if (!IsListEmpty(&List)) {
         NTSTATUS    status; 
 
         status = XENVIF_VIF(TransmitterQueuePackets,
                             AdapterGetVifInterface(Transmitter->Adapter),
-                            HeadPacket);
+                            &List);
         if (!NT_SUCCESS(status))
-            __TransmitterCompletePackets(Transmitter, HeadPacket, 
NDIS_STATUS_NOT_ACCEPTED);
+            __TransmitterCompletePackets(Transmitter, &List, 
NDIS_STATUS_NOT_ACCEPTED);
     }
 
     NDIS_LOWER_IRQL(Irql, DISPATCH_LEVEL);
@@ -322,11 +411,11 @@ TransmitterSendNetBufferLists(
 
 VOID
 TransmitterCompletePackets(
-    IN  PXENNET_TRANSMITTER         Transmitter,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet
+    IN  PXENNET_TRANSMITTER Transmitter,
+    IN  PLIST_ENTRY         List
     )
 {
-    __TransmitterCompletePackets(Transmitter, Packet, NDIS_STATUS_SUCCESS);
+    __TransmitterCompletePackets(Transmitter, List, NDIS_STATUS_SUCCESS);
 }
 
 PXENVIF_VIF_OFFLOAD_OPTIONS
diff --git a/src/xennet/transmitter.h b/src/xennet/transmitter.h
index f63a2a0..0adebdc 100644
--- a/src/xennet/transmitter.h
+++ b/src/xennet/transmitter.h
@@ -49,11 +49,6 @@ TransmitterTeardown(
     );
 
 extern VOID
-TransmitterEnable(
-    IN  PXENNET_TRANSMITTER Transmitter
-    );
-
-extern VOID
 TransmitterSendNetBufferLists (
     IN  PXENNET_TRANSMITTER Transmitter,
     IN  PNET_BUFFER_LIST    NetBufferList,
@@ -63,8 +58,8 @@ TransmitterSendNetBufferLists (
 
 extern VOID
 TransmitterCompletePackets(
-    IN  PXENNET_TRANSMITTER         Transmitter,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet
+    IN  PXENNET_TRANSMITTER Transmitter,
+    IN  PLIST_ENTRY         List
     );
 
 extern PXENVIF_VIF_OFFLOAD_OPTIONS
-- 
1.9.4.msysgit.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.