[USBHUB]
[reactos.git] / reactos / 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 //
178 // wait for pending requests to finish
179 //
180 USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
181
182 //
183 // set status success
184 //
185 Request->SrbStatus = SRB_STATUS_SUCCESS;
186 Status = STATUS_SUCCESS;
187 break;
188 }
189 default:
190 {
191 //
192 // not supported
193 //
194 Status = STATUS_NOT_SUPPORTED;
195 Request->SrbStatus = SRB_STATUS_ERROR;
196 }
197 }
198
199 //
200 // complete request
201 //
202 Irp->IoStatus.Status = Status;
203 IoCompleteRequest(Irp, IO_NO_INCREMENT);
204 return Status;
205 }
206
207 ULONG
208 USBSTOR_GetFieldLength(
209 IN PUCHAR Name,
210 IN ULONG MaxLength)
211 {
212 ULONG Index;
213 ULONG LastCharacterPosition = 0;
214
215 //
216 // scan the field and return last positon which contains a valid character
217 //
218 for(Index = 0; Index < MaxLength; Index++)
219 {
220 if (Name[Index] != ' ')
221 {
222 //
223 // trim white spaces from field
224 //
225 LastCharacterPosition = Index;
226 }
227 }
228
229 //
230 // convert from zero based index to length
231 //
232 return LastCharacterPosition + 1;
233 }
234
235 NTSTATUS
236 USBSTOR_HandleQueryProperty(
237 IN PDEVICE_OBJECT DeviceObject,
238 IN PIRP Irp)
239 {
240 PIO_STACK_LOCATION IoStack;
241 PSTORAGE_PROPERTY_QUERY PropertyQuery;
242 PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader;
243 PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
244 ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber;
245 PPDO_DEVICE_EXTENSION PDODeviceExtension;
246 PUFI_INQUIRY_RESPONSE InquiryData;
247 PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
248 PUCHAR Buffer;
249 PFDO_DEVICE_EXTENSION FDODeviceExtension;
250 UNICODE_STRING SerialNumber;
251 ANSI_STRING AnsiString;
252 NTSTATUS Status;
253
254 DPRINT("USBSTOR_HandleQueryProperty\n");
255
256 //
257 // get current stack location
258 //
259 IoStack = IoGetCurrentIrpStackLocation(Irp);
260
261 //
262 // sanity check
263 //
264 ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY));
265 ASSERT(Irp->AssociatedIrp.SystemBuffer);
266
267 //
268 // get property query
269 //
270 PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
271
272 //
273 // check property type
274 //
275 if (PropertyQuery->PropertyId != StorageDeviceProperty &&
276 PropertyQuery->PropertyId != StorageAdapterProperty)
277 {
278 //
279 // only device property / adapter property are supported
280 //
281 return STATUS_INVALID_PARAMETER_1;
282 }
283
284 //
285 // check query type
286 //
287 if (PropertyQuery->QueryType == PropertyExistsQuery)
288 {
289 //
290 // device property / adapter property is supported
291 //
292 return STATUS_SUCCESS;
293 }
294
295 if (PropertyQuery->QueryType != PropertyStandardQuery)
296 {
297 //
298 // only standard query and exists query are supported
299 //
300 return STATUS_INVALID_PARAMETER_2;
301 }
302
303 //
304 // check if it is a device property
305 //
306 if (PropertyQuery->PropertyId == StorageDeviceProperty)
307 {
308 DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
309
310 //
311 // get device extension
312 //
313 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
314 ASSERT(PDODeviceExtension);
315 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
316
317 //
318 // get device extension
319 //
320 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
321 ASSERT(FDODeviceExtension);
322 ASSERT(FDODeviceExtension->Common.IsFDO);
323
324 //
325 // get inquiry data
326 //
327 InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
328 ASSERT(InquiryData);
329
330 //
331 // compute extra parameters length
332 //
333 FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8);
334 FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16);
335 FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4);
336
337 //
338 // is there a serial number
339 //
340 if (FDODeviceExtension->SerialNumber)
341 {
342 //
343 // get length
344 //
345 FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
346 }
347 else
348 {
349 //
350 // no serial number
351 //
352 FieldLengthSerialNumber = 0;
353 }
354
355 //
356 // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1
357 // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
358 //
359 TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
360
361 //
362 // check if output buffer is long enough
363 //
364 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
365 {
366 //
367 // buffer too small
368 //
369 DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
370 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
371
372 //
373 // return required size
374 //
375 DescriptorHeader->Version = TotalLength;
376 DescriptorHeader->Size = TotalLength;
377
378 Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
379 return STATUS_SUCCESS;
380 }
381
382 //
383 // get device descriptor
384 //
385 DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
386
387 //
388 // initialize device descriptor
389 //
390 DeviceDescriptor->Version = TotalLength;
391 DeviceDescriptor->Size = TotalLength;
392 DeviceDescriptor->DeviceType = InquiryData->DeviceType;
393 DeviceDescriptor->DeviceTypeModifier = (InquiryData->RMB & 0x7F);
394 DeviceDescriptor->RemovableMedia = (InquiryData->RMB & 0x80) ? TRUE : FALSE;
395 DeviceDescriptor->CommandQueueing = FALSE;
396 DeviceDescriptor->BusType = BusTypeUsb;
397 DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
398 DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset + FieldLengthVendor + 1;
399 DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset + FieldLengthProduct + 1;
400 DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
401 DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
402
403 //
404 // copy descriptors
405 //
406 Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
407
408 //
409 // copy vendor
410 //
411 RtlCopyMemory(Buffer, InquiryData->Vendor, FieldLengthVendor);
412 Buffer[FieldLengthVendor] = '\0';
413 Buffer += FieldLengthVendor + 1;
414
415 //
416 // copy product
417 //
418 RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct);
419 Buffer[FieldLengthProduct] = '\0';
420 Buffer += FieldLengthProduct + 1;
421
422 //
423 // copy revision
424 //
425 RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision);
426 Buffer[FieldLengthRevision] = '\0';
427 Buffer += FieldLengthRevision + 1;
428
429 //
430 // copy serial number
431 //
432 if (FieldLengthSerialNumber)
433 {
434 //
435 // init unicode string
436 //
437 RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
438
439 //
440 // init ansi string
441 //
442 AnsiString.Buffer = (PCHAR)Buffer;
443 AnsiString.Length = 0;
444 AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
445
446 //
447 // convert to ansi code
448 //
449 Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
450 ASSERT(Status == STATUS_SUCCESS);
451 }
452
453
454 DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
455 DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
456 DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
457 DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
458
459 //
460 // done
461 //
462 Irp->IoStatus.Information = TotalLength;
463 return STATUS_SUCCESS;
464 }
465 else
466 {
467 //
468 // adapter property query request
469 //
470 DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
471
472 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR))
473 {
474 //
475 // buffer too small
476 //
477 DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
478 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
479
480 //
481 // return required size
482 //
483 DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
484 DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
485
486 Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
487 return STATUS_SUCCESS;
488 }
489
490 //
491 // get adapter descriptor, information is returned in the same buffer
492 //
493 AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
494
495 //
496 // fill out descriptor
497 //
498 AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
499 AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
500 AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute some sane value
501 AdapterDescriptor->MaximumPhysicalPages = 25; //FIXME compute some sane value
502 AdapterDescriptor->AlignmentMask = 0;
503 AdapterDescriptor->AdapterUsesPio = FALSE;
504 AdapterDescriptor->AdapterScansDown = FALSE;
505 AdapterDescriptor->CommandQueueing = FALSE;
506 AdapterDescriptor->AcceleratedTransfer = FALSE;
507 AdapterDescriptor->BusType = BusTypeUsb;
508 AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify
509 AdapterDescriptor->BusMinorVersion = 0x00; //FIXME
510
511 //
512 // store returned length
513 //
514 Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
515
516 //
517 // done
518 //
519 return STATUS_SUCCESS;
520 }
521 }
522
523 NTSTATUS
524 USBSTOR_HandleDeviceControl(
525 IN PDEVICE_OBJECT DeviceObject,
526 IN PIRP Irp)
527 {
528 PIO_STACK_LOCATION IoStack;
529 NTSTATUS Status;
530 PPDO_DEVICE_EXTENSION PDODeviceExtension;
531 PSCSI_ADAPTER_BUS_INFO BusInfo;
532 PSCSI_INQUIRY_DATA InquiryData;
533 PINQUIRYDATA ScsiInquiryData;
534 PUFI_INQUIRY_RESPONSE UFIInquiryResponse;
535
536 //
537 // get current stack location
538 //
539 IoStack = IoGetCurrentIrpStackLocation(Irp);
540
541 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY)
542 {
543 //
544 // query property
545 //
546 Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
547 }
548 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH)
549 {
550 //
551 // query scsi pass through
552 //
553 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
554 Status = STATUS_NOT_SUPPORTED;
555 }
556 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT)
557 {
558 //
559 // query scsi pass through direct
560 //
561 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
562 Status = STATUS_NOT_SUPPORTED;
563 }
564 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER)
565 {
566 //
567 // query serial number
568 //
569 DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
570 Status = STATUS_NOT_SUPPORTED;
571 }
572 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_CAPABILITIES)
573 {
574 PIO_SCSI_CAPABILITIES Capabilities;
575
576 /* Legacy port capability query */
577 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
578 {
579 Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePool(NonPagedPool, sizeof(IO_SCSI_CAPABILITIES));
580 Irp->IoStatus.Information = sizeof(PVOID);
581 }
582 else
583 {
584 Capabilities = Irp->AssociatedIrp.SystemBuffer;
585 Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
586 }
587
588 if (Capabilities)
589 {
590 Capabilities->MaximumTransferLength = MAXULONG;
591 Capabilities->MaximumPhysicalPages = 25;
592 Capabilities->SupportedAsynchronousEvents = 0;
593 Capabilities->AlignmentMask = 0;
594 Capabilities->TaggedQueuing = FALSE;
595 Capabilities->AdapterScansDown = FALSE;
596 Capabilities->AdapterUsesPio = FALSE;
597 Status = STATUS_SUCCESS;
598 }
599 else
600 {
601 Status = STATUS_INSUFFICIENT_RESOURCES;
602 }
603 }
604 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_INQUIRY_DATA)
605 {
606 //
607 // get device extension
608 //
609 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
610 ASSERT(PDODeviceExtension);
611 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
612
613 //
614 // get parameters
615 //
616 BusInfo = Irp->AssociatedIrp.SystemBuffer;
617 InquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
618 ScsiInquiryData = (PINQUIRYDATA)InquiryData->InquiryData;
619
620
621 //
622 // get inquiry data
623 //
624 UFIInquiryResponse = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
625 ASSERT(UFIInquiryResponse);
626
627
628 BusInfo->NumberOfBuses = 1;
629 BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME
630 BusInfo->BusData[0].InitiatorBusId = 0;
631 BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
632
633 InquiryData->PathId = 0;
634 InquiryData->TargetId = 0;
635 InquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
636 InquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
637 InquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
638 InquiryData->NextInquiryDataOffset = 0;
639
640 RtlZeroMemory(ScsiInquiryData, sizeof(INQUIRYDATA));
641 ScsiInquiryData->DeviceType = UFIInquiryResponse->DeviceType;
642 ScsiInquiryData->DeviceTypeQualifier = (UFIInquiryResponse->RMB & 0x7F);
643
644 /* Hack for IoReadPartitionTable call in disk.sys */
645 ScsiInquiryData->RemovableMedia = ((ScsiInquiryData->DeviceType != DIRECT_ACCESS_DEVICE) ? ((UFIInquiryResponse->RMB & 0x80) ? 1 : 0) : 0);
646
647 ScsiInquiryData->Versions = 0x04;
648 ScsiInquiryData->ResponseDataFormat = 0x02;
649 ScsiInquiryData->AdditionalLength = 31;
650 ScsiInquiryData->SoftReset = 0;
651 ScsiInquiryData->CommandQueue = 0;
652 ScsiInquiryData->LinkedCommands = 0;
653 ScsiInquiryData->RelativeAddressing = 0;
654
655 RtlCopyMemory(&ScsiInquiryData->VendorId, UFIInquiryResponse->Vendor, USBSTOR_GetFieldLength(UFIInquiryResponse->Vendor, 8));
656 RtlCopyMemory(&ScsiInquiryData->ProductId, UFIInquiryResponse->Product, USBSTOR_GetFieldLength(UFIInquiryResponse->Product, 16));
657
658 Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
659 Status = STATUS_SUCCESS;
660 }
661 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS)
662 {
663 PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
664
665 Address->Length = sizeof(SCSI_ADDRESS);
666 Address->PortNumber = 0;
667 Address->PathId = 0;
668 Address->TargetId = 0;
669 Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN);
670 Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
671
672 Status = STATUS_SUCCESS;
673 }
674 else
675 {
676 //
677 // unsupported
678 //
679 DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
680 Status = STATUS_NOT_SUPPORTED;
681 }
682
683 return Status;
684 }