diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
index e73781466112a195d009e8a41b05a1574bfd2996..f67a0ff2b9d6ff3d4430c4a433f1148f93ff66d5 100644
--- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
+++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
@@ -39,10 +39,10 @@
 uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
 #endif
 
-Endpoint_FIFOPair_t           USB_Endpoint_FIFOs[ENDPOINT_DETAILS_MAXEP];
+Endpoint_FIFOPair_t       USB_Endpoint_FIFOs[ENDPOINT_TOTAL_ENDPOINTS];
 
-volatile uint8_t              USB_Endpoint_SelectedEndpoint;
-volatile USB_EP_t*            USB_Endpoint_SelectedHandle;
+volatile uint8_t          USB_Endpoint_SelectedEndpoint;
+volatile USB_EP_t*        USB_Endpoint_SelectedHandle;
 volatile Endpoint_FIFO_t* USB_Endpoint_SelectedFIFO;
 
 bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Number,
@@ -66,8 +66,11 @@ bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Number,
 
 void Endpoint_ClearEndpoints(void)
 {
-	for (uint8_t EPNum = 0; EPNum < (ENDPOINT_TOTAL_ENDPOINTS * 2); EPNum++)
-	  ((USB_EP_t*)&USB_EndpointTable)[EPNum].CTRL = 0;
+	for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
+	{
+		USB_EndpointTable.Endpoints[EPNum].IN.CTRL  = 0;
+		USB_EndpointTable.Endpoints[EPNum].OUT.CTRL = 0;
+	}
 }
 
 void Endpoint_ClearStatusStage(void)
diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
index 495aa9707e9bf415ce7d1fdee8b9355b348e79a2..49069d8c291f752915e0ce623e1d27dc47aefab8 100644
--- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
+++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
@@ -391,7 +391,10 @@
 			static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
 			static inline bool Endpoint_IsReadWriteAllowed(void)
 			{
-				return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length);
+				if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN)
+				  return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length);
+				else
+				  return (USB_Endpoint_SelectedFIFO->Position > 0);
 			}
 
 			/** Determines if the currently selected endpoint is configured.
diff --git a/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c b/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c
index 55d137ba3bdd3a9a2465bec72ea6a9e66932b494..3d4151b4e3bffa0cf32775ec0fcd2b0122298332 100644
--- a/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c
+++ b/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c
@@ -35,6 +35,8 @@ uint8_t TEMPLATE_FUNC_NAME (void* const Buffer,
 {
 	uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length));
 
+	Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN);
+
 	if (!(Length))
 	  Endpoint_ClearOUT();
 
diff --git a/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c b/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c
index 36685f0c4313593a6b80d61bd0fec3245a5755fc..e5180693d073e648cd358a2bf8ceb8f6f884e7ff 100644
--- a/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c
+++ b/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c
@@ -36,6 +36,8 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
 	uint8_t* DataStream     = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length));
 	bool     LastPacketFull = false;
 
+	Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN);
+
 	if (Length > USB_ControlRequest.wLength)
 	  Length = USB_ControlRequest.wLength;
 	else if (!(Length))