mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-31 19:26:42 +00:00
[USBSTOR]
- Implement retrieving drive capacity - Use constant from scsi.h instead of defining own format - Don't reset returned parameters length to zero, as ioctl handler might set it svn path=/branches/usb-bringup/; revision=51608
This commit is contained in:
+106
-18
@@ -18,12 +18,70 @@ USBSTOR_HandleExecuteSCSI(
|
||||
IN OUT PSCSI_REQUEST_BLOCK Request,
|
||||
IN PPDO_DEVICE_EXTENSION PDODeviceExtension)
|
||||
{
|
||||
DPRINT1("USBSTOR_HandleExecuteSCSI\n");
|
||||
PCDB pCDB;
|
||||
NTSTATUS Status;
|
||||
|
||||
DbgBreakPoint();
|
||||
//
|
||||
// get SCSI command data block
|
||||
//
|
||||
pCDB = (PCDB)Request->Cdb;
|
||||
|
||||
Request->SrbStatus = SRB_STATUS_ERROR;
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
DPRINT1("USBSTOR_HandleExecuteSCSI Operation Code %x\n", pCDB->AsByte[0]);
|
||||
|
||||
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
|
||||
{
|
||||
//
|
||||
// sanity checks
|
||||
//
|
||||
ASSERT(Request->DataBuffer);
|
||||
|
||||
if (Request->DataTransferLength == sizeof(READ_CAPACITY_DATA_EX))
|
||||
{
|
||||
//
|
||||
// retrieve capacity extended structure
|
||||
//
|
||||
Status = USBSTOR_SendCapacityCmd(DeviceObject, (PREAD_CAPACITY_DATA_EX)Request->DataBuffer, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(Request->DataTransferLength == sizeof(READ_CAPACITY_DATA));
|
||||
|
||||
//
|
||||
// retrieve capacity
|
||||
//
|
||||
Status = USBSTOR_SendCapacityCmd(DeviceObject, NULL, (PREAD_CAPACITY_DATA)Request->DataBuffer);
|
||||
}
|
||||
DPRINT1("USBSTOR_SendCapacityCmd %x\n", Status);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// store returned info length
|
||||
//
|
||||
Irp->IoStatus.Information = Request->DataTransferLength;
|
||||
Request->SrbStatus = SRB_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// failed to retrieve capacity
|
||||
//
|
||||
Irp->IoStatus.Information = 0;
|
||||
Request->SrbStatus = SRB_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
Request->SrbStatus = SRB_STATUS_ERROR;
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
DbgBreakPoint();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
@@ -63,7 +121,7 @@ USBSTOR_HandleInternalDeviceControl(
|
||||
{
|
||||
DPRINT1("SRB_FUNCTION_EXECUTE_SCSI\n");
|
||||
Status = USBSTOR_HandleExecuteSCSI(DeviceObject, Irp, Request, PDODeviceExtension);
|
||||
|
||||
break;
|
||||
}
|
||||
case SRB_FUNCTION_RELEASE_DEVICE:
|
||||
{
|
||||
@@ -411,14 +469,13 @@ USBSTOR_HandleQueryProperty(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_HandleDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
|
||||
//
|
||||
// get current stack location
|
||||
@@ -430,17 +487,48 @@ USBSTOR_HandleDeviceControl(
|
||||
//
|
||||
// query property
|
||||
//
|
||||
return USBSTOR_HandleQueryProperty(DeviceObject, Irp);
|
||||
Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS)
|
||||
{
|
||||
//
|
||||
// query get scsi address
|
||||
//
|
||||
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_GET_ADDRESS NOT implemented\n");
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH)
|
||||
{
|
||||
//
|
||||
// query scsi pass through
|
||||
//
|
||||
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT)
|
||||
{
|
||||
//
|
||||
// query scsi pass through direct
|
||||
//
|
||||
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER)
|
||||
{
|
||||
//
|
||||
// query serial number
|
||||
//
|
||||
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// unsupported
|
||||
//
|
||||
DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
DPRINT1("USBSTOR_HandleDeviceControl IoControl %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
|
||||
DPRINT1("USBSTOR_HandleDeviceControl InputBufferLength %x\n", IoStack->Parameters.DeviceIoControl.InputBufferLength);
|
||||
DPRINT1("USBSTOR_HandleDeviceControl OutputBufferLength %x\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
|
||||
DPRINT1("USBSTOR_HandleDeviceControl InputBuffer %x\n", IoStack->Parameters.DeviceIoControl.Type3InputBuffer);
|
||||
DPRINT1("USBSTOR_HandleDeviceControl SystemBuffer %x\n", Irp->AssociatedIrp.SystemBuffer);
|
||||
DPRINT1("USBSTOR_HandleDeviceControl UserBuffer %x\n", Irp->UserBuffer);
|
||||
DPRINT1("USBSTOR_HandleDeviceControl MdlAddress %x\n", Irp->MdlAddress);
|
||||
|
||||
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return Status;
|
||||
}
|
||||
|
||||
+121
-2
@@ -300,7 +300,6 @@ USBSTOR_SendInquiryCmd(
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PCBW OutControl;
|
||||
|
||||
|
||||
//
|
||||
// get PDO device extension
|
||||
//
|
||||
@@ -322,7 +321,7 @@ USBSTOR_SendInquiryCmd(
|
||||
// initialize inquiry cmd
|
||||
//
|
||||
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
|
||||
Cmd.Code = UFI_INQURIY_CODE;
|
||||
Cmd.Code = SCSIOP_INQUIRY;
|
||||
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
|
||||
Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
|
||||
|
||||
@@ -404,3 +403,123 @@ USBSTOR_SendInquiryCmd(
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_SendCapacityCmd(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PREAD_CAPACITY_DATA_EX CapacityDataEx,
|
||||
OUT PREAD_CAPACITY_DATA CapacityData)
|
||||
{
|
||||
UFI_INQUIRY_CMD Cmd;
|
||||
CSW CSW;
|
||||
NTSTATUS Status;
|
||||
PUFI_CAPACITY_RESPONSE Response;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PCBW OutControl;
|
||||
|
||||
//
|
||||
// get PDO device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// allocate capacity response
|
||||
//
|
||||
Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, sizeof(UFI_CAPACITY_RESPONSE));
|
||||
if (!Response)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize inquiry cmd
|
||||
//
|
||||
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
|
||||
Cmd.Code = SCSIOP_INQUIRY;
|
||||
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
|
||||
Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
|
||||
|
||||
//
|
||||
// now send inquiry cmd
|
||||
//
|
||||
Status = USBSTOR_SendCBW(DeviceObject, UFI_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_CAPACITY_RESPONSE), &OutControl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to send CBW
|
||||
//
|
||||
DPRINT1("USBSTOR_SendCapacityCmd> USBSTOR_SendCBW failed with %x\n", Status);
|
||||
FreeItem(Response);
|
||||
ASSERT(FALSE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// now send inquiry response
|
||||
//
|
||||
Status = USBSTOR_SendData(DeviceObject, sizeof(UFI_CAPACITY_RESPONSE), Response);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to send CBW
|
||||
//
|
||||
DPRINT1("USBSTOR_SendCapacityCmd> USBSTOR_SendData failed with %x\n", Status);
|
||||
FreeItem(Response);
|
||||
ASSERT(FALSE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DPRINT1("LastLogicalBlockAddress %lu\n", Response->LastLogicalBlockAddress);
|
||||
DPRINT1("BlockLength %lu\n", Response->BlockLength);
|
||||
DPRINT1("Medium Length %lu\n", Response->BlockLength * Response->LastLogicalBlockAddress);
|
||||
|
||||
//
|
||||
// store response
|
||||
//
|
||||
if (CapacityDataEx)
|
||||
{
|
||||
CapacityDataEx->LogicalBlockAddress.QuadPart = Response->LastLogicalBlockAddress;
|
||||
CapacityDataEx->BytesPerBlock = Response->BlockLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
CapacityData->LogicalBlockAddress = Response->LastLogicalBlockAddress;
|
||||
CapacityData->BytesPerBlock = Response->BlockLength;
|
||||
}
|
||||
|
||||
//
|
||||
// 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);
|
||||
|
||||
//
|
||||
// FIXME: handle error
|
||||
//
|
||||
ASSERT(CSW.Status == 0);
|
||||
|
||||
//
|
||||
// free item
|
||||
//
|
||||
FreeItem(OutControl);
|
||||
|
||||
//
|
||||
// free response
|
||||
//
|
||||
FreeItem(Response);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,9 +141,16 @@ USBSTOR_DispatchDeviceControl(
|
||||
//
|
||||
Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
//
|
||||
// complete request
|
||||
//
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +167,6 @@ USBSTOR_DispatchScsi(
|
||||
//
|
||||
Status = USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <stdio.h>
|
||||
#include <wdmguid.h>
|
||||
#include <classpnp.h>
|
||||
#include <scsi.h>
|
||||
|
||||
#define USB_STOR_TAG 'sbsu'
|
||||
#define USB_MAXCHILDREN (16)
|
||||
@@ -101,7 +102,6 @@ typedef struct
|
||||
|
||||
C_ASSERT(sizeof(UFI_INQUIRY_CMD) == 12);
|
||||
|
||||
#define UFI_INQURIY_CODE 0x12
|
||||
#define UFI_INQUIRY_CMD_LEN 0x6
|
||||
|
||||
//
|
||||
@@ -122,6 +122,34 @@ typedef struct
|
||||
|
||||
C_ASSERT(sizeof(UFI_INQUIRY_RESPONSE) == 36);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// UFI read capacity cmd
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
UCHAR Code; // operation code 0x25
|
||||
UCHAR LUN; // lun address
|
||||
UCHAR LBA[4]; // logical block address, should be zero
|
||||
UCHAR Reserved1[2]; // reserved 0x00
|
||||
UCHAR PMI; // PMI = 0x00
|
||||
UCHAR Reserved2[3]; // reserved 0x00
|
||||
}UFI_CAPACITY_CMD, *PUFI_CAPACITY_CMD;
|
||||
|
||||
C_ASSERT(sizeof(UFI_CAPACITY_CMD) == 12);
|
||||
|
||||
#define UFI_CAPACITY_CMD_LEN 0xA //FIXME support length 16 too if requested
|
||||
|
||||
//
|
||||
// UFI Read Capcacity command response
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
ULONG LastLogicalBlockAddress; // last logical block address
|
||||
ULONG BlockLength; // block length in bytes
|
||||
}UFI_CAPACITY_RESPONSE, *PUFI_CAPACITY_RESPONSE;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// fdo.c routines
|
||||
@@ -214,6 +242,11 @@ NTSTATUS
|
||||
USBSTOR_SendInquiryCmd(
|
||||
IN PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_SendCapacityCmd(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PREAD_CAPACITY_DATA_EX CapacityDataEx,
|
||||
OUT PREAD_CAPACITY_DATA CapacityData);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user