win-pvdrivers

view xenvbd/xenvbd_storport.c @ 991:e9903455ba9d

Fix low gref resource handling. again.
Tidy up.
author James Harper <james.harper@bendigoit.com.au>
date Fri Sep 21 23:25:36 2012 +1000 (2012-09-21)
parents d9da5f8f7431
children c454b24f92b8
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 /* called with StartIoLock held */
55 static blkif_shadow_t *
56 get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
57 {
58 if (xvdd->shadow_free == 0) {
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 /* called with StartIoLock held */
69 static VOID
70 put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
71 {
72 xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)(shadow->req.id & SHADOW_ID_ID_MASK);
73 shadow->srb = NULL;
74 shadow->reset = FALSE;
75 shadow->aligned_buffer_in_use = FALSE;
76 xvdd->shadow_free++;
77 }
79 static blkif_response_t *
80 XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i)
81 {
82 blkif_other_response_t *rep;
83 if (!xvdd->use_other)
84 return RING_GET_RESPONSE(&xvdd->ring, i);
85 rep = RING_GET_RESPONSE(&xvdd->other_ring, i);
86 xvdd->tmp_rep.id = rep->id;
87 xvdd->tmp_rep.operation = rep->operation;
88 xvdd->tmp_rep.status = rep->status;
89 return &xvdd->tmp_rep;
90 }
92 static VOID
93 XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
94 {
95 blkif_other_request_t *other_req;
97 if (!xvdd->use_other)
98 {
99 *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
100 }
101 else
102 {
103 other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
104 other_req->operation = req->operation;
105 other_req->nr_segments = req->nr_segments;
106 other_req->handle = req->handle;
107 other_req->id = req->id;
108 other_req->sector_number = req->sector_number;
109 memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
110 }
111 xvdd->ring.req_prod_pvt++;
112 }
114 static ULONG
115 XenVbd_InitConfig(PXENVBD_DEVICE_DATA xvdd)
116 {
117 ULONG status;
118 PUCHAR ptr;
119 USHORT type;
120 PCHAR setting, value, value2;
122 FUNCTION_ENTER();
123 /* first read the default config items */
124 ptr = xvdd->device_base;
125 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
126 {
127 switch(type)
128 {
129 case XEN_INIT_TYPE_VECTORS:
130 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
131 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
132 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
133 {
134 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
135 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
136 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
137 return SP_RETURN_BAD_CONFIG;
138 }
139 else
140 memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
141 break;
142 default:
143 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
144 break;
145 }
146 }
148 /* then set up all the configuration requests */
149 ptr = xvdd->device_base;
150 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
151 #pragma warning(suppress:4054)
152 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenVbd_HandleEvent, xvdd);
153 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL, NULL);
154 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
155 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
156 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
157 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
158 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialised);
159 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
160 __ADD_XEN_INIT_UCHAR(&ptr, 20);
161 __ADD_XEN_INIT_UCHAR(&ptr, 0);
162 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
163 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
164 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
165 __ADD_XEN_INIT_UCHAR(&ptr, 20);
166 __ADD_XEN_INIT_UCHAR(&ptr, 0);
167 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
168 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
169 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
170 __ADD_XEN_INIT_UCHAR(&ptr, 50);
171 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
172 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
173 __ADD_XEN_INIT_UCHAR(&ptr, 50);
174 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
175 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
176 __ADD_XEN_INIT_UCHAR(&ptr, 50);
177 __ADD_XEN_INIT_UCHAR(&ptr, 0);
178 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
180 /* then configure */
181 status = xvdd->vectors.XenPci_XenConfigDevice(xvdd->vectors.context);
182 if (!NT_SUCCESS(status))
183 {
184 xvdd->inactive = TRUE;
185 KdPrint(("Failed to complete device configuration (%08x)\n", status));
186 FUNCTION_EXIT();
187 return SP_RETURN_BAD_CONFIG;
188 }
189 FUNCTION_EXIT();
190 return SP_RETURN_FOUND;
191 }
193 static ULONG
194 XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
195 {
196 ULONG i;
197 PUCHAR ptr;
198 USHORT type;
199 PCHAR setting, value, value2;
200 ULONG qemu_protocol_version = 0;
201 BOOLEAN qemu_hide_filter = FALSE;
202 ULONG qemu_hide_flags_value = 0;
204 FUNCTION_ENTER();
206 xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
207 xvdd->sring = NULL;
208 xvdd->event_channel = 0;
210 xvdd->inactive = TRUE;
212 ptr = xvdd->device_base;
213 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
214 {
215 switch(type)
216 {
217 case XEN_INIT_TYPE_VECTORS:
218 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
219 if (dump_mode)
220 {
221 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
222 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
223 {
224 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
225 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
226 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
227 return SP_RETURN_BAD_CONFIG;
228 }
229 else
230 memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
231 }
232 break;
233 case XEN_INIT_TYPE_RING: /* frontend ring */
234 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
235 if (strcmp(setting, "ring-ref") == 0)
236 {
237 xvdd->sring = (blkif_sring_t *)value;
238 FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
239 /* this bit is for when we have to take over an existing ring on a crash dump */
240 xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
241 xvdd->ring.rsp_cons = xvdd->ring.req_prod_pvt;
242 }
243 break;
244 case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
245 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d (%08x)\n", setting, PtrToUlong(value) & 0x3FFFFFFF, PtrToUlong(value)));
246 if (strcmp(setting, "event-channel") == 0)
247 {
248 /* cheat here - save the state of the ring in the topmost bits of the event-channel */
249 xvdd->event_channel_ptr = (ULONG *)(((PCHAR)ptr) - sizeof(ULONG));
250 xvdd->event_channel = PtrToUlong(value) & 0x3FFFFFFF;
251 if (PtrToUlong(value) & 0x80000000)
252 {
253 xvdd->cached_use_other = (BOOLEAN)!!(PtrToUlong(value) & 0x40000000);
254 KdPrint((__DRIVER_NAME " cached_use_other = %d\n", xvdd->cached_use_other));
255 }
256 }
257 break;
258 case XEN_INIT_TYPE_READ_STRING_BACK:
259 case XEN_INIT_TYPE_READ_STRING_FRONT:
260 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
261 if (strcmp(setting, "sectors") == 0)
262 xvdd->total_sectors = parse_numeric_string(value);
263 else if (strcmp(setting, "sector-size") == 0)
264 xvdd->hw_bytes_per_sector = (ULONG)parse_numeric_string(value);
265 else if (strcmp(setting, "device-type") == 0)
266 {
267 if (strcmp(value, "disk") == 0)
268 {
269 KdPrint((__DRIVER_NAME " device-type = Disk\n"));
270 xvdd->device_type = XENVBD_DEVICETYPE_DISK;
271 }
272 else if (strcmp(value, "cdrom") == 0)
273 {
274 KdPrint((__DRIVER_NAME " device-type = CDROM\n"));
275 xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
276 }
277 else
278 {
279 KdPrint((__DRIVER_NAME " device-type = %s (This probably won't work!)\n", value));
280 xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
281 }
282 }
283 else if (strcmp(setting, "mode") == 0)
284 {
285 if (strncmp(value, "r", 1) == 0)
286 {
287 KdPrint((__DRIVER_NAME " mode = r\n"));
288 xvdd->device_mode = XENVBD_DEVICEMODE_READ;
289 }
290 else if (strncmp(value, "w", 1) == 0)
291 {
292 KdPrint((__DRIVER_NAME " mode = w\n"));
293 xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
294 }
295 else
296 {
297 KdPrint((__DRIVER_NAME " mode = unknown\n"));
298 xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
299 }
300 }
301 break;
302 case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
303 qemu_protocol_version = PtrToUlong(value);
304 break;
305 case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
306 qemu_hide_flags_value = PtrToUlong(value);
307 KdPrint((__DRIVER_NAME " qemu_hide_flags_value = %d\n", qemu_hide_flags_value));
308 break;
309 case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
310 qemu_hide_filter = TRUE;
311 KdPrint((__DRIVER_NAME " qemu_hide_filter = TRUE\n"));
312 break;
313 case XEN_INIT_TYPE_STATE_PTR:
314 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
315 xvdd->device_state = (PXENPCI_DEVICE_STATE)value;
316 break;
317 default:
318 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
319 break;
320 }
321 }
323 if (((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) && xvdd->device_type != XENVBD_DEVICETYPE_CDROM) || qemu_hide_filter)
324 xvdd->inactive = FALSE;
326 if (!xvdd->inactive && (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
327 || xvdd->sring == NULL
328 || xvdd->event_channel == 0
329 || xvdd->total_sectors == 0
330 || xvdd->hw_bytes_per_sector == 0))
331 {
332 KdPrint((__DRIVER_NAME " Missing settings\n"));
333 FUNCTION_EXIT();
334 return SP_RETURN_BAD_CONFIG;
335 }
337 if (xvdd->inactive) {
338 KdPrint((__DRIVER_NAME " Device is inactive\n"));
339 } else {
340 if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM) {
341 /* CD/DVD drives must have bytes_per_sector = 2048. */
342 xvdd->bytes_per_sector = 2048;
343 xvdd->hw_bytes_per_sector = 2048;
344 } else {
345 xvdd->bytes_per_sector = 512;
346 }
347 /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
348 xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
350 xvdd->shadow_free = 0;
351 memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
352 for (i = 0; i < SHADOW_ENTRIES; i++) {
353 xvdd->shadows[i].req.id = i;
354 /* make sure leftover real requests's are never confused with dump mode requests */
355 if (dump_mode)
356 xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
357 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
358 }
359 }
361 FUNCTION_EXIT();
362 return SP_RETURN_FOUND;
363 }
365 static __inline ULONG
366 decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
367 {
368 switch (srb->Cdb[0])
369 {
370 case SCSIOP_READ:
371 case SCSIOP_WRITE:
372 return ((ULONG)(UCHAR)srb->Cdb[7] << 8) | (ULONG)(UCHAR)srb->Cdb[8];
373 case SCSIOP_READ16:
374 case SCSIOP_WRITE16:
375 return ((ULONG)(UCHAR)srb->Cdb[10] << 24) | ((ULONG)(UCHAR)srb->Cdb[11] << 16) | ((ULONG)(UCHAR)srb->Cdb[12] << 8) | (ULONG)(UCHAR)srb->Cdb[13];
376 default:
377 return 0;
378 }
379 }
381 static __inline ULONGLONG
382 decode_cdb_sector(PSCSI_REQUEST_BLOCK srb)
383 {
384 ULONGLONG sector;
386 switch (srb->Cdb[0])
387 {
388 case SCSIOP_READ:
389 case SCSIOP_WRITE:
390 sector = ((ULONG)(UCHAR)srb->Cdb[2] << 24) | ((ULONG)(UCHAR)srb->Cdb[3] << 16) | ((ULONG)(UCHAR)srb->Cdb[4] << 8) | (ULONG)(UCHAR)srb->Cdb[5];
391 break;
392 case SCSIOP_READ16:
393 case SCSIOP_WRITE16:
394 sector = ((ULONGLONG)(UCHAR)srb->Cdb[2] << 56) | ((ULONGLONG)(UCHAR)srb->Cdb[3] << 48)
395 | ((ULONGLONG)(UCHAR)srb->Cdb[4] << 40) | ((ULONGLONG)(UCHAR)srb->Cdb[5] << 32)
396 | ((ULONGLONG)(UCHAR)srb->Cdb[6] << 24) | ((ULONGLONG)(UCHAR)srb->Cdb[7] << 16)
397 | ((ULONGLONG)(UCHAR)srb->Cdb[8] << 8) | ((ULONGLONG)(UCHAR)srb->Cdb[9]);
398 //KdPrint((__DRIVER_NAME " sector_number = %d (high) %d (low)\n", (ULONG)(sector >> 32), (ULONG)sector));
399 break;
400 default:
401 sector = 0;
402 break;
403 }
404 return sector;
405 }
407 static __inline BOOLEAN
408 decode_cdb_is_read(PSCSI_REQUEST_BLOCK srb)
409 {
410 switch (srb->Cdb[0])
411 {
412 case SCSIOP_READ:
413 case SCSIOP_READ16:
414 return TRUE;
415 case SCSIOP_WRITE:
416 case SCSIOP_WRITE16:
417 return FALSE;
418 default:
419 return FALSE;
420 }
421 }
423 static VOID
424 XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
425 {
426 srb_list_entry_t *srb_entry = srb->SrbExtension;
427 srb_entry->srb = srb;
428 if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI)
429 {
430 srb_entry->outstanding_requests = 0;
431 srb_entry->length = srb->DataTransferLength;
432 srb_entry->offset = 0;
433 srb_entry->error = FALSE;
434 }
435 InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
436 }
438 /* called with StartIoLock held */
439 static VOID
440 XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVICE_DATA xvdd)
441 {
442 PSCSI_REQUEST_BLOCK srb;
443 srb_list_entry_t *srb_entry;
444 /* sector_number and block_count are the adjusted-to-512-byte-sector values */
445 ULONGLONG sector_number;
446 ULONG block_count;
447 blkif_shadow_t *shadow;
448 ULONG remaining, offset, length;
449 grant_ref_t gref;
450 PUCHAR ptr;
451 int notify;
452 int i;
453 PVOID system_address;
454 BOOLEAN failed;
456 //if (dump_mode) FUNCTION_ENTER();
458 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)
459 {
460 srb = srb_entry->srb;
461 NT_ASSERT(srb);
462 if (srb->Function != SRB_FUNCTION_EXECUTE_SCSI) {
463 KdPrint((__DRIVER_NAME " SRB_FUNCTION_%02x retrieved from ring\n", srb->Function));
464 if (xvdd->shadow_free != SHADOW_ENTRIES) {
465 KdPrint((__DRIVER_NAME " busy\n"));
466 /* put it back at the end of the list just in case something is queued that needs to be processed */
467 InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
468 break; /* stall the queue until it's all empty */
469 }
470 else
471 {
472 KdPrint((__DRIVER_NAME " completing\n"));
473 srb->SrbStatus = SRB_STATUS_SUCCESS;
474 StorPortNotification(RequestComplete, xvdd, srb);
475 continue;
476 }
477 }
479 if (!dump_mode) {
480 if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS) {
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 } else {
488 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
489 system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
490 }
491 block_count = decode_cdb_length(srb);
492 sector_number = decode_cdb_sector(srb);
493 block_count *= xvdd->bytes_per_sector / 512;
494 sector_number *= xvdd->bytes_per_sector / 512;
496 NT_ASSERT(block_count * 512 == srb->DataTransferLength);
498 sector_number += srb_entry->offset / 512;
499 block_count -= srb_entry->offset / 512;
501 NT_ASSERT(block_count > 0);
503 /* look for pending writes that overlap this one */
504 /* we get warnings from drbd if we don't */
505 if (srb_entry->offset == 0) {
506 for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
507 PSCSI_REQUEST_BLOCK srb2;
508 ULONGLONG sector_number2;
509 ULONG block_count2;
511 srb2 = xvdd->shadows[i].srb;
512 if (!srb2)
513 continue;
514 if (decode_cdb_is_read(srb2))
515 continue;
516 block_count2 = decode_cdb_length(srb2);;
517 block_count2 *= xvdd->bytes_per_sector / 512;
518 sector_number2 = decode_cdb_sector(srb2);
519 sector_number2 *= xvdd->bytes_per_sector / 512;
521 if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
522 continue;
523 if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
524 continue;
526 KdPrint((__DRIVER_NAME " Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
527 sector_number, block_count, sector_number2, block_count2));
528 /* put the srb back at the start of the queue */
529 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
530 break; /* stall the queue */
531 }
532 if (i != MAX_SHADOW_ENTRIES) {
533 break; /* stall the queue but submit any outstanding requests */
534 }
535 }
537 shadow = get_shadow_from_freelist(xvdd);
538 if (!shadow) {
539 /* put the srb back at the start of the queue */
540 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
541 break; /* stall the queue but submit any outstanding requests */
542 }
543 NT_ASSERT(!shadow->aligned_buffer_in_use);
544 NT_ASSERT(!shadow->srb);
545 shadow->req.sector_number = sector_number;
546 shadow->req.handle = 0;
547 shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
548 shadow->req.nr_segments = 0;
549 shadow->srb = srb;
550 shadow->length = 0;
551 shadow->system_address = system_address;
552 shadow->reset = FALSE;
554 if (!dump_mode) {
555 if ((ULONG_PTR)shadow->system_address & 511) {
556 xvdd->aligned_buffer_in_use = TRUE;
557 /* limit to aligned_buffer_size */
558 block_count = min(block_count, xvdd->aligned_buffer_size / 512);
559 ptr = (PUCHAR)xvdd->aligned_buffer;
560 if (!decode_cdb_is_read(srb))
561 memcpy(ptr, shadow->system_address, block_count * 512);
562 shadow->aligned_buffer_in_use = TRUE;
563 } else {
564 ptr = (PUCHAR)shadow->system_address;
565 shadow->aligned_buffer_in_use = FALSE;
566 }
567 } else {
568 NT_ASSERT(!((ULONG_PTR)shadow->system_address & 511));
569 ptr = shadow->system_address;
570 shadow->aligned_buffer_in_use = FALSE;
571 }
573 //KdPrint((__DRIVER_NAME " sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
574 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
575 //KdPrint((__DRIVER_NAME " system_address = %p\n", shadow->system_address));
576 //KdPrint((__DRIVER_NAME " offset = %d, length = %d\n", srb_entry->offset, srb_entry->length));
577 //KdPrint((__DRIVER_NAME " ptr = %p\n", ptr));
579 //KdPrint((__DRIVER_NAME " handle = %d\n", shadow->req.handle));
580 //KdPrint((__DRIVER_NAME " operation = %d\n", shadow->req.operation));
582 remaining = block_count * 512;
583 failed = FALSE;
584 while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST) {
585 PHYSICAL_ADDRESS physical_address;
587 if (!dump_mode) {
588 physical_address = MmGetPhysicalAddress(ptr);
589 } else {
590 ULONG length;
591 physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
592 }
593 gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context,
594 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
595 if (gref == INVALID_GRANT_REF) {
596 ULONG i;
597 for (i = 0; i < shadow->req.nr_segments; i++) {
598 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
599 shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
600 }
601 if (shadow->aligned_buffer_in_use) {
602 shadow->aligned_buffer_in_use = FALSE;
603 xvdd->aligned_buffer_in_use = FALSE;
604 }
605 /* put the srb back at the start of the queue */
606 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
607 put_shadow_on_freelist(xvdd, shadow);
608 KdPrint((__DRIVER_NAME " Out of gref's. Deferring\n"));
609 failed = TRUE;
610 /* what if there are no requests currently in progress to kick the queue again?? */
611 break; /* stall the queue but submit any outstanding requests */
612 }
613 offset = physical_address.LowPart & (PAGE_SIZE - 1);
614 length = min(PAGE_SIZE - offset, remaining);
615 NT_ASSERT((offset & 511) == 0);
616 NT_ASSERT((length & 511) == 0);
617 NT_ASSERT(offset + length <= PAGE_SIZE);
618 shadow->req.seg[shadow->req.nr_segments].gref = gref;
619 shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
620 shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
621 remaining -= length;
622 ptr += length;
623 shadow->length += length;
624 shadow->req.nr_segments++;
625 }
626 if (failed)
627 break;
628 srb_entry->offset += shadow->length;
629 srb_entry->outstanding_requests++;
630 if (srb_entry->offset < srb_entry->length) {
631 if (dump_mode) KdPrint((__DRIVER_NAME " inserting back into list\n"));
632 /* put the srb back at the start of the queue to continue on the next request */
633 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
634 }
635 XenVbd_PutRequest(xvdd, &shadow->req);
636 }
637 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
638 if (notify) {
639 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
640 }
641 }
643 static ULONG
644 XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
645 {
646 // PACCESS_RANGE AccessRange;
647 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
648 ULONG status;
649 // PXENPCI_XEN_DEVICE_DATA XenDeviceData;
650 PACCESS_RANGE access_range;
652 UNREFERENCED_PARAMETER(HwContext);
653 UNREFERENCED_PARAMETER(BusInformation);
654 UNREFERENCED_PARAMETER(LowerDevice);
655 UNREFERENCED_PARAMETER(ArgumentString);
657 FUNCTION_ENTER();
658 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
659 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
661 RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
662 *Again = FALSE;
664 KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
665 KdPrint((__DRIVER_NAME " BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
667 if (!dump_mode)
668 {
669 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
670 if (ConfigInfo->NumberOfAccessRanges != 1 && ConfigInfo->NumberOfAccessRanges != 2)
671 {
672 return SP_RETURN_BAD_CONFIG;
673 }
675 access_range = &((*(ConfigInfo->AccessRanges))[0]);
676 KdPrint((__DRIVER_NAME " RangeStart = %08x, RangeLength = %08x\n",
677 access_range->RangeStart.LowPart, access_range->RangeLength));
678 xvdd->device_base = StorPortGetDeviceBase(
679 DeviceExtension,
680 PNPBus, //AdapterInterfaceType,
681 ConfigInfo->SystemIoBusNumber,
682 access_range->RangeStart,
683 access_range->RangeLength,
684 !access_range->RangeInMemory);
685 if (!xvdd->device_base)
686 {
687 KdPrint((__DRIVER_NAME " StorPortGetDeviceBase failed\n"));
688 FUNCTION_EXIT();
689 return SP_RETURN_BAD_CONFIG;
690 }
691 status = XenVbd_InitConfig(xvdd);
692 if (status != SP_RETURN_FOUND)
693 {
694 /* set inactive here so StartIo is harmless - we still get called with a PNP remove (or similar) */
695 xvdd->inactive = TRUE;
696 FUNCTION_EXIT();
697 return status;
698 }
699 xvdd->grant_tag = (ULONG)'VBD0';
700 }
701 else
702 {
703 xvdd->device_base = ConfigInfo->Reserved;
704 xvdd->grant_tag = (ULONG)'DUMP';
705 }
707 xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
708 status = XenVbd_InitFromConfig(xvdd);
709 if (status != SP_RETURN_FOUND)
710 {
711 /* set inactive here so StartIo is harmless - we still get called with a PNP remove (or similar) */
712 xvdd->inactive = TRUE;
713 FUNCTION_EXIT();
714 return status;
715 }
717 xvdd->aligned_buffer_in_use = FALSE;
718 /* align the buffer to PAGE_SIZE */
719 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
720 KdPrint((__DRIVER_NAME " aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
721 KdPrint((__DRIVER_NAME " aligned_buffer = %p\n", xvdd->aligned_buffer));
723 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
724 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
725 KdPrint((__DRIVER_NAME " ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength));
726 KdPrint((__DRIVER_NAME " ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
727 if (!dump_mode)
728 {
729 ConfigInfo->VirtualDevice = TRUE;
730 xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
731 }
732 else
733 {
734 ConfigInfo->VirtualDevice = FALSE;
735 xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
736 }
738 KdPrint((__DRIVER_NAME " ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice));
739 ConfigInfo->ScatterGather = TRUE;
740 ConfigInfo->Master = TRUE;
741 ConfigInfo->CachesData = FALSE;
742 ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
743 KdPrint((__DRIVER_NAME " ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses));
744 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
745 ConfigInfo->AlignmentMask = 0;
746 ConfigInfo->NumberOfBuses = 1;
747 ConfigInfo->InitiatorBusId[0] = 1;
748 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
749 ConfigInfo->MaximumNumberOfTargets = 2;
750 //ConfigInfo->BufferAccessScsiPortControlled = FALSE;
751 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
752 {
753 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
754 //ConfigInfo->Dma32BitAddresses = FALSE;
755 KdPrint((__DRIVER_NAME " Dma64BitAddresses supported\n"));
756 }
757 else
758 {
759 //ConfigInfo->Dma32BitAddresses = TRUE;
760 KdPrint((__DRIVER_NAME " Dma64BitAddresses not supported\n"));
761 }
763 FUNCTION_EXIT();
765 return SP_RETURN_FOUND;
766 }
768 static ULONG
769 XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
770 {
771 ULONG status;
773 FUNCTION_ENTER();
774 status = XenVbd_VirtualHwStorFindAdapter(DeviceExtension, HwContext, BusInformation, NULL, ArgumentString, ConfigInfo, Again);
775 FUNCTION_EXIT();
776 return status;
777 }
779 //do this in StartIo instead to prevent races with the driver initialisation
780 static VOID
781 XenVbd_StartRingDetection(PXENVBD_DEVICE_DATA xvdd)
782 {
783 blkif_request_t *req;
784 int notify;
786 xvdd->ring_detect_state = RING_DETECT_STATE_DETECT1;
787 RtlZeroMemory(xvdd->sring->ring, PAGE_SIZE - FIELD_OFFSET(blkif_sring_t, ring));
788 req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
789 req->operation = 0xff;
790 xvdd->ring.req_prod_pvt++;
791 req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
792 req->operation = 0xff;
793 xvdd->ring.req_prod_pvt++;
795 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
796 if (notify)
797 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
798 }
800 static BOOLEAN
801 XenVbd_HwStorInitialize(PVOID DeviceExtension)
802 {
803 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
805 FUNCTION_ENTER();
806 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
807 KdPrint((__DRIVER_NAME " dump_mode = %d\n", dump_mode));
809 if (!xvdd->inactive)
810 {
811 if (dump_mode)
812 {
813 if (xvdd->cached_use_other)
814 {
815 xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
816 xvdd->use_other = TRUE;
817 }
818 xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
819 }
820 InitializeListHead(&xvdd->srb_list);
821 }
822 FUNCTION_EXIT();
824 return TRUE;
825 }
827 static ULONG
828 XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
829 {
830 PMODE_PARAMETER_HEADER parameter_header = NULL;
831 PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
832 PMODE_PARAMETER_BLOCK param_block;
833 PMODE_FORMAT_PAGE format_page;
834 ULONG offset = 0;
835 UCHAR buffer[1024];
836 BOOLEAN valid_page = FALSE;
837 BOOLEAN cdb_llbaa;
838 BOOLEAN cdb_dbd;
839 UCHAR cdb_page_code;
840 USHORT cdb_allocation_length;
842 UNREFERENCED_PARAMETER(xvdd);
844 RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
845 RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
846 offset = 0;
848 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
850 switch (srb->Cdb[0])
851 {
852 case SCSIOP_MODE_SENSE:
853 cdb_llbaa = FALSE;
854 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
855 cdb_page_code = srb->Cdb[2] & 0x3f;
856 cdb_allocation_length = srb->Cdb[4];
857 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
858 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
859 parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
860 parameter_header->MediumType = 0;
861 parameter_header->DeviceSpecificParameter = 0;
862 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
863 {
864 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
865 parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
866 }
867 offset += sizeof(MODE_PARAMETER_HEADER);
868 break;
869 case SCSIOP_MODE_SENSE10:
870 cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
871 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
872 cdb_page_code = srb->Cdb[2] & 0x3f;
873 cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
874 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE10 llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
875 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
876 parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
877 parameter_header10->MediumType = 0;
878 parameter_header10->DeviceSpecificParameter = 0;
879 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
880 {
881 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
882 parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
883 }
884 offset += sizeof(MODE_PARAMETER_HEADER10);
885 break;
886 default:
887 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
888 return FALSE;
889 }
891 if (!cdb_dbd)
892 {
893 param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
894 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
895 {
896 if (xvdd->total_sectors >> 32)
897 {
898 param_block->DensityCode = 0xff;
899 param_block->NumberOfBlocks[0] = 0xff;
900 param_block->NumberOfBlocks[1] = 0xff;
901 param_block->NumberOfBlocks[2] = 0xff;
902 }
903 else
904 {
905 param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
906 param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
907 param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
908 param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
909 }
910 param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
911 param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
912 param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
913 }
914 offset += sizeof(MODE_PARAMETER_BLOCK);
915 }
916 switch (srb->Cdb[0])
917 {
918 case SCSIOP_MODE_SENSE:
919 parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
920 break;
921 case SCSIOP_MODE_SENSE10:
922 parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);
923 parameter_header10->BlockDescriptorLength[1] = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER10));
924 break;
925 }
926 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_FORMAT_DEVICE || cdb_page_code == MODE_SENSE_RETURN_ALL))
927 {
928 valid_page = TRUE;
929 format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
930 format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
931 format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
932 /* 256 sectors per track */
933 format_page->SectorsPerTrack[0] = 0x01;
934 format_page->SectorsPerTrack[1] = 0x00;
935 /* xxx bytes per sector */
936 format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
937 format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
938 format_page->HardSectorFormating = TRUE;
939 format_page->SoftSectorFormating = TRUE;
940 offset += sizeof(MODE_FORMAT_PAGE);
941 }
942 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_CACHING || cdb_page_code == MODE_SENSE_RETURN_ALL))
943 {
944 PMODE_CACHING_PAGE caching_page;
945 valid_page = TRUE;
946 caching_page = (PMODE_CACHING_PAGE)&buffer[offset];
947 caching_page->PageCode = MODE_PAGE_CACHING;
948 caching_page->PageLength = sizeof(MODE_CACHING_PAGE) - FIELD_OFFSET(MODE_CACHING_PAGE, PageLength);
949 // caching_page-> // all zeros is just fine... maybe
950 offset += sizeof(MODE_CACHING_PAGE);
951 }
952 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_MEDIUM_TYPES || cdb_page_code == MODE_SENSE_RETURN_ALL))
953 {
954 PUCHAR medium_types_page;
955 valid_page = TRUE;
956 medium_types_page = &buffer[offset];
957 medium_types_page[0] = MODE_PAGE_MEDIUM_TYPES;
958 medium_types_page[1] = 0x06;
959 medium_types_page[2] = 0;
960 medium_types_page[3] = 0;
961 medium_types_page[4] = 0;
962 medium_types_page[5] = 0;
963 medium_types_page[6] = 0;
964 medium_types_page[7] = 0;
965 offset += 8;
966 }
967 switch (srb->Cdb[0])
968 {
969 case SCSIOP_MODE_SENSE:
970 parameter_header->ModeDataLength = (UCHAR)(offset - 1);
971 break;
972 case SCSIOP_MODE_SENSE10:
973 parameter_header10->ModeDataLength[0] = (UCHAR)((offset - 2) >> 8);
974 parameter_header10->ModeDataLength[1] = (UCHAR)(offset - 2);
975 break;
976 }
978 if (!valid_page && cdb_page_code != MODE_SENSE_RETURN_ALL)
979 {
980 srb->SrbStatus = SRB_STATUS_ERROR;
981 }
982 else if(offset < srb->DataTransferLength)
983 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
984 else
985 srb->SrbStatus = SRB_STATUS_SUCCESS;
986 srb->DataTransferLength = min(srb->DataTransferLength, offset);
987 srb->ScsiStatus = 0;
988 memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
990 //FUNCTION_EXIT();
992 return TRUE;
993 }
995 static ULONG
996 XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
997 {
998 PSENSE_DATA sd = srb->SenseInfoBuffer;
1000 UNREFERENCED_PARAMETER(xvdd);
1002 if (!srb->SenseInfoBuffer)
1003 return 0;
1005 sd->ErrorCode = 0x70;
1006 sd->Valid = 1;
1007 sd->SenseKey = sense_key;
1008 sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
1009 sd->AdditionalSenseCode = additional_sense_code;
1010 return sizeof(SENSE_DATA);
1013 static VOID
1014 XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
1016 if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
1017 return;
1018 XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
1019 srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
1022 static BOOLEAN
1023 XenVbd_HandleEventSynchronised(PVOID DeviceExtension, PVOID context)
1025 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
1026 PSCSI_REQUEST_BLOCK srb;
1027 RING_IDX i, rp;
1028 ULONG j;
1029 blkif_response_t *rep;
1030 //int block_count;
1031 int more_to_do = TRUE;
1032 blkif_shadow_t *shadow;
1033 ULONG suspend_resume_state_pdo;
1034 srb_list_entry_t *srb_entry;
1036 UNREFERENCED_PARAMETER(context);
1038 //if (dump_mode) FUNCTION_ENTER();
1040 suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
1041 KeMemoryBarrier();
1043 if (suspend_resume_state_pdo != xvdd->device_state->suspend_resume_state_fdo)
1045 //FUNCTION_ENTER();
1046 switch (suspend_resume_state_pdo)
1048 case SR_STATE_SUSPENDING:
1049 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_SUSPENDING\n"));
1050 break;
1051 case SR_STATE_RESUMING:
1052 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_RESUMING\n"));
1053 XenVbd_InitFromConfig(xvdd);
1054 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1055 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1056 break;
1057 case SR_STATE_RUNNING:
1058 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1059 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1060 xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED; /* could be running on different hardware */
1061 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1062 default:
1063 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1064 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1065 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1066 break;
1068 KeMemoryBarrier();
1071 if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
1073 return TRUE;
1076 while (more_to_do)
1078 rp = xvdd->ring.sring->rsp_prod;
1079 KeMemoryBarrier();
1080 for (i = xvdd->ring.rsp_cons; i != rp; i++)
1082 rep = XenVbd_GetResponse(xvdd, i);
1083 /*
1084 * This code is to automatically detect if the backend is using the same
1085 * bit width or a different bit width to us. Later versions of Xen do this
1086 * via a xenstore value, but not all. That 0x0fffffff (notice
1087 * that the msb is not actually set, so we don't have any problems with
1088 * sign extending) is to signify the last entry on the right, which is
1089 * different under 32 and 64 bits, and that is why we set it up there.
1091 * To do the detection, we put two initial entries on the ring, with an op
1092 * of 0xff (which is invalid). The first entry is mostly okay, but the
1093 * second will be grossly misaligned if the backend bit width is different,
1094 * and we detect this and switch frontend structures.
1095 */
1096 switch (xvdd->ring_detect_state)
1098 case RING_DETECT_STATE_NOT_STARTED:
1099 KdPrint((__DRIVER_NAME " premature IRQ\n"));
1100 break;
1101 case RING_DETECT_STATE_DETECT1:
1102 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));
1103 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));
1104 xvdd->ring_detect_state = RING_DETECT_STATE_DETECT2;
1105 break;
1106 case RING_DETECT_STATE_DETECT2:
1107 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));
1108 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));
1109 *xvdd->event_channel_ptr |= 0x80000000;
1110 if (rep->operation != 0xff)
1112 KdPrint((__DRIVER_NAME " switching to 'other' ring size\n"));
1113 xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
1114 xvdd->use_other = TRUE;
1115 *xvdd->event_channel_ptr |= 0x40000000;
1117 xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
1118 break;
1119 case RING_DETECT_STATE_COMPLETE:
1120 shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
1121 if (shadow->reset)
1123 KdPrint((__DRIVER_NAME " discarding reset shadow\n"));
1124 for (j = 0; j < shadow->req.nr_segments; j++)
1126 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1127 shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
1130 else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG))
1132 KdPrint((__DRIVER_NAME " discarding stale (non-dump-mode) shadow\n"));
1134 else
1136 srb = shadow->srb;
1137 NT_ASSERT(srb);
1138 srb_entry = srb->SrbExtension;
1139 NT_ASSERT(srb_entry);
1140 /* 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 */
1141 if (rep->status == BLKIF_RSP_OKAY || (dump_mode && dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
1142 srb->SrbStatus = SRB_STATUS_SUCCESS;
1143 else
1145 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
1146 if (decode_cdb_is_read(srb))
1147 KdPrint((__DRIVER_NAME " Operation = Read\n"));
1148 else
1149 KdPrint((__DRIVER_NAME " Operation = Write\n"));
1150 srb_entry->error = TRUE;
1152 if (shadow->aligned_buffer_in_use)
1154 NT_ASSERT(xvdd->aligned_buffer_in_use);
1155 xvdd->aligned_buffer_in_use = FALSE;
1156 if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
1157 memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
1159 for (j = 0; j < shadow->req.nr_segments; j++)
1161 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1162 shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
1164 srb_entry->outstanding_requests--;
1165 if (!srb_entry->outstanding_requests && srb_entry->offset == srb_entry->length)
1167 if (srb_entry->error)
1169 srb->SrbStatus = SRB_STATUS_ERROR;
1170 srb->ScsiStatus = 0x02;
1171 xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
1172 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1173 XenVbd_MakeAutoSense(xvdd, srb);
1175 StorPortNotification(RequestComplete, xvdd, srb);
1178 put_shadow_on_freelist(xvdd, shadow);
1179 break;
1183 xvdd->ring.rsp_cons = i;
1184 if (i != xvdd->ring.req_prod_pvt)
1186 RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
1188 else
1190 xvdd->ring.sring->rsp_event = i + 1;
1191 more_to_do = FALSE;
1195 XenVbd_PutQueuedSrbsOnRing(xvdd);
1197 if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
1199 if (xvdd->inactive || xvdd->shadow_free == SHADOW_ENTRIES)
1201 /* all entries are purged from the list (or we are inactive). ready to suspend */
1202 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1203 KeMemoryBarrier();
1204 KdPrint((__DRIVER_NAME " Set fdo state SR_STATE_SUSPENDING\n"));
1205 KdPrint((__DRIVER_NAME " Notifying event channel %d\n", xvdd->device_state->pdo_event_channel));
1206 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1209 //if (dump_mode) FUNCTION_EXIT();
1211 return TRUE;
1214 static BOOLEAN
1215 XenVbd_HandleEvent(PVOID DeviceExtension)
1217 BOOLEAN retval;
1218 STOR_LOCK_HANDLE lock_handle;
1220 //if (dump_mode) FUNCTION_ENTER();
1221 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
1222 retval = StorPortSynchronizeAccess(DeviceExtension, XenVbd_HandleEventSynchronised, NULL);
1223 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1224 //if (dump_mode) FUNCTION_EXIT();
1225 return retval;
1228 /* this is only used during hiber and dump */
1229 static BOOLEAN
1230 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
1232 BOOLEAN retval;
1234 //FUNCTION_ENTER();
1235 retval = XenVbd_HandleEventSynchronised(DeviceExtension, NULL);
1236 //FUNCTION_EXIT();
1237 return retval;
1240 static BOOLEAN
1241 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
1243 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1244 //srb_list_entry_t *srb_entry;
1245 int i;
1246 /* need to make sure that each SRB is only reset once */
1247 LIST_ENTRY srb_reset_list;
1248 PLIST_ENTRY list_entry;
1249 //STOR_LOCK_HANDLE lock_handle;
1251 UNREFERENCED_PARAMETER(PathId);
1253 FUNCTION_ENTER();
1255 /* It appears that the StartIo spinlock is already held at this point */
1257 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1259 if (xvdd->ring_detect_state == RING_DETECT_STATE_COMPLETE && xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
1261 xvdd->aligned_buffer_in_use = FALSE;
1263 InitializeListHead(&srb_reset_list);
1265 while((list_entry = RemoveHeadList(&xvdd->srb_list)) != &xvdd->srb_list)
1267 #if DBG
1268 srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
1269 KdPrint((__DRIVER_NAME " adding queued SRB %p to reset list\n", srb_entry->srb));
1270 #endif
1271 InsertTailList(&srb_reset_list, list_entry);
1274 for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
1276 if (xvdd->shadows[i].srb)
1278 srb_list_entry_t *srb_entry = xvdd->shadows[i].srb->SrbExtension;
1279 for (list_entry = srb_reset_list.Flink; list_entry != &srb_reset_list; list_entry = list_entry->Flink)
1281 if (list_entry == &srb_entry->list_entry)
1282 break;
1284 if (list_entry == &srb_reset_list)
1286 KdPrint((__DRIVER_NAME " adding in-flight SRB %p to reset list\n", srb_entry->srb));
1287 InsertTailList(&srb_reset_list, &srb_entry->list_entry);
1289 /* set reset here so that the interrupt won't do anything with the srb but will dispose of the shadow entry correctly */
1290 xvdd->shadows[i].reset = TRUE;
1291 xvdd->shadows[i].srb = NULL;
1292 xvdd->shadows[i].aligned_buffer_in_use = FALSE;
1296 while((list_entry = RemoveHeadList(&srb_reset_list)) != &srb_reset_list)
1298 srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
1299 srb_entry->srb->SrbStatus = SRB_STATUS_BUS_RESET;
1300 KdPrint((__DRIVER_NAME " completing SRB %p with status SRB_STATUS_BUS_RESET\n", srb_entry->srb));
1301 StorPortNotification(RequestComplete, xvdd, srb_entry->srb);
1304 /* send a notify to Dom0 just in case it was missed for some reason (which should _never_ happen) */
1305 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
1307 StorPortNotification(NextRequest, DeviceExtension);
1310 //StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
1312 FUNCTION_EXIT();
1314 return TRUE;
1317 static BOOLEAN
1318 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
1320 PUCHAR data_buffer;
1321 PSCSI_PNP_REQUEST_BLOCK sprb;
1322 PSCSI_POWER_REQUEST_BLOCK spwrb;
1323 PMINIPORT_DUMP_POINTERS dump_pointers;
1324 PCDB cdb;
1325 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1326 ULONG data_transfer_length;
1327 UCHAR srb_status = SRB_STATUS_PENDING;
1328 STOR_LOCK_HANDLE lock_handle;
1330 //if (dump_mode) FUNCTION_ENTER();
1331 //if (dump_mode) KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1333 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
1335 data_transfer_length = srb->DataTransferLength;
1337 if (xvdd->inactive)
1339 KdPrint((__DRIVER_NAME " Inactive srb->Function = %08X\n", srb->Function));
1340 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1341 StorPortNotification(RequestComplete, DeviceExtension, srb);
1342 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1343 return TRUE;
1346 if (xvdd->ring_detect_state == RING_DETECT_STATE_NOT_STARTED)
1348 XenVbd_StartRingDetection(DeviceExtension);
1351 // If we haven't enumerated all the devices yet then just defer the request
1352 if (xvdd->ring_detect_state < RING_DETECT_STATE_COMPLETE)
1354 srb->SrbStatus = SRB_STATUS_BUSY;
1355 StorPortNotification(RequestComplete, DeviceExtension, srb);
1356 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Still figuring out ring)\n"));
1357 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1358 return TRUE;
1361 if (!dump_mode && xvdd->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
1363 //KdPrint((__DRIVER_NAME " --> HwStorStartIo (Suspending/Resuming)\n"));
1364 srb->SrbStatus = SRB_STATUS_BUSY;
1365 StorPortNotification(RequestComplete, DeviceExtension, srb);
1366 //KdPrint((__DRIVER_NAME " <-- HwStorStartIo (Suspending/Resuming)\n"));
1367 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1368 return TRUE;
1371 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
1373 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1374 StorPortNotification(RequestComplete, DeviceExtension, srb);
1375 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun));
1376 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1377 return TRUE;
1380 switch (srb->Function)
1382 case SRB_FUNCTION_EXECUTE_SCSI:
1383 cdb = (PCDB)srb->Cdb;
1385 switch(cdb->CDB6GENERIC.OperationCode)
1387 case SCSIOP_TEST_UNIT_READY:
1388 if (dump_mode)
1389 KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
1390 srb_status = SRB_STATUS_SUCCESS;
1391 srb->ScsiStatus = 0;
1392 break;
1393 case SCSIOP_INQUIRY:
1394 if (dump_mode)
1395 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
1396 // KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
1397 // KdPrint((__DRIVER_NAME " (Length = %d)\n", srb->DataTransferLength));
1399 data_buffer = srb->DataBuffer;
1400 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1401 srb_status = SRB_STATUS_SUCCESS;
1402 switch (xvdd->device_type)
1404 case XENVBD_DEVICETYPE_DISK:
1405 if ((srb->Cdb[1] & 1) == 0)
1407 if (srb->Cdb[2])
1409 srb_status = SRB_STATUS_ERROR;
1411 else
1413 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1414 id->DeviceType = DIRECT_ACCESS_DEVICE;
1415 id->Versions = 4; /* minimum that WHQL says we must support */
1416 id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
1417 id->HiSupport = 1; /* WHQL test says we should set this */
1418 //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1419 id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
1420 id->CommandQueue = 1;
1421 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1422 memcpy(id->ProductId, scsi_disk_model, 16); // product id
1423 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1424 data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
1427 else
1429 switch (srb->Cdb[2])
1431 case VPD_SUPPORTED_PAGES: /* list of pages we support */
1432 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1433 data_buffer[1] = VPD_SUPPORTED_PAGES;
1434 data_buffer[2] = 0x00;
1435 data_buffer[3] = 2;
1436 data_buffer[4] = 0x00;
1437 data_buffer[5] = 0x80;
1438 data_transfer_length = 6;
1439 break;
1440 case VPD_SERIAL_NUMBER: /* serial number */
1441 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1442 data_buffer[1] = VPD_SERIAL_NUMBER;
1443 data_buffer[2] = 0x00;
1444 data_buffer[3] = 8;
1445 memset(&data_buffer[4], ' ', 8);
1446 data_transfer_length = 12;
1447 break;
1448 case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
1449 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1450 data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
1451 data_buffer[2] = 0x00;
1452 data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
1453 data_buffer[4] = 2; /* ASCII */
1454 data_buffer[5] = 1; /* VendorId */
1455 data_buffer[6] = 0;
1456 data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
1457 memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
1458 data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
1459 break;
1460 default:
1461 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1462 srb_status = SRB_STATUS_ERROR;
1463 break;
1466 break;
1467 case XENVBD_DEVICETYPE_CDROM:
1468 if ((srb->Cdb[1] & 1) == 0)
1470 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1471 id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
1472 id->RemovableMedia = 1;
1473 id->Versions = 3;
1474 id->ResponseDataFormat = 0;
1475 id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1476 id->CommandQueue = 1;
1477 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1478 memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
1479 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1480 data_transfer_length = sizeof(INQUIRYDATA);
1482 else
1484 switch (srb->Cdb[2])
1486 case 0x00:
1487 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1488 data_buffer[1] = 0x00;
1489 data_buffer[2] = 0x00;
1490 data_buffer[3] = 2;
1491 data_buffer[4] = 0x00;
1492 data_buffer[5] = 0x80;
1493 data_transfer_length = 6;
1494 break;
1495 case 0x80:
1496 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1497 data_buffer[1] = 0x80;
1498 data_buffer[2] = 0x00;
1499 data_buffer[3] = 8;
1500 data_buffer[4] = 0x31;
1501 data_buffer[5] = 0x32;
1502 data_buffer[6] = 0x33;
1503 data_buffer[7] = 0x34;
1504 data_buffer[8] = 0x35;
1505 data_buffer[9] = 0x36;
1506 data_buffer[10] = 0x37;
1507 data_buffer[11] = 0x38;
1508 data_transfer_length = 12;
1509 break;
1510 default:
1511 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1512 srb_status = SRB_STATUS_ERROR;
1513 break;
1516 break;
1517 default:
1518 //KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", xvdd->device_type));
1519 srb_status = SRB_STATUS_ERROR;
1520 break;
1522 break;
1523 case SCSIOP_READ_CAPACITY:
1524 if (dump_mode)
1525 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1526 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1527 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1528 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1529 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1530 data_buffer = srb->DataBuffer;
1531 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1532 if ((xvdd->total_sectors - 1) >> 32)
1534 data_buffer[0] = 0xff;
1535 data_buffer[1] = 0xff;
1536 data_buffer[2] = 0xff;
1537 data_buffer[3] = 0xff;
1539 else
1541 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1542 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1543 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1544 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1546 data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1547 data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1548 data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1549 data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1550 data_transfer_length = 8;
1551 srb->ScsiStatus = 0;
1552 srb_status = SRB_STATUS_SUCCESS;
1553 break;
1554 case SCSIOP_READ_CAPACITY16:
1555 if (dump_mode)
1556 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1557 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1558 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1559 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1560 data_buffer = srb->DataBuffer;
1561 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1562 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
1563 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
1564 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
1565 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
1566 data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1567 data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1568 data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1569 data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1570 data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1571 data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1572 data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1573 data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1574 data_buffer[12] = 0;
1575 switch (xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector) {
1576 case 1:
1577 data_buffer[13] = 0; /* 512 byte hardware sectors */
1578 break;
1579 case 2:
1580 data_buffer[13] = 1; /* 1024 byte hardware sectors */
1581 break;
1582 case 3:
1583 data_buffer[13] = 2; /* 2048 byte hardware sectors */
1584 break;
1585 case 4:
1586 data_buffer[13] = 2; /* 4096 byte hardware sectors */
1587 break;
1588 default:
1589 data_buffer[13] = 0; /* 512 byte hardware sectors */
1590 KdPrint((__DRIVER_NAME " Unknown logical blocks per physical block %d (%d / %d)\n", xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector, xvdd->hw_bytes_per_sector, xvdd->bytes_per_sector));
1591 break;
1593 data_buffer[14] = 0;
1594 data_buffer[15] = 0;
1595 data_transfer_length = 16;
1596 srb->ScsiStatus = 0;
1597 srb_status = SRB_STATUS_SUCCESS;
1598 break;
1599 case SCSIOP_MODE_SENSE:
1600 case SCSIOP_MODE_SENSE10:
1601 if (dump_mode)
1602 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));
1603 data_transfer_length = XenVbd_FillModePage(xvdd, srb);
1604 srb_status = SRB_STATUS_SUCCESS;
1605 break;
1606 case SCSIOP_READ:
1607 case SCSIOP_READ16:
1608 case SCSIOP_WRITE:
1609 case SCSIOP_WRITE16:
1610 //KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1611 XenVbd_PutSrbOnList(xvdd, srb);
1612 XenVbd_PutQueuedSrbsOnRing(xvdd);
1613 break;
1614 case SCSIOP_VERIFY:
1615 case SCSIOP_VERIFY16:
1616 // Should we do more here?
1617 if (dump_mode)
1618 KdPrint((__DRIVER_NAME " Command = VERIFY\n"));
1619 srb_status = SRB_STATUS_SUCCESS;
1620 break;
1621 #if 0
1622 case SCSIOP_REPORT_LUNS:
1623 if (dump_mode)
1624 KdPrint((__DRIVER_NAME " Command = REPORT_LUNS\n"));
1625 switch (srb->Cdb[1])
1628 srb_status = SRB_STATUS_SUCCESS;;
1629 break;
1630 #endif
1631 case SCSIOP_REQUEST_SENSE:
1632 if (dump_mode)
1633 KdPrint((__DRIVER_NAME " Command = REQUEST_SENSE\n"));
1634 data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
1635 srb_status = SRB_STATUS_SUCCESS;
1636 break;
1637 case SCSIOP_READ_TOC:
1638 if (dump_mode)
1639 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
1640 data_buffer = srb->DataBuffer;
1641 /*
1642 #define READ_TOC_FORMAT_TOC 0x00
1643 #define READ_TOC_FORMAT_SESSION 0x01
1644 #define READ_TOC_FORMAT_FULL_TOC 0x02
1645 #define READ_TOC_FORMAT_PMA 0x03
1646 #define READ_TOC_FORMAT_ATIP 0x04
1647 */
1648 // KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
1649 // KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
1650 // KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
1651 // KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
1652 // KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
1653 // KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
1654 // KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
1655 switch (cdb->READ_TOC.Format2)
1657 case READ_TOC_FORMAT_TOC:
1658 data_buffer[0] = 0; // length MSB
1659 data_buffer[1] = 10; // length LSB
1660 data_buffer[2] = 1; // First Track
1661 data_buffer[3] = 1; // Last Track
1662 data_buffer[4] = 0; // Reserved
1663 data_buffer[5] = 0x14; // current position data + uninterrupted data
1664 data_buffer[6] = 1; // last complete track
1665 data_buffer[7] = 0; // reserved
1666 data_buffer[8] = 0; // MSB Block
1667 data_buffer[9] = 0;
1668 data_buffer[10] = 0;
1669 data_buffer[11] = 0; // LSB Block
1670 data_transfer_length = 12;
1671 srb_status = SRB_STATUS_SUCCESS;
1672 break;
1673 case READ_TOC_FORMAT_SESSION:
1674 case READ_TOC_FORMAT_FULL_TOC:
1675 case READ_TOC_FORMAT_PMA:
1676 case READ_TOC_FORMAT_ATIP:
1677 srb_status = SRB_STATUS_ERROR;
1678 break;
1679 default:
1680 srb_status = SRB_STATUS_ERROR;
1681 break;
1683 break;
1684 case SCSIOP_START_STOP_UNIT:
1685 KdPrint((__DRIVER_NAME " Command = SCSIOP_START_STOP_UNIT\n"));
1686 srb_status = SRB_STATUS_SUCCESS;
1687 break;
1688 case SCSIOP_RESERVE_UNIT:
1689 KdPrint((__DRIVER_NAME " Command = SCSIOP_RESERVE_UNIT\n"));
1690 srb_status = SRB_STATUS_SUCCESS;
1691 break;
1692 case SCSIOP_RELEASE_UNIT:
1693 KdPrint((__DRIVER_NAME " Command = SCSIOP_RELEASE_UNIT\n"));
1694 srb_status = SRB_STATUS_SUCCESS;
1695 break;
1696 default:
1697 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
1698 srb_status = SRB_STATUS_ERROR;
1699 break;
1701 if (srb_status == SRB_STATUS_ERROR)
1703 KdPrint((__DRIVER_NAME " EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
1704 if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
1706 xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
1707 xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
1709 srb->SrbStatus = srb_status;
1710 srb->ScsiStatus = 0x02;
1711 XenVbd_MakeAutoSense(xvdd, srb);
1712 StorPortNotification(RequestComplete, DeviceExtension, srb);
1714 else if (srb_status != SRB_STATUS_PENDING)
1716 if (data_transfer_length > srb->DataTransferLength)
1717 KdPrint((__DRIVER_NAME " data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
1719 if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
1721 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
1722 srb->DataTransferLength = data_transfer_length;
1724 else
1726 srb->SrbStatus = srb_status;
1728 xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
1729 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1730 StorPortNotification(RequestComplete, DeviceExtension, srb);
1732 break;
1733 case SRB_FUNCTION_IO_CONTROL:
1734 KdPrint((__DRIVER_NAME " SRB_FUNCTION_IO_CONTROL\n"));
1735 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1736 StorPortNotification(RequestComplete, DeviceExtension, srb);
1737 break;
1738 case SRB_FUNCTION_FLUSH:
1739 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1740 srb->SrbStatus = SRB_STATUS_SUCCESS;
1741 StorPortNotification(RequestComplete, DeviceExtension, srb);
1742 break;
1743 case SRB_FUNCTION_PNP:
1744 KdPrint((__DRIVER_NAME " SRB_FUNCTION_PNP\n"));
1745 sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
1746 switch (sprb->PnPAction)
1748 case StorStartDevice:
1749 KdPrint((__DRIVER_NAME " StorStartDevice\n"));
1750 break;
1751 case StorRemoveDevice:
1752 KdPrint((__DRIVER_NAME " StorRemoveDevice\n"));
1753 break;
1754 case StorStopDevice:
1755 KdPrint((__DRIVER_NAME " StorStopDevice\n"));
1756 break;
1757 case StorQueryCapabilities:
1758 KdPrint((__DRIVER_NAME " StorQueryCapabilities\n"));
1759 break;
1760 case StorFilterResourceRequirements:
1761 KdPrint((__DRIVER_NAME " StorFilterResourceRequirements\n"));
1762 break;
1763 default:
1764 KdPrint((__DRIVER_NAME " Stor%d\n", sprb->PnPAction));
1765 break;
1767 KdPrint((__DRIVER_NAME " SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
1768 srb->SrbStatus = SRB_STATUS_SUCCESS;
1769 StorPortNotification(RequestComplete, DeviceExtension, srb);
1770 break;
1772 case SRB_FUNCTION_POWER:
1773 KdPrint((__DRIVER_NAME " SRB_FUNCTION_POWER\n"));
1774 spwrb = (PSCSI_POWER_REQUEST_BLOCK)srb;
1775 switch (spwrb->PowerAction)
1777 case StorPowerActionNone:
1778 KdPrint((__DRIVER_NAME " StorPowerActionNone\n"));
1779 break;
1780 case StorPowerActionReserved:
1781 KdPrint((__DRIVER_NAME " StorPowerActionReserved\n"));
1782 break;
1783 case StorPowerActionSleep:
1784 KdPrint((__DRIVER_NAME " StorPowerActionSleep\n"));
1785 break;
1786 case StorPowerActionHibernate:
1787 KdPrint((__DRIVER_NAME " StorPowerActionHibernate\n"));
1788 break;
1789 case StorPowerActionShutdown:
1790 KdPrint((__DRIVER_NAME " StorPowerActionShutdown\n"));
1791 break;
1792 case StorPowerActionShutdownReset:
1793 KdPrint((__DRIVER_NAME " StorPowerActionShutdownReset\n"));
1794 break;
1795 case StorPowerActionShutdownOff:
1796 KdPrint((__DRIVER_NAME " StorPowerActionShutdownOff\n"));
1797 break;
1798 case StorPowerActionWarmEject:
1799 KdPrint((__DRIVER_NAME " StorPowerActionWarmEject\n"));
1800 break;
1801 default:
1802 KdPrint((__DRIVER_NAME " Stor%d\n", spwrb->PowerAction));
1803 break;
1805 XenVbd_PutSrbOnList(xvdd, srb);
1806 XenVbd_PutQueuedSrbsOnRing(xvdd);
1807 break;
1808 case SRB_FUNCTION_DUMP_POINTERS:
1809 KdPrint((__DRIVER_NAME " SRB_FUNCTION_DUMP_POINTERS\n"));
1810 KdPrint((__DRIVER_NAME " DataTransferLength = %d\n", srb->DataTransferLength));
1811 dump_pointers = srb->DataBuffer;
1812 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1813 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1814 KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1815 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1816 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1817 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1818 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1819 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1820 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1821 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1822 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1823 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1824 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1825 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1826 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1827 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1828 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1830 dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
1831 dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
1832 RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
1833 dump_pointers->AdapterObject = NULL;
1834 dump_pointers->MappedRegisterBase = 0;
1835 dump_pointers->CommonBufferSize = 0;
1836 dump_pointers->MiniportPrivateDumpData = (PVOID)xvdd->device_base;
1837 //dump_pointers->SystemIoBusNumber = 0;
1838 dump_pointers->AdapterInterfaceType = Internal;
1839 dump_pointers->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
1840 dump_pointers->NumberOfPhysicalBreaks = dump_pointers->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
1841 dump_pointers->AlignmentMask = 0;
1842 dump_pointers->NumberOfAccessRanges = 1;
1843 dump_pointers->NumberOfBuses = 1;
1844 dump_pointers->Master = TRUE;
1845 dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1846 dump_pointers->MaximumNumberOfTargets = 2;
1848 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1849 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1850 //KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1851 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1852 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1853 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1854 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1855 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1856 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1857 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1858 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1859 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1860 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1861 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1862 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1863 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1864 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1866 srb->SrbStatus = SRB_STATUS_SUCCESS;
1867 StorPortNotification(RequestComplete, DeviceExtension, srb);
1868 break;
1869 case SRB_FUNCTION_SHUTDOWN:
1870 KdPrint((__DRIVER_NAME " SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1871 //ASSERT(IsListEmpty(&xvdd->srb_list));
1872 //ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
1873 XenVbd_PutSrbOnList(xvdd, srb);
1874 XenVbd_PutQueuedSrbsOnRing(xvdd);
1875 //srb->SrbStatus = SRB_STATUS_SUCCESS;
1876 //StorPortNotification(RequestComplete, DeviceExtension, srb);
1877 break;
1878 case SRB_FUNCTION_RESET_BUS:
1879 case SRB_FUNCTION_RESET_DEVICE:
1880 case SRB_FUNCTION_RESET_LOGICAL_UNIT:
1881 /* the path doesn't matter here - only ever one device*/
1882 XenVbd_HwStorResetBus(DeviceExtension, 0);
1883 srb->SrbStatus = SRB_STATUS_SUCCESS;
1884 StorPortNotification(RequestComplete, DeviceExtension, srb);
1885 break;
1887 default:
1888 KdPrint((__DRIVER_NAME " Unhandled srb->Function = %08X\n", srb->Function));
1889 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1890 StorPortNotification(RequestComplete, DeviceExtension, srb);
1891 break;
1894 //if (dump_mode) FUNCTION_EXIT();
1895 StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
1896 return TRUE;
1899 static SCSI_ADAPTER_CONTROL_STATUS
1900 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
1902 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1903 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
1904 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
1905 //KIRQL OldIrql;
1907 FUNCTION_ENTER();
1908 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1909 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
1911 switch (ControlType)
1913 case ScsiQuerySupportedControlTypes:
1914 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
1915 KdPrint((__DRIVER_NAME " ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
1916 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
1917 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
1918 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
1919 break;
1920 case ScsiStopAdapter:
1921 KdPrint((__DRIVER_NAME " ScsiStopAdapter\n"));
1922 if (xvdd->inactive)
1924 KdPrint((__DRIVER_NAME " inactive - nothing to do\n"));
1925 break;
1927 NT_ASSERT(IsListEmpty(&xvdd->srb_list));
1928 NT_ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
1929 break;
1930 case ScsiRestartAdapter:
1931 KdPrint((__DRIVER_NAME " ScsiRestartAdapter\n"));
1932 if (xvdd->inactive)
1934 KdPrint((__DRIVER_NAME " inactive - nothing to do\n"));
1935 break;
1937 /* increase the tag every time we stop/start to track where the gref's came from */
1938 xvdd->grant_tag++;
1939 if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND) {
1940 #pragma warning(suppress:28159)
1941 KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
1943 xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
1945 //XenVbd_StartRingDetection(xvdd);
1946 break;
1947 case ScsiSetBootConfig:
1948 KdPrint((__DRIVER_NAME " ScsiSetBootConfig\n"));
1949 break;
1950 case ScsiSetRunningConfig:
1951 KdPrint((__DRIVER_NAME " ScsiSetRunningConfig\n"));
1952 break;
1953 default:
1954 KdPrint((__DRIVER_NAME " UNKNOWN\n"));
1955 break;
1958 FUNCTION_EXIT();
1960 return Status;
1963 NTSTATUS
1964 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
1966 ULONG status;
1967 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
1968 HW_INITIALIZATION_DATA HwInitializationData;
1969 OBJECT_ATTRIBUTES oa;
1970 HANDLE service_handle;
1971 UNICODE_STRING param_name;
1972 HANDLE param_handle;
1973 UNICODE_STRING value_name;
1974 CHAR buf[256];
1975 ULONG buf_len;
1976 PKEY_VALUE_PARTIAL_INFORMATION kpv;
1978 FUNCTION_ENTER();
1979 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1980 KdPrint((__DRIVER_NAME " DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
1982 /* RegistryPath == NULL when we are invoked as a crash dump driver */
1983 if (!RegistryPath)
1985 dump_mode = TRUE;
1988 if (!dump_mode)
1990 InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
1991 status = ZwOpenKey(&service_handle, KEY_READ, &oa);
1992 if(!NT_SUCCESS(status))
1994 KdPrint((__DRIVER_NAME " ZwOpenKey(Service) returned %08x\n", status));
1996 else
1998 RtlInitUnicodeString(&param_name, L"Parameters");
1999 InitializeObjectAttributes(&oa, &param_name, OBJ_CASE_INSENSITIVE, service_handle, NULL);
2000 status = ZwOpenKey(&param_handle, KEY_READ, &oa);
2001 if(!NT_SUCCESS(status))
2003 KdPrint((__DRIVER_NAME " ZwOpenKey(Parameters) returned %08x\n", status));
2005 else
2007 kpv = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
2008 RtlFillMemory(scsi_device_manufacturer, 8, ' ');
2009 RtlFillMemory(scsi_disk_model, 16, ' ');
2010 RtlFillMemory(scsi_cdrom_model, 16, ' ');
2012 RtlInitUnicodeString(&value_name, L"Manufacturer");
2013 buf_len = 256;
2014 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
2015 if(NT_SUCCESS(status))
2016 wcstombs(scsi_device_manufacturer, (PWCHAR)kpv->Data, min(kpv->DataLength, 8));
2017 else
2018 RtlStringCbCopyA(scsi_device_manufacturer, 8, "XEN ");
2020 RtlInitUnicodeString(&value_name, L"Disk_Model");
2021 buf_len = 256;
2022 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
2023 if(NT_SUCCESS(status))
2024 wcstombs(scsi_disk_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
2025 else
2026 RtlStringCbCopyA(scsi_disk_model, 16, "PV DISK ");
2028 RtlInitUnicodeString(&value_name, L"CDROM_Model");
2029 buf_len = 256;
2030 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
2031 if(NT_SUCCESS(status))
2032 wcstombs(scsi_cdrom_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
2033 else
2034 RtlStringCbCopyA(scsi_cdrom_model, 16, "PV CDROM ");
2035 ZwClose(param_handle);
2037 ZwClose(service_handle);
2039 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
2040 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
2041 VHwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* maybe should be internal? */
2042 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
2043 VHwInitializationData.SpecificLuExtensionSize = 0;
2044 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
2045 VHwInitializationData.NumberOfAccessRanges = 1;
2046 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
2047 //VHwInitializationData.NeedPhysicalAddresses = TRUE;
2048 VHwInitializationData.TaggedQueuing = TRUE;
2049 VHwInitializationData.AutoRequestSense = TRUE;
2050 VHwInitializationData.MultipleRequestPerLu = TRUE;
2051 VHwInitializationData.ReceiveEvent = TRUE;
2052 VHwInitializationData.PortVersionFlags = 0;
2053 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
2054 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
2055 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
2056 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
2057 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
2058 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
2060 else
2062 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
2063 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
2064 HwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* not Internal */
2065 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
2066 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
2067 HwInitializationData.NumberOfAccessRanges = 1;
2068 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
2069 HwInitializationData.NeedPhysicalAddresses = TRUE;
2070 HwInitializationData.TaggedQueuing = FALSE;
2071 HwInitializationData.AutoRequestSense = TRUE;
2072 HwInitializationData.MultipleRequestPerLu = FALSE;
2073 HwInitializationData.ReceiveEvent = TRUE;
2074 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
2075 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
2076 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
2077 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
2078 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
2079 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
2080 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
2083 if(!NT_SUCCESS(status))
2085 KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", status));
2088 FUNCTION_EXIT();
2090 return status;