Commit 0c59d599 authored by Dean Camera's avatar Dean Camera

Altered the Mass Storage Host class driver so that SCSI data STALLs from the...

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.

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.
parent 798cc84f
......@@ -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)
{
/* Transfer the requested data (if any) to or from the device */
ErrorCode = MassStore_SendReceiveData(SCSICommandBlock, (void*)BufferPtr);
/* 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;
}
}
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;
}
/* 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);
}
......@@ -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
*
* <b>Fixed:</b>
* - Core:
......
......@@ -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;
}
Pipe_ClearOUT();
Pipe_WaitUntilReady();
Pipe_Freeze();
if ((BufferPtr != NULL) &&
((ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr)) != PIPE_RWSTREAM_NoError))
if (BufferPtr != NULL)
{
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment