[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:
Johannes Anderwald
2011-05-06 16:25:01 +00:00
parent 5c9e645604
commit ff67bee091
4 changed files with 269 additions and 23 deletions
+106 -18
View File
@@ -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
View File
@@ -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;
}
+8 -2
View File
@@ -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;
+34 -1
View File
@@ -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);
//---------------------------------------------------------------------
//