diff --git a/LUFA/Common/Common.h b/LUFA/Common/Common.h
index fc699b2cd8fd63df8908e5b1713f5eb714fbf4ad..0eee969ec60e5762a13f7beacd81bf2bde77cc9f 100644
--- a/LUFA/Common/Common.h
+++ b/LUFA/Common/Common.h
@@ -116,6 +116,7 @@
 			#define pgm_read_byte(x)         *x
 			#define memcmp_P(...)            memcmp(__VA_ARGS__)
 			#define memcpy_P(...)            memcpy(__VA_ARGS__)
+			#define strlen_P(...)            strlen(__VA_ARGS__)
 			// =================================================
 
 			typedef uint32_t uint_reg_t;
diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt
index 780519dde4f8c21e01d02b11e17e3dca12f03df1..54744066e3b4cf5a3d5f87630105216baedd5a88 100644
--- a/LUFA/DoxygenPages/ChangeLog.txt
+++ b/LUFA/DoxygenPages/ChangeLog.txt
@@ -17,6 +17,7 @@
   *   - Fixed CDC Device class driver's internal serial stream created by \ref CDC_Device_CreateStream not returning the written
   *     character after a successful write (thanks to NicoHood)
   *   - Fixed incorrect endpoint bank setup on the UC3 architecture (thanks to Andrus Aaslaid)
+  *   - Fixed CDC_Device_Send*_P() and CDC_Host_Send*_P() variant functions not compiled out for UC3 architecture
   *  - Library Applications:
   *   - Fixed bootloaders not disabling global interrupts during erase and write operations (thanks to Zoltan)
   *   - Fixed bootloaders accepting flash writes to the bootloader region (thanks to NicoHood)
diff --git a/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c b/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c
index bf6e30141708d346ed596278211ae7a1c2293f23..6813decd782299b5253711a598ba21a85a46c6d3 100644
--- a/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c
+++ b/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c
@@ -155,16 +155,6 @@ uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo
 	return Endpoint_Write_Stream_LE(String, strlen(String), NULL);
 }
 
-uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
-                              const char* const String)
-{
-	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
-	  return ENDPOINT_RWSTREAM_DeviceDisconnected;
-
-	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
-	return Endpoint_Write_PStream_LE(String, strlen_P(String), NULL);
-}
-
 uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
                             const void* const Buffer,
                             const uint16_t Length)
@@ -176,16 +166,28 @@ uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 	return Endpoint_Write_Stream_LE(Buffer, Length, NULL);
 }
 
-uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
-                            const void* const Buffer,
-                            const uint16_t Length)
-{
-	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
-	  return ENDPOINT_RWSTREAM_DeviceDisconnected;
+#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
+	uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+	                                const char* const String)
+	{
+		if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+		  return ENDPOINT_RWSTREAM_DeviceDisconnected;
 
-	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
-	return Endpoint_Write_PStream_LE(Buffer, Length, NULL);
-}
+		Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
+		return Endpoint_Write_PStream_LE(String, strlen_P(String), NULL);
+	}
+
+	uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+	                              const void* const Buffer,
+	                              const uint16_t Length)
+	{
+		if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+		  return ENDPOINT_RWSTREAM_DeviceDisconnected;
+
+		Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
+		return Endpoint_Write_PStream_LE(Buffer, Length, NULL);
+	}
+#endif
 
 uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
                             const uint8_t Data)
@@ -306,51 +308,51 @@ void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDC
 }
 
 #if defined(FDEV_SETUP_STREAM)
-void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
-                             FILE* const Stream)
-{
-	*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
-	fdev_set_udata(Stream, CDCInterfaceInfo);
-}
-
-void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
-                                     FILE* const Stream)
-{
-	*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
-	fdev_set_udata(Stream, CDCInterfaceInfo);
-}
+	void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+	                             FILE* const Stream)
+	{
+		*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
+		fdev_set_udata(Stream, CDCInterfaceInfo);
+	}
 
-static int CDC_Device_putchar(char c,
-                              FILE* Stream)
-{
-	return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : c;
-}
+	void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+	                                     FILE* const Stream)
+	{
+		*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
+		fdev_set_udata(Stream, CDCInterfaceInfo);
+	}
 
-static int CDC_Device_getchar(FILE* Stream)
-{
-	int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
+	static int CDC_Device_putchar(char c,
+	                              FILE* Stream)
+	{
+		return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : c;
+	}
 
-	if (ReceivedByte < 0)
-	  return _FDEV_EOF;
+	static int CDC_Device_getchar(FILE* Stream)
+	{
+		int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
 
-	return ReceivedByte;
-}
+		if (ReceivedByte < 0)
+		  return _FDEV_EOF;
 
-static int CDC_Device_getchar_Blocking(FILE* Stream)
-{
-	int16_t ReceivedByte;
+		return ReceivedByte;
+	}
 
-	while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0)
+	static int CDC_Device_getchar_Blocking(FILE* Stream)
 	{
-		if (USB_DeviceState == DEVICE_STATE_Unattached)
-		  return _FDEV_EOF;
+		int16_t ReceivedByte;
 
-		CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
-		USB_USBTask();
-	}
+		while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0)
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return _FDEV_EOF;
 
-	return ReceivedByte;
-}
+			CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
+			USB_USBTask();
+		}
+
+		return ReceivedByte;
+	}
 #endif
 
 void CDC_Device_Event_Stub(void)
diff --git a/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h b/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h
index 4b307fc9e5a4bf714609525670fcd7bd1dce28bc..6fea69176681ea21260a9f503b7e17d891ff58ac 100644
--- a/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h
+++ b/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h
@@ -182,27 +182,25 @@
 			void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 			                                const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
 
-			/** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is
-			 *  called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank
-			 *  becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
-			 *  for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
+			/** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when
+			 *  the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
+			 *  the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
+			 *  the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
 			 *
 			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 			 *       the call will fail.
 			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
-			 *  \param[in]     Buffer            Pointer to a buffer containing the data to send to the device.
-			 *  \param[in]     Length            Length of the data to send to the host.
+			 *  \param[in]     String            Pointer to the null terminated string to send to the host.
 			 *
 			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 			 */
-			uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
-			                            const void* const Buffer,
-			                            const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+			uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+			                              const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
 
-			/** Sends a given data buffer from PROGMEM space to the attached USB host, if connected. If a host is not connected when the
-			 *  function is called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint
-			 *  bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
+			/** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is
+			 *  called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank
+			 *  becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
 			 *  for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
 			 *
 			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
@@ -214,41 +212,51 @@
 			 *
 			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 			 */
-			uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+			uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 			                            const void* const Buffer,
 			                            const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
 
-			/** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when
-			 *  the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
+			/** Sends a given null terminated string from PROGMEM space to the attached USB host, if connected. If a host is not connected
+			 *  when the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
 			 *  the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
 			 *  the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
 			 *
 			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 			 *       the call will fail.
 			 *
+			 *  \note This function does not exist on architectures that do not have a separate flash memory space.
+			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 			 *  \param[in]     String            Pointer to the null terminated string to send to the host.
 			 *
 			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 			 */
-			uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
-			                              const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+			#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
+				uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+				                                const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+			#endif
 
-			/** Sends a given null terminated string from PROGMEM space to the attached USB host, if connected. If a host is not connected
-			 *  when the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
-			 *  the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
-			 *  the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
+			/** Sends a given data buffer from PROGMEM space to the attached USB host, if connected. If a host is not connected when the
+			 *  function is called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint
+			 *  bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
+			 *  for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
 			 *
 			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 			 *       the call will fail.
 			 *
+			 *  \note This function does not exist on architectures that do not have a separate flash memory space.
+			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
-			 *  \param[in]     String            Pointer to the null terminated string to send to the host.
+			 *  \param[in]     Buffer            Pointer to a buffer containing the data to send to the device.
+			 *  \param[in]     Length            Length of the data to send to the host.
 			 *
 			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 			 */
-			uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
-			                              const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+			#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
+				uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+				                              const void* const Buffer,
+				                              const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+			#endif
 
 			/** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
 			 *  byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
diff --git a/LUFA/Drivers/USB/Class/Host/CDCClassHost.c b/LUFA/Drivers/USB/Class/Host/CDCClassHost.c
index f60fe0047cc702caa6112f66958b62b78aa06b64..d463c667b6f77ff67dfcf05f9ccdd249745a2cff 100644
--- a/LUFA/Drivers/USB/Class/Host/CDCClassHost.c
+++ b/LUFA/Drivers/USB/Class/Host/CDCClassHost.c
@@ -276,9 +276,8 @@ uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
 	return USB_Host_SendControlRequest(NULL);
 }
 
-uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
-                          const void* const Buffer,
-                          const uint16_t Length)
+uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+                            const char* const String)
 {
 	if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
 	  return PIPE_READYWAIT_DeviceDisconnected;
@@ -288,13 +287,13 @@ uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
 	Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
 
 	Pipe_Unfreeze();
-	ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL);
+	ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL);
 	Pipe_Freeze();
 
 	return ErrorCode;
 }
 
-uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
                           const void* const Buffer,
                           const uint16_t Length)
 {
@@ -306,45 +305,48 @@ uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
 	Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
 
 	Pipe_Unfreeze();
-	ErrorCode = Pipe_Write_PStream_LE(Buffer, Length, NULL);
+	ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL);
 	Pipe_Freeze();
 
 	return ErrorCode;
 }
 
-uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
-                            const char* const String)
-{
-	if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
-	  return PIPE_READYWAIT_DeviceDisconnected;
+#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
+	uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+	                              const char* const String)
+	{
+		if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
+		  return PIPE_READYWAIT_DeviceDisconnected;
 
-	uint8_t ErrorCode;
+		uint8_t ErrorCode;
 
-	Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
+		Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
 
-	Pipe_Unfreeze();
-	ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL);
-	Pipe_Freeze();
+		Pipe_Unfreeze();
+		ErrorCode = Pipe_Write_PStream_LE(String, strlen_P(String), NULL);
+		Pipe_Freeze();
 
-	return ErrorCode;
-}
+		return ErrorCode;
+	}
 
-uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
-                            const char* const String)
-{
-	if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
-	  return PIPE_READYWAIT_DeviceDisconnected;
+	uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+	                            const void* const Buffer,
+	                            const uint16_t Length)
+	{
+		if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
+		  return PIPE_READYWAIT_DeviceDisconnected;
 
-	uint8_t ErrorCode;
+		uint8_t ErrorCode;
 
-	Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
+		Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
 
-	Pipe_Unfreeze();
-	ErrorCode = Pipe_Write_PStream_LE(String, strlen_P(String), NULL);
-	Pipe_Freeze();
+		Pipe_Unfreeze();
+		ErrorCode = Pipe_Write_PStream_LE(Buffer, Length, NULL);
+		Pipe_Freeze();
 
-	return ErrorCode;
-}
+		return ErrorCode;
+	}
+#endif
 
 uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
                           const uint8_t Data)
@@ -456,51 +458,51 @@ uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
 }
 
 #if defined(FDEV_SETUP_STREAM)
-void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
-                           FILE* const Stream)
-{
-	*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW);
-	fdev_set_udata(Stream, CDCInterfaceInfo);
-}
-
-void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
-                                   FILE* const Stream)
-{
-	*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
-	fdev_set_udata(Stream, CDCInterfaceInfo);
-}
+	void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+	                           FILE* const Stream)
+	{
+		*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW);
+		fdev_set_udata(Stream, CDCInterfaceInfo);
+	}
 
-static int CDC_Host_putchar(char c,
-                            FILE* Stream)
-{
-	return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
-}
+	void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+	                                   FILE* const Stream)
+	{
+		*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
+		fdev_set_udata(Stream, CDCInterfaceInfo);
+	}
 
-static int CDC_Host_getchar(FILE* Stream)
-{
-	int16_t ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
+	static int CDC_Host_putchar(char c,
+	                            FILE* Stream)
+	{
+		return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
+	}
 
-	if (ReceivedByte < 0)
-	  return _FDEV_EOF;
+	static int CDC_Host_getchar(FILE* Stream)
+	{
+		int16_t ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
 
-	return ReceivedByte;
-}
+		if (ReceivedByte < 0)
+		  return _FDEV_EOF;
 
-static int CDC_Host_getchar_Blocking(FILE* Stream)
-{
-	int16_t ReceivedByte;
+		return ReceivedByte;
+	}
 
-	while ((ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))) < 0)
+	static int CDC_Host_getchar_Blocking(FILE* Stream)
 	{
-		if (USB_HostState == HOST_STATE_Unattached)
-		  return _FDEV_EOF;
+		int16_t ReceivedByte;
 
-		CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
-		USB_USBTask();
-	}
+		while ((ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))) < 0)
+		{
+			if (USB_HostState == HOST_STATE_Unattached)
+			  return _FDEV_EOF;
 
-	return ReceivedByte;
-}
+			CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
+			USB_USBTask();
+		}
+
+		return ReceivedByte;
+	}
 #endif
 
 void CDC_Host_Event_Stub(void)
diff --git a/LUFA/Drivers/USB/Class/Host/CDCClassHost.h b/LUFA/Drivers/USB/Class/Host/CDCClassHost.h
index 13f6a51584c7571dbe2b814b05f535c48dda3bcb..e5dba5d1bc727feb05abc53418a7cdbf31a7c197 100644
--- a/LUFA/Drivers/USB/Class/Host/CDCClassHost.h
+++ b/LUFA/Drivers/USB/Class/Host/CDCClassHost.h
@@ -183,6 +183,22 @@
 			uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
 			                           const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
 
+			/** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the
+			 *  function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe
+			 *  bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows
+			 *  for multiple bytes to be packed into a single pipe packet, increasing data throughput.
+			 *
+			 *  \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
+			 *       call will fail.
+			 *
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
+			 *  \param[in]     String            Pointer to the null terminated string to send to the device.
+			 *
+			 *  \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+			 */
+			uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+			                            const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
 			/** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is
 			 *  called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank
 			 *  becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows for
@@ -201,55 +217,47 @@
 			                          const void* const Buffer,
 			                          const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
 
-			/** Sends a given data buffer from PROGMEM space to the attached USB device, if connected. If a device is not connected when the
-			 *  function is called, the string is discarded. Bytes will be queued for transmission to the host until either the pipe
-			 *  bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows
-			 *  for multiple bytes to be packed into a single pipe packet, increasing data throughput.
+			/** Sends a given null terminated string from PROGMEM space to the attached USB device, if connected. If a device is not connected
+			 *  when the function is called, the string is discarded. Bytes will be queued for transmission to the device until either
+			 *  the pipe bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to
+			 *  the device. This allows for multiple bytes to be packed into a single pipe packet, increasing data throughput.
 			 *
 			 *  \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or
 			 *       the call will fail.
 			 *
+			 *  \note This function does not exist on architectures that do not have a separate flash memory space.
+			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
-			 *  \param[in]     Buffer            Pointer to a buffer containing the data to send to the device.
-			 *  \param[in]     Length            Length of the data to send to the host.
+			 *  \param[in]     String            Pointer to the null terminated string to send to the host.
 			 *
 			 *  \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
 			 */
-			uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
-			                            const void* const Buffer,
-			                            const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+			#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
+				uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+			                                  const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+			#endif
 
-			/** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the
-			 *  function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe
+			/** Sends a given data buffer from PROGMEM space to the attached USB device, if connected. If a device is not connected when the
+			 *  function is called, the string is discarded. Bytes will be queued for transmission to the host until either the pipe
 			 *  bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows
 			 *  for multiple bytes to be packed into a single pipe packet, increasing data throughput.
 			 *
-			 *  \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
-			 *       call will fail.
-			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
-			 *  \param[in]     String            Pointer to the null terminated string to send to the device.
-			 *
-			 *  \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
-			 */
-			uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
-			                            const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
-
-			/** Sends a given null terminated string from PROGMEM space to the attached USB device, if connected. If a device is not connected
-			 *  when the function is called, the string is discarded. Bytes will be queued for transmission to the device until either
-			 *  the pipe bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to
-			 *  the device. This allows for multiple bytes to be packed into a single pipe packet, increasing data throughput.
-			 *
 			 *  \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or
 			 *       the call will fail.
 			 *
+			 *  \note This function does not exist on architectures that do not have a separate flash memory space.
+			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
-			 *  \param[in]     String            Pointer to the null terminated string to send to the host.
+			 *  \param[in]     Buffer            Pointer to a buffer containing the data to send to the device.
+			 *  \param[in]     Length            Length of the data to send to the host.
 			 *
 			 *  \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
 			 */
-			uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
-			                              const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+			#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
+				uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+			                                const void* const Buffer,
+			                                const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+			#endif
 
 			/** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the
 			 *  byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the