diff --git a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
index 19c77c3785dfb0bdbbb7adbb59b3ea488bd0e220..0f9134fea6d1f247ee13a5b27c8e66c6df529a9d 100644
--- a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
+++ b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
@@ -132,8 +132,8 @@ int main(void)
 
 				printf("Vendor \"%.8s\", Product \"%.16s\"\r\n", InquiryData.VendorID, InquiryData.ProductID);
 				
+				printf("Waiting until ready...\r\n");
 				bool DeviceReady;
-				printf("Waiting until ready...\r\n"));
 
 				do
 				{
@@ -150,7 +150,7 @@ int main(void)
 				puts_P(PSTR("Retrieving Capacity... "));
 
 				SCSI_Capacity_t DiskCapacity;
-				if (MS_Host_ReadDeviceCapacity(0, &DiskCapacity))
+				if (MS_Host_ReadDeviceCapacity(&FlashDisk_MS_Interface, 0, &DiskCapacity))
 				{
 					printf("Error retrieving device capacity.\r\n");
 					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h
index b1c5046c6cbed5f8f3c836b5b4004aa738b4dcd6..12a8acdd62eef607b3cb1a0de30c4671efc2e14a 100644
--- a/LUFA/Drivers/USB/Class/Device/Audio.h
+++ b/LUFA/Drivers/USB/Class/Device/Audio.h
@@ -104,21 +104,21 @@
 			 *
 			 *  \return Boolean true if the endpoints were sucessfully configured, false otherwise
 			 */
-			bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
+			bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Processes incomming control requests from the host, that are directed to the given Audio class interface. This should be
 			 *  linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
 			 *
 			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 			 */
-			void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
+			void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** General management task for a given Audio class interface, required for the correct operation of the interface. This should
 			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 			 *
 			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 			 */
-			void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
+			void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Reads the next 8-bit audio sample from the current audio interface.
 			 *
@@ -129,7 +129,7 @@
 			 *
 			 *  \return  Signed 8-bit audio sample from the audio interface
 			 */
-			int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
+			int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Reads the next 16-bit audio sample from the current audio interface.
 			 *
@@ -140,7 +140,7 @@
 			 *
 			 *  \return  Signed 16-bit audio sample from the audio interface
 			 */
-			int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
+			int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Reads the next 24-bit audio sample from the current audio interface.
 			 *
@@ -150,7 +150,7 @@
 			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 			 *  \return  Signed 24-bit audio sample from the audio interface
 			 */
-			int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
+			int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Writes the next 8-bit audio sample to the current audio interface.
 			 *
@@ -160,7 +160,7 @@
 			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 			 *  \param[in] Sample  Signed 8-bit audio sample
 			 */
-			void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const int8_t Sample);
+			void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Writes the next 16-bit audio sample to the current audio interface.
 			 *
@@ -170,7 +170,7 @@
 			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 			 *  \param[in] Sample  Signed 16-bit audio sample
 			 */
-			void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const int16_t Sample);
+			void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Writes the next 24-bit audio sample to the current audio interface.
 			 *
@@ -180,7 +180,7 @@
 			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 			 *  \param[in] Sample  Signed 24-bit audio sample
 			 */
-			void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const int32_t Sample);
+			void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Determines if the given audio interface is ready for a sample to be read from it.
 			 *
@@ -188,7 +188,7 @@
 			 *
 			 *  \return Boolean true if the given Audio interface has a sample to be read, false otherwise
 			 */
-			bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
+			bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Determines if the given audio interface is ready to accept the next sample to be written to it.
 			 *
@@ -196,7 +196,7 @@
 			 *
 			 *  \return Boolean true if the given Audio interface is ready to accept the next sample, false otherwise
 			 */
-			bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
+			bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 	/* Disable C linkage for C++ Compilers: */
 		#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.h b/LUFA/Drivers/USB/Class/Device/CDC.h
index 99f8eb2b2b47c1554c3e7a22d8887f5dc5e21369..dcb1762bd56a0efb38e644375b917d6f629765ac 100644
--- a/LUFA/Drivers/USB/Class/Device/CDC.h
+++ b/LUFA/Drivers/USB/Class/Device/CDC.h
@@ -115,21 +115,21 @@
 			 *
 			 *  \return Boolean true if the endpoints were sucessfully configured, false otherwise
 			 */
-			bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Processes incomming control requests from the host, that are directed to the given CDC class interface. This should be
 			 *  linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
 			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 			 */
-			void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** General management task for a given CDC class interface, required for the correct operation of the interface. This should
 			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 			 */
-			void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
 			 *  line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
@@ -138,7 +138,7 @@
 			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 			 */
-			void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
 			 *  control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
@@ -148,7 +148,7 @@
 			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 			 */
-			void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Sends a given string to the attached USB host, if connected. If a host is not connected when the function is called, the
 			 *  string is discarded.
@@ -159,7 +159,7 @@
 			 *
 			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum
 			 */
-			uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, char* const Data, const uint16_t Length);
+			uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, char* const Data, const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1, 2);
 			
 			/** 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.
@@ -169,7 +169,7 @@
 			 *
 			 *  \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
 			 */
-			uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data);
+			uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Determines the number of bytes received by the CDC interface from the host, waiting to be read.
 			 *
@@ -177,7 +177,7 @@
 			 *
 			 *  \return Total number of buffered bytes received from the host
 			 */
-			uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
 			 *  returns 0. The \ref CDC_Device_BytesReceived() function should be queried before data is recieved to ensure that no data
@@ -187,7 +187,7 @@
 			 *
 			 *  \return Next received byte from the host, or 0 if no data received
 			 */
-			uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
 			 *
@@ -195,7 +195,7 @@
 			 *
 			 *  \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
 			 */
-			uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial
 			 *  control lines (DCD, DSR, etc.) have changed states, or to give BREAK notfications to the host. Line states persist
@@ -204,7 +204,7 @@
 			 *
 			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 			 */
-			void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo);
+			void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
@@ -212,9 +212,9 @@
 			#if defined(INCLUDE_FROM_CDC_CLASS_DEVICE_C)
 				void CDC_Device_Event_Stub(void);
 				void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
-														  ATTR_WEAK ATTR_ALIAS(CDC_Device_Event_Stub);
+														  ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
 				void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
-															 ATTR_WEAK ATTR_ALIAS(CDC_Device_Event_Stub);
+															 ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
 			#endif
 
 	#endif
diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h
index d995c09aa23a17bef1efb0425d213dd415742dce..e3f091bfb45773f0b1c1c4e1a56fce18226ec67b 100644
--- a/LUFA/Drivers/USB/Class/Device/HID.h
+++ b/LUFA/Drivers/USB/Class/Device/HID.h
@@ -102,21 +102,21 @@
 			 *
 			 *  \return Boolean true if the endpoints were sucessfully configured, false otherwise
 			 */
-			bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
+			bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Processes incomming control requests from the host, that are directed to the given HID class interface. This should be
 			 *  linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
 			 *
 			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 			 */		
-			void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
+			void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** General management task for a given HID class interface, required for the correct operation of the interface. This should
 			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 			 *
 			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 			 */
-			void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
+			void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be
 			 *  decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended
@@ -125,7 +125,7 @@
 			 *
 			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 			 */
-			void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
+			void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** HID class driver callback for the user creation of a HID input report. This callback may fire in response to either
 			 *  HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
@@ -142,7 +142,7 @@
 			 *          the idle period (useful for devices which report relative movement), false otherwise
 			 */
 			bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
-                                                     void* ReportData, uint16_t* ReportSize);
+                                                     void* ReportData, uint16_t* ReportSize) ATTR_NON_NULL_PTR_ARG(1, 2, 3, 4);
 			
 			/** HID class driver callback for the user processing of a received HID input report. This callback may fire in response to
 			 *  either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
@@ -155,7 +155,7 @@
 			 *  \param[in] ReportSize  Size in bytes of the received report from the host.
 			 */
 			void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
-			                                          const void* ReportData, const uint16_t ReportSize);
+			                                          const void* ReportData, const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1, 3);
 
 	/* Disable C linkage for C++ Compilers: */
 		#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/Class/Device/MIDI.h b/LUFA/Drivers/USB/Class/Device/MIDI.h
index ce6778fd78ac6aebe88f2cd4404de4b52f66e0ed..c7f7bd92c4234474cb4a930bf3d3f914ac0508de 100644
--- a/LUFA/Drivers/USB/Class/Device/MIDI.h
+++ b/LUFA/Drivers/USB/Class/Device/MIDI.h
@@ -93,21 +93,21 @@
 			 *
 			 *  \return Boolean true if the endpoints were sucessfully configured, false otherwise
 			 */
-			bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo);
+			bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Processes incomming control requests from the host, that are directed to the given MIDI class interface. This should be
 			 *  linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
 			 *
 			 *  \param[in,out] MIDIInterfaceInfo  Pointer to a structure containing a MIDI Class configuration and state.
 			 */		
-			void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo);
+			void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** General management task for a given MIDI class interface, required for the correct operation of the interface. This should
 			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 			 *
 			 *  \param[in,out] MIDIInterfaceInfo  Pointer to a structure containing a MIDI Class configuration and state.
 			 */
-			void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo);
+			void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded.
 			 *
@@ -116,7 +116,8 @@
 			 *
 			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum			 
 			 */
-			uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event);
+			uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
+			                                    MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1, 2);
 
 			/** Receives a MIDI event packet from the host.
 			 *
@@ -125,7 +126,8 @@
 			 *
 			 *  \return Boolean true if a MIDI event packet was received, false otherwise
 			 */
-			bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event);
+			bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
+			                                    MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1, 2);
 
 	/* Disable C linkage for C++ Compilers: */
 		#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.h b/LUFA/Drivers/USB/Class/Device/MassStorage.h
index b207c237e250e4327920f8f779d6ef5887bdc919..4ab43987daee64fe69fd1930e25956a2763102ce 100644
--- a/LUFA/Drivers/USB/Class/Device/MassStorage.h
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.h
@@ -102,21 +102,21 @@
 			 *
 			 *  \return Boolean true if the endpoints were sucessfully configured, false otherwise
 			 */
-			bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
+			bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Processes incomming control requests from the host, that are directed to the given Mass Storage class interface. This should be
 			 *  linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
 			 *
 			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing a Mass Storage Class configuration and state.
 			 */		
-			void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
+			void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should
 			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 			 *
 			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing a Mass Storage configuration and state.
 			 */
-			void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
+			void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the
 			 *  host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible
@@ -127,14 +127,14 @@
 			 *
 			 *  \return Boolean true if the SCSI command was successfully processed, false otherwise
 			 */
-			bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
+			bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 		
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
 		/* Function Prototypes: */
 			#if defined(INCLUDE_FROM_MS_CLASS_DEVICE_C)
-				static void    MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
-				static bool    MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
+				static void    MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+				static bool    MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 				static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void);
 			#endif
 		
diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.h b/LUFA/Drivers/USB/Class/Device/RNDIS.h
index d9a5d7f0be8b525ceee470672ec644198409d860..4b024d9537bea101468ba8474f9de67ae19ac5ac 100644
--- a/LUFA/Drivers/USB/Class/Device/RNDIS.h
+++ b/LUFA/Drivers/USB/Class/Device/RNDIS.h
@@ -110,32 +110,32 @@
 			 *
 			 *  \return Boolean true if the endpoints were sucessfully configured, false otherwise
 			 */
-			bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo);
+			bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Processes incomming control requests from the host, that are directed to the given RNDIS class interface. This should be
 			 *  linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
 			 *
 			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing a RNDIS Class configuration and state.
 			 */		
-			void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo);
+			void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** General management task for a given HID class interface, required for the correct operation of the interface. This should
 			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 			 *
 			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing a RNDIS Class configuration and state.
 			 */
-			void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo);
+			void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 		
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
 		/* Function Prototypes: */
 		#if defined(INCLUDE_FROM_RNDIS_CLASS_DEVICE_C)
-			static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo);
+			static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, 
 			                                          const uint32_t OId, void* const QueryData, const uint16_t QuerySize,
-										              void* ResponseData, uint16_t* const ResponseSize);
+										              void* ResponseData, uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1, 5, 6);
 			static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, const uint32_t OId,
-			                                        void* SetData, const uint16_t SetSize);	
+			                                        void* SetData, const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1, 3);
 		#endif
 		
 	#endif
diff --git a/LUFA/Drivers/USB/Class/Host/CDC.h b/LUFA/Drivers/USB/Class/Host/CDC.h
index 5baafafe5dc4432c70550497dd98aa7c81e45903..f3abb296e749dfdbf769a276941e6f130d8c2377 100644
--- a/LUFA/Drivers/USB/Class/Host/CDC.h
+++ b/LUFA/Drivers/USB/Class/Host/CDC.h
@@ -122,9 +122,9 @@
 			/** General management task for a given CDC host class interface, required for the correct operation of the interface. This should
 			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing an CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing an CDC Class host configuration and state
 			 */
-			void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+			void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Host interface configuration routine, to configure a given CDC host interface instance using the Configuration
 			 *  Descriptor read from an attached USB device. This function automatically updates the given CDC Host instance's
@@ -132,63 +132,63 @@
 			 *  This should be called once after the stack has enumerated the attached device, while the host state machine is in
 			 *  the Addressed state.
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing an CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing an CDC Class host configuration and state
 			 *  \param[in] ConfigDescriptorLength  Length of the attached device's Configuration Descriptor
 			 *  \param[in] DeviceConfigDescriptor  Pointer to a buffer containing the attached device's Configuration Descriptor
 			 */
 			uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint16_t ConfigDescriptorLength,
-			                                uint8_t* DeviceConfigDescriptor);
+			                                uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3);
 			
 			/** Sets the line encoding for the attached device's virtual serial port. This should be called when the LineEncoding
 			 *  values of the interface have been changed to push the new settings to the USB device.
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state
 			 */
-			uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+			uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Sends a Serial Control Line State Change notification to the device. This should be called when the virtual serial
 			 *  control lines (DTR, RTS, etc.) have changed states. Line states persist until they are cleared via a second
 			 *  notification. This should be called each time the CDC class driver's ControlLineStates.HostToDevice value is updated
 			 *  to push the new states to the USB device.
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state
 			 */
-			uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+			uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** Sends a given string to the attached USB device, if connected. If a device is not connected when the function is called, the
 			 *  string is discarded.
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state
 			 *  \param[in] Data  Pointer to the string to send to the device
 			 *  \param[in] Length  Size in bytes of the string to send to the device
 			 */
-			void CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, char* Data, uint16_t Length);
+			void CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, char* Data, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1, 2);
 			
 			/** Sends a given byte to the attached USB device, if connected. If a host is not connected when the function is called, the
 			 *  byte is discarded.
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state
 			 *  \param[in] Data  Byte of data to send to the device
 			 */
-			void CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint8_t Data);
+			void CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Determines the number of bytes received by the CDC interface from the device, waiting to be read.
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state
 			 *
 			 *  \return Total number of buffered bytes received from the device
 			 */
-			uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+			uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function
 			 *  returns 0. The \ref CDC_Host_BytesReceived() function should be queried before data is recieved to ensure that no data
 			 *  underflow occurs.
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state
 			 *
 			 *  \return Next received byte from the device, or 0 if no data received
 			 */
-			uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+			uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			
 			/** CDC class driver event for a control line state change on a CDC host interface. This event fires each time the device notifies
 			 *  the host of a control line state change (containing the virtual serial control line states, such as DCD) and may be hooked in the
@@ -196,9 +196,9 @@
 			 *  are available in the ControlLineStates.DeviceToHost value inside the CDC host interface structure passed as a parameter, set as
 			 *  a mask of CDC_CONTROL_LINE_IN_* masks.
 			 *
-			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state.
+			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class host configuration and state
 			 */
-			void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+			void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
@@ -218,9 +218,9 @@
 			#if defined(INCLUDE_FROM_CDC_CLASS_HOST_C)
 				void CDC_Host_Event_Stub(void);
 				void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
-				                                           ATTR_WEAK ATTR_ALIAS(CDC_Host_Event_Stub);
-				static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor);
-				static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor);
+				                                           ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Host_Event_Stub);
+				static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+				static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
 				static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescriptor);
 			#endif	
 	#endif
diff --git a/LUFA/Drivers/USB/Class/Host/HID.h b/LUFA/Drivers/USB/Class/Host/HID.h
index 3d7a5390a06c93d6ea2eeb39a7c4623ed015db99..6e1a5222b8ac346f73933d3673a783643daddbb3 100644
--- a/LUFA/Drivers/USB/Class/Host/HID.h
+++ b/LUFA/Drivers/USB/Class/Host/HID.h
@@ -104,12 +104,12 @@
 			} HIDHost_EnumerationFailure_ErrorCodes_t;
 	
 		/* Function Prototypes: */
-			void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo);
+			void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 			uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint16_t ConfigDescriptorLength,
-			                                uint8_t* DeviceConfigDescriptor);
+			                                uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3);
 
-			bool    HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo);
-			uint8_t USB_HID_Host_SetProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, bool UseReportProtocol);
+			bool    HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+			uint8_t USB_HID_Host_SetProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, bool UseReportProtocol) ATTR_NON_NULL_PTR_ARG(1);
 		
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
@@ -121,8 +121,8 @@
 
 		/* Function Prototypes: */
 			#if defined(INCLUDE_FROM_HID_CLASS_HOST_C)
-				static uint8_t DComp_HID_Host_NextHIDInterface(void* CurrentDescriptor);
-				static uint8_t DComp_HID_Host_NextInterfaceHIDDataEndpoint(void* CurrentDescriptor);
+				static uint8_t DComp_HID_Host_NextHIDInterface(void* CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+				static uint8_t DComp_HID_Host_NextInterfaceHIDDataEndpoint(void* CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
 			#endif	
 	#endif	
 	
diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.c b/LUFA/Drivers/USB/Class/Host/MassStorage.c
index 6332d3a612726b017e1147a14e7f41341f28a764..ea7ed3d8a363b1648cfe216e6db58dd745951bd1 100644
--- a/LUFA/Drivers/USB/Class/Host/MassStorage.c
+++ b/LUFA/Drivers/USB/Class/Host/MassStorage.c
@@ -131,4 +131,192 @@ void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* MSInterfaceInfo)
 	
 }
 
+static uint8_t MassStore_SendCommand(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, MS_CommandBlockWrapper_t* SCSICommandBlock)
+{
+	uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
+
+	if (++MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF)
+	  MSInterfaceInfo->State.TransactionTag = 1;
+
+	Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
+	Pipe_Unfreeze();
+
+	if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t))) != PIPE_RWSTREAM_NoError)
+	  return ErrorCode;
+
+	Pipe_ClearOUT();
+	while(!(Pipe_IsOUTReady()));
+
+	Pipe_Freeze();
+	
+	return PIPE_RWSTREAM_NoError;
+}
+
+static uint8_t MassStore_WaitForDataReceived(USB_ClassInfo_MS_Host_t* MSInterfaceInfo)
+{
+	uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;
+
+	Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+	Pipe_Unfreeze();
+
+	while (!(Pipe_IsINReceived()))
+	{
+		if (USB_INT_HasOccurred(USB_INT_HSOFI))
+		{
+			USB_INT_Clear(USB_INT_HSOFI);
+			TimeoutMSRem--;
+
+			if (!(TimeoutMSRem))
+			  return PIPE_RWSTREAM_Timeout;
+		}
+	
+		Pipe_Freeze();
+		Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
+		Pipe_Unfreeze();
+
+		if (Pipe_IsStalled())
+		{
+			USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataOUTPipeNumber);
+
+			return PIPE_RWSTREAM_PipeStalled;
+		}
+		
+		Pipe_Freeze();
+		Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+		Pipe_Unfreeze();
+
+		if (Pipe_IsStalled())
+		{
+			USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataINPipeNumber);
+
+			return PIPE_RWSTREAM_PipeStalled;
+		}
+		  
+		if (USB_HostState == HOST_STATE_Unattached)
+		  return PIPE_RWSTREAM_DeviceDisconnected;
+	};
+	
+	Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+	Pipe_Freeze();
+		
+	Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
+	Pipe_Freeze();
+
+	return PIPE_RWSTREAM_NoError;
+}
+
+static uint8_t MassStore_SendReceiveData(USB_ClassInfo_MS_Host_t* MSInterfaceInfo,
+                                         MS_CommandBlockWrapper_t* SCSICommandBlock, void* BufferPtr)
+{
+	uint8_t  ErrorCode = PIPE_RWSTREAM_NoError;
+	uint16_t BytesRem  = SCSICommandBlock->DataTransferLength;
+
+	if (SCSICommandBlock->Flags & COMMAND_DIRECTION_DATA_IN)
+	{
+		Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+		Pipe_Unfreeze();
+		
+		if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError)
+		  return ErrorCode;
+
+		Pipe_ClearIN();
+	}
+	else
+	{
+		Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
+		Pipe_Unfreeze();
+
+		if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError)
+		  return ErrorCode;
+
+		Pipe_ClearOUT();
+		
+		while (!(Pipe_IsOUTReady()))
+		{
+			if (USB_HostState == HOST_STATE_Unattached)
+			  return PIPE_RWSTREAM_DeviceDisconnected;
+		}
+	}
+
+	Pipe_Freeze();
+
+	return PIPE_RWSTREAM_NoError;
+}
+
+static uint8_t MassStore_GetReturnedStatus(USB_ClassInfo_MS_Host_t* MSInterfaceInfo,
+                                           MS_CommandStatusWrapper_t* SCSICommandStatus)
+{
+	uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
+
+	if ((ErrorCode = MassStore_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError)
+	  return ErrorCode;
+
+	Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+	Pipe_Unfreeze();
+	
+	if ((ErrorCode = Pipe_Read_Stream_LE(&SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t))) != PIPE_RWSTREAM_NoError)
+	  return ErrorCode;
+	  
+	Pipe_ClearIN();
+	Pipe_Freeze();
+	
+	return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* MSInterfaceInfo)
+{
+	if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.Active))
+	  return HOST_SENDCONTROL_DeviceDisconnect;
+
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+			.bRequest      = REQ_MassStorageReset,
+			.wValue        = 0,
+			.wIndex        = MSInterfaceInfo->State.InterfaceNumber,
+			.wLength       = 0,
+		};
+	
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	return USB_Host_SendControlRequest(NULL);
+}
+
+uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t* MaxLUNIndex)
+{
+	if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.Active))
+	  return HOST_SENDCONTROL_DeviceDisconnect;
+
+	uint8_t ErrorCode;
+
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+			.bRequest      = REQ_GetMaxLUN,
+			.wValue        = 0,
+			.wIndex        = MSInterfaceInfo->State.InterfaceNumber,
+			.wLength       = 1,
+		};
+		
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled)
+	{
+		Pipe_ClearStall();
+
+		*MaxLUNIndex = 0;
+	}
+	
+	return ErrorCode;
+}
+
+uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, SCSI_Inquiry_Response_t* InquiryData)
+{
+
+}
+
+uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t LUNIndex, bool* DeviceReady);
+uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t LUNIndex,
+                                   SCSI_Capacity_t* DeviceCapacity);
+
 #endif
diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.h b/LUFA/Drivers/USB/Class/Host/MassStorage.h
index 18b2cf4aef125371eced92b55bcd3571b6b663c6..a8a957bab4fa29176ec74200c9c5dc7e06ff4ad2 100644
--- a/LUFA/Drivers/USB/Class/Host/MassStorage.h
+++ b/LUFA/Drivers/USB/Class/Host/MassStorage.h
@@ -78,25 +78,137 @@
 
 					uint16_t DataINPipeSize; /**< Size in bytes of the MS interface's IN data pipe */
 					uint16_t DataOUTPipeSize;  /**< Size in bytes of the MS interface's OUT data pipe */
+					
+					uint32_t TransactionTag; /**< Current transaction tag for data synchronising of packets */
 				} State; /**< State data for the USB class interface within the device. All elements in this section
 						  *   <b>may</b> be set to initial values, but may also be ignored to default to sane values when
 						  *   the interface is enumerated.
 						  */
 			} USB_ClassInfo_MS_Host_t;
 
+			/** Type define for a SCSI Sense structure. Structures of this type are filled out by the
+			 *  device via the MassStore_RequestSense() function, indicating the current sense data of the
+			 *  device (giving explicit error codes for the last issued command). For details of the
+			 *  structure contents, refer to the SCSI specifications.
+			 */
+			typedef struct
+			{
+				uint8_t       ReponseCode;
+
+				uint8_t       SegmentNumber;
+				
+				unsigned char SenseKey            : 4;
+				unsigned char _RESERVED1          : 1;
+				unsigned char ILI                 : 1;
+				unsigned char EOM                 : 1;
+				unsigned char FileMark            : 1;
+				
+				uint8_t      Information[4];
+				uint8_t      AdditionalLength;
+				uint8_t      CmdSpecificInformation[4];
+				uint8_t      AdditionalSenseCode;
+				uint8_t      AdditionalSenseQualifier;
+				uint8_t      FieldReplaceableUnitCode;
+				uint8_t      SenseKeySpecific[3];
+			} SCSI_Request_Sense_Response_t;
+
+			/** Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
+			 *  device via the MassStore_Inquiry() function, retrieving the attached device's information.
+			 *  For details of the structure contents, refer to the SCSI specifications.
+			 */
+			typedef struct
+			{
+				unsigned char DeviceType          : 5;
+				unsigned char PeripheralQualifier : 3;
+				
+				unsigned char _RESERVED1          : 7;
+				unsigned char Removable           : 1;
+				
+				uint8_t      Version;
+				
+				unsigned char ResponseDataFormat  : 4;
+				unsigned char _RESERVED2          : 1;
+				unsigned char NormACA             : 1;
+				unsigned char TrmTsk              : 1;
+				unsigned char AERC                : 1;
+
+				uint8_t      AdditionalLength;
+				uint8_t      _RESERVED3[2];
+
+				unsigned char SoftReset           : 1;
+				unsigned char CmdQue              : 1;
+				unsigned char _RESERVED4          : 1;
+				unsigned char Linked              : 1;
+				unsigned char Sync                : 1;
+				unsigned char WideBus16Bit        : 1;
+				unsigned char WideBus32Bit        : 1;
+				unsigned char RelAddr             : 1;
+				
+				uint8_t      VendorID[8];
+				uint8_t      ProductID[16];
+				uint8_t      RevisionID[4];
+			} SCSI_Inquiry_Response_t;
+			
+			/** SCSI capacity structure, to hold the total capacity of the device in both the number
+			 *  of blocks in the current LUN, and the size of each block. This structure is filled by
+			 *  the device when the MassStore_ReadCapacity() function is called.
+			 */
+			typedef struct
+			{
+				uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device */
+				uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN */
+			} SCSI_Capacity_t;
+
 		/* Enums: */
 			enum
 			{
 				MS_ENUMERROR_NoError                    = 0, /**< Configuration Descriptor was processed successfully */
 				MS_ENUMERROR_InvalidConfigDescriptor    = 1, /**< The device returned an invalid Configuration Descriptor */
-				MS_ENUMERROR_NoMSInterfaceFound        = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor */
+				MS_ENUMERROR_NoMSInterfaceFound         = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor */
 				MS_ENUMERROR_EndpointsNotFound          = 3, /**< Compatible Mass Storage endpoints were not found in the device's interfaces */
 			} MSHost_EnumerationFailure_ErrorCodes_t;
 	
 		/* Function Prototypes: */
-			void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* MSInterfaceInfo);
+			/** General management task for a given Mass Storage host class interface, required for the correct operation of
+			 *  the interface. This should be called frequently in the main program loop, before the master USB management task
+			 *  \ref USB_USBTask().
+			 *
+			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing an MS Class host configuration and state
+			 */
+			void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+			
+			/** Host interface configuration routine, to configure a given Mass Storage host interface instance using the
+			 *  Configuration Descriptor read from an attached USB device. This function automatically updates the given Mass
+			 *  Storage Host instance's state values and configures the pipes required to communicate with the interface if it
+			 *  is found within the device. This should be called once after the stack has enumerated the attached device, while
+			 *  the host state machine is in the Addressed state.
+			 *
+			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing an MS Class host configuration and state
+			 *  \param[in] ConfigDescriptorLength  Length of the attached device's Configuration Descriptor
+			 *  \param[in] DeviceConfigDescriptor  Pointer to a buffer containing the attached device's Configuration Descriptor
+			 */
 			uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint16_t ConfigDescriptorLength,
-			                               uint8_t* DeviceConfigDescriptor);
+			                               uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3);
+
+			/** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface
+			 *  and readying it for the next Mass Storage command.
+			 *
+			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing a MS Class host configuration and state
+			 *
+			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
+			 */
+			uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+			uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t* MaxLUNIndex) ATTR_NON_NULL_PTR_ARG(1, 2);
+
+			uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* MSInterfaceInfo,
+			                               SCSI_Inquiry_Response_t* InquiryData) ATTR_NON_NULL_PTR_ARG(1, 2);
+
+			uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t LUNIndex,
+			                              bool* DeviceReady) ATTR_NON_NULL_PTR_ARG(1, 3);
+
+			uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t LUNIndex,
+			                                   SCSI_Capacity_t* DeviceCapacity) ATTR_NON_NULL_PTR_ARG(1, 3);
 		
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
@@ -105,6 +217,17 @@
 			#define MASS_STORE_SUBCLASS            0x06
 			#define MASS_STORE_PROTOCOL            0x50
 
+			#define REQ_MassStorageReset           0xFF
+			#define REQ_GetMaxLUN                  0xFE
+
+			#define CBW_SIGNATURE                  0x43425355UL
+			#define CSW_SIGNATURE                  0x53425355UL
+			
+			#define COMMAND_DIRECTION_DATA_OUT     (0 << 7)
+			#define COMMAND_DIRECTION_DATA_IN      (1 << 7)
+			
+			#define COMMAND_DATA_TIMEOUT_MS        2000
+
 			#define MS_FOUND_DATAPIPE_IN           (1 << 0)
 			#define MS_FOUND_DATAPIPE_OUT          (1 << 1)
 			
@@ -112,6 +235,14 @@
 			#if defined(INCLUDE_FROM_MS_CLASS_HOST_C)		
 				static uint8_t DComp_NextMassStorageInterface(void* CurrentDescriptor);
 				static uint8_t DComp_NextInterfaceBulkDataEndpoint(void* CurrentDescriptor);
+				
+				static uint8_t MassStore_SendCommand(USB_ClassInfo_MS_Host_t* MSInterfaceInfo,
+				                                     MS_CommandBlockWrapper_t* SCSICommandBlock);
+				static uint8_t MassStore_WaitForDataReceived(USB_ClassInfo_MS_Host_t* MSInterfaceInfo);
+				static uint8_t MassStore_SendReceiveData(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, 
+                                                         MS_CommandBlockWrapper_t* SCSICommandBlock, void* BufferPtr);
+				static uint8_t MassStore_GetReturnedStatus(USB_ClassInfo_MS_Host_t* MSInterfaceInfo,
+				                                           MS_CommandStatusWrapper_t* SCSICommandStatus);
 			#endif
 	#endif
 	
diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt
index 2f77e39d32b889a2add976dbe52b6013fe7637a8..37b079603b712254104192789c1d7f22a0eece4e 100644
--- a/LUFA/ManPages/FutureChanges.txt
+++ b/LUFA/ManPages/FutureChanges.txt
@@ -13,11 +13,16 @@
   *
   *  <b>Targeted for This Release:</b>
   *  - Finish Host Mode Class Drivers
+  *      ( ) Audio
+  *      (C) CDC
+  *      (S) HID
+  *      ( ) MIDI
+  *      (S) Mass Storage
+  *      ( ) Still Image
   *  - Add overviews of each of the officially supported boards to the manual
-  *  - Add hub support to match Atmel's stack
-  *  - Finish AVRISP Project
   *
   *  <b>Targeted for Future Releases:</b>
+  *  - Add hub support to match Atmel's stack
   *  - Add standardized descriptor names to device and host class driver structures
   *  - Remake AVRStudio project files
   *  - Add detailed overviews of how each demo works