Renamed USB_Host_ClearPipeStall() to USB_Host_ClearEndpointStall() as the function...
authorDean Camera <dean@fourwalledcubicle.com>
Wed, 24 Aug 2011 09:50:21 +0000 (09:50 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Wed, 24 Aug 2011 09:50:21 +0000 (09:50 +0000)
Updated MS_Host_ResetMSInterface() to now perform a full Mass Storage reset sequence to prevent data corruption in the event of a device lock up or timeout (thanks to David Lyons).

Add parenthesis around the library Endianness macros that do nothing on a particular architecture to prevent operator precedence issues depending on usage.

Minor documentation corrections.

Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c
Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c
LUFA/Common/Endianness.h
LUFA/Drivers/USB/Class/Host/MassStorage.c
LUFA/Drivers/USB/Class/Host/StillImage.c
LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h
LUFA/Drivers/USB/Core/HostStandardReq.c
LUFA/Drivers/USB/Core/HostStandardReq.h
LUFA/Drivers/USB/Core/StdDescriptors.h
LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h
LUFA/ManPages/ChangeLog.txt

index 48d6035..fea9704 100644 (file)
@@ -145,7 +145,7 @@ static uint8_t MassStore_WaitForDataReceived(void)
                if (Pipe_IsStalled())
                {
                        /* Clear the stall condition on the OUT pipe */
                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;
                }
 
                        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 */
                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;
                }
 
                        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,
 }
 
 /** 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)
 {
  *
  *  \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),
        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);
 
        /* 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
 }
 
 /** Issues a Mass Storage class specific request to determine the index of the highest numbered Logical
index 846a138..5274ab0 100644 (file)
@@ -140,7 +140,7 @@ uint8_t SImage_ReceiveBlockHeader(void)
                if (Pipe_IsStalled())
                {
                        /* Clear the stall condition on the OUT pipe */
                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;
 
                        /* 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 */
                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;
 
                        /* Return error code */
                        return PIPE_RWSTREAM_PipeStalled;
index e263149..6e84626 100644 (file)
                        #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)
                        #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_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 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_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 */
                                //@{
                        #elif !defined(le16_to_cpu)
                                /** \name Run-time endianness conversion */
                                //@{
                                 *
                                 *  \return Endian corrected version of the input value.
                                 */
                                 *
                                 *  \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.
 
                                /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
                                 *  Endianness of the currently selected CPU architecture.
                                 *
                                 *  \return Endian corrected version of the input value.
                                 */
                                 *
                                 *  \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.
 
                                /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
                                 *  Endianness of the currently selected CPU architecture.
                                 *
                                 *  \return Endian corrected version of the input value.
                                 */
                                 *
                                 *  \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.
 
                                /** 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.
                                 *
                                 *  \return Endian corrected version of the input value.
                                 */
                                 *
                                 *  \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.
 
                                /** 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.
                                 *
                                 *  \return Endian corrected version of the input value.
                                 */
                                 *
                                 *  \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.
 
                                /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
                                 *  Endianness of the currently selected CPU architecture.
                                 *
                                 *  \return Endian corrected version of the input value.
                                 */
                                 *
                                 *  \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.
 
                                /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
                                 *  Endianness of the currently selected CPU architecture.
                                 *
                                 *  \return Endian corrected version of the input value.
                                 */
                                 *
                                 *  \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.
 
                                /** 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.
                                 *
                                 *  \return Endian corrected version of the input value.
                                 */
                                 *
                                 *  \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.
 
                                /** 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.
index 60195e9..36503bf 100644 (file)
@@ -226,8 +226,7 @@ static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInte
 
                if (Pipe_IsStalled())
                {
 
                if (Pipe_IsStalled())
                {
-                       USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataOUTPipeNumber);
-
+                       USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
                        return PIPE_RWSTREAM_PipeStalled;
                }
 
                        return PIPE_RWSTREAM_PipeStalled;
                }
 
@@ -237,8 +236,7 @@ static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInte
 
                if (Pipe_IsStalled())
                {
 
                if (Pipe_IsStalled())
                {
-                       USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataINPipeNumber);
-
+                       USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
                        return PIPE_RWSTREAM_PipeStalled;
                }
 
                        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 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),
        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);
 
 
        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,
 }
 
 uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
index 64cae45..48aa864 100644 (file)
@@ -254,7 +254,7 @@ uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInf
 
                if (Pipe_IsStalled())
                {
 
                if (Pipe_IsStalled())
                {
-                       USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber);
+                       USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
                        return PIPE_RWSTREAM_PipeStalled;
                }
 
                        return PIPE_RWSTREAM_PipeStalled;
                }
 
@@ -264,7 +264,7 @@ uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInf
 
                if (Pipe_IsStalled())
                {
 
                if (Pipe_IsStalled())
                {
-                       USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber);
+                       USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
                        return PIPE_RWSTREAM_PipeStalled;
                }
 
                        return PIPE_RWSTREAM_PipeStalled;
                }
 
index 2d99722..40eebef 100644 (file)
                                                const uint16_t Size,
                                                const uint8_t Banks);
 
                                                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
                         *  or written to it, aborting in the case of an error condition (such as a timeout or device disconnect).
                         *
                         *  \ingroup Group_PipeRW_AVR8
index 3da2220..5bbe5d3 100644 (file)
@@ -254,7 +254,7 @@ uint8_t USB_Host_GetDeviceStatus(uint8_t* const FeatureStatus)
        return USB_Host_SendControlRequest(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)
                {
 {
        USB_ControlRequest = (USB_Request_Header_t)
                {
index 7ef439d..ba8d7be 100644 (file)
                         *
                         *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
                         */
                         *
                         *  \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.
 
                        /** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to
                         *  the attached device.
index fc79483..a37ea09 100644 (file)
                                                           *   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
                                                           *   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;
                                                           */
                                #endif
                        } ATTR_PACKED USB_Descriptor_String_t;
index f870038..044dead 100644 (file)
                                                const uint16_t Size,
                                                const uint8_t Banks);
 
                                                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
                         *  or written to it, aborting in the case of an error condition (such as a timeout or device disconnect).
                         *
                         *  \ingroup Group_PipeRW_UC3
index 6782e8d..b5993fd 100644 (file)
   *   - 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
   *   - 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
   *  - 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