win-pvdrivers

changeset 791:150118f124a1 0.11.0.213

Update xenscsi to work with grant table changes.
Better synchronise the re-enumerate events
author James Harper <james.harper@bendigoit.com.au>
date Fri Mar 12 09:39:12 2010 +1100 (2010-03-12)
parents 467005e7f509
children 2a5c4cc78d9d
files xenscsi/xenscsi.c xenscsi/xenscsi.h
line diff
     1.1 --- a/xenscsi/xenscsi.c	Fri Mar 12 09:38:42 2010 +1100
     1.2 +++ b/xenscsi/xenscsi.c	Fri Mar 12 09:39:12 2010 +1100
     1.3 @@ -69,6 +69,40 @@ put_grant_on_freelist(PXENSCSI_DEVICE_DA
     1.4    xsdd->grant_free++;
     1.5  }
     1.6  
     1.7 +static VOID
     1.8 +XenScsi_CheckNewDevice(PVOID DeviceExtension)
     1.9 +{
    1.10 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
    1.11 +
    1.12 +  //FUNCTION_ENTER();
    1.13 +  
    1.14 +  if (InterlockedCompareExchange(&xsdd->shared_paused, SHARED_PAUSED_SCSIPORT_PAUSED, SHARED_PAUSED_PASSIVE_PAUSED) == SHARED_PAUSED_PASSIVE_PAUSED)
    1.15 +  {
    1.16 +    KdPrint((__DRIVER_NAME "     scsiport paused\n"));
    1.17 +    xsdd->scsiport_paused = TRUE;
    1.18 +  }
    1.19 +  if (InterlockedCompareExchange(&xsdd->shared_paused, SHARED_PAUSED_SCSIPORT_UNPAUSED, SHARED_PAUSED_PASSIVE_UNPAUSED) == SHARED_PAUSED_PASSIVE_UNPAUSED)
    1.20 +  {
    1.21 +    int i;
    1.22 +    KdPrint((__DRIVER_NAME "     scsiport unpaused\n"));
    1.23 +    xsdd->scsiport_paused = FALSE;
    1.24 +    for (i = 0; i < 8; i++)
    1.25 +    {  
    1.26 +      if (xsdd->bus_changes[i])
    1.27 +      {
    1.28 +        KdPrint((__DRIVER_NAME "     Sending BusChangeDetected for channel %d\n", i));
    1.29 +        ScsiPortNotification(BusChangeDetected, DeviceExtension, i);
    1.30 +      }
    1.31 +    }
    1.32 +    ScsiPortNotification(NextRequest, DeviceExtension);
    1.33 +  }
    1.34 +  if (xsdd->scsiport_paused) /* check more often if we are paused */
    1.35 +    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenScsi_CheckNewDevice, 100 * 1000); /* 100ms second from the last check */
    1.36 +  else
    1.37 +    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenScsi_CheckNewDevice, 1 * 1000 * 1000); /* 1 second from the last check */
    1.38 +  //FUNCTION_EXIT();
    1.39 +}
    1.40 +
    1.41  static BOOLEAN
    1.42  XenScsi_HwScsiInterrupt(PVOID DeviceExtension)
    1.43  {
    1.44 @@ -81,15 +115,8 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    1.45    vscsiif_shadow_t *shadow;
    1.46    BOOLEAN last_interrupt = FALSE;
    1.47  
    1.48 -  if (xsdd->pause_ack != xsdd->pause_req)
    1.49 -  {
    1.50 -    xsdd->pause_ack = xsdd->pause_req;
    1.51 -    KdPrint((__DRIVER_NAME "     Pause state change to %d\n", xsdd->pause_ack));
    1.52 -    if (!xsdd->pause_ack)
    1.53 -    {
    1.54 -      ScsiPortNotification(NextRequest, DeviceExtension);
    1.55 -    }
    1.56 -  }
    1.57 +  XenScsi_CheckNewDevice(DeviceExtension);
    1.58 +
    1.59    if (!dump_mode && !xsdd->vectors.EvtChn_AckEvent(xsdd->vectors.context, xsdd->event_channel, &last_interrupt))
    1.60    {
    1.61      return FALSE;
    1.62 @@ -165,7 +192,7 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    1.63        //remaining = Srb->DataTransferLength;
    1.64        for (j = 0; j < shadow->req.nr_segments; j++)
    1.65        {
    1.66 -        xsdd->vectors.GntTbl_EndAccess(xsdd->vectors.context, shadow->req.seg[j].gref, TRUE);
    1.67 +        xsdd->vectors.GntTbl_EndAccess(xsdd->vectors.context, shadow->req.seg[j].gref, TRUE, (ULONG)'XPDO');
    1.68          put_grant_on_freelist(xsdd, shadow->req.seg[j].gref);
    1.69          shadow->req.seg[j].gref = 0;
    1.70        }
    1.71 @@ -180,7 +207,7 @@ XenScsi_HwScsiInterrupt(PVOID DeviceExte
    1.72  
    1.73        put_shadow_on_freelist(xsdd, shadow);
    1.74        ScsiPortNotification(RequestComplete, xsdd, Srb);
    1.75 -      if (!xsdd->pause_ack)
    1.76 +      if (!xsdd->scsiport_paused)
    1.77          ScsiPortNotification(NextRequest, DeviceExtension);
    1.78      }
    1.79  
    1.80 @@ -227,27 +254,6 @@ XenScsi_ParseBackendDevice(scsi_dev_t *d
    1.81      dev->host, dev->channel, dev->id, dev->lun));  
    1.82  }
    1.83  
    1.84 -static VOID
    1.85 -XenScsi_WaitPause(PVOID DeviceExtension)
    1.86 -{
    1.87 -  //PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
    1.88 -  //LARGE_INTEGER wait_time;
    1.89 -
    1.90 -  UNREFERENCED_PARAMETER(DeviceExtension);
    1.91 -  FUNCTION_ENTER();
    1.92 -#if 0
    1.93 -  xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->device_state->pdo_event_channel);
    1.94 -  while (xsdd->pause_ack != xsdd->pause_req)
    1.95 -  {
    1.96 -    KdPrint((__DRIVER_NAME "     Waiting...\n"));
    1.97 -    wait_time.QuadPart = -1 * 1000 * 10; /* 1ms */
    1.98 -    KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
    1.99 -    xsdd->vectors.EvtChn_Notify(xsdd->vectors.context, xsdd->device_state->pdo_event_channel);
   1.100 -  }  
   1.101 -#endif
   1.102 -  FUNCTION_EXIT();
   1.103 -}
   1.104 -
   1.105  /* CALLED AT PASSIVE LEVEL */
   1.106  /* If Initialize fails then the watch still gets called but the waits will never be acked... */
   1.107  static VOID
   1.108 @@ -262,14 +268,28 @@ XenScsi_DevWatch(PCHAR path, PVOID Devic
   1.109    ULONG i;
   1.110    ULONG dev_no;
   1.111    ULONG state;
   1.112 -  BOOLEAN changes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   1.113 +  LARGE_INTEGER wait_time;
   1.114 +  #if DBG
   1.115 +  ULONG oldpause;
   1.116 +  #endif
   1.117  
   1.118    UNREFERENCED_PARAMETER(path);
   1.119    
   1.120    /* this can only be called from a watch and so is always serialised */
   1.121    FUNCTION_ENTER();
   1.122 -  xsdd->pause_req = TRUE;
   1.123 -  XenScsi_WaitPause(DeviceExtension);
   1.124 +
   1.125 +  #if DBG
   1.126 +  oldpause =
   1.127 +  #endif
   1.128 +    InterlockedExchange(&xsdd->shared_paused, SHARED_PAUSED_PASSIVE_PAUSED);
   1.129 +  ASSERT(oldpause == SHARED_PAUSED_SCSIPORT_UNPAUSED);
   1.130 +  
   1.131 +  while (InterlockedCompareExchange(&xsdd->shared_paused, SHARED_PAUSED_SCSIPORT_PAUSED, SHARED_PAUSED_SCSIPORT_PAUSED) != SHARED_PAUSED_SCSIPORT_PAUSED)
   1.132 +  {
   1.133 +    KdPrint((__DRIVER_NAME "     Waiting for pause...\n"));
   1.134 +    wait_time.QuadPart = -100 * 1000 * 10; /* 100ms */
   1.135 +    KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
   1.136 +  }
   1.137    
   1.138    KdPrint((__DRIVER_NAME "     Watch triggered on %s\n", path));
   1.139    RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.backend_path);
   1.140 @@ -348,7 +368,7 @@ XenScsi_DevWatch(PCHAR path, PVOID Devic
   1.141          continue;
   1.142        }
   1.143        KdPrint((__DRIVER_NAME "     setting changes[%d]\n", dev->channel));
   1.144 -      changes[dev->channel] = TRUE;
   1.145 +      xsdd->bus_changes[dev->channel] = 1;
   1.146        InsertTailList(&xsdd->dev_list_head, (PLIST_ENTRY)dev);
   1.147      }
   1.148      else
   1.149 @@ -363,17 +383,18 @@ XenScsi_DevWatch(PCHAR path, PVOID Devic
   1.150    }
   1.151    XenPci_FreeMem(devices);
   1.152  
   1.153 -  for (i = 0; i < 8; i++)
   1.154 -  {  
   1.155 -    if (changes[i])
   1.156 -    {
   1.157 -      KdPrint((__DRIVER_NAME "     Sending BusChangeDetected for channel %d\n", i));
   1.158 -      ScsiPortNotification(BusChangeDetected, DeviceExtension, i);
   1.159 -    }
   1.160 +  #if DBG
   1.161 +  oldpause =
   1.162 +  #endif
   1.163 +    InterlockedExchange(&xsdd->shared_paused, SHARED_PAUSED_PASSIVE_UNPAUSED);
   1.164 +  ASSERT(oldpause == SHARED_PAUSED_SCSIPORT_PAUSED);
   1.165 +
   1.166 +  while (InterlockedCompareExchange(&xsdd->shared_paused, SHARED_PAUSED_SCSIPORT_UNPAUSED, SHARED_PAUSED_SCSIPORT_UNPAUSED) != SHARED_PAUSED_SCSIPORT_UNPAUSED)
   1.167 +  {
   1.168 +    KdPrint((__DRIVER_NAME "     Waiting for unpause...\n"));
   1.169 +    wait_time.QuadPart = -100 * 1000 * 10; /* 100ms */
   1.170 +    KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
   1.171    }
   1.172 -
   1.173 -  xsdd->pause_req = FALSE;
   1.174 -  XenScsi_WaitPause(DeviceExtension);
   1.175    KdPrint((__DRIVER_NAME "     Unpaused\n"));
   1.176  
   1.177    FUNCTION_EXIT();
   1.178 @@ -399,8 +420,7 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   1.179    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));  
   1.180    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   1.181    
   1.182 -  xsdd->pause_req = TRUE;
   1.183 -  xsdd->pause_ack = TRUE;
   1.184 +  xsdd->scsiport_paused = TRUE; /* wait for initial scan */
   1.185  
   1.186    KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
   1.187    KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
   1.188 @@ -543,10 +563,12 @@ XenScsi_HwScsiFindAdapter(PVOID DeviceEx
   1.189  static BOOLEAN
   1.190  XenScsi_HwScsiInitialize(PVOID DeviceExtension)
   1.191  {
   1.192 -//  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   1.193 +  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
   1.194    UNREFERENCED_PARAMETER(DeviceExtension);
   1.195  
   1.196    FUNCTION_ENTER();
   1.197 +  xsdd->shared_paused = SHARED_PAUSED_SCSIPORT_UNPAUSED;
   1.198 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenScsi_CheckNewDevice, 1 * 1000 * 1000); /* 1 second */
   1.199    
   1.200    FUNCTION_EXIT();
   1.201  
   1.202 @@ -616,7 +638,7 @@ XenScsi_PutSrbOnRing(PXENSCSI_DEVICE_DAT
   1.203      {
   1.204        return; /* better than crashing... */
   1.205      }
   1.206 -    xsdd->vectors.GntTbl_GrantAccess(xsdd->vectors.context, 0, (ULONG)pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref);
   1.207 +    xsdd->vectors.GntTbl_GrantAccess(xsdd->vectors.context, 0, (ULONG)pfn, 0, shadow->req.seg[shadow->req.nr_segments].gref, (ULONG)'XPDO');
   1.208      shadow->req.seg[shadow->req.nr_segments].offset = (USHORT)(physical_address.LowPart & (PAGE_SIZE - 1));
   1.209      shadow->req.seg[shadow->req.nr_segments].length = (USHORT)min(PAGE_SIZE - (ULONG)shadow->req.seg[shadow->req.nr_segments].offset, remaining);
   1.210      remaining -= (ULONG)shadow->req.seg[shadow->req.nr_segments].length;
   1.211 @@ -643,18 +665,14 @@ XenScsi_HwScsiStartIo(PVOID DeviceExtens
   1.212  
   1.213    //FUNCTION_ENTER();
   1.214    
   1.215 -  if (xsdd->pause_ack != xsdd->pause_req)
   1.216 +  XenScsi_CheckNewDevice(DeviceExtension);
   1.217 +
   1.218 +  if (xsdd->scsiport_paused)
   1.219    {
   1.220 -    xsdd->pause_ack = xsdd->pause_req;
   1.221 -  }
   1.222 -
   1.223 -  if (xsdd->pause_ack)
   1.224 -  {
   1.225 -    FUNCTION_ENTER();
   1.226      KdPrint((__DRIVER_NAME "     Busy\n"));
   1.227      Srb->SrbStatus = SRB_STATUS_BUSY;
   1.228      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   1.229 -    FUNCTION_EXIT();
   1.230 +    //FUNCTION_EXIT();
   1.231      return TRUE;
   1.232    }
   1.233  
   1.234 @@ -669,7 +687,7 @@ XenScsi_HwScsiStartIo(PVOID DeviceExtens
   1.235    {
   1.236      Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
   1.237      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   1.238 -    //KdPrint((__DRIVER_NAME "     Out of bounds\n"));
   1.239 +    KdPrint((__DRIVER_NAME "     Out of bounds\n"));
   1.240      ScsiPortNotification(NextRequest, DeviceExtension);
   1.241      //FUNCTION_EXIT();
   1.242      return TRUE;
     2.1 --- a/xenscsi/xenscsi.h	Fri Mar 12 09:38:42 2010 +1100
     2.2 +++ b/xenscsi/xenscsi.h	Fri Mar 12 09:39:12 2010 +1100
     2.3 @@ -62,11 +62,18 @@ typedef struct {
     2.4    UCHAR lun;
     2.5  } scsi_dev_t;
     2.6  
     2.7 +#if 0
     2.8  #define SCSI_STATE_ENUM_PENDING     0
     2.9  #define SCSI_STATE_ENUM_IN_PROGRESS 1
    2.10  #define SCSI_STATE_ENUM_COMPLETE    2
    2.11  
    2.12  #define XENSCSI_MAX_ENUM_TIME 5
    2.13 +#endif
    2.14 +
    2.15 +#define SHARED_PAUSED_SCSIPORT_UNPAUSED 0
    2.16 +#define SHARED_PAUSED_PASSIVE_PAUSED    1
    2.17 +#define SHARED_PAUSED_SCSIPORT_PAUSED   2
    2.18 +#define SHARED_PAUSED_PASSIVE_UNPAUSED  3
    2.19  
    2.20  struct
    2.21  {
    2.22 @@ -85,11 +92,12 @@ struct
    2.23    XENPCI_VECTORS vectors;
    2.24    
    2.25    LIST_ENTRY dev_list_head;
    2.26 -  
    2.27 -  //STOR_DPC dpc;
    2.28 -  
    2.29 -  BOOLEAN pause_req;
    2.30 -  BOOLEAN pause_ack;
    2.31 +    
    2.32 +  //BOOLEAN pause_req;
    2.33 +  //BOOLEAN pause_ack;
    2.34 +  volatile LONG shared_paused;
    2.35 +  ULONG scsiport_paused; /* scsiport code has acknowledged pause */
    2.36 +  ULONG bus_changes[8];
    2.37  } typedef XENSCSI_DEVICE_DATA, *PXENSCSI_DEVICE_DATA;
    2.38  
    2.39  struct {