diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c index 765d0ed5f2..3546bb276c 100644 --- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c +++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c @@ -83,6 +83,7 @@ static uint8_t MassStore_SendCommand(MS_CommandBlockWrapper_t* const SCSICommand if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t), NULL)) != PIPE_RWSTREAM_NoError) { + Pipe_Freeze(); return ErrorCode; } @@ -95,15 +96,22 @@ static uint8_t MassStore_SendCommand(MS_CommandBlockWrapper_t* const SCSICommand /* Freeze pipe after use */ Pipe_Freeze(); - /* Send data if any has been given */ - if ((BufferPtr != NULL) && - ((ErrorCode = MassStore_SendReceiveData(SCSICommandBlock, BufferPtr)) != PIPE_READYWAIT_NoError)) + if (BufferPtr != NULL) { - Pipe_Freeze(); - return ErrorCode; - } + /* Transfer the requested data (if any) to or from the device */ + ErrorCode = MassStore_SendReceiveData(SCSICommandBlock, (void*)BufferPtr); - return ErrorCode; + /* Only fail completely if the transfer fails without a STALL, as a logical STALL can be recovered from */ + if ((ErrorCode != PIPE_RWSTREAM_NoError) && (ErrorCode != PIPE_RWSTREAM_PipeStalled)) + { + Pipe_Freeze(); + return ErrorCode; + } + } + + /* Retrieve the returned SCSI status from the device */ + MS_CommandStatusWrapper_t SCSIStatusBlock; + return MassStore_GetReturnedStatus(&SCSIStatusBlock); } /** Waits until the attached device is ready to accept data following a CBW, checking @@ -366,8 +374,6 @@ uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex) uint8_t MassStore_Inquiry(const uint8_t LUNIndex, SCSI_Inquiry_Response_t* const InquiryPtr) { - uint8_t ErrorCode = PIPE_RWSTREAM_NoError; - /* Create a CBW with a SCSI command to issue INQUIRY command */ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { @@ -387,23 +393,8 @@ uint8_t MassStore_Inquiry(const uint8_t LUNIndex, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - /* Send the command and any data to the attached device */ - if ((ErrorCode = MassStore_SendCommand(&SCSICommandBlock, InquiryPtr)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - /* Retrieve status information from the attached device */ - if ((ErrorCode = MassStore_GetReturnedStatus(&SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - return ErrorCode; + return MassStore_SendCommand(&SCSICommandBlock, InquiryPtr); } /** Issues a SCSI Request Sense command to the attached device, to determine the current SCSI sense information. This @@ -417,8 +408,6 @@ uint8_t MassStore_Inquiry(const uint8_t LUNIndex, uint8_t MassStore_RequestSense(const uint8_t LUNIndex, SCSI_Request_Sense_Response_t* const SensePtr) { - uint8_t ErrorCode = PIPE_RWSTREAM_NoError; - /* Create a CBW with a SCSI command to issue REQUEST SENSE command */ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { @@ -438,23 +427,8 @@ uint8_t MassStore_RequestSense(const uint8_t LUNIndex, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - /* Send the command and any data to the attached device */ - if ((ErrorCode = MassStore_SendCommand(&SCSICommandBlock, SensePtr)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - /* Retrieve status information from the attached device */ - if ((ErrorCode = MassStore_GetReturnedStatus(&SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - return ErrorCode; + return MassStore_SendCommand(&SCSICommandBlock, SensePtr); } /** Issues a SCSI Device Block Read command to the attached device, to read in one or more data blocks from the @@ -474,8 +448,6 @@ uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint16_t BlockSize, void* BufferPtr) { - uint8_t ErrorCode = PIPE_RWSTREAM_NoError; - /* Create a CBW with a SCSI command to read in the given blocks from the device */ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { @@ -499,23 +471,8 @@ uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - /* Send the command and any data to the attached device */ - if ((ErrorCode = MassStore_SendCommand(&SCSICommandBlock, BufferPtr)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - /* Retrieve status information from the attached device */ - if ((ErrorCode = MassStore_GetReturnedStatus(&SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - return ErrorCode; + return MassStore_SendCommand(&SCSICommandBlock, BufferPtr); } /** Issues a SCSI Device Block Write command to the attached device, to write one or more data blocks to the @@ -535,8 +492,6 @@ uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint16_t BlockSize, void* BufferPtr) { - uint8_t ErrorCode = PIPE_RWSTREAM_NoError; - /* Create a CBW with a SCSI command to write the given blocks to the device */ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { @@ -560,23 +515,8 @@ uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - /* Send the command and any data to the attached device */ - if ((ErrorCode = MassStore_SendCommand(&SCSICommandBlock, BufferPtr)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - /* Retrieve status information from the attached device */ - if ((ErrorCode = MassStore_GetReturnedStatus(&SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - return ErrorCode; + return MassStore_SendCommand(&SCSICommandBlock, BufferPtr); } /** Issues a SCSI Device Test Unit Ready command to the attached device, to determine if the device is ready to accept @@ -588,8 +528,6 @@ uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, */ uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex) { - uint8_t ErrorCode = PIPE_RWSTREAM_NoError; - /* Create a CBW with a SCSI command to issue TEST UNIT READY command */ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { @@ -609,23 +547,8 @@ uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex) } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - /* Send the command and any data to the attached device */ - if ((ErrorCode = MassStore_SendCommand(&SCSICommandBlock, NULL)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - /* Retrieve status information from the attached device */ - if ((ErrorCode = MassStore_GetReturnedStatus(&SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - return ErrorCode; + return MassStore_SendCommand(&SCSICommandBlock, NULL); } /** Issues a SCSI Device Read Capacity command to the attached device, to determine the capacity of the @@ -664,26 +587,14 @@ uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - /* Send the command and any data to the attached device */ if ((ErrorCode = MassStore_SendCommand(&SCSICommandBlock, CapacityPtr)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } + return ErrorCode; /* Endian-correct the read data */ CapacityPtr->Blocks = SwapEndian_32(CapacityPtr->Blocks); CapacityPtr->BlockSize = SwapEndian_32(CapacityPtr->BlockSize); - /* Retrieve status information from the attached device */ - if ((ErrorCode = MassStore_GetReturnedStatus(&SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - return ErrorCode; } @@ -699,8 +610,6 @@ uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, const bool PreventRemoval) { - uint8_t ErrorCode = PIPE_RWSTREAM_NoError; - /* Create a CBW with a SCSI command to issue PREVENT ALLOW MEDIUM REMOVAL command */ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { @@ -720,22 +629,7 @@ uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - /* Send the command and any data to the attached device */ - if ((ErrorCode = MassStore_SendCommand(&SCSICommandBlock, NULL)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - /* Retrieve status information from the attached device */ - if ((ErrorCode = MassStore_GetReturnedStatus(&SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - { - Pipe_Freeze(); - return ErrorCode; - } - - return ErrorCode; + return MassStore_SendCommand(&SCSICommandBlock, NULL); } diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt index 28c4dc5583..64ed7934a3 100644 --- a/LUFA/DoxygenPages/ChangeLog.txt +++ b/LUFA/DoxygenPages/ChangeLog.txt @@ -25,8 +25,11 @@ * - When automatic PLL management mode is enabled on the U4 series AVR8 chips, the PLL is now configured for 48MHz and not * a divided 96MHz, to lower power consumption and to keep the system within the datasheet specs for 3.3V operation (thanks to Scott Vitale) * - Added Class, ClassDevice, ClassHost and ClassCommon to the internal class driver source filenames to prevent ambiguities + * - Altered the Mass Storage Host class driver so that SCSI data STALLs from the attached device can be recovered from automatically without + * having to reset the Mass Storage interface * - Library Applications: - * - None + * - Altered the Mass Storage Host LowLevel demo so that SCSI data STALLs from the attached device can be recovered from automatically without + * having to reset the Mass Storage interface * * Fixed: * - Core: diff --git a/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c b/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c index 96550cc3fc..8a69d15781 100644 --- a/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c +++ b/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c @@ -183,21 +183,28 @@ static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInf if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t), NULL)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - + { + return ErrorCode; + } + Pipe_ClearOUT(); Pipe_WaitUntilReady(); Pipe_Freeze(); - if ((BufferPtr != NULL) && - ((ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr)) != PIPE_RWSTREAM_NoError)) + if (BufferPtr != NULL) { - Pipe_Freeze(); - return ErrorCode; + ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr); + + if ((ErrorCode != PIPE_RWSTREAM_NoError) && (ErrorCode != PIPE_RWSTREAM_PipeStalled)) + { + Pipe_Freeze(); + return ErrorCode; + } } - - return ErrorCode; + + MS_CommandStatusWrapper_t SCSIStatusBlock; + return MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSIStatusBlock); } static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) @@ -358,7 +365,7 @@ uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, uint8_t* const MaxLUNIndex) { - uint8_t ErrorCode = HOST_SENDCONTROL_Successful; + uint8_t ErrorCode; USB_ControlRequest = (USB_Request_Header_t) { @@ -387,8 +394,6 @@ uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) return HOST_SENDCONTROL_DeviceDisconnected; - uint8_t ErrorCode; - MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Inquiry_Response_t)), @@ -406,15 +411,7 @@ uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - - if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, InquiryData)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - return PIPE_RWSTREAM_NoError; + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, InquiryData); } uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, @@ -423,8 +420,6 @@ uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) return HOST_SENDCONTROL_DeviceDisconnected; - uint8_t ErrorCode; - MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { .DataTransferLength = CPU_TO_LE32(0), @@ -442,15 +437,7 @@ uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - - if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - return PIPE_RWSTREAM_NoError; + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL); } uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, @@ -483,17 +470,12 @@ uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInf } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, DeviceCapacity)) != PIPE_RWSTREAM_NoError) return ErrorCode; DeviceCapacity->Blocks = BE32_TO_CPU(DeviceCapacity->Blocks); DeviceCapacity->BlockSize = BE32_TO_CPU(DeviceCapacity->BlockSize); - if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - return PIPE_RWSTREAM_NoError; } @@ -504,8 +486,6 @@ uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) return HOST_SENDCONTROL_DeviceDisconnected; - uint8_t ErrorCode; - MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Request_Sense_Response_t)), @@ -523,15 +503,7 @@ uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - - if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, SenseData)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - return PIPE_RWSTREAM_NoError; + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, SenseData); } uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, @@ -541,8 +513,6 @@ uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInter if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) return HOST_SENDCONTROL_DeviceDisconnected; - uint8_t ErrorCode; - MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { .DataTransferLength = CPU_TO_LE32(0), @@ -560,15 +530,7 @@ uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInter } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - - if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - return PIPE_RWSTREAM_NoError; + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL); } uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, @@ -581,8 +543,6 @@ uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) return HOST_SENDCONTROL_DeviceDisconnected; - uint8_t ErrorCode; - MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { .DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize), @@ -604,15 +564,7 @@ uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - - if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - return PIPE_RWSTREAM_NoError; + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer); } uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, @@ -625,8 +577,6 @@ uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) return HOST_SENDCONTROL_DeviceDisconnected; - uint8_t ErrorCode; - MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) { .DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize), @@ -648,15 +598,7 @@ uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo } }; - MS_CommandStatusWrapper_t SCSICommandStatus; - - if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError) - return ErrorCode; - - return PIPE_RWSTREAM_NoError; + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer); } #endif