diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c index 48d6035695..fea9704f1d 100644 --- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c +++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c @@ -145,7 +145,7 @@ static uint8_t MassStore_WaitForDataReceived(void) if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ - USB_Host_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); return PIPE_RWSTREAM_PipeStalled; } @@ -158,7 +158,7 @@ static uint8_t MassStore_WaitForDataReceived(void) if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ - USB_Host_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); return PIPE_RWSTREAM_PipeStalled; } @@ -274,12 +274,15 @@ static uint8_t MassStore_GetReturnedStatus(MS_CommandStatusWrapper_t* const SCSI } /** Issues a Mass Storage class specific request to reset the attached device's Mass Storage interface, - * readying the device for the next CBW. + * readying the device for the next CBW. The Data endpoints are cleared of any STALL condition once this + * command completes sucessfuly. * * \return A value from the USB_Host_SendControlErrorCodes_t enum, or MASS_STORE_SCSI_COMMAND_FAILED if the SCSI command fails */ uint8_t MassStore_MassStorageReset(void) { + uint8_t ErrorCode; + USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), @@ -291,8 +294,23 @@ uint8_t MassStore_MassStorageReset(void) /* Select the control pipe for the request transfer */ Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + /* Select first data pipe to clear STALL condition if one exists */ + Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); + + if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + /* Select second data pipe to clear STALL condition if one exists */ + Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); - return USB_Host_SendControlRequest(NULL); + if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + return HOST_SENDCONTROL_Successful; } /** Issues a Mass Storage class specific request to determine the index of the highest numbered Logical diff --git a/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c b/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c index 846a1387a7..5274ab0932 100644 --- a/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c +++ b/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c @@ -140,7 +140,7 @@ uint8_t SImage_ReceiveBlockHeader(void) if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ - USB_Host_ClearPipeStall(SIMAGE_DATA_OUT_PIPE); + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); /* Return error code and break out of the loop */ return PIPE_RWSTREAM_PipeStalled; @@ -154,7 +154,7 @@ uint8_t SImage_ReceiveBlockHeader(void) if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ - USB_Host_ClearPipeStall(SIMAGE_DATA_IN_PIPE); + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); /* Return error code */ return PIPE_RWSTREAM_PipeStalled; diff --git a/LUFA/Common/Endianness.h b/LUFA/Common/Endianness.h index e263149753..6e84626ec5 100644 --- a/LUFA/Common/Endianness.h +++ b/LUFA/Common/Endianness.h @@ -102,20 +102,20 @@ #if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu) #define le16_to_cpu(x) SwapEndian_16(x) #define le32_to_cpu(x) SwapEndian_32(x) - #define be16_to_cpu(x) x - #define be32_to_cpu(x) x + #define be16_to_cpu(x) (x) + #define be32_to_cpu(x) (x) #define cpu_to_le16(x) SwapEndian_16(x) #define cpu_to_le32(x) SwapEndian_32(x) - #define cpu_to_be16(x) x - #define cpu_to_be32(x) x + #define cpu_to_be16(x) (x) + #define cpu_to_be32(x) (x) #define LE16_TO_CPU(x) SWAPENDIAN_16(x) #define LE32_TO_CPU(x) SWAPENDIAN_32(x) - #define BE16_TO_CPU(x) x - #define BE32_TO_CPU(x) x + #define BE16_TO_CPU(x) (x) + #define BE32_TO_CPU(x) (x) #define CPU_TO_LE16(x) SWAPENDIAN_16(x) #define CPU_TO_LE32(x) SWAPENDIAN_32(x) - #define CPU_TO_BE16(x) x - #define CPU_TO_BE32(x) x + #define CPU_TO_BE16(x) (x) + #define CPU_TO_BE32(x) (x) #elif !defined(le16_to_cpu) /** \name Run-time endianness conversion */ //@{ @@ -134,7 +134,7 @@ * * \return Endian corrected version of the input value. */ - #define le16_to_cpu(x) x + #define le16_to_cpu(x) (x) /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the * Endianness of the currently selected CPU architecture. @@ -150,7 +150,7 @@ * * \return Endian corrected version of the input value. */ - #define le32_to_cpu(x) x + #define le32_to_cpu(x) (x) /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the * Endianness of the currently selected CPU architecture. @@ -198,7 +198,7 @@ * * \return Endian corrected version of the input value. */ - #define cpu_to_le16(x) x + #define cpu_to_le16(x) (x) /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it * is in Little Endian format regardless of the currently selected CPU architecture. @@ -214,7 +214,7 @@ * * \return Endian corrected version of the input value. */ - #define cpu_to_le32(x) x + #define cpu_to_le32(x) (x) /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it * is in Big Endian format regardless of the currently selected CPU architecture. @@ -267,7 +267,7 @@ * * \return Endian corrected version of the input value. */ - #define LE16_TO_CPU(x) x + #define LE16_TO_CPU(x) (x) /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the * Endianness of the currently selected CPU architecture. @@ -283,7 +283,7 @@ * * \return Endian corrected version of the input value. */ - #define LE32_TO_CPU(x) x + #define LE32_TO_CPU(x) (x) /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the * Endianness of the currently selected CPU architecture. @@ -331,7 +331,7 @@ * * \return Endian corrected version of the input value. */ - #define CPU_TO_LE16(x) x + #define CPU_TO_LE16(x) (x) /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it * is in Little Endian format regardless of the currently selected CPU architecture. @@ -347,7 +347,7 @@ * * \return Endian corrected version of the input value. */ - #define CPU_TO_LE32(x) x + #define CPU_TO_LE32(x) (x) /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it * is in Big Endian format regardless of the currently selected CPU architecture. diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.c b/LUFA/Drivers/USB/Class/Host/MassStorage.c index 60195e9874..36503bf45a 100644 --- a/LUFA/Drivers/USB/Class/Host/MassStorage.c +++ b/LUFA/Drivers/USB/Class/Host/MassStorage.c @@ -226,8 +226,7 @@ static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInte if (Pipe_IsStalled()) { - USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataOUTPipeNumber); - + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); return PIPE_RWSTREAM_PipeStalled; } @@ -237,8 +236,7 @@ static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInte if (Pipe_IsStalled()) { - USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataINPipeNumber); - + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); return PIPE_RWSTREAM_PipeStalled; } @@ -328,6 +326,8 @@ static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterf uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) { + uint8_t ErrorCode; + USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), @@ -339,7 +339,20 @@ uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) Pipe_SelectPipe(PIPE_CONTROLPIPE); - return USB_Host_SendControlRequest(NULL); + if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber); + + if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber); + + if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + return HOST_SENDCONTROL_Successful; } uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.c b/LUFA/Drivers/USB/Class/Host/StillImage.c index 64cae45f63..48aa86431a 100644 --- a/LUFA/Drivers/USB/Class/Host/StillImage.c +++ b/LUFA/Drivers/USB/Class/Host/StillImage.c @@ -254,7 +254,7 @@ uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInf if (Pipe_IsStalled()) { - USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber); + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); return PIPE_RWSTREAM_PipeStalled; } @@ -264,7 +264,7 @@ uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInf if (Pipe_IsStalled()) { - USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber); + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); return PIPE_RWSTREAM_PipeStalled; } diff --git a/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h index 2d9972260f..40eebef754 100644 --- a/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h @@ -860,7 +860,7 @@ const uint16_t Size, const uint8_t Banks); - /** Spin-loops until the currently selected non-control pipe is ready for the next packed of data to be read + /** Spin-loops until the currently selected non-control pipe is ready for the next packet of data to be read * or written to it, aborting in the case of an error condition (such as a timeout or device disconnect). * * \ingroup Group_PipeRW_AVR8 diff --git a/LUFA/Drivers/USB/Core/HostStandardReq.c b/LUFA/Drivers/USB/Core/HostStandardReq.c index 3da2220863..5bbe5d3fd6 100644 --- a/LUFA/Drivers/USB/Core/HostStandardReq.c +++ b/LUFA/Drivers/USB/Core/HostStandardReq.c @@ -254,7 +254,7 @@ uint8_t USB_Host_GetDeviceStatus(uint8_t* const FeatureStatus) return USB_Host_SendControlRequest(FeatureStatus); } -uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointAddress) +uint8_t USB_Host_ClearEndpointStall(const uint8_t EndpointAddress) { USB_ControlRequest = (USB_Request_Header_t) { diff --git a/LUFA/Drivers/USB/Core/HostStandardReq.h b/LUFA/Drivers/USB/Core/HostStandardReq.h index 7ef439d840..ba8d7be4e3 100644 --- a/LUFA/Drivers/USB/Core/HostStandardReq.h +++ b/LUFA/Drivers/USB/Core/HostStandardReq.h @@ -177,7 +177,7 @@ * * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. */ - uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointAddress); + uint8_t USB_Host_ClearEndpointStall(const uint8_t EndpointAddress); /** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to * the attached device. diff --git a/LUFA/Drivers/USB/Core/StdDescriptors.h b/LUFA/Drivers/USB/Core/StdDescriptors.h index fc79483cf1..a37ea09e7b 100644 --- a/LUFA/Drivers/USB/Core/StdDescriptors.h +++ b/LUFA/Drivers/USB/Core/StdDescriptors.h @@ -681,7 +681,8 @@ * Under GCC, strings prefixed with the "L" character (before * the opening string quotation mark) are considered to be * Unicode strings, and may be used instead of an explicit - * array of ASCII characters. + * array of ASCII characters on little endian devices with + * UTF-16-LE \c wchar_t encoding. */ #endif } ATTR_PACKED USB_Descriptor_String_t; diff --git a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h index f8700383c2..044dead1a4 100644 --- a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h @@ -871,7 +871,7 @@ const uint16_t Size, const uint8_t Banks); - /** Spin-loops until the currently selected non-control pipe is ready for the next packed of data to be read + /** Spin-loops until the currently selected non-control pipe is ready for the next packet of data to be read * or written to it, aborting in the case of an error condition (such as a timeout or device disconnect). * * \ingroup Group_PipeRW_UC3 diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 6782e8d599..b5993fd771 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -58,6 +58,10 @@ * - Removed the ENDPOINT_DESCRIPTOR_DIR_* macros, replaced by ENDPOINT_DIR_* instead * - Renamed the JTAG_DEBUG_ASSERT() macro to JTAG_ASSERT() * - Added variable number of axis to HID_DESCRIPTOR_JOYSTICK() for multi-axis joysticks above just X and Y + * - Renamed USB_Host_ClearPipeStall() to USB_Host_ClearEndpointStall() as the function works on an endpoint address within the attached device, + * and not a Pipe within the host + * - The MS_Host_ResetMSInterface() now performs a full Mass Storage reset sequence to prevent data corruption in the event of a device + * lock up or timeout (thanks to David Lyons) * - Library Applications: * - Modified the Low Level and Class Driver AudioInput and AudioOutput demos to support multiple audio sample rates * - Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration