https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f3fd12b9be4143f27f6ce5...
commit f3fd12b9be4143f27f6ce5cbb5f9943b1dedfe20 Author: Victor Perevertkin victor@perevertkin.ru AuthorDate: Sun Mar 31 16:52:04 2019 +0300 Commit: Victor Perevertkin victor@perevertkin.ru CommitDate: Tue Jun 11 04:39:43 2019 +0300
[USBSTOR] Rework the routines for sending internal SCSI requests. Now for each request SenseBuffer is correctly set and 3 attempts are made to be sure the STALL state is cleared and the error is in something else. Remove the usage of UFI_INQUIRY_DATA structure in favor of "standard" INQUIRYDATA structure from scsi.h
Based in Vadim Galyant's patches to usbstor --- drivers/usb/usbstor/disk.c | 71 +++----- drivers/usb/usbstor/misc.c | 2 + drivers/usb/usbstor/pdo.c | 392 +++++++++++++++++++++--------------------- drivers/usb/usbstor/usbstor.h | 38 +--- 4 files changed, 230 insertions(+), 273 deletions(-)
diff --git a/drivers/usb/usbstor/disk.c b/drivers/usb/usbstor/disk.c index cf9c0380136..984296214cf 100644 --- a/drivers/usb/usbstor/disk.c +++ b/drivers/usb/usbstor/disk.c @@ -174,7 +174,7 @@ USBSTOR_HandleQueryProperty( PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor; ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber; PPDO_DEVICE_EXTENSION PDODeviceExtension; - PUFI_INQUIRY_RESPONSE InquiryData; + PINQUIRYDATA InquiryData; PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor; PUCHAR Buffer; PFDO_DEVICE_EXTENSION FDODeviceExtension; @@ -224,13 +224,13 @@ USBSTOR_HandleQueryProperty( ASSERT(FDODeviceExtension); ASSERT(FDODeviceExtension->Common.IsFDO);
- InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; + InquiryData = PDODeviceExtension->InquiryData; ASSERT(InquiryData);
// compute extra parameters length - FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8); - FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16); - FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4); + FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->VendorId, 8); + FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->ProductId, 16); + FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->ProductRevisionLevel, 4);
if (FDODeviceExtension->SerialNumber) { @@ -263,11 +263,11 @@ USBSTOR_HandleQueryProperty( // initialize the device descriptor DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
- DeviceDescriptor->Version = TotalLength; + DeviceDescriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR); DeviceDescriptor->Size = TotalLength; DeviceDescriptor->DeviceType = InquiryData->DeviceType; - DeviceDescriptor->DeviceTypeModifier = (InquiryData->RMB & 0x7F); - DeviceDescriptor->RemovableMedia = (InquiryData->RMB & 0x80) ? TRUE : FALSE; + DeviceDescriptor->DeviceTypeModifier = InquiryData->DeviceTypeModifier; + DeviceDescriptor->RemovableMedia = InquiryData->RemovableMedia; DeviceDescriptor->CommandQueueing = FALSE; DeviceDescriptor->BusType = BusTypeUsb; DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR); @@ -279,15 +279,15 @@ USBSTOR_HandleQueryProperty( // copy descriptors Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
- RtlCopyMemory(Buffer, InquiryData->Vendor, FieldLengthVendor); + RtlCopyMemory(Buffer, InquiryData->VendorId, FieldLengthVendor); Buffer[FieldLengthVendor] = '\0'; Buffer += FieldLengthVendor + 1;
- RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct); + RtlCopyMemory(Buffer, InquiryData->ProductId, FieldLengthProduct); Buffer[FieldLengthProduct] = '\0'; Buffer += FieldLengthProduct + 1;
- RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision); + RtlCopyMemory(Buffer, InquiryData->ProductRevisionLevel, FieldLengthRevision); Buffer[FieldLengthRevision] = '\0'; Buffer += FieldLengthRevision + 1;
@@ -364,9 +364,8 @@ USBSTOR_HandleDeviceControl( NTSTATUS Status; PPDO_DEVICE_EXTENSION PDODeviceExtension; PSCSI_ADAPTER_BUS_INFO BusInfo; - PSCSI_INQUIRY_DATA InquiryData; - PINQUIRYDATA ScsiInquiryData; - PUFI_INQUIRY_RESPONSE UFIInquiryResponse; + PSCSI_INQUIRY_DATA ScsiInquiryData; + PINQUIRYDATA InquiryData;
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -431,11 +430,8 @@ USBSTOR_HandleDeviceControl(
// get parameters BusInfo = Irp->AssociatedIrp.SystemBuffer; - InquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1); - ScsiInquiryData = (PINQUIRYDATA)InquiryData->InquiryData; - - UFIInquiryResponse = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; - ASSERT(UFIInquiryResponse); + ScsiInquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1); + InquiryData = (PINQUIRYDATA)ScsiInquiryData->InquiryData;
BusInfo->NumberOfBuses = 1; @@ -443,30 +439,19 @@ USBSTOR_HandleDeviceControl( BusInfo->BusData[0].InitiatorBusId = 0; BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
- InquiryData->PathId = 0; - InquiryData->TargetId = 0; - InquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN; - InquiryData->DeviceClaimed = PDODeviceExtension->Claimed; - InquiryData->InquiryDataLength = sizeof(INQUIRYDATA); - InquiryData->NextInquiryDataOffset = 0; - - RtlZeroMemory(ScsiInquiryData, sizeof(INQUIRYDATA)); - ScsiInquiryData->DeviceType = UFIInquiryResponse->DeviceType; - ScsiInquiryData->DeviceTypeQualifier = (UFIInquiryResponse->RMB & 0x7F); - - // Hack for IoReadPartitionTable call in disk.sys - ScsiInquiryData->RemovableMedia = ((ScsiInquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ? ((UFIInquiryResponse->RMB & 0x80) ? 1 : 0) : 0); - - ScsiInquiryData->Versions = 0x04; - ScsiInquiryData->ResponseDataFormat = 0x02; - ScsiInquiryData->AdditionalLength = 31; - ScsiInquiryData->SoftReset = 0; - ScsiInquiryData->CommandQueue = 0; - ScsiInquiryData->LinkedCommands = 0; - ScsiInquiryData->RelativeAddressing = 0; - - RtlCopyMemory(&ScsiInquiryData->VendorId, UFIInquiryResponse->Vendor, USBSTOR_GetFieldLength(UFIInquiryResponse->Vendor, 8)); - RtlCopyMemory(&ScsiInquiryData->ProductId, UFIInquiryResponse->Product, USBSTOR_GetFieldLength(UFIInquiryResponse->Product, 16)); + ScsiInquiryData->PathId = 0; + ScsiInquiryData->TargetId = 0; + ScsiInquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN; + ScsiInquiryData->DeviceClaimed = PDODeviceExtension->Claimed; + ScsiInquiryData->InquiryDataLength = sizeof(INQUIRYDATA); + ScsiInquiryData->NextInquiryDataOffset = 0; + + // Note: INQUIRYDATA structure is larger than INQUIRYDATABUFFERSIZE + RtlZeroMemory(InquiryData, sizeof(INQUIRYDATA)); + RtlCopyMemory(InquiryData, PDODeviceExtension->InquiryData, INQUIRYDATABUFFERSIZE); + + InquiryData->Versions = 0x04; + InquiryData->ResponseDataFormat = 0x02; // some devices set this to 1
Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1; Status = STATUS_SUCCESS; diff --git a/drivers/usb/usbstor/misc.c b/drivers/usb/usbstor/misc.c index 671336df88c..3dbbf160813 100644 --- a/drivers/usb/usbstor/misc.c +++ b/drivers/usb/usbstor/misc.c @@ -258,6 +258,7 @@ USBSTOR_ResetDevice( return Status; }
+#if 0 BOOLEAN USBSTOR_IsFloppy( IN PUCHAR Buffer, @@ -319,3 +320,4 @@ USBSTOR_IsFloppy(
return FALSE; } +#endif diff --git a/drivers/usb/usbstor/pdo.c b/drivers/usb/usbstor/pdo.c index 98c01d1cb7b..93caca4e1ef 100644 --- a/drivers/usb/usbstor/pdo.c +++ b/drivers/usb/usbstor/pdo.c @@ -5,6 +5,8 @@ * COPYRIGHT: 2005-2006 James Tabor * 2011-2012 Michael Martin (michael.martin@reactos.org) * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org) + * 2017 Vadim Galyant + * 2019 Victor Perevertkin (victor.perevertkin@reactos.org) */
#include "usbstor.h" @@ -15,7 +17,7 @@
LPCSTR USBSTOR_GetDeviceType( - IN PUFI_INQUIRY_RESPONSE InquiryData, + IN PINQUIRYDATA InquiryData, IN UCHAR IsFloppy) { if (InquiryData->DeviceType == 0) @@ -67,7 +69,7 @@ USBSTOR_GetDeviceType(
LPCSTR USBSTOR_GetGenericType( - IN PUFI_INQUIRY_RESPONSE InquiryData, + IN PINQUIRYDATA InquiryData, IN UCHAR IsFloppy) { if (InquiryData->DeviceType == 0) @@ -198,13 +200,13 @@ USBSTOR_PdoHandleQueryDeviceId( CHAR Buffer[100] = {0}; LPCSTR DeviceType; ULONG Offset = 0; - PUFI_INQUIRY_RESPONSE InquiryData; + PINQUIRYDATA InquiryData; ANSI_STRING AnsiString; UNICODE_STRING DeviceId;
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; ASSERT(DeviceExtension->InquiryData); - InquiryData = (PUFI_INQUIRY_RESPONSE)DeviceExtension->InquiryData; + InquiryData = DeviceExtension->InquiryData;
DeviceType = USBSTOR_GetDeviceType(InquiryData, DeviceExtension->IsFloppy);
@@ -212,17 +214,17 @@ USBSTOR_PdoHandleQueryDeviceId( Offset = sprintf(&Buffer[Offset], "USBSTOR\"); Offset += sprintf(&Buffer[Offset], DeviceType); Offset += sprintf(&Buffer[Offset], "&Ven_"); - Offset += CopyField(InquiryData->Vendor, &Buffer[Offset], 8); + Offset += CopyField(InquiryData->VendorId, &Buffer[Offset], 8); Offset += sprintf(&Buffer[Offset], "&Prod_"); - Offset += CopyField(InquiryData->Product, &Buffer[Offset], 16); + Offset += CopyField(InquiryData->ProductId, &Buffer[Offset], 16); Offset += sprintf(&Buffer[Offset], "&Rev_"); - Offset += CopyField(InquiryData->Revision, &Buffer[Offset], 4); + Offset += CopyField(InquiryData->ProductRevisionLevel, &Buffer[Offset], 4);
RtlInitAnsiString(&AnsiString, (PCSZ)Buffer);
// allocate DeviceId string DeviceId.Length = 0; - DeviceId.MaximumLength = (strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR); + DeviceId.MaximumLength = (USHORT)((strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR)); DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength); if (!DeviceId.Buffer) { @@ -289,12 +291,12 @@ USBSTOR_PdoHandleQueryHardwareId( CHAR Id1[50], Id2[50], Id3[50], Id4[50], Id5[50], Id6[50]; ULONG Id1Length, Id2Length, Id3Length, Id4Length, Id5Length,Id6Length; ULONG Offset, TotalLength, Length; - PUFI_INQUIRY_RESPONSE InquiryData; + PINQUIRYDATA InquiryData;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; ASSERT(FDODeviceExtension->DeviceDescriptor); - InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; + InquiryData = PDODeviceExtension->InquiryData;
DeviceType = USBSTOR_GetDeviceType(InquiryData, PDODeviceExtension->IsFloppy); GenericType = USBSTOR_GetGenericType(InquiryData, PDODeviceExtension->IsFloppy); @@ -302,47 +304,47 @@ USBSTOR_PdoHandleQueryHardwareId( ASSERT(GenericType);
// generate id 1 - // USBSTOR\SCSIType_Vendor(8)_Product(16)_Revision(4) + // USBSTOR\SCSIType_VendorId(8)_ProductId(16)_Revision(4) RtlZeroMemory(Id1, sizeof(Id1)); Offset = 0; Offset = sprintf(&Id1[Offset], "USBSTOR\"); Offset += sprintf(&Id1[Offset], DeviceType); - Offset += CopyField(InquiryData->Vendor, &Id1[Offset], 8); - Offset += CopyField(InquiryData->Product, &Id1[Offset], 16); - Offset += CopyField(InquiryData->Revision, &Id1[Offset], 4); + Offset += CopyField(InquiryData->VendorId, &Id1[Offset], 8); + Offset += CopyField(InquiryData->ProductId, &Id1[Offset], 16); + Offset += CopyField(InquiryData->ProductRevisionLevel, &Id1[Offset], 4); Id1Length = strlen(Id1) + 1; DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId1 %s\n", Id1);
// generate id 2 - // USBSTOR\SCSIType_VENDOR(8)_Product(16) + // USBSTOR\SCSIType_VendorId(8)_ProductId(16) RtlZeroMemory(Id2, sizeof(Id2)); Offset = 0; Offset = sprintf(&Id2[Offset], "USBSTOR\"); Offset += sprintf(&Id2[Offset], DeviceType); - Offset += CopyField(InquiryData->Vendor, &Id2[Offset], 8); - Offset += CopyField(InquiryData->Product, &Id2[Offset], 16); + Offset += CopyField(InquiryData->VendorId, &Id2[Offset], 8); + Offset += CopyField(InquiryData->ProductId, &Id2[Offset], 16); Id2Length = strlen(Id2) + 1; DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId2 %s\n", Id2);
// generate id 3 - // USBSTOR\SCSIType_VENDOR(8) + // USBSTOR\SCSIType_VendorId(8) RtlZeroMemory(Id3, sizeof(Id3)); Offset = 0; Offset = sprintf(&Id3[Offset], "USBSTOR\"); Offset += sprintf(&Id3[Offset], DeviceType); - Offset += CopyField(InquiryData->Vendor, &Id3[Offset], 8); + Offset += CopyField(InquiryData->VendorId, &Id3[Offset], 8); Id3Length = strlen(Id3) + 1; DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId3 %s\n", Id3);
// generate id 4 - // USBSTOR\SCSIType_VENDOR(8)_Product(16)_Revision(1) + // USBSTOR\SCSIType_VendorId(8)_ProductId(16)_Revision(1) RtlZeroMemory(Id4, sizeof(Id4)); Offset = 0; Offset = sprintf(&Id4[Offset], "USBSTOR\"); Offset += sprintf(&Id4[Offset], DeviceType); - Offset += CopyField(InquiryData->Vendor, &Id4[Offset], 8); - Offset += CopyField(InquiryData->Product, &Id4[Offset], 16); - Offset += CopyField(InquiryData->Revision, &Id4[Offset], 1); + Offset += CopyField(InquiryData->VendorId, &Id4[Offset], 8); + Offset += CopyField(InquiryData->ProductId, &Id4[Offset], 16); + Offset += CopyField(InquiryData->ProductRevisionLevel, &Id4[Offset], 1); Id4Length = strlen(Id4) + 1; DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId4 %s\n", Id4);
@@ -404,7 +406,7 @@ USBSTOR_PdoHandleQueryCompatibleId( PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; ASSERT(FDODeviceExtension->DeviceDescriptor); - DeviceType = USBSTOR_GetDeviceType((PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy); + DeviceType = USBSTOR_GetDeviceType(PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy);
// format instance id Length = sprintf(Buffer, "USBSTOR\%s", DeviceType) + 1; @@ -645,201 +647,204 @@ USBSTOR_PdoHandlePnp(
NTSTATUS NTAPI -USBSTOR_CompletionRoutine( +USBSTOR_SyncCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Ctx) { - PKEVENT Event = (PKEVENT)Ctx; - - KeSetEvent(Event, 0, FALSE); + KeSetEvent((PKEVENT)Ctx, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; }
+/* +* @name USBSTOR_SendInternalCdb +* +* Issues an internal SCSI request to device. +* The request is sent in a synchronous way. +*/ +static NTSTATUS -USBSTOR_AllocateIrp( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG DataTransferLength, - IN UCHAR OpCode, - IN PKEVENT Event, - OUT PSCSI_REQUEST_BLOCK *OutRequest, - OUT PIRP *OutIrp) +USBSTOR_SendInternalCdb( + IN PDEVICE_OBJECT PdoDevice, + IN PCDB Cdb, + IN UCHAR CdbLength, + IN ULONG TimeOutValue, + OUT PVOID OutDataBuffer, + OUT PULONG OutDataTransferLength) { - PIRP Irp; + PSCSI_REQUEST_BLOCK Srb; + PSENSE_DATA SenseBuffer; PIO_STACK_LOCATION IoStack; - PSCSI_REQUEST_BLOCK Request; - PCDB pCDB; - - Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); - if (!Irp) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - IoStack = IoGetNextIrpStackLocation(Irp); - - Request = ExAllocatePoolWithTag(NonPagedPool, - sizeof(SCSI_REQUEST_BLOCK), - USB_STOR_TAG); - if (!Request) - { - IoFreeIrp(Irp); - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlZeroMemory(Request, sizeof(SCSI_REQUEST_BLOCK)); - - // allocate data transfer block - Request->DataBuffer = ExAllocatePoolWithTag(NonPagedPool, - DataTransferLength, - USB_STOR_TAG); - if (!Request->DataBuffer) - { - IoFreeIrp(Irp); - ExFreePoolWithTag(Request, USB_STOR_TAG); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Irp->MdlAddress = IoAllocateMdl(Request->DataBuffer, DataTransferLength, FALSE, FALSE, NULL); - if (!Irp->MdlAddress) - { - IoFreeIrp(Irp); - ExFreePoolWithTag(Request->DataBuffer, USB_STOR_TAG); - ExFreePoolWithTag(Request, USB_STOR_TAG); - return STATUS_INSUFFICIENT_RESOURCES; - } - - MmBuildMdlForNonPagedPool(Irp->MdlAddress); - - Request->DataTransferLength = DataTransferLength; - Request->Function = SRB_FUNCTION_EXECUTE_SCSI; - Request->SrbFlags = SRB_FLAGS_DATA_IN; - - RtlZeroMemory(Request->DataBuffer, DataTransferLength); - - // get SCSI command data block - pCDB = (PCDB)Request->Cdb; - - // set op code - pCDB->AsByte[0] = OpCode; - - // store result - IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; - IoStack->Parameters.Others.Argument1 = Request; - IoStack->DeviceObject = DeviceObject; - - KeInitializeEvent(Event, NotificationEvent, FALSE); - - IoSetCompletionRoutine(Irp, USBSTOR_CompletionRoutine, (PVOID)Event, TRUE, TRUE, TRUE); - - *OutIrp = Irp; - *OutRequest = Request; - return STATUS_SUCCESS; -} - -NTSTATUS -USBSTOR_SendIrp( - IN PDEVICE_OBJECT PDODeviceObject, - IN ULONG DataTransferLength, - IN UCHAR OpCode, - OUT PVOID *OutData) -{ - NTSTATUS Status; - PIRP Irp; KEVENT Event; - PPDO_DEVICE_EXTENSION PDODeviceExtension; - PSCSI_REQUEST_BLOCK Request; + PIRP Irp = NULL; + PMDL Mdl = NULL; + ULONG ix = 0; + NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; + UCHAR SrbStatus;
- Status = USBSTOR_AllocateIrp(PDODeviceObject, DataTransferLength, OpCode, &Event, &Request, &Irp); - if (!NT_SUCCESS(Status)) - { - DPRINT1("[USBSTOR] Failed to build irp\n"); - return Status; - } - - PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension; + DPRINT("USBSTOR_SendInternalCdb SCSIOP %x\n", Cdb->CDB6GENERIC.OperationCode);
- ASSERT(Irp); - ASSERT(PDODeviceExtension->LowerDeviceObject); - Status = IoCallDriver(PDODeviceExtension->Self, Irp); + Srb = ExAllocatePoolWithTag(NonPagedPool, + sizeof(SCSI_REQUEST_BLOCK), + USB_STOR_TAG);
- if (Status == STATUS_PENDING) + if (Srb) { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = Irp->IoStatus.Status; - } + SenseBuffer = ExAllocatePoolWithTag(NonPagedPool, + SENSE_BUFFER_SIZE, + USB_STOR_TAG);
- if (NT_SUCCESS(Status)) - { - *OutData = Request->DataBuffer; - } - else - { - ExFreePoolWithTag(Request->DataBuffer, USB_STOR_TAG); - *OutData = NULL; + if (SenseBuffer) + { + Mdl = IoAllocateMdl(OutDataBuffer, + *OutDataTransferLength, + FALSE, + FALSE, + NULL); + + if (!Mdl) + { + ExFreePoolWithTag(SenseBuffer, USB_STOR_TAG); + ExFreePoolWithTag(Srb, USB_STOR_TAG); + return Status; + } + + MmBuildMdlForNonPagedPool(Mdl); + + // make 3 attempts - the device may be in STALL state after the first one + do + { + Irp = IoAllocateIrp(PdoDevice->StackSize, FALSE); + + if (!Irp) + { + break; + } + + IoStack = IoGetNextIrpStackLocation(Irp); + IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoStack->Parameters.Scsi.Srb = Srb; + + RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK)); + + Srb->Length = sizeof(SCSI_REQUEST_BLOCK); + Srb->Function = SRB_FUNCTION_EXECUTE_SCSI; + Srb->CdbLength = CdbLength; + Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE; + Srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_NO_QUEUE_FREEZE; + Srb->DataTransferLength = *OutDataTransferLength; + Srb->TimeOutValue = TimeOutValue; + Srb->DataBuffer = OutDataBuffer; + Srb->SenseInfoBuffer = SenseBuffer; + + RtlCopyMemory(Srb->Cdb, Cdb, CdbLength); + + Irp->MdlAddress = Mdl; + + KeInitializeEvent(&Event, SynchronizationEvent, FALSE); + + IoSetCompletionRoutine(Irp, + USBSTOR_SyncCompletionRoutine, + &Event, + TRUE, + TRUE, + TRUE); + + if (IoCallDriver(PdoDevice, Irp) == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + } + + SrbStatus = SRB_STATUS(Srb->SrbStatus); + + IoFreeIrp(Irp); + Irp = NULL; + + if (SrbStatus == SRB_STATUS_SUCCESS || + SrbStatus == SRB_STATUS_DATA_OVERRUN) + { + Status = STATUS_SUCCESS; + *OutDataTransferLength = Srb->DataTransferLength; + break; + } + + Status = STATUS_UNSUCCESSFUL; + + ++ix; + } while (ix < 3); + + if (Mdl) + { + IoFreeMdl(Mdl); + } + + ExFreePoolWithTag(SenseBuffer, USB_STOR_TAG); + } + + ExFreePoolWithTag(Srb, USB_STOR_TAG); }
- ExFreePoolWithTag(Request, USB_STOR_TAG); - IoFreeMdl(Irp->MdlAddress); - IoFreeIrp(Irp); return Status; }
+/* +* @name USBSTOR_FillInquiryData +* +* Sends a SCSI Inquiry request and fills in the PDODeviceExtension->InquiryData field with a result. +*/ +static NTSTATUS -USBSTOR_SendInquiryIrp( +USBSTOR_FillInquiryData( IN PDEVICE_OBJECT PDODeviceObject) { - NTSTATUS Status; + NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; PPDO_DEVICE_EXTENSION PDODeviceExtension; - PUFI_INQUIRY_RESPONSE Response; + CDB Cdb; + ULONG DataTransferLength = INQUIRYDATABUFFERSIZE; + PINQUIRYDATA InquiryData;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension; + InquiryData = ExAllocatePoolWithTag(NonPagedPool, INQUIRYDATABUFFERSIZE, USB_STOR_TAG);
- Status = USBSTOR_SendIrp(PDODeviceObject, sizeof(UFI_INQUIRY_RESPONSE), SCSIOP_INQUIRY, (PVOID*)&Response); - if (!NT_SUCCESS(Status)) + if (!InquiryData) { - DPRINT1("USBSTOR_SendInquiryIrp Failed with %x\n", Status); + DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status); return Status; }
- DPRINT1("Response %p\n", Response); - DPRINT1("DeviceType %x\n", Response->DeviceType); - DPRINT1("RMB %x\n", Response->RMB); - DPRINT1("Version %x\n", Response->Version); - DPRINT1("Format %x\n", Response->Format); - DPRINT1("Length %x\n", Response->Length); - DPRINT1("Reserved %p\n", Response->Reserved); - DPRINT1("Vendor %c%c%c%c%c%c%c%c\n", Response->Vendor[0], Response->Vendor[1], Response->Vendor[2], Response->Vendor[3], Response->Vendor[4], Response->Vendor[5], Response->Vendor[6], Response->Vendor[7]); - DPRINT1("Product %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", Response->Product[0], Response->Product[1], Response->Product[2], Response->Product[3], - Response->Product[4], Response->Product[5], Response->Product[6], Response->Product[7], - Response->Product[8], Response->Product[9], Response->Product[10], Response->Product[11], - Response->Product[12], Response->Product[13], Response->Product[14], Response->Product[15]); - - DPRINT1("Revision %c%c%c%c\n", Response->Revision[0], Response->Revision[1], Response->Revision[2], Response->Revision[3]); - - PDODeviceExtension->InquiryData = (PVOID)Response; - return Status; -} + RtlZeroMemory(&Cdb, sizeof(Cdb)); + Cdb.CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY; + Cdb.CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
-NTSTATUS -USBSTOR_SendFormatCapacityIrp( - IN PDEVICE_OBJECT PDODeviceObject) -{ - NTSTATUS Status; - PPDO_DEVICE_EXTENSION PDODeviceExtension; - PUCHAR Response; - - PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension; + Status = USBSTOR_SendInternalCdb(PDODeviceObject, &Cdb, CDB6GENERIC_LENGTH, 20, InquiryData, &DataTransferLength);
- Status = USBSTOR_SendIrp(PDODeviceObject, 0xFC, SCSIOP_READ_FORMATTED_CAPACITY, (PVOID*)&Response); if (!NT_SUCCESS(Status)) { + DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status); + ExFreePoolWithTag(InquiryData, USB_STOR_TAG); return Status; }
- PDODeviceExtension->IsFloppy = USBSTOR_IsFloppy(Response, 0xFC /*FIXME*/, &PDODeviceExtension->MediumTypeCode); - - ExFreePoolWithTag(Response, USB_STOR_TAG); + DPRINT("DeviceType %x\n", InquiryData->DeviceType); + DPRINT("DeviceTypeModifier %x\n", InquiryData->DeviceTypeModifier); + DPRINT("RemovableMedia %x\n", InquiryData->RemovableMedia); + DPRINT("Version %x\n", InquiryData->Versions); + DPRINT("Format %x\n", InquiryData->ResponseDataFormat); + DPRINT("Length %x\n", InquiryData->AdditionalLength); + DPRINT("Reserved %p\n", InquiryData->Reserved); + DPRINT("VendorId %c%c%c%c%c%c%c%c\n", InquiryData->VendorId[0], InquiryData->VendorId[1], InquiryData->VendorId[2], InquiryData->VendorId[3], InquiryData->VendorId[4], InquiryData->VendorId[5], InquiryData->VendorId[6], InquiryData->VendorId[7]); + DPRINT("ProductId %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", InquiryData->ProductId[0], InquiryData->ProductId[1], InquiryData->ProductId[2], InquiryData->ProductId[3], + InquiryData->ProductId[4], InquiryData->ProductId[5], InquiryData->ProductId[6], InquiryData->ProductId[7], + InquiryData->ProductId[8], InquiryData->ProductId[9], InquiryData->ProductId[10], InquiryData->ProductId[11], + InquiryData->ProductId[12], InquiryData->ProductId[13], InquiryData->ProductId[14], InquiryData->ProductId[15]); + + DPRINT("Revision %c%c%c%c\n", InquiryData->ProductRevisionLevel[0], InquiryData->ProductRevisionLevel[1], InquiryData->ProductRevisionLevel[2], InquiryData->ProductRevisionLevel[3]); + + PDODeviceExtension->InquiryData = InquiryData; return Status; }
@@ -851,7 +856,6 @@ USBSTOR_CreatePDO( PDEVICE_OBJECT PDO; NTSTATUS Status; PPDO_DEVICE_EXTENSION PDODeviceExtension; - PUFI_INQUIRY_RESPONSE Response; PFDO_DEVICE_EXTENSION FDODeviceExtension;
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -860,6 +864,7 @@ USBSTOR_CreatePDO( Status = IoCreateDevice(DeviceObject->DriverObject, sizeof(PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_MASS_STORAGE, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &PDO); if (!NT_SUCCESS(Status)) { + DPRINT1("Failed to create PDO, status %x\n", Status); return Status; }
@@ -876,7 +881,7 @@ USBSTOR_CreatePDO( PDODeviceExtension->Self = PDO; PDODeviceExtension->LUN = LUN;
- PDO->Flags |= DO_DIRECT_IO | DO_MAP_IO_BUFFER; + PDO->Flags |= DO_DIRECT_IO;
// device is initialized PDO->Flags &= ~DO_DEVICE_INITIALIZING; @@ -885,20 +890,21 @@ USBSTOR_CreatePDO( FDODeviceExtension->ChildPDO[LUN] = PDO;
// send inquiry command by irp - Status = USBSTOR_SendInquiryIrp(PDO); - ASSERT(Status == STATUS_SUCCESS); - - Response = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; - ASSERT(Response); + Status = USBSTOR_FillInquiryData(PDO);
- if (Response->DeviceType == 0) + if (!NT_SUCCESS(Status)) { - // check if it is a floppy - Status = USBSTOR_SendFormatCapacityIrp(PDO); - DPRINT1("[USBSTOR] Status %x IsFloppy %x MediumTypeCode %x\n", Status, PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode); + return Status; + }
- // failing command is non critical - Status = STATUS_SUCCESS; + if (PDODeviceExtension->InquiryData->DeviceType == DIRECT_ACCESS_DEVICE) + { + PDODeviceExtension->IsFloppy = FALSE; // TODO: implement the actual check + } + else + { + // we work only with DIRECT_ACCESS_DEVICE for now + return STATUS_NOT_SUPPORTED; }
return Status; diff --git a/drivers/usb/usbstor/usbstor.h b/drivers/usb/usbstor/usbstor.h index 40b369bd15e..1ac3e33a55e 100644 --- a/drivers/usb/usbstor/usbstor.h +++ b/drivers/usb/usbstor/usbstor.h @@ -68,7 +68,7 @@ typedef struct USBSTOR_COMMON_DEVICE_EXTENSION Common; PDEVICE_OBJECT LowerDeviceObject; // points to FDO UCHAR LUN; // lun id - PVOID InquiryData; // USB SCSI inquiry data + PINQUIRYDATA InquiryData; // USB SCSI inquiry data PUCHAR FormatData; // USB SCSI Read Format Capacity Data UCHAR Claimed; // indicating if it has been claimed by upper driver ULONG BlockLength; // length of block @@ -117,42 +117,6 @@ typedef struct UCHAR Status; // CSW status }CSW, *PCSW;
-//-------------------------------------------------------------------------------------------------------------------------------------------- -// -// UFI INQUIRY command -// -typedef struct -{ - UCHAR Code; // operation code 0x12 - UCHAR LUN; // lun address - UCHAR PageCode; // product data information, always 0x00 - UCHAR Reserved; // reserved 0x00 - UCHAR AllocationLength; // length of inquiry data to be returned, default 36 bytes - UCHAR Reserved1[7]; //reserved bytes 0x00 -}UFI_INQUIRY_CMD, *PUFI_INQUIRY_CMD; - -C_ASSERT(sizeof(UFI_INQUIRY_CMD) == 12); - -#define UFI_INQUIRY_CMD_LEN 0x6 - -// -// UFI INQUIRY command response -// -typedef struct -{ - UCHAR DeviceType; // device type - UCHAR RMB; // removable media bit - UCHAR Version; // contains version 0x00 - UCHAR Format; // response format - UCHAR Length; // additional length - UCHAR Reserved[3]; // reserved - UCHAR Vendor[8]; // vendor identification string - UCHAR Product[16]; // product identification string - UCHAR Revision[4]; // product revision code -}UFI_INQUIRY_RESPONSE, *PUFI_INQUIRY_RESPONSE; - -C_ASSERT(sizeof(UFI_INQUIRY_RESPONSE) == 36); - //-------------------------------------------------------------------------------------------------------------------------------------------- // // UFI read cmd