[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 |