win-pvdrivers

view xenvbd_common/common_miniport.h @ 1018:9c6af8d0bdb6

fix problem with stopping xenvbd. Tidyup.
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 12 20:45:08 2013 +1100 (2013-02-12)
parents fe3af8f4d54b
children aa2e51f67f7c
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2013 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 #if defined(__x86_64__)
21 #define LongLongToPtr(x) (PVOID)(x)
22 #else
23 #define LongLongToPtr(x) UlongToPtr(x)
24 #endif
26 #if defined(__x86_64__)
27 #define ABI_PROTOCOL "x86_64-abi"
28 #else
29 #define ABI_PROTOCOL "x86_32-abi"
30 #endif
32 ULONGLONG parse_numeric_string(PCHAR string) {
33 ULONGLONG val = 0;
34 while (*string != 0) {
35 val = val * 10 + (*string - '0');
36 string++;
37 }
38 return val;
39 }
41 /* called with StartIoLock held */
42 static blkif_shadow_t *
43 get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
44 {
45 if (xvdd->shadow_free == 0) {
46 KdPrint((__DRIVER_NAME " No more shadow entries\n"));
47 return NULL;
48 }
49 xvdd->shadow_free--;
50 //if (xvdd->shadow_free < xvdd->shadow_min_free)
51 // xvdd->shadow_min_free = xvdd->shadow_free;
52 return &xvdd->shadows[xvdd->shadow_free_list[xvdd->shadow_free]];
53 }
55 /* called with StartIoLock held */
56 static VOID
57 put_shadow_on_freelist(PXENVBD_DEVICE_DATA xvdd, blkif_shadow_t *shadow)
58 {
59 xvdd->shadow_free_list[xvdd->shadow_free] = (USHORT)(shadow->req.id & SHADOW_ID_ID_MASK);
60 shadow->srb = NULL;
61 shadow->reset = FALSE;
62 shadow->aligned_buffer_in_use = FALSE;
63 xvdd->shadow_free++;
64 }
66 static __inline ULONG
67 decode_cdb_length(PSCSI_REQUEST_BLOCK srb)
68 {
69 switch (srb->Cdb[0])
70 {
71 case SCSIOP_READ:
72 case SCSIOP_WRITE:
73 return ((ULONG)(UCHAR)srb->Cdb[7] << 8) | (ULONG)(UCHAR)srb->Cdb[8];
74 case SCSIOP_READ16:
75 case SCSIOP_WRITE16:
76 return ((ULONG)(UCHAR)srb->Cdb[10] << 24) | ((ULONG)(UCHAR)srb->Cdb[11] << 16) | ((ULONG)(UCHAR)srb->Cdb[12] << 8) | (ULONG)(UCHAR)srb->Cdb[13];
77 default:
78 return 0;
79 }
80 }
82 static blkif_response_t *
83 XenVbd_GetResponse(PXENVBD_DEVICE_DATA xvdd, int i) {
84 return RING_GET_RESPONSE(&xvdd->ring, i);
85 }
87 static VOID
88 XenVbd_PutRequest(PXENVBD_DEVICE_DATA xvdd, blkif_request_t *req) {
89 *RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt) = *req;
90 xvdd->ring.req_prod_pvt++;
91 }
93 static VOID
94 XenVbd_PutSrbOnList(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb) {
95 srb_list_entry_t *srb_entry = srb->SrbExtension;
96 srb_entry->srb = srb;
97 srb_entry->outstanding_requests = 0;
98 srb_entry->length = srb->DataTransferLength;
99 srb_entry->offset = 0;
100 srb_entry->error = FALSE;
101 InsertTailList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
102 }
104 static __inline ULONGLONG
105 decode_cdb_sector(PSCSI_REQUEST_BLOCK srb)
106 {
107 ULONGLONG sector;
109 switch (srb->Cdb[0])
110 {
111 case SCSIOP_READ:
112 case SCSIOP_WRITE:
113 sector = ((ULONG)(UCHAR)srb->Cdb[2] << 24) | ((ULONG)(UCHAR)srb->Cdb[3] << 16) | ((ULONG)(UCHAR)srb->Cdb[4] << 8) | (ULONG)(UCHAR)srb->Cdb[5];
114 break;
115 case SCSIOP_READ16:
116 case SCSIOP_WRITE16:
117 sector = ((ULONGLONG)(UCHAR)srb->Cdb[2] << 56) | ((ULONGLONG)(UCHAR)srb->Cdb[3] << 48)
118 | ((ULONGLONG)(UCHAR)srb->Cdb[4] << 40) | ((ULONGLONG)(UCHAR)srb->Cdb[5] << 32)
119 | ((ULONGLONG)(UCHAR)srb->Cdb[6] << 24) | ((ULONGLONG)(UCHAR)srb->Cdb[7] << 16)
120 | ((ULONGLONG)(UCHAR)srb->Cdb[8] << 8) | ((ULONGLONG)(UCHAR)srb->Cdb[9]);
121 //KdPrint((__DRIVER_NAME " sector_number = %d (high) %d (low)\n", (ULONG)(sector >> 32), (ULONG)sector));
122 break;
123 default:
124 sector = 0;
125 break;
126 }
127 return sector;
128 }
130 static __inline BOOLEAN
131 decode_cdb_is_read(PSCSI_REQUEST_BLOCK srb)
132 {
133 switch (srb->Cdb[0])
134 {
135 case SCSIOP_READ:
136 case SCSIOP_READ16:
137 return TRUE;
138 case SCSIOP_WRITE:
139 case SCSIOP_WRITE16:
140 return FALSE;
141 default:
142 return FALSE;
143 }
144 }
146 static ULONG
147 XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
148 {
149 PSENSE_DATA sd = srb->SenseInfoBuffer;
151 UNREFERENCED_PARAMETER(xvdd);
153 if (!srb->SenseInfoBuffer)
154 return 0;
156 sd->ErrorCode = 0x70;
157 sd->Valid = 1;
158 sd->SenseKey = sense_key;
159 sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
160 sd->AdditionalSenseCode = additional_sense_code;
161 return sizeof(SENSE_DATA);
162 }
164 static VOID
165 XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb)
166 {
167 if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
168 return;
169 XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
170 srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
171 }
173 /* called with StartIo lock held */
174 static VOID
175 XenVbd_HandleEvent(PXENVBD_DEVICE_DATA xvdd) {
176 PSCSI_REQUEST_BLOCK srb;
177 RING_IDX i, rp;
178 ULONG j;
179 blkif_response_t *rep;
180 //int block_count;
181 int more_to_do = TRUE;
182 blkif_shadow_t *shadow;
183 srb_list_entry_t *srb_entry;
185 //if (dump_mode)
186 //FUNCTION_ENTER();
188 while (more_to_do) {
189 rp = xvdd->ring.sring->rsp_prod;
190 KeMemoryBarrier();
191 for (i = xvdd->ring.rsp_cons; i != rp; i++) {
192 rep = XenVbd_GetResponse(xvdd, i);
193 shadow = &xvdd->shadows[rep->id & SHADOW_ID_ID_MASK];
194 if (shadow->reset) {
195 /* the srb's here have already been returned */
196 FUNCTION_MSG("discarding reset shadow\n");
197 for (j = 0; j < shadow->req.nr_segments; j++) {
198 XnEndAccess(xvdd->handle,
199 shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
200 }
201 } else if (dump_mode && !(rep->id & SHADOW_ID_DUMP_FLAG)) {
202 FUNCTION_MSG("discarding stale (non-dump-mode) shadow\n");
203 } else {
204 srb = shadow->srb;
205 NT_ASSERT(srb);
206 srb_entry = srb->SrbExtension;
207 NT_ASSERT(srb_entry);
208 /* 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 */
209 if (rep->status == BLKIF_RSP_OKAY || (dump_mode && dump_mode_errors++ < DUMP_MODE_ERROR_LIMIT)) {
210 srb->SrbStatus = SRB_STATUS_SUCCESS;
211 } else {
212 KdPrint((__DRIVER_NAME " Xen Operation returned error\n"));
213 if (decode_cdb_is_read(srb))
214 KdPrint((__DRIVER_NAME " Operation = Read\n"));
215 else
216 KdPrint((__DRIVER_NAME " Operation = Write\n"));
217 srb_entry->error = TRUE;
218 }
219 if (shadow->aligned_buffer_in_use) {
220 NT_ASSERT(xvdd->aligned_buffer_in_use);
221 xvdd->aligned_buffer_in_use = FALSE;
222 if (srb->SrbStatus == SRB_STATUS_SUCCESS && decode_cdb_is_read(srb))
223 memcpy((PUCHAR)shadow->system_address, xvdd->aligned_buffer, shadow->length);
224 }
225 for (j = 0; j < shadow->req.nr_segments; j++) {
226 XnEndAccess(xvdd->handle, shadow->req.seg[j].gref, FALSE, xvdd->grant_tag);
227 }
228 srb_entry->outstanding_requests--;
229 if (srb_entry->outstanding_requests == 0 && srb_entry->offset == srb_entry->length) {
230 if (srb_entry->error) {
231 srb->SrbStatus = SRB_STATUS_ERROR;
232 srb->ScsiStatus = 0x02;
233 xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
234 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
235 XenVbd_MakeAutoSense(xvdd, srb);
236 }
237 SxxxPortNotification(RequestComplete, xvdd, srb);
238 }
239 }
240 put_shadow_on_freelist(xvdd, shadow);
241 }
243 /* put queue'd Srbs onto the ring now so we can set the event in the best possible way */
244 if (dump_mode || xvdd->device_state == DEVICE_STATE_ACTIVE) {
245 XenVbd_ProcessSrbList(xvdd);
246 }
248 xvdd->ring.rsp_cons = i;
249 if (i == xvdd->ring.req_prod_pvt) {
250 /* all possible requests complete - can't have more responses than requests */
251 more_to_do = FALSE;
252 xvdd->ring.sring->rsp_event = i + 1;
253 } else {
254 more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xvdd->ring);
255 if (!more_to_do) {
256 xvdd->ring.sring->rsp_event = i + max(1, (SHADOW_ENTRIES - xvdd->shadow_free) / 2);
257 more_to_do = RING_HAS_UNCONSUMED_RESPONSES(&xvdd->ring);
258 }
259 }
260 }
262 if (xvdd->device_state != DEVICE_STATE_ACTIVE && xvdd->device_state != DEVICE_STATE_INACTIVE && xvdd->shadow_free == SHADOW_ENTRIES) {
263 FUNCTION_MSG("ring now empty - completing disconnect\n");
264 XenVbd_CompleteDisconnect(xvdd);
265 }
266 return;
267 }
269 /* called with StartIoLock held */
270 /* returns TRUE if something was put on the ring and notify might be required */
271 static BOOLEAN
272 XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb) {
273 srb_list_entry_t *srb_entry = srb->SrbExtension;
274 /* sector_number and block_count are the adjusted-to-512-byte-sector values */
275 ULONGLONG sector_number;
276 ULONG block_count;
277 blkif_shadow_t *shadow;
278 ULONG remaining, offset, length;
279 grant_ref_t gref;
280 PUCHAR ptr;
281 int i;
282 PVOID system_address;
284 //if (dump_mode) FUNCTION_ENTER();
285 //FUNCTION_MSG("Srb = %p\n", srb);
287 //FUNCTION_MSG("aligned_buffer_in_use = %d\n", xvdd->aligned_buffer_in_use);
288 //FUNCTION_MSG("shadow_free = %d\n", xvdd->shadow_free);
290 NT_ASSERT(srb);
292 if (!dump_mode) {
293 if (SxxxPortGetSystemAddress(xvdd, srb, &system_address) != STATUS_SUCCESS) {
294 FUNCTION_MSG("Failed to map DataBuffer\n");
295 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
296 //if (dump_mode) FUNCTION_EXIT();
297 return FALSE;
298 }
299 system_address = (PUCHAR)system_address + srb_entry->offset;
300 } else {
301 //FUNCTION_MSG("DataBuffer = %p\n", srb->DataBuffer);
302 system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
303 }
304 block_count = decode_cdb_length(srb);
305 sector_number = decode_cdb_sector(srb);
306 block_count *= xvdd->bytes_per_sector / 512;
307 sector_number *= xvdd->bytes_per_sector / 512;
309 NT_ASSERT(block_count * 512 == srb->DataTransferLength);
311 sector_number += srb_entry->offset / 512;
312 block_count -= srb_entry->offset / 512;
314 NT_ASSERT(block_count > 0);
316 /* look for pending writes that overlap this one */
317 /* we get warnings from drbd if we don't */
318 if (srb_entry->offset == 0) {
319 for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
320 PSCSI_REQUEST_BLOCK srb2;
321 ULONGLONG sector_number2;
322 ULONG block_count2;
324 srb2 = xvdd->shadows[i].srb;
325 if (!srb2)
326 continue;
327 if (decode_cdb_is_read(srb2))
328 continue;
329 block_count2 = decode_cdb_length(srb2);;
330 block_count2 *= xvdd->bytes_per_sector / 512;
331 sector_number2 = decode_cdb_sector(srb2);
332 sector_number2 *= xvdd->bytes_per_sector / 512;
334 if (sector_number < sector_number2 && sector_number + block_count <= sector_number2)
335 continue;
336 if (sector_number2 < sector_number && sector_number2 + block_count2 <= sector_number)
337 continue;
339 KdPrint((__DRIVER_NAME " Concurrent outstanding write detected (%I64d, %d) (%I64d, %d)\n",
340 sector_number, block_count, sector_number2, block_count2));
341 break;
342 }
343 if (i != MAX_SHADOW_ENTRIES) {
344 /* put the srb back at the start of the queue */
345 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
346 //if (dump_mode) FUNCTION_EXIT();
347 return FALSE;
348 }
349 }
351 shadow = get_shadow_from_freelist(xvdd);
352 if (!shadow) {
353 /* put the srb back at the start of the queue */
354 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb->SrbExtension);
355 //if (dump_mode) FUNCTION_EXIT();
356 return FALSE;
357 }
358 NT_ASSERT(!shadow->aligned_buffer_in_use);
359 NT_ASSERT(!shadow->srb);
360 shadow->req.sector_number = sector_number;
361 shadow->req.handle = 0;
362 shadow->req.operation = decode_cdb_is_read(srb)?BLKIF_OP_READ:BLKIF_OP_WRITE;
363 shadow->req.nr_segments = 0;
364 shadow->srb = srb;
365 shadow->length = 0;
366 shadow->system_address = system_address;
367 shadow->reset = FALSE;
369 if (!dump_mode) {
370 if ((ULONG_PTR)shadow->system_address & 511) {
371 xvdd->aligned_buffer_in_use = TRUE;
372 /* limit to aligned_buffer_size */
373 block_count = min(block_count, xvdd->aligned_buffer_size / 512);
374 ptr = (PUCHAR)xvdd->aligned_buffer;
375 if (!decode_cdb_is_read(srb))
376 memcpy(ptr, shadow->system_address, block_count * 512);
377 shadow->aligned_buffer_in_use = TRUE;
378 } else {
379 ptr = (PUCHAR)shadow->system_address;
380 shadow->aligned_buffer_in_use = FALSE;
381 }
382 } else {
383 NT_ASSERT(!((ULONG_PTR)shadow->system_address & 511));
384 ptr = shadow->system_address;
385 shadow->aligned_buffer_in_use = FALSE;
386 }
388 remaining = block_count * 512;
389 while (remaining > 0 && shadow->req.nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST) {
390 PHYSICAL_ADDRESS physical_address;
392 if (!dump_mode) {
393 physical_address = MmGetPhysicalAddress(ptr);
394 } else {
395 #if 0
396 ULONG length;
397 physical_address = StorPortGetPhysicalAddress(xvdd, srb, ptr, &length);
398 #endif
399 physical_address = MmGetPhysicalAddress(ptr);
400 }
401 gref = XnGrantAccess(xvdd->handle,
402 (ULONG)(physical_address.QuadPart >> PAGE_SHIFT), FALSE, INVALID_GRANT_REF, xvdd->grant_tag);
403 if (gref == INVALID_GRANT_REF) {
404 ULONG i;
405 for (i = 0; i < shadow->req.nr_segments; i++) {
406 XnEndAccess(xvdd->handle,
407 shadow->req.seg[i].gref, FALSE, xvdd->grant_tag);
408 }
409 if (shadow->aligned_buffer_in_use) {
410 shadow->aligned_buffer_in_use = FALSE;
411 xvdd->aligned_buffer_in_use = FALSE;
412 }
413 /* put the srb back at the start of the queue */
414 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
415 put_shadow_on_freelist(xvdd, shadow);
416 KdPrint((__DRIVER_NAME " Out of gref's. Deferring\n"));
417 /* TODO: what if there are no requests currently in progress to kick the queue again?? timer? */
418 return FALSE;
419 }
420 offset = physical_address.LowPart & (PAGE_SIZE - 1);
421 length = min(PAGE_SIZE - offset, remaining);
422 NT_ASSERT((offset & 511) == 0);
423 NT_ASSERT((length & 511) == 0);
424 NT_ASSERT(offset + length <= PAGE_SIZE);
425 shadow->req.seg[shadow->req.nr_segments].gref = gref;
426 shadow->req.seg[shadow->req.nr_segments].first_sect = (UCHAR)(offset / 512);
427 shadow->req.seg[shadow->req.nr_segments].last_sect = (UCHAR)(((offset + length) / 512) - 1);
428 remaining -= length;
429 ptr += length;
430 shadow->length += length;
431 shadow->req.nr_segments++;
432 }
433 srb_entry->offset += shadow->length;
434 srb_entry->outstanding_requests++;
435 XenVbd_PutRequest(xvdd, &shadow->req);
436 if (srb_entry->offset < srb_entry->length) {
437 /* put the srb back at the start of the queue to continue on the next request */
438 InsertHeadList(&xvdd->srb_list, (PLIST_ENTRY)srb_entry);
439 }
440 //if (dump_mode)
441 //FUNCTION_EXIT();
442 return TRUE;
443 }
445 static ULONG
446 XenVbd_FillModePage(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb) {
447 PMODE_PARAMETER_HEADER parameter_header = NULL;
448 PMODE_PARAMETER_HEADER10 parameter_header10 = NULL;
449 PMODE_PARAMETER_BLOCK param_block;
450 PMODE_FORMAT_PAGE format_page;
451 ULONG offset = 0;
452 UCHAR buffer[1024];
453 BOOLEAN valid_page = FALSE;
454 BOOLEAN cdb_llbaa;
455 BOOLEAN cdb_dbd;
456 UCHAR cdb_page_code;
457 USHORT cdb_allocation_length;
459 UNREFERENCED_PARAMETER(xvdd);
461 RtlZeroMemory(srb->DataBuffer, srb->DataTransferLength);
462 RtlZeroMemory(buffer, ARRAY_SIZE(buffer));
463 offset = 0;
465 //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
467 switch (srb->Cdb[0]) {
468 case SCSIOP_MODE_SENSE:
469 cdb_llbaa = FALSE;
470 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
471 cdb_page_code = srb->Cdb[2] & 0x3f;
472 cdb_allocation_length = srb->Cdb[4];
473 parameter_header = (PMODE_PARAMETER_HEADER)&buffer[offset];
474 parameter_header->MediumType = 0;
475 parameter_header->DeviceSpecificParameter = 0;
476 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ) {
477 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
478 parameter_header->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
479 }
480 offset += sizeof(MODE_PARAMETER_HEADER);
481 break;
482 case SCSIOP_MODE_SENSE10:
483 cdb_llbaa = (BOOLEAN)!!(srb->Cdb[1] & 16);
484 cdb_dbd = (BOOLEAN)!!(srb->Cdb[1] & 8);
485 cdb_page_code = srb->Cdb[2] & 0x3f;
486 cdb_allocation_length = (srb->Cdb[7] << 8) | srb->Cdb[8];
487 parameter_header10 = (PMODE_PARAMETER_HEADER10)&buffer[offset];
488 parameter_header10->MediumType = 0;
489 parameter_header10->DeviceSpecificParameter = 0;
490 if (xvdd->device_mode == XENVBD_DEVICEMODE_READ)
491 {
492 KdPrint((__DRIVER_NAME " Mode sense to a read only disk.\n"));
493 parameter_header10->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
494 }
495 offset += sizeof(MODE_PARAMETER_HEADER10);
496 break;
497 default:
498 KdPrint((__DRIVER_NAME " SCSIOP_MODE_SENSE_WTF (%02x)\n", (ULONG)srb->Cdb[0]));
499 return FALSE;
500 }
502 if (!cdb_dbd) {
503 param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
504 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK) {
505 if (xvdd->total_sectors >> 32) {
506 param_block->DensityCode = 0xff;
507 param_block->NumberOfBlocks[0] = 0xff;
508 param_block->NumberOfBlocks[1] = 0xff;
509 param_block->NumberOfBlocks[2] = 0xff;
510 } else {
511 param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
512 param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
513 param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
514 param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
515 }
516 param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
517 param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
518 param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
519 }
520 offset += sizeof(MODE_PARAMETER_BLOCK);
521 }
522 switch (srb->Cdb[0])
523 {
524 case SCSIOP_MODE_SENSE:
525 parameter_header->BlockDescriptorLength = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER));
526 break;
527 case SCSIOP_MODE_SENSE10:
528 parameter_header10->BlockDescriptorLength[0] = (UCHAR)((offset - sizeof(MODE_PARAMETER_HEADER10)) >> 8);
529 parameter_header10->BlockDescriptorLength[1] = (UCHAR)(offset - sizeof(MODE_PARAMETER_HEADER10));
530 break;
531 }
532 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_FORMAT_DEVICE || cdb_page_code == MODE_SENSE_RETURN_ALL)) {
533 valid_page = TRUE;
534 format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
535 format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
536 format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
537 /* 256 sectors per track */
538 format_page->SectorsPerTrack[0] = 0x01;
539 format_page->SectorsPerTrack[1] = 0x00;
540 /* xxx bytes per sector */
541 format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
542 format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
543 format_page->HardSectorFormating = TRUE;
544 format_page->SoftSectorFormating = TRUE;
545 offset += sizeof(MODE_FORMAT_PAGE);
546 }
547 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_CACHING || cdb_page_code == MODE_SENSE_RETURN_ALL)) {
548 PMODE_CACHING_PAGE caching_page;
549 valid_page = TRUE;
550 caching_page = (PMODE_CACHING_PAGE)&buffer[offset];
551 caching_page->PageCode = MODE_PAGE_CACHING;
552 caching_page->PageLength = sizeof(MODE_CACHING_PAGE) - FIELD_OFFSET(MODE_CACHING_PAGE, PageLength);
553 // caching_page-> // all zeros is just fine... maybe
554 offset += sizeof(MODE_CACHING_PAGE);
555 }
556 if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (cdb_page_code == MODE_PAGE_MEDIUM_TYPES || cdb_page_code == MODE_SENSE_RETURN_ALL)) {
557 PUCHAR medium_types_page;
558 valid_page = TRUE;
559 medium_types_page = &buffer[offset];
560 medium_types_page[0] = MODE_PAGE_MEDIUM_TYPES;
561 medium_types_page[1] = 0x06;
562 medium_types_page[2] = 0;
563 medium_types_page[3] = 0;
564 medium_types_page[4] = 0;
565 medium_types_page[5] = 0;
566 medium_types_page[6] = 0;
567 medium_types_page[7] = 0;
568 offset += 8;
569 }
570 switch (srb->Cdb[0]) {
571 case SCSIOP_MODE_SENSE:
572 parameter_header->ModeDataLength = (UCHAR)(offset - 1);
573 break;
574 case SCSIOP_MODE_SENSE10:
575 parameter_header10->ModeDataLength[0] = (UCHAR)((offset - 2) >> 8);
576 parameter_header10->ModeDataLength[1] = (UCHAR)(offset - 2);
577 break;
578 }
580 if (!valid_page && cdb_page_code != MODE_SENSE_RETURN_ALL) {
581 srb->SrbStatus = SRB_STATUS_ERROR;
582 }
583 else if(offset < srb->DataTransferLength)
584 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
585 else
586 srb->SrbStatus = SRB_STATUS_SUCCESS;
587 srb->DataTransferLength = min(srb->DataTransferLength, offset);
588 srb->ScsiStatus = 0;
589 memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
591 //FUNCTION_EXIT();
593 return TRUE;
594 }
596 static BOOLEAN
597 XenVbd_ResetBus(PXENVBD_DEVICE_DATA xvdd, ULONG PathId) {
598 //srb_list_entry_t *srb_entry;
599 int i;
600 /* need to make sure that each SRB is only reset once */
601 LIST_ENTRY srb_reset_list;
602 PLIST_ENTRY list_entry;
603 //STOR_LOCK_HANDLE lock_handle;
605 UNREFERENCED_PARAMETER(PathId);
607 FUNCTION_ENTER();
609 if (dump_mode) {
610 FUNCTION_MSG("dump mode - doing nothing\n");
611 FUNCTION_EXIT();
612 return TRUE;
613 }
615 /* It appears that the StartIo spinlock is already held at this point */
617 FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
619 xvdd->aligned_buffer_in_use = FALSE;
621 InitializeListHead(&srb_reset_list);
623 /* add all queued srbs to the list */
624 while((list_entry = RemoveHeadList(&xvdd->srb_list)) != &xvdd->srb_list) {
625 #if DBG
626 srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
627 FUNCTION_MSG("adding queued SRB %p to reset list\n", srb_entry->srb);
628 #endif
629 InsertTailList(&srb_reset_list, list_entry);
630 }
632 /* add any in-flight srbs that aren't already on the list (could be multiple shadows per srb if it's been broken up */
633 for (i = 0; i < MAX_SHADOW_ENTRIES; i++) {
634 if (xvdd->shadows[i].srb) {
635 srb_list_entry_t *srb_entry = xvdd->shadows[i].srb->SrbExtension;
636 for (list_entry = srb_reset_list.Flink; list_entry != &srb_reset_list; list_entry = list_entry->Flink) {
637 if (list_entry == &srb_entry->list_entry)
638 break;
639 }
640 if (list_entry == &srb_reset_list) {
641 FUNCTION_MSG("adding in-flight SRB %p to reset list\n", srb_entry->srb);
642 InsertTailList(&srb_reset_list, &srb_entry->list_entry);
643 }
644 /* set reset here so that the interrupt won't do anything with the srb but will dispose of the shadow entry correctly */
645 xvdd->shadows[i].reset = TRUE;
646 xvdd->shadows[i].srb = NULL;
647 xvdd->shadows[i].aligned_buffer_in_use = FALSE;
648 }
649 }
651 while((list_entry = RemoveHeadList(&srb_reset_list)) != &srb_reset_list) {
652 srb_list_entry_t *srb_entry = CONTAINING_RECORD(list_entry, srb_list_entry_t, list_entry);
653 srb_entry->outstanding_requests = 0;
654 srb_entry->srb->SrbStatus = SRB_STATUS_BUS_RESET;
655 FUNCTION_MSG("completing SRB %p with status SRB_STATUS_BUS_RESET\n", srb_entry->srb);
656 SxxxPortNotification(RequestComplete, xvdd, srb_entry->srb);
657 }
659 /* send a notify to Dom0 just in case it was missed for some reason (which should _never_ happen normally but could in dump mode) */
660 XnNotify(xvdd->handle, xvdd->event_channel);
662 SxxxPortNotification(NextLuRequest, xvdd, 0, 0, 0);
663 FUNCTION_EXIT();
665 return TRUE;
666 }
668 /* called with StartIo lock held */
669 VOID
670 XenVbd_ProcessSrbList(PXENVBD_DEVICE_DATA xvdd) {
671 PUCHAR data_buffer;
672 #ifdef _NTSTORPORT_
673 PSCSI_PNP_REQUEST_BLOCK sprb;
674 PSCSI_POWER_REQUEST_BLOCK spwrb;
675 PMINIPORT_DUMP_POINTERS dump_pointers;
676 #endif
677 PCDB cdb;
678 ULONG data_transfer_length;
679 UCHAR srb_status = SRB_STATUS_PENDING;
680 ULONG notify = FALSE;
681 PSCSI_REQUEST_BLOCK srb;
682 srb_list_entry_t *srb_entry;
683 PSRB_IO_CONTROL sic;
684 ULONG prev_offset;
686 if (xvdd->device_state != DEVICE_STATE_ACTIVE) {
687 FUNCTION_MSG("Not yet active - state = %d\n", xvdd->device_state);
688 return;
689 }
691 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) {
692 srb = srb_entry->srb;
693 prev_offset = srb_entry->offset;
694 if (xvdd->device_state == DEVICE_STATE_INACTIVE) {
695 /* need to check again as may have been initialising when this srb was put on the list */
696 FUNCTION_MSG("Inactive Device (in ProcessSrbList)\n");
697 srb->SrbStatus = SRB_STATUS_NO_DEVICE;
698 SxxxPortNotification(RequestComplete, xvdd, srb);
699 continue;
700 }
702 data_transfer_length = srb->DataTransferLength;
704 switch (srb->Function) {
705 case SRB_FUNCTION_EXECUTE_SCSI:
706 cdb = (PCDB)srb->Cdb;
708 switch(cdb->CDB6GENERIC.OperationCode) {
709 case SCSIOP_TEST_UNIT_READY:
710 if (dump_mode)
711 KdPrint((__DRIVER_NAME " Command = TEST_UNIT_READY\n"));
712 srb_status = SRB_STATUS_SUCCESS;
713 srb->ScsiStatus = 0;
714 break;
715 case SCSIOP_INQUIRY:
716 if (dump_mode)
717 KdPrint((__DRIVER_NAME " Command = INQUIRY\n"));
718 // KdPrint((__DRIVER_NAME " (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
719 // KdPrint((__DRIVER_NAME " (Length = %d)\n", srb->DataTransferLength));
721 data_buffer = srb->DataBuffer;
722 RtlZeroMemory(data_buffer, srb->DataTransferLength);
723 srb_status = SRB_STATUS_SUCCESS;
724 switch (xvdd->device_type)
725 {
726 case XENVBD_DEVICETYPE_DISK:
727 if ((srb->Cdb[1] & 1) == 0) {
728 if (srb->Cdb[2]) {
729 srb_status = SRB_STATUS_ERROR;
730 } else {
731 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
732 id->DeviceType = DIRECT_ACCESS_DEVICE;
733 id->Versions = 5; /* SPC-3 */
734 id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
735 id->HiSupport = 1; /* WHQL test says we should set this */
736 //id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
737 id->AdditionalLength = sizeof(INQUIRYDATA) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength) - 1;
738 id->CommandQueue = 1;
739 memcpy(id->VendorId, SCSI_DEVICE_MANUFACTURER, 8); // vendor id
740 memcpy(id->ProductId, SCSI_DISK_MODEL, 16); // product id
741 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
742 data_transfer_length = FIELD_OFFSET(INQUIRYDATA, VendorSpecific);
743 }
744 } else {
745 switch (srb->Cdb[2]) {
746 case VPD_SUPPORTED_PAGES: /* list of pages we support */
747 FUNCTION_MSG("VPD_SUPPORTED_PAGES\n");
748 data_buffer[0] = DIRECT_ACCESS_DEVICE;
749 data_buffer[1] = VPD_SUPPORTED_PAGES;
750 data_buffer[2] = 0x00;
751 data_buffer[3] = 4;
752 data_buffer[4] = VPD_SUPPORTED_PAGES;
753 data_buffer[5] = VPD_SERIAL_NUMBER;
754 data_buffer[6] = VPD_DEVICE_IDENTIFIERS;
755 data_buffer[7] = VPD_BLOCK_LIMITS;
756 data_transfer_length = 8;
757 break;
758 case VPD_SERIAL_NUMBER: /* serial number */
759 FUNCTION_MSG("VPD_SERIAL_NUMBER\n");
760 data_buffer[0] = DIRECT_ACCESS_DEVICE;
761 data_buffer[1] = VPD_SERIAL_NUMBER;
762 data_buffer[2] = 0x00;
763 data_buffer[3] = 8;
764 memset(&data_buffer[4], ' ', 8);
765 data_transfer_length = 12;
766 break;
767 case VPD_DEVICE_IDENTIFIERS: /* identification - we don't support any so just return zero */
768 FUNCTION_MSG("VPD_DEVICE_IDENTIFIERS\n");
769 data_buffer[0] = DIRECT_ACCESS_DEVICE;
770 data_buffer[1] = VPD_DEVICE_IDENTIFIERS;
771 data_buffer[2] = 0x00;
772 //data_buffer[3] = 4 + (UCHAR)strlen(xvdd->vectors.path); /* length */
773 data_buffer[4] = 2; /* ASCII */
774 data_buffer[5] = 1; /* VendorId */
775 data_buffer[6] = 0;
776 //data_buffer[7] = (UCHAR)strlen(xvdd->vectors.path);
777 //memcpy(&data_buffer[8], xvdd->vectors.path, strlen(xvdd->vectors.path));
778 //data_transfer_length = (ULONG)(8 + strlen(xvdd->vectors.path));
779 break;
780 case VPD_BLOCK_LIMITS: /* to indicate support for UNMAP (TRIM/DISCARD) */
781 FUNCTION_MSG("VPD_BLOCK_LIMITS\n");
782 // max descriptors = 1
783 // max sectors = 0xFFFFFFFF
784 // granularity = from xenbus
785 // alignment = from xenbus(?)
786 srb_status = SRB_STATUS_ERROR;
787 break;
788 default:
789 FUNCTION_MSG("Unknown Page %02x requested\n", srb->Cdb[2]);
790 srb_status = SRB_STATUS_ERROR;
791 break;
792 }
793 }
794 break;
795 case XENVBD_DEVICETYPE_CDROM:
796 if ((srb->Cdb[1] & 1) == 0)
797 {
798 PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
799 id->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
800 id->RemovableMedia = 1;
801 id->Versions = 3;
802 id->ResponseDataFormat = 0;
803 id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
804 id->CommandQueue = 1;
805 memcpy(id->VendorId, SCSI_DEVICE_MANUFACTURER, 8); // vendor id
806 memcpy(id->ProductId, SCSI_CDROM_MODEL, 16); // product id
807 memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
808 data_transfer_length = sizeof(INQUIRYDATA);
809 }
810 else
811 {
812 switch (srb->Cdb[2])
813 {
814 case 0x00:
815 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
816 data_buffer[1] = 0x00;
817 data_buffer[2] = 0x00;
818 data_buffer[3] = 2;
819 data_buffer[4] = 0x00;
820 data_buffer[5] = 0x80;
821 data_transfer_length = 6;
822 break;
823 case 0x80:
824 data_buffer[0] = READ_ONLY_DIRECT_ACCESS_DEVICE;
825 data_buffer[1] = 0x80;
826 data_buffer[2] = 0x00;
827 data_buffer[3] = 8;
828 data_buffer[4] = 0x31;
829 data_buffer[5] = 0x32;
830 data_buffer[6] = 0x33;
831 data_buffer[7] = 0x34;
832 data_buffer[8] = 0x35;
833 data_buffer[9] = 0x36;
834 data_buffer[10] = 0x37;
835 data_buffer[11] = 0x38;
836 data_transfer_length = 12;
837 break;
838 default:
839 //KdPrint((__DRIVER_NAME " Unknown Page %02x requested\n", srb->Cdb[2]));
840 srb_status = SRB_STATUS_ERROR;
841 break;
842 }
843 }
844 break;
845 default:
846 //KdPrint((__DRIVER_NAME " Unknown DeviceType %02x requested\n", xvdd->device_type));
847 srb_status = SRB_STATUS_ERROR;
848 break;
849 }
850 break;
851 case SCSIOP_READ_CAPACITY:
852 //if (dump_mode)
853 // KdPrint((__DRIVER_NAME " Command = READ_CAPACITY\n"));
854 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
855 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
856 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
857 //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
858 data_buffer = srb->DataBuffer;
859 RtlZeroMemory(data_buffer, srb->DataTransferLength);
860 if ((xvdd->total_sectors - 1) >> 32)
861 {
862 data_buffer[0] = 0xff;
863 data_buffer[1] = 0xff;
864 data_buffer[2] = 0xff;
865 data_buffer[3] = 0xff;
866 }
867 else
868 {
869 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
870 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
871 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
872 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
873 }
874 data_buffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
875 data_buffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
876 data_buffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
877 data_buffer[7] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
878 data_transfer_length = 8;
879 srb->ScsiStatus = 0;
880 srb_status = SRB_STATUS_SUCCESS;
881 break;
882 case SCSIOP_READ_CAPACITY16:
883 //if (dump_mode)
884 KdPrint((__DRIVER_NAME " Command = READ_CAPACITY16\n"));
885 //KdPrint((__DRIVER_NAME " LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
886 //KdPrint((__DRIVER_NAME " LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
887 //KdPrint((__DRIVER_NAME " PMI = %d\n", srb->Cdb[8] & 1));
888 data_buffer = srb->DataBuffer;
889 RtlZeroMemory(data_buffer, srb->DataTransferLength);
890 data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
891 data_buffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 48) & 0xff;
892 data_buffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 40) & 0xff;
893 data_buffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 32) & 0xff;
894 data_buffer[4] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
895 data_buffer[5] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
896 data_buffer[6] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
897 data_buffer[7] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
898 data_buffer[8] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
899 data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
900 data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
901 data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
902 data_buffer[12] = 0;
903 switch (xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector) {
904 case 1:
905 data_buffer[13] = 0; /* 512 byte hardware sectors */
906 break;
907 case 2:
908 data_buffer[13] = 1; /* 1024 byte hardware sectors */
909 break;
910 case 3:
911 data_buffer[13] = 2; /* 2048 byte hardware sectors */
912 break;
913 case 4:
914 data_buffer[13] = 3; /* 4096 byte hardware sectors */
915 break;
916 default:
917 data_buffer[13] = 0; /* 512 byte hardware sectors */
918 KdPrint((__DRIVER_NAME " Unknown logical blocks per physical block %d (%d / %d)\n", xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector, xvdd->hw_bytes_per_sector, xvdd->bytes_per_sector));
919 break;
920 }
921 data_buffer[14] = 0xC0; //0;
922 data_buffer[15] = 0;
923 data_transfer_length = 16;
924 srb->ScsiStatus = 0;
925 srb_status = SRB_STATUS_SUCCESS;
926 break;
927 case SCSIOP_MODE_SENSE:
928 case SCSIOP_MODE_SENSE10:
929 if (dump_mode)
930 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));
931 data_transfer_length = XenVbd_FillModePage(xvdd, srb);
932 srb_status = SRB_STATUS_SUCCESS;
933 break;
934 case SCSIOP_READ:
935 case SCSIOP_READ16:
936 case SCSIOP_WRITE:
937 case SCSIOP_WRITE16:
938 //FUNCTION_MSG("srb = %p\n", srb);
939 if (XenVbd_PutSrbOnRing(xvdd, srb)) {
940 notify = TRUE;
941 }
942 break;
943 case SCSIOP_WRITE_SAME:
944 case SCSIOP_WRITE_SAME16:
945 /* not yet supported */
946 FUNCTION_MSG("WRITE_SAME\n");
947 break;
948 case SCSIOP_UNMAP:
949 /* not yet supported */
950 FUNCTION_MSG("UNMAP\n");
951 break;
952 case SCSIOP_VERIFY:
953 case SCSIOP_VERIFY16:
954 // Should we do more here?
955 if (dump_mode)
956 KdPrint((__DRIVER_NAME " Command = VERIFY\n"));
957 srb_status = SRB_STATUS_SUCCESS;
958 break;
959 case SCSIOP_REPORT_LUNS:
960 //if (dump_mode)
961 FUNCTION_MSG("Command = REPORT_LUNS\n");
962 switch (srb->Cdb[2]) {
963 case 1:
964 FUNCTION_MSG(" SELECT REPORT = %d\n", srb->Cdb[2] & 255);
965 break;
966 default:
967 FUNCTION_MSG(" SELECT REPORT = %d\n", srb->Cdb[2] & 255);
968 break;
969 }
970 FUNCTION_MSG(" ALLOCATION LENGTH = %d\n", (srb->Cdb[6] << 24)|(srb->Cdb[7] << 16)|(srb->Cdb[8] << 8)|(srb->Cdb[9]));
971 data_buffer = srb->DataBuffer;
972 RtlZeroMemory(data_buffer, srb->DataTransferLength);
973 data_buffer[3] = 8; /* 1 lun */
974 /* rest of the data is blank */
975 data_transfer_length = 16;
976 srb->ScsiStatus = 0;
977 srb_status = SRB_STATUS_SUCCESS;
978 break;
979 case SCSIOP_REQUEST_SENSE:
980 if (dump_mode)
981 KdPrint((__DRIVER_NAME " Command = REQUEST_SENSE\n"));
982 data_transfer_length = XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
983 srb_status = SRB_STATUS_SUCCESS;
984 break;
985 case SCSIOP_READ_TOC:
986 if (dump_mode)
987 KdPrint((__DRIVER_NAME " Command = READ_TOC\n"));
988 data_buffer = srb->DataBuffer;
989 /*
990 #define READ_TOC_FORMAT_TOC 0x00
991 #define READ_TOC_FORMAT_SESSION 0x01
992 #define READ_TOC_FORMAT_FULL_TOC 0x02
993 #define READ_TOC_FORMAT_PMA 0x03
994 #define READ_TOC_FORMAT_ATIP 0x04
995 */
996 // KdPrint((__DRIVER_NAME " Msf = %d\n", cdb->READ_TOC.Msf));
997 // KdPrint((__DRIVER_NAME " LogicalUnitNumber = %d\n", cdb->READ_TOC.LogicalUnitNumber));
998 // KdPrint((__DRIVER_NAME " Format2 = %d\n", cdb->READ_TOC.Format2));
999 // KdPrint((__DRIVER_NAME " StartingTrack = %d\n", cdb->READ_TOC.StartingTrack));
1000 // KdPrint((__DRIVER_NAME " AllocationLength = %d\n", (cdb->READ_TOC.AllocationLength[0] << 8) | cdb->READ_TOC.AllocationLength[1]));
1001 // KdPrint((__DRIVER_NAME " Control = %d\n", cdb->READ_TOC.Control));
1002 // KdPrint((__DRIVER_NAME " Format = %d\n", cdb->READ_TOC.Format));
1003 switch (cdb->READ_TOC.Format2)
1005 case READ_TOC_FORMAT_TOC:
1006 data_buffer[0] = 0; // length MSB
1007 data_buffer[1] = 10; // length LSB
1008 data_buffer[2] = 1; // First Track
1009 data_buffer[3] = 1; // Last Track
1010 data_buffer[4] = 0; // Reserved
1011 data_buffer[5] = 0x14; // current position data + uninterrupted data
1012 data_buffer[6] = 1; // last complete track
1013 data_buffer[7] = 0; // reserved
1014 data_buffer[8] = 0; // MSB Block
1015 data_buffer[9] = 0;
1016 data_buffer[10] = 0;
1017 data_buffer[11] = 0; // LSB Block
1018 data_transfer_length = 12;
1019 srb_status = SRB_STATUS_SUCCESS;
1020 break;
1021 case READ_TOC_FORMAT_SESSION:
1022 case READ_TOC_FORMAT_FULL_TOC:
1023 case READ_TOC_FORMAT_PMA:
1024 case READ_TOC_FORMAT_ATIP:
1025 srb_status = SRB_STATUS_ERROR;
1026 break;
1027 default:
1028 srb_status = SRB_STATUS_ERROR;
1029 break;
1031 break;
1032 case SCSIOP_START_STOP_UNIT:
1033 KdPrint((__DRIVER_NAME " Command = SCSIOP_START_STOP_UNIT\n"));
1034 srb_status = SRB_STATUS_SUCCESS;
1035 break;
1036 case SCSIOP_RESERVE_UNIT:
1037 KdPrint((__DRIVER_NAME " Command = SCSIOP_RESERVE_UNIT\n"));
1038 srb_status = SRB_STATUS_SUCCESS;
1039 break;
1040 case SCSIOP_RELEASE_UNIT:
1041 KdPrint((__DRIVER_NAME " Command = SCSIOP_RELEASE_UNIT\n"));
1042 srb_status = SRB_STATUS_SUCCESS;
1043 break;
1044 default:
1045 KdPrint((__DRIVER_NAME " Unhandled EXECUTE_SCSI Command = %02X\n", srb->Cdb[0]));
1046 xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
1047 srb_status = SRB_STATUS_ERROR;
1048 break;
1050 if (srb_status == SRB_STATUS_ERROR) {
1051 KdPrint((__DRIVER_NAME " EXECUTE_SCSI Command = %02X returned error %02x\n", srb->Cdb[0], xvdd->last_sense_key));
1052 if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE) {
1053 xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
1054 xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
1056 srb->SrbStatus = srb_status;
1057 srb->ScsiStatus = 0x02;
1058 XenVbd_MakeAutoSense(xvdd, srb);
1059 SxxxPortNotification(RequestComplete, xvdd, srb);
1060 } else if (srb_status != SRB_STATUS_PENDING) {
1061 if (data_transfer_length > srb->DataTransferLength)
1062 KdPrint((__DRIVER_NAME " data_transfer_length too big - %d > %d\n", data_transfer_length, srb->DataTransferLength));
1064 if (srb_status == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength) {
1065 srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
1066 srb->DataTransferLength = data_transfer_length;
1067 } else {
1068 srb->SrbStatus = srb_status;
1070 xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
1071 xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
1072 SxxxPortNotification(RequestComplete, xvdd, srb);
1074 break;
1075 case SRB_FUNCTION_FLUSH:
1076 KdPrint((__DRIVER_NAME " SRB_FUNCTION_FLUSH %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1077 srb->SrbStatus = SRB_STATUS_SUCCESS;
1078 SxxxPortNotification(RequestComplete, xvdd, srb);
1079 break;
1080 #ifdef _NTSTORPORT_
1081 case SRB_FUNCTION_PNP:
1082 KdPrint((__DRIVER_NAME " SRB_FUNCTION_PNP\n"));
1083 sprb = (PSCSI_PNP_REQUEST_BLOCK)srb;
1084 switch (sprb->PnPAction)
1086 case StorStartDevice:
1087 KdPrint((__DRIVER_NAME " StorStartDevice\n"));
1088 break;
1089 case StorRemoveDevice:
1090 KdPrint((__DRIVER_NAME " StorRemoveDevice\n"));
1091 break;
1092 case StorStopDevice:
1093 KdPrint((__DRIVER_NAME " StorStopDevice\n"));
1094 break;
1095 case StorQueryCapabilities:
1096 KdPrint((__DRIVER_NAME " StorQueryCapabilities\n"));
1097 break;
1098 case StorFilterResourceRequirements:
1099 KdPrint((__DRIVER_NAME " StorFilterResourceRequirements\n"));
1100 break;
1101 default:
1102 KdPrint((__DRIVER_NAME " Stor%d\n", sprb->PnPAction));
1103 break;
1105 KdPrint((__DRIVER_NAME " SrbPnPFlags = %08x\n", sprb->SrbPnPFlags));
1106 srb->SrbStatus = SRB_STATUS_SUCCESS;
1107 SxxxPortNotification(RequestComplete, xvdd, srb);
1108 break;
1110 case SRB_FUNCTION_POWER:
1111 KdPrint((__DRIVER_NAME " SRB_FUNCTION_POWER\n"));
1112 spwrb = (PSCSI_POWER_REQUEST_BLOCK)srb;
1113 switch (spwrb->PowerAction)
1115 case StorPowerActionNone:
1116 KdPrint((__DRIVER_NAME " StorPowerActionNone\n"));
1117 break;
1118 case StorPowerActionReserved:
1119 KdPrint((__DRIVER_NAME " StorPowerActionReserved\n"));
1120 break;
1121 case StorPowerActionSleep:
1122 KdPrint((__DRIVER_NAME " StorPowerActionSleep\n"));
1123 break;
1124 case StorPowerActionHibernate:
1125 KdPrint((__DRIVER_NAME " StorPowerActionHibernate\n"));
1126 break;
1127 case StorPowerActionShutdown:
1128 KdPrint((__DRIVER_NAME " StorPowerActionShutdown\n"));
1129 break;
1130 case StorPowerActionShutdownReset:
1131 KdPrint((__DRIVER_NAME " StorPowerActionShutdownReset\n"));
1132 break;
1133 case StorPowerActionShutdownOff:
1134 KdPrint((__DRIVER_NAME " StorPowerActionShutdownOff\n"));
1135 break;
1136 case StorPowerActionWarmEject:
1137 KdPrint((__DRIVER_NAME " StorPowerActionWarmEject\n"));
1138 break;
1139 default:
1140 KdPrint((__DRIVER_NAME " Stor%d\n", spwrb->PowerAction));
1141 break;
1143 srb->SrbStatus = SRB_STATUS_SUCCESS;
1144 SxxxPortNotification(RequestComplete, xvdd, srb);
1145 break;
1146 case SRB_FUNCTION_DUMP_POINTERS:
1147 KdPrint((__DRIVER_NAME " SRB_FUNCTION_DUMP_POINTERS\n"));
1148 KdPrint((__DRIVER_NAME " DataTransferLength = %d\n", srb->DataTransferLength));
1149 dump_pointers = srb->DataBuffer;
1150 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1151 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1152 KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1153 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1154 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1155 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1156 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1157 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1158 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1159 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1160 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1161 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1162 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1163 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1164 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1165 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1166 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1168 dump_pointers->Version = DUMP_MINIPORT_VERSION_1;
1169 dump_pointers->Size = sizeof(MINIPORT_DUMP_POINTERS);
1170 RtlStringCchCopyW(dump_pointers->DriverName, DUMP_MINIPORT_NAME_LENGTH, L"xenvbd.sys");
1171 dump_pointers->AdapterObject = NULL;
1172 dump_pointers->MappedRegisterBase = 0;
1173 dump_pointers->CommonBufferSize = 0;
1174 dump_pointers->MiniportPrivateDumpData = xvdd;
1175 dump_pointers->AdapterInterfaceType = Internal;
1176 dump_pointers->MaximumTransferLength = 4 * 1024 * 1024; //BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;;
1177 dump_pointers->NumberOfPhysicalBreaks = dump_pointers->MaximumTransferLength >> PAGE_SHIFT; //BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
1178 dump_pointers->AlignmentMask = 0;
1179 dump_pointers->NumberOfAccessRanges = 1;
1180 dump_pointers->NumberOfBuses = 1;
1181 dump_pointers->Master = TRUE;
1182 dump_pointers->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1183 dump_pointers->MaximumNumberOfTargets = 2;
1185 KdPrint((__DRIVER_NAME " Version = %d\n", dump_pointers->Version));
1186 KdPrint((__DRIVER_NAME " Size = %d\n", dump_pointers->Size));
1187 //KdPrint((__DRIVER_NAME " DriverName = %S\n", dump_pointers->DriverName));
1188 KdPrint((__DRIVER_NAME " AdapterObject = %p\n", dump_pointers->AdapterObject));
1189 KdPrint((__DRIVER_NAME " MappedRegisterBase = %d\n", dump_pointers->MappedRegisterBase));
1190 KdPrint((__DRIVER_NAME " CommonBufferSize = %d\n", dump_pointers->CommonBufferSize));
1191 KdPrint((__DRIVER_NAME " MiniportPrivateDumpData = %p\n", dump_pointers->MiniportPrivateDumpData));
1192 KdPrint((__DRIVER_NAME " SystemIoBusNumber = %d\n", dump_pointers->SystemIoBusNumber));
1193 KdPrint((__DRIVER_NAME " AdapterInterfaceType = %d\n", dump_pointers->AdapterInterfaceType));
1194 KdPrint((__DRIVER_NAME " MaximumTransferLength = %d\n", dump_pointers->MaximumTransferLength));
1195 KdPrint((__DRIVER_NAME " NumberOfPhysicalBreaks = %d\n", dump_pointers->NumberOfPhysicalBreaks));
1196 KdPrint((__DRIVER_NAME " AlignmentMask = %d\n", dump_pointers->AlignmentMask));
1197 KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", dump_pointers->NumberOfAccessRanges));
1198 KdPrint((__DRIVER_NAME " NumberOfBuses = %d\n", dump_pointers->NumberOfBuses));
1199 KdPrint((__DRIVER_NAME " Master = %d\n", dump_pointers->Master));
1200 KdPrint((__DRIVER_NAME " MapBuffers = %d\n", dump_pointers->MapBuffers));
1201 KdPrint((__DRIVER_NAME " MaximumNumberOfTargets = %d\n", dump_pointers->MaximumNumberOfTargets));
1203 srb->SrbStatus = SRB_STATUS_SUCCESS;
1204 SxxxPortNotification(RequestComplete, xvdd, srb);
1205 break;
1206 #endif
1207 case SRB_FUNCTION_SHUTDOWN:
1208 KdPrint((__DRIVER_NAME " SRB_FUNCTION_SHUTDOWN %p, xvdd->shadow_free = %d\n", srb, xvdd->shadow_free));
1209 srb->SrbStatus = SRB_STATUS_SUCCESS;
1210 SxxxPortNotification(RequestComplete, xvdd, srb);
1211 break;
1212 case SRB_FUNCTION_RESET_BUS:
1213 case SRB_FUNCTION_RESET_DEVICE:
1214 case SRB_FUNCTION_RESET_LOGICAL_UNIT:
1215 /* the path doesn't matter here - only ever one device*/
1216 FUNCTION_MSG("SRB_FUNCTION_RESET_XXX\n");
1217 XenVbd_ResetBus(xvdd, 0);
1218 srb->SrbStatus = SRB_STATUS_SUCCESS;
1219 SxxxPortNotification(RequestComplete, xvdd, srb);
1220 break;
1221 case SRB_FUNCTION_WMI:
1222 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1223 SxxxPortNotification(RequestComplete, xvdd, srb);
1224 break;
1225 case SRB_FUNCTION_IO_CONTROL:
1226 FUNCTION_MSG("SRB_FUNCTION_IO_CONTROL\n");
1227 sic = srb->DataBuffer;
1228 FUNCTION_MSG("ControlCode = %d\n", sic->ControlCode);
1229 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1230 SxxxPortNotification(RequestComplete, xvdd, srb);
1231 break;
1232 default:
1233 KdPrint((__DRIVER_NAME " Unhandled srb->Function = %08X\n", srb->Function));
1234 srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
1235 SxxxPortNotification(RequestComplete, xvdd, srb);
1236 break;
1238 if ((PLIST_ENTRY)srb_entry == xvdd->srb_list.Flink && srb_entry->offset == prev_offset) {
1239 FUNCTION_MSG("Same entry\n");
1240 /* same entry was put back onto the head of the list unchanged so we can't progress */
1241 break;
1244 if (notify) {
1245 notify = FALSE;
1246 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xvdd->ring, notify);
1247 if (notify) {
1248 XnNotify(xvdd->handle, xvdd->event_channel);
1251 return;