win-pvdrivers

view xenvbd/xenvbd_storport.c @ 947:a05b13795cb2

storport calls StartIo even when the adapter fails to initialise. Make sure this doesn't crash.
author James Harper <james.harper@bendigoit.com.au>
date Mon Aug 22 23:14:01 2011 +1000 (2011-08-22)
parents dab0168f43c6
children 6e8c5e65f498
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #define INITGUID
21 #include "xenvbd_storport.h"
23 #pragma warning(disable: 4127)
25 #if defined(__x86_64__)
26 #define LongLongToPtr(x) (PVOID)(x)
27 #else
28 #define LongLongToPtr(x) UlongToPtr(x)
29 #endif
31 /* Not really necessary but keeps PREfast happy */
32 DRIVER_INITIALIZE DriverEntry;
33 static BOOLEAN XenVbd_HandleEvent(PVOID DeviceExtension);
35 static BOOLEAN dump_mode = FALSE;
36 #define DUMP_MODE_ERROR_LIMIT 64
37 static ULONG dump_mode_errors = 0;
39 CHAR scsi_device_manufacturer[8];
40 CHAR scsi_disk_model[16];
41 CHAR scsi_cdrom_model[16];
43 ULONGLONG parse_numeric_string(PCHAR string)
44 {
45 ULONGLONG val = 0;
46 while (*string != 0)
47 {
48 val = val * 10 + (*string - '0');
49 string++;
50 }
51 return val;
52 }
54 static blkif_shadow_t *
55 get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
56 {
57 if (xvdd->shadow_free == 0)
58 {
59 KdPrint((__DRIVER_NAME " No more shadow entries\n"));
60 return NULL;
61 }
62 xvdd->shadow_free--;
63 if (xvdd->shadow_free < xvdd->shadow_min_free)
64 xvdd->shadow_min_free = xvdd->shadow_free;
65 return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
66 }
68 static VOID
69 put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
70 {
71 xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)(shadow->req.id & SHADOW_ID_ID_MASK);
72 shadow->srb = NULL;
73 shadow->reset = FALSE;
74 xvdd->shadow_free++;
75 }
77 static blkif_response_t *
78 XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i)
79 {
80 blkif_other_response_t *rep;
81 if (!xvdd->use_other)
82 return RING_GET_RESPONSE(&xvdd->ring, i);
83 rep = RING_GET_RESPONSE(&xvdd->other_ring, i);
84 xvdd->tmp_rep.id = rep->id;
85 xvdd->tmp_rep.operation = rep->operation;
86 xvdd->tmp_rep.status = rep->status;
87 return &xvdd->tmp_rep;
88 }
90 static VOID
91 XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
92 {
93 blkif_other_request_t *other_req;
95 if (!xvdd->use_other)
96 {
97 *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
98 }
99 else
100 {
101 other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
102 other_req->operation = req->operation;
103 other_req->nr_segments = req->nr_segments;
104 other_req->handle = req->handle;
105 other_req->id = req->id;
106 other_req->sector_number = req->sector_number;
107 memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
108 }
109 xvdd->ring.req_prod_pvt++;
110 }
112 static ULONG
113 XenVbd_InitConfig(PXENVBD_DEVICE_DATA xvdd)
114 {
115 ULONG status;
116 PUCHAR ptr;
117 USHORT type;
118 PCHAR setting, value, value2;
120 FUNCTION_ENTER();
121 /* first read the default config items */
122 ptr = xvdd->device_base;
123 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
124 {
125 switch(type)
126 {
127 case XEN_INIT_TYPE_VECTORS:
128 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
129 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
130 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
131 {
132 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
133 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
134 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
135 return SP_RETURN_BAD_CONFIG;
136 }
137 else
138 memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
139 break;
140 default:
141 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
142 break;
143 }
144 }
146 /* then set up all the configuration requests */
147 ptr = xvdd->device_base;
148 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
149 #pragma warning(suppress:4054)
150 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenVbd_HandleEvent, xvdd);
151 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL, NULL);
152 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
153 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
154 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
155 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
156 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialised);
157 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
158 __ADD_XEN_INIT_UCHAR(&ptr, 20);
159 __ADD_XEN_INIT_UCHAR(&ptr, 0);
160 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
161 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
162 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
163 __ADD_XEN_INIT_UCHAR(&ptr, 20);
164 __ADD_XEN_INIT_UCHAR(&ptr, 0);
165 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
166 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
167 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
168 __ADD_XEN_INIT_UCHAR(&ptr, 50);
169 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
170 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
171 __ADD_XEN_INIT_UCHAR(&ptr, 50);
172 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
173 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
174 __ADD_XEN_INIT_UCHAR(&ptr, 50);
175 __ADD_XEN_INIT_UCHAR(&ptr, 0);
176 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
178 /* then configure */
179 status = xvdd->vectors.XenPci_XenConfigDevice(xvdd->vectors.context);
180 if (!NT_SUCCESS(status))
181 {
182 xvdd->inactive = TRUE;
183 KdPrint(("Failed to complete device configuration (%08x)\n", status));
184 FUNCTION_EXIT();
185 return SP_RETURN_BAD_CONFIG;
186 }
187 FUNCTION_EXIT();
188 return SP_RETURN_FOUND;
189 }
191 static ULONG
192 XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
193 {
194 ULONG i;
195 PUCHAR ptr;
196 USHORT type;
197 PCHAR setting, value, value2;
198 ULONG qemu_protocol_version = 0;
199 BOOLEAN qemu_hide_filter = FALSE;
200 ULONG qemu_hide_flags_value = 0;
202 FUNCTION_ENTER();
204 xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
205 xvdd->sring = NULL;
206 xvdd->event_channel = 0;
208 xvdd->inactive = TRUE;
210 ptr = xvdd->device_base;
211 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
212 {
213 switch(type)
214 {
215 case XEN_INIT_TYPE_VECTORS:
216 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
217 if (dump_mode)
218 {
219 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
220 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
221 {
222 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
223 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
224 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
225 return SP_RETURN_BAD_CONFIG;
226 }
227 else
228 memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
229 }
230 break;
231 case XEN_INIT_TYPE_RING: /* frontend ring */
232 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
233 if (strcmp(setting, "ring-ref") == 0)
234 {
235 xvdd->sring = (blkif_sring_t *)value;
236 FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
237 /* this bit is for when we have to take over an existing ring on a crash dump */
238 xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
239 xvdd->ring.rsp_cons = xvdd->ring.req_prod_pvt;
240 }
241 break;
242 case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
243 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d (%08x)\n", setting, PtrToUlong(value) & 0x3FFFFFFF, PtrToUlong(value)));
244 if (strcmp(setting, "event-channel") == 0)
245 {
246 /* cheat here - save the state of the ring in the topmost bits of the event-channel */
247 xvdd->event_channel_ptr = (ULONG *)(((PCHAR)ptr) - sizeof(ULONG));
248 xvdd->event_channel = PtrToUlong(value) & 0x3FFFFFFF;
249 if (PtrToUlong(value) & 0x80000000)
250 {
251 xvdd->cached_use_other = (BOOLEAN)!!(PtrToUlong(value) & 0x40000000);
252 KdPrint((__DRIVER_NAME " cached_use_other = %d\n", xvdd->cached_use_other));
253 }
254 }
255 break;
256 case XEN_INIT_TYPE_READ_STRING_BACK:
257 case XEN_INIT_TYPE_READ_STRING_FRONT:
258 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
259 if (strcmp(setting, "sectors") == 0)
260 xvdd->total_sectors = parse_numeric_string(value);
261 else if (strcmp(setting, "sector-size") == 0)
262 xvdd->bytes_per_sector = (ULONG)parse_numeric_string(value);
263 else if (strcmp(setting, "device-type") == 0)
264 {
265 if (strcmp(value, "disk") == 0)
266 {
267 KdPrint((__DRIVER_NAME " device-type = Disk\n"));
268 xvdd->device_type = XENVBD_DEVICETYPE_DISK;
269 }
270 else if (strcmp(value, "cdrom") == 0)
271 {
272 KdPrint((__DRIVER_NAME " device-type = CDROM\n"));
273 xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
274 }
275 else
276 {
277 KdPrint((__DRIVER_NAME " device-type = %s (This probably won't work!)\n", value));
278 xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
279 }
280 }
281 else if (strcmp(setting, "mode") == 0)
282 {
283 if (strncmp(value, "r", 1) == 0)
284 {
285 KdPrint((__DRIVER_NAME " mode = r\n"));
286 xvdd->device_mode = XENVBD_DEVICEMODE_READ;
287 }
288 else if (strncmp(value, "w", 1) == 0)
289 {
290 KdPrint((__DRIVER_NAME " mode = w\n"));
291 xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
292 }
293 else
294 {
295 KdPrint((__DRIVER_NAME " mode = unknown\n"));
296 xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
297 }
298 }
299 break;
300 case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
301 qemu_protocol_version = PtrToUlong(value);
302 break;
303 case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
304 qemu_hide_flags_value = PtrToUlong(value);
305 KdPrint((__DRIVER_NAME " qemu_hide_flags_value = %d\n", qemu_hide_flags_value));
306 break;
307 case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
308 qemu_hide_filter = TRUE;
309 KdPrint((__DRIVER_NAME " qemu_hide_filter = TRUE\n"));
310 break;
311 case XEN_INIT_TYPE_STATE_PTR:
312 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
313 xvdd->device_state = (PXENPCI_DEVICE_STATE)value;
314 break;
315 default:
316 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
317 break;
318 }
319 }
321 if (((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) && xvdd->device_type != XENVBD_DEVICETYPE_CDROM) || qemu_hide_filter)
322 xvdd->inactive = FALSE;
324 if (!xvdd->inactive && (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
325 || xvdd->sring == NULL
326 || xvdd->event_channel == 0
327 || xvdd->total_sectors == 0
328 || xvdd->bytes_per_sector == 0))
329 {
330 KdPrint((__DRIVER_NAME " Missing settings\n"));
331 FUNCTION_EXIT();
332 return SP_RETURN_BAD_CONFIG;
333 }
335 if (xvdd->inactive)
336 KdPrint((__DRIVER_NAME " Device is inactive\n"));
337 else
338 {
339 if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM)
340 {
341 /* CD/DVD drives must have bytes_per_sector = 2048. */
342 xvdd->bytes_per_sector = 2048;
343 }
345 /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
346 xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
348 xvdd->shadow_free = 0;
349 memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
350 for (i = 0; i < SHADOW_ENTRIES; i++)
351 {
352 xvdd->shadows[i].req.id = i;
353 /* make sure leftover real requests's are never confused with dump mode requests */
354 if (dump_mode)
355 xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
356 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
357 }
358 }
360 FUNCTION_EXIT();
361 return SP_RETURN_FOUND;
362 }
364 static __inline ULONG
365 decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
366 {
367 switch (srb->Cdb[0])
368 {
369 case SCSIOP_READ:
370 case SCSIOP_WRITE:
371 return ((ULONG)(UCHAR)srb->Cdb[7] << 8) | (ULONG)(UCHAR)srb->Cdb[8];
372 case SCSIOP_READ16:
373 case SCSIOP_WRITE16:
374 return ((ULONG)(UCHAR)srb->Cdb[10] << 24) | ((ULONG)(UCHAR)srb->Cdb[11] << 16) | ((ULONG)(UCHAR)srb->Cdb[12] << 8) | (ULONG)(UCHAR)srb->Cdb[13];
375 default:
376 return 0;
377 }
378 }
380 static __inline ULONGLONG
381 decode_cdb_sector(PSCSI_REQUEST_BLOCK srb)
382 {
383 ULONGLONG sector;
385 switch (srb->Cdb[0])
386 {
387 case SCSIOP_READ:
388 case SCSIOP_WRITE:
389 sector = ((ULONG)(UCHAR)srb->Cdb[2] << 24) | ((ULONG)(UCHAR)srb->Cdb[3] << 16) | ((ULONG)(UCHAR)srb->Cdb[4] << 8) | (ULONG)(UCHAR)srb->Cdb[5];
390 break;
391 case SCSIOP_READ16:
392 case SCSIOP_WRITE16:
393 sector = ((ULONGLONG)(UCHAR)srb->Cdb[2] << 56) | ((ULONGLONG)(UCHAR)srb->Cdb[3] << 48)
394 | ((ULONGLONG)(UCHAR)srb->Cdb[4] << 40) | ((ULONGLONG)(UCHAR)srb->Cdb[5] << 32)
395 | ((ULONGLONG)(UCHAR)srb->Cdb[6] << 24) | ((ULONGLONG)(UCHAR)srb->Cdb[7] << 16)
396 | ((ULONGLONG)(UCHAR)srb->Cdb[8] << 8) | ((ULONGLONG)(UCHAR)srb->Cdb[9]);
397 //KdPrint((__DRIVER_NAME " sector_number = %d (high) %d (low)\n", (ULONG)(sector >> 32), (ULONG)sector));
398 break;
399 default:
400 sector = 0;
401 break;
402 }
403 return sector;
404 }
406 static __inline BOOLEAN
407 decode_cdb_is_read(PSCSI_REQUEST_BLOCK srb)
408 {
409 switch (srb->Cdb[0])
410 {
411 case SCSIOP_READ:
412 case SCSIOP_READ16:
413 return TRUE;
414 case SCSIOP_WRITE:
415 case SCSIOP_WRITE16:
416 return FALSE;
417 default:
418 return FALSE;
419 }
420 }
422 static VOID
423 XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
424 {
425 srb_list_entry_t *srb_entry = srb->SrbExtension;
426 srb_entry->srb = srb;
427 if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI)
428 {
429 srb_entry->outstanding_requests = 0;
430 srb_entry->length = srb->DataTransferLength;
431 srb_entry->offset = 0;
432 srb_entry->error = FALSE;
433 }
434 InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
435 }
437 static VOID
438 XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVICE_DATA xvdd)
439 {
440 PSCSI_REQUEST_BLOCK srb;
441 srb_list_entry_t *srb_entry;
442 ULONGLONG sector_number;
443 ULONG block_count;
444 blkif_shadow_t *shadow;
445 ULONG remaining, offset, length;
446 grant_ref_t gref;
447 PUCHAR ptr;
448 int notify;
449 int i;
450 PVOID system_address;
452 //if (dump_mode) FUNCTION_ENTER();
454 while(!xvdd->aligned_buffer_in_use && xvdd->shadow_free && (srb_entry = (srb_list_entry_t *)RemoveHeadList(&xvdd->srb_list)) != (srb_list_entry_t *)&xvdd->srb_list)
455 {
456 srb = srb_entry->srb;
457 ASSERT(srb);
458 if (srb->Function != SRB_FUNCTION_EXECUTE_SCSI)
459 {
460 KdPrint((__DRIVER_NAME " SRB_FUNCTION_%02x retrieved from ring\n", srb->Function));
461 if (xvdd->shadow_free != SHADOW_ENTRIES)
462 {
463 KdPrint((__DRIVER_NAME " busy\n"));
464 /* put it back at the end of the list just in case something is queued that needs to be processed */
465 InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
466 break; /* stall the queue until it's all empty */
467 }
468 else
469 {
470 KdPrint((__DRIVER_NAME " completing\n"));
471 srb->SrbStatus = SRB_STATUS_SUCCESS;
472 StorPortNotification(RequestComplete, xvdd, srb);
473 continue;
474 }
475 }
477 if (!dump_mode)
478 {
479 if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS)
480 {
481 KdPrint((__DRIVER_NAME " Failed to map DataBuffer\n"));
482 srb->SrbStatus = SRB_STATUS_BUSY;
483 StorPortNotification(RequestComplete, xvdd, srb);
484 continue;
485 }
486 system_address = (PUCHAR)system_address + srb_entry->offset;
487 }
488 else
489 {
490 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
491 system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
492 }
493 block_count = decode_cdb_length(srb);
494 block_count *= xvdd->bytes_per_sector / 512;
495 sector_number = decode_cdb_sector(srb);
496 sector_number *= xvdd->bytes_per_sector / 512;
498 ASSERT(block_count * xvdd->bytes_per_sector == srb->DataTransferLength);
500 //KdPrint((__DRIVER_NAME " srb sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
502 sector_number += srb_entry->offset / 512;
503 block_count -= srb_entry->offset / 512;
505 /* look for pending writes that overlap this one */
506 /* we get warnings from drbd if we don't */
507 if (srb_entry->offset == 0)
508 {
509 for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
510 {
511 PSCSI_REQUEST_BLOCK srb2;
512 ULONGLONG sector_number2;
513 ULONG block_count2;
515 srb2 = xvdd->shadows[i].srb;
516 if (!srb2)
517 continue;
518 if (decode_cdb_is_read(srb2))
519 continue;
520 block_count2 = decode_cdb_length(srb2);;
521 block_count2 *= xvdd->bytes_per_sector / 512;
522 sector_number2 = decode_cdb_sector(srb2);
523 sector_number2 *= xvdd->bytes_per_sector / 512;
525 if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
526 continue;
527 if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
528 continue;
530 KdPrint((__DRIVER_NAME " Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
531 sector_number, block_count, sector_number2, block_count2));
532 /* put the srb back at the start of the queue */
533 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
534 break; /* stall the queue */
535 }
536 if (i != MAX_SHADOW_ENTRIES)
537 {
538 break; /* stall the queue but submit any outstanding requests */
539 }
540 }
542 shadow = get_shadow_from_freelist(xvdd);
543 if (!shadow)
544 {
545 /* put the srb back at the start of the queue */
546 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
547 break; /* stall the queue but submit any outstanding requests */
548 }
549 ASSERT(!shadow->aligned_buffer_in_use);
550 ASSERT(!shadow->srb);
551 shadow->req.sector_number = sector_number;
552 shadow->req.handle = 0;
553 shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
554 shadow->req.nr_segments = 0;
555 shadow->srb = srb;
556 shadow->length = 0;
557 shadow->system_address = system_address;
558 shadow->reset = FALSE;
560 if (!dump_mode)
561 {
562 if ((ULONG_PTR)shadow->system_address & 511)
563 {
564 xvdd->aligned_buffer_in_use = TRUE;
565 /* limit to aligned_buffer_size */
566 block_count = min(block_count, xvdd->aligned_buffer_size / 512);
567 ptr = (PUCHAR)xvdd->aligned_buffer;
568 if (!decode_cdb_is_read(srb))
569 memcpy(ptr, shadow->system_address, block_count * 512);
570 shadow->aligned_buffer_in_use = TRUE;
571 }
572 else
573 {
574 ptr = (PUCHAR)shadow->system_address;
575 shadow->aligned_buffer_in_use = FALSE;
576 }
577 }
578 else
579 {
580 ASSERT(!((ULONG_PTR)shadow->system_address & 511));
581 ptr = shadow->system_address;
582 shadow->aligned_buffer_in_use = FALSE;
583 }
585 //KdPrint((__DRIVER_NAME " sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
586 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
587 //KdPrint((__DRIVER_NAME " system_address = %p\n", shadow->system_address));
588 //KdPrint((__DRIVER_NAME " offset = %d, length = %d\n", srb_entry->offset, srb_entry->length));
589 //KdPrint((__DRIVER_NAME " ptr = %p\n", ptr));
591 //KdPrint((__DRIVER_NAME " handle = %d\n", shadow->req.handle));
592 //KdPrint((__DRIVER_NAME " operation = %d\n", shadow->req.operation));
594 remaining = block_count * 512;
595 while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
596 {
597 PHYSICAL_ADDRESS physical_address;
599 if (!dump_mode)
600 {
601 physical_address = MmGetPhysicalAddress(ptr);
602 }
603 else
604 {
605 ULONG length;
606 physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
607 }
608 gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
609 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
610 if (gref == INVALID_GRANT_REF)
611 {
612 ULONG i;
613 for (i = 0; i < shadow->req.nr_segments; i++)
614 {
615 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
616 shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
617 }
618 if (shadow->aligned_buffer_in_use)
619 {
620 shadow->aligned_buffer_in_use = FALSE;
621 xvdd->aligned_buffer_in_use = FALSE;
622 }
623 /* put the srb back at the start of the queue */
624 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
625 put_shadow_on_freelist(xvdd, shadow);
626 KdPrint((__DRIVER_NAME " Out of gref's. Deferring\n"));
627 break; /* stall the queue but submit any outstanding requests */
628 }
629 offset = physical_address.LowPart & (PAGE_SIZE - 1);
630 length = min(PAGE_SIZE - offset, remaining);
631 //if (dump_mode) KdPrint((__DRIVER_NAME " length = %d\n", length));
632 //if (dump_mode) KdPrint((__DRIVER_NAME " offset = %d\n", length));
633 ASSERT((offset & 511) == 0);
634 ASSERT((length & 511) == 0);
635 ASSERT(offset + length <= PAGE_SIZE);
636 shadow->req.seg[shadow->req.nr_segments].gref = gref;
637 shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
638 shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
639 //if (dump_mode) KdPrint((__DRIVER_NAME " gref = %d\n", shadow->req.seg[shadow->req.nr_segments].gref));
640 //if (dump_mode) KdPrint((__DRIVER_NAME " first_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].first_sect));
641 //if (dump_mode) KdPrint((__DRIVER_NAME " last_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].last_sect));
642 remaining -= length;
643 ptr += length;
644 shadow->length += length;
645 shadow->req.nr_segments++;
646 }
647 srb_entry->offset += shadow->length;
648 srb_entry->outstanding_requests++;
649 //KdPrint((__DRIVER_NAME " outstanding_requests = %p\n", srb_entry->outstanding_requests));
650 //KdPrint((__DRIVER_NAME " offset = %d, length = %d\n", srb_entry->offset, srb_entry->length));
651 //KdPrint((__DRIVER_NAME " ptr = %p\n", ptr));
652 if (srb_entry->offset < srb_entry->length)
653 {
654 if (dump_mode) KdPrint((__DRIVER_NAME " inserting back into list\n"));
655 /* put the srb back at the start of the queue to continue on the next request */
656 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
657 }
659 XenVbd_PutRequest(xvdd, &shadow->req);
660 }
661 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
662 if (notify)
663 {
664 //KdPrint((__DRIVER_NAME " Notifying\n"));
665 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
666 }
668 //if (dump_mode) FUNCTION_EXIT();
669 }
671 static ULONG
672 XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
673 {
674 // PACCESS_RANGE AccessRange;
675 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
676 ULONG status;
677 // PXENPCI_XEN_DEVICE_DATA XenDeviceData;
678 PACCESS_RANGE access_range;
680 UNREFERENCED_PARAMETER(HwContext);
681 UNREFERENCED_PARAMETER(BusInformation);
682 UNREFERENCED_PARAMETER(LowerDevice);
683 UNREFERENCED_PARAMETER(ArgumentString);
685 FUNCTION_ENTER();
686 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
687 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
689 RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
690 *Again = FALSE;
692 KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
693 KdPrint((__DRIVER_NAME " BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
695 if (!dump_mode)
696 {
697 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
698 if (ConfigInfo->NumberOfAccessRanges != 1 && ConfigInfo->NumberOfAccessRanges != 2)
699 {
700 return SP_RETURN_BAD_CONFIG;
701 }
703 access_range = &((*(ConfigInfo->AccessRanges))[0]);
704 KdPrint((__DRIVER_NAME " RangeStart = %08x, RangeLength = %08x\n",
705 access_range->RangeStart.LowPart, access_range->RangeLength));
706 xvdd->device_base = StorPortGetDeviceBase(
707 DeviceExtension,
708 PNPBus, //AdapterInterfaceType,
709 ConfigInfo->SystemIoBusNumber,
710 access_range->RangeStart,
711 access_range->RangeLength,
712 !access_range->RangeInMemory);
713 if (!xvdd->device_base)
714 {
715 KdPrint((__DRIVER_NAME " StorPortGetDeviceBase failed\n"));
716 FUNCTION_EXIT();
717 return SP_RETURN_BAD_CONFIG;
718 }
719 status = XenVbd_InitConfig(xvdd);
720 if (status != SP_RETURN_FOUND)
721 {
722 /* set inactive here so StartIo is harmless - we still get called with a PNP remove (or similar) */
723 xvdd->inactive = TRUE;
724 FUNCTION_EXIT();
725 return status;
726 }
727 xvdd->grant_tag = (ULONG)'VBD0';
728 }
729 else
730 {
731 xvdd->device_base = ConfigInfo->Reserved;
732 xvdd->grant_tag = (ULONG)'DUMP';
733 }
735 xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
736 status = XenVbd_InitFromConfig(xvdd);
737 if (status != SP_RETURN_FOUND)
738 {
739 /* set inactive here so StartIo is harmless - we still get called with a PNP remove (or similar) */
740 xvdd->inactive = TRUE;
741 FUNCTION_EXIT();
742 return status;
743 }
745 xvdd->aligned_buffer_in_use = FALSE;
746 /* align the buffer to PAGE_SIZE */
747 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
748 KdPrint((__DRIVER_NAME " aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
749 KdPrint((__DRIVER_NAME " aligned_buffer = %p\n", xvdd->aligned_buffer));
751 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
752 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
753 KdPrint((__DRIVER_NAME " ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength));
754 KdPrint((__DRIVER_NAME " ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
755 if (!dump_mode)
756 {
757 ConfigInfo->VirtualDevice = TRUE;
758 xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
759 }
760 else
761 {
762 ConfigInfo->VirtualDevice = FALSE;
763 xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
764 }
766 KdPrint((__DRIVER_NAME " ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice));
767 ConfigInfo->ScatterGather = TRUE;
768 ConfigInfo->Master = TRUE;
769 ConfigInfo->CachesData = FALSE;
770 ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
771 KdPrint((__DRIVER_NAME " ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses));
772 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
773 ConfigInfo->AlignmentMask = 0;
774 ConfigInfo->NumberOfBuses = 1;
775 ConfigInfo->InitiatorBusId[0] = 1;
776 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
777 ConfigInfo->MaximumNumberOfTargets = 2;
778 //ConfigInfo->BufferAccessScsiPortControlled = FALSE;
779 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
780 {
781 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
782 //ConfigInfo->Dma32BitAddresses = FALSE;
783 KdPrint((__DRIVER_NAME " Dma64BitAddresses supported\n"));
784 }
785 else
786 {
787 //ConfigInfo->Dma32BitAddresses = TRUE;
788 KdPrint((__DRIVER_NAME " Dma64BitAddresses not supported\n"));
789 }
791 FUNCTION_EXIT();
793 return SP_RETURN_FOUND;
794 }
796 static ULONG
797 XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
798 {
799 ULONG status;
801 FUNCTION_ENTER();
802 status = XenVbd_VirtualHwStorFindAdapter(DeviceExtension, HwContext, BusInformation, NULL, ArgumentString, ConfigInfo, Again);
803 FUNCTION_EXIT();
804 return status;
805 }
807 //do this in StartIo instead to prevent races with the driver initialisation
808 static VOID
809 XenVbd_StartRingDetection(PXENVBD_DEVICE_DATA xvdd)
810 {
811 blkif_request_t *req;
812 int notify;
814 xvdd->ring_detect_state = RING_DETECT_STATE_DETECT1;
815 RtlZeroMemory(xvdd->sring->ring, PAGE_SIZE - FIELD_OFFSET(blkif_sring_t, ring));
816 req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
817 req->operation = 0xff;
818 xvdd->ring.req_prod_pvt++;
819 req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
820 req->operation = 0xff;
821 xvdd->ring.req_prod_pvt++;
823 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
824 if (notify)
825 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
826 }
828 static BOOLEAN
829 XenVbd_HwStorInitialize(PVOID DeviceExtension)
830 {
831 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
833 FUNCTION_ENTER();
834 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
835 KdPrint((__DRIVER_NAME " dump_mode = %d\n", dump_mode));
837 if (!xvdd->inactive)
838 {
839 if (dump_mode)
840 {
841 if (xvdd->cached_use_other)
842 {
843 xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
844 xvdd->use_other = TRUE;
845 }
846 xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
847 }
848 InitializeListHead(&xvdd->srb_list);
849 }
850 FUNCTION_EXIT();
852 return TRUE;
853 }
855 static ULONG
856 XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
857 {
858 PMODE_PARAMETER_HEADER parameter_header = NULL;
859 PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
860 PMODE_PARAMETER_BLOCK param_block;
861 PMODE_FORMAT_PAGE format_page;
862 ULONG offset = 0;
863 UCHAR buffer[1024];
864 BOOLEAN valid_page = FALSE;
865 BOOLEAN cdb_llbaa;
866 BOOLEAN cdb_dbd;
867 UCHAR cdb_page_code;
868 USHORT cdb_allocation_length;
870 UNREFERENCED_PARAMETER(xvdd);
872 RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
873 RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
874 offset = 0;
876 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
878 switch (srb->Cdb[0])
879 {
880 case SCSIOP_MODE_SENSE:
881 cdb_llbaa = FALSE;
882 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
883 cdb_page_code = srb->Cdb[2] & 0x3f;
884 cdb_allocation_length = srb->Cdb[4];
885 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
886 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
887 parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
888 parameter_header->MediumType = 0;
889 parameter_header->DeviceSpecificParameter = 0;
890 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
891 {
892 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
893 parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
894 }
895 offset += sizeof(MODE_PARAMETER_HEADER);
896 break;
897 case SCSIOP_MODE_SENSE10:
898 cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
899 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
900 cdb_page_code = srb->Cdb[2] & 0x3f;
901 cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
902 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE10 llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
903 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
904 parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
905 parameter_header10->MediumType = 0;
906 parameter_header10->DeviceSpecificParameter = 0;
907 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
908 {
909 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
910 parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
911 }
912 offset += sizeof(MODE_PARAMETER_HEADER10);
913 break;
914 default:
915 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
916 return FALSE;
917 }
919 if (!cdb_dbd)
920 {
921 param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
922 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
923 {
924 if (xvdd->total_sectors >> 32)
925 {
926 param_block->DensityCode = 0xff;
927 param_block->NumberOfBlocks[0] = 0xff;
928 param_block->NumberOfBlocks[1] = 0xff;
929 param_block->NumberOfBlocks[2] = 0xff;
930 }
931 else
932 {
933 param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
934 param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
935 param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
936 param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
937 }
938 param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
939 param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
940 param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
941 }
942 offset += sizeof(MODE_PARAMETER_BLOCK);
943 }
944 switch (srb->Cdb[0])
945 {
946 case SCSIOP_MODE_SENSE:
947 parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
948 break;
949 case SCSIOP_MODE_SENSE10:
950 parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);
951 parameter_header10->BlockDescriptorLength[1] = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER10));
952 break;
953 }
954 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_FORMAT_DEVICE || cdb_page_code == MODE_SENSE_RETURN_ALL))
955 {
956 valid_page = TRUE;
957 format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
958 format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
959 format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
960 /* 256 sectors per track */
961 format_page->SectorsPerTrack[0] = 0x01;
962 format_page->SectorsPerTrack[1] = 0x00;
963 /* xxx bytes per sector */
964 format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
965 format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
966 format_page->HardSectorFormating = TRUE;
967 format_page->SoftSectorFormating = TRUE;
968 offset += sizeof(MODE_FORMAT_PAGE);
969 }
970 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_CACHING || cdb_page_code == MODE_SENSE_RETURN_ALL))
971 {
972 PMODE_CACHING_PAGE caching_page;
973 valid_page = TRUE;
974 caching_page = (PMODE_CACHING_PAGE)&buffer[offset];
975 caching_page->PageCode = MODE_PAGE_CACHING;
976 caching_page->PageLength = sizeof(MODE_CACHING_PAGE) - FIELD_OFFSET(MODE_CACHING_PAGE, PageLength);
977 // caching_page-> // all zeros is just fine... maybe
978 offset += sizeof(MODE_CACHING_PAGE);
979 }
980 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_MEDIUM_TYPES || cdb_page_code == MODE_SENSE_RETURN_ALL))
981 {
982 PUCHAR medium_types_page;
983 valid_page = TRUE;
984 medium_types_page = &buffer[offset];
985 medium_types_page[0] = MODE_PAGE_MEDIUM_TYPES;
986 medium_types_page[1] = 0x06;
987 medium_types_page[2] = 0;
988 medium_types_page[3] = 0;
989 medium_types_page[4] = 0;
990 medium_types_page[5] = 0;
991 medium_types_page[6] = 0;
992 medium_types_page[7] = 0;
993 offset += 8;
994 }
995 switch (srb->Cdb[0])
996 {
997 case SCSIOP_MODE_SENSE:
998 parameter_header->ModeDataLength = (UCHAR)(offset - 1);
999 break;
1000 case SCSIOP_MODE_SENSE10:
1001 parameter_header10->ModeDataLength[0] = (UCHAR)((offset - 2) >> 8);
1002 parameter_header10->ModeDataLength[1] = (UCHAR)(offset - 2);
1003 break;
1006 if (!valid_page && cdb_page_code != MODE_SENSE_RETURN_ALL)
1008 srb->SrbStatus = SRB_STATUS_ERROR;
1010 else if(offset < srb->DataTransferLength)
1011 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
1012 else
1013 srb->SrbStatus = SRB_STATUS_SUCCESS;
1014 srb->DataTransferLength = min(srb->DataTransferLength, offset);
1015 srb->ScsiStatus = 0;
1016 memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
1018 //FUNCTION_EXIT();
1020 return TRUE;
1023 static ULONG
1024 XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
1026 PSENSE_DATA sd = srb->SenseInfoBuffer;
1028 UNREFERENCED_PARAMETER(xvdd);
1030 if (!srb->SenseInfoBuffer)
1031 return 0;
1033 sd->ErrorCode = 0x70;
1034 sd->Valid = 1;
1035 sd->SenseKey = sense_key;
1036 sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
1037 sd->AdditionalSenseCode = additional_sense_code;
1038 return sizeof(SENSE_DATA);
1041 static VOID
1042 XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
1044 if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
1045 return;
1046 XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
1047 srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
1050 static BOOLEAN
1051 XenVbd_HandleEventSynchronised(PVOID DeviceExtension, PVOID context)
1053 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
1054 PSCSI_REQUEST_BLOCK srb;
1055 RING_IDX i, rp;
1056 ULONG j;
1057 blkif_response_t *rep;
1058 //int block_count;
1059 int more_to_do = TRUE;
1060 blkif_shadow_t *shadow;
1061 ULONG suspend_resume_state_pdo;
1062 srb_list_entry_t *srb_entry;
1064 UNREFERENCED_PARAMETER(context);
1066 //if (dump_mode) FUNCTION_ENTER();
1068 suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
1069 KeMemoryBarrier();
1071 if (suspend_resume_state_pdo != xvdd->device_state->suspend_resume_state_fdo)
1073 //FUNCTION_ENTER();
1074 switch (suspend_resume_state_pdo)
1076 case SR_STATE_SUSPENDING:
1077 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_SUSPENDING\n"));
1078 break;
1079 case SR_STATE_RESUMING:
1080 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_RESUMING\n"));
1081 XenVbd_InitFromConfig(xvdd);
1082 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1083 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1084 break;
1085 case SR_STATE_RUNNING:
1086 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1087 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1088 xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED; /* could be running on different hardware */
1089 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1090 default:
1091 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1092 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1093 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1094 break;
1096 KeMemoryBarrier();
1099 if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
1101 return TRUE;
1104 while (more_to_do)
1106 rp = xvdd->ring.sring->rsp_prod;
1107 KeMemoryBarrier();
1108 for (i = xvdd->ring.rsp_cons; i < rp; i++)
1110 rep = XenVbd_GetResponse(xvdd, i);
1111 /*
1112 * This code is to automatically detect if the backend is using the same
1113 * bit width or a different bit width to us. Later versions of Xen do this
1114 * via a xenstore value, but not all. That 0x0fffffff (notice
1115 * that the msb is not actually set, so we don't have any problems with
1116 * sign extending) is to signify the last entry on the right, which is
1117 * different under 32 and 64 bits, and that is why we set it up there.
1119 * To do the detection, we put two initial entries on the ring, with an op
1120 * of 0xff (which is invalid). The first entry is mostly okay, but the
1121 * second will be grossly misaligned if the backend bit width is different,
1122 * and we detect this and switch frontend structures.
1123 */
1124 switch (xvdd->ring_detect_state)
1126 case RING_DETECT_STATE_NOT_STARTED:
1127 KdPrint((__DRIVER_NAME " premature IRQ\n"));
1128 break;
1129 case RING_DETECT_STATE_DETECT1:
1130 KdPrint((__DRIVER_NAME " ring_detect_state = %d, index = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, i, rep->operation, rep->id, rep->status));
1131 KdPrint((__DRIVER_NAME " req_prod = %d, rsp_prod = %d, rsp_cons = %d\n", xvdd->sring->req_prod, xvdd->sring->rsp_prod, xvdd->ring.rsp_cons));
1132 xvdd->ring_detect_state = RING_DETECT_STATE_DETECT2;
1133 break;
1134 case RING_DETECT_STATE_DETECT2:
1135 KdPrint((__DRIVER_NAME " ring_detect_state = %d, index = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, i, rep->operation, rep->id, rep->status));
1136 KdPrint((__DRIVER_NAME " req_prod = %d, rsp_prod = %d, rsp_cons = %d\n", xvdd->sring->req_prod, xvdd->sring->rsp_prod, xvdd->ring.rsp_cons));
1137 *xvdd->event_channel_ptr |= 0x80000000;
1138 if (rep->operation != 0xff)
1140 KdPrint((__DRIVER_NAME " switching to 'other' ring size\n"));
1141 xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
1142 xvdd->use_other = TRUE;
1143 *xvdd->event_channel_ptr |= 0x40000000;
1145 xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
1146 break;
1147 case RING_DETECT_STATE_COMPLETE:
1148 shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
1149 if (shadow->reset)
1151 KdPrint((__DRIVER_NAME " discarding reset shadow\n"));
1152 for (j = 0; j < shadow->req.nr_segments; j++)
1154 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1155 shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
1158 else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG))
1160 KdPrint((__DRIVER_NAME " discarding stale (non-dump-mode) shadow\n"));
1162 else
1164 srb = shadow->srb;
1165 ASSERT(srb);
1166 srb_entry = srb->SrbExtension;
1167 ASSERT(srb_entry);
1168 /* a few errors occur in dump mode because Xen refuses to allow us to map pages we are using for other stuff. Just ignore them */
1169 if (rep->status == BLKIF_RSP_OKAY || (dump_mode && dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
1170 srb->SrbStatus = SRB_STATUS_SUCCESS;
1171 else
1173 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
1174 if (decode_cdb_is_read(srb))
1175 KdPrint((__DRIVER_NAME " Operation = Read\n"));
1176 else
1177 KdPrint((__DRIVER_NAME " Operation = Write\n"));
1178 srb_entry->error = TRUE;
1180 if (shadow->aligned_buffer_in_use)
1182 ASSERT(xvdd->aligned_buffer_in_use);
1183 xvdd->aligned_buffer_in_use = FALSE;
1184 if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
1185 memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
1187 for (j = 0; j < shadow->req.nr_segments; j++)
1189 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1190 shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
1192 srb_entry->outstanding_requests--;
1193 if (!srb_entry->outstanding_requests && srb_entry->offset == srb_entry->length)
1195 if (srb_entry->error)
1197 srb->SrbStatus = SRB_STATUS_ERROR;
1198 srb->ScsiStatus = 0x02;
1199 xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
1200 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1201 XenVbd_MakeAutoSense(xvdd, srb);
1203 StorPortNotification(RequestComplete, xvdd, srb);
1206 shadow->aligned_buffer_in_use = FALSE;
1207 shadow->srb = NULL;
1208 shadow->reset = FALSE;
1209 put_shadow_on_freelist(xvdd, shadow);
1210 break;
1214 xvdd->ring.rsp_cons = i;
1215 if (i != xvdd->ring.req_prod_pvt)
1217 RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
1219 else
1221 xvdd->ring.sring->rsp_event = i + 1;
1222 more_to_do = FALSE;
1226 //if (start_ring_detect_state == RING_DETECT_STATE_COMPLETE)
1227 XenVbd_PutQueuedSrbsOnRing(xvdd);
1229 if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
1231 if (xvdd->inactive || xvdd->shadow_free == SHADOW_ENTRIES)
1233 /* all entries are purged from the list (or we are inactive). ready to suspend */
1234 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1235 KeMemoryBarrier();
1236 KdPrint((__DRIVER_NAME " Set fdo state SR_STATE_SUSPENDING\n"));
1237 KdPrint((__DRIVER_NAME " Notifying event channel %d\n", xvdd->device_state->pdo_event_channel));
1238 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1241 //if (dump_mode) FUNCTION_EXIT();
1243 return TRUE;
1246 static BOOLEAN
1247 XenVbd_HandleEvent(PVOID DeviceExtension)
1249 BOOLEAN retval;
1250 STOR_LOCK_HANDLE lock_handle;
1252 //if (dump_mode) FUNCTION_ENTER();
1253 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
1254 retval = StorPortSynchronizeAccess(DeviceExtension, XenVbd_HandleEventSynchronised, NULL);
1255 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1256 //if (dump_mode) FUNCTION_EXIT();
1257 return retval;
1260 /* this is only used during hiber and dump */
1261 static BOOLEAN
1262 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
1264 BOOLEAN retval;
1266 //FUNCTION_ENTER();
1267 retval = XenVbd_HandleEventSynchronised(DeviceExtension, NULL);
1268 //FUNCTION_EXIT();
1269 return retval;
1272 static BOOLEAN
1273 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
1275 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1276 //srb_list_entry_t *srb_entry;
1277 int i;
1278 /* need to make sure that each SRB is only reset once */
1279 LIST_ENTRY srb_reset_list;
1280 PLIST_ENTRY list_entry;
1281 //STOR_LOCK_HANDLE lock_handle;
1283 UNREFERENCED_PARAMETER(PathId);
1285 FUNCTION_ENTER();
1287 /* It appears that the StartIo spinlock is already held at this point */
1289 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1291 if (xvdd->ring_detect_state == RING_DETECT_STATE_COMPLETE && xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
1293 xvdd->aligned_buffer_in_use = FALSE;
1295 InitializeListHead(&srb_reset_list);
1297 while((list_entry = RemoveHeadList(&xvdd->srb_list)) != &xvdd->srb_list)
1299 #if DBG
1300 srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
1301 KdPrint((__DRIVER_NAME " adding queued SRB %p to reset list\n", srb_entry->srb));
1302 #endif
1303 InsertTailList(&srb_reset_list, list_entry);
1306 for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
1308 if (xvdd->shadows[i].srb)
1310 srb_list_entry_t *srb_entry = xvdd->shadows[i].srb->SrbExtension;
1311 for (list_entry = srb_reset_list.Flink; list_entry != &srb_reset_list; list_entry = list_entry->Flink)
1313 if (list_entry == &srb_entry->list_entry)
1314 break;
1316 if (list_entry == &srb_reset_list)
1318 KdPrint((__DRIVER_NAME " adding in-flight SRB %p to reset list\n", srb_entry->srb));
1319 InsertTailList(&srb_reset_list, &srb_entry->list_entry);
1321 /* set reset here so that the interrupt won't do anything with the srb but will dispose of the shadow entry correctly */
1322 xvdd->shadows[i].reset = TRUE;
1323 xvdd->shadows[i].srb = NULL;
1324 xvdd->shadows[i].aligned_buffer_in_use = FALSE;
1328 while((list_entry = RemoveHeadList(&srb_reset_list)) != &srb_reset_list)
1330 srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
1331 srb_entry->srb->SrbStatus = SRB_STATUS_BUS_RESET;
1332 KdPrint((__DRIVER_NAME " completing SRB %p with status SRB_STATUS_BUS_RESET\n", srb_entry->srb));
1333 StorPortNotification(RequestComplete, xvdd, srb_entry->srb);
1336 /* send a notify to Dom0 just in case it was missed for some reason (which should _never_ happen) */
1337 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
1339 StorPortNotification(NextRequest, DeviceExtension);
1342 //StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
1344 FUNCTION_EXIT();
1346 return TRUE;
1349 static BOOLEAN
1350 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
1352 PUCHAR data_buffer;
1353 PSCSI_PNP_REQUEST_BLOCK sprb;
1354 PSCSI_POWER_REQUEST_BLOCK spwrb;
1355 PMINIPORT_DUMP_POINTERS dump_pointers;
1356 PCDB cdb;
1357 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1358 ULONG data_transfer_length;
1359 UCHAR srb_status = SRB_STATUS_PENDING;
1360 STOR_LOCK_HANDLE lock_handle;
1362 //if (dump_mode) FUNCTION_ENTER();
1363 //if (dump_mode) KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1365 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
1367 data_transfer_length = srb->DataTransferLength;
1369 if (xvdd->inactive)
1371 KdPrint((__DRIVER_NAME " Inactive srb->Function = %08X\n", srb->Function));
1372 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1373 StorPortNotification(RequestComplete, DeviceExtension, srb);
1374 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1375 return TRUE;
1378 if (xvdd->ring_detect_state == RING_DETECT_STATE_NOT_STARTED)
1380 XenVbd_StartRingDetection(DeviceExtension);
1383 // If we haven't enumerated all the devices yet then just defer the request
1384 if (xvdd->ring_detect_state < RING_DETECT_STATE_COMPLETE)
1386 srb->SrbStatus = SRB_STATUS_BUSY;
1387 StorPortNotification(RequestComplete, DeviceExtension, srb);
1388 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Still figuring out ring)\n"));
1389 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1390 return TRUE;
1393 if (!dump_mode && xvdd->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
1395 //KdPrint((__DRIVER_NAME " --> HwStorStartIo (Suspending/Resuming)\n"));
1396 srb->SrbStatus = SRB_STATUS_BUSY;
1397 StorPortNotification(RequestComplete, DeviceExtension, srb);
1398 //KdPrint((__DRIVER_NAME " <-- HwStorStartIo (Suspending/Resuming)\n"));
1399 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1400 return TRUE;
1403 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
1405 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1406 StorPortNotification(RequestComplete, DeviceExtension, srb);
1407 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun));
1408 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1409 return TRUE;
1412 switch (srb->Function)
1414 case SRB_FUNCTION_EXECUTE_SCSI:
1415 cdb = (PCDB)srb->Cdb;
1417 switch(cdb->CDB6GENERIC.OperationCode)
1419 case SCSIOP_TEST_UNIT_READY:
1420 if (dump_mode)
1421 KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
1422 srb_status = SRB_STATUS_SUCCESS;
1423 srb->ScsiStatus = 0;
1424 break;
1425 case SCSIOP_INQUIRY:
1426 if (dump_mode)
1427 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
1428 // KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
1429 // KdPrint((__DRIVER_NAME " (Length = %d)\n", srb->DataTransferLength));
1431 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1432 data_buffer = srb->DataBuffer;
1433 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1434 srb_status = SRB_STATUS_SUCCESS;
1435 switch (xvdd->device_type)
1437 case XENVBD_DEVICETYPE_DISK:
1438 if ((srb->Cdb[1] & 1) == 0)
1440 if (srb->Cdb[2])
1442 srb_status = SRB_STATUS_ERROR;
1444 else
1446 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1447 id->DeviceType = DIRECT_ACCESS_DEVICE;
1448 id->Versions = 4; /* minimum that WHQL says we must support */
1449 id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
1450 id->HiSupport = 1; /* WHQL test says we should set this */
1451 //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1452 id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
1453 id->CommandQueue = 1;
1454 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1455 memcpy(id->ProductId, scsi_disk_model, 16); // product id
1456 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1457 data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
1460 else
1462 switch (srb->Cdb[2])
1464 case VPD_SUPPORTED_PAGES: /* list of pages we support */
1465 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1466 data_buffer[1] = VPD_SUPPORTED_PAGES;
1467 data_buffer[2] = 0x00;
1468 data_buffer[3] = 2;
1469 data_buffer[4] = 0x00;
1470 data_buffer[5] = 0x80;
1471 data_transfer_length = 6;
1472 break;
1473 case VPD_SERIAL_NUMBER: /* serial number */
1474 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1475 data_buffer[1] = VPD_SERIAL_NUMBER;
1476 data_buffer[2] = 0x00;
1477 data_buffer[3] = 8;
1478 memset(&data_buffer[4], ' ', 8);
1479 data_transfer_length = 12;
1480 break;
1481 case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
1482 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1483 data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
1484 data_buffer[2] = 0x00;
1485 data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
1486 data_buffer[4] = 2; /* ASCII */
1487 data_buffer[5] = 1; /* VendorId */
1488 data_buffer[6] = 0;
1489 data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
1490 memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
1491 data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
1492 break;
1493 default:
1494 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1495 srb_status = SRB_STATUS_ERROR;
1496 break;
1499 break;
1500 case XENVBD_DEVICETYPE_CDROM:
1501 if ((srb->Cdb[1] & 1) == 0)
1503 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1504 id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
1505 id->RemovableMedia = 1;
1506 id->Versions = 3;
1507 id->ResponseDataFormat = 0;
1508 id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1509 id->CommandQueue = 1;
1510 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1511 memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
1512 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1513 data_transfer_length = sizeof(INQUIRYDATA);
1515 else
1517 switch (srb->Cdb[2])
1519 case 0x00:
1520 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1521 data_buffer[1] = 0x00;
1522 data_buffer[2] = 0x00;
1523 data_buffer[3] = 2;
1524 data_buffer[4] = 0x00;
1525 data_buffer[5] = 0x80;
1526 data_transfer_length = 6;
1527 break;
1528 case 0x80:
1529 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1530 data_buffer[1] = 0x80;
1531 data_buffer[2] = 0x00;
1532 data_buffer[3] = 8;
1533 data_buffer[4] = 0x31;
1534 data_buffer[5] = 0x32;
1535 data_buffer[6] = 0x33;
1536 data_buffer[7] = 0x34;
1537 data_buffer[8] = 0x35;
1538 data_buffer[9] = 0x36;
1539 data_buffer[10] = 0x37;
1540 data_buffer[11] = 0x38;
1541 data_transfer_length = 12;
1542 break;
1543 default:
1544 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1545 srb_status = SRB_STATUS_ERROR;
1546 break;
1549 break;
1550 default:
1551 //KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", xvdd->device_type));
1552 srb_status = SRB_STATUS_ERROR;
1553 break;
1555 break;
1556 case SCSIOP_READ_CAPACITY:
1557 if (dump_mode)
1558 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1559 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1560 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1561 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1562 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1563 data_buffer = srb->DataBuffer;
1564 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1565 if ((xvdd->total_sectors - 1) >> 32)
1567 data_buffer[0] = 0xff;
1568 data_buffer[1] = 0xff;
1569 data_buffer[2] = 0xff;
1570 data_buffer[3] = 0xff;
1572 else
1574 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1575 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1576 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1577 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1579 data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1580 data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1581 data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1582 data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1583 data_transfer_length = 8;
1584 srb->ScsiStatus = 0;
1585 srb_status = SRB_STATUS_SUCCESS;
1586 break;
1587 case SCSIOP_READ_CAPACITY16:
1588 if (dump_mode)
1589 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1590 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1591 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1592 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1593 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1594 data_buffer = srb->DataBuffer;
1595 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1596 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
1597 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
1598 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
1599 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
1600 data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1601 data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1602 data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1603 data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1604 data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1605 data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1606 data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1607 data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1608 data_transfer_length = 12;
1609 srb->ScsiStatus = 0;
1610 srb_status = SRB_STATUS_SUCCESS;
1611 break;
1612 case SCSIOP_MODE_SENSE:
1613 case SCSIOP_MODE_SENSE10:
1614 if (dump_mode)
1615 KdPrint((__DRIVER_NAME " Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", srb->Cdb[1] & 0x08, srb->Cdb[2] & 0xC0, srb->Cdb[2] & 0x3F));
1616 data_transfer_length = XenVbd_FillModePage(xvdd, srb);
1617 srb_status = SRB_STATUS_SUCCESS;
1618 break;
1619 case SCSIOP_READ:
1620 case SCSIOP_READ16:
1621 case SCSIOP_WRITE:
1622 case SCSIOP_WRITE16:
1623 //KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1624 XenVbd_PutSrbOnList(xvdd, srb);
1625 XenVbd_PutQueuedSrbsOnRing(xvdd);
1626 break;
1627 case SCSIOP_VERIFY:
1628 case SCSIOP_VERIFY16:
1629 // Should we do more here?
1630 if (dump_mode)
1631 KdPrint((__DRIVER_NAME " Command = VERIFY\n"));
1632 srb_status = SRB_STATUS_SUCCESS;
1633 break;
1634 #if 0
1635 case SCSIOP_REPORT_LUNS:
1636 if (dump_mode)
1637 KdPrint((__DRIVER_NAME " Command = REPORT_LUNS\n"));
1638 switch (srb->Cdb[1])
1641 srb_status = SRB_STATUS_SUCCESS;;
1642 break;
1643 #endif
1644 case SCSIOP_REQUEST_SENSE:
1645 if (dump_mode)
1646 KdPrint((__DRIVER_NAME " Command = REQUEST_SENSE\n"));
1647 data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
1648 srb_status = SRB_STATUS_SUCCESS;
1649 break;
1650 case SCSIOP_READ_TOC:
1651 if (dump_mode)
1652 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
1653 data_buffer = srb->DataBuffer;
1654 /*
1655 #define READ_TOC_FORMAT_TOC 0x00
1656 #define READ_TOC_FORMAT_SESSION 0x01
1657 #define READ_TOC_FORMAT_FULL_TOC 0x02
1658 #define READ_TOC_FORMAT_PMA 0x03
1659 #define READ_TOC_FORMAT_ATIP 0x04
1660 */
1661 // KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
1662 // KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
1663 // KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
1664 // KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
1665 // KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
1666 // KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
1667 // KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
1668 switch (cdb->READ_TOC.Format2)
1670 case READ_TOC_FORMAT_TOC:
1671 data_buffer[0] = 0; // length MSB
1672 data_buffer[1] = 10; // length LSB
1673 data_buffer[2] = 1; // First Track
1674 data_buffer[3] = 1; // Last Track
1675 data_buffer[4] = 0; // Reserved
1676 data_buffer[5] = 0x14; // current position data + uninterrupted data
1677 data_buffer[6] = 1; // last complete track
1678 data_buffer[7] = 0; // reserved
1679 data_buffer[8] = 0; // MSB Block
1680 data_buffer[9] = 0;
1681 data_buffer[10] = 0;
1682 data_buffer[11] = 0; // LSB Block
1683 data_transfer_length = 12;
1684 srb_status = SRB_STATUS_SUCCESS;
1685 break;
1686 case READ_TOC_FORMAT_SESSION:
1687 case READ_TOC_FORMAT_FULL_TOC:
1688 case READ_TOC_FORMAT_PMA:
1689 case READ_TOC_FORMAT_ATIP:
1690 srb_status = SRB_STATUS_ERROR;
1691 break;
1692 default:
1693 srb_status = SRB_STATUS_ERROR;
1694 break;
1696 break;
1697 case SCSIOP_START_STOP_UNIT:
1698 KdPrint((__DRIVER_NAME " Command = SCSIOP_START_STOP_UNIT\n"));
1699 srb_status = SRB_STATUS_SUCCESS;
1700 break;
1701 case SCSIOP_RESERVE_UNIT:
1702 KdPrint((__DRIVER_NAME " Command = SCSIOP_RESERVE_UNIT\n"));
1703 srb_status = SRB_STATUS_SUCCESS;
1704 break;
1705 case SCSIOP_RELEASE_UNIT:
1706 KdPrint((__DRIVER_NAME " Command = SCSIOP_RELEASE_UNIT\n"));
1707 srb_status = SRB_STATUS_SUCCESS;
1708 break;
1709 default:
1710 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
1711 srb_status = SRB_STATUS_ERROR;
1712 break;
1714 if (srb_status == SRB_STATUS_ERROR)
1716 KdPrint((__DRIVER_NAME " EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
1717 if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
1719 xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
1720 xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
1722 srb->SrbStatus = srb_status;
1723 srb->ScsiStatus = 0x02;
1724 XenVbd_MakeAutoSense(xvdd, srb);
1725 StorPortNotification(RequestComplete, DeviceExtension, srb);
1727 else if (srb_status != SRB_STATUS_PENDING)
1729 if (data_transfer_length > srb->DataTransferLength)
1730 KdPrint((__DRIVER_NAME " data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
1732 if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
1734 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
1735 srb->DataTransferLength = data_transfer_length;
1737 else
1739 srb->SrbStatus = srb_status;
1741 xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
1742 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1743 StorPortNotification(RequestComplete, DeviceExtension, srb);
1745 break;
1746 case SRB_FUNCTION_IO_CONTROL:
1747 KdPrint((__DRIVER_NAME " SRB_FUNCTION_IO_CONTROL\n"));
1748 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1749 StorPortNotification(RequestComplete, DeviceExtension, srb);
1750 break;
1751 case SRB_FUNCTION_FLUSH:
1752 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1753 srb->SrbStatus = SRB_STATUS_SUCCESS;
1754 StorPortNotification(RequestComplete, DeviceExtension, srb);
1755 break;
1756 case SRB_FUNCTION_PNP:
1757 KdPrint((__DRIVER_NAME " SRB_FUNCTION_PNP\n"));
1758 sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
1759 switch (sprb->PnPAction)
1761 case StorStartDevice:
1762 KdPrint((__DRIVER_NAME " StorStartDevice\n"));
1763 break;
1764 case StorRemoveDevice:
1765 KdPrint((__DRIVER_NAME " StorRemoveDevice\n"));
1766 break;
1767 case StorStopDevice:
1768 KdPrint((__DRIVER_NAME " StorStopDevice\n"));
1769 break;
1770 case StorQueryCapabilities:
1771 KdPrint((__DRIVER_NAME " StorQueryCapabilities\n"));
1772 break;
1773 case StorFilterResourceRequirements:
1774 KdPrint((__DRIVER_NAME " StorFilterResourceRequirements\n"));
1775 break;
1776 default:
1777 KdPrint((__DRIVER_NAME " Stor%d\n", sprb->PnPAction));
1778 break;
1780 KdPrint((__DRIVER_NAME " SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
1781 srb->SrbStatus = SRB_STATUS_SUCCESS;
1782 StorPortNotification(RequestComplete, DeviceExtension, srb);
1783 break;
1785 case SRB_FUNCTION_POWER:
1786 KdPrint((__DRIVER_NAME " SRB_FUNCTION_POWER\n"));
1787 spwrb = (PSCSI_POWER_REQUEST_BLOCK)srb;
1788 switch (spwrb->PowerAction)
1790 case StorPowerActionNone:
1791 KdPrint((__DRIVER_NAME " StorPowerActionNone\n"));
1792 break;
1793 case StorPowerActionReserved:
1794 KdPrint((__DRIVER_NAME " StorPowerActionReserved\n"));
1795 break;
1796 case StorPowerActionSleep:
1797 KdPrint((__DRIVER_NAME " StorPowerActionSleep\n"));
1798 break;
1799 case StorPowerActionHibernate:
1800 KdPrint((__DRIVER_NAME " StorPowerActionHibernate\n"));
1801 break;
1802 case StorPowerActionShutdown:
1803 KdPrint((__DRIVER_NAME " StorPowerActionShutdown\n"));
1804 break;
1805 case StorPowerActionShutdownReset:
1806 KdPrint((__DRIVER_NAME " StorPowerActionShutdownReset\n"));
1807 break;
1808 case StorPowerActionShutdownOff:
1809 KdPrint((__DRIVER_NAME " StorPowerActionShutdownOff\n"));
1810 break;
1811 case StorPowerActionWarmEject:
1812 KdPrint((__DRIVER_NAME " StorPowerActionWarmEject\n"));
1813 break;
1814 default:
1815 KdPrint((__DRIVER_NAME " Stor%d\n", spwrb->PowerAction));
1816 break;
1818 XenVbd_PutSrbOnList(xvdd, srb);
1819 XenVbd_PutQueuedSrbsOnRing(xvdd);
1820 break;
1821 case SRB_FUNCTION_DUMP_POINTERS:
1822 KdPrint((__DRIVER_NAME " SRB_FUNCTION_DUMP_POINTERS\n"));
1823 KdPrint((__DRIVER_NAME " DataTransferLength = %d\n", srb->DataTransferLength));
1824 dump_pointers = srb->DataBuffer;
1825 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1826 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1827 KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1828 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1829 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1830 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1831 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1832 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1833 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1834 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1835 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1836 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1837 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1838 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1839 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1840 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1841 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1843 dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
1844 dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
1845 RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
1846 dump_pointers->AdapterObject = NULL;
1847 dump_pointers->MappedRegisterBase = 0;
1848 dump_pointers->CommonBufferSize = 0;
1849 dump_pointers->MiniportPrivateDumpData = (PVOID)xvdd->device_base;
1850 //dump_pointers->SystemIoBusNumber = 0;
1851 dump_pointers->AdapterInterfaceType = Internal;
1852 dump_pointers->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
1853 dump_pointers->NumberOfPhysicalBreaks = dump_pointers->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
1854 dump_pointers->AlignmentMask = 0;
1855 dump_pointers->NumberOfAccessRanges = 1;
1856 dump_pointers->NumberOfBuses = 1;
1857 dump_pointers->Master = TRUE;
1858 dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1859 dump_pointers->MaximumNumberOfTargets = 2;
1861 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1862 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1863 //KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1864 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1865 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1866 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1867 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1868 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1869 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1870 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1871 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1872 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1873 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1874 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1875 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1876 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1877 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1879 srb->SrbStatus = SRB_STATUS_SUCCESS;
1880 StorPortNotification(RequestComplete, DeviceExtension, srb);
1881 break;
1882 case SRB_FUNCTION_SHUTDOWN:
1883 KdPrint((__DRIVER_NAME " SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1884 //ASSERT(IsListEmpty(&xvdd->srb_list));
1885 //ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
1886 XenVbd_PutSrbOnList(xvdd, srb);
1887 XenVbd_PutQueuedSrbsOnRing(xvdd);
1888 //srb->SrbStatus = SRB_STATUS_SUCCESS;
1889 //StorPortNotification(RequestComplete, DeviceExtension, srb);
1890 break;
1891 case SRB_FUNCTION_RESET_BUS:
1892 case SRB_FUNCTION_RESET_DEVICE:
1893 case SRB_FUNCTION_RESET_LOGICAL_UNIT:
1894 /* the path doesn't matter here - only ever one device*/
1895 XenVbd_HwStorResetBus(DeviceExtension, 0);
1896 srb->SrbStatus = SRB_STATUS_SUCCESS;
1897 StorPortNotification(RequestComplete, DeviceExtension, srb);
1898 break;
1900 default:
1901 KdPrint((__DRIVER_NAME " Unhandled srb->Function = %08X\n", srb->Function));
1902 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1903 StorPortNotification(RequestComplete, DeviceExtension, srb);
1904 break;
1907 //if (dump_mode) FUNCTION_EXIT();
1908 StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
1909 return TRUE;
1912 static SCSI_ADAPTER_CONTROL_STATUS
1913 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
1915 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1916 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
1917 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
1918 //KIRQL OldIrql;
1920 FUNCTION_ENTER();
1921 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1922 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
1924 switch (ControlType)
1926 case ScsiQuerySupportedControlTypes:
1927 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
1928 KdPrint((__DRIVER_NAME " ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
1929 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
1930 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
1931 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
1932 break;
1933 case ScsiStopAdapter:
1934 KdPrint((__DRIVER_NAME " ScsiStopAdapter\n"));
1935 if (xvdd->inactive)
1937 KdPrint((__DRIVER_NAME " inactive - nothing to do\n"));
1938 break;
1940 ASSERT(IsListEmpty(&xvdd->srb_list));
1941 ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
1942 break;
1943 case ScsiRestartAdapter:
1944 KdPrint((__DRIVER_NAME " ScsiRestartAdapter\n"));
1945 if (xvdd->inactive)
1947 KdPrint((__DRIVER_NAME " inactive - nothing to do\n"));
1948 break;
1950 /* increase the tag every time we stop/start to track where the gref's came from */
1951 xvdd->grant_tag++;
1952 if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND)
1953 KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
1954 xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
1956 //XenVbd_StartRingDetection(xvdd);
1957 break;
1958 case ScsiSetBootConfig:
1959 KdPrint((__DRIVER_NAME " ScsiSetBootConfig\n"));
1960 break;
1961 case ScsiSetRunningConfig:
1962 KdPrint((__DRIVER_NAME " ScsiSetRunningConfig\n"));
1963 break;
1964 default:
1965 KdPrint((__DRIVER_NAME " UNKNOWN\n"));
1966 break;
1969 FUNCTION_EXIT();
1971 return Status;
1974 NTSTATUS
1975 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
1977 ULONG status;
1978 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
1979 HW_INITIALIZATION_DATA HwInitializationData;
1980 OBJECT_ATTRIBUTES oa;
1981 HANDLE service_handle;
1982 UNICODE_STRING param_name;
1983 HANDLE param_handle;
1984 UNICODE_STRING value_name;
1985 CHAR buf[256];
1986 ULONG buf_len;
1987 PKEY_VALUE_PARTIAL_INFORMATION kpv;
1989 FUNCTION_ENTER();
1990 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1991 KdPrint((__DRIVER_NAME " DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
1993 /* RegistryPath == NULL when we are invoked as a crash dump driver */
1994 if (!RegistryPath)
1996 dump_mode = TRUE;
1999 if (!dump_mode)
2001 InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
2002 status = ZwOpenKey(&service_handle, KEY_READ, &oa);
2003 if(!NT_SUCCESS(status))
2005 KdPrint((__DRIVER_NAME " ZwOpenKey(Service) returned %08x\n", status));
2007 else
2009 RtlInitUnicodeString(&param_name, L"Parameters");
2010 InitializeObjectAttributes(&oa, &param_name, OBJ_CASE_INSENSITIVE, service_handle, NULL);
2011 status = ZwOpenKey(&param_handle, KEY_READ, &oa);
2012 if(!NT_SUCCESS(status))
2014 KdPrint((__DRIVER_NAME " ZwOpenKey(Parameters) returned %08x\n", status));
2016 else
2018 kpv = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
2019 RtlFillMemory(scsi_device_manufacturer, 8, ' ');
2020 RtlFillMemory(scsi_disk_model, 16, ' ');
2021 RtlFillMemory(scsi_cdrom_model, 16, ' ');
2023 RtlInitUnicodeString(&value_name, L"Manufacturer");
2024 buf_len = 256;
2025 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
2026 if(NT_SUCCESS(status))
2027 wcstombs(scsi_device_manufacturer, (PWCHAR)kpv->Data, min(kpv->DataLength, 8));
2028 else
2029 RtlStringCbCopyA(scsi_device_manufacturer, 8, "XEN ");
2031 RtlInitUnicodeString(&value_name, L"Disk_Model");
2032 buf_len = 256;
2033 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
2034 if(NT_SUCCESS(status))
2035 wcstombs(scsi_disk_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
2036 else
2037 RtlStringCbCopyA(scsi_disk_model, 16, "PV DISK ");
2039 RtlInitUnicodeString(&value_name, L"CDROM_Model");
2040 buf_len = 256;
2041 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
2042 if(NT_SUCCESS(status))
2043 wcstombs(scsi_cdrom_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
2044 else
2045 RtlStringCbCopyA(scsi_cdrom_model, 16, "PV CDROM ");
2046 ZwClose(param_handle);
2048 ZwClose(service_handle);
2050 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
2051 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
2052 VHwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* maybe should be internal? */
2053 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
2054 VHwInitializationData.SpecificLuExtensionSize = 0;
2055 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
2056 VHwInitializationData.NumberOfAccessRanges = 1;
2057 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
2058 //VHwInitializationData.NeedPhysicalAddresses = TRUE;
2059 VHwInitializationData.TaggedQueuing = TRUE;
2060 VHwInitializationData.AutoRequestSense = TRUE;
2061 VHwInitializationData.MultipleRequestPerLu = TRUE;
2062 VHwInitializationData.ReceiveEvent = TRUE;
2063 VHwInitializationData.PortVersionFlags = 0;
2064 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
2065 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
2066 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
2067 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
2068 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
2069 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
2071 else
2073 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
2074 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
2075 HwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* not Internal */
2076 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
2077 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
2078 HwInitializationData.NumberOfAccessRanges = 1;
2079 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
2080 HwInitializationData.NeedPhysicalAddresses = TRUE;
2081 HwInitializationData.TaggedQueuing = FALSE;
2082 HwInitializationData.AutoRequestSense = TRUE;
2083 HwInitializationData.MultipleRequestPerLu = FALSE;
2084 HwInitializationData.ReceiveEvent = TRUE;
2085 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
2086 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
2087 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
2088 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
2089 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
2090 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
2091 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
2094 if(!NT_SUCCESS(status))
2096 KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", status));
2099 FUNCTION_EXIT();
2101 return status;