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