win-pvdrivers

changeset 81:5d116e9b87fa

Fixed a problem with calling things at the wrong irql, which was probably causing hanging on boot.
author James Harper <james.harper@bendigoit.com.au>
date Mon Dec 31 23:35:05 2007 +1100 (2007-12-31)
parents 43f57f42508c
children 9afafc0eae1d 449304b11e61
files xenvbd/sources xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/xenvbd/sources	Mon Dec 31 12:46:47 2007 +1100
     1.2 +++ b/xenvbd/sources	Mon Dec 31 23:35:05 2007 +1100
     1.3 @@ -1,7 +1,7 @@
     1.4  TARGETNAME=XENVBD
     1.5  TARGETTYPE=DRIVER
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7 -VERSION=0.5.0.6
     1.8 +VERSION=0.5.0.9
     1.9  KMDF_VERSION=1
    1.10  MSC_WARNING_LEVEL=/W4
    1.11  INF_NAME=xenvbd
     2.1 --- a/xenvbd/xenvbd.c	Mon Dec 31 12:46:47 2007 +1100
     2.2 +++ b/xenvbd/xenvbd.c	Mon Dec 31 23:35:05 2007 +1100
     2.3 @@ -87,59 +87,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
     2.4    return Status;
     2.5  }
     2.6  
     2.7 -static ULONG
     2.8 -XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
     2.9 -{
    2.10 -  ULONG Status = SP_RETURN_FOUND;
    2.11 -  ULONG i;
    2.12 -  PACCESS_RANGE AccessRange;
    2.13 -  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
    2.14 -
    2.15 -  KeInitializeSpinLock(&DeviceData->Lock);
    2.16 -  KdPrint((__DRIVER_NAME " --> HwScsiFindAdapter\n"));
    2.17 -  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
    2.18 -
    2.19 -  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
    2.20 -  KdPrint((__DRIVER_NAME "     BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
    2.21 -
    2.22 -  KdPrint((__DRIVER_NAME "     AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
    2.23 -
    2.24 -  for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
    2.25 -  {
    2.26 -    AccessRange = &(*(ConfigInfo->AccessRanges))[i];
    2.27 -    KdPrint((__DRIVER_NAME "     AccessRange %2d: RangeStart = %08x, RangeLength = %08x, RangeInMemory = %d\n", i, AccessRange->RangeStart.LowPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
    2.28 -    switch (i)
    2.29 -    {
    2.30 -    case 0:
    2.31 -      DeviceData->XenDeviceData = (PXENPCI_XEN_DEVICE_DATA)AccessRange->RangeStart.QuadPart;
    2.32 -      KdPrint((__DRIVER_NAME "     Mapped to virtual address %08x\n", DeviceData->XenDeviceData));
    2.33 -      KdPrint((__DRIVER_NAME "     Magic = %08x\n", DeviceData->XenDeviceData->Magic));
    2.34 -      if (DeviceData->XenDeviceData->Magic == XEN_DATA_MAGIC)
    2.35 -      {
    2.36 -      }
    2.37 -      break;
    2.38 -    default:
    2.39 -      break;
    2.40 -    }
    2.41 -  }
    2.42 -
    2.43 -  ConfigInfo->NumberOfBuses = SCSI_BUSES;
    2.44 -  ConfigInfo->MaximumTransferLength = BUF_PAGES_PER_SRB * PAGE_SIZE;
    2.45 -  ConfigInfo->NumberOfPhysicalBreaks = BUF_PAGES_PER_SRB - 1; //11 - 1;
    2.46 -  ConfigInfo->ScatterGather = TRUE;
    2.47 -  ConfigInfo->Master = FALSE;
    2.48 -  ConfigInfo->AlignmentMask = 0;
    2.49 -  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
    2.50 -  ConfigInfo->MaximumNumberOfTargets = SCSI_TARGETS_PER_BUS;
    2.51 -  //ConfigInfo->TaggedQueueing = TRUE;
    2.52 -
    2.53 -  *Again = FALSE;
    2.54 -
    2.55 -  KdPrint((__DRIVER_NAME " <-- HwScsiFindAdapter\n"));  
    2.56 -
    2.57 -  return Status;
    2.58 -}
    2.59 -
    2.60  static __inline uint64_t
    2.61  GET_ID_FROM_FREELIST(PXENVBD_TARGET_DATA TargetData)
    2.62  {
    2.63 @@ -438,9 +385,7 @@ XenVbd_BackEndStateHandler(char *Path, P
    2.64  
    2.65      KdPrint((__DRIVER_NAME "     Set Frontend state to Connected\n"));
    2.66      InterlockedIncrement(&DeviceData->EnumeratedDevices);
    2.67 -    KdPrint((__DRIVER_NAME "     Added a device, notifying\n"));  
    2.68 -    KeSetEvent(&DeviceData->WaitDevicesEvent, 1, FALSE);
    2.69 -
    2.70 +    KdPrint((__DRIVER_NAME "     Added a device\n"));  
    2.71      break;
    2.72  
    2.73    case XenbusStateClosing:
    2.74 @@ -544,6 +489,128 @@ XenVbd_WatchHandler(char *Path, PVOID De
    2.75    return;
    2.76  }
    2.77  
    2.78 +static ULONG
    2.79 +XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
    2.80 +{
    2.81 +  ULONG i, j;
    2.82 +  PACCESS_RANGE AccessRange;
    2.83 +  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
    2.84 +  char **VbdDevices;
    2.85 +  char *msg;
    2.86 +  char buffer[128];
    2.87 +  LARGE_INTEGER WaitTimeout;
    2.88 +
    2.89 +  KeInitializeSpinLock(&DeviceData->Lock);
    2.90 +  KdPrint((__DRIVER_NAME " --> HwScsiFindAdapter\n"));
    2.91 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
    2.92 +
    2.93 +  KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
    2.94 +  KdPrint((__DRIVER_NAME "     BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
    2.95 +
    2.96 +  KdPrint((__DRIVER_NAME "     AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
    2.97 +
    2.98 +  for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
    2.99 +  {
   2.100 +    AccessRange = &(*(ConfigInfo->AccessRanges))[i];
   2.101 +    KdPrint((__DRIVER_NAME "     AccessRange %2d: RangeStart = %08x, RangeLength = %08x, RangeInMemory = %d\n", i, AccessRange->RangeStart.LowPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
   2.102 +    switch (i)
   2.103 +    {
   2.104 +    case 0:
   2.105 +      DeviceData->XenDeviceData = (PXENPCI_XEN_DEVICE_DATA)AccessRange->RangeStart.QuadPart;
   2.106 +      KdPrint((__DRIVER_NAME "     Mapped to virtual address %08x\n", DeviceData->XenDeviceData));
   2.107 +      KdPrint((__DRIVER_NAME "     Magic = %08x\n", DeviceData->XenDeviceData->Magic));
   2.108 +      if (DeviceData->XenDeviceData->Magic != XEN_DATA_MAGIC)
   2.109 +      {
   2.110 +        KdPrint((__DRIVER_NAME "     Invalid Magic Number\n"));
   2.111 +        return SP_RETURN_NOT_FOUND;
   2.112 +      }
   2.113 +      break;
   2.114 +    default:
   2.115 +      break;
   2.116 +    }
   2.117 +  }
   2.118 +
   2.119 +  ConfigInfo->NumberOfBuses = SCSI_BUSES;
   2.120 +  ConfigInfo->MaximumTransferLength = BUF_PAGES_PER_SRB * PAGE_SIZE;
   2.121 +  ConfigInfo->NumberOfPhysicalBreaks = BUF_PAGES_PER_SRB - 1; //11 - 1;
   2.122 +  ConfigInfo->ScatterGather = TRUE;
   2.123 +  ConfigInfo->Master = FALSE;
   2.124 +  ConfigInfo->AlignmentMask = 0;
   2.125 +  ConfigInfo->MaximumNumberOfLogicalUnits = 1;
   2.126 +  ConfigInfo->MaximumNumberOfTargets = SCSI_TARGETS_PER_BUS;
   2.127 +  //ConfigInfo->TaggedQueueing = TRUE;
   2.128 +
   2.129 +
   2.130 +  // This all has to be initialized here as the real Initialize routine
   2.131 +  // is called at DIRQL, and the XenBus stuff has to be called at
   2.132 +  // <= DISPATCH_LEVEL
   2.133 +
   2.134 +  for (i = 0; i < SCSI_BUSES; i++)
   2.135 +  {
   2.136 +    for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
   2.137 +    {
   2.138 +      DeviceData->BusData[i].TargetData[j].Present = 0;
   2.139 +      DeviceData->BusData[i].TargetData[j].DeviceData = DeviceData;
   2.140 +    }
   2.141 +  }
   2.142 +
   2.143 +  DeviceData->XenDeviceData->WatchContext = DeviceExtension;
   2.144 +  KeMemoryBarrier();
   2.145 +  DeviceData->XenDeviceData->WatchHandler = XenVbd_WatchHandler;
   2.146 +
   2.147 +//  KeInitializeEvent(&DeviceData->WaitDevicesEvent, SynchronizationEvent, FALSE);  
   2.148 +  DeviceData->EnumeratedDevices = 0;
   2.149 +  DeviceData->TotalInitialDevices = 0;
   2.150 +
   2.151 +  if (DeviceData->XenDeviceData->AutoEnumerate)
   2.152 +  {
   2.153 +    msg = DeviceData->XenDeviceData->XenInterface.XenBus_List(
   2.154 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
   2.155 +      XBT_NIL, "device/vbd", &VbdDevices);
   2.156 +    if (!msg)
   2.157 +    {
   2.158 +      for (i = 0; VbdDevices[i]; i++)
   2.159 +      {
   2.160 +        KdPrint((__DRIVER_NAME "     found existing vbd device %s\n", VbdDevices[i]));
   2.161 +        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
   2.162 +        XenVbd_WatchHandler(buffer, DeviceData);
   2.163 +        DeviceData->TotalInitialDevices++;
   2.164 +      }  
   2.165 +    }
   2.166 +    //ScsiPortNotification(BusChangeDetected, DeviceData, 0);
   2.167 +  }
   2.168 +
   2.169 +  *Again = FALSE;
   2.170 +
   2.171 +  KdPrint((__DRIVER_NAME " <-- HwScsiFindAdapter\n"));  
   2.172 +
   2.173 +  return SP_RETURN_FOUND;
   2.174 +}
   2.175 +
   2.176 +static VOID 
   2.177 +XenVbd_CheckBusChangedTimer(PVOID DeviceExtension);
   2.178 +
   2.179 +static VOID 
   2.180 +XenVbd_CheckBusEnumeratedTimer(PVOID DeviceExtension)
   2.181 +{
   2.182 +  PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
   2.183 +
   2.184 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   2.185 +  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   2.186 +
   2.187 +  if (DeviceData->EnumeratedDevices >= DeviceData->TotalInitialDevices)
   2.188 +  {
   2.189 +    DeviceData->BusChangePending = 0;
   2.190 +    ScsiPortNotification(NextRequest, DeviceExtension, NULL);
   2.191 +    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
   2.192 +  }
   2.193 +  else
   2.194 +  {
   2.195 +    ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusEnumeratedTimer, 100000);
   2.196 +  }
   2.197 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   2.198 +}
   2.199 +
   2.200  static VOID 
   2.201  XenVbd_CheckBusChangedTimer(PVOID DeviceExtension)
   2.202  {
   2.203 @@ -561,72 +628,11 @@ static BOOLEAN
   2.204  XenVbd_HwScsiInitialize(PVOID DeviceExtension)
   2.205  {
   2.206    PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
   2.207 -  unsigned int i, j;
   2.208 -  NTSTATUS Status;
   2.209 -  char **VbdDevices;
   2.210 -  char *msg;
   2.211 -  char buffer[128];
   2.212 -  LARGE_INTEGER WaitTimeout;
   2.213  
   2.214    KdPrint((__DRIVER_NAME " --> HwScsiInitialize\n"));
   2.215    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   2.216  
   2.217 -  for (i = 0; i < SCSI_BUSES; i++)
   2.218 -  {
   2.219 -    for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
   2.220 -    {
   2.221 -      DeviceData->BusData[i].TargetData[j].Present = 0;
   2.222 -      DeviceData->BusData[i].TargetData[j].DeviceData = DeviceData;
   2.223 -    }
   2.224 -  }
   2.225 -
   2.226 -  DeviceData->XenDeviceData->WatchContext = DeviceExtension;
   2.227 -  KeMemoryBarrier();
   2.228 -  DeviceData->XenDeviceData->WatchHandler = XenVbd_WatchHandler;
   2.229 -
   2.230 -  KeInitializeEvent(&DeviceData->WaitDevicesEvent, SynchronizationEvent, FALSE);  
   2.231 -  DeviceData->EnumeratedDevices = 0;
   2.232 -  if (DeviceData->XenDeviceData->AutoEnumerate)
   2.233 -  {
   2.234 -    msg = DeviceData->XenDeviceData->XenInterface.XenBus_List(
   2.235 -      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
   2.236 -      XBT_NIL, "device/vbd", &VbdDevices);
   2.237 -    if (!msg) {
   2.238 -      for (i = 0; VbdDevices[i]; i++)
   2.239 -      {
   2.240 -        KdPrint((__DRIVER_NAME "     found existing vbd device %s\n", VbdDevices[i]));
   2.241 -        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
   2.242 -        XenVbd_WatchHandler(buffer, DeviceData);
   2.243 -//        WaitTimeout.QuadPart = -600000000;
   2.244 -        KeWaitForSingleObject(&DeviceData->WaitDevicesEvent, Executive, KernelMode, FALSE, NULL);
   2.245 -        KdPrint((__DRIVER_NAME "     %d devices enumerated\n", DeviceData->EnumeratedDevices));
   2.246 -      }  
   2.247 -    }
   2.248 -/*
   2.249 -      for (i = 0; VbdDevices[i]; i++)
   2.250 -      {
   2.251 -        KdPrint((__DRIVER_NAME "     found existing vbd device %s\n", VbdDevices[i]));
   2.252 -        RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
   2.253 -        XenVbd_WatchHandler(buffer, DeviceData);
   2.254 -        //ExFreePoolWithTag(bdDevices[i], XENPCI_POOL_TAG);
   2.255 -      }
   2.256 -      KdPrint((__DRIVER_NAME "     Waiting for %d devices to be enumerated\n", i));
   2.257 -      while (DeviceData->EnumeratedDevices < i)
   2.258 -      {
   2.259 -        WaitTimeout.QuadPart = -600000000;
   2.260 -        if (KeWaitForSingleObject(&DeviceData->WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
   2.261 -        {
   2.262 -          KdPrint((__DRIVER_NAME "     Wait timed out\n"));
   2.263 -          break;
   2.264 -        }
   2.265 -        KdPrint((__DRIVER_NAME "     %d out of %d devices enumerated\n", DeviceData->EnumeratedDevices, i));
   2.266 -      }  
   2.267 -    }
   2.268 -*/
   2.269 -    ScsiPortNotification(BusChangeDetected, DeviceData, 0);
   2.270 -    DeviceData->BusChangePending = 0;
   2.271 -  }
   2.272 -  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
   2.273 +  ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusEnumeratedTimer, 100000);
   2.274  
   2.275    KdPrint((__DRIVER_NAME " <-- HwScsiInitialize\n"));
   2.276  
   2.277 @@ -756,6 +762,15 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   2.278  //  KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
   2.279  //  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   2.280  
   2.281 +  // If we haven't enumerated all the devices yet then just defer the request
   2.282 +  // A timer will issue a NextRequest to get things started again...
   2.283 +  if (DeviceData->EnumeratedDevices < DeviceData->TotalInitialDevices)
   2.284 +  {
   2.285 +    Srb->SrbStatus = SRB_STATUS_BUSY;
   2.286 +    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   2.287 +    return TRUE;
   2.288 +  }
   2.289 +
   2.290    if (Srb->PathId >= SCSI_BUSES || Srb->TargetId >= SCSI_TARGETS_PER_BUS)
   2.291    {
   2.292      Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
     3.1 --- a/xenvbd/xenvbd.h	Mon Dec 31 12:46:47 2007 +1100
     3.2 +++ b/xenvbd/xenvbd.h	Mon Dec 31 23:35:05 2007 +1100
     3.3 @@ -86,8 +86,7 @@ struct
     3.4    int BusChangePending;
     3.5  
     3.6    int EnumeratedDevices;
     3.7 -  KEVENT WaitDevicesEvent;
     3.8 -
     3.9 +  int TotalInitialDevices;
    3.10  } typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
    3.11  
    3.12  #endif