win-pvdrivers

annotate xenvbd_scsiport/xenvbd.c @ 1051:ca993d6b5539

fix regression in xenvbd for >4GB memory
author James Harper <james.harper@bendigoit.com.au>
date Tue May 21 16:09:35 2013 +1000 (2013-05-21)
parents 4de2eb034713
children df3ee58e8b4f
rev   line source
james@1005 1 /*
james@1005 2 PV Drivers for Windows Xen HVM Domains
james@1005 3 Copyright (C) 2007 James Harper
james@1005 4
james@1005 5 This program is free software; you can redistribute it and/or
james@1005 6 modify it under the terms of the GNU General Public License
james@1005 7 as published by the Free Software Foundation; either version 2
james@1005 8 of the License, or (at your option) any later version.
james@1005 9
james@1005 10 This program is distributed in the hope that it will be useful,
james@1005 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
james@1005 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
james@1005 13 GNU General Public License for more details.
james@1005 14
james@1005 15 You should have received a copy of the GNU General Public License
james@1005 16 along with this program; if not, write to the Free Software
james@1005 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
james@1005 18 */
james@1005 19
james@1005 20 #define INITGUID
james@1005 21
james@1005 22 #include "xenvbd.h"
james@1005 23
james@1005 24 #pragma warning(disable: 4127)
james@1005 25
james@1005 26 /* Not really necessary but keeps PREfast happy */
james@1005 27 DRIVER_INITIALIZE DriverEntry;
james@1005 28 static IO_WORKITEM_ROUTINE XenVbd_DisconnectWorkItem;
james@1005 29
james@1005 30 static VOID XenVbd_ProcessSrbList(PXENVBD_DEVICE_DATA xvdd);
james@1005 31 static BOOLEAN XenVbd_ResetBus(PXENVBD_DEVICE_DATA xvdd, ULONG PathId);
james@1005 32 static VOID XenVbd_CompleteDisconnect(PXENVBD_DEVICE_DATA xvdd);
james@1005 33
james@1005 34 static BOOLEAN dump_mode = FALSE;
james@1005 35 #define DUMP_MODE_ERROR_LIMIT 64
james@1005 36 static ULONG dump_mode_errors = 0;
james@1005 37
james@1005 38 #define StorPortAcquireSpinLock(...) {}
james@1005 39 #define StorPortReleaseSpinLock(...) {}
james@1005 40
james@1014 41 static ULONG
james@1014 42 SxxxPortGetSystemAddress(PVOID device_extension, PSCSI_REQUEST_BLOCK srb, PVOID *system_address) {
james@1014 43 UNREFERENCED_PARAMETER(device_extension);
james@1014 44 *system_address = (PUCHAR)srb->DataBuffer;
james@1014 45 return STATUS_SUCCESS;
james@1014 46 }
james@1014 47
james@1025 48 static PHYSICAL_ADDRESS
james@1025 49 SxxxPortGetPhysicalAddress(PVOID device_extension, PSCSI_REQUEST_BLOCK srb, PVOID virtual_address, ULONG *length) {
james@1025 50 UNREFERENCED_PARAMETER(device_extension);
james@1025 51 UNREFERENCED_PARAMETER(srb);
james@1025 52 UNREFERENCED_PARAMETER(length);
james@1025 53 return MmGetPhysicalAddress(virtual_address);
james@1025 54 }
james@1025 55
james@1008 56 #define SxxxPortNotification(NotificationType, DeviceExtension, ...) XenVbd_Notification##NotificationType(DeviceExtension, __VA_ARGS__)
james@1008 57
james@1014 58 static VOID
james@1008 59 XenVbd_NotificationRequestComplete(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb) {
james@1008 60 PXENVBD_SCSIPORT_DATA xvsd = (PXENVBD_SCSIPORT_DATA)xvdd->xvsd;
james@1008 61 srb_list_entry_t *srb_entry = srb->SrbExtension;
james@1008 62 if (srb_entry->outstanding_requests != 0) {
james@1008 63 FUNCTION_MSG("srb outstanding_requests = %d\n", srb_entry->outstanding_requests);
james@1008 64 }
james@1008 65 xvsd->outstanding--;
james@1008 66 ScsiPortNotification(RequestComplete, xvsd, srb);
james@1008 67 }
james@1008 68
james@1008 69 VOID
james@1008 70 XenVbd_NotificationNextLuRequest(PXENVBD_DEVICE_DATA xvdd, UCHAR PathId, UCHAR TargetId, UCHAR Lun) {
james@1008 71 ScsiPortNotification(NextLuRequest, xvdd->xvsd, PathId, TargetId, Lun);
james@1005 72 }
james@1005 73
james@1032 74 VOID
james@1044 75 XenVbd_NotificationNextRequest(PXENVBD_DEVICE_DATA xvdd) {
james@1049 76 ScsiPortNotification(NextRequest, xvdd->xvsd);
james@1044 77 }
james@1044 78
james@1044 79
james@1044 80 VOID
james@1032 81 XenVbd_NotificationBusChangeDetected(PXENVBD_DEVICE_DATA xvdd, UCHAR PathId) {
james@1032 82 ScsiPortNotification(BusChangeDetected, xvdd->xvsd, PathId);
james@1032 83 }
james@1032 84
james@1005 85 #include "..\xenvbd_common\common_miniport.h"
james@1005 86
james@1008 87
james@1005 88 /* called in non-dump mode */
james@1005 89 static ULONG
james@1008 90 XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again) {
james@1005 91 PXENVBD_SCSIPORT_DATA xvsd = (PXENVBD_SCSIPORT_DATA)DeviceExtension;
james@1005 92 PXENVBD_DEVICE_DATA xvdd;
james@1005 93 PACCESS_RANGE access_range;
james@1005 94
james@1005 95 UNREFERENCED_PARAMETER(HwContext);
james@1005 96 UNREFERENCED_PARAMETER(BusInformation);
james@1005 97 UNREFERENCED_PARAMETER(ArgumentString);
james@1005 98
james@1005 99 FUNCTION_ENTER();
james@1027 100 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
james@1027 101 FUNCTION_MSG("xvsd = %p\n", xvsd);
james@1005 102
james@1005 103 if (ConfigInfo->NumberOfAccessRanges != 1) {
james@1005 104 FUNCTION_MSG("NumberOfAccessRanges wrong\n");
james@1005 105 FUNCTION_EXIT();
james@1005 106 return SP_RETURN_BAD_CONFIG;
james@1005 107 }
james@1005 108 if (XnGetVersion() != 1) {
james@1005 109 FUNCTION_MSG("Wrong XnGetVersion\n");
james@1005 110 FUNCTION_EXIT();
james@1005 111 return SP_RETURN_BAD_CONFIG;
james@1005 112 }
james@1027 113 RtlZeroMemory(xvsd, FIELD_OFFSET(XENVBD_SCSIPORT_DATA, aligned_buffer_data));
james@1005 114
james@1005 115 access_range = &((*(ConfigInfo->AccessRanges))[0]);
james@1027 116
james@1027 117 if (!dump_mode) {
james@1027 118 xvdd = (PXENVBD_DEVICE_DATA)(ULONG_PTR)access_range->RangeStart.QuadPart;
james@1027 119 xvsd->xvdd = xvdd;
james@1027 120 xvdd->xvsd = xvsd;
james@1027 121 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvsd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
james@1027 122 } else {
james@1027 123 /* make a copy of xvdd and use that copy */
james@1027 124 xvdd = (PXENVBD_DEVICE_DATA)xvsd->aligned_buffer_data;
james@1027 125 memcpy(xvdd, (PVOID)(ULONG_PTR)access_range->RangeStart.QuadPart, sizeof(XENVBD_DEVICE_DATA));
james@1027 126 /* make sure original xvdd is set to DISCONNECTED or resume will not work */
james@1027 127 ((PXENVBD_DEVICE_DATA)(ULONG_PTR)access_range->RangeStart.QuadPart)->device_state = DEVICE_STATE_DISCONNECTED;
james@1027 128 xvsd->xvdd = xvdd;
james@1027 129 xvdd->xvsd = xvsd;
james@1027 130 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvsd->aligned_buffer_data + sizeof(XENVBD_DEVICE_DATA) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
james@1027 131 if (xvsd->xvdd->device_state != DEVICE_STATE_ACTIVE) {
james@1027 132 /* if we are not connected to the ring when we start dump mode then there is nothing we can do */
james@1027 133 FUNCTION_MSG("Cannot connect backend in dump mode - state = %d\n", xvsd->xvdd->device_state);
james@1027 134 return SP_RETURN_ERROR;
james@1027 135 }
james@1027 136 }
james@1027 137 FUNCTION_MSG("aligned_buffer_data = %p\n", xvsd->aligned_buffer_data);
james@1027 138 FUNCTION_MSG("aligned_buffer = %p\n", xvdd->aligned_buffer);
james@1005 139
james@1005 140 InitializeListHead(&xvdd->srb_list);
james@1005 141 xvdd->aligned_buffer_in_use = FALSE;
james@1005 142 /* align the buffer to PAGE_SIZE */
james@1005 143
james@1005 144 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
james@1005 145 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
james@1005 146 FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
james@1005 147 FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
james@1005 148 if (!dump_mode) {
james@1005 149 xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
james@1005 150 } else {
james@1005 151 xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
james@1005 152 }
james@1005 153
james@1005 154 FUNCTION_MSG("MultipleRequestPerLu = %d\n", ConfigInfo->MultipleRequestPerLu);
james@1005 155 FUNCTION_MSG("TaggedQueuing = %d\n", ConfigInfo->TaggedQueuing);
james@1049 156 FUNCTION_MSG("AutoRequestSense = %d\n", ConfigInfo->AutoRequestSense);
james@1005 157 ConfigInfo->CachesData = FALSE;
james@1005 158 ConfigInfo->MapBuffers = TRUE;
james@1005 159 ConfigInfo->AlignmentMask = 0;
james@1005 160 ConfigInfo->NumberOfBuses = 1;
james@1005 161 ConfigInfo->InitiatorBusId[0] = 1;
james@1005 162 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
james@1005 163 ConfigInfo->MaximumNumberOfTargets = 2;
james@1051 164 FUNCTION_MSG("MapBuffers = %d\n", ConfigInfo->MapBuffers);
james@1051 165 FUNCTION_MSG("NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses);
james@1005 166 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
james@1051 167 FUNCTION_MSG("Dma64BitAddresses supported\n");
james@1005 168 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
james@1051 169 ConfigInfo->ScatterGather = TRUE;
james@1051 170 ConfigInfo->Master = TRUE;
james@1005 171 } else {
james@1005 172 FUNCTION_MSG("Dma64BitAddresses not supported\n");
james@1051 173 ConfigInfo->ScatterGather = FALSE;
james@1051 174 ConfigInfo->Master = FALSE;
james@1005 175 }
james@1005 176 *Again = FALSE;
james@1005 177
james@1005 178 FUNCTION_EXIT();
james@1005 179
james@1005 180 return SP_RETURN_FOUND;
james@1005 181 }
james@1005 182
james@1005 183 /* Called at PASSIVE_LEVEL for non-dump mode */
james@1005 184 static BOOLEAN
james@1008 185 XenVbd_HwScsiInitialize(PVOID DeviceExtension) {
james@1005 186 PXENVBD_SCSIPORT_DATA xvsd = (PXENVBD_SCSIPORT_DATA)DeviceExtension;
james@1005 187 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)xvsd->xvdd;
james@1005 188 ULONG i;
james@1005 189
james@1005 190 FUNCTION_ENTER();
james@1027 191 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
james@1027 192 FUNCTION_MSG("dump_mode = %d\n", dump_mode);
james@1005 193
james@1005 194 xvdd->shadow_free = 0;
james@1005 195 memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
james@1005 196 for (i = 0; i < SHADOW_ENTRIES; i++) {
james@1005 197 xvdd->shadows[i].req.id = i;
james@1005 198 /* make sure leftover real requests's are never confused with dump mode requests */
james@1005 199 if (dump_mode)
james@1005 200 xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
james@1005 201 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
james@1005 202 }
james@1005 203
james@1005 204 if (!dump_mode) {
james@1005 205 /* nothing */
james@1005 206 } else {
james@1005 207 xvdd->grant_tag = (ULONG)'DUMP';
james@1005 208 }
james@1005 209
james@1005 210 FUNCTION_EXIT();
james@1005 211
james@1005 212 return TRUE;
james@1005 213 }
james@1005 214
james@1005 215 /* this is only used during hiber and dump */
james@1005 216 static BOOLEAN
james@1005 217 XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
james@1005 218 {
james@1005 219 PXENVBD_SCSIPORT_DATA xvsd = DeviceExtension;
james@1005 220 XenVbd_HandleEvent(xvsd->xvdd);
james@1008 221 //SxxxPortNotification(NextLuRequest, xvdd, 0, 0, 0);
james@1005 222 return TRUE;
james@1005 223 }
james@1005 224
james@1005 225 static BOOLEAN
james@1005 226 XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
james@1005 227 {
james@1005 228 PXENVBD_SCSIPORT_DATA xvsd = DeviceExtension;
james@1005 229 return XenVbd_ResetBus(xvsd->xvdd, PathId);
james@1005 230 }
james@1005 231
james@1005 232 static VOID
james@1005 233 XenVbd_CompleteDisconnect(PXENVBD_DEVICE_DATA xvdd) {
james@1005 234 PXENVBD_SCSIPORT_DATA xvsd = (PXENVBD_SCSIPORT_DATA)xvdd->xvsd;
james@1005 235 PSCSI_REQUEST_BLOCK srb;
james@1005 236
james@1005 237 if (xvsd->stop_srb) {
james@1005 238 srb = xvsd->stop_srb;
james@1005 239 xvsd->stop_srb = NULL;
james@1005 240 ScsiPortNotification(RequestComplete, xvsd, srb);
james@1005 241 }
james@1005 242 }
james@1005 243
james@1005 244 static BOOLEAN
james@1008 245 XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb) {
james@1005 246 PXENVBD_SCSIPORT_DATA xvsd = DeviceExtension;
james@1005 247 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)xvsd->xvdd;
james@1005 248 PSRB_IO_CONTROL sic;
james@1005 249
james@1008 250 if ((LONG)xvsd->outstanding < 0) {
james@1008 251 FUNCTION_MSG("HwScsiStartIo outstanding = %d\n", xvsd->outstanding);
james@1008 252 }
james@1005 253 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0) {
james@1005 254 FUNCTION_MSG("HwScsiStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun);
james@1005 255 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
james@1005 256 ScsiPortNotification(RequestComplete, xvsd, srb);
james@1005 257 } else if (srb->Function == SRB_FUNCTION_IO_CONTROL && memcmp(((PSRB_IO_CONTROL)srb->DataBuffer)->Signature, XENVBD_CONTROL_SIG, 8) == 0) {
james@1005 258 sic = srb->DataBuffer;
james@1005 259 switch(sic->ControlCode) {
james@1005 260 case XENVBD_CONTROL_EVENT:
james@1005 261 srb->SrbStatus = SRB_STATUS_SUCCESS;
james@1005 262 ScsiPortNotification(RequestComplete, xvsd, srb);
james@1008 263 break;
james@1005 264 case XENVBD_CONTROL_STOP:
james@1005 265 if (xvdd->shadow_free == SHADOW_ENTRIES) {
james@1005 266 srb->SrbStatus = SRB_STATUS_SUCCESS;
james@1005 267 ScsiPortNotification(RequestComplete, xvsd, srb);
james@1008 268 FUNCTION_MSG("CONTROL_STOP done\n");
james@1005 269 } else {
james@1005 270 xvsd->stop_srb = srb;
james@1008 271 FUNCTION_MSG("CONTROL_STOP pended\n");
james@1005 272 }
james@1005 273 break;
james@1005 274 case XENVBD_CONTROL_START:
james@1008 275 // we might need to reload a few things here...
james@1008 276 ScsiPortNotification(RequestComplete, xvsd, srb);
james@1005 277 break;
james@1005 278 default:
james@1005 279 FUNCTION_MSG("XENVBD_CONTROL_%d\n", sic->ControlCode);
james@1008 280 srb->SrbStatus = SRB_STATUS_ERROR;
james@1005 281 ScsiPortNotification(RequestComplete, xvsd, srb);
james@1005 282 break;
james@1005 283 }
james@1005 284 } else if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
james@1005 285 FUNCTION_MSG("HwScsiStartIo Inactive Device (in StartIo)\n");
james@1005 286 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
james@1005 287 ScsiPortNotification(RequestComplete, xvsd, srb);
james@1005 288 } else {
james@1005 289 xvsd->outstanding++;
james@1005 290 XenVbd_PutSrbOnList(xvdd, srb);
james@1005 291 }
james@1014 292 /* HandleEvent also puts queued SRB's on the ring */
james@1014 293 XenVbd_HandleEvent(xvdd);
james@1008 294 /* need 2 spare slots - 1 for EVENT and 1 for STOP/START */
james@1005 295 if (xvsd->outstanding < 30) {
james@1008 296 ScsiPortNotification(NextLuRequest, xvsd, 0, 0, 0);
james@1005 297 } else {
james@1005 298 ScsiPortNotification(NextRequest, xvsd);
james@1005 299 }
james@1005 300 return TRUE;
james@1005 301 }
james@1005 302
james@1005 303 static SCSI_ADAPTER_CONTROL_STATUS
james@1027 304 XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters) {
james@1005 305 PXENVBD_SCSIPORT_DATA xvsd = DeviceExtension;
james@1005 306 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)xvsd->xvdd;
james@1005 307 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
james@1005 308 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
james@1005 309
james@1005 310 FUNCTION_ENTER();
james@1027 311 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
james@1027 312 FUNCTION_MSG("xvsd = %p\n", xvsd);
james@1005 313
james@1027 314 switch (ControlType) {
james@1005 315 case ScsiQuerySupportedControlTypes:
james@1005 316 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
james@1027 317 FUNCTION_MSG("ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType);
james@1005 318 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
james@1005 319 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
james@1005 320 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
james@1005 321 break;
james@1005 322 case ScsiStopAdapter:
james@1027 323 FUNCTION_MSG("ScsiStopAdapter\n");
james@1005 324 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
james@1027 325 FUNCTION_MSG("inactive - nothing to do\n");
james@1005 326 break;
james@1005 327 }
james@1027 328 XN_ASSERT(IsListEmpty(&xvdd->srb_list));
james@1027 329 XN_ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
james@1005 330 break;
james@1005 331 case ScsiRestartAdapter:
james@1027 332 FUNCTION_MSG("ScsiRestartAdapter\n");
james@1008 333 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
james@1027 334 FUNCTION_MSG("inactive - nothing to do\n");
james@1005 335 break;
james@1005 336 }
james@1005 337 /* increase the tag every time we stop/start to track where the gref's came from */
james@1005 338 xvdd->grant_tag++;
james@1005 339 break;
james@1005 340 case ScsiSetBootConfig:
james@1027 341 FUNCTION_MSG("ScsiSetBootConfig\n");
james@1005 342 break;
james@1005 343 case ScsiSetRunningConfig:
james@1027 344 FUNCTION_MSG("ScsiSetRunningConfig\n");
james@1005 345 break;
james@1005 346 default:
james@1027 347 FUNCTION_MSG("UNKNOWN\n");
james@1005 348 break;
james@1005 349 }
james@1005 350
james@1005 351 FUNCTION_EXIT();
james@1005 352
james@1005 353 return Status;
james@1005 354 }
james@1005 355
james@1005 356 NTSTATUS
james@1005 357 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
james@1005 358 ULONG status;
james@1005 359 HW_INITIALIZATION_DATA HwInitializationData;
james@1005 360
james@1005 361 /* RegistryPath == NULL when we are invoked as a crash dump driver */
james@1005 362 if (!RegistryPath) {
james@1005 363 dump_mode = TRUE;
james@1027 364 XnPrintDump();
james@1005 365 }
james@1005 366
james@1005 367 FUNCTION_ENTER();
james@1027 368 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
james@1027 369 FUNCTION_MSG("DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath);
james@1005 370
james@1005 371 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
james@1005 372 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
james@1005 373 HwInitializationData.AdapterInterfaceType = PNPBus; /* not Internal */
james@1005 374 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
james@1005 375 HwInitializationData.NumberOfAccessRanges = 1;
james@1005 376 HwInitializationData.MapBuffers = TRUE;
james@1005 377 HwInitializationData.NeedPhysicalAddresses = FALSE;
james@1005 378 HwInitializationData.TaggedQueuing = TRUE;
james@1005 379 HwInitializationData.AutoRequestSense = TRUE;
james@1005 380 HwInitializationData.MultipleRequestPerLu = TRUE;
james@1005 381 HwInitializationData.ReceiveEvent = FALSE;
james@1005 382 HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
james@1005 383 HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
james@1005 384 HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
james@1005 385 HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
james@1005 386 HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
james@1005 387 if (!dump_mode) {
james@1005 388 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_SCSIPORT_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
james@1005 389 } else {
james@1005 390 HwInitializationData.HwInterrupt = XenVbd_HwScsiInterrupt;
james@1027 391 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_SCSIPORT_DATA, aligned_buffer_data) + sizeof(XENVBD_DEVICE_DATA) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
james@1005 392 }
james@1005 393 status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
james@1005 394
james@1005 395 if(!NT_SUCCESS(status)) {
james@1005 396 FUNCTION_MSG("ScsiPortInitialize failed with status 0x%08x\n", status);
james@1005 397 }
james@1005 398
james@1005 399 FUNCTION_EXIT();
james@1005 400
james@1005 401 return status;
james@1005 402 }