[USBSTOR]

- Implement SCSI mode sense

svn path=/branches/usb-bringup/; revision=51609
This commit is contained in:
Johannes Anderwald 2011-05-06 17:23:19 +00:00
parent ff67bee091
commit 5573560a44
3 changed files with 176 additions and 2 deletions

View file

@ -20,6 +20,7 @@ USBSTOR_HandleExecuteSCSI(
{
PCDB pCDB;
NTSTATUS Status;
ULONG TransferredLength;
//
// get SCSI command data block
@ -73,6 +74,35 @@ USBSTOR_HandleExecuteSCSI(
Request->SrbStatus = SRB_STATUS_ERROR;
}
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE)
{
DPRINT1("SCSIOP_MODE_SENSE DataTransferLength %lu\n", Request->DataTransferLength);
ASSERT(pCDB->MODE_SENSE.AllocationLength == Request->DataTransferLength);
ASSERT(Request->DataBuffer);
//
// send mode sense command
//
Status = USBSTOR_SendModeSenseCmd(DeviceObject, Request, &TransferredLength);
DPRINT1("USBSTOR_SendModeSenseCmd Status %x BytesReturned %lu\n", Status, TransferredLength);
if (NT_SUCCESS(Status))
{
//
// store returned info length
//
Irp->IoStatus.Information = TransferredLength;
Request->SrbStatus = SRB_STATUS_SUCCESS;
}
else
{
//
// failed to retrieve capacity
//
Irp->IoStatus.Information = 0;
Request->SrbStatus = SRB_STATUS_ERROR;
}
}
else
{
UNIMPLEMENTED;

View file

@ -435,7 +435,7 @@ USBSTOR_SendCapacityCmd(
}
//
// initialize inquiry cmd
// initialize capacity cmd
//
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
Cmd.Code = SCSIOP_INQUIRY;
@ -443,7 +443,7 @@ USBSTOR_SendCapacityCmd(
Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
//
// now send inquiry cmd
// now send capacity cmd
//
Status = USBSTOR_SendCBW(DeviceObject, UFI_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_CAPACITY_RESPONSE), &OutControl);
if (!NT_SUCCESS(Status))
@ -523,3 +523,123 @@ USBSTOR_SendCapacityCmd(
return Status;
}
NTSTATUS
USBSTOR_SendModeSenseCmd(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PSCSI_REQUEST_BLOCK Request,
OUT PULONG TransferBufferLength)
{
UFI_SENSE_CMD Cmd;
CSW CSW;
NTSTATUS Status;
PVOID Response;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PCBW OutControl;
PCDB pCDB;
//
// get SCSI command data block
//
pCDB = (PCDB)Request->Cdb;
//
// get PDO device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// allocate sense response from non paged pool
//
Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, Request->DataTransferLength);
if (!Response)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// initialize mode sense cmd
//
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
Cmd.Code = SCSIOP_MODE_SENSE;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.PageCode = pCDB->MODE_SENSE.PageCode;
Cmd.PC = pCDB->MODE_SENSE.Pc;
Cmd.AllocationLength = pCDB->MODE_SENSE.AllocationLength;
//
// now send mode sense cmd
//
Status = USBSTOR_SendCBW(DeviceObject, UFI_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, &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 data block response
//
Status = USBSTOR_SendData(DeviceObject, Request->DataTransferLength, 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;
}
//
// 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);
ASSERT(CSW.DataResidue == 0);
//
// calculate transfer length
//
*TransferBufferLength = Request->DataTransferLength - CSW.DataResidue;
//
// copy buffer
//
RtlCopyMemory(Request->DataBuffer, Response, *TransferBufferLength);
//
// free item
//
FreeItem(OutControl);
//
// free response
//
FreeItem(Response);
//
// done
//
return Status;
}

View file

@ -149,6 +149,22 @@ typedef struct
ULONG BlockLength; // block length in bytes
}UFI_CAPACITY_RESPONSE, *PUFI_CAPACITY_RESPONSE;
//--------------------------------------------------------------------------------------------------------------------------------------------
//
// UFI sense mode cmd
//
typedef struct
{
UCHAR Code; // operation code
UCHAR LUN; // lun address
UCHAR PageCode:6; // page code selector
UCHAR PC:2; // type of parameters to be returned
UCHAR Reserved[4]; // reserved 0x00
USHORT AllocationLength; // parameters length
UCHAR Reserved1[3];
}UFI_SENSE_CMD, *PUFI_SENSE_CMD;
C_ASSERT(sizeof(UFI_CAPACITY_CMD) == 12);
//---------------------------------------------------------------------
//
@ -248,6 +264,12 @@ USBSTOR_SendCapacityCmd(
OUT PREAD_CAPACITY_DATA_EX CapacityDataEx,
OUT PREAD_CAPACITY_DATA CapacityData);
NTSTATUS
USBSTOR_SendModeSenseCmd(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PSCSI_REQUEST_BLOCK Request,
OUT PULONG TransferBufferLength);
//---------------------------------------------------------------------
//
// disk.c routines
@ -261,3 +283,5 @@ NTSTATUS
USBSTOR_HandleDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);