Create a branch for Aleksandar Andrejevic for his work on NTVDM. See http://jira...
[reactos.git] / drivers / usb / usbstor / disk.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbstor/disk.c
5 * PURPOSE: USB block storage device driver.
6 * PROGRAMMERS:
7 * James Tabor
8 * Michael Martin (michael.martin@reactos.org)
9 * Johannes Anderwald (johannes.anderwald@reactos.org)
10 */
11
12 #include "usbstor.h"
13
14 NTSTATUS
15 USBSTOR_HandleInternalDeviceControl(
16 IN PDEVICE_OBJECT DeviceObject,
17 IN PIRP Irp)
18 {
19 PIO_STACK_LOCATION IoStack;
20 PSCSI_REQUEST_BLOCK Request;
21 PPDO_DEVICE_EXTENSION PDODeviceExtension;
22 NTSTATUS Status;
23
24 //
25 // get current stack location
26 //
27 IoStack = IoGetCurrentIrpStackLocation(Irp);
28
29 //
30 // get request block
31 //
32 Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
33
34 //
35 // sanity check
36 //
37 ASSERT(Request);
38
39 //
40 // get device extension
41 //
42 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
43
44 //
45 // sanity check
46 //
47 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
48
49 switch(Request->Function)
50 {
51 case SRB_FUNCTION_EXECUTE_SCSI:
52 {
53 DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n");
54
55 //
56 // check if request is valid
57 //
58 if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT))
59 {
60 //
61 // data is transferred with this irp
62 //
63 if ((Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) == (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) ||
64 Request->DataTransferLength == 0 ||
65 Irp->MdlAddress == NULL)
66 {
67 //
68 // invalid parameter
69 //
70 Status = STATUS_INVALID_PARAMETER;
71 break;
72 }
73 }
74 else
75 {
76 //
77 // sense buffer request
78 //
79 if (Request->DataTransferLength ||
80 Request->DataBuffer ||
81 Irp->MdlAddress)
82 {
83 //
84 // invalid parameter
85 //
86 Status = STATUS_INVALID_PARAMETER;
87 break;
88 }
89 }
90
91 //
92 // add the request
93 //
94 if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, Irp))
95 {
96 //
97 // irp was not added to the queue
98 //
99 IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
100 }
101
102 //
103 // irp pending
104 //
105 return STATUS_PENDING;
106 }
107 case SRB_FUNCTION_RELEASE_DEVICE:
108 {
109 DPRINT1("SRB_FUNCTION_RELEASE_DEVICE\n");
110 //
111 // sanity check
112 //
113 ASSERT(PDODeviceExtension->Claimed == TRUE);
114
115 //
116 // release claim
117 //
118 PDODeviceExtension->Claimed = FALSE;
119 Status = STATUS_SUCCESS;
120 break;
121 }
122 case SRB_FUNCTION_CLAIM_DEVICE:
123 {
124 DPRINT1("SRB_FUNCTION_CLAIM_DEVICE\n");
125 //
126 // check if the device has been claimed
127 //
128 if (PDODeviceExtension->Claimed)
129 {
130 //
131 // device has already been claimed
132 //
133 Status = STATUS_DEVICE_BUSY;
134 Request->SrbStatus = SRB_STATUS_BUSY;
135 break;
136 }
137
138 //
139 // claim device
140 //
141 PDODeviceExtension->Claimed = TRUE;
142
143 //
144 // output device object
145 //
146 Request->DataBuffer = DeviceObject;
147
148 //
149 // completed successfully
150 //
151 Status = STATUS_SUCCESS;
152 break;
153 }
154 case SRB_FUNCTION_RELEASE_QUEUE:
155 {
156 DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n");
157
158 //
159 // release queue
160 //
161 USBSTOR_QueueRelease(PDODeviceExtension->LowerDeviceObject);
162
163 //
164 // set status success
165 //
166 Request->SrbStatus = SRB_STATUS_SUCCESS;
167 Status = STATUS_SUCCESS;
168 break;
169 }
170
171 case SRB_FUNCTION_SHUTDOWN:
172 case SRB_FUNCTION_FLUSH:
173 case SRB_FUNCTION_FLUSH_QUEUE:
174 {
175 DPRINT1("SRB_FUNCTION_FLUSH / SRB_FUNCTION_FLUSH_QUEUE / SRB_FUNCTION_SHUTDOWN\n");
176
177 // HACK: don't flush pending requests
178 #if 0 // we really need a proper storage stack
179 //
180 // wait for pending requests to finish
181 //
182 USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
183 #endif
184 //
185 // set status success
186 //
187 Request->SrbStatus = SRB_STATUS_SUCCESS;
188 Status = STATUS_SUCCESS;
189 break;
190 }
191 default:
192 {
193 //
194 // not supported
195 //
196 Status = STATUS_NOT_SUPPORTED;
197 Request->SrbStatus = SRB_STATUS_ERROR;
198 }
199 }
200
201 //
202 // complete request
203 //
204 Irp->IoStatus.Status = Status;
205 IoCompleteRequest(Irp, IO_NO_INCREMENT);
206 return Status;
207 }
208
209 ULONG
210 USBSTOR_GetFieldLength(
211 IN PUCHAR Name,
212 IN ULONG MaxLength)
213 {
214 ULONG Index;
215 ULONG LastCharacterPosition = 0;
216
217 //
218 // scan the field and return last positon which contains a valid character
219 //
220 for(Index = 0; Index < MaxLength; Index++)
221 {
222 if (Name[Index] != ' ')
223 {
224 //
225 // trim white spaces from field
226 //
227 LastCharacterPosition = Index;
228 }
229 }
230
231 //
232 // convert from zero based index to length
233 //
234 return LastCharacterPosition + 1;
235 }
236
237 NTSTATUS
238 USBSTOR_HandleQueryProperty(
239 IN PDEVICE_OBJECT DeviceObject,
240 IN PIRP Irp)
241 {
242 PIO_STACK_LOCATION IoStack;
243 PSTORAGE_PROPERTY_QUERY PropertyQuery;
244 PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader;
245 PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
246 ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber;
247 PPDO_DEVICE_EXTENSION PDODeviceExtension;
248 PUFI_INQUIRY_RESPONSE InquiryData;
249 PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
250 PUCHAR Buffer;
251 PFDO_DEVICE_EXTENSION FDODeviceExtension;
252 UNICODE_STRING SerialNumber;
253 ANSI_STRING AnsiString;
254 NTSTATUS Status;
255
256 DPRINT("USBSTOR_HandleQueryProperty\n");
257
258 //
259 // get current stack location
260 //
261 IoStack = IoGetCurrentIrpStackLocation(Irp);
262
263 //
264 // sanity check
265 //
266 ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY));
267 ASSERT(Irp->AssociatedIrp.SystemBuffer);
268
269 //
270 // get property query
271 //
272 PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
273
274 //
275 // check property type
276 //
277 if (PropertyQuery->PropertyId != StorageDeviceProperty &&
278 PropertyQuery->PropertyId != StorageAdapterProperty)
279 {
280 //
281 // only device property / adapter property are supported
282 //
283 return STATUS_INVALID_PARAMETER_1;
284 }
285
286 //
287 // check query type
288 //
289 if (PropertyQuery->QueryType == PropertyExistsQuery)
290 {
291 //
292 // device property / adapter property is supported
293 //
294 return STATUS_SUCCESS;
295 }
296
297 if (PropertyQuery->QueryType != PropertyStandardQuery)
298 {
299 //
300 // only standard query and exists query are supported
301 //
302 return STATUS_INVALID_PARAMETER_2;
303 }
304
305 //
306 // check if it is a device property
307 //
308 if (PropertyQuery->PropertyId == StorageDeviceProperty)
309 {
310 DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
311
312 //
313 // get device extension
314 //
315 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
316 ASSERT(PDODeviceExtension);
317 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
318
319 //
320 // get device extension
321 //
322 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
323 ASSERT(FDODeviceExtension);
324 ASSERT(FDODeviceExtension->Common.IsFDO);
325
326 //
327 // get inquiry data
328 //
329 InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
330 ASSERT(InquiryData);
331
332 //
333 // compute extra parameters length
334 //
335 FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8);
336 FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16);
337 FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4);
338
339 //
340 // is there a serial number
341 //
342 if (FDODeviceExtension->SerialNumber)
343 {
344 //
345 // get length
346 //
347 FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
348 }
349 else
350 {
351 //
352 // no serial number
353 //
354 FieldLengthSerialNumber = 0;
355 }
356
357 //
358 // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1
359 // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
360 //
361 TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
362
363 //
364 // check if output buffer is long enough
365 //
366 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
367 {
368 //
369 // buffer too small
370 //
371 DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
372 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
373
374 //
375 // return required size
376 //
377 DescriptorHeader->Version = TotalLength;
378 DescriptorHeader->Size = TotalLength;
379
380 Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
381 return STATUS_SUCCESS;
382 }
383
384 //
385 // get device descriptor
386 //
387 DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
388
389 //
390 // initialize device descriptor
391 //
392 DeviceDescriptor->Version = TotalLength;
393 DeviceDescriptor->Size = TotalLength;
394 DeviceDescriptor->DeviceType = InquiryData->DeviceType;
395 DeviceDescriptor->DeviceTypeModifier = (InquiryData->RMB & 0x7F);
396 DeviceDescriptor->RemovableMedia = (InquiryData->RMB & 0x80) ? TRUE : FALSE;
397 DeviceDescriptor->CommandQueueing = FALSE;
398 DeviceDescriptor->BusType = BusTypeUsb;
399 DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
400 DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset + FieldLengthVendor + 1;
401 DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset + FieldLengthProduct + 1;
402 DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
403 DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
404
405 //
406 // copy descriptors
407 //
408 Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
409
410 //
411 // copy vendor
412 //
413 RtlCopyMemory(Buffer, InquiryData->Vendor, FieldLengthVendor);
414 Buffer[FieldLengthVendor] = '\0';
415 Buffer += FieldLengthVendor + 1;
416
417 //
418 // copy product
419 //
420 RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct);
421 Buffer[FieldLengthProduct] = '\0';
422 Buffer += FieldLengthProduct + 1;
423
424 //
425 // copy revision
426 //
427 RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision);
428 Buffer[FieldLengthRevision] = '\0';
429 Buffer += FieldLengthRevision + 1;
430
431 //
432 // copy serial number
433 //
434 if (FieldLengthSerialNumber)
435 {
436 //
437 // init unicode string
438 //
439 RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
440
441 //
442 // init ansi string
443 //
444 AnsiString.Buffer = (PCHAR)Buffer;
445 AnsiString.Length = 0;
446 AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
447
448 //
449 // convert to ansi code
450 //
451 Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
452 ASSERT(Status == STATUS_SUCCESS);
453 }
454
455
456 DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
457 DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
458 DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
459 DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
460
461 //
462 // done
463 //
464 Irp->IoStatus.Information = TotalLength;
465 return STATUS_SUCCESS;
466 }
467 else
468 {
469 //
470 // adapter property query request
471 //
472 DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
473
474 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR))
475 {
476 //
477 // buffer too small
478 //
479 DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
480 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
481
482 //
483 // return required size
484 //
485 DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
486 DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
487
488 Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
489 return STATUS_SUCCESS;
490 }
491
492 //
493 // get adapter descriptor, information is returned in the same buffer
494 //
495 AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
496
497 //
498 // fill out descriptor
499 //
500 AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
501 AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
502 AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute some sane value
503 AdapterDescriptor->MaximumPhysicalPages = 25; //FIXME compute some sane value
504 AdapterDescriptor->AlignmentMask = 0;
505 AdapterDescriptor->AdapterUsesPio = FALSE;
506 AdapterDescriptor->AdapterScansDown = FALSE;
507 AdapterDescriptor->CommandQueueing = FALSE;
508 AdapterDescriptor->AcceleratedTransfer = FALSE;
509 AdapterDescriptor->BusType = BusTypeUsb;
510 AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify
511 AdapterDescriptor->BusMinorVersion = 0x00; //FIXME
512
513 //
514 // store returned length
515 //
516 Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
517
518 //
519 // done
520 //
521 return STATUS_SUCCESS;
522 }
523 }
524
525 NTSTATUS
526 USBSTOR_HandleDeviceControl(
527 IN PDEVICE_OBJECT DeviceObject,
528 IN PIRP Irp)
529 {
530 PIO_STACK_LOCATION IoStack;
531 NTSTATUS Status;
532 PPDO_DEVICE_EXTENSION PDODeviceExtension;
533 PSCSI_ADAPTER_BUS_INFO BusInfo;
534 PSCSI_INQUIRY_DATA InquiryData;
535 PINQUIRYDATA ScsiInquiryData;
536 PUFI_INQUIRY_RESPONSE UFIInquiryResponse;
537
538 //
539 // get current stack location
540 //
541 IoStack = IoGetCurrentIrpStackLocation(Irp);
542
543 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY)
544 {
545 //
546 // query property
547 //
548 Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
549 }
550 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH)
551 {
552 //
553 // query scsi pass through
554 //
555 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
556 Status = STATUS_NOT_SUPPORTED;
557 }
558 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT)
559 {
560 //
561 // query scsi pass through direct
562 //
563 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
564 Status = STATUS_NOT_SUPPORTED;
565 }
566 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER)
567 {
568 //
569 // query serial number
570 //
571 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
572 Status = STATUS_NOT_SUPPORTED;
573 }
574 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_CAPABILITIES)
575 {
576 PIO_SCSI_CAPABILITIES Capabilities;
577
578 /* Legacy port capability query */
579 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
580 {
581 Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePool(NonPagedPool, sizeof(IO_SCSI_CAPABILITIES));
582 Irp->IoStatus.Information = sizeof(PVOID);
583 }
584 else
585 {
586 Capabilities = Irp->AssociatedIrp.SystemBuffer;
587 Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
588 }
589
590 if (Capabilities)
591 {
592 Capabilities->MaximumTransferLength = MAXULONG;
593 Capabilities->MaximumPhysicalPages = 25;
594 Capabilities->SupportedAsynchronousEvents = 0;
595 Capabilities->AlignmentMask = 0;
596 Capabilities->TaggedQueuing = FALSE;
597 Capabilities->AdapterScansDown = FALSE;
598 Capabilities->AdapterUsesPio = FALSE;
599 Status = STATUS_SUCCESS;
600 }
601 else
602 {
603 Status = STATUS_INSUFFICIENT_RESOURCES;
604 }
605 }
606 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_INQUIRY_DATA)
607 {
608 //
609 // get device extension
610 //
611 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
612 ASSERT(PDODeviceExtension);
613 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
614
615 //
616 // get parameters
617 //
618 BusInfo = Irp->AssociatedIrp.SystemBuffer;
619 InquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
620 ScsiInquiryData = (PINQUIRYDATA)InquiryData->InquiryData;
621
622
623 //
624 // get inquiry data
625 //
626 UFIInquiryResponse = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
627 ASSERT(UFIInquiryResponse);
628
629
630 BusInfo->NumberOfBuses = 1;
631 BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME
632 BusInfo->BusData[0].InitiatorBusId = 0;
633 BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
634
635 InquiryData->PathId = 0;
636 InquiryData->TargetId = 0;
637 InquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
638 InquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
639 InquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
640 InquiryData->NextInquiryDataOffset = 0;
641
642 RtlZeroMemory(ScsiInquiryData, sizeof(INQUIRYDATA));
643 ScsiInquiryData->DeviceType = UFIInquiryResponse->DeviceType;
644 ScsiInquiryData->DeviceTypeQualifier = (UFIInquiryResponse->RMB & 0x7F);
645
646 /* Hack for IoReadPartitionTable call in disk.sys */
647 ScsiInquiryData->RemovableMedia = ((ScsiInquiryData->DeviceType != DIRECT_ACCESS_DEVICE) ? ((UFIInquiryResponse->RMB & 0x80) ? 1 : 0) : 0);
648
649 ScsiInquiryData->Versions = 0x04;
650 ScsiInquiryData->ResponseDataFormat = 0x02;
651 ScsiInquiryData->AdditionalLength = 31;
652 ScsiInquiryData->SoftReset = 0;
653 ScsiInquiryData->CommandQueue = 0;
654 ScsiInquiryData->LinkedCommands = 0;
655 ScsiInquiryData->RelativeAddressing = 0;
656
657 RtlCopyMemory(&ScsiInquiryData->VendorId, UFIInquiryResponse->Vendor, USBSTOR_GetFieldLength(UFIInquiryResponse->Vendor, 8));
658 RtlCopyMemory(&ScsiInquiryData->ProductId, UFIInquiryResponse->Product, USBSTOR_GetFieldLength(UFIInquiryResponse->Product, 16));
659
660 Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
661 Status = STATUS_SUCCESS;
662 }
663 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS)
664 {
665 PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
666
667 Address->Length = sizeof(SCSI_ADDRESS);
668 Address->PortNumber = 0;
669 Address->PathId = 0;
670 Address->TargetId = 0;
671 Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN);
672 Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
673
674 Status = STATUS_SUCCESS;
675 }
676 else
677 {
678 //
679 // unsupported
680 //
681 DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
682 Status = STATUS_NOT_SUPPORTED;
683 }
684
685 return Status;
686 }