win-pvdrivers

changeset 473:3c592df57caf

Updated xenscsi to be a storport driver. It won't work under XP or earlier but it does work under 2003 now.
author James Harper <james.harper@bendigoit.com.au>
date Tue Dec 02 20:58:26 2008 +1100 (2008-12-02)
parents babd1ef136ac
children 3d4ed6b566a0
files xenscsi/xenscsi.c xenscsi/xenscsi.h
line diff
     1.1 --- a/xenscsi/xenscsi.c	Thu Nov 27 21:24:20 2008 +1100
     1.2 +++ b/xenscsi/xenscsi.c	Tue Dec 02 20:58:26 2008 +1100
     1.3 @@ -70,7 +70,19 @@ put_grant_on_freelist(PXENSCSI_DEVICE_DA
     1.4  }
     1.5  
     1.6  static BOOLEAN
     1.7 -XenScsi_HwScsiInterrupt(PVOID DeviceExtension)
     1.8 +XenScsi_HwStorInterrupt(PVOID DeviceExtension)
     1.9 +{
    1.10 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
    1.11 +  if (!dump_mode && !xsdd->vectors.EvtChn_AckEvent(xsdd->vectors.context, xsdd->event_channel))
    1.12 +    return FALSE;
    1.13 +  
    1.14 +  StorPortIssueDpc(DeviceExtension, &xsdd->dpc, NULL, NULL);
    1.15 +  
    1.16 +  return FALSE;
    1.17 +}
    1.18 +
    1.19 +static VOID
    1.20 +XenScsi_HwStorDpc(PSTOR_DPC Dpc, PVOID DeviceExtension, PVOID SystemArgument1, PVOID SystemArgument2)
    1.21  {
    1.22    PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
    1.23    PSCSI_REQUEST_BLOCK Srb;
    1.24 @@ -80,11 +92,14 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    1.25    int more_to_do = TRUE;
    1.26    vscsiif_shadow_t *shadow;
    1.27    ULONG remaining;
    1.28 -
    1.29 -  FUNCTION_ENTER();
    1.30 +  STOR_LOCK_HANDLE lock_handle;
    1.31  
    1.32 -  if (!dump_mode && !xsdd->vectors.EvtChn_AckEvent(xsdd->vectors.context, xsdd->event_channel))
    1.33 -    return FALSE;
    1.34 +  UNREFERENCED_PARAMETER(Dpc);
    1.35 +  UNREFERENCED_PARAMETER(SystemArgument1);
    1.36 +  UNREFERENCED_PARAMETER(SystemArgument2);
    1.37 +  //FUNCTION_ENTER();
    1.38 +
    1.39 +  StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
    1.40  
    1.41    while (more_to_do)
    1.42    {
    1.43 @@ -94,19 +109,23 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    1.44      {
    1.45        rep = RING_GET_RESPONSE(&xsdd->ring, i);
    1.46        shadow = &xsdd->shadows[rep->rqid];
    1.47 -      KdPrint((__DRIVER_NAME "     Operation complete - result = 0x%08x\n", rep->rslt));
    1.48        Srb = shadow->Srb;
    1.49        Srb->ScsiStatus = (UCHAR)rep->rslt;
    1.50        if (rep->sense_len > 0 && Srb->SenseInfoBuffer != NULL)
    1.51        {
    1.52          memcpy(Srb->SenseInfoBuffer, rep->sense_buffer, min(Srb->SenseInfoBufferLength, rep->sense_len));
    1.53        }
    1.54 -      if (!rep->rslt)
    1.55 +      switch(rep->rslt)
    1.56        {
    1.57 +      case 0:
    1.58 +        KdPrint((__DRIVER_NAME "     Xen Operation complete - result = 0x%08x, residual = %d\n", rep->rslt, rep->residual_len));
    1.59          Srb->SrbStatus = SRB_STATUS_SUCCESS;
    1.60 -      }
    1.61 -      else
    1.62 -      {
    1.63 +        break;
    1.64 +      case 0x00010000: /* Device does not exist */
    1.65 +        KdPrint((__DRIVER_NAME "     Xen Operation returned error (result = 0x%08x)\n", rep->rslt));
    1.66 +        Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
    1.67 +        break;
    1.68 +      default:
    1.69          KdPrint((__DRIVER_NAME "     Xen Operation returned error (result = 0x%08x)\n", rep->rslt));
    1.70          Srb->SrbStatus = SRB_STATUS_ERROR;
    1.71          if (rep->sense_len > 0 && !(Srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE) && Srb->SenseInfoBuffer != NULL)
    1.72 @@ -114,6 +133,13 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    1.73            Srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
    1.74          }
    1.75        }
    1.76 +      /* work around a bug in scsiback that gives an incorrect result to REPORT_LUNS - fail it if the output is only 8 bytes */
    1.77 +      if (Srb->Cdb[0] == 0xa0 && Srb->SrbStatus == SRB_STATUS_SUCCESS &&
    1.78 +        Srb->DataTransferLength - rep->residual_len == 8)
    1.79 +      {
    1.80 +        /* SRB_STATUS_ERROR appears to be sufficient here - no need to worry about sense data or anything */
    1.81 +        Srb->SrbStatus = SRB_STATUS_ERROR;
    1.82 +      }
    1.83        remaining = Srb->DataTransferLength;
    1.84        for (j = 0; remaining != 0; j++)
    1.85        {
    1.86 @@ -122,9 +148,18 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    1.87          shadow->req.seg[j].gref = 0;
    1.88          remaining -= shadow->req.seg[j].length;
    1.89        }
    1.90 +
    1.91 +      if (Srb->SrbStatus == SRB_STATUS_SUCCESS && rep->residual_len)
    1.92 +      {
    1.93 +        KdPrint((__DRIVER_NAME "     SRB_STATUS_DATA_OVERRUN DataTransferLength = %d, adjusted = %d\n",
    1.94 +          Srb->DataTransferLength, Srb->DataTransferLength - rep->residual_len));
    1.95 +        Srb->DataTransferLength -= rep->residual_len;
    1.96 +        Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
    1.97 +      }
    1.98 +
    1.99        put_shadow_on_freelist(xsdd, shadow);
   1.100        StorPortNotification(RequestComplete, xsdd, Srb);
   1.101 -      StorPortNotification(NextRequest, xsdd);
   1.102 +      //StorPortNotification(NextRequest, xsdd);
   1.103      }
   1.104  
   1.105      xsdd->ring.rsp_cons = i;
   1.106 @@ -139,13 +174,14 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
   1.107      }
   1.108    }
   1.109  
   1.110 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.111 +  StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
   1.112 +  //FUNCTION_EXIT();
   1.113    
   1.114 -  return FALSE;
   1.115 +  return;
   1.116  }
   1.117  
   1.118  static VOID
   1.119 -XenScsi_ParseBackendDevice(PXENSCSI_DEVICE_DATA xsdd, PCHAR value)
   1.120 +XenScsi_ParseBackendDevice(scsi_dev_t *dev, PCHAR value)
   1.121  {
   1.122    int i = 0;
   1.123    int j = 0;
   1.124 @@ -158,41 +194,184 @@ XenScsi_ParseBackendDevice(PXENSCSI_DEVI
   1.125      if (value[i] == ':' || value[i] == 0)
   1.126      {
   1.127         value[i] = 0;
   1.128 -       xsdd->host = xsdd->channel;
   1.129 -       xsdd->channel = xsdd->id;
   1.130 -       xsdd->id = xsdd->lun;
   1.131 -       xsdd->lun = atoi(&value[j]);
   1.132 +       dev->host = dev->channel;
   1.133 +       dev->channel = dev->id;
   1.134 +       dev->id = dev->lun;
   1.135 +       dev->lun = (UCHAR)atoi(&value[j]);
   1.136         j = i + 1;
   1.137      }
   1.138      i++;
   1.139    }
   1.140    KdPrint((__DRIVER_NAME "     host = %d, channel = %d, id = %d, lun = %d\n",
   1.141 -    xsdd->host, xsdd->channel, xsdd->id, xsdd->lun));  
   1.142 +    dev->host, dev->channel, dev->id, dev->lun));  
   1.143 +}
   1.144 +
   1.145 +/* CALLED AT PASSIVE LEVEL */
   1.146 +static VOID
   1.147 +XenScsi_DevWatch(PCHAR path, PVOID DeviceExtension)
   1.148 +{
   1.149 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   1.150 +  CHAR tmp_path[128];
   1.151 +  PCHAR msg;
   1.152 +  PCHAR *devices;
   1.153 +  PCHAR value;
   1.154 +  scsi_dev_t *dev;
   1.155 +  ULONG i;
   1.156 +  ULONG dev_no;
   1.157 +  ULONG state;
   1.158 +  BOOLEAN changes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   1.159 +  STOR_LOCK_HANDLE lock_handle;
   1.160 +
   1.161 +  UNREFERENCED_PARAMETER(path);
   1.162 +  
   1.163 +  FUNCTION_ENTER();
   1.164 +  
   1.165 +  StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
   1.166 +  if (!xsdd->paused)
   1.167 +  {
   1.168 +    xsdd->state = SCSI_STATE_ENUM_PENDING;
   1.169 +    xsdd->paused = TRUE;
   1.170 +    StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
   1.171 +    StorPortPause(DeviceExtension, XENSCSI_MAX_ENUM_TIME);
   1.172 +  }
   1.173 +  else
   1.174 +  {
   1.175 +    StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
   1.176 +  }
   1.177 +
   1.178 +  KdPrint((__DRIVER_NAME "     Watch triggered on %s\n", path));
   1.179 +  strncpy(tmp_path, xsdd->vectors.backend_path, 128);
   1.180 +  strncat(tmp_path, "/vscsi-devs", 128);
   1.181 +  msg = xsdd->vectors.XenBus_List(xsdd->vectors.context, XBT_NIL, tmp_path, &devices);
   1.182 +  if (msg)
   1.183 +  {
   1.184 +    /* this is pretty fatal ... */
   1.185 +    KdPrint((__DRIVER_NAME "     cannot read - %s\n", msg));
   1.186 +    return;
   1.187 +  }
   1.188 +  for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
   1.189 +    dev != (scsi_dev_t *)&xsdd->dev_list_head;
   1.190 +    dev = (scsi_dev_t *)dev->entry.Flink)
   1.191 +  {
   1.192 +    dev->validated = FALSE;
   1.193 +  }
   1.194 +  
   1.195 +  for (i = 0; devices[i]; i++)
   1.196 +  {
   1.197 +    if (strncmp(devices[i], "dev-", 4) != 0)
   1.198 +    {
   1.199 +      XenPci_FreeMem(devices[i]);
   1.200 +      break; /* not a dev so we are not interested */
   1.201 +    }
   1.202 +    dev_no = atoi(devices[i] + 4);
   1.203 +    strncpy(tmp_path, xsdd->vectors.backend_path, 128);
   1.204 +    strncat(tmp_path, "/vscsi-devs/", 128);
   1.205 +    strncat(tmp_path, devices[i], 128);
   1.206 +    strncat(tmp_path, "/state", 128);
   1.207 +    msg = xsdd->vectors.XenBus_Read(xsdd->vectors.context, XBT_NIL, tmp_path, &value);
   1.208 +    if (msg)
   1.209 +    {
   1.210 +      KdPrint((__DRIVER_NAME "     failed to read state for device %d\n", dev_no));
   1.211 +      state = 0;
   1.212 +    }
   1.213 +    else
   1.214 +      state = atoi(value);
   1.215 +    for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
   1.216 +      dev != (scsi_dev_t *)&xsdd->dev_list_head;
   1.217 +      dev = (scsi_dev_t * )dev->entry.Flink)
   1.218 +    {
   1.219 +      if (dev->dev_no == dev_no)
   1.220 +        break;
   1.221 +    }
   1.222 +    if (dev == (scsi_dev_t *)&xsdd->dev_list_head)
   1.223 +    {
   1.224 +      KdPrint((__DRIVER_NAME "     new dev %d\n", dev_no));
   1.225 +      dev = ExAllocatePoolWithTag(NonPagedPool, sizeof(scsi_dev_t), XENSCSI_POOL_TAG);
   1.226 +      dev->dev_no = dev_no;
   1.227 +      dev->state = state;
   1.228 +      dev->validated = TRUE;
   1.229 +      strncpy(tmp_path, xsdd->vectors.backend_path, 128);
   1.230 +      strncat(tmp_path, "/vscsi-devs/", 128);
   1.231 +      strncat(tmp_path, devices[i], 128);
   1.232 +      strncat(tmp_path, "/v-dev", 128);
   1.233 +      msg = xsdd->vectors.XenBus_Read(xsdd->vectors.context, XBT_NIL, tmp_path, &value);
   1.234 +      if (msg)
   1.235 +      {
   1.236 +        KdPrint((__DRIVER_NAME "     failed to read v-dev for device %d\n", dev_no));
   1.237 +        continue;
   1.238 +      }
   1.239 +      else
   1.240 +      {
   1.241 +        XenScsi_ParseBackendDevice(dev, value);
   1.242 +        // should verify that the controller = this
   1.243 +      }
   1.244 +      strncpy(tmp_path, xsdd->vectors.path, 128);
   1.245 +      strncat(tmp_path, "/vscsi-devs/", 128);
   1.246 +      strncat(tmp_path, devices[i], 128);
   1.247 +      strncat(tmp_path, "/state", 128);      
   1.248 +      msg = xsdd->vectors.XenBus_Write(xsdd->vectors.context, XBT_NIL, tmp_path, "4");
   1.249 +      if (msg)
   1.250 +      {
   1.251 +        KdPrint((__DRIVER_NAME "     failed to write state %d to %s\n", 4, tmp_path));
   1.252 +        continue;
   1.253 +      }
   1.254 +      KdPrint((__DRIVER_NAME "     setting changes[%d]\n", dev->channel));
   1.255 +      changes[dev->channel] = TRUE;
   1.256 +      InsertTailList(&xsdd->dev_list_head, (PLIST_ENTRY)dev);
   1.257 +    }
   1.258 +    else
   1.259 +    {
   1.260 +      // need to manage state change
   1.261 +      // and write frontend state
   1.262 +      dev->state = state;
   1.263 +      dev->validated = TRUE;
   1.264 +      KdPrint((__DRIVER_NAME "     existing dev %d state = %d\n", dev_no, dev->state));
   1.265 +    }
   1.266 +    XenPci_FreeMem(devices[i]);
   1.267 +  }
   1.268 +  XenPci_FreeMem(devices);
   1.269 +
   1.270 +  StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
   1.271 +  xsdd->state = SCSI_STATE_ENUM_COMPLETE;
   1.272 +  xsdd->paused = FALSE;
   1.273 +
   1.274 +  for (i = 0; i < 8; i++)
   1.275 +  {  
   1.276 +    if (changes[i])
   1.277 +    {
   1.278 +      KdPrint((__DRIVER_NAME "     Sending BusChangeDetected for channel %d... NOT!\n", i));
   1.279 +//      StorPortNotification(BusChangeDetected, DeviceExtension, i);
   1.280 +    }
   1.281 +  }
   1.282 +
   1.283 +  KdPrint((__DRIVER_NAME "     Unpaused\n"));
   1.284 +  StorPortResume(DeviceExtension);
   1.285 +
   1.286 +  StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
   1.287 +
   1.288 +  FUNCTION_EXIT();
   1.289  }
   1.290  
   1.291  static ULONG
   1.292 -XenScsi_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
   1.293 +XenScsi_HwStorFindAdapter(PVOID DeviceExtension, PVOID Reserved1, PVOID Reserved2, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PUCHAR Reserved3)
   1.294  {
   1.295    ULONG i;
   1.296 -//  PACCESS_RANGE AccessRange;
   1.297    PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   1.298 -//  ULONG status;
   1.299 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
   1.300    PACCESS_RANGE access_range;
   1.301    PUCHAR ptr;
   1.302    USHORT type;
   1.303    PCHAR setting, value;
   1.304    vscsiif_sring_t *sring;
   1.305 +  CHAR path[128];
   1.306  
   1.307 -  UNREFERENCED_PARAMETER(HwContext);
   1.308 -  UNREFERENCED_PARAMETER(BusInformation);
   1.309 +  UNREFERENCED_PARAMETER(Reserved1);
   1.310 +  UNREFERENCED_PARAMETER(Reserved2);
   1.311    UNREFERENCED_PARAMETER(ArgumentString);
   1.312 +  UNREFERENCED_PARAMETER(Reserved3);
   1.313  
   1.314    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
   1.315    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.316  
   1.317 -  *Again = FALSE;
   1.318 -
   1.319    KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
   1.320    KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
   1.321  
   1.322 @@ -214,7 +393,6 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   1.323      access_range->RangeStart,
   1.324      access_range->RangeLength,
   1.325      !access_range->RangeInMemory);
   1.326 -  //ptr = MmMapIoSpace(access_range->RangeStart, access_range->RangeLength, MmCached);
   1.327    if (ptr == NULL)
   1.328    {
   1.329      KdPrint((__DRIVER_NAME "     Unable to map range\n"));
   1.330 @@ -247,10 +425,6 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   1.331      case XEN_INIT_TYPE_READ_STRING_BACK:
   1.332      case XEN_INIT_TYPE_READ_STRING_FRONT:
   1.333        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   1.334 -      if (strcmp(setting, "b-dev") == 0)
   1.335 -      {
   1.336 -        XenScsi_ParseBackendDevice(xsdd, value);
   1.337 -      }
   1.338        break;
   1.339      case XEN_INIT_TYPE_VECTORS:
   1.340        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   1.341 @@ -290,30 +464,33 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   1.342    ConfigInfo->NumberOfPhysicalBreaks = VSCSIIF_SG_TABLESIZE - 1;
   1.343    ConfigInfo->ScatterGather = TRUE;
   1.344    ConfigInfo->AlignmentMask = 0;
   1.345 -  ConfigInfo->NumberOfBuses = 8;
   1.346 -  ConfigInfo->InitiatorBusId[0] = 7;
   1.347 -  ConfigInfo->InitiatorBusId[1] = 7;
   1.348 -  ConfigInfo->InitiatorBusId[2] = 7;
   1.349 -  ConfigInfo->InitiatorBusId[3] = 7;
   1.350 -  ConfigInfo->InitiatorBusId[4] = 7;
   1.351 -  ConfigInfo->InitiatorBusId[5] = 7;
   1.352 -  ConfigInfo->InitiatorBusId[6] = 7;
   1.353 -  ConfigInfo->InitiatorBusId[7] = 7;
   1.354 +  ConfigInfo->CachesData = FALSE;
   1.355 +  ConfigInfo->NumberOfBuses = SCSI_MAXIMUM_BUSES; //8
   1.356    ConfigInfo->MaximumNumberOfTargets = 16;
   1.357 -  ConfigInfo->MaximumNumberOfLogicalUnits = 255;
   1.358 -  ConfigInfo->BufferAccessScsiPortControlled = TRUE;
   1.359 +  ConfigInfo->MaximumNumberOfLogicalUnits = SCSI_MAXIMUM_LOGICAL_UNITS; // 8
   1.360    if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
   1.361    {
   1.362 -    ConfigInfo->Master = TRUE;
   1.363      ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
   1.364      KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
   1.365    }
   1.366    else
   1.367    {
   1.368 -    ConfigInfo->Master = FALSE;
   1.369      KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
   1.370    }
   1.371 -
   1.372 +  /* from i2o example */
   1.373 +/*
   1.374 +  ConfigInfo->InitiatorBusId[0] = 7;
   1.375 +  ConfigInfo->AlignmentMask = 3;
   1.376 +  ConfigInfo->Dma32BitAddresses = TRUE;
   1.377 +  ConfigInfo->NeedPhysicalAddresses = TRUE;
   1.378 +  ConfigInfo->TaggedQueuing = TRUE;
   1.379 +  ConfigInfo->MapBuffers = STOR_MAP_NO_BUFFERS;
   1.380 +  ConfigInfo->CachesData = TRUE;
   1.381 +*/
   1.382 +  /* end */
   1.383 +  ConfigInfo->ResetTargetSupported = FALSE; // maybe?
   1.384 +  ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
   1.385 +  //ConfigInfo->WmiDataProvider = FALSE; /* i'm not supposed to do this... */
   1.386    xsdd->shadow_free = 0;
   1.387    memset(xsdd->shadows, 0, sizeof(vscsiif_shadow_t) * SHADOW_ENTRIES);
   1.388    for (i = 0; i < SHADOW_ENTRIES; i++)
   1.389 @@ -322,183 +499,221 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   1.390      put_shadow_on_freelist(xsdd, &xsdd->shadows[i]);
   1.391    }
   1.392  
   1.393 +  if (!dump_mode)
   1.394 +  {
   1.395 +    InitializeListHead(&xsdd->dev_list_head);
   1.396 +    /* should do something if we haven't enumerated in a certain time */
   1.397 +    xsdd->state = SCSI_STATE_ENUM_PENDING;
   1.398 +    strncpy(path, xsdd->vectors.backend_path, 128);
   1.399 +    strncat(path, "/vscsi-devs", 128);
   1.400 +    xsdd->vectors.XenBus_AddWatch(xsdd->vectors.context, XBT_NIL, path,
   1.401 +      XenScsi_DevWatch, xsdd);
   1.402 +  }
   1.403    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   1.404  
   1.405    return SP_RETURN_FOUND;
   1.406  }
   1.407  
   1.408  static BOOLEAN
   1.409 -XenScsi_HwScsiInitialize(PVOID DeviceExtension)
   1.410 +XenScsi_HwPassiveInitialization(PVOID DeviceExtension)
   1.411 +{
   1.412 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   1.413 +  
   1.414 +  FUNCTION_ENTER();
   1.415 +  StorPortInitializeDpc(DeviceExtension, &xsdd->dpc, XenScsi_HwStorDpc);
   1.416 +  FUNCTION_EXIT();
   1.417 +  return TRUE;
   1.418 +}
   1.419 +
   1.420 +
   1.421 +static BOOLEAN
   1.422 +XenScsi_HwStorInitialize(PVOID DeviceExtension)
   1.423  {
   1.424  //  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   1.425 +  BOOLEAN retval;
   1.426  
   1.427 -  UNREFERENCED_PARAMETER(DeviceExtension);
   1.428 +  FUNCTION_ENTER();
   1.429    
   1.430 -  FUNCTION_ENTER();
   1.431 +  if ((retval = StorPortEnablePassiveInitialization(DeviceExtension, XenScsi_HwPassiveInitialization)) == TRUE)
   1.432 +    KdPrint((__DRIVER_NAME "     StorPortEnablePassiveInitialization allowed\n"));
   1.433 +  else
   1.434 +  {
   1.435 +    // this is fatal...
   1.436 +    KdPrint((__DRIVER_NAME "     StorPortEnablePassiveInitialization not allowed\n"));
   1.437 +  }
   1.438  
   1.439    FUNCTION_EXIT();
   1.440  
   1.441 -  return TRUE;
   1.442 +  return retval;
   1.443  }
   1.444  
   1.445  static VOID
   1.446  XenScsi_PutSrbOnRing(PXENSCSI_DEVICE_DATA xsdd, PSCSI_REQUEST_BLOCK Srb)
   1.447  {
   1.448 -  PUCHAR ptr;
   1.449    PHYSICAL_ADDRESS physical_address;
   1.450 +  ULONG remaining;
   1.451 +  ULONG i;
   1.452    PFN_NUMBER pfn;
   1.453 -  //int i;
   1.454    vscsiif_shadow_t *shadow;
   1.455 -  int remaining;
   1.456 +  PSTOR_SCATTER_GATHER_LIST sg_list;
   1.457 +  int notify;
   1.458  
   1.459 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   1.460 +  FUNCTION_ENTER();
   1.461  
   1.462    shadow = get_shadow_from_freelist(xsdd);
   1.463    ASSERT(shadow);
   1.464    shadow->Srb = Srb;
   1.465    shadow->req.act = VSCSIIF_ACT_SCSI_CDB;
   1.466    memset(shadow->req.cmnd, 0, VSCSIIF_MAX_COMMAND_SIZE);
   1.467 -  memcpy(shadow->req.cmnd, Srb->Cdb, Srb->CdbLength);
   1.468 -  shadow->req.cmd_len = Srb->CdbLength;
   1.469 -  shadow->req.id = (USHORT)xsdd->id;
   1.470 -  shadow->req.lun = (USHORT)xsdd->lun;
   1.471 -  shadow->req.channel = (USHORT)xsdd->channel;
   1.472 +  memcpy(shadow->req.cmnd, Srb->Cdb, min(Srb->CdbLength, VSCSIIF_MAX_COMMAND_SIZE));
   1.473 +  shadow->req.cmd_len = min(Srb->CdbLength, VSCSIIF_MAX_COMMAND_SIZE);
   1.474 +  shadow->req.timeout_per_command = (USHORT)Srb->TimeOutValue;
   1.475 +  shadow->req.channel = (USHORT)Srb->PathId;
   1.476 +  shadow->req.id = (USHORT)Srb->TargetId;
   1.477 +  shadow->req.lun = (USHORT)Srb->Lun;
   1.478    if (Srb->DataTransferLength && (Srb->SrbFlags & SRB_FLAGS_DATA_IN) && (Srb->SrbFlags & SRB_FLAGS_DATA_OUT))
   1.479    {
   1.480 -    KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_BIDIRECTIONAL\n", Srb->Cdb[0], Srb->DataTransferLength));
   1.481 +    //KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_BIDIRECTIONAL\n", Srb->Cdb[0], Srb->DataTransferLength));
   1.482      shadow->req.sc_data_direction = DMA_BIDIRECTIONAL;
   1.483    }
   1.484    else if (Srb->DataTransferLength && (Srb->SrbFlags & SRB_FLAGS_DATA_IN))
   1.485    {
   1.486 -    KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_FROM_DEVICE\n", Srb->Cdb[0], Srb->DataTransferLength));
   1.487 +    //KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_FROM_DEVICE\n", Srb->Cdb[0], Srb->DataTransferLength));
   1.488      shadow->req.sc_data_direction = DMA_FROM_DEVICE;
   1.489    }
   1.490    else if (Srb->DataTransferLength && (Srb->SrbFlags & SRB_FLAGS_DATA_OUT))
   1.491    {
   1.492 -    KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_TO_DEVICE\n", Srb->Cdb[0], Srb->DataTransferLength));
   1.493 +    //KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_TO_DEVICE\n", Srb->Cdb[0], Srb->DataTransferLength));
   1.494      shadow->req.sc_data_direction = DMA_TO_DEVICE;
   1.495    }
   1.496    else
   1.497    {
   1.498 -    KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_NONE\n", Srb->Cdb[0], Srb->DataTransferLength));
   1.499 +    //KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_NONE\n", Srb->Cdb[0], Srb->DataTransferLength));
   1.500      shadow->req.sc_data_direction = DMA_NONE;
   1.501    }
   1.502 -  //shadow->req.nr_segments = (UINT8)((Srb->DataTransferLength + PAGE_SIZE - 1) >> PAGE_SHIFT);
   1.503 -  //shadow->req.request_bufflen = Srb->DataTransferLength;
   1.504  
   1.505    remaining = Srb->DataTransferLength;
   1.506    shadow->req.seg[0].offset = 0;
   1.507    shadow->req.seg[0].length = 0;
   1.508 +  shadow->req.nr_segments = 0;
   1.509  
   1.510 -  ptr = Srb->DataBuffer;
   1.511 -
   1.512 -  for (shadow->req.nr_segments = 0; remaining != 0; shadow->req.nr_segments++)
   1.513 +  sg_list = StorPortGetScatterGatherList(xsdd, Srb);
   1.514 +  for (i = 0; i < sg_list->NumberOfElements; i++)
   1.515    {
   1.516 -    physical_address = MmGetPhysicalAddress(ptr);
   1.517 -    pfn = (ULONG)(physical_address.QuadPart >> PAGE_SHIFT);
   1.518 -    shadow->req.seg[shadow->req.nr_segments].gref = get_grant_from_freelist(xsdd);
   1.519 -    ASSERT(shadow->req.seg[shadow->req.nr_segments].gref);
   1.520 -    xsdd->vectors.GntTbl_GrantAccess(xsdd->vectors.context, 0, (ULONG)pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref);
   1.521 -    shadow->req.seg[shadow->req.nr_segments].offset = (USHORT)(physical_address.LowPart & (PAGE_SIZE - 1));
   1.522 -    shadow->req.seg[shadow->req.nr_segments].length = (USHORT)min(PAGE_SIZE - shadow->req.seg[shadow->req.nr_segments].offset, remaining);
   1.523 -    remaining -= shadow->req.seg[shadow->req.nr_segments].length;
   1.524 -    ptr += shadow->req.seg[shadow->req.nr_segments].length;
   1.525 -    //KdPrint((__DRIVER_NAME "     Page = %d, Offset = %d, Length = %d, Remaining = %d\n", shadow->req.nr_segments, shadow->req.seg[shadow->req.nr_segments].offset, shadow->req.seg[shadow->req.nr_segments].length, remaining));
   1.526 +    physical_address = sg_list->List[i].PhysicalAddress;
   1.527 +    //KdPrint((__DRIVER_NAME "     Physical address = 0x%08x%08x\n", physical_address.HighPart, physical_address.LowPart));
   1.528 +    remaining = sg_list->List[i].Length;
   1.529 +    while(remaining > 0)
   1.530 +    {
   1.531 +      pfn = (ULONG)(physical_address.QuadPart >> PAGE_SHIFT);
   1.532 +      shadow->req.seg[shadow->req.nr_segments].gref = get_grant_from_freelist(xsdd);
   1.533 +      ASSERT(shadow->req.seg[shadow->req.nr_segments].gref);
   1.534 +      xsdd->vectors.GntTbl_GrantAccess(xsdd->vectors.context, 0, (ULONG)pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref);
   1.535 +      shadow->req.seg[shadow->req.nr_segments].offset = (USHORT)(physical_address.LowPart & (PAGE_SIZE - 1));
   1.536 +      shadow->req.seg[shadow->req.nr_segments].length = (USHORT)min((ULONG)(PAGE_SIZE - shadow->req.seg[shadow->req.nr_segments].offset), remaining);
   1.537 +      remaining -= shadow->req.seg[shadow->req.nr_segments].length;
   1.538 +      physical_address.QuadPart += shadow->req.seg[shadow->req.nr_segments].length;
   1.539 +      //KdPrint((__DRIVER_NAME "     Page = %d, Pfn = 0x%08x, Offset = 0x%03x, Length = %d, Remaining = %d\n", shadow->req.nr_segments, pfn, shadow->req.seg[shadow->req.nr_segments].offset, shadow->req.seg[shadow->req.nr_segments].length, remaining));
   1.540 +      shadow->req.nr_segments++;
   1.541 +    }
   1.542    }
   1.543    *RING_GET_REQUEST(&xsdd->ring, xsdd->ring.req_prod_pvt) = shadow->req;
   1.544    xsdd->ring.req_prod_pvt++;
   1.545 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xsdd->ring, notify);
   1.546 +  if (notify)
   1.547 +    xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->event_channel);
   1.548  
   1.549 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.550 +  FUNCTION_EXIT();
   1.551  }
   1.552  
   1.553  static BOOLEAN
   1.554 -XenScsi_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   1.555 +XenScsi_HwStorBuildIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   1.556  {
   1.557  //  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   1.558 -//  int notify;
   1.559 +  UNREFERENCED_PARAMETER(DeviceExtension);
   1.560 +  UNREFERENCED_PARAMETER(Srb);
   1.561 +
   1.562 +  return TRUE;
   1.563 +}
   1.564 +
   1.565 +/* Called with StartIoLock held */
   1.566 +static BOOLEAN
   1.567 +XenScsi_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   1.568 +{
   1.569 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   1.570 +  scsi_dev_t *dev;
   1.571  
   1.572 -  FUNCTION_ENTER();
   1.573 -  //KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
   1.574 +  // FUNCTION_ENTER();
   1.575 +  if (xsdd->state != SCSI_STATE_ENUM_COMPLETE)
   1.576 +  {
   1.577 +    if (!xsdd->paused)
   1.578 +    {
   1.579 +      xsdd->paused = TRUE;
   1.580 +      StorPortPause(DeviceExtension, XENSCSI_MAX_ENUM_TIME);
   1.581 +    }
   1.582 +    Srb->SrbStatus = SRB_STATUS_PENDING;
   1.583 +    StorPortNotification(RequestComplete, DeviceExtension, Srb);
   1.584 +    return TRUE;
   1.585 +  }
   1.586  
   1.587 -//  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.588 -//  if (Srb->PathId != 0 || Srb->TargetId != 0)
   1.589 -//  {
   1.590 +  for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
   1.591 +    dev != (scsi_dev_t *)&xsdd->dev_list_head;
   1.592 +    dev = (scsi_dev_t * )dev->entry.Flink)
   1.593 +  {
   1.594 +    if (dev->channel == Srb->PathId && dev->id == Srb->TargetId && dev->lun == Srb->Lun)
   1.595 +      break;
   1.596 +  }
   1.597 +  if (dev == (scsi_dev_t *)&xsdd->dev_list_head)
   1.598 +  {
   1.599      Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
   1.600      StorPortNotification(RequestComplete, DeviceExtension, Srb);
   1.601 -    StorPortNotification(NextRequest, DeviceExtension, NULL);
   1.602 -    KdPrint((__DRIVER_NAME "     Out of bounds\n"));
   1.603 -    FUNCTION_EXIT();
   1.604 +    //KdPrint((__DRIVER_NAME "     Out of bounds\n"));
   1.605      return TRUE;
   1.606 -//  }
   1.607 +  }
   1.608  
   1.609 -#if 0
   1.610    switch (Srb->Function)
   1.611    {
   1.612    case SRB_FUNCTION_EXECUTE_SCSI:
   1.613      XenScsi_PutSrbOnRing(xsdd, Srb);
   1.614 -    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xsdd->ring, notify);
   1.615 -    if (notify)
   1.616 -      xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->event_channel);
   1.617 -    if (!xsdd->shadow_free)
   1.618 -      StorPortNotification(NextRequest, DeviceExtension);
   1.619 +    Srb->SrbStatus = SRB_STATUS_PENDING;
   1.620      break;
   1.621    case SRB_FUNCTION_IO_CONTROL:
   1.622      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
   1.623      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   1.624      StorPortNotification(RequestComplete, DeviceExtension, Srb);
   1.625 -    StorPortNotification(NextRequest, DeviceExtension, NULL);
   1.626      break;
   1.627    case SRB_FUNCTION_FLUSH:
   1.628      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
   1.629      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   1.630      StorPortNotification(RequestComplete, DeviceExtension, Srb);
   1.631 -    StorPortNotification(NextRequest, DeviceExtension, NULL);
   1.632      break;
   1.633    default:
   1.634      KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
   1.635      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   1.636      StorPortNotification(RequestComplete, DeviceExtension, Srb);
   1.637 -    StorPortNotification(NextRequest, DeviceExtension, NULL);
   1.638      break;
   1.639    }
   1.640  
   1.641 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.642 +  //FUNCTION_EXIT();
   1.643    return TRUE;
   1.644 -#endif
   1.645  }
   1.646  
   1.647  static BOOLEAN
   1.648 -XenScsi_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
   1.649 +XenScsi_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
   1.650  {
   1.651    UNREFERENCED_PARAMETER(DeviceExtension);
   1.652    UNREFERENCED_PARAMETER(PathId);
   1.653  
   1.654  
   1.655 -  KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
   1.656 +  FUNCTION_ENTER();
   1.657    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.658 -
   1.659 -  KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
   1.660 -
   1.661 -  return TRUE;
   1.662 -}
   1.663 -
   1.664 -static BOOLEAN
   1.665 -XenScsi_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
   1.666 -{
   1.667 -  UNREFERENCED_PARAMETER(DeviceExtension);
   1.668 -  UNREFERENCED_PARAMETER(Context);
   1.669 -  UNREFERENCED_PARAMETER(SaveState);
   1.670 -
   1.671 -  KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
   1.672 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.673 -
   1.674 -  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
   1.675 +  FUNCTION_EXIT();
   1.676  
   1.677    return TRUE;
   1.678  }
   1.679  
   1.680  static SCSI_ADAPTER_CONTROL_STATUS
   1.681 -XenScsi_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
   1.682 +XenScsi_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
   1.683  {
   1.684    SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
   1.685    PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
   1.686 @@ -506,7 +721,7 @@ XenScsi_HwScsiAdapterControl(PVOID Devic
   1.687  
   1.688    UNREFERENCED_PARAMETER(DeviceExtension);
   1.689  
   1.690 -  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
   1.691 +  FUNCTION_ENTER();
   1.692    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.693  
   1.694    switch (ControlType)
   1.695 @@ -516,6 +731,7 @@ XenScsi_HwScsiAdapterControl(PVOID Devic
   1.696      KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
   1.697      SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
   1.698      SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
   1.699 +    SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
   1.700      break;
   1.701    case ScsiStopAdapter:
   1.702      KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
   1.703 @@ -534,7 +750,7 @@ XenScsi_HwScsiAdapterControl(PVOID Devic
   1.704      break;
   1.705    }
   1.706  
   1.707 -  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
   1.708 +  FUNCTION_EXIT();
   1.709  
   1.710    return Status;
   1.711  }
   1.712 @@ -545,36 +761,37 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.713    ULONG Status;
   1.714    HW_INITIALIZATION_DATA HwInitializationData;
   1.715  
   1.716 -  KdPrint((__DRIVER_NAME " --> "__FUNCTION__ "\n"));
   1.717 +  FUNCTION_ENTER();
   1.718 +
   1.719    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.720  
   1.721 +  /* RegistryPath == NULL when we are invoked as a crash dump driver */
   1.722 +  if (!RegistryPath)
   1.723 +  {
   1.724 +    dump_mode = TRUE;
   1.725 +  }
   1.726 +
   1.727    RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
   1.728  
   1.729    HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
   1.730    HwInitializationData.AdapterInterfaceType = Internal;
   1.731 -  HwInitializationData.HwDmaStarted = NULL;
   1.732    HwInitializationData.DeviceExtensionSize = sizeof(XENSCSI_DEVICE_DATA);
   1.733    HwInitializationData.SpecificLuExtensionSize = 0;
   1.734    HwInitializationData.SrbExtensionSize = 0;
   1.735    HwInitializationData.NumberOfAccessRanges = 1;
   1.736 -  HwInitializationData.MapBuffers = TRUE;
   1.737 -  HwInitializationData.NeedPhysicalAddresses = FALSE;
   1.738 +  HwInitializationData.MapBuffers = STOR_MAP_NO_BUFFERS;
   1.739 +  HwInitializationData.NeedPhysicalAddresses = TRUE; // must be TRUE
   1.740    HwInitializationData.TaggedQueuing = TRUE;
   1.741    HwInitializationData.AutoRequestSense = TRUE;
   1.742    HwInitializationData.MultipleRequestPerLu = TRUE;
   1.743 -  HwInitializationData.ReceiveEvent = FALSE;
   1.744 -  HwInitializationData.VendorIdLength = 0;
   1.745 -  HwInitializationData.VendorId = NULL;
   1.746 -  HwInitializationData.DeviceIdLength = 0;
   1.747 -  HwInitializationData.DeviceId = NULL;
   1.748  
   1.749 -  HwInitializationData.HwInitialize = XenScsi_HwScsiInitialize;
   1.750 -  HwInitializationData.HwStartIo = XenScsi_HwScsiStartIo;
   1.751 -  HwInitializationData.HwInterrupt = XenScsi_HwScsiInterrupt;
   1.752 -  HwInitializationData.HwFindAdapter = XenScsi_HwScsiFindAdapter;
   1.753 -  HwInitializationData.HwResetBus = XenScsi_HwScsiResetBus;
   1.754 -  HwInitializationData.HwAdapterState = XenScsi_HwScsiAdapterState;
   1.755 -  HwInitializationData.HwAdapterControl = XenScsi_HwScsiAdapterControl;
   1.756 +  HwInitializationData.HwInitialize = XenScsi_HwStorInitialize;
   1.757 +  HwInitializationData.HwBuildIo = XenScsi_HwStorBuildIo;
   1.758 +  HwInitializationData.HwStartIo = XenScsi_HwStorStartIo;
   1.759 +  HwInitializationData.HwInterrupt = XenScsi_HwStorInterrupt;
   1.760 +  HwInitializationData.HwFindAdapter = XenScsi_HwStorFindAdapter;
   1.761 +  HwInitializationData.HwResetBus = XenScsi_HwStorResetBus;
   1.762 +  HwInitializationData.HwAdapterControl = XenScsi_HwStorAdapterControl;
   1.763  
   1.764    Status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
   1.765    
   1.766 @@ -583,7 +800,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.767      KdPrint((__DRIVER_NAME " StorPortInitialize failed with status 0x%08x\n", Status));
   1.768    }
   1.769  
   1.770 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   1.771 +  FUNCTION_EXIT();
   1.772  
   1.773    return Status;
   1.774  }
     2.1 --- a/xenscsi/xenscsi.h	Thu Nov 27 21:24:20 2008 +1100
     2.2 +++ b/xenscsi/xenscsi.h	Tue Dec 02 20:58:26 2008 +1100
     2.3 @@ -48,26 +48,24 @@ typedef struct {
     2.4  #define SHADOW_ENTRIES 32
     2.5  #define MAX_GRANT_ENTRIES 512
     2.6  
     2.7 -#define SCSI_DEV_STATE_MISSING 0
     2.8 -#define SCSI_DEV_STATE_PRESENT 1
     2.9 -#define SCSI_DEV_STATE_ACTIVE  2
    2.10 -
    2.11  #define SCSI_DEV_NODEV ((ULONG)-1)
    2.12  
    2.13  typedef struct {
    2.14 +  LIST_ENTRY entry;
    2.15    ULONG dev_no; // SCSI_DEV_NODEV == end
    2.16 -  USHORT channel;
    2.17 -  USHORT id;
    2.18 -  USHORT lun;
    2.19 -//  UCHAR state; /* SCSI_DEV_STATE_XXX */
    2.20 +  ULONG state;
    2.21 +  BOOLEAN validated;
    2.22 +  UCHAR host;
    2.23 +  UCHAR channel;
    2.24 +  UCHAR id;
    2.25 +  UCHAR lun;
    2.26  } scsi_dev_t;
    2.27  
    2.28 -typedef struct {
    2.29 -  USHORT state;
    2.30 -  UCHAR devs[1024];
    2.31 -  UCHAR path[128];
    2.32 -  PUCHAR ptr;
    2.33 -} enum_vars_t;
    2.34 +#define SCSI_STATE_ENUM_PENDING     0
    2.35 +#define SCSI_STATE_ENUM_IN_PROGRESS 1
    2.36 +#define SCSI_STATE_ENUM_COMPLETE    2
    2.37 +
    2.38 +#define XENSCSI_MAX_ENUM_TIME 5
    2.39  
    2.40  struct
    2.41  {
    2.42 @@ -82,13 +80,17 @@ struct
    2.43    evtchn_port_t event_channel;
    2.44  
    2.45    vscsiif_front_ring_t ring;
    2.46 +  
    2.47 +  XENPCI_VECTORS vectors;
    2.48 +  
    2.49 +  LIST_ENTRY dev_list_head;
    2.50 +  
    2.51 +  STOR_DPC dpc;
    2.52 +  
    2.53 +  /* protected by StartIoLock */
    2.54 +  BOOLEAN paused;  
    2.55 +  ULONG state;
    2.56  
    2.57 -  int host;
    2.58 -  int channel;
    2.59 -  int id;
    2.60 -  int lun;
    2.61 -
    2.62 -  XENPCI_VECTORS vectors;
    2.63  } typedef XENSCSI_DEVICE_DATA, *PXENSCSI_DEVICE_DATA;
    2.64  
    2.65  enum dma_data_direction {