win-pvdrivers

view xenvbd_storport/xenvbd.c @ 1082:8744ec2a3049

Fix race where storport dpc could be called before it was initialised
author James Harper <james.harper@bendigoit.com.au>
date Thu Dec 12 10:50:27 2013 +1100 (2013-12-12)
parents 0243e3b47f36
children 42381a8db72c
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;
189 UNREFERENCED_PARAMETER(HwContext);
190 UNREFERENCED_PARAMETER(BusInformation);
191 UNREFERENCED_PARAMETER(ArgumentString);
193 FUNCTION_ENTER();
194 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
195 FUNCTION_MSG("xvdd = %p\n", xvdd);
196 FUNCTION_MSG("ArgumentString = %s\n", ArgumentString);
198 memcpy(xvdd, ConfigInfo->Reserved, FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data));
199 if (xvdd->device_state != DEVICE_STATE_ACTIVE) {
200 return SP_RETURN_ERROR;
201 }
202 /* restore hypercall_stubs into dump_xenpci */
203 XnSetHypercallStubs(xvdd->hypercall_stubs);
204 /* make sure original xvdd is set to DISCONNECTED or resume will not work */
205 ((PXENVBD_DEVICE_DATA)ConfigInfo->Reserved)->device_state = DEVICE_STATE_DISCONNECTED;
206 InitializeListHead(&xvdd->srb_list);
207 xvdd->aligned_buffer_in_use = FALSE;
208 /* align the buffer to PAGE_SIZE */
209 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
210 xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
211 xvdd->grant_tag = (ULONG)'DUMP';
212 FUNCTION_MSG("aligned_buffer_data = %p\n", xvdd->aligned_buffer_data);
213 FUNCTION_MSG("aligned_buffer = %p\n", xvdd->aligned_buffer);
215 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024;
216 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT;
217 FUNCTION_MSG("ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength);
218 FUNCTION_MSG("ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
219 ConfigInfo->VirtualDevice = FALSE;
220 ConfigInfo->ScatterGather = TRUE;
221 ConfigInfo->Master = TRUE;
222 ConfigInfo->CachesData = FALSE;
223 ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
224 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
225 ConfigInfo->AlignmentMask = 0;
226 ConfigInfo->NumberOfBuses = 1;
227 ConfigInfo->InitiatorBusId[0] = 1;
228 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
229 ConfigInfo->MaximumNumberOfTargets = 2;
230 ConfigInfo->VirtualDevice = FALSE;
231 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) {
232 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
233 FUNCTION_MSG("Dma64BitAddresses supported\n");
234 } else {
235 FUNCTION_MSG("Dma64BitAddresses not supported\n");
236 }
237 *Again = FALSE;
239 FUNCTION_EXIT();
241 return SP_RETURN_FOUND;
242 }
244 /* Called at PASSIVE_LEVEL for non-dump mode */
245 static BOOLEAN
246 XenVbd_HwStorInitialize(PVOID DeviceExtension)
247 {
248 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
249 ULONG i;
251 FUNCTION_ENTER();
252 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
253 FUNCTION_MSG("dump_mode = %d\n", dump_mode);
255 xvdd->shadow_free = 0;
256 memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
257 for (i = 0; i < SHADOW_ENTRIES; i++) {
258 xvdd->shadows[i].req.id = i;
259 /* make sure leftover real requests's are never confused with dump mode requests */
260 if (dump_mode)
261 xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
262 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
263 }
265 FUNCTION_EXIT();
267 return TRUE;
268 }
270 static VOID
271 XenVbd_HandleEventDpc(PSTOR_DPC dpc, PVOID DeviceExtension, PVOID arg1, PVOID arg2) {
272 STOR_LOCK_HANDLE lock_handle;
273 UNREFERENCED_PARAMETER(dpc);
274 UNREFERENCED_PARAMETER(arg1);
275 UNREFERENCED_PARAMETER(arg2);
277 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
278 XenVbd_HandleEvent(DeviceExtension);
279 StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
280 }
282 static VOID
283 XenVbd_HandleEventDIRQL(PVOID DeviceExtension) {
284 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
285 //if (dump_mode) FUNCTION_ENTER();
286 StorPortIssueDpc(DeviceExtension, &xvdd->dpc, NULL, NULL);
287 //if (dump_mode) FUNCTION_EXIT();
288 return;
289 }
291 /* this is only used during hiber and dump */
292 static BOOLEAN
293 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
294 {
295 //FUNCTION_ENTER();
296 XenVbd_HandleEvent(DeviceExtension);
297 //FUNCTION_EXIT();
298 return TRUE;
299 }
301 static BOOLEAN
302 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
303 {
304 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
305 return XenVbd_ResetBus(xvdd, PathId);
306 }
308 static BOOLEAN
309 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
310 {
311 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
312 STOR_LOCK_HANDLE lock_handle;
314 //if (dump_mode) FUNCTION_ENTER();
315 //if (dump_mode) FUNCTION_MSG("srb = %p\n", srb);
317 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
319 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
320 FUNCTION_MSG("HwStorStartIo Inactive Device (in StartIo)\n");
321 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
322 StorPortNotification(RequestComplete, DeviceExtension, srb);
323 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
324 return TRUE;
325 }
327 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
328 {
329 FUNCTION_MSG("HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun);
330 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
331 StorPortNotification(RequestComplete, DeviceExtension, srb);
332 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
333 return TRUE;
334 }
335 XenVbd_PutSrbOnList(xvdd, srb);
337 /* HandleEvent also puts queued SRB's on the ring */
338 XenVbd_HandleEvent(xvdd);
339 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
340 //if (dump_mode) FUNCTION_EXIT();
341 return TRUE;
342 }
344 static SCSI_ADAPTER_CONTROL_STATUS
345 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
346 {
347 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
348 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
349 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
350 //KIRQL OldIrql;
352 FUNCTION_ENTER();
353 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
354 FUNCTION_MSG("ControlType = %d\n", ControlType);
356 switch (ControlType) {
357 case ScsiQuerySupportedControlTypes:
358 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
359 FUNCTION_MSG("ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType);
360 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
361 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
362 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
363 break;
364 case ScsiStopAdapter:
365 FUNCTION_MSG("ScsiStopAdapter\n");
366 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
367 FUNCTION_MSG("inactive - nothing to do\n");
368 break;
369 }
370 XN_ASSERT(IsListEmpty(&xvdd->srb_list));
371 XN_ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
372 if (xvdd->power_action != StorPowerActionHibernate) {
373 /* if hibernate then device_state will be set on our behalf in the hibernate FindAdapter */
374 xvdd->device_state = DEVICE_STATE_DISCONNECTED;
375 //XenVbd_Disconnect(??);
376 }
377 break;
378 case ScsiRestartAdapter:
379 FUNCTION_MSG("ScsiRestartAdapter\n");
380 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
381 FUNCTION_MSG("inactive - nothing to do\n");
382 break;
383 }
384 /* increase the tag every time we stop/start to track where the gref's came from */
385 xvdd->grant_tag++;
386 IoQueueWorkItem(xvdd->connect_workitem, XenVbd_ConnectWorkItem, DelayedWorkQueue, xvdd);
387 break;
388 case ScsiSetBootConfig:
389 FUNCTION_MSG("ScsiSetBootConfig\n");
390 break;
391 case ScsiSetRunningConfig:
392 FUNCTION_MSG("ScsiSetRunningConfig\n");
393 break;
394 default:
395 FUNCTION_MSG("UNKNOWN\n");
396 break;
397 }
399 FUNCTION_EXIT();
401 return Status;
402 }
404 //BOOLEAN dump_mode_hooked = FALSE;
406 NTSTATUS
407 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
408 ULONG status;
409 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
410 HW_INITIALIZATION_DATA HwInitializationData;
412 FUNCTION_ENTER();
413 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
414 FUNCTION_MSG("DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath);
416 /* RegistryPath == NULL when we are invoked as a crash dump driver */
417 if (!RegistryPath) {
418 dump_mode = TRUE;
419 XnPrintDump();
420 }
422 if (!dump_mode) {
423 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
424 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
425 VHwInitializationData.AdapterInterfaceType = Internal;
426 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
427 VHwInitializationData.SpecificLuExtensionSize = 0;
428 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
429 VHwInitializationData.NumberOfAccessRanges = 0;
430 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
431 VHwInitializationData.TaggedQueuing = TRUE;
432 VHwInitializationData.AutoRequestSense = TRUE;
433 VHwInitializationData.MultipleRequestPerLu = TRUE;
434 VHwInitializationData.ReceiveEvent = TRUE;
435 VHwInitializationData.PortVersionFlags = 0;
436 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
437 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
438 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
439 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
440 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
441 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
442 } else {
443 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
444 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
445 HwInitializationData.AdapterInterfaceType = Internal;
446 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
447 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
448 HwInitializationData.NumberOfAccessRanges = 0;
449 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
450 HwInitializationData.NeedPhysicalAddresses = TRUE;
451 HwInitializationData.TaggedQueuing = FALSE;
452 HwInitializationData.AutoRequestSense = TRUE;
453 HwInitializationData.MultipleRequestPerLu = FALSE;
454 HwInitializationData.ReceiveEvent = TRUE;
455 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
456 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
457 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
458 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
459 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
460 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
461 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
462 }
464 if(!NT_SUCCESS(status)) {
465 FUNCTION_MSG("ScsiPortInitialize failed with status 0x%08x\n", status);
466 }
468 FUNCTION_EXIT();
470 return status;
471 }