win-pvdrivers

changeset 267:f157f82e0293 wdm

Continued porting to WDM. vbd is almost working.
author James Harper <james.harper@bendigoit.com.au>
date Mon May 12 00:20:02 2008 +1000 (2008-05-12)
parents b88529df8b60
children f28ce60f3fa7
files common/include/xen_public.h common/include/xen_windows.h xenpci/evtchn.c xenpci/gnttbl.c xenpci/xenbus.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c xenvbd/sources xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/common/include/xen_public.h	Wed May 07 10:47:03 2008 +1000
     1.2 +++ b/common/include/xen_public.h	Mon May 12 00:20:02 2008 +1000
     1.3 @@ -90,6 +90,7 @@ typedef char *
     1.4  typedef char *
     1.5  (*PXEN_XENBUS_REMWATCH)(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
     1.6  
     1.7 +#if 0
     1.8  typedef struct _XEN_IFACE {
     1.9    INTERFACE InterfaceHeader;
    1.10  
    1.11 @@ -119,9 +120,6 @@ typedef struct _XEN_IFACE {
    1.12    PXEN_XENBUS_REMWATCH XenBus_RemWatch;
    1.13  } XEN_IFACE, *PXEN_IFACE;
    1.14  
    1.15 -#define XEN_DATA_MAGIC 0x12345678
    1.16 -
    1.17 -#if 0
    1.18  typedef struct _XENPCI_IDENTIFICATION_DESCRIPTION
    1.19  {
    1.20    WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Header;
    1.21 @@ -129,20 +127,267 @@ typedef struct _XENPCI_IDENTIFICATION_DE
    1.22    char Path[128];
    1.23    ULONG DeviceIndex;
    1.24  } XENPCI_IDENTIFICATION_DESCRIPTION, *PXENPCI_IDENTIFICATION_DESCRIPTION;
    1.25 +#endif
    1.26 +
    1.27 +
    1.28 +#define XEN_DATA_MAGIC 0x12345678
    1.29  
    1.30  typedef struct {
    1.31 -  ULONG Magic;
    1.32 -  char Path[128];
    1.33 -  ULONG DeviceIndex;
    1.34 -  PXENBUS_WATCH_CALLBACK WatchHandler;
    1.35 -  PVOID WatchContext;
    1.36 -  XEN_IFACE XenInterface;
    1.37 -  BOOLEAN AutoEnumerate;
    1.38 -  CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw;
    1.39 -  CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated;
    1.40 -} XENPCI_XEN_DEVICE_DATA, *PXENPCI_XEN_DEVICE_DATA;
    1.41 +  ULONG magic;
    1.42 +  USHORT length;
    1.43 +
    1.44 +  PVOID context;
    1.45 +  PXEN_EVTCHN_BIND EvtChn_Bind;
    1.46 +  PXEN_EVTCHN_BIND EvtChn_BindDpc;
    1.47 +  PXEN_EVTCHN_UNBIND EvtChn_Unbind;
    1.48 +  PXEN_EVTCHN_MASK EvtChn_Mask;
    1.49 +  PXEN_EVTCHN_UNMASK EvtChn_Unmask;
    1.50 +  PXEN_EVTCHN_NOTIFY EvtChn_Notify;
    1.51 +  PXEN_GNTTBL_GETREF GntTbl_GetRef;
    1.52 +  PXEN_GNTTBL_PUTREF GntTbl_PutRef;
    1.53 +  PXEN_GNTTBL_GRANTACCESS GntTbl_GrantAccess;
    1.54 +  PXEN_GNTTBL_ENDACCESS GntTbl_EndAccess;
    1.55 +} XENPCI_VECTORS, *PXENPCI_VECTORS;
    1.56 +
    1.57 +
    1.58 +#define XEN_INIT_TYPE_END               0
    1.59 +#define XEN_INIT_TYPE_WRITE_STRING      1
    1.60 +#define XEN_INIT_TYPE_RING              2
    1.61 +#define XEN_INIT_TYPE_EVENT_CHANNEL     3
    1.62 +#define XEN_INIT_TYPE_EVENT_CHANNEL_IRQ 4
    1.63 +#define XEN_INIT_TYPE_READ_STRING_FRONT 5
    1.64 +#define XEN_INIT_TYPE_READ_STRING_BACK  6
    1.65 +#define XEN_INIT_TYPE_VECTORS           7
    1.66 +#define XEN_INIT_TYPE_GRANT_ENTRIES     8
    1.67 +
    1.68 +static __inline VOID
    1.69 +__ADD_XEN_INIT_UCHAR(PUCHAR *ptr, UCHAR val)
    1.70 +{
    1.71 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_UCHAR *ptr = %p, val = %d\n", *ptr, val));
    1.72 +  *(PUCHAR)(*ptr) = val;
    1.73 +  *ptr += sizeof(UCHAR);
    1.74 +}
    1.75 +
    1.76 +static __inline VOID
    1.77 +__ADD_XEN_INIT_USHORT(PUCHAR *ptr, USHORT val)
    1.78 +{
    1.79 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_USHORT *ptr = %p, val = %d\n", *ptr, val));
    1.80 +  *(PUSHORT)(*ptr) = val;
    1.81 +  *ptr += sizeof(USHORT);
    1.82 +}
    1.83 +
    1.84 +static __inline VOID
    1.85 +__ADD_XEN_INIT_ULONG(PUCHAR *ptr, ULONG val)
    1.86 +{
    1.87 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_ULONG *ptr = %p, val = %d\n", *ptr, val));
    1.88 +  *(PULONG)(*ptr) = val;
    1.89 +  *ptr += sizeof(ULONG);
    1.90 +}
    1.91 +
    1.92 +static __inline VOID
    1.93 +__ADD_XEN_INIT_PTR(PUCHAR *ptr, PVOID val)
    1.94 +{
    1.95 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_PTR *ptr = %p, val = %p\n", *ptr, val));
    1.96 +  *(PVOID *)(*ptr) = val;
    1.97 +  *ptr += sizeof(PVOID);
    1.98 +}
    1.99 +
   1.100 +static __inline VOID
   1.101 +__ADD_XEN_INIT_STRING(PUCHAR *ptr, PCHAR val)
   1.102 +{
   1.103 +//  KdPrint((__DRIVER_NAME "     ADD_XEN_INIT_STRING *ptr = %p, val = %s\n", *ptr, val));
   1.104 +  RtlStringCbCopyA((PCHAR)*ptr, PAGE_SIZE - (PtrToUlong(*ptr) & (PAGE_SIZE - 1)), val);
   1.105 +  *ptr += strlen(val) + 1;
   1.106 +}
   1.107 +
   1.108 +static __inline UCHAR
   1.109 +__GET_XEN_INIT_UCHAR(PUCHAR *ptr)
   1.110 +{
   1.111 +  UCHAR retval;
   1.112 +  retval = **ptr;
   1.113 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_UCHAR *ptr = %p, retval = %d\n", *ptr, retval));
   1.114 +  *ptr += sizeof(UCHAR);
   1.115 +  return retval;
   1.116 +}
   1.117 +
   1.118 +static __inline USHORT
   1.119 +__GET_XEN_INIT_USHORT(PUCHAR *ptr)
   1.120 +{
   1.121 +  USHORT retval;
   1.122 +  retval = *(PUSHORT)*ptr;
   1.123 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_USHORT *ptr = %p, retval = %d\n", *ptr, retval));
   1.124 +  *ptr += sizeof(USHORT);
   1.125 +  return retval;
   1.126 +}
   1.127 +
   1.128 +static __inline ULONG
   1.129 +__GET_XEN_INIT_ULONG(PUCHAR *ptr)
   1.130 +{
   1.131 +  ULONG retval;
   1.132 +  retval = *(PLONG)*ptr;
   1.133 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_ULONG *ptr = %p, retval = %d\n", *ptr, retval));
   1.134 +  *ptr += sizeof(ULONG);
   1.135 +  return retval;
   1.136 +}
   1.137 +
   1.138 +static __inline PCHAR
   1.139 +__GET_XEN_INIT_STRING(PUCHAR *ptr)
   1.140 +{
   1.141 +  PCHAR retval;
   1.142 +  retval = (PCHAR)*ptr;
   1.143 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_STRING *ptr = %p, retval = %s\n", *ptr, retval));
   1.144 +  *ptr += strlen((PCHAR)*ptr) + 1;
   1.145 +  return retval;
   1.146 +}
   1.147 +
   1.148 +static __inline PVOID
   1.149 +__GET_XEN_INIT_PTR(PUCHAR *ptr)
   1.150 +{
   1.151 +  PVOID retval;
   1.152 +  retval = *(PVOID *)(*ptr);
   1.153 +//  KdPrint((__DRIVER_NAME "     GET_XEN_INIT_PTR *ptr = %p, retval = %p\n", *ptr, retval));
   1.154 +  *ptr += sizeof(PVOID);
   1.155 +  return retval;
   1.156 +}
   1.157  
   1.158 -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_XEN_DEVICE_DATA, GetXenDeviceData);
   1.159 -#endif
   1.160 +static __inline VOID
   1.161 +ADD_XEN_INIT_REQ(PUCHAR *ptr, UCHAR type, PVOID p1, PVOID p2)
   1.162 +{
   1.163 +  __ADD_XEN_INIT_UCHAR(ptr, type);
   1.164 +  switch (type)
   1.165 +  {
   1.166 +  case XEN_INIT_TYPE_END:
   1.167 +  case XEN_INIT_TYPE_VECTORS:
   1.168 +    break;
   1.169 +  case XEN_INIT_TYPE_WRITE_STRING:
   1.170 +    __ADD_XEN_INIT_STRING(ptr, p1);
   1.171 +    __ADD_XEN_INIT_STRING(ptr, p2);
   1.172 +    break;
   1.173 +  case XEN_INIT_TYPE_RING:
   1.174 +  case XEN_INIT_TYPE_EVENT_CHANNEL:
   1.175 +  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   1.176 +  case XEN_INIT_TYPE_READ_STRING_FRONT:
   1.177 +  case XEN_INIT_TYPE_READ_STRING_BACK:
   1.178 +    __ADD_XEN_INIT_STRING(ptr, p1);
   1.179 +    break;
   1.180 +  case XEN_INIT_TYPE_GRANT_ENTRIES:
   1.181 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
   1.182 +    break;
   1.183 +  }
   1.184 +}
   1.185 +
   1.186 +static __inline UCHAR
   1.187 +GET_XEN_INIT_REQ(PUCHAR *ptr, PVOID *p1, PVOID *p2)
   1.188 +{
   1.189 +  UCHAR retval;
   1.190 +
   1.191 +  retval = __GET_XEN_INIT_UCHAR(ptr);
   1.192 +  switch (retval)
   1.193 +  {
   1.194 +  case XEN_INIT_TYPE_END:
   1.195 +  case XEN_INIT_TYPE_VECTORS:
   1.196 +    *p1 = NULL;
   1.197 +    *p2 = NULL;
   1.198 +    break;
   1.199 +  case XEN_INIT_TYPE_WRITE_STRING:
   1.200 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   1.201 +    *p2 = __GET_XEN_INIT_STRING(ptr);
   1.202 +    break;
   1.203 +  case XEN_INIT_TYPE_RING:
   1.204 +  case XEN_INIT_TYPE_EVENT_CHANNEL:
   1.205 +  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   1.206 +  case XEN_INIT_TYPE_READ_STRING_FRONT:
   1.207 +  case XEN_INIT_TYPE_READ_STRING_BACK:
   1.208 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   1.209 +    *p2 = NULL;
   1.210 +    break;
   1.211 +  case XEN_INIT_TYPE_GRANT_ENTRIES:
   1.212 +    *p1 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   1.213 +    break;
   1.214 +  }
   1.215 +  return retval;
   1.216 +}
   1.217 +
   1.218 +static __inline VOID
   1.219 +ADD_XEN_INIT_RSP(PUCHAR *ptr, UCHAR type, PVOID p1, PVOID p2)
   1.220 +{
   1.221 +  __ADD_XEN_INIT_UCHAR(ptr, type);
   1.222 +  switch (type)
   1.223 +  {
   1.224 +  case XEN_INIT_TYPE_END:
   1.225 +  case XEN_INIT_TYPE_WRITE_STRING: /* this shouldn't happen */
   1.226 +    break;
   1.227 +  case XEN_INIT_TYPE_RING:
   1.228 +    __ADD_XEN_INIT_STRING(ptr, p1);
   1.229 +    __ADD_XEN_INIT_PTR(ptr, p2);
   1.230 +    break;
   1.231 +  case XEN_INIT_TYPE_EVENT_CHANNEL:
   1.232 +  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   1.233 +    __ADD_XEN_INIT_STRING(ptr, p1);
   1.234 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
   1.235 +    break;
   1.236 +  case XEN_INIT_TYPE_READ_STRING_FRONT:
   1.237 +  case XEN_INIT_TYPE_READ_STRING_BACK:
   1.238 +    __ADD_XEN_INIT_STRING(ptr, p1);
   1.239 +    __ADD_XEN_INIT_STRING(ptr, p2);
   1.240 +    break;
   1.241 +  case XEN_INIT_TYPE_VECTORS:
   1.242 +    //__ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
   1.243 +    memcpy(*ptr, p2, sizeof(XENPCI_VECTORS));
   1.244 +    *ptr += sizeof(XENPCI_VECTORS);
   1.245 +    break;
   1.246 +  case XEN_INIT_TYPE_GRANT_ENTRIES:
   1.247 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
   1.248 +    memcpy(*ptr, p2, PtrToUlong(p1) * sizeof(grant_entry_t));
   1.249 +    *ptr += PtrToUlong(p1) * sizeof(grant_entry_t);
   1.250 +    break;
   1.251 +  }
   1.252 +}
   1.253 +
   1.254 +static __inline UCHAR
   1.255 +GET_XEN_INIT_RSP(PUCHAR *ptr, PVOID *p1, PVOID *p2)
   1.256 +{
   1.257 +  UCHAR retval;
   1.258 +
   1.259 +  retval = __GET_XEN_INIT_UCHAR(ptr);
   1.260 +  switch (retval)
   1.261 +  {
   1.262 +  case XEN_INIT_TYPE_END:
   1.263 +    *p1 = NULL;
   1.264 +    *p2 = NULL;
   1.265 +    break;
   1.266 +  case XEN_INIT_TYPE_WRITE_STRING:
   1.267 +    // this shouldn't happen - no response here
   1.268 +    break;
   1.269 +  case XEN_INIT_TYPE_RING:
   1.270 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   1.271 +    *p2 = __GET_XEN_INIT_PTR(ptr);
   1.272 +    break;
   1.273 +  case XEN_INIT_TYPE_EVENT_CHANNEL:
   1.274 +  case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ:
   1.275 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   1.276 +    *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   1.277 +    break;
   1.278 +  case XEN_INIT_TYPE_READ_STRING_FRONT:
   1.279 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   1.280 +    *p2 = __GET_XEN_INIT_STRING(ptr);
   1.281 +    break;
   1.282 +  case XEN_INIT_TYPE_READ_STRING_BACK:
   1.283 +    *p1 = __GET_XEN_INIT_STRING(ptr);
   1.284 +    *p2 = __GET_XEN_INIT_STRING(ptr);
   1.285 +    break;
   1.286 +  case XEN_INIT_TYPE_VECTORS:
   1.287 +    *p1 = NULL;
   1.288 +    *p2 = *ptr;
   1.289 +    *ptr += ((PXENPCI_VECTORS)*p2)->length;
   1.290 +    break;
   1.291 +  case XEN_INIT_TYPE_GRANT_ENTRIES:
   1.292 +    *p1 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
   1.293 +    *p2 = *ptr;
   1.294 +    *ptr += PtrToUlong(*p1) * sizeof(grant_entry_t);
   1.295 +    break;
   1.296 +  }
   1.297 +  return retval;
   1.298 +}
   1.299  
   1.300  #endif
     2.1 --- a/common/include/xen_windows.h	Wed May 07 10:47:03 2008 +1000
     2.2 +++ b/common/include/xen_windows.h	Mon May 12 00:20:02 2008 +1000
     2.3 @@ -46,6 +46,9 @@ typedef uint32_t XENSTORE_RING_IDX;
     2.4  
     2.5  #define SPLITSTRING_POOL_TAG (ULONG) 'SSPT'
     2.6  
     2.7 +#define wmb() KeMemoryBarrier()
     2.8 +#define mb() KeMemoryBarrier()
     2.9 +
    2.10  static char **
    2.11  SplitString(char *String, char Split, int MaxParts, int *Count)
    2.12  {
     3.1 --- a/xenpci/evtchn.c	Wed May 07 10:47:03 2008 +1000
     3.2 +++ b/xenpci/evtchn.c	Mon May 12 00:20:02 2008 +1000
     3.3 @@ -40,7 +40,10 @@ EvtChn_DpcBounce(PRKDPC Dpc, PVOID Conte
     3.4    UNREFERENCED_PARAMETER(SystemArgument1);
     3.5    UNREFERENCED_PARAMETER(SystemArgument2);
     3.6  
     3.7 -  action->ServiceRoutine(NULL, action->ServiceContext);
     3.8 +  if (action->type == EVT_ACTION_TYPE_IRQ)
     3.9 +    sw_interrupt((UCHAR)action->vector);
    3.10 +  else
    3.11 +    action->ServiceRoutine(NULL, action->ServiceContext);
    3.12  }
    3.13  
    3.14  static BOOLEAN
    3.15 @@ -56,7 +59,7 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    3.16    unsigned int port;
    3.17    ev_action_t *ev_action;
    3.18  
    3.19 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", cpu));
    3.20 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", cpu));
    3.21  
    3.22    UNREFERENCED_PARAMETER(Interrupt);
    3.23  
    3.24 @@ -73,53 +76,50 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    3.25      {
    3.26        port = (evt_word << 5) + evt_bit;
    3.27        ev_action = &xpdd->ev_actions[port];
    3.28 -      if (ev_action->ServiceRoutine == NULL)
    3.29 -      {
    3.30 -        KdPrint((__DRIVER_NAME "     Unhandled Event!!!\n"));
    3.31 -      }
    3.32 -      else
    3.33 +      switch (ev_action->type)
    3.34        {
    3.35 -        if (ev_action->DpcFlag)
    3.36 -        {
    3.37 -          KdPrint((__DRIVER_NAME "     Scheduling Dpc\n"));
    3.38 -          KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
    3.39 -        }
    3.40 -        else
    3.41 -        {
    3.42 -          ev_action->ServiceRoutine(NULL, ev_action->ServiceContext);
    3.43 -        }
    3.44 +      case EVT_ACTION_TYPE_NORMAL:
    3.45 +        ev_action->ServiceRoutine(NULL, ev_action->ServiceContext);
    3.46 +        break;
    3.47 +      case EVT_ACTION_TYPE_DPC:
    3.48 +      case EVT_ACTION_TYPE_IRQ: /* we have to call the IRQ from DPC or we risk mucking up IRQLs */
    3.49 +        KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
    3.50 +        break;
    3.51 +      default:
    3.52 +        KdPrint((__DRIVER_NAME "     Unhandled Event!!!\n"));
    3.53 +        break;
    3.54        }
    3.55        synch_clear_bit(port, (volatile xen_long_t *)&shared_info_area->evtchn_pending[evt_word]);
    3.56      }
    3.57    }
    3.58  
    3.59 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    3.60 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    3.61  
    3.62 -  /* Need to return FALSE so we can fall through to the scsiport ISR. */
    3.63 -  return FALSE;
    3.64 +  return TRUE;
    3.65  }
    3.66  
    3.67  NTSTATUS
    3.68  EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
    3.69  {
    3.70    PXENPCI_DEVICE_DATA xpdd = Context;
    3.71 -  //KdPrint((__DRIVER_NAME " --> EvtChn_Bind (ServiceRoutine = %08X, ServiceContext = %08x)\n", ServiceRoutine, ServiceContext));
    3.72  
    3.73 -  if(xpdd->ev_actions[Port].ServiceRoutine != NULL)
    3.74 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    3.75 +  
    3.76 +  if (xpdd->ev_actions[Port].type != EVT_ACTION_TYPE_EMPTY)
    3.77    {
    3.78 -    xpdd->ev_actions[Port].ServiceRoutine = NULL;
    3.79 +    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_EMPTY;
    3.80      KeMemoryBarrier(); // make sure we don't call the old Service Routine with the new data...
    3.81      KdPrint((__DRIVER_NAME " Handler for port %d already registered, replacing\n", Port));
    3.82    }
    3.83  
    3.84 -  xpdd->ev_actions[Port].DpcFlag = FALSE;
    3.85 +  xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
    3.86    xpdd->ev_actions[Port].ServiceContext = ServiceContext;
    3.87    KeMemoryBarrier();
    3.88 -  xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
    3.89 +  xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_NORMAL;
    3.90  
    3.91    EvtChn_Unmask(Context, Port);
    3.92  
    3.93 -  KdPrint((__DRIVER_NAME " <-- EvtChn_Bind\n"));
    3.94 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    3.95  
    3.96    return STATUS_SUCCESS;
    3.97  }
    3.98 @@ -129,26 +129,50 @@ EvtChn_BindDpc(PVOID Context, evtchn_por
    3.99  {
   3.100    PXENPCI_DEVICE_DATA xpdd = Context;
   3.101  
   3.102 -  KdPrint((__DRIVER_NAME " --> EvtChn_BindDpc\n"));
   3.103 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.104  
   3.105 -  if(xpdd->ev_actions[Port].ServiceRoutine != NULL)
   3.106 +  if (xpdd->ev_actions[Port].type != EVT_ACTION_TYPE_EMPTY)
   3.107    {
   3.108 +    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_EMPTY;
   3.109 +    KeMemoryBarrier(); // make sure we don't call the old Service Routine with the new data...
   3.110      KdPrint((__DRIVER_NAME " Handler for port %d already registered, replacing\n", Port));
   3.111 -    xpdd->ev_actions[Port].ServiceRoutine = NULL;
   3.112 -    KeMemoryBarrier(); // make sure we don't call the old Service Routine with the new data...
   3.113    }
   3.114  
   3.115 +  xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
   3.116    xpdd->ev_actions[Port].ServiceContext = ServiceContext;
   3.117 -  xpdd->ev_actions[Port].DpcFlag = TRUE;
   3.118 -
   3.119    KeInitializeDpc(&xpdd->ev_actions[Port].Dpc, EvtChn_DpcBounce, &xpdd->ev_actions[Port]);
   3.120 -
   3.121    KeMemoryBarrier(); // make sure that the new service routine is only called once the context is set up
   3.122 -  xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
   3.123 +  xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_DPC;
   3.124  
   3.125    EvtChn_Unmask(Context, Port);
   3.126  
   3.127 -  KdPrint((__DRIVER_NAME " <-- EvtChn_BindDpc\n"));
   3.128 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.129 +
   3.130 +  return STATUS_SUCCESS;
   3.131 +}
   3.132 +
   3.133 +NTSTATUS
   3.134 +EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector)
   3.135 +{
   3.136 +  PXENPCI_DEVICE_DATA xpdd = Context;
   3.137 +
   3.138 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.139 +
   3.140 +  if (xpdd->ev_actions[Port].type != EVT_ACTION_TYPE_EMPTY)
   3.141 +  {
   3.142 +    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_EMPTY;
   3.143 +    KeMemoryBarrier(); // make sure we don't call the old Service Routine with the new data...
   3.144 +    KdPrint((__DRIVER_NAME " Handler for port %d already registered, replacing\n", Port));
   3.145 +  }
   3.146 +
   3.147 +  KeInitializeDpc(&xpdd->ev_actions[Port].Dpc, EvtChn_DpcBounce, &xpdd->ev_actions[Port]);
   3.148 +  xpdd->ev_actions[Port].vector = vector;
   3.149 +  KeMemoryBarrier();
   3.150 +  xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_IRQ;
   3.151 +
   3.152 +  EvtChn_Unmask(Context, Port);
   3.153 +
   3.154 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.155  
   3.156    return STATUS_SUCCESS;
   3.157  }
   3.158 @@ -163,11 +187,9 @@ EvtChn_Unbind(PVOID Context, evtchn_port
   3.159    KeMemoryBarrier();
   3.160    xpdd->ev_actions[Port].ServiceContext = NULL;
   3.161  
   3.162 -  if (xpdd->ev_actions[Port].DpcFlag)
   3.163 +  if (xpdd->ev_actions[Port].type == EVT_ACTION_TYPE_DPC)
   3.164      KeRemoveQueueDpc(&xpdd->ev_actions[Port].Dpc);
   3.165    
   3.166 -  //KdPrint((__DRIVER_NAME " <-- EvtChn_UnBind\n"));
   3.167 -
   3.168    return STATUS_SUCCESS;
   3.169  }
   3.170  
   3.171 @@ -219,8 +241,7 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
   3.172    for (i = 0; i < NR_EVENTS; i++)
   3.173    {
   3.174      EvtChn_Mask(xpdd, i);
   3.175 -    xpdd->ev_actions[i].ServiceRoutine = NULL;
   3.176 -    xpdd->ev_actions[i].ServiceContext = NULL;
   3.177 +    xpdd->ev_actions[i].type = EVT_ACTION_TYPE_EMPTY;
   3.178      xpdd->ev_actions[i].Count = 0;
   3.179    }
   3.180  
     4.1 --- a/xenpci/gnttbl.c	Wed May 07 10:47:03 2008 +1000
     4.2 +++ b/xenpci/gnttbl.c	Mon May 12 00:20:02 2008 +1000
     4.3 @@ -25,6 +25,7 @@ GntTbl_PutRef(PVOID Context, grant_ref_t
     4.4    PXENPCI_DEVICE_DATA xpdd = Context;
     4.5    KIRQL OldIrql;
     4.6  
     4.7 +  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
     4.8    KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
     4.9    xpdd->gnttab_list[ref] = xpdd->gnttab_list[0];
    4.10    xpdd->gnttab_list[0]  = ref;
    4.11 @@ -38,6 +39,7 @@ GntTbl_GetRef(PVOID Context)
    4.12    unsigned int ref;
    4.13    KIRQL OldIrql;
    4.14  
    4.15 +  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    4.16    KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
    4.17    ref = xpdd->gnttab_list[0];
    4.18    xpdd->gnttab_list[0] = xpdd->gnttab_list[ref];
    4.19 @@ -141,7 +143,7 @@ GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
    4.20    xpdd->gnttab_table_physical = XenPci_AllocMMIO(xpdd,
    4.21      PAGE_SIZE * NR_GRANT_FRAMES);
    4.22    xpdd->gnttab_table = MmMapIoSpace(xpdd->gnttab_table_physical,
    4.23 -    PAGE_SIZE * NR_GRANT_FRAMES, MmCached);
    4.24 +    PAGE_SIZE * NR_GRANT_FRAMES, MmNonCached);
    4.25    if (!xpdd->gnttab_table)
    4.26    {
    4.27      KdPrint((__DRIVER_NAME "     Error Mapping Grant Table Shared Memory\n"));
     5.1 --- a/xenpci/xenbus.c	Wed May 07 10:47:03 2008 +1000
     5.2 +++ b/xenpci/xenbus.c	Mon May 12 00:20:02 2008 +1000
     5.3 @@ -297,7 +297,7 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
     5.4    NTSTATUS Status;
     5.5    int i;
     5.6      
     5.7 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     5.8 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     5.9  
    5.10    KeInitializeSpinLock(&xpdd->WatchLock);
    5.11  
    5.12 @@ -305,7 +305,7 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
    5.13  
    5.14    xen_store_mfn = (xen_ulong_t)hvm_get_parameter(xpdd, HVM_PARAM_STORE_PFN);
    5.15    pa_xen_store_interface.QuadPart = xen_store_mfn << PAGE_SHIFT;
    5.16 -  xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmCached);
    5.17 +  xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
    5.18  
    5.19    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
    5.20    {
    5.21 @@ -334,7 +334,7 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
    5.22  
    5.23    EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Interrupt, xpdd);
    5.24  
    5.25 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.26 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.27  
    5.28    return STATUS_SUCCESS;
    5.29  }
    5.30 @@ -344,7 +344,7 @@ XenBus_Stop(PXENPCI_DEVICE_DATA xpdd)
    5.31  {
    5.32    int i;
    5.33  
    5.34 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.35 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.36  
    5.37    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
    5.38    {
    5.39 @@ -356,7 +356,7 @@ XenBus_Stop(PXENPCI_DEVICE_DATA xpdd)
    5.40  
    5.41    EvtChn_Unbind(xpdd, xpdd->xen_store_evtchn);
    5.42  
    5.43 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.44 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.45  
    5.46    return STATUS_SUCCESS;
    5.47  }
    5.48 @@ -380,7 +380,7 @@ XenBus_Close(PXENPCI_DEVICE_DATA xpdd)
    5.49    ZwClose(xpdd->XenBus_WatchThreadHandle);
    5.50    ZwClose(xpdd->XenBus_ReadThreadHandle);
    5.51  
    5.52 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.53 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.54  
    5.55    return STATUS_SUCCESS;
    5.56  }
    5.57 @@ -447,7 +447,6 @@ XenBus_ReadThreadProc(PVOID StartContext
    5.58        KdPrint((__DRIVER_NAME "     Shutdown detected in ReadThreadProc\n"));
    5.59        PsTerminateSystemThread(0);
    5.60      }
    5.61 -    KdPrint((__DRIVER_NAME "     ReadThread Woken\n"));
    5.62      while (xpdd->xen_store_interface->rsp_prod != xpdd->xen_store_interface->rsp_cons)
    5.63      {
    5.64        //KdPrint((__DRIVER_NAME "     a - Rsp_cons %d, rsp_prod %d.\n", xen_store_interface->rsp_cons, xen_store_interface->rsp_prod));
    5.65 @@ -537,7 +536,6 @@ XenBus_WatchThreadProc(PVOID StartContex
    5.66          KdPrint((__DRIVER_NAME "     No watch for index %d\n", index));
    5.67          continue;
    5.68        }
    5.69 -KdPrint((__DRIVER_NAME " --- About to call watch\n"));
    5.70        if (entry->RemovePending)
    5.71        {
    5.72          KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
    5.73 @@ -572,7 +570,7 @@ XenBus_AddWatch(
    5.74    PXENBUS_WATCH_ENTRY w_entry;
    5.75    KIRQL OldIrql;
    5.76  
    5.77 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.78 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.79  
    5.80    ASSERT(strlen(Path) < ARRAY_SIZE(w_entry->Path));
    5.81  
    5.82 @@ -639,7 +637,7 @@ XenBus_RemWatch(
    5.83    struct write_req req[2];
    5.84    KIRQL OldIrql;
    5.85  
    5.86 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.87 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.88  
    5.89    KeAcquireSpinLock(&xpdd->WatchLock, &OldIrql);
    5.90  
    5.91 @@ -696,7 +694,7 @@ XenBus_RemWatch(
    5.92  
    5.93    ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    5.94  
    5.95 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.96 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    5.97  
    5.98    return NULL;
    5.99  }
     6.1 --- a/xenpci/xenpci.h	Wed May 07 10:47:03 2008 +1000
     6.2 +++ b/xenpci/xenpci.h	Mon May 12 00:20:02 2008 +1000
     6.3 @@ -42,6 +42,7 @@ Foundation, Inc., 51 Franklin Street, Fi
     6.4  #include <hvm/params.h>
     6.5  #include <hvm/hvm_op.h>
     6.6  #include <sched.h>
     6.7 +#include <io/xenbus.h>
     6.8  
     6.9  #include <xen_public.h>
    6.10  
    6.11 @@ -56,11 +57,17 @@ DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC82
    6.12  
    6.13  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    6.14  
    6.15 +#define EVT_ACTION_TYPE_EMPTY  0
    6.16 +#define EVT_ACTION_TYPE_NORMAL 1
    6.17 +#define EVT_ACTION_TYPE_DPC    2
    6.18 +#define EVT_ACTION_TYPE_IRQ    3
    6.19 +
    6.20  typedef struct _ev_action_t {
    6.21    PKSERVICE_ROUTINE ServiceRoutine;
    6.22    PVOID ServiceContext;
    6.23 -  BOOLEAN DpcFlag;
    6.24 +  ULONG type; /* EVT_ACTION_TYPE_* */
    6.25    KDPC Dpc;
    6.26 +  ULONG vector;
    6.27    ULONG Count;
    6.28  } ev_action_t;
    6.29  
    6.30 @@ -123,6 +130,7 @@ typedef struct {
    6.31    ULONG platform_mmio_orig_len;
    6.32    ULONG platform_mmio_len;
    6.33    ULONG platform_mmio_alloc;
    6.34 +  USHORT platform_mmio_flags;
    6.35  
    6.36    char *hypercall_stubs;
    6.37  
    6.38 @@ -164,8 +172,14 @@ typedef struct {
    6.39    XENPCI_COMMON common;
    6.40    PDEVICE_OBJECT bus_fdo;
    6.41    char path[128];
    6.42 +  char device[128];
    6.43    ULONG index;
    6.44 -  PHYSICAL_ADDRESS mmio_phys;
    6.45 +  //PHYSICAL_ADDRESS mmio_phys;
    6.46 +  ULONG irq_vector;
    6.47 +  KIRQL irq_level;
    6.48 +  char backend_path[128];
    6.49 +  KEVENT backend_state_event;
    6.50 +  ULONG backend_state;
    6.51  } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
    6.52  
    6.53  typedef struct
    6.54 @@ -174,6 +188,36 @@ typedef struct
    6.55    int state;
    6.56    PXENPCI_PDO_DEVICE_DATA context;
    6.57  } XEN_CHILD, *PXEN_CHILD;
    6.58 +
    6.59 +#define SWINT(x) case x: __asm { int x } break;
    6.60 +
    6.61 +static __inline VOID
    6.62 +sw_interrupt(UCHAR intno)
    6.63 +{
    6.64 +  KdPrint((__DRIVER_NAME "     Calling interrupt %02X\n", intno));
    6.65 +  switch (intno)
    6.66 +  {
    6.67 +  SWINT(0x10) SWINT(0x11) SWINT(0x12) SWINT(0x13) SWINT(0x14) SWINT(0x15) SWINT(0x16) SWINT(0x17)
    6.68 +  SWINT(0x18) SWINT(0x19) SWINT(0x1A) SWINT(0x1B) SWINT(0x1C) SWINT(0x1D) SWINT(0x1E) SWINT(0x1F)
    6.69 +  SWINT(0x20) SWINT(0x21) SWINT(0x22) SWINT(0x23) SWINT(0x24) SWINT(0x25) SWINT(0x26) SWINT(0x27)
    6.70 +  SWINT(0x28) SWINT(0x29) SWINT(0x2A) SWINT(0x2B) SWINT(0x2C) SWINT(0x2D) SWINT(0x2E) SWINT(0x2F)
    6.71 +  SWINT(0x30) SWINT(0x31) SWINT(0x32) SWINT(0x33) SWINT(0x34) SWINT(0x35) SWINT(0x36) SWINT(0x37)
    6.72 +  SWINT(0x38) SWINT(0x39) SWINT(0x3A) SWINT(0x3B) SWINT(0x3C) SWINT(0x3D) SWINT(0x3E) SWINT(0x3F)
    6.73 +  SWINT(0x40) SWINT(0x41) SWINT(0x42) SWINT(0x43) SWINT(0x44) SWINT(0x45) SWINT(0x46) SWINT(0x47)
    6.74 +  SWINT(0x48) SWINT(0x49) SWINT(0x4A) SWINT(0x4B) SWINT(0x4C) SWINT(0x4D) SWINT(0x4E) SWINT(0x4F)
    6.75 +
    6.76 +  SWINT(0x80) SWINT(0x81) SWINT(0x82) SWINT(0x83) SWINT(0x84) SWINT(0x85) SWINT(0x86) SWINT(0x87)
    6.77 +  SWINT(0x88) SWINT(0x89) SWINT(0x8A) SWINT(0x8B) SWINT(0x8C) SWINT(0x8D) SWINT(0x8E) SWINT(0x8F)
    6.78 +
    6.79 +  SWINT(0xB0) SWINT(0xB1) SWINT(0xB2) SWINT(0xB3) SWINT(0xB4) SWINT(0xB5) SWINT(0xB6) SWINT(0xB7)
    6.80 +  SWINT(0xB8) SWINT(0xB9) SWINT(0xBA) SWINT(0xBB) SWINT(0xBC) SWINT(0xBD) SWINT(0xBE) SWINT(0xBF)
    6.81 +
    6.82 +  default:
    6.83 +    KdPrint((__DRIVER_NAME "     interrupt %02X not set up. Blame James.\n", intno));
    6.84 +    KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000002, (ULONG)intno, 0x00000000, 0x00000000);
    6.85 +    break;
    6.86 +  }
    6.87 +}    
    6.88    
    6.89  #include "hypercall.h"
    6.90  
    6.91 @@ -182,6 +226,12 @@ typedef uint32_t XENSTORE_RING_IDX;
    6.92  
    6.93  #define XBT_NIL ((xenbus_transaction_t)0)
    6.94  
    6.95 +static __inline VOID
    6.96 +XenPci_FreeMem(PVOID Ptr)
    6.97 +{
    6.98 +  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
    6.99 +}
   6.100 +
   6.101  NTSTATUS
   6.102  XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.103  NTSTATUS
   6.104 @@ -242,6 +292,8 @@ EvtChn_Bind(PVOID Context, evtchn_port_t
   6.105  NTSTATUS
   6.106  EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
   6.107  NTSTATUS
   6.108 +EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector);
   6.109 +NTSTATUS
   6.110  EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
   6.111  NTSTATUS
   6.112  EvtChn_Notify(PVOID Context, evtchn_port_t Port);
     7.1 --- a/xenpci/xenpci_fdo.c	Wed May 07 10:47:03 2008 +1000
     7.2 +++ b/xenpci/xenpci_fdo.c	Mon May 12 00:20:02 2008 +1000
     7.3 @@ -25,45 +25,13 @@ Foundation, Inc., 51 Franklin Street, Fi
     7.4  #define SHUTDOWN_PATH "control/shutdown"
     7.5  #define BALLOON_PATH "memory/target"
     7.6  
     7.7 -#if 0
     7.8 -static NTSTATUS
     7.9 -XenPCI_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
    7.10 -static NTSTATUS
    7.11 -XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
    7.12 -static NTSTATUS
    7.13 -XenPCI_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
    7.14 -static NTSTATUS
    7.15 -XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE  Device, WDF_POWER_DEVICE_STATE PreviousState);
    7.16 -static NTSTATUS
    7.17 -XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
    7.18 -static NTSTATUS
    7.19 -XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE  Device, WDF_POWER_DEVICE_STATE TargetState);
    7.20 -static VOID
    7.21 -XenPCI_IoDefault(WDFQUEUE Queue, WDFREQUEST Request);
    7.22 -static VOID 
    7.23 -XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length);
    7.24 -static NTSTATUS
    7.25 -XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
    7.26 -static NTSTATUS
    7.27 -XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
    7.28 -static NTSTATUS
    7.29 -XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
    7.30 -static NTSTATUS
    7.31 -XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
    7.32 -static NTSTATUS
    7.33 -XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
    7.34 -static NTSTATUS
    7.35 -XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList);
    7.36 -static NTSTATUS
    7.37 -XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated);
    7.38 -#endif
    7.39 -
    7.40  static VOID
    7.41  XenBus_SysrqHandler(char *Path, PVOID Data);
    7.42  static VOID
    7.43  XenBus_ShutdownHandler(char *Path, PVOID Data);
    7.44  static VOID
    7.45  XenBus_BalloonHandler(char *Path, PVOID Data);
    7.46 +
    7.47  /*
    7.48  static VOID
    7.49  XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
    7.50 @@ -126,16 +94,6 @@ XenPci_Dummy_Fdo(PDEVICE_OBJECT device_o
    7.51  }
    7.52  
    7.53  /*
    7.54 - * Many XEN_IFACE functions allocate memory. Clients must use this to free it.
    7.55 - * (Xenbus_Read, XenBus_List, XenBus_AddWatch, XenBus_RemWatch)
    7.56 - */
    7.57 -static void
    7.58 -XenPCI_FreeMem(PVOID Ptr)
    7.59 -{
    7.60 -  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
    7.61 -}
    7.62 -
    7.63 -/*
    7.64   * Alloc MMIO from the device's MMIO region. There is no corresponding free() fn
    7.65   */
    7.66  PHYSICAL_ADDRESS
    7.67 @@ -175,7 +133,7 @@ XenPci_Init(PXENPCI_DEVICE_DATA xpdd)
    7.68    ret = HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp);
    7.69    KdPrint((__DRIVER_NAME " hypervisor memory op ret = %d\n", ret));
    7.70    xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
    7.71 -    PAGE_SIZE, MmCached);
    7.72 +    PAGE_SIZE, MmNonCached);
    7.73    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    7.74  
    7.75    return STATUS_SUCCESS;
    7.76 @@ -299,7 +257,7 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
    7.77      switch (res_descriptor->Type)
    7.78      {
    7.79      case CmResourceTypeInterrupt:
    7.80 -      KdPrint((__DRIVER_NAME "     irq_number = %d\n", res_descriptor->u.Interrupt.Vector));
    7.81 +      KdPrint((__DRIVER_NAME "     irq_number = %03x\n", res_descriptor->u.Interrupt.Vector));
    7.82        xpdd->irq_number = res_descriptor->u.Interrupt.Vector;
    7.83        memcpy(&InterruptRaw, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
    7.84        break;
    7.85 @@ -316,12 +274,15 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
    7.86        break;
    7.87      case CmResourceTypeMemory:
    7.88        KdPrint((__DRIVER_NAME "     Memory mapped CSR:(%x:%x) Length:(%d)\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Start.HighPart, res_descriptor->u.Memory.Length));
    7.89 +      KdPrint((__DRIVER_NAME "     Memory flags = %04X\n", res_descriptor->Flags));
    7.90        xpdd->platform_mmio_addr = res_descriptor->u.Memory.Start;
    7.91        xpdd->platform_mmio_len = res_descriptor->u.Memory.Length;
    7.92        xpdd->platform_mmio_alloc = 0;
    7.93 +      xpdd->platform_mmio_flags = res_descriptor->Flags;
    7.94        break;
    7.95      case CmResourceTypeInterrupt:
    7.96 -      KdPrint((__DRIVER_NAME "     irq_vector = %d\n", res_descriptor->u.Interrupt.Vector));
    7.97 +      KdPrint((__DRIVER_NAME "     irq_vector = %03x\n", res_descriptor->u.Interrupt.Vector));
    7.98 +      KdPrint((__DRIVER_NAME "     irq_level = %03x\n", res_descriptor->u.Interrupt.Level));
    7.99  	    xpdd->irq_level = (KIRQL)res_descriptor->u.Interrupt.Level;
   7.100    	  xpdd->irq_vector = res_descriptor->u.Interrupt.Vector;
   7.101  	    xpdd->irq_affinity = res_descriptor->u.Interrupt.Affinity;
   7.102 @@ -371,6 +332,7 @@ XenPci_Pnp_QueryRemoveDevice(PDEVICE_OBJ
   7.103  
   7.104    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   7.105  
   7.106 +#if 0
   7.107    if (FALSE)
   7.108    {
   7.109      /* We are in the paging or hibernation path - can't remove */
   7.110 @@ -379,9 +341,12 @@ XenPci_Pnp_QueryRemoveDevice(PDEVICE_OBJ
   7.111    }
   7.112    else
   7.113    {
   7.114 +#endif
   7.115      IoSkipCurrentIrpStackLocation(irp);
   7.116      status = IoCallDriver(xpdd->common.lower_do, irp);
   7.117 +#if 0
   7.118    }
   7.119 +#endif
   7.120  
   7.121    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   7.122  
   7.123 @@ -501,20 +466,20 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
   7.124    NTSTATUS status = STATUS_SUCCESS;
   7.125    PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   7.126    PIRP irp = context;
   7.127 -  int devices = 0;
   7.128 +  int device_count = 0;
   7.129    PDEVICE_RELATIONS dev_relations;
   7.130    PXEN_CHILD child;
   7.131    //char *response;
   7.132 -  char *msgTypes;
   7.133 -  char **Types;
   7.134 -  int i;
   7.135 -  //CHAR buffer[128];
   7.136 +  char *msg;
   7.137 +  char **devices;
   7.138 +  char **instances;
   7.139 +  int i, j;
   7.140 +  CHAR path[128];
   7.141    PDEVICE_OBJECT pdo;
   7.142 -  
   7.143    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   7.144  
   7.145 -  msgTypes = XenBus_List(xpdd, XBT_NIL, "device", &Types);
   7.146 -  if (!msgTypes)
   7.147 +  msg = XenBus_List(xpdd, XBT_NIL, "device", &devices);
   7.148 +  if (!msg)
   7.149    {
   7.150      for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   7.151      {
   7.152 @@ -523,70 +488,84 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
   7.153        child->state = CHILD_STATE_DELETED;
   7.154      }
   7.155  
   7.156 -    for (i = 0; Types[i]; i++)
   7.157 +    for (i = 0; devices[i]; i++)
   7.158      {
   7.159 -      //RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
   7.160 -
   7.161 -      for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   7.162 -      {
   7.163 -        if (strcmp(child->context->path, Types[i]) == 0)
   7.164 -        {
   7.165 -          KdPrint((__DRIVER_NAME "     Existing device %s\n", Types[i]));
   7.166 -          ASSERT(child->state != CHILD_STATE_DELETED);
   7.167 -          child->state = CHILD_STATE_ADDED;
   7.168 -          devices++;
   7.169 -          break;
   7.170 -        }
   7.171 -      }
   7.172 -      if (child == (PXEN_CHILD)&xpdd->child_list)
   7.173 +      RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/%s", devices[i]);
   7.174 +      msg = XenBus_List(xpdd, XBT_NIL, path, &instances);
   7.175 +      if (!msg)
   7.176        {
   7.177 -        KdPrint((__DRIVER_NAME "     New device %s\n", Types[i]));
   7.178 -        child = ExAllocatePoolWithTag(NonPagedPool, sizeof(XEN_CHILD), XENPCI_POOL_TAG);
   7.179 -        child->state = CHILD_STATE_ADDED;
   7.180 -        status = IoCreateDeviceSecure(
   7.181 -          xpdd->common.fdo->DriverObject,
   7.182 -          sizeof(XENPCI_PDO_DEVICE_DATA),
   7.183 -          NULL,
   7.184 -          FILE_DEVICE_UNKNOWN,
   7.185 -          FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
   7.186 -          FALSE,
   7.187 -          &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
   7.188 -          (LPCGUID)&GUID_XENPCI_DEVCLASS,
   7.189 -          &pdo);
   7.190 -        if (!NT_SUCCESS(status))
   7.191 -          KdPrint((__DRIVER_NAME "     IoCreateDevice status = %08X\n", status));
   7.192 -        child->context = (PXENPCI_PDO_DEVICE_DATA)pdo->DeviceExtension;
   7.193 -        child->context->common.fdo = NULL;
   7.194 -        child->context->common.pdo = pdo;
   7.195 -        child->context->common.lower_do = NULL;
   7.196 -        child->context->bus_fdo = device_object;
   7.197 -        strcpy(child->context->path, Types[i]);
   7.198 -        child->context->index = 0;
   7.199 -        child->context->mmio_phys = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
   7.200 -        InsertTailList(&xpdd->child_list, (PLIST_ENTRY)child);
   7.201 -        devices++;
   7.202 +        for (j = 0; instances[j]; j++)
   7.203 +        {
   7.204 +          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/%s/%s", devices[i], instances[j]);
   7.205 +        
   7.206 +          for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   7.207 +          {
   7.208 +            if (strcmp(child->context->path, path) == 0)
   7.209 +            {
   7.210 +              KdPrint((__DRIVER_NAME "     Existing device %s\n", path));
   7.211 +              ASSERT(child->state != CHILD_STATE_DELETED);
   7.212 +              child->state = CHILD_STATE_ADDED;
   7.213 +              device_count++;
   7.214 +              break;
   7.215 +            }
   7.216 +          }
   7.217 +        
   7.218 +          if (child == (PXEN_CHILD)&xpdd->child_list)
   7.219 +          {
   7.220 +            KdPrint((__DRIVER_NAME "     New device %s\n", path));
   7.221 +            child = ExAllocatePoolWithTag(NonPagedPool, sizeof(XEN_CHILD), XENPCI_POOL_TAG);
   7.222 +            child->state = CHILD_STATE_ADDED;
   7.223 +            status = IoCreateDeviceSecure(
   7.224 +              xpdd->common.fdo->DriverObject,
   7.225 +              sizeof(XENPCI_PDO_DEVICE_DATA),
   7.226 +              NULL,
   7.227 +              FILE_DEVICE_UNKNOWN,
   7.228 +              FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
   7.229 +              FALSE,
   7.230 +              &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
   7.231 +              (LPCGUID)&GUID_XENPCI_DEVCLASS,
   7.232 +              &pdo);
   7.233 +            if (!NT_SUCCESS(status))
   7.234 +              KdPrint((__DRIVER_NAME "     IoCreateDevice status = %08X\n", status));
   7.235 +            child->context = (PXENPCI_PDO_DEVICE_DATA)pdo->DeviceExtension;
   7.236 +            child->context->common.fdo = NULL;
   7.237 +            child->context->common.pdo = pdo;
   7.238 +            child->context->common.lower_do = NULL;
   7.239 +            child->context->bus_fdo = device_object;
   7.240 +            RtlStringCbCopyA(child->context->path, ARRAY_SIZE(child->context->path), path);
   7.241 +            RtlStringCbCopyA(child->context->device, ARRAY_SIZE(child->context->device), devices[i]);
   7.242 +            child->context->index = atoi(instances[j]);
   7.243 +            KeInitializeEvent(&child->context->backend_state_event, SynchronizationEvent, FALSE);
   7.244 +            child->context->backend_state = XenbusStateUnknown;
   7.245 +            child->context->backend_path[0] = '\0';
   7.246 +            InsertTailList(&xpdd->child_list, (PLIST_ENTRY)child);
   7.247 +            device_count++;
   7.248 +          }
   7.249 +          ExFreePoolWithTag(instances[j], XENPCI_POOL_TAG);
   7.250 +        }
   7.251 +        XenPci_FreeMem(instances);
   7.252        }
   7.253 -      ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
   7.254 +      ExFreePoolWithTag(devices[i], XENPCI_POOL_TAG);
   7.255      }
   7.256 -    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (devices - 1), XENPCI_POOL_TAG);
   7.257 -    for (child = (PXEN_CHILD)xpdd->child_list.Flink, devices = 0; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   7.258 +    XenPci_FreeMem(devices);
   7.259 +    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (device_count - 1), XENPCI_POOL_TAG);
   7.260 +    for (child = (PXEN_CHILD)xpdd->child_list.Flink, device_count = 0; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
   7.261      {
   7.262        if (child->state == CHILD_STATE_ADDED)
   7.263 -        dev_relations->Objects[devices++] = child->context->common.pdo;
   7.264 +        dev_relations->Objects[device_count++] = child->context->common.pdo;
   7.265      }
   7.266 -    dev_relations->Count = devices;
   7.267 +    dev_relations->Count = device_count;
   7.268  
   7.269      status = STATUS_SUCCESS;
   7.270    }
   7.271    else
   7.272    {
   7.273 -    devices = 0;
   7.274 -    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (devices - 1), XENPCI_POOL_TAG);
   7.275 -    dev_relations->Count = devices;
   7.276 +    /* this should probably fail in an even worse way - a failure here means we failed to do an ls in xenbus so something is really really wrong */
   7.277 +    device_count = 0;
   7.278 +    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (device_count - 1), XENPCI_POOL_TAG);
   7.279 +    dev_relations->Count = device_count;
   7.280    }
   7.281  
   7.282 -  XenPCI_FreeMem(Types);
   7.283 -
   7.284    irp->IoStatus.Status = status;
   7.285    irp->IoStatus.Information = (ULONG_PTR)dev_relations;
   7.286  
   7.287 @@ -624,7 +603,9 @@ XenPci_Pnp_FilterResourceRequirementsCal
   7.288    PIO_RESOURCE_REQUIREMENTS_LIST irrl;
   7.289    ULONG irl;
   7.290    ULONG ird;
   7.291 -    
   7.292 +
   7.293 +  UNREFERENCED_PARAMETER(device_object);
   7.294 +  
   7.295    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (status = %08X)\n", irp->IoStatus.Status));
   7.296    
   7.297    irrl = (PIO_RESOURCE_REQUIREMENTS_LIST)irp->IoStatus.Information;
   7.298 @@ -825,7 +806,7 @@ XenPCI_D0EntryPostInterruptsEnabled(WDFD
   7.299    }
   7.300    WdfChildListEndScan(ChildList);
   7.301  
   7.302 -  XenPCI_FreeMem(Types);
   7.303 +  XenPci_FreeMem(Types);
   7.304  
   7.305    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   7.306  
   7.307 @@ -1042,7 +1023,7 @@ XenPCI_ChildListCreateDevice(
   7.308    ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   7.309  
   7.310    ChildDeviceData->XenInterface.AllocMMIO = XenPci_AllocMMIO;
   7.311 -  ChildDeviceData->XenInterface.FreeMem = XenPCI_FreeMem;
   7.312 +  ChildDeviceData->XenInterface.FreeMem = XenPci_FreeMem;
   7.313  
   7.314    ChildDeviceData->XenInterface.EvtChn_Bind = EvtChn_Bind;
   7.315    ChildDeviceData->XenInterface.EvtChn_Unbind = EvtChn_Unbind;
   7.316 @@ -1202,7 +1183,7 @@ XenBus_ShutdownHandler(char *Path, PVOID
   7.317    if (res)
   7.318    {
   7.319      KdPrint(("Error starting transaction\n"));
   7.320 -    XenPCI_FreeMem(res);
   7.321 +    XenPci_FreeMem(res);
   7.322      return;
   7.323    }
   7.324  
   7.325 @@ -1210,7 +1191,7 @@ XenBus_ShutdownHandler(char *Path, PVOID
   7.326    if (res)
   7.327    {
   7.328      KdPrint(("Error reading shutdown path\n"));
   7.329 -    XenPCI_FreeMem(res);
   7.330 +    XenPci_FreeMem(res);
   7.331      XenBus_EndTransaction(Device, xbt, 1, &retry);
   7.332      return;
   7.333    }
   7.334 @@ -1221,7 +1202,7 @@ XenBus_ShutdownHandler(char *Path, PVOID
   7.335      if (res)
   7.336      {
   7.337        KdPrint(("Error writing shutdown path\n"));
   7.338 -      XenPCI_FreeMem(res);
   7.339 +      XenPci_FreeMem(res);
   7.340        // end trans?
   7.341        return;
   7.342      }
   7.343 @@ -1241,7 +1222,7 @@ XenBus_ShutdownHandler(char *Path, PVOID
   7.344    if (res)
   7.345    {
   7.346      KdPrint(("Error ending transaction\n"));
   7.347 -    XenPCI_FreeMem(res);
   7.348 +    XenPci_FreeMem(res);
   7.349      return;
   7.350    }
   7.351  
   7.352 @@ -1262,7 +1243,7 @@ XenBus_ShutdownHandler(char *Path, PVOID
   7.353      }
   7.354    }
   7.355  
   7.356 -  XenPCI_FreeMem(Value);
   7.357 +  XenPci_FreeMem(Value);
   7.358  
   7.359    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   7.360  }
   7.361 @@ -1290,7 +1271,7 @@ XenBus_BalloonHandler(char *Path, PVOID 
   7.362  
   7.363    XenBus_EndTransaction(Device, xbt, 0, &retry);
   7.364  
   7.365 -  XenPCI_FreeMem(value);
   7.366 +  XenPci_FreeMem(value);
   7.367  
   7.368    KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
   7.369  }
   7.370 @@ -1322,7 +1303,7 @@ XenBus_SysrqHandler(char *Path, PVOID Da
   7.371      if (res)
   7.372      {
   7.373        KdPrint(("Error writing sysrq path\n"));
   7.374 -      XenPCI_FreeMem(res);
   7.375 +      XenPci_FreeMem(res);
   7.376        XenBus_EndTransaction(Device, xbt, 0, &retry);
   7.377        return;
   7.378      }
   7.379 @@ -1336,7 +1317,7 @@ XenBus_SysrqHandler(char *Path, PVOID Da
   7.380  
   7.381    if (Value != NULL)
   7.382    {
   7.383 -    XenPCI_FreeMem(Value);
   7.384 +    XenPci_FreeMem(Value);
   7.385    }
   7.386  
   7.387    switch (letter)
     8.1 --- a/xenpci/xenpci_pdo.c	Wed May 07 10:47:03 2008 +1000
     8.2 +++ b/xenpci/xenpci_pdo.c	Mon May 12 00:20:02 2008 +1000
     8.3 @@ -19,8 +19,10 @@ Foundation, Inc., 51 Franklin Street, Fi
     8.4  
     8.5  #include "xenpci.h"
     8.6  #include <stdlib.h>
     8.7 +#include <io/ring.h>
     8.8  
     8.9  #pragma warning(disable : 4200) // zero-sized array
    8.10 +#pragma warning(disable: 4127) // conditional expression is constant
    8.11  
    8.12  NTSTATUS
    8.13  XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
    8.14 @@ -37,13 +39,107 @@ XenPci_Power_Pdo(PDEVICE_OBJECT device_o
    8.15    return irp->IoStatus.Status;
    8.16  }
    8.17  
    8.18 +static VOID
    8.19 +XenPci_BackEndStateHandler(char *Path, PVOID Context)
    8.20 +{
    8.21 +  PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)Context;
    8.22 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    8.23 +  char *value;
    8.24 +  char *err;
    8.25 +  ULONG new_backend_state;
    8.26 +  char path[128];
    8.27 +
    8.28 +//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    8.29 +
    8.30 +  /* check that path == device/id/state */
    8.31 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
    8.32 +  err = XenBus_Read(xpdd, XBT_NIL, Path, &value);
    8.33 +  if (err)
    8.34 +  {
    8.35 +    KdPrint(("Failed to read %s\n", path, err));
    8.36 +    return;
    8.37 +  }
    8.38 +  new_backend_state = atoi(value);
    8.39 +  XenPci_FreeMem(value);
    8.40 +
    8.41 +  if (xppdd->backend_state == new_backend_state)
    8.42 +  {
    8.43 +    KdPrint((__DRIVER_NAME "     state unchanged\n"));
    8.44 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    8.45 +    return;
    8.46 +  }    
    8.47 +
    8.48 +  xppdd->backend_state = new_backend_state;
    8.49 +
    8.50 +  switch (xppdd->backend_state)
    8.51 +  {
    8.52 +  case XenbusStateUnknown:
    8.53 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown\n"));  
    8.54 +    break;
    8.55 +
    8.56 +  case XenbusStateInitialising:
    8.57 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising\n"));  
    8.58 +    break;
    8.59 +
    8.60 +  case XenbusStateInitWait:
    8.61 +    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait\n"));  
    8.62 +    break;
    8.63 +
    8.64 +  case XenbusStateInitialised:
    8.65 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised\n"));
    8.66 +    break;
    8.67 +
    8.68 +  case XenbusStateConnected:
    8.69 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected\n"));  
    8.70 +    break;
    8.71 +
    8.72 +  case XenbusStateClosing:
    8.73 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing\n"));  
    8.74 +    /* check our current PNP statue - this may be a surprise removal... */
    8.75 +    break;
    8.76 +
    8.77 +  case XenbusStateClosed:
    8.78 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed\n"));  
    8.79 +    break;
    8.80 +
    8.81 +  default:
    8.82 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d\n", xppdd->backend_state));
    8.83 +    break;
    8.84 +  }
    8.85 +
    8.86 +  KeSetEvent(&xppdd->backend_state_event, 1, FALSE);
    8.87 +
    8.88 +//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    8.89 +
    8.90 +  return;
    8.91 +}
    8.92 +
    8.93 +struct dummy_sring {
    8.94 +    RING_IDX req_prod, req_event;
    8.95 +    RING_IDX rsp_prod, rsp_event;
    8.96 +    uint8_t  pad[48];
    8.97 +};
    8.98 +
    8.99  static NTSTATUS
   8.100  XenPci_Pnp_StartDevice(PDEVICE_OBJECT device_object, PIRP irp)
   8.101  {
   8.102 +  PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
   8.103 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
   8.104    PIO_STACK_LOCATION stack;
   8.105    PCM_PARTIAL_RESOURCE_LIST res_list;
   8.106    PCM_PARTIAL_RESOURCE_DESCRIPTOR res_descriptor;
   8.107    ULONG i;
   8.108 +  char path[128];
   8.109 +  PCHAR setting, value;
   8.110 +  PCHAR res;
   8.111 +  PMDL mdl;
   8.112 +  PVOID address;
   8.113 +  grant_ref_t gref;
   8.114 +  evtchn_port_t event_channel;
   8.115 +  UCHAR type;
   8.116 +  PUCHAR in_ptr = NULL, in_start = NULL;
   8.117 +  PUCHAR out_ptr, out_start = NULL;
   8.118 +  XENPCI_VECTORS vectors;
   8.119  
   8.120    UNREFERENCED_PARAMETER(device_object);
   8.121  
   8.122 @@ -51,6 +147,30 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   8.123  
   8.124    stack = IoGetCurrentIrpStackLocation(irp);
   8.125  
   8.126 +  /* Get backend path */
   8.127 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path),
   8.128 +    "%s/backend", xppdd->path);
   8.129 +  res = XenBus_Read(xpdd, XBT_NIL, path, &value);
   8.130 +  if (res)
   8.131 +  {
   8.132 +    KdPrint((__DRIVER_NAME "    Failed to read backend path\n"));
   8.133 +    XenPci_FreeMem(res);
   8.134 +  }
   8.135 +  RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
   8.136 +  XenPci_FreeMem(value);
   8.137 +
   8.138 +  /* Add watch on backend state */
   8.139 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
   8.140 +  XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
   8.141 +
   8.142 +  /* Tell backend we're coming up */
   8.143 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
   8.144 +  XenBus_Printf(xpdd, XBT_NIL, path, "%d", XenbusStateInitialising);
   8.145 +
   8.146 +  // wait here for signal that we are all set up - we should probably add a timeout to make sure we don't hang forever
   8.147 +  while (xppdd->backend_state != XenbusStateInitWait)
   8.148 +    KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, NULL);
   8.149 +
   8.150    res_list = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
   8.151    for (i = 0; i < res_list->Count; i++)
   8.152    {
   8.153 @@ -59,6 +179,7 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   8.154      {
   8.155      case CmResourceTypeInterrupt:
   8.156        KdPrint((__DRIVER_NAME "     irq_number = %d\n", res_descriptor->u.Interrupt.Vector));
   8.157 +      KdPrint((__DRIVER_NAME "     irq_level = %03x\n", res_descriptor->u.Interrupt.Level));
   8.158        break;
   8.159      }
   8.160    }
   8.161 @@ -69,8 +190,122 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   8.162      res_descriptor = &res_list->PartialDescriptors[i];
   8.163      switch (res_descriptor->Type) {
   8.164      case CmResourceTypeInterrupt:
   8.165 -      KdPrint((__DRIVER_NAME "     irq_vector = %d\n", res_descriptor->u.Interrupt.Vector));
   8.166 +      KdPrint((__DRIVER_NAME "     CmResourceTypeInterrupt\n"));
   8.167 +      KdPrint((__DRIVER_NAME "     irq_vector = %03x\n", res_descriptor->u.Interrupt.Vector));
   8.168 +      KdPrint((__DRIVER_NAME "     irq_level = %d\n", res_descriptor->u.Interrupt.Level));
   8.169 +      xppdd->irq_vector = res_descriptor->u.Interrupt.Vector;
   8.170 +      xppdd->irq_level = (KIRQL)res_descriptor->u.Interrupt.Level;
   8.171        break;
   8.172 +    case CmResourceTypeMemory:
   8.173 +      KdPrint((__DRIVER_NAME "     CmResourceTypeMemory\n"));
   8.174 +      KdPrint((__DRIVER_NAME "     Start = %08x, Length = %d\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Length));
   8.175 +      out_ptr = out_start = MmMapIoSpace(res_descriptor->u.Memory.Start, res_descriptor->u.Memory.Length, MmNonCached);
   8.176 +      in_ptr = in_start = ExAllocatePoolWithTag(PagedPool, res_descriptor->u.Memory.Length, XENPCI_POOL_TAG);
   8.177 +      memcpy(in_ptr, out_ptr, res_descriptor->u.Memory.Length);
   8.178 +      
   8.179 +      while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
   8.180 +      {
   8.181 +        switch (type)
   8.182 +        {
   8.183 +        case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
   8.184 +          KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
   8.185 +          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
   8.186 +          XenBus_Printf(xpdd, XBT_NIL, path, "%s", value);
   8.187 +          break;
   8.188 +        case XEN_INIT_TYPE_RING: /* frontend ring */
   8.189 +          /* we only allocate and do the SHARED_RING_INIT here */
   8.190 +          mdl = AllocatePage();
   8.191 +          address = MmGetMdlVirtualAddress(mdl);
   8.192 +          KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, address));
   8.193 +          SHARED_RING_INIT((struct dummy_sring *)address);
   8.194 +          gref = GntTbl_GrantAccess(xpdd, 0, *MmGetMdlPfnArray(mdl), FALSE, 0);
   8.195 +          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
   8.196 +          XenBus_Printf(xpdd, XBT_NIL, path, "%d", gref);
   8.197 +          ADD_XEN_INIT_RSP(&out_ptr, type, setting, address);
   8.198 +          break;
   8.199 +        case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
   8.200 +        case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
   8.201 +          event_channel = EvtChn_AllocUnbound(xpdd, 0);
   8.202 +          KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, event_channel));
   8.203 +          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
   8.204 +          XenBus_Printf(xpdd, XBT_NIL, path, "%d", event_channel);
   8.205 +          ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel));
   8.206 +          if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
   8.207 +            EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector);
   8.208 +          break;
   8.209 +        }
   8.210 +      }
   8.211 +    }
   8.212 +  }
   8.213 +
   8.214 +  /* We are all ready to go */
   8.215 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
   8.216 +  XenBus_Printf(xpdd, XBT_NIL, path, "%d", XenbusStateConnected);
   8.217 +
   8.218 +  // wait here for signal that we are all set up - we should probably add a timeout to make sure we don't hang forever
   8.219 +  while (xppdd->backend_state != XenbusStateConnected)
   8.220 +    KeWaitForSingleObject(&xppdd->backend_state_event, Executive, KernelMode, FALSE, NULL);
   8.221 +
   8.222 +  res_list = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
   8.223 +  for (i = 0; i < res_list->Count; i++)
   8.224 +  {
   8.225 +    res_descriptor = &res_list->PartialDescriptors[i];
   8.226 +    switch (res_descriptor->Type) {
   8.227 +    case CmResourceTypeMemory:
   8.228 +      in_ptr = in_start;
   8.229 +      while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
   8.230 +      {
   8.231 +        switch(type)
   8.232 +        {
   8.233 +        case XEN_INIT_TYPE_READ_STRING_BACK:
   8.234 +        case XEN_INIT_TYPE_READ_STRING_FRONT:
   8.235 +          if (type == XEN_INIT_TYPE_READ_STRING_FRONT)
   8.236 +            RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
   8.237 +          else
   8.238 +            RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->backend_path, setting);
   8.239 +          res = XenBus_Read(xpdd, XBT_NIL, path, &value);
   8.240 +          if (res)
   8.241 +          {
   8.242 +            KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = <failed>\n", setting));
   8.243 +            XenPci_FreeMem(res);
   8.244 +            ADD_XEN_INIT_RSP(&out_ptr, type, setting, NULL);
   8.245 +          }
   8.246 +          else
   8.247 +          {
   8.248 +            KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   8.249 +            ADD_XEN_INIT_RSP(&out_ptr, type, setting, value);
   8.250 +            XenPci_FreeMem(value);
   8.251 +          }
   8.252 +          break;
   8.253 +        case XEN_INIT_TYPE_VECTORS:
   8.254 +          KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   8.255 +          vectors.magic = XEN_DATA_MAGIC;
   8.256 +          vectors.length = sizeof(XENPCI_VECTORS);
   8.257 +          vectors.context = xpdd;
   8.258 +          vectors.EvtChn_Bind = EvtChn_Bind;
   8.259 +          vectors.EvtChn_BindDpc = EvtChn_BindDpc;
   8.260 +          vectors.EvtChn_Unbind = EvtChn_Unbind;
   8.261 +          vectors.EvtChn_Mask = EvtChn_Mask;
   8.262 +          vectors.EvtChn_Unmask = EvtChn_Unmask;
   8.263 +          vectors.EvtChn_Notify = EvtChn_Notify;
   8.264 +          vectors.GntTbl_GetRef = GntTbl_GetRef;
   8.265 +          vectors.GntTbl_PutRef = GntTbl_PutRef;
   8.266 +          vectors.GntTbl_GrantAccess = GntTbl_GrantAccess;
   8.267 +          vectors.GntTbl_EndAccess = GntTbl_EndAccess;
   8.268 +          ADD_XEN_INIT_RSP(&out_ptr, type, NULL, &vectors);
   8.269 +          break;
   8.270 +        case XEN_INIT_TYPE_GRANT_ENTRIES:
   8.271 +          KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(setting)));
   8.272 +          __ADD_XEN_INIT_UCHAR(&out_ptr, type);
   8.273 +          __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(setting));
   8.274 +          for (i = 0; i < PtrToUlong(setting); i++)
   8.275 +            __ADD_XEN_INIT_ULONG(&out_ptr, GntTbl_GetRef(xpdd));
   8.276 +          break;
   8.277 +        }
   8.278 +      }
   8.279 +      ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
   8.280 +      MmUnmapIoSpace(out_start, res_descriptor->u.Memory.Length);
   8.281 +      ExFreePoolWithTag(in_start, XENPCI_POOL_TAG);
   8.282      }
   8.283    }
   8.284    
   8.285 @@ -82,11 +317,14 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   8.286  static NTSTATUS
   8.287  XenPci_QueryResourceRequirements(PDEVICE_OBJECT device_object, PIRP irp)
   8.288  {
   8.289 -  PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
   8.290 +  //PXENPCI_PDO_DEVICE_DATA xppdd = (PXENPCI_PDO_DEVICE_DATA)device_object->DeviceExtension;
   8.291 +  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
   8.292    PIO_RESOURCE_REQUIREMENTS_LIST irrl;
   8.293    PIO_RESOURCE_DESCRIPTOR ird;
   8.294    ULONG length;
   8.295    
   8.296 +  UNREFERENCED_PARAMETER(device_object);
   8.297 +  
   8.298    length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
   8.299      FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
   8.300      sizeof(IO_RESOURCE_DESCRIPTOR) * 3;
   8.301 @@ -101,42 +339,24 @@ XenPci_QueryResourceRequirements(PDEVICE
   8.302    irrl->AlternativeLists = 1;
   8.303    irrl->List[0].Version = 1;
   8.304    irrl->List[0].Revision = 1;
   8.305 -  irrl->List[0].Count = 3;
   8.306 +  irrl->List[0].Count = 0;
   8.307  
   8.308 -  ird = &irrl->List[0].Descriptors[0];
   8.309 +  ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
   8.310    ird->Option = 0;
   8.311    ird->Type = CmResourceTypeInterrupt;
   8.312 -  ird->ShareDisposition = CmResourceShareDeviceExclusive;
   8.313 +  ird->ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
   8.314    ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
   8.315    ird->u.Interrupt.MinimumVector = 1;
   8.316    ird->u.Interrupt.MaximumVector = 6;
   8.317  
   8.318 -  ird = &irrl->List[0].Descriptors[1];
   8.319 +  ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
   8.320    ird->Option = IO_RESOURCE_ALTERNATIVE;
   8.321    ird->Type = CmResourceTypeInterrupt;
   8.322 -  ird->ShareDisposition = CmResourceShareDeviceExclusive;
   8.323 +  ird->ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
   8.324    ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
   8.325 -  ird->u.Interrupt.MinimumVector = 8;
   8.326 +  ird->u.Interrupt.MinimumVector = 10;
   8.327    ird->u.Interrupt.MaximumVector = 14;
   8.328  
   8.329 -  //irq 7 = 0x93
   8.330 -  //irq 11 = 0x81
   8.331 -  //irq ? = 0x52 mouse
   8.332 -  //irq ? = 0xb3 keybouard
   8.333 -  //irq ? = 0x72 atapi
   8.334 -  //irq ? = 0x92 atappi
   8.335 -  //irq 28 = 0x83 xen - 0x183
   8.336 -  
   8.337 -  ird = &irrl->List[0].Descriptors[2];
   8.338 -  ird->Option = 0;
   8.339 -  ird->Type = CmResourceTypeMemory;
   8.340 -  ird->ShareDisposition = CmResourceShareShared;
   8.341 -  ird->Flags = CM_RESOURCE_MEMORY_READ_WRITE; //|CM_RESOURCE_MEMORY_PREFETCHABLE|CM_RESOURCE_MEMORY_CACHEABLE;
   8.342 -  ird->u.Memory.Length = PAGE_SIZE;
   8.343 -  ird->u.Memory.Alignment = PAGE_SIZE;
   8.344 -  ird->u.Memory.MinimumAddress.QuadPart = xppdd->mmio_phys.QuadPart;
   8.345 -  ird->u.Memory.MaximumAddress.QuadPart = xppdd->mmio_phys.QuadPart + PAGE_SIZE - 1;
   8.346 -  
   8.347    irp->IoStatus.Information = (ULONG_PTR)irrl;
   8.348    return STATUS_SUCCESS;
   8.349  }
   8.350 @@ -200,8 +420,6 @@ XenPci_Pnp_Pdo(PDEVICE_OBJECT device_obj
   8.351    WCHAR widebuf[256];
   8.352    unsigned int i;
   8.353    PPNP_BUS_INFORMATION pbi;
   8.354 -  PCM_RESOURCE_LIST crl;
   8.355 -KIRQL old_irql;
   8.356  
   8.357    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   8.358  
   8.359 @@ -261,8 +479,8 @@ KIRQL old_irql;
   8.360      case BusQueryDeviceID: /* REG_SZ */
   8.361        KdPrint((__DRIVER_NAME "     BusQueryDeviceID\n"));
   8.362        buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
   8.363 -      for (i = 0; i < strlen(xppdd->path); i++)
   8.364 -        widebuf[i] = xppdd->path[i];
   8.365 +      for (i = 0; i < strlen(xppdd->device); i++)
   8.366 +        widebuf[i] = xppdd->device[i];
   8.367        widebuf[i] = 0;
   8.368        RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
   8.369        KdPrint((__DRIVER_NAME "     %ls\n", buffer));
   8.370 @@ -272,8 +490,8 @@ KIRQL old_irql;
   8.371      case BusQueryHardwareIDs: /* REG_MULTI_SZ */
   8.372        KdPrint((__DRIVER_NAME "     BusQueryHardwareIDs\n"));
   8.373        buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
   8.374 -      for (i = 0; i < strlen(xppdd->path); i++)
   8.375 -        widebuf[i] = xppdd->path[i];
   8.376 +      for (i = 0; i < strlen(xppdd->device); i++)
   8.377 +        widebuf[i] = xppdd->device[i];
   8.378        widebuf[i] = 0;
   8.379        RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
   8.380        for (i = 0; buffer[i] != 0; i++);
   8.381 @@ -287,8 +505,8 @@ KIRQL old_irql;
   8.382      case BusQueryCompatibleIDs: /* REG_MULTI_SZ */
   8.383        KdPrint((__DRIVER_NAME "     BusQueryCompatibleIDs\n"));
   8.384        buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
   8.385 -      for (i = 0; i < strlen(xppdd->path); i++)
   8.386 -        widebuf[i] = xppdd->path[i];
   8.387 +      for (i = 0; i < strlen(xppdd->device); i++)
   8.388 +        widebuf[i] = xppdd->device[i];
   8.389        widebuf[i] = 0;
   8.390        RtlStringCbPrintfW(buffer, 512, L"Xen\\%ws", widebuf);
   8.391        for (i = 0; buffer[i] != 0; i++);
   8.392 @@ -320,8 +538,8 @@ KIRQL old_irql;
   8.393      case DeviceTextDescription:
   8.394        KdPrint((__DRIVER_NAME "     DeviceTextDescription\n"));
   8.395        buffer = ExAllocatePoolWithTag(PagedPool, 512, XENPCI_POOL_TAG);
   8.396 -      for (i = 0; i < strlen(xppdd->path); i++)
   8.397 -        widebuf[i] = xppdd->path[i];
   8.398 +      for (i = 0; i < strlen(xppdd->device); i++)
   8.399 +        widebuf[i] = xppdd->device[i];
   8.400        widebuf[i] = 0;
   8.401        RtlStringCbPrintfW(buffer, 512, L"Xen %ws device #%d", widebuf, xppdd->index);
   8.402        KdPrint((__DRIVER_NAME "     %ls\n", buffer));
   8.403 @@ -395,22 +613,13 @@ KIRQL old_irql;
   8.404        status = XenPci_Pnp_QueryTargetRelations(device_object, irp);
   8.405        break;  
   8.406      default:
   8.407 -KeRaiseIrql(7, &old_irql);
   8.408 -KdPrint((__DRIVER_NAME "     int 0x81 (xenvbd) (from xenpci)"));
   8.409 +/*
   8.410 +KdPrint((__DRIVER_NAME "     int 0xb1 (xenvbd) (from xenpci)"));
   8.411  __asm {
   8.412    int 0x81
   8.413 +  int 0xb1
   8.414  };
   8.415 -KeLowerIrql(old_irql);
   8.416 -
   8.417 -KeRaiseIrql(7, &old_irql);
   8.418 -KdPrint((__DRIVER_NAME "     int 0x81 (xenvbd) (from xenpci)"));
   8.419 -__asm {
   8.420 -  cli
   8.421 -  int 0x81
   8.422 -  sti
   8.423 -};
   8.424 -KeLowerIrql(old_irql);
   8.425 -    
   8.426 +*/
   8.427        status = irp->IoStatus.Status;
   8.428        break;
   8.429      }
     9.1 --- a/xenvbd/sources	Wed May 07 10:47:03 2008 +1000
     9.2 +++ b/xenvbd/sources	Mon May 12 00:20:02 2008 +1000
     9.3 @@ -6,4 +6,4 @@ TARGETTYPE=DRIVER
     9.4  INF_NAME=$(TARGETNAME)
     9.5  MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
     9.6  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\scsiport.lib
     9.7 -SOURCES=xenvbd.c
     9.8 +SOURCES=xenvbd.c scsiport.c
    10.1 --- a/xenvbd/xenvbd.c	Wed May 07 10:47:03 2008 +1000
    10.2 +++ b/xenvbd/xenvbd.c	Mon May 12 00:20:02 2008 +1000
    10.3 @@ -1,3 +1,22 @@
    10.4 +/*
    10.5 +PV Drivers for Windows Xen HVM Domains
    10.6 +Copyright (C) 2007 James Harper
    10.7 +
    10.8 +This program is free software; you can redistribute it and/or
    10.9 +modify it under the terms of the GNU General Public License
   10.10 +as published by the Free Software Foundation; either version 2
   10.11 +of the License, or (at your option) any later version.
   10.12 +
   10.13 +This program is distributed in the hope that it will be useful,
   10.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.16 +GNU General Public License for more details.
   10.17 +
   10.18 +You should have received a copy of the GNU General Public License
   10.19 +along with this program; if not, write to the Free Software
   10.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   10.21 +*/
   10.22 +
   10.23  #include "xenvbd.h"
   10.24  #include <io/blkif.h>
   10.25  #include <scsi.h>
   10.26 @@ -10,9 +29,6 @@
   10.27  
   10.28  #pragma warning(disable: 4127)
   10.29  
   10.30 -#define wmb() KeMemoryBarrier()
   10.31 -#define mb() KeMemoryBarrier()
   10.32 -
   10.33  DRIVER_INITIALIZE DriverEntry;
   10.34  
   10.35  static ULONG
   10.36 @@ -34,7 +50,119 @@ XenVbd_HwScsiAdapterControl(PVOID Device
   10.37  #pragma alloc_text (INIT, DriverEntry)
   10.38  #endif
   10.39  
   10.40 -static BOOLEAN DumpMode;
   10.41 +static PDRIVER_DISPATCH XenVbd_Pnp_Original;
   10.42 +
   10.43 +static NTSTATUS
   10.44 +XenVbd_Pnp(PDEVICE_OBJECT device_object, PIRP irp)
   10.45 +{
   10.46 +  PIO_STACK_LOCATION stack;
   10.47 +  NTSTATUS status;
   10.48 +  PCM_RESOURCE_LIST old_crl, new_crl;
   10.49 +  PCM_PARTIAL_RESOURCE_LIST prl;
   10.50 +  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
   10.51 +  ULONG old_length, new_length;
   10.52 +  PMDL mdl;
   10.53 +  PUCHAR start, ptr;
   10.54 +
   10.55 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   10.56 +
   10.57 +  stack = IoGetCurrentIrpStackLocation(irp);
   10.58 +
   10.59 +  switch (stack->MinorFunction)
   10.60 +  {
   10.61 +  case IRP_MN_START_DEVICE:
   10.62 +    KdPrint((__DRIVER_NAME "     IRP_MN_START_DEVICE\n"));
   10.63 +    mdl = AllocatePage();
   10.64 +    old_crl = stack->Parameters.StartDevice.AllocatedResourcesTranslated;
   10.65 +    old_length = FIELD_OFFSET(CM_RESOURCE_LIST, List) + 
   10.66 +      FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) +
   10.67 +      FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
   10.68 +      sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * old_crl->List[0].PartialResourceList.Count;
   10.69 +    new_length = old_length + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * 1;
   10.70 +    new_crl = ExAllocatePoolWithTag(PagedPool, new_length, XENVBD_POOL_TAG);
   10.71 +    memcpy(new_crl, old_crl, old_length);
   10.72 +    prl = &new_crl->List[0].PartialResourceList;
   10.73 +    prd = &prl->PartialDescriptors[prl->Count++];
   10.74 +    prd->Type = CmResourceTypeMemory;
   10.75 +    prd->ShareDisposition = CmResourceShareDeviceExclusive;
   10.76 +    prd->Flags = CM_RESOURCE_MEMORY_READ_WRITE|CM_RESOURCE_MEMORY_PREFETCHABLE|CM_RESOURCE_MEMORY_CACHEABLE;
   10.77 +    prd->u.Memory.Start.QuadPart = MmGetMdlPfnArray(mdl)[0] << PAGE_SHIFT;
   10.78 +    prd->u.Memory.Length = PAGE_SIZE;
   10.79 +    KdPrint((__DRIVER_NAME "     Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
   10.80 +    ptr = start = MmGetMdlVirtualAddress(mdl);
   10.81 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL);
   10.82 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_IRQ, "event-channel", NULL);
   10.83 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL);
   10.84 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL);
   10.85 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL);
   10.86 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_VECTORS, NULL, NULL);
   10.87 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, UlongToPtr(GRANT_ENTRIES), NULL);
   10.88 +    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL);
   10.89 +    
   10.90 +    stack->Parameters.StartDevice.AllocatedResourcesTranslated = new_crl;
   10.91 +
   10.92 +    old_crl = stack->Parameters.StartDevice.AllocatedResources;
   10.93 +    new_crl = ExAllocatePoolWithTag(PagedPool, new_length, XENVBD_POOL_TAG);
   10.94 +    memcpy(new_crl, old_crl, old_length);
   10.95 +    prl = &new_crl->List[0].PartialResourceList;
   10.96 +    prd = &prl->PartialDescriptors[prl->Count++];
   10.97 +    prd->Type = CmResourceTypeMemory;
   10.98 +    prd->ShareDisposition = CmResourceShareDeviceExclusive;
   10.99 +    prd->Flags = CM_RESOURCE_MEMORY_READ_WRITE|CM_RESOURCE_MEMORY_PREFETCHABLE|CM_RESOURCE_MEMORY_CACHEABLE;
  10.100 +    prd->u.Memory.Start.QuadPart = MmGetMdlPfnArray(mdl)[0] << PAGE_SHIFT;
  10.101 +    prd->u.Memory.Length = PAGE_SIZE;
  10.102 +    stack->Parameters.StartDevice.AllocatedResources = new_crl;
  10.103 +
  10.104 +    IoCopyCurrentIrpStackLocationToNext(irp);
  10.105 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.106 +
  10.107 +    break;
  10.108 +
  10.109 +  case IRP_MN_QUERY_STOP_DEVICE:
  10.110 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_STOP_DEVICE\n"));
  10.111 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.112 +    break;
  10.113 +
  10.114 +  case IRP_MN_STOP_DEVICE:
  10.115 +    KdPrint((__DRIVER_NAME "     IRP_MN_STOP_DEVICE\n"));
  10.116 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.117 +    break;
  10.118 +
  10.119 +  case IRP_MN_CANCEL_STOP_DEVICE:
  10.120 +    KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_STOP_DEVICE\n"));
  10.121 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.122 +    break;
  10.123 +
  10.124 +  case IRP_MN_QUERY_REMOVE_DEVICE:
  10.125 +    KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_REMOVE_DEVICE\n"));
  10.126 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.127 +    break;
  10.128 +
  10.129 +  case IRP_MN_REMOVE_DEVICE:
  10.130 +    KdPrint((__DRIVER_NAME "     IRP_MN_REMOVE_DEVICE\n"));
  10.131 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.132 +    break;
  10.133 +
  10.134 +  case IRP_MN_CANCEL_REMOVE_DEVICE:
  10.135 +    KdPrint((__DRIVER_NAME "     IRP_MN_CANCEL_REMOVE_DEVICE\n"));
  10.136 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.137 +    break;
  10.138 +
  10.139 +  case IRP_MN_SURPRISE_REMOVAL:
  10.140 +    KdPrint((__DRIVER_NAME "     IRP_MN_SURPRISE_REMOVAL\n"));
  10.141 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.142 +    break;
  10.143 +
  10.144 +  default:
  10.145 +    KdPrint((__DRIVER_NAME "     Unknown Minor = %d\n", stack->MinorFunction));
  10.146 +    status = XenVbd_Pnp_Original(device_object, irp);
  10.147 +    break;
  10.148 +  }
  10.149 +
  10.150 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
  10.151 +
  10.152 +  return status;
  10.153 +}
  10.154  
  10.155  NTSTATUS
  10.156  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
  10.157 @@ -48,15 +176,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  10.158    RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
  10.159  
  10.160    HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
  10.161 -  HwInitializationData.AdapterInterfaceType = Internal; //PNPBus;
  10.162 -  HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
  10.163 -  HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
  10.164 -  HwInitializationData.HwInterrupt = XenVbd_HwScsiInterrupt;
  10.165 -  HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
  10.166 -  HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
  10.167 +  HwInitializationData.AdapterInterfaceType = Internal;
  10.168    HwInitializationData.HwDmaStarted = NULL;
  10.169 -  HwInitializationData.HwAdapterState = XenVbd_HwScsiAdapterState;
  10.170 -  HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_EXTENSION); //sizeof(XENVBD_DEVICE_DATA);
  10.171 +  HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_DATA);
  10.172    HwInitializationData.SpecificLuExtensionSize = 0;
  10.173    HwInitializationData.SrbExtensionSize = 0;
  10.174    HwInitializationData.NumberOfAccessRanges = 1;
  10.175 @@ -70,11 +192,14 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  10.176    HwInitializationData.VendorId = NULL;
  10.177    HwInitializationData.DeviceIdLength = 0;
  10.178    HwInitializationData.DeviceId = NULL;
  10.179 -  HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
  10.180  
  10.181 -  DumpMode = FALSE;
  10.182 +  XenVbd_FillInitCallbacks(&HwInitializationData);
  10.183  
  10.184    Status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
  10.185 +  
  10.186 +  /* this is a bit naughty... */
  10.187 +  XenVbd_Pnp_Original = DriverObject->MajorFunction[IRP_MJ_PNP];
  10.188 +  DriverObject->MajorFunction[IRP_MJ_PNP] = XenVbd_Pnp;
  10.189  
  10.190    if(!NT_SUCCESS(Status))
  10.191    {
  10.192 @@ -85,190 +210,23 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  10.193  
  10.194    return Status;
  10.195  }
  10.196 -
  10.197 +#if 0
  10.198  static __inline uint64_t
  10.199 -GET_ID_FROM_FREELIST(PXENVBD_TARGET_DATA TargetData)
  10.200 +GET_ID_FROM_FREELIST(PXENVBD_DEVICE_DATA device_data)
  10.201  {
  10.202    uint64_t free;
  10.203 -  free = TargetData->shadow_free;
  10.204 -  TargetData->shadow_free = TargetData->shadow[free].req.id;
  10.205 -  TargetData->shadow[free].req.id = 0x0fffffee; /* debug */
  10.206 +  free = device_data->shadow_free;
  10.207 +  device_data->shadow_free = device_data->shadow[free].req.id;
  10.208 +  device_data->shadow[free].req.id = 0x0fffffee; /* debug */
  10.209    return free;
  10.210  }
  10.211 -
  10.212 -static __inline VOID
  10.213 -ADD_ID_TO_FREELIST(PXENVBD_TARGET_DATA TargetData, uint64_t Id)
  10.214 -{
  10.215 -  TargetData->shadow[Id].req.id  = TargetData->shadow_free;
  10.216 -  TargetData->shadow[Id].Srb = NULL;
  10.217 -  TargetData->shadow_free = Id;
  10.218 -}
  10.219 -
  10.220 -static BOOLEAN
  10.221 -XenVbd_Interrupt(PKINTERRUPT Interrupt, PVOID DeviceExtension)
  10.222 -{
  10.223 -  PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
  10.224 -
  10.225 -  UNREFERENCED_PARAMETER(Interrupt);
  10.226 -
  10.227 -  KdPrint((__DRIVER_NAME " --> Interrupt\n"));
  10.228 -
  10.229 -  TargetData->PendingInterrupt = TRUE;
  10.230 -
  10.231 -  KdPrint((__DRIVER_NAME " <-- Interrupt\n"));
  10.232 -
  10.233 -  return TRUE;
  10.234 -}
  10.235 -
  10.236 -static blkif_response_t *
  10.237 -XenVbd_GetResponse(PXENVBD_TARGET_DATA TargetData, int i)
  10.238 -{
  10.239 -  blkif_other_response_t *rep;
  10.240 -  if (!TargetData->use_other)
  10.241 -    return RING_GET_RESPONSE(&TargetData->Ring, i);
  10.242 -  rep = RING_GET_RESPONSE(&TargetData->OtherRing, i);
  10.243 -  TargetData->tmp_rep.id = rep->id;
  10.244 -  TargetData->tmp_rep.operation = rep->operation;
  10.245 -  TargetData->tmp_rep.status = rep->status;
  10.246 -  return &TargetData->tmp_rep;
  10.247 -}
  10.248 -
  10.249 -static VOID
  10.250 -XenVbd_HwScsiInterruptTarget(PVOID DeviceExtension)
  10.251 -{
  10.252 -  PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
  10.253 -  PSCSI_REQUEST_BLOCK Srb;
  10.254 -  RING_IDX i, rp;
  10.255 -  blkif_response_t *rep;
  10.256 -  int BlockCount;
  10.257 -  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
  10.258 -  int more_to_do = TRUE;
  10.259 -
  10.260 -  KdPrint((__DRIVER_NAME " --> HwScsiInterruptTarget\n"));
  10.261 -
  10.262 -#if 0
  10.263 -  while (more_to_do)
  10.264 -  {
  10.265 -    rp = TargetData->Ring.sring->rsp_prod;
  10.266 -    KeMemoryBarrier();
  10.267 -    for (i = TargetData->Ring.rsp_cons; i != rp; i++)
  10.268 -    {
  10.269 -      rep = XenVbd_GetResponse(TargetData, i);
  10.270 -
  10.271 -      //KdPrint((__DRIVER_NAME "     rep = %p\n", rep));
  10.272 -      //KdPrint((__DRIVER_NAME "     rep->id = %d\n", rep->id));
  10.273 -
  10.274 -      /*
  10.275 -       * This code is to automatically detect if the backend is using the same
  10.276 -       * bit width or a different bit width to us. Later versions of Xen do this
  10.277 -       * via a xenstore value, but not all. That 0x0fffffff (notice
  10.278 -       * that the msb is not actually set, so we don't have any problems with
  10.279 -       * sign extending) is to signify the last entry on the right, which is
  10.280 -       * different under 32 and 64 bits, and that is why we set it up there.
  10.281 -
  10.282 -       * To do the detection, we put two initial entries on the ring, with an op
  10.283 -       * of 0xff (which is invalid). The first entry is mostly okay, but the
  10.284 -       * second will be grossly misaligned if the backend bit width is different,
  10.285 -       * and we detect this and switch frontend structures.
  10.286 -       */
  10.287 -      switch (TargetData->ring_detect_state)
  10.288 -      {
  10.289 -      case 0:
  10.290 -        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", TargetData->ring_detect_state, rep->operation, rep->id, rep->status));
  10.291 -        TargetData->ring_detect_state = 1;
  10.292 -        break;
  10.293 -      case 1:
  10.294 -        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", TargetData->ring_detect_state, rep->operation, rep->id, rep->status));
  10.295 -        if (rep->operation != 0xff)
  10.296 -        {
  10.297 -          TargetData->Ring.nr_ents = BLK_OTHER_RING_SIZE;
  10.298 -          TargetData->use_other = TRUE;
  10.299 -        }
  10.300 -        TargetData->shadow[TargetData->Ring.nr_ents - 1].req.id = 0x0fffffff;
  10.301 -        DeviceData->BusChangePending = 1;
  10.302 -        TargetData->ring_detect_state = 2;
  10.303 -        break;
  10.304 -      case 2:
  10.305 -        Srb = TargetData->shadow[rep->id].Srb;
  10.306 -        if (Srb != NULL)
  10.307 -        {
  10.308 -          BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
  10.309 -  
  10.310 -          if (rep->status == BLKIF_RSP_OKAY)
  10.311 -            Srb->SrbStatus = SRB_STATUS_SUCCESS;
  10.312 -          else
  10.313 -          {
  10.314 -            KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
  10.315 -            if (Srb->Cdb[0] == SCSIOP_READ)
  10.316 -              KdPrint((__DRIVER_NAME "     Operation = Read\n"));
  10.317 -            else
  10.318 -              KdPrint((__DRIVER_NAME "     Operation = Write\n"));     
  10.319 -            KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", TargetData->shadow[rep->id].req.sector_number, BlockCount));
  10.320 -            Srb->SrbStatus = SRB_STATUS_ERROR;
  10.321 -          }
  10.322 -          if (Srb->Cdb[0] == SCSIOP_READ)
  10.323 -            memcpy(Srb->DataBuffer, TargetData->shadow[rep->id].Buf, BlockCount * TargetData->BytesPerSector);
  10.324 -    
  10.325 -          ScsiPortNotification(RequestComplete, DeviceData->DeviceExtension, Srb);
  10.326 -          if (!DumpMode)
  10.327 -            ScsiPortNotification(NextLuRequest, DeviceData->DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
  10.328 -          else
  10.329 -            ScsiPortNotification(NextRequest, DeviceData->DeviceExtension);
  10.330 -        }
  10.331 -        ADD_ID_TO_FREELIST(TargetData, rep->id);
  10.332 -      }
  10.333 -    }
  10.334 -
  10.335 -    TargetData->Ring.rsp_cons = i;
  10.336 -    if (i != TargetData->Ring.req_prod_pvt)
  10.337 -    {
  10.338 -      RING_FINAL_CHECK_FOR_RESPONSES(&TargetData->Ring, more_to_do);
  10.339 -    }
  10.340 -    else
  10.341 -    {
  10.342 -      TargetData->Ring.sring->rsp_event = i + 1;
  10.343 -      more_to_do = FALSE;
  10.344 -    }
  10.345 -  }
  10.346 -
  10.347  #endif
  10.348  
  10.349 -  KdPrint((__DRIVER_NAME " <-- HwScsiInterruptTarget\n"));
  10.350 -}
  10.351 -
  10.352 -static BOOLEAN
  10.353 -XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
  10.354 -{
  10.355 -  PXENVBD_DEVICE_DATA DeviceData;
  10.356 -  PXENVBD_TARGET_DATA TargetData;
  10.357 -  int i, j;
  10.358 -
  10.359 -//  KdPrint((__DRIVER_NAME " --> HwScsiInterrupt\n"));
  10.360 -
  10.361 -  DeviceData = ((PXENVBD_DEVICE_EXTENSION)DeviceExtension)->XenVbdDeviceData;
  10.362 -
  10.363 -  KeMemoryBarrier();
  10.364 -  for (i = 0; i < SCSI_BUSES; i++)
  10.365 -  {
  10.366 -    for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
  10.367 -    {
  10.368 -      TargetData = &DeviceData->BusData[i].TargetData[j];
  10.369 -      if (TargetData->Running && (TargetData->PendingInterrupt || (TargetData->Present && DumpMode)))
  10.370 -        XenVbd_HwScsiInterruptTarget(TargetData);
  10.371 -      TargetData->PendingInterrupt = FALSE;
  10.372 -    }
  10.373 -  }
  10.374 -//  KdPrint((__DRIVER_NAME " <-- HwScsiInterrupt\n"));
  10.375 -
  10.376 -  return FALSE;
  10.377 -}
  10.378 -
  10.379  #if 0
  10.380  static VOID
  10.381  XenVbd_BackEndStateHandler(char *Path, PVOID Data)
  10.382  {
  10.383 -  PXENVBD_TARGET_DATA TargetData;
  10.384 -  PXENVBD_DEVICE_DATA DeviceData;
  10.385 +  PXENVBD_DEVICE_DATA device_data;
  10.386    char TmpPath[128];
  10.387    char *Value;
  10.388    int NewState;
  10.389 @@ -283,8 +241,7 @@ XenVbd_BackEndStateHandler(char *Path, P
  10.390    KdPrint((__DRIVER_NAME " --> BackEndStateHandler\n"));
  10.391    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  10.392  
  10.393 -  TargetData = (PXENVBD_TARGET_DATA)Data;
  10.394 -  DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
  10.395 +  device_data = (PXENVBD_TARGET_DATA)Data;
  10.396  
  10.397    DeviceData->XenDeviceData->XenInterface.XenBus_Read(
  10.398      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  10.399 @@ -525,900 +482,4 @@ XenVbd_BackEndStateHandler(char *Path, P
  10.400    KdPrint((__DRIVER_NAME " <-- BackEndStateHandler\n"));
  10.401  }
  10.402  
  10.403 -static VOID
  10.404 -XenVbd_WatchHandler(char *Path, PVOID DeviceExtension)
  10.405 -{
  10.406 -  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
  10.407 -  char **Bits;
  10.408 -  int Count;
  10.409 -  char TmpPath[128];
  10.410 -  char *Value;
  10.411 -  int CurrentBus, CurrentTarget;
  10.412 -  PXENVBD_TARGET_DATA TargetData, VacantTarget;
  10.413 -  KIRQL OldIrql;
  10.414 -  int i;
  10.415 -
  10.416 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "(DeviceData = %p)\n", DeviceData));
  10.417 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  10.418 -
  10.419 -  KdPrint((__DRIVER_NAME "     Path = %s\n", Path));
  10.420 -
  10.421 -  Bits = SplitString(Path, '/', 4, &Count);
  10.422 -  switch (Count)
  10.423 -  {
  10.424 -  case 0:
  10.425 -  case 1:
  10.426 -  case 2:
  10.427 -    break; // should never happen
  10.428 -  case 3:
  10.429 -    break;
  10.430 -  case 4:
  10.431 -    if (strcmp(Bits[3], "state") != 0) // we only care when the state appears
  10.432 -      break;
  10.433 -
  10.434 -    KeAcquireSpinLock(&DeviceData->Lock, &OldIrql);
  10.435 -
  10.436 -    for (VacantTarget = NULL, i = 0; i < SCSI_BUSES * SCSI_TARGETS_PER_BUS; i++)
  10.437 -    {
  10.438 -      CurrentBus = i / SCSI_TARGETS_PER_BUS;
  10.439 -      CurrentTarget = i % SCSI_TARGETS_PER_BUS;
  10.440 -      if (CurrentTarget == 7) // don't use 7 - it would be for the controller
  10.441 -        continue;
  10.442 -      TargetData = &DeviceData->BusData[CurrentBus].TargetData[CurrentTarget];
  10.443 -      if (TargetData->Present && strncmp(TargetData->Path, Path, strlen(TargetData->Path)) == 0 && Path[strlen(TargetData->Path)] == '/')
  10.444 -        break; // already exists
  10.445 -      else if (!TargetData->Present && VacantTarget == NULL)
  10.446 -        VacantTarget = TargetData;
  10.447 -    }
  10.448 -    if (i == SCSI_BUSES * SCSI_TARGETS_PER_BUS && VacantTarget != NULL)
  10.449 -    {
  10.450 -      VacantTarget->Present = 1;
  10.451 -      KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
  10.452 -
  10.453 -      DeviceData->XenDeviceData->XenInterface.XenBus_Read(
  10.454 -        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  10.455 -        XBT_NIL, Path, &Value);
  10.456 -
  10.457 -      if (Value == NULL)
  10.458 -      {
  10.459 -        KdPrint((__DRIVER_NAME "     blank state?\n"));
  10.460 -        break;
  10.461 -      }
  10.462 -      if (atoi(Value) != XenbusStateInitialising)
  10.463 -        DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  10.464 -          DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  10.465 -          XBT_NIL, Path, "%d", XenbusStateClosing);
  10.466 -
  10.467 -      RtlStringCbCopyA(VacantTarget->Path, 128, Bits[0]);
  10.468 -      RtlStringCbCatA(VacantTarget->Path, 128, "/");
  10.469 -      RtlStringCbCatA(VacantTarget->Path, 128, Bits[1]);
  10.470 -      RtlStringCbCatA(VacantTarget->Path, 128, "/");
  10.471 -      RtlStringCbCatA(VacantTarget->Path, 128, Bits[2]);
  10.472 -
  10.473 -      VacantTarget->DeviceIndex = atoi(Bits[2]);
  10.474 -
  10.475 -      RtlStringCbCopyA(TmpPath, 128, VacantTarget->Path);
  10.476 -      RtlStringCbCatA(TmpPath, 128, "/backend");
  10.477 -      DeviceData->XenDeviceData->XenInterface.XenBus_Read(
  10.478 -        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  10.479 -        XBT_NIL, TmpPath, &Value);
  10.480 -      if (Value == NULL)
  10.481 -        KdPrint((__DRIVER_NAME "     Read Failed\n"));
  10.482 -      else
  10.483 -        RtlStringCbCopyA(VacantTarget->BackendPath, 128, Value);
  10.484 -      RtlStringCbCopyA(TmpPath, 128, VacantTarget->BackendPath);
  10.485 -      RtlStringCbCatA(TmpPath, 128, "/state");
  10.486 -
  10.487 -      DeviceData->XenDeviceData->XenInterface.XenBus_AddWatch(
  10.488 -        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  10.489 -        XBT_NIL, TmpPath, XenVbd_BackEndStateHandler, VacantTarget);
  10.490 -    }
  10.491 -    else
  10.492 -      KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
  10.493 -    break;
  10.494 -  }
  10.495 -  
  10.496 -  FreeSplitString(Bits, Count);
  10.497 -
  10.498 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
  10.499 -
  10.500 -  return;
  10.501 -}
  10.502 -
  10.503 -static VOID
  10.504 -XenVbd_EnumerateExisting(PXENVBD_DEVICE_DATA DeviceData)
  10.505 -{
  10.506 -  char *msg;
  10.507 -  ULONG i;
  10.508 -  char **VbdDevices;
  10.509 -  char buffer[128];
  10.510 -  int TotalInitialDevices = 0;
  10.511 -
  10.512 -  msg = DeviceData->XenDeviceData->XenInterface.XenBus_List(
  10.513 -    DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  10.514 -    XBT_NIL, "device/vbd", &VbdDevices);
  10.515 -  if (!msg)
  10.516 -  {
  10.517 -    for (i = 0; VbdDevices[i]; i++)
  10.518 -    {
  10.519 -      KdPrint((__DRIVER_NAME "     found existing vbd device %s\n", VbdDevices[i]));
  10.520 -      RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
  10.521 -      XenVbd_WatchHandler(buffer, DeviceData);
  10.522 -      TotalInitialDevices++;
  10.523 -    }  
  10.524 -  }
  10.525 -  DeviceData->TotalInitialDevices = TotalInitialDevices;
  10.526 -}
  10.527 -
  10.528 -static PXENPCI_XEN_DEVICE_DATA
  10.529 -XenVbd_GetXenDeviceData(PPORT_CONFIGURATION_INFORMATION ConfigInfo)
  10.530 -{
  10.531 -  ULONG i;
  10.532 -  PACCESS_RANGE AccessRange;
  10.533 -  PXENPCI_XEN_DEVICE_DATA XenDeviceData = NULL;
  10.534 -
  10.535 -  for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
  10.536 -  {
  10.537 -    AccessRange = &(*(ConfigInfo->AccessRanges))[i];
  10.538 -    KdPrint((__DRIVER_NAME "     AccessRange %2d: RangeStart = %p, RangeLength = %x, RangeInMemory = %d\n", i, AccessRange->RangeStart.QuadPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
  10.539 -    switch (i)
  10.540 -    {
  10.541 -    case 0:
  10.542 -      XenDeviceData = (PVOID)(xen_ulong_t)AccessRange->RangeStart.QuadPart;
  10.543 -      KdPrint((__DRIVER_NAME "     Mapped to virtual address %p\n", XenDeviceData));
  10.544 -      KdPrint((__DRIVER_NAME "     Magic = %08x\n", XenDeviceData->Magic));
  10.545 -      break;
  10.546 -    default:
  10.547 -      break;
  10.548 -    }
  10.549 -  }
  10.550 -  return XenDeviceData;
  10.551 -}
  10.552 -
  10.553 -static VOID
  10.554 -XenVbd_InitDeviceData(PXENVBD_DEVICE_DATA DeviceData, PPORT_CONFIGURATION_INFORMATION ConfigInfo)
  10.555 -{
  10.556 -  ULONG i, j;
  10.557 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
  10.558 -
  10.559 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
  10.560 -
  10.561 -  KeInitializeSpinLock(&DeviceData->Lock);
  10.562 -
  10.563 -  DeviceData->XenDeviceData = XenVbd_GetXenDeviceData(ConfigInfo);
  10.564 -
  10.565 -  for (i = 0; i < SCSI_BUSES; i++)
  10.566 -  {
  10.567 -    for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
  10.568 -    {
  10.569 -      DeviceData->BusData[i].TargetData[j].Present = 0;
  10.570 -      DeviceData->BusData[i].TargetData[j].Running = 0;
  10.571 -      DeviceData->BusData[i].TargetData[j].DeviceData = DeviceData;
  10.572 -    }
  10.573 -  }
  10.574 -
  10.575 -  DeviceData->XenDeviceData->WatchContext = DeviceData;
  10.576 -  KeMemoryBarrier();
  10.577 -  DeviceData->XenDeviceData->WatchHandler = XenVbd_WatchHandler;
  10.578 -
  10.579 -  DeviceData->EnumeratedDevices = 0;
  10.580 -  DeviceData->TotalInitialDevices = 0;
  10.581 -
  10.582 -  if (DeviceData->XenDeviceData->AutoEnumerate)
  10.583 -  {
  10.584 -    DeviceData->TotalInitialDevices = SCSI_BUSES * SCSI_TARGETS_PER_BUS;
  10.585 -    XenVbd_EnumerateExisting(DeviceData);
  10.586 -  }
  10.587 -
  10.588 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  10.589 -}
  10.590 -
  10.591  #endif
  10.592 -static ULONG
  10.593 -XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
  10.594 -{
  10.595 -  ULONG i, j, k;
  10.596 -//  PACCESS_RANGE AccessRange;
  10.597 -  PXENVBD_DEVICE_DATA DeviceData; // = ((PXENVBD_DEVICE_EXTENSION)DeviceExtension)->XenVbdDeviceData;
  10.598 -//  ULONG status;
  10.599 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
  10.600 -
  10.601 -  UNREFERENCED_PARAMETER(HwContext);
  10.602 -  UNREFERENCED_PARAMETER(BusInformation);
  10.603 -  UNREFERENCED_PARAMETER(ArgumentString);
  10.604 -
  10.605 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
  10.606 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  10.607 -
  10.608 -  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
  10.609 -  KdPrint((__DRIVER_NAME "     BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
  10.610 -
  10.611 -  KdPrint((__DRIVER_NAME "     AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
  10.612 -
  10.613 -  if (KeGetCurrentIrql() == PASSIVE_LEVEL)
  10.614 -  {
  10.615 -    DeviceData = ((PXENVBD_DEVICE_EXTENSION)DeviceExtension)->XenVbdDeviceData = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENVBD_DEVICE_DATA), XENVBD_POOL_TAG);
  10.616 -//    XenVbd_InitDeviceData(DeviceData, ConfigInfo);
  10.617 -//    if (DeviceData->XenDeviceData->Magic != XEN_DATA_MAGIC)
  10.618 -//      return SP_RETURN_NOT_FOUND;
  10.619 -  }
  10.620 -#if 0
  10.621 -  else
  10.622 -  {
  10.623 -    DumpMode = TRUE;
  10.624 -    XenDeviceData = XenVbd_GetXenDeviceData(ConfigInfo);
  10.625 -    if (XenDeviceData == NULL || XenDeviceData->Magic != XEN_DATA_MAGIC)
  10.626 -    {
  10.627 -      return SP_RETURN_NOT_FOUND;
  10.628 -    }
  10.629 -    DeviceData = XenDeviceData->WatchContext;
  10.630 -    ((PXENVBD_DEVICE_EXTENSION)DeviceExtension)->XenVbdDeviceData = DeviceData;
  10.631 -    DeviceData->XenDeviceData->WatchHandler = XenVbd_WatchHandler;
  10.632 -
  10.633 -
  10.634 -    for (i = 0; i < SCSI_BUSES; i++)
  10.635 -    {
  10.636 -      for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
  10.637 -      {
  10.638 -        for (k = 0; k < max(BLK_RING_SIZE, BLK_OTHER_RING_SIZE); k++)
  10.639 -        {
  10.640 -          if (DeviceData->BusData[i].TargetData[j].Present)
  10.641 -            DeviceData->BusData[i].TargetData[j].shadow[k].Srb = NULL;
  10.642 -        }
  10.643 -      }
  10.644 -    }
  10.645 -  }
  10.646 -  KdPrint((__DRIVER_NAME "     DeviceData = %p\n", DeviceData));
  10.647 -#endif
  10.648 -
  10.649 -  DeviceData->DeviceExtension = DeviceExtension;
  10.650 -
  10.651 -  ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
  10.652 -  ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
  10.653 -  ConfigInfo->ScatterGather = TRUE;
  10.654 -  ConfigInfo->AlignmentMask = 0;
  10.655 -  ConfigInfo->NumberOfBuses = SCSI_BUSES;
  10.656 -  for (i = 0; i < ConfigInfo->NumberOfBuses; i++)
  10.657 -  {
  10.658 -    ConfigInfo->InitiatorBusId[i] = 7;
  10.659 -  }
  10.660 -  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
  10.661 -  ConfigInfo->MaximumNumberOfTargets = SCSI_TARGETS_PER_BUS;
  10.662 -  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
  10.663 -  {
  10.664 -    ConfigInfo->Master = TRUE;
  10.665 -    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
  10.666 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
  10.667 -  }
  10.668 -  else
  10.669 -  {
  10.670 -    ConfigInfo->Master = FALSE;
  10.671 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
  10.672 -  }
  10.673 -
  10.674 -  // This all has to be initialized here as the real Initialize routine
  10.675 -  // is called at DIRQL, and the XenBus stuff has to be called at
  10.676 -  // <= DISPATCH_LEVEL
  10.677 -
  10.678 -  *Again = FALSE;
  10.679 -
  10.680 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
  10.681 -
  10.682 -  return SP_RETURN_FOUND;
  10.683 -}
  10.684 -
  10.685 -static VOID 
  10.686 -XenVbd_CheckBusChangedTimer(PVOID DeviceExtension);
  10.687 -
  10.688 -static VOID 
  10.689 -XenVbd_CheckBusEnumeratedTimer(PVOID DeviceExtension)
  10.690 -{
  10.691 -  PXENVBD_DEVICE_DATA DeviceData = ((PXENVBD_DEVICE_EXTENSION)DeviceExtension)->XenVbdDeviceData;
  10.692 -
  10.693 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  10.694 -//  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  10.695 -
  10.696 -  if (DeviceData->EnumeratedDevices >= DeviceData->TotalInitialDevices)
  10.697 -  {
  10.698 -    DeviceData->BusChangePending = 0;
  10.699 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  10.700 -    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
  10.701 -  }
  10.702 -  else
  10.703 -  {
  10.704 -    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusEnumeratedTimer, 100000);
  10.705 -  }
  10.706 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  10.707 -}
  10.708 -
  10.709 -static VOID 
  10.710 -XenVbd_CheckBusChangedTimer(PVOID DeviceExtension)
  10.711 -{
  10.712 -  PXENVBD_DEVICE_DATA DeviceData = ((PXENVBD_DEVICE_EXTENSION)DeviceExtension)->XenVbdDeviceData;
  10.713 -
  10.714 -  if (DeviceData->BusChangePending)
  10.715 -  {
  10.716 -    ScsiPortNotification(BusChangeDetected, DeviceExtension, 0);
  10.717 -    DeviceData->BusChangePending = 0;
  10.718 -  }
  10.719 -  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
  10.720 -}
  10.721 -
  10.722 -static BOOLEAN
  10.723 -XenVbd_HwScsiInitialize(PVOID DeviceExtension)
  10.724 -{
  10.725 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  10.726 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  10.727 -
  10.728 -  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusEnumeratedTimer, 100000);
  10.729 -
  10.730 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  10.731 -
  10.732 -  return TRUE;
  10.733 -}
  10.734 -
  10.735 -static ULONG
  10.736 -XenVbd_FillModePage(PXENVBD_DEVICE_DATA DeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
  10.737 -{
  10.738 -  //PMODE_RIGID_GEOMETRY_PAGE ModeRigidGeometry;
  10.739 -
  10.740 -  UNREFERENCED_PARAMETER(DeviceData);
  10.741 -  UNREFERENCED_PARAMETER(DataBuffer);
  10.742 -  UNREFERENCED_PARAMETER(BufferLength);
  10.743 -  UNREFERENCED_PARAMETER(Offset);
  10.744 -
  10.745 -  switch (PageCode)
  10.746 -  {
  10.747 -/*
  10.748 -  case MODE_PAGE_RIGID_GEOMETRY:
  10.749 -    if (DeviceData->ScsiData->DeviceType == XENVBD_DEVICETYPE_CDROM)
  10.750 -    {
  10.751 -    KdPrint((__DRIVER_NAME "     MODE_PAGE_RIGID_GEOMETRY\n"));
  10.752 -    if (*Offset + sizeof(MODE_RIGID_GEOMETRY_PAGE) > BufferLength)
  10.753 -      return 1;
  10.754 -    ModeRigidGeometry = (PMODE_RIGID_GEOMETRY_PAGE)(DataBuffer + *Offset);
  10.755 -    memset(ModeRigidGeometry, 0, sizeof(MODE_RIGID_GEOMETRY_PAGE));
  10.756 -    ModeRigidGeometry->PageCode = PageCode;
  10.757 -    ModeRigidGeometry->PageSavable = 0;
  10.758 -    ModeRigidGeometry->PageLength = sizeof(MODE_RIGID_GEOMETRY_PAGE);
  10.759 -    ModeRigidGeometry->NumberOfCylinders[0] = (DeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
  10.760 -    ModeRigidGeometry->NumberOfCylinders[1] = (DeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
  10.761 -    ModeRigidGeometry->NumberOfCylinders[2] = (DeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
  10.762 -    ModeRigidGeometry->NumberOfHeads = DeviceData->Geometry.TracksPerCylinder;
  10.763 -    //ModeRigidGeometry->LandZoneCyclinder = 0;
  10.764 -    ModeRigidGeometry->RoataionRate[0] = 0x05;
  10.765 -    ModeRigidGeometry->RoataionRate[0] = 0x39;
  10.766 -    *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
  10.767 -    }
  10.768 -    break;
  10.769 -*/
  10.770 -  case MODE_PAGE_FAULT_REPORTING:
  10.771 -    break;
  10.772 -  default:
  10.773 -    break;
  10.774 -  }
  10.775 -  return 0;
  10.776 -}
  10.777 -
  10.778 -static VOID
  10.779 -XenVbd_PutRequest(PXENVBD_TARGET_DATA TargetData, blkif_request_t *req)
  10.780 -{
  10.781 -  blkif_other_request_t *other_req;
  10.782 -
  10.783 -  if (!TargetData->use_other)
  10.784 -  {
  10.785 -    *RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt) = *req;
  10.786 -  }
  10.787 -  else
  10.788 -  {  
  10.789 -    other_req = RING_GET_REQUEST(&TargetData->OtherRing, TargetData->Ring.req_prod_pvt);
  10.790 -    other_req->operation = req->operation;
  10.791 -    other_req->nr_segments = req->nr_segments;
  10.792 -    other_req->handle = req->handle;
  10.793 -    other_req->id = req->id;
  10.794 -    other_req->sector_number = req->sector_number;
  10.795 -    memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
  10.796 -  }
  10.797 -  TargetData->Ring.req_prod_pvt++;
  10.798 -}
  10.799 -
  10.800 -// Call with device lock held
  10.801 -static VOID
  10.802 -XenVbd_PutSrbOnRing(PXENVBD_TARGET_DATA TargetData, PSCSI_REQUEST_BLOCK Srb)
  10.803 -{
  10.804 -  //PUCHAR DataBuffer;
  10.805 -  int i;
  10.806 -  int BlockCount;
  10.807 -  blkif_shadow_t *shadow;
  10.808 -  uint64_t id;
  10.809 -
  10.810 -// can use SRB_STATUS_BUSY to push the SRB back to windows...
  10.811 -
  10.812 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  10.813 -
  10.814 -  if (RING_FULL(&TargetData->Ring))
  10.815 -  {
  10.816 -    KdPrint((__DRIVER_NAME "     RING IS FULL - EXPECT BADNESS\n"));
  10.817 -    // TODO: Fail badly here
  10.818 -  }
  10.819 -
  10.820 -  id = GET_ID_FROM_FREELIST(TargetData);
  10.821 -  if (id == 0x0fffffff)
  10.822 -  {
  10.823 -    KdPrint((__DRIVER_NAME "     Something is horribly wrong in PutSrbOnRing\n"));
  10.824 -  }
  10.825 -
  10.826 -  shadow = &TargetData->shadow[id];
  10.827 -  shadow->req.id = id;
  10.828 -
  10.829 -  shadow->req.sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
  10.830 -  BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
  10.831 -  shadow->req.handle = 0;
  10.832 -  shadow->req.operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  10.833 -  shadow->Srb = Srb;
  10.834 -
  10.835 -  shadow->req.nr_segments = (UINT8)((BlockCount * TargetData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE);
  10.836 -
  10.837 -  for (i = 0; i < shadow->req.nr_segments; i++)
  10.838 -  {
  10.839 -/*
  10.840 -    shadow->req.seg[i].gref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
  10.841 -      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  10.842 -      0, (ULONG)MmGetMdlPfnArray(TargetData->shadow[shadow->req.id].Mdl)[i], FALSE);
  10.843 -    ASSERT((signed short)shadow->req.seg[i].gref >= 0);
  10.844 -*/
  10.845 -    shadow->req.seg[i].first_sect = 0;
  10.846 -    if (i == shadow->req.nr_segments - 1)
  10.847 -      shadow->req.seg[i].last_sect = (UINT8)((BlockCount - 1) % (PAGE_SIZE / TargetData->BytesPerSector));
  10.848 -    else
  10.849 -      shadow->req.seg[i].last_sect = (UINT8)(PAGE_SIZE / TargetData->BytesPerSector - 1);
  10.850 -  }
  10.851 -  if (Srb->Cdb[0] == SCSIOP_WRITE)
  10.852 -    memcpy(TargetData->shadow[shadow->req.id].Buf, Srb->DataBuffer, BlockCount * TargetData->BytesPerSector);
  10.853 -
  10.854 -  XenVbd_PutRequest(TargetData, &shadow->req);
  10.855 -
  10.856 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  10.857 -}
  10.858 -
  10.859 -static BOOLEAN
  10.860 -XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
  10.861 -{
  10.862 -  PUCHAR DataBuffer;
  10.863 -  PCDB cdb;
  10.864 -  PXENVBD_DEVICE_DATA DeviceData = ((PXENVBD_DEVICE_EXTENSION)DeviceExtension)->XenVbdDeviceData;
  10.865 -  PXENVBD_TARGET_DATA TargetData;
  10.866 -  unsigned int i;
  10.867 -  int notify;
  10.868 -
  10.869 -  KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
  10.870 -
  10.871 -__asm { int 0x91 };
  10.872 -Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  10.873 -ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  10.874 -ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  10.875 -
  10.876 -#if 0
  10.877 -//  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  10.878 -
  10.879 -  // If we haven't enumerated all the devices yet then just defer the request
  10.880 -  // A timer will issue a NextRequest to get things started again...
  10.881 -  if (DeviceData->EnumeratedDevices < DeviceData->TotalInitialDevices)
  10.882 -  {
  10.883 -    Srb->SrbStatus = SRB_STATUS_BUSY;
  10.884 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  10.885 -    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (NotEnumeratedYet)\n"));
  10.886 -    return TRUE;
  10.887 -  }
  10.888 -
  10.889 -  if (Srb->PathId >= SCSI_BUSES || Srb->TargetId >= SCSI_TARGETS_PER_BUS)
  10.890 -  {
  10.891 -    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  10.892 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  10.893 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  10.894 -    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
  10.895 -    return TRUE;
  10.896 -  }
  10.897 -
  10.898 -  TargetData = &DeviceData->BusData[Srb->PathId].TargetData[Srb->TargetId];
  10.899 -
  10.900 -  if (!TargetData->Running)
  10.901 -  {
  10.902 -    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
  10.903 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  10.904 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  10.905 -    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Not Present)\n"));
  10.906 -    return TRUE;
  10.907 -  }
  10.908 -
  10.909 -  switch (Srb->Function)
  10.910 -  {
  10.911 -  case SRB_FUNCTION_EXECUTE_SCSI:
  10.912 -    cdb = (PCDB)Srb->Cdb;
  10.913 -//    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_EXECUTE_SCSI\n"));
  10.914 -
  10.915 -    switch(cdb->CDB6GENERIC.OperationCode)
  10.916 -    {
  10.917 -    case SCSIOP_TEST_UNIT_READY:
  10.918 -//      KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
  10.919 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  10.920 -      Srb->ScsiStatus = 0;
  10.921 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  10.922 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
  10.923 -      break;
  10.924 -    case SCSIOP_INQUIRY:
  10.925 -      KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
  10.926 -      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
  10.927 -      KdPrint((__DRIVER_NAME "     (Length = %d)\n", Srb->DataTransferLength));
  10.928 -      KdPrint((__DRIVER_NAME "     (Srb->Databuffer = %08x)\n", Srb->DataBuffer));
  10.929 -      DataBuffer = Srb->DataBuffer;
  10.930 -      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
  10.931 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  10.932 -      switch (TargetData->DeviceType)
  10.933 -      {
  10.934 -      case XENVBD_DEVICETYPE_DISK:
  10.935 -        if ((Srb->Cdb[1] & 1) == 0)
  10.936 -        {
  10.937 -          DataBuffer[0] = DIRECT_ACCESS_DEVICE;
  10.938 -          DataBuffer[1] = 0x00; // not removable
  10.939 -          DataBuffer[3] = 32;
  10.940 -          memcpy(DataBuffer + 8, "XEN     ", 8); // vendor id
  10.941 -          memcpy(DataBuffer + 16, "PV VBD          ", 16); // product id
  10.942 -          memcpy(DataBuffer + 32, "0000", 4); // product revision level
  10.943 -        }
  10.944 -        else
  10.945 -        {
  10.946 -          switch (Srb->Cdb[2])
  10.947 -          {
  10.948 -          case 0x00:
  10.949 -            DataBuffer[0] = DIRECT_ACCESS_DEVICE;
  10.950 -            DataBuffer[1] = 0x00;
  10.951 -            DataBuffer[2] = 0x00;
  10.952 -            DataBuffer[3] = 2;
  10.953 -            DataBuffer[4] = 0x00;
  10.954 -            DataBuffer[5] = 0x80;
  10.955 -            break;
  10.956 -          case 0x80:
  10.957 -            DataBuffer[0] = DIRECT_ACCESS_DEVICE;
  10.958 -            DataBuffer[1] = 0x80;
  10.959 -            DataBuffer[2] = 0x00;
  10.960 -            DataBuffer[3] = 8;
  10.961 -            DataBuffer[4] = 0x31;
  10.962 -            DataBuffer[5] = 0x32;
  10.963 -            DataBuffer[6] = 0x33;
  10.964 -            DataBuffer[7] = 0x34;
  10.965 -            DataBuffer[8] = 0x35;
  10.966 -            DataBuffer[9] = 0x36;
  10.967 -            DataBuffer[10] = 0x37;
  10.968 -            DataBuffer[11] = 0x38;
  10.969 -            break;
  10.970 -          default:
  10.971 -            KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
  10.972 -            Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  10.973 -            break;
  10.974 -          }
  10.975 -        }
  10.976 -        break;
  10.977 -      case XENVBD_DEVICETYPE_CDROM:
  10.978 -        if ((Srb->Cdb[1] & 1) == 0)
  10.979 -        {
  10.980 -          DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
  10.981 -          DataBuffer[1] = 0x01; // removable
  10.982 -          DataBuffer[3] = 32;
  10.983 -          memcpy(DataBuffer + 8, "XEN     ", 8); // vendor id
  10.984 -          memcpy(DataBuffer + 16, "PV VBD          ", 16); // product id
  10.985 -          memcpy(DataBuffer + 32, "0000", 4); // product revision level
  10.986 -        }
  10.987 -        else
  10.988 -        {
  10.989 -          switch (Srb->Cdb[2])
  10.990 -          {
  10.991 -          case 0x00:
  10.992 -            DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
  10.993 -            DataBuffer[1] = 0x00;
  10.994 -            DataBuffer[2] = 0x00;
  10.995 -            DataBuffer[3] = 2;
  10.996 -            DataBuffer[4] = 0x00;
  10.997 -            DataBuffer[5] = 0x80;
  10.998 -            break;
  10.999 -          case 0x80:
 10.1000 -            DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
 10.1001 -            DataBuffer[1] = 0x80;
 10.1002 -            DataBuffer[2] = 0x00;
 10.1003 -            DataBuffer[3] = 8;
 10.1004 -            DataBuffer[4] = 0x31;
 10.1005 -            DataBuffer[5] = 0x32;
 10.1006 -            DataBuffer[6] = 0x33;
 10.1007 -            DataBuffer[7] = 0x34;
 10.1008 -            DataBuffer[8] = 0x35;
 10.1009 -            DataBuffer[9] = 0x36;
 10.1010 -            DataBuffer[10] = 0x37;
 10.1011 -            DataBuffer[11] = 0x38;
 10.1012 -            break;
 10.1013 -          default:
 10.1014 -            KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
 10.1015 -            Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 10.1016 -            break;
 10.1017 -          }
 10.1018 -        }
 10.1019 -        break;
 10.1020 -      default:
 10.1021 -        KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", TargetData->DeviceType));
 10.1022 -        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 10.1023 -        break;
 10.1024 -      }
 10.1025 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1026 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1027 -      break;
 10.1028 -    case SCSIOP_READ_CAPACITY:
 10.1029 -      KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
 10.1030 -      DataBuffer = Srb->DataBuffer;
 10.1031 -      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
 10.1032 -      DataBuffer[0] = (unsigned char)((TargetData->TotalSectors - 1) >> 24) & 0xff;
 10.1033 -      DataBuffer[1] = (unsigned char)((TargetData->TotalSectors - 1) >> 16) & 0xff;
 10.1034 -      DataBuffer[2] = (unsigned char)((TargetData->TotalSectors - 1) >> 8) & 0xff;
 10.1035 -      DataBuffer[3] = (unsigned char)((TargetData->TotalSectors - 1) >> 0) & 0xff;
 10.1036 -      DataBuffer[4] = (unsigned char)(TargetData->BytesPerSector >> 24) & 0xff;
 10.1037 -      DataBuffer[5] = (unsigned char)(TargetData->BytesPerSector >> 16) & 0xff;
 10.1038 -      DataBuffer[6] = (unsigned char)(TargetData->BytesPerSector >> 8) & 0xff;
 10.1039 -      DataBuffer[7] = (unsigned char)(TargetData->BytesPerSector >> 0) & 0xff;
 10.1040 -      Srb->ScsiStatus = 0;
 10.1041 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
 10.1042 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1043 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1044 -      break;
 10.1045 -    case SCSIOP_MODE_SENSE:
 10.1046 -      KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x10, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
 10.1047 -      KdPrint((__DRIVER_NAME "     Length = %d\n", Srb->DataTransferLength));
 10.1048 -
 10.1049 -      Srb->ScsiStatus = 0;
 10.1050 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
 10.1051 -      Srb->DataTransferLength = 0;
 10.1052 -      DataBuffer = Srb->DataBuffer;
 10.1053 -      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
 10.1054 -      switch(cdb->MODE_SENSE.PageCode)
 10.1055 -      {
 10.1056 -      case MODE_SENSE_RETURN_ALL:
 10.1057 -        //Ptr = (UCHAR *)Srb->DataBuffer;
 10.1058 -        for (i = 0; i < MODE_SENSE_RETURN_ALL; i++)
 10.1059 -        {
 10.1060 -          if (XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength))
 10.1061 -          {
 10.1062 -            break;
 10.1063 -          }
 10.1064 -        }
 10.1065 -        break;
 10.1066 -      default:
 10.1067 -        XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength);
 10.1068 -        break;
 10.1069 -      }
 10.1070 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1071 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1072 -      break;
 10.1073 -    case SCSIOP_READ:
 10.1074 -    case SCSIOP_WRITE:
 10.1075 -//      KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
 10.1076 -      XenVbd_PutSrbOnRing(TargetData, Srb);
 10.1077 -      RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&TargetData->Ring, notify);
 10.1078 -      if (notify)
 10.1079 -        DeviceData->XenDeviceData->XenInterface.EvtChn_Notify(
 10.1080 -          DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
 10.1081 -          TargetData->EventChannel);
 10.1082 -      if (!RING_FULL(&TargetData->Ring) && !DumpMode)
 10.1083 -        ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
 10.1084 -      else
 10.1085 -        ScsiPortNotification(NextRequest, DeviceExtension);
 10.1086 -      break;
 10.1087 -    case SCSIOP_VERIFY:
 10.1088 -      // Should we do more here?
 10.1089 -      KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
 10.1090 -      Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
 10.1091 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);      
 10.1092 -      ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
 10.1093 -      break;
 10.1094 -    case SCSIOP_REPORT_LUNS:
 10.1095 -      KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
 10.1096 -      Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
 10.1097 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1098 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1099 -      break;
 10.1100 -    case SCSIOP_READ_TOC:
 10.1101 -      DataBuffer = Srb->DataBuffer;
 10.1102 -//      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
 10.1103 -/*
 10.1104 -#define READ_TOC_FORMAT_TOC         0x00
 10.1105 -#define READ_TOC_FORMAT_SESSION     0x01
 10.1106 -#define READ_TOC_FORMAT_FULL_TOC    0x02
 10.1107 -#define READ_TOC_FORMAT_PMA         0x03
 10.1108 -#define READ_TOC_FORMAT_ATIP        0x04
 10.1109 -*/
 10.1110 -      KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
 10.1111 -      KdPrint((__DRIVER_NAME "     Msf = %d\n", cdb->READ_TOC.Msf));
 10.1112 -      KdPrint((__DRIVER_NAME "     LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
 10.1113 -      KdPrint((__DRIVER_NAME "     Format2 = %d\n", cdb->READ_TOC.Format2));
 10.1114 -      KdPrint((__DRIVER_NAME "     StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
 10.1115 -      KdPrint((__DRIVER_NAME "     AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
 10.1116 -      KdPrint((__DRIVER_NAME "     Control = %d\n", cdb->READ_TOC.Control));
 10.1117 -      KdPrint((__DRIVER_NAME "     Format = %d\n", cdb->READ_TOC.Format));
 10.1118 -      switch (cdb->READ_TOC.Format2)
 10.1119 -      {
 10.1120 -      case READ_TOC_FORMAT_TOC:
 10.1121 -        DataBuffer[0] = 0; // length MSB
 10.1122 -        DataBuffer[1] = 10; // length LSB
 10.1123 -        DataBuffer[2] = 1; // First Track
 10.1124 -        DataBuffer[3] = 1; // Last Track
 10.1125 -        DataBuffer[4] = 0; // Reserved
 10.1126 -        DataBuffer[5] = 0x14; // current position data + uninterrupted data
 10.1127 -        DataBuffer[6] = 1; // last complete track
 10.1128 -        DataBuffer[7] = 0; // reserved
 10.1129 -        DataBuffer[8] = 0; // MSB Block
 10.1130 -        DataBuffer[9] = 0;
 10.1131 -        DataBuffer[10] = 0;
 10.1132 -        DataBuffer[11] = 0; // LSB Block
 10.1133 -        Srb->SrbStatus = SRB_STATUS_SUCCESS;
 10.1134 -        break;
 10.1135 -      case READ_TOC_FORMAT_SESSION:
 10.1136 -      case READ_TOC_FORMAT_FULL_TOC:
 10.1137 -      case READ_TOC_FORMAT_PMA:
 10.1138 -      case READ_TOC_FORMAT_ATIP:
 10.1139 -        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 10.1140 -        break;
 10.1141 -      }
 10.1142 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1143 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1144 -      break;
 10.1145 -    case SCSIOP_START_STOP_UNIT:
 10.1146 -      KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
 10.1147 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
 10.1148 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1149 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1150 -      break;
 10.1151 -    default:
 10.1152 -      KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
 10.1153 -      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 10.1154 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1155 -      ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1156 -      break;
 10.1157 -    }
 10.1158 -    break;
 10.1159 -  case SRB_FUNCTION_CLAIM_DEVICE:
 10.1160 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_CLAIM_DEVICE\n"));
 10.1161 -//    ObReferenceObject(WdfDeviceWdmGetDeviceObject(Device));
 10.1162 -//    Srb->DataBuffer = WdfDeviceWdmGetDeviceObject(Device);
 10.1163 -    Srb->SrbStatus = SRB_STATUS_SUCCESS;
 10.1164 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1165 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1166 -    break;
 10.1167 -  case SRB_FUNCTION_IO_CONTROL:
 10.1168 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
 10.1169 -    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 10.1170 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1171 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1172 -    break;
 10.1173 -  case SRB_FUNCTION_FLUSH:
 10.1174 -    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
 10.1175 -    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 10.1176 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1177 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1178 -    break;
 10.1179 -  default:
 10.1180 -    KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
 10.1181 -    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
 10.1182 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
 10.1183 -    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
 10.1184 -    break;
 10.1185 -  }
 10.1186 -#endif
 10.1187 -
 10.1188 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
 10.1189 -  return TRUE;
 10.1190 -}
 10.1191 -
 10.1192 -static BOOLEAN
 10.1193 -XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
 10.1194 -{
 10.1195 -  UNREFERENCED_PARAMETER(DeviceExtension);
 10.1196 -  UNREFERENCED_PARAMETER(PathId);
 10.1197 -
 10.1198 -
 10.1199 -  KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
 10.1200 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 10.1201 -
 10.1202 -  KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
 10.1203 -
 10.1204 -  return TRUE;
 10.1205 -}
 10.1206 -
 10.1207 -
 10.1208 -static BOOLEAN
 10.1209 -XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
 10.1210 -{
 10.1211 -  UNREFERENCED_PARAMETER(DeviceExtension);
 10.1212 -  UNREFERENCED_PARAMETER(Context);
 10.1213 -  UNREFERENCED_PARAMETER(SaveState);
 10.1214 -
 10.1215 -  KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
 10.1216 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 10.1217 -
 10.1218 -  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
 10.1219 -
 10.1220 -  return TRUE;
 10.1221 -}
 10.1222 -
 10.1223 -static SCSI_ADAPTER_CONTROL_STATUS
 10.1224 -XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
 10.1225 -{
 10.1226 -  SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
 10.1227 -  PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
 10.1228 -  KIRQL OldIrql;
 10.1229 -
 10.1230 -  UNREFERENCED_PARAMETER(DeviceExtension);
 10.1231 -
 10.1232 -  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
 10.1233 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
 10.1234 -
 10.1235 -  //KdBreakPoint();
 10.1236 -
 10.1237 -  KdPrint((__DRIVER_NAME "     int 0x81 (xenvbd)"));
 10.1238 -  __asm {
 10.1239 -    cli
 10.1240 -    int 0x81
 10.1241 -    sti
 10.1242 -  };
 10.1243 -  
 10.1244 -  KeRaiseIrql(7, &OldIrql);
 10.1245 -  KdPrint((__DRIVER_NAME "     int 0x81 (xenvbd)"));
 10.1246 -  __asm {
 10.1247 -    int 0x81
 10.1248 -  };
 10.1249 -  KeLowerIrql(OldIrql);
 10.1250 -
 10.1251 -  KeRaiseIrql(7, &OldIrql);
 10.1252 -  KdPrint((__DRIVER_NAME "     int 0x81 (xenvbd)"));
 10.1253 -  __asm {
 10.1254 -    cli
 10.1255 -    int 0x81
 10.1256 -    sti
 10.1257 -  };
 10.1258 -  KeLowerIrql(OldIrql);
 10.1259 -
 10.1260 -  /*
 10.1261 -  KdPrint((__DRIVER_NAME "     int 0x07"));
 10.1262 -  __asm { int 0x07 };
 10.1263 -
 10.1264 -  KdPrint((__DRIVER_NAME "     int 0x37"));
 10.1265 -  __asm { int 0x37 };
 10.1266 -  */
 10.1267 -  
 10.1268 -//  KdPrint((__DRIVER_NAME "     int 0x83 (xenpci)"));
 10.1269 -//  __asm { int 0x83 };
 10.1270 -
 10.1271 -  switch (ControlType)
 10.1272 -  {
 10.1273 -  case ScsiQuerySupportedControlTypes:
 10.1274 -    SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
 10.1275 -    KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
 10.1276 -    SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
 10.1277 -    SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
 10.1278 -    break;
 10.1279 -  case ScsiStopAdapter:
 10.1280 -    KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
 10.1281 -    break;
 10.1282 -  case ScsiRestartAdapter:
 10.1283 -    KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
 10.1284 -    break;
 10.1285 -  case ScsiSetBootConfig:
 10.1286 -    KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
 10.1287 -    break;
 10.1288 -  case ScsiSetRunningConfig:
 10.1289 -    KdPrint((__DRIVER_NAME "     ScsiSetRunningConfig\n"));
 10.1290 -    break;
 10.1291 -  default:
 10.1292 -    KdPrint((__DRIVER_NAME "     UNKNOWN\n"));
 10.1293 -    break;
 10.1294 -  }
 10.1295 -
 10.1296 -  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
 10.1297 -
 10.1298 -  return Status;
 10.1299 -}
    11.1 --- a/xenvbd/xenvbd.h	Wed May 07 10:47:03 2008 +1000
    11.2 +++ b/xenvbd/xenvbd.h	Mon May 12 00:20:02 2008 +1000
    11.3 @@ -1,3 +1,22 @@
    11.4 +/*
    11.5 +PV Drivers for Windows Xen HVM Domains
    11.6 +Copyright (C) 2007 James Harper
    11.7 +
    11.8 +This program is free software; you can redistribute it and/or
    11.9 +modify it under the terms of the GNU General Public License
   11.10 +as published by the Free Software Foundation; either version 2
   11.11 +of the License, or (at your option) any later version.
   11.12 +
   11.13 +This program is distributed in the hope that it will be useful,
   11.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.16 +GNU General Public License for more details.
   11.17 +
   11.18 +You should have received a copy of the GNU General Public License
   11.19 +along with this program; if not, write to the Free Software
   11.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   11.21 +*/
   11.22 +
   11.23  #if !defined(_XENVBD_H_)
   11.24  #define _XENVBD_H_
   11.25  
   11.26 @@ -56,15 +75,14 @@ DEFINE_RING_TYPES(blkif_other, struct bl
   11.27  typedef struct {
   11.28    blkif_request_t req;
   11.29    PSCSI_REQUEST_BLOCK Srb;
   11.30 +/*
   11.31    PMDL Mdl;
   11.32    VOID *Buf;
   11.33 +*/
   11.34  } blkif_shadow_t;
   11.35  
   11.36 -//#include "scsidata.h"
   11.37 -
   11.38 -
   11.39 -#define SCSI_BUSES 4
   11.40 -#define SCSI_TARGETS_PER_BUS 16
   11.41 +#define SHADOW_ENTRIES 32
   11.42 +#define GRANT_ENTRIES 128
   11.43  
   11.44  typedef enum {
   11.45    XENVBD_DEVICETYPE_UNKNOWN,
   11.46 @@ -75,55 +93,30 @@ typedef enum {
   11.47  
   11.48  struct
   11.49  {
   11.50 -  int Present;
   11.51 -  int Running;
   11.52 -  BOOLEAN PendingInterrupt;
   11.53 -  PVOID DeviceData; // how can we create a forward definition for this???
   11.54 -  evtchn_port_t EventChannel;
   11.55 -  blkif_shadow_t *shadow;
   11.56 -  uint64_t shadow_free;
   11.57 -  ULONG RingBufPFN;
   11.58 -  int BackendState;
   11.59 -  int FrontendState;
   11.60 -  char Path[128];
   11.61 -  int DeviceIndex;
   11.62 -  char BackendPath[128];
   11.63 +  blkif_shadow_t shadows[SHADOW_ENTRIES];
   11.64 +  USHORT shadow_free_list[SHADOW_ENTRIES];
   11.65 +  USHORT shadow_free;
   11.66 +
   11.67 +  grant_entry_t grants[GRANT_ENTRIES];
   11.68 +  USHORT grant_free_list[GRANT_ENTRIES];
   11.69 +  USHORT grant_free;
   11.70 +
   11.71 +  evtchn_port_t event_channel;
   11.72    union {
   11.73 -    blkif_front_ring_t Ring;
   11.74 -    blkif_other_front_ring_t OtherRing;
   11.75 +    blkif_front_ring_t ring;
   11.76 +    blkif_other_front_ring_t other_ring;
   11.77    };
   11.78    int ring_detect_state;
   11.79    BOOLEAN use_other;
   11.80    blkif_response_t tmp_rep;
   11.81 -  XENVBD_DEVICETYPE DeviceType;
   11.82 +  XENVBD_DEVICETYPE device_type;
   11.83    DISK_GEOMETRY Geometry;
   11.84 -  ULONG BytesPerSector;
   11.85 -  ULONGLONG TotalSectors; 
   11.86 -} typedef XENVBD_TARGET_DATA, *PXENVBD_TARGET_DATA;
   11.87 -
   11.88 -struct
   11.89 -{
   11.90 -  XENVBD_TARGET_DATA TargetData[SCSI_TARGETS_PER_BUS];
   11.91 -} typedef XENVBD_BUS_DATA, *PXENVBD_BUS_DATA;
   11.92 -
   11.93 -struct
   11.94 -{
   11.95 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
   11.96 -  XENVBD_BUS_DATA BusData[SCSI_BUSES];
   11.97 -
   11.98 -  KSPIN_LOCK Lock;
   11.99 -
  11.100 -  int BusChangePending;
  11.101 -
  11.102 -  LONG EnumeratedDevices;
  11.103 -  int TotalInitialDevices;
  11.104 -
  11.105 -  PVOID DeviceExtension;
  11.106 +  ULONG bytes_per_sector;
  11.107 +  ULONGLONG total_sectors;
  11.108 +  XENPCI_VECTORS vectors;
  11.109  } typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
  11.110  
  11.111 -struct
  11.112 -{
  11.113 -  PXENVBD_DEVICE_DATA XenVbdDeviceData;  
  11.114 -} typedef XENVBD_DEVICE_EXTENSION, *PXENVBD_DEVICE_EXTENSION;
  11.115 +VOID
  11.116 +XenVbd_FillInitCallbacks(PHW_INITIALIZATION_DATA HwInitializationData);
  11.117  
  11.118 -#endif
  11.119 +#endif
  11.120 \ No newline at end of file