win-pvdrivers

changeset 775:31c56358c9fc

NDISTest updates. Correctly implement lookahead in xennet. The first buffer must contain the amount windows asks for in lookahead.
author James Harper <james.harper@bendigoit.com.au>
date Sun Feb 07 09:14:18 2010 +1100 (2010-02-07)
parents a3f0201d7fa0
children 5e3af133e8a6
files xennet/xennet.c xennet/xennet.h xennet/xennet_common.c xennet/xennet_oid.c xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/xennet/xennet.c	Mon Feb 01 21:43:12 2010 +1100
     1.2 +++ b/xennet/xennet.c	Sun Feb 07 09:14:18 2010 +1100
     1.3 @@ -406,6 +406,7 @@ XenNet_Init(
     1.4      |NDIS_ATTRIBUTE_BUS_MASTER,
     1.5      NdisInterfaceInternal);
     1.6    xi->multicast_list_size = 0;
     1.7 +  xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;
     1.8  
     1.9    nrl_length = 0;
    1.10    NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
    1.11 @@ -853,7 +854,8 @@ DriverEntry(
    1.12    /* added in v.4 -- use multiple pkts interface */
    1.13    mini_chars.ReturnPacketHandler = XenNet_ReturnPacket;
    1.14    mini_chars.SendPacketsHandler = XenNet_SendPackets;
    1.15 -  mini_chars.CancelSendPacketsHandler = XenNet_CancelSendPackets;
    1.16 +  /* don't support cancel - no point as packets are never queued for long */
    1.17 +  //mini_chars.CancelSendPacketsHandler = XenNet_CancelSendPackets;
    1.18  
    1.19  #ifdef NDIS51_MINIPORT
    1.20    /* added in v.5.1 */
     2.1 --- a/xennet/xennet.h	Mon Feb 01 21:43:12 2010 +1100
     2.2 +++ b/xennet/xennet.h	Sun Feb 07 09:14:18 2010 +1100
     2.3 @@ -164,12 +164,16 @@ SET_NET_ULONG(PVOID ptr, ULONG data)
     2.4  
     2.5  //#define MAX_BUFFERS_PER_PACKET NET_RX_RING_SIZE
     2.6  
     2.7 -#define MAX_ETH_HEADER_SIZE 14
     2.8 -#define MIN_IP4_HEADER_SIZE 20
     2.9 -#define MAX_IP4_HEADER_SIZE (15 * 4)
    2.10 -#define MIN_TCP_HEADER_SIZE 20
    2.11 -#define MAX_TCP_HEADER_SIZE (15 * 4)
    2.12 -#define MAX_PKT_HEADER_SIZE (MAX_ETH_HEADER_SIZE + MAX_IP_HEADER_SIZE + MAX_TCP_HEADER_SIZE)
    2.13 +#define MIN_ETH_HEADER_LENGTH 14
    2.14 +#define MAX_ETH_HEADER_LENGTH 14
    2.15 +#define MIN_IP4_HEADER_LENGTH 20
    2.16 +#define MAX_IP4_HEADER_LENGTH (15 * 4)
    2.17 +#define MIN_TCP_HEADER_LENGTH 20
    2.18 +#define MAX_TCP_HEADER_LENGTH (15 * 4)
    2.19 +#define MAX_PKT_HEADER_LENGTH (MAX_ETH_HEADER_LENGTH + MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
    2.20 +
    2.21 +#define MIN_LOOKAHEAD_LENGTH (MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH)
    2.22 +#define MAX_LOOKAHEAD_LENGTH 256
    2.23  
    2.24  typedef struct
    2.25  {
    2.26 @@ -195,7 +199,6 @@ typedef struct {
    2.27    shared_buffer_t *first_pb;
    2.28    shared_buffer_t *curr_pb;
    2.29    PUCHAR first_buffer_virtual;
    2.30 -  UCHAR header_data[132]; /* maximum possible size of ETH + IP + TCP/UDP headers */
    2.31    ULONG mdl_count;
    2.32    USHORT curr_mdl_offset;
    2.33    USHORT mss;
    2.34 @@ -218,6 +221,8 @@ typedef struct {
    2.35    ULONG tcp_seq;
    2.36    BOOLEAN extra_info;
    2.37    BOOLEAN more_frags;
    2.38 +  /* anything past here doesn't get cleared automatically by the ClearPacketInfo */
    2.39 +  UCHAR header_data[MAX_LOOKAHEAD_LENGTH + MAX_ETH_HEADER_LENGTH];
    2.40  } packet_info_t;
    2.41  
    2.42  #define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4)
    2.43 @@ -244,6 +249,7 @@ struct xennet_info
    2.44    BOOLEAN rx_shutting_down;
    2.45    uint8_t perm_mac_addr[ETH_ALEN];
    2.46    uint8_t curr_mac_addr[ETH_ALEN];
    2.47 +  ULONG current_lookahead;
    2.48  
    2.49    /* Misc. Xen vars */
    2.50    XENPCI_VECTORS vectors;
    2.51 @@ -296,7 +302,6 @@ struct xennet_info
    2.52    ULONG rx_pb_list[RX_PAGE_BUFFERS];
    2.53    shared_buffer_t rx_pbs[RX_PAGE_BUFFERS];
    2.54    USHORT rx_ring_pbs[NET_RX_RING_SIZE];
    2.55 -#define LOOKASIDE_LIST_ALLOC_SIZE 256
    2.56    NPAGED_LOOKASIDE_LIST rx_lookaside_list;
    2.57    /* Receive-ring batched refills. */
    2.58    ULONG rx_target;
    2.59 @@ -395,8 +400,12 @@ XenNet_SetInformation(
    2.60  #define PARSE_TOO_SMALL 1 /* first buffer is too small */
    2.61  #define PARSE_UNKNOWN_TYPE 2
    2.62  
    2.63 +BOOLEAN
    2.64 +XenNet_BuildHeader(packet_info_t *pi, PVOID header, ULONG new_header_size);
    2.65  ULONG
    2.66  XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR buffer, ULONG min_header_size);
    2.67 +BOOLEAN
    2.68 +XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi);
    2.69  
    2.70  VOID
    2.71  XenNet_SumIpHeader(
    2.72 @@ -408,13 +417,12 @@ static __forceinline VOID
    2.73  XenNet_ClearPacketInfo(packet_info_t *pi)
    2.74  {
    2.75  #if 1
    2.76 -  #if 0
    2.77 -  RtlZeroMemory(&pi->mdl_count, sizeof(packet_info_t) - FIELD_OFFSET(packet_info_t, mdl_count));
    2.78 -  #else
    2.79 -  RtlZeroMemory(pi, sizeof(packet_info_t));
    2.80 -  #endif
    2.81 +  RtlZeroMemory(pi, sizeof(packet_info_t) - FIELD_OFFSET(packet_info_t, header_data));
    2.82  #else
    2.83    pi->mdl_count = 0;
    2.84 +  pi->mss = 0;
    2.85 +  pi->ip4_header_length = 0;
    2.86 +  pi->tcp_header_length = 0;
    2.87    pi->curr_mdl_index = pi->curr_mdl_offset = 0;
    2.88    pi->extra_info = pi->more_frags = pi->csum_blank =
    2.89      pi->data_validated = pi->split_required = 0;
     3.1 --- a/xennet/xennet_common.c	Mon Feb 01 21:43:12 2010 +1100
     3.2 +++ b/xennet/xennet_common.c	Sun Feb 07 09:14:18 2010 +1100
     3.3 @@ -25,18 +25,21 @@ Increase the header to a certain size
     3.4  */
     3.5  
     3.6  BOOLEAN
     3.7 -XenNet_BuildHeader(packet_info_t *pi, ULONG new_header_size)
     3.8 +XenNet_BuildHeader(packet_info_t *pi, PUCHAR header, ULONG new_header_size)
     3.9  {
    3.10    ULONG bytes_remaining;
    3.11  
    3.12    //FUNCTION_ENTER();
    3.13  
    3.14 +  if (!header)
    3.15 +    header = pi->header;
    3.16 +
    3.17    if (new_header_size <= pi->header_length)
    3.18    {
    3.19      return TRUE; /* header is already at least the required size */
    3.20    }
    3.21  
    3.22 -  if (pi->header == pi->first_buffer_virtual)
    3.23 +  if (header == pi->first_buffer_virtual)
    3.24    {
    3.25      /* still working in the first buffer */
    3.26      if (new_header_size <= pi->first_buffer_length)
    3.27 @@ -47,24 +50,25 @@ XenNet_BuildHeader(packet_info_t *pi, UL
    3.28        {
    3.29          NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
    3.30          pi->curr_mdl_offset = 0;
    3.31 +        if (pi->curr_pb)
    3.32 +          pi->curr_pb = pi->curr_pb->next;
    3.33        }
    3.34        else
    3.35        {
    3.36          pi->curr_mdl_offset = (USHORT)new_header_size;
    3.37 -        if (pi->curr_pb)
    3.38 -          pi->curr_pb = pi->curr_pb->next;
    3.39        }      
    3.40        return TRUE;
    3.41      }
    3.42      else
    3.43      {
    3.44        //KdPrint((__DRIVER_NAME "     Switching to header_data\n"));
    3.45 -      memcpy(pi->header_data, pi->header, pi->header_length);
    3.46 -      pi->header = pi->header_data;
    3.47 +      memcpy(pi->header_data, header, pi->header_length);
    3.48 +      header = pi->header = pi->header_data;
    3.49      }
    3.50    }
    3.51    
    3.52    bytes_remaining = new_header_size - pi->header_length;
    3.53 +  // TODO: if there are only a small number of bytes left in the current buffer then increase to consume that too...
    3.54  
    3.55    //KdPrint((__DRIVER_NAME "     A bytes_remaining = %d, pi->curr_buffer = %p, pi->mdl_count = %d\n", bytes_remaining, pi->curr_buffer, pi->mdl_count));
    3.56    while (bytes_remaining && pi->curr_buffer)
    3.57 @@ -81,7 +85,7 @@ XenNet_BuildHeader(packet_info_t *pi, UL
    3.58          return FALSE;
    3.59        copy_size = min(bytes_remaining, MmGetMdlByteCount(pi->curr_buffer) - pi->curr_mdl_offset);
    3.60        //KdPrint((__DRIVER_NAME "     B copy_size = %d\n", copy_size));
    3.61 -      memcpy(pi->header + pi->header_length,
    3.62 +      memcpy(header + pi->header_length,
    3.63          src_addr + pi->curr_mdl_offset, copy_size);
    3.64        pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + copy_size);
    3.65        pi->header_length += copy_size;
    3.66 @@ -121,8 +125,10 @@ XenNet_ParsePacketHeader(packet_info_t *
    3.67  
    3.68    pi->header_length = 0;
    3.69    pi->curr_mdl_offset = 0;
    3.70 -    
    3.71 -  if (!XenNet_BuildHeader(pi, max((ULONG)XN_HDR_SIZE, min_header_size)))
    3.72 +
    3.73 +  XenNet_BuildHeader(pi, NULL, min_header_size);
    3.74 +  
    3.75 +  if (!XenNet_BuildHeader(pi, NULL, (ULONG)XN_HDR_SIZE))
    3.76    {
    3.77      KdPrint((__DRIVER_NAME "     packet too small (Ethernet Header)\n"));
    3.78      return PARSE_TOO_SMALL;
    3.79 @@ -134,7 +140,7 @@ XenNet_ParsePacketHeader(packet_info_t *
    3.80      //KdPrint((__DRIVER_NAME "     IP\n"));
    3.81      if (pi->header_length < (ULONG)(XN_HDR_SIZE + 20))
    3.82      {
    3.83 -      if (!XenNet_BuildHeader(pi, (ULONG)(XN_HDR_SIZE + 20)))
    3.84 +      if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + 20)))
    3.85        {
    3.86          KdPrint((__DRIVER_NAME "     packet too small (IP Header)\n"));
    3.87          return PARSE_TOO_SMALL;
    3.88 @@ -149,7 +155,7 @@ XenNet_ParsePacketHeader(packet_info_t *
    3.89      pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
    3.90      if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20))
    3.91      {
    3.92 -      if (!XenNet_BuildHeader(pi, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)))
    3.93 +      if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)))
    3.94        {
    3.95          //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header)\n"));
    3.96          return PARSE_TOO_SMALL;
    3.97 @@ -175,7 +181,7 @@ XenNet_ParsePacketHeader(packet_info_t *
    3.98  
    3.99    if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length))
   3.100    {
   3.101 -    if (!XenNet_BuildHeader(pi, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)))
   3.102 +    if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)))
   3.103      {
   3.104        //KdPrint((__DRIVER_NAME "     packet too small (IP Header + IP Options + TCP Header + TCP Options)\n"));
   3.105        return PARSE_TOO_SMALL;
   3.106 @@ -225,3 +231,59 @@ XenNet_SumIpHeader(
   3.107    csum = ~csum;
   3.108    SET_NET_USHORT(&header[XN_HDR_SIZE + 10], (USHORT)csum);
   3.109  }
   3.110 +
   3.111 +BOOLEAN
   3.112 +XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi)
   3.113 +{
   3.114 +  BOOLEAN is_multicast = FALSE;
   3.115 +  BOOLEAN is_my_multicast = FALSE;
   3.116 +  BOOLEAN is_broadcast = FALSE;
   3.117 +  BOOLEAN is_directed = FALSE;
   3.118 +  ULONG i;
   3.119 +
   3.120 +  if (pi->header[0] == 0xFF && pi->header[1] == 0xFF
   3.121 +      && pi->header[2] == 0xFF && pi->header[3] == 0xFF
   3.122 +      && pi->header[4] == 0xFF && pi->header[5] == 0xFF)
   3.123 +  {
   3.124 +    is_broadcast = TRUE;
   3.125 +  }
   3.126 +  else if (pi->header[0] & 0x01)
   3.127 +  {
   3.128 +    is_multicast = TRUE;
   3.129 +    for (i = 0; i < xi->multicast_list_size; i++)
   3.130 +    {
   3.131 +      if (memcmp(xi->multicast_list[i], pi->header, 6) == 0)
   3.132 +        break;
   3.133 +    }
   3.134 +    if (i < xi->multicast_list_size)
   3.135 +    {
   3.136 +      is_my_multicast = TRUE;
   3.137 +    }    
   3.138 +  }
   3.139 +  if (memcmp(xi->curr_mac_addr, pi->header, ETH_ALEN) == 0)
   3.140 +  {
   3.141 +    is_directed = TRUE;
   3.142 +  }
   3.143 +
   3.144 +  if (is_directed && (xi->packet_filter & NDIS_PACKET_TYPE_DIRECTED))
   3.145 +  {
   3.146 +    return TRUE;
   3.147 +  }  
   3.148 +  if (is_my_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_MULTICAST))
   3.149 +  {
   3.150 +    return TRUE;
   3.151 +  }
   3.152 +  if (is_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST))
   3.153 +  {
   3.154 +    return TRUE;
   3.155 +  }
   3.156 +  if (is_broadcast && (xi->packet_filter & NDIS_PACKET_TYPE_BROADCAST))
   3.157 +  {
   3.158 +    return TRUE;
   3.159 +  }
   3.160 +  if (xi->packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS)
   3.161 +  {
   3.162 +    return TRUE;
   3.163 +  }
   3.164 +  return FALSE;
   3.165 +}
     4.1 --- a/xennet/xennet_oid.c	Mon Feb 01 21:43:12 2010 +1100
     4.2 +++ b/xennet/xennet_oid.c	Sun Feb 07 09:14:18 2010 +1100
     4.3 @@ -128,7 +128,7 @@ XenNet_QueryInformation(
     4.4        temp_data = NdisMedium802_3;
     4.5        break;
     4.6      case OID_GEN_MAXIMUM_LOOKAHEAD:
     4.7 -      temp_data = xi->config_mtu;
     4.8 +      temp_data = MAX_LOOKAHEAD_LENGTH; //xi->config_mtu;
     4.9        break;
    4.10      case OID_GEN_MAXIMUM_FRAME_SIZE:
    4.11        temp_data = xi->config_mtu;
    4.12 @@ -160,7 +160,7 @@ XenNet_QueryInformation(
    4.13        temp_data = xi->packet_filter;
    4.14        break;
    4.15      case OID_GEN_CURRENT_LOOKAHEAD:
    4.16 -      temp_data = xi->config_mtu;
    4.17 +      temp_data = xi->current_lookahead;
    4.18        break;
    4.19      case OID_GEN_DRIVER_VERSION:
    4.20        temp_data = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION;
    4.21 @@ -489,7 +489,7 @@ XenNet_SetInformation(
    4.22        KdPrint(("Unsupported set OID_GEN_VENDOR_DESCRIPTION\n"));
    4.23        break;
    4.24      case OID_GEN_CURRENT_PACKET_FILTER:
    4.25 -      KdPrint(("Set OID_GEN_CURRENT_PACKET_FILTER\n"));
    4.26 +      KdPrint(("Set OID_GEN_CURRENT_PACKET_FILTER (xi = %p)\n", xi));
    4.27        if (*(ULONG *)data & NDIS_PACKET_TYPE_DIRECTED)
    4.28          KdPrint(("  NDIS_PACKET_TYPE_DIRECTED\n"));
    4.29        if (*(ULONG *)data & NDIS_PACKET_TYPE_MULTICAST)
    4.30 @@ -503,7 +503,7 @@ XenNet_SetInformation(
    4.31        if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_FUNCTIONAL)
    4.32          KdPrint(("  NDIS_PACKET_TYPE_ALL_FUNCTIONAL (not supported)\n"));
    4.33        if (*(ULONG *)data & NDIS_PACKET_TYPE_ALL_LOCAL)
    4.34 -        KdPrint(("  NDIS_PACKET_TYPE_ALL_LOCAL (not supported)\n"));
    4.35 +        KdPrint(("  NDIS_PACKET_TYPE_ALL_LOCAL (not supported)\n"));  
    4.36        if (*(ULONG *)data & NDIS_PACKET_TYPE_FUNCTIONAL)
    4.37          KdPrint(("  NDIS_PACKET_TYPE_FUNCTIONAL (not supported)\n"));
    4.38        if (*(ULONG *)data & NDIS_PACKET_TYPE_GROUP)
    4.39 @@ -518,8 +518,8 @@ XenNet_SetInformation(
    4.40        status = NDIS_STATUS_SUCCESS;
    4.41        break;
    4.42      case OID_GEN_CURRENT_LOOKAHEAD:
    4.43 -      KdPrint(("Set OID_GEN_CURRENT_LOOKAHEAD %d\n", *(int *)data));
    4.44 -      // TODO: We should do this...
    4.45 +      xi->current_lookahead = *(ULONG *)data;
    4.46 +      KdPrint(("Set OID_GEN_CURRENT_LOOKAHEAD %d (%p)\n", xi->current_lookahead, xi));
    4.47        status = NDIS_STATUS_SUCCESS;
    4.48        break;
    4.49      case OID_GEN_DRIVER_VERSION:
     5.1 --- a/xennet/xennet_rx.c	Mon Feb 01 21:43:12 2010 +1100
     5.2 +++ b/xennet/xennet_rx.c	Sun Feb 07 09:14:18 2010 +1100
     5.3 @@ -181,120 +181,103 @@ XenNet_MakePacket(struct xennet_info *xi
     5.4    USHORT new_ip4_length;
     5.5    PUCHAR header_va;
     5.6    packet_info_t *pi = &xi->rxpi;
     5.7 +  ULONG out_remaining;
     5.8 +  ULONG tcp_length;
     5.9 +  ULONG header_extra;
    5.10 +  shared_buffer_t *header_buf;
    5.11  
    5.12    //FUNCTION_ENTER();
    5.13 -
    5.14 -  if (!pi->split_required)
    5.15 +  
    5.16 +  packet = get_packet_from_freelist(xi);
    5.17 +  if (packet == NULL)
    5.18    {
    5.19 -    PNDIS_BUFFER buffer;
    5.20 -    shared_buffer_t *page_buf;
    5.21 -    
    5.22 -    //KdPrint((__DRIVER_NAME "     !split_required\n"));
    5.23 -
    5.24 -    packet = get_packet_from_freelist(xi);
    5.25 -    if (packet == NULL)
    5.26 -    {
    5.27 -      /* buffers will be freed in MakePackets */
    5.28 -      KdPrint((__DRIVER_NAME "     No free packets\n"));
    5.29 -      //FUNCTION_EXIT();
    5.30 -      return NULL;
    5.31 -    }
    5.32 -    xi->rx_outstanding++;
    5.33 +    /* buffers will be freed in MakePackets */
    5.34 +    KdPrint((__DRIVER_NAME "     No free packets\n"));
    5.35 +    //FUNCTION_EXIT();
    5.36 +    return NULL;
    5.37 +  }
    5.38 +  
    5.39 +  header_buf = NdisAllocateFromNPagedLookasideList(&xi->rx_lookaside_list);
    5.40 +  ASSERT(header_buf); // lazy
    5.41 +  header_va = (PUCHAR)(header_buf + 1);
    5.42 +  NdisZeroMemory(header_buf, sizeof(shared_buffer_t));
    5.43 +  NdisMoveMemory(header_va, pi->header, pi->header_length);
    5.44 +  //KdPrint((__DRIVER_NAME "     header_length = %d, current_lookahead = %d\n", pi->header_length, xi->current_lookahead));
    5.45 +  //KdPrint((__DRIVER_NAME "     ip4_header_length = %d\n", pi->ip4_header_length));
    5.46 +  //KdPrint((__DRIVER_NAME "     tcp_header_length = %d\n", pi->tcp_header_length));
    5.47 +  /* make sure we satisfy the lookahead requirement */
    5.48 +  XenNet_BuildHeader(pi, header_va, min(MIN_LOOKAHEAD_LENGTH, xi->current_lookahead) + MAX_ETH_HEADER_LENGTH);
    5.49 +  header_extra = pi->header_length - (MAX_ETH_HEADER_LENGTH + pi->ip4_header_length + pi->tcp_header_length);
    5.50 +  ASSERT(pi->header_length <= MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH);
    5.51 +  NdisAllocateBuffer(&status, &out_buffer, xi->rx_buffer_pool, header_va, pi->header_length);
    5.52 +  ASSERT(status == STATUS_SUCCESS);
    5.53 +  NdisChainBufferAtBack(packet, out_buffer);
    5.54 +  *(shared_buffer_t **)&packet->MiniportReservedEx[sizeof(LIST_ENTRY)] = header_buf;
    5.55 +  header_buf->next = pi->curr_pb;
    5.56  
    5.57 -    // what if we needed to consolidate the header? maybe should put that on instead of all the buffers...
    5.58 -    *(shared_buffer_t **)&packet->MiniportReservedEx[sizeof(LIST_ENTRY)] = pi->first_pb;
    5.59 -    
    5.60 -    buffer = pi->first_buffer;
    5.61 -    page_buf = pi->first_pb;
    5.62 -    //KdPrint((__DRIVER_NAME "     packet = %p, first_buffer = %p, first_pb = %p\n", packet, buffer, page_buf));
    5.63 -    while (buffer)
    5.64 -    {
    5.65 -      PNDIS_BUFFER next_buffer;
    5.66 -      //KdPrint((__DRIVER_NAME "     buffer = %p\n", buffer));
    5.67  
    5.68 -      NdisGetNextBuffer(buffer, &next_buffer);
    5.69 -      NDIS_BUFFER_LINKAGE(buffer) = NULL;
    5.70 -      NdisChainBufferAtBack(packet, buffer);
    5.71 -      //ref_pb(xi, page_buf);
    5.72 -      
    5.73 -      buffer = next_buffer;
    5.74 -      page_buf = page_buf->next;
    5.75 -    }
    5.76 +  // TODO: if there are only a few bytes left on the first buffer then add them to the header buffer too... maybe
    5.77  
    5.78 -    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
    5.79 +  //KdPrint((__DRIVER_NAME "     split_required = %d\n", pi->split_required));
    5.80 +  //KdPrint((__DRIVER_NAME "     tcp_length = %d, mss = %d\n", pi->tcp_length, pi->mss));
    5.81 +  //KdPrint((__DRIVER_NAME "     total_length = %d\n", pi->total_length));
    5.82 +  //KdPrint((__DRIVER_NAME "     header_length = %d\n", pi->header_length));
    5.83 +  //KdPrint((__DRIVER_NAME "     header_extra = %d\n", header_extra));
    5.84 +  if (pi->split_required)
    5.85 +  {
    5.86 +    tcp_length = (USHORT)min(pi->mss, pi->tcp_remaining);
    5.87 +    new_ip4_length = (USHORT)(pi->ip4_header_length + pi->tcp_header_length + tcp_length);
    5.88 +    //KdPrint((__DRIVER_NAME "     new_ip4_length = %d\n", new_ip4_length));
    5.89 +    //KdPrint((__DRIVER_NAME "     this tcp_length = %d\n", tcp_length));
    5.90 +    SET_NET_USHORT(&header_va[XN_HDR_SIZE + 2], new_ip4_length);
    5.91 +    SET_NET_ULONG(&header_va[XN_HDR_SIZE + pi->ip4_header_length + 4], pi->tcp_seq);
    5.92 +    pi->tcp_seq += tcp_length;
    5.93 +    pi->tcp_remaining = (USHORT)(pi->tcp_remaining - tcp_length);
    5.94 +    /* part of the packet is already present in the header buffer for lookahead */
    5.95 +    out_remaining = tcp_length - header_extra;
    5.96    }
    5.97    else
    5.98    {
    5.99 -    ULONG out_remaining;
   5.100 -    shared_buffer_t *header_buf;
   5.101 +    out_remaining = pi->total_length - pi->header_length;
   5.102 +  }
   5.103 +  //KdPrint((__DRIVER_NAME "     before loop - out_remaining = %d\n", out_remaining));
   5.104      
   5.105 -    //KdPrint((__DRIVER_NAME "     split_required\n"));
   5.106 -
   5.107 -    packet = get_packet_from_freelist(xi);
   5.108 -    if (packet == NULL)
   5.109 +  while (out_remaining != 0)
   5.110 +  {
   5.111 +    ULONG in_buffer_offset;
   5.112 +    ULONG in_buffer_length;
   5.113 +    ULONG out_length;
   5.114 +    
   5.115 +    //KdPrint((__DRIVER_NAME "     in loop - out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_buffer, pi->curr_pb));
   5.116 +    if (!pi->curr_buffer || !pi->curr_pb)
   5.117      {
   5.118 -      //FUNCTION_EXIT();
   5.119 +      KdPrint((__DRIVER_NAME "     out of buffers for packet\n"));
   5.120 +      // TODO: free some stuff or we'll leak
   5.121        return NULL;
   5.122      }
   5.123 -    xi->rx_outstanding++;
   5.124 -
   5.125 -    ASSERT(sizeof(shared_buffer_t) + pi->header_length < LOOKASIDE_LIST_ALLOC_SIZE);
   5.126 -    header_buf = NdisAllocateFromNPagedLookasideList(&xi->rx_lookaside_list);
   5.127 -    ASSERT(header_buf); // lazy
   5.128 -    header_va = (PUCHAR)(header_buf + 1);
   5.129 -    NdisZeroMemory(header_buf, sizeof(shared_buffer_t));
   5.130 -    NdisMoveMemory(header_va, pi->header, pi->header_length);
   5.131 -
   5.132 -    // TODO: if there are only a few bytes left on the first buffer then add them to the header buffer too
   5.133 -
   5.134 -    NdisAllocateBuffer(&status, &out_buffer, xi->rx_buffer_pool, header_va, pi->header_length);
   5.135 +    NdisQueryBufferOffset(pi->curr_buffer, &in_buffer_offset, &in_buffer_length);
   5.136 +    out_length = min(out_remaining, in_buffer_length - pi->curr_mdl_offset);
   5.137 +    NdisCopyBuffer(&status, &out_buffer, xi->rx_buffer_pool, pi->curr_buffer, pi->curr_mdl_offset, out_length);
   5.138 +    //TODO: check status
   5.139      NdisChainBufferAtBack(packet, out_buffer);
   5.140 -    *(shared_buffer_t **)&packet->MiniportReservedEx[sizeof(LIST_ENTRY)] = header_buf;
   5.141 -    header_buf->next = pi->curr_pb;
   5.142 -
   5.143 -    //KdPrint((__DRIVER_NAME "     header_length = %d\n", pi->header_length));
   5.144 -    //KdPrint((__DRIVER_NAME "     curr_mdl_offset = %d\n", pi->curr_mdl_offset));
   5.145 -    //KdPrint((__DRIVER_NAME "     tcp_remaining = %d\n", pi->tcp_remaining));
   5.146 -    
   5.147 -    //KdPrint((__DRIVER_NAME "     tcp_remaining = %d\n", pi->tcp_remaining));
   5.148 -    out_remaining = (USHORT)min(pi->mss, pi->tcp_remaining);
   5.149 -    new_ip4_length = (USHORT)(pi->ip4_header_length + pi->tcp_header_length + out_remaining);
   5.150 -    SET_NET_USHORT(&header_va[XN_HDR_SIZE + 2], new_ip4_length);
   5.151 -    SET_NET_ULONG(&header_va[XN_HDR_SIZE + pi->ip4_header_length + 4], pi->tcp_seq);
   5.152 -    pi->tcp_seq += out_remaining;
   5.153 -    pi->tcp_remaining = (USHORT)(pi->tcp_remaining - out_remaining);
   5.154 -    do 
   5.155 +    ref_pb(xi, pi->curr_pb);
   5.156 +    pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + out_length);
   5.157 +    if (pi->curr_mdl_offset == in_buffer_length)
   5.158      {
   5.159 -      ULONG in_buffer_offset;
   5.160 -      ULONG in_buffer_length;
   5.161 -      ULONG out_length;
   5.162 -      //UINT tmp_packet_length;
   5.163 -      //KdPrint((__DRIVER_NAME "     curr_buffer = %p\n", pi->curr_buffer));
   5.164 -      //KdPrint((__DRIVER_NAME "     curr_pb = %p\n", pi->curr_pb));
   5.165 -      //KdPrint((__DRIVER_NAME "     out_remaining = %d\n", out_remaining));
   5.166 -      NdisQueryBufferOffset(pi->curr_buffer, &in_buffer_offset, &in_buffer_length);
   5.167 -      out_length = min(out_remaining, in_buffer_length - pi->curr_mdl_offset);
   5.168 -      //KdPrint((__DRIVER_NAME "     out_length = %d\n", out_length));
   5.169 -      NdisCopyBuffer(&status, &out_buffer, xi->rx_buffer_pool, pi->curr_buffer, pi->curr_mdl_offset, out_length);
   5.170 -      //TODO: check status
   5.171 -      //KdPrint((__DRIVER_NAME "     about to add buffer with length = %d\n", MmGetMdlByteCount(out_buffer)));
   5.172 -      NdisChainBufferAtBack(packet, out_buffer);
   5.173 -      //NdisQueryPacketLength(packet, &tmp_packet_length);
   5.174 -      //KdPrint((__DRIVER_NAME "     current packet length = %d\n", tmp_packet_length));
   5.175 -      ref_pb(xi, pi->curr_pb);
   5.176 -      pi->curr_mdl_offset = (USHORT)(pi->curr_mdl_offset + out_length);
   5.177 -      if (pi->curr_mdl_offset == in_buffer_length)
   5.178 -      {
   5.179 -        NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
   5.180 -        pi->curr_pb = pi->curr_pb->next;
   5.181 -        pi->curr_mdl_offset = 0;
   5.182 -      }
   5.183 -      out_remaining -= out_length;
   5.184 -    } while (out_remaining != 0);
   5.185 +      NdisGetNextBuffer(pi->curr_buffer, &pi->curr_buffer);
   5.186 +      pi->curr_pb = pi->curr_pb->next;
   5.187 +      pi->curr_mdl_offset = 0;
   5.188 +    }
   5.189 +    out_remaining -= out_length;
   5.190 +  }
   5.191 +  if (pi->split_required)
   5.192 +  {
   5.193      XenNet_SumIpHeader(header_va, pi->ip4_header_length);
   5.194 -    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   5.195    }
   5.196 -
   5.197 +  NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   5.198 +  if (header_extra > 0)
   5.199 +    pi->header_length -= header_extra;
   5.200 +  xi->rx_outstanding++;
   5.201    //FUNCTION_EXIT();
   5.202    return packet;
   5.203  }
   5.204 @@ -439,7 +422,6 @@ XenNet_MakePackets(
   5.205    PLIST_ENTRY rx_packet_list
   5.206  )
   5.207  {
   5.208 -  USHORT i;
   5.209    ULONG packet_count = 0;
   5.210    PNDIS_PACKET packet;
   5.211    PLIST_ENTRY entry;
   5.212 @@ -447,73 +429,15 @@ XenNet_MakePackets(
   5.213    PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   5.214    ULONG parse_result;  
   5.215    packet_info_t *pi = &xi->rxpi;
   5.216 -  PNDIS_BUFFER buffer;
   5.217 +  //PNDIS_BUFFER buffer;
   5.218    shared_buffer_t *page_buf;
   5.219 -  BOOLEAN accept_packet = FALSE;
   5.220 -  BOOLEAN is_multicast = FALSE;
   5.221 -  BOOLEAN is_my_multicast = FALSE;
   5.222 -  BOOLEAN is_broadcast = FALSE;
   5.223 -  BOOLEAN is_directed = FALSE;
   5.224  
   5.225    //FUNCTION_ENTER();
   5.226  
   5.227    parse_result = XenNet_ParsePacketHeader(pi, NULL, 0);
   5.228    
   5.229 -  //KdPrint((__DRIVER_NAME "     ip4_length = %d, tcp_length = %d\n", pi->ip4_length, pi->tcp_length));
   5.230 -  
   5.231 -  if (pi->header[0] == 0xFF && pi->header[1] == 0xFF
   5.232 -      && pi->header[2] == 0xFF && pi->header[3] == 0xFF
   5.233 -      && pi->header[4] == 0xFF && pi->header[5] == 0xFF)
   5.234 -  {
   5.235 -    is_broadcast = TRUE;
   5.236 -  }
   5.237 -  else if (pi->header[0] & 0x01)
   5.238 -  {
   5.239 -    is_multicast = TRUE;
   5.240 -    for (i = 0; i < xi->multicast_list_size; i++)
   5.241 -    {
   5.242 -      if (memcmp(xi->multicast_list[i], pi->header, 6) == 0)
   5.243 -        break;
   5.244 -    }
   5.245 -    if (i < xi->multicast_list_size)
   5.246 -    {
   5.247 -      is_my_multicast = TRUE;
   5.248 -    }    
   5.249 -  }
   5.250 -  if (memcmp(xi->curr_mac_addr, pi->header, ETH_ALEN) == 0)
   5.251 +  if (!XenNet_FilterAcceptPacket(xi, pi))
   5.252    {
   5.253 -    is_directed = TRUE;
   5.254 -  }
   5.255 -
   5.256 -  if (!accept_packet && (xi->packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS))
   5.257 -  {
   5.258 -    //KdPrint((__DRIVER_NAME "     Accepting packet because NDIS_PACKET_TYPE_PROMISCUOUS\n"));
   5.259 -    accept_packet = TRUE;
   5.260 -  }
   5.261 -  if (!accept_packet && is_broadcast && (xi->packet_filter & NDIS_PACKET_TYPE_BROADCAST))
   5.262 -  {
   5.263 -    //KdPrint((__DRIVER_NAME "     Accepting packet because NDIS_PACKET_TYPE_BROADCAST\n"));
   5.264 -    accept_packet = TRUE;
   5.265 -  }
   5.266 -  if (!accept_packet && is_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST))
   5.267 -  {
   5.268 -    //KdPrint((__DRIVER_NAME "     Accepting packet because NDIS_PACKET_TYPE_ALL_MULTICAST\n"));
   5.269 -    accept_packet = TRUE;
   5.270 -  }
   5.271 -  if (!accept_packet && is_my_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_MULTICAST))
   5.272 -  {
   5.273 -    //KdPrint((__DRIVER_NAME "     Accepting packet because NDIS_PACKET_TYPE_MULTICAST\n"));
   5.274 -    accept_packet = TRUE;
   5.275 -  }
   5.276 -  if (!accept_packet && is_directed && (xi->packet_filter & NDIS_PACKET_TYPE_DIRECTED))
   5.277 -  {
   5.278 -    //KdPrint((__DRIVER_NAME "     Accepting packet because NDIS_PACKET_TYPE_DIRECTED\n"));
   5.279 -    accept_packet = TRUE;
   5.280 -  }
   5.281 -
   5.282 -  if (!accept_packet)
   5.283 -  {
   5.284 -    //KdPrint((__DRIVER_NAME "     Not accepting packet\n"));
   5.285      goto done;
   5.286    }
   5.287  
   5.288 @@ -532,7 +456,6 @@ XenNet_MakePackets(
   5.289        packet_count = 0;
   5.290        goto done;
   5.291      }
   5.292 -
   5.293      if (parse_result == PARSE_OK)
   5.294      {
   5.295        csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   5.296 @@ -581,9 +504,8 @@ XenNet_MakePackets(
   5.297      }
   5.298      entry = (PLIST_ENTRY)&packet->MiniportReservedEx[0];
   5.299      InsertTailList(rx_packet_list, entry);
   5.300 -    XenNet_ClearPacketInfo(pi);
   5.301 -    //FUNCTION_EXIT();
   5.302 -    return 1;
   5.303 +    packet_count = 1;
   5.304 +    goto done;
   5.305    default:
   5.306      packet = XenNet_MakePacket(xi);
   5.307      if (packet == NULL)
   5.308 @@ -595,22 +517,8 @@ XenNet_MakePackets(
   5.309      }
   5.310      entry = (PLIST_ENTRY)&packet->MiniportReservedEx[0];
   5.311      InsertTailList(rx_packet_list, entry);
   5.312 -    XenNet_ClearPacketInfo(pi);
   5.313 -    //FUNCTION_EXIT();
   5.314 -    return 1;
   5.315 -  }
   5.316 -
   5.317 -  /* synchronise the pb with the buffer */
   5.318 -  buffer = pi->first_buffer;
   5.319 -  pi->curr_pb = pi->first_pb;
   5.320 -  //KdPrint((__DRIVER_NAME "     first_buffer = %p, curr_buffer = %p, first_pb = %p, curr_pb = %p\n",
   5.321 -  //  pi->first_buffer, pi->curr_buffer, pi->first_pb, pi->curr_pb));
   5.322 -  
   5.323 -  while (pi->curr_pb != NULL && buffer != pi->curr_buffer)
   5.324 -  {
   5.325 -    NdisGetNextBuffer(buffer, &buffer);
   5.326 -    pi->curr_pb = pi->curr_pb->next;
   5.327 -    //KdPrint((__DRIVER_NAME "     buffer = %p, curr_pb = %p\n", buffer, pi->curr_pb));
   5.328 +    packet_count = 1;
   5.329 +    goto done;
   5.330    }
   5.331    
   5.332    pi->tcp_remaining = pi->tcp_length;
   5.333 @@ -745,6 +653,7 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
   5.334            {
   5.335            case XEN_NETIF_GSO_TYPE_TCPV4:
   5.336              pi->mss = ei->u.gso.size;
   5.337 +            //KdPrint((__DRIVER_NAME "     mss = %d\n", pi->mss));
   5.338              // TODO - put this assertion somewhere ASSERT(header_len + pi->mss <= PAGE_SIZE); // this limits MTU to PAGE_SIZE - XN_HEADER_LEN
   5.339              break;
   5.340            default:
   5.341 @@ -783,6 +692,7 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
   5.342          //ASSERT(status == NDIS_STATUS_SUCCESS); // lazy
   5.343          buffer = page_buf->buffer;
   5.344          NdisAdjustBufferLength(buffer, rxrsp->status);
   5.345 +        //KdPrint((__DRIVER_NAME "     buffer = %p, pb = %p\n", buffer, page_buf));
   5.346          if (pi->first_pb)
   5.347          {
   5.348            //KdPrint((__DRIVER_NAME "     additional buffer\n"));
   5.349 @@ -807,6 +717,8 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
   5.350        /* Packet done, add it to the list */
   5.351        if (!pi->more_frags && !pi->extra_info)
   5.352        {
   5.353 +        pi->curr_pb = pi->first_pb;
   5.354 +        pi->curr_buffer = pi->first_buffer;
   5.355          packet_count += XenNet_MakePackets(xi, &rx_packet_list);
   5.356        }
   5.357      }
   5.358 @@ -837,6 +749,7 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
   5.359    }
   5.360  
   5.361    //KdPrint((__DRIVER_NAME "     packet_count = %d, page_count = %d, avg_page_count = %d, event = %d\n", packet_count, page_count, xi->avg_page_count / 128, event));
   5.362 +  xi->stat_rx_ok += packet_count;
   5.363  
   5.364    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   5.365  
   5.366 @@ -1048,7 +961,8 @@ XenNet_RxInit(xennet_info_t *xi)
   5.367      return FALSE;
   5.368    }
   5.369  
   5.370 -  NdisInitializeNPagedLookasideList(&xi->rx_lookaside_list, NULL, NULL, 0, LOOKASIDE_LIST_ALLOC_SIZE, XENNET_POOL_TAG, 0);
   5.371 +  NdisInitializeNPagedLookasideList(&xi->rx_lookaside_list, NULL, NULL, 0,
   5.372 +    MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH + sizeof(shared_buffer_t), XENNET_POOL_TAG, 0);
   5.373    
   5.374    XenNet_FillRing(xi);
   5.375  
     6.1 --- a/xennet/xennet_tx.c	Mon Feb 01 21:43:12 2010 +1100
     6.2 +++ b/xennet/xennet_tx.c	Sun Feb 07 09:14:18 2010 +1100
     6.3 @@ -276,7 +276,7 @@ XenNet_HWSendPacket(struct xennet_info *
     6.4      ASSERT(tx0->gref != INVALID_GRANT_REF);
     6.5      xi->tx_shadows[tx0->id].gref = tx0->gref;
     6.6      tx0->offset = (USHORT)sg->Elements[sg_element].Address.LowPart & (PAGE_SIZE - 1);
     6.7 -    tx0->size = (USHORT)min(sg->Elements[sg_element].Length, PAGE_SIZE - tx0->offset);
     6.8 +    tx0->size = (USHORT)min(sg->Elements[sg_element].Length, (ULONG)(PAGE_SIZE - tx0->offset));
     6.9      if (tx0->offset + tx0->size > PAGE_SIZE)
    6.10      {
    6.11        KdPrint((__DRIVER_NAME "     offset + size = %d\n", tx0->offset + tx0->size));
    6.12 @@ -328,7 +328,7 @@ XenNet_HWSendPacket(struct xennet_info *
    6.13        xi->tx_shadows[txN->id].gref = txN->gref;
    6.14        txN->offset = (USHORT)(sg->Elements[sg_element].Address.LowPart + sg_offset) & (PAGE_SIZE - 1);
    6.15        ASSERT(sg->Elements[sg_element].Length > sg_offset);
    6.16 -      txN->size = (USHORT)min(sg->Elements[sg_element].Length - sg_offset, PAGE_SIZE - txN->offset);
    6.17 +      txN->size = (USHORT)min(sg->Elements[sg_element].Length - sg_offset, (ULONG)(PAGE_SIZE - txN->offset));
    6.18        if (txN->offset + txN->size > PAGE_SIZE)
    6.19        {
    6.20          KdPrint((__DRIVER_NAME "     offset (%d) + size (%d) = %d\n", txN->offset, txN->size, txN->offset + txN->size));
    6.21 @@ -417,6 +417,7 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
    6.22    RING_IDX cons, prod;
    6.23    PNDIS_PACKET head = NULL, tail = NULL;
    6.24    PNDIS_PACKET packet;
    6.25 +  ULONG tx_packets = 0;
    6.26  
    6.27    UNREFERENCED_PARAMETER(dpc);
    6.28    UNREFERENCED_PARAMETER(arg1);
    6.29 @@ -496,16 +497,22 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
    6.30  
    6.31    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
    6.32  
    6.33 +  /* must be done without holding any locks */
    6.34    while (head)
    6.35    {
    6.36      packet = (PNDIS_PACKET)head;
    6.37      head = *(PNDIS_PACKET *)&packet->MiniportReservedEx[0];
    6.38      NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_SUCCESS);
    6.39 -    xi->tx_outstanding--;
    6.40 -    if (!xi->tx_outstanding && xi->tx_shutting_down)
    6.41 -      KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
    6.42 +    tx_packets++;
    6.43    }
    6.44  
    6.45 +  /* must be done after we have truly given back all packets */
    6.46 +  KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
    6.47 +  xi->tx_outstanding -= tx_packets;
    6.48 +  if (!xi->tx_outstanding && xi->tx_shutting_down)
    6.49 +    KeSetEvent(&xi->tx_idle_event, IO_NO_INCREMENT, FALSE);
    6.50 +  KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
    6.51 +
    6.52    if (xi->device_state->suspend_resume_state_pdo == SR_STATE_SUSPENDING
    6.53      && xi->device_state->suspend_resume_state_fdo != SR_STATE_SUSPENDING
    6.54      && xi->tx_id_free == NET_TX_RING_SIZE)
    6.55 @@ -572,6 +579,7 @@ XenNet_CancelSendPackets(
    6.56    PLIST_ENTRY entry;
    6.57    PNDIS_PACKET packet;
    6.58    PNDIS_PACKET head = NULL, tail = NULL;
    6.59 +  BOOLEAN result;
    6.60  
    6.61    FUNCTION_ENTER();
    6.62  
    6.63 @@ -584,7 +592,9 @@ XenNet_CancelSendPackets(
    6.64      entry = entry->Flink;
    6.65      if (NDIS_GET_PACKET_CANCEL_ID(packet) == CancelId)
    6.66      {
    6.67 -      RemoveEntryList((PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)]);
    6.68 +      KdPrint((__DRIVER_NAME "     Found packet to cancel %p\n", packet));
    6.69 +      result = RemoveEntryList((PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)]);
    6.70 +      ASSERT(result);
    6.71        *(PNDIS_PACKET *)&packet->MiniportReservedEx[0] = NULL;
    6.72        if (head)
    6.73          *(PNDIS_PACKET *)&tail->MiniportReservedEx[0] = packet;
    6.74 @@ -600,6 +610,7 @@ XenNet_CancelSendPackets(
    6.75    {
    6.76      packet = (PNDIS_PACKET)head;
    6.77      head = *(PNDIS_PACKET *)&packet->MiniportReservedEx[0];
    6.78 +    KdPrint((__DRIVER_NAME "     NdisMSendComplete(%p)\n", packet));
    6.79      NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_REQUEST_ABORTED);
    6.80    }
    6.81