win-pvdrivers

view xenvbd/xenvbd_storport.c @ 833:66e79b88f301

just a little quieter
author James Harper <james.harper@bendigoit.com.au>
date Wed Jan 26 12:13:19 2011 +1100 (2011-01-26)
parents d0130ea66500
children e48c6f765e5f
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 ASSERT(shadow);
507 ASSERT(!shadow->aligned_buffer_in_use);
508 ASSERT(!shadow->srb);
509 shadow->req.sector_number = sector_number;
510 shadow->req.handle = 0;
511 shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
512 shadow->req.nr_segments = 0;
513 shadow->srb = srb;
514 shadow->system_address = system_address;
516 if (!dump_mode)
517 {
518 if ((ULONG_PTR)shadow->system_address & 511)
519 {
520 xvdd->aligned_buffer_in_use = TRUE;
521 ptr = xvdd->aligned_buffer;
522 if (!decode_cdb_is_read(srb))
523 memcpy(ptr, shadow->system_address, block_count * 512);
524 shadow->aligned_buffer_in_use = TRUE;
525 }
526 else
527 {
528 ptr = shadow->system_address;
529 shadow->aligned_buffer_in_use = FALSE;
530 }
531 }
532 else
533 {
534 ASSERT(!((ULONG_PTR)shadow->system_address & 511));
535 ptr = srb->DataBuffer;
536 shadow->aligned_buffer_in_use = FALSE;
537 if (block_count > max_dump_mode_blocks)
538 {
539 max_dump_mode_blocks = block_count;
540 KdPrint((__DRIVER_NAME " max_dump_mode_blocks = %d\n", max_dump_mode_blocks));
541 }
542 if (srb->DataTransferLength > max_dump_mode_length)
543 {
544 max_dump_mode_length = srb->DataTransferLength;
545 KdPrint((__DRIVER_NAME " max_dump_mode_length = %d\n", max_dump_mode_length));
546 }
547 }
549 //KdPrint((__DRIVER_NAME " sector_number = %d, block_count = %d\n", (ULONG)shadow->req.sector_number, block_count));
550 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
551 //KdPrint((__DRIVER_NAME " system_address = %p\n", shadow->system_address));
553 //KdPrint((__DRIVER_NAME " handle = %d\n", shadow->req.handle));
554 //KdPrint((__DRIVER_NAME " operation = %d\n", shadow->req.operation));
556 while (remaining > 0)
557 {
558 PHYSICAL_ADDRESS physical_address;
560 if (!dump_mode)
561 {
562 physical_address = MmGetPhysicalAddress(ptr);
563 gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
564 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, (ULONG)'XVBD');
565 }
566 else
567 {
568 ULONG length;
569 physical_address.QuadPart = 0;
570 physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
571 //KdPrint((__DRIVER_NAME " pfn = %08x, length = %d\n", (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), length));
572 gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context, 0,
573 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE,
574 xvdd->dump_grant_refs[shadow->req.nr_segments], (ULONG)'XPDO');
575 }
576 if (gref == INVALID_GRANT_REF)
577 {
578 ULONG i;
579 for (i = 0; i < shadow->req.nr_segments; i++)
580 {
581 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
582 shadow->req.seg[i].gref, FALSE, (ULONG)'XVBD');
583 }
584 if (shadow->aligned_buffer_in_use)
585 {
586 shadow->aligned_buffer_in_use = FALSE;
587 xvdd->aligned_buffer_in_use = FALSE;
588 }
589 /* put the srb back at the start of the queue */
590 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
591 put_shadow_on_freelist(xvdd, shadow);
592 KdPrint((__DRIVER_NAME " Out of gref's. Deferring\n"));
593 return;
594 }
595 offset = physical_address.LowPart & (PAGE_SIZE - 1);
596 length = min(PAGE_SIZE - offset, remaining);
597 //if (dump_mode) KdPrint((__DRIVER_NAME " length = %d\n", length));
598 //if (dump_mode) KdPrint((__DRIVER_NAME " offset = %d\n", length));
599 ASSERT((offset & 511) == 0);
600 ASSERT((length & 511) == 0);
601 ASSERT(offset + length <= PAGE_SIZE);
602 shadow->req.seg[shadow->req.nr_segments].gref = gref;
603 shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset >> 9);
604 shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) >> 9) - 1);
605 //if (dump_mode) KdPrint((__DRIVER_NAME " gref = %d\n", shadow->req.seg[shadow->req.nr_segments].gref));
606 //if (dump_mode) KdPrint((__DRIVER_NAME " first_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].first_sect));
607 //if (dump_mode) KdPrint((__DRIVER_NAME " last_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].last_sect));
608 remaining -= length;
609 ptr += length;
610 shadow->req.nr_segments++;
611 }
613 //KdPrint((__DRIVER_NAME " nr_segments = %d\n", shadow->req.nr_segments));
615 XenVbd_PutRequest(xvdd, &shadow->req);
617 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
618 if (notify)
619 {
620 //KdPrint((__DRIVER_NAME " Notifying\n"));
621 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
622 }
623 }
624 //if (dump_mode) FUNCTION_EXIT();
625 }
627 static ULONG
628 XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
629 {
630 // PACCESS_RANGE AccessRange;
631 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
632 ULONG status;
633 // PXENPCI_XEN_DEVICE_DATA XenDeviceData;
634 PACCESS_RANGE access_range;
636 UNREFERENCED_PARAMETER(HwContext);
637 UNREFERENCED_PARAMETER(BusInformation);
638 UNREFERENCED_PARAMETER(LowerDevice);
639 UNREFERENCED_PARAMETER(ArgumentString);
641 FUNCTION_ENTER();
642 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
643 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
645 RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
646 *Again = FALSE;
648 KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
649 KdPrint((__DRIVER_NAME " BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
651 if (!dump_mode)
652 {
653 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
654 if (ConfigInfo->NumberOfAccessRanges != 1 && ConfigInfo->NumberOfAccessRanges != 2)
655 {
656 return SP_RETURN_BAD_CONFIG;
657 }
659 access_range = &((*(ConfigInfo->AccessRanges))[0]);
660 KdPrint((__DRIVER_NAME " RangeStart = %08x, RangeLength = %08x\n",
661 access_range->RangeStart.LowPart, access_range->RangeLength));
662 xvdd->device_base = StorPortGetDeviceBase(
663 DeviceExtension,
664 PNPBus, //AdapterInterfaceType,
665 ConfigInfo->SystemIoBusNumber,
666 access_range->RangeStart,
667 access_range->RangeLength,
668 !access_range->RangeInMemory);
669 if (!xvdd->device_base)
670 {
671 KdPrint((__DRIVER_NAME " StorPortGetDeviceBase failed\n"));
672 FUNCTION_EXIT();
673 return SP_RETURN_BAD_CONFIG;
674 }
675 status = XenVbd_InitConfig(xvdd);
676 if (status != SP_RETURN_FOUND)
677 {
678 FUNCTION_EXIT();
679 return status;
680 }
681 }
682 else
683 {
684 xvdd->device_base = ConfigInfo->Reserved;
685 }
687 status = XenVbd_InitFromConfig(xvdd);
688 if (status != SP_RETURN_FOUND)
689 {
690 FUNCTION_EXIT();
691 return status;
692 }
694 xvdd->aligned_buffer_in_use = FALSE;
695 /* align the buffer to PAGE_SIZE */
696 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
697 KdPrint((__DRIVER_NAME " aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
698 KdPrint((__DRIVER_NAME " aligned_buffer = %p\n", xvdd->aligned_buffer));
700 ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
701 ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
702 KdPrint((__DRIVER_NAME " ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength));
703 KdPrint((__DRIVER_NAME " ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
704 if (!dump_mode)
705 {
706 ConfigInfo->VirtualDevice = TRUE;
707 }
708 else
709 {
710 ConfigInfo->VirtualDevice = FALSE;
711 }
713 KdPrint((__DRIVER_NAME " ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice));
714 ConfigInfo->ScatterGather = TRUE;
715 ConfigInfo->Master = TRUE;
716 ConfigInfo->CachesData = FALSE;
717 ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
718 KdPrint((__DRIVER_NAME " ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses));
719 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
720 ConfigInfo->AlignmentMask = 0;
721 ConfigInfo->NumberOfBuses = 1;
722 ConfigInfo->InitiatorBusId[0] = 1;
723 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
724 ConfigInfo->MaximumNumberOfTargets = 2;
725 //ConfigInfo->BufferAccessScsiPortControlled = FALSE;
726 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
727 {
728 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
729 //ConfigInfo->Dma32BitAddresses = FALSE;
730 KdPrint((__DRIVER_NAME " Dma64BitAddresses supported\n"));
731 }
732 else
733 {
734 //ConfigInfo->Dma32BitAddresses = TRUE;
735 KdPrint((__DRIVER_NAME " Dma64BitAddresses not supported\n"));
736 }
738 FUNCTION_EXIT();
740 return SP_RETURN_FOUND;
741 }
743 static ULONG
744 XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
745 {
746 ULONG status;
748 FUNCTION_ENTER();
749 status = XenVbd_VirtualHwStorFindAdapter(DeviceExtension, HwContext, BusInformation, NULL, ArgumentString, ConfigInfo, Again);
750 FUNCTION_EXIT();
751 return status;
752 }
754 //do this in StartIo instead to prevent races with the driver initialisation
755 static VOID
756 XenVbd_StartRingDetection(PXENVBD_DEVICE_DATA xvdd)
757 {
758 blkif_request_t *req;
759 int notify;
761 xvdd->ring_detect_state = RING_DETECT_STATE_DETECT1;
762 RtlZeroMemory(xvdd->sring->ring, PAGE_SIZE - FIELD_OFFSET(blkif_sring_t, ring));
763 req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
764 req->operation = 0xff;
765 xvdd->ring.req_prod_pvt++;
766 req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
767 req->operation = 0xff;
768 xvdd->ring.req_prod_pvt++;
770 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
771 if (notify)
772 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
773 }
775 static BOOLEAN
776 XenVbd_HwStorInitialize(PVOID DeviceExtension)
777 {
778 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
780 FUNCTION_ENTER();
781 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
782 KdPrint((__DRIVER_NAME " dump_mode = %d\n", dump_mode));
784 if (!xvdd->inactive)
785 {
786 if (dump_mode)
787 {
788 if (xvdd->cached_use_other)
789 {
790 xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
791 xvdd->use_other = TRUE;
792 }
793 xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
794 }
795 InitializeListHead(&xvdd->srb_list);
796 }
797 FUNCTION_EXIT();
799 return TRUE;
800 }
802 static ULONG
803 XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
804 {
805 PMODE_PARAMETER_HEADER parameter_header = NULL;
806 PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
807 PMODE_PARAMETER_BLOCK param_block;
808 PMODE_FORMAT_PAGE format_page;
809 ULONG offset = 0;
810 UCHAR buffer[1024];
811 BOOLEAN valid_page = FALSE;
812 BOOLEAN cdb_llbaa;
813 BOOLEAN cdb_dbd;
814 UCHAR cdb_page_code;
815 USHORT cdb_allocation_length;
817 UNREFERENCED_PARAMETER(xvdd);
819 RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
820 RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
821 offset = 0;
823 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
825 switch (srb->Cdb[0])
826 {
827 case SCSIOP_MODE_SENSE:
828 cdb_llbaa = FALSE;
829 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
830 cdb_page_code = srb->Cdb[2] & 0x3f;
831 cdb_allocation_length = srb->Cdb[4];
832 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
833 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
834 parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
835 parameter_header->MediumType = 0;
836 parameter_header->DeviceSpecificParameter = 0;
837 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
838 {
839 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
840 parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
841 }
842 offset += sizeof(MODE_PARAMETER_HEADER);
843 break;
844 case SCSIOP_MODE_SENSE10:
845 cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
846 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
847 cdb_page_code = srb->Cdb[2] & 0x3f;
848 cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
849 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE10 llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
850 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
851 parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
852 parameter_header10->MediumType = 0;
853 parameter_header10->DeviceSpecificParameter = 0;
854 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
855 {
856 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
857 parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
858 }
859 offset += sizeof(MODE_PARAMETER_HEADER10);
860 break;
861 default:
862 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
863 return FALSE;
864 }
866 if (!cdb_dbd)
867 {
868 param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
869 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
870 {
871 if (xvdd->total_sectors >> 32)
872 {
873 param_block->DensityCode = 0xff;
874 param_block->NumberOfBlocks[0] = 0xff;
875 param_block->NumberOfBlocks[1] = 0xff;
876 param_block->NumberOfBlocks[2] = 0xff;
877 }
878 else
879 {
880 param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
881 param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
882 param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
883 param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
884 }
885 param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
886 param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
887 param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
888 }
889 offset += sizeof(MODE_PARAMETER_BLOCK);
890 }
891 switch (srb->Cdb[0])
892 {
893 case SCSIOP_MODE_SENSE:
894 parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
895 break;
896 case SCSIOP_MODE_SENSE10:
897 parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);
898 parameter_header10->BlockDescriptorLength[1] = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER10));
899 break;
900 }
901 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_FORMAT_DEVICE || cdb_page_code == MODE_SENSE_RETURN_ALL))
902 {
903 valid_page = TRUE;
904 format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
905 format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
906 format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
907 /* 256 sectors per track */
908 format_page->SectorsPerTrack[0] = 0x01;
909 format_page->SectorsPerTrack[1] = 0x00;
910 /* xxx bytes per sector */
911 format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
912 format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
913 format_page->HardSectorFormating = TRUE;
914 format_page->SoftSectorFormating = TRUE;
915 offset += sizeof(MODE_FORMAT_PAGE);
916 }
917 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_CACHING || cdb_page_code == MODE_SENSE_RETURN_ALL))
918 {
919 PMODE_CACHING_PAGE caching_page;
920 valid_page = TRUE;
921 caching_page = (PMODE_CACHING_PAGE)&buffer[offset];
922 caching_page->PageCode = MODE_PAGE_CACHING;
923 caching_page->PageLength = sizeof(MODE_CACHING_PAGE) - FIELD_OFFSET(MODE_CACHING_PAGE, PageLength);
924 // caching_page-> // all zeros is just fine... maybe
925 offset += sizeof(MODE_CACHING_PAGE);
926 }
927 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_MEDIUM_TYPES || cdb_page_code == MODE_SENSE_RETURN_ALL))
928 {
929 PUCHAR medium_types_page;
930 valid_page = TRUE;
931 medium_types_page = &buffer[offset];
932 medium_types_page[0] = MODE_PAGE_MEDIUM_TYPES;
933 medium_types_page[1] = 0x06;
934 medium_types_page[2] = 0;
935 medium_types_page[3] = 0;
936 medium_types_page[4] = 0;
937 medium_types_page[5] = 0;
938 medium_types_page[6] = 0;
939 medium_types_page[7] = 0;
940 offset += 8;
941 }
942 switch (srb->Cdb[0])
943 {
944 case SCSIOP_MODE_SENSE:
945 parameter_header->ModeDataLength = (UCHAR)(offset - 1);
946 break;
947 case SCSIOP_MODE_SENSE10:
948 parameter_header10->ModeDataLength[0] = (UCHAR)((offset - 2) >> 8);
949 parameter_header10->ModeDataLength[1] = (UCHAR)(offset - 2);
950 break;
951 }
953 if (!valid_page && cdb_page_code != MODE_SENSE_RETURN_ALL)
954 {
955 srb->SrbStatus = SRB_STATUS_ERROR;
956 }
957 else if(offset < srb->DataTransferLength)
958 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
959 else
960 srb->SrbStatus = SRB_STATUS_SUCCESS;
961 srb->DataTransferLength = min(srb->DataTransferLength, offset);
962 srb->ScsiStatus = 0;
963 memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
965 //FUNCTION_EXIT();
967 return TRUE;
968 }
970 static ULONG
971 XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
972 {
973 PSENSE_DATA sd = srb->SenseInfoBuffer;
975 UNREFERENCED_PARAMETER(xvdd);
977 if (!srb->SenseInfoBuffer)
978 return 0;
980 sd->ErrorCode = 0x70;
981 sd->Valid = 1;
982 sd->SenseKey = sense_key;
983 sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
984 sd->AdditionalSenseCode = additional_sense_code;
985 return sizeof(SENSE_DATA);
986 }
988 static VOID
989 XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
990 {
991 if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
992 return;
993 XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
994 srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
995 }
997 static BOOLEAN
998 XenVbd_HandleEventSynchronised(PVOID DeviceExtension, PVOID context)
999 {
1000 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
1001 PSCSI_REQUEST_BLOCK srb;
1002 RING_IDX i, rp;
1003 ULONG j;
1004 blkif_response_t *rep;
1005 int block_count;
1006 int more_to_do = TRUE;
1007 blkif_shadow_t *shadow;
1008 ULONG suspend_resume_state_pdo;
1010 UNREFERENCED_PARAMETER(context);
1012 //if (dump_mode) FUNCTION_ENTER();
1014 suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
1015 KeMemoryBarrier();
1017 if (suspend_resume_state_pdo != xvdd->device_state->suspend_resume_state_fdo)
1019 //FUNCTION_ENTER();
1020 switch (suspend_resume_state_pdo)
1022 case SR_STATE_SUSPENDING:
1023 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_SUSPENDING\n"));
1024 break;
1025 case SR_STATE_RESUMING:
1026 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_RESUMING\n"));
1027 XenVbd_InitFromConfig(xvdd);
1028 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1029 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1030 break;
1031 case SR_STATE_RUNNING:
1032 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
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 default:
1036 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1037 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1038 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1039 break;
1041 KeMemoryBarrier();
1044 if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
1046 return TRUE;
1049 while (more_to_do)
1051 rp = xvdd->ring.sring->rsp_prod;
1052 KeMemoryBarrier();
1053 for (i = xvdd->ring.rsp_cons; i < rp; i++)
1055 rep = XenVbd_GetResponse(xvdd, i);
1056 /*
1057 * This code is to automatically detect if the backend is using the same
1058 * bit width or a different bit width to us. Later versions of Xen do this
1059 * via a xenstore value, but not all. That 0x0fffffff (notice
1060 * that the msb is not actually set, so we don't have any problems with
1061 * sign extending) is to signify the last entry on the right, which is
1062 * different under 32 and 64 bits, and that is why we set it up there.
1064 * To do the detection, we put two initial entries on the ring, with an op
1065 * of 0xff (which is invalid). The first entry is mostly okay, but the
1066 * second will be grossly misaligned if the backend bit width is different,
1067 * and we detect this and switch frontend structures.
1068 */
1069 switch (xvdd->ring_detect_state)
1071 case RING_DETECT_STATE_NOT_STARTED:
1072 KdPrint((__DRIVER_NAME " premature IRQ\n"));
1073 break;
1074 case RING_DETECT_STATE_DETECT1:
1075 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));
1076 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));
1077 xvdd->ring_detect_state = RING_DETECT_STATE_DETECT2;
1078 break;
1079 case RING_DETECT_STATE_DETECT2:
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->event_channel_ptr |= 0x80000000;
1083 if (rep->operation != 0xff)
1085 KdPrint((__DRIVER_NAME " switching to 'other' ring size\n"));
1086 xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
1087 xvdd->use_other = TRUE;
1088 *xvdd->event_channel_ptr |= 0x40000000;
1090 xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
1091 break;
1092 case RING_DETECT_STATE_COMPLETE:
1093 shadow = &xvdd->shadows[rep->id];
1094 srb = shadow->srb;
1095 //KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1096 ASSERT(srb != NULL);
1097 block_count = decode_cdb_length(srb);
1098 block_count *= xvdd->bytes_per_sector / 512;
1099 /* 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 */
1100 if (rep->status == BLKIF_RSP_OKAY || (dump_mode && dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
1101 srb->SrbStatus = SRB_STATUS_SUCCESS;
1102 else
1104 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
1105 if (decode_cdb_is_read(srb))
1106 KdPrint((__DRIVER_NAME " Operation = Read\n"));
1107 else
1108 KdPrint((__DRIVER_NAME " Operation = Write\n"));
1109 if (!dump_mode)
1111 KdPrint((__DRIVER_NAME " Sector = %08X, Count = %d\n", (ULONG)shadow->req.sector_number, block_count));
1112 KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
1113 KdPrint((__DRIVER_NAME " Physical = %08x%08x\n", MmGetPhysicalAddress(shadow->system_address).HighPart, MmGetPhysicalAddress(shadow->system_address).LowPart));
1114 KdPrint((__DRIVER_NAME " PFN = %08x\n", (ULONG)(MmGetPhysicalAddress(shadow->system_address).QuadPart >> PAGE_SHIFT)));
1116 for (j = 0; j < shadow->req.nr_segments; j++)
1118 KdPrint((__DRIVER_NAME " gref = %d\n", shadow->req.seg[j].gref));
1119 KdPrint((__DRIVER_NAME " first_sect = %d\n", shadow->req.seg[j].first_sect));
1120 KdPrint((__DRIVER_NAME " last_sect = %d\n", shadow->req.seg[j].last_sect));
1123 srb->SrbStatus = SRB_STATUS_ERROR;
1124 srb->ScsiStatus = 0x02;
1125 xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
1126 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1127 XenVbd_MakeAutoSense(xvdd, srb);
1129 if (shadow->aligned_buffer_in_use)
1131 ASSERT(xvdd->aligned_buffer_in_use);
1132 xvdd->aligned_buffer_in_use = FALSE;
1133 if (decode_cdb_is_read(srb))
1134 memcpy(shadow->system_address, xvdd->aligned_buffer, block_count * 512);
1137 for (j = 0; j < shadow->req.nr_segments; j++)
1139 if (dump_mode)
1141 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1142 shadow->req.seg[j].gref, TRUE, (ULONG)'XPDO');
1144 else
1146 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1147 shadow->req.seg[j].gref, FALSE, (ULONG)'XVBD');
1150 shadow->aligned_buffer_in_use = FALSE;
1151 shadow->srb = NULL;
1152 put_shadow_on_freelist(xvdd, shadow);
1153 //if (dump_mode) KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1154 StorPortNotification(RequestComplete, xvdd, srb);
1155 break;
1159 xvdd->ring.rsp_cons = i;
1160 if (i != xvdd->ring.req_prod_pvt)
1162 RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
1164 else
1166 xvdd->ring.sring->rsp_event = i + 1;
1167 more_to_do = FALSE;
1171 //if (start_ring_detect_state == RING_DETECT_STATE_COMPLETE)
1172 XenVbd_PutQueuedSrbsOnRing(xvdd);
1174 if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
1176 if (xvdd->inactive || xvdd->shadow_free == SHADOW_ENTRIES)
1178 /* all entries are purged from the list (or we are inactive). ready to suspend */
1179 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1180 KeMemoryBarrier();
1181 KdPrint((__DRIVER_NAME " Set fdo state SR_STATE_SUSPENDING\n"));
1182 KdPrint((__DRIVER_NAME " Notifying event channel %d\n", xvdd->device_state->pdo_event_channel));
1183 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1186 //if (dump_mode) FUNCTION_EXIT();
1188 return TRUE;
1191 static BOOLEAN
1192 XenVbd_HandleEvent(PVOID DeviceExtension)
1194 BOOLEAN retval;
1196 //if (dump_mode) FUNCTION_ENTER();
1197 retval = StorPortSynchronizeAccess(DeviceExtension, XenVbd_HandleEventSynchronised, NULL);
1198 //if (dump_mode) FUNCTION_EXIT();
1199 return retval;
1202 /* this is only used during hiber and dump */
1203 static BOOLEAN
1204 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
1206 BOOLEAN retval;
1208 //FUNCTION_ENTER();
1209 retval = XenVbd_HandleEventSynchronised(DeviceExtension, NULL);
1210 //FUNCTION_EXIT();
1211 return retval;
1214 static BOOLEAN
1215 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
1217 PUCHAR data_buffer;
1218 PSCSI_PNP_REQUEST_BLOCK sprb;
1219 PMINIPORT_DUMP_POINTERS dump_pointers;
1220 PCDB cdb;
1221 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1222 ULONG data_transfer_length;
1223 UCHAR srb_status = SRB_STATUS_PENDING;
1225 //if (dump_mode) FUNCTION_ENTER();
1226 //if (dump_mode) KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1228 data_transfer_length = srb->DataTransferLength;
1230 if (xvdd->inactive)
1232 KdPrint((__DRIVER_NAME " Inactive srb->Function = %08X\n", srb->Function));
1233 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1234 StorPortNotification(RequestComplete, DeviceExtension, srb);
1235 return TRUE;
1238 if (xvdd->ring_detect_state == RING_DETECT_STATE_NOT_STARTED)
1240 XenVbd_StartRingDetection(DeviceExtension);
1243 // If we haven't enumerated all the devices yet then just defer the request
1244 if (xvdd->ring_detect_state < RING_DETECT_STATE_COMPLETE)
1246 srb->SrbStatus = SRB_STATUS_BUSY;
1247 StorPortNotification(RequestComplete, DeviceExtension, srb);
1248 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Still figuring out ring)\n"));
1249 return TRUE;
1252 if (!dump_mode && xvdd->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
1254 //KdPrint((__DRIVER_NAME " --> HwStorStartIo (Suspending/Resuming)\n"));
1255 srb->SrbStatus = SRB_STATUS_BUSY;
1256 StorPortNotification(RequestComplete, DeviceExtension, srb);
1257 //KdPrint((__DRIVER_NAME " <-- HwStorStartIo (Suspending/Resuming)\n"));
1258 return TRUE;
1261 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
1263 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1264 StorPortNotification(RequestComplete, DeviceExtension, srb);
1265 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun));
1266 return TRUE;
1269 switch (srb->Function)
1271 case SRB_FUNCTION_EXECUTE_SCSI:
1272 cdb = (PCDB)srb->Cdb;
1274 switch(cdb->CDB6GENERIC.OperationCode)
1276 case SCSIOP_TEST_UNIT_READY:
1277 if (dump_mode)
1278 KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
1279 srb_status = SRB_STATUS_SUCCESS;
1280 srb->ScsiStatus = 0;
1281 break;
1282 case SCSIOP_INQUIRY:
1283 if (dump_mode)
1284 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
1285 // KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
1286 // KdPrint((__DRIVER_NAME " (Length = %d)\n", srb->DataTransferLength));
1288 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1289 data_buffer = srb->DataBuffer;
1290 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1291 srb_status = SRB_STATUS_SUCCESS;
1292 switch (xvdd->device_type)
1294 case XENVBD_DEVICETYPE_DISK:
1295 if ((srb->Cdb[1] & 1) == 0)
1297 if (srb->Cdb[2])
1299 srb_status = SRB_STATUS_ERROR;
1301 else
1303 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1304 id->DeviceType = DIRECT_ACCESS_DEVICE;
1305 id->Versions = 4; /* minimum that WHQL says we must support */
1306 id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
1307 id->HiSupport = 1; /* WHQL test says we should set this */
1308 //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1309 id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
1310 id->CommandQueue = 1;
1311 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1312 memcpy(id->ProductId, scsi_disk_model, 16); // product id
1313 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1314 data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
1317 else
1319 switch (srb->Cdb[2])
1321 case VPD_SUPPORTED_PAGES: /* list of pages we support */
1322 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1323 data_buffer[1] = VPD_SUPPORTED_PAGES;
1324 data_buffer[2] = 0x00;
1325 data_buffer[3] = 2;
1326 data_buffer[4] = 0x00;
1327 data_buffer[5] = 0x80;
1328 data_transfer_length = 6;
1329 break;
1330 case VPD_SERIAL_NUMBER: /* serial number */
1331 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1332 data_buffer[1] = VPD_SERIAL_NUMBER;
1333 data_buffer[2] = 0x00;
1334 data_buffer[3] = 8;
1335 memset(&data_buffer[4], ' ', 8);
1336 data_transfer_length = 12;
1337 break;
1338 case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
1339 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1340 data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
1341 data_buffer[2] = 0x00;
1342 data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
1343 data_buffer[4] = 2; /* ASCII */
1344 data_buffer[5] = 1; /* VendorId */
1345 data_buffer[6] = 0;
1346 data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
1347 memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
1348 data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
1349 break;
1350 default:
1351 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1352 srb_status = SRB_STATUS_ERROR;
1353 break;
1356 break;
1357 case XENVBD_DEVICETYPE_CDROM:
1358 if ((srb->Cdb[1] & 1) == 0)
1360 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1361 id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
1362 id->RemovableMedia = 1;
1363 id->Versions = 3;
1364 id->ResponseDataFormat = 0;
1365 id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1366 id->CommandQueue = 1;
1367 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1368 memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
1369 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1370 data_transfer_length = sizeof(INQUIRYDATA);
1372 else
1374 switch (srb->Cdb[2])
1376 case 0x00:
1377 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1378 data_buffer[1] = 0x00;
1379 data_buffer[2] = 0x00;
1380 data_buffer[3] = 2;
1381 data_buffer[4] = 0x00;
1382 data_buffer[5] = 0x80;
1383 data_transfer_length = 6;
1384 break;
1385 case 0x80:
1386 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1387 data_buffer[1] = 0x80;
1388 data_buffer[2] = 0x00;
1389 data_buffer[3] = 8;
1390 data_buffer[4] = 0x31;
1391 data_buffer[5] = 0x32;
1392 data_buffer[6] = 0x33;
1393 data_buffer[7] = 0x34;
1394 data_buffer[8] = 0x35;
1395 data_buffer[9] = 0x36;
1396 data_buffer[10] = 0x37;
1397 data_buffer[11] = 0x38;
1398 data_transfer_length = 12;
1399 break;
1400 default:
1401 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1402 srb_status = SRB_STATUS_ERROR;
1403 break;
1406 break;
1407 default:
1408 //KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", xvdd->device_type));
1409 srb_status = SRB_STATUS_ERROR;
1410 break;
1412 break;
1413 case SCSIOP_READ_CAPACITY:
1414 if (dump_mode)
1415 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1416 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1417 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1418 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1419 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1420 data_buffer = srb->DataBuffer;
1421 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1422 if ((xvdd->total_sectors - 1) >> 32)
1424 data_buffer[0] = 0xff;
1425 data_buffer[1] = 0xff;
1426 data_buffer[2] = 0xff;
1427 data_buffer[3] = 0xff;
1429 else
1431 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1432 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1433 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1434 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1436 data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1437 data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1438 data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1439 data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1440 data_transfer_length = 8;
1441 srb->ScsiStatus = 0;
1442 srb_status = SRB_STATUS_SUCCESS;
1443 break;
1444 case SCSIOP_READ_CAPACITY16:
1445 if (dump_mode)
1446 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1447 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1448 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1449 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1450 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1451 data_buffer = srb->DataBuffer;
1452 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1453 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
1454 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
1455 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
1456 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
1457 data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1458 data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1459 data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1460 data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1461 data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1462 data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1463 data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1464 data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1465 data_transfer_length = 12;
1466 srb->ScsiStatus = 0;
1467 srb_status = SRB_STATUS_SUCCESS;
1468 break;
1469 case SCSIOP_MODE_SENSE:
1470 case SCSIOP_MODE_SENSE10:
1471 if (dump_mode)
1472 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));
1473 data_transfer_length = XenVbd_FillModePage(xvdd, srb);
1474 srb_status = SRB_STATUS_SUCCESS;
1475 break;
1476 case SCSIOP_READ:
1477 case SCSIOP_READ16:
1478 case SCSIOP_WRITE:
1479 case SCSIOP_WRITE16:
1480 //KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1481 XenVbd_PutSrbOnList(xvdd, srb);
1482 XenVbd_PutQueuedSrbsOnRing(xvdd);
1483 break;
1484 case SCSIOP_VERIFY:
1485 case SCSIOP_VERIFY16:
1486 // Should we do more here?
1487 if (dump_mode)
1488 KdPrint((__DRIVER_NAME " Command = VERIFY\n"));
1489 srb_status = SRB_STATUS_SUCCESS;
1490 break;
1491 #if 0
1492 case SCSIOP_REPORT_LUNS:
1493 if (dump_mode)
1494 KdPrint((__DRIVER_NAME " Command = REPORT_LUNS\n"));
1495 switch (srb->Cdb[1])
1498 srb_status = SRB_STATUS_SUCCESS;;
1499 break;
1500 #endif
1501 case SCSIOP_REQUEST_SENSE:
1502 if (dump_mode)
1503 KdPrint((__DRIVER_NAME " Command = REQUEST_SENSE\n"));
1504 data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
1505 srb_status = SRB_STATUS_SUCCESS;
1506 break;
1507 case SCSIOP_READ_TOC:
1508 if (dump_mode)
1509 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
1510 data_buffer = srb->DataBuffer;
1511 /*
1512 #define READ_TOC_FORMAT_TOC 0x00
1513 #define READ_TOC_FORMAT_SESSION 0x01
1514 #define READ_TOC_FORMAT_FULL_TOC 0x02
1515 #define READ_TOC_FORMAT_PMA 0x03
1516 #define READ_TOC_FORMAT_ATIP 0x04
1517 */
1518 // KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
1519 // KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
1520 // KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
1521 // KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
1522 // KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
1523 // KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
1524 // KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
1525 switch (cdb->READ_TOC.Format2)
1527 case READ_TOC_FORMAT_TOC:
1528 data_buffer[0] = 0; // length MSB
1529 data_buffer[1] = 10; // length LSB
1530 data_buffer[2] = 1; // First Track
1531 data_buffer[3] = 1; // Last Track
1532 data_buffer[4] = 0; // Reserved
1533 data_buffer[5] = 0x14; // current position data + uninterrupted data
1534 data_buffer[6] = 1; // last complete track
1535 data_buffer[7] = 0; // reserved
1536 data_buffer[8] = 0; // MSB Block
1537 data_buffer[9] = 0;
1538 data_buffer[10] = 0;
1539 data_buffer[11] = 0; // LSB Block
1540 data_transfer_length = 12;
1541 srb_status = SRB_STATUS_SUCCESS;
1542 break;
1543 case READ_TOC_FORMAT_SESSION:
1544 case READ_TOC_FORMAT_FULL_TOC:
1545 case READ_TOC_FORMAT_PMA:
1546 case READ_TOC_FORMAT_ATIP:
1547 srb_status = SRB_STATUS_ERROR;
1548 break;
1549 default:
1550 srb_status = SRB_STATUS_ERROR;
1551 break;
1553 break;
1554 case SCSIOP_START_STOP_UNIT:
1555 KdPrint((__DRIVER_NAME " Command = SCSIOP_START_STOP_UNIT\n"));
1556 srb_status = SRB_STATUS_SUCCESS;
1557 break;
1558 case SCSIOP_RESERVE_UNIT:
1559 KdPrint((__DRIVER_NAME " Command = SCSIOP_RESERVE_UNIT\n"));
1560 srb_status = SRB_STATUS_SUCCESS;
1561 break;
1562 case SCSIOP_RELEASE_UNIT:
1563 KdPrint((__DRIVER_NAME " Command = SCSIOP_RELEASE_UNIT\n"));
1564 srb_status = SRB_STATUS_SUCCESS;
1565 break;
1566 default:
1567 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
1568 srb_status = SRB_STATUS_ERROR;
1569 break;
1571 if (srb_status == SRB_STATUS_ERROR)
1573 KdPrint((__DRIVER_NAME " EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
1574 if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
1576 xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
1577 xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
1579 srb->SrbStatus = srb_status;
1580 srb->ScsiStatus = 0x02;
1581 XenVbd_MakeAutoSense(xvdd, srb);
1582 StorPortNotification(RequestComplete, DeviceExtension, srb);
1584 else if (srb_status != SRB_STATUS_PENDING)
1586 if (data_transfer_length > srb->DataTransferLength)
1587 KdPrint((__DRIVER_NAME " data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
1589 if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
1591 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
1592 srb->DataTransferLength = data_transfer_length;
1594 else
1596 srb->SrbStatus = srb_status;
1598 xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
1599 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1600 StorPortNotification(RequestComplete, DeviceExtension, srb);
1602 break;
1603 case SRB_FUNCTION_IO_CONTROL:
1604 KdPrint((__DRIVER_NAME " SRB_FUNCTION_IO_CONTROL\n"));
1605 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1606 StorPortNotification(RequestComplete, DeviceExtension, srb);
1607 break;
1608 case SRB_FUNCTION_FLUSH:
1609 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1610 srb->SrbStatus = SRB_STATUS_SUCCESS;
1611 StorPortNotification(RequestComplete, DeviceExtension, srb);
1612 break;
1613 case SRB_FUNCTION_PNP:
1614 KdPrint((__DRIVER_NAME " SRB_FUNCTION_PNP\n"));
1615 sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
1616 switch (sprb->PnPAction)
1618 case StorStartDevice:
1619 KdPrint((__DRIVER_NAME " StorStartDevice\n"));
1620 break;
1621 case StorRemoveDevice:
1622 KdPrint((__DRIVER_NAME " StorRemoveDevice\n"));
1623 break;
1624 case StorStopDevice:
1625 KdPrint((__DRIVER_NAME " StorStopDevice\n"));
1626 break;
1627 case StorQueryCapabilities:
1628 KdPrint((__DRIVER_NAME " StorQueryCapabilities\n"));
1629 break;
1630 case StorFilterResourceRequirements:
1631 KdPrint((__DRIVER_NAME " StorFilterResourceRequirements\n"));
1632 break;
1633 default:
1634 KdPrint((__DRIVER_NAME " Stor%d\n", sprb->PnPAction));
1635 break;
1637 KdPrint((__DRIVER_NAME " SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
1638 srb->SrbStatus = SRB_STATUS_SUCCESS;
1639 StorPortNotification(RequestComplete, DeviceExtension, srb);
1640 break;
1641 case SRB_FUNCTION_DUMP_POINTERS:
1642 KdPrint((__DRIVER_NAME " SRB_FUNCTION_DUMP_POINTERS\n"));
1643 KdPrint((__DRIVER_NAME " DataTransferLength = %d\n", srb->DataTransferLength));
1644 //RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
1645 dump_pointers = srb->DataBuffer;
1646 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1647 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1648 KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1649 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1650 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1651 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1652 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1653 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1654 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1655 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1656 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1657 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1658 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1659 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1660 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1661 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1662 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1664 dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
1665 dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
1666 RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
1667 dump_pointers->AdapterObject = NULL;
1668 dump_pointers->MappedRegisterBase = 0;
1669 dump_pointers->CommonBufferSize = 0;
1670 dump_pointers->MiniportPrivateDumpData = (PVOID)xvdd->device_base;
1671 //dump_pointers->SystemIoBusNumber = 0;
1672 dump_pointers->AdapterInterfaceType = Internal;
1673 dump_pointers->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
1674 dump_pointers->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
1675 dump_pointers->AlignmentMask = 0;
1676 dump_pointers->NumberOfAccessRanges = 1;
1677 dump_pointers->NumberOfBuses = 1;
1678 dump_pointers->Master = TRUE;
1679 dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1680 dump_pointers->MaximumNumberOfTargets = 2;
1682 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1683 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1684 KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1685 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1686 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1687 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1688 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1689 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1690 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1691 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1692 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1693 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1694 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1695 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1696 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1697 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1698 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1700 srb->SrbStatus = SRB_STATUS_SUCCESS;
1701 StorPortNotification(RequestComplete, DeviceExtension, srb);
1702 break;
1703 case SRB_FUNCTION_SHUTDOWN:
1704 KdPrint((__DRIVER_NAME " SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1705 srb->SrbStatus = SRB_STATUS_SUCCESS;
1706 StorPortNotification(RequestComplete, DeviceExtension, srb);
1707 break;
1708 default:
1709 KdPrint((__DRIVER_NAME " Unhandled srb->Function = %08X\n", srb->Function));
1710 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1711 StorPortNotification(RequestComplete, DeviceExtension, srb);
1712 break;
1715 //if (dump_mode) FUNCTION_EXIT();
1716 return TRUE;
1719 static BOOLEAN
1720 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
1722 //PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1724 UNREFERENCED_PARAMETER(DeviceExtension);
1725 UNREFERENCED_PARAMETER(PathId);
1727 FUNCTION_ENTER();
1729 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1731 FUNCTION_EXIT();
1734 return TRUE;
1737 static SCSI_ADAPTER_CONTROL_STATUS
1738 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
1740 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1741 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
1742 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
1743 //KIRQL OldIrql;
1745 FUNCTION_ENTER();
1746 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1747 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
1749 switch (ControlType)
1751 case ScsiQuerySupportedControlTypes:
1752 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
1753 KdPrint((__DRIVER_NAME " ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
1754 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
1755 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
1756 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
1757 break;
1758 case ScsiStopAdapter:
1759 KdPrint((__DRIVER_NAME " ScsiStopAdapter\n"));
1760 /* I don't think we actually have to do anything here... xenpci cleans up all the xenbus stuff for us */
1761 break;
1762 case ScsiRestartAdapter:
1763 KdPrint((__DRIVER_NAME " ScsiRestartAdapter\n"));
1764 if (!xvdd->inactive)
1766 /*
1767 if (XenVbd_InitConfig(xvdd) != SP_RETURN_FOUND)
1768 KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
1769 */
1770 if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND)
1771 KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
1772 xvdd->ring_detect_state = RING_DETECT_STATE_NOT_STARTED;
1773 //XenVbd_StartRingDetection(xvdd);
1775 break;
1776 case ScsiSetBootConfig:
1777 KdPrint((__DRIVER_NAME " ScsiSetBootConfig\n"));
1778 break;
1779 case ScsiSetRunningConfig:
1780 KdPrint((__DRIVER_NAME " ScsiSetRunningConfig\n"));
1781 break;
1782 default:
1783 KdPrint((__DRIVER_NAME " UNKNOWN\n"));
1784 break;
1787 FUNCTION_EXIT();
1789 return Status;
1792 NTSTATUS
1793 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
1795 ULONG status;
1796 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
1797 HW_INITIALIZATION_DATA HwInitializationData;
1798 //PVOID driver_extension;
1799 //PUCHAR ptr;
1800 OBJECT_ATTRIBUTES oa;
1801 HANDLE service_handle;
1802 UNICODE_STRING param_name;
1803 HANDLE param_handle;
1804 UNICODE_STRING value_name;
1805 CHAR buf[256];
1806 ULONG buf_len;
1807 PKEY_VALUE_PARTIAL_INFORMATION kpv;
1809 FUNCTION_ENTER();
1810 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1811 KdPrint((__DRIVER_NAME " DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
1813 /* RegistryPath == NULL when we are invoked as a crash dump driver */
1814 if (!RegistryPath)
1816 dump_mode = TRUE;
1819 if (!dump_mode)
1821 InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
1822 status = ZwOpenKey(&service_handle, KEY_READ, &oa);
1823 if(!NT_SUCCESS(status))
1825 KdPrint((__DRIVER_NAME " ZwOpenKey(Service) returned %08x\n", status));
1827 else
1829 RtlInitUnicodeString(&param_name, L"Parameters");
1830 InitializeObjectAttributes(&oa, &param_name, OBJ_CASE_INSENSITIVE, service_handle, NULL);
1831 status = ZwOpenKey(&param_handle, KEY_READ, &oa);
1832 if(!NT_SUCCESS(status))
1834 KdPrint((__DRIVER_NAME " ZwOpenKey(Parameters) returned %08x\n", status));
1836 else
1838 kpv = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
1839 RtlFillMemory(scsi_device_manufacturer, 8, ' ');
1840 RtlFillMemory(scsi_disk_model, 16, ' ');
1841 RtlFillMemory(scsi_cdrom_model, 16, ' ');
1843 RtlInitUnicodeString(&value_name, L"Manufacturer");
1844 buf_len = 256;
1845 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
1846 if(NT_SUCCESS(status))
1847 wcstombs(scsi_device_manufacturer, (PWCHAR)kpv->Data, min(kpv->DataLength, 8));
1848 else
1849 RtlStringCbCopyA(scsi_device_manufacturer, 8, "XEN ");
1851 RtlInitUnicodeString(&value_name, L"Disk_Model");
1852 buf_len = 256;
1853 status = ZwQueryValueKey(param_handle, &value_name, KeyValuePartialInformation, buf, buf_len, &buf_len);
1854 if(NT_SUCCESS(status))
1855 wcstombs(scsi_disk_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
1856 else
1857 RtlStringCbCopyA(scsi_disk_model, 16, "PV DISK ");
1859 RtlInitUnicodeString(&value_name, L"CDROM_Model");
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_cdrom_model, (PWCHAR)kpv->Data, min(kpv->DataLength, 16));
1864 else
1865 RtlStringCbCopyA(scsi_cdrom_model, 16, "PV CDROM ");
1866 ZwClose(param_handle);
1868 ZwClose(service_handle);
1870 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
1871 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
1872 VHwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* maybe should be internal? */
1873 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
1874 VHwInitializationData.SpecificLuExtensionSize = 0;
1875 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
1876 VHwInitializationData.NumberOfAccessRanges = 1;
1877 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
1878 //VHwInitializationData.NeedPhysicalAddresses = TRUE;
1879 VHwInitializationData.TaggedQueuing = TRUE;
1880 VHwInitializationData.AutoRequestSense = TRUE;
1881 VHwInitializationData.MultipleRequestPerLu = TRUE;
1882 VHwInitializationData.ReceiveEvent = TRUE;
1883 VHwInitializationData.PortVersionFlags = 0;
1884 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
1885 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
1886 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
1887 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
1888 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
1889 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
1891 else
1893 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
1894 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
1895 HwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* not Internal */
1896 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
1897 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
1898 HwInitializationData.NumberOfAccessRanges = 1;
1899 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1900 HwInitializationData.NeedPhysicalAddresses = TRUE;
1901 HwInitializationData.TaggedQueuing = FALSE;
1902 HwInitializationData.AutoRequestSense = TRUE;
1903 HwInitializationData.MultipleRequestPerLu = FALSE;
1904 HwInitializationData.ReceiveEvent = TRUE;
1905 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
1906 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
1907 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
1908 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
1909 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
1910 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
1911 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
1914 if(!NT_SUCCESS(status))
1916 KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", status));
1919 FUNCTION_EXIT();
1921 return status;