|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |