Author: janderwald Date: Sun May 8 22:18:55 2011 New Revision: 51654
URL: http://svn.reactos.org/svn/reactos?rev=51654&view=rev Log: [USBSTOR] - Start implementing SCSI read
Modified: branches/usb-bringup/drivers/usb/usbstor/disk.c branches/usb-bringup/drivers/usb/usbstor/scsi.c
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] Sun May 8 22:18:55 2011 @@ -103,6 +103,35 @@ Request->SrbStatus = SRB_STATUS_ERROR; } } + else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ) + { + DPRINT1("SCSIOP_READ DataTransferLength %lu\n", Request->DataTransferLength); + ASSERT(Request->DataBuffer); + + // + // send read command + // + Status = USBSTOR_SendReadCmd(DeviceObject, Request, &TransferredLength); + DPRINT1("USBSTOR_SendReadCmd 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 sense data + // + Irp->IoStatus.Information = 0; + Request->SrbStatus = SRB_STATUS_ERROR; + } + } + else { UNIMPLEMENTED;
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] Sun May 8 22:18:55 2011 @@ -488,6 +488,12 @@ CapacityData->LogicalBlockAddress = Response->LastLogicalBlockAddress; CapacityData->BytesPerBlock = Response->BlockLength; } + + // + // store result in device extension + // + PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress); + PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength);
// // send csw @@ -672,3 +678,138 @@ return Status; }
+NTSTATUS +USBSTOR_SendReadCmd( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PSCSI_REQUEST_BLOCK Request, + OUT PULONG TransferBufferLength) +{ + UFI_READ_CMD Cmd; + CSW CSW; + NTSTATUS Status; + PVOID Response; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PCBW OutControl; + PCDB pCDB; + ULONG BlockCount; + + // + // get SCSI command data block + // + pCDB = (PCDB)Request->Cdb; + + // + // get PDO device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // allocate read buffer response from non paged pool + // + Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, Request->DataTransferLength); + if (!Response) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // FIXME: support more logical blocks + // + ASSERT(Request->DataTransferLength == PDODeviceExtension->BlockLength); + + // + // block count + // + BlockCount = Request->DataTransferLength / PDODeviceExtension->BlockLength; + + // + // initialize read sense cmd + // + RtlZeroMemory(&Cmd, sizeof(UFI_READ_CMD)); + Cmd.Code = SCSIOP_READ; + Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN); + Cmd.ContiguousLogicBlocks = _byteswap_ushort(BlockCount); + + RtlCopyMemory(&Cmd.LogicalBlockAddress, pCDB->READ12.LogicalBlock, sizeof(UCHAR) * 4); + + DPRINT1("BlockAddress %lu BlockCount %lu BlockLength %lu\n", NTOHL(Cmd.LogicalBlockAddress), BlockCount, PDODeviceExtension->BlockLength); + + // + // now send read cmd + // + Status = USBSTOR_SendCBW(DeviceObject, UFI_READ_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, &OutControl); + if (!NT_SUCCESS(Status)) + { + // + // failed to send CBW + // + DPRINT1("USBSTOR_SendReadCmd> USBSTOR_SendCBW failed with %x\n", Status); + FreeItem(Response); + ASSERT(FALSE); + return Status; + } + + // + // now read the logical block + // + Status = USBSTOR_SendData(DeviceObject, Request->DataTransferLength, Response); + if (!NT_SUCCESS(Status)) + { + // + // failed to read logical block + // + DPRINT1("USBSTOR_SendReadCmd> USBSTOR_SendData failed with %x\n", Status); + FreeItem(Response); + ASSERT(FALSE); + return Status; + } + + + DbgBreakPoint(); + + // + // 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; +}