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