diff --git a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c index 19c77c3785..0f9134fea6 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 b1c5046c6c..12a8acdd62 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 99f8eb2b2b..dcb1762bd5 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 d995c09aa2..e3f091bfb4 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 ce6778fd78..c7f7bd92c4 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 b207c237e2..4ab43987da 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 d9a5d7f0be..4b024d9537 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 5baafafe5d..f3abb296e7 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 3d7a5390a0..6e1a5222b8 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 6332d3a612..ea7ed3d8a3 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 18b2cf4aef..a8a957bab4 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 * may 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 2f77e39d32..37b079603b 100644 --- a/LUFA/ManPages/FutureChanges.txt +++ b/LUFA/ManPages/FutureChanges.txt @@ -13,11 +13,16 @@ * * Targeted for This Release: * - 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 * * Targeted for Future Releases: + * - 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