win-pvdrivers

changeset 420:b3f2f9aef0fc

Merged xenvbd.c and scsiport.c
Fixes to make crash dumps work again
author James Harper <james.harper@bendigoit.com.au>
date Thu Aug 21 13:44:24 2008 +1000 (2008-08-21)
parents dcc440136d50
children dcfc2f91a501
files xenvbd/scsiport.c xenvbd/sources xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/xenvbd/scsiport.c	Wed Aug 20 21:36:59 2008 +1000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1215 +0,0 @@
     1.4 -/*
     1.5 -PV Drivers for Windows Xen HVM Domains
     1.6 -Copyright (C) 2007 James Harper
     1.7 -
     1.8 -This program is free software; you can redistribute it and/or
     1.9 -modify it under the terms of the GNU General Public License
    1.10 -as published by the Free Software Foundation; either version 2
    1.11 -of the License, or (at your option) any later version.
    1.12 -
    1.13 -This program is distributed in the hope that it will be useful,
    1.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 -GNU General Public License for more details.
    1.17 -
    1.18 -You should have received a copy of the GNU General Public License
    1.19 -along with this program; if not, write to the Free Software
    1.20 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    1.21 -*/
    1.22 -
    1.23 -#include "xenvbd.h"
    1.24 -#include <io/blkif.h>
    1.25 -#include <scsi.h>
    1.26 -#include <ntddscsi.h>
    1.27 -#include <ntdddisk.h>
    1.28 -#include <stdlib.h>
    1.29 -#include <xen_public.h>
    1.30 -#include <io/xenbus.h>
    1.31 -#include <io/protocols.h>
    1.32 -
    1.33 -#pragma warning(disable: 4127)
    1.34 -
    1.35 -#if defined(__x86_64__)
    1.36 -  #define GET_PAGE_ALIGNED(ptr) ((PVOID)(((ULONGLONG)ptr + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
    1.37 -#else
    1.38 -  #define GET_PAGE_ALIGNED(ptr) UlongToPtr((PtrToUlong(ptr) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
    1.39 -#endif
    1.40 -
    1.41 -static blkif_shadow_t *
    1.42 -get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
    1.43 -{
    1.44 -  if (xvdd->shadow_free == 0)
    1.45 -  {
    1.46 -    KdPrint((__DRIVER_NAME "     No more shadow entries\n"));    
    1.47 -    return NULL;
    1.48 -  }
    1.49 -  xvdd->shadow_free--;
    1.50 -  if (xvdd->shadow_free < xvdd->shadow_min_free)
    1.51 -    xvdd->shadow_min_free = xvdd->shadow_free;
    1.52 -  return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
    1.53 -}
    1.54 -
    1.55 -static VOID
    1.56 -put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
    1.57 -{
    1.58 -  xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)shadow->req.id;
    1.59 -  shadow->srb = NULL;
    1.60 -  xvdd->shadow_free++;
    1.61 -}
    1.62 -
    1.63 -static grant_ref_t
    1.64 -get_grant_from_freelist(PXENVBD_DEVICE_DATA xvdd)
    1.65 -{
    1.66 -  if (xvdd->grant_free == 0)
    1.67 -  {
    1.68 -    KdPrint((__DRIVER_NAME "     No more grant refs\n"));    
    1.69 -    return (grant_ref_t)0x0FFFFFFF;
    1.70 -  }
    1.71 -  xvdd->grant_free--;
    1.72 -  return xvdd->grant_free_list[xvdd->grant_free];
    1.73 -}
    1.74 -
    1.75 -static VOID
    1.76 -put_grant_on_freelist(PXENVBD_DEVICE_DATA xvdd, grant_ref_t grant)
    1.77 -{
    1.78 -  xvdd->grant_free_list[xvdd->grant_free] = grant;
    1.79 -  xvdd->grant_free++;
    1.80 -}
    1.81 -
    1.82 -static blkif_response_t *
    1.83 -XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i)
    1.84 -{
    1.85 -  blkif_other_response_t *rep;
    1.86 -  if (!xvdd->use_other)
    1.87 -    return RING_GET_RESPONSE(&xvdd->ring, i);
    1.88 -  rep = RING_GET_RESPONSE(&xvdd->other_ring, i);
    1.89 -  xvdd->tmp_rep.id = rep->id;
    1.90 -  xvdd->tmp_rep.operation = rep->operation;
    1.91 -  xvdd->tmp_rep.status = rep->status;
    1.92 -  return &xvdd->tmp_rep;
    1.93 -}
    1.94 -
    1.95 -static VOID
    1.96 -XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
    1.97 -{
    1.98 -  blkif_other_request_t *other_req;
    1.99 -
   1.100 -  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
   1.101 -  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
   1.102 -  //KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
   1.103 -  //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
   1.104 -  if (!xvdd->use_other)
   1.105 -  {
   1.106 -    *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
   1.107 -  }
   1.108 -  else
   1.109 -  {  
   1.110 -    other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
   1.111 -    other_req->operation = req->operation;
   1.112 -    other_req->nr_segments = req->nr_segments;
   1.113 -    other_req->handle = req->handle;
   1.114 -    other_req->id = req->id;
   1.115 -    other_req->sector_number = req->sector_number;
   1.116 -    memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
   1.117 -  }
   1.118 -  xvdd->ring.req_prod_pvt++;
   1.119 -  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
   1.120 -  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
   1.121 -  //KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
   1.122 -  //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
   1.123 -}
   1.124 -
   1.125 -static ULONG
   1.126 -XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
   1.127 -{
   1.128 -  ULONG i;
   1.129 -  PUCHAR ptr;
   1.130 -  USHORT type;
   1.131 -  PCHAR setting, value;
   1.132 -
   1.133 -  xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
   1.134 -  xvdd->sring = NULL;
   1.135 -  xvdd->event_channel = 0;
   1.136 -  
   1.137 -  ptr = xvdd->device_base;
   1.138 -  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID) &setting, (PVOID) &value)) != XEN_INIT_TYPE_END)
   1.139 -  {
   1.140 -    switch(type)
   1.141 -    {
   1.142 -    case XEN_INIT_TYPE_RING: /* frontend ring */
   1.143 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
   1.144 -      if (strcmp(setting, "ring-ref") == 0)
   1.145 -      {
   1.146 -        xvdd->sring = (blkif_sring_t *)value;
   1.147 -        FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
   1.148 -        /* this bit is for when we have to take over an existing ring on a bug check */
   1.149 -        xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
   1.150 -        xvdd->ring.rsp_cons = xvdd->sring->rsp_prod;
   1.151 -      }
   1.152 -      break;
   1.153 -    case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
   1.154 -    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */
   1.155 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
   1.156 -      if (strcmp(setting, "event-channel") == 0)
   1.157 -      {
   1.158 -        xvdd->event_channel = PtrToUlong(value);
   1.159 -      }
   1.160 -      break;
   1.161 -    case XEN_INIT_TYPE_READ_STRING_BACK:
   1.162 -    case XEN_INIT_TYPE_READ_STRING_FRONT:
   1.163 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   1.164 -      if (strcmp(setting, "sectors") == 0)
   1.165 -        xvdd->total_sectors = atoi(value);
   1.166 -      else if (strcmp(setting, "sector-size") == 0)
   1.167 -        xvdd->bytes_per_sector = atoi(value);
   1.168 -      else if (strcmp(setting, "device-type") == 0)
   1.169 -      {
   1.170 -        if (strcmp(value, "disk") == 0)
   1.171 -        {
   1.172 -          KdPrint((__DRIVER_NAME "     device-type = Disk\n"));    
   1.173 -          xvdd->device_type = XENVBD_DEVICETYPE_DISK;
   1.174 -        }
   1.175 -        else if (strcmp(value, "cdrom") == 0)
   1.176 -        {
   1.177 -          KdPrint((__DRIVER_NAME "     device-type = CDROM\n"));    
   1.178 -          xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
   1.179 -        }
   1.180 -        else
   1.181 -        {
   1.182 -          KdPrint((__DRIVER_NAME "     device-type = %s (This probably won't work!)\n", value));
   1.183 -          xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
   1.184 -        }
   1.185 -      }
   1.186 -      else if (strcmp(setting, "mode") == 0)
   1.187 -      {
   1.188 -        if (strncmp(value, "r", 1) == 0)
   1.189 -        {
   1.190 -          KdPrint((__DRIVER_NAME "     mode = r\n"));    
   1.191 -          xvdd->device_mode = XENVBD_DEVICEMODE_READ;
   1.192 -        }
   1.193 -        else if (strncmp(value, "w", 1) == 0)
   1.194 -        {
   1.195 -          KdPrint((__DRIVER_NAME "     mode = w\n"));    
   1.196 -          xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
   1.197 -        }
   1.198 -        else
   1.199 -        {
   1.200 -          KdPrint((__DRIVER_NAME "     mode = unknown\n"));
   1.201 -          xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
   1.202 -        }
   1.203 -      }
   1.204 -      break;
   1.205 -    case XEN_INIT_TYPE_VECTORS:
   1.206 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   1.207 -      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   1.208 -        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   1.209 -      {
   1.210 -        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   1.211 -          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   1.212 -        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.213 -        return SP_RETURN_BAD_CONFIG;
   1.214 -      }
   1.215 -      else
   1.216 -        memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
   1.217 -      break;
   1.218 -    case XEN_INIT_TYPE_GRANT_ENTRIES:
   1.219 -      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(setting)));
   1.220 -      xvdd->grant_entries = (USHORT)PtrToUlong(setting);
   1.221 -      memcpy(&xvdd->grant_free_list, value, sizeof(grant_ref_t) * xvdd->grant_entries);
   1.222 -      xvdd->grant_free = xvdd->grant_entries;
   1.223 -      break;
   1.224 -    case XEN_INIT_TYPE_STATE_PTR:
   1.225 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   1.226 -      xvdd->device_state = (PXENPCI_DEVICE_STATE)value;
   1.227 -      break;
   1.228 -    default:
   1.229 -      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   1.230 -      break;
   1.231 -    }
   1.232 -  }
   1.233 -  if (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
   1.234 -    || xvdd->sring == NULL
   1.235 -    || xvdd->event_channel == 0
   1.236 -    || xvdd->total_sectors == 0
   1.237 -    || xvdd->bytes_per_sector == 0)
   1.238 -  {
   1.239 -    KdPrint((__DRIVER_NAME "     Missing settings\n"));
   1.240 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.241 -    return SP_RETURN_BAD_CONFIG;
   1.242 -  }
   1.243 -
   1.244 -  /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
   1.245 -#ifdef __MINGW32__
   1.246 -  /* mingw can't divide, so shift instead (assumes bps is ^2 and at least 512) */
   1.247 -  {
   1.248 -    ULONG num_512_byte_sectors = xvdd->bytes_per_sector / 512;
   1.249 -    ULONG index;
   1.250 -
   1.251 -    bit_scan_forward(&index, num_512_byte_sectors);
   1.252 -    xvdd->total_sectors <<= index-1;
   1.253 -  }
   1.254 -#else
   1.255 -  xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
   1.256 -#endif
   1.257 -
   1.258 -
   1.259 -  xvdd->shadow_free = 0;
   1.260 -  memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
   1.261 -  for (i = 0; i < SHADOW_ENTRIES; i++)
   1.262 -  {
   1.263 -    xvdd->shadows[i].req.id = i;
   1.264 -    put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
   1.265 -  }
   1.266 -  
   1.267 -  return SP_RETURN_FOUND;
   1.268 -}
   1.269 -
   1.270 -static VOID
   1.271 -XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, ULONG srb_offset)
   1.272 -{
   1.273 -  ULONG block_count, transfer_length;
   1.274 -  blkif_shadow_t *shadow;
   1.275 -  PHYSICAL_ADDRESS physical_address;
   1.276 -  ULONG pfn;
   1.277 -  ULONG remaining, offset, length;
   1.278 -  PUCHAR ptr;
   1.279 -  int notify;
   1.280 -
   1.281 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.282 -
   1.283 -  //ASSERT(!(srb_offset == 0 && xvdd->split_request_in_progress));
   1.284 -  block_count = (srb->Cdb[7] << 8) | srb->Cdb[8];
   1.285 -  block_count *= xvdd->bytes_per_sector / 512;
   1.286 -  if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
   1.287 -  {
   1.288 -    ptr = GET_PAGE_ALIGNED(srb->SrbExtension);
   1.289 -    transfer_length = min(block_count * 512 - srb_offset, UNALIGNED_DOUBLE_BUFFER_SIZE);
   1.290 -    if (!srb_offset)
   1.291 -    {
   1.292 -      xvdd->unaligned_requests++;
   1.293 -      xvdd->unaligned_bytes += transfer_length;
   1.294 -    }
   1.295 -  }
   1.296 -  else
   1.297 -  {
   1.298 -    ptr = srb->DataBuffer;
   1.299 -    transfer_length = block_count * 512;
   1.300 -    xvdd->aligned_requests++;
   1.301 -    xvdd->aligned_bytes += transfer_length;
   1.302 -  }
   1.303 -
   1.304 -  if (xvdd->grant_free <= ADDRESS_AND_SIZE_TO_SPAN_PAGES(ptr, transfer_length))
   1.305 -  {
   1.306 -    ASSERT(!xvdd->pending_srb);
   1.307 -    //KdPrint((__DRIVER_NAME "     No enough grants - deferring\n"));
   1.308 -    xvdd->pending_srb = srb;
   1.309 -    xvdd->no_free_grant_requests++;
   1.310 -    return;
   1.311 -  }
   1.312 -  
   1.313 -  shadow = get_shadow_from_freelist(xvdd);
   1.314 -  ASSERT(shadow);
   1.315 -  shadow->req.sector_number = (srb->Cdb[2] << 24) | (srb->Cdb[3] << 16) | (srb->Cdb[4] << 8) | srb->Cdb[5];
   1.316 -  shadow->req.sector_number *= xvdd->bytes_per_sector / 512;
   1.317 -  shadow->req.handle = 0;
   1.318 -  shadow->req.operation = (srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
   1.319 -  shadow->req.nr_segments = 0;
   1.320 -  shadow->offset = srb_offset;
   1.321 -  shadow->length = transfer_length;
   1.322 -  shadow->srb = srb;
   1.323 -
   1.324 -  //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
   1.325 -  //KdPrint((__DRIVER_NAME "     SrbExtension = %p\n", srb->SrbExtension));
   1.326 -  //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
   1.327 -
   1.328 -  if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
   1.329 -  {
   1.330 -    shadow->req.sector_number += srb_offset / 512; //xvdd->bytes_per_sector;
   1.331 -    //KdPrint((__DRIVER_NAME "     Using unaligned buffer - DataBuffer = %p, SrbExtension = %p, total length = %d, offset = %d, length = %d, sector = %d\n", srb->DataBuffer, srb->SrbExtension, block_count * 512, shadow->offset, shadow->length, shadow->req.sector_number));
   1.332 -    if (srb->Cdb[0] == SCSIOP_WRITE)
   1.333 -    {
   1.334 -      memcpy(ptr, ((PUCHAR)srb->DataBuffer) + srb_offset, shadow->length);
   1.335 -    }
   1.336 -  }
   1.337 -  else
   1.338 -  {
   1.339 -    ptr = srb->DataBuffer;
   1.340 -  }
   1.341 -  //KdPrint((__DRIVER_NAME "     sector_number = %d\n", (ULONG)shadow->req.sector_number));
   1.342 -  //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
   1.343 -  //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
   1.344 -    
   1.345 -  remaining = shadow->length;  
   1.346 -  while (remaining > 0)
   1.347 -  {
   1.348 -    physical_address = MmGetPhysicalAddress(ptr);
   1.349 -    pfn = (ULONG)(physical_address.QuadPart >> PAGE_SHIFT);
   1.350 -    shadow->req.seg[shadow->req.nr_segments].gref = get_grant_from_freelist(xvdd);
   1.351 -    ASSERT(shadow->req.seg[shadow->req.nr_segments].gref != INVALID_GRANT_REF);
   1.352 -    xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0, pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref);
   1.353 -    offset = (ULONG)(physical_address.QuadPart & (PAGE_SIZE - 1));
   1.354 -    ASSERT((offset & 511) == 0);
   1.355 -    length = min(PAGE_SIZE - offset, remaining);
   1.356 -    shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
   1.357 -    shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
   1.358 -    remaining -= length;
   1.359 -    ptr += length;
   1.360 -    //KdPrint((__DRIVER_NAME "     seg[%d].gref = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].gref));
   1.361 -    //KdPrint((__DRIVER_NAME "     seg[%d].first_sect = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].first_sect));
   1.362 -    //KdPrint((__DRIVER_NAME "     seg[%d].last_sect = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].last_sect));
   1.363 -    shadow->req.nr_segments++;
   1.364 -  }
   1.365 -  //KdPrint((__DRIVER_NAME "     nr_segments = %d\n", shadow->req.nr_segments));
   1.366 -
   1.367 -  XenVbd_PutRequest(xvdd, &shadow->req);
   1.368 -
   1.369 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   1.370 -  if (notify)
   1.371 -  {
   1.372 -    //KdPrint((__DRIVER_NAME "     Notifying\n"));
   1.373 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   1.374 -  }
   1.375 -
   1.376 -  if (xvdd->shadow_free && srb_offset == 0)
   1.377 -    ScsiPortNotification(NextLuRequest, xvdd, 0, 0, 0);
   1.378 -
   1.379 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.380 -}
   1.381 -
   1.382 -#define RESUME_CHECK_TIMER_INTERVAL (100 * 1000)
   1.383 -
   1.384 -static VOID
   1.385 -XenVbd_HwScsiTimer(PVOID DeviceExtension)
   1.386 -{
   1.387 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   1.388 -  ULONG i;
   1.389 -  blkif_shadow_t shadows[SHADOW_ENTRIES];
   1.390 -  ULONG shadow_entries;
   1.391 -  blkif_shadow_t *shadow;  
   1.392 -
   1.393 -  if (xvdd->device_state->resume_state == RESUME_STATE_FRONTEND_RESUME)
   1.394 -  {
   1.395 -    KdPrint((__DRIVER_NAME "     found device in resume state\n"));
   1.396 -    FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
   1.397 -    // re-submit srb's
   1.398 -    
   1.399 -    shadow_entries = 0;
   1.400 -    for (i = 0; i < SHADOW_ENTRIES; i++)
   1.401 -    {
   1.402 -      shadow = &xvdd->shadows[i];
   1.403 -      if (shadow->srb)
   1.404 -      {
   1.405 -        shadows[shadow_entries++] = xvdd->shadows[i];
   1.406 -        shadow->srb = NULL;
   1.407 -      }
   1.408 -    }
   1.409 -
   1.410 -    XenVbd_InitFromConfig(xvdd);
   1.411 -    
   1.412 -    for (i = 0; i < shadow_entries; i++)
   1.413 -    {
   1.414 -      shadow = &shadows[i];
   1.415 -      XenVbd_PutSrbOnRing(xvdd, shadow->srb, shadow->offset);
   1.416 -    }
   1.417 -    
   1.418 -    xvdd->device_state->resume_state = RESUME_STATE_RUNNING;
   1.419 -    
   1.420 -    if (i == 0)
   1.421 -    {
   1.422 -      /* no requests, so we might need to tell scsiport that we can accept a new one if we deferred one earlier */
   1.423 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.424 -    }
   1.425 -  }
   1.426 -  
   1.427 -  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, RESUME_CHECK_TIMER_INTERVAL);
   1.428 -}
   1.429 -
   1.430 -static ULONG DDKAPI
   1.431 -XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
   1.432 -{
   1.433 -//  PACCESS_RANGE AccessRange;
   1.434 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   1.435 -  ULONG status;
   1.436 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
   1.437 -  PACCESS_RANGE access_range;
   1.438 -
   1.439 -  UNREFERENCED_PARAMETER(HwContext);
   1.440 -  UNREFERENCED_PARAMETER(BusInformation);
   1.441 -  UNREFERENCED_PARAMETER(ArgumentString);
   1.442 -
   1.443 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
   1.444 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.445 -
   1.446 -  *Again = FALSE;
   1.447 -
   1.448 -  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
   1.449 -  KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
   1.450 -
   1.451 -  if (ConfigInfo->NumberOfAccessRanges != 1)
   1.452 -  {
   1.453 -    KdPrint((__DRIVER_NAME "     NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));    
   1.454 -    return SP_RETURN_BAD_CONFIG;
   1.455 -  }
   1.456 -
   1.457 -  access_range = &((*(ConfigInfo->AccessRanges))[0]);
   1.458 -
   1.459 -  KdPrint((__DRIVER_NAME "     RangeStart = %08x, RangeLength = %08x\n",
   1.460 -    access_range->RangeStart.LowPart, access_range->RangeLength));
   1.461 -
   1.462 -  xvdd->device_base = ScsiPortGetDeviceBase(
   1.463 -    DeviceExtension,
   1.464 -    ConfigInfo->AdapterInterfaceType,
   1.465 -    ConfigInfo->SystemIoBusNumber,
   1.466 -    access_range->RangeStart,
   1.467 -    access_range->RangeLength,
   1.468 -    !access_range->RangeInMemory);
   1.469 -  if (xvdd->device_base == NULL)
   1.470 -  {
   1.471 -    KdPrint((__DRIVER_NAME "     Unable to map range\n"));
   1.472 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   1.473 -    return SP_RETURN_BAD_CONFIG;
   1.474 -  }
   1.475 -
   1.476 -  status = XenVbd_InitFromConfig(xvdd);
   1.477 -  if (status != SP_RETURN_FOUND)
   1.478 -    return status;
   1.479 -  
   1.480 -  ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
   1.481 -  ConfigInfo->NumberOfPhysicalBreaks = 0; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
   1.482 -  ConfigInfo->ScatterGather = TRUE;
   1.483 -  ConfigInfo->AlignmentMask = 0;
   1.484 -  ConfigInfo->NumberOfBuses = 1;
   1.485 -  ConfigInfo->InitiatorBusId[0] = 1;
   1.486 -  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
   1.487 -  ConfigInfo->MaximumNumberOfTargets = 2;
   1.488 -  ConfigInfo->BufferAccessScsiPortControlled = TRUE;
   1.489 -  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
   1.490 -  {
   1.491 -    ConfigInfo->Master = TRUE;
   1.492 -    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
   1.493 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
   1.494 -  }
   1.495 -  else
   1.496 -  {
   1.497 -    ConfigInfo->Master = FALSE;
   1.498 -    KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
   1.499 -  }
   1.500 -
   1.501 -  xvdd->ring_detect_state = 0;
   1.502 -
   1.503 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   1.504 -
   1.505 -  return SP_RETURN_FOUND;
   1.506 -}
   1.507 -
   1.508 -static BOOLEAN DDKAPI
   1.509 -XenVbd_HwScsiInitialize(PVOID DeviceExtension)
   1.510 -{
   1.511 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   1.512 -  blkif_request_t *req;
   1.513 -  int i;
   1.514 -  int notify;
   1.515 -  
   1.516 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.517 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.518 -
   1.519 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
   1.520 -  req->operation = 0xff;
   1.521 -  req->nr_segments = 0;
   1.522 -  for (i = 0; i < BLKIF_MAX_SEGMENTS_PER_REQUEST; i++)
   1.523 -  {
   1.524 -    req->seg[i].gref = 0; //0xffffffff;
   1.525 -    req->seg[i].first_sect = 0; //0xff;
   1.526 -    req->seg[i].last_sect = 0; //0xff;
   1.527 -  }
   1.528 -  xvdd->ring.req_prod_pvt++;
   1.529 -
   1.530 -  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
   1.531 -  req->operation = 0xff;
   1.532 -  req->nr_segments = 0;
   1.533 -  for (i = 0; i < BLKIF_MAX_SEGMENTS_PER_REQUEST; i++)
   1.534 -  {
   1.535 -    req->seg[i].gref = 0; //0xffffffff;
   1.536 -    req->seg[i].first_sect = 0; //0xff;
   1.537 -    req->seg[i].last_sect = 0; //0xff;
   1.538 -  }
   1.539 -  xvdd->ring.req_prod_pvt++;
   1.540 -
   1.541 -  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   1.542 -  if (notify)
   1.543 -    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   1.544 -
   1.545 -  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, RESUME_CHECK_TIMER_INTERVAL);
   1.546 -
   1.547 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.548 -
   1.549 -  return TRUE;
   1.550 -}
   1.551 -
   1.552 -static ULONG
   1.553 -XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
   1.554 -{
   1.555 -  PCDB cdb;
   1.556 -  PMODE_PARAMETER_HEADER parameter_header;
   1.557 -  PMODE_PARAMETER_BLOCK param_block;
   1.558 -  PMODE_FORMAT_PAGE format_page;
   1.559 -  UCHAR page_code;
   1.560 -  ULONG offset;
   1.561 -  UCHAR buffer[256];
   1.562 -  BOOLEAN valid_page = FALSE;
   1.563 -
   1.564 -  UNREFERENCED_PARAMETER(xvdd);
   1.565 -
   1.566 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.567 -  
   1.568 -  cdb = (PCDB)srb->Cdb;
   1.569 -  page_code = cdb->MODE_SENSE.PageCode;
   1.570 -  offset = 0;
   1.571 -  RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
   1.572 -  RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
   1.573 -
   1.574 -  parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
   1.575 -  parameter_header->MediumType = 0;
   1.576 -  parameter_header->DeviceSpecificParameter = 0;
   1.577 -  parameter_header->BlockDescriptorLength = 0;
   1.578 -  offset += sizeof(MODE_PARAMETER_HEADER);
   1.579 -  
   1.580 -  if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
   1.581 -  {
   1.582 -    KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
   1.583 -    parameter_header->DeviceSpecificParameter|=MODE_DSP_WRITE_PROTECT; 
   1.584 -  }
   1.585 -  
   1.586 -  if (!cdb->MODE_SENSE.Dbd)
   1.587 -  {
   1.588 -    parameter_header->BlockDescriptorLength += sizeof(MODE_PARAMETER_BLOCK);
   1.589 -    param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
   1.590 -    if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
   1.591 -    {
   1.592 -      if (xvdd->total_sectors >> 32) 
   1.593 -      {
   1.594 -        param_block->DensityCode = 0xff;
   1.595 -        param_block->NumberOfBlocks[0] = 0xff;
   1.596 -        param_block->NumberOfBlocks[1] = 0xff;
   1.597 -        param_block->NumberOfBlocks[2] = 0xff;
   1.598 -      }
   1.599 -      else
   1.600 -      {
   1.601 -        param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
   1.602 -        param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
   1.603 -        param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
   1.604 -        param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
   1.605 -      }
   1.606 -      param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
   1.607 -      param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
   1.608 -      param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
   1.609 -    }
   1.610 -    offset += sizeof(MODE_PARAMETER_BLOCK);
   1.611 -  }
   1.612 -  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (page_code == MODE_PAGE_FORMAT_DEVICE || page_code == MODE_SENSE_RETURN_ALL))
   1.613 -  {
   1.614 -    valid_page = TRUE;
   1.615 -    format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
   1.616 -    format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
   1.617 -    format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
   1.618 -    /* 256 sectors per track */
   1.619 -    format_page->SectorsPerTrack[0] = 0x01;
   1.620 -    format_page->SectorsPerTrack[1] = 0x00;
   1.621 -    /* xxx bytes per sector */
   1.622 -    format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
   1.623 -    format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
   1.624 -    format_page->HardSectorFormating = TRUE;
   1.625 -    format_page->SoftSectorFormating = TRUE;
   1.626 -    offset += sizeof(MODE_FORMAT_PAGE);
   1.627 -  }
   1.628 -  parameter_header->ModeDataLength = (UCHAR)(offset - 1);
   1.629 -  if (!valid_page && page_code != MODE_SENSE_RETURN_ALL)
   1.630 -  {
   1.631 -    srb->SrbStatus = SRB_STATUS_ERROR;
   1.632 -  }
   1.633 -  else if(offset < srb->DataTransferLength)
   1.634 -    srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
   1.635 -  else
   1.636 -    srb->SrbStatus = SRB_STATUS_SUCCESS;
   1.637 -  srb->DataTransferLength = min(srb->DataTransferLength, offset);
   1.638 -  srb->ScsiStatus = 0;
   1.639 -  memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
   1.640 -  
   1.641 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.642 -
   1.643 -  return TRUE;
   1.644 -}
   1.645 -
   1.646 -static VOID
   1.647 -XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
   1.648 -{
   1.649 -  PSENSE_DATA sd = srb->SenseInfoBuffer;
   1.650 - 
   1.651 -  UNREFERENCED_PARAMETER(xvdd);
   1.652 -  
   1.653 -  if (!srb->SenseInfoBuffer)
   1.654 -    return;
   1.655 -  
   1.656 -  sd->ErrorCode = 0x70;
   1.657 -  sd->Valid = 1;
   1.658 -  sd->SenseKey = sense_key;
   1.659 -  sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
   1.660 -  sd->AdditionalSenseCode = additional_sense_code;
   1.661 -  return;
   1.662 -}
   1.663 -
   1.664 -static VOID
   1.665 -XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
   1.666 -{
   1.667 -  if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
   1.668 -    return;
   1.669 -  XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
   1.670 -  srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
   1.671 -}
   1.672 -
   1.673 -static BOOLEAN DDKAPI
   1.674 -XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
   1.675 -{
   1.676 -  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   1.677 -  PSCSI_REQUEST_BLOCK srb;
   1.678 -  RING_IDX i, rp;
   1.679 -  int j;
   1.680 -  blkif_response_t *rep;
   1.681 -  int block_count;
   1.682 -  int more_to_do = TRUE;
   1.683 -  blkif_shadow_t *shadow;
   1.684 -  ULONG offset;
   1.685 -
   1.686 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.687 -
   1.688 -  if (!xvdd->vectors.EvtChn_AckEvent(xvdd->vectors.context, xvdd->event_channel))
   1.689 -    return FALSE; /* interrupt was not for us */
   1.690 -  if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
   1.691 -  {
   1.692 -    //KdPrint((__DRIVER_NAME " --- " __FUNCTION__ " device_state event\n"));
   1.693 -    xvdd->device_state->resume_state_ack = xvdd->device_state->resume_state;
   1.694 -    KeMemoryBarrier();
   1.695 -    return FALSE;
   1.696 -  }
   1.697 -
   1.698 -  xvdd->interrupts++;
   1.699 -  while (more_to_do)
   1.700 -  {
   1.701 -    rp = xvdd->ring.sring->rsp_prod;
   1.702 -    KeMemoryBarrier();
   1.703 -    for (i = xvdd->ring.rsp_cons; i != rp; i++)
   1.704 -    {
   1.705 -      rep = XenVbd_GetResponse(xvdd, i);
   1.706 -/*
   1.707 -* This code is to automatically detect if the backend is using the same
   1.708 -* bit width or a different bit width to us. Later versions of Xen do this
   1.709 -* via a xenstore value, but not all. That 0x0fffffff (notice
   1.710 -* that the msb is not actually set, so we don't have any problems with
   1.711 -* sign extending) is to signify the last entry on the right, which is
   1.712 -* different under 32 and 64 bits, and that is why we set it up there.
   1.713 -
   1.714 -* To do the detection, we put two initial entries on the ring, with an op
   1.715 -* of 0xff (which is invalid). The first entry is mostly okay, but the
   1.716 -* second will be grossly misaligned if the backend bit width is different,
   1.717 -* and we detect this and switch frontend structures.
   1.718 -*/
   1.719 -      switch (xvdd->ring_detect_state)
   1.720 -      {
   1.721 -      case 0:
   1.722 -        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
   1.723 -        xvdd->ring_detect_state = 1;
   1.724 -        break;
   1.725 -      case 1:
   1.726 -        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
   1.727 -        if (rep->operation != 0xff)
   1.728 -        {
   1.729 -          xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
   1.730 -          xvdd->use_other = TRUE;
   1.731 -        }
   1.732 -        xvdd->ring_detect_state = 2;
   1.733 -        ScsiPortNotification(NextRequest, DeviceExtension);
   1.734 -        break;
   1.735 -      case 2:
   1.736 -        //KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
   1.737 -        shadow = &xvdd->shadows[rep->id];
   1.738 -        srb = shadow->srb;
   1.739 -        ASSERT(srb != NULL);
   1.740 -        block_count = (srb->Cdb[7] << 8) | srb->Cdb[8];
   1.741 -        block_count *= xvdd->bytes_per_sector / 512;
   1.742 -        if (rep->status == BLKIF_RSP_OKAY)
   1.743 -          srb->SrbStatus = SRB_STATUS_SUCCESS;
   1.744 -        else
   1.745 -        {
   1.746 -          KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
   1.747 -          if (srb->Cdb[0] == SCSIOP_READ)
   1.748 -            KdPrint((__DRIVER_NAME "     Operation = Read\n"));
   1.749 -          else
   1.750 -            KdPrint((__DRIVER_NAME "     Operation = Write\n"));     
   1.751 -          KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", shadow->req.sector_number, block_count));
   1.752 -          srb->SrbStatus = SRB_STATUS_ERROR;
   1.753 -          srb->ScsiStatus = 0x02;
   1.754 -          xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
   1.755 -          xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
   1.756 -          XenVbd_MakeAutoSense(xvdd, srb);
   1.757 -        }
   1.758 -        for (j = 0; j < shadow->req.nr_segments; j++)
   1.759 -        {
   1.760 -          BOOLEAN result = xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context, shadow->req.seg[j].gref, TRUE);
   1.761 -          ASSERT(result);
   1.762 -          put_grant_on_freelist(xvdd, shadow->req.seg[j].gref);
   1.763 -        }
   1.764 -
   1.765 -        if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
   1.766 -        {
   1.767 -          if (srb->Cdb[0] == SCSIOP_READ)
   1.768 -            memcpy(((PUCHAR)srb->DataBuffer) + shadow->offset, GET_PAGE_ALIGNED(srb->SrbExtension), shadow->length);
   1.769 -          offset = shadow->offset + shadow->length;
   1.770 -          put_shadow_on_freelist(xvdd, shadow);
   1.771 -          if (offset == block_count * xvdd->bytes_per_sector)
   1.772 -          {
   1.773 -            ScsiPortNotification(RequestComplete, xvdd, srb);
   1.774 -            ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.775 -          }
   1.776 -          else
   1.777 -          {
   1.778 -            XenVbd_PutSrbOnRing(xvdd, srb, offset);
   1.779 -          }
   1.780 -        }
   1.781 -        else
   1.782 -        {
   1.783 -          put_shadow_on_freelist(xvdd, shadow);
   1.784 -          ScsiPortNotification(RequestComplete, xvdd, srb);
   1.785 -          if (xvdd->pending_srb)
   1.786 -          {
   1.787 -            srb = xvdd->pending_srb;
   1.788 -            xvdd->pending_srb = NULL;
   1.789 -            XenVbd_PutSrbOnRing(xvdd, srb, 0);
   1.790 -          }
   1.791 -          else
   1.792 -            ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   1.793 -        }
   1.794 -        break;
   1.795 -      }
   1.796 -    }
   1.797 -
   1.798 -    xvdd->ring.rsp_cons = i;
   1.799 -    if (i != xvdd->ring.req_prod_pvt)
   1.800 -    {
   1.801 -      RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
   1.802 -    }
   1.803 -    else
   1.804 -    {
   1.805 -      xvdd->ring.sring->rsp_event = i + 1;
   1.806 -      more_to_do = FALSE;
   1.807 -    }
   1.808 -  }
   1.809 -
   1.810 -  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
   1.811 -  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
   1.812 -  //KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
   1.813 -  //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
   1.814 -
   1.815 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.816 -
   1.817 -  return FALSE; /* we just don't know... */
   1.818 -}
   1.819 -
   1.820 -static BOOLEAN DDKAPI
   1.821 -XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   1.822 -{
   1.823 -  PUCHAR DataBuffer;
   1.824 -  PCDB cdb;
   1.825 -  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
   1.826 -
   1.827 -  //KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
   1.828 -
   1.829 -  // If we haven't enumerated all the devices yet then just defer the request
   1.830 -  if (xvdd->ring_detect_state < 2)
   1.831 -  {
   1.832 -    Srb->SrbStatus = SRB_STATUS_BUSY;
   1.833 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   1.834 -    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Still figuring out ring)\n"));
   1.835 -    return TRUE;
   1.836 -  }
   1.837 -
   1.838 -  if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
   1.839 -  {
   1.840 -    Srb->SrbStatus = SRB_STATUS_BUSY;
   1.841 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   1.842 -    //KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Resuming)\n"));
   1.843 -    return TRUE;
   1.844 -  }
   1.845 -
   1.846 -  if (Srb->PathId != 0 || Srb->TargetId != 0)
   1.847 -  {
   1.848 -    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
   1.849 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   1.850 -    ScsiPortNotification(NextRequest, DeviceExtension);
   1.851 -    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
   1.852 -    return TRUE;
   1.853 -  }
   1.854 -
   1.855 -  switch (Srb->Function)
   1.856 -  {
   1.857 -  case SRB_FUNCTION_EXECUTE_SCSI:
   1.858 -    cdb = (PCDB)Srb->Cdb;
   1.859 -//    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_EXECUTE_SCSI\n"));
   1.860 -
   1.861 -    switch(cdb->CDB6GENERIC.OperationCode)
   1.862 -    {
   1.863 -    case SCSIOP_TEST_UNIT_READY:
   1.864 -      //KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
   1.865 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   1.866 -      Srb->ScsiStatus = 0;
   1.867 -      break;
   1.868 -    case SCSIOP_INQUIRY:
   1.869 -//      KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
   1.870 -//      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
   1.871 -//      KdPrint((__DRIVER_NAME "     (Length = %d)\n", Srb->DataTransferLength));
   1.872 -//      KdPrint((__DRIVER_NAME "     (Srb->Databuffer = %08x)\n", Srb->DataBuffer));
   1.873 -      DataBuffer = Srb->DataBuffer;
   1.874 -      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
   1.875 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   1.876 -      switch (xvdd->device_type)
   1.877 -      {
   1.878 -      case XENVBD_DEVICETYPE_DISK:
   1.879 -        if ((Srb->Cdb[1] & 1) == 0)
   1.880 -        {
   1.881 -          PINQUIRYDATA id = (PINQUIRYDATA)DataBuffer;
   1.882 -          id->DeviceType = DIRECT_ACCESS_DEVICE;
   1.883 -          id->Versions = 3;
   1.884 -          id->ResponseDataFormat = 0;
   1.885 -          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
   1.886 -          id->CommandQueue = 1;
   1.887 -          memcpy(id->VendorId, "XEN     ", 8); // vendor id
   1.888 -          memcpy(id->ProductId, "PV DISK         ", 16); // product id
   1.889 -          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
   1.890 -        }
   1.891 -        else
   1.892 -        {
   1.893 -          switch (Srb->Cdb[2])
   1.894 -          {
   1.895 -          case 0x00:
   1.896 -            DataBuffer[0] = DIRECT_ACCESS_DEVICE;
   1.897 -            DataBuffer[1] = 0x00;
   1.898 -            DataBuffer[2] = 0x00;
   1.899 -            DataBuffer[3] = 2;
   1.900 -            DataBuffer[4] = 0x00;
   1.901 -            DataBuffer[5] = 0x80;
   1.902 -            break;
   1.903 -          case 0x80:
   1.904 -            DataBuffer[0] = DIRECT_ACCESS_DEVICE;
   1.905 -            DataBuffer[1] = 0x80;
   1.906 -            DataBuffer[2] = 0x00;
   1.907 -            DataBuffer[3] = 8;
   1.908 -            memset(&DataBuffer[4], ' ', 8);
   1.909 -            break;
   1.910 -          default:
   1.911 -            //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
   1.912 -            Srb->SrbStatus = SRB_STATUS_ERROR;
   1.913 -            break;
   1.914 -          }
   1.915 -        }
   1.916 -        break;
   1.917 -      case XENVBD_DEVICETYPE_CDROM:
   1.918 -        if ((Srb->Cdb[1] & 1) == 0)
   1.919 -        {
   1.920 -          PINQUIRYDATA id = (PINQUIRYDATA)DataBuffer;
   1.921 -          id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
   1.922 -          id->RemovableMedia = 1;
   1.923 -          id->Versions = 3;
   1.924 -          id->ResponseDataFormat = 0;
   1.925 -          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
   1.926 -          id->CommandQueue = 1;
   1.927 -          memcpy(id->VendorId, "XEN     ", 8); // vendor id
   1.928 -          memcpy(id->ProductId, "PV CDROM        ", 16); // product id
   1.929 -          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
   1.930 -        }
   1.931 -        else
   1.932 -        {
   1.933 -          switch (Srb->Cdb[2])
   1.934 -          {
   1.935 -          case 0x00:
   1.936 -            DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
   1.937 -            DataBuffer[1] = 0x00;
   1.938 -            DataBuffer[2] = 0x00;
   1.939 -            DataBuffer[3] = 2;
   1.940 -            DataBuffer[4] = 0x00;
   1.941 -            DataBuffer[5] = 0x80;
   1.942 -            break;
   1.943 -          case 0x80:
   1.944 -            DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
   1.945 -            DataBuffer[1] = 0x80;
   1.946 -            DataBuffer[2] = 0x00;
   1.947 -            DataBuffer[3] = 8;
   1.948 -            DataBuffer[4] = 0x31;
   1.949 -            DataBuffer[5] = 0x32;
   1.950 -            DataBuffer[6] = 0x33;
   1.951 -            DataBuffer[7] = 0x34;
   1.952 -            DataBuffer[8] = 0x35;
   1.953 -            DataBuffer[9] = 0x36;
   1.954 -            DataBuffer[10] = 0x37;
   1.955 -            DataBuffer[11] = 0x38;
   1.956 -            break;
   1.957 -          default:
   1.958 -            //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
   1.959 -            Srb->SrbStatus = SRB_STATUS_ERROR;
   1.960 -            break;
   1.961 -          }
   1.962 -        }
   1.963 -        break;
   1.964 -      default:
   1.965 -        //KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", xvdd->device_type));
   1.966 -        Srb->SrbStatus = SRB_STATUS_ERROR;
   1.967 -        break;
   1.968 -      }
   1.969 -      break;
   1.970 -    case SCSIOP_READ_CAPACITY:
   1.971 -      //KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
   1.972 -      //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", Srb->Cdb[1] >> 4, Srb->Cdb[1] & 1));
   1.973 -      //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", Srb->Cdb[2], Srb->Cdb[3], Srb->Cdb[4], Srb->Cdb[5]));
   1.974 -      //KdPrint((__DRIVER_NAME "       PMI = %d\n", Srb->Cdb[8] & 1));
   1.975 -      DataBuffer = Srb->DataBuffer;
   1.976 -      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
   1.977 -      if ((xvdd->total_sectors - 1) >> 32)
   1.978 -      {
   1.979 -        DataBuffer[0] = 0xff;
   1.980 -        DataBuffer[1] = 0xff;
   1.981 -        DataBuffer[2] = 0xff;
   1.982 -        DataBuffer[3] = 0xff;
   1.983 -      }
   1.984 -      else
   1.985 -      {
   1.986 -        DataBuffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
   1.987 -        DataBuffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
   1.988 -        DataBuffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
   1.989 -        DataBuffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
   1.990 -      }
   1.991 -      DataBuffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
   1.992 -      DataBuffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
   1.993 -      DataBuffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
   1.994 -      DataBuffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
   1.995 -      Srb->ScsiStatus = 0;
   1.996 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   1.997 -      break;
   1.998 -    case SCSIOP_MODE_SENSE:
   1.999 -//      KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x08, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
  1.1000 -      XenVbd_FillModePage(xvdd, Srb);
  1.1001 -      break;
  1.1002 -    case SCSIOP_WRITE:
  1.1003 -    case SCSIOP_READ:
  1.1004 -//      KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
  1.1005 -      XenVbd_PutSrbOnRing(xvdd, Srb, 0);
  1.1006 -      break;
  1.1007 -    case SCSIOP_VERIFY:
  1.1008 -      // Should we do more here?
  1.1009 -//      KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
  1.1010 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  1.1011 -      break;
  1.1012 -    case SCSIOP_REPORT_LUNS:
  1.1013 -//      KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
  1.1014 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;;
  1.1015 -      break;
  1.1016 -    case SCSIOP_REQUEST_SENSE:
  1.1017 -//      KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
  1.1018 -      XenVbd_MakeSense(xvdd, Srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
  1.1019 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  1.1020 -      break;      
  1.1021 -    case SCSIOP_READ_TOC:
  1.1022 -      DataBuffer = Srb->DataBuffer;
  1.1023 -//      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
  1.1024 -/*
  1.1025 -#define READ_TOC_FORMAT_TOC         0x00
  1.1026 -#define READ_TOC_FORMAT_SESSION     0x01
  1.1027 -#define READ_TOC_FORMAT_FULL_TOC    0x02
  1.1028 -#define READ_TOC_FORMAT_PMA         0x03
  1.1029 -#define READ_TOC_FORMAT_ATIP        0x04
  1.1030 -*/
  1.1031 -//      KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
  1.1032 -//      KdPrint((__DRIVER_NAME "     Msf = %d\n", cdb->READ_TOC.Msf));
  1.1033 -//      KdPrint((__DRIVER_NAME "     LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
  1.1034 -//      KdPrint((__DRIVER_NAME "     Format2 = %d\n", cdb->READ_TOC.Format2));
  1.1035 -//      KdPrint((__DRIVER_NAME "     StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
  1.1036 -//      KdPrint((__DRIVER_NAME "     AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
  1.1037 -//      KdPrint((__DRIVER_NAME "     Control = %d\n", cdb->READ_TOC.Control));
  1.1038 -//      KdPrint((__DRIVER_NAME "     Format = %d\n", cdb->READ_TOC.Format));
  1.1039 -      switch (cdb->READ_TOC.Format2)
  1.1040 -      {
  1.1041 -      case READ_TOC_FORMAT_TOC:
  1.1042 -        DataBuffer[0] = 0; // length MSB
  1.1043 -        DataBuffer[1] = 10; // length LSB
  1.1044 -        DataBuffer[2] = 1; // First Track
  1.1045 -        DataBuffer[3] = 1; // Last Track
  1.1046 -        DataBuffer[4] = 0; // Reserved
  1.1047 -        DataBuffer[5] = 0x14; // current position data + uninterrupted data
  1.1048 -        DataBuffer[6] = 1; // last complete track
  1.1049 -        DataBuffer[7] = 0; // reserved
  1.1050 -        DataBuffer[8] = 0; // MSB Block
  1.1051 -        DataBuffer[9] = 0;
  1.1052 -        DataBuffer[10] = 0;
  1.1053 -        DataBuffer[11] = 0; // LSB Block
  1.1054 -        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  1.1055 -        break;
  1.1056 -      case READ_TOC_FORMAT_SESSION:
  1.1057 -      case READ_TOC_FORMAT_FULL_TOC:
  1.1058 -      case READ_TOC_FORMAT_PMA:
  1.1059 -      case READ_TOC_FORMAT_ATIP:
  1.1060 -        Srb->SrbStatus = SRB_STATUS_ERROR;
  1.1061 -        break;
  1.1062 -      }
  1.1063 -      break;
  1.1064 -    case SCSIOP_START_STOP_UNIT:
  1.1065 -//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
  1.1066 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  1.1067 -      break;
  1.1068 -    case SCSIOP_RESERVE_UNIT:
  1.1069 -//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
  1.1070 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  1.1071 -      break;
  1.1072 -    case SCSIOP_RELEASE_UNIT:
  1.1073 -//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
  1.1074 -      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  1.1075 -      break;
  1.1076 -    default:
  1.1077 -      //KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
  1.1078 -      Srb->SrbStatus = SRB_STATUS_ERROR;
  1.1079 -      break;
  1.1080 -    }
  1.1081 -    if (Srb->SrbStatus == SRB_STATUS_ERROR)
  1.1082 -    {
  1.1083 -      //KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", Srb->Cdb[0], xvdd->last_sense_key));
  1.1084 -      if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
  1.1085 -      {
  1.1086 -        xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
  1.1087 -        xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
  1.1088 -      }
  1.1089 -      Srb->ScsiStatus = 0x02;
  1.1090 -      XenVbd_MakeAutoSense(xvdd, Srb);
  1.1091 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  1.1092 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  1.1093 -    }
  1.1094 -    else if (Srb->SrbStatus != SRB_STATUS_PENDING)
  1.1095 -    {
  1.1096 -      xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
  1.1097 -      xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
  1.1098 -      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  1.1099 -      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  1.1100 -    }
  1.1101 -    break;
  1.1102 -  case SRB_FUNCTION_IO_CONTROL:
  1.1103 -    //KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
  1.1104 -    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  1.1105 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  1.1106 -    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  1.1107 -    break;
  1.1108 -  case SRB_FUNCTION_FLUSH:
  1.1109 -    //KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
  1.1110 -    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  1.1111 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  1.1112 -    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  1.1113 -    break;
  1.1114 -  default:
  1.1115 -    //KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
  1.1116 -    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  1.1117 -    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  1.1118 -    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  1.1119 -    break;
  1.1120 -  }
  1.1121 -
  1.1122 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  1.1123 -  return TRUE;
  1.1124 -}
  1.1125 -
  1.1126 -static BOOLEAN DDKAPI
  1.1127 -XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
  1.1128 -{
  1.1129 -  UNREFERENCED_PARAMETER(DeviceExtension);
  1.1130 -  UNREFERENCED_PARAMETER(PathId);
  1.1131 -
  1.1132 -  KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
  1.1133 -
  1.1134 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  1.1135 -  ScsiPortNotification(NextRequest, DeviceExtension);
  1.1136 -
  1.1137 -  KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
  1.1138 -
  1.1139 -
  1.1140 -  return TRUE;
  1.1141 -}
  1.1142 -
  1.1143 -static BOOLEAN DDKAPI
  1.1144 -XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
  1.1145 -{
  1.1146 -  UNREFERENCED_PARAMETER(DeviceExtension);
  1.1147 -  UNREFERENCED_PARAMETER(Context);
  1.1148 -  UNREFERENCED_PARAMETER(SaveState);
  1.1149 -
  1.1150 -  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  1.1151 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  1.1152 -
  1.1153 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  1.1154 -
  1.1155 -  return TRUE;
  1.1156 -}
  1.1157 -
  1.1158 -static SCSI_ADAPTER_CONTROL_STATUS DDKAPI
  1.1159 -XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
  1.1160 -{
  1.1161 -  SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
  1.1162 -  PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
  1.1163 -  //KIRQL OldIrql;
  1.1164 -
  1.1165 -  UNREFERENCED_PARAMETER(DeviceExtension);
  1.1166 -
  1.1167 -  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
  1.1168 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  1.1169 -
  1.1170 -  switch (ControlType)
  1.1171 -  {
  1.1172 -  case ScsiQuerySupportedControlTypes:
  1.1173 -    SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
  1.1174 -    KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
  1.1175 -    SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
  1.1176 -    SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
  1.1177 -    SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
  1.1178 -    break;
  1.1179 -  case ScsiStopAdapter:
  1.1180 -    KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
  1.1181 -    /* I don't think we actually have to do anything here... xenpci cleans up all the xenbus stuff for us */
  1.1182 -    break;
  1.1183 -  case ScsiRestartAdapter:
  1.1184 -    KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
  1.1185 -    break;
  1.1186 -  case ScsiSetBootConfig:
  1.1187 -    KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
  1.1188 -    break;
  1.1189 -  case ScsiSetRunningConfig:
  1.1190 -    KdPrint((__DRIVER_NAME "     ScsiSetRunningConfig\n"));
  1.1191 -    break;
  1.1192 -  default:
  1.1193 -    KdPrint((__DRIVER_NAME "     UNKNOWN\n"));
  1.1194 -    break;
  1.1195 -  }
  1.1196 -
  1.1197 -  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
  1.1198 -
  1.1199 -  return Status;
  1.1200 -}
  1.1201 -
  1.1202 -VOID
  1.1203 -XenVbd_FillInitCallbacks(PHW_INITIALIZATION_DATA HwInitializationData)
  1.1204 -{
  1.1205 -  KdPrint((__DRIVER_NAME " --> "__FUNCTION__ "\n"));
  1.1206 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  1.1207 -
  1.1208 -  HwInitializationData->HwInitialize = XenVbd_HwScsiInitialize;
  1.1209 -  HwInitializationData->HwStartIo = XenVbd_HwScsiStartIo;
  1.1210 -  HwInitializationData->HwInterrupt = XenVbd_HwScsiInterrupt;
  1.1211 -  HwInitializationData->HwFindAdapter = XenVbd_HwScsiFindAdapter;
  1.1212 -  HwInitializationData->HwResetBus = XenVbd_HwScsiResetBus;
  1.1213 -  HwInitializationData->HwDmaStarted = NULL;
  1.1214 -  HwInitializationData->HwAdapterState = XenVbd_HwScsiAdapterState;
  1.1215 -  HwInitializationData->HwAdapterControl = XenVbd_HwScsiAdapterControl;
  1.1216 -
  1.1217 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  1.1218 -}
     2.1 --- a/xenvbd/sources	Wed Aug 20 21:36:59 2008 +1000
     2.2 +++ b/xenvbd/sources	Thu Aug 21 13:44:24 2008 +1000
     2.3 @@ -6,4 +6,4 @@ TARGETTYPE=DRIVER
     2.4  INF_NAME=$(TARGETNAME)
     2.5  MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
     2.6  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\scsiport.lib
     2.7 -SOURCES=xenvbd.c scsiport.c
     2.8 +SOURCES=xenvbd.c
     3.1 --- a/xenvbd/xenvbd.c	Wed Aug 20 21:36:59 2008 +1000
     3.2 +++ b/xenvbd/xenvbd.c	Thu Aug 21 13:44:24 2008 +1000
     3.3 @@ -35,6 +35,1176 @@ DRIVER_INITIALIZE DriverEntry;
     3.4  #pragma alloc_text (INIT, DriverEntry)
     3.5  #endif
     3.6  
     3.7 +#if defined(__x86_64__)
     3.8 +  #define GET_PAGE_ALIGNED(ptr) ((PVOID)(((ULONGLONG)ptr + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
     3.9 +#else
    3.10 +  #define GET_PAGE_ALIGNED(ptr) UlongToPtr((PtrToUlong(ptr) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
    3.11 +#endif
    3.12 +
    3.13 +static BOOLEAN dump_mode = FALSE;
    3.14 +
    3.15 +static blkif_shadow_t *
    3.16 +get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
    3.17 +{
    3.18 +  if (xvdd->shadow_free == 0)
    3.19 +  {
    3.20 +    KdPrint((__DRIVER_NAME "     No more shadow entries\n"));    
    3.21 +    return NULL;
    3.22 +  }
    3.23 +  xvdd->shadow_free--;
    3.24 +  if (xvdd->shadow_free < xvdd->shadow_min_free)
    3.25 +    xvdd->shadow_min_free = xvdd->shadow_free;
    3.26 +  return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
    3.27 +}
    3.28 +
    3.29 +static VOID
    3.30 +put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
    3.31 +{
    3.32 +  xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)shadow->req.id;
    3.33 +  shadow->srb = NULL;
    3.34 +  xvdd->shadow_free++;
    3.35 +}
    3.36 +
    3.37 +static grant_ref_t
    3.38 +get_grant_from_freelist(PXENVBD_DEVICE_DATA xvdd)
    3.39 +{
    3.40 +  if (xvdd->grant_free == 0)
    3.41 +  {
    3.42 +    KdPrint((__DRIVER_NAME "     No more grant refs\n"));    
    3.43 +    return (grant_ref_t)0x0FFFFFFF;
    3.44 +  }
    3.45 +  xvdd->grant_free--;
    3.46 +  return xvdd->grant_free_list[xvdd->grant_free];
    3.47 +}
    3.48 +
    3.49 +static VOID
    3.50 +put_grant_on_freelist(PXENVBD_DEVICE_DATA xvdd, grant_ref_t grant)
    3.51 +{
    3.52 +  xvdd->grant_free_list[xvdd->grant_free] = grant;
    3.53 +  xvdd->grant_free++;
    3.54 +}
    3.55 +
    3.56 +static blkif_response_t *
    3.57 +XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i)
    3.58 +{
    3.59 +  blkif_other_response_t *rep;
    3.60 +  if (!xvdd->use_other)
    3.61 +    return RING_GET_RESPONSE(&xvdd->ring, i);
    3.62 +  rep = RING_GET_RESPONSE(&xvdd->other_ring, i);
    3.63 +  xvdd->tmp_rep.id = rep->id;
    3.64 +  xvdd->tmp_rep.operation = rep->operation;
    3.65 +  xvdd->tmp_rep.status = rep->status;
    3.66 +  return &xvdd->tmp_rep;
    3.67 +}
    3.68 +
    3.69 +static VOID
    3.70 +XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
    3.71 +{
    3.72 +  blkif_other_request_t *other_req;
    3.73 +
    3.74 +  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
    3.75 +  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
    3.76 +  //KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
    3.77 +  //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
    3.78 +  if (!xvdd->use_other)
    3.79 +  {
    3.80 +    *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
    3.81 +  }
    3.82 +  else
    3.83 +  {  
    3.84 +    other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
    3.85 +    other_req->operation = req->operation;
    3.86 +    other_req->nr_segments = req->nr_segments;
    3.87 +    other_req->handle = req->handle;
    3.88 +    other_req->id = req->id;
    3.89 +    other_req->sector_number = req->sector_number;
    3.90 +    memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
    3.91 +  }
    3.92 +  xvdd->ring.req_prod_pvt++;
    3.93 +  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
    3.94 +  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
    3.95 +  //KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
    3.96 +  //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
    3.97 +}
    3.98 +
    3.99 +static ULONG
   3.100 +XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
   3.101 +{
   3.102 +  ULONG i;
   3.103 +  PUCHAR ptr;
   3.104 +  USHORT type;
   3.105 +  PCHAR setting, value;
   3.106 +
   3.107 +  xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
   3.108 +  xvdd->sring = NULL;
   3.109 +  xvdd->event_channel = 0;
   3.110 +  
   3.111 +  ptr = xvdd->device_base;
   3.112 +  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID) &setting, (PVOID) &value)) != XEN_INIT_TYPE_END)
   3.113 +  {
   3.114 +    switch(type)
   3.115 +    {
   3.116 +    case XEN_INIT_TYPE_RING: /* frontend ring */
   3.117 +      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
   3.118 +      if (strcmp(setting, "ring-ref") == 0)
   3.119 +      {
   3.120 +        xvdd->sring = (blkif_sring_t *)value;
   3.121 +        FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
   3.122 +        /* this bit is for when we have to take over an existing ring on a bug check */
   3.123 +        xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
   3.124 +        xvdd->ring.rsp_cons = xvdd->sring->rsp_prod;
   3.125 +      }
   3.126 +      break;
   3.127 +    case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
   3.128 +    case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */
   3.129 +      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value)));
   3.130 +      if (strcmp(setting, "event-channel") == 0)
   3.131 +      {
   3.132 +        xvdd->event_channel = PtrToUlong(value);
   3.133 +      }
   3.134 +      break;
   3.135 +    case XEN_INIT_TYPE_READ_STRING_BACK:
   3.136 +    case XEN_INIT_TYPE_READ_STRING_FRONT:
   3.137 +      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   3.138 +      if (strcmp(setting, "sectors") == 0)
   3.139 +        xvdd->total_sectors = atoi(value);
   3.140 +      else if (strcmp(setting, "sector-size") == 0)
   3.141 +        xvdd->bytes_per_sector = atoi(value);
   3.142 +      else if (strcmp(setting, "device-type") == 0)
   3.143 +      {
   3.144 +        if (strcmp(value, "disk") == 0)
   3.145 +        {
   3.146 +          KdPrint((__DRIVER_NAME "     device-type = Disk\n"));    
   3.147 +          xvdd->device_type = XENVBD_DEVICETYPE_DISK;
   3.148 +        }
   3.149 +        else if (strcmp(value, "cdrom") == 0)
   3.150 +        {
   3.151 +          KdPrint((__DRIVER_NAME "     device-type = CDROM\n"));    
   3.152 +          xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
   3.153 +        }
   3.154 +        else
   3.155 +        {
   3.156 +          KdPrint((__DRIVER_NAME "     device-type = %s (This probably won't work!)\n", value));
   3.157 +          xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
   3.158 +        }
   3.159 +      }
   3.160 +      else if (strcmp(setting, "mode") == 0)
   3.161 +      {
   3.162 +        if (strncmp(value, "r", 1) == 0)
   3.163 +        {
   3.164 +          KdPrint((__DRIVER_NAME "     mode = r\n"));    
   3.165 +          xvdd->device_mode = XENVBD_DEVICEMODE_READ;
   3.166 +        }
   3.167 +        else if (strncmp(value, "w", 1) == 0)
   3.168 +        {
   3.169 +          KdPrint((__DRIVER_NAME "     mode = w\n"));    
   3.170 +          xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
   3.171 +        }
   3.172 +        else
   3.173 +        {
   3.174 +          KdPrint((__DRIVER_NAME "     mode = unknown\n"));
   3.175 +          xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
   3.176 +        }
   3.177 +      }
   3.178 +      break;
   3.179 +    case XEN_INIT_TYPE_VECTORS:
   3.180 +      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   3.181 +      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   3.182 +        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   3.183 +      {
   3.184 +        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   3.185 +          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   3.186 +        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.187 +        return SP_RETURN_BAD_CONFIG;
   3.188 +      }
   3.189 +      else
   3.190 +        memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
   3.191 +      break;
   3.192 +    case XEN_INIT_TYPE_GRANT_ENTRIES:
   3.193 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(setting)));
   3.194 +      xvdd->grant_entries = (USHORT)PtrToUlong(setting);
   3.195 +      memcpy(&xvdd->grant_free_list, value, sizeof(grant_ref_t) * xvdd->grant_entries);
   3.196 +      xvdd->grant_free = xvdd->grant_entries;
   3.197 +      break;
   3.198 +    case XEN_INIT_TYPE_STATE_PTR:
   3.199 +      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   3.200 +      xvdd->device_state = (PXENPCI_DEVICE_STATE)value;
   3.201 +      break;
   3.202 +    default:
   3.203 +      //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   3.204 +      break;
   3.205 +    }
   3.206 +  }
   3.207 +  if (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
   3.208 +    || xvdd->sring == NULL
   3.209 +    || xvdd->event_channel == 0
   3.210 +    || xvdd->total_sectors == 0
   3.211 +    || xvdd->bytes_per_sector == 0)
   3.212 +  {
   3.213 +    KdPrint((__DRIVER_NAME "     Missing settings\n"));
   3.214 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.215 +    return SP_RETURN_BAD_CONFIG;
   3.216 +  }
   3.217 +
   3.218 +  /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
   3.219 +#ifdef __MINGW32__
   3.220 +  /* mingw can't divide, so shift instead (assumes bps is ^2 and at least 512) */
   3.221 +  {
   3.222 +    ULONG num_512_byte_sectors = xvdd->bytes_per_sector / 512;
   3.223 +    ULONG index;
   3.224 +
   3.225 +    bit_scan_forward(&index, num_512_byte_sectors);
   3.226 +    xvdd->total_sectors <<= index-1;
   3.227 +  }
   3.228 +#else
   3.229 +  xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
   3.230 +#endif
   3.231 +
   3.232 +
   3.233 +  xvdd->shadow_free = 0;
   3.234 +  memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
   3.235 +  for (i = 0; i < SHADOW_ENTRIES; i++)
   3.236 +  {
   3.237 +    xvdd->shadows[i].req.id = i;
   3.238 +    put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
   3.239 +  }
   3.240 +  
   3.241 +  return SP_RETURN_FOUND;
   3.242 +}
   3.243 +
   3.244 +static VOID
   3.245 +XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, ULONG srb_offset)
   3.246 +{
   3.247 +  ULONG block_count, transfer_length;
   3.248 +  blkif_shadow_t *shadow;
   3.249 +  PHYSICAL_ADDRESS physical_address;
   3.250 +  ULONG pfn;
   3.251 +  ULONG remaining, offset, length;
   3.252 +  PUCHAR ptr;
   3.253 +  int notify;
   3.254 +
   3.255 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.256 +
   3.257 +  //ASSERT(!(srb_offset == 0 && xvdd->split_request_in_progress));
   3.258 +  block_count = (srb->Cdb[7] << 8) | srb->Cdb[8];
   3.259 +  block_count *= xvdd->bytes_per_sector / 512;
   3.260 +  if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
   3.261 +  {
   3.262 +    ptr = GET_PAGE_ALIGNED(srb->SrbExtension);
   3.263 +    transfer_length = min(block_count * 512 - srb_offset, UNALIGNED_DOUBLE_BUFFER_SIZE);
   3.264 +    if (!srb_offset)
   3.265 +    {
   3.266 +      xvdd->unaligned_requests++;
   3.267 +      xvdd->unaligned_bytes += transfer_length;
   3.268 +    }
   3.269 +  }
   3.270 +  else
   3.271 +  {
   3.272 +    ptr = srb->DataBuffer;
   3.273 +    transfer_length = block_count * 512;
   3.274 +    xvdd->aligned_requests++;
   3.275 +    xvdd->aligned_bytes += transfer_length;
   3.276 +  }
   3.277 +
   3.278 +  if (xvdd->grant_free <= ADDRESS_AND_SIZE_TO_SPAN_PAGES(ptr, transfer_length))
   3.279 +  {
   3.280 +    ASSERT(!xvdd->pending_srb);
   3.281 +    //KdPrint((__DRIVER_NAME "     No enough grants - deferring\n"));
   3.282 +    xvdd->pending_srb = srb;
   3.283 +    xvdd->no_free_grant_requests++;
   3.284 +    return;
   3.285 +  }
   3.286 +  
   3.287 +  shadow = get_shadow_from_freelist(xvdd);
   3.288 +  ASSERT(shadow);
   3.289 +  shadow->req.sector_number = (srb->Cdb[2] << 24) | (srb->Cdb[3] << 16) | (srb->Cdb[4] << 8) | srb->Cdb[5];
   3.290 +  shadow->req.sector_number *= xvdd->bytes_per_sector / 512;
   3.291 +  shadow->req.handle = 0;
   3.292 +  shadow->req.operation = (srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
   3.293 +  shadow->req.nr_segments = 0;
   3.294 +  shadow->offset = srb_offset;
   3.295 +  shadow->length = transfer_length;
   3.296 +  shadow->srb = srb;
   3.297 +
   3.298 +  //KdPrint((__DRIVER_NAME "     sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
   3.299 +  //KdPrint((__DRIVER_NAME "     SrbExtension = %p\n", srb->SrbExtension));
   3.300 +  //KdPrint((__DRIVER_NAME "     DataBuffer   = %p\n", srb->DataBuffer));
   3.301 +
   3.302 +  if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
   3.303 +  {
   3.304 +    shadow->req.sector_number += srb_offset / 512; //xvdd->bytes_per_sector;
   3.305 +    //KdPrint((__DRIVER_NAME "     Using unaligned buffer - DataBuffer = %p, SrbExtension = %p, total length = %d, offset = %d, length = %d, sector = %d\n", srb->DataBuffer, srb->SrbExtension, block_count * 512, shadow->offset, shadow->length, shadow->req.sector_number));
   3.306 +    if (srb->Cdb[0] == SCSIOP_WRITE)
   3.307 +    {
   3.308 +      memcpy(ptr, ((PUCHAR)srb->DataBuffer) + srb_offset, shadow->length);
   3.309 +    }
   3.310 +  }
   3.311 +  else
   3.312 +  {
   3.313 +    ptr = srb->DataBuffer;
   3.314 +  }
   3.315 +  //KdPrint((__DRIVER_NAME "     sector_number = %d\n", (ULONG)shadow->req.sector_number));
   3.316 +  //KdPrint((__DRIVER_NAME "     handle = %d\n", shadow->req.handle));
   3.317 +  //KdPrint((__DRIVER_NAME "     operation = %d\n", shadow->req.operation));
   3.318 +    
   3.319 +  remaining = shadow->length;  
   3.320 +  while (remaining > 0)
   3.321 +  {
   3.322 +    physical_address = MmGetPhysicalAddress(ptr);
   3.323 +    pfn = (ULONG)(physical_address.QuadPart >> PAGE_SHIFT);
   3.324 +    shadow->req.seg[shadow->req.nr_segments].gref = get_grant_from_freelist(xvdd);
   3.325 +    ASSERT(shadow->req.seg[shadow->req.nr_segments].gref != INVALID_GRANT_REF);
   3.326 +    xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0, pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref);
   3.327 +    offset = (ULONG)(physical_address.QuadPart & (PAGE_SIZE - 1));
   3.328 +    ASSERT((offset & 511) == 0);
   3.329 +    length = min(PAGE_SIZE - offset, remaining);
   3.330 +    shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
   3.331 +    shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
   3.332 +    remaining -= length;
   3.333 +    ptr += length;
   3.334 +    //KdPrint((__DRIVER_NAME "     seg[%d].gref = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].gref));
   3.335 +    //KdPrint((__DRIVER_NAME "     seg[%d].first_sect = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].first_sect));
   3.336 +    //KdPrint((__DRIVER_NAME "     seg[%d].last_sect = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].last_sect));
   3.337 +    shadow->req.nr_segments++;
   3.338 +  }
   3.339 +  //KdPrint((__DRIVER_NAME "     nr_segments = %d\n", shadow->req.nr_segments));
   3.340 +
   3.341 +  XenVbd_PutRequest(xvdd, &shadow->req);
   3.342 +
   3.343 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   3.344 +  if (notify)
   3.345 +  {
   3.346 +    //KdPrint((__DRIVER_NAME "     Notifying\n"));
   3.347 +    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   3.348 +  }
   3.349 +
   3.350 +  if (xvdd->shadow_free && srb_offset == 0)
   3.351 +    ScsiPortNotification(NextLuRequest, xvdd, 0, 0, 0);
   3.352 +
   3.353 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.354 +}
   3.355 +
   3.356 +#define RESUME_CHECK_TIMER_INTERVAL (100 * 1000)
   3.357 +
   3.358 +static VOID
   3.359 +XenVbd_HwScsiTimer(PVOID DeviceExtension)
   3.360 +{
   3.361 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   3.362 +  ULONG i;
   3.363 +  blkif_shadow_t shadows[SHADOW_ENTRIES];
   3.364 +  ULONG shadow_entries;
   3.365 +  blkif_shadow_t *shadow;  
   3.366 +
   3.367 +  if (xvdd->device_state->resume_state == RESUME_STATE_FRONTEND_RESUME)
   3.368 +  {
   3.369 +    KdPrint((__DRIVER_NAME "     found device in resume state\n"));
   3.370 +    FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
   3.371 +    // re-submit srb's
   3.372 +    
   3.373 +    shadow_entries = 0;
   3.374 +    for (i = 0; i < SHADOW_ENTRIES; i++)
   3.375 +    {
   3.376 +      shadow = &xvdd->shadows[i];
   3.377 +      if (shadow->srb)
   3.378 +      {
   3.379 +        shadows[shadow_entries++] = xvdd->shadows[i];
   3.380 +        shadow->srb = NULL;
   3.381 +      }
   3.382 +    }
   3.383 +
   3.384 +    XenVbd_InitFromConfig(xvdd);
   3.385 +    
   3.386 +    for (i = 0; i < shadow_entries; i++)
   3.387 +    {
   3.388 +      shadow = &shadows[i];
   3.389 +      XenVbd_PutSrbOnRing(xvdd, shadow->srb, shadow->offset);
   3.390 +    }
   3.391 +    
   3.392 +    xvdd->device_state->resume_state = RESUME_STATE_RUNNING;
   3.393 +    
   3.394 +    if (i == 0)
   3.395 +    {
   3.396 +      /* no requests, so we might need to tell scsiport that we can accept a new one if we deferred one earlier */
   3.397 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   3.398 +    }
   3.399 +  }
   3.400 +  
   3.401 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, RESUME_CHECK_TIMER_INTERVAL);
   3.402 +}
   3.403 +
   3.404 +static ULONG DDKAPI
   3.405 +XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
   3.406 +{
   3.407 +//  PACCESS_RANGE AccessRange;
   3.408 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   3.409 +  ULONG status;
   3.410 +//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
   3.411 +  PACCESS_RANGE access_range;
   3.412 +
   3.413 +  UNREFERENCED_PARAMETER(HwContext);
   3.414 +  UNREFERENCED_PARAMETER(BusInformation);
   3.415 +  UNREFERENCED_PARAMETER(ArgumentString);
   3.416 +
   3.417 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
   3.418 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   3.419 +
   3.420 +  *Again = FALSE;
   3.421 +
   3.422 +  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
   3.423 +  KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
   3.424 +
   3.425 +  if (ConfigInfo->NumberOfAccessRanges != 1)
   3.426 +  {
   3.427 +    KdPrint((__DRIVER_NAME "     NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));    
   3.428 +    return SP_RETURN_BAD_CONFIG;
   3.429 +  }
   3.430 +
   3.431 +  access_range = &((*(ConfigInfo->AccessRanges))[0]);
   3.432 +
   3.433 +  KdPrint((__DRIVER_NAME "     RangeStart = %08x, RangeLength = %08x\n",
   3.434 +    access_range->RangeStart.LowPart, access_range->RangeLength));
   3.435 +
   3.436 +  xvdd->device_base = ScsiPortGetDeviceBase(
   3.437 +    DeviceExtension,
   3.438 +    ConfigInfo->AdapterInterfaceType,
   3.439 +    ConfigInfo->SystemIoBusNumber,
   3.440 +    access_range->RangeStart,
   3.441 +    access_range->RangeLength,
   3.442 +    !access_range->RangeInMemory);
   3.443 +  if (xvdd->device_base == NULL)
   3.444 +  {
   3.445 +    KdPrint((__DRIVER_NAME "     Unable to map range\n"));
   3.446 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   3.447 +    return SP_RETURN_BAD_CONFIG;
   3.448 +  }
   3.449 +
   3.450 +  status = XenVbd_InitFromConfig(xvdd);
   3.451 +  if (status != SP_RETURN_FOUND)
   3.452 +    return status;
   3.453 +  
   3.454 +  ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
   3.455 +  ConfigInfo->NumberOfPhysicalBreaks = 0; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
   3.456 +  ConfigInfo->ScatterGather = TRUE;
   3.457 +  ConfigInfo->AlignmentMask = 0;
   3.458 +  ConfigInfo->NumberOfBuses = 1;
   3.459 +  ConfigInfo->InitiatorBusId[0] = 1;
   3.460 +  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
   3.461 +  ConfigInfo->MaximumNumberOfTargets = 2;
   3.462 +  ConfigInfo->BufferAccessScsiPortControlled = TRUE;
   3.463 +  if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
   3.464 +  {
   3.465 +    ConfigInfo->Master = TRUE;
   3.466 +    ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
   3.467 +    KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
   3.468 +  }
   3.469 +  else
   3.470 +  {
   3.471 +    ConfigInfo->Master = FALSE;
   3.472 +    KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
   3.473 +  }
   3.474 +
   3.475 +  xvdd->ring_detect_state = 0;
   3.476 +
   3.477 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   3.478 +
   3.479 +  return SP_RETURN_FOUND;
   3.480 +}
   3.481 +
   3.482 +static BOOLEAN DDKAPI
   3.483 +XenVbd_HwScsiInitialize(PVOID DeviceExtension)
   3.484 +{
   3.485 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   3.486 +  blkif_request_t *req;
   3.487 +  int i;
   3.488 +  int notify;
   3.489 +  
   3.490 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.491 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   3.492 +
   3.493 +  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
   3.494 +  req->operation = 0xff;
   3.495 +  req->nr_segments = 0;
   3.496 +  for (i = 0; i < BLKIF_MAX_SEGMENTS_PER_REQUEST; i++)
   3.497 +  {
   3.498 +    req->seg[i].gref = 0; //0xffffffff;
   3.499 +    req->seg[i].first_sect = 0; //0xff;
   3.500 +    req->seg[i].last_sect = 0; //0xff;
   3.501 +  }
   3.502 +  xvdd->ring.req_prod_pvt++;
   3.503 +
   3.504 +  req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
   3.505 +  req->operation = 0xff;
   3.506 +  req->nr_segments = 0;
   3.507 +  for (i = 0; i < BLKIF_MAX_SEGMENTS_PER_REQUEST; i++)
   3.508 +  {
   3.509 +    req->seg[i].gref = 0; //0xffffffff;
   3.510 +    req->seg[i].first_sect = 0; //0xff;
   3.511 +    req->seg[i].last_sect = 0; //0xff;
   3.512 +  }
   3.513 +  xvdd->ring.req_prod_pvt++;
   3.514 +
   3.515 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
   3.516 +  if (notify)
   3.517 +    xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   3.518 +
   3.519 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_HwScsiTimer, RESUME_CHECK_TIMER_INTERVAL);
   3.520 +
   3.521 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.522 +
   3.523 +  return TRUE;
   3.524 +}
   3.525 +
   3.526 +static ULONG
   3.527 +XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
   3.528 +{
   3.529 +  PCDB cdb;
   3.530 +  PMODE_PARAMETER_HEADER parameter_header;
   3.531 +  PMODE_PARAMETER_BLOCK param_block;
   3.532 +  PMODE_FORMAT_PAGE format_page;
   3.533 +  UCHAR page_code;
   3.534 +  ULONG offset;
   3.535 +  UCHAR buffer[256];
   3.536 +  BOOLEAN valid_page = FALSE;
   3.537 +
   3.538 +  UNREFERENCED_PARAMETER(xvdd);
   3.539 +
   3.540 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.541 +  
   3.542 +  cdb = (PCDB)srb->Cdb;
   3.543 +  page_code = cdb->MODE_SENSE.PageCode;
   3.544 +  offset = 0;
   3.545 +  RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
   3.546 +  RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
   3.547 +
   3.548 +  parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
   3.549 +  parameter_header->MediumType = 0;
   3.550 +  parameter_header->DeviceSpecificParameter = 0;
   3.551 +  parameter_header->BlockDescriptorLength = 0;
   3.552 +  offset += sizeof(MODE_PARAMETER_HEADER);
   3.553 +  
   3.554 +  if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
   3.555 +  {
   3.556 +    KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
   3.557 +    parameter_header->DeviceSpecificParameter|=MODE_DSP_WRITE_PROTECT; 
   3.558 +  }
   3.559 +  
   3.560 +  if (!cdb->MODE_SENSE.Dbd)
   3.561 +  {
   3.562 +    parameter_header->BlockDescriptorLength += sizeof(MODE_PARAMETER_BLOCK);
   3.563 +    param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
   3.564 +    if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
   3.565 +    {
   3.566 +      if (xvdd->total_sectors >> 32) 
   3.567 +      {
   3.568 +        param_block->DensityCode = 0xff;
   3.569 +        param_block->NumberOfBlocks[0] = 0xff;
   3.570 +        param_block->NumberOfBlocks[1] = 0xff;
   3.571 +        param_block->NumberOfBlocks[2] = 0xff;
   3.572 +      }
   3.573 +      else
   3.574 +      {
   3.575 +        param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
   3.576 +        param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
   3.577 +        param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
   3.578 +        param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
   3.579 +      }
   3.580 +      param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
   3.581 +      param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
   3.582 +      param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
   3.583 +    }
   3.584 +    offset += sizeof(MODE_PARAMETER_BLOCK);
   3.585 +  }
   3.586 +  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (page_code == MODE_PAGE_FORMAT_DEVICE || page_code == MODE_SENSE_RETURN_ALL))
   3.587 +  {
   3.588 +    valid_page = TRUE;
   3.589 +    format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
   3.590 +    format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
   3.591 +    format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
   3.592 +    /* 256 sectors per track */
   3.593 +    format_page->SectorsPerTrack[0] = 0x01;
   3.594 +    format_page->SectorsPerTrack[1] = 0x00;
   3.595 +    /* xxx bytes per sector */
   3.596 +    format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
   3.597 +    format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
   3.598 +    format_page->HardSectorFormating = TRUE;
   3.599 +    format_page->SoftSectorFormating = TRUE;
   3.600 +    offset += sizeof(MODE_FORMAT_PAGE);
   3.601 +  }
   3.602 +  parameter_header->ModeDataLength = (UCHAR)(offset - 1);
   3.603 +  if (!valid_page && page_code != MODE_SENSE_RETURN_ALL)
   3.604 +  {
   3.605 +    srb->SrbStatus = SRB_STATUS_ERROR;
   3.606 +  }
   3.607 +  else if(offset < srb->DataTransferLength)
   3.608 +    srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
   3.609 +  else
   3.610 +    srb->SrbStatus = SRB_STATUS_SUCCESS;
   3.611 +  srb->DataTransferLength = min(srb->DataTransferLength, offset);
   3.612 +  srb->ScsiStatus = 0;
   3.613 +  memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
   3.614 +  
   3.615 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.616 +
   3.617 +  return TRUE;
   3.618 +}
   3.619 +
   3.620 +static VOID
   3.621 +XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
   3.622 +{
   3.623 +  PSENSE_DATA sd = srb->SenseInfoBuffer;
   3.624 + 
   3.625 +  UNREFERENCED_PARAMETER(xvdd);
   3.626 +  
   3.627 +  if (!srb->SenseInfoBuffer)
   3.628 +    return;
   3.629 +  
   3.630 +  sd->ErrorCode = 0x70;
   3.631 +  sd->Valid = 1;
   3.632 +  sd->SenseKey = sense_key;
   3.633 +  sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
   3.634 +  sd->AdditionalSenseCode = additional_sense_code;
   3.635 +  return;
   3.636 +}
   3.637 +
   3.638 +static VOID
   3.639 +XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
   3.640 +{
   3.641 +  if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
   3.642 +    return;
   3.643 +  XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
   3.644 +  srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
   3.645 +}
   3.646 +
   3.647 +static BOOLEAN DDKAPI
   3.648 +XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
   3.649 +{
   3.650 +  PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   3.651 +  PSCSI_REQUEST_BLOCK srb;
   3.652 +  RING_IDX i, rp;
   3.653 +  int j;
   3.654 +  blkif_response_t *rep;
   3.655 +  int block_count;
   3.656 +  int more_to_do = TRUE;
   3.657 +  blkif_shadow_t *shadow;
   3.658 +  ULONG offset;
   3.659 +
   3.660 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.661 +
   3.662 +  /* in dump mode I think we get called on a timer, not by an actual IRQ */
   3.663 +  if (!dump_mode && !xvdd->vectors.EvtChn_AckEvent(xvdd->vectors.context, xvdd->event_channel))
   3.664 +    return FALSE; /* interrupt was not for us */
   3.665 +  if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
   3.666 +  {
   3.667 +    //KdPrint((__DRIVER_NAME " --- " __FUNCTION__ " device_state event\n"));
   3.668 +    xvdd->device_state->resume_state_ack = xvdd->device_state->resume_state;
   3.669 +    KeMemoryBarrier();
   3.670 +    return FALSE;
   3.671 +  }
   3.672 +
   3.673 +  xvdd->interrupts++;
   3.674 +  while (more_to_do)
   3.675 +  {
   3.676 +    rp = xvdd->ring.sring->rsp_prod;
   3.677 +    KeMemoryBarrier();
   3.678 +    for (i = xvdd->ring.rsp_cons; i != rp; i++)
   3.679 +    {
   3.680 +      rep = XenVbd_GetResponse(xvdd, i);
   3.681 +/*
   3.682 +* This code is to automatically detect if the backend is using the same
   3.683 +* bit width or a different bit width to us. Later versions of Xen do this
   3.684 +* via a xenstore value, but not all. That 0x0fffffff (notice
   3.685 +* that the msb is not actually set, so we don't have any problems with
   3.686 +* sign extending) is to signify the last entry on the right, which is
   3.687 +* different under 32 and 64 bits, and that is why we set it up there.
   3.688 +
   3.689 +* To do the detection, we put two initial entries on the ring, with an op
   3.690 +* of 0xff (which is invalid). The first entry is mostly okay, but the
   3.691 +* second will be grossly misaligned if the backend bit width is different,
   3.692 +* and we detect this and switch frontend structures.
   3.693 +*/
   3.694 +      switch (xvdd->ring_detect_state)
   3.695 +      {
   3.696 +      case 0:
   3.697 +        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
   3.698 +        xvdd->ring_detect_state = 1;
   3.699 +        break;
   3.700 +      case 1:
   3.701 +        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
   3.702 +        if (rep->operation != 0xff)
   3.703 +        {
   3.704 +          xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
   3.705 +          xvdd->use_other = TRUE;
   3.706 +        }
   3.707 +        xvdd->ring_detect_state = 2;
   3.708 +        ScsiPortNotification(NextRequest, DeviceExtension);
   3.709 +        break;
   3.710 +      case 2:
   3.711 +        //KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
   3.712 +        shadow = &xvdd->shadows[rep->id];
   3.713 +        srb = shadow->srb;
   3.714 +        ASSERT(srb != NULL);
   3.715 +        block_count = (srb->Cdb[7] << 8) | srb->Cdb[8];
   3.716 +        block_count *= xvdd->bytes_per_sector / 512;
   3.717 +        if (rep->status == BLKIF_RSP_OKAY)
   3.718 +          srb->SrbStatus = SRB_STATUS_SUCCESS;
   3.719 +        else
   3.720 +        {
   3.721 +          KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
   3.722 +          if (srb->Cdb[0] == SCSIOP_READ)
   3.723 +            KdPrint((__DRIVER_NAME "     Operation = Read\n"));
   3.724 +          else
   3.725 +            KdPrint((__DRIVER_NAME "     Operation = Write\n"));     
   3.726 +          KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", shadow->req.sector_number, block_count));
   3.727 +          srb->SrbStatus = SRB_STATUS_ERROR;
   3.728 +          srb->ScsiStatus = 0x02;
   3.729 +          xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
   3.730 +          xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
   3.731 +          XenVbd_MakeAutoSense(xvdd, srb);
   3.732 +        }
   3.733 +        for (j = 0; j < shadow->req.nr_segments; j++)
   3.734 +        {
   3.735 +          BOOLEAN result = xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context, shadow->req.seg[j].gref, TRUE);
   3.736 +          ASSERT(result);
   3.737 +          put_grant_on_freelist(xvdd, shadow->req.seg[j].gref);
   3.738 +        }
   3.739 +
   3.740 +        if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
   3.741 +        {
   3.742 +          if (srb->Cdb[0] == SCSIOP_READ)
   3.743 +            memcpy(((PUCHAR)srb->DataBuffer) + shadow->offset, GET_PAGE_ALIGNED(srb->SrbExtension), shadow->length);
   3.744 +          offset = shadow->offset + shadow->length;
   3.745 +          put_shadow_on_freelist(xvdd, shadow);
   3.746 +          if (offset == block_count * xvdd->bytes_per_sector)
   3.747 +          {
   3.748 +            ScsiPortNotification(RequestComplete, xvdd, srb);
   3.749 +            ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   3.750 +          }
   3.751 +          else
   3.752 +          {
   3.753 +            XenVbd_PutSrbOnRing(xvdd, srb, offset);
   3.754 +          }
   3.755 +        }
   3.756 +        else
   3.757 +        {
   3.758 +          put_shadow_on_freelist(xvdd, shadow);
   3.759 +          ScsiPortNotification(RequestComplete, xvdd, srb);
   3.760 +          if (xvdd->pending_srb)
   3.761 +          {
   3.762 +            srb = xvdd->pending_srb;
   3.763 +            xvdd->pending_srb = NULL;
   3.764 +            XenVbd_PutSrbOnRing(xvdd, srb, 0);
   3.765 +          }
   3.766 +          else
   3.767 +            ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   3.768 +        }
   3.769 +        break;
   3.770 +      }
   3.771 +    }
   3.772 +
   3.773 +    xvdd->ring.rsp_cons = i;
   3.774 +    if (i != xvdd->ring.req_prod_pvt)
   3.775 +    {
   3.776 +      RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
   3.777 +    }
   3.778 +    else
   3.779 +    {
   3.780 +      xvdd->ring.sring->rsp_event = i + 1;
   3.781 +      more_to_do = FALSE;
   3.782 +    }
   3.783 +  }
   3.784 +
   3.785 +  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_prod = %d\n", xvdd->ring.sring->rsp_prod));
   3.786 +  //KdPrint((__DRIVER_NAME "     ring.sring->rsp_event = %d\n", xvdd->ring.sring->rsp_event));
   3.787 +  //KdPrint((__DRIVER_NAME "     ring.rsp_cons = %d\n", xvdd->ring.rsp_cons));
   3.788 +  //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
   3.789 +
   3.790 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.791 +
   3.792 +  return FALSE; /* we just don't know... */
   3.793 +}
   3.794 +
   3.795 +static BOOLEAN DDKAPI
   3.796 +XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   3.797 +{
   3.798 +  PUCHAR DataBuffer;
   3.799 +  PCDB cdb;
   3.800 +  PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
   3.801 +
   3.802 +  //KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
   3.803 +
   3.804 +  // If we haven't enumerated all the devices yet then just defer the request
   3.805 +  if (xvdd->ring_detect_state < 2)
   3.806 +  {
   3.807 +    Srb->SrbStatus = SRB_STATUS_BUSY;
   3.808 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   3.809 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Still figuring out ring)\n"));
   3.810 +    return TRUE;
   3.811 +  }
   3.812 +
   3.813 +  if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
   3.814 +  {
   3.815 +    Srb->SrbStatus = SRB_STATUS_BUSY;
   3.816 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   3.817 +    //KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Resuming)\n"));
   3.818 +    return TRUE;
   3.819 +  }
   3.820 +
   3.821 +  if (Srb->PathId != 0 || Srb->TargetId != 0)
   3.822 +  {
   3.823 +    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
   3.824 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   3.825 +    ScsiPortNotification(NextRequest, DeviceExtension);
   3.826 +    KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
   3.827 +    return TRUE;
   3.828 +  }
   3.829 +
   3.830 +  switch (Srb->Function)
   3.831 +  {
   3.832 +  case SRB_FUNCTION_EXECUTE_SCSI:
   3.833 +    cdb = (PCDB)Srb->Cdb;
   3.834 +//    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_EXECUTE_SCSI\n"));
   3.835 +
   3.836 +    switch(cdb->CDB6GENERIC.OperationCode)
   3.837 +    {
   3.838 +    case SCSIOP_TEST_UNIT_READY:
   3.839 +      //KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
   3.840 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   3.841 +      Srb->ScsiStatus = 0;
   3.842 +      break;
   3.843 +    case SCSIOP_INQUIRY:
   3.844 +//      KdPrint((__DRIVER_NAME "     Command = INQUIRY\n"));
   3.845 +//      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
   3.846 +//      KdPrint((__DRIVER_NAME "     (Length = %d)\n", Srb->DataTransferLength));
   3.847 +//      KdPrint((__DRIVER_NAME "     (Srb->Databuffer = %08x)\n", Srb->DataBuffer));
   3.848 +      DataBuffer = Srb->DataBuffer;
   3.849 +      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
   3.850 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   3.851 +      switch (xvdd->device_type)
   3.852 +      {
   3.853 +      case XENVBD_DEVICETYPE_DISK:
   3.854 +        if ((Srb->Cdb[1] & 1) == 0)
   3.855 +        {
   3.856 +          PINQUIRYDATA id = (PINQUIRYDATA)DataBuffer;
   3.857 +          id->DeviceType = DIRECT_ACCESS_DEVICE;
   3.858 +          id->Versions = 3;
   3.859 +          id->ResponseDataFormat = 0;
   3.860 +          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
   3.861 +          id->CommandQueue = 1;
   3.862 +          memcpy(id->VendorId, "XEN     ", 8); // vendor id
   3.863 +          memcpy(id->ProductId, "PV DISK         ", 16); // product id
   3.864 +          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
   3.865 +        }
   3.866 +        else
   3.867 +        {
   3.868 +          switch (Srb->Cdb[2])
   3.869 +          {
   3.870 +          case 0x00:
   3.871 +            DataBuffer[0] = DIRECT_ACCESS_DEVICE;
   3.872 +            DataBuffer[1] = 0x00;
   3.873 +            DataBuffer[2] = 0x00;
   3.874 +            DataBuffer[3] = 2;
   3.875 +            DataBuffer[4] = 0x00;
   3.876 +            DataBuffer[5] = 0x80;
   3.877 +            break;
   3.878 +          case 0x80:
   3.879 +            DataBuffer[0] = DIRECT_ACCESS_DEVICE;
   3.880 +            DataBuffer[1] = 0x80;
   3.881 +            DataBuffer[2] = 0x00;
   3.882 +            DataBuffer[3] = 8;
   3.883 +            memset(&DataBuffer[4], ' ', 8);
   3.884 +            break;
   3.885 +          default:
   3.886 +            //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
   3.887 +            Srb->SrbStatus = SRB_STATUS_ERROR;
   3.888 +            break;
   3.889 +          }
   3.890 +        }
   3.891 +        break;
   3.892 +      case XENVBD_DEVICETYPE_CDROM:
   3.893 +        if ((Srb->Cdb[1] & 1) == 0)
   3.894 +        {
   3.895 +          PINQUIRYDATA id = (PINQUIRYDATA)DataBuffer;
   3.896 +          id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
   3.897 +          id->RemovableMedia = 1;
   3.898 +          id->Versions = 3;
   3.899 +          id->ResponseDataFormat = 0;
   3.900 +          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
   3.901 +          id->CommandQueue = 1;
   3.902 +          memcpy(id->VendorId, "XEN     ", 8); // vendor id
   3.903 +          memcpy(id->ProductId, "PV CDROM        ", 16); // product id
   3.904 +          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
   3.905 +        }
   3.906 +        else
   3.907 +        {
   3.908 +          switch (Srb->Cdb[2])
   3.909 +          {
   3.910 +          case 0x00:
   3.911 +            DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
   3.912 +            DataBuffer[1] = 0x00;
   3.913 +            DataBuffer[2] = 0x00;
   3.914 +            DataBuffer[3] = 2;
   3.915 +            DataBuffer[4] = 0x00;
   3.916 +            DataBuffer[5] = 0x80;
   3.917 +            break;
   3.918 +          case 0x80:
   3.919 +            DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
   3.920 +            DataBuffer[1] = 0x80;
   3.921 +            DataBuffer[2] = 0x00;
   3.922 +            DataBuffer[3] = 8;
   3.923 +            DataBuffer[4] = 0x31;
   3.924 +            DataBuffer[5] = 0x32;
   3.925 +            DataBuffer[6] = 0x33;
   3.926 +            DataBuffer[7] = 0x34;
   3.927 +            DataBuffer[8] = 0x35;
   3.928 +            DataBuffer[9] = 0x36;
   3.929 +            DataBuffer[10] = 0x37;
   3.930 +            DataBuffer[11] = 0x38;
   3.931 +            break;
   3.932 +          default:
   3.933 +            //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", Srb->Cdb[2]));
   3.934 +            Srb->SrbStatus = SRB_STATUS_ERROR;
   3.935 +            break;
   3.936 +          }
   3.937 +        }
   3.938 +        break;
   3.939 +      default:
   3.940 +        //KdPrint((__DRIVER_NAME "     Unknown DeviceType %02x requested\n", xvdd->device_type));
   3.941 +        Srb->SrbStatus = SRB_STATUS_ERROR;
   3.942 +        break;
   3.943 +      }
   3.944 +      break;
   3.945 +    case SCSIOP_READ_CAPACITY:
   3.946 +      //KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
   3.947 +      //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", Srb->Cdb[1] >> 4, Srb->Cdb[1] & 1));
   3.948 +      //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", Srb->Cdb[2], Srb->Cdb[3], Srb->Cdb[4], Srb->Cdb[5]));
   3.949 +      //KdPrint((__DRIVER_NAME "       PMI = %d\n", Srb->Cdb[8] & 1));
   3.950 +      DataBuffer = Srb->DataBuffer;
   3.951 +      RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
   3.952 +      if ((xvdd->total_sectors - 1) >> 32)
   3.953 +      {
   3.954 +        DataBuffer[0] = 0xff;
   3.955 +        DataBuffer[1] = 0xff;
   3.956 +        DataBuffer[2] = 0xff;
   3.957 +        DataBuffer[3] = 0xff;
   3.958 +      }
   3.959 +      else
   3.960 +      {
   3.961 +        DataBuffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
   3.962 +        DataBuffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
   3.963 +        DataBuffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
   3.964 +        DataBuffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
   3.965 +      }
   3.966 +      DataBuffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
   3.967 +      DataBuffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
   3.968 +      DataBuffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
   3.969 +      DataBuffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
   3.970 +      Srb->ScsiStatus = 0;
   3.971 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   3.972 +      break;
   3.973 +    case SCSIOP_MODE_SENSE:
   3.974 +//      KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x08, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
   3.975 +      XenVbd_FillModePage(xvdd, Srb);
   3.976 +      break;
   3.977 +    case SCSIOP_WRITE:
   3.978 +    case SCSIOP_READ:
   3.979 +//      KdPrint((__DRIVER_NAME "     Command = READ/WRITE\n"));
   3.980 +      XenVbd_PutSrbOnRing(xvdd, Srb, 0);
   3.981 +      break;
   3.982 +    case SCSIOP_VERIFY:
   3.983 +      // Should we do more here?
   3.984 +//      KdPrint((__DRIVER_NAME "     Command = VERIFY\n"));
   3.985 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   3.986 +      break;
   3.987 +    case SCSIOP_REPORT_LUNS:
   3.988 +//      KdPrint((__DRIVER_NAME "     Command = REPORT_LUNS\n"));
   3.989 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;;
   3.990 +      break;
   3.991 +    case SCSIOP_REQUEST_SENSE:
   3.992 +//      KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
   3.993 +      XenVbd_MakeSense(xvdd, Srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
   3.994 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
   3.995 +      break;      
   3.996 +    case SCSIOP_READ_TOC:
   3.997 +      DataBuffer = Srb->DataBuffer;
   3.998 +//      DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
   3.999 +/*
  3.1000 +#define READ_TOC_FORMAT_TOC         0x00
  3.1001 +#define READ_TOC_FORMAT_SESSION     0x01
  3.1002 +#define READ_TOC_FORMAT_FULL_TOC    0x02
  3.1003 +#define READ_TOC_FORMAT_PMA         0x03
  3.1004 +#define READ_TOC_FORMAT_ATIP        0x04
  3.1005 +*/
  3.1006 +//      KdPrint((__DRIVER_NAME "     Command = READ_TOC\n"));
  3.1007 +//      KdPrint((__DRIVER_NAME "     Msf = %d\n", cdb->READ_TOC.Msf));
  3.1008 +//      KdPrint((__DRIVER_NAME "     LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
  3.1009 +//      KdPrint((__DRIVER_NAME "     Format2 = %d\n", cdb->READ_TOC.Format2));
  3.1010 +//      KdPrint((__DRIVER_NAME "     StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
  3.1011 +//      KdPrint((__DRIVER_NAME "     AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
  3.1012 +//      KdPrint((__DRIVER_NAME "     Control = %d\n", cdb->READ_TOC.Control));
  3.1013 +//      KdPrint((__DRIVER_NAME "     Format = %d\n", cdb->READ_TOC.Format));
  3.1014 +      switch (cdb->READ_TOC.Format2)
  3.1015 +      {
  3.1016 +      case READ_TOC_FORMAT_TOC:
  3.1017 +        DataBuffer[0] = 0; // length MSB
  3.1018 +        DataBuffer[1] = 10; // length LSB
  3.1019 +        DataBuffer[2] = 1; // First Track
  3.1020 +        DataBuffer[3] = 1; // Last Track
  3.1021 +        DataBuffer[4] = 0; // Reserved
  3.1022 +        DataBuffer[5] = 0x14; // current position data + uninterrupted data
  3.1023 +        DataBuffer[6] = 1; // last complete track
  3.1024 +        DataBuffer[7] = 0; // reserved
  3.1025 +        DataBuffer[8] = 0; // MSB Block
  3.1026 +        DataBuffer[9] = 0;
  3.1027 +        DataBuffer[10] = 0;
  3.1028 +        DataBuffer[11] = 0; // LSB Block
  3.1029 +        Srb->SrbStatus = SRB_STATUS_SUCCESS;
  3.1030 +        break;
  3.1031 +      case READ_TOC_FORMAT_SESSION:
  3.1032 +      case READ_TOC_FORMAT_FULL_TOC:
  3.1033 +      case READ_TOC_FORMAT_PMA:
  3.1034 +      case READ_TOC_FORMAT_ATIP:
  3.1035 +        Srb->SrbStatus = SRB_STATUS_ERROR;
  3.1036 +        break;
  3.1037 +      }
  3.1038 +      break;
  3.1039 +    case SCSIOP_START_STOP_UNIT:
  3.1040 +//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_START_STOP_UNIT\n"));
  3.1041 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  3.1042 +      break;
  3.1043 +    case SCSIOP_RESERVE_UNIT:
  3.1044 +//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RESERVE_UNIT\n"));
  3.1045 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  3.1046 +      break;
  3.1047 +    case SCSIOP_RELEASE_UNIT:
  3.1048 +//      KdPrint((__DRIVER_NAME "     Command = SCSIOP_RELEASE_UNIT\n"));
  3.1049 +      Srb->SrbStatus = SRB_STATUS_SUCCESS;
  3.1050 +      break;
  3.1051 +    default:
  3.1052 +      //KdPrint((__DRIVER_NAME "     Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
  3.1053 +      Srb->SrbStatus = SRB_STATUS_ERROR;
  3.1054 +      break;
  3.1055 +    }
  3.1056 +    if (Srb->SrbStatus == SRB_STATUS_ERROR)
  3.1057 +    {
  3.1058 +      //KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", Srb->Cdb[0], xvdd->last_sense_key));
  3.1059 +      if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
  3.1060 +      {
  3.1061 +        xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
  3.1062 +        xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
  3.1063 +      }
  3.1064 +      Srb->ScsiStatus = 0x02;
  3.1065 +      XenVbd_MakeAutoSense(xvdd, Srb);
  3.1066 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  3.1067 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  3.1068 +    }
  3.1069 +    else if (Srb->SrbStatus != SRB_STATUS_PENDING)
  3.1070 +    {
  3.1071 +      xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
  3.1072 +      xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
  3.1073 +      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  3.1074 +      ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  3.1075 +    }
  3.1076 +    break;
  3.1077 +  case SRB_FUNCTION_IO_CONTROL:
  3.1078 +    //KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
  3.1079 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  3.1080 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  3.1081 +    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  3.1082 +    break;
  3.1083 +  case SRB_FUNCTION_FLUSH:
  3.1084 +    //KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
  3.1085 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  3.1086 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  3.1087 +    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  3.1088 +    break;
  3.1089 +  default:
  3.1090 +    //KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
  3.1091 +    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  3.1092 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
  3.1093 +    ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
  3.1094 +    break;
  3.1095 +  }
  3.1096 +
  3.1097 +  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  3.1098 +  return TRUE;
  3.1099 +}
  3.1100 +
  3.1101 +static BOOLEAN DDKAPI
  3.1102 +XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
  3.1103 +{
  3.1104 +  UNREFERENCED_PARAMETER(DeviceExtension);
  3.1105 +  UNREFERENCED_PARAMETER(PathId);
  3.1106 +
  3.1107 +  KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
  3.1108 +
  3.1109 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  3.1110 +  ScsiPortNotification(NextRequest, DeviceExtension);
  3.1111 +
  3.1112 +  KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
  3.1113 +
  3.1114 +
  3.1115 +  return TRUE;
  3.1116 +}
  3.1117 +
  3.1118 +static BOOLEAN DDKAPI
  3.1119 +XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
  3.1120 +{
  3.1121 +  UNREFERENCED_PARAMETER(DeviceExtension);
  3.1122 +  UNREFERENCED_PARAMETER(Context);
  3.1123 +  UNREFERENCED_PARAMETER(SaveState);
  3.1124 +
  3.1125 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
  3.1126 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  3.1127 +
  3.1128 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  3.1129 +
  3.1130 +  return TRUE;
  3.1131 +}
  3.1132 +
  3.1133 +static SCSI_ADAPTER_CONTROL_STATUS DDKAPI
  3.1134 +XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
  3.1135 +{
  3.1136 +  SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
  3.1137 +  PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
  3.1138 +  //KIRQL OldIrql;
  3.1139 +
  3.1140 +  UNREFERENCED_PARAMETER(DeviceExtension);
  3.1141 +
  3.1142 +  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
  3.1143 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  3.1144 +
  3.1145 +  switch (ControlType)
  3.1146 +  {
  3.1147 +  case ScsiQuerySupportedControlTypes:
  3.1148 +    SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
  3.1149 +    KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
  3.1150 +    SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
  3.1151 +    SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
  3.1152 +    SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
  3.1153 +    break;
  3.1154 +  case ScsiStopAdapter:
  3.1155 +    KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
  3.1156 +    /* I don't think we actually have to do anything here... xenpci cleans up all the xenbus stuff for us */
  3.1157 +    break;
  3.1158 +  case ScsiRestartAdapter:
  3.1159 +    KdPrint((__DRIVER_NAME "     ScsiRestartAdapter\n"));
  3.1160 +    break;
  3.1161 +  case ScsiSetBootConfig:
  3.1162 +    KdPrint((__DRIVER_NAME "     ScsiSetBootConfig\n"));
  3.1163 +    break;
  3.1164 +  case ScsiSetRunningConfig:
  3.1165 +    KdPrint((__DRIVER_NAME "     ScsiSetRunningConfig\n"));
  3.1166 +    break;
  3.1167 +  default:
  3.1168 +    KdPrint((__DRIVER_NAME "     UNKNOWN\n"));
  3.1169 +    break;
  3.1170 +  }
  3.1171 +
  3.1172 +  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
  3.1173 +
  3.1174 +  return Status;
  3.1175 +}
  3.1176 +
  3.1177  NTSTATUS
  3.1178  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
  3.1179  {
  3.1180 @@ -47,7 +1217,10 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  3.1181  
  3.1182    conf_info = IoGetConfigurationInformation();
  3.1183    KdPrint((__DRIVER_NAME "     conf_info->DiskCount = %d\n", conf_info->DiskCount));
  3.1184 -  if (conf_info->DiskCount)
  3.1185 +  /* RegistryPath == NULL when we are invoked as a crash dump driver */
  3.1186 +  if (!RegistryPath)
  3.1187 +    dump_mode = TRUE;
  3.1188 +  if (conf_info->DiskCount && RegistryPath)
  3.1189    {
  3.1190      KdPrint((__DRIVER_NAME "     Not loaded at boot time so not loading\n"));
  3.1191      KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  3.1192 @@ -74,7 +1247,14 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  3.1193    HwInitializationData.DeviceIdLength = 0;
  3.1194    HwInitializationData.DeviceId = NULL;
  3.1195  
  3.1196 -  XenVbd_FillInitCallbacks(&HwInitializationData);
  3.1197 +  HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
  3.1198 +  HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
  3.1199 +  HwInitializationData.HwInterrupt = XenVbd_HwScsiInterrupt;
  3.1200 +  HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
  3.1201 +  HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
  3.1202 +  HwInitializationData.HwDmaStarted = NULL;
  3.1203 +  HwInitializationData.HwAdapterState = XenVbd_HwScsiAdapterState;
  3.1204 +  HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
  3.1205  
  3.1206    status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
  3.1207    
  3.1208 @@ -87,3 +1267,4 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
  3.1209  
  3.1210    return status;
  3.1211  }
  3.1212 +
     4.1 --- a/xenvbd/xenvbd.h	Wed Aug 20 21:36:59 2008 +1000
     4.2 +++ b/xenvbd/xenvbd.h	Thu Aug 21 13:44:24 2008 +1000
     4.3 @@ -145,8 +145,5 @@ struct
     4.4    ULONGLONG no_free_grant_requests;
     4.5  } typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
     4.6  
     4.7 -VOID
     4.8 -XenVbd_FillInitCallbacks(PHW_INITIALIZATION_DATA HwInitializationData);
     4.9 -
    4.10  #endif
    4.11