aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-08-26 07:01:32 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-08-26 07:01:32 +0000
commitee744abb7efd5fef49782991d58895e10696809a (patch)
tree1efb545a069d2e969be60a7e4f827b26024ac13b
parentf547eb36080dacf275cd94fc3ddfb4c618c587fa (diff)
downloadlufa-ee744abb7efd5fef49782991d58895e10696809a.tar.gz
lufa-ee744abb7efd5fef49782991d58895e10696809a.tar.bz2
lufa-ee744abb7efd5fef49782991d58895e10696809a.zip
More work on the Mass Storage Host mode Class driver.
Added ATTR_NON_NULL_PTR_ARG() attributes to the class drivers to improve user code reliability by disallowing explicit NULL pointers as pointer parameters in function calls where the parameter must not be NULL. Disabled building of the Demos/Host/ClassDriver directory until Host Mode Class drivers are complete to prevent build errors in the meantime.
-rw-r--r--Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c4
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.h22
-rw-r--r--LUFA/Drivers/USB/Class/Device/CDC.h26
-rw-r--r--LUFA/Drivers/USB/Class/Device/HID.h12
-rw-r--r--LUFA/Drivers/USB/Class/Device/MIDI.h12
-rw-r--r--LUFA/Drivers/USB/Class/Device/MassStorage.h12
-rw-r--r--LUFA/Drivers/USB/Class/Device/RNDIS.h12
-rw-r--r--LUFA/Drivers/USB/Class/Host/CDC.h42
-rw-r--r--LUFA/Drivers/USB/Class/Host/HID.h12
-rw-r--r--LUFA/Drivers/USB/Class/Host/MassStorage.c188
-rw-r--r--LUFA/Drivers/USB/Class/Host/MassStorage.h137
-rw-r--r--LUFA/ManPages/FutureChanges.txt9
12 files changed, 407 insertions, 81 deletions
diff --git a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
index 19c77c378..0f9134fea 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 b1c5046c6..12a8acdd6 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 99f8eb2b2..dcb1762bd 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 d995c09aa..e3f091bfb 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 ce6778fd7..c7f7bd92c 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 b207c237e..4ab43987d 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 d9a5d7f0b..4b024d953 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 5baafafe5..f3abb296e 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 3d7a5390a..6e1a5222b 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 6332d3a61..ea7ed3d8a 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 18b2cf4ae..a8a957bab 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 2f77e39d3..37b079603 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