mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[USBSTOR]
- Implement retrieving string device type from SCSI device type - Handle BusQueryDeviceId - Implement support routines for sending CBW / CSW / Data - Implement retrieving device type (SCSI inquiry request) - WIP svn path=/branches/usb-bringup/; revision=51567
This commit is contained in:
parent
991d02daa5
commit
7821a805ef
5 changed files with 714 additions and 5 deletions
|
@ -3,7 +3,7 @@ add_definitions(-DDEBUG_MODE)
|
|||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
||||
|
||||
add_library(usbstor SHARED descriptor.c fdo.c misc.c pdo.c usbstor.c usbstor.rc)
|
||||
add_library(usbstor SHARED descriptor.c fdo.c misc.c pdo.c scsi.c usbstor.c usbstor.rc)
|
||||
|
||||
set_module_type(usbstor kernelmodedriver)
|
||||
add_importlibs(usbstor ntoskrnl hal usbd)
|
||||
|
|
|
@ -11,6 +11,221 @@
|
|||
|
||||
#include "usbstor.h"
|
||||
|
||||
LPCSTR
|
||||
USBSTOR_GetDeviceType(
|
||||
IN PUFI_INQUIRY_RESPONSE InquiryData)
|
||||
{
|
||||
//
|
||||
// check if device type is zero
|
||||
//
|
||||
if (InquiryData->DeviceType == 0)
|
||||
{
|
||||
//
|
||||
// direct access device
|
||||
//
|
||||
|
||||
//
|
||||
// FIXME: check if floppy
|
||||
//
|
||||
return "Disk";
|
||||
}
|
||||
|
||||
//
|
||||
// FIXME: use constant - derrived from http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type
|
||||
//
|
||||
switch (InquiryData->DeviceType)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
//
|
||||
// sequential device, i.e magnetic tape
|
||||
//
|
||||
return "Sequential";
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
//
|
||||
// write once device
|
||||
//
|
||||
return "Worm";
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
//
|
||||
// CDROM device
|
||||
//
|
||||
return "CdRom";
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
//
|
||||
// optical memory device
|
||||
//
|
||||
return "Optical";
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
//
|
||||
// medium change device
|
||||
//
|
||||
return "Changer";
|
||||
}
|
||||
default:
|
||||
{
|
||||
//
|
||||
// other device
|
||||
//
|
||||
return "CdRom";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ULONG
|
||||
CopyField(
|
||||
IN PUCHAR Name,
|
||||
IN PUCHAR Buffer,
|
||||
IN ULONG MaxLength)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
for(Index = 0; Index < MaxLength; Index++)
|
||||
{
|
||||
if (Name[Index] == '\0')
|
||||
return Index;
|
||||
|
||||
Buffer[Index] = Name[Index];
|
||||
}
|
||||
|
||||
return MaxLength;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_PdoHandleQueryDeviceId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
UCHAR Buffer[100];
|
||||
LPCSTR DeviceType;
|
||||
ULONG Offset = 0, Index;
|
||||
PUFI_INQUIRY_RESPONSE InquiryData;
|
||||
ANSI_STRING AnsiString;
|
||||
UNICODE_STRING DeviceId;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(DeviceExtension->InquiryData);
|
||||
|
||||
//
|
||||
// get inquiry data
|
||||
//
|
||||
InquiryData = (PUFI_INQUIRY_RESPONSE)DeviceExtension->InquiryData;
|
||||
|
||||
//
|
||||
// get device type
|
||||
//
|
||||
DeviceType = USBSTOR_GetDeviceType(InquiryData);
|
||||
|
||||
//
|
||||
// lets create device string
|
||||
//
|
||||
Offset = sprintf(&Buffer[Offset], "USBSTOR\\%s&Ven_", DeviceType);
|
||||
|
||||
//
|
||||
// copy vendor id
|
||||
//
|
||||
Offset += CopyField(InquiryData->Vendor, &Buffer[Offset], 8);
|
||||
|
||||
//
|
||||
// copy product string
|
||||
//
|
||||
Offset += sprintf(&Buffer[Offset], "&Prod_");
|
||||
|
||||
//
|
||||
// copy product identifier
|
||||
//
|
||||
Offset += CopyField(InquiryData->Product, &Buffer[Offset], 16);
|
||||
|
||||
//
|
||||
// copy revision string
|
||||
//
|
||||
Offset += sprintf(&Buffer[Offset], "&Rev_");
|
||||
|
||||
//
|
||||
// copy revision identifer
|
||||
//
|
||||
Offset += CopyField(InquiryData->Revision, &Buffer[Offset], 4);
|
||||
|
||||
//
|
||||
// FIXME: device serial number
|
||||
//
|
||||
Offset +=sprintf(&Buffer[Offset], "\\00000000&%d", DeviceExtension->LUN);
|
||||
|
||||
//
|
||||
// now convert restricted characters to underscores
|
||||
//
|
||||
for(Index = 0; Index < Offset; Index++)
|
||||
{
|
||||
if (Buffer[Index] <= ' ' || Buffer[Index] >= 0x7F /* last printable ascii character */ || Buffer[Index] == ',')
|
||||
{
|
||||
//
|
||||
// convert to underscore
|
||||
//
|
||||
Buffer[Index] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// now initialize ansi string
|
||||
//
|
||||
RtlInitAnsiString(&AnsiString, (PCSZ)Buffer);
|
||||
|
||||
//
|
||||
// allocate DeviceId string
|
||||
//
|
||||
DeviceId.Length = 0;
|
||||
DeviceId.MaximumLength = (Offset + 2) * sizeof(WCHAR);
|
||||
DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength);
|
||||
if (!DeviceId.Buffer)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// convert to unicode
|
||||
//
|
||||
Status = RtlAnsiStringToUnicodeString(&DeviceId, &AnsiString, FALSE);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceId.Buffer;
|
||||
}
|
||||
|
||||
DPRINT1("DeviceId %wZ\n", &DeviceId);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_PdoHandleDeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -102,9 +317,20 @@ USBSTOR_PdoHandlePnp(
|
|||
Status = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
case IRP_MN_QUERY_ID:
|
||||
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID unimplemented\n");
|
||||
{
|
||||
if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
|
||||
{
|
||||
//
|
||||
// handle query device id
|
||||
//
|
||||
Status = USBSTOR_PdoHandleQueryDeviceId(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_REMOVE_DEVICE unimplemented\n");
|
||||
Status = STATUS_SUCCESS;
|
||||
|
@ -209,6 +435,8 @@ USBSTOR_CreatePDO(
|
|||
//
|
||||
*ChildDeviceObject = PDO;
|
||||
|
||||
USBSTOR_SendInquiryCmd(PDO);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
|
|
406
drivers/usb/usbstor/scsi.c
Normal file
406
drivers/usb/usbstor/scsi.c
Normal file
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbstor/pdo.c
|
||||
* PURPOSE: USB block storage device driver.
|
||||
* PROGRAMMERS:
|
||||
* James Tabor
|
||||
* Michael Martin (michael.martin@reactos.org)
|
||||
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "usbstor.h"
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_BuildCBW(
|
||||
IN ULONG Tag,
|
||||
IN ULONG DataTransferLength,
|
||||
IN UCHAR LUN,
|
||||
IN UCHAR CommandBlockLength,
|
||||
IN PUCHAR CommandBlock,
|
||||
IN OUT PCBW Control)
|
||||
{
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(CommandBlockLength <= 16);
|
||||
|
||||
//
|
||||
// now initialize CBW
|
||||
//
|
||||
Control->Signature = CBW_SIGNATURE;
|
||||
Control->Tag = Tag;
|
||||
Control->DataTransferLength = DataTransferLength;
|
||||
Control->Flags = 0x80;
|
||||
Control->LUN = (LUN & MAX_LUN);
|
||||
Control->CommandBlockLength = CommandBlockLength;
|
||||
|
||||
//
|
||||
// copy command block
|
||||
//
|
||||
RtlCopyMemory(Control->CommandBlock, CommandBlock, CommandBlockLength);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_SendCBW(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN UCHAR CommandBlockLength,
|
||||
IN PUCHAR CommandBlock,
|
||||
IN ULONG DataTransferLength,
|
||||
OUT PCBW *OutControl)
|
||||
{
|
||||
PCBW Control;
|
||||
NTSTATUS Status;
|
||||
PURB Urb;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
|
||||
//
|
||||
// get PDO device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// get FDO device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// first allocate CBW
|
||||
//
|
||||
Control = (PCBW)AllocateItem(NonPagedPool, 512);
|
||||
if (!Control)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// first allocate CBW
|
||||
//
|
||||
Status = USBSTOR_BuildCBW(0xDEADDEAD, DataTransferLength, PDODeviceExtension->LUN, CommandBlockLength, CommandBlock, Control);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to build CBW
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// now build the urb
|
||||
//
|
||||
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(URB));
|
||||
if (!Urb)
|
||||
{
|
||||
//
|
||||
// failed to allocate urb
|
||||
//
|
||||
FreeItem(Control);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// now initialize the urb
|
||||
//
|
||||
Urb->UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
|
||||
Urb->UrbBulkOrInterruptTransfer.Hdr.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
|
||||
Urb->UrbBulkOrInterruptTransfer.PipeHandle = FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle;
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferBuffer = (PVOID)Control;
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = sizeof(CBW);
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK;
|
||||
|
||||
//
|
||||
// now send urb
|
||||
//
|
||||
Status = USBSTOR_SyncUrbRequest(FDODeviceExtension->LowerDeviceObject, Urb);
|
||||
|
||||
//
|
||||
// free urb
|
||||
//
|
||||
FreeItem(Urb);
|
||||
|
||||
//
|
||||
// store cbw
|
||||
//
|
||||
*OutControl = Control;
|
||||
|
||||
//
|
||||
// return operation status
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_SendData(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG DataTransferLength,
|
||||
IN PVOID DataTransfer)
|
||||
{
|
||||
PMDL TransferBufferMDL;
|
||||
PURB Urb;
|
||||
NTSTATUS Status;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
|
||||
//
|
||||
// get PDO device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// get FDO device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// allocate mdl for buffer, buffer must be allocated from NonPagedPool
|
||||
//
|
||||
TransferBufferMDL = IoAllocateMdl(DataTransfer, DataTransferLength, FALSE, FALSE, NULL);
|
||||
if (!TransferBufferMDL)
|
||||
{
|
||||
//
|
||||
// failed to allocate MDL
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// build mdl for nonpaged pool
|
||||
//
|
||||
MmBuildMdlForNonPagedPool(TransferBufferMDL);
|
||||
|
||||
//
|
||||
// now build the urb
|
||||
//
|
||||
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(URB));
|
||||
if (!Urb)
|
||||
{
|
||||
//
|
||||
// failed to allocate urb
|
||||
//
|
||||
IoFreeMdl(TransferBufferMDL);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// now initialize the urb
|
||||
//
|
||||
Urb->UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
|
||||
Urb->UrbBulkOrInterruptTransfer.Hdr.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
|
||||
Urb->UrbBulkOrInterruptTransfer.PipeHandle = FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle;
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL = TransferBufferMDL;
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = DataTransferLength;
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
|
||||
|
||||
//
|
||||
// now send urb
|
||||
//
|
||||
Status = USBSTOR_SyncUrbRequest(FDODeviceExtension->LowerDeviceObject, Urb);
|
||||
|
||||
//
|
||||
// free urb
|
||||
//
|
||||
FreeItem(Urb);
|
||||
|
||||
//
|
||||
// free mdl
|
||||
//
|
||||
IoFreeMdl(TransferBufferMDL);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_SendCSW(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID Data,
|
||||
IN ULONG DataLength,
|
||||
OUT PCSW OutCSW)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
PURB Urb;
|
||||
|
||||
//
|
||||
// get PDO device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// get FDO device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// now build the urb
|
||||
//
|
||||
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(URB));
|
||||
if (!Urb)
|
||||
{
|
||||
//
|
||||
// failed to allocate urb
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// now initialize the urb
|
||||
//
|
||||
Urb->UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
|
||||
Urb->UrbBulkOrInterruptTransfer.Hdr.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
|
||||
Urb->UrbBulkOrInterruptTransfer.PipeHandle = FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle;
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferBuffer = Data;
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = DataLength;
|
||||
Urb->UrbBulkOrInterruptTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
|
||||
|
||||
//
|
||||
// now send urb
|
||||
//
|
||||
Status = USBSTOR_SyncUrbRequest(FDODeviceExtension->LowerDeviceObject, Urb);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// copy csw status
|
||||
//
|
||||
RtlCopyMemory(OutCSW, Data, sizeof(CSW));
|
||||
}
|
||||
|
||||
//
|
||||
// free urb
|
||||
//
|
||||
FreeItem(Urb);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_SendInquiryCmd(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
UFI_INQUIRY_CMD Cmd;
|
||||
CSW CSW;
|
||||
NTSTATUS Status;
|
||||
PUFI_INQUIRY_RESPONSE Response;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PCBW OutControl;
|
||||
|
||||
|
||||
//
|
||||
// get PDO device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// allocate inquiry response
|
||||
//
|
||||
Response = (PUFI_INQUIRY_RESPONSE)AllocateItem(NonPagedPool, sizeof(UFI_INQUIRY_RESPONSE));
|
||||
if (!Response)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize inquiry cmd
|
||||
//
|
||||
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
|
||||
Cmd.Code = UFI_INQURIY_CODE;
|
||||
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
|
||||
Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
|
||||
|
||||
//
|
||||
// now send inquiry cmd
|
||||
//
|
||||
Status = USBSTOR_SendCBW(DeviceObject, UFI_INQUIRY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_INQUIRY_RESPONSE), &OutControl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to send CBW
|
||||
//
|
||||
DPRINT1("USBSTOR_SendInquiryCmd> USBSTOR_SendCBW failed with %x\n", Status);
|
||||
FreeItem(Response);
|
||||
ASSERT(FALSE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// now send inquiry response
|
||||
//
|
||||
Status = USBSTOR_SendData(DeviceObject, sizeof(UFI_INQUIRY_RESPONSE), Response);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to send CBW
|
||||
//
|
||||
DPRINT1("USBSTOR_SendInquiryCmd> USBSTOR_SendData failed with %x\n", Status);
|
||||
FreeItem(Response);
|
||||
ASSERT(FALSE);
|
||||
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 %x\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]);
|
||||
|
||||
//
|
||||
// send csw
|
||||
//
|
||||
Status = USBSTOR_SendCSW(DeviceObject, OutControl, 512, &CSW);
|
||||
|
||||
DPRINT1("------------------------\n");
|
||||
DPRINT1("CSW %p\n", &CSW);
|
||||
DPRINT1("Signature %x\n", CSW.Signature);
|
||||
DPRINT1("Tag %x\n", CSW.Tag);
|
||||
DPRINT1("DataResidue %x\n", CSW.DataResidue);
|
||||
DPRINT1("Status %x\n", CSW.Status);
|
||||
|
||||
//
|
||||
// free item
|
||||
//
|
||||
FreeItem(OutControl);
|
||||
|
||||
//
|
||||
// store inquiry data
|
||||
//
|
||||
PDODeviceExtension->InquiryData = (PVOID)Response;
|
||||
|
||||
//
|
||||
// FIXME: handle error
|
||||
//
|
||||
ASSERT(CSW.Status == 0);
|
||||
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
|
@ -239,9 +239,9 @@ DriverEntry(
|
|||
DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
|
||||
|
||||
//
|
||||
// driver start i/o routine
|
||||
// FIXME: driver start i/o routine
|
||||
//
|
||||
DriverObject->DriverStartIo = USBSTOR_StartIo;
|
||||
//DriverObject->DriverStartIo = USBSTOR_StartIo;
|
||||
|
||||
|
||||
//
|
||||
|
|
|
@ -52,7 +52,8 @@ typedef struct
|
|||
{
|
||||
COMMON_DEVICE_EXTENSION Common;
|
||||
PDEVICE_OBJECT LowerDeviceObject; // points to FDO
|
||||
|
||||
UCHAR LUN; // lun id
|
||||
PVOID InquiryData; // USB SCSI inquiry data
|
||||
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
|
@ -61,6 +62,66 @@ typedef struct
|
|||
//
|
||||
#define USB_BULK_GET_MAX_LUN 0xFE
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG Signature; // CBW signature
|
||||
ULONG Tag; // CBW Tag of operation
|
||||
ULONG DataTransferLength; // data transfer length
|
||||
UCHAR Flags; // CBW Flags endpoint direction
|
||||
UCHAR LUN; // lun unit
|
||||
UCHAR CommandBlockLength; // Command block length
|
||||
UCHAR CommandBlock[16];
|
||||
}CBW, *PCBW;
|
||||
|
||||
#define CBW_SIGNATURE 0x43425355
|
||||
#define MAX_LUN 0xF
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG Signature; // CSW signature
|
||||
ULONG Tag; // CSW tag
|
||||
ULONG DataResidue; // CSW data transfer diff
|
||||
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_INQURIY_CODE 0x12
|
||||
#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
|
||||
USHORT Reserved; // 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);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// fdo.c routines
|
||||
|
@ -119,6 +180,13 @@ USBSTOR_GetMaxLUN(
|
|||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PFDO_DEVICE_EXTENSION DeviceExtension);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
USBSTOR_SyncForwardIrpCompletionRoutine(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp,
|
||||
PVOID Context);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
|
@ -138,3 +206,10 @@ NTSTATUS
|
|||
USBSTOR_GetPipeHandles(
|
||||
IN PFDO_DEVICE_EXTENSION DeviceExtension);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// scsi.c routines
|
||||
//
|
||||
NTSTATUS
|
||||
USBSTOR_SendInquiryCmd(
|
||||
IN PDEVICE_OBJECT DeviceObject);
|
||||
|
|
Loading…
Reference in a new issue