https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f3fd12b9be4143f27f6ce…
commit f3fd12b9be4143f27f6ce5cbb5f9943b1dedfe20
Author: Victor Perevertkin <victor(a)perevertkin.ru>
AuthorDate: Sun Mar 31 16:52:04 2019 +0300
Commit: Victor Perevertkin <victor(a)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(a)reactos.org)
* 2011-2013 Johannes Anderwald (johannes.anderwald(a)reactos.org)
+ * 2017 Vadim Galyant
+ * 2019 Victor Perevertkin (victor.perevertkin(a)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