win-pvdrivers

changeset 411:ee82244eed7c

Many many updates to improve stability etc and performance.
author James Harper <james.harper@bendigoit.com.au>
date Tue Aug 12 15:08:19 2008 +1000 (2008-08-12)
parents a25065ea9cca
children 54cd7acad4f9
files common.inc common/include/xen_public.h installer.nsi xenhide/xenhide.c xennet/xennet.c xennet/xennet.h xennet/xennet_common.c xennet/xennet_oid.c xennet/xennet_rx.c xennet/xennet_tx.c xenpci/evtchn.c xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c xenstub/xenstub.c
line diff
     1.1 --- a/common.inc	Thu Jul 31 15:22:30 2008 +1000
     1.2 +++ b/common.inc	Tue Aug 12 15:08:19 2008 +1000
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.9.10.10
     1.5 +VERSION=0.9.10.11
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  MSC_WARNING_LEVEL=/W4
     1.8  INCLUDES = ..\common\include;..\common\include\public
     2.1 --- a/common/include/xen_public.h	Thu Jul 31 15:22:30 2008 +1000
     2.2 +++ b/common/include/xen_public.h	Tue Aug 12 15:08:19 2008 +1000
     2.3 @@ -115,7 +115,6 @@ typedef struct {
     2.4    PXEN_GNTTBL_ENDACCESS GntTbl_EndAccess;
     2.5    PXEN_XENPCI_XEN_CONFIG_DEVICE XenPci_XenConfigDevice;
     2.6    PXEN_XENPCI_XEN_SHUTDOWN_DEVICE XenPci_XenShutdownDevice;
     2.7 -
     2.8  } XENPCI_VECTORS, *PXENPCI_VECTORS;
     2.9  
    2.10  #define RESUME_STATE_RUNNING            0
     3.1 --- a/installer.nsi	Thu Jul 31 15:22:30 2008 +1000
     3.2 +++ b/installer.nsi	Tue Aug 12 15:08:19 2008 +1000
     3.3 @@ -3,7 +3,7 @@
     3.4  
     3.5  !define AppName "Xen PV Drivers"
     3.6  !define StartMenu "$SMPROGRAMS\${AppName}"
     3.7 -!define Version "0.9.11-pre9"
     3.8 +!define Version "0.9.11-pre10"
     3.9  #!define Version "$%VERSION%"
    3.10  Name "${AppName}"
    3.11  InstallDir "$PROGRAMFILES\${AppName}"
     4.1 --- a/xenhide/xenhide.c	Thu Jul 31 15:22:30 2008 +1000
     4.2 +++ b/xenhide/xenhide.c	Tue Aug 12 15:08:19 2008 +1000
     4.3 @@ -349,8 +349,13 @@ XenHide_Pass(PDEVICE_OBJECT DeviceObject
     4.4    PXENHIDE_DEVICE_DATA xhdd = (PXENHIDE_DEVICE_DATA)DeviceObject->DeviceExtension;
     4.5    NTSTATUS status;
     4.6      
     4.7 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     4.8 +
     4.9    IoSkipCurrentIrpStackLocation(Irp);
    4.10    status = IoCallDriver(xhdd->lower_do, Irp);
    4.11 +
    4.12 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
    4.13 +
    4.14    return status;
    4.15  }
    4.16  
    4.17 @@ -413,7 +418,7 @@ XenHide_Pnp(PDEVICE_OBJECT device_object
    4.18    ULONG i, j;
    4.19    KIRQL old_irql;
    4.20  
    4.21 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    4.22 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (device_object = %p)\n", device_object));
    4.23  
    4.24    stack = IoGetCurrentIrpStackLocation(irp);
    4.25  
    4.26 @@ -437,7 +442,7 @@ XenHide_Pnp(PDEVICE_OBJECT device_object
    4.27      if (xhdd->hide_type == XENHIDE_TYPE_PCI_BUS && stack->Parameters.QueryDeviceRelations.Type == BusRelations)
    4.28      {
    4.29        //KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_DEVICE_RELATIONS - BusRelations\n"));
    4.30 -      IoMarkIrpPending(irp);
    4.31 +      //IoMarkIrpPending(irp);
    4.32        status = XenHide_SendAndWaitForIrp(device_object, irp);
    4.33        relations = (PDEVICE_RELATIONS)irp->IoStatus.Information;
    4.34        for (i = 0, j = 0; i < relations->Count; i++)
    4.35 @@ -465,11 +470,22 @@ XenHide_Pnp(PDEVICE_OBJECT device_object
    4.36      }
    4.37      else
    4.38      {
    4.39 +      //KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_DEVICE_RELATIONS - %d\n", stack->Parameters.QueryDeviceRelations.Type));
    4.40        IoSkipCurrentIrpStackLocation(irp);
    4.41        status = IoCallDriver(xhdd->lower_do, irp);
    4.42      }
    4.43      break;
    4.44 +  case IRP_MN_REMOVE_DEVICE:
    4.45 +    //KdPrint((__DRIVER_NAME "     IRP_MN_REMOVE_DEVICE\n"));
    4.46 +    IoSkipCurrentIrpStackLocation(irp);
    4.47 +    status = IoCallDriver(xhdd->lower_do, irp);
    4.48 +    IoDetachDevice(xhdd->lower_do);
    4.49 +    IoDeleteDevice(device_object);
    4.50 +    //irp->IoStatus.Status = status;
    4.51 +    //IoCompleteRequest(irp, IO_NO_INCREMENT);
    4.52 +    break;
    4.53    default:
    4.54 +    //KdPrint((__DRIVER_NAME "     Unhandled Minor = %d\n", stack->MinorFunction));
    4.55      IoSkipCurrentIrpStackLocation(irp);
    4.56      status = IoCallDriver(xhdd->lower_do, irp);
    4.57      break;
     5.1 --- a/xennet/xennet.c	Thu Jul 31 15:22:30 2008 +1000
     5.2 +++ b/xennet/xennet.c	Tue Aug 12 15:08:19 2008 +1000
     5.3 @@ -130,13 +130,13 @@ XenNet_InterruptIsr(
     5.4    //FUNCTION_ENTER();
     5.5  
     5.6    *QueueMiniportHandleInterrupt = (BOOLEAN)!!xi->connected;
     5.7 -  *InterruptRecognized = FALSE; /* we can't be sure here... */
     5.8 +  *InterruptRecognized = TRUE;
     5.9  
    5.10    //FUNCTION_EXIT();
    5.11  }
    5.12  
    5.13  static DDKAPI VOID
    5.14 -XenNet_InterruptDpc(NDIS_HANDLE  MiniportAdapterContext)
    5.15 +XenNet_InterruptDpc(NDIS_HANDLE MiniportAdapterContext)
    5.16  {
    5.17    struct xennet_info *xi = MiniportAdapterContext;
    5.18  
    5.19 @@ -399,6 +399,7 @@ XenNet_Init(
    5.20    KeInitializeSpinLock(&xi->rx_lock);
    5.21  
    5.22    InitializeListHead(&xi->tx_waiting_pkt_list);
    5.23 +  InitializeListHead(&xi->tx_sent_pkt_list);
    5.24  
    5.25    NdisAllocatePacketPool(&status, &xi->packet_pool, XN_RX_QUEUE_LEN * 8,
    5.26      PROTOCOL_RESERVED_SIZE_IN_PACKET);
    5.27 @@ -560,7 +561,7 @@ XenNet_Init(
    5.28    KeMemoryBarrier(); // packets could be received anytime after we set Frontent to Connected
    5.29  
    5.30    status = NdisMRegisterInterrupt(&xi->interrupt, MiniportAdapterHandle, irq_vector, irq_level,
    5.31 -    TRUE, TRUE, NdisInterruptLatched);
    5.32 +    TRUE, FALSE, NdisInterruptLatched);
    5.33    if (!NT_SUCCESS(status))
    5.34    {
    5.35      KdPrint(("NdisMRegisterInterrupt failed with 0x%x\n", status));
     6.1 --- a/xennet/xennet.h	Thu Jul 31 15:22:30 2008 +1000
     6.2 +++ b/xennet/xennet.h	Tue Aug 12 15:08:19 2008 +1000
     6.3 @@ -189,11 +189,12 @@ struct xennet_info
     6.4    /* tx related - protected by tx_lock */
     6.5    KSPIN_LOCK tx_lock;
     6.6    LIST_ENTRY tx_waiting_pkt_list;
     6.7 +  LIST_ENTRY tx_sent_pkt_list;
     6.8    struct netif_tx_front_ring tx;
     6.9    ULONG tx_id_free;
    6.10    ULONG tx_no_id_used;
    6.11    USHORT tx_id_list[NET_TX_RING_SIZE];
    6.12 -  PNDIS_PACKET tx_pkts[NET_TX_RING_SIZE];
    6.13 +  //PNDIS_PACKET tx_pkts[NET_TX_RING_SIZE];
    6.14    PNDIS_BUFFER tx_mdls[NET_TX_RING_SIZE];
    6.15    freelist_t tx_freelist;
    6.16  
     7.1 --- a/xennet/xennet_common.c	Thu Jul 31 15:22:30 2008 +1000
     7.2 +++ b/xennet/xennet_common.c	Tue Aug 12 15:08:19 2008 +1000
     7.3 @@ -55,7 +55,7 @@ XenNet_ParsePacketHeader(
     7.4      pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
     7.5      if (header_length < (ULONG)(pi->ip4_header_length + 20))
     7.6      {
     7.7 -      KdPrint((__DRIVER_NAME "     first buffer is only %d bytes long, must be >= %d\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)));
     7.8 +      KdPrint((__DRIVER_NAME "     first buffer is only %d bytes long, must be >= %d (1)\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)));
     7.9        // we need to do something conclusive here...
    7.10        return PARSE_TOO_SMALL;
    7.11      }
    7.12 @@ -78,7 +78,7 @@ XenNet_ParsePacketHeader(
    7.13  
    7.14    if (header_length < (ULONG)(pi->ip4_header_length + pi->tcp_header_length))
    7.15    {
    7.16 -    KdPrint((__DRIVER_NAME "     first buffer is only %d bytes long, must be >= %d\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)));
    7.17 +    KdPrint((__DRIVER_NAME "     first buffer is only %d bytes long, must be >= %d (2)\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)));
    7.18      return PARSE_TOO_SMALL;
    7.19    }
    7.20  
    7.21 @@ -172,6 +172,8 @@ XenFreelist_Timer(
    7.22      for (i = 0; i < (int)min(16, fl->page_free_lowest - fl->page_free_target); i++)
    7.23      {
    7.24        mdl = XenFreelist_GetPage(fl);
    7.25 +      if (!mdl)
    7.26 +        break;
    7.27        fl->xi->vectors.GntTbl_EndAccess(fl->xi->vectors.context,
    7.28          *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)), 0);
    7.29        FreePages(mdl);
    7.30 @@ -206,6 +208,8 @@ XenFreelist_GetPage(freelist_t *fl)
    7.31    if (fl->page_free == 0)
    7.32    {
    7.33      mdl = AllocatePagesExtra(1, sizeof(grant_ref_t));
    7.34 +    if (!mdl)
    7.35 +      return NULL;
    7.36      pfn = *MmGetMdlPfnArray(mdl);
    7.37      *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = fl->xi->vectors.GntTbl_GrantAccess(
    7.38        fl->xi->vectors.context, 0,
     8.1 --- a/xennet/xennet_oid.c	Thu Jul 31 15:22:30 2008 +1000
     8.2 +++ b/xennet/xennet_oid.c	Tue Aug 12 15:08:19 2008 +1000
     8.3 @@ -119,7 +119,7 @@ XenNet_QueryInformation(
     8.4        temp_data = NdisMedium802_3;
     8.5        break;
     8.6      case OID_GEN_MAXIMUM_LOOKAHEAD:
     8.7 -      temp_data = XN_DATA_SIZE;
     8.8 +      temp_data = PAGE_SIZE; //XN_DATA_SIZE;
     8.9        break;
    8.10      case OID_GEN_MAXIMUM_FRAME_SIZE:
    8.11        // According to the specs, OID_GEN_MAXIMUM_FRAME_SIZE does not include the header, so
    8.12 @@ -132,7 +132,6 @@ XenNet_QueryInformation(
    8.13      case OID_GEN_TRANSMIT_BUFFER_SPACE:
    8.14        /* pkts times sizeof ring, maybe? */
    8.15        /* multiply this by some small number as we can queue additional packets */
    8.16 -//      temp_data = XN_MAX_PKT_SIZE * NET_TX_RING_SIZE;
    8.17        temp_data = PAGE_SIZE * NET_TX_RING_SIZE * 4;
    8.18        break;
    8.19      case OID_GEN_RECEIVE_BUFFER_SPACE:
     9.1 --- a/xennet/xennet_rx.c	Thu Jul 31 15:22:30 2008 +1000
     9.2 +++ b/xennet/xennet_rx.c	Tue Aug 12 15:08:19 2008 +1000
     9.3 @@ -26,26 +26,20 @@ XenNet_RxBufferAlloc(struct xennet_info 
     9.4  {
     9.5    unsigned short id;
     9.6    PMDL mdl;
     9.7 -  int i, batch_target, notify;
     9.8 +  ULONG i, notify;
     9.9 +  ULONG batch_target;
    9.10    RING_IDX req_prod = xi->rx.req_prod_pvt;
    9.11    netif_rx_request_t *req;
    9.12 -#if DBG
    9.13 -  int cycles = 0;
    9.14 -#endif
    9.15 -#if defined(XEN_PROFILE)
    9.16 -  LARGE_INTEGER tsc, dummy;
    9.17 -#endif
    9.18  
    9.19  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.20 -#if defined(XEN_PROFILE)
    9.21 -  tsc = KeQueryPerformanceCounter(&dummy);
    9.22 -#endif
    9.23  
    9.24    batch_target = xi->rx_target - (req_prod - xi->rx.rsp_cons);
    9.25  
    9.26 +  if (batch_target < (xi->rx_target >> 2))
    9.27 +    return NDIS_STATUS_SUCCESS; /* only refill if we are less than 3/4 full already */
    9.28 +
    9.29    for (i = 0; i < batch_target; i++)
    9.30    {
    9.31 -    ASSERT(cycles++ < 256);
    9.32      if (xi->rx_id_free == 0)
    9.33      {
    9.34        KdPrint((__DRIVER_NAME "     Added %d out of %d buffers to rx ring (ran out of id's)\n", i, batch_target));
    9.35 @@ -61,7 +55,6 @@ XenNet_RxBufferAlloc(struct xennet_info 
    9.36  
    9.37      /* Give to netback */
    9.38      id = (USHORT)((req_prod + i) & (NET_RX_RING_SIZE - 1));
    9.39 -//    KdPrint((__DRIVER_NAME "     id = %d\n", id));
    9.40      ASSERT(xi->rx_mdls[id] == NULL);
    9.41      xi->rx_mdls[id] = mdl;
    9.42      req = RING_GET_REQUEST(&xi->rx, req_prod + i);
    9.43 @@ -76,15 +69,105 @@ XenNet_RxBufferAlloc(struct xennet_info 
    9.44      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
    9.45    }
    9.46  
    9.47 -
    9.48  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.49  
    9.50 -#if defined(XEN_PROFILE)
    9.51 -  ProfTime_RxBufferAlloc.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
    9.52 -  ProfCount_RxBufferAlloc++;
    9.53 -#endif
    9.54 +  return NDIS_STATUS_SUCCESS;
    9.55 +}
    9.56  
    9.57 -  return NDIS_STATUS_SUCCESS;
    9.58 +static PNDIS_PACKET
    9.59 +get_packet_from_freelist(struct xennet_info *xi)
    9.60 +{
    9.61 +  NDIS_STATUS status;
    9.62 +  PNDIS_PACKET packet;
    9.63 +
    9.64 +  if (!xi->rx_packet_free)
    9.65 +  {
    9.66 +    NdisAllocatePacket(&status, &packet, xi->packet_pool);
    9.67 +    ASSERT(status == NDIS_STATUS_SUCCESS);
    9.68 +    NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
    9.69 +  }
    9.70 +  else
    9.71 +  {
    9.72 +    xi->rx_packet_free--;
    9.73 +    packet = xi->rx_packet_list[xi->rx_packet_free];
    9.74 +  }
    9.75 +  return packet;
    9.76 +}
    9.77 +
    9.78 +static VOID
    9.79 +put_packet_on_freelist(struct xennet_info *xi, PNDIS_PACKET packet)
    9.80 +{
    9.81 +  NdisReinitializePacket(packet);
    9.82 +  xi->rx_packet_list[xi->rx_packet_free] = packet;
    9.83 +  xi->rx_packet_free++;
    9.84 +}
    9.85 +
    9.86 +static VOID
    9.87 +packet_freelist_dispose(struct xennet_info *xi)
    9.88 +{
    9.89 +  while(xi->rx_packet_free != 0)
    9.90 +  {
    9.91 +    xi->rx_packet_free--;
    9.92 +    NdisFreePacket(xi->rx_packet_list[xi->rx_packet_free]);
    9.93 +  }
    9.94 +}
    9.95 +
    9.96 +static PNDIS_PACKET
    9.97 +XenNet_MakePacket(struct xennet_info *xi)
    9.98 +{
    9.99 +  PNDIS_PACKET packet;
   9.100 +  PUCHAR in_buffer;
   9.101 +  PNDIS_BUFFER out_mdl;
   9.102 +  PUCHAR out_buffer;
   9.103 +  USHORT out_offset;
   9.104 +  USHORT out_remaining;
   9.105 +  USHORT length;
   9.106 +  USHORT new_ip4_length;
   9.107 +  //NDIS_STATUS status;
   9.108 +  USHORT i;
   9.109 +
   9.110 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   9.111 +
   9.112 +  if (!xi->rxpi.split_required)
   9.113 +  {
   9.114 +    packet = get_packet_from_freelist(xi);
   9.115 +    xi->rx_outstanding++;
   9.116 +    for (i = 0; i < xi->rxpi.mdl_count; i++)
   9.117 +      NdisChainBufferAtBack(packet, xi->rxpi.mdls[i]);
   9.118 +    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   9.119 +  }
   9.120 +  else
   9.121 +  {
   9.122 +    out_mdl = XenFreelist_GetPage(&xi->rx_freelist);
   9.123 +    if (!out_mdl)
   9.124 +      return NULL;
   9.125 +    packet = get_packet_from_freelist(xi);
   9.126 +    xi->rx_outstanding++;
   9.127 +    out_buffer = MmGetMdlVirtualAddress(out_mdl);
   9.128 +    out_offset = XN_HDR_SIZE + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length;
   9.129 +    out_remaining = min(xi->rxpi.mss, xi->rxpi.tcp_remaining);
   9.130 +    NdisAdjustBufferLength(out_mdl, out_offset + out_remaining);
   9.131 +    memcpy(out_buffer, xi->rxpi.header, out_offset);
   9.132 +    new_ip4_length = out_remaining + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length;
   9.133 +    SET_NET_USHORT(out_buffer[XN_HDR_SIZE + 2], new_ip4_length);
   9.134 +    SET_NET_ULONG(out_buffer[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 4], xi->rxpi.tcp_seq);
   9.135 +    xi->rxpi.tcp_seq += out_remaining;
   9.136 +    xi->rxpi.tcp_remaining = xi->rxpi.tcp_remaining - out_remaining;
   9.137 +    do 
   9.138 +    {
   9.139 +      ASSERT(xi->rxpi.curr_mdl < xi->rxpi.mdl_count);
   9.140 +      in_buffer = XenNet_GetData(&xi->rxpi, out_remaining, &length);
   9.141 +      memcpy(&out_buffer[out_offset], in_buffer, length);
   9.142 +      out_remaining = out_remaining - length;
   9.143 +      out_offset = out_offset + length;
   9.144 +    } while (out_remaining != 0); // && in_buffer != NULL);
   9.145 +    NdisChainBufferAtBack(packet, out_mdl);
   9.146 +    XenNet_SumIpHeader(out_buffer, xi->rxpi.ip4_header_length);
   9.147 +    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   9.148 +  }
   9.149 +
   9.150 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (%p)\n", packet));
   9.151 +  return packet;
   9.152  }
   9.153  
   9.154  /*
   9.155 @@ -109,13 +192,9 @@ XenNet_SumPacketData(
   9.156    PUSHORT csum_ptr;
   9.157    USHORT remaining;
   9.158    USHORT ip4_length;
   9.159 -
   9.160 +  
   9.161  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   9.162  
   9.163 -  #if defined(XEN_PROFILE)
   9.164 -  ProfCount_RxPacketsCsumOffload++;
   9.165 -  #endif
   9.166 -
   9.167    NdisGetFirstBufferFromPacketSafe(packet, &mdl, &buffer, &buffer_length, &total_length, NormalPagePriority);
   9.168    ASSERT(mdl);
   9.169  
   9.170 @@ -190,114 +269,20 @@ XenNet_SumPacketData(
   9.171      csum = (csum & 0xFFFF) + (csum >> 16);
   9.172    *csum_ptr = (USHORT)~GET_NET_USHORT(csum);
   9.173  
   9.174 -//  KdPrint((__DRIVER_NAME "     csum = %04x\n", *csum_ptr));
   9.175 -
   9.176  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   9.177  }
   9.178  
   9.179 -static PNDIS_PACKET
   9.180 -get_packet_from_freelist(struct xennet_info *xi)
   9.181 -{
   9.182 -  NDIS_STATUS status;
   9.183 -  PNDIS_PACKET packet;
   9.184 -
   9.185 -  if (!xi->rx_packet_free)
   9.186 -  {
   9.187 -    NdisAllocatePacket(&status, &packet, xi->packet_pool);
   9.188 -    ASSERT(status == NDIS_STATUS_SUCCESS);
   9.189 -    NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
   9.190 -  }
   9.191 -  else
   9.192 -  {
   9.193 -    xi->rx_packet_free--;
   9.194 -    packet = xi->rx_packet_list[xi->rx_packet_free];
   9.195 -  }
   9.196 -  return packet;
   9.197 -}
   9.198 -
   9.199 -static VOID
   9.200 -put_packet_on_freelist(struct xennet_info *xi, PNDIS_PACKET packet)
   9.201 -{
   9.202 -  NdisReinitializePacket(packet);
   9.203 -  xi->rx_packet_list[xi->rx_packet_free] = packet;
   9.204 -  xi->rx_packet_free++;
   9.205 -}
   9.206 -
   9.207 -static VOID
   9.208 -packet_freelist_dispose(struct xennet_info *xi)
   9.209 -{
   9.210 -  while(xi->rx_packet_free != 0)
   9.211 -  {
   9.212 -    xi->rx_packet_free--;
   9.213 -    NdisFreePacket(xi->rx_packet_list[xi->rx_packet_free]);
   9.214 -  }
   9.215 -}
   9.216 -
   9.217 -static PNDIS_PACKET
   9.218 -XenNet_MakePacket(
   9.219 -  struct xennet_info *xi
   9.220 -)
   9.221 -{
   9.222 -  PNDIS_PACKET packet;
   9.223 -  PUCHAR in_buffer;
   9.224 -  PNDIS_BUFFER out_mdl;
   9.225 -  PUCHAR out_buffer;
   9.226 -  USHORT out_offset;
   9.227 -  USHORT out_remaining;
   9.228 -  USHORT length;
   9.229 -  USHORT new_ip4_length;
   9.230 -  //NDIS_STATUS status;
   9.231 -  USHORT i;
   9.232 -
   9.233 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   9.234 -
   9.235 -  packet = get_packet_from_freelist(xi);
   9.236 -  xi->rx_outstanding++;
   9.237 -
   9.238 -  if (!xi->rxpi.split_required)
   9.239 -  {
   9.240 -    for (i = 0; i < xi->rxpi.mdl_count; i++)
   9.241 -      NdisChainBufferAtBack(packet, xi->rxpi.mdls[i]);
   9.242 -    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   9.243 -  }
   9.244 -  else
   9.245 -  {
   9.246 -    out_mdl = XenFreelist_GetPage(&xi->rx_freelist);
   9.247 -    out_buffer = MmGetMdlVirtualAddress(out_mdl);
   9.248 -    out_offset = XN_HDR_SIZE + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length;
   9.249 -    out_remaining = min(xi->rxpi.mss, xi->rxpi.tcp_remaining);
   9.250 -    NdisAdjustBufferLength(out_mdl, out_offset + out_remaining);
   9.251 -    memcpy(out_buffer, xi->rxpi.header, out_offset);
   9.252 -    new_ip4_length = out_remaining + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length;
   9.253 -    SET_NET_USHORT(out_buffer[XN_HDR_SIZE + 2], new_ip4_length);
   9.254 -    SET_NET_ULONG(out_buffer[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 4], xi->rxpi.tcp_seq);
   9.255 -    xi->rxpi.tcp_seq += out_remaining;
   9.256 -    xi->rxpi.tcp_remaining = xi->rxpi.tcp_remaining - out_remaining;
   9.257 -    do 
   9.258 -    {
   9.259 -      ASSERT(xi->rxpi.curr_mdl < xi->rxpi.mdl_count);
   9.260 -      in_buffer = XenNet_GetData(&xi->rxpi, out_remaining, &length);
   9.261 -      memcpy(&out_buffer[out_offset], in_buffer, length);
   9.262 -      out_remaining = out_remaining - length;
   9.263 -      out_offset = out_offset + length;
   9.264 -    } while (out_remaining != 0); // && in_buffer != NULL);
   9.265 -    NdisChainBufferAtBack(packet, out_mdl);
   9.266 -    XenNet_SumIpHeader(out_buffer, xi->rxpi.ip4_header_length);
   9.267 -    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   9.268 -  }
   9.269 -
   9.270 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (%p)\n", packet));
   9.271 -  return packet;
   9.272 -}
   9.273 -
   9.274 -static VOID
   9.275 +static ULONG
   9.276  XenNet_MakePackets(
   9.277    struct xennet_info *xi,
   9.278 -  PNDIS_PACKET *packets,
   9.279 -  PULONG packet_count_p
   9.280 +  PLIST_ENTRY rx_packet_list
   9.281  )
   9.282  {
   9.283    USHORT i;
   9.284 +  ULONG packet_count = 0;
   9.285 +  PNDIS_PACKET packet;
   9.286 +  PLIST_ENTRY entry;
   9.287 +  UCHAR psh;
   9.288  
   9.289  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "(packets = %p, packet_count = %d)\n", packets, *packet_count_p));
   9.290  
   9.291 @@ -309,44 +294,65 @@ XenNet_MakePackets(
   9.292        break;
   9.293      // fallthrough
   9.294    case 17:  // UDP
   9.295 -    ASSERT(*packet_count_p < NET_RX_RING_SIZE);
   9.296 -    packets[*packet_count_p] = XenNet_MakePacket(xi);
   9.297 +    packet = XenNet_MakePacket(xi);
   9.298      if (xi->rxpi.csum_calc_required)
   9.299 -      XenNet_SumPacketData(&xi->rxpi, packets[*packet_count_p]);
   9.300 -    (*packet_count_p)++;
   9.301 -    return;
   9.302 +      XenNet_SumPacketData(&xi->rxpi, packet);
   9.303 +    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   9.304 +    InsertTailList(rx_packet_list, entry);
   9.305 +    RtlZeroMemory(&xi->rxpi, sizeof(xi->rxpi));
   9.306 +    return 1;
   9.307    default:
   9.308 -    ASSERT(*packet_count_p < NET_RX_RING_SIZE);
   9.309 -    packets[*packet_count_p] = XenNet_MakePacket(xi);
   9.310 -    (*packet_count_p)++;
   9.311 -    return;
   9.312 +    packet = XenNet_MakePacket(xi);
   9.313 +    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   9.314 +    InsertTailList(rx_packet_list, entry);
   9.315 +    RtlZeroMemory(&xi->rxpi, sizeof(xi->rxpi));
   9.316 +    return 1;
   9.317    }
   9.318 -//  KdPrint((__DRIVER_NAME "     splitting packet\n"));
   9.319 +
   9.320    xi->rxpi.tcp_remaining = xi->rxpi.tcp_length;
   9.321    if (MmGetMdlByteCount(xi->rxpi.mdls[0]) > (ULONG)(XN_HDR_SIZE + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length))
   9.322      xi->rxpi.curr_mdl_offset = XN_HDR_SIZE + xi->rxpi.ip4_header_length + xi->rxpi.tcp_header_length;
   9.323    else
   9.324      xi->rxpi.curr_mdl = 1;
   9.325  
   9.326 +  // we can make this assumption as we are only ever doing this for tcp4
   9.327 +  psh = xi->rxpi.header[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 14] & 16;
   9.328    while (xi->rxpi.tcp_remaining)
   9.329    {
   9.330 -    ASSERT(*packet_count_p < NET_RX_RING_SIZE);
   9.331 -    packets[*packet_count_p] = XenNet_MakePacket(xi);
   9.332 -    XenNet_SumPacketData(&xi->rxpi, packets[*packet_count_p]);
   9.333 -    (*packet_count_p)++;
   9.334 +    PUCHAR buffer;
   9.335 +    PMDL mdl;
   9.336 +    UINT total_length;
   9.337 +    UINT buffer_length;
   9.338 +    packet = XenNet_MakePacket(xi);
   9.339 +    if (!packet)
   9.340 +      break; /* we are out of memory - just drop the packets */
   9.341 +    if (psh)
   9.342 +    {
   9.343 +      NdisGetFirstBufferFromPacketSafe(packet, &mdl, &buffer, &buffer_length, &total_length, NormalPagePriority);
   9.344 +      if (xi->rxpi.tcp_remaining)
   9.345 +      {
   9.346 +        buffer[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 14] &= ~16;
   9.347 +      }
   9.348 +      else
   9.349 +        buffer[XN_HDR_SIZE + xi->rxpi.ip4_header_length + 14] |= 16;
   9.350 +    }
   9.351 +    XenNet_SumPacketData(&xi->rxpi, packet);
   9.352 +    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   9.353 +    InsertTailList(rx_packet_list, entry);
   9.354 +    packet_count++;
   9.355    }
   9.356  
   9.357    ASSERT(xi->rxpi.curr_mdl == xi->rxpi.mdl_count);
   9.358 -  // TODO: restore psh status to last packet
   9.359    for (i = 0; i < xi->rxpi.mdl_count; i++)
   9.360    {
   9.361      NdisAdjustBufferLength(xi->rxpi.mdls[i], PAGE_SIZE);
   9.362      XenFreelist_PutPage(&xi->rx_freelist, xi->rxpi.mdls[i]);
   9.363    }
   9.364 +  RtlZeroMemory(&xi->rxpi, sizeof(xi->rxpi));  
   9.365  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (split)\n"));
   9.366 +  return packet_count;
   9.367  }
   9.368  
   9.369 -#define MAXIMUM_PACKETS_PER_INTERRUPT 128
   9.370  #define MAXIMUM_PACKETS_PER_INDICATE 32
   9.371  
   9.372  // Called at DISPATCH_LEVEL
   9.373 @@ -354,14 +360,11 @@ NDIS_STATUS
   9.374  XenNet_RxBufferCheck(struct xennet_info *xi)
   9.375  {
   9.376    RING_IDX cons, prod;
   9.377 -  /* the highest number of packets we receive could be (65535 - header) / mss
   9.378 -     for a low mss this could be even higher than NET_RX_RING_SIZE...
   9.379 -     what can we do? */
   9.380 -  PNDIS_PACKET packets[NET_RX_RING_SIZE];
   9.381 +  LIST_ENTRY rx_packet_list;
   9.382 +  PLIST_ENTRY entry;
   9.383 +  PNDIS_PACKET packets[MAXIMUM_PACKETS_PER_INDICATE];
   9.384    ULONG packet_count = 0;
   9.385 -  ULONG total_packets = 0;
   9.386    PMDL mdl;
   9.387 -  int moretodo;
   9.388    struct netif_rx_response *rxrsp = NULL;
   9.389    struct netif_extra_info *ei;
   9.390    USHORT id;
   9.391 @@ -372,13 +375,14 @@ XenNet_RxBufferCheck(struct xennet_info 
   9.392  
   9.393    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
   9.394  
   9.395 +  InitializeListHead(&rx_packet_list);
   9.396    //KdPrint((__DRIVER_NAME " --- " __FUNCTION__ " xi->rx.sring->rsp_prod = %d, xi->rx.rsp_cons = %d\n", xi->rx.sring->rsp_prod, xi->rx.rsp_cons));
   9.397 -    
   9.398 +
   9.399    do {
   9.400      prod = xi->rx.sring->rsp_prod;
   9.401 -    KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
   9.402 +    KeMemoryBarrier(); /* Ensure we see responses up to 'prop'. */
   9.403  
   9.404 -    for (cons = xi->rx.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INDICATE; cons++)
   9.405 +    for (cons = xi->rx.rsp_cons; cons != prod; cons++)
   9.406      {
   9.407        id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
   9.408        ASSERT(xi->rx_mdls[id]);
   9.409 @@ -437,37 +441,37 @@ XenNet_RxBufferCheck(struct xennet_info 
   9.410        /* Packet done, add it to the list */
   9.411        if (!xi->rxpi.more_frags && !xi->rxpi.extra_info)
   9.412        {
   9.413 -        /* we should probably check here and make sure that we have enough
   9.414 -           space for these packets, and if we don't, defer MakePackets until
   9.415 -           we have Indicated the current packets... */
   9.416 -        XenNet_MakePackets(xi, packets, &packet_count);
   9.417 -        RtlZeroMemory(&xi->rxpi, sizeof(xi->rxpi));
   9.418 +        packet_count += XenNet_MakePackets(xi, &rx_packet_list);
   9.419        }
   9.420      }
   9.421      xi->rx.rsp_cons = cons;
   9.422 -
   9.423 -    XenNet_RxBufferAlloc(xi);
   9.424 -
   9.425 -    if (packet_count > 0)
   9.426 +    if (!RING_HAS_UNCONSUMED_RESPONSES(&xi->rx))
   9.427      {
   9.428 -      KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   9.429 -      NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
   9.430 -      KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
   9.431 -      total_packets += packet_count;
   9.432 -      packet_count = 0;
   9.433 +      xi->rx.sring->rsp_event = cons + 1; //new_ring_buffer_size + 1;
   9.434 +      KeMemoryBarrier();
   9.435      }
   9.436 +  } while (RING_HAS_UNCONSUMED_RESPONSES(&xi->rx));
   9.437  
   9.438 -    RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, moretodo);
   9.439 -  } while (moretodo && total_packets < MAXIMUM_PACKETS_PER_INTERRUPT);
   9.440 +  if (xi->rxpi.more_frags || xi->rxpi.extra_info)
   9.441 +    KdPrint((__DRIVER_NAME "     Partial receive (more_frags = %d, extra_info = %d, total_length = %d, mdl_count = %d)\n", xi->rxpi.more_frags, xi->rxpi.extra_info, xi->rxpi.total_length, xi->rxpi.mdl_count));
   9.442  
   9.443    /* Give netback more buffers */
   9.444    XenNet_RxBufferAlloc(xi);
   9.445  
   9.446 -  if (xi->rxpi.more_frags || xi->rxpi.extra_info)
   9.447 -    KdPrint(("Partial receive (more_frags = %d, extra_info = %d, total_length = %d, mdl_count = %d)\n", xi->rxpi.more_frags, xi->rxpi.extra_info, xi->rxpi.total_length, xi->rxpi.mdl_count));
   9.448 -
   9.449    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   9.450  
   9.451 +  entry = RemoveHeadList(&rx_packet_list);
   9.452 +  packet_count = 0;
   9.453 +  while (entry != &rx_packet_list)
   9.454 +  {
   9.455 +    packets[packet_count++] = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   9.456 +    entry = RemoveHeadList(&rx_packet_list);
   9.457 +    if (packet_count == MAXIMUM_PACKETS_PER_INDICATE || entry == &rx_packet_list)
   9.458 +    {
   9.459 +      NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
   9.460 +      packet_count = 0;
   9.461 +    }
   9.462 +  }
   9.463    return NDIS_STATUS_SUCCESS;
   9.464  }
   9.465  
   9.466 @@ -574,7 +578,6 @@ XenNet_RxInit(xennet_info_t *xi)
   9.467    }
   9.468  
   9.469    xi->rx_outstanding = 0;
   9.470 -
   9.471    XenFreelist_Init(xi, &xi->rx_freelist, &xi->rx_lock);
   9.472  
   9.473    XenNet_RxBufferAlloc(xi);
    10.1 --- a/xennet/xennet_tx.c	Thu Jul 31 15:22:30 2008 +1000
    10.2 +++ b/xennet/xennet_tx.c	Tue Aug 12 15:08:19 2008 +1000
    10.3 @@ -22,12 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fi
    10.4  
    10.5  #define FREELIST_ID_ERROR 0xFFFF
    10.6  
    10.7 -#ifdef XEN_PROFILE
    10.8 -#define PC_INC(var) var++
    10.9 -#else
   10.10 -#define PC_INC(var)
   10.11 -#endif
   10.12 -
   10.13  static ULONG
   10.14  free_requests(struct xennet_info *xi)
   10.15  {
   10.16 @@ -86,7 +80,7 @@ XenNet_PutOnTxRing(
   10.17  
   10.18    id = get_id_from_freelist(xi);
   10.19    ASSERT(id != FREELIST_ID_ERROR);
   10.20 -  ASSERT(xi->tx_pkts[id] == NULL);
   10.21 +  //ASSERT(xi->tx_pkts[id] == NULL);
   10.22    tx = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   10.23    tx->gref = get_grant_ref(mdl);
   10.24    xi->tx_mdls[id] = mdl;
   10.25 @@ -94,7 +88,6 @@ XenNet_PutOnTxRing(
   10.26    tx->offset = 0;
   10.27    tx->size = (USHORT)MmGetMdlByteCount(mdl);
   10.28    tx->flags = flags;
   10.29 -  PC_INC(ProfCount_TxPacketsTotal);
   10.30  
   10.31    return tx;
   10.32  }
   10.33 @@ -109,7 +102,7 @@ XenNet_HWSendPacket(struct xennet_info *
   10.34    struct netif_tx_request *tx = NULL;
   10.35    struct netif_extra_info *ei = NULL;
   10.36    PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   10.37 -  UINT total_packet_length;
   10.38 +  //UINT total_packet_length;
   10.39    ULONG mss;
   10.40    PMDL in_mdl;
   10.41    PUCHAR in_buffer = NULL;
   10.42 @@ -123,15 +116,12 @@ XenNet_HWSendPacket(struct xennet_info *
   10.43    int pages_required;
   10.44    int page_num;
   10.45    USHORT copied;
   10.46 +  UINT first_buffer_length; /* not used */
   10.47 +  UINT total_length;
   10.48    
   10.49 -#if defined(XEN_PROFILE)
   10.50 -  LARGE_INTEGER tsc, dummy;
   10.51 -
   10.52 -  tsc = KeQueryPerformanceCounter(&dummy);
   10.53 -#endif
   10.54 -
   10.55    RtlZeroMemory(&pi, sizeof(pi));
   10.56 -
   10.57 +  NdisGetFirstBufferFromPacketSafe(packet, &in_mdl, &pi.header, &first_buffer_length, &total_length, NormalPagePriority);
   10.58 +  
   10.59    csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   10.60      packet, TcpIpChecksumPacketInfo);
   10.61    mss = PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo));
   10.62 @@ -139,9 +129,7 @@ XenNet_HWSendPacket(struct xennet_info *
   10.63    if (mss)
   10.64      ndis_lso = TRUE;
   10.65  
   10.66 -  NdisQueryPacket(packet, NULL, NULL, &in_mdl, &total_packet_length);
   10.67 -
   10.68 -  pages_required = (total_packet_length + PAGE_SIZE - 1) / PAGE_SIZE;
   10.69 +  pages_required = (total_length + PAGE_SIZE - 1) / PAGE_SIZE;
   10.70  
   10.71    if (pages_required + !!ndis_lso > (int)free_requests(xi))
   10.72    {
   10.73 @@ -152,8 +140,16 @@ XenNet_HWSendPacket(struct xennet_info *
   10.74    for (page_num = 0, in_remaining = 0; page_num < pages_required; page_num++)
   10.75    {
   10.76      pi.mdls[page_num] = XenFreelist_GetPage(&xi->tx_freelist);
   10.77 +    if (!pi.mdls[page_num])
   10.78 +    {
   10.79 +      KdPrint((__DRIVER_NAME "     Out of buffers on send\n"));
   10.80 +      pages_required = page_num;
   10.81 +      for (page_num = 0; page_num < pages_required; page_num++)
   10.82 +        XenFreelist_PutPage(&xi->tx_freelist, pi.mdls[page_num]);
   10.83 +      return FALSE;
   10.84 +    }
   10.85      out_buffer = MmGetMdlVirtualAddress(pi.mdls[page_num]);
   10.86 -    out_remaining = (USHORT)min(PAGE_SIZE, total_packet_length - page_num * PAGE_SIZE);
   10.87 +    out_remaining = (USHORT)min(PAGE_SIZE, total_length - page_num * PAGE_SIZE);
   10.88      NdisAdjustBufferLength(pi.mdls[page_num], out_remaining);
   10.89      while (out_remaining > 0)
   10.90      {
   10.91 @@ -180,7 +176,6 @@ XenNet_HWSendPacket(struct xennet_info *
   10.92      || csum_info->Transmit.NdisPacketUdpChecksum)
   10.93    {
   10.94      flags |= NETTXF_csum_blank | NETTXF_data_validated;
   10.95 -    PC_INC(ProfCount_TxPacketsCsumOffload);
   10.96    }
   10.97  
   10.98    if (ndis_lso)
   10.99 @@ -202,7 +197,7 @@ XenNet_HWSendPacket(struct xennet_info *
  10.100  
  10.101    /* (A) */
  10.102    tx = XenNet_PutOnTxRing(xi, pi.mdls[0], flags);
  10.103 -  tx->size = (USHORT)total_packet_length;
  10.104 +  tx->size = (USHORT)total_length;
  10.105    xi->tx.req_prod_pvt++;
  10.106  
  10.107    /* (B) */
  10.108 @@ -229,7 +224,6 @@ XenNet_HWSendPacket(struct xennet_info *
  10.109    }
  10.110  
  10.111    /* only set the packet on the last buffer, clear more_data */
  10.112 -  xi->tx_pkts[tx->id] = packet;
  10.113    tx->flags &= ~NETTXF_more_data;
  10.114  
  10.115    if (ndis_lso)
  10.116 @@ -237,6 +231,8 @@ XenNet_HWSendPacket(struct xennet_info *
  10.117      NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo) = UlongToPtr(pi.tcp_length);
  10.118    }
  10.119  
  10.120 +  xi->stat_tx_ok++;
  10.121 +
  10.122    return TRUE;
  10.123  }
  10.124  
  10.125 @@ -254,10 +250,12 @@ XenNet_SendQueuedPackets(struct xennet_i
  10.126    /* if empty, the above returns head*, not NULL */
  10.127    while (entry != &xi->tx_waiting_pkt_list)
  10.128    {
  10.129 -    //KdPrint((__DRIVER_NAME "     Packet ready to send\n"));
  10.130      packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
  10.131 +    //KdPrint((__DRIVER_NAME "     Packet ready to send\n"));
  10.132      success = XenNet_HWSendPacket(xi, packet);
  10.133 -    if (!success)
  10.134 +    if (success)
  10.135 +      InsertTailList(&xi->tx_sent_pkt_list, entry);
  10.136 +    else
  10.137      {
  10.138        InsertHeadList(&xi->tx_waiting_pkt_list, entry);
  10.139        break;
  10.140 @@ -272,23 +270,52 @@ XenNet_SendQueuedPackets(struct xennet_i
  10.141    }
  10.142  }
  10.143  
  10.144 +// Called at <= DISPATCH_LEVEL with tx spinlock _NOT_ held
  10.145 +static VOID
  10.146 +XenNet_ReturnSentPackets(struct xennet_info *xi)
  10.147 +{
  10.148 +  PLIST_ENTRY entry;
  10.149 +  PNDIS_PACKET packets[32];
  10.150 +  int packet_index = 0;
  10.151 +  int i = 0;
  10.152 +  KIRQL old_irql;
  10.153 +  
  10.154 +  old_irql = KeRaiseIrqlToDpcLevel();
  10.155 +  KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
  10.156 +  entry = RemoveHeadList(&xi->tx_sent_pkt_list);
  10.157 +  
  10.158 +  while (entry != &xi->tx_sent_pkt_list)
  10.159 +  {
  10.160 +    packets[packet_index++] = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
  10.161 +    entry = RemoveHeadList(&xi->tx_sent_pkt_list);
  10.162 +    // try to minimize the need to acquire the spinlock repeatedly
  10.163 +    if (packet_index == 32 || entry == &xi->tx_sent_pkt_list)
  10.164 +    {
  10.165 +      KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
  10.166 +      for (i = 0; i < packet_index; i++)
  10.167 +        NdisMSendComplete(xi->adapter_handle, packets[i], NDIS_STATUS_SUCCESS);
  10.168 +      if (entry != &xi->tx_sent_pkt_list) /* don't acquire the lock if we have no more packets to SendComplete */
  10.169 +        KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
  10.170 +      packet_index = 0;
  10.171 +    }
  10.172 +  }
  10.173 +  if (!i) /* i will be == 0 if we didn't SendComplete any packets, and thus we will still have the lock */
  10.174 +    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
  10.175 +  KeLowerIrql(old_irql);
  10.176 +}
  10.177 +
  10.178  // Called at DISPATCH_LEVEL
  10.179  NDIS_STATUS
  10.180  XenNet_TxBufferGC(struct xennet_info *xi)
  10.181  {
  10.182    RING_IDX cons, prod;
  10.183    unsigned short id;
  10.184 -  PNDIS_PACKET packets[NET_TX_RING_SIZE];
  10.185 -  ULONG packet_count = 0;
  10.186 -  int moretodo;
  10.187 -  ULONG i;
  10.188  
  10.189    ASSERT(xi->connected);
  10.190    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
  10.191  
  10.192  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  10.193  
  10.194 -
  10.195    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
  10.196  
  10.197    do {
  10.198 @@ -302,20 +329,12 @@ XenNet_TxBufferGC(struct xennet_info *xi
  10.199        txrsp = RING_GET_RESPONSE(&xi->tx, cons);
  10.200        if (txrsp->status == NETIF_RSP_NULL)
  10.201        {
  10.202 -//        KdPrint((__DRIVER_NAME "     NETIF_RSP_NULL\n"));
  10.203          put_no_id_on_freelist(xi);
  10.204          continue; // This would be the response to an extra_info packet
  10.205        }
  10.206  
  10.207        id = txrsp->id;
  10.208   
  10.209 -      packets[packet_count] = xi->tx_pkts[id];
  10.210 -      if (packets[packet_count])
  10.211 -      {
  10.212 -        xi->tx_pkts[id] = NULL;
  10.213 -        packet_count++;
  10.214 -        xi->stat_tx_ok++;
  10.215 -      }
  10.216        if (xi->tx_mdls[id])
  10.217        {
  10.218          NdisAdjustBufferLength(xi->tx_mdls[id], PAGE_SIZE);
  10.219 @@ -326,25 +345,16 @@ XenNet_TxBufferGC(struct xennet_info *xi
  10.220      }
  10.221  
  10.222      xi->tx.rsp_cons = prod;
  10.223 -
  10.224 -    RING_FINAL_CHECK_FOR_RESPONSES(&xi->tx, moretodo);
  10.225 -  } while (moretodo);
  10.226 +    xi->tx.sring->rsp_event = prod + (NET_TX_RING_SIZE >> 2);
  10.227 +    KeMemoryBarrier();
  10.228 +  } while (prod != xi->tx.sring->rsp_prod);
  10.229  
  10.230    /* if queued packets, send them now */
  10.231    XenNet_SendQueuedPackets(xi);
  10.232  
  10.233    KeReleaseSpinLockFromDpcLevel(&xi->tx_lock);
  10.234  
  10.235 -//  if (packet_count)
  10.236 -//    KdPrint((__DRIVER_NAME " --- " __FUNCTION__ " %d packets completed\n"));
  10.237 -  for (i = 0; i < packet_count; i++)
  10.238 -  {
  10.239 -    /* A miniport driver must release any spin lock that it is holding before
  10.240 -       calling NdisMSendComplete. */
  10.241 -    NdisMSendComplete(xi->adapter_handle, packets[i], NDIS_STATUS_SUCCESS);
  10.242 -  }
  10.243 -
  10.244 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  10.245 +  XenNet_ReturnSentPackets(xi);
  10.246  
  10.247    return NDIS_STATUS_SUCCESS;
  10.248  }
  10.249 @@ -379,7 +389,8 @@ XenNet_SendPackets(
  10.250      XenNet_SendQueuedPackets(xi);
  10.251  
  10.252    KeReleaseSpinLock(&xi->tx_lock, OldIrql);
  10.253 -
  10.254 +  
  10.255 +  XenNet_ReturnSentPackets(xi);
  10.256  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  10.257  }
  10.258  
  10.259 @@ -388,7 +399,7 @@ XenNet_TxResumeStart(xennet_info_t *xi)
  10.260  {
  10.261    int i;
  10.262    KIRQL old_irql;
  10.263 -  PLIST_ENTRY entry;
  10.264 +//  PLIST_ENTRY entry;
  10.265  
  10.266    KeAcquireSpinLock(&xi->tx_lock, &old_irql);
  10.267    for (i = 0; i < NET_TX_RING_SIZE; i++)
  10.268 @@ -398,6 +409,7 @@ XenNet_TxResumeStart(xennet_info_t *xi)
  10.269        XenFreelist_PutPage(&xi->tx_freelist, xi->tx_mdls[i]);
  10.270        xi->tx_mdls[i] = NULL;
  10.271      }
  10.272 +#if 0
  10.273      /* this may result in packets being sent out of order... I don't think it matters though */
  10.274      if (xi->tx_pkts[i])
  10.275      {
  10.276 @@ -406,6 +418,7 @@ XenNet_TxResumeStart(xennet_info_t *xi)
  10.277        InsertTailList(&xi->tx_waiting_pkt_list, entry);
  10.278        xi->tx_pkts[i] = 0;
  10.279      }
  10.280 +#endif
  10.281    }
  10.282    XenFreelist_ResumeStart(&xi->tx_freelist);
  10.283    xi->tx_id_free = 0;
  10.284 @@ -424,6 +437,7 @@ XenNet_TxResumeEnd(xennet_info_t *xi)
  10.285    XenFreelist_ResumeEnd(&xi->tx_freelist);
  10.286    XenNet_SendQueuedPackets(xi);
  10.287    KeReleaseSpinLock(&xi->tx_lock, old_irql);
  10.288 +  XenNet_ReturnSentPackets(xi);
  10.289  }
  10.290  
  10.291  BOOLEAN
  10.292 @@ -478,9 +492,11 @@ XenNet_TxShutdown(xennet_info_t *xi)
  10.293    /* free sent-but-not-completed packets */
  10.294    for (i = 0; i < NET_TX_RING_SIZE; i++)
  10.295    {
  10.296 +/*  
  10.297      packet = xi->tx_pkts[i];
  10.298      if (packet)
  10.299        NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_FAILURE);
  10.300 +*/
  10.301      mdl = xi->tx_mdls[i];
  10.302      if (mdl)
  10.303        XenFreelist_PutPage(&xi->tx_freelist, xi->tx_mdls[i]);
    11.1 --- a/xenpci/evtchn.c	Thu Jul 31 15:22:30 2008 +1000
    11.2 +++ b/xenpci/evtchn.c	Tue Aug 12 15:08:19 2008 +1000
    11.3 @@ -99,20 +99,26 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    11.4        handled = TRUE;
    11.5        port = (evt_word << 5) + evt_bit;
    11.6        ev_action = &xpdd->ev_actions[port];
    11.7 +      ev_action->count++;
    11.8        switch (ev_action->type)
    11.9        {
   11.10        case EVT_ACTION_TYPE_NORMAL:
   11.11 +        synch_clear_bit(evt_bit, (volatile xen_long_t *)&shared_info_area->evtchn_pending[evt_word]);
   11.12          ev_action->ServiceRoutine(NULL, ev_action->ServiceContext);
   11.13          break;
   11.14 +      case EVT_ACTION_TYPE_IRQ:
   11.15 +        synch_clear_bit(evt_bit, (volatile xen_long_t *)&shared_info_area->evtchn_pending[evt_word]);
   11.16 +        sw_interrupt((UCHAR)ev_action->vector);
   11.17 +        break;
   11.18        case EVT_ACTION_TYPE_DPC:
   11.19 -      case EVT_ACTION_TYPE_IRQ: /* we have to call the IRQ from DPC or we risk mucking up IRQLs */
   11.20 +        synch_clear_bit(evt_bit, (volatile xen_long_t *)&shared_info_area->evtchn_pending[evt_word]);
   11.21          KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
   11.22          break;
   11.23        default:
   11.24 +        synch_clear_bit(evt_bit, (volatile xen_long_t *)&shared_info_area->evtchn_pending[evt_word]);
   11.25          KdPrint((__DRIVER_NAME "     Unhandled Event!!!\n"));
   11.26          break;
   11.27        }
   11.28 -      synch_clear_bit(evt_bit, (volatile xen_long_t *)&shared_info_area->evtchn_pending[evt_word]);
   11.29      }
   11.30    }
   11.31  
   11.32 @@ -282,7 +288,7 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
   11.33    {
   11.34      EvtChn_Mask(xpdd, i);
   11.35      xpdd->ev_actions[i].type = EVT_ACTION_TYPE_EMPTY;
   11.36 -    xpdd->ev_actions[i].Count = 0;
   11.37 +    xpdd->ev_actions[i].count = 0;
   11.38    }
   11.39  
   11.40    for (i = 0; i < 8; i++)
    12.1 --- a/xenpci/xenpci.c	Thu Jul 31 15:22:30 2008 +1000
    12.2 +++ b/xenpci/xenpci.c	Tue Aug 12 15:08:19 2008 +1000
    12.3 @@ -117,6 +117,41 @@ XenPci_Irp_Cleanup(PDEVICE_OBJECT device
    12.4  }
    12.5  
    12.6  static DDKAPI NTSTATUS
    12.7 +XenPci_SystemControl(PDEVICE_OBJECT device_object, PIRP irp)
    12.8 +{
    12.9 +  NTSTATUS status;
   12.10 +  PXENPCI_COMMON common = device_object->DeviceExtension;
   12.11 +  
   12.12 +  if (common->lower_do)
   12.13 +    status = XenPci_SystemControl_Fdo(device_object, irp);
   12.14 +  else
   12.15 +    status = XenPci_SystemControl_Pdo(device_object, irp);  
   12.16 +
   12.17 +  return status;
   12.18 +}
   12.19 +
   12.20 +static DDKAPI NTSTATUS
   12.21 +XenPci_Dummy(PDEVICE_OBJECT device_object, PIRP irp)
   12.22 +{
   12.23 +  NTSTATUS status;
   12.24 +  PIO_STACK_LOCATION stack;
   12.25 +  PXENPCI_COMMON common = device_object->DeviceExtension;
   12.26 +  
   12.27 +  FUNCTION_ENTER();
   12.28 +
   12.29 +  UNREFERENCED_PARAMETER(device_object);
   12.30 +
   12.31 +  stack = IoGetCurrentIrpStackLocation(irp);
   12.32 +  KdPrint((__DRIVER_NAME "     Major = %d, Minor = %d\n", stack->MajorFunction, stack->MinorFunction));
   12.33 +  IoSkipCurrentIrpStackLocation(irp);
   12.34 +  status = IoCallDriver(common->lower_do, irp);
   12.35 +
   12.36 +  FUNCTION_EXIT();
   12.37 +  
   12.38 +  return status;
   12.39 +}
   12.40 +
   12.41 +static DDKAPI NTSTATUS
   12.42  XenPci_AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject)
   12.43  {
   12.44    NTSTATUS status;
   12.45 @@ -207,10 +242,10 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   12.46    DriverObject->MajorFunction[IRP_MJ_CREATE] = XenPci_Irp_Create;
   12.47    DriverObject->MajorFunction[IRP_MJ_CLOSE] = XenPci_Irp_Close;
   12.48    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = XenPci_Irp_Cleanup;
   12.49 -  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NULL; //XenPci_Dummy;
   12.50 +  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = XenPci_Dummy;
   12.51    DriverObject->MajorFunction[IRP_MJ_READ] = XenPci_Irp_Read;
   12.52 -  DriverObject->MajorFunction[IRP_MJ_WRITE] = NULL; //XenPci_Dummy;
   12.53 -  DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = NULL; //XenPci_Dummy;
   12.54 +  DriverObject->MajorFunction[IRP_MJ_WRITE] = XenPci_Dummy;
   12.55 +  DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = XenPci_SystemControl;
   12.56  
   12.57    FUNCTION_EXIT();
   12.58  
    13.1 --- a/xenpci/xenpci.h	Thu Jul 31 15:22:30 2008 +1000
    13.2 +++ b/xenpci/xenpci.h	Tue Aug 12 15:08:19 2008 +1000
    13.3 @@ -73,7 +73,7 @@ typedef struct _ev_action_t {
    13.4    ULONG type; /* EVT_ACTION_TYPE_* */
    13.5    KDPC Dpc;
    13.6    ULONG vector;
    13.7 -  ULONG Count;
    13.8 +  ULONG count;
    13.9    PVOID xpdd;
   13.10  } ev_action_t;
   13.11  
   13.12 @@ -246,6 +246,7 @@ typedef struct {
   13.13    char path[128];
   13.14    char device[128];
   13.15    ULONG index;
   13.16 +  ULONG irq_number;
   13.17    ULONG irq_vector;
   13.18    KIRQL irq_level;
   13.19    char backend_path[128];
   13.20 @@ -355,6 +356,8 @@ NTSTATUS
   13.21  XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
   13.22  NTSTATUS
   13.23  XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
   13.24 +NTSTATUS
   13.25 +XenPci_SystemControl_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
   13.26  
   13.27  NTSTATUS
   13.28  XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   13.29 @@ -370,12 +373,17 @@ NTSTATUS
   13.30  XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   13.31  NTSTATUS
   13.32  XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   13.33 +NTSTATUS
   13.34 +XenPci_SystemControl_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   13.35  
   13.36  NTSTATUS
   13.37  XenPci_Pdo_Suspend(PDEVICE_OBJECT device_object);
   13.38  NTSTATUS
   13.39  XenPci_Pdo_Resume(PDEVICE_OBJECT device_object);
   13.40  
   13.41 +VOID
   13.42 +XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
   13.43 +
   13.44  char *
   13.45  XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
   13.46  char *
    14.1 --- a/xenpci/xenpci_fdo.c	Thu Jul 31 15:22:30 2008 +1000
    14.2 +++ b/xenpci/xenpci_fdo.c	Tue Aug 12 15:08:19 2008 +1000
    14.3 @@ -40,7 +40,6 @@ XenPci_Power_Fdo(PDEVICE_OBJECT device_o
    14.4    POWER_STATE_TYPE power_type;
    14.5    POWER_STATE power_state;
    14.6    PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    14.7 -  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    14.8  
    14.9    UNREFERENCED_PARAMETER(device_object);
   14.10    
   14.11 @@ -53,6 +52,7 @@ XenPci_Power_Fdo(PDEVICE_OBJECT device_o
   14.12    switch (stack->MinorFunction)
   14.13    {
   14.14    case IRP_MN_POWER_SEQUENCE:
   14.15 +    //irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
   14.16      KdPrint((__DRIVER_NAME "     IRP_MN_POWER_SEQUENCE\n"));
   14.17      break;
   14.18    case IRP_MN_QUERY_POWER:
   14.19 @@ -68,15 +68,19 @@ XenPci_Power_Fdo(PDEVICE_OBJECT device_o
   14.20        KdPrint((__DRIVER_NAME "     SystemPowerState\n"));
   14.21        break;
   14.22      default:
   14.23 -      break;
   14.24 +      KdPrint((__DRIVER_NAME "     %d\n", power_type));
   14.25      }    
   14.26      break;
   14.27    case IRP_MN_WAIT_WAKE:
   14.28 +    KdPrint((__DRIVER_NAME "     IRP_MN_WAIT_WAKE\n"));
   14.29      break;
   14.30 +  default:
   14.31 +    KdPrint((__DRIVER_NAME "     IRP_MN_%d\n", stack->MinorFunction));
   14.32 +    break;  
   14.33    }
   14.34    PoStartNextPowerIrp(irp);
   14.35    IoSkipCurrentIrpStackLocation(irp);
   14.36 -  status =  PoCallDriver (xpdd->common.lower_do, irp);
   14.37 +  status = PoCallDriver(xpdd->common.lower_do, irp);
   14.38    
   14.39    FUNCTION_EXIT();
   14.40  
   14.41 @@ -616,6 +620,17 @@ XenBus_DummyXenbusThreadProc(PVOID Start
   14.42    }
   14.43  }
   14.44  
   14.45 +static VOID 
   14.46 +XenPci_DumpPdoConfigs(PXENPCI_DEVICE_DATA xpdd)
   14.47 +{
   14.48 +  PXEN_CHILD child;
   14.49 +
   14.50 +  for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   14.51 +  {
   14.52 +    XenPci_DumpPdoConfig(child->context->common.pdo);
   14.53 +  }  
   14.54 +}
   14.55 +
   14.56  static VOID
   14.57  XenPci_SysrqHandler(char *path, PVOID context)
   14.58  {
   14.59 @@ -658,6 +673,8 @@ XenPci_SysrqHandler(char *path, PVOID co
   14.60  
   14.61    switch (letter)
   14.62    {
   14.63 +  case 0:
   14.64 +    break;
   14.65    case 'B':
   14.66      KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000001, 0x00000000, 0x00000000, 0x00000000);
   14.67      break;
   14.68 @@ -669,6 +686,10 @@ XenPci_SysrqHandler(char *path, PVOID co
   14.69    	work_item = IoAllocateWorkItem(xpdd->common.fdo);
   14.70      IoQueueWorkItem(work_item, XenPci_BeginSuspend, DelayedWorkQueue, NULL);
   14.71      break;
   14.72 +  case 'C':
   14.73 +    /* call shutdown from here for testing */
   14.74 +  	XenPci_DumpPdoConfigs(xpdd);
   14.75 +    break;
   14.76    default:
   14.77      KdPrint(("     Unhandled sysrq letter %c\n", letter));
   14.78      break;
   14.79 @@ -1211,7 +1232,7 @@ XenPci_Pnp_Fdo(PDEVICE_OBJECT device_obj
   14.80    PIO_STACK_LOCATION stack;
   14.81    PXENPCI_DEVICE_DATA xpdd;
   14.82  
   14.83 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   14.84 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   14.85  
   14.86    xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   14.87  
   14.88 @@ -1344,14 +1365,14 @@ XenPci_Pnp_Fdo(PDEVICE_OBJECT device_obj
   14.89      break;
   14.90      
   14.91    default:
   14.92 -    //KdPrint((__DRIVER_NAME "     Unhandled Minor = %d\n", stack->MinorFunction));
   14.93 +    KdPrint((__DRIVER_NAME "     Unhandled Minor = %d\n", stack->MinorFunction));
   14.94      IoSkipCurrentIrpStackLocation(irp);
   14.95      break;
   14.96    }
   14.97  
   14.98    status = IoCallDriver(xpdd->common.lower_do, irp);
   14.99  
  14.100 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
  14.101 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
  14.102  
  14.103    return status;
  14.104  }
  14.105 @@ -1448,6 +1469,27 @@ XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT de
  14.106    return status;
  14.107  }
  14.108  
  14.109 +DDKAPI NTSTATUS
  14.110 +XenPci_SystemControl_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
  14.111 +{
  14.112 +  NTSTATUS status;
  14.113 +  PIO_STACK_LOCATION stack;
  14.114 +  PXENPCI_COMMON common = device_object->DeviceExtension;
  14.115 +  
  14.116 +  FUNCTION_ENTER();
  14.117 +
  14.118 +  UNREFERENCED_PARAMETER(device_object);
  14.119 +
  14.120 +  stack = IoGetCurrentIrpStackLocation(irp);
  14.121 +  KdPrint((__DRIVER_NAME "     Minor = %d\n", stack->MinorFunction));
  14.122 +  IoSkipCurrentIrpStackLocation(irp);
  14.123 +  status = IoCallDriver(common->lower_do, irp);
  14.124 +
  14.125 +  FUNCTION_EXIT();
  14.126 +  
  14.127 +  return status;
  14.128 +}
  14.129 +
  14.130  #if 0
  14.131  static VOID
  14.132  XenPci_BalloonHandler(char *Path, PVOID Data)
    15.1 --- a/xenpci/xenpci_pdo.c	Thu Jul 31 15:22:30 2008 +1000
    15.2 +++ b/xenpci/xenpci_pdo.c	Tue Aug 12 15:08:19 2008 +1000
    15.3 @@ -817,6 +817,18 @@ XenPci_Pdo_Suspend(PDEVICE_OBJECT device
    15.4    return status;
    15.5  }
    15.6  
    15.7 +VOID
    15.8 +XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object)
    15.9 +{
   15.10 +  PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
   15.11 +
   15.12 +  KdPrint((__DRIVER_NAME "     path = %s\n", xppdd->path));
   15.13 +  KdPrint((__DRIVER_NAME "     backend_path = %s\n", xppdd->backend_path));
   15.14 +  KdPrint((__DRIVER_NAME "     irq_number = %d\n", xppdd->irq_number));
   15.15 +  KdPrint((__DRIVER_NAME "     irq_level = %d\n", xppdd->irq_level));
   15.16 +  KdPrint((__DRIVER_NAME "     irq_vector = %x\n", xppdd->irq_vector));
   15.17 +}
   15.18 +
   15.19  static NTSTATUS
   15.20  XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
   15.21  {
   15.22 @@ -841,6 +853,22 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   15.23      return status;
   15.24    }
   15.25  
   15.26 +  prl = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
   15.27 +  for (i = 0; i < prl->Count; i++)
   15.28 +  {
   15.29 +    prd = & prl->PartialDescriptors[i];
   15.30 +    switch (prd->Type)
   15.31 +    {
   15.32 +    case CmResourceTypeInterrupt:
   15.33 +      KdPrint((__DRIVER_NAME "     CmResourceTypeInterrupt\n"));
   15.34 +      KdPrint((__DRIVER_NAME "     irq_number = %02x\n", prd->u.Interrupt.Vector));
   15.35 +      //KdPrint((__DRIVER_NAME "     irq_level = %d\n", prd->u.Interrupt.Level));
   15.36 +      xppdd->irq_number = prd->u.Interrupt.Vector;
   15.37 +      //xppdd->irq_level = (KIRQL)prd->u.Interrupt.Level;
   15.38 +      break;
   15.39 +    }
   15.40 +  }
   15.41 +
   15.42    prl = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
   15.43    for (i = 0; i < prl->Count; i++)
   15.44    {
   15.45 @@ -1360,3 +1388,20 @@ XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT de
   15.46  
   15.47    return status;
   15.48  }
   15.49 +
   15.50 +DDKAPI NTSTATUS
   15.51 +XenPci_SystemControl_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
   15.52 +{
   15.53 +  NTSTATUS status;
   15.54 +
   15.55 +  UNREFERENCED_PARAMETER(device_object);
   15.56 +
   15.57 +  FUNCTION_ENTER();
   15.58 +  
   15.59 +  status = irp->IoStatus.Status;
   15.60 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
   15.61 +  
   15.62 +  FUNCTION_EXIT();
   15.63 +
   15.64 +  return status;
   15.65 +}
    16.1 --- a/xenstub/xenstub.c	Thu Jul 31 15:22:30 2008 +1000
    16.2 +++ b/xenstub/xenstub.c	Tue Aug 12 15:08:19 2008 +1000
    16.3 @@ -103,7 +103,6 @@ XenStub_Irp_Pnp(PDEVICE_OBJECT device_ob
    16.4    {
    16.5    case IRP_MN_START_DEVICE:
    16.6      //KdPrint((__DRIVER_NAME "     IRP_MN_START_DEVICE\n"));
    16.7 -    IoMarkIrpPending(irp);
    16.8      status = XenStub_SendAndWaitForIrp(device_object, irp);
    16.9      status = irp->IoStatus.Status = STATUS_SUCCESS;
   16.10      IoCompleteRequest(irp, IO_NO_INCREMENT);
   16.11 @@ -256,6 +255,28 @@ XenStub_AddDevice(PDRIVER_OBJECT DriverO
   16.12  }
   16.13  
   16.14  NTSTATUS
   16.15 +XenStub_Pass(PDEVICE_OBJECT device_object, PIRP irp)
   16.16 +{
   16.17 +  NTSTATUS status;
   16.18 +  PIO_STACK_LOCATION stack;
   16.19 +  PXENSTUB_DEVICE_DATA xsdd = device_object->DeviceExtension;
   16.20 +  
   16.21 +  FUNCTION_ENTER();
   16.22 +
   16.23 +  UNREFERENCED_PARAMETER(device_object);
   16.24 +
   16.25 +  stack = IoGetCurrentIrpStackLocation(irp);
   16.26 +  //KdPrint((__DRIVER_NAME "     Minor = %d\n", stack->MinorFunction));
   16.27 +  IoSkipCurrentIrpStackLocation(irp);
   16.28 +  status = IoCallDriver(xsdd->lower_do, irp);
   16.29 +
   16.30 +  FUNCTION_EXIT();
   16.31 +  
   16.32 +  return status;
   16.33 +}
   16.34 +
   16.35 +
   16.36 +NTSTATUS
   16.37  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
   16.38  {
   16.39    NTSTATUS status = STATUS_SUCCESS;
   16.40 @@ -267,13 +288,13 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   16.41    DriverObject->DriverExtension->AddDevice = XenStub_AddDevice;
   16.42    DriverObject->MajorFunction[IRP_MJ_PNP] = XenStub_Irp_Pnp;
   16.43    DriverObject->MajorFunction[IRP_MJ_POWER] = XenStub_Irp_Power;
   16.44 -  DriverObject->MajorFunction[IRP_MJ_CREATE] = NULL;
   16.45 -  DriverObject->MajorFunction[IRP_MJ_CLOSE] = NULL;
   16.46 -  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NULL;
   16.47 -  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NULL;
   16.48 -  DriverObject->MajorFunction[IRP_MJ_READ] = NULL;
   16.49 -  DriverObject->MajorFunction[IRP_MJ_WRITE] = NULL;
   16.50 -  DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = NULL;
   16.51 +  DriverObject->MajorFunction[IRP_MJ_CREATE] = XenStub_Pass;
   16.52 +  DriverObject->MajorFunction[IRP_MJ_CLOSE] = XenStub_Pass;
   16.53 +  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = XenStub_Pass;
   16.54 +  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = XenStub_Pass;
   16.55 +  DriverObject->MajorFunction[IRP_MJ_READ] = XenStub_Pass;
   16.56 +  DriverObject->MajorFunction[IRP_MJ_WRITE] = XenStub_Pass;
   16.57 +  DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = XenStub_Pass;
   16.58  
   16.59    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   16.60