win-pvdrivers

view xenvbd/xenvbd.c @ 74:06b4321b7068

Created a common AllocagePages routine in xen_windows.h
Updated xennet and xenvbd to use it.
Updated xennet's method of getting the virtual address from the Mdl
author James Harper <james.harper@bendigoit.com.au>
date Thu Dec 20 21:37:20 2007 +1100 (2007-12-20)
parents f74723639713
children b7863ede7a37
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 ULONG
91 XenVbd_HwScsiFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
92 {
93 ULONG Status = SP_RETURN_FOUND;
94 ULONG i;
95 PACCESS_RANGE AccessRange;
96 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
98 KeInitializeSpinLock(&DeviceData->Lock);
99 KdPrint((__DRIVER_NAME " --> HwScsiFindAdapter\n"));
100 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
102 KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
103 KdPrint((__DRIVER_NAME " BusInterruptVector = %d\n", ConfigInfo->BusInterruptVector));
105 KdPrint((__DRIVER_NAME " AccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
107 for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
108 {
109 AccessRange = &(*(ConfigInfo->AccessRanges))[i];
110 KdPrint((__DRIVER_NAME " AccessRange %2d: RangeStart = %08x, RangeLength = %08x, RangeInMemory = %d\n", i, AccessRange->RangeStart.LowPart, AccessRange->RangeLength, AccessRange->RangeInMemory));
111 switch (i)
112 {
113 case 0:
114 DeviceData->XenDeviceData = (PXENPCI_XEN_DEVICE_DATA)AccessRange->RangeStart.QuadPart;
115 KdPrint((__DRIVER_NAME " Mapped to virtual address %08x\n", DeviceData->XenDeviceData));
116 KdPrint((__DRIVER_NAME " Magic = %08x\n", DeviceData->XenDeviceData->Magic));
117 if (DeviceData->XenDeviceData->Magic == XEN_DATA_MAGIC)
118 {
119 }
120 break;
121 default:
122 break;
123 }
124 }
126 ConfigInfo->NumberOfBuses = SCSI_BUSES;
127 ConfigInfo->MaximumTransferLength = BUF_PAGES_PER_SRB * PAGE_SIZE;
128 ConfigInfo->NumberOfPhysicalBreaks = BUF_PAGES_PER_SRB - 1; //11 - 1;
129 ConfigInfo->ScatterGather = TRUE;
130 ConfigInfo->Master = FALSE;
131 ConfigInfo->AlignmentMask = 0;
132 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
133 ConfigInfo->MaximumNumberOfTargets = SCSI_TARGETS_PER_BUS;
134 //ConfigInfo->TaggedQueueing = TRUE;
136 *Again = FALSE;
138 KdPrint((__DRIVER_NAME " <-- HwScsiFindAdapter\n"));
140 return Status;
141 }
143 static __inline uint64_t
144 GET_ID_FROM_FREELIST(PXENVBD_TARGET_DATA TargetData)
145 {
146 uint64_t free;
147 free = TargetData->shadow_free;
148 TargetData->shadow_free = TargetData->shadow[free].req.id;
149 TargetData->shadow[free].req.id = 0x0fffffee; /* debug */
150 return free;
151 }
153 static __inline VOID
154 ADD_ID_TO_FREELIST(PXENVBD_TARGET_DATA TargetData, uint64_t Id)
155 {
156 TargetData->shadow[Id].req.id = TargetData->shadow_free;
157 TargetData->shadow[Id].Srb = NULL;
158 TargetData->shadow_free = Id;
159 }
161 //static HANDLE XenVbd_ScsiPortThreadHandle;
162 //static KEVENT XenVbd_ScsiPortThreadEvent;
164 static VOID
165 XenVbd_Interrupt(PKINTERRUPT Interrupt, PVOID DeviceExtension)
166 {
167 PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
169 // KdPrint((__DRIVER_NAME " --> Interrupt\n"));
171 TargetData->PendingInterrupt = TRUE;
173 // KdPrint((__DRIVER_NAME " <-- Interrupt\n"));
174 return;
175 }
177 static VOID
178 XenVbd_HwScsiInterruptTarget(PVOID DeviceExtension)
179 {
180 PXENVBD_TARGET_DATA TargetData = (PXENVBD_TARGET_DATA)DeviceExtension;
181 PSCSI_REQUEST_BLOCK Srb;
182 RING_IDX i, rp;
183 int j;
184 blkif_response_t *rep;
185 char *DataBuffer;
186 int more_to_do;
187 int BlockCount;
188 KIRQL Irql;
189 int notify;
190 KAPC_STATE ApcState;
191 PIRP Irp;
192 PXENVBD_DEVICE_DATA DeviceData;
194 // KdPrint((__DRIVER_NAME " --> HwScsiInterruptTarget\n"));
196 DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
197 more_to_do = TRUE;
199 while (more_to_do)
200 {
201 rp = TargetData->Ring.sring->rsp_prod;
202 KeMemoryBarrier();
203 for (i = TargetData->Ring.rsp_cons; i != rp; i++)
204 {
205 rep = RING_GET_RESPONSE(&TargetData->Ring, i);
206 Srb = TargetData->shadow[rep->id].Srb;
207 BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
209 if (rep->status == BLKIF_RSP_OKAY)
210 Srb->SrbStatus = SRB_STATUS_SUCCESS;
211 else
212 {
213 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
214 if (Srb->Cdb[0] == SCSIOP_READ)
215 KdPrint((__DRIVER_NAME " Operation = Read\n"));
216 else
217 KdPrint((__DRIVER_NAME " Operation = Write\n"));
218 KdPrint((__DRIVER_NAME " Sector = %08X, Count = %d\n", TargetData->shadow[rep->id].req.sector_number, BlockCount));
219 Srb->SrbStatus = SRB_STATUS_ERROR;
220 }
221 for (j = 0; j < TargetData->shadow[rep->id].req.nr_segments; j++)
222 DeviceData->XenDeviceData->GntTblInterface.EndAccess(
223 DeviceData->XenDeviceData->GntTblInterface.InterfaceHeader.Context,
224 TargetData->shadow[rep->id].req.seg[j].gref);
225 if (Srb->Cdb[0] == SCSIOP_READ)
226 memcpy(Srb->DataBuffer, TargetData->shadow[rep->id].Buf, BlockCount * TargetData->BytesPerSector);
228 ScsiPortNotification(RequestComplete, DeviceData, Srb);
229 ScsiPortNotification(NextLuRequest, DeviceData, Srb->PathId, Srb->TargetId, Srb->Lun);
231 ADD_ID_TO_FREELIST(TargetData, rep->id);
232 }
234 TargetData->Ring.rsp_cons = i;
235 if (i != TargetData->Ring.req_prod_pvt)
236 {
237 RING_FINAL_CHECK_FOR_RESPONSES(&TargetData->Ring, more_to_do);
238 }
239 else
240 {
241 TargetData->Ring.sring->rsp_event = i + 1;
242 more_to_do = FALSE;
243 }
244 }
246 // KdPrint((__DRIVER_NAME " <-- HwScsiInterruptTarget\n"));
248 return FALSE;
249 }
251 static BOOLEAN
252 XenVbd_HwScsiInterrupt(PVOID DeviceExtension)
253 {
254 PXENVBD_DEVICE_DATA DeviceData;
255 PXENVBD_TARGET_DATA TargetData;
256 int i, j;
258 // KdPrint((__DRIVER_NAME " --> HwScsiInterrupt\n"));
260 DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
262 KeMemoryBarrier();
263 for (i = 0; i < SCSI_BUSES; i++)
264 {
265 for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
266 {
267 TargetData = &DeviceData->BusData[i].TargetData[j];
268 if (TargetData->PendingInterrupt)
269 XenVbd_HwScsiInterruptTarget(TargetData);
270 TargetData->PendingInterrupt = FALSE;
271 }
272 }
273 // KdPrint((__DRIVER_NAME " <-- HwScsiInterrupt\n"));
275 return TRUE;
276 }
278 static VOID
279 XenVbd_BackEndStateHandler(char *Path, PVOID Data)
280 {
281 PXENVBD_TARGET_DATA TargetData;
282 PXENVBD_DEVICE_DATA DeviceData;
283 char TmpPath[128];
284 char *Value;
285 int NewState;
286 PMDL Mdl;
287 grant_ref_t ref;
288 blkif_sring_t *SharedRing;
289 ULONG PFN;
290 //XENVBD_DEVICE_IDENTIFICATION_DESCRIPTION Description;
291 KIRQL OldIrql;
292 NTSTATUS status;
293 int i;
295 KdPrint((__DRIVER_NAME " --> BackEndStateHandler\n"));
296 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
298 TargetData = (PXENVBD_TARGET_DATA)Data;
299 DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
301 DeviceData->XenDeviceData->XenBusInterface.Read(
302 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
303 XBT_NIL, Path, &Value);
305 NewState = atoi(Value);
306 switch (NewState)
307 {
308 case XenbusStateUnknown:
309 KdPrint((__DRIVER_NAME " Backend State Changed to Unknown\n"));
310 break;
312 case XenbusStateInitialising:
313 KdPrint((__DRIVER_NAME " Backend State Changed to Initialising\n"));
314 break;
316 case XenbusStateInitWait:
317 KdPrint((__DRIVER_NAME " Backend State Changed to InitWait\n"));
319 TargetData->EventChannel = DeviceData->XenDeviceData->EvtChnInterface.AllocUnbound(
320 DeviceData->XenDeviceData->EvtChnInterface.InterfaceHeader.Context, 0);
321 DeviceData->XenDeviceData->EvtChnInterface.Bind(
322 DeviceData->XenDeviceData->EvtChnInterface.InterfaceHeader.Context,
323 TargetData->EventChannel, XenVbd_Interrupt, TargetData);
324 Mdl = AllocatePage();
325 PFN = *MmGetMdlPfnArray(Mdl);
326 SharedRing = (blkif_sring_t *)MmGetMdlVirtualAddress(Mdl);
327 SHARED_RING_INIT(SharedRing);
328 FRONT_RING_INIT(&TargetData->Ring, SharedRing, PAGE_SIZE);
329 ref = DeviceData->XenDeviceData->GntTblInterface.GrantAccess(
330 DeviceData->XenDeviceData->GntTblInterface.InterfaceHeader.Context,
331 0, PFN, FALSE);
333 TargetData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(blkif_shadow_t) * BLK_RING_SIZE, XENVBD_POOL_TAG);
335 memset(TargetData->shadow, 0, sizeof(blkif_shadow_t) * BLK_RING_SIZE);
336 for (i = 0; i < BLK_RING_SIZE; i++)
337 {
338 TargetData->shadow[i].req.id = i + 1;
339 TargetData->shadow[i].Mdl = AllocatePages(BUF_PAGES_PER_SRB); // stupid that we have to do this!
340 TargetData->shadow[i].Buf = MmGetMdlVirtualAddress(TargetData->shadow[i].Mdl);
341 }
342 TargetData->shadow_free = 0;
343 TargetData->shadow[BLK_RING_SIZE - 1].req.id = 0x0fffffff;
345 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
346 RtlStringCbCatA(TmpPath, 128, "/ring-ref");
347 DeviceData->XenDeviceData->XenBusInterface.Printf(DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", ref);
349 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
350 RtlStringCbCatA(TmpPath, 128, "/event-channel");
351 DeviceData->XenDeviceData->XenBusInterface.Printf(DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", TargetData->EventChannel);
353 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
354 RtlStringCbCatA(TmpPath, 128, "/state");
355 DeviceData->XenDeviceData->XenBusInterface.Printf(DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
357 KdPrint((__DRIVER_NAME " Set Frontend state to Initialised\n"));
358 break;
360 case XenbusStateInitialised:
361 KdPrint((__DRIVER_NAME " Backend State Changed to Initialised\n"));
362 break;
364 case XenbusStateConnected:
365 KdPrint((__DRIVER_NAME " Backend State Changed to Connected\n"));
367 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
368 RtlStringCbCatA(TmpPath, 128, "/device-type");
369 DeviceData->XenDeviceData->XenBusInterface.Read(
370 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
371 XBT_NIL, TmpPath, &Value);
372 if (strcmp(Value, "disk") == 0)
373 {
374 KdPrint((__DRIVER_NAME " DeviceType = Disk\n"));
375 TargetData->DeviceType = XENVBD_DEVICETYPE_DISK;
376 }
377 else if (strcmp(Value, "cdrom") == 0)
378 {
379 KdPrint((__DRIVER_NAME " DeviceType = CDROM\n"));
380 TargetData->DeviceType = XENVBD_DEVICETYPE_CDROM;
381 }
382 else
383 {
384 KdPrint((__DRIVER_NAME " DeviceType = %s (This probably won't work!)\n", Value));
385 TargetData->DeviceType = XENVBD_DEVICETYPE_UNKNOWN;
386 }
388 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
389 RtlStringCbCatA(TmpPath, 128, "/type"); // should probably check that this is 'phy' or 'file' or at least not ''
390 DeviceData->XenDeviceData->XenBusInterface.Read(
391 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
392 XBT_NIL, TmpPath, &Value);
393 KdPrint((__DRIVER_NAME " Backend Type = %s\n", Value));
394 ExFreePool(Value);
396 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
397 RtlStringCbCatA(TmpPath, 128, "/mode"); // should store this...
398 DeviceData->XenDeviceData->XenBusInterface.Read(
399 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
400 XBT_NIL, TmpPath, &Value);
401 KdPrint((__DRIVER_NAME " Backend Mode = %s\n", Value));
402 ExFreePool(Value);
404 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
405 RtlStringCbCatA(TmpPath, 128, "/sector-size");
406 DeviceData->XenDeviceData->XenBusInterface.Read(
407 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
408 XBT_NIL, TmpPath, &Value);
409 // should complain if Value == NULL
410 TargetData->BytesPerSector = atoi(Value);
412 KdPrint((__DRIVER_NAME " BytesPerSector = %d\n", TargetData->BytesPerSector));
414 RtlStringCbCopyA(TmpPath, 128, TargetData->BackendPath);
415 RtlStringCbCatA(TmpPath, 128, "/sectors");
416 DeviceData->XenDeviceData->XenBusInterface.Read(
417 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
418 XBT_NIL, TmpPath, &Value);
419 // should complain if Value == NULL
420 TargetData->TotalSectors = (ULONGLONG)atol(Value);
422 KdPrint((__DRIVER_NAME " TotalSectors = %d\n", TargetData->TotalSectors));
424 // should probably use the partition table (if one exists) here for the sectorspertrack and trackspercylinder values
425 TargetData->Geometry.MediaType = FixedMedia;
426 TargetData->Geometry.BytesPerSector = TargetData->BytesPerSector;
427 TargetData->Geometry.SectorsPerTrack = 63;
428 TargetData->Geometry.TracksPerCylinder = 255;
429 TargetData->Geometry.Cylinders.QuadPart = TargetData->TotalSectors / TargetData->Geometry.SectorsPerTrack / TargetData->Geometry.TracksPerCylinder;
430 KdPrint((__DRIVER_NAME " Geometry C/H/S = %d/%d/%d\n", TargetData->Geometry.Cylinders.LowPart, TargetData->Geometry.TracksPerCylinder, TargetData->Geometry.SectorsPerTrack));
432 // now ask windows to rescan the scsi bus...
433 DeviceData->BusChangePending = 1;
435 RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
436 RtlStringCbCatA(TmpPath, 128, "/state");
437 DeviceData->XenDeviceData->XenBusInterface.Printf(DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateConnected);
439 KdPrint((__DRIVER_NAME " Set Frontend state to Connected\n"));
440 InterlockedIncrement(&DeviceData->EnumeratedDevices);
441 KdPrint((__DRIVER_NAME " Added a device, notifying\n"));
442 KeSetEvent(&DeviceData->WaitDevicesEvent, 1, FALSE);
444 break;
446 case XenbusStateClosing:
447 KdPrint((__DRIVER_NAME " Backend State Changed to Closing\n"));
448 break;
450 case XenbusStateClosed:
451 KdPrint((__DRIVER_NAME " Backend State Changed to Closed\n"));
452 break;
454 default:
455 KdPrint((__DRIVER_NAME " Backend State Changed to Undefined = %d\n", NewState));
456 break;
457 }
459 KdPrint((__DRIVER_NAME " <-- BackEndStateHandler\n"));
460 }
462 static VOID
463 XenVbd_WatchHandler(char *Path, PVOID DeviceExtension)
464 {
465 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
466 char **Bits;
467 int Count;
468 char TmpPath[128];
469 char *Value;
470 int CurrentBus, CurrentTarget;
471 PXENVBD_TARGET_DATA TargetData, VacantTarget;
472 KIRQL OldIrql;
473 int i, j;
475 KdPrint((__DRIVER_NAME " --> WatchHandler (DeviceData = %08x)\n", DeviceData));
477 KdPrint((__DRIVER_NAME " Path = %s\n", Path));
479 Bits = SplitString(Path, '/', 4, &Count);
480 switch (Count)
481 {
482 case 0:
483 case 1:
484 case 2:
485 break; // should never happen
486 case 3:
487 break;
488 case 4:
489 if (strcmp(Bits[3], "state") != 0) // we only care when the state appears
490 break;
492 KeAcquireSpinLock(&DeviceData->Lock, &OldIrql);
494 for (VacantTarget = NULL,i = 0; i < SCSI_BUSES * SCSI_TARGETS_PER_BUS; i++)
495 {
496 CurrentBus = i / SCSI_TARGETS_PER_BUS;
497 CurrentTarget = i % SCSI_TARGETS_PER_BUS;
498 if (CurrentTarget == 7) // don't use 7 - it would be for the controller
499 continue;
500 TargetData = &DeviceData->BusData[CurrentBus].TargetData[CurrentTarget];
501 if (TargetData->Present && strncmp(TargetData->Path, Path, strlen(TargetData->Path)) == 0 && Path[strlen(TargetData->Path)] == '/')
502 break; // already exists
503 else if (!TargetData->Present && VacantTarget == NULL)
504 VacantTarget = TargetData;
505 }
506 if (i == SCSI_BUSES * SCSI_TARGETS_PER_BUS && VacantTarget != NULL)
507 {
508 VacantTarget->Present = 1;
509 KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
511 RtlStringCbCopyA(VacantTarget->Path, 128, Bits[0]);
512 RtlStringCbCatA(VacantTarget->Path, 128, "/");
513 RtlStringCbCatA(VacantTarget->Path, 128, Bits[1]);
514 RtlStringCbCatA(VacantTarget->Path, 128, "/");
515 RtlStringCbCatA(VacantTarget->Path, 128, Bits[2]);
517 VacantTarget->DeviceIndex = atoi(Bits[2]);
519 RtlStringCbCopyA(TmpPath, 128, VacantTarget->Path);
520 RtlStringCbCatA(TmpPath, 128, "/backend");
521 DeviceData->XenDeviceData->XenBusInterface.Read(
522 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
523 XBT_NIL, TmpPath, &Value);
524 if (Value == NULL)
525 KdPrint((__DRIVER_NAME " Read Failed\n"));
526 else
527 RtlStringCbCopyA(VacantTarget->BackendPath, 128, Value);
528 RtlStringCbCopyA(TmpPath, 128, VacantTarget->BackendPath);
529 RtlStringCbCatA(TmpPath, 128, "/state");
531 DeviceData->XenDeviceData->XenBusInterface.AddWatch(
532 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
533 XBT_NIL, TmpPath, XenVbd_BackEndStateHandler, VacantTarget);
534 }
535 else
536 KeReleaseSpinLock(&DeviceData->Lock, OldIrql);
537 break;
538 }
540 FreeSplitString(Bits, Count);
542 KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));
544 return;
545 }
547 static VOID
548 XenVbd_CheckBusChangedTimer(PVOID DeviceExtension)
549 {
550 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
552 if (DeviceData->BusChangePending)
553 {
554 ScsiPortNotification(BusChangeDetected, DeviceData, 0);
555 DeviceData->BusChangePending = 0;
556 }
557 ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
558 }
560 static BOOLEAN
561 XenVbd_HwScsiInitialize(PVOID DeviceExtension)
562 {
563 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
564 unsigned int i, j;
565 NTSTATUS Status;
566 char **VbdDevices;
567 char *msg;
568 char buffer[128];
569 LARGE_INTEGER WaitTimeout;
571 KdPrint((__DRIVER_NAME " --> HwScsiInitialize\n"));
572 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
574 for (i = 0; i < SCSI_BUSES; i++)
575 {
576 for (j = 0; j < SCSI_TARGETS_PER_BUS; j++)
577 {
578 DeviceData->BusData[i].TargetData[j].Present = 0;
579 DeviceData->BusData[i].TargetData[j].DeviceData = DeviceData;
580 }
581 }
583 DeviceData->XenDeviceData->WatchContext = DeviceExtension;
584 KeMemoryBarrier();
585 DeviceData->XenDeviceData->WatchHandler = XenVbd_WatchHandler;
587 KeInitializeEvent(&DeviceData->WaitDevicesEvent, SynchronizationEvent, FALSE);
588 DeviceData->EnumeratedDevices = 0;
589 if (DeviceData->XenDeviceData->AutoEnumerate)
590 {
591 msg = DeviceData->XenDeviceData->XenBusInterface.List(
592 DeviceData->XenDeviceData->XenBusInterface.InterfaceHeader.Context,
593 XBT_NIL, "device/vbd", &VbdDevices);
594 if (!msg) {
595 for (i = 0; VbdDevices[i]; i++)
596 {
597 KdPrint((__DRIVER_NAME " found existing vbd device %s\n", VbdDevices[i]));
598 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
599 XenVbd_WatchHandler(buffer, DeviceData);
600 // WaitTimeout.QuadPart = -600000000;
601 KeWaitForSingleObject(&DeviceData->WaitDevicesEvent, Executive, KernelMode, FALSE, NULL);
602 KdPrint((__DRIVER_NAME " %d devices enumerated\n", DeviceData->EnumeratedDevices));
603 }
604 }
605 /*
606 for (i = 0; VbdDevices[i]; i++)
607 {
608 KdPrint((__DRIVER_NAME " found existing vbd device %s\n", VbdDevices[i]));
609 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/vbd/%s/state", VbdDevices[i]);
610 XenVbd_WatchHandler(buffer, DeviceData);
611 //ExFreePoolWithTag(bdDevices[i], XENPCI_POOL_TAG);
612 }
613 KdPrint((__DRIVER_NAME " Waiting for %d devices to be enumerated\n", i));
614 while (DeviceData->EnumeratedDevices < i)
615 {
616 WaitTimeout.QuadPart = -600000000;
617 if (KeWaitForSingleObject(&DeviceData->WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
618 {
619 KdPrint((__DRIVER_NAME " Wait timed out\n"));
620 break;
621 }
622 KdPrint((__DRIVER_NAME " %d out of %d devices enumerated\n", DeviceData->EnumeratedDevices, i));
623 }
624 }
625 */
626 ScsiPortNotification(BusChangeDetected, DeviceData, 0);
627 DeviceData->BusChangePending = 0;
628 }
629 ScsiPortNotification(RequestTimerCall, DeviceExtension, XenVbd_CheckBusChangedTimer, 1000000);
631 KdPrint((__DRIVER_NAME " <-- HwScsiInitialize\n"));
633 return TRUE;
634 }
636 static ULONG
637 XenVbd_FillModePage(PXENVBD_DEVICE_DATA DeviceData, UCHAR PageCode, PUCHAR DataBuffer, ULONG BufferLength, PULONG Offset)
638 {
639 PMODE_RIGID_GEOMETRY_PAGE ModeRigidGeometry;
641 switch (PageCode)
642 {
643 /*
644 case MODE_PAGE_RIGID_GEOMETRY:
645 if (DeviceData->ScsiData->DeviceType == XENVBD_DEVICETYPE_CDROM)
646 {
647 KdPrint((__DRIVER_NAME " MODE_PAGE_RIGID_GEOMETRY\n"));
648 if (*Offset + sizeof(MODE_RIGID_GEOMETRY_PAGE) > BufferLength)
649 return 1;
650 ModeRigidGeometry = (PMODE_RIGID_GEOMETRY_PAGE)(DataBuffer + *Offset);
651 memset(ModeRigidGeometry, 0, sizeof(MODE_RIGID_GEOMETRY_PAGE));
652 ModeRigidGeometry->PageCode = PageCode;
653 ModeRigidGeometry->PageSavable = 0;
654 ModeRigidGeometry->PageLength = sizeof(MODE_RIGID_GEOMETRY_PAGE);
655 ModeRigidGeometry->NumberOfCylinders[0] = (DeviceData->Geometry.Cylinders.LowPart >> 16) & 0xFF;
656 ModeRigidGeometry->NumberOfCylinders[1] = (DeviceData->Geometry.Cylinders.LowPart >> 8) & 0xFF;
657 ModeRigidGeometry->NumberOfCylinders[2] = (DeviceData->Geometry.Cylinders.LowPart >> 0) & 0xFF;
658 ModeRigidGeometry->NumberOfHeads = DeviceData->Geometry.TracksPerCylinder;
659 //ModeRigidGeometry->LandZoneCyclinder = 0;
660 ModeRigidGeometry->RoataionRate[0] = 0x05;
661 ModeRigidGeometry->RoataionRate[0] = 0x39;
662 *Offset += sizeof(MODE_RIGID_GEOMETRY_PAGE);
663 }
664 break;
665 */
666 case MODE_PAGE_FAULT_REPORTING:
667 break;
668 default:
669 break;
670 }
671 return 0;
672 }
674 // Call with device lock held
675 static VOID
676 XenVbd_PutSrbOnRing(PXENVBD_TARGET_DATA TargetData, PSCSI_REQUEST_BLOCK Srb)
677 {
678 //PUCHAR DataBuffer;
679 blkif_request_t *req;
680 int i;
681 int j;
682 int BlockCount;
683 int sect_offset;
684 PVOID CurrentVirtual;
685 ULONG CurrentLength;
686 ULONG SegmentLength;
687 SCSI_PHYSICAL_ADDRESS PageAddress;
688 int Iterations;
689 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
691 // can use SRB_STATUS_BUSY to push the SRB back to windows...
693 // KdPrint((__DRIVER_NAME " --> PutSrbOnRing\n"));
695 if (RING_FULL(&TargetData->Ring))
696 {
697 KdPrint((__DRIVER_NAME " RING IS FULL - EXPECT BADNESS\n"));
698 // TODO: Fail badly here
699 }
701 req = RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt);
703 req->sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
704 BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
706 req->id = GET_ID_FROM_FREELIST(TargetData);
708 if (req->id == 0x0fffffff)
709 {
710 KdPrint((__DRIVER_NAME " Something is horribly wrong in PutSrbOnRing\n"));
711 }
713 req->handle = 0;
714 req->operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
715 TargetData->shadow[req->id].Srb = Srb;
717 // KdPrint((__DRIVER_NAME " DataBuffer = %08X\n", Srb->DataBuffer));
718 // KdPrint((__DRIVER_NAME " BlockCount = %08X\n", BlockCount));
720 req->nr_segments = (BlockCount * TargetData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE;
721 // KdPrint((__DRIVER_NAME " req->nr_segments = %08X\n", req->nr_segments));
723 for (i = 0; i < req->nr_segments; i++)
724 {
725 req->seg[i].gref = DeviceData->XenDeviceData->GntTblInterface.GrantAccess(
726 DeviceData->XenDeviceData->GntTblInterface.InterfaceHeader.Context,
727 0, MmGetMdlPfnArray(TargetData->shadow[req->id].Mdl)[i], FALSE);
728 req->seg[i].first_sect = 0;
729 if (i == req->nr_segments - 1)
730 req->seg[i].last_sect = (BlockCount - 1) % (PAGE_SIZE / TargetData->BytesPerSector);
731 else
732 req->seg[i].last_sect = PAGE_SIZE / TargetData->BytesPerSector - 1;
733 // KdPrint((__DRIVER_NAME " Page %d, first_sect = %d, last_sect = %d\n", i, req->seg[i].first_sect, req->seg[i].last_sect));
734 }
735 if (Srb->Cdb[0] == SCSIOP_WRITE)
736 memcpy(TargetData->shadow[req->id].Buf, Srb->DataBuffer, BlockCount * TargetData->BytesPerSector);
737 TargetData->shadow[req->id].req = *req;
738 TargetData->Ring.req_prod_pvt++;
740 // KdPrint((__DRIVER_NAME " <-- PutSrbOnRing\n"));
741 }
743 static BOOLEAN
744 XenVbd_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
745 {
746 PUCHAR DataBuffer;
747 PCDB cdb;
748 PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)DeviceExtension;
749 PXENVBD_TARGET_DATA TargetData;
750 unsigned int i;
751 KIRQL KIrql;
752 int notify;
753 SCSI_PHYSICAL_ADDRESS ScsiPhysicalAddress;
754 ULONG Length;
756 // KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
757 // KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
759 if (Srb->PathId >= SCSI_BUSES || Srb->TargetId >= SCSI_TARGETS_PER_BUS)
760 {
761 Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
762 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
763 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
764 KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Out of bounds)\n"));
765 return TRUE;
766 }
768 TargetData = &DeviceData->BusData[Srb->PathId].TargetData[Srb->TargetId];
770 if (!TargetData->Present)
771 {
772 Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
773 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
774 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
775 KdPrint((__DRIVER_NAME " --- HwScsiStartIo (Not Present)\n"));
776 return TRUE;
777 }
779 switch (Srb->Function)
780 {
781 case SRB_FUNCTION_EXECUTE_SCSI:
782 cdb = (PCDB)Srb->Cdb;
783 // KdPrint((__DRIVER_NAME " SRB_FUNCTION_EXECUTE_SCSI\n"));
784 switch(cdb->CDB6GENERIC.OperationCode)
785 {
786 case SCSIOP_TEST_UNIT_READY:
787 // KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
788 Srb->SrbStatus = SRB_STATUS_SUCCESS;
789 Srb->ScsiStatus = 0;
790 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
791 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
792 break;
793 case SCSIOP_INQUIRY:
794 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
795 KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", Srb->Cdb[1] >> 5, Srb->Cdb[1] & 1, Srb->Cdb[2]));
796 KdPrint((__DRIVER_NAME " (Length = %d)\n", Srb->DataTransferLength));
797 KdPrint((__DRIVER_NAME " (Srb->Databuffer = %08x)\n", Srb->DataBuffer));
798 // KdPrint((__DRIVER_NAME " PhysicalAddress.LowPart = %08x\n", ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Length).LowPart));
799 // DataBuffer = ScsiPortGetVirtualAddress(DeviceData, ScsiPortGetPhysicalAddress(DeviceData, Srb, Srb->DataBuffer, &Length));
800 // KdPrint((__DRIVER_NAME " (Databuffer = %08x)\n", DataBuffer));
801 // break;
802 DataBuffer = Srb->DataBuffer;
803 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
804 Srb->SrbStatus = SRB_STATUS_SUCCESS;
805 switch (TargetData->DeviceType)
806 {
807 case XENVBD_DEVICETYPE_DISK:
808 if ((Srb->Cdb[1] & 1) == 0)
809 {
810 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
811 DataBuffer[1] = 0x00; // not removable
812 DataBuffer[3] = 32;
813 memcpy(DataBuffer + 8, "XEN ", 8); // vendor id
814 memcpy(DataBuffer + 16, "PV VBD ", 16); // product id
815 memcpy(DataBuffer + 32, "0000", 4); // product revision level
816 }
817 else
818 {
819 switch (Srb->Cdb[2])
820 {
821 case 0x00:
822 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
823 DataBuffer[1] = 0x00;
824 DataBuffer[2] = 0x00;
825 DataBuffer[3] = 2;
826 DataBuffer[4] = 0x00;
827 DataBuffer[5] = 0x80;
828 break;
829 case 0x80:
830 DataBuffer[0] = DIRECT_ACCESS_DEVICE;
831 DataBuffer[1] = 0x80;
832 DataBuffer[2] = 0x00;
833 DataBuffer[3] = 8;
834 DataBuffer[4] = 0x31;
835 DataBuffer[5] = 0x32;
836 DataBuffer[6] = 0x33;
837 DataBuffer[7] = 0x34;
838 DataBuffer[8] = 0x35;
839 DataBuffer[9] = 0x36;
840 DataBuffer[10] = 0x37;
841 DataBuffer[11] = 0x38;
842 break;
843 default:
844 KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", Srb->Cdb[2]));
845 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
846 break;
847 }
848 }
849 break;
850 case XENVBD_DEVICETYPE_CDROM:
851 if ((Srb->Cdb[1] & 1) == 0)
852 {
853 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
854 DataBuffer[1] = 0x01; // removable
855 DataBuffer[3] = 32;
856 memcpy(DataBuffer + 8, "XEN ", 8); // vendor id
857 memcpy(DataBuffer + 16, "PV VBD ", 16); // product id
858 memcpy(DataBuffer + 32, "0000", 4); // product revision level
859 }
860 else
861 {
862 switch (Srb->Cdb[2])
863 {
864 case 0x00:
865 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
866 DataBuffer[1] = 0x00;
867 DataBuffer[2] = 0x00;
868 DataBuffer[3] = 2;
869 DataBuffer[4] = 0x00;
870 DataBuffer[5] = 0x80;
871 break;
872 case 0x80:
873 DataBuffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
874 DataBuffer[1] = 0x80;
875 DataBuffer[2] = 0x00;
876 DataBuffer[3] = 8;
877 DataBuffer[4] = 0x31;
878 DataBuffer[5] = 0x32;
879 DataBuffer[6] = 0x33;
880 DataBuffer[7] = 0x34;
881 DataBuffer[8] = 0x35;
882 DataBuffer[9] = 0x36;
883 DataBuffer[10] = 0x37;
884 DataBuffer[11] = 0x38;
885 break;
886 default:
887 KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", Srb->Cdb[2]));
888 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
889 break;
890 }
891 }
892 break;
893 default:
894 KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", TargetData->DeviceType));
895 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
896 break;
897 }
898 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
899 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
900 break;
901 case SCSIOP_READ_CAPACITY:
902 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
903 DataBuffer = Srb->DataBuffer;
904 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
905 DataBuffer[0] = (unsigned char)((TargetData->TotalSectors - 1) >> 24) & 0xff;
906 DataBuffer[1] = (unsigned char)((TargetData->TotalSectors - 1) >> 16) & 0xff;
907 DataBuffer[2] = (unsigned char)((TargetData->TotalSectors - 1) >> 8) & 0xff;
908 DataBuffer[3] = (unsigned char)((TargetData->TotalSectors - 1) >> 0) & 0xff;
909 DataBuffer[4] = (unsigned char)(TargetData->BytesPerSector >> 24) & 0xff;
910 DataBuffer[5] = (unsigned char)(TargetData->BytesPerSector >> 16) & 0xff;
911 DataBuffer[6] = (unsigned char)(TargetData->BytesPerSector >> 8) & 0xff;
912 DataBuffer[7] = (unsigned char)(TargetData->BytesPerSector >> 0) & 0xff;
913 Srb->ScsiStatus = 0;
914 Srb->SrbStatus = SRB_STATUS_SUCCESS;
915 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
916 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
917 break;
918 case SCSIOP_MODE_SENSE:
919 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));
920 KdPrint((__DRIVER_NAME " Length = %d\n", Srb->DataTransferLength));
922 Srb->ScsiStatus = 0;
923 Srb->SrbStatus = SRB_STATUS_SUCCESS;
924 Srb->DataTransferLength = 0;
925 DataBuffer = Srb->DataBuffer;
926 RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
927 switch(cdb->MODE_SENSE.PageCode)
928 {
929 case MODE_SENSE_RETURN_ALL:
930 //Ptr = (UCHAR *)Srb->DataBuffer;
931 for (i = 0; i < MODE_SENSE_RETURN_ALL; i++)
932 {
933 if (XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength))
934 {
935 break;
936 }
937 }
938 break;
939 default:
940 XenVbd_FillModePage(DeviceData, cdb->MODE_SENSE.PageCode, DataBuffer, cdb->MODE_SENSE.AllocationLength, &Srb->DataTransferLength);
941 break;
942 }
943 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
944 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
945 break;
946 case SCSIOP_READ:
947 case SCSIOP_WRITE:
948 // KdPrint((__DRIVER_NAME " Command = READ/WRITE\n"));
949 XenVbd_PutSrbOnRing(TargetData, Srb);
950 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&TargetData->Ring, notify);
951 if (notify)
952 DeviceData->XenDeviceData->EvtChnInterface.Notify(
953 DeviceData->XenDeviceData->EvtChnInterface.InterfaceHeader.Context,
954 TargetData->EventChannel);
955 if (!RING_FULL(&TargetData->Ring))
956 ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
957 else
958 ScsiPortNotification(NextRequest, DeviceExtension);
959 break;
960 case SCSIOP_REPORT_LUNS:
961 KdPrint((__DRIVER_NAME " Command = REPORT_LUNS\n"));
962 Srb->SrbStatus = SRB_STATUS_SUCCESS; //SRB_STATUS_INVALID_REQUEST;
963 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
964 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
965 break;
966 case SCSIOP_READ_TOC:
967 DataBuffer = Srb->DataBuffer;
968 // DataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
969 /*
970 #define READ_TOC_FORMAT_TOC 0x00
971 #define READ_TOC_FORMAT_SESSION 0x01
972 #define READ_TOC_FORMAT_FULL_TOC 0x02
973 #define READ_TOC_FORMAT_PMA 0x03
974 #define READ_TOC_FORMAT_ATIP 0x04
975 */
976 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
977 KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
978 KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
979 KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
980 KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
981 KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
982 KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
983 KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
984 switch (cdb->READ_TOC.Format2)
985 {
986 case READ_TOC_FORMAT_TOC:
987 DataBuffer[0] = 0; // length MSB
988 DataBuffer[1] = 10; // length LSB
989 DataBuffer[2] = 1; // First Track
990 DataBuffer[3] = 1; // Last Track
991 DataBuffer[4] = 0; // Reserved
992 DataBuffer[5] = 0x14; // current position data + uninterrupted data
993 DataBuffer[6] = 1; // last complete track
994 DataBuffer[7] = 0; // reserved
995 DataBuffer[8] = 0; // MSB Block
996 DataBuffer[9] = 0;
997 DataBuffer[10] = 0;
998 DataBuffer[11] = 0; // LSB Block
999 Srb->SrbStatus = SRB_STATUS_SUCCESS;
1000 break;
1001 case READ_TOC_FORMAT_SESSION:
1002 case READ_TOC_FORMAT_FULL_TOC:
1003 case READ_TOC_FORMAT_PMA:
1004 case READ_TOC_FORMAT_ATIP:
1005 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1006 break;
1008 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1009 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1010 break;
1011 default:
1012 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", Srb->Cdb[0]));
1013 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1014 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1015 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1016 break;
1018 break;
1019 case SRB_FUNCTION_CLAIM_DEVICE:
1020 KdPrint((__DRIVER_NAME " SRB_FUNCTION_CLAIM_DEVICE\n"));
1021 // ObReferenceObject(WdfDeviceWdmGetDeviceObject(Device));
1022 // Srb->DataBuffer = WdfDeviceWdmGetDeviceObject(Device);
1023 Srb->SrbStatus = SRB_STATUS_SUCCESS;
1024 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1025 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1026 break;
1027 case SRB_FUNCTION_IO_CONTROL:
1028 KdPrint((__DRIVER_NAME " SRB_FUNCTION_IO_CONTROL\n"));
1029 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1030 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1031 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1032 break;
1033 case SRB_FUNCTION_FLUSH:
1034 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH\n"));
1035 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1036 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1037 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1038 break;
1039 default:
1040 KdPrint((__DRIVER_NAME " Unhandled Srb->Function = %08X\n", Srb->Function));
1041 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1042 ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
1043 ScsiPortNotification(NextRequest, DeviceExtension, NULL);
1044 break;
1047 // KdPrint((__DRIVER_NAME " <-- HwScsiStartIo\n"));
1049 return TRUE;
1052 static BOOLEAN
1053 XenVbd_HwScsiResetBus(PVOID DeviceExtension, ULONG PathId)
1055 KdPrint((__DRIVER_NAME " --> HwScsiResetBus\n"));
1056 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1058 KdPrint((__DRIVER_NAME " <-- HwScsiResetBus\n"));
1060 return TRUE;
1064 static BOOLEAN
1065 XenVbd_HwScsiAdapterState(PVOID DeviceExtension, PVOID Context, BOOLEAN SaveState)
1067 KdPrint((__DRIVER_NAME " --> HwScsiAdapterState\n"));
1068 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1070 KdPrint((__DRIVER_NAME " <-- HwScsiAdapterState\n"));
1072 return TRUE;
1075 static SCSI_ADAPTER_CONTROL_STATUS
1076 XenVbd_HwScsiAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
1078 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
1079 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
1081 KdPrint((__DRIVER_NAME " --> HwScsiAdapterControl\n"));
1082 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1084 switch (ControlType)
1086 case ScsiQuerySupportedControlTypes:
1087 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
1088 KdPrint((__DRIVER_NAME " ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
1089 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
1090 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
1091 break;
1092 case ScsiStopAdapter:
1093 KdPrint((__DRIVER_NAME " ScsiStopAdapter\n"));
1094 break;
1095 case ScsiRestartAdapter:
1096 KdPrint((__DRIVER_NAME " ScsiRestartAdapter\n"));
1097 break;
1098 case ScsiSetBootConfig:
1099 KdPrint((__DRIVER_NAME " ScsiSetBootConfig\n"));
1100 break;
1101 case ScsiSetRunningConfig:
1102 KdPrint((__DRIVER_NAME " ScsiSetRunningConfig\n"));
1103 break;
1104 default:
1105 KdPrint((__DRIVER_NAME " UNKNOWN\n"));
1106 break;
1109 KdPrint((__DRIVER_NAME " <-- HwScsiAdapterControl\n"));
1111 return Status;