mirror of
https://github.com/reactos/reactos.git
synced 2025-05-01 19:50:36 +00:00
[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
This commit is contained in:
parent
ed6724cd7e
commit
f3fd12b9be
4 changed files with 230 additions and 273 deletions
|
@ -174,7 +174,7 @@ USBSTOR_HandleQueryProperty(
|
||||||
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
|
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
|
||||||
ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber;
|
ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber;
|
||||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||||
PUFI_INQUIRY_RESPONSE InquiryData;
|
PINQUIRYDATA InquiryData;
|
||||||
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
|
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
|
||||||
PUCHAR Buffer;
|
PUCHAR Buffer;
|
||||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
@ -224,13 +224,13 @@ USBSTOR_HandleQueryProperty(
|
||||||
ASSERT(FDODeviceExtension);
|
ASSERT(FDODeviceExtension);
|
||||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
|
InquiryData = PDODeviceExtension->InquiryData;
|
||||||
ASSERT(InquiryData);
|
ASSERT(InquiryData);
|
||||||
|
|
||||||
// compute extra parameters length
|
// compute extra parameters length
|
||||||
FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8);
|
FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->VendorId, 8);
|
||||||
FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16);
|
FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->ProductId, 16);
|
||||||
FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4);
|
FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->ProductRevisionLevel, 4);
|
||||||
|
|
||||||
if (FDODeviceExtension->SerialNumber)
|
if (FDODeviceExtension->SerialNumber)
|
||||||
{
|
{
|
||||||
|
@ -263,11 +263,11 @@ USBSTOR_HandleQueryProperty(
|
||||||
// initialize the device descriptor
|
// initialize the device descriptor
|
||||||
DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
|
DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
DeviceDescriptor->Version = TotalLength;
|
DeviceDescriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
||||||
DeviceDescriptor->Size = TotalLength;
|
DeviceDescriptor->Size = TotalLength;
|
||||||
DeviceDescriptor->DeviceType = InquiryData->DeviceType;
|
DeviceDescriptor->DeviceType = InquiryData->DeviceType;
|
||||||
DeviceDescriptor->DeviceTypeModifier = (InquiryData->RMB & 0x7F);
|
DeviceDescriptor->DeviceTypeModifier = InquiryData->DeviceTypeModifier;
|
||||||
DeviceDescriptor->RemovableMedia = (InquiryData->RMB & 0x80) ? TRUE : FALSE;
|
DeviceDescriptor->RemovableMedia = InquiryData->RemovableMedia;
|
||||||
DeviceDescriptor->CommandQueueing = FALSE;
|
DeviceDescriptor->CommandQueueing = FALSE;
|
||||||
DeviceDescriptor->BusType = BusTypeUsb;
|
DeviceDescriptor->BusType = BusTypeUsb;
|
||||||
DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
|
DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
|
||||||
|
@ -279,15 +279,15 @@ USBSTOR_HandleQueryProperty(
|
||||||
// copy descriptors
|
// copy descriptors
|
||||||
Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
|
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] = '\0';
|
||||||
Buffer += FieldLengthVendor + 1;
|
Buffer += FieldLengthVendor + 1;
|
||||||
|
|
||||||
RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct);
|
RtlCopyMemory(Buffer, InquiryData->ProductId, FieldLengthProduct);
|
||||||
Buffer[FieldLengthProduct] = '\0';
|
Buffer[FieldLengthProduct] = '\0';
|
||||||
Buffer += FieldLengthProduct + 1;
|
Buffer += FieldLengthProduct + 1;
|
||||||
|
|
||||||
RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision);
|
RtlCopyMemory(Buffer, InquiryData->ProductRevisionLevel, FieldLengthRevision);
|
||||||
Buffer[FieldLengthRevision] = '\0';
|
Buffer[FieldLengthRevision] = '\0';
|
||||||
Buffer += FieldLengthRevision + 1;
|
Buffer += FieldLengthRevision + 1;
|
||||||
|
|
||||||
|
@ -364,9 +364,8 @@ USBSTOR_HandleDeviceControl(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||||
PSCSI_ADAPTER_BUS_INFO BusInfo;
|
PSCSI_ADAPTER_BUS_INFO BusInfo;
|
||||||
PSCSI_INQUIRY_DATA InquiryData;
|
PSCSI_INQUIRY_DATA ScsiInquiryData;
|
||||||
PINQUIRYDATA ScsiInquiryData;
|
PINQUIRYDATA InquiryData;
|
||||||
PUFI_INQUIRY_RESPONSE UFIInquiryResponse;
|
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
@ -431,11 +430,8 @@ USBSTOR_HandleDeviceControl(
|
||||||
|
|
||||||
// get parameters
|
// get parameters
|
||||||
BusInfo = Irp->AssociatedIrp.SystemBuffer;
|
BusInfo = Irp->AssociatedIrp.SystemBuffer;
|
||||||
InquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
|
ScsiInquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
|
||||||
ScsiInquiryData = (PINQUIRYDATA)InquiryData->InquiryData;
|
InquiryData = (PINQUIRYDATA)ScsiInquiryData->InquiryData;
|
||||||
|
|
||||||
UFIInquiryResponse = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
|
|
||||||
ASSERT(UFIInquiryResponse);
|
|
||||||
|
|
||||||
|
|
||||||
BusInfo->NumberOfBuses = 1;
|
BusInfo->NumberOfBuses = 1;
|
||||||
|
@ -443,30 +439,19 @@ USBSTOR_HandleDeviceControl(
|
||||||
BusInfo->BusData[0].InitiatorBusId = 0;
|
BusInfo->BusData[0].InitiatorBusId = 0;
|
||||||
BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
|
BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
|
||||||
|
|
||||||
InquiryData->PathId = 0;
|
ScsiInquiryData->PathId = 0;
|
||||||
InquiryData->TargetId = 0;
|
ScsiInquiryData->TargetId = 0;
|
||||||
InquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
|
ScsiInquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
|
||||||
InquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
|
ScsiInquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
|
||||||
InquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
|
ScsiInquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
|
||||||
InquiryData->NextInquiryDataOffset = 0;
|
ScsiInquiryData->NextInquiryDataOffset = 0;
|
||||||
|
|
||||||
RtlZeroMemory(ScsiInquiryData, sizeof(INQUIRYDATA));
|
// Note: INQUIRYDATA structure is larger than INQUIRYDATABUFFERSIZE
|
||||||
ScsiInquiryData->DeviceType = UFIInquiryResponse->DeviceType;
|
RtlZeroMemory(InquiryData, sizeof(INQUIRYDATA));
|
||||||
ScsiInquiryData->DeviceTypeQualifier = (UFIInquiryResponse->RMB & 0x7F);
|
RtlCopyMemory(InquiryData, PDODeviceExtension->InquiryData, INQUIRYDATABUFFERSIZE);
|
||||||
|
|
||||||
// Hack for IoReadPartitionTable call in disk.sys
|
InquiryData->Versions = 0x04;
|
||||||
ScsiInquiryData->RemovableMedia = ((ScsiInquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ? ((UFIInquiryResponse->RMB & 0x80) ? 1 : 0) : 0);
|
InquiryData->ResponseDataFormat = 0x02; // some devices set this to 1
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
|
Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
|
@ -258,6 +258,7 @@ USBSTOR_ResetDevice(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
USBSTOR_IsFloppy(
|
USBSTOR_IsFloppy(
|
||||||
IN PUCHAR Buffer,
|
IN PUCHAR Buffer,
|
||||||
|
@ -319,3 +320,4 @@ USBSTOR_IsFloppy(
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* COPYRIGHT: 2005-2006 James Tabor
|
* COPYRIGHT: 2005-2006 James Tabor
|
||||||
* 2011-2012 Michael Martin (michael.martin@reactos.org)
|
* 2011-2012 Michael Martin (michael.martin@reactos.org)
|
||||||
* 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
|
* 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
|
* 2017 Vadim Galyant
|
||||||
|
* 2019 Victor Perevertkin (victor.perevertkin@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "usbstor.h"
|
#include "usbstor.h"
|
||||||
|
@ -15,7 +17,7 @@
|
||||||
|
|
||||||
LPCSTR
|
LPCSTR
|
||||||
USBSTOR_GetDeviceType(
|
USBSTOR_GetDeviceType(
|
||||||
IN PUFI_INQUIRY_RESPONSE InquiryData,
|
IN PINQUIRYDATA InquiryData,
|
||||||
IN UCHAR IsFloppy)
|
IN UCHAR IsFloppy)
|
||||||
{
|
{
|
||||||
if (InquiryData->DeviceType == 0)
|
if (InquiryData->DeviceType == 0)
|
||||||
|
@ -67,7 +69,7 @@ USBSTOR_GetDeviceType(
|
||||||
|
|
||||||
LPCSTR
|
LPCSTR
|
||||||
USBSTOR_GetGenericType(
|
USBSTOR_GetGenericType(
|
||||||
IN PUFI_INQUIRY_RESPONSE InquiryData,
|
IN PINQUIRYDATA InquiryData,
|
||||||
IN UCHAR IsFloppy)
|
IN UCHAR IsFloppy)
|
||||||
{
|
{
|
||||||
if (InquiryData->DeviceType == 0)
|
if (InquiryData->DeviceType == 0)
|
||||||
|
@ -198,13 +200,13 @@ USBSTOR_PdoHandleQueryDeviceId(
|
||||||
CHAR Buffer[100] = {0};
|
CHAR Buffer[100] = {0};
|
||||||
LPCSTR DeviceType;
|
LPCSTR DeviceType;
|
||||||
ULONG Offset = 0;
|
ULONG Offset = 0;
|
||||||
PUFI_INQUIRY_RESPONSE InquiryData;
|
PINQUIRYDATA InquiryData;
|
||||||
ANSI_STRING AnsiString;
|
ANSI_STRING AnsiString;
|
||||||
UNICODE_STRING DeviceId;
|
UNICODE_STRING DeviceId;
|
||||||
|
|
||||||
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
ASSERT(DeviceExtension->InquiryData);
|
ASSERT(DeviceExtension->InquiryData);
|
||||||
InquiryData = (PUFI_INQUIRY_RESPONSE)DeviceExtension->InquiryData;
|
InquiryData = DeviceExtension->InquiryData;
|
||||||
|
|
||||||
DeviceType = USBSTOR_GetDeviceType(InquiryData, DeviceExtension->IsFloppy);
|
DeviceType = USBSTOR_GetDeviceType(InquiryData, DeviceExtension->IsFloppy);
|
||||||
|
|
||||||
|
@ -212,17 +214,17 @@ USBSTOR_PdoHandleQueryDeviceId(
|
||||||
Offset = sprintf(&Buffer[Offset], "USBSTOR\\");
|
Offset = sprintf(&Buffer[Offset], "USBSTOR\\");
|
||||||
Offset += sprintf(&Buffer[Offset], DeviceType);
|
Offset += sprintf(&Buffer[Offset], DeviceType);
|
||||||
Offset += sprintf(&Buffer[Offset], "&Ven_");
|
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 += sprintf(&Buffer[Offset], "&Prod_");
|
||||||
Offset += CopyField(InquiryData->Product, &Buffer[Offset], 16);
|
Offset += CopyField(InquiryData->ProductId, &Buffer[Offset], 16);
|
||||||
Offset += sprintf(&Buffer[Offset], "&Rev_");
|
Offset += sprintf(&Buffer[Offset], "&Rev_");
|
||||||
Offset += CopyField(InquiryData->Revision, &Buffer[Offset], 4);
|
Offset += CopyField(InquiryData->ProductRevisionLevel, &Buffer[Offset], 4);
|
||||||
|
|
||||||
RtlInitAnsiString(&AnsiString, (PCSZ)Buffer);
|
RtlInitAnsiString(&AnsiString, (PCSZ)Buffer);
|
||||||
|
|
||||||
// allocate DeviceId string
|
// allocate DeviceId string
|
||||||
DeviceId.Length = 0;
|
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);
|
DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength);
|
||||||
if (!DeviceId.Buffer)
|
if (!DeviceId.Buffer)
|
||||||
{
|
{
|
||||||
|
@ -289,12 +291,12 @@ USBSTOR_PdoHandleQueryHardwareId(
|
||||||
CHAR Id1[50], Id2[50], Id3[50], Id4[50], Id5[50], Id6[50];
|
CHAR Id1[50], Id2[50], Id3[50], Id4[50], Id5[50], Id6[50];
|
||||||
ULONG Id1Length, Id2Length, Id3Length, Id4Length, Id5Length,Id6Length;
|
ULONG Id1Length, Id2Length, Id3Length, Id4Length, Id5Length,Id6Length;
|
||||||
ULONG Offset, TotalLength, Length;
|
ULONG Offset, TotalLength, Length;
|
||||||
PUFI_INQUIRY_RESPONSE InquiryData;
|
PINQUIRYDATA InquiryData;
|
||||||
|
|
||||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
||||||
ASSERT(FDODeviceExtension->DeviceDescriptor);
|
ASSERT(FDODeviceExtension->DeviceDescriptor);
|
||||||
InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
|
InquiryData = PDODeviceExtension->InquiryData;
|
||||||
|
|
||||||
DeviceType = USBSTOR_GetDeviceType(InquiryData, PDODeviceExtension->IsFloppy);
|
DeviceType = USBSTOR_GetDeviceType(InquiryData, PDODeviceExtension->IsFloppy);
|
||||||
GenericType = USBSTOR_GetGenericType(InquiryData, PDODeviceExtension->IsFloppy);
|
GenericType = USBSTOR_GetGenericType(InquiryData, PDODeviceExtension->IsFloppy);
|
||||||
|
@ -302,47 +304,47 @@ USBSTOR_PdoHandleQueryHardwareId(
|
||||||
ASSERT(GenericType);
|
ASSERT(GenericType);
|
||||||
|
|
||||||
// generate id 1
|
// generate id 1
|
||||||
// USBSTOR\SCSIType_Vendor(8)_Product(16)_Revision(4)
|
// USBSTOR\SCSIType_VendorId(8)_ProductId(16)_Revision(4)
|
||||||
RtlZeroMemory(Id1, sizeof(Id1));
|
RtlZeroMemory(Id1, sizeof(Id1));
|
||||||
Offset = 0;
|
Offset = 0;
|
||||||
Offset = sprintf(&Id1[Offset], "USBSTOR\\");
|
Offset = sprintf(&Id1[Offset], "USBSTOR\\");
|
||||||
Offset += sprintf(&Id1[Offset], DeviceType);
|
Offset += sprintf(&Id1[Offset], DeviceType);
|
||||||
Offset += CopyField(InquiryData->Vendor, &Id1[Offset], 8);
|
Offset += CopyField(InquiryData->VendorId, &Id1[Offset], 8);
|
||||||
Offset += CopyField(InquiryData->Product, &Id1[Offset], 16);
|
Offset += CopyField(InquiryData->ProductId, &Id1[Offset], 16);
|
||||||
Offset += CopyField(InquiryData->Revision, &Id1[Offset], 4);
|
Offset += CopyField(InquiryData->ProductRevisionLevel, &Id1[Offset], 4);
|
||||||
Id1Length = strlen(Id1) + 1;
|
Id1Length = strlen(Id1) + 1;
|
||||||
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId1 %s\n", Id1);
|
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId1 %s\n", Id1);
|
||||||
|
|
||||||
// generate id 2
|
// generate id 2
|
||||||
// USBSTOR\SCSIType_VENDOR(8)_Product(16)
|
// USBSTOR\SCSIType_VendorId(8)_ProductId(16)
|
||||||
RtlZeroMemory(Id2, sizeof(Id2));
|
RtlZeroMemory(Id2, sizeof(Id2));
|
||||||
Offset = 0;
|
Offset = 0;
|
||||||
Offset = sprintf(&Id2[Offset], "USBSTOR\\");
|
Offset = sprintf(&Id2[Offset], "USBSTOR\\");
|
||||||
Offset += sprintf(&Id2[Offset], DeviceType);
|
Offset += sprintf(&Id2[Offset], DeviceType);
|
||||||
Offset += CopyField(InquiryData->Vendor, &Id2[Offset], 8);
|
Offset += CopyField(InquiryData->VendorId, &Id2[Offset], 8);
|
||||||
Offset += CopyField(InquiryData->Product, &Id2[Offset], 16);
|
Offset += CopyField(InquiryData->ProductId, &Id2[Offset], 16);
|
||||||
Id2Length = strlen(Id2) + 1;
|
Id2Length = strlen(Id2) + 1;
|
||||||
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId2 %s\n", Id2);
|
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId2 %s\n", Id2);
|
||||||
|
|
||||||
// generate id 3
|
// generate id 3
|
||||||
// USBSTOR\SCSIType_VENDOR(8)
|
// USBSTOR\SCSIType_VendorId(8)
|
||||||
RtlZeroMemory(Id3, sizeof(Id3));
|
RtlZeroMemory(Id3, sizeof(Id3));
|
||||||
Offset = 0;
|
Offset = 0;
|
||||||
Offset = sprintf(&Id3[Offset], "USBSTOR\\");
|
Offset = sprintf(&Id3[Offset], "USBSTOR\\");
|
||||||
Offset += sprintf(&Id3[Offset], DeviceType);
|
Offset += sprintf(&Id3[Offset], DeviceType);
|
||||||
Offset += CopyField(InquiryData->Vendor, &Id3[Offset], 8);
|
Offset += CopyField(InquiryData->VendorId, &Id3[Offset], 8);
|
||||||
Id3Length = strlen(Id3) + 1;
|
Id3Length = strlen(Id3) + 1;
|
||||||
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId3 %s\n", Id3);
|
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId3 %s\n", Id3);
|
||||||
|
|
||||||
// generate id 4
|
// generate id 4
|
||||||
// USBSTOR\SCSIType_VENDOR(8)_Product(16)_Revision(1)
|
// USBSTOR\SCSIType_VendorId(8)_ProductId(16)_Revision(1)
|
||||||
RtlZeroMemory(Id4, sizeof(Id4));
|
RtlZeroMemory(Id4, sizeof(Id4));
|
||||||
Offset = 0;
|
Offset = 0;
|
||||||
Offset = sprintf(&Id4[Offset], "USBSTOR\\");
|
Offset = sprintf(&Id4[Offset], "USBSTOR\\");
|
||||||
Offset += sprintf(&Id4[Offset], DeviceType);
|
Offset += sprintf(&Id4[Offset], DeviceType);
|
||||||
Offset += CopyField(InquiryData->Vendor, &Id4[Offset], 8);
|
Offset += CopyField(InquiryData->VendorId, &Id4[Offset], 8);
|
||||||
Offset += CopyField(InquiryData->Product, &Id4[Offset], 16);
|
Offset += CopyField(InquiryData->ProductId, &Id4[Offset], 16);
|
||||||
Offset += CopyField(InquiryData->Revision, &Id4[Offset], 1);
|
Offset += CopyField(InquiryData->ProductRevisionLevel, &Id4[Offset], 1);
|
||||||
Id4Length = strlen(Id4) + 1;
|
Id4Length = strlen(Id4) + 1;
|
||||||
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId4 %s\n", Id4);
|
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId4 %s\n", Id4);
|
||||||
|
|
||||||
|
@ -404,7 +406,7 @@ USBSTOR_PdoHandleQueryCompatibleId(
|
||||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
||||||
ASSERT(FDODeviceExtension->DeviceDescriptor);
|
ASSERT(FDODeviceExtension->DeviceDescriptor);
|
||||||
DeviceType = USBSTOR_GetDeviceType((PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy);
|
DeviceType = USBSTOR_GetDeviceType(PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy);
|
||||||
|
|
||||||
// format instance id
|
// format instance id
|
||||||
Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1;
|
Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1;
|
||||||
|
@ -645,201 +647,204 @@ USBSTOR_PdoHandlePnp(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
USBSTOR_CompletionRoutine(
|
USBSTOR_SyncCompletionRoutine(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PVOID Ctx)
|
IN PVOID Ctx)
|
||||||
{
|
{
|
||||||
PKEVENT Event = (PKEVENT)Ctx;
|
KeSetEvent((PKEVENT)Ctx, IO_NO_INCREMENT, FALSE);
|
||||||
|
|
||||||
KeSetEvent(Event, 0, FALSE);
|
|
||||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
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
|
NTSTATUS
|
||||||
USBSTOR_AllocateIrp(
|
USBSTOR_SendInternalCdb(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT PdoDevice,
|
||||||
IN ULONG DataTransferLength,
|
IN PCDB Cdb,
|
||||||
IN UCHAR OpCode,
|
IN UCHAR CdbLength,
|
||||||
IN PKEVENT Event,
|
IN ULONG TimeOutValue,
|
||||||
OUT PSCSI_REQUEST_BLOCK *OutRequest,
|
OUT PVOID OutDataBuffer,
|
||||||
OUT PIRP *OutIrp)
|
OUT PULONG OutDataTransferLength)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
PSCSI_REQUEST_BLOCK Srb;
|
||||||
|
PSENSE_DATA SenseBuffer;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PSCSI_REQUEST_BLOCK Request;
|
KEVENT Event;
|
||||||
PCDB pCDB;
|
PIRP Irp = NULL;
|
||||||
|
PMDL Mdl = NULL;
|
||||||
|
ULONG ix = 0;
|
||||||
|
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
UCHAR SrbStatus;
|
||||||
|
|
||||||
|
DPRINT("USBSTOR_SendInternalCdb SCSIOP %x\n", Cdb->CDB6GENERIC.OperationCode);
|
||||||
|
|
||||||
|
Srb = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
sizeof(SCSI_REQUEST_BLOCK),
|
||||||
|
USB_STOR_TAG);
|
||||||
|
|
||||||
|
if (Srb)
|
||||||
|
{
|
||||||
|
SenseBuffer = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
SENSE_BUFFER_SIZE,
|
||||||
|
USB_STOR_TAG);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
|
||||||
if (!Irp)
|
if (!Irp)
|
||||||
{
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IoStack = IoGetNextIrpStackLocation(Irp);
|
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->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
|
||||||
IoStack->Parameters.Others.Argument1 = Request;
|
IoStack->Parameters.Scsi.Srb = Srb;
|
||||||
IoStack->DeviceObject = DeviceObject;
|
|
||||||
|
|
||||||
KeInitializeEvent(Event, NotificationEvent, FALSE);
|
RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
|
||||||
|
|
||||||
IoSetCompletionRoutine(Irp, USBSTOR_CompletionRoutine, (PVOID)Event, TRUE, TRUE, TRUE);
|
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;
|
||||||
|
|
||||||
*OutIrp = Irp;
|
RtlCopyMemory(Srb->Cdb, Cdb, CdbLength);
|
||||||
*OutRequest = Request;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
Irp->MdlAddress = Mdl;
|
||||||
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;
|
|
||||||
|
|
||||||
Status = USBSTOR_AllocateIrp(PDODeviceObject, DataTransferLength, OpCode, &Event, &Request, &Irp);
|
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
|
IoSetCompletionRoutine(Irp,
|
||||||
|
USBSTOR_SyncCompletionRoutine,
|
||||||
|
&Event,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
if (IoCallDriver(PdoDevice, Irp) == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
DPRINT1("[USBSTOR] Failed to build irp\n");
|
KeWaitForSingleObject(&Event,
|
||||||
return Status;
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
|
SrbStatus = SRB_STATUS(Srb->SrbStatus);
|
||||||
|
|
||||||
ASSERT(Irp);
|
|
||||||
ASSERT(PDODeviceExtension->LowerDeviceObject);
|
|
||||||
Status = IoCallDriver(PDODeviceExtension->Self, Irp);
|
|
||||||
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = Irp->IoStatus.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
*OutData = Request->DataBuffer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ExFreePoolWithTag(Request->DataBuffer, USB_STOR_TAG);
|
|
||||||
*OutData = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExFreePoolWithTag(Request, USB_STOR_TAG);
|
|
||||||
IoFreeMdl(Irp->MdlAddress);
|
|
||||||
IoFreeIrp(Irp);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @name USBSTOR_FillInquiryData
|
||||||
|
*
|
||||||
|
* Sends a SCSI Inquiry request and fills in the PDODeviceExtension->InquiryData field with a result.
|
||||||
|
*/
|
||||||
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
USBSTOR_SendInquiryIrp(
|
USBSTOR_FillInquiryData(
|
||||||
IN PDEVICE_OBJECT PDODeviceObject)
|
IN PDEVICE_OBJECT PDODeviceObject)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||||
PUFI_INQUIRY_RESPONSE Response;
|
CDB Cdb;
|
||||||
|
ULONG DataTransferLength = INQUIRYDATABUFFERSIZE;
|
||||||
|
PINQUIRYDATA InquiryData;
|
||||||
|
|
||||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
|
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 (!InquiryData)
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
DPRINT1("USBSTOR_SendInquiryIrp Failed with %x\n", Status);
|
DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("Response %p\n", Response);
|
RtlZeroMemory(&Cdb, sizeof(Cdb));
|
||||||
DPRINT1("DeviceType %x\n", Response->DeviceType);
|
Cdb.CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
|
||||||
DPRINT1("RMB %x\n", Response->RMB);
|
Cdb.CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
|
||||||
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]);
|
Status = USBSTOR_SendInternalCdb(PDODeviceObject, &Cdb, CDB6GENERIC_LENGTH, 20, InquiryData, &DataTransferLength);
|
||||||
|
|
||||||
PDODeviceExtension->InquiryData = (PVOID)Response;
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
USBSTOR_SendFormatCapacityIrp(
|
|
||||||
IN PDEVICE_OBJECT PDODeviceObject)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
|
||||||
PUCHAR Response;
|
|
||||||
|
|
||||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
Status = USBSTOR_SendIrp(PDODeviceObject, 0xFC, SCSIOP_READ_FORMATTED_CAPACITY, (PVOID*)&Response);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status);
|
||||||
|
ExFreePoolWithTag(InquiryData, USB_STOR_TAG);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
PDODeviceExtension->IsFloppy = USBSTOR_IsFloppy(Response, 0xFC /*FIXME*/, &PDODeviceExtension->MediumTypeCode);
|
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]);
|
||||||
|
|
||||||
ExFreePoolWithTag(Response, USB_STOR_TAG);
|
DPRINT("Revision %c%c%c%c\n", InquiryData->ProductRevisionLevel[0], InquiryData->ProductRevisionLevel[1], InquiryData->ProductRevisionLevel[2], InquiryData->ProductRevisionLevel[3]);
|
||||||
|
|
||||||
|
PDODeviceExtension->InquiryData = InquiryData;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,7 +856,6 @@ USBSTOR_CreatePDO(
|
||||||
PDEVICE_OBJECT PDO;
|
PDEVICE_OBJECT PDO;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||||
PUFI_INQUIRY_RESPONSE Response;
|
|
||||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
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);
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("Failed to create PDO, status %x\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,7 +881,7 @@ USBSTOR_CreatePDO(
|
||||||
PDODeviceExtension->Self = PDO;
|
PDODeviceExtension->Self = PDO;
|
||||||
PDODeviceExtension->LUN = LUN;
|
PDODeviceExtension->LUN = LUN;
|
||||||
|
|
||||||
PDO->Flags |= DO_DIRECT_IO | DO_MAP_IO_BUFFER;
|
PDO->Flags |= DO_DIRECT_IO;
|
||||||
|
|
||||||
// device is initialized
|
// device is initialized
|
||||||
PDO->Flags &= ~DO_DEVICE_INITIALIZING;
|
PDO->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
@ -885,20 +890,21 @@ USBSTOR_CreatePDO(
|
||||||
FDODeviceExtension->ChildPDO[LUN] = PDO;
|
FDODeviceExtension->ChildPDO[LUN] = PDO;
|
||||||
|
|
||||||
// send inquiry command by irp
|
// send inquiry command by irp
|
||||||
Status = USBSTOR_SendInquiryIrp(PDO);
|
Status = USBSTOR_FillInquiryData(PDO);
|
||||||
ASSERT(Status == STATUS_SUCCESS);
|
|
||||||
|
|
||||||
Response = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
|
if (!NT_SUCCESS(Status))
|
||||||
ASSERT(Response);
|
|
||||||
|
|
||||||
if (Response->DeviceType == 0)
|
|
||||||
{
|
{
|
||||||
// check if it is a floppy
|
return Status;
|
||||||
Status = USBSTOR_SendFormatCapacityIrp(PDO);
|
}
|
||||||
DPRINT1("[USBSTOR] Status %x IsFloppy %x MediumTypeCode %x\n", Status, PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode);
|
|
||||||
|
|
||||||
// failing command is non critical
|
if (PDODeviceExtension->InquiryData->DeviceType == DIRECT_ACCESS_DEVICE)
|
||||||
Status = STATUS_SUCCESS;
|
{
|
||||||
|
PDODeviceExtension->IsFloppy = FALSE; // TODO: implement the actual check
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we work only with DIRECT_ACCESS_DEVICE for now
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -68,7 +68,7 @@ typedef struct
|
||||||
USBSTOR_COMMON_DEVICE_EXTENSION Common;
|
USBSTOR_COMMON_DEVICE_EXTENSION Common;
|
||||||
PDEVICE_OBJECT LowerDeviceObject; // points to FDO
|
PDEVICE_OBJECT LowerDeviceObject; // points to FDO
|
||||||
UCHAR LUN; // lun id
|
UCHAR LUN; // lun id
|
||||||
PVOID InquiryData; // USB SCSI inquiry data
|
PINQUIRYDATA InquiryData; // USB SCSI inquiry data
|
||||||
PUCHAR FormatData; // USB SCSI Read Format Capacity Data
|
PUCHAR FormatData; // USB SCSI Read Format Capacity Data
|
||||||
UCHAR Claimed; // indicating if it has been claimed by upper driver
|
UCHAR Claimed; // indicating if it has been claimed by upper driver
|
||||||
ULONG BlockLength; // length of block
|
ULONG BlockLength; // length of block
|
||||||
|
@ -117,42 +117,6 @@ typedef struct
|
||||||
UCHAR Status; // CSW status
|
UCHAR Status; // CSW status
|
||||||
}CSW, *PCSW;
|
}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
|
// UFI read cmd
|
||||||
|
|
Loading…
Reference in a new issue