win-pvdrivers

changeset 343:6cfd70daada3

Lots more changes to support xenvbd save/restore
author James Harper <james.harper@bendigoit.com.au>
date Sun Jun 29 22:46:40 2008 +1000 (2008-06-29)
parents eabe51317e3a
children b827e78992a3 a7c4b65e754a
files xennet/xennet.c xennet/xennet.h xennet/xennet_common.c xennet/xennet_rx.c xennet/xennet_tx.c xenpci/evtchn.c xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c xenvbd/scsiport.c
line diff
     1.1 --- a/xennet/xennet.c	Thu Jun 26 16:55:43 2008 +1000
     1.2 +++ b/xennet/xennet.c	Sun Jun 29 22:46:40 2008 +1000
     1.3 @@ -110,8 +110,117 @@ XenNet_InterruptDpc(NDIS_HANDLE  Minipor
     1.4    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
     1.5  }
     1.6  
     1.7 +static NDIS_STATUS
     1.8 +XenNet_ConnectBackend(struct xennet_info *xi)
     1.9 +{
    1.10 +  PUCHAR ptr;
    1.11 +  UCHAR type;
    1.12 +  PCHAR setting, value;
    1.13 +  UINT i;
    1.14 +
    1.15 +  ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    1.16 +
    1.17 +  ptr = xi->config_page;
    1.18 +  while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value)) != XEN_INIT_TYPE_END)
    1.19 +  {
    1.20 +    switch(type)
    1.21 +    {
    1.22 +    case XEN_INIT_TYPE_RING: /* frontend ring */
    1.23 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
    1.24 +      if (strcmp(setting, "tx-ring-ref") == 0)
    1.25 +      {
    1.26 +        FRONT_RING_INIT(&xi->tx, (netif_tx_sring_t *)value, PAGE_SIZE);
    1.27 +      } else if (strcmp(setting, "rx-ring-ref") == 0)
    1.28 +      {
    1.29 +        FRONT_RING_INIT(&xi->rx, (netif_rx_sring_t *)value, PAGE_SIZE);
    1.30 +      }
    1.31 +      break;
    1.32 +    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */
    1.33 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
    1.34 +      if (strcmp(setting, "event-channel") == 0)
    1.35 +      {
    1.36 +        xi->event_channel = PtrToUlong(value);
    1.37 +      }
    1.38 +      break;
    1.39 +    case XEN_INIT_TYPE_READ_STRING_BACK:
    1.40 +    case XEN_INIT_TYPE_READ_STRING_FRONT:
    1.41 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
    1.42 +      if (strcmp(setting, "mac") == 0)
    1.43 +      {
    1.44 +        char *s, *e;
    1.45 +        s = value;
    1.46 +        for (i = 0; i < ETH_ALEN; i++) {
    1.47 +          xi->perm_mac_addr[i] = (UINT8)simple_strtoul(s, &e, 16);
    1.48 +          if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
    1.49 +            KdPrint((__DRIVER_NAME "Error parsing MAC address\n"));
    1.50 +          }
    1.51 +          s = e + 1;
    1.52 +        }
    1.53 +        memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
    1.54 +      }
    1.55 +      break;
    1.56 +    case XEN_INIT_TYPE_VECTORS:
    1.57 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
    1.58 +      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
    1.59 +        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
    1.60 +      {
    1.61 +        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
    1.62 +          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
    1.63 +        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.64 +        return NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
    1.65 +      }
    1.66 +      else
    1.67 +        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
    1.68 +      break;
    1.69 +    default:
    1.70 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
    1.71 +      break;
    1.72 +    }
    1.73 +  }
    1.74 +  return NDIS_STATUS_SUCCESS;
    1.75 +}
    1.76 +
    1.77 +static VOID
    1.78 +XenNet_Resume(PDEVICE_OBJECT device_object, PVOID context)
    1.79 +{
    1.80 +  struct xennet_info *xi = context;
    1.81 +  
    1.82 +  UNREFERENCED_PARAMETER(device_object);
    1.83 +  
    1.84 +  XenNet_RxResumeStart(xi);
    1.85 +  XenNet_TxResumeStart(xi);
    1.86 +  XenNet_ConnectBackend(xi);
    1.87 +  xi->device_state->resume_state = RESUME_STATE_RUNNING;
    1.88 +  XenNet_RxResumeEnd(xi);
    1.89 +  XenNet_TxResumeEnd(xi);
    1.90 +  NdisMSetPeriodicTimer(&xi->resume_timer, 100);
    1.91 +}
    1.92 +
    1.93 +static VOID 
    1.94 +XenResumeCheck_Timer(
    1.95 + PVOID SystemSpecific1,
    1.96 + PVOID FunctionContext,
    1.97 + PVOID SystemSpecific2,
    1.98 + PVOID SystemSpecific3
    1.99 +)
   1.100 +{
   1.101 +  struct xennet_info *xi = FunctionContext;
   1.102 +  PIO_WORKITEM work_item;
   1.103 +  BOOLEAN timer_cancelled;
   1.104 + 
   1.105 +  UNREFERENCED_PARAMETER(SystemSpecific1);
   1.106 +  UNREFERENCED_PARAMETER(SystemSpecific2);
   1.107 +  UNREFERENCED_PARAMETER(SystemSpecific3);
   1.108 + 
   1.109 +  if (xi->device_state->resume_state == RESUME_STATE_FRONTEND_RESUME)
   1.110 +  {
   1.111 +    NdisMCancelTimer(&xi->resume_timer, &timer_cancelled);
   1.112 +  	work_item = IoAllocateWorkItem(xi->fdo);
   1.113 +  	IoQueueWorkItem(work_item, XenNet_Resume, DelayedWorkQueue, xi);
   1.114 +  }
   1.115 +}
   1.116 +
   1.117  // Called at <= DISPATCH_LEVEL
   1.118 -
   1.119  static NDIS_STATUS
   1.120  XenNet_Init(
   1.121    OUT PNDIS_STATUS OpenErrorStatus,
   1.122 @@ -123,7 +232,6 @@ XenNet_Init(
   1.123    )
   1.124  {
   1.125    NDIS_STATUS status;
   1.126 -  UINT i, j;
   1.127    BOOLEAN medium_found = FALSE;
   1.128    struct xennet_info *xi = NULL;
   1.129    ULONG nrl_length;
   1.130 @@ -131,13 +239,14 @@ XenNet_Init(
   1.131    PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
   1.132    KIRQL irq_level = 0;
   1.133    ULONG irq_vector = 0;
   1.134 -  UCHAR type;
   1.135 -  PUCHAR ptr;
   1.136 -  PCHAR setting, value;
   1.137 -  ULONG length;
   1.138    NDIS_HANDLE config_handle;
   1.139    NDIS_STRING config_param_name;
   1.140    PNDIS_CONFIGURATION_PARAMETER config_param;
   1.141 +  ULONG i;
   1.142 +  PUCHAR ptr;
   1.143 +  UCHAR type;
   1.144 +  PCHAR setting, value;
   1.145 +  ULONG length;
   1.146    CHAR buf[128];
   1.147    
   1.148    UNREFERENCED_PARAMETER(OpenErrorStatus);
   1.149 @@ -284,6 +393,10 @@ XenNet_Init(
   1.150        else
   1.151          memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
   1.152        break;
   1.153 +    case XEN_INIT_TYPE_STATE_PTR:
   1.154 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   1.155 +      xi->device_state = (PXENPCI_DEVICE_STATE)value;
   1.156 +      break;
   1.157      default:
   1.158        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   1.159        break;
   1.160 @@ -379,63 +492,7 @@ XenNet_Init(
   1.161    status = xi->vectors.XenPci_XenConfigDevice(xi->vectors.context);
   1.162    // check return value
   1.163  
   1.164 -  ptr = xi->config_page;
   1.165 -  while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value)) != XEN_INIT_TYPE_END)
   1.166 -  {
   1.167 -    switch(type)
   1.168 -    {
   1.169 -    case XEN_INIT_TYPE_RING: /* frontend ring */
   1.170 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
   1.171 -      if (strcmp(setting, "tx-ring-ref") == 0)
   1.172 -      {
   1.173 -        FRONT_RING_INIT(&xi->tx, (netif_tx_sring_t *)value, PAGE_SIZE);
   1.174 -      } else if (strcmp(setting, "rx-ring-ref") == 0)
   1.175 -      {
   1.176 -        FRONT_RING_INIT(&xi->rx, (netif_rx_sring_t *)value, PAGE_SIZE);
   1.177 -      }
   1.178 -      break;
   1.179 -    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */
   1.180 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
   1.181 -      if (strcmp(setting, "event-channel") == 0)
   1.182 -      {
   1.183 -        xi->event_channel = PtrToUlong(value);
   1.184 -      }
   1.185 -      break;
   1.186 -    case XEN_INIT_TYPE_READ_STRING_BACK:
   1.187 -    case XEN_INIT_TYPE_READ_STRING_FRONT:
   1.188 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   1.189 -      if (strcmp(setting, "mac") == 0)
   1.190 -      {
   1.191 -        char *s, *e;
   1.192 -        s = value;
   1.193 -        for (j = 0; j < ETH_ALEN; j++) {
   1.194 -          xi->perm_mac_addr[j] = (UINT8)simple_strtoul(s, &e, 16);
   1.195 -          if ((s == e) || (*e != ((j == ETH_ALEN-1) ? '\0' : ':'))) {
   1.196 -            KdPrint((__DRIVER_NAME "Error parsing MAC address\n"));
   1.197 -          }
   1.198 -          s = e + 1;
   1.199 -        }
   1.200 -        memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
   1.201 -      }
   1.202 -      break;
   1.203 -    case XEN_INIT_TYPE_VECTORS:
   1.204 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   1.205 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   1.206 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   1.207 -      {
   1.208 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   1.209 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   1.210 -        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.211 -        return NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
   1.212 -      }
   1.213 -      else
   1.214 -        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
   1.215 -      break;
   1.216 -    default:
   1.217 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   1.218 -      break;
   1.219 -    }
   1.220 -  }
   1.221 +  status = XenNet_ConnectBackend(xi);
   1.222    
   1.223    KeInitializeEvent(&xi->shutdown_event, SynchronizationEvent, FALSE);  
   1.224  
   1.225 @@ -456,6 +513,9 @@ XenNet_Init(
   1.226      //goto err;
   1.227    }
   1.228  
   1.229 +  NdisMInitializeTimer(&xi->resume_timer, xi->adapter_handle, XenResumeCheck_Timer, xi);
   1.230 +  NdisMSetPeriodicTimer(&xi->resume_timer, 100);
   1.231 +
   1.232    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.233  
   1.234    return NDIS_STATUS_SUCCESS;
     2.1 --- a/xennet/xennet.h	Thu Jun 26 16:55:43 2008 +1000
     2.2 +++ b/xennet/xennet.h	Sun Jun 29 22:46:40 2008 +1000
     2.3 @@ -146,6 +146,7 @@ typedef struct
     2.4    ULONG page_free_target;
     2.5    NDIS_MINIPORT_TIMER timer;
     2.6    PKSPIN_LOCK lock;
     2.7 +  BOOLEAN grants_resumed;
     2.8  } freelist_t;
     2.9  
    2.10  struct xennet_info
    2.11 @@ -168,9 +169,8 @@ struct xennet_info
    2.12    UINT8 curr_mac_addr[ETH_ALEN];
    2.13  
    2.14    /* Misc. Xen vars */
    2.15 -  //XEN_IFACE XenInterface;
    2.16 -  //PXENPCI_XEN_DEVICE_DATA pdo_data;
    2.17    XENPCI_VECTORS vectors;
    2.18 +  PXENPCI_DEVICE_STATE device_state;
    2.19    evtchn_port_t event_channel;
    2.20    ULONG state;
    2.21    KEVENT shutdown_event;
    2.22 @@ -195,7 +195,7 @@ struct xennet_info
    2.23    /* rx_related - protected by rx_lock */
    2.24    struct netif_rx_front_ring rx;
    2.25    ULONG rx_id_free;
    2.26 -  PNDIS_BUFFER rx_buffers[NET_RX_RING_SIZE];
    2.27 +  PNDIS_BUFFER rx_mdls[NET_RX_RING_SIZE];
    2.28    freelist_t rx_freelist;
    2.29    packet_info_t rxpi;
    2.30    PNDIS_PACKET rx_packet_list[NET_RX_RING_SIZE * 2];
    2.31 @@ -221,6 +221,8 @@ struct xennet_info
    2.32    /* config stuff calculated from the above */
    2.33    ULONG config_max_pkt_size;
    2.34  
    2.35 +  NDIS_MINIPORT_TIMER resume_timer;
    2.36 +
    2.37    /* stats */
    2.38    ULONG64 stat_tx_ok;
    2.39    ULONG64 stat_rx_ok;
    2.40 @@ -275,10 +277,22 @@ XenNet_RxInit(xennet_info_t *xi);
    2.41  BOOLEAN
    2.42  XenNet_RxShutdown(xennet_info_t *xi);
    2.43  
    2.44 +VOID
    2.45 +XenNet_RxResumeStart(xennet_info_t *xi);
    2.46 +
    2.47 +VOID
    2.48 +XenNet_RxResumeEnd(xennet_info_t *xi);
    2.49 +
    2.50  NDIS_STATUS
    2.51  XenNet_TxBufferGC(struct xennet_info *xi);
    2.52  
    2.53  VOID
    2.54 +XenNet_TxResumeStart(xennet_info_t *xi);
    2.55 +
    2.56 +VOID
    2.57 +XenNet_TxResumeEnd(xennet_info_t *xi);
    2.58 +
    2.59 +VOID
    2.60  XenNet_SendPackets(
    2.61    IN NDIS_HANDLE MiniportAdapterContext,
    2.62    IN PPNDIS_PACKET PacketArray,
    2.63 @@ -348,3 +362,7 @@ VOID
    2.64  XenFreelist_PutPage(freelist_t *fl, PMDL mdl);
    2.65  VOID
    2.66  XenFreelist_Dispose(freelist_t *fl);
    2.67 +VOID
    2.68 +XenFreelist_ResumeStart(freelist_t *fl);
    2.69 +VOID
    2.70 +XenFreelist_ResumeEnd(freelist_t *fl);
     3.1 --- a/xennet/xennet_common.c	Thu Jun 26 16:55:43 2008 +1000
     3.2 +++ b/xennet/xennet_common.c	Sun Jun 29 22:46:40 2008 +1000
     3.3 @@ -143,7 +143,7 @@ XenNet_GetData(
     3.4    return buffer;
     3.5  }
     3.6  
     3.7 -
     3.8 +/* Called at DISPATCH LEVEL */
     3.9  static VOID 
    3.10  XenFreelist_Timer(
    3.11    PVOID SystemSpecific1,
    3.12 @@ -160,6 +160,9 @@ XenFreelist_Timer(
    3.13    UNREFERENCED_PARAMETER(SystemSpecific2);
    3.14    UNREFERENCED_PARAMETER(SystemSpecific3);
    3.15  
    3.16 +  if (fl->xi->device_state->resume_state != RESUME_STATE_RUNNING && !fl->grants_resumed)
    3.17 +    return;
    3.18 +    
    3.19    KeAcquireSpinLockAtDpcLevel(fl->lock);
    3.20  
    3.21    //KdPrint((__DRIVER_NAME " --- timer - page_free_lowest = %d\n", fl->page_free_lowest));
    3.22 @@ -192,6 +195,7 @@ XenFreelist_Init(struct xennet_info *xi,
    3.23    fl->page_free = 0;
    3.24    fl->page_free_lowest = 0;
    3.25    fl->page_free_target = 16; /* tune this */
    3.26 +  fl->grants_resumed = FALSE;
    3.27    NdisMInitializeTimer(&fl->timer, fl->xi->adapter_handle, XenFreelist_Timer, fl);
    3.28    NdisMSetPeriodicTimer(&fl->timer, 1000);
    3.29  }
    3.30 @@ -209,6 +213,7 @@ XenFreelist_GetPage(freelist_t *fl)
    3.31      *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = fl->xi->vectors.GntTbl_GrantAccess(
    3.32        fl->xi->vectors.context, 0,
    3.33        (uint32_t)pfn, FALSE, 0);
    3.34 +    /* we really should check if our grant was successful... */
    3.35    }
    3.36    else
    3.37    {
    3.38 @@ -245,3 +250,32 @@ XenFreelist_Dispose(freelist_t *fl)
    3.39      FreePages(mdl);
    3.40    }
    3.41  }
    3.42 +
    3.43 +static VOID
    3.44 +XenFreelist_ReGrantMdl(freelist_t *fl, PMDL mdl)
    3.45 +{
    3.46 +  PFN_NUMBER pfn;
    3.47 +  pfn = *MmGetMdlPfnArray(mdl);
    3.48 +  *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = fl->xi->vectors.GntTbl_GrantAccess(
    3.49 +    fl->xi->vectors.context, 0,
    3.50 +    (uint32_t)pfn, FALSE, 0);
    3.51 +}
    3.52 +
    3.53 +/* re-grant all the pages, as the grant table was wiped on resume */
    3.54 +VOID
    3.55 +XenFreelist_ResumeStart(freelist_t *fl)
    3.56 +{
    3.57 +  ULONG i;
    3.58 +  
    3.59 +  for (i = 0; i < fl->page_free; i++)
    3.60 +  {
    3.61 +    XenFreelist_ReGrantMdl(fl, fl->page_list[i]);
    3.62 +  }
    3.63 +  fl->grants_resumed = TRUE;
    3.64 +}
    3.65 +
    3.66 +VOID
    3.67 +XenFreelist_ResumeEnd(freelist_t *fl)
    3.68 +{
    3.69 +  fl->grants_resumed = FALSE;
    3.70 +}
     4.1 --- a/xennet/xennet_rx.c	Thu Jun 26 16:55:43 2008 +1000
     4.2 +++ b/xennet/xennet_rx.c	Sun Jun 29 22:46:40 2008 +1000
     4.3 @@ -62,8 +62,8 @@ XenNet_RxBufferAlloc(struct xennet_info 
     4.4      /* Give to netback */
     4.5      id = (USHORT)((req_prod + i) & (NET_RX_RING_SIZE - 1));
     4.6  //    KdPrint((__DRIVER_NAME "     id = %d\n", id));
     4.7 -    ASSERT(xi->rx_buffers[id] == NULL);
     4.8 -    xi->rx_buffers[id] = mdl;
     4.9 +    ASSERT(xi->rx_mdls[id] == NULL);
    4.10 +    xi->rx_mdls[id] = mdl;
    4.11      req = RING_GET_REQUEST(&xi->rx, req_prod + i);
    4.12      req->gref = get_grant_ref(mdl);
    4.13      req->id = id;
    4.14 @@ -365,19 +365,9 @@ XenNet_RxBufferCheck(struct xennet_info 
    4.15    struct netif_rx_response *rxrsp = NULL;
    4.16    struct netif_extra_info *ei;
    4.17    USHORT id;
    4.18 -#if DBG
    4.19 -  int cycles = 0;
    4.20 -#endif
    4.21 -#if defined(XEN_PROFILE)
    4.22 -  LARGE_INTEGER tsc, dummy;
    4.23 -#endif
    4.24    
    4.25  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    4.26  
    4.27 -#if defined(XEN_PROFILE)
    4.28 -  tsc = KeQueryPerformanceCounter(&dummy);
    4.29 -#endif
    4.30 -
    4.31    ASSERT(xi->connected);
    4.32  
    4.33    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    4.34 @@ -385,17 +375,15 @@ XenNet_RxBufferCheck(struct xennet_info 
    4.35    //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));
    4.36      
    4.37    do {
    4.38 -    ASSERT(cycles++ < 256);
    4.39      prod = xi->rx.sring->rsp_prod;
    4.40      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
    4.41  
    4.42      for (cons = xi->rx.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INDICATE; cons++)
    4.43      {
    4.44 -      ASSERT(cycles++ < 256);
    4.45        id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
    4.46 -      ASSERT(xi->rx_buffers[id]);
    4.47 -      mdl = xi->rx_buffers[id];
    4.48 -      xi->rx_buffers[id] = NULL;
    4.49 +      ASSERT(xi->rx_mdls[id]);
    4.50 +      mdl = xi->rx_mdls[id];
    4.51 +      xi->rx_mdls[id] = NULL;
    4.52        xi->rx_id_free++;
    4.53        if (xi->rxpi.extra_info)
    4.54        {
    4.55 @@ -464,9 +452,6 @@ XenNet_RxBufferCheck(struct xennet_info 
    4.56      {
    4.57        KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    4.58        NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
    4.59 -#if defined(XEN_PROFILE)
    4.60 -      ProfCount_CallsToIndicateReceive++;
    4.61 -#endif
    4.62        KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    4.63        total_packets += packet_count;
    4.64        packet_count = 0;
    4.65 @@ -478,21 +463,16 @@ XenNet_RxBufferCheck(struct xennet_info 
    4.66    /* Give netback more buffers */
    4.67    XenNet_RxBufferAlloc(xi);
    4.68  
    4.69 -if (xi->rxpi.more_frags || xi->rxpi.extra_info)
    4.70 -  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));
    4.71 +  if (xi->rxpi.more_frags || xi->rxpi.extra_info)
    4.72 +    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));
    4.73  
    4.74    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    4.75  
    4.76 -#if defined(XEN_PROFILE)
    4.77 -  ProfTime_RxBufferCheck.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
    4.78 -  ProfCount_RxBufferCheck++;
    4.79 -#endif
    4.80 -
    4.81    return NDIS_STATUS_SUCCESS;
    4.82  }
    4.83  
    4.84  /* called at DISPATCH_LEVEL */
    4.85 -
    4.86 +/* it's okay for return packet to be called while resume_state != RUNNING as the packet will simply be added back to the freelist, the grants will be fixed later */
    4.87  VOID
    4.88  XenNet_ReturnPacket(
    4.89    IN NDIS_HANDLE MiniportAdapterContext,
    4.90 @@ -501,25 +481,11 @@ XenNet_ReturnPacket(
    4.91  {
    4.92    struct xennet_info *xi = MiniportAdapterContext;
    4.93    PMDL mdl;
    4.94 -#if DBG
    4.95 -  int cycles = 0;
    4.96 -#endif
    4.97 -#if defined(XEN_PROFILE)
    4.98 -  LARGE_INTEGER tsc, dummy;
    4.99 -#endif
   4.100 -
   4.101 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (%p)\n", Packet));
   4.102 -
   4.103 -#if defined(XEN_PROFILE)
   4.104 -  tsc = KeQueryPerformanceCounter(&dummy);
   4.105 -#endif
   4.106 -
   4.107    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
   4.108  
   4.109    NdisUnchainBufferAtBack(Packet, &mdl);
   4.110    while (mdl)
   4.111    {
   4.112 -    ASSERT(cycles++ < 256);
   4.113      NdisAdjustBufferLength(mdl, PAGE_SIZE);
   4.114      XenFreelist_PutPage(&xi->rx_freelist, mdl);
   4.115      NdisUnchainBufferAtBack(Packet, &mdl);
   4.116 @@ -531,11 +497,6 @@ XenNet_ReturnPacket(
   4.117    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   4.118    
   4.119  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.120 -
   4.121 -#if defined(XEN_PROFILE)
   4.122 -  ProfTime_ReturnPacket.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
   4.123 -  ProfCount_ReturnPacket++;
   4.124 -#endif
   4.125  }
   4.126  
   4.127  /*
   4.128 @@ -555,17 +516,49 @@ XenNet_RxBufferFree(struct xennet_info *
   4.129  
   4.130    for (i = 0; i < NET_RX_RING_SIZE; i++)
   4.131    {
   4.132 -    KdPrint((__DRIVER_NAME "     Ring slot %d = %p\n", i, xi->rx_buffers[i]));
   4.133 -    if (!xi->rx_buffers[i])
   4.134 +    KdPrint((__DRIVER_NAME "     Ring slot %d = %p\n", i, xi->rx_mdls[i]));
   4.135 +    if (!xi->rx_mdls[i])
   4.136        continue;
   4.137  
   4.138 -    mdl = xi->rx_buffers[i];
   4.139 +    mdl = xi->rx_mdls[i];
   4.140      NdisAdjustBufferLength(mdl, PAGE_SIZE);
   4.141      KdPrint((__DRIVER_NAME "     Calling PutPage - page_free = %d\n", xi->rx_freelist.page_free));
   4.142      XenFreelist_PutPage(&xi->rx_freelist, mdl);
   4.143    }
   4.144  }
   4.145  
   4.146 +VOID
   4.147 +XenNet_RxResumeStart(xennet_info_t *xi)
   4.148 +{
   4.149 +  int i;
   4.150 +  KIRQL old_irql;
   4.151 +
   4.152 +  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   4.153 +  for (i = 0; i < NET_RX_RING_SIZE; i++)
   4.154 +  {
   4.155 +    if (xi->rx_mdls[i])
   4.156 +    {
   4.157 +      XenFreelist_PutPage(&xi->rx_freelist, xi->rx_mdls[i]);
   4.158 +      xi->rx_mdls[i] = NULL;
   4.159 +    }
   4.160 +  }
   4.161 +  XenFreelist_ResumeStart(&xi->rx_freelist);
   4.162 +  xi->rx_id_free = NET_RX_RING_SIZE;
   4.163 +  xi->rx_outstanding = 0;
   4.164 +  KeReleaseSpinLock(&xi->rx_lock, old_irql);
   4.165 +}
   4.166 +
   4.167 +VOID
   4.168 +XenNet_RxResumeEnd(xennet_info_t *xi)
   4.169 +{
   4.170 +  KIRQL old_irql;
   4.171 +
   4.172 +  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   4.173 +  XenFreelist_ResumeEnd(&xi->rx_freelist);
   4.174 +  XenNet_RxBufferAlloc(xi);
   4.175 +  KeReleaseSpinLock(&xi->rx_lock, old_irql);
   4.176 +}
   4.177 +
   4.178  BOOLEAN
   4.179  XenNet_RxInit(xennet_info_t *xi)
   4.180  {
   4.181 @@ -577,7 +570,7 @@ XenNet_RxInit(xennet_info_t *xi)
   4.182  
   4.183    for (i = 0; i < NET_RX_RING_SIZE; i++)
   4.184    {
   4.185 -    xi->rx_buffers[i] = NULL;
   4.186 +    xi->rx_mdls[i] = NULL;
   4.187    }
   4.188  
   4.189    xi->rx_outstanding = 0;
     5.1 --- a/xennet/xennet_tx.c	Thu Jun 26 16:55:43 2008 +1000
     5.2 +++ b/xennet/xennet_tx.c	Sun Jun 29 22:46:40 2008 +1000
     5.3 @@ -248,24 +248,12 @@ XenNet_SendQueuedPackets(struct xennet_i
     5.4    PLIST_ENTRY entry;
     5.5    PNDIS_PACKET packet;
     5.6    int notify;
     5.7 -#if defined(XEN_PROFILE)
     5.8 -  LARGE_INTEGER tsc, dummy;
     5.9 -#endif
    5.10 -
    5.11 -#if DBG
    5.12 -  int cycles = 0;
    5.13 -#endif
    5.14    BOOLEAN success;
    5.15  
    5.16 -#if defined(XEN_PROFILE)
    5.17 -  tsc = KeQueryPerformanceCounter(&dummy);
    5.18 -#endif
    5.19 -
    5.20    entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
    5.21    /* if empty, the above returns head*, not NULL */
    5.22    while (entry != &xi->tx_waiting_pkt_list)
    5.23    {
    5.24 -    ASSERT(cycles++ < 65536);
    5.25      //KdPrint((__DRIVER_NAME "     Packet ready to send\n"));
    5.26      packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
    5.27      success = XenNet_HWSendPacket(xi, packet);
    5.28 @@ -282,11 +270,6 @@ XenNet_SendQueuedPackets(struct xennet_i
    5.29    {
    5.30      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
    5.31    }
    5.32 -
    5.33 -#if defined(XEN_PROFILE)
    5.34 -  ProfTime_SendQueuedPackets.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
    5.35 -  ProfCount_SendQueuedPackets++;
    5.36 -#endif
    5.37  }
    5.38  
    5.39  // Called at DISPATCH_LEVEL
    5.40 @@ -299,26 +282,16 @@ XenNet_TxBufferGC(struct xennet_info *xi
    5.41    ULONG packet_count = 0;
    5.42    int moretodo;
    5.43    ULONG i;
    5.44 -#if DBG
    5.45 -  int cycles = 0;
    5.46 -#endif
    5.47 -#if defined(XEN_PROFILE)
    5.48 -  LARGE_INTEGER tsc, dummy;
    5.49 -#endif
    5.50  
    5.51    ASSERT(xi->connected);
    5.52    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
    5.53  
    5.54  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.55  
    5.56 -#if defined(XEN_PROFILE)
    5.57 -  tsc = KeQueryPerformanceCounter(&dummy);
    5.58 -#endif
    5.59  
    5.60    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
    5.61  
    5.62    do {
    5.63 -    ASSERT(cycles++ < 65536);
    5.64      prod = xi->tx.sring->rsp_prod;
    5.65      KeMemoryBarrier(); /* Ensure we see responses up to 'rsp_prod'. */
    5.66  
    5.67 @@ -326,8 +299,6 @@ XenNet_TxBufferGC(struct xennet_info *xi
    5.68      {
    5.69        struct netif_tx_response *txrsp;
    5.70  
    5.71 -      ASSERT(cycles++ < 65536);
    5.72 -
    5.73        txrsp = RING_GET_RESPONSE(&xi->tx, cons);
    5.74        if (txrsp->status == NETIF_RSP_NULL)
    5.75        {
    5.76 @@ -375,14 +346,10 @@ XenNet_TxBufferGC(struct xennet_info *xi
    5.77  
    5.78  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.79  
    5.80 -#if defined(XEN_PROFILE)
    5.81 -  ProfTime_TxBufferGC.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
    5.82 -  ProfCount_TxBufferGC++;
    5.83 -#endif
    5.84 -
    5.85    return NDIS_STATUS_SUCCESS;
    5.86  }
    5.87  
    5.88 +// called at <= DISPATCH_LEVEL
    5.89  VOID
    5.90  XenNet_SendPackets(
    5.91    IN NDIS_HANDLE MiniportAdapterContext,
    5.92 @@ -395,15 +362,6 @@ XenNet_SendPackets(
    5.93    UINT i;
    5.94    PLIST_ENTRY entry;
    5.95    KIRQL OldIrql;
    5.96 -#if defined(XEN_PROFILE)
    5.97 -  LARGE_INTEGER tsc, dummy;
    5.98 -  KIRQL OldIrql2;
    5.99 -#endif
   5.100 -
   5.101 -#if defined(XEN_PROFILE)
   5.102 -  KeRaiseIrql(DISPATCH_LEVEL, &OldIrql2);
   5.103 -  tsc = KeQueryPerformanceCounter(&dummy);
   5.104 -#endif
   5.105  
   5.106    KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
   5.107  
   5.108 @@ -415,40 +373,57 @@ XenNet_SendPackets(
   5.109      *(ULONG *)&packet->MiniportReservedEx = 0;
   5.110      entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   5.111      InsertTailList(&xi->tx_waiting_pkt_list, entry);
   5.112 -#if defined(XEN_PROFILE)
   5.113 -    ProfCount_PacketsPerSendPackets++;
   5.114 -#endif
   5.115    }
   5.116  
   5.117 -  XenNet_SendQueuedPackets(xi);
   5.118 +  if (xi->device_state->resume_state == RESUME_STATE_RUNNING)
   5.119 +    XenNet_SendQueuedPackets(xi);
   5.120  
   5.121    KeReleaseSpinLock(&xi->tx_lock, OldIrql);
   5.122  
   5.123 -#if defined(XEN_PROFILE)
   5.124 -  ProfTime_SendPackets.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
   5.125 -  ProfCount_SendPackets++;
   5.126 -  KeLowerIrql(OldIrql2);
   5.127 -#endif
   5.128 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.129 +}
   5.130  
   5.131 -#if defined(XEN_PROFILE)
   5.132 -  if ((ProfCount_SendPackets & 1023) == 0)
   5.133 +VOID
   5.134 +XenNet_TxResumeStart(xennet_info_t *xi)
   5.135 +{
   5.136 +  int i;
   5.137 +  KIRQL old_irql;
   5.138 +  PLIST_ENTRY entry;
   5.139 +
   5.140 +  KeAcquireSpinLock(&xi->tx_lock, &old_irql);
   5.141 +  for (i = 0; i < NET_TX_RING_SIZE; i++)
   5.142    {
   5.143 -    KdPrint((__DRIVER_NAME "     ***\n"));
   5.144 -    KdPrint((__DRIVER_NAME "     RxBufferAlloc     Count = %10d, Avg Time     = %10ld\n", ProfCount_RxBufferAlloc, (ProfCount_RxBufferAlloc == 0)?0:(ProfTime_RxBufferAlloc.QuadPart / ProfCount_RxBufferAlloc)));
   5.145 -    KdPrint((__DRIVER_NAME "     ReturnPacket      Count = %10d, Avg Time     = %10ld\n", ProfCount_ReturnPacket, (ProfCount_ReturnPacket == 0)?0:(ProfTime_ReturnPacket.QuadPart / ProfCount_ReturnPacket)));
   5.146 -    KdPrint((__DRIVER_NAME "     RxBufferCheck     Count = %10d, Avg Time     = %10ld\n", ProfCount_RxBufferCheck, (ProfCount_RxBufferCheck == 0)?0:(ProfTime_RxBufferCheck.QuadPart / ProfCount_RxBufferCheck)));
   5.147 -    KdPrint((__DRIVER_NAME "     RxBufferCheckTop                      Avg Time     = %10ld\n", (ProfCount_RxBufferCheck == 0)?0:(ProfTime_RxBufferCheckTopHalf.QuadPart / ProfCount_RxBufferCheck)));
   5.148 -    KdPrint((__DRIVER_NAME "     RxBufferCheckBot                      Avg Time     = %10ld\n", (ProfCount_RxBufferCheck == 0)?0:(ProfTime_RxBufferCheckBotHalf.QuadPart / ProfCount_RxBufferCheck)));
   5.149 -    KdPrint((__DRIVER_NAME "     Linearize         Count = %10d, Avg Time     = %10ld\n", ProfCount_Linearize, (ProfCount_Linearize == 0)?0:(ProfTime_Linearize.QuadPart / ProfCount_Linearize)));
   5.150 -    KdPrint((__DRIVER_NAME "     SendPackets       Count = %10d, Avg Time     = %10ld\n", ProfCount_SendPackets, (ProfCount_SendPackets == 0)?0:(ProfTime_SendPackets.QuadPart / ProfCount_SendPackets)));
   5.151 -    KdPrint((__DRIVER_NAME "     Packets per SendPackets = %10d\n", (ProfCount_SendPackets == 0)?0:(ProfCount_PacketsPerSendPackets / ProfCount_SendPackets)));
   5.152 -    KdPrint((__DRIVER_NAME "     SendQueuedPackets Count = %10d, Avg Time     = %10ld\n", ProfCount_SendQueuedPackets, (ProfCount_SendQueuedPackets == 0)?0:(ProfTime_SendQueuedPackets.QuadPart / ProfCount_SendQueuedPackets)));
   5.153 -    KdPrint((__DRIVER_NAME "     TxBufferGC        Count = %10d, Avg Time     = %10ld\n", ProfCount_TxBufferGC, (ProfCount_TxBufferGC == 0)?0:(ProfTime_TxBufferGC.QuadPart / ProfCount_TxBufferGC)));
   5.154 -    KdPrint((__DRIVER_NAME "     RxPackets         Total = %10d, Csum Offload = %10d, Calls To Receive = %10d\n", ProfCount_RxPacketsTotal, ProfCount_RxPacketsCsumOffload, ProfCount_CallsToIndicateReceive));
   5.155 -    KdPrint((__DRIVER_NAME "     TxPackets         Total = %10d, Csum Offload = %10d, Large Offload    = %10d\n", ProfCount_TxPacketsTotal, ProfCount_TxPacketsCsumOffload, ProfCount_TxPacketsLargeOffload));
   5.156 +    if (xi->tx_mdls[i])
   5.157 +    {
   5.158 +      XenFreelist_PutPage(&xi->tx_freelist, xi->tx_mdls[i]);
   5.159 +      xi->tx_mdls[i] = NULL;
   5.160 +    }
   5.161 +    /* this may result in packets being sent out of order... I don't think it matters though */
   5.162 +    if (xi->tx_pkts[i])
   5.163 +    {
   5.164 +      *(ULONG *)&xi->tx_pkts[i]->MiniportReservedEx = 0;
   5.165 +      entry = (PLIST_ENTRY)&xi->tx_pkts[i]->MiniportReservedEx[sizeof(PVOID)];
   5.166 +      InsertTailList(&xi->tx_waiting_pkt_list, entry);
   5.167 +      xi->tx_pkts[i] = 0;
   5.168 +    }
   5.169    }
   5.170 -#endif
   5.171 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   5.172 +  XenFreelist_ResumeStart(&xi->tx_freelist);
   5.173 +  xi->tx_id_free = 0;
   5.174 +  xi->tx_no_id_used = 0;
   5.175 +  for (i = 0; i < NET_TX_RING_SIZE; i++)
   5.176 +    put_id_on_freelist(xi, (USHORT)i);
   5.177 +  KeReleaseSpinLock(&xi->tx_lock, old_irql);
   5.178 +}
   5.179 +
   5.180 +VOID
   5.181 +XenNet_TxResumeEnd(xennet_info_t *xi)
   5.182 +{
   5.183 +  KIRQL old_irql;
   5.184 +
   5.185 +  KeAcquireSpinLock(&xi->tx_lock, &old_irql);
   5.186 +  XenFreelist_ResumeEnd(&xi->tx_freelist);
   5.187 +  XenNet_SendQueuedPackets(xi);
   5.188 +  KeReleaseSpinLock(&xi->tx_lock, old_irql);
   5.189  }
   5.190  
   5.191  BOOLEAN
     6.1 --- a/xenpci/evtchn.c	Thu Jun 26 16:55:43 2008 +1000
     6.2 +++ b/xenpci/evtchn.c	Sun Jun 29 22:46:40 2008 +1000
     6.3 @@ -120,8 +120,7 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
     6.4    unsigned int port;
     6.5    ev_action_t *ev_action;
     6.6  
     6.7 -if (xpdd->suspending)
     6.8 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", cpu));
     6.9 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", cpu));
    6.10  
    6.11    UNREFERENCED_PARAMETER(Interrupt);
    6.12  
    6.13 @@ -155,8 +154,7 @@ if (xpdd->suspending)
    6.14      }
    6.15    }
    6.16  
    6.17 -if (xpdd->suspending)
    6.18 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    6.19 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    6.20  
    6.21    return TRUE;
    6.22  }
    6.23 @@ -365,16 +363,10 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
    6.24    return status;
    6.25  }
    6.26  
    6.27 -VOID
    6.28 -EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd)
    6.29 -{
    6.30 -  EvtChn_Connect(xpdd);
    6.31 -}
    6.32 -
    6.33  NTSTATUS
    6.34  EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd)
    6.35  {
    6.36 -  UNREFERENCED_PARAMETER(xpdd);
    6.37 +  IoDisconnectInterrupt(xpdd->interrupt);
    6.38  
    6.39    return STATUS_SUCCESS;
    6.40  }
     7.1 --- a/xenpci/xenpci_fdo.c	Thu Jun 26 16:55:43 2008 +1000
     7.2 +++ b/xenpci/xenpci_fdo.c	Sun Jun 29 22:46:40 2008 +1000
     7.3 @@ -321,6 +321,8 @@ XenPci_CompleteResume(PDEVICE_OBJECT dev
     7.4      // how can we signal children that they are ready to restart again?
     7.5    }
     7.6  
     7.7 +  xpdd->suspending = 0;
     7.8 +
     7.9    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    7.10  }
    7.11  
    7.12 @@ -329,6 +331,7 @@ struct {
    7.13    volatile LONG nr_spinning;
    7.14  } typedef SUSPEND_INFO, *PSUSPEND_INFO;
    7.15  
    7.16 +/* Called at DISPATCH_LEVEL */
    7.17  static VOID
    7.18  XenPci_Suspend(
    7.19    PRKDPC Dpc,
    7.20 @@ -341,7 +344,6 @@ XenPci_Suspend(
    7.21    ULONG ActiveProcessorCount;
    7.22    KIRQL old_irql;
    7.23    int cancelled;
    7.24 -  int i;
    7.25    PIO_WORKITEM work_item;
    7.26    PXEN_CHILD child;
    7.27    //PUCHAR gnttbl_backup[PAGE_SIZE * NR_GRANT_FRAMES];
    7.28 @@ -389,8 +391,9 @@ XenPci_Suspend(
    7.29    XenPci_Init(xpdd);
    7.30    
    7.31    GntTbl_Map(Context, 0, NR_GRANT_FRAMES - 1);
    7.32 -  
    7.33 -  EvtChn_Resume(xpdd);
    7.34 +
    7.35 +  /* this enabled interrupts again too */  
    7.36 +  EvtChn_Init(xpdd);
    7.37  
    7.38    //memcpy(xpdd->gnttab_table, gnttbl_backup, PAGE_SIZE * NR_GRANT_FRAMES);
    7.39  
    7.40 @@ -409,12 +412,6 @@ XenPci_Suspend(
    7.41    }
    7.42    KdPrint((__DRIVER_NAME "     all other processors have stopped spinning\n"));
    7.43  
    7.44 -  // enable xen interrupts again
    7.45 -  for (i = 0; i < MAX_VIRT_CPUS; i++)
    7.46 -  {
    7.47 -    xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 0;
    7.48 -  }
    7.49 -
    7.50  	work_item = IoAllocateWorkItem(xpdd->common.fdo);
    7.51  	IoQueueWorkItem(work_item, XenPci_CompleteResume, DelayedWorkQueue, NULL);
    7.52    
    7.53 @@ -441,14 +438,14 @@ XenPci_BeginSuspend(PXENPCI_DEVICE_DATA 
    7.54      suspend_info->do_spin = 1;
    7.55      RtlZeroMemory(suspend_info, sizeof(SUSPEND_INFO));
    7.56  
    7.57 -    // TODO: Disable all our devices  
    7.58 -    // TODO: Disable xenbus
    7.59 +    // I think we need to synchronise with the interrupt here...
    7.60  
    7.61      for (i = 0; i < MAX_VIRT_CPUS; i++)
    7.62      {
    7.63        xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
    7.64      }
    7.65      KeMemoryBarrier();
    7.66 +    EvtChn_Shutdown(xpdd);
    7.67      KeFlushQueuedDpcs();
    7.68  
    7.69      //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask); // this is for Vista+
    7.70 @@ -575,11 +572,11 @@ XenPci_DeviceWatchHandler(char *path, PV
    7.71    char *value;
    7.72    PXENPCI_DEVICE_DATA xpdd = context;
    7.73  
    7.74 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    7.75 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    7.76  
    7.77 -  KdPrint((__DRIVER_NAME "     path = %s\n", path));
    7.78 +//  KdPrint((__DRIVER_NAME "     path = %s\n", path));
    7.79    bits = SplitString(path, '/', 4, &count);
    7.80 -  KdPrint((__DRIVER_NAME "     count = %d\n", count));
    7.81 +//  KdPrint((__DRIVER_NAME "     count = %d\n", count));
    7.82  
    7.83    if (count == 3)
    7.84    {
    7.85 @@ -599,7 +596,7 @@ XenPci_DeviceWatchHandler(char *path, PV
    7.86    }
    7.87    FreeSplitString(bits, count);
    7.88  
    7.89 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    7.90 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    7.91  }
    7.92  
    7.93  static VOID
     8.1 --- a/xenpci/xenpci_pdo.c	Thu Jun 26 16:55:43 2008 +1000
     8.2 +++ b/xenpci/xenpci_pdo.c	Sun Jun 29 22:46:40 2008 +1000
     8.3 @@ -691,7 +691,7 @@ XenPci_Resume(PDEVICE_OBJECT device_obje
     8.4      if (xppdd->assigned_resources_ptr)
     8.5      {
     8.6        // reset things - feed the 'requested resources' back in
     8.7 -      ADD_XEN_INIT_RSP(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
     8.8 +      ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
     8.9        src = xppdd->requested_resources_start;
    8.10        xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, XENPCI_POOL_TAG);;
    8.11        xppdd->assigned_resources_ptr = xppdd->assigned_resources_start;
     9.1 --- a/xenvbd/scsiport.c	Thu Jun 26 16:55:43 2008 +1000
     9.2 +++ b/xenvbd/scsiport.c	Sun Jun 29 22:46:40 2008 +1000
     9.3 @@ -373,6 +373,12 @@ XenVbd_HwScsiTimer(PVOID DeviceExtension
     9.4      }
     9.5      
     9.6      xvdd->device_state->resume_state = RESUME_STATE_RUNNING;
     9.7 +    
     9.8 +    if (i == 0)
     9.9 +    {
    9.10 +      /* no requests, so we might need to tell scsiport that we can accept a new one if we deferred one earlier */
    9.11 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
    9.12 +    }
    9.13    }
    9.14    
    9.15    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, RESUME_CHECK_TIMER_INTERVAL);
    9.16 @@ -762,6 +768,14 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
    9.17      return TRUE;
    9.18    }
    9.19  
    9.20 +  if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
    9.21 +  {
    9.22 +    Srb->SrbStatus = SRB_STATUS_BUSY;
    9.23 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
    9.24 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Resuming)\n"));
    9.25 +    return TRUE;
    9.26 +  }
    9.27 +
    9.28    if (Srb->PathId != 0 || Srb->TargetId != 0)
    9.29    {
    9.30      Srb->SrbStatus = SRB_STATUS_NO_DEVICE;