win-pvdrivers

view xenvbd/xenvbd_storport.c @ 982:e9011a1ba5bb

started rewriting xenpci<->child interface
author James Harper <james.harper@bendigoit.com.au>
date Mon Aug 13 17:10:03 2012 +1000 (2012-08-13)
parents 8f483a2b2991
children
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 #define scsi_device_manufacturer "XEN "
40 #define scsi_disk_model "PV DISK "
41 #define scsi_cdrom_model "PV CDROM "
43 ULONGLONG parse_numeric_string(PCHAR string)
44 {
45 ULONGLONG val = 0;
46 while (*string != 0)
47 {
48 val = val * 10 + (*string - '0');
49 string++;
50 }
51 return val;
52 }
54 static blkif_shadow_t *
55 get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
56 {
57 if (xvdd->shadow_free == 0)
58 {
59 KdPrint((__DRIVER_NAME " No more shadow entries\n"));
60 return NULL;
61 }
62 xvdd->shadow_free--;
63 if (xvdd->shadow_free < xvdd->shadow_min_free)
64 xvdd->shadow_min_free = xvdd->shadow_free;
65 return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
66 }
68 static VOID
69 put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
70 {
71 xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)(shadow->req.id & SHADOW_ID_ID_MASK);
72 shadow->srb = NULL;
73 shadow->reset = FALSE;
74 xvdd->shadow_free++;
75 }
77 #if 0
78 static ULONG
79 XenVbd_InitConfig(PXENVBD_DEVICE_DATA xvdd)
80 {
81 ULONG status;
82 PUCHAR ptr;
83 USHORT type;
84 PCHAR setting, value, value2;
86 FUNCTION_ENTER();
87 /* first read the default config items */
88 ptr = xvdd->device_base;
89 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
90 {
91 switch(type)
92 {
93 case XEN_INIT_TYPE_VECTORS:
94 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
95 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
96 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
97 {
98 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
99 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
100 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
101 return SP_RETURN_BAD_CONFIG;
102 }
103 else
104 memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
105 break;
106 default:
107 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
108 break;
109 }
110 }
112 /* then set up all the configuration requests */
113 ptr = xvdd->device_base;
114 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
115 #pragma warning(suppress:4054)
116 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenVbd_HandleEvent, xvdd);
117 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL, NULL);
118 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
119 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
120 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
121 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL);
122 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialised);
123 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
124 __ADD_XEN_INIT_UCHAR(&ptr, 20);
125 __ADD_XEN_INIT_UCHAR(&ptr, 0);
126 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_POST_CONNECT, NULL, NULL, NULL);
127 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
128 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateConnected);
129 __ADD_XEN_INIT_UCHAR(&ptr, 20);
130 __ADD_XEN_INIT_UCHAR(&ptr, 0);
131 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_SHUTDOWN, NULL, NULL, NULL);
132 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
133 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosing);
134 __ADD_XEN_INIT_UCHAR(&ptr, 50);
135 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
136 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateClosed);
137 __ADD_XEN_INIT_UCHAR(&ptr, 50);
138 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitialising);
139 __ADD_XEN_INIT_UCHAR(&ptr, XenbusStateInitWait);
140 __ADD_XEN_INIT_UCHAR(&ptr, 50);
141 __ADD_XEN_INIT_UCHAR(&ptr, 0);
142 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
144 /* then configure */
145 status = xvdd->vectors.XenPci_XenConfigDevice(xvdd->vectors.context);
146 if (!NT_SUCCESS(status))
147 {
148 xvdd->inactive = TRUE;
149 KdPrint(("Failed to complete device configuration (%08x)\n", status));
150 FUNCTION_EXIT();
151 return SP_RETURN_BAD_CONFIG;
152 }
153 FUNCTION_EXIT();
154 return SP_RETURN_FOUND;
155 }
156 #endif
158 static ULONG
159 XenVbd_InitFromConfig(PXENVBD_DEVICE_DATA xvdd)
160 {
161 ULONG i;
162 PUCHAR ptr;
163 USHORT type;
164 PCHAR setting, value, value2;
165 ULONG qemu_protocol_version = 0;
166 BOOLEAN qemu_hide_filter = FALSE;
167 ULONG qemu_hide_flags_value = 0;
169 FUNCTION_ENTER();
171 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
172 #pragma warning(suppress:4054)
173 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenVbd_HandleEvent, xvdd);
174 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL, NULL);
175 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "mode", NULL, NULL);
176 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL, NULL);
177 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL, NULL);
179 // allocate page(s?) of memory
180 // grant page
181 // write to backend as ring-ref
182 // allocate event channel
183 // write to backend as event-channel
184 // write protocol = "x86_64-abi"
185 // set watch on backend state
186 // change state to 2
187 // wait for backend state change
188 // read device-type
189 // read mode
190 // read sectors
191 // read sector-size
193 xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
194 xvdd->sring = NULL;
195 xvdd->event_channel = 0;
197 xvdd->inactive = TRUE;
199 ptr = xvdd->device_base;
200 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
201 {
202 switch(type)
203 {
204 case XEN_INIT_TYPE_VECTORS:
205 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n"));
206 if (dump_mode)
207 {
208 if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
209 ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
210 {
211 KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n",
212 ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
213 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
214 return SP_RETURN_BAD_CONFIG;
215 }
216 else
217 memcpy(&xvdd->vectors, value, sizeof(XENPCI_VECTORS));
218 }
219 break;
220 case XEN_INIT_TYPE_RING: /* frontend ring */
221 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
222 if (strcmp(setting, "ring-ref") == 0)
223 {
224 xvdd->sring = (blkif_sring_t *)value;
225 FRONT_RING_INIT(&xvdd->ring, xvdd->sring, PAGE_SIZE);
226 /* this bit is for when we have to take over an existing ring on a crash dump */
227 xvdd->ring.req_prod_pvt = xvdd->sring->req_prod;
228 xvdd->ring.rsp_cons = xvdd->ring.req_prod_pvt;
229 }
230 break;
231 case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
232 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d (%08x)\n", setting, PtrToUlong(value) & 0x3FFFFFFF, PtrToUlong(value)));
233 if (strcmp(setting, "event-channel") == 0)
234 {
235 /* cheat here - save the state of the ring in the topmost bits of the event-channel */
236 xvdd->event_channel_ptr = (ULONG *)(((PCHAR)ptr) - sizeof(ULONG));
237 xvdd->event_channel = PtrToUlong(value);
238 }
239 break;
240 case XEN_INIT_TYPE_READ_STRING_BACK:
241 case XEN_INIT_TYPE_READ_STRING_FRONT:
242 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
243 if (strcmp(setting, "sectors") == 0)
244 xvdd->total_sectors = parse_numeric_string(value);
245 else if (strcmp(setting, "sector-size") == 0)
246 xvdd->bytes_per_sector = (ULONG)parse_numeric_string(value);
247 else if (strcmp(setting, "device-type") == 0)
248 {
249 if (strcmp(value, "disk") == 0)
250 {
251 KdPrint((__DRIVER_NAME " device-type = Disk\n"));
252 xvdd->device_type = XENVBD_DEVICETYPE_DISK;
253 }
254 else if (strcmp(value, "cdrom") == 0)
255 {
256 KdPrint((__DRIVER_NAME " device-type = CDROM\n"));
257 xvdd->device_type = XENVBD_DEVICETYPE_CDROM;
258 }
259 else
260 {
261 KdPrint((__DRIVER_NAME " device-type = %s (This probably won't work!)\n", value));
262 xvdd->device_type = XENVBD_DEVICETYPE_UNKNOWN;
263 }
264 }
265 else if (strcmp(setting, "mode") == 0)
266 {
267 if (strncmp(value, "r", 1) == 0)
268 {
269 KdPrint((__DRIVER_NAME " mode = r\n"));
270 xvdd->device_mode = XENVBD_DEVICEMODE_READ;
271 }
272 else if (strncmp(value, "w", 1) == 0)
273 {
274 KdPrint((__DRIVER_NAME " mode = w\n"));
275 xvdd->device_mode = XENVBD_DEVICEMODE_WRITE;
276 }
277 else
278 {
279 KdPrint((__DRIVER_NAME " mode = unknown\n"));
280 xvdd->device_mode = XENVBD_DEVICEMODE_UNKNOWN;
281 }
282 }
283 break;
284 case XEN_INIT_TYPE_QEMU_PROTOCOL_VERSION:
285 qemu_protocol_version = PtrToUlong(value);
286 break;
287 case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
288 qemu_hide_flags_value = PtrToUlong(value);
289 KdPrint((__DRIVER_NAME " qemu_hide_flags_value = %d\n", qemu_hide_flags_value));
290 break;
291 case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
292 qemu_hide_filter = TRUE;
293 KdPrint((__DRIVER_NAME " qemu_hide_filter = TRUE\n"));
294 break;
295 case XEN_INIT_TYPE_STATE_PTR:
296 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
297 xvdd->device_state = (PXENPCI_DEVICE_STATE)value;
298 break;
299 default:
300 KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type));
301 break;
302 }
303 }
305 if (((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) && xvdd->device_type != XENVBD_DEVICETYPE_CDROM) || qemu_hide_filter)
306 xvdd->inactive = FALSE;
308 if (!xvdd->inactive && (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
309 || xvdd->sring == NULL
310 || xvdd->event_channel == 0
311 || xvdd->total_sectors == 0
312 || xvdd->bytes_per_sector == 0))
313 {
314 KdPrint((__DRIVER_NAME " Missing settings\n"));
315 FUNCTION_EXIT();
316 return SP_RETURN_BAD_CONFIG;
317 }
319 if (xvdd->inactive)
320 KdPrint((__DRIVER_NAME " Device is inactive\n"));
321 else
322 {
323 if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM)
324 {
325 /* CD/DVD drives must have bytes_per_sector = 2048. */
326 xvdd->bytes_per_sector = 2048;
327 }
329 /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
330 xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
332 xvdd->shadow_free = 0;
333 memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
334 for (i = 0; i < SHADOW_ENTRIES; i++)
335 {
336 xvdd->shadows[i].req.id = i;
337 /* make sure leftover real requests's are never confused with dump mode requests */
338 if (dump_mode)
339 xvdd->shadows[i].req.id |= SHADOW_ID_DUMP_FLAG;
340 put_shadow_on_freelist(xvdd, &xvdd->shadows[i]);
341 }
342 }
344 FUNCTION_EXIT();
345 return SP_RETURN_FOUND;
346 }
348 static __inline ULONG
349 decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
350 {
351 switch (srb->Cdb[0])
352 {
353 case SCSIOP_READ:
354 case SCSIOP_WRITE:
355 return ((ULONG)(UCHAR)srb->Cdb[7] << 8) | (ULONG)(UCHAR)srb->Cdb[8];
356 case SCSIOP_READ16:
357 case SCSIOP_WRITE16:
358 return ((ULONG)(UCHAR)srb->Cdb[10] << 24) | ((ULONG)(UCHAR)srb->Cdb[11] << 16) | ((ULONG)(UCHAR)srb->Cdb[12] << 8) | (ULONG)(UCHAR)srb->Cdb[13];
359 default:
360 return 0;
361 }
362 }
364 static __inline ULONGLONG
365 decode_cdb_sector(PSCSI_REQUEST_BLOCK srb)
366 {
367 ULONGLONG sector;
369 switch (srb->Cdb[0])
370 {
371 case SCSIOP_READ:
372 case SCSIOP_WRITE:
373 sector = ((ULONG)(UCHAR)srb->Cdb[2] << 24) | ((ULONG)(UCHAR)srb->Cdb[3] << 16) | ((ULONG)(UCHAR)srb->Cdb[4] << 8) | (ULONG)(UCHAR)srb->Cdb[5];
374 break;
375 case SCSIOP_READ16:
376 case SCSIOP_WRITE16:
377 sector = ((ULONGLONG)(UCHAR)srb->Cdb[2] << 56) | ((ULONGLONG)(UCHAR)srb->Cdb[3] << 48)
378 | ((ULONGLONG)(UCHAR)srb->Cdb[4] << 40) | ((ULONGLONG)(UCHAR)srb->Cdb[5] << 32)
379 | ((ULONGLONG)(UCHAR)srb->Cdb[6] << 24) | ((ULONGLONG)(UCHAR)srb->Cdb[7] << 16)
380 | ((ULONGLONG)(UCHAR)srb->Cdb[8] << 8) | ((ULONGLONG)(UCHAR)srb->Cdb[9]);
381 //KdPrint((__DRIVER_NAME " sector_number = %d (high) %d (low)\n", (ULONG)(sector >> 32), (ULONG)sector));
382 break;
383 default:
384 sector = 0;
385 break;
386 }
387 return sector;
388 }
390 static __inline BOOLEAN
391 decode_cdb_is_read(PSCSI_REQUEST_BLOCK srb)
392 {
393 switch (srb->Cdb[0])
394 {
395 case SCSIOP_READ:
396 case SCSIOP_READ16:
397 return TRUE;
398 case SCSIOP_WRITE:
399 case SCSIOP_WRITE16:
400 return FALSE;
401 default:
402 return FALSE;
403 }
404 }
406 static VOID
407 XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
408 {
409 srb_list_entry_t *srb_entry = srb->SrbExtension;
410 srb_entry->srb = srb;
411 if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI)
412 {
413 srb_entry->outstanding_requests = 0;
414 srb_entry->length = srb->DataTransferLength;
415 srb_entry->offset = 0;
416 srb_entry->error = FALSE;
417 }
418 InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
419 }
421 static VOID
422 XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVICE_DATA xvdd)
423 {
424 PSCSI_REQUEST_BLOCK srb;
425 srb_list_entry_t *srb_entry;
426 ULONGLONG sector_number;
427 ULONG block_count;
428 blkif_shadow_t *shadow;
429 ULONG remaining, offset, length;
430 grant_ref_t gref;
431 PUCHAR ptr;
432 int notify;
433 int i;
434 PVOID system_address;
436 //if (dump_mode) FUNCTION_ENTER();
438 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)
439 {
440 srb = srb_entry->srb;
441 ASSERT(srb);
442 if (srb->Function != SRB_FUNCTION_EXECUTE_SCSI)
443 {
444 KdPrint((__DRIVER_NAME " SRB_FUNCTION_%02x retrieved from ring\n", srb->Function));
445 if (xvdd->shadow_free != SHADOW_ENTRIES)
446 {
447 KdPrint((__DRIVER_NAME " busy\n"));
448 /* put it back at the end of the list just in case something is queued that needs to be processed */
449 InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
450 break; /* stall the queue until it's all empty */
451 }
452 else
453 {
454 KdPrint((__DRIVER_NAME " completing\n"));
455 srb->SrbStatus = SRB_STATUS_SUCCESS;
456 StorPortNotification(RequestComplete, xvdd, srb);
457 continue;
458 }
459 }
461 if (!dump_mode)
462 {
463 if (StorPortGetSystemAddress(xvdd, srb, &system_address) != STOR_STATUS_SUCCESS)
464 {
465 KdPrint((__DRIVER_NAME " Failed to map DataBuffer\n"));
466 srb->SrbStatus = SRB_STATUS_BUSY;
467 StorPortNotification(RequestComplete, xvdd, srb);
468 continue;
469 }
470 system_address = (PUCHAR)system_address + srb_entry->offset;
471 }
472 else
473 {
474 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
475 system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
476 }
477 block_count = decode_cdb_length(srb);
478 block_count *= xvdd->bytes_per_sector / 512;
479 sector_number = decode_cdb_sector(srb);
480 sector_number *= xvdd->bytes_per_sector / 512;
482 ASSERT(block_count * xvdd->bytes_per_sector == srb->DataTransferLength);
484 //KdPrint((__DRIVER_NAME " srb sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
486 sector_number += srb_entry->offset / 512;
487 block_count -= srb_entry->offset / 512;
489 /* look for pending writes that overlap this one */
490 /* we get warnings from drbd if we don't */
491 if (srb_entry->offset == 0)
492 {
493 for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
494 {
495 PSCSI_REQUEST_BLOCK srb2;
496 ULONGLONG sector_number2;
497 ULONG block_count2;
499 srb2 = xvdd->shadows[i].srb;
500 if (!srb2)
501 continue;
502 if (decode_cdb_is_read(srb2))
503 continue;
504 block_count2 = decode_cdb_length(srb2);;
505 block_count2 *= xvdd->bytes_per_sector / 512;
506 sector_number2 = decode_cdb_sector(srb2);
507 sector_number2 *= xvdd->bytes_per_sector / 512;
509 if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
510 continue;
511 if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
512 continue;
514 KdPrint((__DRIVER_NAME " Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
515 sector_number, block_count, sector_number2, block_count2));
516 /* put the srb back at the start of the queue */
517 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
518 break; /* stall the queue */
519 }
520 if (i != MAX_SHADOW_ENTRIES)
521 {
522 break; /* stall the queue but submit any outstanding requests */
523 }
524 }
526 shadow = get_shadow_from_freelist(xvdd);
527 if (!shadow)
528 {
529 /* put the srb back at the start of the queue */
530 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
531 break; /* stall the queue but submit any outstanding requests */
532 }
533 ASSERT(!shadow->aligned_buffer_in_use);
534 ASSERT(!shadow->srb);
535 shadow->req.sector_number = sector_number;
536 shadow->req.handle = 0;
537 shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
538 shadow->req.nr_segments = 0;
539 shadow->srb = srb;
540 shadow->length = 0;
541 shadow->system_address = system_address;
542 shadow->reset = FALSE;
544 if (!dump_mode)
545 {
546 if ((ULONG_PTR)shadow->system_address & 511)
547 {
548 xvdd->aligned_buffer_in_use = TRUE;
549 /* limit to aligned_buffer_size */
550 block_count = min(block_count, xvdd->aligned_buffer_size / 512);
551 ptr = (PUCHAR)xvdd->aligned_buffer;
552 if (!decode_cdb_is_read(srb))
553 memcpy(ptr, shadow->system_address, block_count * 512);
554 shadow->aligned_buffer_in_use = TRUE;
555 }
556 else
557 {
558 ptr = (PUCHAR)shadow->system_address;
559 shadow->aligned_buffer_in_use = FALSE;
560 }
561 }
562 else
563 {
564 ASSERT(!((ULONG_PTR)shadow->system_address & 511));
565 ptr = shadow->system_address;
566 shadow->aligned_buffer_in_use = FALSE;
567 }
569 //KdPrint((__DRIVER_NAME " sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
570 //KdPrint((__DRIVER_NAME " DataBuffer = %p\n", srb->DataBuffer));
571 //KdPrint((__DRIVER_NAME " system_address = %p\n", shadow->system_address));
572 //KdPrint((__DRIVER_NAME " offset = %d, length = %d\n", srb_entry->offset, srb_entry->length));
573 //KdPrint((__DRIVER_NAME " ptr = %p\n", ptr));
575 //KdPrint((__DRIVER_NAME " handle = %d\n", shadow->req.handle));
576 //KdPrint((__DRIVER_NAME " operation = %d\n", shadow->req.operation));
578 remaining = block_count * 512;
579 while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
580 {
581 PHYSICAL_ADDRESS physical_address;
583 if (!dump_mode)
584 {
585 physical_address = MmGetPhysicalAddress(ptr);
586 }
587 else
588 {
589 ULONG length;
590 physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
591 }
592 gref = xvdd->vectors.GntTbl_GrantAccess(xvdd->vectors.context,
593 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
594 if (gref == INVALID_GRANT_REF)
595 {
596 ULONG i;
597 for (i = 0; i < shadow->req.nr_segments; i++)
598 {
599 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
600 shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
601 }
602 if (shadow->aligned_buffer_in_use)
603 {
604 shadow->aligned_buffer_in_use = FALSE;
605 xvdd->aligned_buffer_in_use = FALSE;
606 }
607 /* put the srb back at the start of the queue */
608 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
609 put_shadow_on_freelist(xvdd, shadow);
610 KdPrint((__DRIVER_NAME " Out of gref's. Deferring\n"));
611 break; /* stall the queue but submit any outstanding requests */
612 }
613 offset = physical_address.LowPart & (PAGE_SIZE - 1);
614 length = min(PAGE_SIZE - offset, remaining);
615 //if (dump_mode) KdPrint((__DRIVER_NAME " length = %d\n", length));
616 //if (dump_mode) KdPrint((__DRIVER_NAME " offset = %d\n", length));
617 ASSERT((offset & 511) == 0);
618 ASSERT((length & 511) == 0);
619 ASSERT(offset + length <= PAGE_SIZE);
620 shadow->req.seg[shadow->req.nr_segments].gref = gref;
621 shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
622 shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
623 //if (dump_mode) KdPrint((__DRIVER_NAME " gref = %d\n", shadow->req.seg[shadow->req.nr_segments].gref));
624 //if (dump_mode) KdPrint((__DRIVER_NAME " first_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].first_sect));
625 //if (dump_mode) KdPrint((__DRIVER_NAME " last_sect = %d\n", shadow->req.seg[shadow->req.nr_segments].last_sect));
626 remaining -= length;
627 ptr += length;
628 shadow->length += length;
629 shadow->req.nr_segments++;
630 }
631 srb_entry->offset += shadow->length;
632 srb_entry->outstanding_requests++;
633 //KdPrint((__DRIVER_NAME " outstanding_requests = %p\n", srb_entry->outstanding_requests));
634 //KdPrint((__DRIVER_NAME " offset = %d, length = %d\n", srb_entry->offset, srb_entry->length));
635 //KdPrint((__DRIVER_NAME " ptr = %p\n", ptr));
636 if (srb_entry->offset < srb_entry->length)
637 {
638 if (dump_mode) KdPrint((__DRIVER_NAME " inserting back into list\n"));
639 /* put the srb back at the start of the queue to continue on the next request */
640 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
641 }
643 *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = shadow->req;
644 }
645 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
646 if (notify)
647 {
648 //KdPrint((__DRIVER_NAME " Notifying\n"));
649 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
650 }
652 //if (dump_mode) FUNCTION_EXIT();
653 }
655 /* called at PASSIVE_LEVEL except in dump mode */
656 static ULONG
657 XenVbd_VirtualHwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PVOID LowerDevice, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
658 {
659 // PACCESS_RANGE AccessRange;
660 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
661 ULONG status;
662 // PXENPCI_XEN_DEVICE_DATA XenDeviceData;
664 UNREFERENCED_PARAMETER(HwContext);
665 UNREFERENCED_PARAMETER(BusInformation);
666 UNREFERENCED_PARAMETER(LowerDevice);
667 UNREFERENCED_PARAMETER(ArgumentString);
669 FUNCTION_ENTER();
670 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
671 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
673 RtlZeroMemory(xvdd, sizeof(XENVBD_DEVICE_DATA));
674 *Again = FALSE;
676 if (!dump_mode)
677 {
678 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));
679 if (ConfigInfo->NumberOfAccessRanges != 1 && ConfigInfo->NumberOfAccessRanges != 2)
680 {
681 return SP_RETURN_BAD_CONFIG;
682 }
683 xvdd->grant_tag = (ULONG)'VBD0';
684 }
685 else
686 {
687 // do something with the ConfigInfo->Reserved... it's the dump pointers xvdd->device_base = ConfigInfo->Reserved;
688 xvdd->grant_tag = (ULONG)'DUMP';
689 }
691 status = XenVbd_InitFromConfig(xvdd);
692 if (status != SP_RETURN_FOUND)
693 {
694 /* set inactive here so StartIo is harmless - we still get called with a PNP remove (or similar) */
695 xvdd->inactive = TRUE;
696 FUNCTION_EXIT();
697 return status;
698 }
700 xvdd->aligned_buffer_in_use = FALSE;
701 /* align the buffer to PAGE_SIZE */
702 xvdd->aligned_buffer = (PVOID)((ULONG_PTR)((PUCHAR)xvdd->aligned_buffer_data + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
703 KdPrint((__DRIVER_NAME " aligned_buffer_data = %p\n", xvdd->aligned_buffer_data));
704 KdPrint((__DRIVER_NAME " aligned_buffer = %p\n", xvdd->aligned_buffer));
706 ConfigInfo->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
707 ConfigInfo->NumberOfPhysicalBreaks = ConfigInfo->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
708 KdPrint((__DRIVER_NAME " ConfigInfo->MaximumTransferLength = %d\n", ConfigInfo->MaximumTransferLength));
709 KdPrint((__DRIVER_NAME " ConfigInfo->NumberOfPhysicalBreaks = %d\n", ConfigInfo->NumberOfPhysicalBreaks));
710 if (!dump_mode)
711 {
712 ConfigInfo->VirtualDevice = TRUE;
713 xvdd->aligned_buffer_size = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
714 }
715 else
716 {
717 ConfigInfo->VirtualDevice = FALSE;
718 xvdd->aligned_buffer_size = DUMP_MODE_UNALIGNED_PAGES * PAGE_SIZE;
719 }
721 KdPrint((__DRIVER_NAME " ConfigInfo->VirtualDevice = %d\n", ConfigInfo->VirtualDevice));
722 ConfigInfo->ScatterGather = TRUE;
723 ConfigInfo->Master = TRUE;
724 ConfigInfo->CachesData = FALSE;
725 ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS;
726 KdPrint((__DRIVER_NAME " ConfigInfo->NeedPhysicalAddresses = %d\n", ConfigInfo->NeedPhysicalAddresses));
727 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
728 ConfigInfo->AlignmentMask = 0;
729 ConfigInfo->NumberOfBuses = 1;
730 ConfigInfo->InitiatorBusId[0] = 1;
731 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
732 ConfigInfo->MaximumNumberOfTargets = 2;
733 //ConfigInfo->BufferAccessScsiPortControlled = FALSE;
734 if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
735 {
736 ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;
737 //ConfigInfo->Dma32BitAddresses = FALSE;
738 KdPrint((__DRIVER_NAME " Dma64BitAddresses supported\n"));
739 }
740 else
741 {
742 //ConfigInfo->Dma32BitAddresses = TRUE;
743 KdPrint((__DRIVER_NAME " Dma64BitAddresses not supported\n"));
744 }
746 FUNCTION_EXIT();
748 return SP_RETURN_FOUND;
749 }
751 static ULONG
752 XenVbd_HwStorFindAdapter(PVOID DeviceExtension, PVOID HwContext, PVOID BusInformation, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PBOOLEAN Again)
753 {
754 ULONG status;
756 FUNCTION_ENTER();
757 status = XenVbd_VirtualHwStorFindAdapter(DeviceExtension, HwContext, BusInformation, NULL, ArgumentString, ConfigInfo, Again);
758 FUNCTION_EXIT();
759 return status;
760 }
762 static BOOLEAN
763 XenVbd_HwStorInitialize(PVOID DeviceExtension)
764 {
765 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
767 FUNCTION_ENTER();
768 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
769 KdPrint((__DRIVER_NAME " dump_mode = %d\n", dump_mode));
771 if (!xvdd->inactive) {
772 InitializeListHead(&xvdd->srb_list);
773 }
774 FUNCTION_EXIT();
776 return TRUE;
777 }
779 static ULONG
780 XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
781 {
782 PMODE_PARAMETER_HEADER parameter_header = NULL;
783 PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
784 PMODE_PARAMETER_BLOCK param_block;
785 PMODE_FORMAT_PAGE format_page;
786 ULONG offset = 0;
787 UCHAR buffer[1024];
788 BOOLEAN valid_page = FALSE;
789 BOOLEAN cdb_llbaa;
790 BOOLEAN cdb_dbd;
791 UCHAR cdb_page_code;
792 USHORT cdb_allocation_length;
794 UNREFERENCED_PARAMETER(xvdd);
796 RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
797 RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
798 offset = 0;
800 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
802 switch (srb->Cdb[0])
803 {
804 case SCSIOP_MODE_SENSE:
805 cdb_llbaa = FALSE;
806 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
807 cdb_page_code = srb->Cdb[2] & 0x3f;
808 cdb_allocation_length = srb->Cdb[4];
809 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
810 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
811 parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
812 parameter_header->MediumType = 0;
813 parameter_header->DeviceSpecificParameter = 0;
814 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
815 {
816 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
817 parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
818 }
819 offset += sizeof(MODE_PARAMETER_HEADER);
820 break;
821 case SCSIOP_MODE_SENSE10:
822 cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
823 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
824 cdb_page_code = srb->Cdb[2] & 0x3f;
825 cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
826 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE10 llbaa = %d, dbd = %d, page_code = %d, allocation_length = %d\n",
827 cdb_llbaa, cdb_dbd, cdb_page_code, cdb_allocation_length));
828 parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
829 parameter_header10->MediumType = 0;
830 parameter_header10->DeviceSpecificParameter = 0;
831 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
832 {
833 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
834 parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
835 }
836 offset += sizeof(MODE_PARAMETER_HEADER10);
837 break;
838 default:
839 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
840 return FALSE;
841 }
843 if (!cdb_dbd)
844 {
845 param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
846 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
847 {
848 if (xvdd->total_sectors >> 32)
849 {
850 param_block->DensityCode = 0xff;
851 param_block->NumberOfBlocks[0] = 0xff;
852 param_block->NumberOfBlocks[1] = 0xff;
853 param_block->NumberOfBlocks[2] = 0xff;
854 }
855 else
856 {
857 param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
858 param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
859 param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
860 param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
861 }
862 param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
863 param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
864 param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
865 }
866 offset += sizeof(MODE_PARAMETER_BLOCK);
867 }
868 switch (srb->Cdb[0])
869 {
870 case SCSIOP_MODE_SENSE:
871 parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
872 break;
873 case SCSIOP_MODE_SENSE10:
874 parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);
875 parameter_header10->BlockDescriptorLength[1] = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER10));
876 break;
877 }
878 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_FORMAT_DEVICE || cdb_page_code == MODE_SENSE_RETURN_ALL))
879 {
880 valid_page = TRUE;
881 format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
882 format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
883 format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
884 /* 256 sectors per track */
885 format_page->SectorsPerTrack[0] = 0x01;
886 format_page->SectorsPerTrack[1] = 0x00;
887 /* xxx bytes per sector */
888 format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
889 format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
890 format_page->HardSectorFormating = TRUE;
891 format_page->SoftSectorFormating = TRUE;
892 offset += sizeof(MODE_FORMAT_PAGE);
893 }
894 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_CACHING || cdb_page_code == MODE_SENSE_RETURN_ALL))
895 {
896 PMODE_CACHING_PAGE caching_page;
897 valid_page = TRUE;
898 caching_page = (PMODE_CACHING_PAGE)&buffer[offset];
899 caching_page->PageCode = MODE_PAGE_CACHING;
900 caching_page->PageLength = sizeof(MODE_CACHING_PAGE) - FIELD_OFFSET(MODE_CACHING_PAGE, PageLength);
901 // caching_page-> // all zeros is just fine... maybe
902 offset += sizeof(MODE_CACHING_PAGE);
903 }
904 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_MEDIUM_TYPES || cdb_page_code == MODE_SENSE_RETURN_ALL))
905 {
906 PUCHAR medium_types_page;
907 valid_page = TRUE;
908 medium_types_page = &buffer[offset];
909 medium_types_page[0] = MODE_PAGE_MEDIUM_TYPES;
910 medium_types_page[1] = 0x06;
911 medium_types_page[2] = 0;
912 medium_types_page[3] = 0;
913 medium_types_page[4] = 0;
914 medium_types_page[5] = 0;
915 medium_types_page[6] = 0;
916 medium_types_page[7] = 0;
917 offset += 8;
918 }
919 switch (srb->Cdb[0])
920 {
921 case SCSIOP_MODE_SENSE:
922 parameter_header->ModeDataLength = (UCHAR)(offset - 1);
923 break;
924 case SCSIOP_MODE_SENSE10:
925 parameter_header10->ModeDataLength[0] = (UCHAR)((offset - 2) >> 8);
926 parameter_header10->ModeDataLength[1] = (UCHAR)(offset - 2);
927 break;
928 }
930 if (!valid_page && cdb_page_code != MODE_SENSE_RETURN_ALL)
931 {
932 srb->SrbStatus = SRB_STATUS_ERROR;
933 }
934 else if(offset < srb->DataTransferLength)
935 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
936 else
937 srb->SrbStatus = SRB_STATUS_SUCCESS;
938 srb->DataTransferLength = min(srb->DataTransferLength, offset);
939 srb->ScsiStatus = 0;
940 memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
942 //FUNCTION_EXIT();
944 return TRUE;
945 }
947 static ULONG
948 XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
949 {
950 PSENSE_DATA sd = srb->SenseInfoBuffer;
952 UNREFERENCED_PARAMETER(xvdd);
954 if (!srb->SenseInfoBuffer)
955 return 0;
957 sd->ErrorCode = 0x70;
958 sd->Valid = 1;
959 sd->SenseKey = sense_key;
960 sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
961 sd->AdditionalSenseCode = additional_sense_code;
962 return sizeof(SENSE_DATA);
963 }
965 static VOID
966 XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
967 {
968 if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
969 return;
970 XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
971 srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
972 }
974 static BOOLEAN
975 XenVbd_HandleEventSynchronised(PVOID DeviceExtension, PVOID context)
976 {
977 PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
978 PSCSI_REQUEST_BLOCK srb;
979 RING_IDX i, rp;
980 ULONG j;
981 blkif_response_t *rep;
982 //int block_count;
983 int more_to_do = TRUE;
984 blkif_shadow_t *shadow;
985 ULONG suspend_resume_state_pdo;
986 srb_list_entry_t *srb_entry;
988 UNREFERENCED_PARAMETER(context);
990 //if (dump_mode) FUNCTION_ENTER();
992 suspend_resume_state_pdo = xvdd->device_state->suspend_resume_state_pdo;
993 KeMemoryBarrier();
995 if (suspend_resume_state_pdo != xvdd->device_state->suspend_resume_state_fdo)
996 {
997 //FUNCTION_ENTER();
998 switch (suspend_resume_state_pdo)
999 {
1000 case SR_STATE_SUSPENDING:
1001 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_SUSPENDING\n"));
1002 break;
1003 case SR_STATE_RESUMING:
1004 KdPrint((__DRIVER_NAME " New pdo state SR_STATE_RESUMING\n"));
1005 XenVbd_InitFromConfig(xvdd);
1006 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1007 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1008 break;
1009 case SR_STATE_RUNNING:
1010 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1011 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1012 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1013 default:
1014 KdPrint((__DRIVER_NAME " New pdo state %d\n", suspend_resume_state_pdo));
1015 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1016 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1017 break;
1019 KeMemoryBarrier();
1022 if (xvdd->device_state->suspend_resume_state_fdo != SR_STATE_RUNNING)
1024 return TRUE;
1027 while (more_to_do)
1029 rp = xvdd->ring.sring->rsp_prod;
1030 KeMemoryBarrier();
1031 for (i = xvdd->ring.rsp_cons; i != rp; i++)
1033 rep = RING_GET_RESPONSE(&xvdd->ring, i);
1034 shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
1035 if (shadow->reset)
1037 KdPrint((__DRIVER_NAME " discarding reset shadow\n"));
1038 for (j = 0; j < shadow->req.nr_segments; j++)
1040 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1041 shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
1044 else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG))
1046 KdPrint((__DRIVER_NAME " discarding stale (non-dump-mode) shadow\n"));
1048 else
1050 srb = shadow->srb;
1051 ASSERT(srb);
1052 srb_entry = srb->SrbExtension;
1053 ASSERT(srb_entry);
1054 /* 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 */
1055 if (rep->status == BLKIF_RSP_OKAY || (dump_mode && dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT))
1056 srb->SrbStatus = SRB_STATUS_SUCCESS;
1057 else
1059 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
1060 if (decode_cdb_is_read(srb))
1061 KdPrint((__DRIVER_NAME " Operation = Read\n"));
1062 else
1063 KdPrint((__DRIVER_NAME " Operation = Write\n"));
1064 srb_entry->error = TRUE;
1066 if (shadow->aligned_buffer_in_use)
1068 ASSERT(xvdd->aligned_buffer_in_use);
1069 xvdd->aligned_buffer_in_use = FALSE;
1070 if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
1071 memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
1073 for (j = 0; j < shadow->req.nr_segments; j++)
1075 xvdd->vectors.GntTbl_EndAccess(xvdd->vectors.context,
1076 shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
1078 srb_entry->outstanding_requests--;
1079 if (!srb_entry->outstanding_requests && srb_entry->offset == srb_entry->length)
1081 if (srb_entry->error)
1083 srb->SrbStatus = SRB_STATUS_ERROR;
1084 srb->ScsiStatus = 0x02;
1085 xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
1086 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1087 XenVbd_MakeAutoSense(xvdd, srb);
1089 StorPortNotification(RequestComplete, xvdd, srb);
1092 shadow->aligned_buffer_in_use = FALSE;
1093 shadow->srb = NULL;
1094 shadow->reset = FALSE;
1095 put_shadow_on_freelist(xvdd, shadow);
1096 break;
1099 xvdd->ring.rsp_cons = i;
1100 if (i != xvdd->ring.req_prod_pvt)
1102 RING_FINAL_CHECK_FOR_RESPONSES(&xvdd->ring, more_to_do);
1104 else
1106 xvdd->ring.sring->rsp_event = i + 1;
1107 more_to_do = FALSE;
1111 XenVbd_PutQueuedSrbsOnRing(xvdd);
1113 if (suspend_resume_state_pdo == SR_STATE_SUSPENDING)
1115 if (xvdd->inactive || xvdd->shadow_free == SHADOW_ENTRIES)
1117 /* all entries are purged from the list (or we are inactive). ready to suspend */
1118 xvdd->device_state->suspend_resume_state_fdo = suspend_resume_state_pdo;
1119 KeMemoryBarrier();
1120 KdPrint((__DRIVER_NAME " Set fdo state SR_STATE_SUSPENDING\n"));
1121 KdPrint((__DRIVER_NAME " Notifying event channel %d\n", xvdd->device_state->pdo_event_channel));
1122 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->device_state->pdo_event_channel);
1125 //if (dump_mode) FUNCTION_EXIT();
1127 return TRUE;
1130 static BOOLEAN
1131 XenVbd_HandleEvent(PVOID DeviceExtension)
1133 BOOLEAN retval;
1134 STOR_LOCK_HANDLE lock_handle;
1136 //if (dump_mode) FUNCTION_ENTER();
1137 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
1138 retval = StorPortSynchronizeAccess(DeviceExtension, XenVbd_HandleEventSynchronised, NULL);
1139 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1140 //if (dump_mode) FUNCTION_EXIT();
1141 return retval;
1144 /* this is only used during hiber and dump */
1145 static BOOLEAN
1146 XenVbd_HwStorInterrupt(PVOID DeviceExtension)
1148 BOOLEAN retval;
1150 //FUNCTION_ENTER();
1151 retval = XenVbd_HandleEventSynchronised(DeviceExtension, NULL);
1152 //FUNCTION_EXIT();
1153 return retval;
1156 static BOOLEAN
1157 XenVbd_HwStorResetBus(PVOID DeviceExtension, ULONG PathId)
1159 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1160 //srb_list_entry_t *srb_entry;
1161 int i;
1162 /* need to make sure that each SRB is only reset once */
1163 LIST_ENTRY srb_reset_list;
1164 PLIST_ENTRY list_entry;
1165 //STOR_LOCK_HANDLE lock_handle;
1167 UNREFERENCED_PARAMETER(PathId);
1169 FUNCTION_ENTER();
1171 /* It appears that the StartIo spinlock is already held at this point */
1173 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1175 if (xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
1177 xvdd->aligned_buffer_in_use = FALSE;
1179 InitializeListHead(&srb_reset_list);
1181 while((list_entry = RemoveHeadList(&xvdd->srb_list)) != &xvdd->srb_list)
1183 #if DBG
1184 srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
1185 KdPrint((__DRIVER_NAME " adding queued SRB %p to reset list\n", srb_entry->srb));
1186 #endif
1187 InsertTailList(&srb_reset_list, list_entry);
1190 for (i = 0; i < MAX_SHADOW_ENTRIES; i++)
1192 if (xvdd->shadows[i].srb)
1194 srb_list_entry_t *srb_entry = xvdd->shadows[i].srb->SrbExtension;
1195 for (list_entry = srb_reset_list.Flink; list_entry != &srb_reset_list; list_entry = list_entry->Flink)
1197 if (list_entry == &srb_entry->list_entry)
1198 break;
1200 if (list_entry == &srb_reset_list)
1202 KdPrint((__DRIVER_NAME " adding in-flight SRB %p to reset list\n", srb_entry->srb));
1203 InsertTailList(&srb_reset_list, &srb_entry->list_entry);
1205 /* set reset here so that the interrupt won't do anything with the srb but will dispose of the shadow entry correctly */
1206 xvdd->shadows[i].reset = TRUE;
1207 xvdd->shadows[i].srb = NULL;
1208 xvdd->shadows[i].aligned_buffer_in_use = FALSE;
1212 while((list_entry = RemoveHeadList(&srb_reset_list)) != &srb_reset_list)
1214 srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
1215 srb_entry->srb->SrbStatus = SRB_STATUS_BUS_RESET;
1216 KdPrint((__DRIVER_NAME " completing SRB %p with status SRB_STATUS_BUS_RESET\n", srb_entry->srb));
1217 StorPortNotification(RequestComplete, xvdd, srb_entry->srb);
1220 /* send a notify to Dom0 just in case it was missed for some reason (which should _never_ happen) */
1221 xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
1223 StorPortNotification(NextRequest, DeviceExtension);
1226 //StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
1228 FUNCTION_EXIT();
1230 return TRUE;
1233 static BOOLEAN
1234 XenVbd_HwStorStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK srb)
1236 PUCHAR data_buffer;
1237 PSCSI_PNP_REQUEST_BLOCK sprb;
1238 PSCSI_POWER_REQUEST_BLOCK spwrb;
1239 PMINIPORT_DUMP_POINTERS dump_pointers;
1240 PCDB cdb;
1241 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1242 ULONG data_transfer_length;
1243 UCHAR srb_status = SRB_STATUS_PENDING;
1244 STOR_LOCK_HANDLE lock_handle;
1246 //if (dump_mode) FUNCTION_ENTER();
1247 //if (dump_mode) KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1249 StorPortAcquireSpinLock(DeviceExtension, StartIoLock, NULL, &lock_handle);
1251 data_transfer_length = srb->DataTransferLength;
1253 if (xvdd->inactive)
1255 KdPrint((__DRIVER_NAME " Inactive srb->Function = %08X\n", srb->Function));
1256 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1257 StorPortNotification(RequestComplete, DeviceExtension, srb);
1258 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1259 return TRUE;
1262 if (!dump_mode && xvdd->device_state->suspend_resume_state_pdo != SR_STATE_RUNNING)
1264 //KdPrint((__DRIVER_NAME " --> HwStorStartIo (Suspending/Resuming)\n"));
1265 srb->SrbStatus = SRB_STATUS_BUSY;
1266 StorPortNotification(RequestComplete, DeviceExtension, srb);
1267 //KdPrint((__DRIVER_NAME " <-- HwStorStartIo (Suspending/Resuming)\n"));
1268 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1269 return TRUE;
1272 if (srb->PathId != 0 || srb->TargetId != 0 || srb->Lun != 0)
1274 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
1275 StorPortNotification(RequestComplete, DeviceExtension, srb);
1276 KdPrint((__DRIVER_NAME " --- HwStorStartIo (Out of bounds - PathId = %d, TargetId = %d, Lun = %d)\n", srb->PathId, srb->TargetId, srb->Lun));
1277 StorPortReleaseSpinLock (DeviceExtension, &lock_handle);
1278 return TRUE;
1281 switch (srb->Function)
1283 case SRB_FUNCTION_EXECUTE_SCSI:
1284 cdb = (PCDB)srb->Cdb;
1286 switch(cdb->CDB6GENERIC.OperationCode)
1288 case SCSIOP_TEST_UNIT_READY:
1289 if (dump_mode)
1290 KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
1291 srb_status = SRB_STATUS_SUCCESS;
1292 srb->ScsiStatus = 0;
1293 break;
1294 case SCSIOP_INQUIRY:
1295 if (dump_mode)
1296 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
1297 // KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
1298 // KdPrint((__DRIVER_NAME " (Length = %d)\n", srb->DataTransferLength));
1300 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1301 data_buffer = srb->DataBuffer;
1302 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1303 srb_status = SRB_STATUS_SUCCESS;
1304 switch (xvdd->device_type)
1306 case XENVBD_DEVICETYPE_DISK:
1307 if ((srb->Cdb[1] & 1) == 0)
1309 if (srb->Cdb[2])
1311 srb_status = SRB_STATUS_ERROR;
1313 else
1315 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1316 id->DeviceType = DIRECT_ACCESS_DEVICE;
1317 id->Versions = 4; /* minimum that WHQL says we must support */
1318 id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
1319 id->HiSupport = 1; /* WHQL test says we should set this */
1320 //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1321 id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
1322 id->CommandQueue = 1;
1323 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1324 memcpy(id->ProductId, scsi_disk_model, 16); // product id
1325 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1326 data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
1329 else
1331 switch (srb->Cdb[2])
1333 case VPD_SUPPORTED_PAGES: /* list of pages we support */
1334 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1335 data_buffer[1] = VPD_SUPPORTED_PAGES;
1336 data_buffer[2] = 0x00;
1337 data_buffer[3] = 2;
1338 data_buffer[4] = 0x00;
1339 data_buffer[5] = 0x80;
1340 data_transfer_length = 6;
1341 break;
1342 case VPD_SERIAL_NUMBER: /* serial number */
1343 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1344 data_buffer[1] = VPD_SERIAL_NUMBER;
1345 data_buffer[2] = 0x00;
1346 data_buffer[3] = 8;
1347 memset(&data_buffer[4], ' ', 8);
1348 data_transfer_length = 12;
1349 break;
1350 case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
1351 data_buffer[0] = DIRECT_ACCESS_DEVICE;
1352 data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
1353 data_buffer[2] = 0x00;
1354 data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
1355 data_buffer[4] = 2; /* ASCII */
1356 data_buffer[5] = 1; /* VendorId */
1357 data_buffer[6] = 0;
1358 data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
1359 memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
1360 data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
1361 break;
1362 default:
1363 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1364 srb_status = SRB_STATUS_ERROR;
1365 break;
1368 break;
1369 case XENVBD_DEVICETYPE_CDROM:
1370 if ((srb->Cdb[1] & 1) == 0)
1372 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
1373 id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
1374 id->RemovableMedia = 1;
1375 id->Versions = 3;
1376 id->ResponseDataFormat = 0;
1377 id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
1378 id->CommandQueue = 1;
1379 memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
1380 memcpy(id->ProductId, scsi_cdrom_model, 16); // product id
1381 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
1382 data_transfer_length = sizeof(INQUIRYDATA);
1384 else
1386 switch (srb->Cdb[2])
1388 case 0x00:
1389 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1390 data_buffer[1] = 0x00;
1391 data_buffer[2] = 0x00;
1392 data_buffer[3] = 2;
1393 data_buffer[4] = 0x00;
1394 data_buffer[5] = 0x80;
1395 data_transfer_length = 6;
1396 break;
1397 case 0x80:
1398 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
1399 data_buffer[1] = 0x80;
1400 data_buffer[2] = 0x00;
1401 data_buffer[3] = 8;
1402 data_buffer[4] = 0x31;
1403 data_buffer[5] = 0x32;
1404 data_buffer[6] = 0x33;
1405 data_buffer[7] = 0x34;
1406 data_buffer[8] = 0x35;
1407 data_buffer[9] = 0x36;
1408 data_buffer[10] = 0x37;
1409 data_buffer[11] = 0x38;
1410 data_transfer_length = 12;
1411 break;
1412 default:
1413 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
1414 srb_status = SRB_STATUS_ERROR;
1415 break;
1418 break;
1419 default:
1420 //KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", xvdd->device_type));
1421 srb_status = SRB_STATUS_ERROR;
1422 break;
1424 break;
1425 case SCSIOP_READ_CAPACITY:
1426 if (dump_mode)
1427 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1428 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1429 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1430 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1431 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1432 data_buffer = srb->DataBuffer;
1433 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1434 if ((xvdd->total_sectors - 1) >> 32)
1436 data_buffer[0] = 0xff;
1437 data_buffer[1] = 0xff;
1438 data_buffer[2] = 0xff;
1439 data_buffer[3] = 0xff;
1441 else
1443 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1444 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1445 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1446 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1448 data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1449 data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1450 data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1451 data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1452 data_transfer_length = 8;
1453 srb->ScsiStatus = 0;
1454 srb_status = SRB_STATUS_SUCCESS;
1455 break;
1456 case SCSIOP_READ_CAPACITY16:
1457 if (dump_mode)
1458 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
1459 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
1460 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
1461 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
1462 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
1463 data_buffer = srb->DataBuffer;
1464 RtlZeroMemory(data_buffer, srb->DataTransferLength);
1465 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
1466 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
1467 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
1468 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
1469 data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
1470 data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
1471 data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
1472 data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
1473 data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
1474 data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
1475 data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
1476 data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
1477 data_transfer_length = 12;
1478 srb->ScsiStatus = 0;
1479 srb_status = SRB_STATUS_SUCCESS;
1480 break;
1481 case SCSIOP_MODE_SENSE:
1482 case SCSIOP_MODE_SENSE10:
1483 if (dump_mode)
1484 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));
1485 data_transfer_length = XenVbd_FillModePage(xvdd, srb);
1486 srb_status = SRB_STATUS_SUCCESS;
1487 break;
1488 case SCSIOP_READ:
1489 case SCSIOP_READ16:
1490 case SCSIOP_WRITE:
1491 case SCSIOP_WRITE16:
1492 //KdPrint((__DRIVER_NAME " srb = %p\n", srb));
1493 XenVbd_PutSrbOnList(xvdd, srb);
1494 XenVbd_PutQueuedSrbsOnRing(xvdd);
1495 break;
1496 case SCSIOP_VERIFY:
1497 case SCSIOP_VERIFY16:
1498 // Should we do more here?
1499 if (dump_mode)
1500 KdPrint((__DRIVER_NAME " Command = VERIFY\n"));
1501 srb_status = SRB_STATUS_SUCCESS;
1502 break;
1503 #if 0
1504 case SCSIOP_REPORT_LUNS:
1505 if (dump_mode)
1506 KdPrint((__DRIVER_NAME " Command = REPORT_LUNS\n"));
1507 switch (srb->Cdb[1])
1510 srb_status = SRB_STATUS_SUCCESS;;
1511 break;
1512 #endif
1513 case SCSIOP_REQUEST_SENSE:
1514 if (dump_mode)
1515 KdPrint((__DRIVER_NAME " Command = REQUEST_SENSE\n"));
1516 data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
1517 srb_status = SRB_STATUS_SUCCESS;
1518 break;
1519 case SCSIOP_READ_TOC:
1520 if (dump_mode)
1521 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
1522 data_buffer = srb->DataBuffer;
1523 /*
1524 #define READ_TOC_FORMAT_TOC 0x00
1525 #define READ_TOC_FORMAT_SESSION 0x01
1526 #define READ_TOC_FORMAT_FULL_TOC 0x02
1527 #define READ_TOC_FORMAT_PMA 0x03
1528 #define READ_TOC_FORMAT_ATIP 0x04
1529 */
1530 // KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
1531 // KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
1532 // KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
1533 // KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
1534 // KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
1535 // KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
1536 // KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
1537 switch (cdb->READ_TOC.Format2)
1539 case READ_TOC_FORMAT_TOC:
1540 data_buffer[0] = 0; // length MSB
1541 data_buffer[1] = 10; // length LSB
1542 data_buffer[2] = 1; // First Track
1543 data_buffer[3] = 1; // Last Track
1544 data_buffer[4] = 0; // Reserved
1545 data_buffer[5] = 0x14; // current position data + uninterrupted data
1546 data_buffer[6] = 1; // last complete track
1547 data_buffer[7] = 0; // reserved
1548 data_buffer[8] = 0; // MSB Block
1549 data_buffer[9] = 0;
1550 data_buffer[10] = 0;
1551 data_buffer[11] = 0; // LSB Block
1552 data_transfer_length = 12;
1553 srb_status = SRB_STATUS_SUCCESS;
1554 break;
1555 case READ_TOC_FORMAT_SESSION:
1556 case READ_TOC_FORMAT_FULL_TOC:
1557 case READ_TOC_FORMAT_PMA:
1558 case READ_TOC_FORMAT_ATIP:
1559 srb_status = SRB_STATUS_ERROR;
1560 break;
1561 default:
1562 srb_status = SRB_STATUS_ERROR;
1563 break;
1565 break;
1566 case SCSIOP_START_STOP_UNIT:
1567 KdPrint((__DRIVER_NAME " Command = SCSIOP_START_STOP_UNIT\n"));
1568 srb_status = SRB_STATUS_SUCCESS;
1569 break;
1570 case SCSIOP_RESERVE_UNIT:
1571 KdPrint((__DRIVER_NAME " Command = SCSIOP_RESERVE_UNIT\n"));
1572 srb_status = SRB_STATUS_SUCCESS;
1573 break;
1574 case SCSIOP_RELEASE_UNIT:
1575 KdPrint((__DRIVER_NAME " Command = SCSIOP_RELEASE_UNIT\n"));
1576 srb_status = SRB_STATUS_SUCCESS;
1577 break;
1578 default:
1579 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
1580 srb_status = SRB_STATUS_ERROR;
1581 break;
1583 if (srb_status == SRB_STATUS_ERROR)
1585 KdPrint((__DRIVER_NAME " EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
1586 if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
1588 xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
1589 xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
1591 srb->SrbStatus = srb_status;
1592 srb->ScsiStatus = 0x02;
1593 XenVbd_MakeAutoSense(xvdd, srb);
1594 StorPortNotification(RequestComplete, DeviceExtension, srb);
1596 else if (srb_status != SRB_STATUS_PENDING)
1598 if (data_transfer_length > srb->DataTransferLength)
1599 KdPrint((__DRIVER_NAME " data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
1601 if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
1603 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
1604 srb->DataTransferLength = data_transfer_length;
1606 else
1608 srb->SrbStatus = srb_status;
1610 xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
1611 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1612 StorPortNotification(RequestComplete, DeviceExtension, srb);
1614 break;
1615 case SRB_FUNCTION_IO_CONTROL:
1616 KdPrint((__DRIVER_NAME " SRB_FUNCTION_IO_CONTROL\n"));
1617 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1618 StorPortNotification(RequestComplete, DeviceExtension, srb);
1619 break;
1620 case SRB_FUNCTION_FLUSH:
1621 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1622 srb->SrbStatus = SRB_STATUS_SUCCESS;
1623 StorPortNotification(RequestComplete, DeviceExtension, srb);
1624 break;
1625 case SRB_FUNCTION_PNP:
1626 KdPrint((__DRIVER_NAME " SRB_FUNCTION_PNP\n"));
1627 sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
1628 switch (sprb->PnPAction)
1630 case StorStartDevice:
1631 KdPrint((__DRIVER_NAME " StorStartDevice\n"));
1632 break;
1633 case StorRemoveDevice:
1634 KdPrint((__DRIVER_NAME " StorRemoveDevice\n"));
1635 break;
1636 case StorStopDevice:
1637 KdPrint((__DRIVER_NAME " StorStopDevice\n"));
1638 break;
1639 case StorQueryCapabilities:
1640 KdPrint((__DRIVER_NAME " StorQueryCapabilities\n"));
1641 break;
1642 case StorFilterResourceRequirements:
1643 KdPrint((__DRIVER_NAME " StorFilterResourceRequirements\n"));
1644 break;
1645 default:
1646 KdPrint((__DRIVER_NAME " Stor%d\n", sprb->PnPAction));
1647 break;
1649 KdPrint((__DRIVER_NAME " SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
1650 srb->SrbStatus = SRB_STATUS_SUCCESS;
1651 StorPortNotification(RequestComplete, DeviceExtension, srb);
1652 break;
1654 case SRB_FUNCTION_POWER:
1655 KdPrint((__DRIVER_NAME " SRB_FUNCTION_POWER\n"));
1656 spwrb = (PSCSI_POWER_REQUEST_BLOCK)srb;
1657 switch (spwrb->PowerAction)
1659 case StorPowerActionNone:
1660 KdPrint((__DRIVER_NAME " StorPowerActionNone\n"));
1661 break;
1662 case StorPowerActionReserved:
1663 KdPrint((__DRIVER_NAME " StorPowerActionReserved\n"));
1664 break;
1665 case StorPowerActionSleep:
1666 KdPrint((__DRIVER_NAME " StorPowerActionSleep\n"));
1667 break;
1668 case StorPowerActionHibernate:
1669 KdPrint((__DRIVER_NAME " StorPowerActionHibernate\n"));
1670 break;
1671 case StorPowerActionShutdown:
1672 KdPrint((__DRIVER_NAME " StorPowerActionShutdown\n"));
1673 break;
1674 case StorPowerActionShutdownReset:
1675 KdPrint((__DRIVER_NAME " StorPowerActionShutdownReset\n"));
1676 break;
1677 case StorPowerActionShutdownOff:
1678 KdPrint((__DRIVER_NAME " StorPowerActionShutdownOff\n"));
1679 break;
1680 case StorPowerActionWarmEject:
1681 KdPrint((__DRIVER_NAME " StorPowerActionWarmEject\n"));
1682 break;
1683 default:
1684 KdPrint((__DRIVER_NAME " Stor%d\n", spwrb->PowerAction));
1685 break;
1687 XenVbd_PutSrbOnList(xvdd, srb);
1688 XenVbd_PutQueuedSrbsOnRing(xvdd);
1689 break;
1690 case SRB_FUNCTION_DUMP_POINTERS:
1691 KdPrint((__DRIVER_NAME " SRB_FUNCTION_DUMP_POINTERS\n"));
1692 KdPrint((__DRIVER_NAME " DataTransferLength = %d\n", srb->DataTransferLength));
1693 dump_pointers = srb->DataBuffer;
1694 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1695 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1696 KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1697 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1698 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1699 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1700 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1701 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1702 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1703 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1704 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1705 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1706 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1707 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1708 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1709 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1710 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1712 dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
1713 dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
1714 RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
1715 dump_pointers->AdapterObject = NULL;
1716 dump_pointers->MappedRegisterBase = 0;
1717 dump_pointers->CommonBufferSize = 0;
1718 dump_pointers->MiniportPrivateDumpData = (PVOID)xvdd->device_base;
1719 //dump_pointers->SystemIoBusNumber = 0;
1720 dump_pointers->AdapterInterfaceType = Internal;
1721 dump_pointers->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
1722 dump_pointers->NumberOfPhysicalBreaks = dump_pointers->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
1723 dump_pointers->AlignmentMask = 0;
1724 dump_pointers->NumberOfAccessRanges = 1;
1725 dump_pointers->NumberOfBuses = 1;
1726 dump_pointers->Master = TRUE;
1727 dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1728 dump_pointers->MaximumNumberOfTargets = 2;
1730 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1731 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1732 //KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1733 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1734 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1735 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1736 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1737 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1738 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1739 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1740 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1741 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1742 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1743 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1744 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1745 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1746 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1748 srb->SrbStatus = SRB_STATUS_SUCCESS;
1749 StorPortNotification(RequestComplete, DeviceExtension, srb);
1750 break;
1751 case SRB_FUNCTION_SHUTDOWN:
1752 KdPrint((__DRIVER_NAME " SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1753 //ASSERT(IsListEmpty(&xvdd->srb_list));
1754 //ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
1755 XenVbd_PutSrbOnList(xvdd, srb);
1756 XenVbd_PutQueuedSrbsOnRing(xvdd);
1757 //srb->SrbStatus = SRB_STATUS_SUCCESS;
1758 //StorPortNotification(RequestComplete, DeviceExtension, srb);
1759 break;
1760 case SRB_FUNCTION_RESET_BUS:
1761 case SRB_FUNCTION_RESET_DEVICE:
1762 case SRB_FUNCTION_RESET_LOGICAL_UNIT:
1763 /* the path doesn't matter here - only ever one device*/
1764 XenVbd_HwStorResetBus(DeviceExtension, 0);
1765 srb->SrbStatus = SRB_STATUS_SUCCESS;
1766 StorPortNotification(RequestComplete, DeviceExtension, srb);
1767 break;
1769 default:
1770 KdPrint((__DRIVER_NAME " Unhandled srb->Function = %08X\n", srb->Function));
1771 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1772 StorPortNotification(RequestComplete, DeviceExtension, srb);
1773 break;
1776 //if (dump_mode) FUNCTION_EXIT();
1777 StorPortReleaseSpinLock(DeviceExtension, &lock_handle);
1778 return TRUE;
1781 static SCSI_ADAPTER_CONTROL_STATUS
1782 XenVbd_HwStorAdapterControl(PVOID DeviceExtension, SCSI_ADAPTER_CONTROL_TYPE ControlType, PVOID Parameters)
1784 PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
1785 SCSI_ADAPTER_CONTROL_STATUS Status = ScsiAdapterControlSuccess;
1786 PSCSI_SUPPORTED_CONTROL_TYPE_LIST SupportedControlTypeList;
1787 //KIRQL OldIrql;
1789 FUNCTION_ENTER();
1790 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1791 KdPrint((__DRIVER_NAME " xvdd = %p\n", xvdd));
1793 switch (ControlType)
1795 case ScsiQuerySupportedControlTypes:
1796 SupportedControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
1797 KdPrint((__DRIVER_NAME " ScsiQuerySupportedControlTypes (Max = %d)\n", SupportedControlTypeList->MaxControlType));
1798 SupportedControlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
1799 SupportedControlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
1800 SupportedControlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
1801 break;
1802 case ScsiStopAdapter:
1803 KdPrint((__DRIVER_NAME " ScsiStopAdapter\n"));
1804 if (xvdd->inactive)
1806 KdPrint((__DRIVER_NAME " inactive - nothing to do\n"));
1807 break;
1809 ASSERT(IsListEmpty(&xvdd->srb_list));
1810 ASSERT(xvdd->shadow_free == SHADOW_ENTRIES);
1811 break;
1812 case ScsiRestartAdapter:
1813 KdPrint((__DRIVER_NAME " ScsiRestartAdapter\n"));
1814 if (xvdd->inactive) {
1815 KdPrint((__DRIVER_NAME " inactive - nothing to do\n"));
1816 break;
1818 /* increase the tag every time we stop/start to track where the gref's came from */
1819 xvdd->grant_tag++;
1820 if (XenVbd_InitFromConfig(xvdd) != SP_RETURN_FOUND) {
1821 #pragma warning(suppress:28159)
1822 KeBugCheckEx(DATA_COHERENCY_EXCEPTION, 0, (ULONG_PTR)xvdd, 0, 0);
1824 break;
1825 case ScsiSetBootConfig:
1826 KdPrint((__DRIVER_NAME " ScsiSetBootConfig\n"));
1827 break;
1828 case ScsiSetRunningConfig:
1829 KdPrint((__DRIVER_NAME " ScsiSetRunningConfig\n"));
1830 break;
1831 default:
1832 KdPrint((__DRIVER_NAME " UNKNOWN\n"));
1833 break;
1836 FUNCTION_EXIT();
1838 return Status;
1841 NTSTATUS
1842 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
1844 ULONG status;
1846 FUNCTION_ENTER();
1847 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
1848 KdPrint((__DRIVER_NAME " DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
1850 /* RegistryPath == NULL when we are invoked as a crash dump driver */
1851 if (!RegistryPath) {
1852 dump_mode = TRUE;
1855 if (!dump_mode) {
1856 VIRTUAL_HW_INITIALIZATION_DATA VHwInitializationData;
1857 RtlZeroMemory(&VHwInitializationData, sizeof(VIRTUAL_HW_INITIALIZATION_DATA));
1858 VHwInitializationData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
1859 VHwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* maybe should be internal? */
1860 VHwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE;
1861 VHwInitializationData.SpecificLuExtensionSize = 0;
1862 VHwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
1863 VHwInitializationData.NumberOfAccessRanges = 1;
1864 VHwInitializationData.MapBuffers = STOR_MAP_ALL_BUFFERS;
1865 //VHwInitializationData.NeedPhysicalAddresses = TRUE;
1866 VHwInitializationData.TaggedQueuing = TRUE;
1867 VHwInitializationData.AutoRequestSense = TRUE;
1868 VHwInitializationData.MultipleRequestPerLu = TRUE;
1869 VHwInitializationData.ReceiveEvent = TRUE;
1870 VHwInitializationData.PortVersionFlags = 0;
1871 VHwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
1872 VHwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
1873 VHwInitializationData.HwFindAdapter = XenVbd_VirtualHwStorFindAdapter;
1874 VHwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
1875 VHwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
1876 status = StorPortInitialize(DriverObject, RegistryPath, (PHW_INITIALIZATION_DATA)&VHwInitializationData, NULL);
1877 } else {
1878 HW_INITIALIZATION_DATA HwInitializationData;
1879 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
1880 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
1881 HwInitializationData.AdapterInterfaceType = Internal; //PNPBus; /* not Internal */
1882 HwInitializationData.DeviceExtensionSize = FIELD_OFFSET(XENVBD_DEVICE_DATA, aligned_buffer_data) + UNALIGNED_BUFFER_DATA_SIZE_DUMP_MODE;
1883 HwInitializationData.SrbExtensionSize = sizeof(srb_list_entry_t);
1884 HwInitializationData.NumberOfAccessRanges = 1;
1885 HwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1886 HwInitializationData.NeedPhysicalAddresses = TRUE;
1887 HwInitializationData.TaggedQueuing = FALSE;
1888 HwInitializationData.AutoRequestSense = TRUE;
1889 HwInitializationData.MultipleRequestPerLu = FALSE;
1890 HwInitializationData.ReceiveEvent = TRUE;
1891 HwInitializationData.HwInitialize = XenVbd_HwStorInitialize;
1892 HwInitializationData.HwStartIo = XenVbd_HwStorStartIo;
1893 HwInitializationData.HwFindAdapter = XenVbd_HwStorFindAdapter;
1894 HwInitializationData.HwResetBus = XenVbd_HwStorResetBus;
1895 HwInitializationData.HwAdapterControl = XenVbd_HwStorAdapterControl;
1896 HwInitializationData.HwInterrupt = XenVbd_HwStorInterrupt;
1897 status = StorPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
1900 if(!NT_SUCCESS(status)) {
1901 KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", status));
1904 FUNCTION_EXIT();
1906 return status;