From 8df0cf3241ff7de055850b630e8d878d1023bb5d Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Wed, 9 Nov 2011 12:29:14 +0000
Subject: [PATCH] Fixed race conditions in the CDC, HID and Mass Storage class
 drivers when processing some control requests.

---
 LUFA/DoxygenPages/ChangeLog.txt             |  1 +
 LUFA/DoxygenPages/LUFAPoweredProjects.txt   |  4 ++++
 LUFA/Drivers/USB/Class/Device/CDC.c         | 10 +++++++++-
 LUFA/Drivers/USB/Class/Device/HID.c         |  2 ++
 LUFA/Drivers/USB/Class/Device/MassStorage.c |  1 +
 5 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt
index 41a65489b..38359378e 100644
--- a/LUFA/DoxygenPages/ChangeLog.txt
+++ b/LUFA/DoxygenPages/ChangeLog.txt
@@ -26,6 +26,7 @@
   *  - Core:
   *   - Fixed ring buffer size limited to 255 elements, instead of the intended 65535 elements.
   *   - Fixed CDC class drivers not saving and sending all 16-bits of the control line states (thanks to Matthew Swabey)
+  *   - Fixed race conditions in the CDC, HID and Mass Storage class drivers when processing some control requests
   *  - Library Applications:
   *   - Added reliability patches to the AVRISP-MKII Clone project's PDI/TPI protocols (thanks to Justin Mattair)
   *   - Fixed AVRISP-MKII Clone compile warning on AVR8 U4 targets even when NO_VTARGET_DETECT is enabled
diff --git a/LUFA/DoxygenPages/LUFAPoweredProjects.txt b/LUFA/DoxygenPages/LUFAPoweredProjects.txt
index 4b85285b8..b0a89dd4d 100644
--- a/LUFA/DoxygenPages/LUFAPoweredProjects.txt
+++ b/LUFA/DoxygenPages/LUFAPoweredProjects.txt
@@ -136,6 +136,10 @@
  *  - Elektor Magazine, "20 x Open Source" by Jens Nickel, March 2010 Issue
  *  - Circuit Cellar Magazine, "Advanced USB Design Debugging" by Collin O'Flynn, August 2010 Issue
  *
+ *  \section Sec_PortsAndForks Non-Official LUFA Ports and Forks
+ *  - NXP's official "nxpusblib" LUFA fork, for LPC devices: http://www.lpcware.com/content/project/nxpusblib
+ *  - Kevin Mehall's LUFA port to the NXP LPC13xx: https://github.com/kevinmehall/LUFA-LPC13xx
+ *
  *  \section Sec_LUFANotableMentions Other Notable Mentions of LUFA
  *  - Adafruit "Ask an Engineer", 7th November 2010
  *  - Arduino 2010 Keynote speech
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c
index dc8c1e7a6..29e5c25eb 100644
--- a/LUFA/Drivers/USB/Class/Device/CDC.c
+++ b/LUFA/Drivers/USB/Class/Device/CDC.c
@@ -51,10 +51,14 @@ void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInter
 			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 			{
 				Endpoint_ClearSETUP();
+
+				while (!(Endpoint_IsINReady()));
+
 				Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
 				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat);
 				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType);
 				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits);
+
 				Endpoint_ClearIN();
 				Endpoint_ClearStatusStage();
 			}
@@ -64,13 +68,17 @@ void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInter
 			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 			{
 				Endpoint_ClearSETUP();
+
+				while (!(Endpoint_IsOUTReceived()));
+
 				CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE();
 				CDCInterfaceInfo->State.LineEncoding.CharFormat  = Endpoint_Read_8();
 				CDCInterfaceInfo->State.LineEncoding.ParityType  = Endpoint_Read_8();
 				CDCInterfaceInfo->State.LineEncoding.DataBits    = Endpoint_Read_8();
+
 				Endpoint_ClearOUT();
 				Endpoint_ClearStatusStage();
-
+			
 				EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
 			}
 
diff --git a/LUFA/Drivers/USB/Class/Device/HID.c b/LUFA/Drivers/USB/Class/Device/HID.c
index 3b0f87a61..ec02138ab 100644
--- a/LUFA/Drivers/USB/Class/Device/HID.c
+++ b/LUFA/Drivers/USB/Class/Device/HID.c
@@ -94,6 +94,7 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
 			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 			{
 				Endpoint_ClearSETUP();
+				while (!(Endpoint_IsINReady()));
 				Endpoint_Write_8(HIDInterfaceInfo->State.UsingReportProtocol);
 				Endpoint_ClearIN();
 				Endpoint_ClearStatusStage();
@@ -124,6 +125,7 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
 			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 			{
 				Endpoint_ClearSETUP();
+				while (!(Endpoint_IsINReady()));
 				Endpoint_Write_8(HIDInterfaceInfo->State.IdleCount >> 2);
 				Endpoint_ClearIN();
 				Endpoint_ClearStatusStage();
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.c b/LUFA/Drivers/USB/Class/Device/MassStorage.c
index 9d5ff7d20..7586c2812 100644
--- a/LUFA/Drivers/USB/Class/Device/MassStorage.c
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.c
@@ -61,6 +61,7 @@ void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfac
 			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 			{
 				Endpoint_ClearSETUP();
+				while (!(Endpoint_IsINReady()));
 				Endpoint_Write_8(MSInterfaceInfo->Config.TotalLUNs - 1);
 				Endpoint_ClearIN();
 				Endpoint_ClearStatusStage();
-- 
GitLab