win-pvdrivers

view xenvbd_storport/xenvbd.c @ 1095:42381a8db72c

Fix compile under Win8 DDK
author James Harper <james.harper@bendigoit.com.au>
date Mon Jan 13 20:26:53 2014 +1100 (2014-01-13)
parents 8744ec2a3049
children 27bd2a5a4704
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 StorPortInitializeDpc(DeviceExtension, &xvdd->dpc, XenVbd_HandleEventDpc);
145 xvdd->grant_tag = (ULONG)'XVBD';
147 /* save hypercall_stubs for crash dump */
148 xvdd->hypercall_stubs = XnGetHypercallStubs();
150 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
151 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
152 FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
153 FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
154 ConfigInfo->VirtualDevice = TRUE;
155 xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
156 status = XenVbd_Connect(DeviceExtension, FALSE);
158 FUNCTION_MSG("ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice);
159 ConfigInfo->ScatterGather = TRUE;
160 ConfigInfo->Master = TRUE;
161 ConfigInfo->CachesData = FALSE;
162 ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
163 FUNCTION_MSG("ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses);
164 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
165 ConfigInfo->AlignmentMask = 0;
166 ConfigInfo->NumberOfBuses = 1;
167 ConfigInfo->InitiatorBusId[0] = 1;
168 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
169 ConfigInfo->MaximumNumberOfTargets = 2;
170 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
171 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
172 FUNCTION_MSG("Dma64BitAddresses supported\n");
173 } else {
174 FUNCTION_MSG("Dma64BitAddresses not supported\n");
175 }
176 *Again = FALSE;
178 FUNCTION_EXIT();
180 return SP_RETURN_FOUND;
181 }
183 /* called in dump mode */
184 static ULONG
185 XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
186 {
187 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
188 #if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8)
189 PVOID dump_data = ConfigInfo->MiniportDumpData;
190 #else
191 PVOID dump_data = ConfigInfo->Reserved;
192 #endif
195 UNREFERENCED_PARAMETER(HwContext);
196 UNREFERENCED_PARAMETER(BusInformation);
197 UNREFERENCED_PARAMETER(ArgumentString);
199 FUNCTION_ENTER();
200 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
201 FUNCTION_MSG("xvdd = %p\n", xvdd);
202 FUNCTION_MSG("ArgumentString = %s\n", ArgumentString);
204 memcpy(xvdd, dump_data, FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data));
205 if (xvdd->device_state != DEVICE_STATE_ACTIVE) {
206 return SP_RETURN_ERROR;
207 }
208 /* restore hypercall_stubs into dump_xenpci */
209 XnSetHypercallStubs(xvdd->hypercall_stubs);
210 /* make sure original xvdd is set to DISCONNECTED or resume will not work */
211 ((PXENVBD_DEVICE_DATA)dump_data)->device_state = DEVICE_STATE_DISCONNECTED;
212 InitializeListHead(&xvdd->srb_list);
213 xvdd->aligned_buffer_in_use = FALSE;
214 /* align the buffer to PAGE_SIZE */
215 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
216 xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
217 xvdd->grant_tag = (ULONG)'DUMP';
218 FUNCTION_MSG("aligned_buffer_data = %p\n", xvdd->aligned_buffer_data);
219 FUNCTION_MSG("aligned_buffer = %p\n", xvdd->aligned_buffer);
221 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024;
222 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT;
223 FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
224 FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
225 ConfigInfo->VirtualDevice = FALSE;
226 ConfigInfo->ScatterGather = TRUE;
227 ConfigInfo->Master = TRUE;
228 ConfigInfo->CachesData = FALSE;
229 ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
230 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
231 ConfigInfo->AlignmentMask = 0;
232 ConfigInfo->NumberOfBuses = 1;
233 ConfigInfo->InitiatorBusId[0] = 1;
234 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
235 ConfigInfo->MaximumNumberOfTargets = 2;
236 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
237 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
238 FUNCTION_MSG("Dma64BitAddresses supported\n");
239 } else {
240 FUNCTION_MSG("Dma64BitAddresses not supported\n");
241 }
242 *Again = FALSE;
244 FUNCTION_EXIT();
246 return SP_RETURN_FOUND;
247 }
249 /* Called at PASSIVE_LEVEL for non-dump mode */
250 static BOOLEAN
251 XenVbd_HwStorInitialize(PVOID DeviceExtension)
252 {
253 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
254 ULONG i;
256 FUNCTION_ENTER();
257 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
258 FUNCTION_MSG("dump_mode = %d\n", dump_mode);
260 xvdd->shadow_free = 0;
261 memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
262 for (i = 0; i < SHADOW_ENTRIES; i++) {
263 xvdd->shadows[i].req.id = i;
264 /* make sure leftover real requests's are never confused with dump mode requests */
265 if (dump_mode)
266 xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
267 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
268 }
270 FUNCTION_EXIT();
272 return TRUE;
273 }
275 static VOID
276 XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2) {
277 STOR_LOCK_HANDLE lock_handle;
278 UNREFERENCED_PARAMETER(dpc);
279 UNREFERENCED_PARAMETER(arg1);
280 UNREFERENCED_PARAMETER(arg2);
282 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
283 XenVbd_HandleEvent(DeviceExtension);
284 StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
285 }
287 static VOID
288 XenVbd_HandleEventDIRQL(PVOID DeviceExtension) {
289 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
290 //if (dump_mode) FUNCTION_ENTER();
291 StorPortIssueDpc(DeviceExtension, &xvdd->dpc, NULL, NULL);
292 //if (dump_mode) FUNCTION_EXIT();
293 return;
294 }
296 /* this is only used during hiber and dump */
297 static BOOLEAN
298 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
299 {
300 //FUNCTION_ENTER();
301 XenVbd_HandleEvent(DeviceExtension);
302 //FUNCTION_EXIT();
303 return TRUE;
304 }
306 static BOOLEAN
307 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
308 {
309 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
310 return XenVbd_ResetBus(xvdd, PathId);
311 }
313 static BOOLEAN
314 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
315 {
316 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
317 STOR_LOCK_HANDLE lock_handle;
319 //if (dump_mode) FUNCTION_ENTER();
320 //if (dump_mode) FUNCTION_MSG("srb = %p\n", srb);
322 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
324 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
325 FUNCTION_MSG("HwStorStartIo Inactive Device (in StartIo)\n");
326 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
327 StorPortNotification(RequestComplete, DeviceExtension, srb);
328 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
329 return TRUE;
330 }
332 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
333 {
334 FUNCTION_MSG("HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun);
335 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
336 StorPortNotification(RequestComplete, DeviceExtension, srb);
337 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
338 return TRUE;
339 }
340 XenVbd_PutSrbOnList(xvdd, srb);
342 /* HandleEvent also puts queued SRB's on the ring */
343 XenVbd_HandleEvent(xvdd);
344 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
345 //if (dump_mode) FUNCTION_EXIT();
346 return TRUE;
347 }
349 static SCSI_ADAPTER_CONTROL_STATUS
350 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
351 {
352 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
353 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
354 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
355 //KIRQL OldIrql;
357 FUNCTION_ENTER();
358 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
359 FUNCTION_MSG("ControlType = %d\n", ControlType);
361 switch (ControlType) {
362 case ScsiQuerySupportedControlTypes:
363 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
364 FUNCTION_MSG("ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType);
365 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
366 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
367 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
368 break;
369 case ScsiStopAdapter:
370 FUNCTION_MSG("ScsiStopAdapter\n");
371 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
372 FUNCTION_MSG("inactive - nothing to do\n");
373 break;
374 }
375 XN_ASSERT(IsListEmpty(&xvdd->srb_list));
376 XN_ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
377 if (xvdd->power_action != StorPowerActionHibernate) {
378 /* if hibernate then device_state will be set on our behalf in the hibernate FindAdapter */
379 xvdd->device_state = DEVICE_STATE_DISCONNECTED;
380 //XenVbd_Disconnect(??);
381 }
382 break;
383 case ScsiRestartAdapter:
384 FUNCTION_MSG("ScsiRestartAdapter\n");
385 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
386 FUNCTION_MSG("inactive - nothing to do\n");
387 break;
388 }
389 /* increase the tag every time we stop/start to track where the gref's came from */
390 xvdd->grant_tag++;
391 IoQueueWorkItem(xvdd->connect_workitem, XenVbd_ConnectWorkItem, DelayedWorkQueue, xvdd);
392 break;
393 case ScsiSetBootConfig:
394 FUNCTION_MSG("ScsiSetBootConfig\n");
395 break;
396 case ScsiSetRunningConfig:
397 FUNCTION_MSG("ScsiSetRunningConfig\n");
398 break;
399 default:
400 FUNCTION_MSG("UNKNOWN\n");
401 break;
402 }
404 FUNCTION_EXIT();
406 return Status;
407 }
409 //BOOLEAN dump_mode_hooked = FALSE;
411 NTSTATUS
412 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
413 ULONG status;
414 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
415 HW_INITIALIZATION_DATA HwInitializationData;
417 FUNCTION_ENTER();
418 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
419 FUNCTION_MSG("DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath);
421 /* RegistryPath == NULL when we are invoked as a crash dump driver */
422 if (!RegistryPath) {
423 dump_mode = TRUE;
424 XnPrintDump();
425 }
427 if (!dump_mode) {
428 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
429 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
430 VHwInitializationData.AdapterInterfaceType = Internal;
431 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
432 VHwInitializationData.SpecificLuExtensionSize = 0;
433 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
434 VHwInitializationData.NumberOfAccessRanges = 0;
435 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
436 VHwInitializationData.TaggedQueuing = TRUE;
437 VHwInitializationData.AutoRequestSense = TRUE;
438 VHwInitializationData.MultipleRequestPerLu = TRUE;
439 VHwInitializationData.ReceiveEvent = TRUE;
440 VHwInitializationData.PortVersionFlags = 0;
441 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
442 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
443 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
444 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
445 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
446 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
447 } else {
448 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
449 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
450 HwInitializationData.AdapterInterfaceType = Internal;
451 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
452 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
453 HwInitializationData.NumberOfAccessRanges = 0;
454 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
455 HwInitializationData.NeedPhysicalAddresses = TRUE;
456 HwInitializationData.TaggedQueuing = FALSE;
457 HwInitializationData.AutoRequestSense = TRUE;
458 HwInitializationData.MultipleRequestPerLu = FALSE;
459 HwInitializationData.ReceiveEvent = TRUE;
460 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
461 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
462 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
463 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
464 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
465 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
466 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
467 }
469 if(!NT_SUCCESS(status)) {
470 FUNCTION_MSG("ScsiPortInitialize failed with status 0x%08x\n", status);
471 }
473 FUNCTION_EXIT();
475 return status;
476 }