win-pvdrivers

view xenvbd_storport/xenvbd.c @ 1025:aa2e51f67f7c

Fix hibernate under Win8. Change debugprints.
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 19 15:14:53 2013 +1100 (2013-02-19)
parents fe3af8f4d54b
children 0243e3b47f36
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #define INITGUID
22 #include "xenvbd.h"
24 #pragma warning(disable: 4127)
26 /* Not really necessary but keeps PREfast happy */
27 DRIVER_INITIALIZE DriverEntry;
28 static IO_WORKITEM_ROUTINE XenVbd_DisconnectWorkItem;
29 static IO_WORKITEM_ROUTINE XenVbd_ConnectWorkItem;
31 static VOID XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2);
32 static VOID XenVbd_HandleEventDIRQL(PVOID DeviceExtension);
33 static VOID XenVbd_ProcessSrbList(PXENVBD_DEVICE_DATA xvdd);
34 static VOID XenVbd_DeviceCallback(PVOID context, ULONG callback_type, PVOID value);
35 static VOID XenVbd_StopRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend);
36 static VOID XenVbd_StartRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend);
37 static VOID XenVbd_CompleteDisconnect(PXENVBD_DEVICE_DATA xvdd);
39 #define SxxxPortNotification(...) StorPortNotification(__VA_ARGS__)
40 #define SxxxPortGetSystemAddress(xvdd, srb, system_address) StorPortGetSystemAddress(xvdd, srb, system_address)
41 #define SxxxPortGetPhysicalAddress(xvdd, srb, virtual_address, length) StorPortGetPhysicalAddress(xvdd, srb, virtual_address, length)
43 static BOOLEAN dump_mode = FALSE;
44 #define DUMP_MODE_ERROR_LIMIT 64
45 static ULONG dump_mode_errors = 0;
47 #include "..\xenvbd_common\common_miniport.h"
48 #include "..\xenvbd_common\common_xen.h"
50 static VOID
51 XenVbd_StopRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend) {
52 NTSTATUS status;
53 STOR_LOCK_HANDLE lock_handle;
55 UNREFERENCED_PARAMETER(suspend);
57 StorPortAcquireSpinLock(xvdd, StartIoLock, NULL, &lock_handle);
58 xvdd->device_state = DEVICE_STATE_DISCONNECTING;
59 if (xvdd->shadow_free == SHADOW_ENTRIES) {
60 FUNCTION_MSG("Ring already empty\n");
61 /* nothing on the ring - okay to disconnect now */
62 StorPortReleaseSpinLock(xvdd, &lock_handle);
63 status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);
64 } else {
65 FUNCTION_MSG("Ring not empty - shadow_free = %d\n", xvdd->shadow_free);
66 /* ring is busy. workitem will set XenbusStateClosing when its empty */
67 StorPortReleaseSpinLock(xvdd, &lock_handle);
68 }
69 }
71 static VOID
72 XenVbd_StartRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend) {
73 STOR_LOCK_HANDLE lock_handle;
75 UNREFERENCED_PARAMETER(suspend);
77 StorPortAcquireSpinLock(xvdd, StartIoLock, NULL, &lock_handle);
78 XenVbd_ProcessSrbList(xvdd);
79 StorPortReleaseSpinLock(xvdd, &lock_handle);
80 }
82 static VOID
83 XenVbd_DisconnectWorkItem(PDEVICE_OBJECT device_object, PVOID context) {
84 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)context;
85 ULONG status;
87 UNREFERENCED_PARAMETER(device_object);
88 FUNCTION_ENTER();
89 status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);
90 FUNCTION_EXIT();
91 }
93 static VOID
94 XenVbd_ConnectWorkItem(PDEVICE_OBJECT device_object, PVOID context) {
95 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)context;
97 UNREFERENCED_PARAMETER(device_object);
98 FUNCTION_ENTER();
99 XenVbd_Connect(xvdd, TRUE);
100 FUNCTION_EXIT();
101 }
103 static VOID
104 XenVbd_CompleteDisconnect(PXENVBD_DEVICE_DATA xvdd) {
105 IoQueueWorkItem(xvdd->disconnect_workitem, XenVbd_DisconnectWorkItem, DelayedWorkQueue, xvdd);
106 }
108 /* called in non-dump mode */
109 static ULONG
110 XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
111 {
112 NTSTATUS status;
113 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
115 //UNREFERENCED_PARAMETER(HwContext);
116 UNREFERENCED_PARAMETER(BusInformation);
117 UNREFERENCED_PARAMETER(LowerDevice);
118 UNREFERENCED_PARAMETER(ArgumentString);
120 FUNCTION_ENTER();
121 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
122 FUNCTION_MSG("xvdd = %p\n", xvdd);
124 if (XnGetVersion() != 1) {
125 FUNCTION_MSG("Wrong XnGetVersion\n");
126 FUNCTION_EXIT();
127 return SP_RETURN_BAD_CONFIG;
128 }
130 RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
131 InitializeListHead(&xvdd->srb_list);
132 KeInitializeEvent(&xvdd->device_state_event, SynchronizationEvent, FALSE);
133 KeInitializeEvent(&xvdd->backend_event, SynchronizationEvent, FALSE);
134 xvdd->pdo = (PDEVICE_OBJECT)HwContext; // TODO: maybe should get PDO from FDO below? HwContext isn't really documented
135 xvdd->fdo = (PDEVICE_OBJECT)BusInformation;
136 xvdd->disconnect_workitem = IoAllocateWorkItem(xvdd->fdo);
137 xvdd->connect_workitem = IoAllocateWorkItem(xvdd->fdo);
138 xvdd->aligned_buffer_in_use = FALSE;
139 /* align the buffer to PAGE_SIZE */
140 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
141 FUNCTION_MSG("aligned_buffer_data = %p\n", xvdd->aligned_buffer_data);
142 FUNCTION_MSG("aligned_buffer = %p\n", xvdd->aligned_buffer);
144 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
145 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
146 FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
147 FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
148 ConfigInfo->VirtualDevice = TRUE;
149 xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
150 status = XenVbd_Connect(DeviceExtension, FALSE);
152 FUNCTION_MSG("ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice);
153 ConfigInfo->ScatterGather = TRUE;
154 ConfigInfo->Master = TRUE;
155 ConfigInfo->CachesData = FALSE;
156 ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
157 FUNCTION_MSG("ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses);
158 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
159 ConfigInfo->AlignmentMask = 0;
160 ConfigInfo->NumberOfBuses = 1;
161 ConfigInfo->InitiatorBusId[0] = 1;
162 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
163 ConfigInfo->MaximumNumberOfTargets = 2;
164 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
165 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
166 FUNCTION_MSG("Dma64BitAddresses supported\n");
167 } else {
168 FUNCTION_MSG("Dma64BitAddresses not supported\n");
169 }
170 *Again = FALSE;
172 FUNCTION_EXIT();
174 return SP_RETURN_FOUND;
175 }
177 /* called in dump mode */
178 static ULONG
179 XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
180 {
181 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
183 UNREFERENCED_PARAMETER(HwContext);
184 UNREFERENCED_PARAMETER(BusInformation);
185 UNREFERENCED_PARAMETER(ArgumentString);
187 FUNCTION_ENTER();
188 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
189 FUNCTION_MSG("xvdd = %p\n", xvdd);
190 FUNCTION_MSG("ArgumentString = %s\n", ArgumentString);
192 memcpy(xvdd, ConfigInfo->Reserved, FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data));
193 if (xvdd->device_state != DEVICE_STATE_ACTIVE) {
194 return SP_RETURN_ERROR;
195 }
196 /* make sure original xvdd is set to DISCONNECTED or resume will not work */
197 ((PXENVBD_DEVICE_DATA)ConfigInfo->Reserved)->device_state = DEVICE_STATE_DISCONNECTED;
198 InitializeListHead(&xvdd->srb_list);
199 xvdd->aligned_buffer_in_use = FALSE;
200 /* align the buffer to PAGE_SIZE */
201 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
202 xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
203 FUNCTION_MSG("aligned_buffer_data = %p\n", xvdd->aligned_buffer_data);
204 FUNCTION_MSG("aligned_buffer = %p\n", xvdd->aligned_buffer);
206 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024;
207 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT;
208 FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
209 FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
210 ConfigInfo->VirtualDevice = FALSE;
211 ConfigInfo->ScatterGather = TRUE;
212 ConfigInfo->Master = TRUE;
213 ConfigInfo->CachesData = FALSE;
214 ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
215 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
216 ConfigInfo->AlignmentMask = 0;
217 ConfigInfo->NumberOfBuses = 1;
218 ConfigInfo->InitiatorBusId[0] = 1;
219 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
220 ConfigInfo->MaximumNumberOfTargets = 2;
221 ConfigInfo->VirtualDevice = FALSE;
222 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
223 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
224 FUNCTION_MSG("Dma64BitAddresses supported\n");
225 } else {
226 FUNCTION_MSG("Dma64BitAddresses not supported\n");
227 }
228 *Again = FALSE;
230 FUNCTION_EXIT();
232 return SP_RETURN_FOUND;
233 }
235 /* Called at PASSIVE_LEVEL for non-dump mode */
236 static BOOLEAN
237 XenVbd_HwStorInitialize(PVOID DeviceExtension)
238 {
239 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
240 ULONG i;
242 FUNCTION_ENTER();
243 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
244 FUNCTION_MSG("dump_mode = %d\n", dump_mode);
246 xvdd->shadow_free = 0;
247 memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
248 for (i = 0; i < SHADOW_ENTRIES; i++) {
249 xvdd->shadows[i].req.id = i;
250 /* make sure leftover real requests's are never confused with dump mode requests */
251 if (dump_mode)
252 xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
253 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
254 }
256 if (!dump_mode) {
257 StorPortInitializeDpc(DeviceExtension, &xvdd->dpc, XenVbd_HandleEventDpc);
258 } else {
259 xvdd->grant_tag = (ULONG)'DUMP';
260 }
262 FUNCTION_EXIT();
264 return TRUE;
265 }
267 static VOID
268 XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2) {
269 STOR_LOCK_HANDLE lock_handle;
270 UNREFERENCED_PARAMETER(dpc);
271 UNREFERENCED_PARAMETER(arg1);
272 UNREFERENCED_PARAMETER(arg2);
274 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
275 XenVbd_HandleEvent(DeviceExtension);
276 StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
277 }
279 static VOID
280 XenVbd_HandleEventDIRQL(PVOID DeviceExtension) {
281 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
282 //if (dump_mode) FUNCTION_ENTER();
283 StorPortIssueDpc(DeviceExtension, &xvdd->dpc, NULL, NULL);
284 //if (dump_mode) FUNCTION_EXIT();
285 return;
286 }
288 /* this is only used during hiber and dump */
289 static BOOLEAN
290 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
291 {
292 //FUNCTION_ENTER();
293 XenVbd_HandleEvent(DeviceExtension);
294 //FUNCTION_EXIT();
295 return TRUE;
296 }
298 static BOOLEAN
299 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
300 {
301 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
302 return XenVbd_ResetBus(xvdd, PathId);
303 }
305 static BOOLEAN
306 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
307 {
308 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
309 STOR_LOCK_HANDLE lock_handle;
311 //if (dump_mode) FUNCTION_ENTER();
312 //if (dump_mode) FUNCTION_MSG("srb = %p\n", srb);
314 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
316 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
317 FUNCTION_MSG("HwStorStartIo Inactive Device (in StartIo)\n");
318 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
319 StorPortNotification(RequestComplete, DeviceExtension, srb);
320 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
321 return TRUE;
322 }
324 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
325 {
326 FUNCTION_MSG("HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun);
327 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
328 StorPortNotification(RequestComplete, DeviceExtension, srb);
329 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
330 return TRUE;
331 }
332 XenVbd_PutSrbOnList(xvdd, srb);
334 /* HandleEvent also puts queued SRB's on the ring */
335 XenVbd_HandleEvent(xvdd);
336 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
337 //if (dump_mode) FUNCTION_EXIT();
338 return TRUE;
339 }
341 static SCSI_ADAPTER_CONTROL_STATUS
342 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
343 {
344 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
345 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
346 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
347 //KIRQL OldIrql;
349 FUNCTION_ENTER();
350 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
351 FUNCTION_MSG("ControlType = %d\n", ControlType);
353 switch (ControlType) {
354 case ScsiQuerySupportedControlTypes:
355 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
356 FUNCTION_MSG("ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType);
357 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
358 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
359 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
360 break;
361 case ScsiStopAdapter:
362 FUNCTION_MSG("ScsiStopAdapter\n");
363 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
364 FUNCTION_MSG("inactive - nothing to do\n");
365 break;
366 }
367 XN_ASSERT(IsListEmpty(&xvdd->srb_list));
368 XN_ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
369 if (xvdd->power_action != StorPowerActionHibernate) {
370 /* if hibernate then device_state will be set on our behalf in the hibernate FindAdapter */
371 xvdd->device_state = DEVICE_STATE_DISCONNECTED;
372 //XenVbd_Disconnect(??);
373 }
374 break;
375 case ScsiRestartAdapter:
376 FUNCTION_MSG("ScsiRestartAdapter\n");
377 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
378 FUNCTION_MSG("inactive - nothing to do\n");
379 break;
380 }
381 /* increase the tag every time we stop/start to track where the gref's came from */
382 xvdd->grant_tag++;
383 IoQueueWorkItem(xvdd->connect_workitem, XenVbd_ConnectWorkItem, DelayedWorkQueue, xvdd);
384 break;
385 case ScsiSetBootConfig:
386 FUNCTION_MSG("ScsiSetBootConfig\n");
387 break;
388 case ScsiSetRunningConfig:
389 FUNCTION_MSG("ScsiSetRunningConfig\n");
390 break;
391 default:
392 FUNCTION_MSG("UNKNOWN\n");
393 break;
394 }
396 FUNCTION_EXIT();
398 return Status;
399 }
401 //BOOLEAN dump_mode_hooked = FALSE;
403 NTSTATUS
404 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
405 ULONG status;
406 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
407 HW_INITIALIZATION_DATA HwInitializationData;
409 FUNCTION_ENTER();
410 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
411 FUNCTION_MSG("DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath);
413 /* RegistryPath == NULL when we are invoked as a crash dump driver */
414 if (!RegistryPath) {
415 dump_mode = TRUE;
416 XnPrintDump();
417 }
419 if (!dump_mode) {
420 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
421 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
422 VHwInitializationData.AdapterInterfaceType = Internal;
423 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
424 VHwInitializationData.SpecificLuExtensionSize = 0;
425 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
426 VHwInitializationData.NumberOfAccessRanges = 0;
427 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
428 VHwInitializationData.TaggedQueuing = TRUE;
429 VHwInitializationData.AutoRequestSense = TRUE;
430 VHwInitializationData.MultipleRequestPerLu = TRUE;
431 VHwInitializationData.ReceiveEvent = TRUE;
432 VHwInitializationData.PortVersionFlags = 0;
433 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
434 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
435 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
436 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
437 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
438 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
439 } else {
440 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
441 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
442 HwInitializationData.AdapterInterfaceType = Internal;
443 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
444 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
445 HwInitializationData.NumberOfAccessRanges = 0;
446 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
447 HwInitializationData.NeedPhysicalAddresses = TRUE;
448 HwInitializationData.TaggedQueuing = FALSE;
449 HwInitializationData.AutoRequestSense = TRUE;
450 HwInitializationData.MultipleRequestPerLu = FALSE;
451 HwInitializationData.ReceiveEvent = TRUE;
452 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
453 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
454 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
455 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
456 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
457 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
458 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
459 }
461 if(!NT_SUCCESS(status)) {
462 FUNCTION_MSG("ScsiPortInitialize failed with status 0x%08x\n", status);
463 }
465 FUNCTION_EXIT();
467 return status;
468 }