win-pvdrivers

changeset 781:2b2bf47e8672

implement a queue for srb's. Sometimes we get one when we aren't expecting it...
author James Harper <james.harper@bendigoit.com.au>
date Mon Feb 15 19:46:29 2010 +1100 (2010-02-15)
parents 3da023729e6b
children 6304eb6bb690
files xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/xenvbd/xenvbd.c	Wed Feb 10 10:11:16 2010 +1100
     1.2 +++ b/xenvbd/xenvbd.c	Mon Feb 15 19:46:29 2010 +1100
     1.3 @@ -344,117 +344,131 @@ decode_cdb_is_read(PSCSI_REQUEST_BLOCK s
     1.4  ULONG max_dump_mode_size = 0;
     1.5  
     1.6  static VOID
     1.7 -XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
     1.8 +XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
     1.9  {
    1.10 +  srb_list_entry_t *list_entry = srb->SrbExtension;
    1.11 +  list_entry->srb = srb;
    1.12 +  InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)list_entry);
    1.13 +}
    1.14 +
    1.15 +static VOID
    1.16 +XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVICE_DATA xvdd)
    1.17 +{
    1.18 +  PSCSI_REQUEST_BLOCK srb;
    1.19 +  srb_list_entry_t *srb_entry;
    1.20    ULONG block_count;
    1.21    blkif_shadow_t *shadow;
    1.22    ULONG remaining, offset, length;
    1.23    grant_ref_t gref;
    1.24    PUCHAR ptr;
    1.25    int notify;
    1.26 +  
    1.27  
    1.28    //FUNCTION_ENTER();
    1.29  
    1.30 -  //KdPrint((__DRIVER_NAME "     A StartIo srb = %p\n", srb));
    1.31 -
    1.32 -  /* everything should wait if an aligned buffer is in use */
    1.33 -  ASSERT(!xvdd->aligned_buffer_in_use);
    1.34 -  
    1.35 -  block_count = decode_cdb_length(srb);;
    1.36 -  block_count *= xvdd->bytes_per_sector / 512;
    1.37 -  remaining = block_count * 512;
    1.38 -
    1.39 -  shadow = get_shadow_from_freelist(xvdd);
    1.40 -  ASSERT(shadow);
    1.41 -  shadow->req.sector_number = decode_cdb_sector(srb);
    1.42 -  shadow->req.sector_number *= xvdd->bytes_per_sector / 512;
    1.43 -  shadow->req.handle = 0;
    1.44 -  shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
    1.45 -  shadow->req.nr_segments = 0;
    1.46 -  shadow->srb = srb;
    1.47 -
    1.48 -  if ((ULONG_PTR)srb->DataBuffer & 511)
    1.49 -  {
    1.50 -    xvdd->aligned_buffer_in_use = TRUE;
    1.51 -    ptr = xvdd->aligned_buffer;
    1.52 -    if (!decode_cdb_is_read(srb))
    1.53 -      memcpy(ptr, srb->DataBuffer, block_count * 512);
    1.54 -    shadow->aligned_buffer_in_use = TRUE;
    1.55 -  }
    1.56 -  else
    1.57 -  {
    1.58 -    ptr = srb->DataBuffer;
    1.59 -    shadow->aligned_buffer_in_use = FALSE;
    1.60 -  }
    1.61 -
    1.62 -  if (dump_mode && block_count > max_dump_mode_size)
    1.63 -  {
    1.64 -    max_dump_mode_size = block_count;
    1.65 -    KdPrint((__DRIVER_NAME "     max_dump_mode_size = %d\n", max_dump_mode_size));
    1.66 -  }
    1.67 -
    1.68 -  //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
    1.69 -  //KdPrint((__DRIVER_NAME "     SrbExtension = %p\n", srb->SrbExtension));
    1.70 -  //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
    1.71 +  if (xvdd->aligned_buffer_in_use)
    1.72 +    return;
    1.73  
    1.74 -  //KdPrint((__DRIVER_NAME "     sector_number = %d\n", (ULONG)shadow->req.sector_number));
    1.75 -  //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
    1.76 -  //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
    1.77 -  
    1.78 -  while (remaining > 0)
    1.79 +  while(xvdd->shadow_free && (srb_entry = (srb_list_entry_t *)RemoveHeadList(&xvdd->srb_list)) != (srb_list_entry_t *)&xvdd->srb_list)
    1.80    {
    1.81 -    PHYSICAL_ADDRESS physical_address = MmGetPhysicalAddress(ptr);
    1.82 +    srb = srb_entry->srb;
    1.83 +    block_count = decode_cdb_length(srb);;
    1.84 +    block_count *= xvdd->bytes_per_sector / 512;
    1.85 +    remaining = block_count * 512;
    1.86 +
    1.87 +    shadow = get_shadow_from_freelist(xvdd);
    1.88 +    ASSERT(shadow);
    1.89 +    ASSERT(!shadow->aligned_buffer_in_use);
    1.90 +    ASSERT(!shadow->srb);
    1.91 +    shadow->req.sector_number = decode_cdb_sector(srb);
    1.92 +    shadow->req.sector_number *= xvdd->bytes_per_sector / 512;
    1.93 +    shadow->req.handle = 0;
    1.94 +    shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
    1.95 +    shadow->req.nr_segments = 0;
    1.96 +    shadow->srb = srb;
    1.97 +
    1.98 +    if ((ULONG_PTR)srb->DataBuffer & 511)
    1.99 +    {
   1.100 +      xvdd->aligned_buffer_in_use = TRUE;
   1.101 +      ptr = xvdd->aligned_buffer;
   1.102 +      if (!decode_cdb_is_read(srb))
   1.103 +        memcpy(ptr, srb->DataBuffer, block_count * 512);
   1.104 +      shadow->aligned_buffer_in_use = TRUE;
   1.105 +    }
   1.106 +    else
   1.107 +    {
   1.108 +      ptr = srb->DataBuffer;
   1.109 +      shadow->aligned_buffer_in_use = FALSE;
   1.110 +    }
   1.111 +
   1.112 +    if (dump_mode && block_count > max_dump_mode_size)
   1.113 +    {
   1.114 +      max_dump_mode_size = block_count;
   1.115 +      KdPrint((__DRIVER_NAME "     max_dump_mode_size = %d\n", max_dump_mode_size));
   1.116 +    }
   1.117 +
   1.118 +    //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
   1.119 +    //KdPrint((__DRIVER_NAME "     SrbExtension = %p\n", srb->SrbExtension));
   1.120 +    //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
   1.121 +
   1.122 +    //KdPrint((__DRIVER_NAME "     sector_number = %d\n", (ULONG)shadow->req.sector_number));
   1.123 +    //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
   1.124 +    //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
   1.125      
   1.126 -    gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
   1.127 -              (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF);
   1.128 -    if (gref == INVALID_GRANT_REF)
   1.129 +    while (remaining > 0)
   1.130      {
   1.131 -      ULONG i;
   1.132 -      for (i = 0; i < shadow->req.nr_segments; i++)
   1.133 +      PHYSICAL_ADDRESS physical_address = MmGetPhysicalAddress(ptr);
   1.134 +      
   1.135 +      gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
   1.136 +                (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF);
   1.137 +      if (gref == INVALID_GRANT_REF)
   1.138        {
   1.139 -        xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
   1.140 -          shadow->req.seg[i].gref, FALSE);
   1.141 -      }
   1.142 -      if (shadow->aligned_buffer_in_use)
   1.143 -      {
   1.144 -        shadow->aligned_buffer_in_use = FALSE;
   1.145 -        xvdd->aligned_buffer_in_use = FALSE;
   1.146 +        ULONG i;
   1.147 +        for (i = 0; i < shadow->req.nr_segments; i++)
   1.148 +        {
   1.149 +          xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
   1.150 +            shadow->req.seg[i].gref, FALSE);
   1.151 +        }
   1.152 +        if (shadow->aligned_buffer_in_use)
   1.153 +        {
   1.154 +          shadow->aligned_buffer_in_use = FALSE;
   1.155 +          xvdd->aligned_buffer_in_use = FALSE;
   1.156 +        }
   1.157 +        /* put the srb back at the start of the queue */
   1.158 +        InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
   1.159 +        put_shadow_on_freelist(xvdd, shadow);
   1.160 +        KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
   1.161 +        return;
   1.162        }
   1.163 -      srb->SrbStatus = SRB_STATUS_BUSY;
   1.164 -      ScsiPortNotification(RequestComplete, xvdd, srb);
   1.165 -      KdPrint((__DRIVER_NAME "     Out of gref's. Deferring\n"));
   1.166 -      return;
   1.167 +      offset = physical_address.LowPart & (PAGE_SIZE - 1);
   1.168 +      length = min(PAGE_SIZE - offset, remaining);
   1.169 +      ASSERT((offset & 511) == 0);
   1.170 +      ASSERT((length & 511) == 0);
   1.171 +      ASSERT(offset + length <= PAGE_SIZE);
   1.172 +      shadow->req.seg[shadow->req.nr_segments].gref = gref;
   1.173 +      shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
   1.174 +      shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
   1.175 +      remaining -= length;
   1.176 +      ptr += length;
   1.177 +      shadow->req.nr_segments++;
   1.178      }
   1.179 -    offset = physical_address.LowPart & (PAGE_SIZE - 1);
   1.180 -    length = min(PAGE_SIZE - offset, remaining);
   1.181 -    ASSERT((offset & 511) == 0);
   1.182 -    ASSERT((length & 511) == 0);
   1.183 -    ASSERT(offset + length <= PAGE_SIZE);
   1.184 -    shadow->req.seg[shadow->req.nr_segments].gref = gref;
   1.185 -    shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
   1.186 -    shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
   1.187 -    remaining -= length;
   1.188 -    ptr += length;
   1.189 -    shadow->req.nr_segments++;
   1.190 +
   1.191 +    //KdPrint((__DRIVER_NAME "     nr_segments = %d\n", shadow->req.nr_segments));
   1.192 +
   1.193 +    XenVbd_PutRequest(xvdd, &shadow->req);
   1.194 +
   1.195 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   1.196 +    if (notify)
   1.197 +    {
   1.198 +      //KdPrint((__DRIVER_NAME "     Notifying\n"));
   1.199 +      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   1.200 +    }
   1.201 +
   1.202    }
   1.203 -
   1.204 -  //KdPrint((__DRIVER_NAME "     nr_segments = %d\n", shadow->req.nr_segments));
   1.205 -
   1.206 -  XenVbd_PutRequest(xvdd, &shadow->req);
   1.207 -
   1.208 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   1.209 -  if (notify)
   1.210 -  {
   1.211 -    //KdPrint((__DRIVER_NAME "     Notifying\n"));
   1.212 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   1.213 -  }
   1.214 -
   1.215    if (xvdd->shadow_free && !xvdd->aligned_buffer_in_use)
   1.216    {
   1.217 -    //KdPrint((__DRIVER_NAME "     A NextLuRequest\n"));
   1.218      ScsiPortNotification(NextLuRequest, xvdd, 0, 0, 0);
   1.219    }
   1.220 -
   1.221    //FUNCTION_EXIT();
   1.222  }
   1.223  
   1.224 @@ -523,6 +537,7 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
   1.225    }
   1.226  
   1.227    xvdd->aligned_buffer_in_use = FALSE;
   1.228 +  /* align the buffer to PAGE_SIZE */
   1.229    xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
   1.230    KdPrint((__DRIVER_NAME "     aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
   1.231    KdPrint((__DRIVER_NAME "     aligned_buffer = %p\n", xvdd->aligned_buffer));
   1.232 @@ -614,6 +629,7 @@ XenVbd_HwScsiInitialize(PVOID DeviceExte
   1.233        }
   1.234        xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
   1.235      }
   1.236 +    InitializeListHead(&xvdd->srb_list);
   1.237    }
   1.238    FUNCTION_EXIT();
   1.239  
   1.240 @@ -807,7 +823,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   1.241          KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
   1.242          xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
   1.243          xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
   1.244 -        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.245 +        ScsiPortNotification(NextRequest, DeviceExtension);
   1.246        default:
   1.247          KdPrint((__DRIVER_NAME "     New pdo state %d\n", suspend_resume_state_pdo));
   1.248          xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
   1.249 @@ -905,20 +921,25 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   1.250            xvdd->aligned_buffer_in_use = FALSE;
   1.251            if (decode_cdb_is_read(srb))
   1.252              memcpy(srb->DataBuffer, xvdd->aligned_buffer, block_count * 512);
   1.253 +//KdPrint((__DRIVER_NAME "     Completed use of buffer\n"));
   1.254          }
   1.255 +        
   1.256 +#if 0
   1.257 +if (xvdd->aligned_buffer_in_use)
   1.258 +{
   1.259 +KdPrint((__DRIVER_NAME "     Completed request while aligned buffer in use\n"));
   1.260 +}
   1.261 +#endif
   1.262          for (j = 0; j < shadow->req.nr_segments; j++)
   1.263          {
   1.264            xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
   1.265              shadow->req.seg[j].gref, FALSE);
   1.266          }
   1.267 +        shadow->aligned_buffer_in_use = FALSE;
   1.268 +        shadow->srb = NULL;
   1.269          put_shadow_on_freelist(xvdd, shadow);
   1.270          //KdPrint((__DRIVER_NAME "     B RequestComplete srb = %p\n", srb));
   1.271          ScsiPortNotification(RequestComplete, xvdd, srb);
   1.272 -        if (!xvdd->aligned_buffer_in_use && suspend_resume_state_pdo == SR_STATE_RUNNING)
   1.273 -        {
   1.274 -          //KdPrint((__DRIVER_NAME "     B NextLuRequest\n"));
   1.275 -          ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.276 -        }
   1.277          break;
   1.278        }
   1.279      }
   1.280 @@ -935,6 +956,8 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   1.281      }
   1.282    }
   1.283  
   1.284 +  XenVbd_PutQueuedSrbsOnRing(xvdd);
   1.285 +
   1.286    if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
   1.287    {
   1.288      if (xvdd->inactive || xvdd->shadow_free == SHADOW_ENTRIES)
   1.289 @@ -960,6 +983,12 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   1.290    PCDB cdb;
   1.291    PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
   1.292  
   1.293 +
   1.294 +if (xvdd->aligned_buffer_in_use)
   1.295 +{
   1.296 +  KdPrint((__DRIVER_NAME "     New request while aligned buffer in use - Function = %x, next_request = %d\n", srb->Function, xvdd->next_request));
   1.297 +}
   1.298 +
   1.299    if (xvdd->inactive)
   1.300    {
   1.301      KdPrint((__DRIVER_NAME "     Inactive srb->Function = %08X\n", srb->Function));
   1.302 @@ -1001,6 +1030,11 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   1.303    case SRB_FUNCTION_EXECUTE_SCSI:
   1.304      cdb = (PCDB)srb->Cdb;
   1.305  
   1.306 +if (xvdd->aligned_buffer_in_use)
   1.307 +{
   1.308 +  KdPrint((__DRIVER_NAME "     New request while aligned buffer in use - OP = %x, next_request = %d\n", cdb->CDB6GENERIC.OperationCode, xvdd->next_request));
   1.309 +}
   1.310 +
   1.311      switch(cdb->CDB6GENERIC.OperationCode)
   1.312      {
   1.313      case SCSIOP_TEST_UNIT_READY:
   1.314 @@ -1183,9 +1217,8 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   1.315      case SCSIOP_READ16:
   1.316      case SCSIOP_WRITE:
   1.317      case SCSIOP_WRITE16:
   1.318 -      //if (dump_mode)
   1.319 -      //  KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
   1.320 -      XenVbd_PutSrbOnRing(xvdd, srb);
   1.321 +      XenVbd_PutSrbOnList(xvdd, srb);
   1.322 +      XenVbd_PutQueuedSrbsOnRing(xvdd);
   1.323        break;
   1.324      case SCSIOP_VERIFY:
   1.325      case SCSIOP_VERIFY16:
   1.326 @@ -1279,7 +1312,9 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   1.327        XenVbd_MakeAutoSense(xvdd, srb);
   1.328        ScsiPortNotification(RequestComplete, DeviceExtension, srb);
   1.329        if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
   1.330 -        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.331 +      {
   1.332 +        ScsiPortNotification(NextRequest, DeviceExtension);
   1.333 +      }
   1.334      }
   1.335      else if (srb->SrbStatus != SRB_STATUS_PENDING)
   1.336      {
   1.337 @@ -1287,7 +1322,9 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   1.338        xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
   1.339        ScsiPortNotification(RequestComplete, DeviceExtension, srb);
   1.340        if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
   1.341 -        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.342 +      {
   1.343 +        ScsiPortNotification(NextRequest, DeviceExtension);
   1.344 +      }
   1.345      }
   1.346      break;
   1.347    case SRB_FUNCTION_IO_CONTROL:
   1.348 @@ -1295,28 +1332,36 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   1.349      srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   1.350      ScsiPortNotification(RequestComplete, DeviceExtension, srb);
   1.351      if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
   1.352 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.353 +    {
   1.354 +      ScsiPortNotification(NextRequest, DeviceExtension);
   1.355 +    }
   1.356      break;
   1.357    case SRB_FUNCTION_FLUSH:
   1.358      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
   1.359      srb->SrbStatus = SRB_STATUS_SUCCESS;
   1.360      ScsiPortNotification(RequestComplete, DeviceExtension, srb);
   1.361      if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
   1.362 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.363 +    {
   1.364 +      ScsiPortNotification(NextRequest, DeviceExtension);
   1.365 +    }
   1.366      break;
   1.367    case SRB_FUNCTION_SHUTDOWN:
   1.368      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
   1.369      srb->SrbStatus = SRB_STATUS_SUCCESS;
   1.370      ScsiPortNotification(RequestComplete, DeviceExtension, srb);
   1.371      if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
   1.372 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.373 +    {
   1.374 +      ScsiPortNotification(NextRequest, DeviceExtension);
   1.375 +    }
   1.376      break;
   1.377    default:
   1.378      KdPrint((__DRIVER_NAME "     Unhandled srb->Function = %08X\n", srb->Function));
   1.379      srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   1.380      ScsiPortNotification(RequestComplete, DeviceExtension, srb);
   1.381      if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
   1.382 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.383 +    {
   1.384 +      ScsiPortNotification(NextRequest, DeviceExtension);
   1.385 +    }
   1.386      break;
   1.387    }
   1.388  
   1.389 @@ -1508,7 +1553,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.390    HwInitializationData.AdapterInterfaceType = PNPBus;
   1.391    HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_DATA);
   1.392    HwInitializationData.SpecificLuExtensionSize = 0;
   1.393 -  HwInitializationData.SrbExtensionSize = 0;
   1.394 +  HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
   1.395    HwInitializationData.NumberOfAccessRanges = 1;
   1.396    HwInitializationData.MapBuffers = TRUE;
   1.397    HwInitializationData.NeedPhysicalAddresses = FALSE;
     2.1 --- a/xenvbd/xenvbd.h	Wed Feb 10 10:11:16 2010 +1100
     2.2 +++ b/xenvbd/xenvbd.h	Mon Feb 15 19:46:29 2010 +1100
     2.3 @@ -75,6 +75,11 @@ typedef struct blkif_other_response blki
     2.4  DEFINE_RING_TYPES(blkif_other, struct blkif_other_request, struct blkif_other_response);
     2.5  
     2.6  typedef struct {
     2.7 +  LIST_ENTRY list_entry;
     2.8 +  PSCSI_REQUEST_BLOCK srb;
     2.9 +} srb_list_entry_t;
    2.10 +
    2.11 +typedef struct {
    2.12    blkif_request_t req;
    2.13    PSCSI_REQUEST_BLOCK srb;
    2.14    BOOLEAN aligned_buffer_in_use;
    2.15 @@ -131,7 +136,8 @@ struct
    2.16    ULONGLONG total_sectors;
    2.17    XENPCI_VECTORS vectors;
    2.18    PXENPCI_DEVICE_STATE device_state;
    2.19 -  PSCSI_REQUEST_BLOCK pending_srb;
    2.20 +  LIST_ENTRY srb_list;
    2.21 +  ULONG next_request; // debug - true if nextrequest has been sent
    2.22    //grant_ref_t dump_grant_refs[BLKIF_MAX_SEGMENTS_PER_REQUEST - 1];
    2.23    BOOLEAN aligned_buffer_in_use;
    2.24    PVOID aligned_buffer;