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

Re: [win-pv-devel] [PATCH for 8.1] Make sure XENBUS interfaces are released when going into S4



> -----Original Message-----
> From: Paul Durrant [mailto:pdurrant@xxxxxxxxx]
> Sent: 03 December 2015 13:07
> To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Paul Durrant
> Subject: [PATCH for 8.1] Make sure XENBUS interfaces are released when
> going into S4
> 
> Because a transition into and out of S4 means a new domain is built, it's
> crucial that all XENBUS interfaces are released (so that things like
> event channels, grant tables and the xenstore ring get re-constructed).
> 
> This patch fixes code paths where this was not being done. It also adds
> some more logging during AdapterEnable/Disable and when moving
> between
> D0 and D3.
> 
> Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>

Note that this patch introduces a race between cache destruction and packet 
transmission which can lead to a NULL pointer dereference. The only sound 
solution I can see to this is to move hashing into XENVIF so that XENNET no 
longer needs to use caches and their lifecycle can then be protected by the 
MRSW VIF interface lock.
Since that's a significant amount of code change it's going to take a while and 
so I will not back-port this patch until then.

  Paul

> ---
>  src/xennet/adapter.c     | 2719 +++++++++++++++++++++++-------------------
> ----
>  src/xennet/adapter.h     |    2 +-
>  src/xennet/miniport.c    |   21 +-
>  src/xennet/receiver.c    |   18 +
>  src/xennet/receiver.h    |   10 +
>  src/xennet/transmitter.c |   63 +-
>  src/xennet/transmitter.h |   10 +
>  7 files changed, 1471 insertions(+), 1372 deletions(-)
> 
> diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c
> index f9b3cf1..2c35636 100644
> --- a/src/xennet/adapter.c
> +++ b/src/xennet/adapter.c
> @@ -1074,1576 +1074,1671 @@ AdapterGetReceiver(
>      return Adapter->Receiver;
>  }
> 
> -NDIS_STATUS
> -AdapterEnable(
> -    IN  PXENNET_ADAPTER     Adapter
> +static FORCEINLINE PVOID
> +__AdapterAllocate(
> +    IN  ULONG   Length
>      )
>  {
> -    NTSTATUS        status;
> -
> -    if (Adapter->Enabled)
> -        return NDIS_STATUS_SUCCESS;
> -
> -    status = XENVIF_VIF(Enable,
> -                        &Adapter->VifInterface,
> -                        AdapterVifCallback,
> -                        Adapter);
> -    if (!NT_SUCCESS(status))
> -        goto fail1;
> -
> -    Adapter->Enabled = TRUE;
> -
> -    return NDIS_STATUS_SUCCESS;
> +    return __AllocateNonPagedPoolWithTag(Length, ADAPTER_POOL_TAG);
> +}
> 
> -fail1:
> -    return NDIS_STATUS_FAILURE;
> +static FORCEINLINE VOID
> +__AdapterFree(
> +    IN  PVOID   Buffer
> +    )
> +{
> +    __FreePoolWithTag(Buffer, ADAPTER_POOL_TAG);
>  }
> 
> -BOOLEAN
> -AdapterDisable(
> -    IN  PXENNET_ADAPTER     Adapter
> +static FORCEINLINE PANSI_STRING
> +__AdapterMultiSzToUpcaseAnsi(
> +    IN  PCHAR       Buffer
>      )
>  {
> -    if (!Adapter->Enabled)
> -        return FALSE;
> +    PANSI_STRING    Ansi;
> +    LONG            Index;
> +    LONG            Count;
> +    NTSTATUS        status;
> 
> -    XENVIF_VIF(Disable,
> -               &Adapter->VifInterface);
> +    Index = 0;
> +    Count = 0;
> +    for (;;) {
> +        if (Buffer[Index] == '\0') {
> +            Count++;
> +            Index++;
> 
> -    AdapterMediaStateChange(Adapter);
> +            // Check for double NUL
> +            if (Buffer[Index] == '\0')
> +                break;
> +        } else {
> +            Buffer[Index] = (CHAR)toupper(Buffer[Index]);
> +            Index++;
> +        }
> +    }
> 
> -    Adapter->Enabled = FALSE;
> +    Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
> 
> -    return TRUE;
> -}
> +    status = STATUS_NO_MEMORY;
> +    if (Ansi == NULL)
> +        goto fail1;
> 
> -VOID
> -AdapterMediaStateChange(
> -    IN  PXENNET_ADAPTER     Adapter
> -    )
> -{
> -    NDIS_LINK_STATE         LinkState;
> -    NDIS_STATUS_INDICATION  StatusIndication;
> +    for (Index = 0; Index < Count; Index++) {
> +        ULONG   Length;
> 
> -    RtlZeroMemory(&LinkState, sizeof (NDIS_LINK_STATE));
> -    LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1;
> -    LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
> -    LinkState.Header.Size = sizeof(NDIS_LINK_STATE);
> +        Length = (ULONG)strlen(Buffer);
> +        Ansi[Index].MaximumLength = (USHORT)(Length + 1);
> +        Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
> 
> -    XENVIF_VIF(MacQueryState,
> -               &Adapter->VifInterface,
> -               &LinkState.MediaConnectState,
> -               &LinkState.RcvLinkSpeed,
> -               &LinkState.MediaDuplexState);
> +        status = STATUS_NO_MEMORY;
> +        if (Ansi[Index].Buffer == NULL)
> +            goto fail2;
> 
> -    if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
> -        Info("LINK: STATE UNKNOWN\n");
> -    } else if (LinkState.MediaConnectState ==
> MediaConnectStateDisconnected) {
> -        Info("LINK: DOWN\n");
> -    } else {
> -        ASSERT3U(LinkState.MediaConnectState, ==,
> MediaConnectStateConnected);
> +        RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
> +        Ansi[Index].Length = (USHORT)Length;
> 
> -        if (LinkState.MediaDuplexState == MediaDuplexStateHalf)
> -            Info("LINK: UP: SPEED=%u DUPLEX=HALF\n",
> LinkState.RcvLinkSpeed);
> -        else if (LinkState.MediaDuplexState == MediaDuplexStateFull)
> -            Info("LINK: UP: SPEED=%u DUPLEX=FULL\n", LinkState.RcvLinkSpeed);
> -        else
> -            Info("LINK: UP: SPEED=%u DUPLEX=UNKNOWN\n",
> LinkState.RcvLinkSpeed);
> +        Buffer += Length + 1;
>      }
> 
> -    LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
> +    return Ansi;
> 
> -    RtlZeroMemory(&StatusIndication, sizeof (NDIS_STATUS_INDICATION));
> -    StatusIndication.Header.Type =
> NDIS_OBJECT_TYPE_STATUS_INDICATION;
> -    StatusIndication.Header.Revision =
> NDIS_STATUS_INDICATION_REVISION_1;
> -    StatusIndication.Header.Size = sizeof (NDIS_STATUS_INDICATION);
> +fail2:
> +    Error("fail2\n");
> 
> -    StatusIndication.SourceHandle = Adapter->NdisAdapterHandle;
> -    StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE;
> -    StatusIndication.StatusBuffer = &LinkState;
> -    StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE);
> +    while (--Index >= 0)
> +        __AdapterFree(Ansi[Index].Buffer);
> 
> -    NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication);
> +    __AdapterFree(Ansi);
> +
> +fail1:
> +    Error("fail1 (%08x)\n", status);
> +
> +    return NULL;
>  }
> 
> -NDIS_STATUS
> -AdapterSetInformation(
> -    IN  PXENNET_ADAPTER     Adapter,
> -    IN  PNDIS_OID_REQUEST   Request
> +static FORCEINLINE VOID
> +__AdapterFreeAnsi(
> +    IN  PANSI_STRING    Ansi
>      )
>  {
> -    PVOID                   Buffer;
> -    ULONG                   BufferLength;
> -    ULONG                   BytesNeeded;
> -    ULONG                   BytesRead;
> -    BOOLEAN                 Warn;
> -    NDIS_STATUS             ndisStatus;
> +    ULONG               Index;
> 
> -    Buffer = Request->DATA.SET_INFORMATION.InformationBuffer;
> -    BufferLength = Request-
> >DATA.SET_INFORMATION.InformationBufferLength;
> -    BytesNeeded = BytesRead = 0;
> -    Warn = TRUE;
> -    ndisStatus = NDIS_STATUS_SUCCESS;
> +    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
> +        __AdapterFree(Ansi[Index].Buffer);
> 
> -    switch (Request->DATA.SET_INFORMATION.Oid) {
> -    case OID_PNP_SET_POWER:
> -        BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
> -        // do nothing
> -        break;
> +    __AdapterFree(Ansi);
> +}
> 
> -    case OID_GEN_CURRENT_LOOKAHEAD:
> -        BytesNeeded = sizeof(ULONG);
> -        Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
> -        if (BufferLength == BytesNeeded) {
> -            Adapter->CurrentLookahead = *(PULONG)Buffer;
> -            BytesRead = sizeof(ULONG);
> -        }
> -        break;
> +static FORCEINLINE BOOLEAN
> +__AdapterMatchDistribution(
> +    IN  PXENNET_ADAPTER Adapter,
> +    IN  PCHAR           Buffer
> +    )
> +{
> +    PCHAR               Vendor;
> +    PCHAR               Product;
> +    PCHAR               Context;
> +    const CHAR          *Text;
> +    BOOLEAN             Match;
> +    ULONG               Index;
> +    NTSTATUS            status;
> 
> -    case OID_GEN_CURRENT_PACKET_FILTER:
> -        BytesNeeded = sizeof(ULONG);
> -        if (BufferLength == BytesNeeded) {
> -            ndisStatus = AdapterSetPacketFilter(Adapter,
> -                                                (PULONG)Buffer);
> -            BytesRead = sizeof(ULONG);
> -        }
> -        break;
> +    UNREFERENCED_PARAMETER(Adapter);
> 
> -    case OID_802_3_MULTICAST_LIST:
> -        BytesNeeded = ETHERNET_ADDRESS_LENGTH;
> -        if (BufferLength % ETHERNET_ADDRESS_LENGTH == 0) {
> -            ndisStatus = AdapterSetMulticastAddresses(Adapter,
> -                                                      Buffer,
> -                                                      BufferLength / 
> ETHERNET_ADDRESS_LENGTH);
> -            if (ndisStatus == NDIS_STATUS_SUCCESS)
> -                BytesRead = BufferLength;
> -        } else {
> -            ndisStatus = NDIS_STATUS_INVALID_LENGTH;
> -        }
> -        break;
> +    status = STATUS_INVALID_PARAMETER;
> 
> -    case OID_OFFLOAD_ENCAPSULATION:
> -        BytesNeeded = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
> -        if (BufferLength >= BytesNeeded) {
> -            ndisStatus = AdapterGetOffloadEncapsulation(Adapter,
> -                                                        
> (PNDIS_OFFLOAD_ENCAPSULATION)Buffer);
> -            if (ndisStatus == NDIS_STATUS_SUCCESS)
> -                BytesRead = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
> -        }
> -        break;
> +    Vendor = __strtok_r(Buffer, " ", &Context);
> +    if (Vendor == NULL)
> +        goto fail1;
> 
> -    case OID_TCP_OFFLOAD_PARAMETERS:
> -        BytesNeeded = sizeof(NDIS_OFFLOAD_PARAMETERS);
> -        if (BufferLength >= BytesNeeded) {
> -            ndisStatus = AdapterGetTcpOffloadParameters(Adapter,
> -                                                        
> (PNDIS_OFFLOAD_PARAMETERS)Buffer);
> -            if (ndisStatus == NDIS_STATUS_SUCCESS)
> -                BytesRead = sizeof(NDIS_OFFLOAD_PARAMETERS);
> -        }
> -        break;
> +    Product = __strtok_r(NULL, " ", &Context);
> +    if (Product == NULL)
> +        goto fail2;
> 
> -    case OID_GEN_HD_SPLIT_PARAMETERS:
> -        BytesNeeded = sizeof(NDIS_HD_SPLIT_PARAMETERS);
> -        if (BufferLength >= BytesNeeded) {
> -            ndisStatus = AdapterGetHeaderDataSplitParameters(Adapter,
> -                                                             
> (PNDIS_HD_SPLIT_PARAMETERS)Buffer);
> -            if (ndisStatus == NDIS_STATUS_SUCCESS)
> -                BytesRead = sizeof(NDIS_HD_SPLIT_PARAMETERS);
> -        }
> -        break;
> +    Match = TRUE;
> 
> -    case OID_GEN_INTERRUPT_MODERATION:
> -    case OID_GEN_MACHINE_NAME:
> -        Warn = FALSE;
> -        /*FALLTHRU*/
> -    default:
> -        if (Warn)
> -            Warning("UNSUPPORTED OID %08x\n", Request-
> >DATA.QUERY_INFORMATION.Oid);
> +    Text = VENDOR_NAME_STR;
> 
> -        ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
> -        break;
> +    for (Index = 0; Text[Index] != 0; Index++) {
> +        if (!isalnum((UCHAR)Text[Index])) {
> +            if (Vendor[Index] != '_') {
> +                Match = FALSE;
> +                break;
> +            }
> +        } else {
> +            if (Vendor[Index] != Text[Index]) {
> +                Match = FALSE;
> +                break;
> +            }
> +        }
>      }
> 
> -    Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded;
> -    if (ndisStatus == NDIS_STATUS_SUCCESS)
> -        Request->DATA.SET_INFORMATION.BytesRead = BytesRead;
> +    Text = "XENNET";
> 
> -    return ndisStatus;
> -}
> +    if (_stricmp(Product, Text) != 0)
> +        Match = FALSE;
> 
> -static FORCEINLINE NDIS_STATUS
> -__CopyBuffer(
> -    IN  PVOID   Destination,
> -    IN  ULONG   DestinationLength,
> -    IN  PVOID   Source,
> -    IN  ULONG   SourceLength,
> -    OUT PULONG  CopyLength
> -    )
> -{
> -    *CopyLength = __min(SourceLength, DestinationLength);
> -    RtlCopyMemory(Destination, Source, *CopyLength);
> +    return Match;
> 
> -    return (DestinationLength >= SourceLength) ?
> -           NDIS_STATUS_SUCCESS :
> -           NDIS_STATUS_BUFFER_TOO_SHORT;
> -}
> +fail2:
> +    Error("fail2\n");
> 
> -static FORCEINLINE NDIS_STATUS
> -__SetUlong(
> -    IN  PVOID   Destination,
> -    IN  ULONG   DestinationLength,
> -    IN  ULONG   Source,
> -    OUT PULONG  CopyLength
> -    )
> -{
> -    return __CopyBuffer(Destination,
> -                        DestinationLength & ~3,
> -                        &Source,
> -                        sizeof (ULONG),
> -                        CopyLength);
> +fail1:
> +    Error("fail1 (%08x)\n", status);
> +
> +    return FALSE;
>  }
> 
> -static FORCEINLINE NDIS_STATUS
> -__SetUlong64(
> -    IN  PVOID   Destination,
> -    IN  ULONG   DestinationLength,
> -    IN  ULONG64 Source,
> -    OUT PULONG  CopyLength
> +static FORCEINLINE VOID
> +__AdapterClearDistribution(
> +    IN  PXENNET_ADAPTER Adapter
>      )
>  {
> -    NDIS_STATUS ndisStatus;
> +    PCHAR               Buffer;
> +    PANSI_STRING        Distributions;
> +    ULONG               Index;
> +    NTSTATUS            status;
> 
> -    ndisStatus =  __CopyBuffer(Destination,
> -                               DestinationLength & ~3,
> -                               &Source,
> -                               sizeof (ULONG64),
> -                               CopyLength);
> -    if (DestinationLength >= 4)
> -        ndisStatus = NDIS_STATUS_SUCCESS;
> +    Trace("====>\n");
> 
> -    return ndisStatus;
> -}
> +    status = XENBUS_STORE(Directory,
> +                          &Adapter->StoreInterface,
> +                          NULL,
> +                          NULL,
> +                          "drivers",
> +                          &Buffer);
> +    if (NT_SUCCESS(status)) {
> +        Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer);
> 
> -NDIS_STATUS
> -AdapterQueryInformation(
> -    IN  PXENNET_ADAPTER     Adapter,
> -    IN  PNDIS_OID_REQUEST   Request
> -    )
> -{
> -    PVOID                   Buffer;
> -    ULONG                   BufferLength;
> -    ULONG                   BytesNeeded;
> -    ULONG                   BytesWritten;
> -    ULONG                   Value32;
> -    ULONGLONG               Value64;
> -    ETHERNET_ADDRESS        EthernetAddress;
> -    BOOLEAN                 Warn;
> -    NDIS_STATUS             ndisStatus;
> +        XENBUS_STORE(Free,
> +                     &Adapter->StoreInterface,
> +                     Buffer);
> +    } else {
> +        Distributions = NULL;
> +    }
> 
> -    Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
> -    BufferLength = Request-
> >DATA.QUERY_INFORMATION.InformationBufferLength;
> -    BytesNeeded = BytesWritten = 0;
> -    Warn = TRUE;
> -    ndisStatus = NDIS_STATUS_SUCCESS;
> +    if (Distributions == NULL)
> +        goto done;
> 
> -    switch (Request->DATA.QUERY_INFORMATION.Oid) {
> -    case OID_PNP_CAPABILITIES:
> -        BytesNeeded = sizeof(Adapter->Capabilities);
> -        ndisStatus = __CopyBuffer(Buffer,
> -                                  BufferLength,
> -                                  &Adapter->Capabilities,
> -                                  BytesNeeded,
> -                                  &BytesWritten);
> -        break;
> +    for (Index = 0; Distributions[Index].Buffer != NULL; Index++) {
> +        PANSI_STRING    Distribution = &Distributions[Index];
> 
> -    case OID_PNP_QUERY_POWER:
> -        BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
> -        BytesWritten = 0;
> -        // do nothing
> -        break;
> +        status = XENBUS_STORE(Read,
> +                              &Adapter->StoreInterface,
> +                              NULL,
> +                              "drivers",
> +                              Distribution->Buffer,
> +                              &Buffer);
> +        if (!NT_SUCCESS(status))
> +            continue;
> 
> -    case OID_GEN_SUPPORTED_LIST:
> -        BytesNeeded = sizeof(XennetSupportedOids);
> -        ndisStatus = __CopyBuffer(Buffer,
> -                                  BufferLength,
> -                                  &XennetSupportedOids[0],
> -                                  BytesNeeded,
> -                                  &BytesWritten);
> -        break;
> +        if (__AdapterMatchDistribution(Adapter, Buffer))
> +            (VOID) XENBUS_STORE(Remove,
> +                                &Adapter->StoreInterface,
> +                                NULL,
> +                                "drivers",
> +                                Distribution->Buffer);
> 
> -    case OID_GEN_HARDWARE_STATUS:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                NdisHardwareStatusReady,
> -                                &BytesWritten);
> -        break;
> +        XENBUS_STORE(Free,
> +                     &Adapter->StoreInterface,
> +                     Buffer);
> +    }
> 
> -    case OID_GEN_MEDIA_SUPPORTED:
> -    case OID_GEN_MEDIA_IN_USE:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                XENNET_MEDIA_TYPE,
> -                                &BytesWritten);
> -        break;
> +    __AdapterFreeAnsi(Distributions);
> 
> -    case OID_GEN_MAXIMUM_LOOKAHEAD:
> -    case OID_GEN_TRANSMIT_BLOCK_SIZE:
> -    case OID_GEN_RECEIVE_BLOCK_SIZE:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Adapter->MaximumFrameSize,
> -                                &BytesWritten);
> -        break;
> +done:
> +    Trace("<====\n");
> +}
> 
> -    case OID_GEN_TRANSMIT_BUFFER_SPACE:
> -    case OID_GEN_RECEIVE_BUFFER_SPACE:
> -        XENVIF_VIF(TransmitterQueryRingSize,
> -                    &Adapter->VifInterface,
> -                    (PULONG)&Value32);
> -        Value32 *= Adapter->MaximumFrameSize;
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Value32,
> -                                &BytesWritten);
> -        break;
> +#define MAXIMUM_INDEX   255
> 
> -    case OID_GEN_VENDOR_DESCRIPTION:
> -        BytesNeeded = (ULONG)strlen(VENDOR_NAME_STR) + 1;
> -        ndisStatus = __CopyBuffer(Buffer,
> -                                  BufferLength,
> -                                  VENDOR_NAME_STR,
> -                                  BytesNeeded,
> -                                  &BytesWritten);
> -        break;
> +static FORCEINLINE NTSTATUS
> +__AdapterSetDistribution(
> +    IN  PXENNET_ADAPTER Adapter
> +    )
> +{
> +    ULONG               Index;
> +    CHAR                Distribution[MAXNAMELEN];
> +    CHAR                Vendor[MAXNAMELEN];
> +    const CHAR          *Product;
> +    NTSTATUS            status;
> 
> -    case OID_GEN_VENDOR_DRIVER_VERSION:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8,
> -                                &BytesWritten);
> -        break;
> +    Trace("====>\n");
> 
> -    case OID_GEN_DRIVER_VERSION:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (6 << 8) | 0, // NDIS 6.0
> -                                &BytesWritten);
> -        break;
> +    Index = 0;
> +    while (Index <= MAXIMUM_INDEX) {
> +        PCHAR   Buffer;
> 
> -    case OID_GEN_MAC_OPTIONS:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                XENNET_MAC_OPTIONS,
> -                                &BytesWritten);
> -        break;
> +        status = RtlStringCbPrintfA(Distribution,
> +                                    MAXNAMELEN,
> +                                    "%u",
> +                                    Index);
> +        ASSERT(NT_SUCCESS(status));
> 
> -    case OID_GEN_STATISTICS:
> -        BytesNeeded = sizeof(NDIS_STATISTICS_INFO);
> -        ndisStatus = AdapterQueryGeneralStatistics(Adapter,
> -                                                   
> (PNDIS_STATISTICS_INFO)Buffer,
> -                                                   BufferLength,
> -                                                   &BytesWritten);
> -        break;
> +        status = XENBUS_STORE(Read,
> +                              &Adapter->StoreInterface,
> +                              NULL,
> +                              "drivers",
> +                              Distribution,
> +                              &Buffer);
> +        if (!NT_SUCCESS(status)) {
> +            if (status == STATUS_OBJECT_NAME_NOT_FOUND)
> +                goto update;
> 
> -    case OID_802_3_MULTICAST_LIST:
> -        ndisStatus = AdapterQueryMulticastList(Adapter,
> -                                               Buffer,
> -                                               BufferLength,
> -                                               &BytesNeeded,
> -                                               &BytesWritten);
> -        break;
> +            goto fail1;
> +        }
> 
> -    case OID_802_3_PERMANENT_ADDRESS:
> -        XENVIF_VIF(MacQueryPermanentAddress,
> -                    &Adapter->VifInterface,
> -                    &EthernetAddress);
> -        BytesNeeded = sizeof(ETHERNET_ADDRESS);
> -        ndisStatus = __CopyBuffer(Buffer,
> -                                  BufferLength,
> -                                  &EthernetAddress,
> -                                  BytesNeeded,
> -                                  &BytesWritten);
> -        break;
> +        XENBUS_STORE(Free,
> +                     &Adapter->StoreInterface,
> +                     Buffer);
> 
> -    case OID_802_3_CURRENT_ADDRESS:
> -        XENVIF_VIF(MacQueryCurrentAddress,
> -                    &Adapter->VifInterface,
> -                    &EthernetAddress);
> -        BytesNeeded = sizeof(ETHERNET_ADDRESS);
> -        ndisStatus = __CopyBuffer(Buffer,
> -                                  BufferLength,
> -                                  &EthernetAddress,
> -                                  BytesNeeded,
> -                                  &BytesWritten);
> -        break;
> +        Index++;
> +    }
> 
> -    case OID_GEN_MAXIMUM_FRAME_SIZE:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Adapter->MaximumFrameSize -
> -                                    sizeof(ETHERNET_TAGGED_HEADER),
> -                                &BytesWritten);
> -        break;
> +    status = STATUS_UNSUCCESSFUL;
> +    goto fail2;
> 
> -    case OID_GEN_MAXIMUM_TOTAL_SIZE:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Adapter->MaximumFrameSize -
> -                                    sizeof(ETHERNET_TAGGED_HEADER) +
> -                                    sizeof (ETHERNET_UNTAGGED_HEADER),
> -                                &BytesWritten);
> -        break;
> +update:
> +    status = RtlStringCbPrintfA(Vendor,
> +                                MAXNAMELEN,
> +                                "%s",
> +                                VENDOR_NAME_STR);
> +    ASSERT(NT_SUCCESS(status));
> 
> -    case OID_GEN_CURRENT_LOOKAHEAD:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Adapter->CurrentLookahead,
> -                                &BytesWritten);
> -        break;
> +    for (Index  = 0; Vendor[Index] != '\0'; Index++)
> +        if (!isalnum((UCHAR)Vendor[Index]))
> +            Vendor[Index] = '_';
> 
> -    case OID_GEN_VENDOR_ID:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                0x5853,
> -                                &BytesWritten);
> -        break;
> +    Product = "XENNET";
> 
> -    case OID_GEN_LINK_SPEED:
> -        XENVIF_VIF(MacQueryState,
> -                   &Adapter->VifInterface,
> -                   NULL,
> -                   &Value64,
> -                   NULL);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)(Value64 / 100),
> -                                &BytesWritten);
> -        break;
> +#if DBG
> +#define ATTRIBUTES   "(DEBUG)"
> +#else
> +#define ATTRIBUTES   ""
> +#endif
> 
> -    case OID_GEN_MEDIA_CONNECT_STATUS:
> -        XENVIF_VIF(MacQueryState,
> -                    &Adapter->VifInterface,
> -                    (PNET_IF_MEDIA_CONNECT_STATE)&Value32,
> -                    NULL,
> -                    NULL);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Value32,
> -                                &BytesWritten);
> -        break;
> +    (VOID) XENBUS_STORE(Printf,
> +                        &Adapter->StoreInterface,
> +                        NULL,
> +                        "drivers",
> +                        Distribution,
> +                        "%s %s %u.%u.%u %s",
> +                        Vendor,
> +                        Product,
> +                        MAJOR_VERSION,
> +                        MINOR_VERSION,
> +                        MICRO_VERSION,
> +                        ATTRIBUTES
> +                        );
> 
> -    case OID_GEN_MAXIMUM_SEND_PACKETS:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                16,
> -                                &BytesWritten);
> -        break;
> +#undef  ATTRIBUTES
> 
> -    case OID_GEN_CURRENT_PACKET_FILTER:
> -        AdapterGetPacketFilter(Adapter, &Value32);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Value32,
> -                                &BytesWritten);
> -        break;
> +    Trace("<====\n");
> +    return STATUS_SUCCESS;
> 
> -    case OID_GEN_XMIT_OK:
> -        AdapterGetXmitOk(Adapter, &Value64);
> -        BytesNeeded = sizeof(ULONG64);
> -        ndisStatus = __SetUlong64(Buffer,
> -                                  BufferLength,
> -                                  Value64,
> -                                  &BytesWritten);
> -        break;
> +fail2:
> +    Error("fail2\n");
> 
> -    case OID_GEN_RCV_OK:
> -        AdapterGetRcvOk(Adapter, &Value64);
> -        BytesNeeded = sizeof(ULONG64);
> -        ndisStatus = __SetUlong64(Buffer,
> -                                  BufferLength,
> -                                  Value64,
> -                                  &BytesWritten);
> -        break;
> +fail1:
> +    Error("fail1 (%08x)\n", status);
> 
> -    case OID_GEN_XMIT_ERROR:
> -        AdapterGetXmitError(Adapter, &Value32);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Value32,
> -                                &BytesWritten);
> -        break;
> +    return status;
> +}
> 
> -    case OID_GEN_RCV_ERROR:
> -        AdapterGetRcvError(Adapter, &Value32);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                Value32,
> -                                &BytesWritten);
> -        break;
> +static DECLSPEC_NOINLINE VOID
> +AdapterSuspendCallbackLate(
> +    IN  PVOID       Argument
> +    )
> +{
> +    PXENNET_ADAPTER Adapter = Argument;
> 
> -    case OID_GEN_RCV_NO_BUFFER:
> -    case OID_GEN_TRANSMIT_QUEUE_LENGTH:
> -    case OID_GEN_RCV_CRC_ERROR:
> -    case OID_802_3_RCV_ERROR_ALIGNMENT:
> -    case OID_802_3_XMIT_ONE_COLLISION:
> -    case OID_802_3_XMIT_MORE_COLLISIONS:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                0,
> -                                &BytesWritten);
> -        break;
> +    (VOID) __AdapterSetDistribution(Adapter);
> +}
> 
> -    case OID_802_3_MAXIMUM_LIST_SIZE:
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                32,
> -                                &BytesWritten);
> -        break;
> +static NTSTATUS
> +AdapterSetDistribution(
> +    IN  PXENNET_ADAPTER Adapter
> +    )
> +{
> +    LONG                Count;
> +    NTSTATUS            status;
> 
> -    case OID_GEN_DIRECTED_BYTES_XMIT:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_TRANSMITTER_UNICAST_OCTETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    Trace("====>\n");
> 
> -    case OID_GEN_DIRECTED_FRAMES_XMIT:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_TRANSMITTER_UNICAST_PACKETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    Count = InterlockedIncrement(&AdapterCount);
> +    ASSERT(Count != 0);
> 
> -    case OID_GEN_MULTICAST_BYTES_XMIT:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_TRANSMITTER_MULTICAST_OCTETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    if (Count != 1)
> +        goto done;
> 
> -    case OID_GEN_MULTICAST_FRAMES_XMIT:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_TRANSMITTER_MULTICAST_PACKETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    status = __AdapterSetDistribution(Adapter);
> +    if (!NT_SUCCESS(status))
> +        goto fail1;
> +
> +    status = XENBUS_SUSPEND(Register,
> +                            &Adapter->SuspendInterface,
> +                            SUSPEND_CALLBACK_LATE,
> +                            AdapterSuspendCallbackLate,
> +                            Adapter,
> +                            &Adapter->SuspendCallbackLate);
> +    if (!NT_SUCCESS(status))
> +        goto fail2;
> +
> +done:
> +    Trace("<====\n");
> +    return STATUS_SUCCESS;
> +
> +fail2:
> +    Error("fail2\n");
> +
> +    __AdapterClearDistribution(Adapter);
> +
> +fail1:
> +    Error("fail1 (%08x)\n", status);
> +
> +    return status;
> +}
> +
> +static VOID
> +AdapterClearDistribution(
> +    IN  PXENNET_ADAPTER Adapter
> +    )
> +{
> +    LONG                Count;
> +
> +    Trace("====>\n");
> +
> +    Count = InterlockedDecrement(&AdapterCount);
> +
> +    if (Count != 0)
> +        goto done;
> +
> +    XENBUS_SUSPEND(Deregister,
> +                   &Adapter->SuspendInterface,
> +                   Adapter->SuspendCallbackLate);
> +    Adapter->SuspendCallbackLate = NULL;
> +
> +    __AdapterClearDistribution(Adapter);
> +
> +done:
> +    Trace("<====\n");
> +}
> +
> +NDIS_STATUS
> +AdapterEnable(
> +    IN  PXENNET_ADAPTER     Adapter
> +    )
> +{
> +    NTSTATUS                status;
> +    NDIS_STATUS             ndisStatus;
> +
> +    ASSERT(!Adapter->Enabled);
> +
> +    status = XENBUS_CACHE(Acquire,
> +                          &Adapter->CacheInterface);
> +    if (!NT_SUCCESS(status))
> +        goto fail1;
> +
> +    status = XENBUS_STORE(Acquire,
> +                          &Adapter->StoreInterface);
> +    if (!NT_SUCCESS(status))
> +        goto fail2;
> +
> +    status = XENBUS_SUSPEND(Acquire,
> +                            &Adapter->SuspendInterface);
> +    if (!NT_SUCCESS(status))
> +        goto fail3;
> +
> +    (VOID) AdapterSetDistribution(Adapter);
> +
> +    ndisStatus = TransmitterEnable(Adapter->Transmitter);
> +    if (ndisStatus != NDIS_STATUS_SUCCESS)
> +        goto fail4;
> +
> +    ndisStatus = ReceiverEnable(Adapter->Receiver);
> +    if (ndisStatus != NDIS_STATUS_SUCCESS)
> +        goto fail5;
> +
> +    status = XENVIF_VIF(Enable,
> +                        &Adapter->VifInterface,
> +                        AdapterVifCallback,
> +                        Adapter);
> +    if (!NT_SUCCESS(status))
> +        goto fail6;
> +
> +    AdapterMediaStateChange(Adapter);
> +
> +    Adapter->Enabled = TRUE;
> +
> +    return NDIS_STATUS_SUCCESS;
> +
> +fail6:
> +    ReceiverDisable(Adapter->Receiver);
> +
> +fail5:
> +    TransmitterDisable(Adapter->Transmitter);
> +
> +fail4:
> +    AdapterClearDistribution(Adapter);
> +
> +    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
> +
> +fail3:
> +    XENBUS_STORE(Release, &Adapter->StoreInterface);
> +
> +fail2:
> +    XENBUS_CACHE(Release, &Adapter->CacheInterface);
> +
> +fail1:
> +    return NDIS_STATUS_FAILURE;
> +}
> 
> -    case OID_GEN_BROADCAST_BYTES_XMIT:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_TRANSMITTER_BROADCAST_OCTETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +VOID
> +AdapterDisable(
> +    IN  PXENNET_ADAPTER     Adapter
> +    )
> +{
> +    ASSERT(Adapter->Enabled);
> +    Adapter->Enabled = FALSE;
> 
> -    case OID_GEN_BROADCAST_FRAMES_XMIT:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_TRANSMITTER_BROADCAST_PACKETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    XENVIF_VIF(Disable,
> +               &Adapter->VifInterface);
> 
> -    case OID_GEN_DIRECTED_BYTES_RCV:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_RECEIVER_UNICAST_OCTETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    AdapterMediaStateChange(Adapter);
> 
> -    case OID_GEN_DIRECTED_FRAMES_RCV:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_RECEIVER_UNICAST_PACKETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    ReceiverDisable(Adapter->Receiver);
> +    TransmitterDisable(Adapter->Transmitter);
> 
> -    case OID_GEN_MULTICAST_BYTES_RCV:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_RECEIVER_MULTICAST_OCTETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    AdapterClearDistribution(Adapter);
> 
> -    case OID_GEN_MULTICAST_FRAMES_RCV:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_RECEIVER_MULTICAST_PACKETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
> +    XENBUS_STORE(Release, &Adapter->StoreInterface);
> +    XENBUS_CACHE(Release, &Adapter->CacheInterface);
> +}
> 
> -    case OID_GEN_BROADCAST_BYTES_RCV:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_RECEIVER_BROADCAST_OCTETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +VOID
> +AdapterMediaStateChange(
> +    IN  PXENNET_ADAPTER     Adapter
> +    )
> +{
> +    NDIS_LINK_STATE         LinkState;
> +    NDIS_STATUS_INDICATION  StatusIndication;
> 
> -    case OID_GEN_BROADCAST_FRAMES_RCV:
> -        XENVIF_VIF(QueryStatistic,
> -                   &Adapter->VifInterface,
> -                   XENVIF_RECEIVER_BROADCAST_PACKETS,
> -                   &Value64);
> -        BytesNeeded = sizeof(ULONG);
> -        ndisStatus = __SetUlong(Buffer,
> -                                BufferLength,
> -                                (ULONG)Value64,
> -                                &BytesWritten);
> -        break;
> +    RtlZeroMemory(&LinkState, sizeof (NDIS_LINK_STATE));
> +    LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1;
> +    LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
> +    LinkState.Header.Size = sizeof(NDIS_LINK_STATE);
> 
> -    case OID_GEN_INTERRUPT_MODERATION:
> -        BytesNeeded = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
> -        ndisStatus = AdapterInterruptModeration(Adapter,
> -
> (PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer,
> -                                                BufferLength,
> -                                                &BytesWritten);
> -        break;
> +    XENVIF_VIF(MacQueryState,
> +               &Adapter->VifInterface,
> +               &LinkState.MediaConnectState,
> +               &LinkState.RcvLinkSpeed,
> +               &LinkState.MediaDuplexState);
> 
> -    case OID_IP4_OFFLOAD_STATS:
> -    case OID_IP6_OFFLOAD_STATS:
> -    case OID_GEN_SUPPORTED_GUIDS:
> -        // We don't handle these since NDIS 6.0 is supposed to do this for us
> -    case OID_GEN_MAC_ADDRESS:
> -    case OID_GEN_MAX_LINK_SPEED:
> -        // ignore these common unwanted OIDs
> -     case OID_GEN_INIT_TIME_MS:
> -     case OID_GEN_RESET_COUNTS:
> -     case OID_GEN_MEDIA_SENSE_COUNTS:
> -        Warn = FALSE;
> -        /*FALLTHRU*/
> -    default:
> -        if (Warn)
> -            Warning("UNSUPPORTED OID %08x\n", Request-
> >DATA.QUERY_INFORMATION.Oid);
> +    if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
> +        Info("LINK: STATE UNKNOWN\n");
> +    } else if (LinkState.MediaConnectState ==
> MediaConnectStateDisconnected) {
> +        Info("LINK: DOWN\n");
> +    } else {
> +        ASSERT3U(LinkState.MediaConnectState, ==,
> MediaConnectStateConnected);
> 
> -        ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
> -        break;
> +        if (LinkState.MediaDuplexState == MediaDuplexStateHalf)
> +            Info("LINK: UP: SPEED=%u DUPLEX=HALF\n",
> LinkState.RcvLinkSpeed);
> +        else if (LinkState.MediaDuplexState == MediaDuplexStateFull)
> +            Info("LINK: UP: SPEED=%u DUPLEX=FULL\n",
> LinkState.RcvLinkSpeed);
> +        else
> +            Info("LINK: UP: SPEED=%u DUPLEX=UNKNOWN\n",
> LinkState.RcvLinkSpeed);
>      }
> 
> -    Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
> -    Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
> +    LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
> 
> -    return ndisStatus;
> +    RtlZeroMemory(&StatusIndication, sizeof (NDIS_STATUS_INDICATION));
> +    StatusIndication.Header.Type =
> NDIS_OBJECT_TYPE_STATUS_INDICATION;
> +    StatusIndication.Header.Revision =
> NDIS_STATUS_INDICATION_REVISION_1;
> +    StatusIndication.Header.Size = sizeof (NDIS_STATUS_INDICATION);
> +
> +    StatusIndication.SourceHandle = Adapter->NdisAdapterHandle;
> +    StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE;
> +    StatusIndication.StatusBuffer = &LinkState;
> +    StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE);
> +
> +    NdisMIndicateStatusEx(Adapter->NdisAdapterHandle,
> &StatusIndication);
>  }
> 
> -static NTSTATUS
> -__QueryInterface(
> -    IN  PDEVICE_OBJECT  DeviceObject,
> -    IN  const GUID      *Guid,
> -    IN  ULONG           Version,
> -    OUT PINTERFACE      Interface,
> -    IN  ULONG           Size,
> -    IN  BOOLEAN         Optional
> +NDIS_STATUS
> +AdapterSetInformation(
> +    IN  PXENNET_ADAPTER     Adapter,
> +    IN  PNDIS_OID_REQUEST   Request
>      )
>  {
> -    KEVENT              Event;
> -    IO_STATUS_BLOCK     StatusBlock;
> -    PIRP                Irp;
> -    PIO_STACK_LOCATION  StackLocation;
> -    NTSTATUS            status;
> +    PVOID                   Buffer;
> +    ULONG                   BufferLength;
> +    ULONG                   BytesNeeded;
> +    ULONG                   BytesRead;
> +    BOOLEAN                 Warn;
> +    NDIS_STATUS             ndisStatus;
> 
> -    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
> +    Buffer = Request->DATA.SET_INFORMATION.InformationBuffer;
> +    BufferLength = Request-
> >DATA.SET_INFORMATION.InformationBufferLength;
> +    BytesNeeded = BytesRead = 0;
> +    Warn = TRUE;
> +    ndisStatus = NDIS_STATUS_SUCCESS;
> 
> -    KeInitializeEvent(&Event, NotificationEvent, FALSE);
> -    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
> +    switch (Request->DATA.SET_INFORMATION.Oid) {
> +    case OID_PNP_SET_POWER:
> +        BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
> +        if (BufferLength >= BytesNeeded) {
> +            PNDIS_DEVICE_POWER_STATE PowerState;
> 
> -    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
> -                                       DeviceObject,
> -                                       NULL,
> -                                       0,
> -                                       NULL,
> -                                       &Event,
> -                                       &StatusBlock);
> +            PowerState = (PNDIS_DEVICE_POWER_STATE)Buffer;
> +            switch (*PowerState) {
> +            case NdisDeviceStateD0:
> +                Info("SET_POWER: D0\n");
> +                break;
> 
> -    status = STATUS_UNSUCCESSFUL;
> -    if (Irp == NULL)
> -        goto fail1;
> +            case NdisDeviceStateD1:
> +                Info("SET_POWER: D1\n");
> +                break;
> 
> -    StackLocation = IoGetNextIrpStackLocation(Irp);
> -    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
> +            case NdisDeviceStateD2:
> +                Info("SET_POWER: D2\n");
> +                break;
> 
> -    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
> -    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
> -    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
> -    StackLocation->Parameters.QueryInterface.Interface = Interface;
> +            case NdisDeviceStateD3:
> +                Info("SET_POWER: D3\n");
> +                break;
> +            }
> +        }
> +        // do nothing
> +        break;
> 
> -    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
> +    case OID_GEN_CURRENT_LOOKAHEAD:
> +        BytesNeeded = sizeof(ULONG);
> +        Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
> +        if (BufferLength == BytesNeeded) {
> +            Adapter->CurrentLookahead = *(PULONG)Buffer;
> +            BytesRead = sizeof(ULONG);
> +        }
> +        break;
> 
> -    status = IoCallDriver(DeviceObject, Irp);
> -    if (status == STATUS_PENDING) {
> -        (VOID) KeWaitForSingleObject(&Event,
> -                                     Executive,
> -                                     KernelMode,
> -                                     FALSE,
> -                                     NULL);
> -        status = StatusBlock.Status;
> -    }
> +    case OID_GEN_CURRENT_PACKET_FILTER:
> +        BytesNeeded = sizeof(ULONG);
> +        if (BufferLength == BytesNeeded) {
> +            ndisStatus = AdapterSetPacketFilter(Adapter,
> +                                                (PULONG)Buffer);
> +            BytesRead = sizeof(ULONG);
> +        }
> +        break;
> 
> -    if (!NT_SUCCESS(status)) {
> -        if (status == STATUS_NOT_SUPPORTED && Optional)
> -            goto done;
> +    case OID_802_3_MULTICAST_LIST:
> +        BytesNeeded = ETHERNET_ADDRESS_LENGTH;
> +        if (BufferLength % ETHERNET_ADDRESS_LENGTH == 0) {
> +            ndisStatus = AdapterSetMulticastAddresses(Adapter,
> +                                                      Buffer,
> +                                                      BufferLength / 
> ETHERNET_ADDRESS_LENGTH);
> +            if (ndisStatus == NDIS_STATUS_SUCCESS)
> +                BytesRead = BufferLength;
> +        } else {
> +            ndisStatus = NDIS_STATUS_INVALID_LENGTH;
> +        }
> +        break;
> 
> -        goto fail2;
> -    }
> +    case OID_OFFLOAD_ENCAPSULATION:
> +        BytesNeeded = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
> +        if (BufferLength >= BytesNeeded) {
> +            ndisStatus = AdapterGetOffloadEncapsulation(Adapter,
> +                                                        
> (PNDIS_OFFLOAD_ENCAPSULATION)Buffer);
> +            if (ndisStatus == NDIS_STATUS_SUCCESS)
> +                BytesRead = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
> +        }
> +        break;
> 
> -done:
> -    return STATUS_SUCCESS;
> +    case OID_TCP_OFFLOAD_PARAMETERS:
> +        BytesNeeded = sizeof(NDIS_OFFLOAD_PARAMETERS);
> +        if (BufferLength >= BytesNeeded) {
> +            ndisStatus = AdapterGetTcpOffloadParameters(Adapter,
> +                                                        
> (PNDIS_OFFLOAD_PARAMETERS)Buffer);
> +            if (ndisStatus == NDIS_STATUS_SUCCESS)
> +                BytesRead = sizeof(NDIS_OFFLOAD_PARAMETERS);
> +        }
> +        break;
> 
> -fail2:
> -    Error("fail2\n");
> +    case OID_GEN_HD_SPLIT_PARAMETERS:
> +        BytesNeeded = sizeof(NDIS_HD_SPLIT_PARAMETERS);
> +        if (BufferLength >= BytesNeeded) {
> +            ndisStatus = AdapterGetHeaderDataSplitParameters(Adapter,
> +                                                             
> (PNDIS_HD_SPLIT_PARAMETERS)Buffer);
> +            if (ndisStatus == NDIS_STATUS_SUCCESS)
> +                BytesRead = sizeof(NDIS_HD_SPLIT_PARAMETERS);
> +        }
> +        break;
> 
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> +    case OID_GEN_INTERRUPT_MODERATION:
> +    case OID_GEN_MACHINE_NAME:
> +        Warn = FALSE;
> +        /*FALLTHRU*/
> +    default:
> +        if (Warn)
> +            Warning("UNSUPPORTED OID %08x\n", Request-
> >DATA.QUERY_INFORMATION.Oid);
> 
> -    return status;
> -}
> +        ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
> +        break;
> +    }
> 
> -#pragma prefast(push)
> -#pragma prefast(disable:6102)
> +    Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded;
> +    if (ndisStatus == NDIS_STATUS_SUCCESS)
> +        Request->DATA.SET_INFORMATION.BytesRead = BytesRead;
> 
> -#define READ_PROPERTY(field, name, defaultval, handle)  \
> -    do {                                                \
> -        NDIS_STATUS                     _Status;        \
> -        NDIS_STRING                     _Value;         \
> -        PNDIS_CONFIGURATION_PARAMETER   _Data;          \
> -        RtlInitUnicodeString(&_Value, name);            \
> -        NdisReadConfiguration(&_Status, &_Data, handle, \
> -                        &_Value, NdisParameterInteger); \
> -        if (_Status == NDIS_STATUS_SUCCESS)             \
> -            field = _Data->ParameterData.IntegerData;   \
> -        else                                            \
> -            field = defaultval;                         \
> -    } while (FALSE);
> +    return ndisStatus;
> +}
> 
> -static NDIS_STATUS
> -AdapterGetAdvancedSettings(
> -    IN  PXENNET_ADAPTER Adapter
> +static FORCEINLINE NDIS_STATUS
> +__CopyBuffer(
> +    IN  PVOID   Destination,
> +    IN  ULONG   DestinationLength,
> +    IN  PVOID   Source,
> +    IN  ULONG   SourceLength,
> +    OUT PULONG  CopyLength
>      )
>  {
> -    NDIS_CONFIGURATION_OBJECT   Config;
> -    NDIS_HANDLE                 Handle;
> -    NDIS_STATUS                 ndisStatus;
> -
> -    RtlZeroMemory(&Config, sizeof(NDIS_CONFIGURATION_OBJECT));
> -    Config.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
> -    Config.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
> -    Config.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
> -    Config.NdisHandle = Adapter->NdisAdapterHandle;
> -    Config.Flags = 0;
> -
> -    ndisStatus = NdisOpenConfigurationEx(&Config, &Handle);
> -    if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail1;
> -
> -    READ_PROPERTY(Adapter->Properties.ipv4_csum,
> L"*IPChecksumOffloadIPv4", 3, Handle);
> -    READ_PROPERTY(Adapter->Properties.tcpv4_csum,
> L"*TCPChecksumOffloadIPv4", 3, Handle);
> -    READ_PROPERTY(Adapter->Properties.udpv4_csum,
> L"*UDPChecksumOffloadIPv4", 3, Handle);
> -    READ_PROPERTY(Adapter->Properties.tcpv6_csum,
> L"*TCPChecksumOffloadIPv6", 3, Handle);
> -    READ_PROPERTY(Adapter->Properties.udpv6_csum,
> L"*UDPChecksumOffloadIPv6", 3, Handle);
> -    READ_PROPERTY(Adapter->Properties.lsov4, L"*LSOv2IPv4", 1, Handle);
> -    READ_PROPERTY(Adapter->Properties.lsov6, L"*LSOv2IPv6", 1, Handle);
> -    READ_PROPERTY(Adapter->Properties.lrov4, L"LROIPv4", 1, Handle);
> -    READ_PROPERTY(Adapter->Properties.lrov6, L"LROIPv6", 1, Handle);
> -    READ_PROPERTY(Adapter->Properties.need_csum_value,
> L"NeedChecksumValue", 1, Handle);
> -    READ_PROPERTY(Adapter->Properties.HeaderDataSplit,
> L"*HeaderDataSplit", 1, Handle);
> -
> -    NdisCloseConfiguration(Handle);
> -
> -    return NDIS_STATUS_SUCCESS;
> +    *CopyLength = __min(SourceLength, DestinationLength);
> +    RtlCopyMemory(Destination, Source, *CopyLength);
> 
> -fail1:
> -    return NDIS_STATUS_FAILURE;
> +    return (DestinationLength >= SourceLength) ?
> +           NDIS_STATUS_SUCCESS :
> +           NDIS_STATUS_BUFFER_TOO_SHORT;
>  }
> 
> -#undef READ_PROPERTY
> -
> -#pragma prefast(pop)
> -
> -static NDIS_STATUS
> -AdapterSetRegistrationAttributes(
> -    IN  PXENNET_ADAPTER Adapter
> +static FORCEINLINE NDIS_STATUS
> +__SetUlong(
> +    IN  PVOID   Destination,
> +    IN  ULONG   DestinationLength,
> +    IN  ULONG   Source,
> +    OUT PULONG  CopyLength
>      )
>  {
> -    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES   Attribs;
> -    NDIS_STATUS                                     ndisStatus;
> +    return __CopyBuffer(Destination,
> +                        DestinationLength & ~3,
> +                        &Source,
> +                        sizeof (ULONG),
> +                        CopyLength);
> +}
> 
> -    RtlZeroMemory(&Attribs,
> sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
> -    Attribs.Header.Type =
> NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
> -    Attribs.Header.Revision =
> NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
> -    Attribs.Header.Size =
> sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
> -    Attribs.MiniportAdapterContext = (NDIS_HANDLE)Adapter;
> -    Attribs.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER |
> -                             NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
> -    Attribs.CheckForHangTimeInSeconds = 0;
> -    Attribs.InterfaceType = XENNET_INTERFACE_TYPE;
> +static FORCEINLINE NDIS_STATUS
> +__SetUlong64(
> +    IN  PVOID   Destination,
> +    IN  ULONG   DestinationLength,
> +    IN  ULONG64 Source,
> +    OUT PULONG  CopyLength
> +    )
> +{
> +    NDIS_STATUS ndisStatus;
> 
> -    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
> -                                            
> (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
> +    ndisStatus =  __CopyBuffer(Destination,
> +                               DestinationLength & ~3,
> +                               &Source,
> +                               sizeof (ULONG64),
> +                               CopyLength);
> +    if (DestinationLength >= 4)
> +        ndisStatus = NDIS_STATUS_SUCCESS;
> 
>      return ndisStatus;
>  }
> 
> -static NDIS_STATUS
> -AdapterSetGeneralAttributes(
> -    IN  PXENNET_ADAPTER Adapter
> +NDIS_STATUS
> +AdapterQueryInformation(
> +    IN  PXENNET_ADAPTER     Adapter,
> +    IN  PNDIS_OID_REQUEST   Request
>      )
>  {
> -    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES    Attribs;
> -    NDIS_STATUS                                 ndisStatus;
> -
> -    RtlZeroMemory(&Attribs,
> sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
> -    Attribs.Header.Type =
> NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
> -    Attribs.Header.Revision =
> NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
> -    Attribs.Header.Size =
> sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);
> -    Attribs.MediaType = XENNET_MEDIA_TYPE;
> -
> -    XENVIF_VIF(MacQueryMaximumFrameSize,
> -               &Adapter->VifInterface,
> -               (PULONG)&Adapter->MaximumFrameSize);
> -
> -    Attribs.MtuSize = Adapter->MaximumFrameSize - sizeof
> (ETHERNET_TAGGED_HEADER);
> -    Attribs.MaxXmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
> -    Attribs.MaxRcvLinkSpeed = XENNET_MEDIA_MAX_SPEED;
> -    Attribs.XmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
> -    Attribs.RcvLinkSpeed = XENNET_MEDIA_MAX_SPEED;
> -    Attribs.MediaConnectState = MediaConnectStateConnected;
> -    Attribs.MediaDuplexState = MediaDuplexStateFull;
> -    Attribs.LookaheadSize = Adapter->MaximumFrameSize;
> -    Attribs.PowerManagementCapabilities = &Adapter->Capabilities;
> -    Attribs.MacOptions = XENNET_MAC_OPTIONS;
> -    Attribs.SupportedPacketFilters = XENNET_SUPPORTED_PACKET_FILTERS;
> -    Attribs.MaxMulticastListSize = 32;
> -    Attribs.MacAddressLength = ETHERNET_ADDRESS_LENGTH;
> -
> -    XENVIF_VIF(MacQueryPermanentAddress,
> -               &Adapter->VifInterface,
> -               (PETHERNET_ADDRESS)&Attribs.PermanentMacAddress);
> -    XENVIF_VIF(MacQueryCurrentAddress,
> -               &Adapter->VifInterface,
> -               (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress);
> +    PVOID                   Buffer;
> +    ULONG                   BufferLength;
> +    ULONG                   BytesNeeded;
> +    ULONG                   BytesWritten;
> +    ULONG                   Value32;
> +    ULONGLONG               Value64;
> +    ETHERNET_ADDRESS        EthernetAddress;
> +    BOOLEAN                 Warn;
> +    NDIS_STATUS             ndisStatus;
> 
> -    Attribs.PhysicalMediumType = NdisPhysicalMedium802_3;
> -    Attribs.RecvScaleCapabilities = NULL;
> -    Attribs.AccessType = NET_IF_ACCESS_BROADCAST;
> -    Attribs.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
> -    Attribs.ConnectionType = NET_IF_CONNECTION_DEDICATED;
> -    Attribs.IfType = IF_TYPE_ETHERNET_CSMACD;
> -    Attribs.IfConnectorPresent = TRUE;
> -    Attribs.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |
> -                                  NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |
> -                                  
> NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED |
> -                                  
> NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED |
> -                                  
> NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED |
> -
> NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED |
> -                                  
> NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED
> |
> -
> NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED |
> -                                  NDIS_STATISTICS_RCV_OK_SUPPORTED |
> -                                  NDIS_STATISTICS_RCV_ERROR_SUPPORTED |
> -                                  
> NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED |
> -                                  
> NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED |
> -                                  
> NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED |
> -                                  
> NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED
> |
> -                                  
> NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED |
> -                                  
> NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED
> |
> -                                  NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;
> -
> -    Attribs.SupportedOidList = XennetSupportedOids;
> -    Attribs.SupportedOidListLength = sizeof(XennetSupportedOids);
> +    Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
> +    BufferLength = Request-
> >DATA.QUERY_INFORMATION.InformationBufferLength;
> +    BytesNeeded = BytesWritten = 0;
> +    Warn = TRUE;
> +    ndisStatus = NDIS_STATUS_SUCCESS;
> 
> -    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
> -                                            
> (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
> +    switch (Request->DATA.QUERY_INFORMATION.Oid) {
> +    case OID_PNP_CAPABILITIES:
> +        BytesNeeded = sizeof(Adapter->Capabilities);
> +        ndisStatus = __CopyBuffer(Buffer,
> +                                  BufferLength,
> +                                  &Adapter->Capabilities,
> +                                  BytesNeeded,
> +                                  &BytesWritten);
> +        break;
> 
> -    return ndisStatus;
> -}
> +    case OID_PNP_QUERY_POWER:
> +        BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
> 
> -static NDIS_STATUS
> -AdapterSetOffloadAttributes(
> -    IN  PXENNET_ADAPTER Adapter
> -    )
> -{
> -    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES    Attribs;
> -    XENVIF_VIF_OFFLOAD_OPTIONS                  Options;
> -    PXENVIF_VIF_OFFLOAD_OPTIONS                 RxOptions;
> -    PXENVIF_VIF_OFFLOAD_OPTIONS                 TxOptions;
> -    NDIS_OFFLOAD                                Default;
> -    NDIS_OFFLOAD                                Supported;
> -    NDIS_STATUS                                 ndisStatus;
> +        if (BufferLength >= BytesNeeded) {
> +            PNDIS_DEVICE_POWER_STATE PowerState;
> 
> -    TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
> -    RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
> +            PowerState = (PNDIS_DEVICE_POWER_STATE)Buffer;
> +            switch (*PowerState) {
> +            case NdisDeviceStateD0:
> +                Info("QUERY_POWER: D0\n");
> +                break;
> 
> -    TxOptions->Value = 0;
> -    TxOptions->OffloadTagManipulation = 1;
> +            case NdisDeviceStateD1:
> +                Info("QUERY_POWER: D1\n");
> +                break;
> 
> -    RxOptions->Value = 0;
> -    RxOptions->OffloadTagManipulation = 1;
> +            case NdisDeviceStateD2:
> +                Info("QUERY_POWER: D2\n");
> +                break;
> 
> -    if (Adapter->Properties.need_csum_value)
> -        RxOptions->NeedChecksumValue = 1;
> +            case NdisDeviceStateD3:
> +                Info("QUERY_POWER: D3\n");
> +                break;
> +            }
> +        }
> 
> -    if (Adapter->Properties.lrov4) {
> -        RxOptions->OffloadIpVersion4LargePacket = 1;
> -        RxOptions->NeedLargePacketSplit = 1;
> -    }
> +        BytesWritten = 0;
> +        // do nothing
> +        break;
> 
> -    if (Adapter->Properties.lrov6) {
> -        RxOptions->OffloadIpVersion6LargePacket = 1;
> -        RxOptions->NeedLargePacketSplit = 1;
> -    }
> +    case OID_GEN_SUPPORTED_LIST:
> +        BytesNeeded = sizeof(XennetSupportedOids);
> +        ndisStatus = __CopyBuffer(Buffer,
> +                                  BufferLength,
> +                                  &XennetSupportedOids[0],
> +                                  BytesNeeded,
> +                                  &BytesWritten);
> +        break;
> 
> -    XENVIF_VIF(ReceiverSetOffloadOptions,
> -               &Adapter->VifInterface,
> -               *RxOptions);
> +    case OID_GEN_HARDWARE_STATUS:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                NdisHardwareStatusReady,
> +                                &BytesWritten);
> +        break;
> 
> -    XENVIF_VIF(TransmitterQueryOffloadOptions,
> -               &Adapter->VifInterface,
> -               &Options);
> +    case OID_GEN_MEDIA_SUPPORTED:
> +    case OID_GEN_MEDIA_IN_USE:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                XENNET_MEDIA_TYPE,
> +                                &BytesWritten);
> +        break;
> 
> -    RtlZeroMemory(&Supported, sizeof(NDIS_OFFLOAD));
> -    Supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
> -    Supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
> -    Supported.Header.Size = sizeof(NDIS_OFFLOAD);
> +    case OID_GEN_MAXIMUM_LOOKAHEAD:
> +    case OID_GEN_TRANSMIT_BLOCK_SIZE:
> +    case OID_GEN_RECEIVE_BLOCK_SIZE:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Adapter->MaximumFrameSize,
> +                                &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv4Receive.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> +    case OID_GEN_TRANSMIT_BUFFER_SPACE:
> +    case OID_GEN_RECEIVE_BUFFER_SPACE:
> +        XENVIF_VIF(TransmitterQueryRingSize,
> +                    &Adapter->VifInterface,
> +                    (PULONG)&Value32);
> +        Value32 *= Adapter->MaximumFrameSize;
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Value32,
> +                                &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv4Receive.IpChecksum = 1;
> -    Supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
> +    case OID_GEN_VENDOR_DESCRIPTION:
> +        BytesNeeded = (ULONG)strlen(VENDOR_NAME_STR) + 1;
> +        ndisStatus = __CopyBuffer(Buffer,
> +                                  BufferLength,
> +                                  VENDOR_NAME_STR,
> +                                  BytesNeeded,
> +                                  &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv4Receive.TcpChecksum = 1;
> -    Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
> +    case OID_GEN_VENDOR_DRIVER_VERSION:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8,
> +                                &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv4Receive.UdpChecksum = 1;
> +    case OID_GEN_DRIVER_VERSION:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (6 << 8) | 0, // NDIS 6.0
> +                                &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv6Receive.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> +    case OID_GEN_MAC_OPTIONS:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                XENNET_MAC_OPTIONS,
> +                                &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
> +    case OID_GEN_STATISTICS:
> +        BytesNeeded = sizeof(NDIS_STATISTICS_INFO);
> +        ndisStatus = AdapterQueryGeneralStatistics(Adapter,
> +                                                   
> (PNDIS_STATISTICS_INFO)Buffer,
> +                                                   BufferLength,
> +                                                   &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv6Receive.TcpChecksum = 1;
> -    Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
> +    case OID_802_3_MULTICAST_LIST:
> +        ndisStatus = AdapterQueryMulticastList(Adapter,
> +                                               Buffer,
> +                                               BufferLength,
> +                                               &BytesNeeded,
> +                                               &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv6Receive.UdpChecksum = 1;
> +    case OID_802_3_PERMANENT_ADDRESS:
> +        XENVIF_VIF(MacQueryPermanentAddress,
> +                    &Adapter->VifInterface,
> +                    &EthernetAddress);
> +        BytesNeeded = sizeof(ETHERNET_ADDRESS);
> +        ndisStatus = __CopyBuffer(Buffer,
> +                                  BufferLength,
> +                                  &EthernetAddress,
> +                                  BytesNeeded,
> +                                  &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv4Transmit.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> +    case OID_802_3_CURRENT_ADDRESS:
> +        XENVIF_VIF(MacQueryCurrentAddress,
> +                    &Adapter->VifInterface,
> +                    &EthernetAddress);
> +        BytesNeeded = sizeof(ETHERNET_ADDRESS);
> +        ndisStatus = __CopyBuffer(Buffer,
> +                                  BufferLength,
> +                                  &EthernetAddress,
> +                                  BytesNeeded,
> +                                  &BytesWritten);
> +        break;
> +
> +    case OID_GEN_MAXIMUM_FRAME_SIZE:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Adapter->MaximumFrameSize -
> +                                    sizeof(ETHERNET_TAGGED_HEADER),
> +                                &BytesWritten);
> +        break;
> +
> +    case OID_GEN_MAXIMUM_TOTAL_SIZE:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Adapter->MaximumFrameSize -
> +                                    sizeof(ETHERNET_TAGGED_HEADER) +
> +                                    sizeof (ETHERNET_UNTAGGED_HEADER),
> +                                &BytesWritten);
> +        break;
> +
> +    case OID_GEN_CURRENT_LOOKAHEAD:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Adapter->CurrentLookahead,
> +                                &BytesWritten);
> +        break;
> +
> +    case OID_GEN_VENDOR_ID:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                0x5853,
> +                                &BytesWritten);
> +        break;
> +
> +    case OID_GEN_LINK_SPEED:
> +        XENVIF_VIF(MacQueryState,
> +                   &Adapter->VifInterface,
> +                   NULL,
> +                   &Value64,
> +                   NULL);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)(Value64 / 100),
> +                                &BytesWritten);
> +        break;
> +
> +    case OID_GEN_MEDIA_CONNECT_STATUS:
> +        XENVIF_VIF(MacQueryState,
> +                    &Adapter->VifInterface,
> +                    (PNET_IF_MEDIA_CONNECT_STATE)&Value32,
> +                    NULL,
> +                    NULL);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Value32,
> +                                &BytesWritten);
> +        break;
> +
> +    case OID_GEN_MAXIMUM_SEND_PACKETS:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                16,
> +                                &BytesWritten);
> +        break;
> 
> -    if (Options.OffloadIpVersion4HeaderChecksum) {
> -        Supported.Checksum.IPv4Transmit.IpChecksum = 1;
> -        Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
> -    }
> +    case OID_GEN_CURRENT_PACKET_FILTER:
> +        AdapterGetPacketFilter(Adapter, &Value32);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Value32,
> +                                &BytesWritten);
> +        break;
> 
> -    if (Options.OffloadIpVersion4TcpChecksum) {
> -        Supported.Checksum.IPv4Transmit.TcpChecksum = 1;
> -        Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
> -    }
> +    case OID_GEN_XMIT_OK:
> +        AdapterGetXmitOk(Adapter, &Value64);
> +        BytesNeeded = sizeof(ULONG64);
> +        ndisStatus = __SetUlong64(Buffer,
> +                                  BufferLength,
> +                                  Value64,
> +                                  &BytesWritten);
> +        break;
> 
> -    if (Options.OffloadIpVersion4UdpChecksum)
> -        Supported.Checksum.IPv4Transmit.UdpChecksum = 1;
> +    case OID_GEN_RCV_OK:
> +        AdapterGetRcvOk(Adapter, &Value64);
> +        BytesNeeded = sizeof(ULONG64);
> +        ndisStatus = __SetUlong64(Buffer,
> +                                  BufferLength,
> +                                  Value64,
> +                                  &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv6Transmit.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> +    case OID_GEN_XMIT_ERROR:
> +        AdapterGetXmitError(Adapter, &Value32);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Value32,
> +                                &BytesWritten);
> +        break;
> 
> -    Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
> +    case OID_GEN_RCV_ERROR:
> +        AdapterGetRcvError(Adapter, &Value32);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                Value32,
> +                                &BytesWritten);
> +        break;
> 
> -    if (Options.OffloadIpVersion6TcpChecksum) {
> -        Supported.Checksum.IPv6Transmit.TcpChecksum = 1;
> -        Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
> -    }
> +    case OID_GEN_RCV_NO_BUFFER:
> +    case OID_GEN_TRANSMIT_QUEUE_LENGTH:
> +    case OID_GEN_RCV_CRC_ERROR:
> +    case OID_802_3_RCV_ERROR_ALIGNMENT:
> +    case OID_802_3_XMIT_ONE_COLLISION:
> +    case OID_802_3_XMIT_MORE_COLLISIONS:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                0,
> +                                &BytesWritten);
> +        break;
> 
> -    if (Options.OffloadIpVersion6UdpChecksum)
> -        Supported.Checksum.IPv6Transmit.UdpChecksum = 1;
> +    case OID_802_3_MAXIMUM_LIST_SIZE:
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                32,
> +                                &BytesWritten);
> +        break;
> 
> -    if (Options.OffloadIpVersion4LargePacket) {
> -        XENVIF_VIF(TransmitterQueryLargePacketSize,
> +    case OID_GEN_DIRECTED_BYTES_XMIT:
> +        XENVIF_VIF(QueryStatistic,
>                     &Adapter->VifInterface,
> -                   4,
> -                   &Supported.LsoV2.IPv4.MaxOffLoadSize);
> -        Supported.LsoV2.IPv4.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> -        Supported.LsoV2.IPv4.MinSegmentCount = 2;
> -    }
> +                   XENVIF_TRANSMITTER_UNICAST_OCTETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (Options.OffloadIpVersion6LargePacket) {
> -        XENVIF_VIF(TransmitterQueryLargePacketSize,
> +    case OID_GEN_DIRECTED_FRAMES_XMIT:
> +        XENVIF_VIF(QueryStatistic,
>                     &Adapter->VifInterface,
> -                   6,
> -                   &Supported.LsoV2.IPv6.MaxOffLoadSize);
> -        Supported.LsoV2.IPv6.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> -        Supported.LsoV2.IPv6.MinSegmentCount = 2;
> -        Supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
> -        Supported.LsoV2.IPv6.TcpOptionsSupported = 1;
> -    }
> -
> -    Default = Supported;
> +                   XENVIF_TRANSMITTER_UNICAST_PACKETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.ipv4_csum & 2))
> -        Default.Checksum.IPv4Receive.IpChecksum = 0;
> +    case OID_GEN_MULTICAST_BYTES_XMIT:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_TRANSMITTER_MULTICAST_OCTETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.tcpv4_csum & 2))
> -        Default.Checksum.IPv4Receive.TcpChecksum = 0;
> +    case OID_GEN_MULTICAST_FRAMES_XMIT:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_TRANSMITTER_MULTICAST_PACKETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.udpv4_csum & 2))
> -        Default.Checksum.IPv4Receive.UdpChecksum = 0;
> +    case OID_GEN_BROADCAST_BYTES_XMIT:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_TRANSMITTER_BROADCAST_OCTETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.tcpv6_csum & 2))
> -        Default.Checksum.IPv6Receive.TcpChecksum = 0;
> +    case OID_GEN_BROADCAST_FRAMES_XMIT:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_TRANSMITTER_BROADCAST_PACKETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.udpv6_csum & 2))
> -        Default.Checksum.IPv6Receive.UdpChecksum = 0;
> +    case OID_GEN_DIRECTED_BYTES_RCV:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_RECEIVER_UNICAST_OCTETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.ipv4_csum & 1))
> -        Default.Checksum.IPv4Transmit.IpChecksum = 0;
> +    case OID_GEN_DIRECTED_FRAMES_RCV:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_RECEIVER_UNICAST_PACKETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.tcpv4_csum & 1))
> -        Default.Checksum.IPv4Transmit.TcpChecksum = 0;
> +    case OID_GEN_MULTICAST_BYTES_RCV:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_RECEIVER_MULTICAST_OCTETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.udpv4_csum & 1))
> -        Default.Checksum.IPv4Transmit.UdpChecksum = 0;
> +    case OID_GEN_MULTICAST_FRAMES_RCV:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_RECEIVER_MULTICAST_PACKETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.tcpv6_csum & 1))
> -        Default.Checksum.IPv6Transmit.TcpChecksum = 0;
> +    case OID_GEN_BROADCAST_BYTES_RCV:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_RECEIVER_BROADCAST_OCTETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.udpv6_csum & 1))
> -        Default.Checksum.IPv6Transmit.UdpChecksum = 0;
> +    case OID_GEN_BROADCAST_FRAMES_RCV:
> +        XENVIF_VIF(QueryStatistic,
> +                   &Adapter->VifInterface,
> +                   XENVIF_RECEIVER_BROADCAST_PACKETS,
> +                   &Value64);
> +        BytesNeeded = sizeof(ULONG);
> +        ndisStatus = __SetUlong(Buffer,
> +                                BufferLength,
> +                                (ULONG)Value64,
> +                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.lsov4)) {
> -        Default.LsoV2.IPv4.MaxOffLoadSize = 0;
> -        Default.LsoV2.IPv4.MinSegmentCount = 0;
> -    }
> +    case OID_GEN_INTERRUPT_MODERATION:
> +        BytesNeeded =
> sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
> +        ndisStatus = AdapterInterruptModeration(Adapter,
> +
> (PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer,
> +                                                BufferLength,
> +                                                &BytesWritten);
> +        break;
> 
> -    if (!(Adapter->Properties.lsov6)) {
> -        Default.LsoV2.IPv6.MaxOffLoadSize = 0;
> -        Default.LsoV2.IPv6.MinSegmentCount = 0;
> -    }
> +    case OID_IP4_OFFLOAD_STATS:
> +    case OID_IP6_OFFLOAD_STATS:
> +    case OID_GEN_SUPPORTED_GUIDS:
> +        // We don't handle these since NDIS 6.0 is supposed to do this for us
> +    case OID_GEN_MAC_ADDRESS:
> +    case OID_GEN_MAX_LINK_SPEED:
> +        // ignore these common unwanted OIDs
> +     case OID_GEN_INIT_TIME_MS:
> +     case OID_GEN_RESET_COUNTS:
> +     case OID_GEN_MEDIA_SENSE_COUNTS:
> +        Warn = FALSE;
> +        /*FALLTHRU*/
> +    default:
> +        if (Warn)
> +            Warning("UNSUPPORTED OID %08x\n", Request-
> >DATA.QUERY_INFORMATION.Oid);
> 
> -    if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof
> (NDIS_OFFLOAD))) {
> -        Adapter->Offload = Default;
> -        DISPLAY_OFFLOAD(Default);
> +        ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
> +        break;
>      }
> 
> -    RtlZeroMemory(&Attribs,
> sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES));
> -    Attribs.Header.Type =
> NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
> -    Attribs.Header.Revision =
> NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
> -    Attribs.Header.Size = sizeof(Attribs);
> -    Attribs.DefaultOffloadConfiguration = &Default;
> -    Attribs.HardwareOffloadCapabilities = &Supported;
> +    Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
> +    Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
> 
> -    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
> -                                            
> (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
>      return ndisStatus;
>  }
> 
> -static NDIS_STATUS
> -AdapterSetHeaderDataSplitAttributes(
> -    IN  PXENNET_ADAPTER                                 Adapter
> +static NTSTATUS
> +__QueryInterface(
> +    IN  PDEVICE_OBJECT  DeviceObject,
> +    IN  const GUID      *Guid,
> +    IN  ULONG           Version,
> +    OUT PINTERFACE      Interface,
> +    IN  ULONG           Size,
> +    IN  BOOLEAN         Optional
>      )
>  {
> -    NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES    Attribs;
> -    NDIS_HD_SPLIT_ATTRIBUTES                            Split;
> -    NDIS_STATUS                                         NdisStatus;
> -
> -    RtlZeroMemory(&Attribs, sizeof(Attribs));
> +    KEVENT              Event;
> +    IO_STATUS_BLOCK     StatusBlock;
> +    PIRP                Irp;
> +    PIO_STACK_LOCATION  StackLocation;
> +    NTSTATUS            status;
> 
> -    Attribs.Header.Type =
> NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES
> ;
> -    Attribs.Header.Revision =
> NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
> -    Attribs.Header.Size =
> NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVI
> SION_1;
> +    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
> 
> -    RtlZeroMemory(&Split, sizeof(Split));
> +    KeInitializeEvent(&Event, NotificationEvent, FALSE);
> +    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
> 
> -    Split.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
> -    Split.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
> -    Split.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
> -    Split.HardwareCapabilities =
> -        NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT |
> -        NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |
> -        NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |
> -        NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;
> +    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
> +                                       DeviceObject,
> +                                       NULL,
> +                                       0,
> +                                       NULL,
> +                                       &Event,
> +                                       &StatusBlock);
> 
> -    if (Adapter->Properties.HeaderDataSplit != 0)
> -        Split.CurrentCapabilities = Split.HardwareCapabilities;
> +    status = STATUS_UNSUCCESSFUL;
> +    if (Irp == NULL)
> +        goto fail1;
> 
> -    Attribs.HDSplitAttributes = &Split;
> +    StackLocation = IoGetNextIrpStackLocation(Irp);
> +    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
> 
> -    NdisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
> -                                            
> (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
> -    if (NdisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail1;
> +    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
> +    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
> +    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
> +    StackLocation->Parameters.QueryInterface.Interface = Interface;
> 
> -    if (Split.HDSplitFlags == NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {
> -        ASSERT(Split.CurrentCapabilities &
> NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT);
> +    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
> 
> -        Info("BackfillSize = %u\n", Split.BackfillSize);
> -        Info("MaxHeaderSize = %u\n", Split.MaxHeaderSize);
> +    status = IoCallDriver(DeviceObject, Irp);
> +    if (status == STATUS_PENDING) {
> +        (VOID) KeWaitForSingleObject(&Event,
> +                                     Executive,
> +                                     KernelMode,
> +                                     FALSE,
> +                                     NULL);
> +        status = StatusBlock.Status;
> +    }
> 
> -        XENVIF_VIF(ReceiverSetBackfillSize,
> -                   &Adapter->VifInterface,
> -                   Split.BackfillSize);
> +    if (!NT_SUCCESS(status)) {
> +        if (status == STATUS_NOT_SUPPORTED && Optional)
> +            goto done;
> 
> -        ReceiverSplitHeaderData(Adapter->Receiver, Split.MaxHeaderSize);
> +        goto fail2;
>      }
> 
> -    return NDIS_STATUS_SUCCESS;
> +done:
> +    return STATUS_SUCCESS;
> +
> +fail2:
> +    Error("fail2\n");
> 
>  fail1:
> -    Error("fail1 (%08x)\n", NdisStatus);
> +    Error("fail1 (%08x)\n", status);
> 
> -    return NdisStatus;
> +    return status;
>  }
> 
> -static FORCEINLINE PVOID
> -__AdapterAllocate(
> -    IN  ULONG   Length
> -    )
> -{
> -    return __AllocateNonPagedPoolWithTag(Length, ADAPTER_POOL_TAG);
> -}
> +#pragma prefast(push)
> +#pragma prefast(disable:6102)
> 
> -static FORCEINLINE VOID
> -__AdapterFree(
> -    IN  PVOID   Buffer
> -    )
> -{
> -    __FreePoolWithTag(Buffer, ADAPTER_POOL_TAG);
> -}
> +#define READ_PROPERTY(field, name, defaultval, handle)  \
> +    do {                                                \
> +        NDIS_STATUS                     _Status;        \
> +        NDIS_STRING                     _Value;         \
> +        PNDIS_CONFIGURATION_PARAMETER   _Data;          \
> +        RtlInitUnicodeString(&_Value, name);            \
> +        NdisReadConfiguration(&_Status, &_Data, handle, \
> +                        &_Value, NdisParameterInteger); \
> +        if (_Status == NDIS_STATUS_SUCCESS)             \
> +            field = _Data->ParameterData.IntegerData;   \
> +        else                                            \
> +            field = defaultval;                         \
> +    } while (FALSE);
> 
> -static FORCEINLINE PANSI_STRING
> -__AdapterMultiSzToUpcaseAnsi(
> -    IN  PCHAR       Buffer
> +static NDIS_STATUS
> +AdapterGetAdvancedSettings(
> +    IN  PXENNET_ADAPTER Adapter
>      )
>  {
> -    PANSI_STRING    Ansi;
> -    LONG            Index;
> -    LONG            Count;
> -    NTSTATUS        status;
> -
> -    Index = 0;
> -    Count = 0;
> -    for (;;) {
> -        if (Buffer[Index] == '\0') {
> -            Count++;
> -            Index++;
> -
> -            // Check for double NUL
> -            if (Buffer[Index] == '\0')
> -                break;
> -        } else {
> -            Buffer[Index] = (CHAR)toupper(Buffer[Index]);
> -            Index++;
> -        }
> -    }
> +    NDIS_CONFIGURATION_OBJECT   Config;
> +    NDIS_HANDLE                 Handle;
> +    NDIS_STATUS                 ndisStatus;
> 
> -    Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
> +    RtlZeroMemory(&Config, sizeof(NDIS_CONFIGURATION_OBJECT));
> +    Config.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
> +    Config.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
> +    Config.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
> +    Config.NdisHandle = Adapter->NdisAdapterHandle;
> +    Config.Flags = 0;
> 
> -    status = STATUS_NO_MEMORY;
> -    if (Ansi == NULL)
> +    ndisStatus = NdisOpenConfigurationEx(&Config, &Handle);
> +    if (ndisStatus != NDIS_STATUS_SUCCESS)
>          goto fail1;
> 
> -    for (Index = 0; Index < Count; Index++) {
> -        ULONG   Length;
> -
> -        Length = (ULONG)strlen(Buffer);
> -        Ansi[Index].MaximumLength = (USHORT)(Length + 1);
> -        Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
> -
> -        status = STATUS_NO_MEMORY;
> -        if (Ansi[Index].Buffer == NULL)
> -            goto fail2;
> -
> -        RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
> -        Ansi[Index].Length = (USHORT)Length;
> -
> -        Buffer += Length + 1;
> -    }
> -
> -    return Ansi;
> -
> -fail2:
> -    Error("fail2\n");
> +    READ_PROPERTY(Adapter->Properties.ipv4_csum,
> L"*IPChecksumOffloadIPv4", 3, Handle);
> +    READ_PROPERTY(Adapter->Properties.tcpv4_csum,
> L"*TCPChecksumOffloadIPv4", 3, Handle);
> +    READ_PROPERTY(Adapter->Properties.udpv4_csum,
> L"*UDPChecksumOffloadIPv4", 3, Handle);
> +    READ_PROPERTY(Adapter->Properties.tcpv6_csum,
> L"*TCPChecksumOffloadIPv6", 3, Handle);
> +    READ_PROPERTY(Adapter->Properties.udpv6_csum,
> L"*UDPChecksumOffloadIPv6", 3, Handle);
> +    READ_PROPERTY(Adapter->Properties.lsov4, L"*LSOv2IPv4", 1, Handle);
> +    READ_PROPERTY(Adapter->Properties.lsov6, L"*LSOv2IPv6", 1, Handle);
> +    READ_PROPERTY(Adapter->Properties.lrov4, L"LROIPv4", 1, Handle);
> +    READ_PROPERTY(Adapter->Properties.lrov6, L"LROIPv6", 1, Handle);
> +    READ_PROPERTY(Adapter->Properties.need_csum_value,
> L"NeedChecksumValue", 1, Handle);
> +    READ_PROPERTY(Adapter->Properties.HeaderDataSplit,
> L"*HeaderDataSplit", 1, Handle);
> 
> -    while (--Index >= 0)
> -        __AdapterFree(Ansi[Index].Buffer);
> +    NdisCloseConfiguration(Handle);
> 
> -    __AdapterFree(Ansi);
> +    return NDIS_STATUS_SUCCESS;
> 
>  fail1:
> -    Error("fail1 (%08x)\n", status);
> -
> -    return NULL;
> +    return NDIS_STATUS_FAILURE;
>  }
> 
> -static FORCEINLINE VOID
> -__AdapterFreeAnsi(
> -    IN  PANSI_STRING    Ansi
> +#undef READ_PROPERTY
> +
> +#pragma prefast(pop)
> +
> +static NDIS_STATUS
> +AdapterSetRegistrationAttributes(
> +    IN  PXENNET_ADAPTER Adapter
>      )
>  {
> -    ULONG               Index;
> +    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES   Attribs;
> +    NDIS_STATUS                                     ndisStatus;
> +
> +    RtlZeroMemory(&Attribs,
> sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
> +    Attribs.Header.Type =
> NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
> +    Attribs.Header.Revision =
> NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
> +    Attribs.Header.Size =
> sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
> +    Attribs.MiniportAdapterContext = (NDIS_HANDLE)Adapter;
> +    Attribs.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER |
> +                             NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
> +    Attribs.CheckForHangTimeInSeconds = 0;
> +    Attribs.InterfaceType = XENNET_INTERFACE_TYPE;
> 
> -    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
> -        __AdapterFree(Ansi[Index].Buffer);
> +    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
> +                                            
> (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
> 
> -    __AdapterFree(Ansi);
> +    return ndisStatus;
>  }
> 
> -static FORCEINLINE BOOLEAN
> -__AdapterMatchDistribution(
> -    IN  PXENNET_ADAPTER Adapter,
> -    IN  PCHAR           Buffer
> +static NDIS_STATUS
> +AdapterSetGeneralAttributes(
> +    IN  PXENNET_ADAPTER Adapter
>      )
>  {
> -    PCHAR               Vendor;
> -    PCHAR               Product;
> -    PCHAR               Context;
> -    const CHAR          *Text;
> -    BOOLEAN             Match;
> -    ULONG               Index;
> -    NTSTATUS            status;
> +    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES    Attribs;
> +    NDIS_STATUS                                 ndisStatus;
> 
> -    UNREFERENCED_PARAMETER(Adapter);
> +    RtlZeroMemory(&Attribs,
> sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
> +    Attribs.Header.Type =
> NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
> +    Attribs.Header.Revision =
> NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
> +    Attribs.Header.Size =
> sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);
> +    Attribs.MediaType = XENNET_MEDIA_TYPE;
> 
> -    status = STATUS_INVALID_PARAMETER;
> +    XENVIF_VIF(MacQueryMaximumFrameSize,
> +               &Adapter->VifInterface,
> +               (PULONG)&Adapter->MaximumFrameSize);
> 
> -    Vendor = __strtok_r(Buffer, " ", &Context);
> -    if (Vendor == NULL)
> -        goto fail1;
> +    Attribs.MtuSize = Adapter->MaximumFrameSize - sizeof
> (ETHERNET_TAGGED_HEADER);
> +    Attribs.MaxXmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
> +    Attribs.MaxRcvLinkSpeed = XENNET_MEDIA_MAX_SPEED;
> +    Attribs.XmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
> +    Attribs.RcvLinkSpeed = XENNET_MEDIA_MAX_SPEED;
> +    Attribs.MediaConnectState = MediaConnectStateConnected;
> +    Attribs.MediaDuplexState = MediaDuplexStateFull;
> +    Attribs.LookaheadSize = Adapter->MaximumFrameSize;
> +    Attribs.PowerManagementCapabilities = &Adapter->Capabilities;
> +    Attribs.MacOptions = XENNET_MAC_OPTIONS;
> +    Attribs.SupportedPacketFilters = XENNET_SUPPORTED_PACKET_FILTERS;
> +    Attribs.MaxMulticastListSize = 32;
> +    Attribs.MacAddressLength = ETHERNET_ADDRESS_LENGTH;
> 
> -    Product = __strtok_r(NULL, " ", &Context);
> -    if (Product == NULL)
> -        goto fail2;
> +    XENVIF_VIF(MacQueryPermanentAddress,
> +               &Adapter->VifInterface,
> +               (PETHERNET_ADDRESS)&Attribs.PermanentMacAddress);
> +    XENVIF_VIF(MacQueryCurrentAddress,
> +               &Adapter->VifInterface,
> +               (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress);
> 
> -    Match = TRUE;
> +    Attribs.PhysicalMediumType = NdisPhysicalMedium802_3;
> +    Attribs.RecvScaleCapabilities = NULL;
> +    Attribs.AccessType = NET_IF_ACCESS_BROADCAST;
> +    Attribs.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
> +    Attribs.ConnectionType = NET_IF_CONNECTION_DEDICATED;
> +    Attribs.IfType = IF_TYPE_ETHERNET_CSMACD;
> +    Attribs.IfConnectorPresent = TRUE;
> +    Attribs.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |
> +                                  NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |
> +                                  
> NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED |
> +                                  
> NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED
> |
> +                                  
> NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED |
> +
> NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED |
> +                                  
> NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED
> |
> +
> NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED |
> +                                  NDIS_STATISTICS_RCV_OK_SUPPORTED |
> +                                  NDIS_STATISTICS_RCV_ERROR_SUPPORTED |
> +                                  
> NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED |
> +                                  
> NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED |
> +                                  
> NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED |
> +                                  
> NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED
> |
> +                                  
> NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED |
> +
> NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED |
> +                                  NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;
> +
> +    Attribs.SupportedOidList = XennetSupportedOids;
> +    Attribs.SupportedOidListLength = sizeof(XennetSupportedOids);
> 
> -    Text = VENDOR_NAME_STR;
> +    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
> +                                            
> (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
> 
> -    for (Index = 0; Text[Index] != 0; Index++) {
> -        if (!isalnum((UCHAR)Text[Index])) {
> -            if (Vendor[Index] != '_') {
> -                Match = FALSE;
> -                break;
> -            }
> -        } else {
> -            if (Vendor[Index] != Text[Index]) {
> -                Match = FALSE;
> -                break;
> -            }
> -        }
> -    }
> +    return ndisStatus;
> +}
> 
> -    Text = "XENNET";
> +static NDIS_STATUS
> +AdapterSetOffloadAttributes(
> +    IN  PXENNET_ADAPTER Adapter
> +    )
> +{
> +    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES    Attribs;
> +    XENVIF_VIF_OFFLOAD_OPTIONS                  Options;
> +    PXENVIF_VIF_OFFLOAD_OPTIONS                 RxOptions;
> +    PXENVIF_VIF_OFFLOAD_OPTIONS                 TxOptions;
> +    NDIS_OFFLOAD                                Default;
> +    NDIS_OFFLOAD                                Supported;
> +    NDIS_STATUS                                 ndisStatus;
> 
> -    if (_stricmp(Product, Text) != 0)
> -        Match = FALSE;
> +    TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
> +    RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
> 
> -    return Match;
> +    TxOptions->Value = 0;
> +    TxOptions->OffloadTagManipulation = 1;
> 
> -fail2:
> -    Error("fail2\n");
> +    RxOptions->Value = 0;
> +    RxOptions->OffloadTagManipulation = 1;
> 
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> +    if (Adapter->Properties.need_csum_value)
> +        RxOptions->NeedChecksumValue = 1;
> 
> -    return FALSE;
> -}
> +    if (Adapter->Properties.lrov4) {
> +        RxOptions->OffloadIpVersion4LargePacket = 1;
> +        RxOptions->NeedLargePacketSplit = 1;
> +    }
> 
> -static FORCEINLINE VOID
> -__AdapterClearDistribution(
> -    IN  PXENNET_ADAPTER Adapter
> -    )
> -{
> -    PCHAR               Buffer;
> -    PANSI_STRING        Distributions;
> -    ULONG               Index;
> -    NTSTATUS            status;
> +    if (Adapter->Properties.lrov6) {
> +        RxOptions->OffloadIpVersion6LargePacket = 1;
> +        RxOptions->NeedLargePacketSplit = 1;
> +    }
> 
> -    Trace("====>\n");
> +    XENVIF_VIF(ReceiverSetOffloadOptions,
> +               &Adapter->VifInterface,
> +               *RxOptions);
> 
> -    status = XENBUS_STORE(Directory,
> -                          &Adapter->StoreInterface,
> -                          NULL,
> -                          NULL,
> -                          "drivers",
> -                          &Buffer);
> -    if (NT_SUCCESS(status)) {
> -        Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer);
> +    XENVIF_VIF(TransmitterQueryOffloadOptions,
> +               &Adapter->VifInterface,
> +               &Options);
> 
> -        XENBUS_STORE(Free,
> -                     &Adapter->StoreInterface,
> -                     Buffer);
> -    } else {
> -        Distributions = NULL;
> -    }
> +    RtlZeroMemory(&Supported, sizeof(NDIS_OFFLOAD));
> +    Supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
> +    Supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
> +    Supported.Header.Size = sizeof(NDIS_OFFLOAD);
> 
> -    if (Distributions == NULL)
> -        goto done;
> +    Supported.Checksum.IPv4Receive.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> 
> -    for (Index = 0; Distributions[Index].Buffer != NULL; Index++) {
> -        PANSI_STRING    Distribution = &Distributions[Index];
> +    Supported.Checksum.IPv4Receive.IpChecksum = 1;
> +    Supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
> 
> -        status = XENBUS_STORE(Read,
> -                              &Adapter->StoreInterface,
> -                              NULL,
> -                              "drivers",
> -                              Distribution->Buffer,
> -                              &Buffer);
> -        if (!NT_SUCCESS(status))
> -            continue;
> +    Supported.Checksum.IPv4Receive.TcpChecksum = 1;
> +    Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
> 
> -        if (__AdapterMatchDistribution(Adapter, Buffer))
> -            (VOID) XENBUS_STORE(Remove,
> -                                &Adapter->StoreInterface,
> -                                NULL,
> -                                "drivers",
> -                                Distribution->Buffer);
> +    Supported.Checksum.IPv4Receive.UdpChecksum = 1;
> 
> -        XENBUS_STORE(Free,
> -                     &Adapter->StoreInterface,
> -                     Buffer);
> -    }
> +    Supported.Checksum.IPv6Receive.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> 
> -    __AdapterFreeAnsi(Distributions);
> +    Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
> 
> -done:
> -    Trace("<====\n");
> -}
> +    Supported.Checksum.IPv6Receive.TcpChecksum = 1;
> +    Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
> 
> -#define MAXIMUM_INDEX   255
> +    Supported.Checksum.IPv6Receive.UdpChecksum = 1;
> 
> -static FORCEINLINE NTSTATUS
> -__AdapterSetDistribution(
> -    IN  PXENNET_ADAPTER Adapter
> -    )
> -{
> -    ULONG               Index;
> -    CHAR                Distribution[MAXNAMELEN];
> -    CHAR                Vendor[MAXNAMELEN];
> -    const CHAR          *Product;
> -    NTSTATUS            status;
> +    Supported.Checksum.IPv4Transmit.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> 
> -    Trace("====>\n");
> +    if (Options.OffloadIpVersion4HeaderChecksum) {
> +        Supported.Checksum.IPv4Transmit.IpChecksum = 1;
> +        Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
> +    }
> 
> -    Index = 0;
> -    while (Index <= MAXIMUM_INDEX) {
> -        PCHAR   Buffer;
> +    if (Options.OffloadIpVersion4TcpChecksum) {
> +        Supported.Checksum.IPv4Transmit.TcpChecksum = 1;
> +        Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
> +    }
> 
> -        status = RtlStringCbPrintfA(Distribution,
> -                                    MAXNAMELEN,
> -                                    "%u",
> -                                    Index);
> -        ASSERT(NT_SUCCESS(status));
> +    if (Options.OffloadIpVersion4UdpChecksum)
> +        Supported.Checksum.IPv4Transmit.UdpChecksum = 1;
> 
> -        status = XENBUS_STORE(Read,
> -                              &Adapter->StoreInterface,
> -                              NULL,
> -                              "drivers",
> -                              Distribution,
> -                              &Buffer);
> -        if (!NT_SUCCESS(status)) {
> -            if (status == STATUS_OBJECT_NAME_NOT_FOUND)
> -                goto update;
> +    Supported.Checksum.IPv6Transmit.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> +
> +    Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
> 
> -            goto fail1;
> -        }
> +    if (Options.OffloadIpVersion6TcpChecksum) {
> +        Supported.Checksum.IPv6Transmit.TcpChecksum = 1;
> +        Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
> +    }
> 
> -        XENBUS_STORE(Free,
> -                     &Adapter->StoreInterface,
> -                     Buffer);
> +    if (Options.OffloadIpVersion6UdpChecksum)
> +        Supported.Checksum.IPv6Transmit.UdpChecksum = 1;
> 
> -        Index++;
> +    if (Options.OffloadIpVersion4LargePacket) {
> +        XENVIF_VIF(TransmitterQueryLargePacketSize,
> +                   &Adapter->VifInterface,
> +                   4,
> +                   &Supported.LsoV2.IPv4.MaxOffLoadSize);
> +        Supported.LsoV2.IPv4.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> +        Supported.LsoV2.IPv4.MinSegmentCount = 2;
>      }
> 
> -    status = STATUS_UNSUCCESSFUL;
> -    goto fail2;
> +    if (Options.OffloadIpVersion6LargePacket) {
> +        XENVIF_VIF(TransmitterQueryLargePacketSize,
> +                   &Adapter->VifInterface,
> +                   6,
> +                   &Supported.LsoV2.IPv6.MaxOffLoadSize);
> +        Supported.LsoV2.IPv6.Encapsulation =
> NDIS_ENCAPSULATION_IEEE_802_3;
> +        Supported.LsoV2.IPv6.MinSegmentCount = 2;
> +        Supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
> +        Supported.LsoV2.IPv6.TcpOptionsSupported = 1;
> +    }
> 
> -update:
> -    status = RtlStringCbPrintfA(Vendor,
> -                                MAXNAMELEN,
> -                                "%s",
> -                                VENDOR_NAME_STR);
> -    ASSERT(NT_SUCCESS(status));
> +    Default = Supported;
> 
> -    for (Index  = 0; Vendor[Index] != '\0'; Index++)
> -        if (!isalnum((UCHAR)Vendor[Index]))
> -            Vendor[Index] = '_';
> +    if (!(Adapter->Properties.ipv4_csum & 2))
> +        Default.Checksum.IPv4Receive.IpChecksum = 0;
> 
> -    Product = "XENNET";
> +    if (!(Adapter->Properties.tcpv4_csum & 2))
> +        Default.Checksum.IPv4Receive.TcpChecksum = 0;
> 
> -#if DBG
> -#define ATTRIBUTES   "(DEBUG)"
> -#else
> -#define ATTRIBUTES   ""
> -#endif
> +    if (!(Adapter->Properties.udpv4_csum & 2))
> +        Default.Checksum.IPv4Receive.UdpChecksum = 0;
> 
> -    (VOID) XENBUS_STORE(Printf,
> -                        &Adapter->StoreInterface,
> -                        NULL,
> -                        "drivers",
> -                        Distribution,
> -                        "%s %s %u.%u.%u %s",
> -                        Vendor,
> -                        Product,
> -                        MAJOR_VERSION,
> -                        MINOR_VERSION,
> -                        MICRO_VERSION,
> -                        ATTRIBUTES
> -                        );
> +    if (!(Adapter->Properties.tcpv6_csum & 2))
> +        Default.Checksum.IPv6Receive.TcpChecksum = 0;
> 
> -#undef  ATTRIBUTES
> +    if (!(Adapter->Properties.udpv6_csum & 2))
> +        Default.Checksum.IPv6Receive.UdpChecksum = 0;
> 
> -    Trace("<====\n");
> -    return STATUS_SUCCESS;
> +    if (!(Adapter->Properties.ipv4_csum & 1))
> +        Default.Checksum.IPv4Transmit.IpChecksum = 0;
> 
> -fail2:
> -    Error("fail2\n");
> +    if (!(Adapter->Properties.tcpv4_csum & 1))
> +        Default.Checksum.IPv4Transmit.TcpChecksum = 0;
> 
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> +    if (!(Adapter->Properties.udpv4_csum & 1))
> +        Default.Checksum.IPv4Transmit.UdpChecksum = 0;
> 
> -    return status;
> -}
> +    if (!(Adapter->Properties.tcpv6_csum & 1))
> +        Default.Checksum.IPv6Transmit.TcpChecksum = 0;
> 
> -static DECLSPEC_NOINLINE VOID
> -AdapterSuspendCallbackLate(
> -    IN  PVOID       Argument
> -    )
> -{
> -    PXENNET_ADAPTER Adapter = Argument;
> +    if (!(Adapter->Properties.udpv6_csum & 1))
> +        Default.Checksum.IPv6Transmit.UdpChecksum = 0;
> 
> -    (VOID) __AdapterSetDistribution(Adapter);
> -}
> +    if (!(Adapter->Properties.lsov4)) {
> +        Default.LsoV2.IPv4.MaxOffLoadSize = 0;
> +        Default.LsoV2.IPv4.MinSegmentCount = 0;
> +    }
> 
> -static NTSTATUS
> -AdapterSetDistribution(
> -    IN  PXENNET_ADAPTER Adapter
> -    )
> -{
> -    LONG                Count;
> -    NTSTATUS            status;
> +    if (!(Adapter->Properties.lsov6)) {
> +        Default.LsoV2.IPv6.MaxOffLoadSize = 0;
> +        Default.LsoV2.IPv6.MinSegmentCount = 0;
> +    }
> 
> -    Trace("====>\n");
> +    if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof
> (NDIS_OFFLOAD))) {
> +        Adapter->Offload = Default;
> +        DISPLAY_OFFLOAD(Default);
> +    }
> 
> -    Count = InterlockedIncrement(&AdapterCount);
> -    ASSERT(Count != 0);
> +    RtlZeroMemory(&Attribs,
> sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES));
> +    Attribs.Header.Type =
> NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
> +    Attribs.Header.Revision =
> NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
> +    Attribs.Header.Size = sizeof(Attribs);
> +    Attribs.DefaultOffloadConfiguration = &Default;
> +    Attribs.HardwareOffloadCapabilities = &Supported;
> 
> -    if (Count != 1)
> -        goto done;
> +    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
> +                                            
> (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
> +    return ndisStatus;
> +}
> 
> -    status = __AdapterSetDistribution(Adapter);
> -    if (!NT_SUCCESS(status))
> -        goto fail1;
> +static NDIS_STATUS
> +AdapterSetHeaderDataSplitAttributes(
> +    IN  PXENNET_ADAPTER                                 Adapter
> +    )
> +{
> +    NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES    Attribs;
> +    NDIS_HD_SPLIT_ATTRIBUTES                            Split;
> +    NDIS_STATUS                                         NdisStatus;
> 
> -    status = XENBUS_SUSPEND(Register,
> -                            &Adapter->SuspendInterface,
> -                            SUSPEND_CALLBACK_LATE,
> -                            AdapterSuspendCallbackLate,
> -                            Adapter,
> -                            &Adapter->SuspendCallbackLate);
> -    if (!NT_SUCCESS(status))
> -        goto fail2;
> +    RtlZeroMemory(&Attribs, sizeof(Attribs));
> 
> -done:
> -    Trace("<====\n");
> -    return STATUS_SUCCESS;
> +    Attribs.Header.Type =
> NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES
> ;
> +    Attribs.Header.Revision =
> NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
> +    Attribs.Header.Size =
> NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVI
> SION_1;
> 
> -fail2:
> -    Error("fail2\n");
> +    RtlZeroMemory(&Split, sizeof(Split));
> 
> -    __AdapterClearDistribution(Adapter);
> +    Split.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
> +    Split.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
> +    Split.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
> +    Split.HardwareCapabilities =
> +        NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT |
> +        NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |
> +        NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |
> +        NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;
> 
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> +    if (Adapter->Properties.HeaderDataSplit != 0)
> +        Split.CurrentCapabilities = Split.HardwareCapabilities;
> 
> -    return status;
> -}
> +    Attribs.HDSplitAttributes = &Split;
> 
> -static VOID
> -AdapterClearDistribution(
> -    IN  PXENNET_ADAPTER Adapter
> -    )
> -{
> -    LONG                Count;
> +    NdisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
> +                                            
> (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
> +    if (NdisStatus != NDIS_STATUS_SUCCESS)
> +        goto fail1;
> 
> -    Trace("====>\n");
> +    if (Split.HDSplitFlags == NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {
> +        ASSERT(Split.CurrentCapabilities &
> NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT);
> 
> -    Count = InterlockedDecrement(&AdapterCount);
> +        Info("BackfillSize = %u\n", Split.BackfillSize);
> +        Info("MaxHeaderSize = %u\n", Split.MaxHeaderSize);
> 
> -    if (Count != 0)
> -        goto done;
> +        XENVIF_VIF(ReceiverSetBackfillSize,
> +                   &Adapter->VifInterface,
> +                   Split.BackfillSize);
> 
> -    XENBUS_SUSPEND(Deregister,
> -                   &Adapter->SuspendInterface,
> -                   Adapter->SuspendCallbackLate);
> -    Adapter->SuspendCallbackLate = NULL;
> +        ReceiverSplitHeaderData(Adapter->Receiver, Split.MaxHeaderSize);
> +    }
> 
> -    __AdapterClearDistribution(Adapter);
> +    return NDIS_STATUS_SUCCESS;
> 
> -done:
> -    Trace("<====\n");
> +fail1:
> +    Error("fail1 (%08x)\n", NdisStatus);
> +
> +    return NdisStatus;
>  }
> 
>  NDIS_STATUS
> @@ -2715,52 +2810,35 @@ AdapterInitialize(
>      if (!NT_SUCCESS(status))
>          goto fail6;
> 
> -    status = XENBUS_CACHE(Acquire,
> -                          &(*Adapter)->CacheInterface);
> -    if (!NT_SUCCESS(status))
> -        goto fail7;
> -
> -    status = XENBUS_STORE(Acquire,
> -                          &(*Adapter)->StoreInterface);
> -    if (!NT_SUCCESS(status))
> -        goto fail8;
> -
> -    status = XENBUS_SUSPEND(Acquire,
> -                            &(*Adapter)->SuspendInterface);
> -    if (!NT_SUCCESS(status))
> -        goto fail9;
> -
> -    (VOID) AdapterSetDistribution(*Adapter);
> -
>      (*Adapter)->NdisAdapterHandle = Handle;
> 
>      ndisStatus = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter);
>      if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail10;
> +        goto fail7;
> 
>      ndisStatus = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver);
>      if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail11;
> +        goto fail8;
> 
>      ndisStatus = AdapterGetAdvancedSettings(*Adapter);
>      if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail12;
> +        goto fail9;
> 
>      ndisStatus = AdapterSetRegistrationAttributes(*Adapter);
>      if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail13;
> +        goto fail10;
> 
>      ndisStatus = AdapterSetGeneralAttributes(*Adapter);
>      if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail14;
> +        goto fail11;
> 
>      ndisStatus = AdapterSetOffloadAttributes(*Adapter);
>      if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail15;
> +        goto fail12;
> 
>      ndisStatus = AdapterSetHeaderDataSplitAttributes(*Adapter);
>      if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail16;
> +        goto fail13;
> 
>      RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION));
>      Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
> @@ -2777,43 +2855,23 @@ AdapterInitialize(
>      if (ndisStatus != NDIS_STATUS_SUCCESS)
>          (*Adapter)->NdisDmaHandle = NULL;
> 
> -    ndisStatus = AdapterEnable(*Adapter);
> -    if (ndisStatus != NDIS_STATUS_SUCCESS)
> -        goto fail17;
> -
>      return NDIS_STATUS_SUCCESS;
> 
> -fail17:
> -    if ((*Adapter)->NdisDmaHandle)
> -        NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle);
> -    (*Adapter)->NdisDmaHandle = NULL;
> -
> -fail16:
> -fail15:
> -fail14:
>  fail13:
>  fail12:
> +fail11:
> +fail10:
> +fail9:
>      ReceiverTeardown((*Adapter)->Receiver);
>      (*Adapter)->Receiver = NULL;
> -fail11:
> 
> +fail8:
>      TransmitterTeardown((*Adapter)->Transmitter);
>      (*Adapter)->Transmitter = NULL;
> 
> -fail10:
> +fail7:
>      (*Adapter)->NdisAdapterHandle = NULL;
> 
> -    AdapterClearDistribution(*Adapter);
> -
> -    XENBUS_SUSPEND(Release, &(*Adapter)->SuspendInterface);
> -
> -fail9:
> -    XENBUS_STORE(Release, &(*Adapter)->StoreInterface);
> -
> -fail8:
> -    XENBUS_CACHE(Release, &(*Adapter)->CacheInterface);
> -
> -fail7:
>      XENVIF_VIF(Release, &(*Adapter)->VifInterface);
> 
>  fail6:
> @@ -2852,9 +2910,6 @@ AdapterTeardown(
> 
>      AdapterClearDistribution(Adapter);
> 
> -    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
> -    XENBUS_STORE(Release, &Adapter->StoreInterface);
> -    XENBUS_CACHE(Release, &Adapter->CacheInterface);
>      XENVIF_VIF(Release, &Adapter->VifInterface);
> 
>      RtlZeroMemory(&Adapter->SuspendInterface,
> sizeof(XENBUS_SUSPEND_INTERFACE));
> diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h
> index 3cc1d90..5b2495a 100644
> --- a/src/xennet/adapter.h
> +++ b/src/xennet/adapter.h
> @@ -99,7 +99,7 @@ AdapterEnable(
>      IN  PXENNET_ADAPTER     Adapter
>      );
> 
> -extern BOOLEAN
> +extern VOID
>  AdapterDisable(
>      IN  PXENNET_ADAPTER     Adapter
>      );
> diff --git a/src/xennet/miniport.c b/src/xennet/miniport.c
> index 5500418..1883db5 100644
> --- a/src/xennet/miniport.c
> +++ b/src/xennet/miniport.c
> @@ -66,7 +66,7 @@ MiniportInitializeEx(
>      PXENNET_ADAPTER                     Adapter;
>      NDIS_STATUS                         NdisStatus;
> 
> -    Trace("====>\n");
> +    Info("====>\n");
> 
>      UNREFERENCED_PARAMETER(MiniportDriverContext);
>      UNREFERENCED_PARAMETER(MiniportInitParameters);
> @@ -75,7 +75,7 @@ MiniportInitializeEx(
>      if (NdisStatus != NDIS_STATUS_SUCCESS)
>          goto fail1;
> 
> -    Trace("<====\n");
> +    Info("<====\n");
> 
>      return NDIS_STATUS_SUCCESS;
> 
> @@ -97,16 +97,14 @@ MiniportHaltEx(
> 
>      UNREFERENCED_PARAMETER(HaltAction);
> 
> -    Trace("====>\n");
> +    Info("====>\n");
> 
>      if (Adapter == NULL)
>          return;
> 
> -    (VOID) AdapterDisable(Adapter);
> -
>      AdapterTeardown(Adapter);
> 
> -    Trace("<====\n");
> +    Info("<====\n");
>  }
> 
>  static
> @@ -131,12 +129,11 @@ MiniportPause(
> 
>      UNREFERENCED_PARAMETER(MiniportPauseParameters);
> 
> -    Trace("====>\n");
> +    Info("====>\n");
> 
> -    if (AdapterDisable(Adapter))
> -        AdapterMediaStateChange(Adapter);
> +    AdapterDisable(Adapter);
> 
> -    Trace("<====\n");
> +    Info("<====\n");
> 
>      return NDIS_STATUS_SUCCESS;
>  }
> @@ -154,11 +151,11 @@ MiniportRestart(
> 
>      UNREFERENCED_PARAMETER(MiniportRestartParameters);
> 
> -    Trace("====>\n");
> +    Info("====>\n");
> 
>      NdisStatus = AdapterEnable(Adapter);
> 
> -    Trace("<====\n");
> +    Info("<====\n");
> 
>      return NdisStatus;
>  }
> diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c
> index 17ab27f..8bfc10b 100644
> --- a/src/xennet/receiver.c
> +++ b/src/xennet/receiver.c
> @@ -359,6 +359,24 @@ fail1:
>      return status;
>  }
> 
> +NDIS_STATUS
> +ReceiverEnable (
> +    IN  PXENNET_RECEIVER    Receiver
> +    )
> +{
> +    UNREFERENCED_PARAMETER(Receiver);
> +
> +    return NDIS_STATUS_SUCCESS;
> +}
> +
> +VOID
> +ReceiverDisable (
> +    IN  PXENNET_RECEIVER    Receiver
> +    )
> +{
> +    UNREFERENCED_PARAMETER(Receiver);
> +}
> +
>  VOID
>  ReceiverTeardown(
>      IN  PXENNET_RECEIVER    Receiver
> diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h
> index b2cc809..33701a9 100644
> --- a/src/xennet/receiver.h
> +++ b/src/xennet/receiver.h
> @@ -43,6 +43,16 @@ ReceiverInitialize(
>      OUT PXENNET_RECEIVER    *Receiver
>      );
> 
> +extern NDIS_STATUS
> +ReceiverEnable(
> +    IN  PXENNET_RECEIVER    Receiver
> +    );
> +
> +extern VOID
> +ReceiverDisable(
> +    IN  PXENNET_RECEIVER    Receiver
> +    );
> +
>  extern VOID
>  ReceiverTeardown(
>      IN  PXENNET_RECEIVER    Receiver
> diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c
> index a617b7d..8c80c7e 100644
> --- a/src/xennet/transmitter.c
> +++ b/src/xennet/transmitter.c
> @@ -141,16 +141,10 @@ TransmitterInitialize (
>      OUT PXENNET_TRANSMITTER *Transmitter
>      )
>  {
> -    NTSTATUS                status;
> -    PXENBUS_CACHE_INTERFACE CacheInterface;
> -
> -    CacheInterface = AdapterGetCacheInterface(Adapter);
> -
>      *Transmitter = ExAllocatePoolWithTag(NonPagedPool,
>                                           sizeof(XENNET_TRANSMITTER),
>                                           TRANSMITTER_POOL_TAG);
> 
> -    status = STATUS_NO_MEMORY;
>      if (*Transmitter == NULL)
>          goto fail1;
> 
> @@ -160,6 +154,22 @@ TransmitterInitialize (
> 
>      KeInitializeSpinLock(&(*Transmitter)->Lock);
> 
> +    return NDIS_STATUS_SUCCESS;
> +
> +fail1:
> +    return NDIS_STATUS_FAILURE;
> +}
> +
> +NDIS_STATUS
> +TransmitterEnable (
> +    IN  PXENNET_TRANSMITTER Transmitter
> +    )
> +{
> +    PXENBUS_CACHE_INTERFACE CacheInterface;
> +    NTSTATUS                status;
> +
> +    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
> +
>      status = XENBUS_CACHE(Create,
>                            CacheInterface,
>                            "packet_cache",
> @@ -169,10 +179,10 @@ TransmitterInitialize (
>                            __TransmitterPacketDtor,
>                            __TransmitterPacketAcquireLock,
>                            __TransmitterPacketReleaseLock,
> -                          *Transmitter,
> -                          &(*Transmitter)->PacketCache);
> +                          Transmitter,
> +                          &Transmitter->PacketCache);
>      if (!NT_SUCCESS(status))
> -        goto fail2;
> +        goto fail1;
> 
>      status = XENBUS_CACHE(Create,
>                            CacheInterface,
> @@ -183,27 +193,20 @@ TransmitterInitialize (
>                            __TransmitterBufferDtor,
>                            __TransmitterBufferAcquireLock,
>                            __TransmitterBufferReleaseLock,
> -                          *Transmitter,
> -                          &(*Transmitter)->BufferCache);
> +                          Transmitter,
> +                          &Transmitter->BufferCache);
>      if (!NT_SUCCESS(status))
> -        goto fail3;
> +        goto fail2;
> 
>      return NDIS_STATUS_SUCCESS;
> 
> -fail3:
> -    XENBUS_CACHE(Destroy,
> -                 CacheInterface,
> -                 (*Transmitter)->PacketCache);
> -    (*Transmitter)->PacketCache = NULL;
> -
>  fail2:
>      Error("fail2\n");
> 
> -    RtlZeroMemory(&(*Transmitter)->Lock, sizeof(KSPIN_LOCK));
> -
> -    ExFreePoolWithTag(*Transmitter, TRANSMITTER_POOL_TAG);
> -
> -    *Transmitter = NULL;
> +    XENBUS_CACHE(Destroy,
> +                 CacheInterface,
> +                 Transmitter->PacketCache);
> +    Transmitter->PacketCache = NULL;
> 
>  fail1:
>      Error("fail1\n (%08x)", status);
> @@ -212,7 +215,7 @@ fail1:
>  }
> 
>  VOID
> -TransmitterTeardown(
> +TransmitterDisable (
>      IN  PXENNET_TRANSMITTER Transmitter
>      )
>  {
> @@ -220,9 +223,6 @@ TransmitterTeardown(
> 
>      CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
> 
> -    Transmitter->Adapter = NULL;
> -    Transmitter->OffloadOptions.Value = 0;
> -
>      XENBUS_CACHE(Destroy,
>                   CacheInterface,
>                   Transmitter->BufferCache);
> @@ -232,6 +232,15 @@ TransmitterTeardown(
>                   CacheInterface,
>                   Transmitter->PacketCache);
>      Transmitter->PacketCache = NULL;
> +}
> +
> +VOID
> +TransmitterTeardown(
> +    IN  PXENNET_TRANSMITTER Transmitter
> +    )
> +{
> +    Transmitter->Adapter = NULL;
> +    Transmitter->OffloadOptions.Value = 0;
> 
>      RtlZeroMemory(&Transmitter->Lock, sizeof(KSPIN_LOCK));
> 
> diff --git a/src/xennet/transmitter.h b/src/xennet/transmitter.h
> index 0adebdc..363b91e 100644
> --- a/src/xennet/transmitter.h
> +++ b/src/xennet/transmitter.h
> @@ -43,6 +43,16 @@ TransmitterInitialize(
>      OUT PXENNET_TRANSMITTER *Transmitter
>      );
> 
> +extern NDIS_STATUS
> +TransmitterEnable(
> +    IN  PXENNET_TRANSMITTER Transmitter
> +    );
> +
> +extern VOID
> +TransmitterDisable(
> +    IN  PXENNET_TRANSMITTER Transmitter
> +    );
> +
>  extern VOID
>  TransmitterTeardown(
>      IN  PXENNET_TRANSMITTER Transmitter
> --
> 2.1.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®.