win-pvdrivers

view xenvbd/xenvbd_storport.c @ 839:e48c6f765e5f

Do the right thing on running out of shadow entries. Fix SMP issue (virtual storport does not locking).
author James Harper <james.harper@bendigoit.com.au>
date Thu Feb 03 14:13:00 2011 +1100 (2011-02-03)
parents 66e79b88f301
children 2f4e64007b0f
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;
72 shadow->srb = NULL;
73 xvdd->shadow_free++;
74 }
76 static blkif_response_t *
77 XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i)
78 {
79 blkif_other_response_t *rep;
80 if (!xvdd->use_other)
81 return RING_GET_RESPONSE(&xvdd->ring, i);
82 rep = RING_GET_RESPONSE(&xvdd->other_ring, i);
83 xvdd->tmp_rep.id = rep->id;
84 xvdd->tmp_rep.operation = rep->operation;
85 xvdd->tmp_rep.status = rep->status;
86 return &xvdd->tmp_rep;
87 }
89 static VOID
90 XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req)
91 {
92 blkif_other_request_t *other_req;
94 if (!xvdd->use_other)
95 {
96 *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
97 }
98 else
99 {
100 other_req = RING_GET_REQUEST(&xvdd->other_ring, xvdd->ring.req_prod_pvt);
101 other_req->operation = req->operation;
102 other_req->nr_segments = req->nr_segments;
103 other_req->handle = req->handle;
104 other_req->id = req->id;
105 other_req->sector_number = req->sector_number;
106 memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
107 }
108 xvdd->ring.req_prod_pvt++;
109 }
111 static ULONG
112 XenVbd_InitConfig(PXENVBD_DEVICE_DATA xvdd)
113 {
114 ULONG status;
115 PUCHAR ptr;
116 USHORT type;
117 PCHAR setting, value, value2;
119 FUNCTION_ENTER();
120 /* first read the default config items */
121 ptr = xvdd->device_base;
122 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
123 {
124 switch(type)
125 {
126 case XEN_INIT_TYPE_VECTORS:
127 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
128 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
129 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
130 {
131 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
132 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
133 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
134 return SP_RETURN_BAD_CONFIG;
135 }
136 else
137 memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
138 break;
139 default:
140 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
141 break;
142 }
143 }
145 /* then set up all the configuration requests */
146 ptr = xvdd->device_base;
147 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
148 #pragma warning(suppress:4054)
149 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenVbd_HandleEvent, xvdd);
150 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL, NULL);
151 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
152 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
153 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
154 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, NULL, ULongToPtr(BLKIF_MAX_SEGMENTS_PER_REQUEST), NULL); /* for use in crash dump */
155 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
156 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
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, 0);
162 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
163 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
164 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
165 __ADD_XEN_INIT_UCHAR(&ptr, 50);
166 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
167 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
168 __ADD_XEN_INIT_UCHAR(&ptr, 50);
169 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
170 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
171 __ADD_XEN_INIT_UCHAR(&ptr, 50);
172 __ADD_XEN_INIT_UCHAR(&ptr, 0);
173 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
175 /* then configure */
176 status = xvdd->vectors.XenPci_XenConfigDevice(xvdd->vectors.context);
177 if (!NT_SUCCESS(status))
178 {
179 KdPrint(("Failed to complete device configuration (%08x)\n", status));
180 FUNCTION_EXIT();
181 return SP_RETURN_BAD_CONFIG;
182 }
183 FUNCTION_EXIT();
184 return SP_RETURN_FOUND;
185 }
187 static ULONG
188 XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
189 {
190 ULONG i;
191 PUCHAR ptr;
192 USHORT type;
193 PCHAR setting, value, value2;
194 ULONG qemu_protocol_version = 0;
195 BOOLEAN qemu_hide_filter = FALSE;
196 ULONG qemu_hide_flags_value = 0;
198 FUNCTION_ENTER();
200 xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
201 xvdd->sring = NULL;
202 xvdd->event_channel = 0;
204 xvdd->inactive = TRUE;
206 ptr = xvdd->device_base;
207 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
208 {
209 switch(type)
210 {
211 case XEN_INIT_TYPE_VECTORS:
212 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
213 if (dump_mode)
214 {
215 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
216 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
217 {
218 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
219 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
220 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
221 return SP_RETURN_BAD_CONFIG;
222 }
223 else
224 memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
225 }
226 break;
227 case XEN_INIT_TYPE_RING: /* frontend ring */
228 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
229 if (strcmp(setting, "ring-ref") == 0)
230 {
231 xvdd->sring = (blkif_sring_t *)value;
232 FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
233 /* this bit is for when we have to take over an existing ring on a crash dump */
234 xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
235 xvdd->ring.rsp_cons = xvdd->ring.req_prod_pvt;
236 }
237 break;
238 case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
239 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value) & 0x3FFFFFFF));
240 if (strcmp(setting, "event-channel") == 0)
241 {
242 /* cheat here - save the state of the ring in the topmost bits of the event-channel */
243 xvdd->event_channel_ptr = (ULONG *)(((PCHAR)ptr) - sizeof(ULONG));
244 xvdd->event_channel = PtrToUlong(value) & 0x3FFFFFFF;
245 if (PtrToUlong(value) & 0x80000000)
246 {
247 xvdd->cached_use_other = (BOOLEAN)!!(PtrToUlong(value) & 0x40000000);
248 KdPrint((__DRIVER_NAME " cached_use_other = %d\n", xvdd->cached_use_other));
249 }
250 }
251 break;
252 case XEN_INIT_TYPE_READ_STRING_BACK:
253 case XEN_INIT_TYPE_READ_STRING_FRONT:
254 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
255 if (strcmp(setting, "sectors") == 0)
256 xvdd->total_sectors = parse_numeric_string(value);
257 else if (strcmp(setting, "sector-size") == 0)
258 xvdd->bytes_per_sector = (ULONG)parse_numeric_string(value);
259 else if (strcmp(setting, "device-type") == 0)
260 {
261 if (strcmp(value, "disk") == 0)
262 {
263 KdPrint((__DRIVER_NAME " device-type = Disk\n"));
264 xvdd->device_type = XENVBD_DEVICETYPE_DISK;
265 }
266 else if (strcmp(value, "cdrom") == 0)
267 {
268 KdPrint((__DRIVER_NAME " device-type = CDROM\n"));
269 xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
270 }
271 else
272 {
273 KdPrint((__DRIVER_NAME " device-type = %s (This probably won't work!)\n", value));
274 xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
275 }
276 }
277 else if (strcmp(setting, "mode") == 0)
278 {
279 if (strncmp(value, "r", 1) == 0)
280 {
281 KdPrint((__DRIVER_NAME " mode = r\n"));
282 xvdd->device_mode = XENVBD_DEVICEMODE_READ;
283 }
284 else if (strncmp(value, "w", 1) == 0)
285 {
286 KdPrint((__DRIVER_NAME " mode = w\n"));
287 xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
288 }
289 else
290 {
291 KdPrint((__DRIVER_NAME " mode = unknown\n"));
292 xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
293 }
294 }
295 break;
296 case XEN_INIT_TYPE_GRANT_ENTRIES:
297 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - entries = %d\n", PtrToUlong(setting)));
298 memcpy(xvdd->dump_grant_refs, value, PtrToUlong(setting) * sizeof(grant_ref_t));
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 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
354 }
355 }
357 FUNCTION_EXIT();
358 return SP_RETURN_FOUND;
359 }
361 static __inline ULONG
362 decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
363 {
364 switch (srb->Cdb[0])
365 {
366 case SCSIOP_READ:
367 case SCSIOP_WRITE:
368 return ((ULONG)(UCHAR)srb->Cdb[7] << 8) | (ULONG)(UCHAR)srb->Cdb[8];
369 case SCSIOP_READ16:
370 case SCSIOP_WRITE16:
371 return ((ULONG)(UCHAR)srb->Cdb[10] << 24) | ((ULONG)(UCHAR)srb->Cdb[11] << 16) | ((ULONG)(UCHAR)srb->Cdb[12] << 8) | (ULONG)(UCHAR)srb->Cdb[13];
372 default:
373 return 0;
374 }
375 }
377 static __inline ULONGLONG
378 decode_cdb_sector(PSCSI_REQUEST_BLOCK srb)
379 {
380 ULONGLONG sector;
382 switch (srb->Cdb[0])
383 {
384 case SCSIOP_READ:
385 case SCSIOP_WRITE:
386 sector = ((ULONG)(UCHAR)srb->Cdb[2] << 24) | ((ULONG)(UCHAR)srb->Cdb[3] << 16) | ((ULONG)(UCHAR)srb->Cdb[4] << 8) | (ULONG)(UCHAR)srb->Cdb[5];
387 break;
388 case SCSIOP_READ16:
389 case SCSIOP_WRITE16:
390 sector = ((ULONGLONG)(UCHAR)srb->Cdb[2] << 56) | ((ULONGLONG)(UCHAR)srb->Cdb[3] << 48)
391 | ((ULONGLONG)(UCHAR)srb->Cdb[4] << 40) | ((ULONGLONG)(UCHAR)srb->Cdb[5] << 32)
392 | ((ULONGLONG)(UCHAR)srb->Cdb[6] << 24) | ((ULONGLONG)(UCHAR)srb->Cdb[7] << 16)
393 | ((ULONGLONG)(UCHAR)srb->Cdb[8] << 8) | ((ULONGLONG)(UCHAR)srb->Cdb[9]);
394 //KdPrint((__DRIVER_NAME " sector_number = %d (high) %d (low)\n", (ULONG)(sector >> 32), (ULONG)sector));
395 break;
396 default:
397 sector = 0;
398 break;
399 }
400 return sector;
401 }
403 static __inline BOOLEAN
404 decode_cdb_is_read(PSCSI_REQUEST_BLOCK srb)
405 {
406 switch (srb->Cdb[0])
407 {
408 case SCSIOP_READ:
409 case SCSIOP_READ16:
410 return TRUE;
411 case SCSIOP_WRITE:
412 case SCSIOP_WRITE16:
413 return FALSE;
414 default:
415 return FALSE;
416 }
417 }
419 ULONG max_dump_mode_blocks = 0;
420 ULONG max_dump_mode_length = 0;
422 static VOID
423 XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
424 {
425 srb_list_entry_t *list_entry = srb->SrbExtension;
426 list_entry->srb = srb;
427 InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)list_entry);
428 }
430 static VOID
431 XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVICE_DATA xvdd)
432 {
433 PSCSI_REQUEST_BLOCK srb;
434 srb_list_entry_t *srb_entry;
435 ULONGLONG sector_number;
436 ULONG block_count;
437 blkif_shadow_t *shadow;
438 ULONG remaining, offset, length;
439 grant_ref_t gref;
440 PUCHAR ptr;
441 int notify;
442 int i;
443 PVOID system_address;
445 //if (dump_mode) FUNCTION_ENTER();
447 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)
448 {
449 srb = srb_entry->srb;
450 //if (dump_mode) KdPrint((__DRIVER_NAME " srb = %p\n", srb));
451 if (!dump_mode)
452 {
453 if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS)
454 {
455 KdPrint((__DRIVER_NAME " Failed to map DataBuffer\n"));
456 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
457 StorPortNotification(RequestComplete, xvdd, srb);
458 continue;
459 }
460 }
461 else
462 {
463 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
464 system_address = srb->DataBuffer;
465 }
466 block_count = decode_cdb_length(srb);
467 block_count *= xvdd->bytes_per_sector / 512;
468 sector_number = decode_cdb_sector(srb);
469 sector_number *= xvdd->bytes_per_sector / 512;
471 //if (dump_mode) KdPrint((__DRIVER_NAME " sector_number = %I64d, block_count = %d, bytes_per_sector = %d, DataTransferLength = %d\n", sector_number, block_count, xvdd->bytes_per_sector, srb->DataTransferLength));
472 ASSERT(block_count * xvdd->bytes_per_sector == srb->DataTransferLength);
474 /* look for pending writes that overlap this one */
475 /* we get warnings from drbd if we don't */
476 for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
477 {
478 PSCSI_REQUEST_BLOCK srb2;
479 ULONGLONG sector_number2;
480 ULONG block_count2;
482 srb2 = xvdd->shadows[i].srb;
483 if (!srb2)
484 continue;
485 if (decode_cdb_is_read(srb2))
486 continue;
487 block_count2 = decode_cdb_length(srb2);;
488 block_count2 *= xvdd->bytes_per_sector / 512;
489 sector_number2 = decode_cdb_sector(srb2);
490 sector_number2 *= xvdd->bytes_per_sector / 512;
492 if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
493 continue;
494 if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
495 continue;
497 KdPrint((__DRIVER_NAME " Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
498 sector_number, block_count, sector_number2, block_count2));
499 /* put the srb back at the start of the queue */
500 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
501 return; /* stall the queue */
502 }
504 remaining = block_count * 512;
505 shadow = get_shadow_from_freelist(xvdd);
506 if (!shadow)
507 {
508 /* put the srb back at the start of the queue */
509 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
510 return; /* stall the queue */
511 }
512 ASSERT(!shadow->aligned_buffer_in_use);
513 ASSERT(!shadow->srb);
514 shadow->req.sector_number = sector_number;
515 shadow->req.handle = 0;
516 shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
517 shadow->req.nr_segments = 0;
518 shadow->srb = srb;
519 shadow->system_address = system_address;
521 if (!dump_mode)
522 {
523 if ((ULONG_PTR)shadow->system_address & 511)
524 {
525 xvdd->aligned_buffer_in_use = TRUE;
526 ptr = xvdd->aligned_buffer;
527 if (!decode_cdb_is_read(srb))
528 memcpy(ptr, shadow->system_address, block_count * 512);
529 shadow->aligned_buffer_in_use = TRUE;
530 }
531 else
532 {
533 ptr = shadow->system_address;
534 shadow->aligned_buffer_in_use = FALSE;
535 }
536 }
537 else
538 {
539 ASSERT(!((ULONG_PTR)shadow->system_address & 511));
540 ptr = srb->DataBuffer;
541 shadow->aligned_buffer_in_use = FALSE;
542 if (block_count > max_dump_mode_blocks)
543 {
544 max_dump_mode_blocks = block_count;
545 KdPrint((__DRIVER_NAME " max_dump_mode_blocks = %d\n", max_dump_mode_blocks));
546 }
547 if (srb->DataTransferLength > max_dump_mode_length)
548 {
549 max_dump_mode_length = srb->DataTransferLength;
550 KdPrint((__DRIVER_NAME " max_dump_mode_length = %d\n", max_dump_mode_length));
551 }
552 }
554 //KdPrint((__DRIVER_NAME " sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
555 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
556 //KdPrint((__DRIVER_NAME " system_address = %p\n", shadow->system_address));
558 //KdPrint((__DRIVER_NAME " handle = %d\n", shadow->req.handle));
559 //KdPrint((__DRIVER_NAME " operation = %d\n", shadow->req.operation));
561 while (remaining > 0)
562 {
563 PHYSICAL_ADDRESS physical_address;
565 if (!dump_mode)
566 {
567 physical_address = MmGetPhysicalAddress(ptr);
568 gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
569 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XVBD');
570 }
571 else
572 {
573 ULONG length;
574 physical_address.QuadPart = 0;
575 physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
576 //KdPrint((__DRIVER_NAME " pfn = %08x, length = %d\n", (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), length));
577 gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
578 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE,
579 xvdd->dump_grant_refs[shadow->req.nr_segments], (ULONG)'XPDO');
580 }
581 if (gref == INVALID_GRANT_REF)
582 {
583 ULONG i;
584 for (i = 0; i < shadow->req.nr_segments; i++)
585 {
586 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
587 shadow->req.seg[i].gref, FALSE, (ULONG)'XVBD');
588 }
589 if (shadow->aligned_buffer_in_use)
590 {
591 shadow->aligned_buffer_in_use = FALSE;
592 xvdd->aligned_buffer_in_use = FALSE;
593 }
594 /* put the srb back at the start of the queue */
595 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
596 put_shadow_on_freelist(xvdd, shadow);
597 KdPrint((__DRIVER_NAME " Out of gref's. Deferring\n"));
598 return;
599 }
600 offset = physical_address.LowPart & (PAGE_SIZE - 1);
601 length = min(PAGE_SIZE - offset, remaining);
602 //if (dump_mode) KdPrint((__DRIVER_NAME " length = %d\n", length));
603 //if (dump_mode) KdPrint((__DRIVER_NAME " offset = %d\n", length));
604 ASSERT((offset & 511) == 0);
605 ASSERT((length & 511) == 0);
606 ASSERT(offset + length <= PAGE_SIZE);
607 shadow->req.seg[shadow->req.nr_segments].gref = gref;
608 shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
609 shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
610 //if (dump_mode) KdPrint((__DRIVER_NAME " gref = %d\n", shadow->req.seg[shadow->req.nr_segments].gref));
611 //if (dump_mode) KdPrint((__DRIVER_NAME " first_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].first_sect));
612 //if (dump_mode) KdPrint((__DRIVER_NAME " last_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].last_sect));
613 remaining -= length;
614 ptr += length;
615 shadow->req.nr_segments++;
616 }
618 //KdPrint((__DRIVER_NAME " nr_segments = %d\n", shadow->req.nr_segments));
620 XenVbd_PutRequest(xvdd, &shadow->req);
622 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
623 if (notify)
624 {
625 //KdPrint((__DRIVER_NAME " Notifying\n"));
626 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
627 }
628 }
629 //if (dump_mode) FUNCTION_EXIT();
630 }
632 static ULONG
633 XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
634 {
635 // PACCESS_RANGE AccessRange;
636 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
637 ULONG status;
638 // PXENPCI_XEN_DEVICE_DATA XenDeviceData;
639 PACCESS_RANGE access_range;
641 UNREFERENCED_PARAMETER(HwContext);
642 UNREFERENCED_PARAMETER(BusInformation);
643 UNREFERENCED_PARAMETER(LowerDevice);
644 UNREFERENCED_PARAMETER(ArgumentString);
646 FUNCTION_ENTER();
647 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
648 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
650 RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
651 *Again = FALSE;
653 KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
654 KdPrint((__DRIVER_NAME " BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
656 if (!dump_mode)
657 {
658 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
659 if (ConfigInfo->NumberOfAccessRanges != 1 && ConfigInfo->NumberOfAccessRanges != 2)
660 {
661 return SP_RETURN_BAD_CONFIG;
662 }
664 access_range = &((*(ConfigInfo->AccessRanges))[0]);
665 KdPrint((__DRIVER_NAME " RangeStart = %08x, RangeLength = %08x\n",
666 access_range->RangeStart.LowPart, access_range->RangeLength));
667 xvdd->device_base = StorPortGetDeviceBase(
668 DeviceExtension,
669 PNPBus, //AdapterInterfaceType,
670 ConfigInfo->SystemIoBusNumber,
671 access_range->RangeStart,
672 access_range->RangeLength,
673 !access_range->RangeInMemory);
674 if (!xvdd->device_base)
675 {
676 KdPrint((__DRIVER_NAME " StorPortGetDeviceBase failed\n"));
677 FUNCTION_EXIT();
678 return SP_RETURN_BAD_CONFIG;
679 }
680 status = XenVbd_InitConfig(xvdd);
681 if (status != SP_RETURN_FOUND)
682 {
683 FUNCTION_EXIT();
684 return status;
685 }
686 }
687 else
688 {
689 xvdd->device_base = ConfigInfo->Reserved;
690 }
692 status = XenVbd_InitFromConfig(xvdd);
693 if (status != SP_RETURN_FOUND)
694 {
695 FUNCTION_EXIT();
696 return status;
697 }
699 xvdd->aligned_buffer_in_use = FALSE;
700 /* align the buffer to PAGE_SIZE */
701 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
702 KdPrint((__DRIVER_NAME " aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
703 KdPrint((__DRIVER_NAME " aligned_buffer = %p\n", xvdd->aligned_buffer));
705 ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
706 ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
707 KdPrint((__DRIVER_NAME " ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength));
708 KdPrint((__DRIVER_NAME " ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
709 if (!dump_mode)
710 {
711 ConfigInfo->VirtualDevice = TRUE;
712 }
713 else
714 {
715 ConfigInfo->VirtualDevice = FALSE;
716 }
718 KdPrint((__DRIVER_NAME " ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice));
719 ConfigInfo->ScatterGather = TRUE;
720 ConfigInfo->Master = TRUE;
721 ConfigInfo->CachesData = FALSE;
722 ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
723 KdPrint((__DRIVER_NAME " ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses));
724 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
725 ConfigInfo->AlignmentMask = 0;
726 ConfigInfo->NumberOfBuses = 1;
727 ConfigInfo->InitiatorBusId[0] = 1;
728 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
729 ConfigInfo->MaximumNumberOfTargets = 2;
730 //ConfigInfo->BufferAccessScsiPortControlled = FALSE;
731 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
732 {
733 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
734 //ConfigInfo->Dma32BitAddresses = FALSE;
735 KdPrint((__DRIVER_NAME " Dma64BitAddresses supported\n"));
736 }
737 else
738 {
739 //ConfigInfo->Dma32BitAddresses = TRUE;
740 KdPrint((__DRIVER_NAME " Dma64BitAddresses not supported\n"));
741 }
743 FUNCTION_EXIT();
745 return SP_RETURN_FOUND;
746 }
748 static ULONG
749 XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
750 {
751 ULONG status;
753 FUNCTION_ENTER();
754 status = XenVbd_VirtualHwStorFindAdapter(DeviceExtension, HwContext, BusInformation, NULL, ArgumentString, ConfigInfo, Again);
755 FUNCTION_EXIT();
756 return status;
757 }
759 //do this in StartIo instead to prevent races with the driver initialisation
760 static VOID
761 XenVbd_StartRingDetection(PXENVBD_DEVICE_DATA xvdd)
762 {
763 blkif_request_t *req;
764 int notify;
766 xvdd->ring_detect_state = RING_DETECT_STATE_DETECT1;
767 RtlZeroMemory(xvdd->sring->ring, PAGE_SIZE - FIELD_OFFSET(blkif_sring_t, ring));
768 req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
769 req->operation = 0xff;
770 xvdd->ring.req_prod_pvt++;
771 req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
772 req->operation = 0xff;
773 xvdd->ring.req_prod_pvt++;
775 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
776 if (notify)
777 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
778 }
780 static BOOLEAN
781 XenVbd_HwStorInitialize(PVOID DeviceExtension)
782 {
783 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
785 FUNCTION_ENTER();
786 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
787 KdPrint((__DRIVER_NAME " dump_mode = %d\n", dump_mode));
789 if (!xvdd->inactive)
790 {
791 if (dump_mode)
792 {
793 if (xvdd->cached_use_other)
794 {
795 xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
796 xvdd->use_other = TRUE;
797 }
798 xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
799 }
800 InitializeListHead(&xvdd->srb_list);
801 }
802 FUNCTION_EXIT();
804 return TRUE;
805 }
807 static ULONG
808 XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
809 {
810 PMODE_PARAMETER_HEADER parameter_header = NULL;
811 PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
812 PMODE_PARAMETER_BLOCK param_block;
813 PMODE_FORMAT_PAGE format_page;
814 ULONG offset = 0;
815 UCHAR buffer[1024];
816 BOOLEAN valid_page = FALSE;
817 BOOLEAN cdb_llbaa;
818 BOOLEAN cdb_dbd;
819 UCHAR cdb_page_code;
820 USHORT cdb_allocation_length;
822 UNREFERENCED_PARAMETER(xvdd);
824 RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
825 RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
826 offset = 0;
828 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
830 switch (srb->Cdb[0])
831 {
832 case SCSIOP_MODE_SENSE:
833 cdb_llbaa = FALSE;
834 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
835 cdb_page_code = srb->Cdb[2] & 0x3f;
836 cdb_allocation_length = srb->Cdb[4];
837 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
838 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
839 parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
840 parameter_header->MediumType = 0;
841 parameter_header->DeviceSpecificParameter = 0;
842 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
843 {
844 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
845 parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
846 }
847 offset += sizeof(MODE_PARAMETER_HEADER);
848 break;
849 case SCSIOP_MODE_SENSE10:
850 cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
851 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
852 cdb_page_code = srb->Cdb[2] & 0x3f;
853 cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
854 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE10 llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
855 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
856 parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
857 parameter_header10->MediumType = 0;
858 parameter_header10->DeviceSpecificParameter = 0;
859 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
860 {
861 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
862 parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
863 }
864 offset += sizeof(MODE_PARAMETER_HEADER10);
865 break;
866 default:
867 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
868 return FALSE;
869 }
871 if (!cdb_dbd)
872 {
873 param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
874 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
875 {
876 if (xvdd->total_sectors >> 32)
877 {
878 param_block->DensityCode = 0xff;
879 param_block->NumberOfBlocks[0] = 0xff;
880 param_block->NumberOfBlocks[1] = 0xff;
881 param_block->NumberOfBlocks[2] = 0xff;
882 }
883 else
884 {
885 param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
886 param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
887 param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
888 param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
889 }
890 param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
891 param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
892 param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
893 }
894 offset += sizeof(MODE_PARAMETER_BLOCK);
895 }
896 switch (srb->Cdb[0])
897 {
898 case SCSIOP_MODE_SENSE:
899 parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
900 break;
901 case SCSIOP_MODE_SENSE10:
902 parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);
903 parameter_header10->BlockDescriptorLength[1] = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER10));
904 break;
905 }
906 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_FORMAT_DEVICE || cdb_page_code == MODE_SENSE_RETURN_ALL))
907 {
908 valid_page = TRUE;
909 format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
910 format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
911 format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
912 /* 256 sectors per track */
913 format_page->SectorsPerTrack[0] = 0x01;
914 format_page->SectorsPerTrack[1] = 0x00;
915 /* xxx bytes per sector */
916 format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
917 format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
918 format_page->HardSectorFormating = TRUE;
919 format_page->SoftSectorFormating = TRUE;
920 offset += sizeof(MODE_FORMAT_PAGE);
921 }
922 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_CACHING || cdb_page_code == MODE_SENSE_RETURN_ALL))
923 {
924 PMODE_CACHING_PAGE caching_page;
925 valid_page = TRUE;
926 caching_page = (PMODE_CACHING_PAGE)&buffer[offset];
927 caching_page->PageCode = MODE_PAGE_CACHING;
928 caching_page->PageLength = sizeof(MODE_CACHING_PAGE) - FIELD_OFFSET(MODE_CACHING_PAGE, PageLength);
929 // caching_page-> // all zeros is just fine... maybe
930 offset += sizeof(MODE_CACHING_PAGE);
931 }
932 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_MEDIUM_TYPES || cdb_page_code == MODE_SENSE_RETURN_ALL))
933 {
934 PUCHAR medium_types_page;
935 valid_page = TRUE;
936 medium_types_page = &buffer[offset];
937 medium_types_page[0] = MODE_PAGE_MEDIUM_TYPES;
938 medium_types_page[1] = 0x06;
939 medium_types_page[2] = 0;
940 medium_types_page[3] = 0;
941 medium_types_page[4] = 0;
942 medium_types_page[5] = 0;
943 medium_types_page[6] = 0;
944 medium_types_page[7] = 0;
945 offset += 8;
946 }
947 switch (srb->Cdb[0])
948 {
949 case SCSIOP_MODE_SENSE:
950 parameter_header->ModeDataLength = (UCHAR)(offset - 1);
951 break;
952 case SCSIOP_MODE_SENSE10:
953 parameter_header10->ModeDataLength[0] = (UCHAR)((offset - 2) >> 8);
954 parameter_header10->ModeDataLength[1] = (UCHAR)(offset - 2);
955 break;
956 }
958 if (!valid_page && cdb_page_code != MODE_SENSE_RETURN_ALL)
959 {
960 srb->SrbStatus = SRB_STATUS_ERROR;
961 }
962 else if(offset < srb->DataTransferLength)
963 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
964 else
965 srb->SrbStatus = SRB_STATUS_SUCCESS;
966 srb->DataTransferLength = min(srb->DataTransferLength, offset);
967 srb->ScsiStatus = 0;
968 memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
970 //FUNCTION_EXIT();
972 return TRUE;
973 }
975 static ULONG
976 XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
977 {
978 PSENSE_DATA sd = srb->SenseInfoBuffer;
980 UNREFERENCED_PARAMETER(xvdd);
982 if (!srb->SenseInfoBuffer)
983 return 0;
985 sd->ErrorCode = 0x70;
986 sd->Valid = 1;
987 sd->SenseKey = sense_key;
988 sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
989 sd->AdditionalSenseCode = additional_sense_code;
990 return sizeof(SENSE_DATA);
991 }
993 static VOID
994 XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
995 {
996 if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
997 return;
998 XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
999 srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
1002 static BOOLEAN
1003 XenVbd_HandleEventSynchronised(PVOID DeviceExtension, PVOID context)
1005 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
1006 PSCSI_REQUEST_BLOCK srb;
1007 RING_IDX i, rp;
1008 ULONG j;
1009 blkif_response_t *rep;
1010 int block_count;
1011 int more_to_do = TRUE;
1012 blkif_shadow_t *shadow;
1013 ULONG suspend_resume_state_pdo;
1015 UNREFERENCED_PARAMETER(context);
1017 //if (dump_mode) FUNCTION_ENTER();
1019 suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
1020 KeMemoryBarrier();
1022 if (suspend_resume_state_pdo != xvdd->device_state->suspend_resume_state_fdo)
1024 //FUNCTION_ENTER();
1025 switch (suspend_resume_state_pdo)
1027 case SR_STATE_SUSPENDING:
1028 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_SUSPENDING\n"));
1029 break;
1030 case SR_STATE_RESUMING:
1031 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_RESUMING\n"));
1032 XenVbd_InitFromConfig(xvdd);
1033 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1034 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1035 break;
1036 case SR_STATE_RUNNING:
1037 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1038 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1039 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1040 default:
1041 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1042 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1043 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1044 break;
1046 KeMemoryBarrier();
1049 if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
1051 return TRUE;
1054 while (more_to_do)
1056 rp = xvdd->ring.sring->rsp_prod;
1057 KeMemoryBarrier();
1058 for (i = xvdd->ring.rsp_cons; i < rp; i++)
1060 rep = XenVbd_GetResponse(xvdd, i);
1061 /*
1062 * This code is to automatically detect if the backend is using the same
1063 * bit width or a different bit width to us. Later versions of Xen do this
1064 * via a xenstore value, but not all. That 0x0fffffff (notice
1065 * that the msb is not actually set, so we don't have any problems with
1066 * sign extending) is to signify the last entry on the right, which is
1067 * different under 32 and 64 bits, and that is why we set it up there.
1069 * To do the detection, we put two initial entries on the ring, with an op
1070 * of 0xff (which is invalid). The first entry is mostly okay, but the
1071 * second will be grossly misaligned if the backend bit width is different,
1072 * and we detect this and switch frontend structures.
1073 */
1074 switch (xvdd->ring_detect_state)
1076 case RING_DETECT_STATE_NOT_STARTED:
1077 KdPrint((__DRIVER_NAME " premature IRQ\n"));
1078 break;
1079 case RING_DETECT_STATE_DETECT1:
1080 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));
1081 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));
1082 xvdd->ring_detect_state = RING_DETECT_STATE_DETECT2;
1083 break;
1084 case RING_DETECT_STATE_DETECT2:
1085 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));
1086 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));
1087 *xvdd->event_channel_ptr |= 0x80000000;
1088 if (rep->operation != 0xff)
1090 KdPrint((__DRIVER_NAME " switching to 'other' ring size\n"));
1091 xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
1092 xvdd->use_other = TRUE;
1093 *xvdd->event_channel_ptr |= 0x40000000;
1095 xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
1096 break;
1097 case RING_DETECT_STATE_COMPLETE:
1098 shadow = &xvdd->shadows[rep->id];
1099 srb = shadow->srb;
1100 //KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1101 ASSERT(srb != NULL);
1102 block_count = decode_cdb_length(srb);
1103 block_count *= xvdd->bytes_per_sector / 512;
1104 /* 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 */
1105 if (rep->status == BLKIF_RSP_OKAY || (dump_mode && dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
1106 srb->SrbStatus = SRB_STATUS_SUCCESS;
1107 else
1109 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
1110 if (decode_cdb_is_read(srb))
1111 KdPrint((__DRIVER_NAME " Operation = Read\n"));
1112 else
1113 KdPrint((__DRIVER_NAME " Operation = Write\n"));
1114 if (!dump_mode)
1116 KdPrint((__DRIVER_NAME " Sector = %08X, Count = %d\n", (ULONG)shadow->req.sector_number, block_count));
1117 KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
1118 KdPrint((__DRIVER_NAME " Physical = %08x%08x\n", MmGetPhysicalAddress(shadow->system_address).HighPart, MmGetPhysicalAddress(shadow->system_address).LowPart));
1119 KdPrint((__DRIVER_NAME " PFN = %08x\n", (ULONG)(MmGetPhysicalAddress(shadow->system_address).QuadPart >> PAGE_SHIFT)));
1121 for (j = 0; j < shadow->req.nr_segments; j++)
1123 KdPrint((__DRIVER_NAME " gref = %d\n", shadow->req.seg[j].gref));
1124 KdPrint((__DRIVER_NAME " first_sect = %d\n", shadow->req.seg[j].first_sect));
1125 KdPrint((__DRIVER_NAME " last_sect = %d\n", shadow->req.seg[j].last_sect));
1128 srb->SrbStatus = SRB_STATUS_ERROR;
1129 srb->ScsiStatus = 0x02;
1130 xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
1131 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1132 XenVbd_MakeAutoSense(xvdd, srb);
1134 if (shadow->aligned_buffer_in_use)
1136 ASSERT(xvdd->aligned_buffer_in_use);
1137 xvdd->aligned_buffer_in_use = FALSE;
1138 if (decode_cdb_is_read(srb))
1139 memcpy(shadow->system_address, xvdd->aligned_buffer, block_count * 512);
1142 for (j = 0; j < shadow->req.nr_segments; j++)
1144 if (dump_mode)
1146 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1147 shadow->req.seg[j].gref, TRUE, (ULONG)'XPDO');
1149 else
1151 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1152 shadow->req.seg[j].gref, FALSE, (ULONG)'XVBD');
1155 shadow->aligned_buffer_in_use = FALSE;
1156 shadow->srb = NULL;
1157 put_shadow_on_freelist(xvdd, shadow);
1158 //if (dump_mode) KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1159 StorPortNotification(RequestComplete, xvdd, srb);
1160 break;
1164 xvdd->ring.rsp_cons = i;
1165 if (i != xvdd->ring.req_prod_pvt)
1167 RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
1169 else
1171 xvdd->ring.sring->rsp_event = i + 1;
1172 more_to_do = FALSE;
1176 //if (start_ring_detect_state == RING_DETECT_STATE_COMPLETE)
1177 XenVbd_PutQueuedSrbsOnRing(xvdd);
1179 if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
1181 if (xvdd->inactive || xvdd->shadow_free == SHADOW_ENTRIES)
1183 /* all entries are purged from the list (or we are inactive). ready to suspend */
1184 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1185 KeMemoryBarrier();
1186 KdPrint((__DRIVER_NAME " Set fdo state SR_STATE_SUSPENDING\n"));
1187 KdPrint((__DRIVER_NAME " Notifying event channel %d\n", xvdd->device_state->pdo_event_channel));
1188 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1191 //if (dump_mode) FUNCTION_EXIT();
1193 return TRUE;
1196 static BOOLEAN
1197 XenVbd_HandleEvent(PVOID DeviceExtension)
1199 BOOLEAN retval;
1200 STOR_LOCK_HANDLE lock_handle;
1202 //if (dump_mode) FUNCTION_ENTER();
1203 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
1204 retval = StorPortSynchronizeAccess(DeviceExtension, XenVbd_HandleEventSynchronised, NULL);
1205 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1206 //if (dump_mode) FUNCTION_EXIT();
1207 return retval;
1210 /* this is only used during hiber and dump */
1211 static BOOLEAN
1212 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
1214 BOOLEAN retval;
1216 //FUNCTION_ENTER();
1217 retval = XenVbd_HandleEventSynchronised(DeviceExtension, NULL);
1218 //FUNCTION_EXIT();
1219 return retval;
1222 static BOOLEAN
1223 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
1225 PUCHAR data_buffer;
1226 PSCSI_PNP_REQUEST_BLOCK sprb;
1227 PMINIPORT_DUMP_POINTERS dump_pointers;
1228 PCDB cdb;
1229 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1230 ULONG data_transfer_length;
1231 UCHAR srb_status = SRB_STATUS_PENDING;
1232 STOR_LOCK_HANDLE lock_handle;
1234 //if (dump_mode) FUNCTION_ENTER();
1235 //if (dump_mode) KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1237 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
1239 data_transfer_length = srb->DataTransferLength;
1241 if (xvdd->inactive)
1243 KdPrint((__DRIVER_NAME " Inactive srb->Function = %08X\n", srb->Function));
1244 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1245 StorPortNotification(RequestComplete, DeviceExtension, srb);
1246 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1247 return TRUE;
1250 if (xvdd->ring_detect_state == RING_DETECT_STATE_NOT_STARTED)
1252 XenVbd_StartRingDetection(DeviceExtension);
1255 // If we haven't enumerated all the devices yet then just defer the request
1256 if (xvdd->ring_detect_state < RING_DETECT_STATE_COMPLETE)
1258 srb->SrbStatus = SRB_STATUS_BUSY;
1259 StorPortNotification(RequestComplete, DeviceExtension, srb);
1260 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Still figuring out ring)\n"));
1261 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1262 return TRUE;
1265 if (!dump_mode && xvdd->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
1267 //KdPrint((__DRIVER_NAME " --> HwStorStartIo (Suspending/Resuming)\n"));
1268 srb->SrbStatus = SRB_STATUS_BUSY;
1269 StorPortNotification(RequestComplete, DeviceExtension, srb);
1270 //KdPrint((__DRIVER_NAME " <-- HwStorStartIo (Suspending/Resuming)\n"));
1271 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1272 return TRUE;
1275 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
1277 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1278 StorPortNotification(RequestComplete, DeviceExtension, srb);
1279 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun));
1280 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1281 return TRUE;
1284 switch (srb->Function)
1286 case SRB_FUNCTION_EXECUTE_SCSI:
1287 cdb = (PCDB)srb->Cdb;
1289 switch(cdb->CDB6GENERIC.OperationCode)
1291 case SCSIOP_TEST_UNIT_READY:
1292 if (dump_mode)
1293 KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
1294 srb_status = SRB_STATUS_SUCCESS;
1295 srb->ScsiStatus = 0;
1296 break;
1297 case SCSIOP_INQUIRY:
1298 if (dump_mode)
1299 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
1300 // KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
1301 // KdPrint((__DRIVER_NAME " (Length = %d)\n", srb->DataTransferLength));
1303 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1304 data_buffer = srb->DataBuffer;
1305 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1306 srb_status = SRB_STATUS_SUCCESS;
1307 switch (xvdd->device_type)
1309 case XENVBD_DEVICETYPE_DISK:
1310 if ((srb->Cdb[1] & 1) == 0)
1312 if (srb->Cdb[2])
1314 srb_status = SRB_STATUS_ERROR;
1316 else
1318 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1319 id->DeviceType = DIRECT_ACCESS_DEVICE;
1320 id->Versions = 4; /* minimum that WHQL says we must support */
1321 id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
1322 id->HiSupport = 1; /* WHQL test says we should set this */
1323 //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1324 id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
1325 id->CommandQueue = 1;
1326 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1327 memcpy(id->ProductId, scsi_disk_model, 16); // product id
1328 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1329 data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
1332 else
1334 switch (srb->Cdb[2])
1336 case VPD_SUPPORTED_PAGES: /* list of pages we support */
1337 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1338 data_buffer[1] = VPD_SUPPORTED_PAGES;
1339 data_buffer[2] = 0x00;
1340 data_buffer[3] = 2;
1341 data_buffer[4] = 0x00;
1342 data_buffer[5] = 0x80;
1343 data_transfer_length = 6;
1344 break;
1345 case VPD_SERIAL_NUMBER: /* serial number */
1346 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1347 data_buffer[1] = VPD_SERIAL_NUMBER;
1348 data_buffer[2] = 0x00;
1349 data_buffer[3] = 8;
1350 memset(&data_buffer[4], ' ', 8);
1351 data_transfer_length = 12;
1352 break;
1353 case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
1354 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1355 data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
1356 data_buffer[2] = 0x00;
1357 data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
1358 data_buffer[4] = 2; /* ASCII */
1359 data_buffer[5] = 1; /* VendorId */
1360 data_buffer[6] = 0;
1361 data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
1362 memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
1363 data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
1364 break;
1365 default:
1366 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1367 srb_status = SRB_STATUS_ERROR;
1368 break;
1371 break;
1372 case XENVBD_DEVICETYPE_CDROM:
1373 if ((srb->Cdb[1] & 1) == 0)
1375 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1376 id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
1377 id->RemovableMedia = 1;
1378 id->Versions = 3;
1379 id->ResponseDataFormat = 0;
1380 id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1381 id->CommandQueue = 1;
1382 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1383 memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
1384 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1385 data_transfer_length = sizeof(INQUIRYDATA);
1387 else
1389 switch (srb->Cdb[2])
1391 case 0x00:
1392 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1393 data_buffer[1] = 0x00;
1394 data_buffer[2] = 0x00;
1395 data_buffer[3] = 2;
1396 data_buffer[4] = 0x00;
1397 data_buffer[5] = 0x80;
1398 data_transfer_length = 6;
1399 break;
1400 case 0x80:
1401 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1402 data_buffer[1] = 0x80;
1403 data_buffer[2] = 0x00;
1404 data_buffer[3] = 8;
1405 data_buffer[4] = 0x31;
1406 data_buffer[5] = 0x32;
1407 data_buffer[6] = 0x33;
1408 data_buffer[7] = 0x34;
1409 data_buffer[8] = 0x35;
1410 data_buffer[9] = 0x36;
1411 data_buffer[10] = 0x37;
1412 data_buffer[11] = 0x38;
1413 data_transfer_length = 12;
1414 break;
1415 default:
1416 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1417 srb_status = SRB_STATUS_ERROR;
1418 break;
1421 break;
1422 default:
1423 //KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", xvdd->device_type));
1424 srb_status = SRB_STATUS_ERROR;
1425 break;
1427 break;
1428 case SCSIOP_READ_CAPACITY:
1429 if (dump_mode)
1430 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1431 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1432 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1433 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1434 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1435 data_buffer = srb->DataBuffer;
1436 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1437 if ((xvdd->total_sectors - 1) >> 32)
1439 data_buffer[0] = 0xff;
1440 data_buffer[1] = 0xff;
1441 data_buffer[2] = 0xff;
1442 data_buffer[3] = 0xff;
1444 else
1446 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1447 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1448 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1449 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1451 data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1452 data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1453 data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1454 data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1455 data_transfer_length = 8;
1456 srb->ScsiStatus = 0;
1457 srb_status = SRB_STATUS_SUCCESS;
1458 break;
1459 case SCSIOP_READ_CAPACITY16:
1460 if (dump_mode)
1461 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1462 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1463 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1464 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1465 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1466 data_buffer = srb->DataBuffer;
1467 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1468 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
1469 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
1470 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
1471 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
1472 data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1473 data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1474 data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1475 data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1476 data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1477 data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1478 data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1479 data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1480 data_transfer_length = 12;
1481 srb->ScsiStatus = 0;
1482 srb_status = SRB_STATUS_SUCCESS;
1483 break;
1484 case SCSIOP_MODE_SENSE:
1485 case SCSIOP_MODE_SENSE10:
1486 if (dump_mode)
1487 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));
1488 data_transfer_length = XenVbd_FillModePage(xvdd, srb);
1489 srb_status = SRB_STATUS_SUCCESS;
1490 break;
1491 case SCSIOP_READ:
1492 case SCSIOP_READ16:
1493 case SCSIOP_WRITE:
1494 case SCSIOP_WRITE16:
1495 //KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1496 XenVbd_PutSrbOnList(xvdd, srb);
1497 XenVbd_PutQueuedSrbsOnRing(xvdd);
1498 break;
1499 case SCSIOP_VERIFY:
1500 case SCSIOP_VERIFY16:
1501 // Should we do more here?
1502 if (dump_mode)
1503 KdPrint((__DRIVER_NAME " Command = VERIFY\n"));
1504 srb_status = SRB_STATUS_SUCCESS;
1505 break;
1506 #if 0
1507 case SCSIOP_REPORT_LUNS:
1508 if (dump_mode)
1509 KdPrint((__DRIVER_NAME " Command = REPORT_LUNS\n"));
1510 switch (srb->Cdb[1])
1513 srb_status = SRB_STATUS_SUCCESS;;
1514 break;
1515 #endif
1516 case SCSIOP_REQUEST_SENSE:
1517 if (dump_mode)
1518 KdPrint((__DRIVER_NAME " Command = REQUEST_SENSE\n"));
1519 data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
1520 srb_status = SRB_STATUS_SUCCESS;
1521 break;
1522 case SCSIOP_READ_TOC:
1523 if (dump_mode)
1524 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
1525 data_buffer = srb->DataBuffer;
1526 /*
1527 #define READ_TOC_FORMAT_TOC 0x00
1528 #define READ_TOC_FORMAT_SESSION 0x01
1529 #define READ_TOC_FORMAT_FULL_TOC 0x02
1530 #define READ_TOC_FORMAT_PMA 0x03
1531 #define READ_TOC_FORMAT_ATIP 0x04
1532 */
1533 // KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
1534 // KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
1535 // KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
1536 // KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
1537 // KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
1538 // KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
1539 // KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
1540 switch (cdb->READ_TOC.Format2)
1542 case READ_TOC_FORMAT_TOC:
1543 data_buffer[0] = 0; // length MSB
1544 data_buffer[1] = 10; // length LSB
1545 data_buffer[2] = 1; // First Track
1546 data_buffer[3] = 1; // Last Track
1547 data_buffer[4] = 0; // Reserved
1548 data_buffer[5] = 0x14; // current position data + uninterrupted data
1549 data_buffer[6] = 1; // last complete track
1550 data_buffer[7] = 0; // reserved
1551 data_buffer[8] = 0; // MSB Block
1552 data_buffer[9] = 0;
1553 data_buffer[10] = 0;
1554 data_buffer[11] = 0; // LSB Block
1555 data_transfer_length = 12;
1556 srb_status = SRB_STATUS_SUCCESS;
1557 break;
1558 case READ_TOC_FORMAT_SESSION:
1559 case READ_TOC_FORMAT_FULL_TOC:
1560 case READ_TOC_FORMAT_PMA:
1561 case READ_TOC_FORMAT_ATIP:
1562 srb_status = SRB_STATUS_ERROR;
1563 break;
1564 default:
1565 srb_status = SRB_STATUS_ERROR;
1566 break;
1568 break;
1569 case SCSIOP_START_STOP_UNIT:
1570 KdPrint((__DRIVER_NAME " Command = SCSIOP_START_STOP_UNIT\n"));
1571 srb_status = SRB_STATUS_SUCCESS;
1572 break;
1573 case SCSIOP_RESERVE_UNIT:
1574 KdPrint((__DRIVER_NAME " Command = SCSIOP_RESERVE_UNIT\n"));
1575 srb_status = SRB_STATUS_SUCCESS;
1576 break;
1577 case SCSIOP_RELEASE_UNIT:
1578 KdPrint((__DRIVER_NAME " Command = SCSIOP_RELEASE_UNIT\n"));
1579 srb_status = SRB_STATUS_SUCCESS;
1580 break;
1581 default:
1582 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
1583 srb_status = SRB_STATUS_ERROR;
1584 break;
1586 if (srb_status == SRB_STATUS_ERROR)
1588 KdPrint((__DRIVER_NAME " EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
1589 if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
1591 xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
1592 xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
1594 srb->SrbStatus = srb_status;
1595 srb->ScsiStatus = 0x02;
1596 XenVbd_MakeAutoSense(xvdd, srb);
1597 StorPortNotification(RequestComplete, DeviceExtension, srb);
1599 else if (srb_status != SRB_STATUS_PENDING)
1601 if (data_transfer_length > srb->DataTransferLength)
1602 KdPrint((__DRIVER_NAME " data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
1604 if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
1606 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
1607 srb->DataTransferLength = data_transfer_length;
1609 else
1611 srb->SrbStatus = srb_status;
1613 xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
1614 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1615 StorPortNotification(RequestComplete, DeviceExtension, srb);
1617 break;
1618 case SRB_FUNCTION_IO_CONTROL:
1619 KdPrint((__DRIVER_NAME " SRB_FUNCTION_IO_CONTROL\n"));
1620 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1621 StorPortNotification(RequestComplete, DeviceExtension, srb);
1622 break;
1623 case SRB_FUNCTION_FLUSH:
1624 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1625 srb->SrbStatus = SRB_STATUS_SUCCESS;
1626 StorPortNotification(RequestComplete, DeviceExtension, srb);
1627 break;
1628 case SRB_FUNCTION_PNP:
1629 KdPrint((__DRIVER_NAME " SRB_FUNCTION_PNP\n"));
1630 sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
1631 switch (sprb->PnPAction)
1633 case StorStartDevice:
1634 KdPrint((__DRIVER_NAME " StorStartDevice\n"));
1635 break;
1636 case StorRemoveDevice:
1637 KdPrint((__DRIVER_NAME " StorRemoveDevice\n"));
1638 break;
1639 case StorStopDevice:
1640 KdPrint((__DRIVER_NAME " StorStopDevice\n"));
1641 break;
1642 case StorQueryCapabilities:
1643 KdPrint((__DRIVER_NAME " StorQueryCapabilities\n"));
1644 break;
1645 case StorFilterResourceRequirements:
1646 KdPrint((__DRIVER_NAME " StorFilterResourceRequirements\n"));
1647 break;
1648 default:
1649 KdPrint((__DRIVER_NAME " Stor%d\n", sprb->PnPAction));
1650 break;
1652 KdPrint((__DRIVER_NAME " SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
1653 srb->SrbStatus = SRB_STATUS_SUCCESS;
1654 StorPortNotification(RequestComplete, DeviceExtension, srb);
1655 break;
1656 case SRB_FUNCTION_DUMP_POINTERS:
1657 KdPrint((__DRIVER_NAME " SRB_FUNCTION_DUMP_POINTERS\n"));
1658 KdPrint((__DRIVER_NAME " DataTransferLength = %d\n", srb->DataTransferLength));
1659 //RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
1660 dump_pointers = srb->DataBuffer;
1661 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1662 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1663 KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1664 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1665 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1666 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1667 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1668 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1669 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1670 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1671 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1672 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1673 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1674 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1675 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1676 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1677 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1679 dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
1680 dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
1681 RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
1682 dump_pointers->AdapterObject = NULL;
1683 dump_pointers->MappedRegisterBase = 0;
1684 dump_pointers->CommonBufferSize = 0;
1685 dump_pointers->MiniportPrivateDumpData = (PVOID)xvdd->device_base;
1686 //dump_pointers->SystemIoBusNumber = 0;
1687 dump_pointers->AdapterInterfaceType = Internal;
1688 dump_pointers->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
1689 dump_pointers->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
1690 dump_pointers->AlignmentMask = 0;
1691 dump_pointers->NumberOfAccessRanges = 1;
1692 dump_pointers->NumberOfBuses = 1;
1693 dump_pointers->Master = TRUE;
1694 dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1695 dump_pointers->MaximumNumberOfTargets = 2;
1697 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1698 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1699 KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1700 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1701 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1702 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1703 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1704 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1705 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1706 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1707 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1708 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1709 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1710 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1711 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1712 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1713 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1715 srb->SrbStatus = SRB_STATUS_SUCCESS;
1716 StorPortNotification(RequestComplete, DeviceExtension, srb);
1717 break;
1718 case SRB_FUNCTION_SHUTDOWN:
1719 KdPrint((__DRIVER_NAME " SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1720 srb->SrbStatus = SRB_STATUS_SUCCESS;
1721 StorPortNotification(RequestComplete, DeviceExtension, srb);
1722 break;
1723 default:
1724 KdPrint((__DRIVER_NAME " Unhandled srb->Function = %08X\n", srb->Function));
1725 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1726 StorPortNotification(RequestComplete, DeviceExtension, srb);
1727 break;
1730 //if (dump_mode) FUNCTION_EXIT();
1731 StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
1732 return TRUE;
1735 static BOOLEAN
1736 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
1738 //PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1740 UNREFERENCED_PARAMETER(DeviceExtension);
1741 UNREFERENCED_PARAMETER(PathId);
1743 FUNCTION_ENTER();
1745 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1747 FUNCTION_EXIT();
1750 return TRUE;
1753 static SCSI_ADAPTER_CONTROL_STATUS
1754 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
1756 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1757 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
1758 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
1759 //KIRQL OldIrql;
1761 FUNCTION_ENTER();
1762 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1763 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
1765 switch (ControlType)
1767 case ScsiQuerySupportedControlTypes:
1768 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
1769 KdPrint((__DRIVER_NAME " ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
1770 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
1771 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
1772 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
1773 break;
1774 case ScsiStopAdapter:
1775 KdPrint((__DRIVER_NAME " ScsiStopAdapter\n"));
1776 /* I don't think we actually have to do anything here... xenpci cleans up all the xenbus stuff for us */
1777 break;
1778 case ScsiRestartAdapter:
1779 KdPrint((__DRIVER_NAME " ScsiRestartAdapter\n"));
1780 if (!xvdd->inactive)
1782 /*
1783 if (XenVbd_InitConfig(xvdd) != SP_RETURN_FOUND)
1784 KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
1785 */
1786 if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND)
1787 KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
1788 xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
1789 //XenVbd_StartRingDetection(xvdd);
1791 break;
1792 case ScsiSetBootConfig:
1793 KdPrint((__DRIVER_NAME " ScsiSetBootConfig\n"));
1794 break;
1795 case ScsiSetRunningConfig:
1796 KdPrint((__DRIVER_NAME " ScsiSetRunningConfig\n"));
1797 break;
1798 default:
1799 KdPrint((__DRIVER_NAME " UNKNOWN\n"));
1800 break;
1803 FUNCTION_EXIT();
1805 return Status;
1808 NTSTATUS
1809 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
1811 ULONG status;
1812 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
1813 HW_INITIALIZATION_DATA HwInitializationData;
1814 //PVOID driver_extension;
1815 //PUCHAR ptr;
1816 OBJECT_ATTRIBUTES oa;
1817 HANDLE service_handle;
1818 UNICODE_STRING param_name;
1819 HANDLE param_handle;
1820 UNICODE_STRING value_name;
1821 CHAR buf[256];
1822 ULONG buf_len;
1823 PKEY_VALUE_PARTIAL_INFORMATION kpv;
1825 FUNCTION_ENTER();
1826 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1827 KdPrint((__DRIVER_NAME " DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
1829 /* RegistryPath == NULL when we are invoked as a crash dump driver */
1830 if (!RegistryPath)
1832 dump_mode = TRUE;
1835 if (!dump_mode)
1837 InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
1838 status = ZwOpenKey(&service_handle, KEY_READ, &oa);
1839 if(!NT_SUCCESS(status))
1841 KdPrint((__DRIVER_NAME " ZwOpenKey(Service) returned %08x\n", status));
1843 else
1845 RtlInitUnicodeString(&param_name, L"Parameters");
1846 InitializeObjectAttributes(&oa, &param_name, OBJ_CASE_INSENSITIVE, service_handle, NULL);
1847 status = ZwOpenKey(&param_handle, KEY_READ, &oa);
1848 if(!NT_SUCCESS(status))
1850 KdPrint((__DRIVER_NAME " ZwOpenKey(Parameters) returned %08x\n", status));
1852 else
1854 kpv = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
1855 RtlFillMemory(scsi_device_manufacturer, 8, ' ');
1856 RtlFillMemory(scsi_disk_model, 16, ' ');
1857 RtlFillMemory(scsi_cdrom_model, 16, ' ');
1859 RtlInitUnicodeString(&value_name, L"Manufacturer");
1860 buf_len = 256;
1861 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
1862 if(NT_SUCCESS(status))
1863 wcstombs(scsi_device_manufacturer, (PWCHAR)kpv->Data, min(kpv->DataLength, 8));
1864 else
1865 RtlStringCbCopyA(scsi_device_manufacturer, 8, "XEN ");
1867 RtlInitUnicodeString(&value_name, L"Disk_Model");
1868 buf_len = 256;
1869 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
1870 if(NT_SUCCESS(status))
1871 wcstombs(scsi_disk_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
1872 else
1873 RtlStringCbCopyA(scsi_disk_model, 16, "PV DISK ");
1875 RtlInitUnicodeString(&value_name, L"CDROM_Model");
1876 buf_len = 256;
1877 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
1878 if(NT_SUCCESS(status))
1879 wcstombs(scsi_cdrom_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
1880 else
1881 RtlStringCbCopyA(scsi_cdrom_model, 16, "PV CDROM ");
1882 ZwClose(param_handle);
1884 ZwClose(service_handle);
1886 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
1887 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
1888 VHwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* maybe should be internal? */
1889 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
1890 VHwInitializationData.SpecificLuExtensionSize = 0;
1891 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
1892 VHwInitializationData.NumberOfAccessRanges = 1;
1893 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
1894 //VHwInitializationData.NeedPhysicalAddresses = TRUE;
1895 VHwInitializationData.TaggedQueuing = TRUE;
1896 VHwInitializationData.AutoRequestSense = TRUE;
1897 VHwInitializationData.MultipleRequestPerLu = TRUE;
1898 VHwInitializationData.ReceiveEvent = TRUE;
1899 VHwInitializationData.PortVersionFlags = 0;
1900 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
1901 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
1902 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
1903 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
1904 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
1905 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
1907 else
1909 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
1910 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
1911 HwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* not Internal */
1912 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
1913 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
1914 HwInitializationData.NumberOfAccessRanges = 1;
1915 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1916 HwInitializationData.NeedPhysicalAddresses = TRUE;
1917 HwInitializationData.TaggedQueuing = FALSE;
1918 HwInitializationData.AutoRequestSense = TRUE;
1919 HwInitializationData.MultipleRequestPerLu = FALSE;
1920 HwInitializationData.ReceiveEvent = TRUE;
1921 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
1922 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
1923 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
1924 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
1925 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
1926 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
1927 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
1930 if(!NT_SUCCESS(status))
1932 KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", status));
1935 FUNCTION_EXIT();
1937 return status;