win-pvdrivers

view xenvbd_storport/xenvbd.c @ 1099:27bd2a5a4704

License change from GPL to BSD
author James Harper <james.harper@bendigoit.com.au>
date Thu Mar 13 13:38:31 2014 +1100 (2014-03-13)
parents 42381a8db72c
children d5d8c518a090
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
4 Copyright (c) 2014, James Harper
5 All rights reserved.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 * Neither the name of James Harper nor the
15 names of its contributors may be used to endorse or promote products
16 derived from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL JAMES HARPER BE LIABLE FOR ANY
22 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
30 #define INITGUID
32 #include "xenvbd.h"
34 #pragma warning(disable: 4127)
36 /* Not really necessary but keeps PREfast happy */
37 DRIVER_INITIALIZE DriverEntry;
38 static IO_WORKITEM_ROUTINE XenVbd_DisconnectWorkItem;
39 static IO_WORKITEM_ROUTINE XenVbd_ConnectWorkItem;
41 static VOID XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2);
42 static VOID XenVbd_HandleEventDIRQL(PVOID DeviceExtension);
43 static VOID XenVbd_ProcessSrbList(PXENVBD_DEVICE_DATA xvdd);
44 static VOID XenVbd_DeviceCallback(PVOID context, ULONG callback_type, PVOID value);
45 static VOID XenVbd_StopRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend);
46 static VOID XenVbd_StartRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend);
47 static VOID XenVbd_CompleteDisconnect(PXENVBD_DEVICE_DATA xvdd);
49 #define SxxxPortNotification(...) StorPortNotification(__VA_ARGS__)
50 #define SxxxPortGetSystemAddress(xvdd, srb, system_address) StorPortGetSystemAddress(xvdd, srb, system_address)
51 #define SxxxPortGetPhysicalAddress(xvdd, srb, virtual_address, length) StorPortGetPhysicalAddress(xvdd, srb, virtual_address, length)
53 static BOOLEAN dump_mode = FALSE;
54 #define DUMP_MODE_ERROR_LIMIT 64
55 static ULONG dump_mode_errors = 0;
57 #include "..\xenvbd_common\common_miniport.h"
58 #include "..\xenvbd_common\common_xen.h"
60 static VOID
61 XenVbd_StopRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend) {
62 NTSTATUS status;
63 STOR_LOCK_HANDLE lock_handle;
65 UNREFERENCED_PARAMETER(suspend);
67 StorPortAcquireSpinLock(xvdd, StartIoLock, NULL, &lock_handle);
68 xvdd->device_state = DEVICE_STATE_DISCONNECTING;
69 if (xvdd->shadow_free == SHADOW_ENTRIES) {
70 FUNCTION_MSG("Ring already empty\n");
71 /* nothing on the ring - okay to disconnect now */
72 StorPortReleaseSpinLock(xvdd, &lock_handle);
73 status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);
74 } else {
75 FUNCTION_MSG("Ring not empty - shadow_free = %d\n", xvdd->shadow_free);
76 /* ring is busy. workitem will set XenbusStateClosing when its empty */
77 StorPortReleaseSpinLock(xvdd, &lock_handle);
78 }
79 }
81 static VOID
82 XenVbd_StartRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend) {
83 STOR_LOCK_HANDLE lock_handle;
85 UNREFERENCED_PARAMETER(suspend);
87 StorPortAcquireSpinLock(xvdd, StartIoLock, NULL, &lock_handle);
88 XenVbd_ProcessSrbList(xvdd);
89 StorPortReleaseSpinLock(xvdd, &lock_handle);
90 }
92 static VOID
93 XenVbd_DisconnectWorkItem(PDEVICE_OBJECT device_object, PVOID context) {
94 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)context;
95 ULONG status;
97 UNREFERENCED_PARAMETER(device_object);
98 FUNCTION_ENTER();
99 status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);
100 FUNCTION_EXIT();
101 }
103 static VOID
104 XenVbd_ConnectWorkItem(PDEVICE_OBJECT device_object, PVOID context) {
105 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)context;
107 UNREFERENCED_PARAMETER(device_object);
108 FUNCTION_ENTER();
109 XenVbd_Connect(xvdd, TRUE);
110 FUNCTION_EXIT();
111 }
113 static VOID
114 XenVbd_CompleteDisconnect(PXENVBD_DEVICE_DATA xvdd) {
115 IoQueueWorkItem(xvdd->disconnect_workitem, XenVbd_DisconnectWorkItem, DelayedWorkQueue, xvdd);
116 }
118 /* called in non-dump mode */
119 static ULONG
120 XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
121 {
122 NTSTATUS status;
123 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
125 //UNREFERENCED_PARAMETER(HwContext);
126 UNREFERENCED_PARAMETER(BusInformation);
127 UNREFERENCED_PARAMETER(LowerDevice);
128 UNREFERENCED_PARAMETER(ArgumentString);
130 FUNCTION_ENTER();
131 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
132 FUNCTION_MSG("xvdd = %p\n", xvdd);
134 if (XnGetVersion() != 1) {
135 FUNCTION_MSG("Wrong XnGetVersion\n");
136 FUNCTION_EXIT();
137 return SP_RETURN_BAD_CONFIG;
138 }
140 RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
141 InitializeListHead(&xvdd->srb_list);
142 KeInitializeEvent(&xvdd->device_state_event, SynchronizationEvent, FALSE);
143 KeInitializeEvent(&xvdd->backend_event, SynchronizationEvent, FALSE);
144 xvdd->pdo = (PDEVICE_OBJECT)HwContext; // TODO: maybe should get PDO from FDO below? HwContext isn't really documented
145 xvdd->fdo = (PDEVICE_OBJECT)BusInformation;
146 xvdd->disconnect_workitem = IoAllocateWorkItem(xvdd->fdo);
147 xvdd->connect_workitem = IoAllocateWorkItem(xvdd->fdo);
148 xvdd->aligned_buffer_in_use = FALSE;
149 /* align the buffer to PAGE_SIZE */
150 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
151 FUNCTION_MSG("aligned_buffer_data = %p\n", xvdd->aligned_buffer_data);
152 FUNCTION_MSG("aligned_buffer = %p\n", xvdd->aligned_buffer);
154 StorPortInitializeDpc(DeviceExtension, &xvdd->dpc, XenVbd_HandleEventDpc);
155 xvdd->grant_tag = (ULONG)'XVBD';
157 /* save hypercall_stubs for crash dump */
158 xvdd->hypercall_stubs = XnGetHypercallStubs();
160 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
161 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
162 FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
163 FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
164 ConfigInfo->VirtualDevice = TRUE;
165 xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
166 status = XenVbd_Connect(DeviceExtension, FALSE);
168 FUNCTION_MSG("ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice);
169 ConfigInfo->ScatterGather = TRUE;
170 ConfigInfo->Master = TRUE;
171 ConfigInfo->CachesData = FALSE;
172 ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
173 FUNCTION_MSG("ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses);
174 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
175 ConfigInfo->AlignmentMask = 0;
176 ConfigInfo->NumberOfBuses = 1;
177 ConfigInfo->InitiatorBusId[0] = 1;
178 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
179 ConfigInfo->MaximumNumberOfTargets = 2;
180 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
181 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
182 FUNCTION_MSG("Dma64BitAddresses supported\n");
183 } else {
184 FUNCTION_MSG("Dma64BitAddresses not supported\n");
185 }
186 *Again = FALSE;
188 FUNCTION_EXIT();
190 return SP_RETURN_FOUND;
191 }
193 /* called in dump mode */
194 static ULONG
195 XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
196 {
197 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
198 #if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8)
199 PVOID dump_data = ConfigInfo->MiniportDumpData;
200 #else
201 PVOID dump_data = ConfigInfo->Reserved;
202 #endif
205 UNREFERENCED_PARAMETER(HwContext);
206 UNREFERENCED_PARAMETER(BusInformation);
207 UNREFERENCED_PARAMETER(ArgumentString);
209 FUNCTION_ENTER();
210 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
211 FUNCTION_MSG("xvdd = %p\n", xvdd);
212 FUNCTION_MSG("ArgumentString = %s\n", ArgumentString);
214 memcpy(xvdd, dump_data, FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data));
215 if (xvdd->device_state != DEVICE_STATE_ACTIVE) {
216 return SP_RETURN_ERROR;
217 }
218 /* restore hypercall_stubs into dump_xenpci */
219 XnSetHypercallStubs(xvdd->hypercall_stubs);
220 /* make sure original xvdd is set to DISCONNECTED or resume will not work */
221 ((PXENVBD_DEVICE_DATA)dump_data)->device_state = DEVICE_STATE_DISCONNECTED;
222 InitializeListHead(&xvdd->srb_list);
223 xvdd->aligned_buffer_in_use = FALSE;
224 /* align the buffer to PAGE_SIZE */
225 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
226 xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
227 xvdd->grant_tag = (ULONG)'DUMP';
228 FUNCTION_MSG("aligned_buffer_data = %p\n", xvdd->aligned_buffer_data);
229 FUNCTION_MSG("aligned_buffer = %p\n", xvdd->aligned_buffer);
231 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024;
232 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT;
233 FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
234 FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
235 ConfigInfo->VirtualDevice = FALSE;
236 ConfigInfo->ScatterGather = TRUE;
237 ConfigInfo->Master = TRUE;
238 ConfigInfo->CachesData = FALSE;
239 ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
240 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
241 ConfigInfo->AlignmentMask = 0;
242 ConfigInfo->NumberOfBuses = 1;
243 ConfigInfo->InitiatorBusId[0] = 1;
244 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
245 ConfigInfo->MaximumNumberOfTargets = 2;
246 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
247 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
248 FUNCTION_MSG("Dma64BitAddresses supported\n");
249 } else {
250 FUNCTION_MSG("Dma64BitAddresses not supported\n");
251 }
252 *Again = FALSE;
254 FUNCTION_EXIT();
256 return SP_RETURN_FOUND;
257 }
259 /* Called at PASSIVE_LEVEL for non-dump mode */
260 static BOOLEAN
261 XenVbd_HwStorInitialize(PVOID DeviceExtension)
262 {
263 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
264 ULONG i;
266 FUNCTION_ENTER();
267 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
268 FUNCTION_MSG("dump_mode = %d\n", dump_mode);
270 xvdd->shadow_free = 0;
271 memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
272 for (i = 0; i < SHADOW_ENTRIES; i++) {
273 xvdd->shadows[i].req.id = i;
274 /* make sure leftover real requests's are never confused with dump mode requests */
275 if (dump_mode)
276 xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
277 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
278 }
280 FUNCTION_EXIT();
282 return TRUE;
283 }
285 static VOID
286 XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2) {
287 STOR_LOCK_HANDLE lock_handle;
288 UNREFERENCED_PARAMETER(dpc);
289 UNREFERENCED_PARAMETER(arg1);
290 UNREFERENCED_PARAMETER(arg2);
292 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
293 XenVbd_HandleEvent(DeviceExtension);
294 StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
295 }
297 static VOID
298 XenVbd_HandleEventDIRQL(PVOID DeviceExtension) {
299 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
300 //if (dump_mode) FUNCTION_ENTER();
301 StorPortIssueDpc(DeviceExtension, &xvdd->dpc, NULL, NULL);
302 //if (dump_mode) FUNCTION_EXIT();
303 return;
304 }
306 /* this is only used during hiber and dump */
307 static BOOLEAN
308 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
309 {
310 //FUNCTION_ENTER();
311 XenVbd_HandleEvent(DeviceExtension);
312 //FUNCTION_EXIT();
313 return TRUE;
314 }
316 static BOOLEAN
317 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
318 {
319 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
320 return XenVbd_ResetBus(xvdd, PathId);
321 }
323 static BOOLEAN
324 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
325 {
326 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
327 STOR_LOCK_HANDLE lock_handle;
329 //if (dump_mode) FUNCTION_ENTER();
330 //if (dump_mode) FUNCTION_MSG("srb = %p\n", srb);
332 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
334 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
335 FUNCTION_MSG("HwStorStartIo Inactive Device (in StartIo)\n");
336 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
337 StorPortNotification(RequestComplete, DeviceExtension, srb);
338 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
339 return TRUE;
340 }
342 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
343 {
344 FUNCTION_MSG("HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun);
345 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
346 StorPortNotification(RequestComplete, DeviceExtension, srb);
347 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
348 return TRUE;
349 }
350 XenVbd_PutSrbOnList(xvdd, srb);
352 /* HandleEvent also puts queued SRB's on the ring */
353 XenVbd_HandleEvent(xvdd);
354 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
355 //if (dump_mode) FUNCTION_EXIT();
356 return TRUE;
357 }
359 static SCSI_ADAPTER_CONTROL_STATUS
360 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
361 {
362 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
363 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
364 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
365 //KIRQL OldIrql;
367 FUNCTION_ENTER();
368 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
369 FUNCTION_MSG("ControlType = %d\n", ControlType);
371 switch (ControlType) {
372 case ScsiQuerySupportedControlTypes:
373 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
374 FUNCTION_MSG("ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType);
375 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
376 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
377 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
378 break;
379 case ScsiStopAdapter:
380 FUNCTION_MSG("ScsiStopAdapter\n");
381 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
382 FUNCTION_MSG("inactive - nothing to do\n");
383 break;
384 }
385 XN_ASSERT(IsListEmpty(&xvdd->srb_list));
386 XN_ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
387 if (xvdd->power_action != StorPowerActionHibernate) {
388 /* if hibernate then device_state will be set on our behalf in the hibernate FindAdapter */
389 xvdd->device_state = DEVICE_STATE_DISCONNECTED;
390 //XenVbd_Disconnect(??);
391 }
392 break;
393 case ScsiRestartAdapter:
394 FUNCTION_MSG("ScsiRestartAdapter\n");
395 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
396 FUNCTION_MSG("inactive - nothing to do\n");
397 break;
398 }
399 /* increase the tag every time we stop/start to track where the gref's came from */
400 xvdd->grant_tag++;
401 IoQueueWorkItem(xvdd->connect_workitem, XenVbd_ConnectWorkItem, DelayedWorkQueue, xvdd);
402 break;
403 case ScsiSetBootConfig:
404 FUNCTION_MSG("ScsiSetBootConfig\n");
405 break;
406 case ScsiSetRunningConfig:
407 FUNCTION_MSG("ScsiSetRunningConfig\n");
408 break;
409 default:
410 FUNCTION_MSG("UNKNOWN\n");
411 break;
412 }
414 FUNCTION_EXIT();
416 return Status;
417 }
419 //BOOLEAN dump_mode_hooked = FALSE;
421 NTSTATUS
422 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
423 ULONG status;
424 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
425 HW_INITIALIZATION_DATA HwInitializationData;
427 FUNCTION_ENTER();
428 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
429 FUNCTION_MSG("DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath);
431 /* RegistryPath == NULL when we are invoked as a crash dump driver */
432 if (!RegistryPath) {
433 dump_mode = TRUE;
434 XnPrintDump();
435 }
437 if (!dump_mode) {
438 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
439 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
440 VHwInitializationData.AdapterInterfaceType = Internal;
441 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
442 VHwInitializationData.SpecificLuExtensionSize = 0;
443 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
444 VHwInitializationData.NumberOfAccessRanges = 0;
445 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
446 VHwInitializationData.TaggedQueuing = TRUE;
447 VHwInitializationData.AutoRequestSense = TRUE;
448 VHwInitializationData.MultipleRequestPerLu = TRUE;
449 VHwInitializationData.ReceiveEvent = TRUE;
450 VHwInitializationData.PortVersionFlags = 0;
451 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
452 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
453 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
454 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
455 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
456 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
457 } else {
458 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
459 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
460 HwInitializationData.AdapterInterfaceType = Internal;
461 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
462 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
463 HwInitializationData.NumberOfAccessRanges = 0;
464 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
465 HwInitializationData.NeedPhysicalAddresses = TRUE;
466 HwInitializationData.TaggedQueuing = FALSE;
467 HwInitializationData.AutoRequestSense = TRUE;
468 HwInitializationData.MultipleRequestPerLu = FALSE;
469 HwInitializationData.ReceiveEvent = TRUE;
470 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
471 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
472 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
473 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
474 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
475 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
476 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
477 }
479 if(!NT_SUCCESS(status)) {
480 FUNCTION_MSG("ScsiPortInitialize failed with status 0x%08x\n", status);
481 }
483 FUNCTION_EXIT();
485 return status;
486 }