Author: janderwald Date: Fri May 6 16:25:01 2011 New Revision: 51608
URL: http://svn.reactos.org/svn/reactos?rev=51608&view=rev Log: [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
Modified: branches/usb-bringup/drivers/usb/usbstor/disk.c branches/usb-bringup/drivers/usb/usbstor/scsi.c branches/usb-bringup/drivers/usb/usbstor/usbstor.c branches/usb-bringup/drivers/usb/usbstor/usbstor.h
Modified: branches/usb-bringup/drivers/usb/usbstor/disk.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/... ============================================================================== --- branches/usb-bringup/drivers/usb/usbstor/disk.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbstor/disk.c [iso-8859-1] Fri May 6 16:25:01 2011 @@ -18,12 +18,70 @@ IN OUT PSCSI_REQUEST_BLOCK Request, IN PPDO_DEVICE_EXTENSION PDODeviceExtension) { - DPRINT1("USBSTOR_HandleExecuteSCSI\n"); - - DbgBreakPoint(); - - Request->SrbStatus = SRB_STATUS_ERROR; - return STATUS_NOT_SUPPORTED; + PCDB pCDB; + NTSTATUS Status; + + // + // get SCSI command data block + // + pCDB = (PCDB)Request->Cdb; + + 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 @@ { DPRINT1("SRB_FUNCTION_EXECUTE_SCSI\n"); Status = USBSTOR_HandleExecuteSCSI(DeviceObject, Irp, Request, PDODeviceExtension); - + break; } case SRB_FUNCTION_RELEASE_DEVICE: { @@ -411,14 +469,13 @@ } }
- - NTSTATUS USBSTOR_HandleDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IoStack; + NTSTATUS Status;
// // get current stack location @@ -430,17 +487,48 @@ // // query property // - return USBSTOR_HandleQueryProperty(DeviceObject, Irp); - } - - 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; + 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; + } + + return Status; }
Modified: branches/usb-bringup/drivers/usb/usbstor/scsi.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/... ============================================================================== --- branches/usb-bringup/drivers/usb/usbstor/scsi.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbstor/scsi.c [iso-8859-1] Fri May 6 16:25:01 2011 @@ -300,7 +300,6 @@ PPDO_DEVICE_EXTENSION PDODeviceExtension; PCBW OutControl;
- // // get PDO device extension // @@ -322,7 +321,7 @@ // 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 @@ // 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; +} +
Modified: branches/usb-bringup/drivers/usb/usbstor/usbstor.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/... ============================================================================== --- branches/usb-bringup/drivers/usb/usbstor/usbstor.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbstor/usbstor.c [iso-8859-1] Fri May 6 16:25:01 2011 @@ -141,9 +141,16 @@ // 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 @@ // Status = USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
- Irp->IoStatus.Information = 0; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status;
Modified: branches/usb-bringup/drivers/usb/usbstor/usbstor.h URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/... ============================================================================== --- branches/usb-bringup/drivers/usb/usbstor/usbstor.h [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbstor/usbstor.h [iso-8859-1] Fri May 6 16:25:01 2011 @@ -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 @@
C_ASSERT(sizeof(UFI_INQUIRY_CMD) == 12);
-#define UFI_INQURIY_CODE 0x12 #define UFI_INQUIRY_CMD_LEN 0x6
// @@ -122,6 +122,34 @@
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 @@ USBSTOR_SendInquiryCmd( IN PDEVICE_OBJECT DeviceObject);
+NTSTATUS +USBSTOR_SendCapacityCmd( + IN PDEVICE_OBJECT DeviceObject, + OUT PREAD_CAPACITY_DATA_EX CapacityDataEx, + OUT PREAD_CAPACITY_DATA CapacityData);
//--------------------------------------------------------------------- //