win-pvdrivers

changeset 478:76e2404c5d5f

Merge with tip
author Steve Meisner <steve.meisner@virtualcomputer.com>
date Wed Dec 03 12:55:54 2008 -0500 (2008-12-03)
parents 87c36cd31d9f 525a6f4ca9a1
children 4cb1179f76d8
files
line diff
     1.1 --- a/common/include/xen_public.h	Wed Dec 03 12:22:15 2008 -0500
     1.2 +++ b/common/include/xen_public.h	Wed Dec 03 12:55:54 2008 -0500
     1.3 @@ -101,6 +101,16 @@ typedef NTSTATUS
     1.4  typedef NTSTATUS
     1.5  (*PXEN_XENPCI_XEN_SHUTDOWN_DEVICE)(PVOID Context);
     1.6  
     1.7 +#ifndef XENPCI_POOL_TAG
     1.8 +#define XENPCI_POOL_TAG (ULONG) 'XenP'
     1.9 +#endif
    1.10 +
    1.11 +static __inline VOID
    1.12 +XenPci_FreeMem(PVOID Ptr)
    1.13 +{
    1.14 +  ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
    1.15 +}
    1.16 +
    1.17  #define XEN_DATA_MAGIC 0x12345678
    1.18  
    1.19  typedef struct {
    1.20 @@ -124,6 +134,18 @@ typedef struct {
    1.21    PXEN_XENPCI_XEN_CONFIG_DEVICE XenPci_XenConfigDevice;
    1.22    PXEN_XENPCI_XEN_SHUTDOWN_DEVICE XenPci_XenShutdownDevice;
    1.23  
    1.24 +  CHAR path[128];
    1.25 +  CHAR backend_path[128];
    1.26 +
    1.27 +  PXEN_XENBUS_READ XenBus_Read;
    1.28 +  PXEN_XENBUS_WRITE XenBus_Write;
    1.29 +  PXEN_XENBUS_PRINTF XenBus_Printf;
    1.30 +  PXEN_XENBUS_STARTTRANSACTION XenBus_StartTransaction;
    1.31 +  PXEN_XENBUS_ENDTRANSACTION XenBus_EndTransaction;
    1.32 +  PXEN_XENBUS_LIST XenBus_List;
    1.33 +  PXEN_XENBUS_ADDWATCH XenBus_AddWatch;
    1.34 +  PXEN_XENBUS_REMWATCH XenBus_RemWatch;
    1.35 +
    1.36  } XENPCI_VECTORS, *PXENPCI_VECTORS;
    1.37  
    1.38  #define RESUME_STATE_RUNNING            0
     2.1 --- a/xenpci/xenpci.h	Wed Dec 03 12:22:15 2008 -0500
     2.2 +++ b/xenpci/xenpci.h	Wed Dec 03 12:55:54 2008 -0500
     2.3 @@ -272,9 +272,6 @@ typedef struct {
     2.4    PUCHAR assigned_resources_ptr;
     2.5    XENPCI_DEVICE_STATE device_state;
     2.6    BOOLEAN restart_on_resume;
     2.7 -  PXEN_COMM_IFACE comm_iface;
     2.8 -  KSPIN_LOCK comm_iface_spinlock;
     2.9 -  USHORT req_cons;
    2.10  } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
    2.11  
    2.12  typedef struct
    2.13 @@ -346,11 +343,13 @@ sw_interrupt(UCHAR intno)
    2.14  
    2.15  #define XBT_NIL ((xenbus_transaction_t)0)
    2.16  
    2.17 +#if 0
    2.18  static __inline VOID
    2.19  XenPci_FreeMem(PVOID Ptr)
    2.20  {
    2.21    ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
    2.22  }
    2.23 +#endif
    2.24  
    2.25  NTSTATUS
    2.26  hvm_get_stubs(PXENPCI_DEVICE_DATA xpdd);
     3.1 --- a/xenpci/xenpci_pdo.c	Wed Dec 03 12:22:15 2008 -0500
     3.2 +++ b/xenpci/xenpci_pdo.c	Wed Dec 03 12:55:54 2008 -0500
     3.3 @@ -396,6 +396,88 @@ XenPci_GntTbl_GetRef(PVOID Context)
     3.4    return GntTbl_GetRef(xpdd);
     3.5  }
     3.6  
     3.7 +PCHAR
     3.8 +XenPci_XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value)
     3.9 +{
    3.10 +  PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    3.11 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    3.12 +  return XenBus_Read(xpdd, xbt, path, value);
    3.13 +}
    3.14 +
    3.15 +PCHAR
    3.16 +XenPci_XenBus_Write(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *value)
    3.17 +{
    3.18 +  PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    3.19 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    3.20 +  return XenBus_Write(xpdd, xbt, path, value);
    3.21 +}
    3.22 +
    3.23 +PCHAR
    3.24 +XenPci_XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *fmt, ...)
    3.25 +{
    3.26 +  //PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    3.27 +  //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    3.28 +  //return XenBus_Printf(xpdd, xbt, path, value);
    3.29 +  UNREFERENCED_PARAMETER(Context);
    3.30 +  UNREFERENCED_PARAMETER(xbt);
    3.31 +  UNREFERENCED_PARAMETER(path);
    3.32 +  UNREFERENCED_PARAMETER(fmt);
    3.33 +  return NULL;
    3.34 +}
    3.35 +
    3.36 +PCHAR
    3.37 +XenPci_XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt)
    3.38 +{
    3.39 +  PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    3.40 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    3.41 +  return XenBus_StartTransaction(xpdd, xbt);
    3.42 +}
    3.43 +
    3.44 +PCHAR
    3.45 +XenPci_XenBus_EndTransaction(PVOID Context, xenbus_transaction_t xbt, int abort, int *retry)
    3.46 +{
    3.47 +  PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    3.48 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    3.49 +  return XenBus_EndTransaction(xpdd, xbt, abort, retry);
    3.50 +}
    3.51 +
    3.52 +PCHAR
    3.53 +XenPci_XenBus_List(PVOID Context, xenbus_transaction_t xbt, const char *prefix, char ***contents)
    3.54 +{
    3.55 +  PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    3.56 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    3.57 +  return XenBus_List(xpdd, xbt, prefix, contents);
    3.58 +}
    3.59 +
    3.60 +PCHAR
    3.61 +XenPci_XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, const char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
    3.62 +{
    3.63 +  PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    3.64 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    3.65 +  PCHAR retval;
    3.66 +  
    3.67 +  FUNCTION_ENTER();
    3.68 +  retval = XenBus_AddWatch(xpdd, xbt, path, ServiceRoutine, ServiceContext);
    3.69 +  if (retval == NULL)
    3.70 +  {
    3.71 +    KdPrint((__DRIVER_NAME "     XenPci_XenBus_AddWatch - %s = NULL\n", path));
    3.72 +  }
    3.73 +  else
    3.74 +  {
    3.75 +    KdPrint((__DRIVER_NAME "     XenPci_XenBus_AddWatch - %s = %s\n", path, retval));
    3.76 +  }
    3.77 +  FUNCTION_EXIT();
    3.78 +  return retval;
    3.79 +}
    3.80 +
    3.81 +PCHAR
    3.82 +XenPci_XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, const char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
    3.83 +{
    3.84 +  PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    3.85 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    3.86 +  return XenBus_RemWatch(xpdd, xbt, path, ServiceRoutine, ServiceContext);
    3.87 +}
    3.88 +
    3.89  static NTSTATUS
    3.90  XenPci_XenShutdownDevice(PVOID Context)
    3.91  {
    3.92 @@ -502,6 +584,17 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
    3.93    vectors.GntTbl_EndAccess = XenPci_GntTbl_EndAccess;
    3.94    vectors.XenPci_XenConfigDevice = XenPci_XenConfigDevice;
    3.95    vectors.XenPci_XenShutdownDevice = XenPci_XenShutdownDevice;
    3.96 +  strncpy(vectors.path, xppdd->path, 128);
    3.97 +  strncpy(vectors.backend_path, xppdd->backend_path, 128);
    3.98 +  vectors.XenBus_Read = XenPci_XenBus_Read;
    3.99 +  vectors.XenBus_Write = XenPci_XenBus_Write;
   3.100 +  vectors.XenBus_Printf = XenPci_XenBus_Printf;
   3.101 +  vectors.XenBus_StartTransaction = XenPci_XenBus_StartTransaction;
   3.102 +  vectors.XenBus_EndTransaction = XenPci_XenBus_EndTransaction;
   3.103 +  vectors.XenBus_List = XenPci_XenBus_List;
   3.104 +  vectors.XenBus_AddWatch = XenPci_XenBus_AddWatch;
   3.105 +  vectors.XenBus_RemWatch = XenPci_XenBus_RemWatch;
   3.106 + 
   3.107    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors);
   3.108    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state);
   3.109  
     4.1 --- a/xenscsi/xenscsi.c	Wed Dec 03 12:22:15 2008 -0500
     4.2 +++ b/xenscsi/xenscsi.c	Wed Dec 03 12:55:54 2008 -0500
     4.3 @@ -70,7 +70,19 @@ put_grant_on_freelist(PXENSCSI_DEVICE_DA
     4.4  }
     4.5  
     4.6  static BOOLEAN
     4.7 -XenScsi_HwScsiInterrupt(PVOID DeviceExtension)
     4.8 +XenScsi_HwStorInterrupt(PVOID DeviceExtension)
     4.9 +{
    4.10 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
    4.11 +  if (!dump_mode && !xsdd->vectors.EvtChn_AckEvent(xsdd->vectors.context, xsdd->event_channel))
    4.12 +    return FALSE;
    4.13 +  
    4.14 +  StorPortIssueDpc(DeviceExtension, &xsdd->dpc, NULL, NULL);
    4.15 +  
    4.16 +  return FALSE;
    4.17 +}
    4.18 +
    4.19 +static VOID
    4.20 +XenScsi_HwStorDpc(PSTOR_DPC Dpc, PVOID DeviceExtension, PVOID SystemArgument1, PVOID SystemArgument2)
    4.21  {
    4.22    PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
    4.23    PSCSI_REQUEST_BLOCK Srb;
    4.24 @@ -80,11 +92,14 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    4.25    int more_to_do = TRUE;
    4.26    vscsiif_shadow_t *shadow;
    4.27    ULONG remaining;
    4.28 +  STOR_LOCK_HANDLE lock_handle;
    4.29  
    4.30 -  FUNCTION_ENTER();
    4.31 +  UNREFERENCED_PARAMETER(Dpc);
    4.32 +  UNREFERENCED_PARAMETER(SystemArgument1);
    4.33 +  UNREFERENCED_PARAMETER(SystemArgument2);
    4.34 +  //FUNCTION_ENTER();
    4.35  
    4.36 -  if (!dump_mode && !xsdd->vectors.EvtChn_AckEvent(xsdd->vectors.context, xsdd->event_channel))
    4.37 -    return FALSE;
    4.38 +  StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
    4.39  
    4.40    while (more_to_do)
    4.41    {
    4.42 @@ -94,19 +109,23 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    4.43      {
    4.44        rep = RING_GET_RESPONSE(&xsdd->ring, i);
    4.45        shadow = &xsdd->shadows[rep->rqid];
    4.46 -      KdPrint((__DRIVER_NAME "     Operation complete - result = 0x%08x\n", rep->rslt));
    4.47        Srb = shadow->Srb;
    4.48        Srb->ScsiStatus = (UCHAR)rep->rslt;
    4.49        if (rep->sense_len > 0 && Srb->SenseInfoBuffer != NULL)
    4.50        {
    4.51          memcpy(Srb->SenseInfoBuffer, rep->sense_buffer, min(Srb->SenseInfoBufferLength, rep->sense_len));
    4.52        }
    4.53 -      if (!rep->rslt)
    4.54 +      switch(rep->rslt)
    4.55        {
    4.56 +      case 0:
    4.57 +        KdPrint((__DRIVER_NAME "     Xen Operation complete - result = 0x%08x, residual = %d\n", rep->rslt, rep->residual_len));
    4.58          Srb->SrbStatus = SRB_STATUS_SUCCESS;
    4.59 -      }
    4.60 -      else
    4.61 -      {
    4.62 +        break;
    4.63 +      case 0x00010000: /* Device does not exist */
    4.64 +        KdPrint((__DRIVER_NAME "     Xen Operation returned error (result = 0x%08x)\n", rep->rslt));
    4.65 +        Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
    4.66 +        break;
    4.67 +      default:
    4.68          KdPrint((__DRIVER_NAME "     Xen Operation returned error (result = 0x%08x)\n", rep->rslt));
    4.69          Srb->SrbStatus = SRB_STATUS_ERROR;
    4.70          if (rep->sense_len > 0 && !(Srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE) && Srb->SenseInfoBuffer != NULL)
    4.71 @@ -114,6 +133,13 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    4.72            Srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
    4.73          }
    4.74        }
    4.75 +      /* work around a bug in scsiback that gives an incorrect result to REPORT_LUNS - fail it if the output is only 8 bytes */
    4.76 +      if (Srb->Cdb[0] == 0xa0 && Srb->SrbStatus == SRB_STATUS_SUCCESS &&
    4.77 +        Srb->DataTransferLength - rep->residual_len == 8)
    4.78 +      {
    4.79 +        /* SRB_STATUS_ERROR appears to be sufficient here - no need to worry about sense data or anything */
    4.80 +        Srb->SrbStatus = SRB_STATUS_ERROR;
    4.81 +      }
    4.82        remaining = Srb->DataTransferLength;
    4.83        for (j = 0; remaining != 0; j++)
    4.84        {
    4.85 @@ -122,9 +148,18 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    4.86          shadow->req.seg[j].gref = 0;
    4.87          remaining -= shadow->req.seg[j].length;
    4.88        }
    4.89 +
    4.90 +      if (Srb->SrbStatus == SRB_STATUS_SUCCESS && rep->residual_len)
    4.91 +      {
    4.92 +        KdPrint((__DRIVER_NAME "     SRB_STATUS_DATA_OVERRUN DataTransferLength = %d, adjusted = %d\n",
    4.93 +          Srb->DataTransferLength, Srb->DataTransferLength - rep->residual_len));
    4.94 +        Srb->DataTransferLength -= rep->residual_len;
    4.95 +        Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
    4.96 +      }
    4.97 +
    4.98        put_shadow_on_freelist(xsdd, shadow);
    4.99        StorPortNotification(RequestComplete, xsdd, Srb);
   4.100 -      StorPortNotification(NextRequest, xsdd);
   4.101 +      //StorPortNotification(NextRequest, xsdd);
   4.102      }
   4.103  
   4.104      xsdd->ring.rsp_cons = i;
   4.105 @@ -139,13 +174,14 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
   4.106      }
   4.107    }
   4.108  
   4.109 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.110 +  StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
   4.111 +  //FUNCTION_EXIT();
   4.112    
   4.113 -  return FALSE;
   4.114 +  return;
   4.115  }
   4.116  
   4.117  static VOID
   4.118 -XenScsi_ParseBackendDevice(PXENSCSI_DEVICE_DATA xsdd, PCHAR value)
   4.119 +XenScsi_ParseBackendDevice(scsi_dev_t *dev, PCHAR value)
   4.120  {
   4.121    int i = 0;
   4.122    int j = 0;
   4.123 @@ -158,41 +194,184 @@ XenScsi_ParseBackendDevice(PXENSCSI_DEVI
   4.124      if (value[i] == ':' || value[i] == 0)
   4.125      {
   4.126         value[i] = 0;
   4.127 -       xsdd->host = xsdd->channel;
   4.128 -       xsdd->channel = xsdd->id;
   4.129 -       xsdd->id = xsdd->lun;
   4.130 -       xsdd->lun = atoi(&value[j]);
   4.131 +       dev->host = dev->channel;
   4.132 +       dev->channel = dev->id;
   4.133 +       dev->id = dev->lun;
   4.134 +       dev->lun = (UCHAR)atoi(&value[j]);
   4.135         j = i + 1;
   4.136      }
   4.137      i++;
   4.138    }
   4.139    KdPrint((__DRIVER_NAME "     host = %d, channel = %d, id = %d, lun = %d\n",
   4.140 -    xsdd->host, xsdd->channel, xsdd->id, xsdd->lun));  
   4.141 +    dev->host, dev->channel, dev->id, dev->lun));  
   4.142 +}
   4.143 +
   4.144 +/* CALLED AT PASSIVE LEVEL */
   4.145 +static VOID
   4.146 +XenScsi_DevWatch(PCHAR path, PVOID DeviceExtension)
   4.147 +{
   4.148 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   4.149 +  CHAR tmp_path[128];
   4.150 +  PCHAR msg;
   4.151 +  PCHAR *devices;
   4.152 +  PCHAR value;
   4.153 +  scsi_dev_t *dev;
   4.154 +  ULONG i;
   4.155 +  ULONG dev_no;
   4.156 +  ULONG state;
   4.157 +  BOOLEAN changes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   4.158 +  STOR_LOCK_HANDLE lock_handle;
   4.159 +
   4.160 +  UNREFERENCED_PARAMETER(path);
   4.161 +  
   4.162 +  FUNCTION_ENTER();
   4.163 +  
   4.164 +  StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
   4.165 +  if (!xsdd->paused)
   4.166 +  {
   4.167 +    xsdd->state = SCSI_STATE_ENUM_PENDING;
   4.168 +    xsdd->paused = TRUE;
   4.169 +    StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
   4.170 +    StorPortPause(DeviceExtension, XENSCSI_MAX_ENUM_TIME);
   4.171 +  }
   4.172 +  else
   4.173 +  {
   4.174 +    StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
   4.175 +  }
   4.176 +
   4.177 +  KdPrint((__DRIVER_NAME "     Watch triggered on %s\n", path));
   4.178 +  strncpy(tmp_path, xsdd->vectors.backend_path, 128);
   4.179 +  strncat(tmp_path, "/vscsi-devs", 128);
   4.180 +  msg = xsdd->vectors.XenBus_List(xsdd->vectors.context, XBT_NIL, tmp_path, &devices);
   4.181 +  if (msg)
   4.182 +  {
   4.183 +    /* this is pretty fatal ... */
   4.184 +    KdPrint((__DRIVER_NAME "     cannot read - %s\n", msg));
   4.185 +    return;
   4.186 +  }
   4.187 +  for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
   4.188 +    dev != (scsi_dev_t *)&xsdd->dev_list_head;
   4.189 +    dev = (scsi_dev_t *)dev->entry.Flink)
   4.190 +  {
   4.191 +    dev->validated = FALSE;
   4.192 +  }
   4.193 +  
   4.194 +  for (i = 0; devices[i]; i++)
   4.195 +  {
   4.196 +    if (strncmp(devices[i], "dev-", 4) != 0)
   4.197 +    {
   4.198 +      XenPci_FreeMem(devices[i]);
   4.199 +      break; /* not a dev so we are not interested */
   4.200 +    }
   4.201 +    dev_no = atoi(devices[i] + 4);
   4.202 +    strncpy(tmp_path, xsdd->vectors.backend_path, 128);
   4.203 +    strncat(tmp_path, "/vscsi-devs/", 128);
   4.204 +    strncat(tmp_path, devices[i], 128);
   4.205 +    strncat(tmp_path, "/state", 128);
   4.206 +    msg = xsdd->vectors.XenBus_Read(xsdd->vectors.context, XBT_NIL, tmp_path, &value);
   4.207 +    if (msg)
   4.208 +    {
   4.209 +      KdPrint((__DRIVER_NAME "     failed to read state for device %d\n", dev_no));
   4.210 +      state = 0;
   4.211 +    }
   4.212 +    else
   4.213 +      state = atoi(value);
   4.214 +    for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
   4.215 +      dev != (scsi_dev_t *)&xsdd->dev_list_head;
   4.216 +      dev = (scsi_dev_t * )dev->entry.Flink)
   4.217 +    {
   4.218 +      if (dev->dev_no == dev_no)
   4.219 +        break;
   4.220 +    }
   4.221 +    if (dev == (scsi_dev_t *)&xsdd->dev_list_head)
   4.222 +    {
   4.223 +      KdPrint((__DRIVER_NAME "     new dev %d\n", dev_no));
   4.224 +      dev = ExAllocatePoolWithTag(NonPagedPool, sizeof(scsi_dev_t), XENSCSI_POOL_TAG);
   4.225 +      dev->dev_no = dev_no;
   4.226 +      dev->state = state;
   4.227 +      dev->validated = TRUE;
   4.228 +      strncpy(tmp_path, xsdd->vectors.backend_path, 128);
   4.229 +      strncat(tmp_path, "/vscsi-devs/", 128);
   4.230 +      strncat(tmp_path, devices[i], 128);
   4.231 +      strncat(tmp_path, "/v-dev", 128);
   4.232 +      msg = xsdd->vectors.XenBus_Read(xsdd->vectors.context, XBT_NIL, tmp_path, &value);
   4.233 +      if (msg)
   4.234 +      {
   4.235 +        KdPrint((__DRIVER_NAME "     failed to read v-dev for device %d\n", dev_no));
   4.236 +        continue;
   4.237 +      }
   4.238 +      else
   4.239 +      {
   4.240 +        XenScsi_ParseBackendDevice(dev, value);
   4.241 +        // should verify that the controller = this
   4.242 +      }
   4.243 +      strncpy(tmp_path, xsdd->vectors.path, 128);
   4.244 +      strncat(tmp_path, "/vscsi-devs/", 128);
   4.245 +      strncat(tmp_path, devices[i], 128);
   4.246 +      strncat(tmp_path, "/state", 128);      
   4.247 +      msg = xsdd->vectors.XenBus_Write(xsdd->vectors.context, XBT_NIL, tmp_path, "4");
   4.248 +      if (msg)
   4.249 +      {
   4.250 +        KdPrint((__DRIVER_NAME "     failed to write state %d to %s\n", 4, tmp_path));
   4.251 +        continue;
   4.252 +      }
   4.253 +      KdPrint((__DRIVER_NAME "     setting changes[%d]\n", dev->channel));
   4.254 +      changes[dev->channel] = TRUE;
   4.255 +      InsertTailList(&xsdd->dev_list_head, (PLIST_ENTRY)dev);
   4.256 +    }
   4.257 +    else
   4.258 +    {
   4.259 +      // need to manage state change
   4.260 +      // and write frontend state
   4.261 +      dev->state = state;
   4.262 +      dev->validated = TRUE;
   4.263 +      KdPrint((__DRIVER_NAME "     existing dev %d state = %d\n", dev_no, dev->state));
   4.264 +    }
   4.265 +    XenPci_FreeMem(devices[i]);
   4.266 +  }
   4.267 +  XenPci_FreeMem(devices);
   4.268 +
   4.269 +  StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
   4.270 +  xsdd->state = SCSI_STATE_ENUM_COMPLETE;
   4.271 +  xsdd->paused = FALSE;
   4.272 +
   4.273 +  for (i = 0; i < 8; i++)
   4.274 +  {  
   4.275 +    if (changes[i])
   4.276 +    {
   4.277 +      KdPrint((__DRIVER_NAME "     Sending BusChangeDetected for channel %d... NOT!\n", i));
   4.278 +//      StorPortNotification(BusChangeDetected, DeviceExtension, i);
   4.279 +    }
   4.280 +  }
   4.281 +
   4.282 +  KdPrint((__DRIVER_NAME "     Unpaused\n"));
   4.283 +  StorPortResume(DeviceExtension);
   4.284 +
   4.285 +  StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
   4.286 +
   4.287 +  FUNCTION_EXIT();
   4.288  }
   4.289  
   4.290  static ULONG
   4.291 -XenScsi_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
   4.292 +XenScsi_HwStorFindAdapter(PVOID DeviceExtension, PVOID Reserved1, PVOID Reserved2, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PUCHAR Reserved3)
   4.293  {
   4.294    ULONG i;
   4.295 -//  PACCESS_RANGE AccessRange;
   4.296    PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   4.297 -//  ULONG status;
   4.298 -//  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
   4.299    PACCESS_RANGE access_range;
   4.300    PUCHAR ptr;
   4.301    USHORT type;
   4.302    PCHAR setting, value;
   4.303    vscsiif_sring_t *sring;
   4.304 +  CHAR path[128];
   4.305  
   4.306 -  UNREFERENCED_PARAMETER(HwContext);
   4.307 -  UNREFERENCED_PARAMETER(BusInformation);
   4.308 +  UNREFERENCED_PARAMETER(Reserved1);
   4.309 +  UNREFERENCED_PARAMETER(Reserved2);
   4.310    UNREFERENCED_PARAMETER(ArgumentString);
   4.311 +  UNREFERENCED_PARAMETER(Reserved3);
   4.312  
   4.313    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
   4.314    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.315  
   4.316 -  *Again = FALSE;
   4.317 -
   4.318    KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
   4.319    KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
   4.320  
   4.321 @@ -214,7 +393,6 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   4.322      access_range->RangeStart,
   4.323      access_range->RangeLength,
   4.324      !access_range->RangeInMemory);
   4.325 -  //ptr = MmMapIoSpace(access_range->RangeStart, access_range->RangeLength, MmCached);
   4.326    if (ptr == NULL)
   4.327    {
   4.328      KdPrint((__DRIVER_NAME "     Unable to map range\n"));
   4.329 @@ -247,10 +425,6 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   4.330      case XEN_INIT_TYPE_READ_STRING_BACK:
   4.331      case XEN_INIT_TYPE_READ_STRING_FRONT:
   4.332        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   4.333 -      if (strcmp(setting, "b-dev") == 0)
   4.334 -      {
   4.335 -        XenScsi_ParseBackendDevice(xsdd, value);
   4.336 -      }
   4.337        break;
   4.338      case XEN_INIT_TYPE_VECTORS:
   4.339        KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   4.340 @@ -290,30 +464,33 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   4.341    ConfigInfo->NumberOfPhysicalBreaks = VSCSIIF_SG_TABLESIZE - 1;
   4.342    ConfigInfo->ScatterGather = TRUE;
   4.343    ConfigInfo->AlignmentMask = 0;
   4.344 -  ConfigInfo->NumberOfBuses = 8;
   4.345 -  ConfigInfo->InitiatorBusId[0] = 7;
   4.346 -  ConfigInfo->InitiatorBusId[1] = 7;
   4.347 -  ConfigInfo->InitiatorBusId[2] = 7;
   4.348 -  ConfigInfo->InitiatorBusId[3] = 7;
   4.349 -  ConfigInfo->InitiatorBusId[4] = 7;
   4.350 -  ConfigInfo->InitiatorBusId[5] = 7;
   4.351 -  ConfigInfo->InitiatorBusId[6] = 7;
   4.352 -  ConfigInfo->InitiatorBusId[7] = 7;
   4.353 +  ConfigInfo->CachesData = FALSE;
   4.354 +  ConfigInfo->NumberOfBuses = SCSI_MAXIMUM_BUSES; //8
   4.355    ConfigInfo->MaximumNumberOfTargets = 16;
   4.356 -  ConfigInfo->MaximumNumberOfLogicalUnits = 255;
   4.357 -  ConfigInfo->BufferAccessScsiPortControlled = TRUE;
   4.358 +  ConfigInfo->MaximumNumberOfLogicalUnits = SCSI_MAXIMUM_LOGICAL_UNITS; // 8
   4.359    if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
   4.360    {
   4.361 -    ConfigInfo->Master = TRUE;
   4.362      ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
   4.363      KdPrint((__DRIVER_NAME "     Dma64BitAddresses supported\n"));
   4.364    }
   4.365    else
   4.366    {
   4.367 -    ConfigInfo->Master = FALSE;
   4.368      KdPrint((__DRIVER_NAME "     Dma64BitAddresses not supported\n"));
   4.369    }
   4.370 -
   4.371 +  /* from i2o example */
   4.372 +/*
   4.373 +  ConfigInfo->InitiatorBusId[0] = 7;
   4.374 +  ConfigInfo->AlignmentMask = 3;
   4.375 +  ConfigInfo->Dma32BitAddresses = TRUE;
   4.376 +  ConfigInfo->NeedPhysicalAddresses = TRUE;
   4.377 +  ConfigInfo->TaggedQueuing = TRUE;
   4.378 +  ConfigInfo->MapBuffers = STOR_MAP_NO_BUFFERS;
   4.379 +  ConfigInfo->CachesData = TRUE;
   4.380 +*/
   4.381 +  /* end */
   4.382 +  ConfigInfo->ResetTargetSupported = FALSE; // maybe?
   4.383 +  ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
   4.384 +  //ConfigInfo->WmiDataProvider = FALSE; /* i'm not supposed to do this... */
   4.385    xsdd->shadow_free = 0;
   4.386    memset(xsdd->shadows, 0, sizeof(vscsiif_shadow_t) * SHADOW_ENTRIES);
   4.387    for (i = 0; i < SHADOW_ENTRIES; i++)
   4.388 @@ -322,183 +499,221 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   4.389      put_shadow_on_freelist(xsdd, &xsdd->shadows[i]);
   4.390    }
   4.391  
   4.392 +  if (!dump_mode)
   4.393 +  {
   4.394 +    InitializeListHead(&xsdd->dev_list_head);
   4.395 +    /* should do something if we haven't enumerated in a certain time */
   4.396 +    xsdd->state = SCSI_STATE_ENUM_PENDING;
   4.397 +    strncpy(path, xsdd->vectors.backend_path, 128);
   4.398 +    strncat(path, "/vscsi-devs", 128);
   4.399 +    xsdd->vectors.XenBus_AddWatch(xsdd->vectors.context, XBT_NIL, path,
   4.400 +      XenScsi_DevWatch, xsdd);
   4.401 +  }
   4.402    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   4.403  
   4.404    return SP_RETURN_FOUND;
   4.405  }
   4.406  
   4.407  static BOOLEAN
   4.408 -XenScsi_HwScsiInitialize(PVOID DeviceExtension)
   4.409 +XenScsi_HwPassiveInitialization(PVOID DeviceExtension)
   4.410 +{
   4.411 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   4.412 +  
   4.413 +  FUNCTION_ENTER();
   4.414 +  StorPortInitializeDpc(DeviceExtension, &xsdd->dpc, XenScsi_HwStorDpc);
   4.415 +  FUNCTION_EXIT();
   4.416 +  return TRUE;
   4.417 +}
   4.418 +
   4.419 +
   4.420 +static BOOLEAN
   4.421 +XenScsi_HwStorInitialize(PVOID DeviceExtension)
   4.422  {
   4.423  //  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   4.424 +  BOOLEAN retval;
   4.425  
   4.426 -  UNREFERENCED_PARAMETER(DeviceExtension);
   4.427 +  FUNCTION_ENTER();
   4.428    
   4.429 -  FUNCTION_ENTER();
   4.430 +  if ((retval = StorPortEnablePassiveInitialization(DeviceExtension, XenScsi_HwPassiveInitialization)) == TRUE)
   4.431 +    KdPrint((__DRIVER_NAME "     StorPortEnablePassiveInitialization allowed\n"));
   4.432 +  else
   4.433 +  {
   4.434 +    // this is fatal...
   4.435 +    KdPrint((__DRIVER_NAME "     StorPortEnablePassiveInitialization not allowed\n"));
   4.436 +  }
   4.437  
   4.438    FUNCTION_EXIT();
   4.439  
   4.440 -  return TRUE;
   4.441 +  return retval;
   4.442  }
   4.443  
   4.444  static VOID
   4.445  XenScsi_PutSrbOnRing(PXENSCSI_DEVICE_DATA xsdd, PSCSI_REQUEST_BLOCK Srb)
   4.446  {
   4.447 -  PUCHAR ptr;
   4.448    PHYSICAL_ADDRESS physical_address;
   4.449 +  ULONG remaining;
   4.450 +  ULONG i;
   4.451    PFN_NUMBER pfn;
   4.452 -  //int i;
   4.453    vscsiif_shadow_t *shadow;
   4.454 -  int remaining;
   4.455 +  PSTOR_SCATTER_GATHER_LIST sg_list;
   4.456 +  int notify;
   4.457  
   4.458 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   4.459 +  FUNCTION_ENTER();
   4.460  
   4.461    shadow = get_shadow_from_freelist(xsdd);
   4.462    ASSERT(shadow);
   4.463    shadow->Srb = Srb;
   4.464    shadow->req.act = VSCSIIF_ACT_SCSI_CDB;
   4.465    memset(shadow->req.cmnd, 0, VSCSIIF_MAX_COMMAND_SIZE);
   4.466 -  memcpy(shadow->req.cmnd, Srb->Cdb, Srb->CdbLength);
   4.467 -  shadow->req.cmd_len = Srb->CdbLength;
   4.468 -  shadow->req.id = (USHORT)xsdd->id;
   4.469 -  shadow->req.lun = (USHORT)xsdd->lun;
   4.470 -  shadow->req.channel = (USHORT)xsdd->channel;
   4.471 +  memcpy(shadow->req.cmnd, Srb->Cdb, min(Srb->CdbLength, VSCSIIF_MAX_COMMAND_SIZE));
   4.472 +  shadow->req.cmd_len = min(Srb->CdbLength, VSCSIIF_MAX_COMMAND_SIZE);
   4.473 +  shadow->req.timeout_per_command = (USHORT)Srb->TimeOutValue;
   4.474 +  shadow->req.channel = (USHORT)Srb->PathId;
   4.475 +  shadow->req.id = (USHORT)Srb->TargetId;
   4.476 +  shadow->req.lun = (USHORT)Srb->Lun;
   4.477    if (Srb->DataTransferLength && (Srb->SrbFlags & SRB_FLAGS_DATA_IN) && (Srb->SrbFlags & SRB_FLAGS_DATA_OUT))
   4.478    {
   4.479 -    KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_BIDIRECTIONAL\n", Srb->Cdb[0], Srb->DataTransferLength));
   4.480 +    //KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_BIDIRECTIONAL\n", Srb->Cdb[0], Srb->DataTransferLength));
   4.481      shadow->req.sc_data_direction = DMA_BIDIRECTIONAL;
   4.482    }
   4.483    else if (Srb->DataTransferLength && (Srb->SrbFlags & SRB_FLAGS_DATA_IN))
   4.484    {
   4.485 -    KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_FROM_DEVICE\n", Srb->Cdb[0], Srb->DataTransferLength));
   4.486 +    //KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_FROM_DEVICE\n", Srb->Cdb[0], Srb->DataTransferLength));
   4.487      shadow->req.sc_data_direction = DMA_FROM_DEVICE;
   4.488    }
   4.489    else if (Srb->DataTransferLength && (Srb->SrbFlags & SRB_FLAGS_DATA_OUT))
   4.490    {
   4.491 -    KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_TO_DEVICE\n", Srb->Cdb[0], Srb->DataTransferLength));
   4.492 +    //KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_TO_DEVICE\n", Srb->Cdb[0], Srb->DataTransferLength));
   4.493      shadow->req.sc_data_direction = DMA_TO_DEVICE;
   4.494    }
   4.495    else
   4.496    {
   4.497 -    KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_NONE\n", Srb->Cdb[0], Srb->DataTransferLength));
   4.498 +    //KdPrint((__DRIVER_NAME "     Cmd = %02x, Length = %d, DMA_NONE\n", Srb->Cdb[0], Srb->DataTransferLength));
   4.499      shadow->req.sc_data_direction = DMA_NONE;
   4.500    }
   4.501 -  //shadow->req.nr_segments = (UINT8)((Srb->DataTransferLength + PAGE_SIZE - 1) >> PAGE_SHIFT);
   4.502 -  //shadow->req.request_bufflen = Srb->DataTransferLength;
   4.503  
   4.504    remaining = Srb->DataTransferLength;
   4.505    shadow->req.seg[0].offset = 0;
   4.506    shadow->req.seg[0].length = 0;
   4.507 +  shadow->req.nr_segments = 0;
   4.508  
   4.509 -  ptr = Srb->DataBuffer;
   4.510 -
   4.511 -  for (shadow->req.nr_segments = 0; remaining != 0; shadow->req.nr_segments++)
   4.512 +  sg_list = StorPortGetScatterGatherList(xsdd, Srb);
   4.513 +  for (i = 0; i < sg_list->NumberOfElements; i++)
   4.514    {
   4.515 -    physical_address = MmGetPhysicalAddress(ptr);
   4.516 -    pfn = (ULONG)(physical_address.QuadPart >> PAGE_SHIFT);
   4.517 -    shadow->req.seg[shadow->req.nr_segments].gref = get_grant_from_freelist(xsdd);
   4.518 -    ASSERT(shadow->req.seg[shadow->req.nr_segments].gref);
   4.519 -    xsdd->vectors.GntTbl_GrantAccess(xsdd->vectors.context, 0, (ULONG)pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref);
   4.520 -    shadow->req.seg[shadow->req.nr_segments].offset = (USHORT)(physical_address.LowPart & (PAGE_SIZE - 1));
   4.521 -    shadow->req.seg[shadow->req.nr_segments].length = (USHORT)min(PAGE_SIZE - shadow->req.seg[shadow->req.nr_segments].offset, remaining);
   4.522 -    remaining -= shadow->req.seg[shadow->req.nr_segments].length;
   4.523 -    ptr += shadow->req.seg[shadow->req.nr_segments].length;
   4.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));
   4.525 +    physical_address = sg_list->List[i].PhysicalAddress;
   4.526 +    //KdPrint((__DRIVER_NAME "     Physical address = 0x%08x%08x\n", physical_address.HighPart, physical_address.LowPart));
   4.527 +    remaining = sg_list->List[i].Length;
   4.528 +    while(remaining > 0)
   4.529 +    {
   4.530 +      pfn = (ULONG)(physical_address.QuadPart >> PAGE_SHIFT);
   4.531 +      shadow->req.seg[shadow->req.nr_segments].gref = get_grant_from_freelist(xsdd);
   4.532 +      ASSERT(shadow->req.seg[shadow->req.nr_segments].gref);
   4.533 +      xsdd->vectors.GntTbl_GrantAccess(xsdd->vectors.context, 0, (ULONG)pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref);
   4.534 +      shadow->req.seg[shadow->req.nr_segments].offset = (USHORT)(physical_address.LowPart & (PAGE_SIZE - 1));
   4.535 +      shadow->req.seg[shadow->req.nr_segments].length = (USHORT)min((ULONG)(PAGE_SIZE - shadow->req.seg[shadow->req.nr_segments].offset), remaining);
   4.536 +      remaining -= shadow->req.seg[shadow->req.nr_segments].length;
   4.537 +      physical_address.QuadPart += shadow->req.seg[shadow->req.nr_segments].length;
   4.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));
   4.539 +      shadow->req.nr_segments++;
   4.540 +    }
   4.541    }
   4.542    *RING_GET_REQUEST(&xsdd->ring, xsdd->ring.req_prod_pvt) = shadow->req;
   4.543    xsdd->ring.req_prod_pvt++;
   4.544 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xsdd->ring, notify);
   4.545 +  if (notify)
   4.546 +    xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->event_channel);
   4.547  
   4.548 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.549 +  FUNCTION_EXIT();
   4.550  }
   4.551  
   4.552  static BOOLEAN
   4.553 -XenScsi_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   4.554 +XenScsi_HwStorBuildIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   4.555  {
   4.556  //  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   4.557 -//  int notify;
   4.558 +  UNREFERENCED_PARAMETER(DeviceExtension);
   4.559 +  UNREFERENCED_PARAMETER(Srb);
   4.560  
   4.561 -  FUNCTION_ENTER();
   4.562 -  //KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
   4.563 +  return TRUE;
   4.564 +}
   4.565  
   4.566 -//  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.567 -//  if (Srb->PathId != 0 || Srb->TargetId != 0)
   4.568 -//  {
   4.569 +/* Called with StartIoLock held */
   4.570 +static BOOLEAN
   4.571 +XenScsi_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
   4.572 +{
   4.573 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   4.574 +  scsi_dev_t *dev;
   4.575 +
   4.576 +  // FUNCTION_ENTER();
   4.577 +  if (xsdd->state != SCSI_STATE_ENUM_COMPLETE)
   4.578 +  {
   4.579 +    if (!xsdd->paused)
   4.580 +    {
   4.581 +      xsdd->paused = TRUE;
   4.582 +      StorPortPause(DeviceExtension, XENSCSI_MAX_ENUM_TIME);
   4.583 +    }
   4.584 +    Srb->SrbStatus = SRB_STATUS_PENDING;
   4.585 +    StorPortNotification(RequestComplete, DeviceExtension, Srb);
   4.586 +    return TRUE;
   4.587 +  }
   4.588 +
   4.589 +  for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
   4.590 +    dev != (scsi_dev_t *)&xsdd->dev_list_head;
   4.591 +    dev = (scsi_dev_t * )dev->entry.Flink)
   4.592 +  {
   4.593 +    if (dev->channel == Srb->PathId && dev->id == Srb->TargetId && dev->lun == Srb->Lun)
   4.594 +      break;
   4.595 +  }
   4.596 +  if (dev == (scsi_dev_t *)&xsdd->dev_list_head)
   4.597 +  {
   4.598      Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
   4.599      StorPortNotification(RequestComplete, DeviceExtension, Srb);
   4.600 -    StorPortNotification(NextRequest, DeviceExtension, NULL);
   4.601 -    KdPrint((__DRIVER_NAME "     Out of bounds\n"));
   4.602 -    FUNCTION_EXIT();
   4.603 +    //KdPrint((__DRIVER_NAME "     Out of bounds\n"));
   4.604      return TRUE;
   4.605 -//  }
   4.606 +  }
   4.607  
   4.608 -#if 0
   4.609    switch (Srb->Function)
   4.610    {
   4.611    case SRB_FUNCTION_EXECUTE_SCSI:
   4.612      XenScsi_PutSrbOnRing(xsdd, Srb);
   4.613 -    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xsdd->ring, notify);
   4.614 -    if (notify)
   4.615 -      xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->event_channel);
   4.616 -    if (!xsdd->shadow_free)
   4.617 -      StorPortNotification(NextRequest, DeviceExtension);
   4.618 +    Srb->SrbStatus = SRB_STATUS_PENDING;
   4.619      break;
   4.620    case SRB_FUNCTION_IO_CONTROL:
   4.621      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
   4.622      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   4.623      StorPortNotification(RequestComplete, DeviceExtension, Srb);
   4.624 -    StorPortNotification(NextRequest, DeviceExtension, NULL);
   4.625      break;
   4.626    case SRB_FUNCTION_FLUSH:
   4.627      KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
   4.628      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   4.629      StorPortNotification(RequestComplete, DeviceExtension, Srb);
   4.630 -    StorPortNotification(NextRequest, DeviceExtension, NULL);
   4.631      break;
   4.632    default:
   4.633      KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
   4.634      Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
   4.635      StorPortNotification(RequestComplete, DeviceExtension, Srb);
   4.636 -    StorPortNotification(NextRequest, DeviceExtension, NULL);
   4.637      break;
   4.638    }
   4.639  
   4.640 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.641 +  //FUNCTION_EXIT();
   4.642    return TRUE;
   4.643 -#endif
   4.644  }
   4.645  
   4.646  static BOOLEAN
   4.647 -XenScsi_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
   4.648 +XenScsi_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
   4.649  {
   4.650    UNREFERENCED_PARAMETER(DeviceExtension);
   4.651    UNREFERENCED_PARAMETER(PathId);
   4.652  
   4.653  
   4.654 -  KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
   4.655 +  FUNCTION_ENTER();
   4.656    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.657 -
   4.658 -  KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
   4.659 -
   4.660 -  return TRUE;
   4.661 -}
   4.662 -
   4.663 -static BOOLEAN
   4.664 -XenScsi_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
   4.665 -{
   4.666 -  UNREFERENCED_PARAMETER(DeviceExtension);
   4.667 -  UNREFERENCED_PARAMETER(Context);
   4.668 -  UNREFERENCED_PARAMETER(SaveState);
   4.669 -
   4.670 -  KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
   4.671 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.672 -
   4.673 -  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
   4.674 +  FUNCTION_EXIT();
   4.675  
   4.676    return TRUE;
   4.677  }
   4.678  
   4.679  static SCSI_ADAPTER_CONTROL_STATUS
   4.680 -XenScsi_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
   4.681 +XenScsi_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
   4.682  {
   4.683    SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
   4.684    PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
   4.685 @@ -506,7 +721,7 @@ XenScsi_HwScsiAdapterControl(PVOID Devic
   4.686  
   4.687    UNREFERENCED_PARAMETER(DeviceExtension);
   4.688  
   4.689 -  KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
   4.690 +  FUNCTION_ENTER();
   4.691    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.692  
   4.693    switch (ControlType)
   4.694 @@ -516,6 +731,7 @@ XenScsi_HwScsiAdapterControl(PVOID Devic
   4.695      KdPrint((__DRIVER_NAME "     ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
   4.696      SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
   4.697      SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
   4.698 +    SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
   4.699      break;
   4.700    case ScsiStopAdapter:
   4.701      KdPrint((__DRIVER_NAME "     ScsiStopAdapter\n"));
   4.702 @@ -534,7 +750,7 @@ XenScsi_HwScsiAdapterControl(PVOID Devic
   4.703      break;
   4.704    }
   4.705  
   4.706 -  KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
   4.707 +  FUNCTION_EXIT();
   4.708  
   4.709    return Status;
   4.710  }
   4.711 @@ -545,36 +761,37 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   4.712    ULONG Status;
   4.713    HW_INITIALIZATION_DATA HwInitializationData;
   4.714  
   4.715 -  KdPrint((__DRIVER_NAME " --> "__FUNCTION__ "\n"));
   4.716 +  FUNCTION_ENTER();
   4.717 +
   4.718    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   4.719  
   4.720 +  /* RegistryPath == NULL when we are invoked as a crash dump driver */
   4.721 +  if (!RegistryPath)
   4.722 +  {
   4.723 +    dump_mode = TRUE;
   4.724 +  }
   4.725 +
   4.726    RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
   4.727  
   4.728    HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
   4.729    HwInitializationData.AdapterInterfaceType = Internal;
   4.730 -  HwInitializationData.HwDmaStarted = NULL;
   4.731    HwInitializationData.DeviceExtensionSize = sizeof(XENSCSI_DEVICE_DATA);
   4.732    HwInitializationData.SpecificLuExtensionSize = 0;
   4.733    HwInitializationData.SrbExtensionSize = 0;
   4.734    HwInitializationData.NumberOfAccessRanges = 1;
   4.735 -  HwInitializationData.MapBuffers = TRUE;
   4.736 -  HwInitializationData.NeedPhysicalAddresses = FALSE;
   4.737 +  HwInitializationData.MapBuffers = STOR_MAP_NO_BUFFERS;
   4.738 +  HwInitializationData.NeedPhysicalAddresses = TRUE; // must be TRUE
   4.739    HwInitializationData.TaggedQueuing = TRUE;
   4.740    HwInitializationData.AutoRequestSense = TRUE;
   4.741    HwInitializationData.MultipleRequestPerLu = TRUE;
   4.742 -  HwInitializationData.ReceiveEvent = FALSE;
   4.743 -  HwInitializationData.VendorIdLength = 0;
   4.744 -  HwInitializationData.VendorId = NULL;
   4.745 -  HwInitializationData.DeviceIdLength = 0;
   4.746 -  HwInitializationData.DeviceId = NULL;
   4.747  
   4.748 -  HwInitializationData.HwInitialize = XenScsi_HwScsiInitialize;
   4.749 -  HwInitializationData.HwStartIo = XenScsi_HwScsiStartIo;
   4.750 -  HwInitializationData.HwInterrupt = XenScsi_HwScsiInterrupt;
   4.751 -  HwInitializationData.HwFindAdapter = XenScsi_HwScsiFindAdapter;
   4.752 -  HwInitializationData.HwResetBus = XenScsi_HwScsiResetBus;
   4.753 -  HwInitializationData.HwAdapterState = XenScsi_HwScsiAdapterState;
   4.754 -  HwInitializationData.HwAdapterControl = XenScsi_HwScsiAdapterControl;
   4.755 +  HwInitializationData.HwInitialize = XenScsi_HwStorInitialize;
   4.756 +  HwInitializationData.HwBuildIo = XenScsi_HwStorBuildIo;
   4.757 +  HwInitializationData.HwStartIo = XenScsi_HwStorStartIo;
   4.758 +  HwInitializationData.HwInterrupt = XenScsi_HwStorInterrupt;
   4.759 +  HwInitializationData.HwFindAdapter = XenScsi_HwStorFindAdapter;
   4.760 +  HwInitializationData.HwResetBus = XenScsi_HwStorResetBus;
   4.761 +  HwInitializationData.HwAdapterControl = XenScsi_HwStorAdapterControl;
   4.762  
   4.763    Status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
   4.764    
   4.765 @@ -583,7 +800,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   4.766      KdPrint((__DRIVER_NAME " StorPortInitialize failed with status 0x%08x\n", Status));
   4.767    }
   4.768  
   4.769 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.770 +  FUNCTION_EXIT();
   4.771  
   4.772    return Status;
   4.773  }
     5.1 --- a/xenscsi/xenscsi.h	Wed Dec 03 12:22:15 2008 -0500
     5.2 +++ b/xenscsi/xenscsi.h	Wed Dec 03 12:55:54 2008 -0500
     5.3 @@ -48,26 +48,24 @@ typedef struct {
     5.4  #define SHADOW_ENTRIES 32
     5.5  #define MAX_GRANT_ENTRIES 512
     5.6  
     5.7 -#define SCSI_DEV_STATE_MISSING 0
     5.8 -#define SCSI_DEV_STATE_PRESENT 1
     5.9 -#define SCSI_DEV_STATE_ACTIVE  2
    5.10 -
    5.11  #define SCSI_DEV_NODEV ((ULONG)-1)
    5.12  
    5.13  typedef struct {
    5.14 +  LIST_ENTRY entry;
    5.15    ULONG dev_no; // SCSI_DEV_NODEV == end
    5.16 -  USHORT channel;
    5.17 -  USHORT id;
    5.18 -  USHORT lun;
    5.19 -//  UCHAR state; /* SCSI_DEV_STATE_XXX */
    5.20 +  ULONG state;
    5.21 +  BOOLEAN validated;
    5.22 +  UCHAR host;
    5.23 +  UCHAR channel;
    5.24 +  UCHAR id;
    5.25 +  UCHAR lun;
    5.26  } scsi_dev_t;
    5.27  
    5.28 -typedef struct {
    5.29 -  USHORT state;
    5.30 -  UCHAR devs[1024];
    5.31 -  UCHAR path[128];
    5.32 -  PUCHAR ptr;
    5.33 -} enum_vars_t;
    5.34 +#define SCSI_STATE_ENUM_PENDING     0
    5.35 +#define SCSI_STATE_ENUM_IN_PROGRESS 1
    5.36 +#define SCSI_STATE_ENUM_COMPLETE    2
    5.37 +
    5.38 +#define XENSCSI_MAX_ENUM_TIME 5
    5.39  
    5.40  struct
    5.41  {
    5.42 @@ -82,13 +80,17 @@ struct
    5.43    evtchn_port_t event_channel;
    5.44  
    5.45    vscsiif_front_ring_t ring;
    5.46 +  
    5.47 +  XENPCI_VECTORS vectors;
    5.48 +  
    5.49 +  LIST_ENTRY dev_list_head;
    5.50 +  
    5.51 +  STOR_DPC dpc;
    5.52 +  
    5.53 +  /* protected by StartIoLock */
    5.54 +  BOOLEAN paused;  
    5.55 +  ULONG state;
    5.56  
    5.57 -  int host;
    5.58 -  int channel;
    5.59 -  int id;
    5.60 -  int lun;
    5.61 -
    5.62 -  XENPCI_VECTORS vectors;
    5.63  } typedef XENSCSI_DEVICE_DATA, *PXENSCSI_DEVICE_DATA;
    5.64  
    5.65  enum dma_data_direction {