win-pvdrivers

changeset 351:b827e78992a3

Automated merge with ssh://win-pvdrivers@xenbits.xensource.com/win-pvdrivers.hg
author Andy Grover <andy.grover@oracle.com>
date Tue Jul 01 15:30:44 2008 -0700 (2008-07-01)
parents 6b41ede6aec5 6cfd70daada3
children 961762808bab
files xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c
line diff
     1.1 --- a/common/include/xen_public.h	Tue Jul 01 15:24:49 2008 -0700
     1.2 +++ b/common/include/xen_public.h	Tue Jul 01 15:30:44 2008 -0700
     1.3 @@ -115,8 +115,19 @@ typedef struct {
     1.4    PXEN_GNTTBL_ENDACCESS GntTbl_EndAccess;
     1.5    PXEN_XENPCI_XEN_CONFIG_DEVICE XenPci_XenConfigDevice;
     1.6    PXEN_XENPCI_XEN_SHUTDOWN_DEVICE XenPci_XenShutdownDevice;
     1.7 +
     1.8  } XENPCI_VECTORS, *PXENPCI_VECTORS;
     1.9  
    1.10 +#define RESUME_STATE_RUNNING            0
    1.11 +#define RESUME_STATE_BACKEND_RESUME     1
    1.12 +#define RESUME_STATE_FRONTEND_RESUME    2
    1.13 +
    1.14 +typedef struct {
    1.15 +  ULONG magic;
    1.16 +  USHORT length;
    1.17 +
    1.18 +  ULONG resume_state;
    1.19 +} XENPCI_DEVICE_STATE, *PXENPCI_DEVICE_STATE;
    1.20  
    1.21  #define XEN_INIT_TYPE_END               0
    1.22  #define XEN_INIT_TYPE_WRITE_STRING      1
    1.23 @@ -129,11 +140,12 @@ typedef struct {
    1.24  #define XEN_INIT_TYPE_GRANT_ENTRIES     8
    1.25  //#define XEN_INIT_TYPE_COPY_PTR          9
    1.26  #define XEN_INIT_TYPE_RUN               10
    1.27 +#define XEN_INIT_TYPE_STATE_PTR         11
    1.28  
    1.29  static __inline VOID
    1.30  __ADD_XEN_INIT_UCHAR(PUCHAR *ptr, UCHAR val)
    1.31  {
    1.32 -  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_UCHAR *ptr = %p, val = %d\n", *ptr, val));
    1.33 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_UCHAR *ptr = %p, val = %d\n", *ptr, val));
    1.34    *(PUCHAR)(*ptr) = val;
    1.35    *ptr += sizeof(UCHAR);
    1.36  }
    1.37 @@ -141,7 +153,7 @@ static __inline VOID
    1.38  static __inline VOID
    1.39  __ADD_XEN_INIT_USHORT(PUCHAR *ptr, USHORT val)
    1.40  {
    1.41 -  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_USHORT *ptr = %p, val = %d\n", *ptr, val));
    1.42 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_USHORT *ptr = %p, val = %d\n", *ptr, val));
    1.43    *(PUSHORT)(*ptr) = val;
    1.44    *ptr += sizeof(USHORT);
    1.45  }
    1.46 @@ -149,7 +161,7 @@ static __inline VOID
    1.47  static __inline VOID
    1.48  __ADD_XEN_INIT_ULONG(PUCHAR *ptr, ULONG val)
    1.49  {
    1.50 -  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_ULONG *ptr = %p, val = %d\n", *ptr, val));
    1.51 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_ULONG *ptr = %p, val = %d\n", *ptr, val));
    1.52    *(PULONG)(*ptr) = val;
    1.53    *ptr += sizeof(ULONG);
    1.54  }
    1.55 @@ -157,7 +169,7 @@ static __inline VOID
    1.56  static __inline VOID
    1.57  __ADD_XEN_INIT_PTR(PUCHAR *ptr, PVOID val)
    1.58  {
    1.59 -  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_PTR *ptr = %p, val = %p\n", *ptr, val));
    1.60 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_PTR *ptr = %p, val = %p\n", *ptr, val));
    1.61    *(PVOID *)(*ptr) = val;
    1.62    *ptr += sizeof(PVOID);
    1.63  }
    1.64 @@ -165,7 +177,7 @@ static __inline VOID
    1.65  static __inline VOID
    1.66  __ADD_XEN_INIT_STRING(PUCHAR *ptr, PCHAR val)
    1.67  {
    1.68 -  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_STRING *ptr = %p, val = %s\n", *ptr, val));
    1.69 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_STRING *ptr = %p, val = %s\n", *ptr, val));
    1.70    RtlStringCbCopyA((PCHAR)*ptr, PAGE_SIZE - (PtrToUlong(*ptr) & (PAGE_SIZE - 1)), val);
    1.71    *ptr += strlen(val) + 1;
    1.72  }
    1.73 @@ -175,7 +187,7 @@ static __inline UCHAR
    1.74  {
    1.75    UCHAR retval;
    1.76    retval = **ptr;
    1.77 -  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_UCHAR *ptr = %p, retval = %d\n", *ptr, retval));
    1.78 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_UCHAR *ptr = %p, retval = %d\n", *ptr, retval));
    1.79    *ptr += sizeof(UCHAR);
    1.80    return retval;
    1.81  }
    1.82 @@ -185,7 +197,7 @@ static __inline USHORT
    1.83  {
    1.84    USHORT retval;
    1.85    retval = *(PUSHORT)*ptr;
    1.86 -  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_USHORT *ptr = %p, retval = %d\n", *ptr, retval));
    1.87 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_USHORT *ptr = %p, retval = %d\n", *ptr, retval));
    1.88    *ptr += sizeof(USHORT);
    1.89    return retval;
    1.90  }
    1.91 @@ -195,7 +207,7 @@ static __inline ULONG
    1.92  {
    1.93    ULONG retval;
    1.94    retval = *(PLONG)*ptr;
    1.95 -  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_ULONG *ptr = %p, retval = %d\n", *ptr, retval));
    1.96 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_ULONG *ptr = %p, retval = %d\n", *ptr, retval));
    1.97    *ptr += sizeof(ULONG);
    1.98    return retval;
    1.99  }
   1.100 @@ -205,7 +217,7 @@ static __inline PCHAR
   1.101  {
   1.102    PCHAR retval;
   1.103    retval = (PCHAR)*ptr;
   1.104 -  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_STRING *ptr = %p, retval = %s\n", *ptr, retval));
   1.105 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_STRING *ptr = %p, retval = %s\n", *ptr, retval));
   1.106    *ptr += strlen((PCHAR)*ptr) + 1;
   1.107    return retval;
   1.108  }
   1.109 @@ -215,7 +227,7 @@ static __inline PVOID
   1.110  {
   1.111    PVOID retval;
   1.112    retval = *(PVOID *)(*ptr);
   1.113 -  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_PTR *ptr = %p, retval = %p\n", *ptr, retval));
   1.114 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_PTR *ptr = %p, retval = %p\n", *ptr, retval));
   1.115    *ptr += sizeof(PVOID);
   1.116    return retval;
   1.117  }
   1.118 @@ -229,6 +241,7 @@ ADD_XEN_INIT_REQ(PUCHAR *ptr, UCHAR type
   1.119    case XEN_INIT_TYPE_END:
   1.120    case XEN_INIT_TYPE_VECTORS:
   1.121    case XEN_INIT_TYPE_RUN:
   1.122 +  case XEN_INIT_TYPE_STATE_PTR:
   1.123      break;
   1.124    case XEN_INIT_TYPE_WRITE_STRING:
   1.125      __ADD_XEN_INIT_STRING(ptr, p1);
   1.126 @@ -261,6 +274,7 @@ GET_XEN_INIT_REQ(PUCHAR *ptr, PVOID *p1,
   1.127    case XEN_INIT_TYPE_END:
   1.128    case XEN_INIT_TYPE_VECTORS:
   1.129    case XEN_INIT_TYPE_RUN:
   1.130 +  case XEN_INIT_TYPE_STATE_PTR:
   1.131      *p1 = NULL;
   1.132      *p2 = NULL;
   1.133      break;
   1.134 @@ -320,6 +334,9 @@ ADD_XEN_INIT_RSP(PUCHAR *ptr, UCHAR type
   1.135      memcpy(*ptr, p2, PtrToUlong(p1) * sizeof(grant_entry_t));
   1.136      *ptr += PtrToUlong(p1) * sizeof(grant_entry_t);
   1.137      break;
   1.138 +  case XEN_INIT_TYPE_STATE_PTR:
   1.139 +    __ADD_XEN_INIT_PTR(ptr, p2);
   1.140 +    break;
   1.141  //  case XEN_INIT_TYPE_COPY_PTR:
   1.142  //    __ADD_XEN_INIT_STRING(ptr, p1);
   1.143  //    __ADD_XEN_INIT_PTR(ptr, p2);
   1.144 @@ -370,6 +387,9 @@ GET_XEN_INIT_RSP(PUCHAR *ptr, PVOID *p1,
   1.145      *p2 = *ptr;
   1.146      *ptr += PtrToUlong(*p1) * sizeof(grant_ref_t);
   1.147      break;
   1.148 +  case XEN_INIT_TYPE_STATE_PTR:
   1.149 +    *p2 = __GET_XEN_INIT_PTR(ptr);
   1.150 +    break;
   1.151  //  case XEN_INIT_TYPE_COPY_PTR:
   1.152  //    *p1 = __GET_XEN_INIT_STRING(ptr);
   1.153  //    *p2 = __GET_XEN_INIT_PTR(ptr);
     2.1 --- a/xenhide/xenhide.c	Tue Jul 01 15:24:49 2008 -0700
     2.2 +++ b/xenhide/xenhide.c	Tue Jul 01 15:30:44 2008 -0700
     2.3 @@ -187,7 +187,7 @@ XenHide_IdSuffixMatches(PDEVICE_OBJECT p
     2.4        
     2.5      if (!NT_SUCCESS(status))
     2.6      {
     2.7 -      KdPrint((__DRIVER_NAME "     i = %d, status = %x, ids_length = %d\n", i, status, ids_length));
     2.8 +      //KdPrint((__DRIVER_NAME "     i = %d, status = %x, ids_length = %d\n", i, status, ids_length));
     2.9        continue;
    2.10      }
    2.11      
    2.12 @@ -201,12 +201,12 @@ XenHide_IdSuffixMatches(PDEVICE_OBJECT p
    2.13          ptr += string_length - wcslen(matching_id);
    2.14          string_length -= wcslen(matching_id);
    2.15        }
    2.16 -      KdPrint((__DRIVER_NAME "     Comparing '%S' and '%S'\n", ptr, matching_id));
    2.17 +      //KdPrint((__DRIVER_NAME "     Comparing '%S' and '%S'\n", ptr, matching_id));
    2.18        if (wcscmp(ptr, matching_id) == 0)
    2.19         return TRUE;
    2.20      }
    2.21    }
    2.22 -  KdPrint((__DRIVER_NAME "     No match\n"));  
    2.23 +  //KdPrint((__DRIVER_NAME "     No match\n"));  
    2.24    return FALSE;
    2.25  }
    2.26  
    2.27 @@ -236,7 +236,7 @@ XenHide_AddDevice(
    2.28      device_description[0] = 0;
    2.29    }
    2.30  
    2.31 -  KdPrint((__DRIVER_NAME "     Checking '%S'\n", device_description));
    2.32 +  //KdPrint((__DRIVER_NAME "     Checking '%S'\n", device_description));
    2.33  
    2.34    length = sizeof(GUID);
    2.35    status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyBusTypeGuid, length, &bus_type, &length);
    2.36 @@ -391,7 +391,7 @@ XenHide_Pnp(PDEVICE_OBJECT device_object
    2.37    ULONG i, j;
    2.38    KIRQL old_irql;
    2.39  
    2.40 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.41 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.42  
    2.43    stack = IoGetCurrentIrpStackLocation(irp);
    2.44  
    2.45 @@ -453,7 +453,7 @@ XenHide_Pnp(PDEVICE_OBJECT device_object
    2.46      break;
    2.47    }
    2.48  
    2.49 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (returning with status %08x)\n", status));
    2.50 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (returning with status %08x)\n", status));
    2.51  
    2.52    return status;
    2.53  }
     3.1 --- a/xennet/xennet.c	Tue Jul 01 15:24:49 2008 -0700
     3.2 +++ b/xennet/xennet.c	Tue Jul 01 15:30:44 2008 -0700
     3.3 @@ -110,8 +110,117 @@ XenNet_InterruptDpc(NDIS_HANDLE  Minipor
     3.4    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
     3.5  }
     3.6  
     3.7 +static NDIS_STATUS
     3.8 +XenNet_ConnectBackend(struct xennet_info *xi)
     3.9 +{
    3.10 +  PUCHAR ptr;
    3.11 +  UCHAR type;
    3.12 +  PCHAR setting, value;
    3.13 +  UINT i;
    3.14 +
    3.15 +  ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    3.16 +
    3.17 +  ptr = xi->config_page;
    3.18 +  while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value)) != XEN_INIT_TYPE_END)
    3.19 +  {
    3.20 +    switch(type)
    3.21 +    {
    3.22 +    case XEN_INIT_TYPE_RING: /* frontend ring */
    3.23 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
    3.24 +      if (strcmp(setting, "tx-ring-ref") == 0)
    3.25 +      {
    3.26 +        FRONT_RING_INIT(&xi->tx, (netif_tx_sring_t *)value, PAGE_SIZE);
    3.27 +      } else if (strcmp(setting, "rx-ring-ref") == 0)
    3.28 +      {
    3.29 +        FRONT_RING_INIT(&xi->rx, (netif_rx_sring_t *)value, PAGE_SIZE);
    3.30 +      }
    3.31 +      break;
    3.32 +    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */
    3.33 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
    3.34 +      if (strcmp(setting, "event-channel") == 0)
    3.35 +      {
    3.36 +        xi->event_channel = PtrToUlong(value);
    3.37 +      }
    3.38 +      break;
    3.39 +    case XEN_INIT_TYPE_READ_STRING_BACK:
    3.40 +    case XEN_INIT_TYPE_READ_STRING_FRONT:
    3.41 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
    3.42 +      if (strcmp(setting, "mac") == 0)
    3.43 +      {
    3.44 +        char *s, *e;
    3.45 +        s = value;
    3.46 +        for (i = 0; i < ETH_ALEN; i++) {
    3.47 +          xi->perm_mac_addr[i] = (UINT8)simple_strtoul(s, &e, 16);
    3.48 +          if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
    3.49 +            KdPrint((__DRIVER_NAME "Error parsing MAC address\n"));
    3.50 +          }
    3.51 +          s = e + 1;
    3.52 +        }
    3.53 +        memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
    3.54 +      }
    3.55 +      break;
    3.56 +    case XEN_INIT_TYPE_VECTORS:
    3.57 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
    3.58 +      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
    3.59 +        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
    3.60 +      {
    3.61 +        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
    3.62 +          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
    3.63 +        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    3.64 +        return NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
    3.65 +      }
    3.66 +      else
    3.67 +        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
    3.68 +      break;
    3.69 +    default:
    3.70 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
    3.71 +      break;
    3.72 +    }
    3.73 +  }
    3.74 +  return NDIS_STATUS_SUCCESS;
    3.75 +}
    3.76 +
    3.77 +static VOID
    3.78 +XenNet_Resume(PDEVICE_OBJECT device_object, PVOID context)
    3.79 +{
    3.80 +  struct xennet_info *xi = context;
    3.81 +  
    3.82 +  UNREFERENCED_PARAMETER(device_object);
    3.83 +  
    3.84 +  XenNet_RxResumeStart(xi);
    3.85 +  XenNet_TxResumeStart(xi);
    3.86 +  XenNet_ConnectBackend(xi);
    3.87 +  xi->device_state->resume_state = RESUME_STATE_RUNNING;
    3.88 +  XenNet_RxResumeEnd(xi);
    3.89 +  XenNet_TxResumeEnd(xi);
    3.90 +  NdisMSetPeriodicTimer(&xi->resume_timer, 100);
    3.91 +}
    3.92 +
    3.93 +static VOID 
    3.94 +XenResumeCheck_Timer(
    3.95 + PVOID SystemSpecific1,
    3.96 + PVOID FunctionContext,
    3.97 + PVOID SystemSpecific2,
    3.98 + PVOID SystemSpecific3
    3.99 +)
   3.100 +{
   3.101 +  struct xennet_info *xi = FunctionContext;
   3.102 +  PIO_WORKITEM work_item;
   3.103 +  BOOLEAN timer_cancelled;
   3.104 + 
   3.105 +  UNREFERENCED_PARAMETER(SystemSpecific1);
   3.106 +  UNREFERENCED_PARAMETER(SystemSpecific2);
   3.107 +  UNREFERENCED_PARAMETER(SystemSpecific3);
   3.108 + 
   3.109 +  if (xi->device_state->resume_state == RESUME_STATE_FRONTEND_RESUME)
   3.110 +  {
   3.111 +    NdisMCancelTimer(&xi->resume_timer, &timer_cancelled);
   3.112 +  	work_item = IoAllocateWorkItem(xi->fdo);
   3.113 +  	IoQueueWorkItem(work_item, XenNet_Resume, DelayedWorkQueue, xi);
   3.114 +  }
   3.115 +}
   3.116 +
   3.117  // Called at <= DISPATCH_LEVEL
   3.118 -
   3.119  static NDIS_STATUS
   3.120  XenNet_Init(
   3.121    OUT PNDIS_STATUS OpenErrorStatus,
   3.122 @@ -123,7 +232,6 @@ XenNet_Init(
   3.123    )
   3.124  {
   3.125    NDIS_STATUS status;
   3.126 -  UINT i, j;
   3.127    BOOLEAN medium_found = FALSE;
   3.128    struct xennet_info *xi = NULL;
   3.129    ULONG nrl_length;
   3.130 @@ -131,13 +239,14 @@ XenNet_Init(
   3.131    PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
   3.132    KIRQL irq_level = 0;
   3.133    ULONG irq_vector = 0;
   3.134 -  UCHAR type;
   3.135 -  PUCHAR ptr;
   3.136 -  PCHAR setting, value;
   3.137 -  ULONG length;
   3.138    NDIS_HANDLE config_handle;
   3.139    NDIS_STRING config_param_name;
   3.140    PNDIS_CONFIGURATION_PARAMETER config_param;
   3.141 +  ULONG i;
   3.142 +  PUCHAR ptr;
   3.143 +  UCHAR type;
   3.144 +  PCHAR setting, value;
   3.145 +  ULONG length;
   3.146    CHAR buf[128];
   3.147    
   3.148    UNREFERENCED_PARAMETER(OpenErrorStatus);
   3.149 @@ -284,6 +393,10 @@ XenNet_Init(
   3.150        else
   3.151          memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
   3.152        break;
   3.153 +    case XEN_INIT_TYPE_STATE_PTR:
   3.154 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   3.155 +      xi->device_state = (PXENPCI_DEVICE_STATE)value;
   3.156 +      break;
   3.157      default:
   3.158        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   3.159        break;
   3.160 @@ -379,63 +492,7 @@ XenNet_Init(
   3.161    status = xi->vectors.XenPci_XenConfigDevice(xi->vectors.context);
   3.162    // check return value
   3.163  
   3.164 -  ptr = xi->config_page;
   3.165 -  while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value)) != XEN_INIT_TYPE_END)
   3.166 -  {
   3.167 -    switch(type)
   3.168 -    {
   3.169 -    case XEN_INIT_TYPE_RING: /* frontend ring */
   3.170 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
   3.171 -      if (strcmp(setting, "tx-ring-ref") == 0)
   3.172 -      {
   3.173 -        FRONT_RING_INIT(&xi->tx, (netif_tx_sring_t *)value, PAGE_SIZE);
   3.174 -      } else if (strcmp(setting, "rx-ring-ref") == 0)
   3.175 -      {
   3.176 -        FRONT_RING_INIT(&xi->rx, (netif_rx_sring_t *)value, PAGE_SIZE);
   3.177 -      }
   3.178 -      break;
   3.179 -    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */
   3.180 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
   3.181 -      if (strcmp(setting, "event-channel") == 0)
   3.182 -      {
   3.183 -        xi->event_channel = PtrToUlong(value);
   3.184 -      }
   3.185 -      break;
   3.186 -    case XEN_INIT_TYPE_READ_STRING_BACK:
   3.187 -    case XEN_INIT_TYPE_READ_STRING_FRONT:
   3.188 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   3.189 -      if (strcmp(setting, "mac") == 0)
   3.190 -      {
   3.191 -        char *s, *e;
   3.192 -        s = value;
   3.193 -        for (j = 0; j < ETH_ALEN; j++) {
   3.194 -          xi->perm_mac_addr[j] = (UINT8)simple_strtoul(s, &e, 16);
   3.195 -          if ((s == e) || (*e != ((j == ETH_ALEN-1) ? '\0' : ':'))) {
   3.196 -            KdPrint((__DRIVER_NAME "Error parsing MAC address\n"));
   3.197 -          }
   3.198 -          s = e + 1;
   3.199 -        }
   3.200 -        memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN);
   3.201 -      }
   3.202 -      break;
   3.203 -    case XEN_INIT_TYPE_VECTORS:
   3.204 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   3.205 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   3.206 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   3.207 -      {
   3.208 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   3.209 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   3.210 -        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.211 -        return NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
   3.212 -      }
   3.213 -      else
   3.214 -        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
   3.215 -      break;
   3.216 -    default:
   3.217 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   3.218 -      break;
   3.219 -    }
   3.220 -  }
   3.221 +  status = XenNet_ConnectBackend(xi);
   3.222    
   3.223    KeInitializeEvent(&xi->shutdown_event, SynchronizationEvent, FALSE);  
   3.224  
   3.225 @@ -456,6 +513,9 @@ XenNet_Init(
   3.226      //goto err;
   3.227    }
   3.228  
   3.229 +  NdisMInitializeTimer(&xi->resume_timer, xi->adapter_handle, XenResumeCheck_Timer, xi);
   3.230 +  NdisMSetPeriodicTimer(&xi->resume_timer, 100);
   3.231 +
   3.232    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.233  
   3.234    return NDIS_STATUS_SUCCESS;
     4.1 --- a/xennet/xennet.h	Tue Jul 01 15:24:49 2008 -0700
     4.2 +++ b/xennet/xennet.h	Tue Jul 01 15:30:44 2008 -0700
     4.3 @@ -146,6 +146,7 @@ typedef struct
     4.4    ULONG page_free_target;
     4.5    NDIS_MINIPORT_TIMER timer;
     4.6    PKSPIN_LOCK lock;
     4.7 +  BOOLEAN grants_resumed;
     4.8  } freelist_t;
     4.9  
    4.10  struct xennet_info
    4.11 @@ -168,9 +169,8 @@ struct xennet_info
    4.12    UINT8 curr_mac_addr[ETH_ALEN];
    4.13  
    4.14    /* Misc. Xen vars */
    4.15 -  //XEN_IFACE XenInterface;
    4.16 -  //PXENPCI_XEN_DEVICE_DATA pdo_data;
    4.17    XENPCI_VECTORS vectors;
    4.18 +  PXENPCI_DEVICE_STATE device_state;
    4.19    evtchn_port_t event_channel;
    4.20    ULONG state;
    4.21    KEVENT shutdown_event;
    4.22 @@ -195,7 +195,7 @@ struct xennet_info
    4.23    /* rx_related - protected by rx_lock */
    4.24    struct netif_rx_front_ring rx;
    4.25    ULONG rx_id_free;
    4.26 -  PNDIS_BUFFER rx_buffers[NET_RX_RING_SIZE];
    4.27 +  PNDIS_BUFFER rx_mdls[NET_RX_RING_SIZE];
    4.28    freelist_t rx_freelist;
    4.29    packet_info_t rxpi;
    4.30    PNDIS_PACKET rx_packet_list[NET_RX_RING_SIZE * 2];
    4.31 @@ -221,6 +221,8 @@ struct xennet_info
    4.32    /* config stuff calculated from the above */
    4.33    ULONG config_max_pkt_size;
    4.34  
    4.35 +  NDIS_MINIPORT_TIMER resume_timer;
    4.36 +
    4.37    /* stats */
    4.38    ULONG64 stat_tx_ok;
    4.39    ULONG64 stat_rx_ok;
    4.40 @@ -275,10 +277,22 @@ XenNet_RxInit(xennet_info_t *xi);
    4.41  BOOLEAN
    4.42  XenNet_RxShutdown(xennet_info_t *xi);
    4.43  
    4.44 +VOID
    4.45 +XenNet_RxResumeStart(xennet_info_t *xi);
    4.46 +
    4.47 +VOID
    4.48 +XenNet_RxResumeEnd(xennet_info_t *xi);
    4.49 +
    4.50  NDIS_STATUS
    4.51  XenNet_TxBufferGC(struct xennet_info *xi);
    4.52  
    4.53  VOID
    4.54 +XenNet_TxResumeStart(xennet_info_t *xi);
    4.55 +
    4.56 +VOID
    4.57 +XenNet_TxResumeEnd(xennet_info_t *xi);
    4.58 +
    4.59 +VOID
    4.60  XenNet_SendPackets(
    4.61    IN NDIS_HANDLE MiniportAdapterContext,
    4.62    IN PPNDIS_PACKET PacketArray,
    4.63 @@ -348,3 +362,7 @@ VOID
    4.64  XenFreelist_PutPage(freelist_t *fl, PMDL mdl);
    4.65  VOID
    4.66  XenFreelist_Dispose(freelist_t *fl);
    4.67 +VOID
    4.68 +XenFreelist_ResumeStart(freelist_t *fl);
    4.69 +VOID
    4.70 +XenFreelist_ResumeEnd(freelist_t *fl);
     5.1 --- a/xennet/xennet_common.c	Tue Jul 01 15:24:49 2008 -0700
     5.2 +++ b/xennet/xennet_common.c	Tue Jul 01 15:30:44 2008 -0700
     5.3 @@ -143,7 +143,7 @@ XenNet_GetData(
     5.4    return buffer;
     5.5  }
     5.6  
     5.7 -
     5.8 +/* Called at DISPATCH LEVEL */
     5.9  static VOID 
    5.10  XenFreelist_Timer(
    5.11    PVOID SystemSpecific1,
    5.12 @@ -160,6 +160,9 @@ XenFreelist_Timer(
    5.13    UNREFERENCED_PARAMETER(SystemSpecific2);
    5.14    UNREFERENCED_PARAMETER(SystemSpecific3);
    5.15  
    5.16 +  if (fl->xi->device_state->resume_state != RESUME_STATE_RUNNING && !fl->grants_resumed)
    5.17 +    return;
    5.18 +    
    5.19    KeAcquireSpinLockAtDpcLevel(fl->lock);
    5.20  
    5.21    //KdPrint((__DRIVER_NAME " --- timer - page_free_lowest = %d\n", fl->page_free_lowest));
    5.22 @@ -192,6 +195,7 @@ XenFreelist_Init(struct xennet_info *xi,
    5.23    fl->page_free = 0;
    5.24    fl->page_free_lowest = 0;
    5.25    fl->page_free_target = 16; /* tune this */
    5.26 +  fl->grants_resumed = FALSE;
    5.27    NdisMInitializeTimer(&fl->timer, fl->xi->adapter_handle, XenFreelist_Timer, fl);
    5.28    NdisMSetPeriodicTimer(&fl->timer, 1000);
    5.29  }
    5.30 @@ -209,6 +213,7 @@ XenFreelist_GetPage(freelist_t *fl)
    5.31      *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = fl->xi->vectors.GntTbl_GrantAccess(
    5.32        fl->xi->vectors.context, 0,
    5.33        (uint32_t)pfn, FALSE, 0);
    5.34 +    /* we really should check if our grant was successful... */
    5.35    }
    5.36    else
    5.37    {
    5.38 @@ -245,3 +250,32 @@ XenFreelist_Dispose(freelist_t *fl)
    5.39      FreePages(mdl);
    5.40    }
    5.41  }
    5.42 +
    5.43 +static VOID
    5.44 +XenFreelist_ReGrantMdl(freelist_t *fl, PMDL mdl)
    5.45 +{
    5.46 +  PFN_NUMBER pfn;
    5.47 +  pfn = *MmGetMdlPfnArray(mdl);
    5.48 +  *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = fl->xi->vectors.GntTbl_GrantAccess(
    5.49 +    fl->xi->vectors.context, 0,
    5.50 +    (uint32_t)pfn, FALSE, 0);
    5.51 +}
    5.52 +
    5.53 +/* re-grant all the pages, as the grant table was wiped on resume */
    5.54 +VOID
    5.55 +XenFreelist_ResumeStart(freelist_t *fl)
    5.56 +{
    5.57 +  ULONG i;
    5.58 +  
    5.59 +  for (i = 0; i < fl->page_free; i++)
    5.60 +  {
    5.61 +    XenFreelist_ReGrantMdl(fl, fl->page_list[i]);
    5.62 +  }
    5.63 +  fl->grants_resumed = TRUE;
    5.64 +}
    5.65 +
    5.66 +VOID
    5.67 +XenFreelist_ResumeEnd(freelist_t *fl)
    5.68 +{
    5.69 +  fl->grants_resumed = FALSE;
    5.70 +}
     6.1 --- a/xennet/xennet_rx.c	Tue Jul 01 15:24:49 2008 -0700
     6.2 +++ b/xennet/xennet_rx.c	Tue Jul 01 15:30:44 2008 -0700
     6.3 @@ -62,8 +62,8 @@ XenNet_RxBufferAlloc(struct xennet_info 
     6.4      /* Give to netback */
     6.5      id = (USHORT)((req_prod + i) & (NET_RX_RING_SIZE - 1));
     6.6  //    KdPrint((__DRIVER_NAME "     id = %d\n", id));
     6.7 -    ASSERT(xi->rx_buffers[id] == NULL);
     6.8 -    xi->rx_buffers[id] = mdl;
     6.9 +    ASSERT(xi->rx_mdls[id] == NULL);
    6.10 +    xi->rx_mdls[id] = mdl;
    6.11      req = RING_GET_REQUEST(&xi->rx, req_prod + i);
    6.12      req->gref = get_grant_ref(mdl);
    6.13      req->id = id;
    6.14 @@ -365,19 +365,9 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.15    struct netif_rx_response *rxrsp = NULL;
    6.16    struct netif_extra_info *ei;
    6.17    USHORT id;
    6.18 -#if DBG
    6.19 -  int cycles = 0;
    6.20 -#endif
    6.21 -#if defined(XEN_PROFILE)
    6.22 -  LARGE_INTEGER tsc, dummy;
    6.23 -#endif
    6.24    
    6.25  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.26  
    6.27 -#if defined(XEN_PROFILE)
    6.28 -  tsc = KeQueryPerformanceCounter(&dummy);
    6.29 -#endif
    6.30 -
    6.31    ASSERT(xi->connected);
    6.32  
    6.33    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    6.34 @@ -385,17 +375,15 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.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));
    6.36      
    6.37    do {
    6.38 -    ASSERT(cycles++ < 256);
    6.39      prod = xi->rx.sring->rsp_prod;
    6.40      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
    6.41  
    6.42      for (cons = xi->rx.rsp_cons; cons != prod && packet_count < MAXIMUM_PACKETS_PER_INDICATE; cons++)
    6.43      {
    6.44 -      ASSERT(cycles++ < 256);
    6.45        id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
    6.46 -      ASSERT(xi->rx_buffers[id]);
    6.47 -      mdl = xi->rx_buffers[id];
    6.48 -      xi->rx_buffers[id] = NULL;
    6.49 +      ASSERT(xi->rx_mdls[id]);
    6.50 +      mdl = xi->rx_mdls[id];
    6.51 +      xi->rx_mdls[id] = NULL;
    6.52        xi->rx_id_free++;
    6.53        if (xi->rxpi.extra_info)
    6.54        {
    6.55 @@ -464,9 +452,6 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.56      {
    6.57        KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    6.58        NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
    6.59 -#if defined(XEN_PROFILE)
    6.60 -      ProfCount_CallsToIndicateReceive++;
    6.61 -#endif
    6.62        KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
    6.63        total_packets += packet_count;
    6.64        packet_count = 0;
    6.65 @@ -478,21 +463,16 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.66    /* Give netback more buffers */
    6.67    XenNet_RxBufferAlloc(xi);
    6.68  
    6.69 -if (xi->rxpi.more_frags || xi->rxpi.extra_info)
    6.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));
    6.71 +  if (xi->rxpi.more_frags || xi->rxpi.extra_info)
    6.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));
    6.73  
    6.74    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
    6.75  
    6.76 -#if defined(XEN_PROFILE)
    6.77 -  ProfTime_RxBufferCheck.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
    6.78 -  ProfCount_RxBufferCheck++;
    6.79 -#endif
    6.80 -
    6.81    return NDIS_STATUS_SUCCESS;
    6.82  }
    6.83  
    6.84  /* called at DISPATCH_LEVEL */
    6.85 -
    6.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 */
    6.87  VOID
    6.88  XenNet_ReturnPacket(
    6.89    IN NDIS_HANDLE MiniportAdapterContext,
    6.90 @@ -501,25 +481,11 @@ XenNet_ReturnPacket(
    6.91  {
    6.92    struct xennet_info *xi = MiniportAdapterContext;
    6.93    PMDL mdl;
    6.94 -#if DBG
    6.95 -  int cycles = 0;
    6.96 -#endif
    6.97 -#if defined(XEN_PROFILE)
    6.98 -  LARGE_INTEGER tsc, dummy;
    6.99 -#endif
   6.100 -
   6.101 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (%p)\n", Packet));
   6.102 -
   6.103 -#if defined(XEN_PROFILE)
   6.104 -  tsc = KeQueryPerformanceCounter(&dummy);
   6.105 -#endif
   6.106 -
   6.107    KeAcquireSpinLockAtDpcLevel(&xi->rx_lock);
   6.108  
   6.109    NdisUnchainBufferAtBack(Packet, &mdl);
   6.110    while (mdl)
   6.111    {
   6.112 -    ASSERT(cycles++ < 256);
   6.113      NdisAdjustBufferLength(mdl, PAGE_SIZE);
   6.114      XenFreelist_PutPage(&xi->rx_freelist, mdl);
   6.115      NdisUnchainBufferAtBack(Packet, &mdl);
   6.116 @@ -531,11 +497,6 @@ XenNet_ReturnPacket(
   6.117    KeReleaseSpinLockFromDpcLevel(&xi->rx_lock);
   6.118    
   6.119  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   6.120 -
   6.121 -#if defined(XEN_PROFILE)
   6.122 -  ProfTime_ReturnPacket.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
   6.123 -  ProfCount_ReturnPacket++;
   6.124 -#endif
   6.125  }
   6.126  
   6.127  /*
   6.128 @@ -555,17 +516,49 @@ XenNet_RxBufferFree(struct xennet_info *
   6.129  
   6.130    for (i = 0; i < NET_RX_RING_SIZE; i++)
   6.131    {
   6.132 -    KdPrint((__DRIVER_NAME "     Ring slot %d = %p\n", i, xi->rx_buffers[i]));
   6.133 -    if (!xi->rx_buffers[i])
   6.134 +    KdPrint((__DRIVER_NAME "     Ring slot %d = %p\n", i, xi->rx_mdls[i]));
   6.135 +    if (!xi->rx_mdls[i])
   6.136        continue;
   6.137  
   6.138 -    mdl = xi->rx_buffers[i];
   6.139 +    mdl = xi->rx_mdls[i];
   6.140      NdisAdjustBufferLength(mdl, PAGE_SIZE);
   6.141      KdPrint((__DRIVER_NAME "     Calling PutPage - page_free = %d\n", xi->rx_freelist.page_free));
   6.142      XenFreelist_PutPage(&xi->rx_freelist, mdl);
   6.143    }
   6.144  }
   6.145  
   6.146 +VOID
   6.147 +XenNet_RxResumeStart(xennet_info_t *xi)
   6.148 +{
   6.149 +  int i;
   6.150 +  KIRQL old_irql;
   6.151 +
   6.152 +  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   6.153 +  for (i = 0; i < NET_RX_RING_SIZE; i++)
   6.154 +  {
   6.155 +    if (xi->rx_mdls[i])
   6.156 +    {
   6.157 +      XenFreelist_PutPage(&xi->rx_freelist, xi->rx_mdls[i]);
   6.158 +      xi->rx_mdls[i] = NULL;
   6.159 +    }
   6.160 +  }
   6.161 +  XenFreelist_ResumeStart(&xi->rx_freelist);
   6.162 +  xi->rx_id_free = NET_RX_RING_SIZE;
   6.163 +  xi->rx_outstanding = 0;
   6.164 +  KeReleaseSpinLock(&xi->rx_lock, old_irql);
   6.165 +}
   6.166 +
   6.167 +VOID
   6.168 +XenNet_RxResumeEnd(xennet_info_t *xi)
   6.169 +{
   6.170 +  KIRQL old_irql;
   6.171 +
   6.172 +  KeAcquireSpinLock(&xi->rx_lock, &old_irql);
   6.173 +  XenFreelist_ResumeEnd(&xi->rx_freelist);
   6.174 +  XenNet_RxBufferAlloc(xi);
   6.175 +  KeReleaseSpinLock(&xi->rx_lock, old_irql);
   6.176 +}
   6.177 +
   6.178  BOOLEAN
   6.179  XenNet_RxInit(xennet_info_t *xi)
   6.180  {
   6.181 @@ -577,7 +570,7 @@ XenNet_RxInit(xennet_info_t *xi)
   6.182  
   6.183    for (i = 0; i < NET_RX_RING_SIZE; i++)
   6.184    {
   6.185 -    xi->rx_buffers[i] = NULL;
   6.186 +    xi->rx_mdls[i] = NULL;
   6.187    }
   6.188  
   6.189    xi->rx_outstanding = 0;
     7.1 --- a/xennet/xennet_tx.c	Tue Jul 01 15:24:49 2008 -0700
     7.2 +++ b/xennet/xennet_tx.c	Tue Jul 01 15:30:44 2008 -0700
     7.3 @@ -248,24 +248,12 @@ XenNet_SendQueuedPackets(struct xennet_i
     7.4    PLIST_ENTRY entry;
     7.5    PNDIS_PACKET packet;
     7.6    int notify;
     7.7 -#if defined(XEN_PROFILE)
     7.8 -  LARGE_INTEGER tsc, dummy;
     7.9 -#endif
    7.10 -
    7.11 -#if DBG
    7.12 -  int cycles = 0;
    7.13 -#endif
    7.14    BOOLEAN success;
    7.15  
    7.16 -#if defined(XEN_PROFILE)
    7.17 -  tsc = KeQueryPerformanceCounter(&dummy);
    7.18 -#endif
    7.19 -
    7.20    entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
    7.21    /* if empty, the above returns head*, not NULL */
    7.22    while (entry != &xi->tx_waiting_pkt_list)
    7.23    {
    7.24 -    ASSERT(cycles++ < 65536);
    7.25      //KdPrint((__DRIVER_NAME "     Packet ready to send\n"));
    7.26      packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
    7.27      success = XenNet_HWSendPacket(xi, packet);
    7.28 @@ -282,11 +270,6 @@ XenNet_SendQueuedPackets(struct xennet_i
    7.29    {
    7.30      xi->vectors.EvtChn_Notify(xi->vectors.context, xi->event_channel);
    7.31    }
    7.32 -
    7.33 -#if defined(XEN_PROFILE)
    7.34 -  ProfTime_SendQueuedPackets.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
    7.35 -  ProfCount_SendQueuedPackets++;
    7.36 -#endif
    7.37  }
    7.38  
    7.39  // Called at DISPATCH_LEVEL
    7.40 @@ -299,26 +282,16 @@ XenNet_TxBufferGC(struct xennet_info *xi
    7.41    ULONG packet_count = 0;
    7.42    int moretodo;
    7.43    ULONG i;
    7.44 -#if DBG
    7.45 -  int cycles = 0;
    7.46 -#endif
    7.47 -#if defined(XEN_PROFILE)
    7.48 -  LARGE_INTEGER tsc, dummy;
    7.49 -#endif
    7.50  
    7.51    ASSERT(xi->connected);
    7.52    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
    7.53  
    7.54  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    7.55  
    7.56 -#if defined(XEN_PROFILE)
    7.57 -  tsc = KeQueryPerformanceCounter(&dummy);
    7.58 -#endif
    7.59  
    7.60    KeAcquireSpinLockAtDpcLevel(&xi->tx_lock);
    7.61  
    7.62    do {
    7.63 -    ASSERT(cycles++ < 65536);
    7.64      prod = xi->tx.sring->rsp_prod;
    7.65      KeMemoryBarrier(); /* Ensure we see responses up to 'rsp_prod'. */
    7.66  
    7.67 @@ -326,8 +299,6 @@ XenNet_TxBufferGC(struct xennet_info *xi
    7.68      {
    7.69        struct netif_tx_response *txrsp;
    7.70  
    7.71 -      ASSERT(cycles++ < 65536);
    7.72 -
    7.73        txrsp = RING_GET_RESPONSE(&xi->tx, cons);
    7.74        if (txrsp->status == NETIF_RSP_NULL)
    7.75        {
    7.76 @@ -375,14 +346,10 @@ XenNet_TxBufferGC(struct xennet_info *xi
    7.77  
    7.78  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    7.79  
    7.80 -#if defined(XEN_PROFILE)
    7.81 -  ProfTime_TxBufferGC.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
    7.82 -  ProfCount_TxBufferGC++;
    7.83 -#endif
    7.84 -
    7.85    return NDIS_STATUS_SUCCESS;
    7.86  }
    7.87  
    7.88 +// called at <= DISPATCH_LEVEL
    7.89  VOID
    7.90  XenNet_SendPackets(
    7.91    IN NDIS_HANDLE MiniportAdapterContext,
    7.92 @@ -395,15 +362,6 @@ XenNet_SendPackets(
    7.93    UINT i;
    7.94    PLIST_ENTRY entry;
    7.95    KIRQL OldIrql;
    7.96 -#if defined(XEN_PROFILE)
    7.97 -  LARGE_INTEGER tsc, dummy;
    7.98 -  KIRQL OldIrql2;
    7.99 -#endif
   7.100 -
   7.101 -#if defined(XEN_PROFILE)
   7.102 -  KeRaiseIrql(DISPATCH_LEVEL, &OldIrql2);
   7.103 -  tsc = KeQueryPerformanceCounter(&dummy);
   7.104 -#endif
   7.105  
   7.106    KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
   7.107  
   7.108 @@ -415,40 +373,57 @@ XenNet_SendPackets(
   7.109      *(ULONG *)&packet->MiniportReservedEx = 0;
   7.110      entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   7.111      InsertTailList(&xi->tx_waiting_pkt_list, entry);
   7.112 -#if defined(XEN_PROFILE)
   7.113 -    ProfCount_PacketsPerSendPackets++;
   7.114 -#endif
   7.115    }
   7.116  
   7.117 -  XenNet_SendQueuedPackets(xi);
   7.118 +  if (xi->device_state->resume_state == RESUME_STATE_RUNNING)
   7.119 +    XenNet_SendQueuedPackets(xi);
   7.120  
   7.121    KeReleaseSpinLock(&xi->tx_lock, OldIrql);
   7.122  
   7.123 -#if defined(XEN_PROFILE)
   7.124 -  ProfTime_SendPackets.QuadPart += KeQueryPerformanceCounter(&dummy).QuadPart - tsc.QuadPart;
   7.125 -  ProfCount_SendPackets++;
   7.126 -  KeLowerIrql(OldIrql2);
   7.127 -#endif
   7.128 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   7.129 +}
   7.130  
   7.131 -#if defined(XEN_PROFILE)
   7.132 -  if ((ProfCount_SendPackets & 1023) == 0)
   7.133 +VOID
   7.134 +XenNet_TxResumeStart(xennet_info_t *xi)
   7.135 +{
   7.136 +  int i;
   7.137 +  KIRQL old_irql;
   7.138 +  PLIST_ENTRY entry;
   7.139 +
   7.140 +  KeAcquireSpinLock(&xi->tx_lock, &old_irql);
   7.141 +  for (i = 0; i < NET_TX_RING_SIZE; i++)
   7.142    {
   7.143 -    KdPrint((__DRIVER_NAME "     ***\n"));
   7.144 -    KdPrint((__DRIVER_NAME "     RxBufferAlloc     Count = %10d, Avg Time     = %10ld\n", ProfCount_RxBufferAlloc, (ProfCount_RxBufferAlloc == 0)?0:(ProfTime_RxBufferAlloc.QuadPart / ProfCount_RxBufferAlloc)));
   7.145 -    KdPrint((__DRIVER_NAME "     ReturnPacket      Count = %10d, Avg Time     = %10ld\n", ProfCount_ReturnPacket, (ProfCount_ReturnPacket == 0)?0:(ProfTime_ReturnPacket.QuadPart / ProfCount_ReturnPacket)));
   7.146 -    KdPrint((__DRIVER_NAME "     RxBufferCheck     Count = %10d, Avg Time     = %10ld\n", ProfCount_RxBufferCheck, (ProfCount_RxBufferCheck == 0)?0:(ProfTime_RxBufferCheck.QuadPart / ProfCount_RxBufferCheck)));
   7.147 -    KdPrint((__DRIVER_NAME "     RxBufferCheckTop                      Avg Time     = %10ld\n", (ProfCount_RxBufferCheck == 0)?0:(ProfTime_RxBufferCheckTopHalf.QuadPart / ProfCount_RxBufferCheck)));
   7.148 -    KdPrint((__DRIVER_NAME "     RxBufferCheckBot                      Avg Time     = %10ld\n", (ProfCount_RxBufferCheck == 0)?0:(ProfTime_RxBufferCheckBotHalf.QuadPart / ProfCount_RxBufferCheck)));
   7.149 -    KdPrint((__DRIVER_NAME "     Linearize         Count = %10d, Avg Time     = %10ld\n", ProfCount_Linearize, (ProfCount_Linearize == 0)?0:(ProfTime_Linearize.QuadPart / ProfCount_Linearize)));
   7.150 -    KdPrint((__DRIVER_NAME "     SendPackets       Count = %10d, Avg Time     = %10ld\n", ProfCount_SendPackets, (ProfCount_SendPackets == 0)?0:(ProfTime_SendPackets.QuadPart / ProfCount_SendPackets)));
   7.151 -    KdPrint((__DRIVER_NAME "     Packets per SendPackets = %10d\n", (ProfCount_SendPackets == 0)?0:(ProfCount_PacketsPerSendPackets / ProfCount_SendPackets)));
   7.152 -    KdPrint((__DRIVER_NAME "     SendQueuedPackets Count = %10d, Avg Time     = %10ld\n", ProfCount_SendQueuedPackets, (ProfCount_SendQueuedPackets == 0)?0:(ProfTime_SendQueuedPackets.QuadPart / ProfCount_SendQueuedPackets)));
   7.153 -    KdPrint((__DRIVER_NAME "     TxBufferGC        Count = %10d, Avg Time     = %10ld\n", ProfCount_TxBufferGC, (ProfCount_TxBufferGC == 0)?0:(ProfTime_TxBufferGC.QuadPart / ProfCount_TxBufferGC)));
   7.154 -    KdPrint((__DRIVER_NAME "     RxPackets         Total = %10d, Csum Offload = %10d, Calls To Receive = %10d\n", ProfCount_RxPacketsTotal, ProfCount_RxPacketsCsumOffload, ProfCount_CallsToIndicateReceive));
   7.155 -    KdPrint((__DRIVER_NAME "     TxPackets         Total = %10d, Csum Offload = %10d, Large Offload    = %10d\n", ProfCount_TxPacketsTotal, ProfCount_TxPacketsCsumOffload, ProfCount_TxPacketsLargeOffload));
   7.156 +    if (xi->tx_mdls[i])
   7.157 +    {
   7.158 +      XenFreelist_PutPage(&xi->tx_freelist, xi->tx_mdls[i]);
   7.159 +      xi->tx_mdls[i] = NULL;
   7.160 +    }
   7.161 +    /* this may result in packets being sent out of order... I don't think it matters though */
   7.162 +    if (xi->tx_pkts[i])
   7.163 +    {
   7.164 +      *(ULONG *)&xi->tx_pkts[i]->MiniportReservedEx = 0;
   7.165 +      entry = (PLIST_ENTRY)&xi->tx_pkts[i]->MiniportReservedEx[sizeof(PVOID)];
   7.166 +      InsertTailList(&xi->tx_waiting_pkt_list, entry);
   7.167 +      xi->tx_pkts[i] = 0;
   7.168 +    }
   7.169    }
   7.170 -#endif
   7.171 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   7.172 +  XenFreelist_ResumeStart(&xi->tx_freelist);
   7.173 +  xi->tx_id_free = 0;
   7.174 +  xi->tx_no_id_used = 0;
   7.175 +  for (i = 0; i < NET_TX_RING_SIZE; i++)
   7.176 +    put_id_on_freelist(xi, (USHORT)i);
   7.177 +  KeReleaseSpinLock(&xi->tx_lock, old_irql);
   7.178 +}
   7.179 +
   7.180 +VOID
   7.181 +XenNet_TxResumeEnd(xennet_info_t *xi)
   7.182 +{
   7.183 +  KIRQL old_irql;
   7.184 +
   7.185 +  KeAcquireSpinLock(&xi->tx_lock, &old_irql);
   7.186 +  XenFreelist_ResumeEnd(&xi->tx_freelist);
   7.187 +  XenNet_SendQueuedPackets(xi);
   7.188 +  KeReleaseSpinLock(&xi->tx_lock, old_irql);
   7.189  }
   7.190  
   7.191  BOOLEAN
     8.1 --- a/xenpci/evtchn.c	Tue Jul 01 15:24:49 2008 -0700
     8.2 +++ b/xenpci/evtchn.c	Tue Jul 01 15:30:44 2008 -0700
     8.3 @@ -98,10 +98,13 @@ EvtChn_DpcBounce(PRKDPC Dpc, PVOID Conte
     8.4    UNREFERENCED_PARAMETER(SystemArgument1);
     8.5    UNREFERENCED_PARAMETER(SystemArgument2);
     8.6  
     8.7 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     8.8 +
     8.9    if (action->type == EVT_ACTION_TYPE_IRQ)
    8.10      sw_interrupt((UCHAR)action->vector);
    8.11    else
    8.12      action->ServiceRoutine(NULL, action->ServiceContext);
    8.13 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    8.14  }
    8.15  
    8.16  static DDKAPI BOOLEAN
    8.17 @@ -172,6 +175,7 @@ EvtChn_Bind(PVOID Context, evtchn_port_t
    8.18  
    8.19    xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
    8.20    xpdd->ev_actions[Port].ServiceContext = ServiceContext;
    8.21 +  xpdd->ev_actions[Port].xpdd = xpdd;
    8.22    KeMemoryBarrier();
    8.23    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_NORMAL;
    8.24  
    8.25 @@ -198,6 +202,7 @@ EvtChn_BindDpc(PVOID Context, evtchn_por
    8.26  
    8.27    xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
    8.28    xpdd->ev_actions[Port].ServiceContext = ServiceContext;
    8.29 +  xpdd->ev_actions[Port].xpdd = xpdd;
    8.30    KeInitializeDpc(&xpdd->ev_actions[Port].Dpc, EvtChn_DpcBounce, &xpdd->ev_actions[Port]);
    8.31    KeMemoryBarrier(); // make sure that the new service routine is only called once the context is set up
    8.32    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_DPC;
    8.33 @@ -225,6 +230,7 @@ EvtChn_BindIrq(PVOID Context, evtchn_por
    8.34  
    8.35    KeInitializeDpc(&xpdd->ev_actions[Port].Dpc, EvtChn_DpcBounce, &xpdd->ev_actions[Port]);
    8.36    xpdd->ev_actions[Port].vector = vector;
    8.37 +  xpdd->ev_actions[Port].xpdd = xpdd;
    8.38    KeMemoryBarrier();
    8.39    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_IRQ;
    8.40  
    8.41 @@ -293,10 +299,9 @@ EvtChn_AllocUnbound(PVOID Context, domid
    8.42    return op.port;
    8.43  }
    8.44  
    8.45 -NTSTATUS
    8.46 -EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
    8.47 +static VOID
    8.48 +EvtChn_Connect(PXENPCI_DEVICE_DATA xpdd)
    8.49  {
    8.50 -  NTSTATUS status;
    8.51    int i;
    8.52  
    8.53    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    8.54 @@ -320,25 +325,6 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
    8.55      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
    8.56    }
    8.57  
    8.58 -  status = IoConnectInterrupt(
    8.59 -    &xpdd->interrupt,
    8.60 -	EvtChn_Interrupt,
    8.61 -	xpdd,
    8.62 -	NULL,
    8.63 -	xpdd->irq_vector,
    8.64 -	xpdd->irq_level,
    8.65 -	xpdd->irq_level,
    8.66 -	LevelSensitive,
    8.67 -	TRUE, /* this is a bit of a hack to make xenvbd work */
    8.68 -	xpdd->irq_affinity,
    8.69 -	FALSE);
    8.70 -  
    8.71 -  if (!NT_SUCCESS(status))
    8.72 -  {
    8.73 -    KdPrint((__DRIVER_NAME "     IoConnectInterrupt failed 0x%08x\n", status));
    8.74 -    return status;
    8.75 -  }
    8.76 -
    8.77    hvm_set_parameter(xpdd, HVM_PARAM_CALLBACK_IRQ, xpdd->irq_number);
    8.78  
    8.79    for (i = 0; i < MAX_VIRT_CPUS; i++)
    8.80 @@ -346,15 +332,41 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
    8.81      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 0;
    8.82    }
    8.83    
    8.84 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    8.85 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    8.86 +}
    8.87  
    8.88 +NTSTATUS
    8.89 +EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
    8.90 +{
    8.91 +  NTSTATUS status;
    8.92 +  
    8.93 +  EvtChn_Connect(xpdd);
    8.94 +  
    8.95 +  status = IoConnectInterrupt(
    8.96 +    &xpdd->interrupt,
    8.97 +  	EvtChn_Interrupt,
    8.98 +  	xpdd,
    8.99 +  	NULL,
   8.100 +  	xpdd->irq_vector,
   8.101 +  	xpdd->irq_level,
   8.102 +  	xpdd->irq_level,
   8.103 +  	LevelSensitive,
   8.104 +  	TRUE,
   8.105 +  	xpdd->irq_affinity,
   8.106 +  	FALSE);
   8.107 +  
   8.108 +  if (!NT_SUCCESS(status))
   8.109 +  {
   8.110 +    KdPrint((__DRIVER_NAME "     IoConnectInterrupt failed 0x%08x\n", status));
   8.111 +    return status;
   8.112 +  }
   8.113    return status;
   8.114  }
   8.115  
   8.116  NTSTATUS
   8.117  EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd)
   8.118  {
   8.119 -  UNREFERENCED_PARAMETER(xpdd);
   8.120 +  IoDisconnectInterrupt(xpdd->interrupt);
   8.121  
   8.122    return STATUS_SUCCESS;
   8.123  }
     9.1 --- a/xenpci/xenbus.c	Tue Jul 01 15:24:49 2008 -0700
     9.2 +++ b/xenpci/xenbus.c	Tue Jul 01 15:30:44 2008 -0700
     9.3 @@ -41,7 +41,7 @@ static int allocate_xenbus_id(PXENPCI_DE
     9.4    static int probe;
     9.5    int o_probe;
     9.6  
     9.7 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     9.8 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     9.9  
    9.10    for (;;)
    9.11    {
    9.12 @@ -68,7 +68,7 @@ static int allocate_xenbus_id(PXENPCI_DE
    9.13    //init_waitqueue_head(&req_info[o_probe].waitq);
    9.14    KeInitializeEvent(&xpdd->req_info[o_probe].WaitEvent, SynchronizationEvent, FALSE);
    9.15  
    9.16 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.17 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.18  
    9.19    return o_probe;
    9.20  }
    9.21 @@ -136,7 +136,7 @@ static void xb_write(
    9.22    struct xsd_sockmsg m = {type, req_id, trans_id };
    9.23    struct write_req header_req = { &m, sizeof(m) };
    9.24  
    9.25 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.26 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.27  
    9.28    for (r = 0; r < nr_reqs; r++)
    9.29      len += (size_t)req[r].len;
    9.30 @@ -201,7 +201,7 @@ static void xb_write(
    9.31    /* Send evtchn to notify remote */
    9.32    EvtChn_Notify(xpdd, xpdd->xen_store_evtchn);
    9.33  
    9.34 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.35 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.36  }
    9.37  
    9.38  static struct xsd_sockmsg *
    9.39 @@ -214,7 +214,7 @@ xenbus_msg_reply(
    9.40  {
    9.41    int id;
    9.42  
    9.43 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.44 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.45  
    9.46    id = allocate_xenbus_id(xpdd);
    9.47  
    9.48 @@ -224,7 +224,7 @@ xenbus_msg_reply(
    9.49  
    9.50    release_xenbus_id(xpdd, id);
    9.51  
    9.52 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.53 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.54  
    9.55    return xpdd->req_info[id].Reply;
    9.56  }
    9.57 @@ -242,7 +242,7 @@ XenBus_Read(
    9.58    char *res;
    9.59    char *msg;
    9.60  
    9.61 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.62 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.63  
    9.64    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    9.65  
    9.66 @@ -258,7 +258,7 @@ XenBus_Read(
    9.67    ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    9.68    *value = res;
    9.69  
    9.70 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.71 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.72  
    9.73    return NULL;
    9.74  }
    9.75 @@ -280,7 +280,7 @@ XenBus_Write(
    9.76    struct xsd_sockmsg *rep;
    9.77    char *msg;
    9.78  
    9.79 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.80 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    9.81  
    9.82    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    9.83  
    9.84 @@ -290,16 +290,28 @@ XenBus_Write(
    9.85      return msg;
    9.86    ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    9.87  
    9.88 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.89 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    9.90  
    9.91    return NULL;
    9.92  }
    9.93  
    9.94 +static VOID
    9.95 +XenBus_Connect(PXENPCI_DEVICE_DATA xpdd)
    9.96 +{
    9.97 +  PHYSICAL_ADDRESS pa_xen_store_interface;
    9.98 +  xen_ulong_t xen_store_mfn;
    9.99 +
   9.100 +  xpdd->xen_store_evtchn = (evtchn_port_t)hvm_get_parameter(xpdd, HVM_PARAM_STORE_EVTCHN);
   9.101 +  xen_store_mfn = (xen_ulong_t)hvm_get_parameter(xpdd, HVM_PARAM_STORE_PFN);
   9.102 +  pa_xen_store_interface.QuadPart = (ULONGLONG)xen_store_mfn << PAGE_SHIFT;
   9.103 +  xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
   9.104 +
   9.105 +  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Interrupt, xpdd);
   9.106 +}
   9.107 +
   9.108  NTSTATUS
   9.109  XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   9.110  {
   9.111 -  PHYSICAL_ADDRESS pa_xen_store_interface;
   9.112 -  xen_ulong_t xen_store_mfn;
   9.113    NTSTATUS Status;
   9.114    int i;
   9.115      
   9.116 @@ -309,12 +321,6 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   9.117  
   9.118    KeInitializeSpinLock(&xpdd->WatchLock);
   9.119  
   9.120 -  xpdd->xen_store_evtchn = (evtchn_port_t)hvm_get_parameter(xpdd, HVM_PARAM_STORE_EVTCHN);
   9.121 -
   9.122 -  xen_store_mfn = (xen_ulong_t)hvm_get_parameter(xpdd, HVM_PARAM_STORE_PFN);
   9.123 -  pa_xen_store_interface.QuadPart = (ULONGLONG)xen_store_mfn << PAGE_SHIFT;
   9.124 -  xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
   9.125 -
   9.126    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   9.127    {
   9.128      xpdd->XenBus_WatchEntries[i].Active = 0;
   9.129 @@ -340,8 +346,8 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   9.130      return STATUS_UNSUCCESSFUL;
   9.131    }
   9.132  
   9.133 -  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Interrupt, xpdd);
   9.134 -
   9.135 +  XenBus_Connect(xpdd);
   9.136 +  
   9.137  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   9.138  
   9.139    return STATUS_SUCCESS;
   9.140 @@ -592,14 +598,25 @@ XenBus_SendAddWatch(
   9.141    return msg;
   9.142  }
   9.143  
   9.144 +/* called at PASSIVE_LEVEL */
   9.145  VOID
   9.146  XenBus_Resume(PXENPCI_DEVICE_DATA xpdd)
   9.147  {
   9.148    int i;
   9.149 +
   9.150 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   9.151 +
   9.152 +  XenBus_Connect(xpdd);
   9.153    
   9.154    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   9.155 +  {
   9.156      if (xpdd->XenBus_WatchEntries[i].Active)
   9.157 +    {
   9.158 +      KdPrint((__DRIVER_NAME "     Adding watch for path = %s\n", xpdd->XenBus_WatchEntries[i].Path));
   9.159        XenBus_SendAddWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
   9.160 +    }
   9.161 +  }
   9.162 +  KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch\n"));
   9.163  }
   9.164  
   9.165  char *
   9.166 @@ -651,11 +668,11 @@ XenBus_AddWatch(
   9.167    if (msg)
   9.168    {
   9.169      xpdd->XenBus_WatchEntries[i].Active = 0;
   9.170 -    KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch (%s)\n", msg));
   9.171 +    //KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch (%s)\n", msg));
   9.172      return msg;
   9.173    }
   9.174  
   9.175 -  KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch\n"));
   9.176 +  //KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch\n"));
   9.177  
   9.178    return NULL;
   9.179  }
    10.1 --- a/xenpci/xenpci.h	Tue Jul 01 15:24:49 2008 -0700
    10.2 +++ b/xenpci/xenpci.h	Tue Jul 01 15:30:44 2008 -0700
    10.3 @@ -74,6 +74,7 @@ typedef struct _ev_action_t {
    10.4    KDPC Dpc;
    10.5    ULONG vector;
    10.6    ULONG Count;
    10.7 +  PVOID xpdd;
    10.8  } ev_action_t;
    10.9  
   10.10  typedef struct _XENBUS_WATCH_RING
   10.11 @@ -168,6 +169,7 @@ typedef struct {
   10.12    KIRQL irq_level;
   10.13    KAFFINITY irq_affinity;
   10.14  
   10.15 +  PHYSICAL_ADDRESS shared_info_area_unmapped;
   10.16    shared_info_t *shared_info_area;
   10.17  
   10.18    PHYSICAL_ADDRESS platform_mmio_addr;
   10.19 @@ -239,8 +241,11 @@ typedef struct {
   10.20    ULONG backend_state;
   10.21    PHYSICAL_ADDRESS config_page_phys;
   10.22    ULONG config_page_length;
   10.23 +  PUCHAR requested_resources_start;
   10.24 +  PUCHAR requested_resources_ptr;
   10.25    PUCHAR assigned_resources_start;
   10.26    PUCHAR assigned_resources_ptr;
   10.27 +  XENPCI_DEVICE_STATE device_state;
   10.28  } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
   10.29  
   10.30  typedef struct
   10.31 @@ -352,7 +357,8 @@ XenPci_Irp_Read_Pdo(PDEVICE_OBJECT devic
   10.32  NTSTATUS
   10.33  XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   10.34  
   10.35 -
   10.36 +NTSTATUS
   10.37 +XenPci_Resume(PDEVICE_OBJECT device_object);
   10.38  
   10.39  char *
   10.40  XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
   10.41 @@ -388,6 +394,8 @@ XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpd
   10.42  
   10.43  NTSTATUS
   10.44  EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
   10.45 +VOID
   10.46 +EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
   10.47  NTSTATUS
   10.48  EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd);
   10.49  
    11.1 --- a/xenpci/xenpci_fdo.c	Tue Jul 01 15:24:49 2008 -0700
    11.2 +++ b/xenpci/xenpci_fdo.c	Tue Jul 01 15:30:44 2008 -0700
    11.3 @@ -134,32 +134,31 @@ XenPci_Init(PXENPCI_DEVICE_DATA xpdd)
    11.4  {
    11.5    struct xen_add_to_physmap xatp;
    11.6    int ret;
    11.7 -  PHYSICAL_ADDRESS shared_info_area_unmapped;
    11.8  
    11.9    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   11.10  
   11.11    hvm_get_stubs(xpdd);
   11.12  
   11.13 -  shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
   11.14 -  KdPrint((__DRIVER_NAME " shared_info_area_unmapped.QuadPart = %lx\n", shared_info_area_unmapped.QuadPart));
   11.15 +  if (!xpdd->shared_info_area_unmapped.QuadPart)
   11.16 +  {
   11.17 +    xpdd->shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
   11.18 +    xpdd->shared_info_area = MmMapIoSpace(xpdd->shared_info_area_unmapped,
   11.19 +      PAGE_SIZE, MmNonCached);
   11.20 +  }
   11.21 +  KdPrint((__DRIVER_NAME " shared_info_area_unmapped.QuadPart = %lx\n", xpdd->shared_info_area_unmapped.QuadPart));
   11.22    xatp.domid = DOMID_SELF;
   11.23    xatp.idx = 0;
   11.24    xatp.space = XENMAPSPACE_shared_info;
   11.25 -  xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
   11.26 +  xatp.gpfn = (xen_pfn_t)(xpdd->shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
   11.27    KdPrint((__DRIVER_NAME " gpfn = %d\n", xatp.gpfn));
   11.28    ret = HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp);
   11.29    KdPrint((__DRIVER_NAME " hypervisor memory op ret = %d\n", ret));
   11.30 -  xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
   11.31 -    PAGE_SIZE, MmNonCached);
   11.32 +
   11.33    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   11.34  
   11.35    return STATUS_SUCCESS;
   11.36  }
   11.37  
   11.38 -#if 0
   11.39 -WDFQUEUE ReadQueue;
   11.40 -#endif
   11.41 -
   11.42  static NTSTATUS
   11.43  XenPci_Pnp_IoCompletion(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
   11.44  {
   11.45 @@ -304,11 +303,37 @@ XenBus_ShutdownIoCancel(PDEVICE_OBJECT d
   11.46    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   11.47  }
   11.48  
   11.49 +static VOID
   11.50 +XenPci_CompleteResume(PDEVICE_OBJECT device_object, PVOID context)
   11.51 +{
   11.52 +  PXENPCI_DEVICE_DATA xpdd;
   11.53 +  PXEN_CHILD child;
   11.54 +
   11.55 +  UNREFERENCED_PARAMETER(context);
   11.56 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   11.57 +
   11.58 +  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   11.59 +
   11.60 +  XenBus_Resume(xpdd);
   11.61 +
   11.62 +  for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   11.63 +  {
   11.64 +    XenPci_Resume(child->context->common.pdo);
   11.65 +    child->context->device_state.resume_state = RESUME_STATE_FRONTEND_RESUME;
   11.66 +    // how can we signal children that they are ready to restart again?
   11.67 +  }
   11.68 +
   11.69 +  xpdd->suspending = 0;
   11.70 +
   11.71 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   11.72 +}
   11.73 +
   11.74  struct {
   11.75 -  ULONG do_spin;
   11.76 -  ULONG nr_spinning;
   11.77 +  volatile ULONG do_spin;
   11.78 +  volatile LONG nr_spinning;
   11.79  } typedef SUSPEND_INFO, *PSUSPEND_INFO;
   11.80  
   11.81 +/* Called at DISPATCH_LEVEL */
   11.82  static DDKAPI VOID
   11.83  XenPci_Suspend(
   11.84    PRKDPC Dpc,
   11.85 @@ -319,9 +344,11 @@ XenPci_Suspend(
   11.86    PXENPCI_DEVICE_DATA xpdd = Context;
   11.87    PSUSPEND_INFO suspend_info = SystemArgument1;
   11.88    ULONG ActiveProcessorCount;
   11.89 -  KIRQL OldIrql;
   11.90 +  KIRQL old_irql;
   11.91    int cancelled;
   11.92 -  int i;
   11.93 +  PIO_WORKITEM work_item;
   11.94 +  PXEN_CHILD child;
   11.95 +  //PUCHAR gnttbl_backup[PAGE_SIZE * NR_GRANT_FRAMES];
   11.96  
   11.97    UNREFERENCED_PARAMETER(Dpc);
   11.98    UNREFERENCED_PARAMETER(SystemArgument2);
   11.99 @@ -330,34 +357,55 @@ XenPci_Suspend(
  11.100  
  11.101    if (KeGetCurrentProcessorNumber() != 0)
  11.102    {
  11.103 +    KeRaiseIrql(HIGH_LEVEL, &old_irql);
  11.104      KdPrint((__DRIVER_NAME "     spinning...\n"));
  11.105 -    InterlockedIncrement((volatile LONG *)&suspend_info->nr_spinning);
  11.106 +    InterlockedIncrement(&suspend_info->nr_spinning);
  11.107      KeMemoryBarrier();
  11.108      while(suspend_info->do_spin)
  11.109      {
  11.110        /* we should be able to wait more nicely than this... */
  11.111      }
  11.112      KeMemoryBarrier();
  11.113 -    InterlockedDecrement((volatile LONG *)&suspend_info->nr_spinning);    
  11.114 +    InterlockedDecrement(&suspend_info->nr_spinning);    
  11.115      KdPrint((__DRIVER_NAME "     ...done spinning\n"));
  11.116      KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
  11.117 +    KeLowerIrql(old_irql);
  11.118      return;
  11.119    }
  11.120    ActiveProcessorCount = (ULONG)KeNumberProcessors;
  11.121  
  11.122 +  KeRaiseIrql(HIGH_LEVEL, &old_irql);
  11.123 +  
  11.124    KdPrint((__DRIVER_NAME "     waiting for all other processors to spin\n"));
  11.125 -  while (suspend_info->nr_spinning < ActiveProcessorCount - 1)
  11.126 +  while (suspend_info->nr_spinning < (LONG)ActiveProcessorCount - 1)
  11.127    {
  11.128        /* we should be able to wait more nicely than this... */
  11.129    }
  11.130    KdPrint((__DRIVER_NAME "     all other processors are spinning\n"));
  11.131  
  11.132 -  KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  11.133 +  // make a backup of the grant table - we are going to keep it instead of throwing it away
  11.134 +  //memcpy(gnttbl_backup, xpdd->gnttab_table, PAGE_SIZE * NR_GRANT_FRAMES);
  11.135 +
  11.136    KdPrint((__DRIVER_NAME "     calling suspend\n"));
  11.137    cancelled = hvm_shutdown(Context, SHUTDOWN_suspend);
  11.138    KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
  11.139 -  KeLowerIrql(OldIrql);
  11.140  
  11.141 +  XenPci_Init(xpdd);
  11.142 +  
  11.143 +  GntTbl_Map(Context, 0, NR_GRANT_FRAMES - 1);
  11.144 +
  11.145 +  /* this enabled interrupts again too */  
  11.146 +  EvtChn_Init(xpdd);
  11.147 +
  11.148 +  //memcpy(xpdd->gnttab_table, gnttbl_backup, PAGE_SIZE * NR_GRANT_FRAMES);
  11.149 +
  11.150 +  for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
  11.151 +  {
  11.152 +    child->context->device_state.resume_state = RESUME_STATE_BACKEND_RESUME;
  11.153 +  }
  11.154 +
  11.155 +  KeLowerIrql(old_irql);
  11.156 +  
  11.157    KdPrint((__DRIVER_NAME "     waiting for all other processors to stop spinning\n"));
  11.158    suspend_info->do_spin = 0;
  11.159    while (suspend_info->nr_spinning != 0)
  11.160 @@ -366,19 +414,13 @@ XenPci_Suspend(
  11.161    }
  11.162    KdPrint((__DRIVER_NAME "     all other processors have stopped spinning\n"));
  11.163  
  11.164 -  for (i = 0; i < MAX_VIRT_CPUS; i++)
  11.165 -  {
  11.166 -    xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
  11.167 -  }
  11.168 -
  11.169 -  GntTbl_Map(Context, 0, NR_GRANT_FRAMES - 1);
  11.170 -  XenBus_Resume(xpdd);
  11.171 -  // TODO: Enable xenbus
  11.172 -  // TODO: Enable all our devices  
  11.173 -
  11.174 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
  11.175 +	work_item = IoAllocateWorkItem(xpdd->common.fdo);
  11.176 +	IoQueueWorkItem(work_item, XenPci_CompleteResume, DelayedWorkQueue, NULL);
  11.177 +  
  11.178 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.179  }
  11.180  
  11.181 +/* Called at PASSIVE_LEVEL */
  11.182  static VOID
  11.183  XenPci_BeginSuspend(PXENPCI_DEVICE_DATA xpdd)
  11.184  {
  11.185 @@ -398,13 +440,16 @@ XenPci_BeginSuspend(PXENPCI_DEVICE_DATA 
  11.186      suspend_info->do_spin = 1;
  11.187      RtlZeroMemory(suspend_info, sizeof(SUSPEND_INFO));
  11.188  
  11.189 -    // TODO: Disable all our devices  
  11.190 -    // TODO: Disable xenbus
  11.191 +    // I think we need to synchronise with the interrupt here...
  11.192  
  11.193      for (i = 0; i < MAX_VIRT_CPUS; i++)
  11.194      {
  11.195        xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
  11.196      }
  11.197 +    KeMemoryBarrier();
  11.198 +    EvtChn_Shutdown(xpdd);
  11.199 +    KeFlushQueuedDpcs();
  11.200 +
  11.201      //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask); // this is for Vista+
  11.202      ActiveProcessorCount = (ULONG)KeNumberProcessors;
  11.203      KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  11.204 @@ -529,11 +574,11 @@ XenPci_DeviceWatchHandler(char *path, PV
  11.205    char *value;
  11.206    PXENPCI_DEVICE_DATA xpdd = context;
  11.207  
  11.208 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  11.209 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  11.210  
  11.211 -  KdPrint((__DRIVER_NAME "     path = %s\n", path));
  11.212 +//  KdPrint((__DRIVER_NAME "     path = %s\n", path));
  11.213    bits = SplitString(path, '/', 4, &count);
  11.214 -  KdPrint((__DRIVER_NAME "     count = %d\n", count));
  11.215 +//  KdPrint((__DRIVER_NAME "     count = %d\n", count));
  11.216  
  11.217    if (count == 3)
  11.218    {
  11.219 @@ -553,7 +598,7 @@ XenPci_DeviceWatchHandler(char *path, PV
  11.220    }
  11.221    FreeSplitString(bits, count);
  11.222  
  11.223 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.224 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  11.225  }
  11.226  
  11.227  static DDKAPI VOID
    12.1 --- a/xenpci/xenpci_pdo.c	Tue Jul 01 15:24:49 2008 -0700
    12.2 +++ b/xenpci/xenpci_pdo.c	Tue Jul 01 15:30:44 2008 -0700
    12.3 @@ -411,7 +411,10 @@ XenPci_XenShutdownDevice(PVOID Context)
    12.4  }
    12.5  
    12.6  static NTSTATUS
    12.7 -XenPci_XenConfigDevice(PVOID context)
    12.8 +XenPci_XenConfigDevice(PVOID context);
    12.9 +
   12.10 +static NTSTATUS
   12.11 +XenPci_XenConfigDeviceSpecifyBuffers(PVOID context, PUCHAR src, PUCHAR dst)
   12.12  {
   12.13    PXENPCI_PDO_DEVICE_DATA xppdd = context;
   12.14    PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
   12.15 @@ -422,20 +425,20 @@ XenPci_XenConfigDevice(PVOID context)
   12.16    PCHAR res;
   12.17    PVOID address;
   12.18    UCHAR type;
   12.19 -  PUCHAR in_ptr, in_start;
   12.20 -  PUCHAR out_ptr, out_start;
   12.21 +  PUCHAR in_ptr; //, in_start;
   12.22 +  PUCHAR out_ptr; //, out_start;
   12.23    XENPCI_VECTORS vectors;
   12.24    ULONG event_channel;
   12.25    BOOLEAN run = FALSE;
   12.26    PMDL ring;
   12.27    grant_ref_t gref;
   12.28 +  BOOLEAN done_xenbus_init = FALSE;
   12.29   
   12.30    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   12.31  
   12.32 -  out_ptr = out_start = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
   12.33 -  in_ptr = in_start = ExAllocatePoolWithTag(PagedPool, xppdd->config_page_length, XENPCI_POOL_TAG);
   12.34 -  memcpy(in_ptr, out_ptr, xppdd->config_page_length);
   12.35 -
   12.36 +  in_ptr = src;
   12.37 +  out_ptr = dst;
   12.38 +  
   12.39    // always add vectors
   12.40    vectors.magic = XEN_DATA_MAGIC;
   12.41    vectors.length = sizeof(XENPCI_VECTORS);
   12.42 @@ -453,10 +456,23 @@ XenPci_XenConfigDevice(PVOID context)
   12.43    vectors.XenPci_XenConfigDevice = XenPci_XenConfigDevice;
   12.44    vectors.XenPci_XenShutdownDevice = XenPci_XenShutdownDevice;
   12.45    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors);
   12.46 +  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state);
   12.47  
   12.48    // first pass, possibly before state == Connected
   12.49    while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
   12.50    {
   12.51 +    if (!done_xenbus_init)
   12.52 +    {
   12.53 +      if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
   12.54 +      {
   12.55 +        status = STATUS_UNSUCCESSFUL;
   12.56 +        goto error;
   12.57 +      }
   12.58 +      done_xenbus_init = TRUE;
   12.59 +    }
   12.60 +    
   12.61 +    ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value);
   12.62 +
   12.63      switch (type)
   12.64      {
   12.65      case XEN_INIT_TYPE_RUN:
   12.66 @@ -527,15 +543,18 @@ XenPci_XenConfigDevice(PVOID context)
   12.67    {
   12.68      goto error;
   12.69    }
   12.70 -  if (run && XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
   12.71 +  if (run)
   12.72    {
   12.73 -    status = STATUS_UNSUCCESSFUL;
   12.74 -    goto error;
   12.75 +    if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
   12.76 +    {
   12.77 +      status = STATUS_UNSUCCESSFUL;
   12.78 +      goto error;
   12.79 +    }
   12.80    }
   12.81  
   12.82    // second pass, possibly after state == Connected
   12.83 -  in_ptr = in_start;
   12.84 -  while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value)) != XEN_INIT_TYPE_END)
   12.85 +  in_ptr = src;
   12.86 +  while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
   12.87    {
   12.88      switch(type)
   12.89      {
   12.90 @@ -578,35 +597,47 @@ XenPci_XenConfigDevice(PVOID context)
   12.91    }
   12.92  
   12.93  error:
   12.94 -  ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
   12.95 -  MmUnmapIoSpace(out_start, xppdd->config_page_length);
   12.96 -  ExFreePoolWithTag(in_start, XENPCI_POOL_TAG);
   12.97 -
   12.98    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (%08x\n", status));
   12.99  
  12.100    return status;
  12.101  }
  12.102  
  12.103  static NTSTATUS
  12.104 -XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
  12.105 +XenPci_XenConfigDevice(PVOID context)
  12.106  {
  12.107 -  NTSTATUS status = STATUS_SUCCESS;
  12.108 +  NTSTATUS status;
  12.109 +  PUCHAR src, dst;
  12.110 +  PXENPCI_PDO_DEVICE_DATA xppdd = context;  
  12.111 +
  12.112 +  src = ExAllocatePoolWithTag(PagedPool, xppdd->config_page_length, XENPCI_POOL_TAG);
  12.113 +  dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
  12.114 +  memcpy(src, dst, xppdd->config_page_length);
  12.115 +  
  12.116 +  status = XenPci_XenConfigDeviceSpecifyBuffers(xppdd, src, dst);
  12.117 +
  12.118 +  MmUnmapIoSpace(dst, xppdd->config_page_length);
  12.119 +  ExFreePoolWithTag(src, XENPCI_POOL_TAG);
  12.120 +  
  12.121 +  return status;
  12.122 +}
  12.123 +
  12.124 +static NTSTATUS
  12.125 +XenPci_GetBackendAndAddWatch(PDEVICE_OBJECT device_object)
  12.126 +{
  12.127    PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
  12.128    PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  12.129 -  PIO_STACK_LOCATION stack;
  12.130 -  PCM_PARTIAL_RESOURCE_LIST prl;
  12.131 -  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
  12.132 -  ULONG i;
  12.133    char path[128];
  12.134 -  PCHAR value;
  12.135    PCHAR res;
  12.136 - 
  12.137 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  12.138 +  PCHAR value;
  12.139  
  12.140 -  DUMP_CURRENT_PNP_STATE(xppdd);
  12.141 +  if (strlen(xppdd->backend_path) != 0)
  12.142 +  {
  12.143 +    // this must be the restore path - remove the existing watch
  12.144 +    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  12.145 +    KdPrint((__DRIVER_NAME "    Removing old watch on %s\n", path));
  12.146 +    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
  12.147 +  }
  12.148    
  12.149 -  stack = IoGetCurrentIrpStackLocation(irp);
  12.150 -
  12.151    /* Get backend path */
  12.152    RtlStringCbPrintfA(path, ARRAY_SIZE(path),
  12.153      "%s/backend", xppdd->path);
  12.154 @@ -624,12 +655,84 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
  12.155    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  12.156    XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
  12.157  
  12.158 -  if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
  12.159 +  return STATUS_SUCCESS;
  12.160 +}
  12.161 +
  12.162 +NTSTATUS
  12.163 +XenPci_Resume(PDEVICE_OBJECT device_object)
  12.164 +{
  12.165 +  NTSTATUS status;
  12.166 +  PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
  12.167 +  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  12.168 +  //PUCHAR in_ptr;
  12.169 +  //UCHAR type;
  12.170 +  //PVOID setting;
  12.171 +  //PVOID value;
  12.172 +  //CHAR path[256];
  12.173 +  //PVOID address;
  12.174 +  ULONG old_backend_state;
  12.175 +  PUCHAR src, dst;
  12.176 +
  12.177 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  12.178 +
  12.179 +  old_backend_state = xppdd->backend_state;
  12.180 +  status = XenPci_GetBackendAndAddWatch(device_object);
  12.181 +  if (!NT_SUCCESS(status))
  12.182 +    return status;
  12.183 +  
  12.184 +  if (xppdd->common.current_pnp_state == Started && old_backend_state == XenbusStateConnected)
  12.185    {
  12.186 -    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  12.187 -    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
  12.188 -    return STATUS_UNSUCCESSFUL;
  12.189 +  
  12.190 +    if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
  12.191 +    {
  12.192 +      // this is probably an unrecoverable situation...
  12.193 +      return STATUS_UNSUCCESSFUL;
  12.194 +    }
  12.195 +    if (xppdd->assigned_resources_ptr)
  12.196 +    {
  12.197 +      // reset things - feed the 'requested resources' back in
  12.198 +      ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL);
  12.199 +      src = xppdd->requested_resources_start;
  12.200 +      xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, XENPCI_POOL_TAG);;
  12.201 +      xppdd->assigned_resources_ptr = xppdd->assigned_resources_start;
  12.202 +      
  12.203 +      dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached);
  12.204 +      
  12.205 +      status = XenPci_XenConfigDeviceSpecifyBuffers(xppdd, src, dst);
  12.206 +
  12.207 +      MmUnmapIoSpace(dst, xppdd->config_page_length);
  12.208 +      ExFreePoolWithTag(src, XENPCI_POOL_TAG);
  12.209 +    }
  12.210 +    if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
  12.211 +    {
  12.212 +      // this is definitely an unrecoverable situation...
  12.213 +      return STATUS_UNSUCCESSFUL;
  12.214 +    }
  12.215    }
  12.216 +  return STATUS_SUCCESS;
  12.217 +} 
  12.218 +
  12.219 +static NTSTATUS
  12.220 +XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
  12.221 +{
  12.222 +  NTSTATUS status = STATUS_SUCCESS;
  12.223 +  PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
  12.224 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
  12.225 +  PIO_STACK_LOCATION stack;
  12.226 +  PCM_PARTIAL_RESOURCE_LIST prl;
  12.227 +  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
  12.228 +  ULONG i;
  12.229 +  char path[128];
  12.230 + 
  12.231 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  12.232 +
  12.233 +  DUMP_CURRENT_PNP_STATE(xppdd);
  12.234 +  
  12.235 +  stack = IoGetCurrentIrpStackLocation(irp);
  12.236 +
  12.237 +  status = XenPci_GetBackendAndAddWatch(device_object);
  12.238 +  if (!NT_SUCCESS(status))
  12.239 +    return status;
  12.240  
  12.241    prl = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
  12.242    for (i = 0; i < prl->Count; i++)
  12.243 @@ -649,8 +752,11 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
  12.244        KdPrint((__DRIVER_NAME "     Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
  12.245        xppdd->config_page_phys = prd->u.Memory.Start;
  12.246        xppdd->config_page_length = prd->u.Memory.Length;
  12.247 +      xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
  12.248        xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
  12.249 +      
  12.250        status = XenPci_XenConfigDevice(xppdd);
  12.251 +
  12.252        if (!NT_SUCCESS(status))
  12.253        {
  12.254          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  12.255 @@ -819,7 +925,7 @@ XenPci_Pnp_Pdo(PDEVICE_OBJECT device_obj
  12.256    PPNP_BUS_INFORMATION pbi;
  12.257    ULONG *usage_type;
  12.258  
  12.259 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  12.260 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  12.261  
  12.262    stack = IoGetCurrentIrpStackLocation(irp);
  12.263  
  12.264 @@ -1064,7 +1170,7 @@ XenPci_Pnp_Pdo(PDEVICE_OBJECT device_obj
  12.265      break;
  12.266        
  12.267    default:
  12.268 -    KdPrint((__DRIVER_NAME "     Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
  12.269 +    //KdPrint((__DRIVER_NAME "     Unhandled Minor = %d, Status = %08x\n", stack->MinorFunction, irp->IoStatus.Status));
  12.270      status = irp->IoStatus.Status;
  12.271      break;
  12.272    }
  12.273 @@ -1072,7 +1178,7 @@ XenPci_Pnp_Pdo(PDEVICE_OBJECT device_obj
  12.274    irp->IoStatus.Status = status;
  12.275    IoCompleteRequest(irp, IO_NO_INCREMENT);
  12.276  
  12.277 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
  12.278 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
  12.279  
  12.280    return status;
  12.281  }
    13.1 --- a/xenvbd/scsiport.c	Tue Jul 01 15:24:49 2008 -0700
    13.2 +++ b/xenvbd/scsiport.c	Tue Jul 01 15:30:44 2008 -0700
    13.3 @@ -90,72 +90,40 @@ XenVbd_GetResponse(PXENVBD_DEVICE_DATA x
    13.4  }
    13.5  
    13.6  static VOID
    13.7 -XenVbd_HwScsiTimer(PVOID DeviceExtension)
    13.8 +XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
    13.9  {
   13.10 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   13.11 +  blkif_other_request_t *other_req;
   13.12  
   13.13 -  KdPrint((__DRIVER_NAME "     aligned requests   = %I64d, aligned bytes   = %I64d\n", xvdd->aligned_requests, xvdd->aligned_bytes));
   13.14 -  KdPrint((__DRIVER_NAME "     unaligned requests = %I64d, unaligned bytes = %I64d\n", xvdd->unaligned_requests, xvdd->unaligned_bytes));
   13.15 -  KdPrint((__DRIVER_NAME "     interrupts = %I64d\n", xvdd->interrupts));
   13.16 -  KdPrint((__DRIVER_NAME "     no_free_grant_requests = %I64d\n", xvdd->no_free_grant_requests));
   13.17 -  xvdd->shadow_min_free = xvdd->shadow_free;
   13.18 -  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, 60 * 1000 * 1000);
   13.19 +  if (!xvdd->use_other)
   13.20 +  {
   13.21 +    *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
   13.22 +  }
   13.23 +  else
   13.24 +  {  
   13.25 +    other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
   13.26 +    other_req->operation = req->operation;
   13.27 +    other_req->nr_segments = req->nr_segments;
   13.28 +    other_req->handle = req->handle;
   13.29 +    other_req->id = req->id;
   13.30 +    other_req->sector_number = req->sector_number;
   13.31 +    memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
   13.32 +  }
   13.33 +  xvdd->ring.req_prod_pvt++;
   13.34  }
   13.35  
   13.36  static ULONG
   13.37 -XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
   13.38 +XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
   13.39  {
   13.40    ULONG i;
   13.41 -//  PACCESS_RANGE AccessRange;
   13.42 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   13.43 -//  ULONG status;
   13.44 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
   13.45 -  PACCESS_RANGE access_range;
   13.46    PUCHAR ptr;
   13.47    USHORT type;
   13.48    PCHAR setting, value;
   13.49 -  blkif_sring_t *sring;
   13.50 -
   13.51 -  UNREFERENCED_PARAMETER(HwContext);
   13.52 -  UNREFERENCED_PARAMETER(BusInformation);
   13.53 -  UNREFERENCED_PARAMETER(ArgumentString);
   13.54 -
   13.55 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
   13.56 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   13.57 -
   13.58 -  *Again = FALSE;
   13.59 -
   13.60 -  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
   13.61 -  KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
   13.62 -
   13.63 -  if (ConfigInfo->NumberOfAccessRanges != 1)
   13.64 -  {
   13.65 -    KdPrint((__DRIVER_NAME "     NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));    
   13.66 -    return SP_RETURN_BAD_CONFIG;
   13.67 -  }
   13.68 -
   13.69 -  access_range = &((*(ConfigInfo->AccessRanges))[0]);
   13.70 -
   13.71 -  KdPrint((__DRIVER_NAME "     RangeStart = %08x, RangeLength = %08x\n",
   13.72 -    access_range->RangeStart.LowPart, access_range->RangeLength));
   13.73 -
   13.74 -  ptr = ScsiPortGetDeviceBase(
   13.75 -    DeviceExtension,
   13.76 -    ConfigInfo->AdapterInterfaceType,
   13.77 -    ConfigInfo->SystemIoBusNumber,
   13.78 -    access_range->RangeStart,
   13.79 -    access_range->RangeLength,
   13.80 -    !access_range->RangeInMemory);
   13.81 -  if (ptr == NULL)
   13.82 -  {
   13.83 -    KdPrint((__DRIVER_NAME "     Unable to map range\n"));
   13.84 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   13.85 -    return SP_RETURN_BAD_CONFIG;
   13.86 -  }
   13.87  
   13.88    xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
   13.89 -  sring = NULL;
   13.90 +  xvdd->sring = NULL;
   13.91    xvdd->event_channel = 0;
   13.92 +  
   13.93 +  ptr = xvdd->device_base;
   13.94    while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value)) != XEN_INIT_TYPE_END)
   13.95    {
   13.96      switch(type)
   13.97 @@ -164,11 +132,11 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
   13.98        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
   13.99        if (strcmp(setting, "ring-ref") == 0)
  13.100        {
  13.101 -        sring = (blkif_sring_t *)value;
  13.102 -        FRONT_RING_INIT(&xvdd->ring, sring, PAGE_SIZE);
  13.103 +        xvdd->sring = (blkif_sring_t *)value;
  13.104 +        FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
  13.105          /* this bit is for when we have to take over an existing ring on a bug check */
  13.106 -        xvdd->ring.req_prod_pvt = sring->req_prod;
  13.107 -        xvdd->ring.rsp_cons = sring->rsp_prod;
  13.108 +        xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
  13.109 +        xvdd->ring.rsp_cons = xvdd->sring->rsp_prod;
  13.110        }
  13.111        break;
  13.112      case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
  13.113 @@ -224,13 +192,17 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
  13.114        memcpy(&xvdd->grant_free_list, value, sizeof(grant_ref_t) * xvdd->grant_entries);
  13.115        xvdd->grant_free = xvdd->grant_entries;
  13.116        break;
  13.117 +    case XEN_INIT_TYPE_STATE_PTR:
  13.118 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
  13.119 +      xvdd->device_state = (PXENPCI_DEVICE_STATE)value;
  13.120 +      break;
  13.121      default:
  13.122        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
  13.123        break;
  13.124      }
  13.125    }
  13.126    if (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
  13.127 -    || sring == NULL
  13.128 +    || xvdd->sring == NULL
  13.129      || xvdd->event_channel == 0
  13.130      || xvdd->total_sectors == 0
  13.131      || xvdd->bytes_per_sector == 0)
  13.132 @@ -239,32 +211,9 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
  13.133      KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  13.134      return SP_RETURN_BAD_CONFIG;
  13.135    }
  13.136 -  
  13.137 +
  13.138    /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
  13.139    xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
  13.140 -  
  13.141 -  ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  13.142 -  ConfigInfo->NumberOfPhysicalBreaks = 0; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
  13.143 -  ConfigInfo->ScatterGather = TRUE;
  13.144 -  ConfigInfo->AlignmentMask = 0;
  13.145 -  ConfigInfo->NumberOfBuses = 1;
  13.146 -  ConfigInfo->InitiatorBusId[0] = 1;
  13.147 -  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  13.148 -  ConfigInfo->MaximumNumberOfTargets = 2;
  13.149 -  ConfigInfo->BufferAccessScsiPortControlled = TRUE;
  13.150 -  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
  13.151 -  {
  13.152 -    ConfigInfo->Master = TRUE;
  13.153 -    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  13.154 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
  13.155 -  }
  13.156 -  else
  13.157 -  {
  13.158 -    ConfigInfo->Master = FALSE;
  13.159 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
  13.160 -  }
  13.161 -
  13.162 -  xvdd->ring_detect_state = 0;
  13.163  
  13.164    xvdd->shadow_free = 0;
  13.165    memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
  13.166 @@ -273,76 +222,8 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
  13.167      xvdd->shadows[i].req.id = i;
  13.168      put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
  13.169    }
  13.170 -
  13.171 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
  13.172 -
  13.173 -  return SP_RETURN_FOUND;
  13.174 -}
  13.175 -
  13.176 -static BOOLEAN
  13.177 -XenVbd_HwScsiInitialize(PVOID DeviceExtension)
  13.178 -{
  13.179 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  13.180 -  blkif_request_t *req;
  13.181 -  int i;
  13.182 -  int notify;
  13.183    
  13.184 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  13.185 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  13.186 -
  13.187 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
  13.188 -  req->operation = 0xff;
  13.189 -  req->nr_segments = 0;
  13.190 -  for (i = 0; i < req->nr_segments; i++)
  13.191 -  {
  13.192 -    req->seg[i].gref = 0xffffffff;
  13.193 -    req->seg[i].first_sect = 0xff;
  13.194 -    req->seg[i].last_sect = 0xff;
  13.195 -  }
  13.196 -  xvdd->ring.req_prod_pvt++;
  13.197 -
  13.198 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
  13.199 -  req->operation = 0xff;
  13.200 -  req->nr_segments = 0;
  13.201 -  for (i = 0; i < req->nr_segments; i++)
  13.202 -  {
  13.203 -    req->seg[i].gref = 0xffffffff;
  13.204 -    req->seg[i].first_sect = 0xff;
  13.205 -    req->seg[i].last_sect = 0xff;
  13.206 -  }
  13.207 -  xvdd->ring.req_prod_pvt++;
  13.208 -
  13.209 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
  13.210 -  if (notify)
  13.211 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
  13.212 -
  13.213 -  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, 60 * 1000 * 1000);
  13.214 -
  13.215 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  13.216 -
  13.217 -  return TRUE;
  13.218 -}
  13.219 -
  13.220 -static VOID
  13.221 -XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
  13.222 -{
  13.223 -  blkif_other_request_t *other_req;
  13.224 -
  13.225 -  if (!xvdd->use_other)
  13.226 -  {
  13.227 -    *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
  13.228 -  }
  13.229 -  else
  13.230 -  {  
  13.231 -    other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
  13.232 -    other_req->operation = req->operation;
  13.233 -    other_req->nr_segments = req->nr_segments;
  13.234 -    other_req->handle = req->handle;
  13.235 -    other_req->id = req->id;
  13.236 -    other_req->sector_number = req->sector_number;
  13.237 -    memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
  13.238 -  }
  13.239 -  xvdd->ring.req_prod_pvt++;
  13.240 +  return SP_RETURN_FOUND;
  13.241  }
  13.242  
  13.243  static VOID
  13.244 @@ -447,6 +328,184 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
  13.245    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  13.246  }
  13.247  
  13.248 +#define RESUME_CHECK_TIMER_INTERVAL (100 * 1000)
  13.249 +
  13.250 +static VOID
  13.251 +XenVbd_HwScsiTimer(PVOID DeviceExtension)
  13.252 +{
  13.253 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  13.254 +  ULONG i;
  13.255 +  blkif_shadow_t shadows[SHADOW_ENTRIES];
  13.256 +  ULONG shadow_entries;
  13.257 +  blkif_shadow_t *shadow;  
  13.258 +
  13.259 +/*
  13.260 +  KdPrint((__DRIVER_NAME "     aligned requests   = %I64d, aligned bytes   = %I64d\n", xvdd->aligned_requests, xvdd->aligned_bytes));
  13.261 +  KdPrint((__DRIVER_NAME "     unaligned requests = %I64d, unaligned bytes = %I64d\n", xvdd->unaligned_requests, xvdd->unaligned_bytes));
  13.262 +  KdPrint((__DRIVER_NAME "     interrupts = %I64d\n", xvdd->interrupts));
  13.263 +  KdPrint((__DRIVER_NAME "     no_free_grant_requests = %I64d\n", xvdd->no_free_grant_requests));
  13.264 +  xvdd->shadow_min_free = xvdd->shadow_free;
  13.265 +*/
  13.266 +
  13.267 +  if (xvdd->device_state->resume_state == RESUME_STATE_FRONTEND_RESUME)
  13.268 +  {
  13.269 +    KdPrint((__DRIVER_NAME "     found device in resume state\n"));
  13.270 +    FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
  13.271 +    // re-submit srb's
  13.272 +    
  13.273 +    shadow_entries = 0;
  13.274 +    for (i = 0; i < SHADOW_ENTRIES; i++)
  13.275 +    {
  13.276 +      shadow = &xvdd->shadows[i];
  13.277 +      if (shadow->srb)
  13.278 +      {
  13.279 +        shadows[shadow_entries++] = xvdd->shadows[i];
  13.280 +        shadow->srb = NULL;
  13.281 +      }
  13.282 +    }
  13.283 +
  13.284 +    XenVbd_InitFromConfig(xvdd);
  13.285 +    
  13.286 +    for (i = 0; i < shadow_entries; i++)
  13.287 +    {
  13.288 +      shadow = &shadows[i];
  13.289 +      XenVbd_PutSrbOnRing(xvdd, shadow->srb, shadow->offset);
  13.290 +    }
  13.291 +    
  13.292 +    xvdd->device_state->resume_state = RESUME_STATE_RUNNING;
  13.293 +    
  13.294 +    if (i == 0)
  13.295 +    {
  13.296 +      /* no requests, so we might need to tell scsiport that we can accept a new one if we deferred one earlier */
  13.297 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  13.298 +    }
  13.299 +  }
  13.300 +  
  13.301 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, RESUME_CHECK_TIMER_INTERVAL);
  13.302 +}
  13.303 +
  13.304 +static ULONG
  13.305 +XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  13.306 +{
  13.307 +//  PACCESS_RANGE AccessRange;
  13.308 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  13.309 +  ULONG status;
  13.310 +//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
  13.311 +  PACCESS_RANGE access_range;
  13.312 +
  13.313 +  UNREFERENCED_PARAMETER(HwContext);
  13.314 +  UNREFERENCED_PARAMETER(BusInformation);
  13.315 +  UNREFERENCED_PARAMETER(ArgumentString);
  13.316 +
  13.317 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
  13.318 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  13.319 +
  13.320 +  *Again = FALSE;
  13.321 +
  13.322 +  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
  13.323 +  KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
  13.324 +
  13.325 +  if (ConfigInfo->NumberOfAccessRanges != 1)
  13.326 +  {
  13.327 +    KdPrint((__DRIVER_NAME "     NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));    
  13.328 +    return SP_RETURN_BAD_CONFIG;
  13.329 +  }
  13.330 +
  13.331 +  access_range = &((*(ConfigInfo->AccessRanges))[0]);
  13.332 +
  13.333 +  KdPrint((__DRIVER_NAME "     RangeStart = %08x, RangeLength = %08x\n",
  13.334 +    access_range->RangeStart.LowPart, access_range->RangeLength));
  13.335 +
  13.336 +  xvdd->device_base = ScsiPortGetDeviceBase(
  13.337 +    DeviceExtension,
  13.338 +    ConfigInfo->AdapterInterfaceType,
  13.339 +    ConfigInfo->SystemIoBusNumber,
  13.340 +    access_range->RangeStart,
  13.341 +    access_range->RangeLength,
  13.342 +    !access_range->RangeInMemory);
  13.343 +  if (xvdd->device_base == NULL)
  13.344 +  {
  13.345 +    KdPrint((__DRIVER_NAME "     Unable to map range\n"));
  13.346 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
  13.347 +    return SP_RETURN_BAD_CONFIG;
  13.348 +  }
  13.349 +
  13.350 +  status = XenVbd_InitFromConfig(xvdd);
  13.351 +  if (status != SP_RETURN_FOUND)
  13.352 +    return status;
  13.353 +  
  13.354 +  ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  13.355 +  ConfigInfo->NumberOfPhysicalBreaks = 0; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
  13.356 +  ConfigInfo->ScatterGather = TRUE;
  13.357 +  ConfigInfo->AlignmentMask = 0;
  13.358 +  ConfigInfo->NumberOfBuses = 1;
  13.359 +  ConfigInfo->InitiatorBusId[0] = 1;
  13.360 +  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  13.361 +  ConfigInfo->MaximumNumberOfTargets = 2;
  13.362 +  ConfigInfo->BufferAccessScsiPortControlled = TRUE;
  13.363 +  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
  13.364 +  {
  13.365 +    ConfigInfo->Master = TRUE;
  13.366 +    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  13.367 +    KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
  13.368 +  }
  13.369 +  else
  13.370 +  {
  13.371 +    ConfigInfo->Master = FALSE;
  13.372 +    KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
  13.373 +  }
  13.374 +
  13.375 +  xvdd->ring_detect_state = 0;
  13.376 +
  13.377 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
  13.378 +
  13.379 +  return SP_RETURN_FOUND;
  13.380 +}
  13.381 +
  13.382 +static BOOLEAN
  13.383 +XenVbd_HwScsiInitialize(PVOID DeviceExtension)
  13.384 +{
  13.385 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
  13.386 +  blkif_request_t *req;
  13.387 +  int i;
  13.388 +  int notify;
  13.389 +  
  13.390 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  13.391 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  13.392 +
  13.393 +  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
  13.394 +  req->operation = 0xff;
  13.395 +  req->nr_segments = 0;
  13.396 +  for (i = 0; i < req->nr_segments; i++)
  13.397 +  {
  13.398 +    req->seg[i].gref = 0xffffffff;
  13.399 +    req->seg[i].first_sect = 0xff;
  13.400 +    req->seg[i].last_sect = 0xff;
  13.401 +  }
  13.402 +  xvdd->ring.req_prod_pvt++;
  13.403 +
  13.404 +  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
  13.405 +  req->operation = 0xff;
  13.406 +  req->nr_segments = 0;
  13.407 +  for (i = 0; i < req->nr_segments; i++)
  13.408 +  {
  13.409 +    req->seg[i].gref = 0xffffffff;
  13.410 +    req->seg[i].first_sect = 0xff;
  13.411 +    req->seg[i].last_sect = 0xff;
  13.412 +  }
  13.413 +  xvdd->ring.req_prod_pvt++;
  13.414 +
  13.415 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
  13.416 +  if (notify)
  13.417 +    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
  13.418 +
  13.419 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, RESUME_CHECK_TIMER_INTERVAL);
  13.420 +
  13.421 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  13.422 +
  13.423 +  return TRUE;
  13.424 +}
  13.425 +
  13.426  static ULONG
  13.427  XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
  13.428  {
  13.429 @@ -461,7 +520,7 @@ XenVbd_FillModePage(PXENVBD_DEVICE_DATA 
  13.430  
  13.431    UNREFERENCED_PARAMETER(xvdd);
  13.432  
  13.433 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  13.434 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  13.435    
  13.436    cdb = (PCDB)srb->Cdb;
  13.437    page_code = cdb->MODE_SENSE.PageCode;
  13.438 @@ -530,7 +589,7 @@ XenVbd_FillModePage(PXENVBD_DEVICE_DATA 
  13.439    srb->ScsiStatus = 0;
  13.440    memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
  13.441    
  13.442 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  13.443 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  13.444  
  13.445    return TRUE;
  13.446  }
  13.447 @@ -709,6 +768,14 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  13.448      return TRUE;
  13.449    }
  13.450  
  13.451 +  if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
  13.452 +  {
  13.453 +    Srb->SrbStatus = SRB_STATUS_BUSY;
  13.454 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  13.455 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Resuming)\n"));
  13.456 +    return TRUE;
  13.457 +  }
  13.458 +
  13.459    if (Srb->PathId != 0 || Srb->TargetId != 0)
  13.460    {
  13.461      Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  13.462 @@ -834,7 +901,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
  13.463        }
  13.464        break;
  13.465      case SCSIOP_READ_CAPACITY:
  13.466 -      KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
  13.467 +      //KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
  13.468        //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", Srb->Cdb[1] >> 4, Srb->Cdb[1] & 1));
  13.469        //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", Srb->Cdb[2], Srb->Cdb[3], Srb->Cdb[4], Srb->Cdb[5]));
  13.470        //KdPrint((__DRIVER_NAME "       PMI = %d\n", Srb->Cdb[8] & 1));
    14.1 --- a/xenvbd/xenvbd.h	Tue Jul 01 15:24:49 2008 -0700
    14.2 +++ b/xenvbd/xenvbd.h	Tue Jul 01 15:30:44 2008 -0700
    14.3 @@ -100,7 +100,10 @@ struct
    14.4    grant_ref_t grant_free_list[MAX_GRANT_ENTRIES];
    14.5    USHORT grant_free;
    14.6    USHORT grant_entries;
    14.7 +  
    14.8 +  PUCHAR device_base;
    14.9  
   14.10 +  blkif_sring_t *sring;
   14.11    evtchn_port_t event_channel;
   14.12    union {
   14.13      blkif_front_ring_t ring;
   14.14 @@ -116,6 +119,7 @@ struct
   14.15    ULONG bytes_per_sector;
   14.16    ULONGLONG total_sectors;
   14.17    XENPCI_VECTORS vectors;
   14.18 +  PXENPCI_DEVICE_STATE device_state;
   14.19    PSCSI_REQUEST_BLOCK pending_srb;
   14.20    
   14.21    ULONGLONG interrupts;