win-pvdrivers

changeset 841:2f4e64007b0f

Hibernation and suspend/resume fixes.
Storport now handles large requests and breaks them up
author James Harper <james.harper@bendigoit.com.au>
date Sat Feb 05 17:32:12 2011 +1100 (2011-02-05)
parents c750a369bce5
children e4c8307c3042
files 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/xenvbd_storport.c xenvbd/xenvbd_storport.h
line diff
     1.1 --- a/common/include/xen_windows.h	Thu Feb 03 14:26:04 2011 +1100
     1.2 +++ b/common/include/xen_windows.h	Sat Feb 05 17:32:12 2011 +1100
     1.3 @@ -514,6 +514,7 @@ ADD_XEN_INIT_REQ(PUCHAR *ptr, UCHAR type
     1.4      __ADD_XEN_INIT_PTR(ptr, p3);
     1.5      break;
     1.6    case XEN_INIT_TYPE_GRANT_ENTRIES:
     1.7 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
     1.8      __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
     1.9      break;
    1.10  //  case XEN_INIT_TYPE_COPY_PTR:
    1.11 @@ -559,6 +560,7 @@ GET_XEN_INIT_REQ(PUCHAR *ptr, PVOID *p1,
    1.12      *p3 = __GET_XEN_INIT_PTR(ptr);
    1.13      break;
    1.14    case XEN_INIT_TYPE_GRANT_ENTRIES:
    1.15 +    *p1 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
    1.16      *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
    1.17      break;
    1.18    }
    1.19 @@ -599,6 +601,7 @@ ADD_XEN_INIT_RSP(PUCHAR *ptr, UCHAR type
    1.20      break;
    1.21    case XEN_INIT_TYPE_GRANT_ENTRIES:
    1.22      __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p1));
    1.23 +    __ADD_XEN_INIT_ULONG(ptr, PtrToUlong(p2));
    1.24      memcpy(*ptr, p2, PtrToUlong(p1) * sizeof(grant_entry_t));
    1.25      *ptr += PtrToUlong(p1) * sizeof(grant_entry_t);
    1.26      break;
    1.27 @@ -657,8 +660,9 @@ GET_XEN_INIT_RSP(PUCHAR *ptr, PVOID *p1,
    1.28      break;
    1.29    case XEN_INIT_TYPE_GRANT_ENTRIES:
    1.30      *p1 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
    1.31 -    *p2 = *ptr;
    1.32 -    *ptr += PtrToUlong(*p1) * sizeof(grant_ref_t);
    1.33 +    *p2 = UlongToPtr(__GET_XEN_INIT_ULONG(ptr));
    1.34 +    *p3 = *ptr;
    1.35 +    *ptr += PtrToUlong(*p2) * sizeof(grant_ref_t);
    1.36      break;
    1.37    case XEN_INIT_TYPE_STATE_PTR:
    1.38      *p2 = __GET_XEN_INIT_PTR(ptr);
     2.1 --- a/xenpci/evtchn.c	Thu Feb 03 14:26:04 2011 +1100
     2.2 +++ b/xenpci/evtchn.c	Sat Feb 05 17:32:12 2011 +1100
     2.3 @@ -154,40 +154,43 @@ to CPU != 0, but we should always use vc
     2.4        switch (ev_action->type)
     2.5        {
     2.6        case EVT_ACTION_TYPE_NORMAL:
     2.7 -        //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_NORMAL\n"));
     2.8 +        //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_NORMAL port = %d\n", port));
     2.9          ev_action->ServiceRoutine(ev_action->ServiceContext);
    2.10          break;
    2.11        case EVT_ACTION_TYPE_IRQ:
    2.12 -        //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_IRQ\n"));
    2.13 +        //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_IRQ port = %d\n", port));
    2.14          synch_set_bit(evt_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[pcpu][evt_word]);
    2.15          deferred = TRUE;
    2.16          break;
    2.17        case EVT_ACTION_TYPE_DPC:
    2.18 -        //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_DPC\n"));
    2.19 +        //KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_DPC port = %d\n", port));
    2.20          KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
    2.21          break;
    2.22        case EVT_ACTION_TYPE_SUSPEND:
    2.23          KdPrint((__DRIVER_NAME "     EVT_ACTION_TYPE_SUSPEND\n"));
    2.24          for (i = 0; i < ARRAY_SIZE(xpdd->evtchn_pending_pvt[pcpu]); i++)
    2.25          {
    2.26 -          switch(xpdd->ev_actions[i].type)
    2.27 +          if (!(xpdd->ev_actions[i].flags & EVT_ACTION_FLAGS_NO_SUSPEND))
    2.28            {
    2.29 -          case EVT_ACTION_TYPE_IRQ:
    2.30 +            switch(xpdd->ev_actions[i].type)
    2.31              {
    2.32 -              int suspend_bit = i & (BITS_PER_LONG - 1);
    2.33 -              int suspend_word = i >> BITS_PER_LONG_SHIFT;
    2.34 -              synch_set_bit(suspend_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[pcpu][suspend_word]);
    2.35 +            case EVT_ACTION_TYPE_IRQ:
    2.36 +              {
    2.37 +                int suspend_bit = i & (BITS_PER_LONG - 1);
    2.38 +                int suspend_word = i >> BITS_PER_LONG_SHIFT;
    2.39 +                synch_set_bit(suspend_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[pcpu][suspend_word]);
    2.40 +              }
    2.41 +              break;
    2.42 +            case EVT_ACTION_TYPE_NORMAL:
    2.43 +              if (xpdd->ev_actions[i].ServiceRoutine)
    2.44 +              {
    2.45 +                xpdd->ev_actions[i].ServiceRoutine(xpdd->ev_actions[i].ServiceContext);
    2.46 +              }
    2.47 +              break;
    2.48 +            case EVT_ACTION_TYPE_DPC:
    2.49 +              KeInsertQueueDpc(&xpdd->ev_actions[i].Dpc, NULL, NULL);
    2.50 +              break;
    2.51              }
    2.52 -            break;
    2.53 -          case EVT_ACTION_TYPE_NORMAL:
    2.54 -            if (xpdd->ev_actions[i].ServiceRoutine)
    2.55 -            {
    2.56 -              xpdd->ev_actions[i].ServiceRoutine(xpdd->ev_actions[i].ServiceContext);
    2.57 -            }
    2.58 -            break;
    2.59 -          case EVT_ACTION_TYPE_DPC:
    2.60 -            KeInsertQueueDpc(&xpdd->ev_actions[i].Dpc, NULL, NULL);
    2.61 -            break;
    2.62            }
    2.63          }
    2.64          KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
    2.65 @@ -232,7 +235,7 @@ EvtChn_EvtInterruptDisable(WDFINTERRUPT 
    2.66  }
    2.67  
    2.68  NTSTATUS
    2.69 -EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
    2.70 +EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags)
    2.71  {
    2.72    PXENPCI_DEVICE_DATA xpdd = Context;
    2.73    ev_action_t *action = &xpdd->ev_actions[Port];
    2.74 @@ -248,6 +251,7 @@ EvtChn_Bind(PVOID Context, evtchn_port_t
    2.75    xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
    2.76    xpdd->ev_actions[Port].ServiceContext = ServiceContext;
    2.77    xpdd->ev_actions[Port].xpdd = xpdd;
    2.78 +  xpdd->ev_actions[Port].flags = flags;
    2.79    KeMemoryBarrier();
    2.80    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_NORMAL;
    2.81  
    2.82 @@ -259,7 +263,7 @@ EvtChn_Bind(PVOID Context, evtchn_port_t
    2.83  }
    2.84  
    2.85  NTSTATUS
    2.86 -EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext)
    2.87 +EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags)
    2.88  {
    2.89    PXENPCI_DEVICE_DATA xpdd = Context;
    2.90    ev_action_t *action = &xpdd->ev_actions[Port];
    2.91 @@ -275,6 +279,7 @@ EvtChn_BindDpc(PVOID Context, evtchn_por
    2.92    xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
    2.93    xpdd->ev_actions[Port].ServiceContext = ServiceContext;
    2.94    xpdd->ev_actions[Port].xpdd = xpdd;
    2.95 +  xpdd->ev_actions[Port].flags = flags;
    2.96    KeMemoryBarrier(); // make sure that the new service routine is only called once the context is set up
    2.97    InterlockedExchange((volatile LONG *)&action->type, EVT_ACTION_TYPE_DPC);
    2.98  
    2.99 @@ -286,7 +291,7 @@ EvtChn_BindDpc(PVOID Context, evtchn_por
   2.100  }
   2.101  
   2.102  NTSTATUS
   2.103 -EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description)
   2.104 +EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description, ULONG flags)
   2.105  {
   2.106    PXENPCI_DEVICE_DATA xpdd = Context;
   2.107    ev_action_t *action = &xpdd->ev_actions[Port];
   2.108 @@ -304,7 +309,8 @@ EvtChn_BindIrq(PVOID Context, evtchn_por
   2.109    KeMemoryBarrier();
   2.110    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_IRQ;
   2.111    RtlStringCbCopyA(xpdd->ev_actions[Port].description, 128, description);
   2.112 -
   2.113 +  xpdd->ev_actions[Port].flags = flags;
   2.114 +  
   2.115    EvtChn_Unmask(Context, Port);
   2.116  
   2.117    FUNCTION_EXIT();
   2.118 @@ -455,7 +461,7 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
   2.119  
   2.120    KeInitializeEvent(&xpdd->pdo_suspend_event, SynchronizationEvent, FALSE);
   2.121    xpdd->pdo_event_channel = EvtChn_AllocIpi(xpdd, 0);
   2.122 -  EvtChn_BindDpc(xpdd, xpdd->pdo_event_channel, EvtChn_PdoEventChannelDpc, xpdd);
   2.123 +  EvtChn_BindDpc(xpdd, xpdd->pdo_event_channel, EvtChn_PdoEventChannelDpc, xpdd, EVT_ACTION_FLAGS_DEFAULT);
   2.124    xpdd->ev_actions[xpdd->pdo_event_channel].type = EVT_ACTION_TYPE_SUSPEND; /* override dpc type */
   2.125    
   2.126    KdPrint((__DRIVER_NAME "     pdo_event_channel = %d\n", xpdd->pdo_event_channel));
     3.1 --- a/xenpci/gnttbl.c	Thu Feb 03 14:26:04 2011 +1100
     3.2 +++ b/xenpci/gnttbl.c	Sat Feb 05 17:32:12 2011 +1100
     3.3 @@ -187,6 +187,7 @@ GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
     3.4    #if DBG
     3.5    xpdd->gnttbl_tag = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(ULONG), XENPCI_POOL_TAG);
     3.6    RtlZeroMemory(xpdd->gnttbl_tag, grant_entries * sizeof(ULONG));
     3.7 +  xpdd->gnttbl_tag_copy = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(ULONG), XENPCI_POOL_TAG);
     3.8    #endif
     3.9    xpdd->gnttbl_table_copy = ExAllocatePoolWithTag(NonPagedPool, xpdd->grant_frames * PAGE_SIZE, XENPCI_POOL_TAG);
    3.10    ASSERT(xpdd->gnttbl_table_copy); // lazy
    3.11 @@ -233,7 +234,52 @@ GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
    3.12  VOID
    3.13  GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd)
    3.14  {
    3.15 +  int grant_entries;
    3.16 +  int i;
    3.17 +  
    3.18 +  FUNCTION_ENTER();
    3.19 +  
    3.20 +  /* copy some grant refs and switch to an alternate freelist, but only on hiber */
    3.21 +  if (KeGetCurrentIrql() <= DISPATCH_LEVEL)
    3.22 +  {
    3.23 +    KdPrint((__DRIVER_NAME "     backing up grant ref stack\n"));
    3.24 +    for (i = 0; i < HIBER_GREF_COUNT; i++)
    3.25 +    {
    3.26 +      xpdd->hiber_grefs[i] = INVALID_GRANT_REF;
    3.27 +    }
    3.28 +    for (i = 0; i < HIBER_GREF_COUNT; i++)
    3.29 +    {
    3.30 +      if ((xpdd->hiber_grefs[i] = GntTbl_GetRef(xpdd, (ULONG)'HIBR')) == INVALID_GRANT_REF)
    3.31 +        break;
    3.32 +    }
    3.33 +    KdPrint((__DRIVER_NAME "     %d grant refs reserved\n", i));
    3.34 +    xpdd->gnttbl_ss_copy = xpdd->gnttbl_ss;
    3.35 +    stack_new(&xpdd->gnttbl_ss, HIBER_GREF_COUNT);
    3.36 +  }
    3.37 +  else
    3.38 +  {
    3.39 +    xpdd->gnttbl_ss_copy = NULL;
    3.40 +  }
    3.41 +  
    3.42    memcpy(xpdd->gnttbl_table_copy, xpdd->gnttbl_table, xpdd->grant_frames * PAGE_SIZE);
    3.43 +  #if DBG
    3.44 +  /* even though gnttbl_tag is actually preserved, it is used by the dump driver so must be restored to exactly the same state as it was on suspend */
    3.45 +  grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
    3.46 +  memcpy(xpdd->gnttbl_tag_copy, xpdd->gnttbl_tag, grant_entries * sizeof(ULONG));
    3.47 +  #endif
    3.48 +
    3.49 +  /* put the grant entries on the new freelist, after copying the tables above */
    3.50 +  if (KeGetCurrentIrql() <= DISPATCH_LEVEL)
    3.51 +  {
    3.52 +    for (i = 0; i < HIBER_GREF_COUNT; i++)
    3.53 +    {
    3.54 +      if (xpdd->hiber_grefs[i] == INVALID_GRANT_REF)
    3.55 +        break;
    3.56 +      GntTbl_PutRef(xpdd, xpdd->hiber_grefs[i], (ULONG)'HIBR');
    3.57 +    }
    3.58 +  }
    3.59 +  
    3.60 +  FUNCTION_EXIT();
    3.61  }
    3.62  
    3.63  VOID
    3.64 @@ -242,8 +288,10 @@ GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd)
    3.65    ULONG new_grant_frames;
    3.66    ULONG result;
    3.67    int i;  
    3.68 +  int grant_entries;
    3.69 +
    3.70    FUNCTION_ENTER();
    3.71 -  
    3.72 +
    3.73    for (i = 0; i < (int)xpdd->grant_frames; i++)
    3.74    {
    3.75      struct xen_memory_reservation reservation;
    3.76 @@ -270,6 +318,25 @@ GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd)
    3.77    result = GntTbl_Map(xpdd, 0, xpdd->grant_frames - 1);
    3.78    KdPrint((__DRIVER_NAME "     GntTbl_Map result = %d\n", result));
    3.79    memcpy(xpdd->gnttbl_table, xpdd->gnttbl_table_copy, xpdd->grant_frames * PAGE_SIZE);
    3.80 -  
    3.81 +  #if DBG
    3.82 +  grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t)));
    3.83 +  memcpy(xpdd->gnttbl_tag, xpdd->gnttbl_tag_copy, grant_entries * sizeof(ULONG));
    3.84 +  #endif
    3.85 +
    3.86 +  /* switch back and put the hiber grants back again */
    3.87 +  if (xpdd->gnttbl_ss_copy)
    3.88 +  {
    3.89 +    KdPrint((__DRIVER_NAME "     restoring grant ref stack\n"));
    3.90 +    stack_delete(xpdd->gnttbl_ss, NULL, NULL);
    3.91 +    xpdd->gnttbl_ss = xpdd->gnttbl_ss_copy;
    3.92 +    for (i = 0; i < HIBER_GREF_COUNT; i++)
    3.93 +    {
    3.94 +      if (xpdd->hiber_grefs[i] == INVALID_GRANT_REF)
    3.95 +        break;
    3.96 +      GntTbl_PutRef(xpdd, xpdd->hiber_grefs[i], (ULONG)'HIBR');
    3.97 +    }
    3.98 +    xpdd->gnttbl_ss_copy = NULL;
    3.99 +  }
   3.100 +    
   3.101    FUNCTION_EXIT();
   3.102  }
     4.1 --- a/xenpci/xenbus.c	Thu Feb 03 14:26:04 2011 +1100
     4.2 +++ b/xenpci/xenbus.c	Sat Feb 05 17:32:12 2011 +1100
     4.3 @@ -358,7 +358,7 @@ XenBus_Connect(PXENPCI_DEVICE_DATA xpdd)
     4.4    pa_xen_store_interface.QuadPart = (ULONGLONG)xen_store_mfn << PAGE_SHIFT;
     4.5    xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached);
     4.6  
     4.7 -  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd);
     4.8 +  EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd, EVT_ACTION_FLAGS_NO_SUSPEND);
     4.9    
    4.10    return STATUS_SUCCESS;
    4.11  }
     5.1 --- a/xenpci/xenpci.h	Thu Feb 03 14:26:04 2011 +1100
     5.2 +++ b/xenpci/xenpci.h	Sat Feb 05 17:32:12 2011 +1100
     5.3 @@ -69,6 +69,10 @@ DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC82
     5.4  #define EVT_ACTION_TYPE_SUSPEND 4
     5.5  #define EVT_ACTION_TYPE_NEW     5 /* setup of event is in progress */
     5.6  
     5.7 +#define EVT_ACTION_FLAGS_DEFAULT    0 /* no special flags */
     5.8 +#define EVT_ACTION_FLAGS_NO_SUSPEND 1 /* should not be fired on EVT_ACTION_TYPE_SUSPEND event */
     5.9 +
    5.10 +
    5.11  #define XEN_PV_PRODUCT_NUMBER   0x0002
    5.12  #define XEN_PV_PRODUCT_BUILD    0x00000001
    5.13  
    5.14 @@ -79,6 +83,7 @@ typedef struct _ev_action_t {
    5.15    PVOID ServiceContext;
    5.16    CHAR description[128];
    5.17    ULONG type; /* EVT_ACTION_TYPE_* */
    5.18 +  ULONG flags; /* EVT_ACTION_FLAGS_* */
    5.19    KDPC Dpc;
    5.20    ULONG port;
    5.21    ULONG vector;
    5.22 @@ -117,6 +122,9 @@ typedef struct _XENBUS_WATCH_ENTRY {
    5.23  #define SUSPEND_STATE_HIGH_IRQL 2 /* all processors are at high IRQL and spinning */
    5.24  #define SUSPEND_STATE_RESUMING  3 /* we are the other side of the suspend and things are starting to get back to normal */
    5.25  
    5.26 +/* we take some grant refs out and put them aside so that we dont get corrupted by hibernate */
    5.27 +#define HIBER_GREF_COUNT 128
    5.28 +
    5.29  typedef struct {  
    5.30    WDFDEVICE wdf_device;
    5.31    
    5.32 @@ -152,11 +160,14 @@ typedef struct {
    5.33  
    5.34    /* grant related */
    5.35    struct stack_state *gnttbl_ss;
    5.36 +  struct stack_state *gnttbl_ss_copy;
    5.37 +  grant_ref_t hiber_grefs[HIBER_GREF_COUNT];
    5.38 +  PMDL gnttbl_mdl;
    5.39    grant_entry_t *gnttbl_table;
    5.40 -  PMDL gnttbl_mdl;
    5.41    grant_entry_t *gnttbl_table_copy;
    5.42    #if DBG
    5.43    PULONG gnttbl_tag;
    5.44 +  PULONG gnttbl_tag_copy;
    5.45    #endif
    5.46    ULONG grant_frames;
    5.47  
    5.48 @@ -252,8 +263,6 @@ typedef struct {
    5.49    XENPCI_STATE_MAP_ELEMENT xb_post_connect_map[5];
    5.50    XENPCI_STATE_MAP_ELEMENT xb_shutdown_map[5];
    5.51    
    5.52 -  
    5.53 -  
    5.54    BOOLEAN hiber_usage_kludge;
    5.55  } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
    5.56  
    5.57 @@ -460,11 +469,11 @@ EvtChn_Mask(PVOID Context, evtchn_port_t
    5.58  NTSTATUS
    5.59  EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
    5.60  NTSTATUS
    5.61 -EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
    5.62 +EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags);
    5.63  NTSTATUS
    5.64 -EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
    5.65 +EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags);
    5.66  NTSTATUS
    5.67 -EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description);
    5.68 +EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description, ULONG flags);
    5.69  evtchn_port_t
    5.70  EvtChn_AllocIpi(PVOID context, ULONG vcpu);
    5.71  NTSTATUS
     6.1 --- a/xenpci/xenpci_fdo.c	Thu Feb 03 14:26:04 2011 +1100
     6.2 +++ b/xenpci/xenpci_fdo.c	Sat Feb 05 17:32:12 2011 +1100
     6.3 @@ -476,7 +476,7 @@ XenPci_ConnectSuspendEvt(PXENPCI_DEVICE_
     6.4    KdPrint((__DRIVER_NAME "     suspend event channel = %d\n", xpdd->suspend_evtchn));
     6.5    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/suspend/event-channel");
     6.6    XenBus_Printf(xpdd, XBT_NIL, path, "%d", xpdd->suspend_evtchn);
     6.7 -  EvtChn_BindDpc(xpdd, xpdd->suspend_evtchn, XenPci_SuspendEvtDpc, xpdd->wdf_device);
     6.8 +  EvtChn_BindDpc(xpdd, xpdd->suspend_evtchn, XenPci_SuspendEvtDpc, xpdd->wdf_device, EVT_ACTION_FLAGS_NO_SUSPEND);
     6.9    
    6.10    return STATUS_SUCCESS;
    6.11  }
    6.12 @@ -940,7 +940,9 @@ XenPci_EvtDeviceD0Exit(WDFDEVICE device,
    6.13    }
    6.14    else
    6.15    {
    6.16 +    EvtChn_Suspend(xpdd);
    6.17      GntTbl_Suspend(xpdd);
    6.18 +    
    6.19    }
    6.20  
    6.21    FUNCTION_EXIT();
     7.1 --- a/xenpci/xenpci_pdo.c	Thu Feb 03 14:26:04 2011 +1100
     7.2 +++ b/xenpci/xenpci_pdo.c	Sat Feb 05 17:32:12 2011 +1100
     7.3 @@ -251,7 +251,7 @@ XenPci_EvtChn_Bind(PVOID context, evtchn
     7.4    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
     7.5    PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
     7.6    
     7.7 -  return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext);
     7.8 +  return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT);
     7.9  }
    7.10  
    7.11  static NTSTATUS
    7.12 @@ -261,7 +261,7 @@ XenPci_EvtChn_BindDpc(PVOID context, evt
    7.13    PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
    7.14    PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
    7.15    
    7.16 -  return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext);
    7.17 +  return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT);
    7.18  }
    7.19  
    7.20  static NTSTATUS
    7.21 @@ -581,8 +581,8 @@ XenPci_XenShutdownDevice(PVOID context)
    7.22          EvtChn_Close(xpdd, PtrToUlong(value));
    7.23          break;
    7.24        case XEN_INIT_TYPE_GRANT_ENTRIES:
    7.25 -        for (i = 0; i < PtrToUlong(setting); i++)
    7.26 -          GntTbl_EndAccess(xpdd, ((grant_ref_t *)value)[i], FALSE, (ULONG)'XPDO');
    7.27 +        for (i = 0; i < PtrToUlong(value); i++)
    7.28 +          GntTbl_EndAccess(xpdd, ((grant_ref_t *)value2)[i], FALSE, PtrToUlong(setting));
    7.29          break;
    7.30        }
    7.31      }
    7.32 @@ -697,6 +697,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
    7.33            ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring, NULL);
    7.34            // add the grant entry too so it gets freed automatically
    7.35            __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_GRANT_ENTRIES);
    7.36 +          __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, (ULONG)'XPDO');
    7.37            __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, 1);
    7.38            __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
    7.39          }
    7.40 @@ -725,17 +726,17 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
    7.41          ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel), NULL);
    7.42          if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
    7.43          {
    7.44 -          EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector, path);
    7.45 +          EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector, path, EVT_ACTION_FLAGS_DEFAULT);
    7.46          }
    7.47          else if (type == XEN_INIT_TYPE_EVENT_CHANNEL_DPC)
    7.48          {
    7.49            #pragma warning(suppress:4055)
    7.50 -          EvtChn_BindDpc(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2);
    7.51 +          EvtChn_BindDpc(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2, EVT_ACTION_FLAGS_DEFAULT);
    7.52          }
    7.53          else
    7.54          {
    7.55            #pragma warning(suppress:4055)
    7.56 -          EvtChn_Bind(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2);
    7.57 +          EvtChn_Bind(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2, EVT_ACTION_FLAGS_DEFAULT);
    7.58          }
    7.59        }
    7.60        else
    7.61 @@ -829,11 +830,13 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
    7.62        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value)));
    7.63        __ADD_XEN_INIT_UCHAR(&out_ptr, type);
    7.64        __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, type);
    7.65 +      __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(setting));
    7.66 +      __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(setting));
    7.67        __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(value));
    7.68        __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(value));
    7.69        for (i = 0; i < PtrToUlong(value); i++)
    7.70        {
    7.71 -        gref = GntTbl_GetRef(xpdd, 'XPDO');
    7.72 +        gref = GntTbl_GetRef(xpdd, PtrToUlong(setting));
    7.73          __ADD_XEN_INIT_ULONG(&out_ptr, gref);
    7.74          __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref);
    7.75        }
     8.1 --- a/xenvbd/xenvbd_storport.c	Thu Feb 03 14:26:04 2011 +1100
     8.2 +++ b/xenvbd/xenvbd_storport.c	Sat Feb 05 17:32:12 2011 +1100
     8.3 @@ -151,7 +151,6 @@ XenVbd_InitConfig(PXENVBD_DEVICE_DATA xv
     8.4    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
     8.5    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
     8.6    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
     8.7 -  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, NULL, ULongToPtr(BLKIF_MAX_SEGMENTS_PER_REQUEST), NULL); /* for use in crash dump */
     8.8    ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
     8.9    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
    8.10    __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
    8.11 @@ -236,7 +235,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
    8.12        }
    8.13        break;
    8.14      case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
    8.15 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value) & 0x3FFFFFFF));
    8.16 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d (%08x)\n", setting, PtrToUlong(value) & 0x3FFFFFFF, PtrToUlong(value)));
    8.17        if (strcmp(setting, "event-channel") == 0)
    8.18        {
    8.19          /* cheat here - save the state of the ring in the topmost bits of the event-channel */
    8.20 @@ -293,10 +292,6 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
    8.21          }
    8.22        }
    8.23        break;
    8.24 -    case XEN_INIT_TYPE_GRANT_ENTRIES:
    8.25 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - entries = %d\n", PtrToUlong(setting)));
    8.26 -      memcpy(xvdd->dump_grant_refs, value, PtrToUlong(setting) * sizeof(grant_ref_t));
    8.27 -      break;
    8.28      case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
    8.29        qemu_protocol_version = PtrToUlong(value);
    8.30        break;
    8.31 @@ -416,15 +411,19 @@ decode_cdb_is_read(PSCSI_REQUEST_BLOCK s
    8.32    }
    8.33  }
    8.34  
    8.35 -ULONG max_dump_mode_blocks = 0;
    8.36 -ULONG max_dump_mode_length = 0;
    8.37 -
    8.38  static VOID
    8.39  XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
    8.40  {
    8.41 -  srb_list_entry_t *list_entry = srb->SrbExtension;
    8.42 -  list_entry->srb = srb;
    8.43 -  InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)list_entry);
    8.44 +  srb_list_entry_t *srb_entry = srb->SrbExtension;
    8.45 +  srb_entry->srb = srb;
    8.46 +  if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI)
    8.47 +  {
    8.48 +    srb_entry->outstanding_requests = 0;
    8.49 +    srb_entry->length = srb->DataTransferLength;
    8.50 +    srb_entry->offset = 0;
    8.51 +    srb_entry->error = FALSE;
    8.52 +  }
    8.53 +  InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
    8.54  }
    8.55  
    8.56  static VOID
    8.57 @@ -447,7 +446,26 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    8.58    while(!xvdd->aligned_buffer_in_use && xvdd->shadow_free && (srb_entry = (srb_list_entry_t *)RemoveHeadList(&xvdd->srb_list)) != (srb_list_entry_t *)&xvdd->srb_list)
    8.59    {
    8.60      srb = srb_entry->srb;
    8.61 -    //if (dump_mode) KdPrint((__DRIVER_NAME "     srb = %p\n", srb));
    8.62 +    ASSERT(srb);
    8.63 +    if (srb->Function != SRB_FUNCTION_EXECUTE_SCSI)
    8.64 +    {
    8.65 +      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_%02x retrieved from ring\n", srb->Function));
    8.66 +      if (xvdd->shadow_free != SHADOW_ENTRIES)
    8.67 +      {
    8.68 +        KdPrint((__DRIVER_NAME "     busy\n"));
    8.69 +        /* put it back at the end of the list just in case something is queued that needs to be processed */
    8.70 +        InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
    8.71 +        break; /* stall the queue until it's all empty */
    8.72 +      }
    8.73 +      else
    8.74 +      {
    8.75 +        KdPrint((__DRIVER_NAME "     completing\n"));
    8.76 +        srb->SrbStatus = SRB_STATUS_SUCCESS;
    8.77 +        StorPortNotification(RequestComplete, xvdd, srb);
    8.78 +        continue;
    8.79 +      }
    8.80 +    }
    8.81 +
    8.82      if (!dump_mode)
    8.83      {
    8.84        if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS)
    8.85 @@ -457,57 +475,68 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    8.86          StorPortNotification(RequestComplete, xvdd, srb);
    8.87          continue;
    8.88        }
    8.89 +      system_address = (PUCHAR)system_address + srb_entry->offset;
    8.90      }
    8.91      else
    8.92      {
    8.93        //KdPrint((__DRIVER_NAME "     DataBuffer = %p\n", srb->DataBuffer));
    8.94 -      system_address = srb->DataBuffer;
    8.95 +      system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
    8.96      }
    8.97      block_count = decode_cdb_length(srb);
    8.98      block_count *= xvdd->bytes_per_sector / 512;
    8.99      sector_number = decode_cdb_sector(srb);
   8.100      sector_number *= xvdd->bytes_per_sector / 512;
   8.101  
   8.102 -    //if (dump_mode) KdPrint((__DRIVER_NAME "     sector_number = %I64d, block_count = %d, bytes_per_sector = %d, DataTransferLength = %d\n", sector_number, block_count, xvdd->bytes_per_sector, srb->DataTransferLength));
   8.103      ASSERT(block_count * xvdd->bytes_per_sector == srb->DataTransferLength);
   8.104      
   8.105 +    //KdPrint((__DRIVER_NAME "     srb sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
   8.106 +    
   8.107 +    sector_number += srb_entry->offset / 512;
   8.108 +    block_count -= srb_entry->offset / 512;
   8.109 +
   8.110      /* look for pending writes that overlap this one */
   8.111      /* we get warnings from drbd if we don't */
   8.112 -    for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
   8.113 +    if (srb_entry->offset == 0)
   8.114      {
   8.115 -      PSCSI_REQUEST_BLOCK srb2;
   8.116 -      ULONGLONG sector_number2;
   8.117 -      ULONG block_count2;
   8.118 -      
   8.119 -      srb2 = xvdd->shadows[i].srb;
   8.120 -      if (!srb2)
   8.121 -        continue;
   8.122 -      if (decode_cdb_is_read(srb2))
   8.123 -        continue;
   8.124 -      block_count2 = decode_cdb_length(srb2);;
   8.125 -      block_count2 *= xvdd->bytes_per_sector / 512;
   8.126 -      sector_number2 = decode_cdb_sector(srb2);
   8.127 -      sector_number2 *= xvdd->bytes_per_sector / 512;
   8.128 -      
   8.129 -      if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
   8.130 -        continue;
   8.131 -      if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
   8.132 -        continue;
   8.133 +      for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
   8.134 +      {
   8.135 +        PSCSI_REQUEST_BLOCK srb2;
   8.136 +        ULONGLONG sector_number2;
   8.137 +        ULONG block_count2;
   8.138 +        
   8.139 +        srb2 = xvdd->shadows[i].srb;
   8.140 +        if (!srb2)
   8.141 +          continue;
   8.142 +        if (decode_cdb_is_read(srb2))
   8.143 +          continue;
   8.144 +        block_count2 = decode_cdb_length(srb2);;
   8.145 +        block_count2 *= xvdd->bytes_per_sector / 512;
   8.146 +        sector_number2 = decode_cdb_sector(srb2);
   8.147 +        sector_number2 *= xvdd->bytes_per_sector / 512;
   8.148 +        
   8.149 +        if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
   8.150 +          continue;
   8.151 +        if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
   8.152 +          continue;
   8.153  
   8.154 -      KdPrint((__DRIVER_NAME "     Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
   8.155 -        sector_number, block_count, sector_number2, block_count2));
   8.156 -      /* put the srb back at the start of the queue */
   8.157 -      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
   8.158 -      return; /* stall the queue */
   8.159 +        KdPrint((__DRIVER_NAME "     Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
   8.160 +          sector_number, block_count, sector_number2, block_count2));
   8.161 +        /* put the srb back at the start of the queue */
   8.162 +        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
   8.163 +        break; /* stall the queue */
   8.164 +      }
   8.165 +      if (i != MAX_SHADOW_ENTRIES)
   8.166 +      {
   8.167 +        break; /* stall the queue but submit any outstanding requests */
   8.168 +      }
   8.169      }
   8.170 -
   8.171 -    remaining = block_count * 512;
   8.172 +    
   8.173      shadow = get_shadow_from_freelist(xvdd);
   8.174      if (!shadow)
   8.175      {
   8.176        /* put the srb back at the start of the queue */
   8.177        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
   8.178 -      return; /* stall the queue */
   8.179 +      break; /* stall the queue but submit any outstanding requests */
   8.180      }
   8.181      ASSERT(!shadow->aligned_buffer_in_use);
   8.182      ASSERT(!shadow->srb);
   8.183 @@ -516,6 +545,7 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
   8.184      shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
   8.185      shadow->req.nr_segments = 0;
   8.186      shadow->srb = srb;
   8.187 +    shadow->length = 0;
   8.188      shadow->system_address = system_address;
   8.189  
   8.190      if (!dump_mode)
   8.191 @@ -523,68 +553,58 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
   8.192        if ((ULONG_PTR)shadow->system_address & 511)
   8.193        {
   8.194          xvdd->aligned_buffer_in_use = TRUE;
   8.195 -        ptr = xvdd->aligned_buffer;
   8.196 +        ptr = (PUCHAR)xvdd->aligned_buffer;
   8.197          if (!decode_cdb_is_read(srb))
   8.198            memcpy(ptr, shadow->system_address, block_count * 512);
   8.199          shadow->aligned_buffer_in_use = TRUE;
   8.200 +        /* limit to aligned_buffer_size */
   8.201 +        block_count = min(block_count, xvdd->aligned_buffer_size / 512);
   8.202        }
   8.203        else
   8.204        {
   8.205 -        ptr = shadow->system_address;
   8.206 +        ptr = (PUCHAR)shadow->system_address;
   8.207          shadow->aligned_buffer_in_use = FALSE;
   8.208        }
   8.209      }
   8.210      else
   8.211      {
   8.212        ASSERT(!((ULONG_PTR)shadow->system_address & 511));
   8.213 -      ptr = srb->DataBuffer;
   8.214 +      ptr = shadow->system_address;
   8.215        shadow->aligned_buffer_in_use = FALSE;
   8.216 -      if (block_count > max_dump_mode_blocks)
   8.217 -      {
   8.218 -        max_dump_mode_blocks = block_count;
   8.219 -        KdPrint((__DRIVER_NAME "     max_dump_mode_blocks = %d\n", max_dump_mode_blocks));
   8.220 -      }
   8.221 -      if (srb->DataTransferLength > max_dump_mode_length)
   8.222 -      {
   8.223 -        max_dump_mode_length = srb->DataTransferLength;
   8.224 -        KdPrint((__DRIVER_NAME "     max_dump_mode_length = %d\n", max_dump_mode_length));
   8.225 -      }
   8.226      }
   8.227  
   8.228 -    //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
   8.229 +    //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
   8.230      //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
   8.231      //KdPrint((__DRIVER_NAME "     system_address   = %p\n", shadow->system_address));
   8.232 +    //KdPrint((__DRIVER_NAME "     offset   = %d, length = %d\n", srb_entry->offset, srb_entry->length));
   8.233 +    //KdPrint((__DRIVER_NAME "     ptr   = %p\n", ptr));
   8.234  
   8.235      //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
   8.236      //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
   8.237      
   8.238 -    while (remaining > 0)
   8.239 +    remaining = block_count * 512;
   8.240 +    while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
   8.241      {
   8.242        PHYSICAL_ADDRESS physical_address;
   8.243  
   8.244        if (!dump_mode)
   8.245        {
   8.246          physical_address = MmGetPhysicalAddress(ptr);
   8.247 -        gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
   8.248 -                 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XVBD');
   8.249        }
   8.250        else
   8.251        {
   8.252          ULONG length;       
   8.253 -        physical_address.QuadPart = 0;
   8.254          physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
   8.255 -        //KdPrint((__DRIVER_NAME "     pfn = %08x, length = %d\n", (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), length));
   8.256 -        gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
   8.257 -                 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE,
   8.258 -                 xvdd->dump_grant_refs[shadow->req.nr_segments], (ULONG)'XPDO');
   8.259        }
   8.260 +      gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
   8.261 +             (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
   8.262        if (gref == INVALID_GRANT_REF)
   8.263        {
   8.264          ULONG i;
   8.265          for (i = 0; i < shadow->req.nr_segments; i++)
   8.266          {
   8.267            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
   8.268 -            shadow->req.seg[i].gref, FALSE, (ULONG)'XVBD');
   8.269 +            shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
   8.270          }
   8.271          if (shadow->aligned_buffer_in_use)
   8.272          {
   8.273 @@ -595,7 +615,7 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
   8.274          InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
   8.275          put_shadow_on_freelist(xvdd, shadow);
   8.276          KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
   8.277 -        return;
   8.278 +        break; /* stall the queue but submit any outstanding requests */
   8.279        }
   8.280        offset = physical_address.LowPart & (PAGE_SIZE - 1);
   8.281        length = min(PAGE_SIZE - offset, remaining);
   8.282 @@ -605,27 +625,37 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
   8.283        ASSERT((length & 511) == 0);
   8.284        ASSERT(offset + length <= PAGE_SIZE);
   8.285        shadow->req.seg[shadow->req.nr_segments].gref = gref;
   8.286 -      shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
   8.287 -      shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
   8.288 +      shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
   8.289 +      shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
   8.290        //if (dump_mode) KdPrint((__DRIVER_NAME "     gref = %d\n", shadow->req.seg[shadow->req.nr_segments].gref));
   8.291        //if (dump_mode) KdPrint((__DRIVER_NAME "     first_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].first_sect));
   8.292        //if (dump_mode) KdPrint((__DRIVER_NAME "     last_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].last_sect));
   8.293        remaining -= length;
   8.294        ptr += length;
   8.295 +      shadow->length += length;
   8.296        shadow->req.nr_segments++;
   8.297      }
   8.298 -
   8.299 -    //KdPrint((__DRIVER_NAME "     nr_segments = %d\n", shadow->req.nr_segments));
   8.300 +    srb_entry->offset += shadow->length;
   8.301 +    srb_entry->outstanding_requests++;
   8.302 +    //KdPrint((__DRIVER_NAME "     outstanding_requests   = %p\n", srb_entry->outstanding_requests));
   8.303 +    //KdPrint((__DRIVER_NAME "     offset   = %d, length = %d\n", srb_entry->offset, srb_entry->length));
   8.304 +    //KdPrint((__DRIVER_NAME "     ptr   = %p\n", ptr));
   8.305 +    if (srb_entry->offset < srb_entry->length)
   8.306 +    {
   8.307 +      if (dump_mode) KdPrint((__DRIVER_NAME "     inserting back into list\n"));
   8.308 +      /* put the srb back at the start of the queue to continue on the next request */
   8.309 +      InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
   8.310 +    }
   8.311  
   8.312      XenVbd_PutRequest(xvdd, &shadow->req);
   8.313 -
   8.314 -    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   8.315 -    if (notify)
   8.316 -    {
   8.317 -      //KdPrint((__DRIVER_NAME "     Notifying\n"));
   8.318 -      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   8.319 -    }
   8.320    }
   8.321 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   8.322 +  if (notify)
   8.323 +  {
   8.324 +    //KdPrint((__DRIVER_NAME "     Notifying\n"));
   8.325 +    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   8.326 +  }
   8.327 +    
   8.328    //if (dump_mode) FUNCTION_EXIT();
   8.329  }
   8.330  
   8.331 @@ -683,12 +713,15 @@ XenVbd_VirtualHwStorFindAdapter(PVOID De
   8.332        FUNCTION_EXIT();
   8.333        return status;
   8.334      }
   8.335 +    xvdd->grant_tag = (ULONG)'VBD0';
   8.336    }
   8.337    else
   8.338    {
   8.339      xvdd->device_base = ConfigInfo->Reserved;
   8.340 +    xvdd->grant_tag = (ULONG)'DUMP';
   8.341    }
   8.342    
   8.343 +  xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
   8.344    status = XenVbd_InitFromConfig(xvdd);
   8.345    if (status != SP_RETURN_FOUND)
   8.346    {
   8.347 @@ -702,17 +735,19 @@ XenVbd_VirtualHwStorFindAdapter(PVOID De
   8.348    KdPrint((__DRIVER_NAME "     aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
   8.349    KdPrint((__DRIVER_NAME "     aligned_buffer = %p\n", xvdd->aligned_buffer));
   8.350  
   8.351 -  ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
   8.352 -  ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
   8.353 +  ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
   8.354 +  ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
   8.355    KdPrint((__DRIVER_NAME "     ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength));
   8.356    KdPrint((__DRIVER_NAME "     ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
   8.357    if (!dump_mode)
   8.358    {
   8.359      ConfigInfo->VirtualDevice = TRUE;
   8.360 +    xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
   8.361    }
   8.362    else
   8.363    {
   8.364      ConfigInfo->VirtualDevice = FALSE;
   8.365 +    xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
   8.366    }
   8.367    
   8.368    KdPrint((__DRIVER_NAME "     ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice));
   8.369 @@ -1007,10 +1042,11 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   8.370    RING_IDX i, rp;
   8.371    ULONG j;
   8.372    blkif_response_t *rep;
   8.373 -  int block_count;
   8.374 +  //int block_count;
   8.375    int more_to_do = TRUE;
   8.376    blkif_shadow_t *shadow;
   8.377    ULONG suspend_resume_state_pdo;
   8.378 +  srb_list_entry_t *srb_entry;
   8.379  
   8.380    UNREFERENCED_PARAMETER(context);
   8.381    
   8.382 @@ -1036,6 +1072,7 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   8.383        case SR_STATE_RUNNING:
   8.384          KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
   8.385          xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
   8.386 +        xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED; /* could be running on different hardware */
   8.387          xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
   8.388        default:
   8.389          KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
   8.390 @@ -1097,10 +1134,11 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   8.391        case RING_DETECT_STATE_COMPLETE:
   8.392          shadow = &xvdd->shadows[rep->id];
   8.393          srb = shadow->srb;
   8.394 -        //KdPrint((__DRIVER_NAME "     srb = %p\n", srb));
   8.395 -        ASSERT(srb != NULL);
   8.396 -        block_count = decode_cdb_length(srb);
   8.397 -        block_count *= xvdd->bytes_per_sector / 512;
   8.398 +        ASSERT(srb);
   8.399 +        srb_entry = srb->SrbExtension;
   8.400 +        ASSERT(srb_entry);
   8.401 +        //block_count = decode_cdb_length(srb);
   8.402 +        //block_count *= xvdd->bytes_per_sector / 512;
   8.403          /* a few errors occur in dump mode because Xen refuses to allow us to map pages we are using for other stuff. Just ignore them */
   8.404          if (rep->status == BLKIF_RSP_OKAY || (dump_mode &&  dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
   8.405            srb->SrbStatus = SRB_STATUS_SUCCESS;
   8.406 @@ -1113,7 +1151,7 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   8.407              KdPrint((__DRIVER_NAME "     Operation = Write\n"));
   8.408            if (!dump_mode)
   8.409            {
   8.410 -            KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", (ULONG)shadow->req.sector_number, block_count));
   8.411 +            KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", (ULONG)shadow->req.sector_number, shadow->length / 512));
   8.412              KdPrint((__DRIVER_NAME "     DataBuffer = %p\n", srb->DataBuffer));
   8.413              KdPrint((__DRIVER_NAME "     Physical = %08x%08x\n", MmGetPhysicalAddress(shadow->system_address).HighPart, MmGetPhysicalAddress(shadow->system_address).LowPart));
   8.414              KdPrint((__DRIVER_NAME "     PFN = %08x\n", (ULONG)(MmGetPhysicalAddress(shadow->system_address).QuadPart >> PAGE_SHIFT)));
   8.415 @@ -1125,38 +1163,38 @@ XenVbd_HandleEventSynchronised(PVOID Dev
   8.416                KdPrint((__DRIVER_NAME "     last_sect = %d\n", shadow->req.seg[j].last_sect));
   8.417              }
   8.418            }
   8.419 -          srb->SrbStatus = SRB_STATUS_ERROR;
   8.420 -          srb->ScsiStatus = 0x02;
   8.421 -          xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
   8.422 -          xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
   8.423 -          XenVbd_MakeAutoSense(xvdd, srb);
   8.424 +          srb_entry->error = TRUE;
   8.425          }
   8.426          if (shadow->aligned_buffer_in_use)
   8.427          {
   8.428            ASSERT(xvdd->aligned_buffer_in_use);
   8.429            xvdd->aligned_buffer_in_use = FALSE;
   8.430            if (decode_cdb_is_read(srb))
   8.431 -            memcpy(shadow->system_address, xvdd->aligned_buffer, block_count * 512);
   8.432 +            memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
   8.433          }
   8.434          
   8.435          for (j = 0; j < shadow->req.nr_segments; j++)
   8.436          {
   8.437 -          if (dump_mode)
   8.438 -          {
   8.439 -            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
   8.440 -              shadow->req.seg[j].gref, TRUE, (ULONG)'XPDO');
   8.441 -          }
   8.442 -          else
   8.443 -          {
   8.444 -            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
   8.445 -              shadow->req.seg[j].gref, FALSE, (ULONG)'XVBD');
   8.446 -          }
   8.447 +          xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
   8.448 +            shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
   8.449          }
   8.450          shadow->aligned_buffer_in_use = FALSE;
   8.451          shadow->srb = NULL;
   8.452          put_shadow_on_freelist(xvdd, shadow);
   8.453          //if (dump_mode) KdPrint((__DRIVER_NAME "     srb = %p\n", srb));
   8.454 -        StorPortNotification(RequestComplete, xvdd, srb);
   8.455 +        srb_entry->outstanding_requests--;
   8.456 +        if (!srb_entry->outstanding_requests && srb_entry->offset == srb_entry->length)
   8.457 +        {
   8.458 +          if (srb_entry->error)
   8.459 +          {
   8.460 +            srb->SrbStatus = SRB_STATUS_ERROR;
   8.461 +            srb->ScsiStatus = 0x02;
   8.462 +            xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
   8.463 +            xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
   8.464 +            XenVbd_MakeAutoSense(xvdd, srb);
   8.465 +          }        
   8.466 +          StorPortNotification(RequestComplete, xvdd, srb);
   8.467 +        }
   8.468          break;
   8.469        }
   8.470      }
   8.471 @@ -1224,6 +1262,7 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
   8.472  {
   8.473    PUCHAR data_buffer;
   8.474    PSCSI_PNP_REQUEST_BLOCK sprb;
   8.475 +  PSCSI_POWER_REQUEST_BLOCK spwrb;
   8.476    PMINIPORT_DUMP_POINTERS dump_pointers;
   8.477    PCDB cdb;
   8.478    PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
   8.479 @@ -1653,10 +1692,46 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
   8.480      srb->SrbStatus = SRB_STATUS_SUCCESS;
   8.481      StorPortNotification(RequestComplete, DeviceExtension, srb);
   8.482      break;
   8.483 +    
   8.484 +  case SRB_FUNCTION_POWER:
   8.485 +    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_POWER\n"));
   8.486 +    spwrb = (PSCSI_POWER_REQUEST_BLOCK)srb;
   8.487 +    switch (spwrb->PowerAction)
   8.488 +    {
   8.489 +    case StorPowerActionNone:
   8.490 +      KdPrint((__DRIVER_NAME "      StorPowerActionNone\n"));
   8.491 +      break;
   8.492 +    case StorPowerActionReserved:
   8.493 +      KdPrint((__DRIVER_NAME "      StorPowerActionReserved\n"));
   8.494 +      break;
   8.495 +    case StorPowerActionSleep:
   8.496 +      KdPrint((__DRIVER_NAME "      StorPowerActionSleep\n"));
   8.497 +      break;
   8.498 +    case StorPowerActionHibernate:
   8.499 +      KdPrint((__DRIVER_NAME "      StorPowerActionHibernate\n"));
   8.500 +      break;
   8.501 +    case StorPowerActionShutdown:
   8.502 +      KdPrint((__DRIVER_NAME "      StorPowerActionShutdown\n"));
   8.503 +      break;
   8.504 +    case StorPowerActionShutdownReset:
   8.505 +      KdPrint((__DRIVER_NAME "      StorPowerActionShutdownReset\n"));
   8.506 +      break;
   8.507 +    case StorPowerActionShutdownOff:
   8.508 +      KdPrint((__DRIVER_NAME "      StorPowerActionShutdownOff\n"));
   8.509 +      break;
   8.510 +    case StorPowerActionWarmEject:
   8.511 +      KdPrint((__DRIVER_NAME "      StorPowerActionWarmEject\n"));
   8.512 +      break;
   8.513 +    default:
   8.514 +      KdPrint((__DRIVER_NAME "      Stor%d\n", spwrb->PowerAction));
   8.515 +      break;
   8.516 +    }
   8.517 +    XenVbd_PutSrbOnList(xvdd, srb);
   8.518 +    XenVbd_PutQueuedSrbsOnRing(xvdd);
   8.519 +    break;
   8.520    case SRB_FUNCTION_DUMP_POINTERS:
   8.521      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_DUMP_POINTERS\n"));
   8.522      KdPrint((__DRIVER_NAME "     DataTransferLength = %d\n", srb->DataTransferLength));
   8.523 -    //RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
   8.524      dump_pointers = srb->DataBuffer;
   8.525      KdPrint((__DRIVER_NAME "      Version = %d\n", dump_pointers->Version));
   8.526      KdPrint((__DRIVER_NAME "      Size = %d\n", dump_pointers->Size));
   8.527 @@ -1685,8 +1760,8 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
   8.528      dump_pointers->MiniportPrivateDumpData = (PVOID)xvdd->device_base;
   8.529      //dump_pointers->SystemIoBusNumber = 0;
   8.530      dump_pointers->AdapterInterfaceType = Internal;
   8.531 -    dump_pointers->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
   8.532 -    dump_pointers->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
   8.533 +    dump_pointers->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
   8.534 +    dump_pointers->NumberOfPhysicalBreaks = dump_pointers->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
   8.535      dump_pointers->AlignmentMask = 0;
   8.536      dump_pointers->NumberOfAccessRanges = 1;
   8.537      dump_pointers->NumberOfBuses = 1;
   8.538 @@ -1696,7 +1771,7 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
   8.539  
   8.540      KdPrint((__DRIVER_NAME "      Version = %d\n", dump_pointers->Version));
   8.541      KdPrint((__DRIVER_NAME "      Size = %d\n", dump_pointers->Size));
   8.542 -    KdPrint((__DRIVER_NAME "      DriverName = %S\n", dump_pointers->DriverName));
   8.543 +    //KdPrint((__DRIVER_NAME "      DriverName = %S\n", dump_pointers->DriverName));
   8.544      KdPrint((__DRIVER_NAME "      AdapterObject = %p\n", dump_pointers->AdapterObject));
   8.545      KdPrint((__DRIVER_NAME "      MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
   8.546      KdPrint((__DRIVER_NAME "      CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
   8.547 @@ -1717,8 +1792,12 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
   8.548      break;
   8.549    case SRB_FUNCTION_SHUTDOWN:
   8.550      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
   8.551 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
   8.552 -    StorPortNotification(RequestComplete, DeviceExtension, srb);
   8.553 +    //ASSERT(IsListEmpty(&xvdd->srb_list));
   8.554 +    //ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
   8.555 +    XenVbd_PutSrbOnList(xvdd, srb);
   8.556 +    XenVbd_PutQueuedSrbsOnRing(xvdd);
   8.557 +    //srb->SrbStatus = SRB_STATUS_SUCCESS;
   8.558 +    //StorPortNotification(RequestComplete, DeviceExtension, srb);
   8.559      break;
   8.560    default:
   8.561      KdPrint((__DRIVER_NAME "     Unhandled srb->Function = %08X\n", srb->Function));
   8.562 @@ -1773,21 +1852,28 @@ XenVbd_HwStorAdapterControl(PVOID Device
   8.563      break;
   8.564    case ScsiStopAdapter:
   8.565      KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
   8.566 -    /* I don't think we actually have to do anything here... xenpci cleans up all the xenbus stuff for us */
   8.567 +    if (xvdd->inactive)
   8.568 +    {
   8.569 +      KdPrint((__DRIVER_NAME "     inactive - nothing to do\n"));
   8.570 +      break;
   8.571 +    }
   8.572 +    ASSERT(IsListEmpty(&xvdd->srb_list));
   8.573 +    ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
   8.574      break;
   8.575    case ScsiRestartAdapter:
   8.576      KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
   8.577 -    if (!xvdd->inactive)
   8.578 +    if (xvdd->inactive)
   8.579      {
   8.580 -/*
   8.581 -      if (XenVbd_InitConfig(xvdd) != SP_RETURN_FOUND)
   8.582 -        KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
   8.583 -*/
   8.584 -      if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND)
   8.585 -        KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
   8.586 -      xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
   8.587 -      //XenVbd_StartRingDetection(xvdd);
   8.588 +      KdPrint((__DRIVER_NAME "     inactive - nothing to do\n"));
   8.589 +      break;
   8.590      }
   8.591 +    /* increase the tag every time we stop/start to track where the gref's came from */
   8.592 +    xvdd->grant_tag++;
   8.593 +    if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND)
   8.594 +      KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
   8.595 +    xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
   8.596 +    
   8.597 +    //XenVbd_StartRingDetection(xvdd);
   8.598      break;
   8.599    case ScsiSetBootConfig:
   8.600      KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
     9.1 --- a/xenvbd/xenvbd_storport.h	Thu Feb 03 14:26:04 2011 +1100
     9.2 +++ b/xenvbd/xenvbd_storport.h	Sat Feb 05 17:32:12 2011 +1100
     9.3 @@ -76,12 +76,18 @@ DEFINE_RING_TYPES(blkif_other, struct bl
     9.4  typedef struct {
     9.5    LIST_ENTRY list_entry;
     9.6    PSCSI_REQUEST_BLOCK srb;
     9.7 +  ULONG length; /* cached srb length */
     9.8 +  ULONG offset; /* current srb offset */
     9.9 +  ULONG outstanding_requests; /* number of requests sent to xen for this srb */
    9.10 +  BOOLEAN error; /* true if any sub requests have returned an error */
    9.11  } srb_list_entry_t;
    9.12  
    9.13  typedef struct {
    9.14    blkif_request_t req;
    9.15 +  srb_list_entry_t *srb_list_entry;
    9.16    PSCSI_REQUEST_BLOCK srb;
    9.17    PVOID system_address;
    9.18 +  ULONG length;
    9.19    BOOLEAN aligned_buffer_in_use;
    9.20  } blkif_shadow_t;
    9.21  
    9.22 @@ -106,6 +112,9 @@ typedef enum {
    9.23  #define RING_DETECT_STATE_DETECT2      2
    9.24  #define RING_DETECT_STATE_COMPLETE     3
    9.25  
    9.26 +/* if this is ever increased to more than 1 then we need a way of tracking it properly */
    9.27 +#define DUMP_MODE_UNALIGNED_PAGES 1 /* only for unaligned buffer use */
    9.28 +
    9.29  struct
    9.30  {
    9.31    BOOLEAN inactive;
    9.32 @@ -114,6 +123,7 @@ struct
    9.33    USHORT shadow_free_list[MAX_SHADOW_ENTRIES];
    9.34    USHORT shadow_free;
    9.35    USHORT shadow_min_free;
    9.36 +  ULONG grant_tag;
    9.37  
    9.38    PUCHAR device_base;
    9.39  
    9.40 @@ -137,8 +147,8 @@ struct
    9.41    XENPCI_VECTORS vectors;
    9.42    PXENPCI_DEVICE_STATE device_state;
    9.43    LIST_ENTRY srb_list;
    9.44 -  grant_ref_t dump_grant_refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    9.45    BOOLEAN aligned_buffer_in_use;
    9.46 +  ULONG aligned_buffer_size;
    9.47    PVOID aligned_buffer;
    9.48  /*  
    9.49    ULONGLONG interrupts;
    9.50 @@ -147,13 +157,12 @@ struct
    9.51    ULONGLONG unaligned_requests;
    9.52    ULONGLONG unaligned_bytes;
    9.53  */
    9.54 -  #define BLKIF_MAX_SEGMENTS_PER_REQUEST_DUMP_MODE 1
    9.55 +  /* this is the size of the buffer to allocate at the end of DeviceExtenstion. It includes an extra PAGE_SIZE-1 bytes to assure that we can always align to PAGE_SIZE */
    9.56    #define UNALIGNED_BUFFER_DATA_SIZE ((BLKIF_MAX_SEGMENTS_PER_REQUEST + 1) * PAGE_SIZE - 1)
    9.57 -  #define UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE ((BLKIF_MAX_SEGMENTS_PER_REQUEST_DUMP_MODE + 1) * PAGE_SIZE - 1)
    9.58 +  #define UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE ((DUMP_MODE_UNALIGNED_PAGES + 1) * PAGE_SIZE - 1)
    9.59    /* this has to be right at the end of DeviceExtension */
    9.60    /* can't allocate too much data in dump mode so size DeviceExtensionSize accordingly */
    9.61    UCHAR aligned_buffer_data[1];
    9.62  } typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
    9.63  
    9.64  #endif
    9.65 -