win-pvdrivers

view xenvbd/xenvbd.c @ 66:be0e5f13ec5f

Fixed a merge problem. Appears to be working now.
author James Harper <james.harper@bendigoit.com.au>
date Wed Dec 19 20:27:40 2007 +1100 (2007-12-19)
parents d01d2a544b72
children 21502e79acc3
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 #define wmb() KeMemoryBarrier()
11 #define mb() KeMemoryBarrier()
13 #define BUF_PAGES_PER_SRB 11
15 DRIVER_INITIALIZE DriverEntry;
17 static ULONG
18 XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again);
19 static BOOLEAN
20 XenVbd_HwScsiInitialize(PVOID DeviceExtension);
21 static BOOLEAN
22 XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb);
23 static BOOLEAN
24 XenVbd_HwScsiInterrupt(PVOID DeviceExtension);
25 static BOOLEAN
26 XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId);
27 static BOOLEAN
28 XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState);
29 static SCSI_ADAPTER_CONTROL_STATUS
30 XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters);
32 #ifdef ALLOC_PRAGMA
33 #pragma alloc_text (INIT, DriverEntry)
34 #endif
36 static BOOLEAN AutoEnumerate;
38 NTSTATUS
39 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
40 {
41 ULONG Status;
42 HW_INITIALIZATION_DATA HwInitializationData;
44 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
46 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
48 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
49 HwInitializationData.AdapterInterfaceType = Internal; //PNPBus;
50 HwInitializationData.HwInitialize = XenVbd_HwScsiInitialize;
51 HwInitializationData.HwStartIo = XenVbd_HwScsiStartIo;
52 HwInitializationData.HwInterrupt = XenVbd_HwScsiInterrupt;
53 HwInitializationData.HwFindAdapter = XenVbd_HwScsiFindAdapter;
54 HwInitializationData.HwResetBus = XenVbd_HwScsiResetBus;
55 HwInitializationData.HwDmaStarted = NULL;
56 HwInitializationData.HwAdapterState = NULL;
57 HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_DATA);
58 HwInitializationData.SpecificLuExtensionSize = 0;
59 HwInitializationData.SrbExtensionSize = 0;
60 HwInitializationData.NumberOfAccessRanges = 1;
62 //HwInitializationData.MapBuffers = FALSE;
63 HwInitializationData.MapBuffers = TRUE;
65 HwInitializationData.NeedPhysicalAddresses = FALSE;
66 // HwInitializationData.NeedPhysicalAddresses = TRUE;
68 HwInitializationData.TaggedQueuing = TRUE; //FALSE;
69 HwInitializationData.AutoRequestSense = FALSE;
70 HwInitializationData.MultipleRequestPerLu = FALSE;
71 HwInitializationData.ReceiveEvent = FALSE; // check this
72 HwInitializationData.VendorIdLength = 0;
73 HwInitializationData.VendorId = NULL;
74 HwInitializationData.DeviceIdLength = 0;
75 HwInitializationData.DeviceId = NULL;
76 HwInitializationData.HwAdapterControl = XenVbd_HwScsiAdapterControl;
78 Status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
80 if(!NT_SUCCESS(Status))
81 {
82 KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", Status));
83 }
85 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
87 return Status;
88 }
90 static PMDL
91 AllocatePages(int Pages)
92 {
93 PMDL Mdl;
94 PVOID Buf;
96 //KdPrint((__DRIVER_NAME " --- AllocatePages IRQL = %d\n", KeGetCurrentIrql()));
97 Buf = ExAllocatePoolWithTag(NonPagedPool, Pages * PAGE_SIZE, XENVBD_POOL_TAG);
98 if (Buf == NULL)
99 {
100 KdPrint((__DRIVER_NAME " AllocatePages Failed at ExAllocatePoolWithTag\n"));
101 }
102 Mdl = IoAllocateMdl(Buf, Pages * PAGE_SIZE, FALSE, FALSE, NULL);
103 if (Mdl == NULL)
104 {
105 KdPrint((__DRIVER_NAME " AllocatePages Failed at IoAllocateMdl\n"));
106 }
107 MmBuildMdlForNonPagedPool(Mdl);
109 return Mdl;
110 }
112 static PMDL
113 AllocatePage()
114 {
115 return AllocatePages(1);
116 }
118 static VOID
119 FreePages(PMDL Mdl)
120 {
121 PVOID Buf = MmGetMdlVirtualAddress(Mdl);
122 //KdPrint((__DRIVER_NAME " --- FreePages IRQL = %d\n", KeGetCurrentIrql()));
123 //KdPrint((__DRIVER_NAME " FreePages Failed at IoAllocateMdl\n"));
124 //KdPrint((__DRIVER_NAME " FreePages Buf = %08x\n", Buf));
125 IoFreeMdl(Mdl);
126 ExFreePoolWithTag(Buf, XENVBD_POOL_TAG);
127 }
129 static ULONG
130 XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
131 {
132 ULONG Status = SP_RETURN_FOUND;
133 ULONG i;
134 PACCESS_RANGE AccessRange;
135 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
137 KeInitializeSpinLock(&DeviceData->Lock);
138 KdPrint((__DRIVER_NAME " --> HwScsiFindAdapter\n"));
139 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
141 KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
142 KdPrint((__DRIVER_NAME " BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
144 KdPrint((__DRIVER_NAME " AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
146 for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
147 {
148 AccessRange = &(*(ConfigInfo->AccessRanges))[i];
149 KdPrint((__DRIVER_NAME " AccessRange %2d: RangeStart = %08x, RangeLength = %08x, RangeInMemory = %d\n", i, AccessRange->RangeStart.LowPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
150 switch (i)
151 {
152 case 0:
153 DeviceData->XenDeviceData = (PXENPCI_XEN_DEVICE_DATA)AccessRange->RangeStart.QuadPart;
154 KdPrint((__DRIVER_NAME " Mapped to virtual address %08x\n", DeviceData->XenDeviceData));
155 KdPrint((__DRIVER_NAME " Magic = %08x\n", DeviceData->XenDeviceData->Magic));
156 if (DeviceData->XenDeviceData->Magic == XEN_DATA_MAGIC)
157 {
158 }
159 break;
160 default:
161 break;
162 }
163 }
165 ConfigInfo->NumberOfBuses = SCSI_BUSES;
166 ConfigInfo->MaximumTransferLength = BUF_PAGES_PER_SRB * PAGE_SIZE;
167 ConfigInfo->NumberOfPhysicalBreaks = BUF_PAGES_PER_SRB - 1; //11 - 1;
168 ConfigInfo->ScatterGather = TRUE;
169 ConfigInfo->Master = FALSE;
170 ConfigInfo->AlignmentMask = 0;
171 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
172 ConfigInfo->MaximumNumberOfTargets = SCSI_TARGETS_PER_BUS;
173 //ConfigInfo->TaggedQueueing = TRUE;
175 *Again = FALSE;
177 KdPrint((__DRIVER_NAME " <-- HwScsiFindAdapter\n"));
179 return Status;
180 }
182 static __inline uint64_t
183 GET_ID_FROM_FREELIST(PXENVBD_TARGET_DATA TargetData)
184 {
185 uint64_t free;
186 free = TargetData->shadow_free;
187 TargetData->shadow_free = TargetData->shadow[free].req.id;
188 TargetData->shadow[free].req.id = 0x0fffffee; /* debug */
189 return free;
190 }
192 static __inline VOID
193 ADD_ID_TO_FREELIST(PXENVBD_TARGET_DATA TargetData, uint64_t Id)
194 {
195 TargetData->shadow[Id].req.id = TargetData->shadow_free;
196 TargetData->shadow[Id].Srb = NULL;
197 TargetData->shadow_free = Id;
198 }
200 //static HANDLE XenVbd_ScsiPortThreadHandle;
201 //static KEVENT XenVbd_ScsiPortThreadEvent;
203 static VOID
204 XenVbd_Interrupt(PKINTERRUPT Interrupt, PVOID DeviceExtension)
205 {
206 PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
208 TargetData->PendingInterrupt = TRUE;
209 return;
210 }
212 static VOID
213 XenVbd_HwScsiInterruptTarget(PVOID DeviceExtension)
214 {
215 PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
216 PSCSI_REQUEST_BLOCK Srb;
217 RING_IDX i, rp;
218 int j;
219 blkif_response_t *rep;
220 char *DataBuffer;
221 int more_to_do;
222 int BlockCount;
223 KIRQL Irql;
224 int notify;
225 KAPC_STATE ApcState;
226 PIRP Irp;
227 PXENVBD_DEVICE_DATA DeviceData;
229 // KdPrint((__DRIVER_NAME " --> HwScsiInterruptTarget\n"));
231 DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
232 more_to_do = TRUE;
234 while (more_to_do)
235 {
236 rp = TargetData->Ring.sring->rsp_prod;
237 KeMemoryBarrier();
238 for (i = TargetData->Ring.rsp_cons; i != rp; i++)
239 {
240 rep = RING_GET_RESPONSE(&TargetData->Ring, i);
241 Srb = TargetData->shadow[rep->id].Srb;
242 BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
244 if (rep->status == BLKIF_RSP_OKAY)
245 Srb->SrbStatus = SRB_STATUS_SUCCESS;
246 else
247 {
248 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
249 if (Srb->Cdb[0] == SCSIOP_READ)
250 KdPrint((__DRIVER_NAME " Operation = Read\n"));
251 else
252 KdPrint((__DRIVER_NAME " Operation = Write\n"));
253 KdPrint((__DRIVER_NAME " Sector = %08X, Count = %d\n", TargetData->shadow[rep->id].req.sector_number, BlockCount));
254 Srb->SrbStatus = SRB_STATUS_ERROR;
255 }
256 for (j = 0; j < TargetData->shadow[rep->id].req.nr_segments; j++)
257 DeviceData->XenDeviceData->GntTblInterface.EndAccess(
258 DeviceData->XenDeviceData->GntTblInterface.InterfaceHeader.Context,
259 TargetData->shadow[rep->id].req.seg[j].gref);
260 if (Srb->Cdb[0] == SCSIOP_READ)
261 memcpy(Srb->DataBuffer, TargetData->shadow[rep->id].Buf, BlockCount * TargetData->BytesPerSector);
263 ScsiPortNotification(RequestComplete, DeviceData, Srb);
264 ScsiPortNotification(NextLuRequest, DeviceData, Srb->PathId, Srb->TargetId, Srb->Lun);
266 ADD_ID_TO_FREELIST(TargetData, rep->id);
267 }
269 TargetData->Ring.rsp_cons = i;
270 if (i != TargetData->Ring.req_prod_pvt)
271 {
272 RING_FINAL_CHECK_FOR_RESPONSES(&TargetData->Ring, more_to_do);
273 }
274 else
275 {
276 TargetData->Ring.sring->rsp_event = i + 1;
277 more_to_do = FALSE;
278 }
279 }
281 // KdPrint((__DRIVER_NAME " <-- HwScsiInterruptTarget\n"));
283 return FALSE;
284 }
286 static BOOLEAN
287 XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
288 {
289 PXENVBD_DEVICE_DATA DeviceData;
290 PXENVBD_TARGET_DATA TargetData;
291 int i, j;
293 // KdPrint((__DRIVER_NAME " --> HwScsiInterrupt\n"));
295 DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
297 KeMemoryBarrier();
298 for (i = 0; i < SCSI_BUSES; i++)
299 {
300 for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
301 {
302 TargetData = &DeviceData->BusData[i].TargetData[j];
303 if (TargetData->PendingInterrupt)
304 XenVbd_HwScsiInterruptTarget(TargetData);
305 TargetData->PendingInterrupt = FALSE;
306 }
307 }
308 // KdPrint((__DRIVER_NAME " <-- HwScsiInterrupt\n"));
310 return TRUE;
311 }
313 static VOID
314 XenVbd_BackEndStateHandler(char *Path, PVOID Data)
315 {
316 PXENVBD_TARGET_DATA TargetData;
317 PXENVBD_DEVICE_DATA DeviceData;
318 char TmpPath[128];
319 char *Value;
320 int NewState;
321 PMDL Mdl;
322 grant_ref_t ref;
323 blkif_sring_t *SharedRing;
324 ULONG PFN;
325 //XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION Description;
326 KIRQL OldIrql;
327 NTSTATUS status;
328 int i;
330 KdPrint((__DRIVER_NAME " --> BackEndStateHandler\n"));
331 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
333 TargetData = (PXENVBD_TARGET_DATA)Data;
334 DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
336 DeviceData->XenDeviceData->XenBusInterface.Read(
337 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
338 XBT_NIL, Path, &Value);
340 NewState = atoi(Value);
341 switch (NewState)
342 {
343 case XenbusStateUnknown:
344 KdPrint((__DRIVER_NAME " Backend State Changed to Unknown\n"));
345 break;
347 case XenbusStateInitialising:
348 KdPrint((__DRIVER_NAME " Backend State Changed to Initialising\n"));
349 break;
351 case XenbusStateInitWait:
352 KdPrint((__DRIVER_NAME " Backend State Changed to InitWait\n"));
354 TargetData->EventChannel = DeviceData->XenDeviceData->EvtChnInterface.AllocUnbound(
355 DeviceData->XenDeviceData->EvtChnInterface.InterfaceHeader.Context, 0);
356 DeviceData->XenDeviceData->EvtChnInterface.Bind(
357 DeviceData->XenDeviceData->EvtChnInterface.InterfaceHeader.Context,
358 TargetData->EventChannel, XenVbd_Interrupt, TargetData);
359 Mdl = AllocatePage();
360 PFN = *MmGetMdlPfnArray(Mdl);
361 SharedRing = (blkif_sring_t *)MmGetMdlVirtualAddress(Mdl);
362 SHARED_RING_INIT(SharedRing);
363 FRONT_RING_INIT(&TargetData->Ring, SharedRing, PAGE_SIZE);
364 ref = DeviceData->XenDeviceData->GntTblInterface.GrantAccess(
365 DeviceData->XenDeviceData->GntTblInterface.InterfaceHeader.Context,
366 0, PFN, FALSE);
368 TargetData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(blkif_shadow_t) * BLK_RING_SIZE, XENVBD_POOL_TAG);
370 memset(TargetData->shadow, 0, sizeof(blkif_shadow_t) * BLK_RING_SIZE);
371 for (i = 0; i < BLK_RING_SIZE; i++)
372 {
373 TargetData->shadow[i].req.id = i + 1;
374 TargetData->shadow[i].Mdl = AllocatePages(BUF_PAGES_PER_SRB); // stupid that we have to do this!
375 TargetData->shadow[i].Buf = MmGetMdlVirtualAddress(TargetData->shadow[i].Mdl);
376 }
377 TargetData->shadow_free = 0;
378 TargetData->shadow[BLK_RING_SIZE - 1].req.id = 0x0fffffff;
380 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
381 RtlStringCbCatA(TmpPath, 128, "/ring-ref");
382 DeviceData->XenDeviceData->XenBusInterface.Printf(DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", ref);
384 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
385 RtlStringCbCatA(TmpPath, 128, "/event-channel");
386 DeviceData->XenDeviceData->XenBusInterface.Printf(DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", TargetData->EventChannel);
388 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
389 RtlStringCbCatA(TmpPath, 128, "/state");
390 DeviceData->XenDeviceData->XenBusInterface.Printf(DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
392 KdPrint((__DRIVER_NAME " Set Frontend state to Initialised\n"));
393 break;
395 case XenbusStateInitialised:
396 KdPrint((__DRIVER_NAME " Backend State Changed to Initialised\n"));
397 break;
399 case XenbusStateConnected:
400 KdPrint((__DRIVER_NAME " Backend State Changed to Connected\n"));
402 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
403 RtlStringCbCatA(TmpPath, 128, "/device-type");
404 DeviceData->XenDeviceData->XenBusInterface.Read(
405 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
406 XBT_NIL, TmpPath, &Value);
407 if (strcmp(Value, "disk") == 0)
408 {
409 KdPrint((__DRIVER_NAME " DeviceType = Disk\n"));
410 TargetData->DeviceType = XENVBD_DEVICETYPE_DISK;
411 }
412 else if (strcmp(Value, "cdrom") == 0)
413 {
414 KdPrint((__DRIVER_NAME " DeviceType = CDROM\n"));
415 TargetData->DeviceType = XENVBD_DEVICETYPE_CDROM;
416 }
417 else
418 {
419 KdPrint((__DRIVER_NAME " DeviceType = %s (This probably won't work!)\n", Value));
420 TargetData->DeviceType = XENVBD_DEVICETYPE_UNKNOWN;
421 }
423 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
424 RtlStringCbCatA(TmpPath, 128, "/type"); // should probably check that this is 'phy' or 'file' or at least not ''
425 DeviceData->XenDeviceData->XenBusInterface.Read(
426 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
427 XBT_NIL, TmpPath, &Value);
428 KdPrint((__DRIVER_NAME " Backend Type = %s\n", Value));
429 ExFreePool(Value);
431 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
432 RtlStringCbCatA(TmpPath, 128, "/mode"); // should store this...
433 DeviceData->XenDeviceData->XenBusInterface.Read(
434 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
435 XBT_NIL, TmpPath, &Value);
436 KdPrint((__DRIVER_NAME " Backend Mode = %s\n", Value));
437 ExFreePool(Value);
439 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
440 RtlStringCbCatA(TmpPath, 128, "/sector-size");
441 DeviceData->XenDeviceData->XenBusInterface.Read(
442 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
443 XBT_NIL, TmpPath, &Value);
444 // should complain if Value == NULL
445 TargetData->BytesPerSector = atoi(Value);
447 KdPrint((__DRIVER_NAME " BytesPerSector = %d\n", TargetData->BytesPerSector));
449 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
450 RtlStringCbCatA(TmpPath, 128, "/sectors");
451 DeviceData->XenDeviceData->XenBusInterface.Read(
452 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
453 XBT_NIL, TmpPath, &Value);
454 // should complain if Value == NULL
455 TargetData->TotalSectors = (ULONGLONG)atol(Value);
457 KdPrint((__DRIVER_NAME " TotalSectors = %d\n", TargetData->TotalSectors));
459 // should probably use the partition table (if one exists) here for the sectorspertrack and trackspercylinder values
460 TargetData->Geometry.MediaType = FixedMedia;
461 TargetData->Geometry.BytesPerSector = TargetData->BytesPerSector;
462 TargetData->Geometry.SectorsPerTrack = 63;
463 TargetData->Geometry.TracksPerCylinder = 255;
464 TargetData->Geometry.Cylinders.QuadPart = TargetData->TotalSectors / TargetData->Geometry.SectorsPerTrack / TargetData->Geometry.TracksPerCylinder;
465 KdPrint((__DRIVER_NAME " Geometry C/H/S = %d/%d/%d\n", TargetData->Geometry.Cylinders.LowPart, TargetData->Geometry.TracksPerCylinder, TargetData->Geometry.SectorsPerTrack));
467 // now ask windows to rescan the scsi bus...
468 DeviceData->BusChangePending = 1;
470 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
471 RtlStringCbCatA(TmpPath, 128, "/state");
472 DeviceData->XenDeviceData->XenBusInterface.Printf(DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateConnected);
474 KdPrint((__DRIVER_NAME " Set Frontend state to Connected\n"));
475 InterlockedIncrement(&DeviceData->EnumeratedDevices);
476 KdPrint((__DRIVER_NAME " Added a device, notifying\n"));
477 KeSetEvent(&DeviceData->WaitDevicesEvent, 1, FALSE);
479 break;
481 case XenbusStateClosing:
482 KdPrint((__DRIVER_NAME " Backend State Changed to Closing\n"));
483 break;
485 case XenbusStateClosed:
486 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
487 break;
489 default:
490 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", NewState));
491 break;
492 }
494 KdPrint((__DRIVER_NAME " <-- BackEndStateHandler\n"));
495 }
497 static VOID
498 XenVbd_WatchHandler(char *Path, PVOID DeviceExtension)
499 {
500 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
501 char **Bits;
502 int Count;
503 char TmpPath[128];
504 char *Value;
505 int CurrentBus, CurrentTarget;
506 PXENVBD_TARGET_DATA TargetData, VacantTarget;
507 KIRQL OldIrql;
508 int i, j;
510 KdPrint((__DRIVER_NAME " --> WatchHandler (DeviceData = %08x)\n", DeviceData));
512 KdPrint((__DRIVER_NAME " Path = %s\n", Path));
514 Bits = SplitString(Path, '/', 4, &Count);
515 switch (Count)
516 {
517 case 0:
518 case 1:
519 case 2:
520 break; // should never happen
521 case 3:
522 break;
523 case 4:
524 if (strcmp(Bits[3], "state") != 0) // we only care when the state appears
525 break;
527 KeAcquireSpinLock(&DeviceData->Lock, &OldIrql);
529 for (VacantTarget = NULL,i = 0; i < SCSI_BUSES * SCSI_TARGETS_PER_BUS; i++)
530 {
531 CurrentBus = i / SCSI_TARGETS_PER_BUS;
532 CurrentTarget = i % SCSI_TARGETS_PER_BUS;
533 if (CurrentTarget == 7) // don't use 7 - it would be for the controller
534 continue;
535 TargetData = &DeviceData->BusData[CurrentBus].TargetData[CurrentTarget];
536 if (TargetData->Present && strncmp(TargetData->Path, Path, strlen(TargetData->Path)) == 0 && Path[strlen(TargetData->Path)] == '/')
537 break; // already exists
538 else if (!TargetData->Present && VacantTarget == NULL)
539 VacantTarget = TargetData;
540 }
541 if (i == SCSI_BUSES * SCSI_TARGETS_PER_BUS && VacantTarget != NULL)
542 {
543 VacantTarget->Present = 1;
544 KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
546 RtlStringCbCopyA(VacantTarget->Path, 128, Bits[0]);
547 RtlStringCbCatA(VacantTarget->Path, 128, "/");
548 RtlStringCbCatA(VacantTarget->Path, 128, Bits[1]);
549 RtlStringCbCatA(VacantTarget->Path, 128, "/");
550 RtlStringCbCatA(VacantTarget->Path, 128, Bits[2]);
552 VacantTarget->DeviceIndex = atoi(Bits[2]);
554 RtlStringCbCopyA(TmpPath, 128, VacantTarget->Path);
555 RtlStringCbCatA(TmpPath, 128, "/backend");
556 DeviceData->XenDeviceData->XenBusInterface.Read(
557 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
558 XBT_NIL, TmpPath, &Value);
559 if (Value == NULL)
560 KdPrint((__DRIVER_NAME " Read Failed\n"));
561 else
562 RtlStringCbCopyA(VacantTarget->BackendPath, 128, Value);
563 RtlStringCbCopyA(TmpPath, 128, VacantTarget->BackendPath);
564 RtlStringCbCatA(TmpPath, 128, "/state");
566 DeviceData->XenDeviceData->XenBusInterface.AddWatch(
567 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
568 XBT_NIL, TmpPath, XenVbd_BackEndStateHandler, VacantTarget);
569 }
570 else
571 KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
572 break;
573 }
575 FreeSplitString(Bits, Count);
577 KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));
579 return;
580 }
582 static VOID
583 XenVbd_CheckBusChangedTimer(PVOID DeviceExtension)
584 {
585 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
587 if (DeviceData->BusChangePending)
588 {
589 ScsiPortNotification(BusChangeDetected, DeviceData, 0);
590 DeviceData->BusChangePending = 0;
591 }
592 ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
593 }
595 static BOOLEAN
596 XenVbd_HwScsiInitialize(PVOID DeviceExtension)
597 {
598 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
599 unsigned int i, j;
600 NTSTATUS Status;
601 char **VbdDevices;
602 char *msg;
603 char buffer[128];
604 LARGE_INTEGER WaitTimeout;
606 KdPrint((__DRIVER_NAME " --> HwScsiInitialize\n"));
607 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
609 for (i = 0; i < SCSI_BUSES; i++)
610 {
611 for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
612 {
613 DeviceData->BusData[i].TargetData[j].Present = 0;
614 DeviceData->BusData[i].TargetData[j].DeviceData = DeviceData;
615 }
616 }
618 DeviceData->XenDeviceData->WatchContext = DeviceExtension;
619 KeMemoryBarrier();
620 DeviceData->XenDeviceData->WatchHandler = XenVbd_WatchHandler;
622 KeInitializeEvent(&DeviceData->WaitDevicesEvent, SynchronizationEvent, FALSE);
623 DeviceData->EnumeratedDevices = 0;
624 if (DeviceData->XenDeviceData->AutoEnumerate)
625 {
626 msg = DeviceData->XenDeviceData->XenBusInterface.List(
627 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
628 XBT_NIL, "device/vbd", &VbdDevices);
629 if (!msg) {
630 for (i = 0; VbdDevices[i]; i++)
631 {
632 KdPrint((__DRIVER_NAME " found existing vbd device %s\n", VbdDevices[i]));
633 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
634 XenVbd_WatchHandler(buffer, DeviceData);
635 // WaitTimeout.QuadPart = -600000000;
636 KeWaitForSingleObject(&DeviceData->WaitDevicesEvent, Executive, KernelMode, FALSE, NULL);
637 KdPrint((__DRIVER_NAME " %d devices enumerated\n", DeviceData->EnumeratedDevices));
638 }
639 }
640 /*
641 for (i = 0; VbdDevices[i]; i++)
642 {
643 KdPrint((__DRIVER_NAME " found existing vbd device %s\n", VbdDevices[i]));
644 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
645 XenVbd_WatchHandler(buffer, DeviceData);
646 //ExFreePoolWithTag(bdDevices[i], XENPCI_POOL_TAG);
647 }
648 KdPrint((__DRIVER_NAME " Waiting for %d devices to be enumerated\n", i));
649 while (DeviceData->EnumeratedDevices < i)
650 {
651 WaitTimeout.QuadPart = -600000000;
652 if (KeWaitForSingleObject(&DeviceData->WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
653 {
654 KdPrint((__DRIVER_NAME " Wait timed out\n"));
655 break;
656 }
657 KdPrint((__DRIVER_NAME " %d out of %d devices enumerated\n", DeviceData->EnumeratedDevices, i));
658 }
659 }
660 */
661 ScsiPortNotification(BusChangeDetected, DeviceData, 0);
662 DeviceData->BusChangePending = 0;
663 }
664 ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
666 KdPrint((__DRIVER_NAME " <-- HwScsiInitialize\n"));
668 return TRUE;
669 }
671 static ULONG
672 XenVbd_FillModePage(PXENVBD_DEVICE_DATA DeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
673 {
674 PMODE_RIGID_GEOMETRY_PAGE ModeRigidGeometry;
676 switch (PageCode)
677 {
678 /*
679 case MODE_PAGE_RIGID_GEOMETRY:
680 if (DeviceData->ScsiData->DeviceType == XENVBD_DEVICETYPE_CDROM)
681 {
682 KdPrint((__DRIVER_NAME " MODE_PAGE_RIGID_GEOMETRY\n"));
683 if (*Offset + sizeof(MODE_RIGID_GEOMETRY_PAGE) > BufferLength)
684 return 1;
685 ModeRigidGeometry = (PMODE_RIGID_GEOMETRY_PAGE)(DataBuffer + *Offset);
686 memset(ModeRigidGeometry, 0, sizeof(MODE_RIGID_GEOMETRY_PAGE));
687 ModeRigidGeometry->PageCode = PageCode;
688 ModeRigidGeometry->PageSavable = 0;
689 ModeRigidGeometry->PageLength = sizeof(MODE_RIGID_GEOMETRY_PAGE);
690 ModeRigidGeometry->NumberOfCylinders[0] = (DeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
691 ModeRigidGeometry->NumberOfCylinders[1] = (DeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
692 ModeRigidGeometry->NumberOfCylinders[2] = (DeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
693 ModeRigidGeometry->NumberOfHeads = DeviceData->Geometry.TracksPerCylinder;
694 //ModeRigidGeometry->LandZoneCyclinder = 0;
695 ModeRigidGeometry->RoataionRate[0] = 0x05;
696 ModeRigidGeometry->RoataionRate[0] = 0x39;
697 *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
698 }
699 break;
700 */
701 case MODE_PAGE_FAULT_REPORTING:
702 break;
703 default:
704 break;
705 }
706 return 0;
707 }
709 // Call with device lock held
710 static VOID
711 XenVbd_PutSrbOnRing(PXENVBD_TARGET_DATA TargetData, PSCSI_REQUEST_BLOCK Srb)
712 {
713 //PUCHAR DataBuffer;
714 blkif_request_t *req;
715 int i;
716 int j;
717 int BlockCount;
718 int sect_offset;
719 PVOID CurrentVirtual;
720 ULONG CurrentLength;
721 ULONG SegmentLength;
722 SCSI_PHYSICAL_ADDRESS PageAddress;
723 int Iterations;
724 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
726 // can use SRB_STATUS_BUSY to push the SRB back to windows...
728 // KdPrint((__DRIVER_NAME " --> PutSrbOnRing\n"));
730 if (RING_FULL(&TargetData->Ring))
731 {
732 KdPrint((__DRIVER_NAME " RING IS FULL - EXPECT BADNESS\n"));
733 // TODO: Fail badly here
734 }
736 req = RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt);
738 req->sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
739 BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
741 req->id = GET_ID_FROM_FREELIST(TargetData);
743 if (req->id == 0x0fffffff)
744 {
745 KdPrint((__DRIVER_NAME " Something is horribly wrong in PutSrbOnRing\n"));
746 }
748 req->handle = 0;
749 req->operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
750 TargetData->shadow[req->id].Srb = Srb;
752 // KdPrint((__DRIVER_NAME " DataBuffer = %08X\n", Srb->DataBuffer));
753 // KdPrint((__DRIVER_NAME " BlockCount = %08X\n", BlockCount));
755 req->nr_segments = (BlockCount * TargetData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE;
756 // KdPrint((__DRIVER_NAME " req->nr_segments = %08X\n", req->nr_segments));
758 for (i = 0; i < req->nr_segments; i++)
759 {
760 req->seg[i].gref = DeviceData->XenDeviceData->GntTblInterface.GrantAccess(
761 DeviceData->XenDeviceData->GntTblInterface.InterfaceHeader.Context,
762 0, MmGetMdlPfnArray(TargetData->shadow[req->id].Mdl)[i], FALSE);
763 req->seg[i].first_sect = 0;
764 if (i == req->nr_segments - 1)
765 req->seg[i].last_sect = (BlockCount - 1) % (PAGE_SIZE / TargetData->BytesPerSector);
766 else
767 req->seg[i].last_sect = PAGE_SIZE / TargetData->BytesPerSector - 1;
768 // KdPrint((__DRIVER_NAME " Page %d, first_sect = %d, last_sect = %d\n", i, req->seg[i].first_sect, req->seg[i].last_sect));
769 }
770 if (Srb->Cdb[0] == SCSIOP_WRITE)
771 memcpy(TargetData->shadow[req->id].Buf, Srb->DataBuffer, BlockCount * TargetData->BytesPerSector);
772 TargetData->shadow[req->id].req = *req;
773 TargetData->Ring.req_prod_pvt++;
775 // KdPrint((__DRIVER_NAME " <-- PutSrbOnRing\n"));
776 }
778 static BOOLEAN
779 XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
780 {
781 PUCHAR DataBuffer;
782 PCDB cdb;
783 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
784 PXENVBD_TARGET_DATA TargetData;
785 unsigned int i;
786 KIRQL KIrql;
787 int notify;
788 SCSI_PHYSICAL_ADDRESS ScsiPhysicalAddress;
789 ULONG Length;
791 // KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
792 // KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
794 if (Srb->PathId >= SCSI_BUSES || Srb->TargetId >= SCSI_TARGETS_PER_BUS)
795 {
796 Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
797 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
798 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
799 KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
800 return TRUE;
801 }
803 TargetData = &DeviceData->BusData[Srb->PathId].TargetData[Srb->TargetId];
805 if (!TargetData->Present)
806 {
807 Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
808 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
809 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
810 KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Not Present)\n"));
811 return TRUE;
812 }
814 switch (Srb->Function)
815 {
816 case SRB_FUNCTION_EXECUTE_SCSI:
817 cdb = (PCDB)Srb->Cdb;
818 // KdPrint((__DRIVER_NAME " SRB_FUNCTION_EXECUTE_SCSI\n"));
819 switch(cdb->CDB6GENERIC.OperationCode)
820 {
821 case SCSIOP_TEST_UNIT_READY:
822 KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
823 Srb->SrbStatus = SRB_STATUS_SUCCESS;
824 Srb->ScsiStatus = 0;
825 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
826 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
827 break;
828 case SCSIOP_INQUIRY:
829 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
830 KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
831 KdPrint((__DRIVER_NAME " (Length = %d)\n", Srb->DataTransferLength));
832 KdPrint((__DRIVER_NAME " (Srb->Databuffer = %08x)\n", Srb->DataBuffer));
833 // KdPrint((__DRIVER_NAME " PhysicalAddress.LowPart = %08x\n", ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Length).LowPart));
834 // DataBuffer = ScsiPortGetVirtualAddress(DeviceData, ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Length));
835 // KdPrint((__DRIVER_NAME " (Databuffer = %08x)\n", DataBuffer));
836 // break;
837 DataBuffer = Srb->DataBuffer;
838 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
839 Srb->SrbStatus = SRB_STATUS_SUCCESS;
840 switch (TargetData->DeviceType)
841 {
842 case XENVBD_DEVICETYPE_DISK:
843 if ((Srb->Cdb[1] & 1) == 0)
844 {
845 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
846 DataBuffer[1] = 0x00; // not removable
847 DataBuffer[3] = 32;
848 memcpy(DataBuffer + 8, "XEN ", 8); // vendor id
849 memcpy(DataBuffer + 16, "PV VBD ", 16); // product id
850 memcpy(DataBuffer + 32, "0000", 4); // product revision level
851 }
852 else
853 {
854 switch (Srb->Cdb[2])
855 {
856 case 0x00:
857 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
858 DataBuffer[1] = 0x00;
859 DataBuffer[2] = 0x00;
860 DataBuffer[3] = 2;
861 DataBuffer[4] = 0x00;
862 DataBuffer[5] = 0x80;
863 break;
864 case 0x80:
865 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
866 DataBuffer[1] = 0x80;
867 DataBuffer[2] = 0x00;
868 DataBuffer[3] = 8;
869 DataBuffer[4] = 0x31;
870 DataBuffer[5] = 0x32;
871 DataBuffer[6] = 0x33;
872 DataBuffer[7] = 0x34;
873 DataBuffer[8] = 0x35;
874 DataBuffer[9] = 0x36;
875 DataBuffer[10] = 0x37;
876 DataBuffer[11] = 0x38;
877 break;
878 default:
879 KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", Srb->Cdb[2]));
880 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
881 break;
882 }
883 }
884 break;
885 case XENVBD_DEVICETYPE_CDROM:
886 if ((Srb->Cdb[1] & 1) == 0)
887 {
888 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
889 DataBuffer[1] = 0x01; // removable
890 DataBuffer[3] = 32;
891 memcpy(DataBuffer + 8, "XEN ", 8); // vendor id
892 memcpy(DataBuffer + 16, "PV VBD ", 16); // product id
893 memcpy(DataBuffer + 32, "0000", 4); // product revision level
894 }
895 else
896 {
897 switch (Srb->Cdb[2])
898 {
899 case 0x00:
900 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
901 DataBuffer[1] = 0x00;
902 DataBuffer[2] = 0x00;
903 DataBuffer[3] = 2;
904 DataBuffer[4] = 0x00;
905 DataBuffer[5] = 0x80;
906 break;
907 case 0x80:
908 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
909 DataBuffer[1] = 0x80;
910 DataBuffer[2] = 0x00;
911 DataBuffer[3] = 8;
912 DataBuffer[4] = 0x31;
913 DataBuffer[5] = 0x32;
914 DataBuffer[6] = 0x33;
915 DataBuffer[7] = 0x34;
916 DataBuffer[8] = 0x35;
917 DataBuffer[9] = 0x36;
918 DataBuffer[10] = 0x37;
919 DataBuffer[11] = 0x38;
920 break;
921 default:
922 KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", Srb->Cdb[2]));
923 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
924 break;
925 }
926 }
927 break;
928 default:
929 KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", TargetData->DeviceType));
930 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
931 break;
932 }
933 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
934 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
935 break;
936 case SCSIOP_READ_CAPACITY:
937 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
938 DataBuffer = Srb->DataBuffer;
939 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
940 DataBuffer[0] = (unsigned char)((TargetData->TotalSectors - 1) >> 24) & 0xff;
941 DataBuffer[1] = (unsigned char)((TargetData->TotalSectors - 1) >> 16) & 0xff;
942 DataBuffer[2] = (unsigned char)((TargetData->TotalSectors - 1) >> 8) & 0xff;
943 DataBuffer[3] = (unsigned char)((TargetData->TotalSectors - 1) >> 0) & 0xff;
944 DataBuffer[4] = (unsigned char)(TargetData->BytesPerSector >> 24) & 0xff;
945 DataBuffer[5] = (unsigned char)(TargetData->BytesPerSector >> 16) & 0xff;
946 DataBuffer[6] = (unsigned char)(TargetData->BytesPerSector >> 8) & 0xff;
947 DataBuffer[7] = (unsigned char)(TargetData->BytesPerSector >> 0) & 0xff;
948 Srb->ScsiStatus = 0;
949 Srb->SrbStatus = SRB_STATUS_SUCCESS;
950 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
951 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
952 break;
953 case SCSIOP_MODE_SENSE:
954 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));
955 KdPrint((__DRIVER_NAME " Length = %d\n", Srb->DataTransferLength));
957 Srb->ScsiStatus = 0;
958 Srb->SrbStatus = SRB_STATUS_SUCCESS;
959 Srb->DataTransferLength = 0;
960 DataBuffer = Srb->DataBuffer;
961 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
962 switch(cdb->MODE_SENSE.PageCode)
963 {
964 case MODE_SENSE_RETURN_ALL:
965 //Ptr = (UCHAR *)Srb->DataBuffer;
966 for (i = 0; i < MODE_SENSE_RETURN_ALL; i++)
967 {
968 if (XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength))
969 {
970 break;
971 }
972 }
973 break;
974 default:
975 XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength);
976 break;
977 }
978 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
979 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
980 break;
981 case SCSIOP_READ:
982 case SCSIOP_WRITE:
983 // KdPrint((__DRIVER_NAME " Command = READ/WRITE\n"));
984 XenVbd_PutSrbOnRing(TargetData, Srb);
985 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&TargetData->Ring, notify);
986 if (notify)
987 DeviceData->XenDeviceData->EvtChnInterface.Notify(
988 DeviceData->XenDeviceData->EvtChnInterface.InterfaceHeader.Context,
989 TargetData->EventChannel);
990 if (!RING_FULL(&TargetData->Ring))
991 ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
992 else
993 ScsiPortNotification(NextRequest, DeviceExtension);
994 break;
995 case SCSIOP_REPORT_LUNS:
996 KdPrint((__DRIVER_NAME " Command = REPORT_LUNS\n"));
997 Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
998 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
999 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1000 break;
1001 case SCSIOP_READ_TOC:
1002 DataBuffer = Srb->DataBuffer;
1003 // DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
1004 /*
1005 #define READ_TOC_FORMAT_TOC 0x00
1006 #define READ_TOC_FORMAT_SESSION 0x01
1007 #define READ_TOC_FORMAT_FULL_TOC 0x02
1008 #define READ_TOC_FORMAT_PMA 0x03
1009 #define READ_TOC_FORMAT_ATIP 0x04
1010 */
1011 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
1012 KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
1013 KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
1014 KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
1015 KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
1016 KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
1017 KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
1018 KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
1019 switch (cdb->READ_TOC.Format2)
1021 case READ_TOC_FORMAT_TOC:
1022 DataBuffer[0] = 0; // length MSB
1023 DataBuffer[1] = 10; // length LSB
1024 DataBuffer[2] = 1; // First Track
1025 DataBuffer[3] = 1; // Last Track
1026 DataBuffer[4] = 0; // Reserved
1027 DataBuffer[5] = 0x14; // current position data + uninterrupted data
1028 DataBuffer[6] = 1; // last complete track
1029 DataBuffer[7] = 0; // reserved
1030 DataBuffer[8] = 0; // MSB Block
1031 DataBuffer[9] = 0;
1032 DataBuffer[10] = 0;
1033 DataBuffer[11] = 0; // LSB Block
1034 Srb->SrbStatus = SRB_STATUS_SUCCESS;
1035 break;
1036 case READ_TOC_FORMAT_SESSION:
1037 case READ_TOC_FORMAT_FULL_TOC:
1038 case READ_TOC_FORMAT_PMA:
1039 case READ_TOC_FORMAT_ATIP:
1040 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1041 break;
1043 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1044 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1045 break;
1046 default:
1047 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
1048 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1049 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1050 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1051 break;
1053 break;
1054 case SRB_FUNCTION_CLAIM_DEVICE:
1055 KdPrint((__DRIVER_NAME " SRB_FUNCTION_CLAIM_DEVICE\n"));
1056 // ObReferenceObject(WdfDeviceWdmGetDeviceObject(Device));
1057 // Srb->DataBuffer = WdfDeviceWdmGetDeviceObject(Device);
1058 Srb->SrbStatus = SRB_STATUS_SUCCESS;
1059 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1060 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1061 break;
1062 case SRB_FUNCTION_IO_CONTROL:
1063 KdPrint((__DRIVER_NAME " SRB_FUNCTION_IO_CONTROL\n"));
1064 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1065 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1066 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1067 break;
1068 case SRB_FUNCTION_FLUSH:
1069 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH\n"));
1070 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1071 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1072 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1073 break;
1074 default:
1075 KdPrint((__DRIVER_NAME " Unhandled Srb->Function = %08X\n", Srb->Function));
1076 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1077 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1078 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1079 break;
1082 // KdPrint((__DRIVER_NAME " <-- HwScsiStartIo\n"));
1084 return TRUE;
1087 static BOOLEAN
1088 XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
1090 KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
1091 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1093 KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
1095 return TRUE;
1099 static BOOLEAN
1100 XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
1102 KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
1103 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1105 KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
1107 return TRUE;
1110 static SCSI_ADAPTER_CONTROL_STATUS
1111 XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
1113 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
1114 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
1116 KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
1117 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1119 switch (ControlType)
1121 case ScsiQuerySupportedControlTypes:
1122 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
1123 KdPrint((__DRIVER_NAME " ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
1124 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
1125 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
1126 break;
1127 case ScsiStopAdapter:
1128 KdPrint((__DRIVER_NAME " ScsiStopAdapter\n"));
1129 break;
1130 case ScsiRestartAdapter:
1131 KdPrint((__DRIVER_NAME " ScsiRestartAdapter\n"));
1132 break;
1133 case ScsiSetBootConfig:
1134 KdPrint((__DRIVER_NAME " ScsiSetBootConfig\n"));
1135 break;
1136 case ScsiSetRunningConfig:
1137 KdPrint((__DRIVER_NAME " ScsiSetRunningConfig\n"));
1138 break;
1139 default:
1140 KdPrint((__DRIVER_NAME " UNKNOWN\n"));
1141 break;
1144 KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
1146 return Status;