win-pvdrivers

view xenvbd/xenvbd.c @ 156:9a1f4acc38fb

Working on amd64 changes to try and get xenvbd to load properly. Fixed up the compiler warnings under x64 which were caused by public/io/ring.h.
author James Harper <james.harper@bendigoit.com.au>
date Fri Jan 25 13:36:43 2008 +1100 (2008-01-25)
parents edbeec8025e8
children 58d13f9f8ef3
line source
1 #include "xenvbd.h"
2 #include <io/blkif.h>
3 #include <scsi.h>
4 #include <ntddscsi.h>
5 #include <ntdddisk.h>
6 #include <stdlib.h>
7 #include <xen_public.h>
8 #include <io/xenbus.h>
10 #pragma warning(disable: 4127)
12 #define wmb() KeMemoryBarrier()
13 #define mb() KeMemoryBarrier()
15 #define BUF_PAGES_PER_SRB 11
17 DRIVER_INITIALIZE DriverEntry;
19 static ULONG
20 XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again);
21 static BOOLEAN
22 XenVbd_HwScsiInitialize(PVOID DeviceExtension);
23 static BOOLEAN
24 XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb);
25 static BOOLEAN
26 XenVbd_HwScsiInterrupt(PVOID DeviceExtension);
27 static BOOLEAN
28 XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId);
29 static BOOLEAN
30 XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState);
31 static SCSI_ADAPTER_CONTROL_STATUS
32 XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters);
34 #ifdef ALLOC_PRAGMA
35 #pragma alloc_text (INIT, DriverEntry)
36 #endif
38 static BOOLEAN AutoEnumerate;
40 NTSTATUS
41 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
42 {
43 ULONG Status;
44 HW_INITIALIZATION_DATA HwInitializationData;
46 KdPrint((__DRIVER_NAME " --> "__FUNCTION__ "\n"));
47 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
49 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
51 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
52 HwInitializationData.AdapterInterfaceType = Internal; //PNPBus;
53 HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
54 HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
55 HwInitializationData.HwInterrupt = XenVbd_HwScsiInterrupt;
56 HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
57 HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
58 HwInitializationData.HwDmaStarted = NULL;
59 HwInitializationData.HwAdapterState = NULL;
60 HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_DATA);
61 HwInitializationData.SpecificLuExtensionSize = 0;
62 HwInitializationData.SrbExtensionSize = 0;
63 HwInitializationData.NumberOfAccessRanges = 1;
64 HwInitializationData.MapBuffers = TRUE;
65 HwInitializationData.NeedPhysicalAddresses = FALSE;
66 HwInitializationData.TaggedQueuing = TRUE;
67 HwInitializationData.AutoRequestSense = FALSE;
68 HwInitializationData.MultipleRequestPerLu = FALSE;
69 HwInitializationData.ReceiveEvent = FALSE;
70 HwInitializationData.VendorIdLength = 0;
71 HwInitializationData.VendorId = NULL;
72 HwInitializationData.DeviceIdLength = 0;
73 HwInitializationData.DeviceId = NULL;
74 HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
76 Status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
78 if(!NT_SUCCESS(Status))
79 {
80 KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", Status));
81 }
83 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
85 return Status;
86 }
88 static __inline uint64_t
89 GET_ID_FROM_FREELIST(PXENVBD_TARGET_DATA TargetData)
90 {
91 uint64_t free;
92 free = TargetData->shadow_free;
93 TargetData->shadow_free = TargetData->shadow[free].req.id;
94 TargetData->shadow[free].req.id = 0x0fffffee; /* debug */
95 return free;
96 }
98 static __inline VOID
99 ADD_ID_TO_FREELIST(PXENVBD_TARGET_DATA TargetData, uint64_t Id)
100 {
101 TargetData->shadow[Id].req.id = TargetData->shadow_free;
102 TargetData->shadow[Id].Srb = NULL;
103 TargetData->shadow_free = Id;
104 }
106 static BOOLEAN
107 XenVbd_Interrupt(PKINTERRUPT Interrupt, PVOID DeviceExtension)
108 {
109 PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
111 UNREFERENCED_PARAMETER(Interrupt);
113 KdPrint((__DRIVER_NAME " --> Interrupt\n"));
115 TargetData->PendingInterrupt = TRUE;
117 KdPrint((__DRIVER_NAME " <-- Interrupt\n"));
119 return TRUE;
120 }
122 static VOID
123 XenVbd_HwScsiInterruptTarget(PVOID DeviceExtension)
124 {
125 PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
126 PSCSI_REQUEST_BLOCK Srb;
127 RING_IDX i, rp;
128 int j;
129 blkif_response_t *rep;
130 int BlockCount;
131 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
132 int more_to_do = TRUE;
134 KdPrint((__DRIVER_NAME " --> HwScsiInterruptTarget\n"));
136 while (more_to_do)
137 {
138 rp = TargetData->Ring.sring->rsp_prod;
139 KeMemoryBarrier();
140 for (i = TargetData->Ring.rsp_cons; i != rp; i++)
141 {
142 rep = RING_GET_RESPONSE(&TargetData->Ring, i);
143 Srb = TargetData->shadow[rep->id].Srb;
144 BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
146 if (rep->status == BLKIF_RSP_OKAY)
147 Srb->SrbStatus = SRB_STATUS_SUCCESS;
148 else
149 {
150 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
151 if (Srb->Cdb[0] == SCSIOP_READ)
152 KdPrint((__DRIVER_NAME " Operation = Read\n"));
153 else
154 KdPrint((__DRIVER_NAME " Operation = Write\n"));
155 KdPrint((__DRIVER_NAME " Sector = %08X, Count = %d\n", TargetData->shadow[rep->id].req.sector_number, BlockCount));
156 Srb->SrbStatus = SRB_STATUS_ERROR;
157 }
158 for (j = 0; j < TargetData->shadow[rep->id].req.nr_segments; j++)
159 DeviceData->XenDeviceData->XenInterface.GntTbl_EndAccess(
160 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
161 TargetData->shadow[rep->id].req.seg[j].gref);
162 if (Srb->Cdb[0] == SCSIOP_READ)
163 memcpy(Srb->DataBuffer, TargetData->shadow[rep->id].Buf, BlockCount * TargetData->BytesPerSector);
165 ScsiPortNotification(RequestComplete, DeviceData, Srb);
166 ScsiPortNotification(NextLuRequest, DeviceData, Srb->PathId, Srb->TargetId, Srb->Lun);
168 ADD_ID_TO_FREELIST(TargetData, rep->id);
169 }
171 TargetData->Ring.rsp_cons = i;
172 if (i != TargetData->Ring.req_prod_pvt)
173 {
174 RING_FINAL_CHECK_FOR_RESPONSES(&TargetData->Ring, more_to_do);
175 }
176 else
177 {
178 TargetData->Ring.sring->rsp_event = i + 1;
179 more_to_do = FALSE;
180 }
181 }
183 KdPrint((__DRIVER_NAME " <-- HwScsiInterruptTarget\n"));
184 }
186 static BOOLEAN
187 XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
188 {
189 PXENVBD_DEVICE_DATA DeviceData;
190 PXENVBD_TARGET_DATA TargetData;
191 int i, j;
193 KdPrint((__DRIVER_NAME " --> HwScsiInterrupt\n"));
195 DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
197 KeMemoryBarrier();
198 for (i = 0; i < SCSI_BUSES; i++)
199 {
200 for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
201 {
202 TargetData = &DeviceData->BusData[i].TargetData[j];
203 if (TargetData->PendingInterrupt)
204 XenVbd_HwScsiInterruptTarget(TargetData);
205 TargetData->PendingInterrupt = FALSE;
206 }
207 }
208 KdPrint((__DRIVER_NAME " <-- HwScsiInterrupt\n"));
210 return TRUE;
211 }
213 static VOID
214 XenVbd_BackEndStateHandler(char *Path, PVOID Data)
215 {
216 PXENVBD_TARGET_DATA TargetData;
217 PXENVBD_DEVICE_DATA DeviceData;
218 char TmpPath[128];
219 char *Value;
220 int NewState;
221 PMDL Mdl;
222 grant_ref_t ref;
223 blkif_sring_t *SharedRing;
224 ULONG PFN;
225 ULONG i;
227 KdPrint((__DRIVER_NAME " --> BackEndStateHandler\n"));
228 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
230 TargetData = (PXENVBD_TARGET_DATA)Data;
231 DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
233 DeviceData->XenDeviceData->XenInterface.XenBus_Read(
234 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
235 XBT_NIL, Path, &Value);
237 NewState = atoi(Value);
238 switch (NewState)
239 {
240 case XenbusStateUnknown:
241 KdPrint((__DRIVER_NAME " Backend State Changed to Unknown\n"));
242 break;
244 case XenbusStateInitialising:
245 KdPrint((__DRIVER_NAME " Backend State Changed to Initialising\n"));
246 break;
248 case XenbusStateInitWait:
249 KdPrint((__DRIVER_NAME " Backend State Changed to InitWait\n"));
251 TargetData->EventChannel = DeviceData->XenDeviceData->XenInterface.EvtChn_AllocUnbound(
252 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, 0);
253 DeviceData->XenDeviceData->XenInterface.EvtChn_Bind(
254 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
255 TargetData->EventChannel, XenVbd_Interrupt, TargetData);
256 Mdl = AllocatePage();
257 PFN = (ULONG)*MmGetMdlPfnArray(Mdl);
258 SharedRing = (blkif_sring_t *)MmGetMdlVirtualAddress(Mdl);
259 SHARED_RING_INIT(SharedRing);
260 FRONT_RING_INIT(&TargetData->Ring, SharedRing, PAGE_SIZE);
261 ref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
262 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
263 0, PFN, FALSE);
265 TargetData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(blkif_shadow_t) * BLK_RING_SIZE, XENVBD_POOL_TAG);
267 memset(TargetData->shadow, 0, sizeof(blkif_shadow_t) * BLK_RING_SIZE);
268 for (i = 0; i < BLK_RING_SIZE; i++)
269 {
270 TargetData->shadow[i].req.id = i + 1;
271 TargetData->shadow[i].Mdl = AllocatePages(BUF_PAGES_PER_SRB); // stupid that we have to do this!
272 TargetData->shadow[i].Buf = MmGetMdlVirtualAddress(TargetData->shadow[i].Mdl);
273 }
274 TargetData->shadow_free = 0;
275 TargetData->shadow[BLK_RING_SIZE - 1].req.id = 0x0fffffff;
277 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
278 RtlStringCbCatA(TmpPath, 128, "/ring-ref");
279 DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", ref);
281 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
282 RtlStringCbCatA(TmpPath, 128, "/event-channel");
283 DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", TargetData->EventChannel);
285 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
286 RtlStringCbCatA(TmpPath, 128, "/state");
287 DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
289 KdPrint((__DRIVER_NAME " Set Frontend state to Initialised\n"));
290 break;
292 case XenbusStateInitialised:
293 KdPrint((__DRIVER_NAME " Backend State Changed to Initialised\n"));
294 break;
296 case XenbusStateConnected:
297 KdPrint((__DRIVER_NAME " Backend State Changed to Connected\n"));
299 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
300 RtlStringCbCatA(TmpPath, 128, "/device-type");
301 DeviceData->XenDeviceData->XenInterface.XenBus_Read(
302 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
303 XBT_NIL, TmpPath, &Value);
304 if (strcmp(Value, "disk") == 0)
305 {
306 KdPrint((__DRIVER_NAME " DeviceType = Disk\n"));
307 TargetData->DeviceType = XENVBD_DEVICETYPE_DISK;
308 }
309 else if (strcmp(Value, "cdrom") == 0)
310 {
311 KdPrint((__DRIVER_NAME " DeviceType = CDROM\n"));
312 TargetData->DeviceType = XENVBD_DEVICETYPE_CDROM;
313 }
314 else
315 {
316 KdPrint((__DRIVER_NAME " DeviceType = %s (This probably won't work!)\n", Value));
317 TargetData->DeviceType = XENVBD_DEVICETYPE_UNKNOWN;
318 }
320 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
321 RtlStringCbCatA(TmpPath, 128, "/type"); // should probably check that this is 'phy' or 'file' or at least not ''
322 DeviceData->XenDeviceData->XenInterface.XenBus_Read(
323 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
324 XBT_NIL, TmpPath, &Value);
325 KdPrint((__DRIVER_NAME " Backend Type = %s\n", Value));
326 ExFreePool(Value);
328 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
329 RtlStringCbCatA(TmpPath, 128, "/mode"); // should store this...
330 DeviceData->XenDeviceData->XenInterface.XenBus_Read(
331 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
332 XBT_NIL, TmpPath, &Value);
333 KdPrint((__DRIVER_NAME " Backend Mode = %s\n", Value));
334 ExFreePool(Value);
336 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
337 RtlStringCbCatA(TmpPath, 128, "/sector-size");
338 DeviceData->XenDeviceData->XenInterface.XenBus_Read(
339 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
340 XBT_NIL, TmpPath, &Value);
341 // should complain if Value == NULL
342 TargetData->BytesPerSector = atoi(Value);
344 KdPrint((__DRIVER_NAME " BytesPerSector = %d\n", TargetData->BytesPerSector));
346 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
347 RtlStringCbCatA(TmpPath, 128, "/sectors");
348 DeviceData->XenDeviceData->XenInterface.XenBus_Read(
349 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
350 XBT_NIL, TmpPath, &Value);
351 // should complain if Value == NULL
352 TargetData->TotalSectors = (ULONGLONG)atol(Value);
354 KdPrint((__DRIVER_NAME " TotalSectors = %d\n", TargetData->TotalSectors));
356 // should probably use the partition table (if one exists) here for the sectorspertrack and trackspercylinder values
357 TargetData->Geometry.MediaType = FixedMedia;
358 TargetData->Geometry.BytesPerSector = TargetData->BytesPerSector;
359 TargetData->Geometry.SectorsPerTrack = 63;
360 TargetData->Geometry.TracksPerCylinder = 255;
361 TargetData->Geometry.Cylinders.QuadPart = TargetData->TotalSectors / TargetData->Geometry.SectorsPerTrack / TargetData->Geometry.TracksPerCylinder;
362 KdPrint((__DRIVER_NAME " Geometry C/H/S = %d/%d/%d\n", TargetData->Geometry.Cylinders.LowPart, TargetData->Geometry.TracksPerCylinder, TargetData->Geometry.SectorsPerTrack));
364 // now ask windows to rescan the scsi bus...
365 DeviceData->BusChangePending = 1;
367 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
368 RtlStringCbCatA(TmpPath, 128, "/state");
369 DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateConnected);
371 KdPrint((__DRIVER_NAME " Set Frontend state to Connected\n"));
372 InterlockedIncrement(&DeviceData->EnumeratedDevices);
373 KdPrint((__DRIVER_NAME " Added a device\n"));
374 break;
376 case XenbusStateClosing:
377 KdPrint((__DRIVER_NAME " Backend State Changed to Closing\n"));
378 // this behaviour is only to properly close down to then restart in the case of a dump
379 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
380 RtlStringCbCatA(TmpPath, 128, "/state");
381 DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateClosed);
382 KdPrint((__DRIVER_NAME " Set Frontend state to Closed\n"));
383 break;
385 case XenbusStateClosed:
386 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
387 // this behaviour is only to properly close down to then restart in the case of a dump
388 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
389 RtlStringCbCatA(TmpPath, 128, "/state");
390 DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateInitialising);
391 KdPrint((__DRIVER_NAME " Set Frontend state to Initialising\n"));
392 break;
394 default:
395 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", NewState));
396 break;
397 }
399 KdPrint((__DRIVER_NAME " <-- BackEndStateHandler\n"));
400 }
402 static VOID
403 XenVbd_WatchHandler(char *Path, PVOID DeviceExtension)
404 {
405 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
406 char **Bits;
407 int Count;
408 char TmpPath[128];
409 char *Value;
410 int CurrentBus, CurrentTarget;
411 PXENVBD_TARGET_DATA TargetData, VacantTarget;
412 KIRQL OldIrql;
413 int i;
415 KdPrint((__DRIVER_NAME " --> WatchHandler (DeviceData = %08x)\n", DeviceData));
416 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
418 KdPrint((__DRIVER_NAME " Path = %s\n", Path));
420 Bits = SplitString(Path, '/', 4, &Count);
421 switch (Count)
422 {
423 case 0:
424 case 1:
425 case 2:
426 break; // should never happen
427 case 3:
428 break;
429 case 4:
430 if (strcmp(Bits[3], "state") != 0) // we only care when the state appears
431 break;
433 KeAcquireSpinLock(&DeviceData->Lock, &OldIrql);
435 for (VacantTarget = NULL,i = 0; i < SCSI_BUSES * SCSI_TARGETS_PER_BUS; i++)
436 {
437 CurrentBus = i / SCSI_TARGETS_PER_BUS;
438 CurrentTarget = i % SCSI_TARGETS_PER_BUS;
439 if (CurrentTarget == 7) // don't use 7 - it would be for the controller
440 continue;
441 TargetData = &DeviceData->BusData[CurrentBus].TargetData[CurrentTarget];
442 if (TargetData->Present && strncmp(TargetData->Path, Path, strlen(TargetData->Path)) == 0 && Path[strlen(TargetData->Path)] == '/')
443 break; // already exists
444 else if (!TargetData->Present && VacantTarget == NULL)
445 VacantTarget = TargetData;
446 }
447 if (i == SCSI_BUSES * SCSI_TARGETS_PER_BUS && VacantTarget != NULL)
448 {
449 VacantTarget->Present = 1;
450 KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
452 DeviceData->XenDeviceData->XenInterface.XenBus_Read(
453 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
454 XBT_NIL, Path, &Value);
456 if (Value == NULL)
457 {
458 KdPrint((__DRIVER_NAME " blank state?\n"));
459 break;
460 }
461 if (atoi(Value) != XenbusStateInitialising)
462 DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
463 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
464 XBT_NIL, Path, "%d", XenbusStateClosing);
466 RtlStringCbCopyA(VacantTarget->Path, 128, Bits[0]);
467 RtlStringCbCatA(VacantTarget->Path, 128, "/");
468 RtlStringCbCatA(VacantTarget->Path, 128, Bits[1]);
469 RtlStringCbCatA(VacantTarget->Path, 128, "/");
470 RtlStringCbCatA(VacantTarget->Path, 128, Bits[2]);
472 VacantTarget->DeviceIndex = atoi(Bits[2]);
474 RtlStringCbCopyA(TmpPath, 128, VacantTarget->Path);
475 RtlStringCbCatA(TmpPath, 128, "/backend");
476 DeviceData->XenDeviceData->XenInterface.XenBus_Read(
477 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
478 XBT_NIL, TmpPath, &Value);
479 if (Value == NULL)
480 KdPrint((__DRIVER_NAME " Read Failed\n"));
481 else
482 RtlStringCbCopyA(VacantTarget->BackendPath, 128, Value);
483 RtlStringCbCopyA(TmpPath, 128, VacantTarget->BackendPath);
484 RtlStringCbCatA(TmpPath, 128, "/state");
486 DeviceData->XenDeviceData->XenInterface.XenBus_AddWatch(
487 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
488 XBT_NIL, TmpPath, XenVbd_BackEndStateHandler, VacantTarget);
489 }
490 else
491 KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
492 break;
493 }
495 FreeSplitString(Bits, Count);
497 KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));
499 return;
500 }
502 static ULONG
503 XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
504 {
505 ULONG i, j;
506 PACCESS_RANGE AccessRange;
507 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
508 char **VbdDevices;
509 char *msg;
510 char buffer[128];
512 UNREFERENCED_PARAMETER(HwContext);
513 UNREFERENCED_PARAMETER(BusInformation);
514 UNREFERENCED_PARAMETER(ArgumentString);
515 KeInitializeSpinLock(&DeviceData->Lock);
516 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
517 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
519 //#if 0
520 // testing this for dump mode
521 if (KeGetCurrentIrql() > ConfigInfo->BusInterruptLevel)
522 ConfigInfo->BusInterruptLevel = KeGetCurrentIrql();
524 KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
525 KdPrint((__DRIVER_NAME " BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
527 KdPrint((__DRIVER_NAME " AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
529 for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
530 {
531 AccessRange = &(*(ConfigInfo->AccessRanges))[i];
532 KdPrint((__DRIVER_NAME " AccessRange %2d: RangeStart = %p, RangeLength = %x, RangeInMemory = %d\n", i, AccessRange->RangeStart.QuadPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
533 switch (i)
534 {
535 case 0:
536 DeviceData->XenDeviceData = (PVOID)(xen_ulong_t)AccessRange->RangeStart.QuadPart;
537 KdPrint((__DRIVER_NAME " Mapped to virtual address %p\n", DeviceData->XenDeviceData));
538 KdPrint((__DRIVER_NAME " Magic = %08x\n", DeviceData->XenDeviceData->Magic));
539 if (DeviceData->XenDeviceData->Magic != XEN_DATA_MAGIC)
540 {
541 KdPrint((__DRIVER_NAME " Invalid Magic Number\n"));
542 return SP_RETURN_NOT_FOUND;
543 }
544 break;
545 default:
546 break;
547 }
548 }
550 ConfigInfo->MaximumTransferLength = BUF_PAGES_PER_SRB * PAGE_SIZE;
551 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
552 ConfigInfo->NumberOfPhysicalBreaks = 2; //BUF_PAGES_PER_SRB - 1; //11 - 1;
553 ConfigInfo->ScatterGather = TRUE;
554 ConfigInfo->Master = FALSE;
555 ConfigInfo->AlignmentMask = 0;
556 ConfigInfo->NumberOfBuses = SCSI_BUSES;
557 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
558 ConfigInfo->MaximumNumberOfTargets = SCSI_TARGETS_PER_BUS * SCSI_BUSES;
559 //ConfigInfo->TaggedQueueing = TRUE;
562 // This all has to be initialized here as the real Initialize routine
563 // is called at DIRQL, and the XenBus stuff has to be called at
564 // <= DISPATCH_LEVEL
566 for (i = 0; i < SCSI_BUSES; i++)
567 {
568 for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
569 {
570 DeviceData->BusData[i].TargetData[j].Present = 0;
571 DeviceData->BusData[i].TargetData[j].DeviceData = DeviceData;
572 }
573 }
575 DeviceData->XenDeviceData->WatchContext = DeviceExtension;
576 KeMemoryBarrier();
577 DeviceData->XenDeviceData->WatchHandler = XenVbd_WatchHandler;
579 // KeInitializeEvent(&DeviceData->WaitDevicesEvent, SynchronizationEvent, FALSE);
580 DeviceData->EnumeratedDevices = 0;
581 DeviceData->TotalInitialDevices = 0;
583 if (DeviceData->XenDeviceData->AutoEnumerate)
584 {
585 msg = DeviceData->XenDeviceData->XenInterface.XenBus_List(
586 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
587 XBT_NIL, "device/vbd", &VbdDevices);
588 if (!msg)
589 {
590 for (i = 0; VbdDevices[i]; i++)
591 {
592 KdPrint((__DRIVER_NAME " found existing vbd device %s\n", VbdDevices[i]));
593 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
594 XenVbd_WatchHandler(buffer, DeviceData);
595 DeviceData->TotalInitialDevices++;
596 }
597 }
598 //ScsiPortNotification(BusChangeDetected, DeviceData, 0);
599 }
601 //#endif
603 *Again = FALSE;
605 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
607 return SP_RETURN_FOUND;
608 }
610 static VOID
611 XenVbd_CheckBusChangedTimer(PVOID DeviceExtension);
613 static VOID
614 XenVbd_CheckBusEnumeratedTimer(PVOID DeviceExtension)
615 {
616 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
618 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
619 // KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
621 if (DeviceData->EnumeratedDevices >= DeviceData->TotalInitialDevices)
622 {
623 DeviceData->BusChangePending = 0;
624 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
625 ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
626 }
627 else
628 {
629 ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusEnumeratedTimer, 100000);
630 }
631 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
632 }
634 static VOID
635 XenVbd_CheckBusChangedTimer(PVOID DeviceExtension)
636 {
637 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
639 if (DeviceData->BusChangePending)
640 {
641 ScsiPortNotification(BusChangeDetected, DeviceData, 0);
642 DeviceData->BusChangePending = 0;
643 }
644 ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
645 }
647 static BOOLEAN
648 XenVbd_HwScsiInitialize(PVOID DeviceExtension)
649 {
650 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
651 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
653 ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusEnumeratedTimer, 100000);
655 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
657 return TRUE;
658 }
660 static ULONG
661 XenVbd_FillModePage(PXENVBD_DEVICE_DATA DeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
662 {
663 //PMODE_RIGID_GEOMETRY_PAGE ModeRigidGeometry;
665 UNREFERENCED_PARAMETER(DeviceData);
666 UNREFERENCED_PARAMETER(DataBuffer);
667 UNREFERENCED_PARAMETER(BufferLength);
668 UNREFERENCED_PARAMETER(Offset);
670 switch (PageCode)
671 {
672 /*
673 case MODE_PAGE_RIGID_GEOMETRY:
674 if (DeviceData->ScsiData->DeviceType == XENVBD_DEVICETYPE_CDROM)
675 {
676 KdPrint((__DRIVER_NAME " MODE_PAGE_RIGID_GEOMETRY\n"));
677 if (*Offset + sizeof(MODE_RIGID_GEOMETRY_PAGE) > BufferLength)
678 return 1;
679 ModeRigidGeometry = (PMODE_RIGID_GEOMETRY_PAGE)(DataBuffer + *Offset);
680 memset(ModeRigidGeometry, 0, sizeof(MODE_RIGID_GEOMETRY_PAGE));
681 ModeRigidGeometry->PageCode = PageCode;
682 ModeRigidGeometry->PageSavable = 0;
683 ModeRigidGeometry->PageLength = sizeof(MODE_RIGID_GEOMETRY_PAGE);
684 ModeRigidGeometry->NumberOfCylinders[0] = (DeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
685 ModeRigidGeometry->NumberOfCylinders[1] = (DeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
686 ModeRigidGeometry->NumberOfCylinders[2] = (DeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
687 ModeRigidGeometry->NumberOfHeads = DeviceData->Geometry.TracksPerCylinder;
688 //ModeRigidGeometry->LandZoneCyclinder = 0;
689 ModeRigidGeometry->RoataionRate[0] = 0x05;
690 ModeRigidGeometry->RoataionRate[0] = 0x39;
691 *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
692 }
693 break;
694 */
695 case MODE_PAGE_FAULT_REPORTING:
696 break;
697 default:
698 break;
699 }
700 return 0;
701 }
703 // Call with device lock held
704 static VOID
705 XenVbd_PutSrbOnRing(PXENVBD_TARGET_DATA TargetData, PSCSI_REQUEST_BLOCK Srb)
706 {
707 //PUCHAR DataBuffer;
708 blkif_request_t *req;
709 int i;
710 int BlockCount;
711 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
713 // can use SRB_STATUS_BUSY to push the SRB back to windows...
715 // KdPrint((__DRIVER_NAME " --> PutSrbOnRing\n"));
717 if (RING_FULL(&TargetData->Ring))
718 {
719 KdPrint((__DRIVER_NAME " RING IS FULL - EXPECT BADNESS\n"));
720 // TODO: Fail badly here
721 }
723 req = RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt);
725 req->sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
726 BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
728 req->id = GET_ID_FROM_FREELIST(TargetData);
730 if (req->id == 0x0fffffff)
731 {
732 KdPrint((__DRIVER_NAME " Something is horribly wrong in PutSrbOnRing\n"));
733 }
735 req->handle = 0;
736 req->operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
737 TargetData->shadow[req->id].Srb = Srb;
739 // KdPrint((__DRIVER_NAME " DataBuffer = %08X\n", Srb->DataBuffer));
740 // KdPrint((__DRIVER_NAME " BlockCount = %08X\n", BlockCount));
742 req->nr_segments = (UINT8)((BlockCount * TargetData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE);
743 // KdPrint((__DRIVER_NAME " req->nr_segments = %08X\n", req->nr_segments));
745 for (i = 0; i < req->nr_segments; i++)
746 {
747 req->seg[i].gref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
748 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
749 0, (ULONG)MmGetMdlPfnArray(TargetData->shadow[req->id].Mdl)[i], FALSE);
750 req->seg[i].first_sect = 0;
751 if (i == req->nr_segments - 1)
752 req->seg[i].last_sect = (UINT8)((BlockCount - 1) % (PAGE_SIZE / TargetData->BytesPerSector));
753 else
754 req->seg[i].last_sect = (UINT8)(PAGE_SIZE / TargetData->BytesPerSector - 1);
755 // KdPrint((__DRIVER_NAME " Page %d, first_sect = %d, last_sect = %d\n", i, req->seg[i].first_sect, req->seg[i].last_sect));
756 }
757 if (Srb->Cdb[0] == SCSIOP_WRITE)
758 memcpy(TargetData->shadow[req->id].Buf, Srb->DataBuffer, BlockCount * TargetData->BytesPerSector);
759 TargetData->shadow[req->id].req = *req;
760 TargetData->Ring.req_prod_pvt++;
762 // KdPrint((__DRIVER_NAME " <-- PutSrbOnRing\n"));
763 }
765 static BOOLEAN
766 XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
767 {
768 PUCHAR DataBuffer;
769 PCDB cdb;
770 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
771 PXENVBD_TARGET_DATA TargetData;
772 unsigned int i;
773 int notify;
775 KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
776 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
778 // If we haven't enumerated all the devices yet then just defer the request
779 // A timer will issue a NextRequest to get things started again...
780 if (DeviceData->EnumeratedDevices < DeviceData->TotalInitialDevices)
781 {
782 Srb->SrbStatus = SRB_STATUS_BUSY;
783 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
784 return TRUE;
785 }
787 if (Srb->PathId >= SCSI_BUSES || Srb->TargetId >= SCSI_TARGETS_PER_BUS)
788 {
789 Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
790 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
791 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
792 KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
793 return TRUE;
794 }
796 TargetData = &DeviceData->BusData[Srb->PathId].TargetData[Srb->TargetId];
798 if (!TargetData->Present)
799 {
800 Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
801 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
802 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
803 KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Not Present)\n"));
804 return TRUE;
805 }
807 switch (Srb->Function)
808 {
809 case SRB_FUNCTION_EXECUTE_SCSI:
810 cdb = (PCDB)Srb->Cdb;
811 // KdPrint((__DRIVER_NAME " SRB_FUNCTION_EXECUTE_SCSI\n"));
812 switch(cdb->CDB6GENERIC.OperationCode)
813 {
814 case SCSIOP_TEST_UNIT_READY:
815 // KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
816 Srb->SrbStatus = SRB_STATUS_SUCCESS;
817 Srb->ScsiStatus = 0;
818 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
819 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
820 break;
821 case SCSIOP_INQUIRY:
822 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
823 KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
824 KdPrint((__DRIVER_NAME " (Length = %d)\n", Srb->DataTransferLength));
825 KdPrint((__DRIVER_NAME " (Srb->Databuffer = %08x)\n", Srb->DataBuffer));
826 // KdPrint((__DRIVER_NAME " PhysicalAddress.LowPart = %08x\n", ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Length).LowPart));
827 // DataBuffer = ScsiPortGetVirtualAddress(DeviceData, ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Length));
828 // KdPrint((__DRIVER_NAME " (Databuffer = %08x)\n", DataBuffer));
829 // break;
830 DataBuffer = Srb->DataBuffer;
831 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
832 Srb->SrbStatus = SRB_STATUS_SUCCESS;
833 switch (TargetData->DeviceType)
834 {
835 case XENVBD_DEVICETYPE_DISK:
836 if ((Srb->Cdb[1] & 1) == 0)
837 {
838 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
839 DataBuffer[1] = 0x00; // not removable
840 DataBuffer[3] = 32;
841 memcpy(DataBuffer + 8, "XEN ", 8); // vendor id
842 memcpy(DataBuffer + 16, "PV VBD ", 16); // product id
843 memcpy(DataBuffer + 32, "0000", 4); // product revision level
844 }
845 else
846 {
847 switch (Srb->Cdb[2])
848 {
849 case 0x00:
850 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
851 DataBuffer[1] = 0x00;
852 DataBuffer[2] = 0x00;
853 DataBuffer[3] = 2;
854 DataBuffer[4] = 0x00;
855 DataBuffer[5] = 0x80;
856 break;
857 case 0x80:
858 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
859 DataBuffer[1] = 0x80;
860 DataBuffer[2] = 0x00;
861 DataBuffer[3] = 8;
862 DataBuffer[4] = 0x31;
863 DataBuffer[5] = 0x32;
864 DataBuffer[6] = 0x33;
865 DataBuffer[7] = 0x34;
866 DataBuffer[8] = 0x35;
867 DataBuffer[9] = 0x36;
868 DataBuffer[10] = 0x37;
869 DataBuffer[11] = 0x38;
870 break;
871 default:
872 KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", Srb->Cdb[2]));
873 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
874 break;
875 }
876 }
877 break;
878 case XENVBD_DEVICETYPE_CDROM:
879 if ((Srb->Cdb[1] & 1) == 0)
880 {
881 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
882 DataBuffer[1] = 0x01; // removable
883 DataBuffer[3] = 32;
884 memcpy(DataBuffer + 8, "XEN ", 8); // vendor id
885 memcpy(DataBuffer + 16, "PV VBD ", 16); // product id
886 memcpy(DataBuffer + 32, "0000", 4); // product revision level
887 }
888 else
889 {
890 switch (Srb->Cdb[2])
891 {
892 case 0x00:
893 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
894 DataBuffer[1] = 0x00;
895 DataBuffer[2] = 0x00;
896 DataBuffer[3] = 2;
897 DataBuffer[4] = 0x00;
898 DataBuffer[5] = 0x80;
899 break;
900 case 0x80:
901 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
902 DataBuffer[1] = 0x80;
903 DataBuffer[2] = 0x00;
904 DataBuffer[3] = 8;
905 DataBuffer[4] = 0x31;
906 DataBuffer[5] = 0x32;
907 DataBuffer[6] = 0x33;
908 DataBuffer[7] = 0x34;
909 DataBuffer[8] = 0x35;
910 DataBuffer[9] = 0x36;
911 DataBuffer[10] = 0x37;
912 DataBuffer[11] = 0x38;
913 break;
914 default:
915 KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", Srb->Cdb[2]));
916 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
917 break;
918 }
919 }
920 break;
921 default:
922 KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", TargetData->DeviceType));
923 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
924 break;
925 }
926 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
927 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
928 break;
929 case SCSIOP_READ_CAPACITY:
930 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
931 DataBuffer = Srb->DataBuffer;
932 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
933 DataBuffer[0] = (unsigned char)((TargetData->TotalSectors - 1) >> 24) & 0xff;
934 DataBuffer[1] = (unsigned char)((TargetData->TotalSectors - 1) >> 16) & 0xff;
935 DataBuffer[2] = (unsigned char)((TargetData->TotalSectors - 1) >> 8) & 0xff;
936 DataBuffer[3] = (unsigned char)((TargetData->TotalSectors - 1) >> 0) & 0xff;
937 DataBuffer[4] = (unsigned char)(TargetData->BytesPerSector >> 24) & 0xff;
938 DataBuffer[5] = (unsigned char)(TargetData->BytesPerSector >> 16) & 0xff;
939 DataBuffer[6] = (unsigned char)(TargetData->BytesPerSector >> 8) & 0xff;
940 DataBuffer[7] = (unsigned char)(TargetData->BytesPerSector >> 0) & 0xff;
941 Srb->ScsiStatus = 0;
942 Srb->SrbStatus = SRB_STATUS_SUCCESS;
943 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
944 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
945 break;
946 case SCSIOP_MODE_SENSE:
947 KdPrint((__DRIVER_NAME " Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x10, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
948 KdPrint((__DRIVER_NAME " Length = %d\n", Srb->DataTransferLength));
950 Srb->ScsiStatus = 0;
951 Srb->SrbStatus = SRB_STATUS_SUCCESS;
952 Srb->DataTransferLength = 0;
953 DataBuffer = Srb->DataBuffer;
954 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
955 switch(cdb->MODE_SENSE.PageCode)
956 {
957 case MODE_SENSE_RETURN_ALL:
958 //Ptr = (UCHAR *)Srb->DataBuffer;
959 for (i = 0; i < MODE_SENSE_RETURN_ALL; i++)
960 {
961 if (XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength))
962 {
963 break;
964 }
965 }
966 break;
967 default:
968 XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength);
969 break;
970 }
971 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
972 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
973 break;
974 case SCSIOP_READ:
975 case SCSIOP_WRITE:
976 // KdPrint((__DRIVER_NAME " Command = READ/WRITE\n"));
977 XenVbd_PutSrbOnRing(TargetData, Srb);
978 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&TargetData->Ring, notify);
979 if (notify)
980 DeviceData->XenDeviceData->XenInterface.EvtChn_Notify(
981 DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
982 TargetData->EventChannel);
983 if (!RING_FULL(&TargetData->Ring))
984 ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
985 else
986 ScsiPortNotification(NextRequest, DeviceExtension);
987 break;
988 case SCSIOP_REPORT_LUNS:
989 KdPrint((__DRIVER_NAME " Command = REPORT_LUNS\n"));
990 Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
991 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
992 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
993 break;
994 case SCSIOP_READ_TOC:
995 DataBuffer = Srb->DataBuffer;
996 // DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
997 /*
998 #define READ_TOC_FORMAT_TOC 0x00
999 #define READ_TOC_FORMAT_SESSION 0x01
1000 #define READ_TOC_FORMAT_FULL_TOC 0x02
1001 #define READ_TOC_FORMAT_PMA 0x03
1002 #define READ_TOC_FORMAT_ATIP 0x04
1003 */
1004 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
1005 KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
1006 KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
1007 KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
1008 KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
1009 KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
1010 KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
1011 KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
1012 switch (cdb->READ_TOC.Format2)
1014 case READ_TOC_FORMAT_TOC:
1015 DataBuffer[0] = 0; // length MSB
1016 DataBuffer[1] = 10; // length LSB
1017 DataBuffer[2] = 1; // First Track
1018 DataBuffer[3] = 1; // Last Track
1019 DataBuffer[4] = 0; // Reserved
1020 DataBuffer[5] = 0x14; // current position data + uninterrupted data
1021 DataBuffer[6] = 1; // last complete track
1022 DataBuffer[7] = 0; // reserved
1023 DataBuffer[8] = 0; // MSB Block
1024 DataBuffer[9] = 0;
1025 DataBuffer[10] = 0;
1026 DataBuffer[11] = 0; // LSB Block
1027 Srb->SrbStatus = SRB_STATUS_SUCCESS;
1028 break;
1029 case READ_TOC_FORMAT_SESSION:
1030 case READ_TOC_FORMAT_FULL_TOC:
1031 case READ_TOC_FORMAT_PMA:
1032 case READ_TOC_FORMAT_ATIP:
1033 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1034 break;
1036 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1037 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1038 break;
1039 default:
1040 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
1041 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1042 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1043 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1044 break;
1046 break;
1047 case SRB_FUNCTION_CLAIM_DEVICE:
1048 KdPrint((__DRIVER_NAME " SRB_FUNCTION_CLAIM_DEVICE\n"));
1049 // ObReferenceObject(WdfDeviceWdmGetDeviceObject(Device));
1050 // Srb->DataBuffer = WdfDeviceWdmGetDeviceObject(Device);
1051 Srb->SrbStatus = SRB_STATUS_SUCCESS;
1052 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1053 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1054 break;
1055 case SRB_FUNCTION_IO_CONTROL:
1056 KdPrint((__DRIVER_NAME " SRB_FUNCTION_IO_CONTROL\n"));
1057 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1058 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1059 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1060 break;
1061 case SRB_FUNCTION_FLUSH:
1062 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH\n"));
1063 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1064 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1065 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1066 break;
1067 default:
1068 KdPrint((__DRIVER_NAME " Unhandled Srb->Function = %08X\n", Srb->Function));
1069 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1070 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1071 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1072 break;
1075 KdPrint((__DRIVER_NAME " <-- HwScsiStartIo\n"));
1077 return TRUE;
1080 static BOOLEAN
1081 XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
1083 UNREFERENCED_PARAMETER(DeviceExtension);
1084 UNREFERENCED_PARAMETER(PathId);
1087 KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
1088 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1090 KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
1092 return TRUE;
1096 static BOOLEAN
1097 XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
1099 UNREFERENCED_PARAMETER(DeviceExtension);
1100 UNREFERENCED_PARAMETER(Context);
1101 UNREFERENCED_PARAMETER(SaveState);
1103 KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
1104 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1106 KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
1108 return TRUE;
1111 static SCSI_ADAPTER_CONTROL_STATUS
1112 XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
1114 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
1115 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
1117 UNREFERENCED_PARAMETER(DeviceExtension);
1119 KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
1120 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1122 switch (ControlType)
1124 case ScsiQuerySupportedControlTypes:
1125 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
1126 KdPrint((__DRIVER_NAME " ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
1127 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
1128 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
1129 break;
1130 case ScsiStopAdapter:
1131 KdPrint((__DRIVER_NAME " ScsiStopAdapter\n"));
1132 break;
1133 case ScsiRestartAdapter:
1134 KdPrint((__DRIVER_NAME " ScsiRestartAdapter\n"));
1135 break;
1136 case ScsiSetBootConfig:
1137 KdPrint((__DRIVER_NAME " ScsiSetBootConfig\n"));
1138 break;
1139 case ScsiSetRunningConfig:
1140 KdPrint((__DRIVER_NAME " ScsiSetRunningConfig\n"));
1141 break;
1142 default:
1143 KdPrint((__DRIVER_NAME " UNKNOWN\n"));
1144 break;
1147 KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
1149 return Status;