diff --git a/drivers/usb/usbstor/disk.c b/drivers/usb/usbstor/disk.c index b11fa28bc8b..fa5d464442b 100644 --- a/drivers/usb/usbstor/disk.c +++ b/drivers/usb/usbstor/disk.c @@ -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; } diff --git a/drivers/usb/usbstor/scsi.c b/drivers/usb/usbstor/scsi.c index 74eeecd761c..18a5680f9ee 100644 --- a/drivers/usb/usbstor/scsi.c +++ b/drivers/usb/usbstor/scsi.c @@ -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; +} + diff --git a/drivers/usb/usbstor/usbstor.c b/drivers/usb/usbstor/usbstor.c index 1142d902997..28296495faf 100644 --- a/drivers/usb/usbstor/usbstor.c +++ b/drivers/usb/usbstor/usbstor.c @@ -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; diff --git a/drivers/usb/usbstor/usbstor.h b/drivers/usb/usbstor/usbstor.h index b9e0e2e581b..7f663dc5116 100644 --- a/drivers/usb/usbstor/usbstor.h +++ b/drivers/usb/usbstor/usbstor.h @@ -14,6 +14,7 @@ #include #include #include +#include #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); //--------------------------------------------------------------------- //