diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index a6e4b24f..28d4c6be 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/usbx_device_classes) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/usbx_host_classes) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/usbx_host_controllers) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/usbx_network) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/usbx_pictbridge) diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h index 86613b0a..b8f0c6eb 100755 --- a/common/core/inc/ux_api.h +++ b/common/core/inc/ux_api.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* ux_api.h PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -115,6 +115,13 @@ /* standalone compiling error, */ /* added CCID trace IDs, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added feedback size defs, */ +/* added shared device config */ +/* descriptor for enum scan, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -282,7 +289,7 @@ typedef signed char SCHAR; #define AZURE_RTOS_USBX #define USBX_MAJOR_VERSION 6 #define USBX_MINOR_VERSION 1 -#define USBX_PATCH_VERSION 11 +#define USBX_PATCH_VERSION 12 /* Macros for concatenating tokens, where UX_CONCATn concatenates n tokens. */ @@ -1130,6 +1137,9 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_MAX_NUMBER_OF_TRANSACTIONS_MASK 0x1800u #define UX_MAX_NUMBER_OF_TRANSACTIONS_SHIFT 11 +#define UX_FEEDBACK_SIZE_FULL_SPEED 3 /* 10.10 format fits into 3 bytes. */ +#define UX_FEEDBACK_SIZE_HIGH_SPEED 4 /* 12.13 format fits into 4 bytes. */ + #define UX_REQUEST_DIRECTION 0x80u #define UX_REQUEST_IN 0x80u #define UX_REQUEST_OUT 0x00u @@ -1261,9 +1271,9 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_DEVICE_CONNECTION 0x81u #define UX_DEVICE_DISCONNECTION 0x82u - + /* Host change callback events : _callback(event, NULL, NULL) */ - + #define UX_STANDALONE_WAIT_BACKGROUND_TASK 0x00u @@ -1398,6 +1408,7 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_INVALID_STATE 0xfb #define UX_INVALID_PARAMETER 0xfa #define UX_ABORTED 0xf9 +#define UX_MATH_OVERFLOW 0xf8 #define UX_TOO_MANY_DEVICES 0x11 #define UX_MEMORY_INSUFFICIENT 0x12 @@ -1469,6 +1480,7 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_HOST_CLASS_AUDIO_WRONG_TYPE 0x80 #define UX_HOST_CLASS_AUDIO_WRONG_INTERFACE 0x81 +#define UX_HOST_CLASS_AUDIO_WRONG_FREQUENCY 0x82 #define UX_CLASS_CDC_ECM_LINK_STATE_DOWN_ERROR 0x90 @@ -1898,6 +1910,8 @@ typedef struct UX_DEVICE_STRUCT ULONG ux_device_power_source; struct UX_CONFIGURATION_STRUCT *ux_device_current_configuration; + UCHAR *ux_device_packed_configuration; + ULONG ux_device_packed_configuration_keep_count; #if !defined(UX_HOST_STANDALONE) UX_SEMAPHORE ux_device_protection_semaphore; #endif @@ -2709,7 +2723,7 @@ UINT ux_host_stack_class_instance_get(UX_HOST_CLASS *host_class, UINT class_i UINT ux_host_stack_class_register(UCHAR *class_name, UINT (*class_entry_function)(struct UX_HOST_CLASS_COMMAND_STRUCT *)); UINT ux_host_stack_class_unregister(UINT (*class_entry_function)(struct UX_HOST_CLASS_COMMAND_STRUCT *)); UINT ux_host_stack_configuration_interface_get(UX_CONFIGURATION *configuration, UINT interface_index, - UINT alternate_setting_index, UX_INTERFACE **interface); + UINT alternate_setting_index, UX_INTERFACE **ux_interface); UINT ux_host_stack_device_configuration_activate(UX_CONFIGURATION *configuration); UINT ux_host_stack_device_configuration_deactivate(UX_DEVICE *device); UINT ux_host_stack_device_configuration_get(UX_DEVICE *device, UINT configuration_index, UX_CONFIGURATION **configuration); @@ -2721,8 +2735,8 @@ UINT ux_host_stack_hcd_register(UCHAR *hcd_name, UINT (*hcd_initialize_functi UINT ux_host_stack_hcd_unregister(UCHAR *hcd_name, ULONG hcd_param1, ULONG hcd_param2); UINT ux_host_stack_initialize(UINT (*ux_system_host_change_function)(ULONG, UX_HOST_CLASS *, VOID *)); UINT ux_host_stack_uninitialize(VOID); -UINT ux_host_stack_interface_endpoint_get(UX_INTERFACE *interface, UINT endpoint_index, UX_ENDPOINT **endpoint); -UINT ux_host_stack_interface_setting_select(UX_INTERFACE *interface); +UINT ux_host_stack_interface_endpoint_get(UX_INTERFACE *ux_interface, UINT endpoint_index, UX_ENDPOINT **endpoint); +UINT ux_host_stack_interface_setting_select(UX_INTERFACE *ux_interface); UINT ux_host_stack_transfer_request(UX_TRANSFER *transfer_request); UINT ux_host_stack_transfer_request_abort(UX_TRANSFER *transfer_request); VOID ux_host_stack_hnp_polling_thread_entry(ULONG id); @@ -2762,11 +2776,11 @@ UINT ux_device_stack_initialize(UCHAR * device_framework_high_speed, ULONG de UCHAR * language_id_framework, ULONG language_id_framework_length, UINT (*ux_system_slave_change_function)(ULONG)); UINT ux_device_stack_uninitialize(VOID); -UINT ux_device_stack_interface_delete(UX_SLAVE_INTERFACE *interface); +UINT ux_device_stack_interface_delete(UX_SLAVE_INTERFACE *ux_interface); UINT ux_device_stack_interface_get(UINT interface_value); UINT ux_device_stack_interface_set(UCHAR * device_framework, ULONG device_framework_length, ULONG alternate_setting_value); -UINT ux_device_stack_interface_start(UX_SLAVE_INTERFACE *interface); +UINT ux_device_stack_interface_start(UX_SLAVE_INTERFACE *ux_interface); UINT ux_device_stack_transfer_request(UX_SLAVE_TRANSFER *transfer_request, ULONG slave_length, ULONG host_length); UINT ux_device_stack_transfer_request_abort(UX_SLAVE_TRANSFER *transfer_request, ULONG completion_code); diff --git a/common/core/inc/ux_class_audio10.h b/common/core/inc/ux_class_audio10.h new file mode 100644 index 00000000..5ccab931 --- /dev/null +++ b/common/core/inc/ux_class_audio10.h @@ -0,0 +1,1201 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* COMPONENT DEFINITION RELEASE */ +/* */ +/* ux_class_audio10.h PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains all the header and structures used by the */ +/* USBX Audio Class (UAC) 1.0. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ + +#ifndef UX_CLASS_AUDIO10_H +#define UX_CLASS_AUDIO10_H + +/* Define Audio Class Codes. */ + +#define UX_CLASS_AUDIO10_CLASS 0x01 +#define UX_CLASS_AUDIO10_SUBCLASS_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_SUBCLASS_AUDIOCONTROL 0x01 +#define UX_CLASS_AUDIO10_SUBCLASS_AUDIOSTREAMING 0x02 +#define UX_CLASS_AUDIO10_SUBCLASS_MIDISTREAMING 0x03 +#define UX_CLASS_AUDIO10_PROTOCOL_UNDEFINED 0x00 + + +/* Define Audio Class desctiptor types. */ +#define UX_CLASS_AUDIO10_CS_UNDEFINED 0x20 +#define UX_CLASS_AUDIO10_CS_DEVICE 0x21 +#define UX_CLASS_AUDIO10_CS_CONFIGURATION 0x22 +#define UX_CLASS_AUDIO10_CS_STRING 0x23 +#define UX_CLASS_AUDIO10_CS_INTERFACE 0x24 +#define UX_CLASS_AUDIO10_CS_ENDPOINT 0x25 + + +/* Define Audio Class AC interface descriptor subclasses. */ + +#define UX_CLASS_AUDIO10_AC_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_AC_HEADER 0x01 +#define UX_CLASS_AUDIO10_AC_INPUT_TERMINAL 0x02 +#define UX_CLASS_AUDIO10_AC_OUTPUT_TERMINAL 0x03 +#define UX_CLASS_AUDIO10_AC_MIXER_UNIT 0x04 +#define UX_CLASS_AUDIO10_AC_SELECTOR_UNIT 0x05 +#define UX_CLASS_AUDIO10_AC_FEATURE_UNIT 0x06 +#define UX_CLASS_AUDIO10_AC_PROCESSING_UNIT 0x07 +#define UX_CLASS_AUDIO10_AC_EXTENSION_UNIT 0x08 + + +/* Define Audio Class Processing Unit (PU) Process Types (PT). */ + +#define UX_CLASS_AUDIO10_PROCESS_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_PROCESS_UP_DOWN_MIX 0x01 +#define UX_CLASS_AUDIO10_PROCESS_DOLBY_PROLOGIC 0x02 +#define UX_CLASS_AUDIO10_PROCESS_3D_STEREO_EXTENDER 0x03 +#define UX_CLASS_AUDIO10_PROCESS_REVERBERATION 0x04 +#define UX_CLASS_AUDIO10_PROCESS_CHORUS 0x05 +#define UX_CLASS_AUDIO10_PROCESS_DYN_RANGE_COMP 0x06 + + +/* Define Audio Class AS interface descriptor subclasses. */ + +#define UX_CLASS_AUDIO10_AS_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_AS_GENERAL 0x01 +#define UX_CLASS_AUDIO10_AS_FORMAT_TYPE 0x02 +#define UX_CLASS_AUDIO10_AS_FORMAT_SPECIFIC 0x03 + + +/* Define Audio Class endpoint descriptor subtypes. */ + +#define UX_CLASS_AUDIO10_EP_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_EP_GENERAL 0x01 + + +/* Define Audio Class request codes. */ + +#define UX_CLASS_AUDIO10_REQUEST_CODE_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_SET_CUR 0x01 +#define UX_CLASS_AUDIO10_GET_CUR 0x81 +#define UX_CLASS_AUDIO10_SET_MIN 0x02 +#define UX_CLASS_AUDIO10_GET_MIN 0x82 +#define UX_CLASS_AUDIO10_SET_MAX 0x03 +#define UX_CLASS_AUDIO10_GET_MAX 0x83 +#define UX_CLASS_AUDIO10_SET_RES 0x04 +#define UX_CLASS_AUDIO10_GET_RES 0x84 +#define UX_CLASS_AUDIO10_SET_MEM 0x05 +#define UX_CLASS_AUDIO10_GET_MEM 0x85 +#define UX_CLASS_AUDIO10_GET_STAT 0xFF + + +/* Define Audio Class terminal control selectors. */ + +#define UX_CLASS_AUDIO10_TE_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_TE_COPY_PROTECT_CONTROL 0x01 + +/* Define Audio Class feature unit control selectors. */ + +#define UX_CLASS_AUDIO10_FU_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_FU_MUTE_CONTROL 0x01 +#define UX_CLASS_AUDIO10_FU_VOLUME_CONTROL 0x02 +#define UX_CLASS_AUDIO10_FU_BASS_CONTROL 0x03 +#define UX_CLASS_AUDIO10_FU_MID_CONTROL 0x04 +#define UX_CLASS_AUDIO10_FU_TREBLE_CONTROL 0x05 +#define UX_CLASS_AUDIO10_FU_GRAPHIC_EQUALIZER_CONTROL 0x06 +#define UX_CLASS_AUDIO10_FU_AUTOMATIC_GAIN_CONTROL 0x07 +#define UX_CLASS_AUDIO10_FU_DELAY_CONTROL 0x08 +#define UX_CLASS_AUDIO10_FU_BASS_BOOST_CONTROL 0x09 +#define UX_CLASS_AUDIO10_FU_LOUNDNESS_CONTROL 0x0A + + +/* Define Audio Class processing unit control selectors. */ + +/* Define Audio Class up/down-mix (UD) processing unit control selectors. */ + +#define UX_CLASS_AUDIO10_UD_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_UD_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO10_UD_MODE_SELECT_CONTROL 0x02 + +/* Define Audio Class dolby prologic (DP) processing unit control selectors. */ + +#define UX_CLASS_AUDIO10_DP_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_DP_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO10_DP_MODE_SELECT_CONTROL 0x02 + +/* Define Audio Class 3D stereo extender (3D) processing unit control selectors. */ + +#define UX_CLASS_AUDIO10_3D_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_3D_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO10_3D_SPACIOUSNESS_CONTROL 0x02 + +/* Define Audio Class reverberation (RV) processing unit control selectors. */ + +#define UX_CLASS_AUDIO10_RV_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_RV_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO10_RV_LEVEL_CONTROL 0x02 +#define UX_CLASS_AUDIO10_RV_TIME_CONTROL 0x03 +#define UX_CLASS_AUDIO10_RV_FEEDBACK_CONTROL 0x04 + +/* Define Audio Class chorus (CH) processing unit control selectors. */ + +#define UX_CLASS_AUDIO10_CHORUS_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_CHORUS_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO10_CHORUS_LEVEL_CONTROL 0x02 +#define UX_CLASS_AUDIO10_CHORUS_RATE_CONTROL 0x03 +#define UX_CLASS_AUDIO10_CHORUS_DEPTH_CONTROL 0x04 + +/* Define Audio Class dynamic range compressor (DR) processing unit control selectors. */ + +#define UX_CLASS_AUDIO10_DR_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_DR_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO10_DR_COMPRESSION_RATE_CONTROL 0x02 +#define UX_CLASS_AUDIO10_DR_MAXAMPL_CONTROL 0x03 +#define UX_CLASS_AUDIO10_DR_THRESHOLD_CONTROL 0x04 +#define UX_CLASS_AUDIO10_DR_ATTACK_TIME 0x05 +#define UX_CLASS_AUDIO10_DR_RELEASE_TIME 0x06 + +/* Define Audio Class extension unit (XU) control selectors. */ + +#define UX_CLASS_AUDIO10_XU_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_XU_ENABLE_CONTROL 0x01 + + +/* Define Audio Class endpoint control selectors. */ + +#define UX_CLASS_AUDIO10_EP_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_EP_SAMPLING_FREQ_CONTROL 0x01 +#define UX_CLASS_AUDIO10_EP_PITCH_CONTROL 0x02 + + +/* Define Audio Class format type codes. */ + +#define UX_CLASS_AUDIO10_FORMAT_TYPE_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_I 0x01 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_II 0x02 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III 0x03 + +/* Define Audio Class format tag codes. */ + +#define UX_CLASS_AUDIO10_FORMAT_TYPE_I_UNDEFINED 0x0000 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_I_PCM 0x0001 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_I_PCM8 0x0002 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_I_IEEE_FLOAT 0x0003 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_I_ALAW 0x0004 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_I_MULAW 0x0005 + +#define UX_CLASS_AUDIO10_FORMAT_TYPE_II_UNDEFINED 0x1000 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_II_MPEG 0x1001 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_II_AC3 0x1002 + +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III_UNDEFINED 0x2000 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III_IEC1937_AC3 0x2001 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III_IEC1937_MPEG1_L1 0x2002 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III_IEC1937_MPEG1_L2_3 0x2003 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III_IEC1937_MPEG2_NOEXT 0x2003 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III_IEC1937_MPEG2_EXT 0x2004 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III_IEC1937_MPEG2_L1_LS 0x2005 +#define UX_CLASS_AUDIO10_FORMAT_TYPE_III_IEC1937_MPEG2_L2_3_LS 0x2006 + + +/* Define Audio Class MPEG (MP) control selectors. */ + +#define UX_CLASS_AUDIO10_MP_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_MP_DUAL_CHANNEL_CONTROL 0x01 +#define UX_CLASS_AUDIO10_MP_SECOND_STEREO_CONTROL 0x02 +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_CONTROL 0x03 +#define UX_CLASS_AUDIO10_MP_DYN_RANGE_CONTROL 0x04 +#define UX_CLASS_AUDIO10_MP_SCALING_CONTROL 0x05 +#define UX_CLASS_AUDIO10_MP_HILO_SCALING_CONTROL 0x06 + +/* Define Audio Class AC-3 (AC) control selectors. */ + +#define UX_CLASS_AUDIO10_AC_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO10_AC_MODE_CONTROL 0x01 +#define UX_CLASS_AUDIO10_AC_DYN_RANGE_CONTROL 0x02 +#define UX_CLASS_AUDIO10_AC_SCALING_CONTROL 0x03 +#define UX_CLASS_AUDIO10_AC_HILO_SCALING_CONTROL 0x04 + + +/* Class descriptor structures (packed). + * Typedefs to be used: + * - for byte : UCHAR/CHAR + * - for word : USHORT/SHORT + * - for double word (dword): ULONG/LONG + * - for 64-bit-width word : ULONG64 + * Field offset considerations inside descriptor: + * - Minimum fields alignment: byte (8-bit) + * - Field is not byte and not aligned : field declared as bytes array (UCHAR[]) + * - Field is word and word aligned : field declared as USHORT/SHORT + * - Field is dword and dword aligned : field declared as ULONG/LONG + */ + + +/* Audio Class AC interface header descriptors (bInCollection=1). */ + +typedef struct UX_CLASS_AUDIO10_AC_HEADER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bcdADC[2]; + UCHAR wTotalLength[2]; + UCHAR bInCollection; + UCHAR baInterfaceNr[1]; +} UX_CLASS_AUDIO10_AC_HEADER_DESCRIPTOR; + +/* Define Audio Class input terminal descriptor (ITD). */ + +typedef struct UX_CLASS_AUDIO10_AC_INPUT_TERMINAL_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR bNrChannels; + USHORT wChannelConfig; + UCHAR iChannelNames; + UCHAR iTerminal; +} UX_CLASS_AUDIO10_AC_INPUT_TERMINAL_DESCRIPTOR, UX_CLASS_AUDIO10_AC_ITD; + +/* Define Audio Class output terminal descriptor (OTD). */ + +typedef struct UX_CLASS_AUDIO10_AC_OUTPUT_TERMINAL_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR bSourceID; + UCHAR iTerminal; +} UX_CLASS_AUDIO10_AC_OUTPUT_TERMINAL_DESCRIPTOR, UX_CLASS_AUDIO10_AC_OTD; + +/* Define Audio Class mixer unit descriptor (MUD, bNrInPins=1, bmMixerControls N=1). */ + +typedef struct UX_CLASS_AUDIO10_AC_MIXER_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + UCHAR wChannelConfig[2]; + UCHAR iChannelNames; + UCHAR bmControls[1]; + UCHAR iMixer; +} UX_CLASS_AUDIO10_AC_MIXER_UNIT_DESCRIPTOR, UX_CLASS_AUDIO10_AC_MUD; + +/* Define Audio Class selector unit descriptor (SUD, bNrInPins=1). */ + +typedef struct UX_CLASS_AUDIO10_AC_SELECTOR_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR iSelector; +} UX_CLASS_AUDIO10_AC_SELECTOR_UNIT_DESCRIPTOR, UX_CLASS_AUDIO10_AC_SUD; + +/* Define Audio Class feature unit descriptor (FUD, ch=1, bControlSize=2). */ + +typedef struct UX_CLASS_AUDIO10_AC_FEATURE_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bSourceID; + UCHAR bControlSize; + UCHAR bmaControls[2 * 2]; + UCHAR iFeature; +} UX_CLASS_AUDIO10_AC_FEATURE_UNIT_DESCRIPTOR, UX_CLASS_AUDIO10_AC_FUD; + +/* FUD::bmControls. */ +#define UX_CLASS_AUDIO10_FUD_CONTROL_MUTE (1u << 0) +#define UX_CLASS_AUDIO10_FUD_CONTROL_VOLUME (1u << 1) +#define UX_CLASS_AUDIO10_FUD_CONTROL_BASS (1u << 2) +#define UX_CLASS_AUDIO10_FUD_CONTROL_MID (1u << 3) +#define UX_CLASS_AUDIO10_FUD_CONTROL_TREBLE (1u << 4) +#define UX_CLASS_AUDIO10_FUD_CONTROL_GRAPHIC_EQ (1u << 5) +#define UX_CLASS_AUDIO10_FUD_CONTROL_AUTO_GAIN (1u << 6) +#define UX_CLASS_AUDIO10_FUD_CONTROL_DELAY (1u << 7) +#define UX_CLASS_AUDIO10_FUD_CONTROL_BASS_BOOST (1u << 8) +#define UX_CLASS_AUDIO10_FUD_CONTROL_LOUDNESS (1u << 9) + +/* Define Audio Class processing unit descriptor (PUD, bNrInPins=1,bControlSize=1). */ + +typedef struct UX_CLASS_AUDIO10_AC_PROCESSING_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + USHORT wProcessType; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + UCHAR wChannelConfig; + UCHAR iChannelNames; + UCHAR bControlSize; + UCHAR bmControls[1]; + UCHAR iProcessing; +} UX_CLASS_AUDIO10_AC_PROCESSING_UNIT_DESCRIPTOR, UX_CLASS_AUDIO10_AC_PUD; + +/* Define Audio Class up/down processing unit descriptor (PUD, bNrInPins=1,bControlSize=1,bNrModes=1). */ + +typedef struct UX_CLASS_AUDIO10_AC_UP_DOWN_PROCESSING_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + USHORT wProcessType; + UCHAR bNrInPins; + UCHAR bSourceID; + UCHAR bNrChannels; + UCHAR wChannelConfig[2]; + UCHAR iChannelNames; + UCHAR bControlSize; + UCHAR bmControls[1]; + UCHAR iProcessing; + UCHAR bNrModes; + UCHAR waModes[2 * 1]; +} UX_CLASS_AUDIO10_AC_UP_DOWN_PROCESSING_UNIT_DESCRIPTOR, UX_CLASS_AUDIO10_AC_UDD; + +/* UDD::bmControls. */ +#define UX_CLASS_AUDIO10_UDD_CONTROL_ENABLE (1u << 0) +#define UX_CLASS_AUDIO10_UDD_CONTROL_MODE_SELECT (1u << 1) + +/* Define Audio Class dolby prologic processing unit descriptor (DPD, bNrInPins=1,bControlSize=1,bNrModes=1). */ + +typedef struct UX_CLASS_AUDIO10_AC_DOLBY_PROCESSING_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + USHORT wProcessType; + UCHAR bNrInPins; + UCHAR bSourceID; + UCHAR bNrChannels; + UCHAR wChannelConfig[2]; + UCHAR iChannelNames; + UCHAR bControlSize; + UCHAR bmControls[1]; + UCHAR iProcessing; + UCHAR bNrModes; + UCHAR daModes[2 * 1]; +} UX_CLASS_AUDIO10_AC_DOLBY_PROCESSING_UNIT_DESCRIPTOR, UX_CLASS_AUDIO10_AC_DPD; + +/* DPD::bmaControls. */ +#define UX_CLASS_AUDIO10_DPD_CONTROL_ENABLE (1u << 0) +#define UX_CLASS_AUDIO10_DPD_CONTROL_MODE_SELECT (1u << 1) + +/* Define Audio Class 3D Stereo Extender (3D) Processing Unit Descriptor. */ +typedef UX_CLASS_AUDIO10_AC_PUD UX_CLASS_AUDIO10_AC_3D_STEREO_EXT_PROCESSING_UNIT_DESCRIPTOR; +typedef UX_CLASS_AUDIO10_AC_PUD UX_CLASS_AUDIO10_AC_3DD; + +/* 3DD::bmaControls. */ +#define UX_CLASS_AUDIO10_3DD_CONTROL_ENABLE (1u << 0) +#define UX_CLASS_AUDIO10_3DD_CONTROL_MODE_SELECT (1u << 1) + +/* Define Audio Class Reverberation (RV) Processing Unit Descriptor. */ +typedef UX_CLASS_AUDIO10_AC_PUD UX_CLASS_AUDIO10_AC_REVERBERATION_PROCESSING_UNIT_DESCRIPTOR; +typedef UX_CLASS_AUDIO10_AC_PUD UX_CLASS_AUDIO10_AC_RVD; + +/* RVD::bmaControls. */ +#define UX_CLASS_AUDIO10_RVD_CONTROL_ENABLE (1u << 0) +#define UX_CLASS_AUDIO10_RVD_CONTROL_REVERB_TYPE (1u << 1) +#define UX_CLASS_AUDIO10_RVD_CONTROL_REVERB_LEVEL (1u << 2) +#define UX_CLASS_AUDIO10_RVD_CONTROL_REVERB_TIME (1u << 3) +#define UX_CLASS_AUDIO10_RVD_CONTROL_REVERB_DELAY_FEEDBACK (1u << 4) + +/* Define Audio Class Chorus (CH) Processing Unit Descriptor. */ +typedef UX_CLASS_AUDIO10_AC_PUD UX_CLASS_AUDIO10_AC_CHORUS_PROCESSING_UNIT_DESCRIPTOR; +typedef UX_CLASS_AUDIO10_AC_PUD UX_CLASS_AUDIO10_AC_CHORUSD; + +/* CHORUSD::bmaControls. */ +#define UX_CLASS_AUDIO10_CHORUSD_CONTROL_ENABLE (1u << 0) +#define UX_CLASS_AUDIO10_CHORUSD_CONTROL_CHORUS_LEVEL (1u << 1) +#define UX_CLASS_AUDIO10_CHORUSD_CONTROL_CHORUS_MODULATION_RATE (1u << 2) +#define UX_CLASS_AUDIO10_CHORUSD_CONTROL_CHORUS_MODULATION_DEPTH (1u << 3) + +/* Define Audio Class Dynamic Range Compressor (DR) Processing Unit Descriptor. */ +typedef UX_CLASS_AUDIO10_AC_PUD UX_CLASS_AUDIO10_AC_DYN_RNG_COMP_PROCESSING_UNIT_DESCRIPTOR; +typedef UX_CLASS_AUDIO10_AC_PUD UX_CLASS_AUDIO10_AC_DRD; + +/* DRD::bmaControls. */ +#define UX_CLASS_AUDIO10_DRD_CONTROL_ENABLE (1u << 0) +#define UX_CLASS_AUDIO10_DRD_CONTROL_COMPRESSION_RATIO (1u << 1) +#define UX_CLASS_AUDIO10_DRD_CONTROL_MAXAMPL (1u << 2) +#define UX_CLASS_AUDIO10_DRD_CONTROL_THRESHOLD (1u << 3) +#define UX_CLASS_AUDIO10_DRD_CONTROL_ATTACH_TIME (1u << 4) +#define UX_CLASS_AUDIO10_DRD_CONTROL_RELEASE_TIME (1u << 5) + +/* Define Audio Class Extension unit descriptor (XUD, bNrInPins=1,bControlSize=1). */ + +typedef struct UX_CLASS_AUDIO10_AC_EXTENSION_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + USHORT wExtensionCode; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + UCHAR wChannelConfig[2]; + UCHAR iChannelNames; + UCHAR bControlSize; + UCHAR bmControls[1]; + UCHAR iExtension; +} UX_CLASS_AUDIO10_AC_EXTENSION_UNIT_DESCRIPTOR, UX_CLASS_AUDIO10_AC_XUD; + +/* XUD::bmaControls. */ +#define UX_CLASS_AUDIO10_XUD_CONTROL_ENABLE (1u << 0) + +/* Define Audio Class Associated Interface descriptor (Association-specific x=1). */ + +typedef struct UX_CLASS_AUDIO10_ASSOCIATED_INTERFACE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bInterfaceNr; + UCHAR assoc_specific; +} UX_CLASS_AUDIO10_ASSOCIATED_INTERFACE_DESCRIPTOR; + +/* Define Audio Class Interrupt/Isochronous Endpoint Descriptor. */ + +typedef struct UX_CLASS_AUDIO10_ENDPOINT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bEndpointAddress; + UCHAR bmAttributes; + UCHAR wMaxPacketSize; + UCHAR bInterval; + UCHAR bRefresh; + UCHAR bSynchAddress; +} UX_CLASS_AUDIO10_ENDPOINT_DESCRIPTOR, UX_CLASS_AUDIO10_EPD; + +/* Audio class-specific AS interface descriptor. */ + +typedef struct UX_CLASS_AUDIO10_AS_INTERFACE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalLink; + UCHAR bDelay; + UCHAR wFormatTag[2]; +} UX_CLASS_AUDIO10_AS_INTERFACE_DESCRIPTOR, UX_CLASS_AUDIO10_AS_IFACED; + + +/* Audio class-specific isochronous audio data endpoint descriptor (EPD). */ + +typedef struct UX_CLASS_AUDIO10_ISOCH_ENDPOINT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bmAttributes; + UCHAR bLockDelayUnits; + UCHAR wLockDelay[2]; +} UX_CLASS_AUDIO10_ISOCH_ENDPOINT_DESCRIPTOR, UX_CLASS_AUDIO10_ISOCH_EPD; + +/* EPD::bmAttributes. */ +#define UX_CLASS_AUDIO10_ISOCH_EPD_ATTR_SAMPLING_FREQ (0x1u << 0) +#define UX_CLASS_AUDIO10_ISOCH_EPD_ATTR_PITCH (0x1u << 1) +#define UX_CLASS_AUDIO10_ISOCH_EPD_ATTR_MAX_PACKET_SIZE_ONLY (0x1u << 7) + +/* EPD::bLockDelayUnits. */ +#define UX_CLASS_AUDIO10_EPD_LOCK_DELAY_UNITS_UNDEFINED 0 +#define UX_CLASS_AUDIO10_EPD_LOCK_DELAY_UNITS_MS 1 +#define UX_CLASS_AUDIO10_EPD_LOCK_DELAY_UNITS_DEC_PCM_SAMPLES 2 + + +/* Audio class control request layout. */ + +typedef struct UX_CLASS_AUDIO10_REQUEST_VALUE_CS_STRUCT { + UCHAR unused_zero; + UCHAR control_sel; /* Control Selector (CS) */ +} UX_CLASS_AUDIO10_REQUEST_VALUE_CS; + +typedef struct UX_CLASS_AUDIO10_REQUEST_VALUE_MIXER_STRUCT { + UCHAR output_ch_num; /* Output Channel Number (OCN) */ + UCHAR input_ch_num; /* Input Channel Number (ICN) */ +} UX_CLASS_AUDIO10_REQUEST_VALUE_MIXER; + +typedef struct UX_CLASS_AUDIO10_REQUEST_VALUE_CONTROL_STRUCT { + UCHAR unused_zero; + UCHAR cs; /* CS */ +} UX_CLASS_AUDIO10_REQUEST_VALUE_CONTROL; + +typedef struct UX_CLASS_AUDIO10_REQUEST_INDEX_EP_STRUCT { + UCHAR ep_addr; /* Endpoint Address */ + UCHAR unused_zero; +} UX_CLASS_AUDIO10_REQUEST_INDEX_EP; + +typedef struct UX_CLASS_AUDIO10_REQUEST_INDEX_INTERFACE_STRUCT { + UCHAR iface_num; /* Interface number */ + UCHAR entity_id; +} UX_CLASS_AUDIO10_REQUEST_INDEX_INTERFACE; + +typedef struct UX_CLASS_AUDIO10_REQUEST_INDEX_CONTROL_STRUCT { + UCHAR ep_iface; /* Endpoint Address/Interface Number */ + UCHAR entity_id_zero; /* Entity ID/Zero */ +} UX_CLASS_AUDIO10_REQUEST_INDEX_CONTROL; + +typedef struct UX_CLASS_AUDIO10_REQUEST_STRUCT +{ + UCHAR bmRequestType; + UCHAR bRequest; + union UX_CLASS_AUDIO10_REQUEST_VALUE_UNION { + USHORT value; + UX_CLASS_AUDIO10_REQUEST_VALUE_CS + control_cs; + UX_CLASS_AUDIO10_REQUEST_VALUE_MIXER + control_mixer; + UX_CLASS_AUDIO10_REQUEST_VALUE_CONTROL + control; + USHORT mem_offset; + } wValue; + union UX_CLASS_AUDIO10_REQUEST_INDEX_UNION { + USHORT value; + UX_CLASS_AUDIO10_REQUEST_INDEX_EP + ep; + UX_CLASS_AUDIO10_REQUEST_INDEX_INTERFACE + iface; + UX_CLASS_AUDIO10_REQUEST_INDEX_CONTROL + control; + } wIndex; + USHORT wLength; +} UX_CLASS_AUDIO10_REQUEST; + +/* Audio Class 1.0 Copy Protect Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_COPY_PROTECT_CONTROL_PARAMETER_STRUCT +{ + UCHAR bCopyProtect; +} UX_CLASS_AUDIO10_COPY_PROTECT_CONTROL_PARAMETER; + +#define UX_CLASS_AUDIO10_COPY_PROTECT_CONTROL_CPL0 (1u << 0) +#define UX_CLASS_AUDIO10_COPY_PROTECT_CONTROL_CPL1 (1u << 1) +#define UX_CLASS_AUDIO10_COPY_PROTECT_CONTROL_CPL2 (1u << 2) + +/* Audio Class 1.0 Mixer Control Parameter (specific control or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_MIXER_CONTROL_PARAMETER_STRUCT +{ + USHORT wMixer; +} UX_CLASS_AUDIO10_MIXER_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_MIXER_CONTROL_PARAMETER_FF_STRUCT +{ + USHORT wMixer[1]; +} UX_CLASS_AUDIO10_MIXER_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Selector Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_SELECTOR_CONTROL_PARAMETER_STRUCT +{ + UCHAR bSelector; +} UX_CLASS_AUDIO10_SELECTOR_CONTROL_PARAMETER; + +/* Audio Class 1.0 Mute Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_MUTE_CONTROL_PARAMETER_STRUCT +{ + UCHAR bMute; +} UX_CLASS_AUDIO10_MUTE_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_MUTE_CONTROL_PARAMETER_FF_STRUCT +{ + UCHAR bMute[1]; +} UX_CLASS_AUDIO10_MUTE_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Volume Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_VOLUME_CONTROL_PARAMETER_STRUCT +{ + SHORT wVolume; +} UX_CLASS_AUDIO10_VOLUME_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_VOLUME_CONTROL_PARAMETER_FF_STRUCT +{ + SHORT wVolume[1]; +} UX_CLASS_AUDIO10_VOLUME_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Bass Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_BASS_CONTROL_PARAMETER_STRUCT +{ + UCHAR bBass; +} UX_CLASS_AUDIO10_BASS_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_BASS_CONTROL_PARAMETER_FF_STRUCT +{ + UCHAR bBass[1]; +} UX_CLASS_AUDIO10_BASS_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Mid Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_MID_CONTROL_PARAMETER_STRUCT +{ + UCHAR bMid; +} UX_CLASS_AUDIO10_MID_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_MID_CONTROL_PARAMETER_FF_STRUCT +{ + UCHAR bMid[1]; +} UX_CLASS_AUDIO10_MID_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Treble Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_TREBLE_CONTROL_PARAMETER_STRUCT +{ + UCHAR bTreble; +} UX_CLASS_AUDIO10_TREBLE_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_TREBLE_CONTROL_PARAMETER_FF_STRUCT +{ + UCHAR bTreble[1]; +} UX_CLASS_AUDIO10_TREBLE_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Graphic Equalizer Control Parameter (NrBits=1) */ + +typedef struct UX_CLASS_AUDIO10_GRAPHIC_EQ_CONTROL_PARAMETER_STRUCT +{ + ULONG bmBandsPresent; + UCHAR bBand[1]; +} UX_CLASS_AUDIO10_GRAPHIC_EQ_CONTROL_PARAMETER; + +/* Audio Class 1.0 Automatic Gain Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_AG_CONTROL_PARAMETER_STRUCT +{ + UCHAR bAGC; +} UX_CLASS_AUDIO10_AG_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_AG_CONTROL_PARAMETER_FF_STRUCT +{ + UCHAR bAGC[1]; +} UX_CLASS_AUDIO10_AG_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Delay Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_DELAY_CONTROL_PARAMETER_STRUCT +{ + SHORT wDelay; +} UX_CLASS_AUDIO10_DELAY_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_DELAY_CONTROL_PARAMETER_FF_STRUCT +{ + SHORT wDelay[1]; +} UX_CLASS_AUDIO10_DELAY_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 BassBoost Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_BASSBOOST_CONTROL_PARAMETER_STRUCT +{ + UCHAR bBassBoost; +} UX_CLASS_AUDIO10_BASSBOOST_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_BASSBOOST_CONTROL_PARAMETER_FF_STRUCT +{ + UCHAR bBassBoost[1]; +} UX_CLASS_AUDIO10_BASSBOOST_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Loudness Control Parameter (specific CH or 0xFF) */ + +typedef struct UX_CLASS_AUDIO10_LOUDNESS_CONTROL_PARAMETER_STRUCT +{ + UCHAR bLoudness; +} UX_CLASS_AUDIO10_LOUDNESS_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_LOUDNESS_CONTROL_PARAMETER_FF_STRUCT +{ + UCHAR bLoudness[1]; +} UX_CLASS_AUDIO10_LOUDNESS_CONTROL_PARAMETER_FF; + +/* Audio Class 1.0 Enable Processing Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_ENABLE_PROCESSING_CONTROL_PARAMETER_STRUCT +{ + UCHAR bEnable; +} UX_CLASS_AUDIO10_ENABLE_PROCESSING_CONTROL_PARAMETER; + +/* Audio Class 1.0 Spaciousness Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_SPACIOUSNESS_CONTROL_PARAMETER_STRUCT +{ + UCHAR bSpaciousness; +} UX_CLASS_AUDIO10_SPACIOUSNESS_CONTROL_PARAMETER; + +/* Audio Class 1.0 ReverbType Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_REVERB_TYPE_CONTROL_PARAMETER_STRUCT +{ + UCHAR bReverbType; +} UX_CLASS_AUDIO10_REVERB_TYPE_CONTROL_PARAMETER; + +#define UX_CLASS_AUDIO10_REVERB_TYPE_ROOM_1 0 +#define UX_CLASS_AUDIO10_REVERB_TYPE_SMALL_ROOM 0 +#define UX_CLASS_AUDIO10_REVERB_TYPE_ROOM_2 1 +#define UX_CLASS_AUDIO10_REVERB_TYPE_MEDIUM_ROOM 1 +#define UX_CLASS_AUDIO10_REVERB_TYPE_ROOM_3 2 +#define UX_CLASS_AUDIO10_REVERB_TYPE_LARGE_ROOM 2 +#define UX_CLASS_AUDIO10_REVERB_TYPE_HALL_1 3 +#define UX_CLASS_AUDIO10_REVERB_TYPE_MEDIUM_CONCERT_HALL 3 +#define UX_CLASS_AUDIO10_REVERB_TYPE_HALL_2 4 +#define UX_CLASS_AUDIO10_REVERB_TYPE_LARGE_CONCERT_HALL 4 +#define UX_CLASS_AUDIO10_REVERB_TYPE_PLATE 5 +#define UX_CLASS_AUDIO10_REVERB_TYPE_PLATE_REVERBERATION 5 +#define UX_CLASS_AUDIO10_REVERB_TYPE_DELAY 6 +#define UX_CLASS_AUDIO10_REVERB_TYPE_PANNING_DELAY 7 + +/* Audio Class 1.0 ReverbLevel Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_REVERB_LEVEL_CONTROL_PARAMETER_STRUCT +{ + UCHAR bReverbLevel; +} UX_CLASS_AUDIO10_REVERB_LEVEL_CONTROL_PARAMETER; + +/* Audio Class 1.0 ReverTime Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_REVERB_TIME_CONTROL_PARAMETER_STRUCT +{ + USHORT wReverTime; +} UX_CLASS_AUDIO10_REVERB_TIME_CONTROL_PARAMETER; + +/* Audio Class 1.0 ReverbDelayFeedback Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_REVERB_FEEDBACK_CONTROL_PARAMETER_STRUCT +{ + UCHAR bReverbFeedback; +} UX_CLASS_AUDIO10_REVERB_FEEDBACK_CONTROL_PARAMETER; + +/* Audio Class 1.0 ChorusLevel Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_CHORUS_LEVEL_CONTROL_PARAMETER_STRUCT +{ + UCHAR bChorusLevel; +} UX_CLASS_AUDIO10_CHORUS_LEVEL_CONTROL_PARAMETER; + +/* Audio Class 1.0 ChorusRate Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_CHORUS_RATE_CONTROL_PARAMETER_STRUCT +{ + USHORT wChorusRate; +} UX_CLASS_AUDIO10_CHORUS_RATE_CONTROL_PARAMETER; + +/* Audio Class 1.0 ChorusModulationDepth Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_CHORUS_DEPTH_CONTROL_PARAMETER_STRUCT +{ + USHORT wChorusDepth; +} UX_CLASS_AUDIO10_CHORUS_DEPTH_CONTROL_PARAMETER; + +/* Audio Class 1.0 Dynamic Range Compressor Compression Ratio Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_COMPRESSION_RATIO_CONTROL_PARAMETER_STRUCT +{ + USHORT wRatio; +} UX_CLASS_AUDIO10_COMPRESSION_RATIO_CONTROL_PARAMETER; + +/* Audio Class 1.0 Dynamic Range Compressor MaxAmpl Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_MAXAMPL_CONTROL_PARAMETER_STRUCT +{ + USHORT wMaxAmpl; +} UX_CLASS_AUDIO10_MAXAMPL_CONTROL_PARAMETER; + +/* Audio Class 1.0 Dynamic Range Compressor Threshold Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_THRESHOLD_CONTROL_PARAMETER_STRUCT +{ + USHORT wThreshold; +} UX_CLASS_AUDIO10_THRESHOLD_CONTROL_PARAMETER; + +/* Audio Class 1.0 Dynamic Range Compressor AttachTime Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_ATTACK_TIME_CONTROL_PARAMETER_STRUCT +{ + USHORT wAttachTime; +} UX_CLASS_AUDIO10_ATTACK_TIME_CONTROL_PARAMETER; + +/* Audio Class 1.0 Dynamic Range Compressor ReleaseTime Control Parameter */ + +typedef struct UX_CLASS_AUDIO10_RELEASE_TIME_CONTROL_PARAMETER_STRUCT +{ + USHORT wReleaseTime; +} UX_CLASS_AUDIO10_RELEASE_TIME_CONTROL_PARAMETER; + +/* Audio Class 1.0 Enable Processing Control (XU_ENABLE_CONTROL) Parameter */ + +typedef struct UX_CLASS_AUDIO10_XU_ENABLE_CONTROL_PARAMETER_STRUCT +{ + UCHAR bOn; +} UX_CLASS_AUDIO10_XU_ENABLE_CONTROL_PARAMETER; + +/* Audio Class 1.0 Sampling Frequency Control (SAMPLING_FREQ_CONTROL) Parameter */ + +typedef struct UX_CLASS_AUDIO10_SAMPLING_FREQ_CONTROL_PARAMETER_STRUCT +{ + UCHAR tSampleFreq[3]; +} UX_CLASS_AUDIO10_SAMPLING_FREQ_CONTROL_PARAMETER; + +/* Audio Class 1.0 Pitch Control (PITCH_CONTROL) Parameter */ + +typedef struct UX_CLASS_AUDIO10_PITCH_CONTROL_PARAMETER_STRUCT +{ + UCHAR bPitchEnable; +} UX_CLASS_AUDIO10_PITCH_CONTROL_PARAMETER; + +/* Audio Class 1.0 Continuous Sampling Frequency. */ + +typedef struct UX_CLASS_AUDIO10_CONTINUOUS_SAMPLING_FREQ_STRUCT +{ + UCHAR tLowerSamFreq[3]; + UCHAR tUpperSamFreq[3]; +} UX_CLASS_AUDIO10_CONTINUOUS_SAMPLING_FREQ; + +/* Audio Class 1.0 Discrete Sampling Frequency (N=1). */ + +typedef struct UX_CLASS_AUDIO10_DISCRETE_SAMPLING_FREQ_STRUCT +{ + UCHAR tSamFreq[3 * 1]; +} UX_CLASS_AUDIO10_DISCRETE_SAMPLING_FREQ; + +/* Audio Class 1.0 Type I Format Type Descriptor */ + +typedef struct UX_CLASS_AUDIO10_TYPE_I_FORMAT_TYPE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + UCHAR bNrChannels; + UCHAR bSubframeSize; + UCHAR bBitResolution; + UCHAR bSamFreqType; +} UX_CLASS_AUDIO10_TYPE_I_FORMAT_TYPE_DESCRIPTOR; + +typedef struct UX_CLASS_AUDIO10_TYPE_I_FORMAT_TYPE_CONTINUOUS_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + UCHAR bNrChannels; + UCHAR bSubframeSize; + UCHAR bBitResolution; + UCHAR bSamFreqType; /* 0 */ + UCHAR tLowerSamFreq[3]; + UCHAR tUpperSamFreq[3]; +} +UX_CLASS_AUDIO10_TYPE_I_FORMAT_TYPE_CONTINUOUS_DESCRIPTOR, +UX_CLASS_AUDIO10_TYPE_I_FORMAT_TYPE_DESCRIPTOR_0; + +typedef struct UX_CLASS_AUDIO10_TYPE_I_FORMAT_TYPE_DISCRETE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + UCHAR bNrChannels; + UCHAR bSubframeSize; + UCHAR bBitResolution; + UCHAR bSamFreqType; /* 1 */ + UCHAR tSamFreq[3 * 1]; +} +UX_CLASS_AUDIO10_TYPE_I_FORMAT_TYPE_DISCRETE_DESCRIPTOR, +UX_CLASS_AUDIO10_TYPE_I_FORMAT_TYPE_DESCRIPTOR_1; + +typedef struct UX_CLASS_AUDIO10_TYPE_II_FORMAT_TYPE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + USHORT wMaxBitRate; + USHORT wSamplesPerFrame; + UCHAR bSamFreqType; +} UX_CLASS_AUDIO10_TYPE_II_FORMAT_TYPE_DESCRIPTOR; + +typedef struct UX_CLASS_AUDIO10_TYPE_II_FORMAT_TYPE_CONTINUOUS_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + USHORT wMaxBitRate; + USHORT wSamplesPerFrame; + UCHAR bSamFreqType; /* 0 */ + UCHAR tLowerSamFreq[3]; + UCHAR tUpperSamFreq[3]; +} +UX_CLASS_AUDIO10_TYPE_II_FORMAT_TYPE_CONTINUOUS_DESCRIPTOR, +UX_CLASS_AUDIO10_TYPE_II_FORMAT_TYPE_DESCRIPTOR_0; + +typedef struct UX_CLASS_AUDIO10_TYPE_II_FORMAT_TYPE_DISCRETE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + USHORT wMaxBitRate; + USHORT wSamplesPerFrame; + UCHAR bSamFreqType; /* 1 */ + UCHAR tSamFreq[3 * 1]; +} +UX_CLASS_AUDIO10_TYPE_II_FORMAT_TYPE_DISCRETE_DESCRIPTOR, +UX_CLASS_AUDIO10_TYPE_II_FORMAT_TYPE_DESCRIPTOR_1; + + +/* Audio Class 1.0 MPEG (MP) Format-Specific Descriptor (MPEGD) */ + +typedef struct UX_CLASS_AUDIO10_MPEG_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR wFormatTag[2]; + UCHAR bmMPEGCapabilities[2]; + UCHAR bmMPEGFeatures; +} UX_CLASS_AUDIO10_MPEG_DESCRIPTOR, UX_CLASS_AUDIO10_MPEGD; + +/* MPEG::bmMPEGCapabilities. */ +#define UX_CLASS_AUDIO10_MPEGD_CAP_LAYER_MASK (0x7u << 0) +#define UX_CLASS_AUDIO10_MPEGD_CAP_LAYER_I (0x1u << 0) +#define UX_CLASS_AUDIO10_MPEGD_CAP_LAYER_II (0x1u << 1) +#define UX_CLASS_AUDIO10_MPEGD_CAP_LAYER_III (0x1u << 2) +#define UX_CLASS_AUDIO10_MPEGD_CAP_MPEG1_ONLY (0x1u << 3) +#define UX_CLASS_AUDIO10_MPEGD_CAP_MPEG1_DUAL_CH (0x1u << 4) +#define UX_CLASS_AUDIO10_MPEGD_CAP_MPEG2_STEREO (0x1u << 5) +#define UX_CLASS_AUDIO10_MPEGD_CAP_MPEG2_7_1_CH (0x1u << 6) +#define UX_CLASS_AUDIO10_MPEGD_CAP_ADAPTIVE_MULTI_CH_PREDICT (0x1u << 7) +#define UX_CLASS_AUDIO10_MPEGD_CAP_MPEG2_MULTILINGUAL_MASK (0x3u << 8) +#define UX_CLASS_AUDIO10_MPEGD_CAP_MPEG2_MULTI_NOT_SUPPORT (0x0u << 8) +#define UX_CLASS_AUDIO10_MPEGD_CAP_MPEG2_MULTI_FS (0x1u << 8) +#define UX_CLASS_AUDIO10_MPEGD_CAP_MPEG2_MULTI_FS_HALF_FS (0x3u << 8) + +/* MPEG::bmMPEGFeatures. */ +#define UX_CLASS_AUDIO10_MPEGD_FEAT_IDYN_RNG_CTRL_MASK (0x3u << 4) /* Internal Dynamic Range Control */ +#define UX_CLASS_AUDIO10_MPEGD_FEAT_IDYN_RNG_CTRL_NOT_SUP (0x0u << 4) /* Not support */ +#define UX_CLASS_AUDIO10_MPEGD_FEAT_IDYN_RNG_CTRL_NOT_SCAL (0x1u << 4) /* Not scalable */ +#define UX_CLASS_AUDIO10_MPEGD_FEAT_IDYN_RNG_CTRL_SCAL_COMMON (0x2u << 4) /* Common boost and cut scaling value */ +#define UX_CLASS_AUDIO10_MPEGD_FEAT_IDYN_RNG_CTRL_SCAL_SEPARA (0x3u << 4) /* Separate boost and cut scaling value */ + +/* Audio Class 1.0 Dual Channel Control */ + +typedef struct UX_CLASS_AUDIO10_MP_DUAL_CHANNEL_CONTROL_PARAMETER_STRUCT +{ + UCHAR BChannel2Enable; +} UX_CLASS_AUDIO10_MP_DUAL_CHANNEL_CONTROL_PARAMETER; + +/* Audio Class 1.0 Second Stereo Control */ + +typedef struct UX_CLASS_AUDIO10_MP_2ND_STEREO_CONTROL_PARAMETER_STRUCT +{ + UCHAR B2ndStereoEnable; +} UX_CLASS_AUDIO10_MP_2ND_STEREO_CONTROL_PARAMETER; + +/* Audio Class 1.0 Multilingual Control */ + +typedef struct UX_CLASS_AUDIO10_MP_MULTILINGUAL_CONTROL_PARAMETER_STRUCT +{ + UCHAR bMultiLingual; +} UX_CLASS_AUDIO10_MP_MULTILINGUAL_CONTROL_PARAMETER; + +/* bMultiLingual */ +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_DECODE_NO_CHANNEL 0 +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_DECODE_CHANNEL_1 1 +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_DECODE_CHANNEL_2 2 +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_DECODE_CHANNEL_3 3 +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_DECODE_CHANNEL_4 4 +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_DECODE_CHANNEL_5 5 +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_DECODE_CHANNEL_6 6 +#define UX_CLASS_AUDIO10_MP_MULTILINGUAL_DECODE_CHANNEL_7 7 + +/* Audio Class 1.0 Dynamic Range Control (MP_DYN_RANGE_CONTROL) */ + +typedef struct UX_CLASS_AUDIO10_MP_DYN_RANGE_CONTROL_PARAMETER_STRUCT +{ + UCHAR bEnable; +} UX_CLASS_AUDIO10_MP_DYN_RANGE_CONTROL_PARAMETER; + +/* Audio Class 1.0 Scaling Control */ + +typedef struct UX_CLASS_AUDIO10_MP_SCALING_CONTROL_PARAMETER_STRUCT +{ + UCHAR bScale; +} UX_CLASS_AUDIO10_MP_SCALING_CONTROL_PARAMETER; + +/* Audio Class 1.0 High/Low (HILO) Scaling Control */ + +typedef struct UX_CLASS_AUDIO10_MP_HILO_SCALING_CONTROL_PARAMETER_STRUCT +{ + UCHAR bLowScale; + UCHAR bHighScale; +} UX_CLASS_AUDIO10_MP_HILO_SCALING_CONTROL_PARAMETER; + + +/* Audio Class 1.0 AC-3 Format Descriptor */ + +typedef struct UX_CLASS_AUDIO10_AS_AC_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR wFormatTag[2]; + UCHAR bmBSID[4]; + UCHAR bmAC3Features; +} UX_CLASS_AUDIO10_AS_AC_DESCRIPTOR, UX_CLASS_AUDIO10_AS_ACD; + +/* AC3 DECODER::bmAC3Features. */ +#define UX_CLASS_AUDIO10_ACD_FEAT_RF_MODE (0x1u << 0) +#define UX_CLASS_AUDIO10_ACD_FEAT_LINE_MODE (0x1u << 1) +#define UX_CLASS_AUDIO10_ACD_FEAT_CUSTOM0_MODE (0x1u << 2) +#define UX_CLASS_AUDIO10_ACD_FEAT_CUSTOM1_MODE (0x1u << 3) +#define UX_CLASS_AUDIO10_ACD_FEAT_IDYN_RNG_CTRL_MASK (0x3u << 4) /* Internal Dynamic Range Control */ +#define UX_CLASS_AUDIO10_ACD_FEAT_IDYN_RNG_CTRL_NOT_SUP (0x0u << 4) /* Not support */ +#define UX_CLASS_AUDIO10_ACD_FEAT_IDYN_RNG_CTRL_NOT_SCAL (0x3u << 4) /* Not scalable */ +#define UX_CLASS_AUDIO10_ACD_FEAT_IDYN_RNG_CTRL_SCAL_COMMON (0x3u << 4) /* Common boost and cut scaling value */ +#define UX_CLASS_AUDIO10_ACD_FEAT_IDYN_RNG_CTRL_SCAL_SEPARATE (0x3u << 4) /* Separate boost and cut scaling value */ + +/* Audio Class 1.0 AC-3 Mode Control (AC_MODE_CONTROL) */ + +typedef struct UX_CLASS_AUDIO10_AS_AC_MODE_CONTROL_PARAMETER_STRUCT +{ + UCHAR bMode; +} UX_CLASS_AUDIO10_AS_AC_MODE_CONTROL_PARAMETER; + +/* AC-3 Compression Mode Control. */ +#define UX_CLASS_AUDIO10_AC_MODE_RF (0x1u << 0) +#define UX_CLASS_AUDIO10_AC_MODE_LINE (0x1u << 1) +#define UX_CLASS_AUDIO10_AC_MODE_CUSTOM0 (0x1u << 2) +#define UX_CLASS_AUDIO10_AC_MODE_CUSTOM1 (0x1u << 3) + +/* Audio Class 1.0 AC-3 Dynamic Range Control (AC_DYN_RANGE_CONTROL) */ + +typedef struct UX_CLASS_AUDIO10_AS_AC_DYN_RANGE_CONTROL_PARAMETER_STRUCT +{ + UCHAR bMode; +} UX_CLASS_AUDIO10_AS_AC_DYN_RANGE_CONTROL_PARAMETER; + +/* Audio Class 1.0 AC-3 Scaling Control (AC_SCALING_CONTROL) */ + +typedef struct UX_CLASS_AUDIO10_AS_AC_SCALING_CONTROL_PARAMETER_STRUCT +{ + UCHAR bScale; +} UX_CLASS_AUDIO10_AS_AC_SCALING_CONTROL_PARAMETER; + +/* Audio Class 1.0 AC-3 High/Low Scaling Control (AC_HILO_SCALING_CONTROL) */ + +typedef struct UX_CLASS_AUDIO10_AS_AC_HILO_SCALING_CONTROL_PARAMETER_STRUCT +{ + UCHAR bLowScale; + UCHAR bHighScale; +} UX_CLASS_AUDIO10_AS_AC_HILO_SCALING_CONTROL_PARAMETER; + +typedef struct UX_CLASS_AUDIO10_TYPE_III_FORMAT_TYPE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + UCHAR bNrChannels; + UCHAR bSubframeSize; + UCHAR bBitResolution; + UCHAR bSamFreqType; +} UX_CLASS_AUDIO10_TYPE_III_FORMAT_TYPE_DESCRIPTOR; + +typedef struct UX_CLASS_AUDIO10_TYPE_III_FORMAT_TYPE_CONTINUOUS_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + UCHAR bNrChannels; + UCHAR bSubframeSize; + UCHAR bBitResolution; + UCHAR bSamFreqType; /* 0 */ + UCHAR tLowerSamFreq[3]; + UCHAR tUpperSamFreq[3]; +} +UX_CLASS_AUDIO10_TYPE_III_FORMAT_TYPE_CONTINUOUS_DESCRIPTOR, +UX_CLASS_AUDIO10_TYPE_III_FORMAT_TYPE_DESCRIPTOR_0; + +typedef struct UX_CLASS_AUDIO10_TYPE_III_FORMAT_TYPE_DISCRETE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + UCHAR bNrChannels; + UCHAR bSubframeSize; + UCHAR bBitResolution; + UCHAR bSamFreqType; /* 1 */ + UCHAR tSamFreq[3 * 1]; +} +UX_CLASS_AUDIO10_TYPE_III_FORMAT_TYPE_DISCRETE_DESCRIPTOR, +UX_CLASS_AUDIO10_TYPE_III_FORMAT_TYPE_DESCRIPTOR_1; + +/* Audio Class 1.0 Interrupt Status Word */ +typedef struct UX_CLASS_AUDIO10_INT_STATUS_STRUCT +{ + UCHAR bStatusType; + UCHAR bOriginator; +} UX_CLASS_AUDIO10_INT_STATUS; + +/* Status Word::bStatusType. */ +#define UX_CLASS_AUDIO10_INT_STATUS_TYPE_PENDING (0x1u << 7) +#define UX_CLASS_AUDIO10_INT_STATUS_TYPE_MEM_CHANGED (0x1u << 6) +#define UX_CLASS_AUDIO10_INT_STATUS_TYPE_ORIGINATOR_MASK (0xFu << 0) +#define UX_CLASS_AUDIO10_INT_STATUS_TYPE_ORIGINATOR_AC (0x0u << 0) /* AudioControl interface */ +#define UX_CLASS_AUDIO10_INT_STATUS_TYPE_ORIGINATOR_AS (0x1u << 0) /* AudioStreaming interface */ +#define UX_CLASS_AUDIO10_INT_STATUS_TYPE_ORIGINATOR_AS_EP (0x2u << 0) /* AudioStreaming endpoint */ + + +#endif diff --git a/common/core/inc/ux_class_audio20.h b/common/core/inc/ux_class_audio20.h new file mode 100644 index 00000000..89feeb39 --- /dev/null +++ b/common/core/inc/ux_class_audio20.h @@ -0,0 +1,1699 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* COMPONENT DEFINITION RELEASE */ +/* */ +/* ux_class_audio20.h PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains all the header and structures used by the */ +/* USBX Audio Class (UAC) 2.0. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ + +#ifndef UX_CLASS_AUDIO20_H +#define UX_CLASS_AUDIO20_H + +/* Define Audio Class Codes. */ + +#define UX_CLASS_AUDIO20_IP_VERSION_02_00 0x20 + +#define UX_CLASS_AUDIO20_CLASS 0x01 +#define UX_CLASS_AUDIO20_SUBCLASS_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_SUBCLASS_AUDIOCONTROL 0x01 +#define UX_CLASS_AUDIO20_SUBCLASS_AUDIOSTREAMING 0x02 +#define UX_CLASS_AUDIO20_SUBCLASS_MIDISTREAMING 0x03 +#define UX_CLASS_AUDIO20_PROTOCOL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_PROTOCOL_02_00 UX_CLASS_AUDIO20_IP_VERSION_02_00 + + +/* Define Audio Function (AF) code. */ + +#define UX_CLASS_AUDIO20_AF_VERSION_02_00 UX_CLASS_AUDIO20_IP_VERSION_02_00 + + +/* Define Audio Class function category codes. */ + +#define UX_CLASS_AUDIO20_CATEGORY_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_CATEGORY_DESKTOP_SPEAKER 0x01 +#define UX_CLASS_AUDIO20_CATEGORY_HOME_THEATER 0x02 +#define UX_CLASS_AUDIO20_CATEGORY_MICROPHONE 0x03 +#define UX_CLASS_AUDIO20_CATEGORY_HEADSET 0x04 +#define UX_CLASS_AUDIO20_CATEGORY_TELEPHONE 0x05 +#define UX_CLASS_AUDIO20_CATEGORY_CONVERTER 0x06 +#define UX_CLASS_AUDIO20_CATEGORY_VOICE_SOUND_RECORDER 0x07 +#define UX_CLASS_AUDIO20_CATEGORY_I_O_BOX 0x08 +#define UX_CLASS_AUDIO20_CATEGORY_MUSICAL_INSTRUMENT 0x09 +#define UX_CLASS_AUDIO20_CATEGORY_PRO_AUDIO 0x0A +#define UX_CLASS_AUDIO20_CATEGORY_AUDIO_VIDEO 0x0B +#define UX_CLASS_AUDIO20_CATEGORY_CONTROL_PANEL 0x0C +#define UX_CLASS_AUDIO20_CATEGORY_OTHER 0xFF + + +/* Define Audio Class desctiptor types. */ +#define UX_CLASS_AUDIO20_CS_UNDEFINED 0x20 +#define UX_CLASS_AUDIO20_CS_DEVICE 0x21 +#define UX_CLASS_AUDIO20_CS_CONFIGURATION 0x22 +#define UX_CLASS_AUDIO20_CS_STRING 0x23 +#define UX_CLASS_AUDIO20_CS_INTERFACE 0x24 +#define UX_CLASS_AUDIO20_CS_ENDPOINT 0x25 + + +/* Define Audio Class AC interface descriptor subclasses. */ + +#define UX_CLASS_AUDIO20_AC_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_AC_HEADER 0x01 +#define UX_CLASS_AUDIO20_AC_INPUT_TERMINAL 0x02 +#define UX_CLASS_AUDIO20_AC_OUTPUT_TERMINAL 0x03 +#define UX_CLASS_AUDIO20_AC_MIXER_UNIT 0x04 +#define UX_CLASS_AUDIO20_AC_SELECTOR_UNIT 0x05 +#define UX_CLASS_AUDIO20_AC_FEATURE_UNIT 0x06 +#define UX_CLASS_AUDIO20_AC_EFFECT_UNIT 0x07 +#define UX_CLASS_AUDIO20_AC_PROCESSING_UNIT 0x08 +#define UX_CLASS_AUDIO20_AC_EXTENSION_UNIT 0x09 +#define UX_CLASS_AUDIO20_AC_CLOCK_SOURCE 0x0A +#define UX_CLASS_AUDIO20_AC_CLOCK_SELECTOR 0x0B +#define UX_CLASS_AUDIO20_AC_CLOCK_MULTIPLIER 0x0C +#define UX_CLASS_AUDIO20_AC_SAMPLE_RATE_CONVERTER 0x0D + +/* Define Audio Class Effect Unit (EU) Effect Types (ET). */ + +#define UX_CLASS_AUDIO20_EFFECT_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_EFFECT_PARAM_EQ_SECTION 0x01 +#define UX_CLASS_AUDIO20_EFFECT_REVERBERATION 0x02 +#define UX_CLASS_AUDIO20_EFFECT_MOD_DELAY 0x03 +#define UX_CLASS_AUDIO20_EFFECT_DYN_RANGE_COMP 0x04 + +/* Define Audio Class Processing Unit (PU) Process Types (PT). */ + +#define UX_CLASS_AUDIO20_PROCESS_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_PROCESS_UP_DOWN_MIX 0x01 +#define UX_CLASS_AUDIO20_PROCESS_DOLBY_PROLOGIC 0x02 +#define UX_CLASS_AUDIO20_PROCESS_STEREO_EXTENDER 0x03 + + +/* Define Audio Class AS interface descriptor subclasses. */ + +#define UX_CLASS_AUDIO20_AS_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_AS_GENERAL 0x01 +#define UX_CLASS_AUDIO20_AS_FORMAT_TYPE 0x02 +#define UX_CLASS_AUDIO20_AS_ENCODER 0x03 +#define UX_CLASS_AUDIO20_AS_DECODER 0x04 + + +/* Define Audio Class endpoint descriptor subtypes. */ + +#define UX_CLASS_AUDIO20_EP_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_EP_GENERAL 0x01 + + +/* Define Audio Class Encoder Type codes. */ + +#define UX_CLASS_AUDIO20_ENCODER_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_ENCODER_OTHER 0x01 +#define UX_CLASS_AUDIO20_ENCODER_MPEG 0x02 +#define UX_CLASS_AUDIO20_ENCODER_AC3 0x03 +#define UX_CLASS_AUDIO20_ENCODER_WMA 0x04 +#define UX_CLASS_AUDIO20_ENCODER_DTS 0x05 + +/* Define Audio Class Decoder Type codes. */ + +#define UX_CLASS_AUDIO20_DECODER_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_DECODER_OTHER 0x01 +#define UX_CLASS_AUDIO20_DECODER_MPEG 0x02 +#define UX_CLASS_AUDIO20_DECODER_AC3 0x03 +#define UX_CLASS_AUDIO20_DECODER_WMA 0x04 +#define UX_CLASS_AUDIO20_DECODER_DTS 0x05 + + +/* Define Audio Class request codes. */ + +#define UX_CLASS_AUDIO20_REQUEST_CODE_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_CUR 0x01 +#define UX_CLASS_AUDIO20_RANGE 0x02 +#define UX_CLASS_AUDIO20_MEM 0x03 + + +/* Define Audio Class clock source control selectors. */ + +#define UX_CLASS_AUDIO20_CS_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL 0x01 +#define UX_CLASS_AUDIO20_CS_CLOCK_VALID_CONTROL 0x02 + +/* Define Audio Class clock selector control selectors. */ + +#define UX_CLASS_AUDIO20_CX_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_CX_CLOCK_SELECTOR_CONTROL 0x01 + +/* Define Audio Class clock multiplier control selectors. */ + +#define UX_CLASS_AUDIO20_CM_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_CM_NUMERATOR_CONTROL 0x01 +#define UX_CLASS_AUDIO20_CM_DENOMINATOR_CONTROL 0x02 + +/* Define Audio Class terminal control selectors. */ + +#define UX_CLASS_AUDIO20_TE_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_TE_COPY_PROTECT_CONTROL 0x01 +#define UX_CLASS_AUDIO20_TE_CONNECTOR_CONTROL 0x02 +#define UX_CLASS_AUDIO20_TE_OVERLOAD_CONTROL 0x03 +#define UX_CLASS_AUDIO20_TE_CLUSTER_CONTROL 0x04 +#define UX_CLASS_AUDIO20_TE_UNDERFLOW_CONTROL 0x05 +#define UX_CLASS_AUDIO20_TE_OVERFLOW_CONTROL 0x06 +#define UX_CLASS_AUDIO20_TE_LATENCY_CONTROL 0x07 + +/* Define Audio Class mixer control selectors. */ + +#define UX_CLASS_AUDIO20_MU_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_MU_MIXER_CONTROL 0x01 +#define UX_CLASS_AUDIO20_MU_CLUSTER_CONTROL 0x02 +#define UX_CLASS_AUDIO20_MU_UNDERFLOW_CONTROL 0x03 +#define UX_CLASS_AUDIO20_MU_OVERFLOW_CONTROL 0x04 +#define UX_CLASS_AUDIO20_MU_LATENCY_CONTROL 0x05 + +/* Define Audio Class selector control selectors. */ + +#define UX_CLASS_AUDIO20_SU_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_SU_SELECTOR_CONTROL 0x01 +#define UX_CLASS_AUDIO20_SU_LATENCY_CONTROL 0x02 + +/* Define Audio Class feature unit control selectors. */ + +#define UX_CLASS_AUDIO20_FU_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_FU_MUTE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_FU_VOLUME_CONTROL 0x02 +#define UX_CLASS_AUDIO20_FU_BASS_CONTROL 0x03 +#define UX_CLASS_AUDIO20_FU_MID_CONTROL 0x04 +#define UX_CLASS_AUDIO20_FU_TREBLE_CONTROL 0x05 +#define UX_CLASS_AUDIO20_FU_GRAPHIC_EQUALIZER_CONTROL 0x06 +#define UX_CLASS_AUDIO20_FU_AUTOMATIC_GAIN_CONTROL 0x07 +#define UX_CLASS_AUDIO20_FU_DELAY_CONTROL 0x08 +#define UX_CLASS_AUDIO20_FU_BASS_BOOST_CONTROL 0x09 +#define UX_CLASS_AUDIO20_FU_LOUNDNESS_CONTROL 0x0A +#define UX_CLASS_AUDIO20_FU_INPUT_GAIN_CONTROL 0x0B +#define UX_CLASS_AUDIO20_FU_INPUT_GAIN_PAD_CONTROL 0x0C +#define UX_CLASS_AUDIO20_FU_PHASE_INVERTER_CONTROL 0x0D +#define UX_CLASS_AUDIO20_FU_UNDERFLOW_CONTROL 0x0E +#define UX_CLASS_AUDIO20_FU_OVERFLOW_CONTROL 0x0F +#define UX_CLASS_AUDIO20_FU_LATENCY_CONTROL 0x10 + +/* Define Audio Class effect unit control selectors. */ + +/* Define Audio Class parametric equalizer (PE) section effect unit control selectors. */ +#define UX_CLASS_AUDIO20_PE_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_PE_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_PE_CENTERFREQ_CONTROL 0x02 +#define UX_CLASS_AUDIO20_PE_QFACTOR_CONTROL 0x03 +#define UX_CLASS_AUDIO20_PE_GAIN_CONTROL 0x04 +#define UX_CLASS_AUDIO20_PE_UNDERFLOW_CONTROL 0x05 +#define UX_CLASS_AUDIO20_PE_OVERFLOW_CONTROL 0x06 +#define UX_CLASS_AUDIO20_PE_LATENCY_CONTROL 0x07 + +/* Define Audio Class reverberation (RV) section effect unit control selectors. */ +#define UX_CLASS_AUDIO20_RV_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_RV_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_RV_TYPE_CONTROL 0x02 +#define UX_CLASS_AUDIO20_RV_LEVEL_CONTROL 0x03 +#define UX_CLASS_AUDIO20_RV_TIME_CONTROL 0x04 +#define UX_CLASS_AUDIO20_RV_FEEDBACK_CONTROL 0x05 +#define UX_CLASS_AUDIO20_RV_PREDELAY_CONTROL 0x06 +#define UX_CLASS_AUDIO20_RV_DENSITY_CONTROL 0x07 +#define UX_CLASS_AUDIO20_RV_HIFREQ_ROLLOFF_CONTROL 0x08 +#define UX_CLASS_AUDIO20_RV_UNDERFLOW_CONTROL 0x09 +#define UX_CLASS_AUDIO20_RV_OVERFLOW_CONTROL 0x0A +#define UX_CLASS_AUDIO20_RV_LATENCY_CONTROL 0x0B + +/* Define Audio Class modulation delay (MD) effect unit control selectors. */ + +#define UX_CLASS_AUDIO20_MD_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_MD_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_MD_BALANCE_CONTROL 0x02 +#define UX_CLASS_AUDIO20_MD_RATE_CONTROL 0x03 +#define UX_CLASS_AUDIO20_MD_DEPTH_CONTROL 0x04 +#define UX_CLASS_AUDIO20_MD_TIME_CONTROL 0x05 +#define UX_CLASS_AUDIO20_MD_FEEDBACK_CONTROL 0x06 +#define UX_CLASS_AUDIO20_MD_UNDERFLOW_CONTROL 0x07 +#define UX_CLASS_AUDIO20_MD_OVERFLOW_CONTROL 0x08 +#define UX_CLASS_AUDIO20_MD_LATENCY_CONTROL 0x09 + +/* Define Audio Class dynamic range (DR) compressor effect unit control selectors. */ + +#define UX_CLASS_AUDIO20_DR_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_DR_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_DR_COMPRESSION_RATE_CONTROL 0x02 +#define UX_CLASS_AUDIO20_DR_MAXAMPL_CONTROL 0x03 +#define UX_CLASS_AUDIO20_DR_THRESHOLD_CONTROL 0x04 +#define UX_CLASS_AUDIO20_DR_ATTACK_TIME_CONTROL 0x05 +#define UX_CLASS_AUDIO20_DR_RELEASE_TIME_CONTROL 0x06 +#define UX_CLASS_AUDIO20_DR_UNDERFLOW_CONTROL 0x07 +#define UX_CLASS_AUDIO20_DR_OVERFLOW_CONTROL 0x08 +#define UX_CLASS_AUDIO20_DR_LATENCY_CONTROL 0x09 + +/* Define Audio Class processing unit control selectors. */ + +/* Define Audio Class up/down-mix (UD) processing unit control selectors. */ + +#define UX_CLASS_AUDIO20_UD_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_UD_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_UD_MODE_SELECT_CONTROL 0x02 +#define UX_CLASS_AUDIO20_UD_CLUSTER_CONTROL 0x03 +#define UX_CLASS_AUDIO20_UD_UNDERFLOW_CONTROL 0x04 +#define UX_CLASS_AUDIO20_UD_OVERFLOW_CONTROL 0x05 +#define UX_CLASS_AUDIO20_UD_LATENCY_CONTROL 0x06 + +/* Define Audio Class dolby prologic (DP) processing unit control selectors. */ + +#define UX_CLASS_AUDIO20_DP_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_DP_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_DP_MODE_SELECT_CONTROL 0x02 +#define UX_CLASS_AUDIO20_DP_CLUSTER_CONTROL 0x03 +#define UX_CLASS_AUDIO20_DP_UNDERFLOW_CONTROL 0x04 +#define UX_CLASS_AUDIO20_DP_OVERFLOW_CONTROL 0x05 +#define UX_CLASS_AUDIO20_DP_LATENCY_CONTROL 0x06 + +/* Define Audio Class stereo extender (ST_EXT) processing unit control selectors. */ + +#define UX_CLASS_AUDIO20_ST_EXT_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_ST_EXT_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_ST_EXT_WIDTH_CONTROL 0x02 +#define UX_CLASS_AUDIO20_ST_EXT_UNDERFLOW_CONTROL 0x03 +#define UX_CLASS_AUDIO20_ST_EXT_OVERFLOW_CONTROL 0x04 +#define UX_CLASS_AUDIO20_ST_EXT_LATENCY_CONTROL 0x05 + +/* Define Audio Class extension unit (XU) control selectors. */ + +#define UX_CLASS_AUDIO20_XU_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_XU_ENABLE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_XU_CLUSTER_CONTROL 0x02 +#define UX_CLASS_AUDIO20_XU_UNDERFLOW_CONTROL 0x03 +#define UX_CLASS_AUDIO20_XU_OVERFLOW_CONTROL 0x04 +#define UX_CLASS_AUDIO20_XU_LATENCY_CONTROL 0x05 + + +/* Define Audio Class AudioStreaming interface control selectors. */ + +#define UX_CLASS_AUDIO20_AS_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_AS_ACT_ALT_SETTING_CONTROL 0x01 +#define UX_CLASS_AUDIO20_AS_VAL_ALT_SETTINGS_CONTROL 0x02 +#define UX_CLASS_AUDIO20_AS_AUDIO_DATA_FORMAT_CONTROL 0x03 + +/* Define Audio Class encoder (EN) control selectors. */ + +#define UX_CLASS_AUDIO20_EN_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_EN_BIT_RATE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_EN_QUALITY_CONTROL 0x02 +#define UX_CLASS_AUDIO20_EN_VBR_CONTROL 0x03 +#define UX_CLASS_AUDIO20_EN_TYPE_CONTROL 0x04 +#define UX_CLASS_AUDIO20_EN_UNDERFLOW_CONTROL 0x05 +#define UX_CLASS_AUDIO20_EN_OVERFLOW_CONTROL 0x06 +#define UX_CLASS_AUDIO20_EN_ENCODER_ERROR_CONTROL 0x07 +#define UX_CLASS_AUDIO20_EN_PARAM1_CONTROL 0x08 +#define UX_CLASS_AUDIO20_EN_PARAM2_CONTROL 0x09 +#define UX_CLASS_AUDIO20_EN_PARAM3_CONTROL 0x0A +#define UX_CLASS_AUDIO20_EN_PARAM4_CONTROL 0x0B +#define UX_CLASS_AUDIO20_EN_PARAM5_CONTROL 0x0C +#define UX_CLASS_AUDIO20_EN_PARAM6_CONTROL 0x0D +#define UX_CLASS_AUDIO20_EN_PARAM7_CONTROL 0x0E +#define UX_CLASS_AUDIO20_EN_PARAM8_CONTROL 0x0F + +/* Define Audio Class decoder control selectors. */ + +/* Define Audio Class MPEG decoder (MD) control selectors. */ + +#define UX_CLASS_AUDIO20_MD_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_MD_DUAL_CHANNEL_CONTROL 0x01 +#define UX_CLASS_AUDIO20_MD_SECOND_STEREO_CONTROL 0x02 +#define UX_CLASS_AUDIO20_MD_MULTILINGUAL_CONTROL 0x03 +#define UX_CLASS_AUDIO20_MD_DYN_RANGE_CONTROL 0x04 +#define UX_CLASS_AUDIO20_MD_SCALING_CONTROL 0x05 +#define UX_CLASS_AUDIO20_MD_HILO_SCALING_CONTROL 0x06 +#define UX_CLASS_AUDIO20_MD_UNDERFLOW_CONTROL 0x07 +#define UX_CLASS_AUDIO20_MD_OVERFLOW_CONTROL 0x08 +#define UX_CLASS_AUDIO20_MD_DECODER_ERROR_CONTROL 0x09 + +/* Define Audio Class AC-3 decoder (AD) control selectors. */ + +#define UX_CLASS_AUDIO20_AD_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_AD_MODE_CONTROL 0x01 +#define UX_CLASS_AUDIO20_AD_DYN_RANGE_CONTROL 0x02 +#define UX_CLASS_AUDIO20_AD_SCALING_CONTROL 0x03 +#define UX_CLASS_AUDIO20_AD_HILO_SCALING_CONTROL 0x04 +#define UX_CLASS_AUDIO20_AD_UNDERFLOW_CONTROL 0x05 +#define UX_CLASS_AUDIO20_AD_OVERFLOW_CONTROL 0x06 +#define UX_CLASS_AUDIO20_AD_DECODER_ERROR_CONTROL 0x07 + +/* Define Audio Class WMA decoder (WD) control selectors. */ + +#define UX_CLASS_AUDIO20_WD_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_WD_UNDERFLOW_CONTROL 0x01 +#define UX_CLASS_AUDIO20_WD_OVERFLOW_CONTROL 0x02 +#define UX_CLASS_AUDIO20_WD_DECODER_ERROR_CONTROL 0x03 + +/* Define Audio Class DTS decoder (DD) control selectors. */ + +#define UX_CLASS_AUDIO20_DD_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_DD_UNDERFLOW_CONTROL 0x01 +#define UX_CLASS_AUDIO20_DD_OVERFLOW_CONTROL 0x02 +#define UX_CLASS_AUDIO20_DD_DECODER_ERROR_CONTROL 0x03 + + +/* Define Audio Class endpoint control selectors. */ + +#define UX_CLASS_AUDIO20_EP_CONTROL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_EP_PITCH_CONTROL 0x01 +#define UX_CLASS_AUDIO20_EP_DATA_OVERRUN_CONTROL 0x02 +#define UX_CLASS_AUDIO20_EP_DATA_UNDERRUN_CONTROL 0x03 + + +/* Define Audio Class format type codes. */ + +#define UX_CLASS_AUDIO20_FORMAT_TYPE_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_FORMAT_TYPE_I 0x01 +#define UX_CLASS_AUDIO20_FORMAT_TYPE_II 0x02 +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III 0x03 +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV 0x04 +#define UX_CLASS_AUDIO20_EXT_FORMAT_TYPE_I 0x81 +#define UX_CLASS_AUDIO20_EXT_FORMAT_TYPE_II 0x82 +#define UX_CLASS_AUDIO20_EXT_FORMAT_TYPE_III 0x83 + + +/* Define Audio Class encoding format type I bit allocations. */ + +#define UX_CLASS_AUDIO20_FORMAT_TYPE_I_PCM (1u << 0) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_I_PCM8 (1u << 1) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_I_IEEE_FLOAT (1u << 2) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_I_ALAW (1u << 3) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_I_MULAW (1u << 4) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_I_RAW (1u << 31) + +/* Define Audio Class encoding format type II bit allocations. */ + +#define UX_CLASS_AUDIO20_FORMAT_TYPE_II_MPEG (1u << 0) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_II_AC3 (1u << 1) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_II_WMA (1u << 2) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_II_DTS (1u << 3) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_II_RAW_DATA (1u << 31) + +/* Define Audio Class encoding format type III bit allocations. */ + +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_AC3 (1u << 0) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_MPEG1_LAYER1 (1u << 1) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_MPEG1_LAYER2_3 (1u << 2) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_MPEG2_NOEXT (1u << 2) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_MPEG2_EXT (1u << 3) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_MPEG2_AAC_ADTS (1u << 4) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_MPEG2_LAYER1_LS (1u << 5) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_MPEG2_LAYER2_3_LS (1u << 6) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_DTS_I (1u << 7) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_DTS_II (1u << 8) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_DTS_III (1u << 9) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_ATRAC (1u << 10) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_IEC61937_ATRAC2_3 (1u << 11) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_III_WMA (1u << 12) + +/* Define Audio Class encoding format type IV bit allocations. */ + +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_PCM (1u << 0) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_PCM8 (1u << 1) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEEE_FLOAT (1u << 2) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_ALAW (1u << 3) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_MULAW (1u << 4) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_MPEG (1u << 5) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_AC3 (1u << 6) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_WMA (1u << 7) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_AC3 (1u << 8) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_MPEG1_LAYER1 (1u << 9) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_MPEG1_LAYER2_3 (1u << 10) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_MPEG2_NOEXT (1u << 10) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_MPEG2_EXT (1u << 11) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_MPEG2_AAC_ADTS (1u << 12) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_MPEG2_LAYER1_LS (1u << 13) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_MPEG2_LAYER2_3_LS (1u << 14) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_DTS_I (1u << 15) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_DTS_II (1u << 16) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_DTS_III (1u << 17) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_ATRAC (1u << 18) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC61937_ATRAC2_3 (1u << 19) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_TYPE_III_WMA (1u << 20) +#define UX_CLASS_AUDIO20_FORMAT_TYPE_IV_IEC60958_PCM (1u << 21) + +/* Define Audio Class side band protocol codes. */ + +#define UX_CLASS_AUDIO20_SIDE_BAND_PROTOCOL_UNDEFINED 0x00 +#define UX_CLASS_AUDIO20_SIDE_BAND_PRES_TIMESTAMP_PROTOCOL 0x01 + + +/* Define Audio Class bmControls bit pair. */ + +#define UX_CLASS_AUDIO20_CONTROL_MASK 0x3u +#define UX_CLASS_AUDIO20_CONTROL_NOT_PRESENT 0x0u +#define UX_CLASS_AUDIO20_CONTROL_READ_ONLY 0x1u +#define UX_CLASS_AUDIO20_CONTROL_PROGRAMMABLE 0x3u + +/* Control position from control selector (CS). */ +#define UX_CLASS_AUDIO20_CONTROL_POS(cs) (((cs)-1) << 1) + + + +/* Class descriptor structures (packed). + * Typedefs to be used: + * - for byte : UCHAR/CHAR + * - for word : USHORT/SHORT + * - for double word (dword): ULONG/LONG + * - for 64-bit-width word : ULONG64 + * Field offset considerations inside descriptor: + * - Minimum fields alignment: byte (8-bit) + * - Field is not byte and not aligned : field declared as bytes array (UCHAR[]) + * - Field is word and word aligned : field declared as USHORT/SHORT + * - Field is dword and dword aligned : field declared as ULONG/LONG + */ + +/* Audio Class Audio Channel Cluster Descriptor. */ + +typedef struct UX_CLASS_AUDIO20_CHANNEL_CLUSTER_DESCRIPTOR_STRUCT +{ + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; +} UX_CLASS_AUDIO20_CHANNEL_CLUSTER_DESCRIPTOR; + +/* bmChannelConfig channel bits (F-Front,L-Left,R-Right,C-Center,B-Back,S-Side,T-Top). */ +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_FL (1u << 0) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_FR (1u << 1) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_FC (1u << 2) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_LFE (1u << 3) /* Low Frequency Effects */ +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_BL (1u << 4) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_BR (1u << 5) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_FLC (1u << 6) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_FRC (1u << 7) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_BC (1u << 8) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_SL (1u << 9) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_SR (1u << 10) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TC (1u << 11) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TFL (1u << 12) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TFC (1u << 13) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TFR (1u << 14) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TBL (1u << 15) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TBC (1u << 16) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TBR (1u << 17) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TFLC (1u << 18) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TFRC (1u << 19) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_LLFE (1u << 20) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_RLFE (1u << 21) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TSL (1u << 22) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_TSR (1u << 23) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_BottomC (1u << 24) /* Bottom Center */ +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_BLC (1u << 25) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_BRC (1u << 26) +#define UX_CLASS_AUDIO20_CHANNEL_CLUSTER_CHANNEL_RD (1u << 31) /* Raw Data */ + +/* Audio Class AC interface header descriptors. */ + +typedef struct UX_CLASS_AUDIO20_AC_HEADER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bcdADC[2]; + UCHAR bCategory; + USHORT wTotalLength; + UCHAR bmControls; +} UX_CLASS_AUDIO20_AC_HEADER_DESCRIPTOR; + +/* Define Audio Class clock source descriptor (CSD). */ + +typedef struct UX_CLASS_AUDIO20_AC_CLOCK_SOURCE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bClockID; + UCHAR bmAttributes; + UCHAR bmControls; + UCHAR bAssocTerminal; + UCHAR iClockSource; +} UX_CLASS_AUDIO20_AC_CLOCK_SOURCE_DESCRIPTOR, UX_CLASS_AUDIO20_AC_CSD; + +/* CSD::bmAttributes. */ +#define UX_CLASS_AUDIO20_CSD_ATTR_CLOCK_TYPE_MASK (0x3u) +#define UX_CLASS_AUDIO20_CSD_ATTR_CLOCK_TYPE_EXTERNAL (0x0u) +#define UX_CLASS_AUDIO20_CSD_ATTR_CLOCK_TYPE_INTERNAL_FIXED (0x1u) +#define UX_CLASS_AUDIO20_CSD_ATTR_CLOCK_TYPE_INTERNAL_VARIABLE (0x2u) +#define UX_CLASS_AUDIO20_CSD_ATTR_CLOCK_TYPE_INTERNAL_PROGRAMMABLE (0x3u) +#define UX_CLASS_AUDIO20_CSD_ATTR_CLOCK_SYNCH_TO_SOF (0x1u << 2) + +/* CSD::bmControls. */ +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_FREQ_POS (0) +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_FREQ_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_FREQ_POS) +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_FREQ(v) ((v) << UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_FREQ_POS) +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_VALIDITY_POS (2) +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_VALIDITY_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_VALIDITY_POS) +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_VALIDITY(v) ((v) << UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_VALIDITY_POS) + +/* Define Audio Class clock selector descriptor (CXD, bNrInPins=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_CLOCK_SELECTOR_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bClockID; + UCHAR bNrInPins; + UCHAR baCSourceID[1]; + UCHAR bmControls; + UCHAR iClockSelector; +} UX_CLASS_AUDIO20_AC_CLOCK_SELECTOR_DESCRIPTOR, UX_CLASS_AUDIO20_AC_CXD; + +/* CXD::bmControls. */ +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_SELECTOR_POS (0) +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_SELECTOR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_SELECTOR_POS) +#define UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_SELECTOR(v) ((v) << UX_CLASS_AUDIO20_CSD_CONTROL_CLOCK_SELECTOR_POS) + +/* Define Audio Class clock multiplier descriptor (CMD). */ + +typedef struct UX_CLASS_AUDIO20_AC_CLOCK_MULTIPLIER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bClockID; + UCHAR bCSourceID; + UCHAR bmControls; + UCHAR iClockMultiplier; +} UX_CLASS_AUDIO20_AC_CLOCK_MULTIPLIER_DESCRIPTOR, UX_CLASS_AUDIO20_AC_CMD; + +/* CMD::bmControls. */ +#define UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_NUMERATOR_POS (0) +#define UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_NUMERATOR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_NUMERATOR_POS) +#define UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_NUMERATOR(v) ((v) << UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_NUMERATOR_POS) +#define UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_DENOMINATOR_POS (2) +#define UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_DENOMINATOR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_DENOMINATOR_POS) +#define UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_DENOMINATOR(v) ((v) << UX_CLASS_AUDIO20_CMD_CONTROL_CLOCK_DENOMINATOR_POS) + +/* Define Audio Class input terminal descriptor (ITD). */ + +typedef struct UX_CLASS_AUDIO20_AC_INPUT_TERMINAL_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR bCSourceID; + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; + USHORT bmControls; + UCHAR iTerminal; +} UX_CLASS_AUDIO20_AC_INPUT_TERMINAL_DESCRIPTOR, UX_CLASS_AUDIO20_AC_ITD; + +/* ITD::bmControls. */ +#define UX_CLASS_AUDIO20_ITD_CONTROL_COPY_PROTECT_POS (0) +#define UX_CLASS_AUDIO20_ITD_CONTROL_COPY_PROTECT_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ITD_CONTROL_COPY_PROTECT_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_COPY_PROTECT(v) ((v) << UX_CLASS_AUDIO20_ITD_CONTROL_COPY_PROTECT_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_CONNECTOR_POS (2) +#define UX_CLASS_AUDIO20_ITD_CONTROL_CONNECTOR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ITD_CONTROL_CONNECTOR_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_CONNECTOR(v) ((v) << UX_CLASS_AUDIO20_ITD_CONTROL_CONNECTOR_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_OVERLOAD_POS (4) +#define UX_CLASS_AUDIO20_ITD_CONTROL_OVERLOAD_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ITD_CONTROL_OVERLOAD_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_OVERLOAD(v) ((v) << UX_CLASS_AUDIO20_ITD_CONTROL_OVERLOAD_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_CLUSTER_POS (6) +#define UX_CLASS_AUDIO20_ITD_CONTROL_CLUSTER_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ITD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_CLUSTER(v) ((v) << UX_CLASS_AUDIO20_ITD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_UNDERFLOW_POS (8) +#define UX_CLASS_AUDIO20_ITD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ITD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_ITD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_OVERFLOW_POS (10) +#define UX_CLASS_AUDIO20_ITD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ITD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_ITD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_ITD_CONTROL_OVERFLOW_POS) + +/* Define Audio Class output terminal descriptor (OTD). */ + +typedef struct UX_CLASS_AUDIO20_AC_OUTPUT_TERMINAL_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR bSourceID; + UCHAR bCSourceID; + UCHAR bmControls[2]; + UCHAR iTerminal; +} UX_CLASS_AUDIO20_AC_OUTPUT_TERMINAL_DESCRIPTOR, UX_CLASS_AUDIO20_AC_OTD; + +/* OTD::bmControls. */ +#define UX_CLASS_AUDIO20_OTD_CONTROL_COPY_PROTECT_POS (0) +#define UX_CLASS_AUDIO20_OTD_CONTROL_COPY_PROTECT_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_OTD_CONTROL_COPY_PROTECT_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_COPY_PROTECT(v) ((v) << UX_CLASS_AUDIO20_OTD_CONTROL_COPY_PROTECT_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_CONNECTOR_POS (2) +#define UX_CLASS_AUDIO20_OTD_CONTROL_CONNECTOR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_OTD_CONTROL_CONNECTOR_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_CONNECTOR(v) ((v) << UX_CLASS_AUDIO20_OTD_CONTROL_CONNECTOR_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_OVERLOAD_POS (4) +#define UX_CLASS_AUDIO20_OTD_CONTROL_OVERLOAD_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_OTD_CONTROL_OVERLOAD_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_OVERLOAD(v) ((v) << UX_CLASS_AUDIO20_OTD_CONTROL_OVERLOAD_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_UNDERFLOW_POS (6) +#define UX_CLASS_AUDIO20_OTD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_OTD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_OTD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_OVERFLOW_POS (8) +#define UX_CLASS_AUDIO20_OTD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_OTD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_OTD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_OTD_CONTROL_OVERFLOW_POS) + +/* Define Audio Class mixer unit descriptor (MUD, bNrInPins=1, bmMixerControls N=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_MIXER_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; + UCHAR bmMixerControls[1]; + UCHAR bmControls; + UCHAR iMixer; +} UX_CLASS_AUDIO20_AC_MIXER_UNIT_DESCRIPTOR, UX_CLASS_AUDIO20_AC_MUD; + +/* MUD::bmControls. */ +#define UX_CLASS_AUDIO20_MUD_CONTROL_CLUSTER_POS (0) +#define UX_CLASS_AUDIO20_MUD_CONTROL_CLUSTER_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MUD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_MUD_CONTROL_CLUSTER(v) ((v) << UX_CLASS_AUDIO20_MUD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_MUD_CONTROL_UNDERFLOW_POS (2) +#define UX_CLASS_AUDIO20_MUD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MUD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_MUD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_MUD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_MUD_CONTROL_OVERFLOW_POS (4) +#define UX_CLASS_AUDIO20_MUD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MUD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_MUD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_MUD_CONTROL_OVERFLOW_POS) + +/* Define Audio Class selector unit descriptor (SUD, bNrInPins=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_SELECTOR_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bmControls; + UCHAR iSelector; +} UX_CLASS_AUDIO20_AC_SELECTOR_UNIT_DESCRIPTOR, UX_CLASS_AUDIO20_AC_SUD; + +/* SUD::bmControls. */ +#define UX_CLASS_AUDIO20_SUD_CONTROL_SELECTOR_POS (0) +#define UX_CLASS_AUDIO20_SUD_CONTROL_SELECTOR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_SUD_CONTROL_SELECTOR_POS) +#define UX_CLASS_AUDIO20_SUD_CONTROL_SELECTOR(v) ((v) << UX_CLASS_AUDIO20_SUD_CONTROL_SELECTOR_POS) + +/* Define Audio Class feature unit descriptor (FUD, ch=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_FEATURE_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + UCHAR bSourceID; + UCHAR bmaControls[4 * 2]; + UCHAR iFeature; +} UX_CLASS_AUDIO20_AC_FEATURE_UNIT_DESCRIPTOR, UX_CLASS_AUDIO20_AC_FUD; + +/* FUD::bmControls. */ +#define UX_CLASS_AUDIO20_FUD_CONTROL_MUTE_POS (0) +#define UX_CLASS_AUDIO20_FUD_CONTROL_MUTE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_MUTE_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_MUTE(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_MUTE_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_VOLUME_POS (2) +#define UX_CLASS_AUDIO20_FUD_CONTROL_VOLUME_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_VOLUME_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_VOLUME(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_VOLUME_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_BASS_POS (4) +#define UX_CLASS_AUDIO20_FUD_CONTROL_BASS_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_BASS_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_BASS(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_BASS_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_MID_POS (6) +#define UX_CLASS_AUDIO20_FUD_CONTROL_MID_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_MID_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_MID(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_MID_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_TREBLE_POS (8) +#define UX_CLASS_AUDIO20_FUD_CONTROL_TREBLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_TREBLE_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_TREBLE(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_TREBLE_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_GRAPHIC_EQ_POS (10) +#define UX_CLASS_AUDIO20_FUD_CONTROL_GRAPHIC_EQ_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_GRAPHIC_EQ_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_GRAPHIC_EQ(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_GRAPHIC_EQ_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_AUTO_GAIN_POS (12) +#define UX_CLASS_AUDIO20_FUD_CONTROL_AUTO_GAIN_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_AUTO_GAIN_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_AUTO_GAIN(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_AUTO_GAIN_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_DELAY_POS (14) +#define UX_CLASS_AUDIO20_FUD_CONTROL_DELAY_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_DELAY_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_DELAY(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_DELAY_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_BASS_BOOST_POS (16) +#define UX_CLASS_AUDIO20_FUD_CONTROL_BASS_BOOST_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_BASS_BOOST_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_BASS_BOOST(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_BASS_BOOST_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_LOUDNESS_POS (18) +#define UX_CLASS_AUDIO20_FUD_CONTROL_LOUDNESS_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_LOUDNESS_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_LOUDNESS(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_LOUDNESS_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_POS (20) +#define UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_PAD_POS (22) +#define UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_PAD_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_PAD_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_PAD(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_INPUT_GAIN_PAD_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_PHASE_INVERTER_POS (24) +#define UX_CLASS_AUDIO20_FUD_CONTROL_PHASE_INVERTER_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_PHASE_INVERTER_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_PHASE_INVERTER(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_PHASE_INVERTER_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_UNDERFLOW_POS (26) +#define UX_CLASS_AUDIO20_FUD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_OVERFLOW_POS (28) +#define UX_CLASS_AUDIO20_FUD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_FUD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_FUD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_FUD_CONTROL_OVERFLOW_POS) + +typedef struct UX_CLASS_AUDIO20_AC_FEATURE_UNIT_DESCRIPTOR_1_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + UCHAR bSourceID; + UCHAR bmaControl0[4]; + UCHAR bmaControl1[4]; + UCHAR iFeature; +} UX_CLASS_AUDIO20_AC_FEATURE_UNIT_DESCRIPTOR_1, UX_CLASS_AUDIO20_AC_FUD_1; + +typedef struct UX_CLASS_AUDIO20_AC_FEATURE_UNIT_DESCRIPTOR_2_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + UCHAR bSourceID; + UCHAR bmaControl0[4]; + UCHAR bmaControl1[4]; + UCHAR bmaControl2[4]; + UCHAR iFeature; +} UX_CLASS_AUDIO20_AC_FEATURE_UNIT_DESCRIPTOR_2, UX_CLASS_AUDIO20_AC_FUD_2; + +/* Define Audio Class sampling rate converter descriptor (RDU). */ + +typedef struct UX_CLASS_AUDIO20_AC_SAMPLING_RATE_CONVERTER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + UCHAR bSourceID; + UCHAR bSourceInID; + UCHAR bSourceOutID; + UCHAR iSRC; +} UX_CLASS_AUDIO20_AC_SAMPLING_RATE_CONVERTER_DESCRIPTOR, UX_CLASS_AUDIO20_AC_RUD; + +/* Define Audio Class effect unit descriptor (EUD, ch=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_EFFECT_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + USHORT wEffectType; + UCHAR bSourceID; + UCHAR bmaControls[4 * 2]; + UCHAR iEffects; +} UX_CLASS_AUDIO20_AC_EFFECT_UNIT_DESCRIPTOR, UX_CLASS_AUDIO20_AC_EUD; + +typedef struct UX_CLASS_AUDIO20_AC_EFFECT_UNIT_DESCRIPTOR_1_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + USHORT wEffectType; + UCHAR bSourceID; + UCHAR bmaControl0[4]; + UCHAR bmaControl1[4]; + UCHAR iEffects; +} UX_CLASS_AUDIO20_AC_EFFECT_UNIT_DESCRIPTOR_1, UX_CLASS_AUDIO20_AC_EUD_1; + +typedef struct UX_CLASS_AUDIO20_AC_EFFECT_UNIT_DESCRIPTOR_2_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + USHORT wEffectType; + UCHAR bSourceID; + UCHAR bmaControl0[4]; + UCHAR bmaControl1[4]; + UCHAR bmaControl2[4]; + UCHAR iEffects; +} UX_CLASS_AUDIO20_AC_EFFECT_UNIT_DESCRIPTOR_2, UX_CLASS_AUDIO20_AC_EUD_2; + +/* Parametric Equalizer Section (PEQS) EUD(PED)::bmaControls. */ +#define UX_CLASS_AUDIO20_PED_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_PED_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_PED_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_PED_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_CENTER_FREQ_POS (2) +#define UX_CLASS_AUDIO20_PED_CONTROL_CENTER_FREQ_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_PED_CONTROL_CENTER_FREQ_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_CENTER_FREQ(v) ((v) << UX_CLASS_AUDIO20_PED_CONTROL_CENTER_FREQ_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_Q_FACTOR_POS (4) +#define UX_CLASS_AUDIO20_PED_CONTROL_Q_FACTOR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_PED_CONTROL_Q_FACTOR_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_Q_FACTOR(v) ((v) << UX_CLASS_AUDIO20_PED_CONTROL_Q_FACTOR_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_GAIN_POS (6) +#define UX_CLASS_AUDIO20_PED_CONTROL_GAIN_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_PED_CONTROL_GAIN_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_GAIN(v) ((v) << UX_CLASS_AUDIO20_PED_CONTROL_GAIN_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_UNDERFLOW_POS (8) +#define UX_CLASS_AUDIO20_PED_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_PED_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_PED_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_OVERFLOW_POS (10) +#define UX_CLASS_AUDIO20_PED_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_PED_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_PED_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_PED_CONTROL_OVERFLOW_POS) + +/* Reverberation EUD(RVD)::bmaControls. */ +#define UX_CLASS_AUDIO20_RVD_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_RVD_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_TYPE_POS (2) +#define UX_CLASS_AUDIO20_RVD_CONTROL_TYPE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_TYPE_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_TYPE(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_TYPE_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_LEVEL_POS (4) +#define UX_CLASS_AUDIO20_RVD_CONTROL_LEVEL_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_LEVEL_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_LEVEL(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_LEVEL_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_TIME_POS (6) +#define UX_CLASS_AUDIO20_RVD_CONTROL_TIME_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_TIME_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_TIME(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_TIME_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_DELAY_FEEDBACK_POS (8) +#define UX_CLASS_AUDIO20_RVD_CONTROL_DELAY_FEEDBACK_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_DELAY_FEEDBACK_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_DELAY_FEEDBACK(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_DELAY_FEEDBACK_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_PRE_DELAY_POS (10) +#define UX_CLASS_AUDIO20_RVD_CONTROL_PRE_DELAY_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_PRE_DELAY_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_PRE_DELAY(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_PRE_DELAY_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_DENSITY_POS (12) +#define UX_CLASS_AUDIO20_RVD_CONTROL_DENSITY_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_DENSITY_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_DENSITY(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_DENSITY_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_HI_FREQ_ROLL_OFF_POS (14) +#define UX_CLASS_AUDIO20_RVD_CONTROL_HI_FREQ_ROLL_OFF_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_HI_FREQ_ROLL_OFF_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_HI_FREQ_ROLL_OFF(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_HI_FREQ_ROLL_OFF_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_UNDERFLOW_POS (16) +#define UX_CLASS_AUDIO20_RVD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_OVERFLOW_POS (18) +#define UX_CLASS_AUDIO20_RVD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_RVD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_RVD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_RVD_CONTROL_OVERFLOW_POS) + +/* Modulation Delay EUD(MDD)::bmaControls. */ +#define UX_CLASS_AUDIO20_MDD_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_MDD_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MDD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_MDD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_BALANCE_POS (2) +#define UX_CLASS_AUDIO20_MDD_CONTROL_BALANCE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MDD_CONTROL_BALANCE_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_BALANCE(v) ((v) << UX_CLASS_AUDIO20_MDD_CONTROL_BALANCE_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_RATE_POS (4) +#define UX_CLASS_AUDIO20_MDD_CONTROL_RATE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MDD_CONTROL_RATE_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_RATE(v) ((v) << UX_CLASS_AUDIO20_MDD_CONTROL_RATE_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_DEPTH_POS (6) +#define UX_CLASS_AUDIO20_MDD_CONTROL_DEPTH_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MDD_CONTROL_DEPTH_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_DEPTH(v) ((v) << UX_CLASS_AUDIO20_MDD_CONTROL_DEPTH_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_TIME_POS (8) +#define UX_CLASS_AUDIO20_MDD_CONTROL_TIME_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MDD_CONTROL_TIME_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_TIME(v) ((v) << UX_CLASS_AUDIO20_MDD_CONTROL_TIME_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_FEEDBACK_LEVEL_POS (10) +#define UX_CLASS_AUDIO20_MDD_CONTROL_FEEDBACK_LEVEL_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MDD_CONTROL_FEEDBACK_LEVEL_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_FEEDBACK_LEVEL(v) ((v) << UX_CLASS_AUDIO20_MDD_CONTROL_FEEDBACK_LEVEL_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_UNDERFLOW_POS (12) +#define UX_CLASS_AUDIO20_MDD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MDD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_MDD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_OVERFLOW_POS (14) +#define UX_CLASS_AUDIO20_MDD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MDD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_MDD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_MDD_CONTROL_OVERFLOW_POS) + +/* Dynamic Range Compressor EUD(DRD)::bmaControls. */ +#define UX_CLASS_AUDIO20_DRD_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_DRD_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DRD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_DRD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_COMPRESS_RATIO_POS (2) +#define UX_CLASS_AUDIO20_DRD_CONTROL_COMPRESS_RATIO_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DRD_CONTROL_COMPRESS_RATIO_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_COMPRESS_RATIO(v) ((v) << UX_CLASS_AUDIO20_DRD_CONTROL_COMPRESS_RATIO_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_MAX_AMPL_POS (4) +#define UX_CLASS_AUDIO20_DRD_CONTROL_MAX_AMPL_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DRD_CONTROL_MAX_AMPL_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_MAX_AMPL(v) ((v) << UX_CLASS_AUDIO20_DRD_CONTROL_MAX_AMPL_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_THRESHOLD_POS (6) +#define UX_CLASS_AUDIO20_DRD_CONTROL_THRESHOLD_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DRD_CONTROL_THRESHOLD_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_THRESHOLD(v) ((v) << UX_CLASS_AUDIO20_DRD_CONTROL_THRESHOLD_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_ATTACK_TIME_POS (8) +#define UX_CLASS_AUDIO20_DRD_CONTROL_ATTACK_TIME_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DRD_CONTROL_ATTACK_TIME_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_ATTACK_TIME(v) ((v) << UX_CLASS_AUDIO20_DRD_CONTROL_ATTACK_TIME_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_RELEASE_TIME_POS (10) +#define UX_CLASS_AUDIO20_DRD_CONTROL_RELEASE_TIME_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DRD_CONTROL_RELEASE_TIME_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_RELEASE_TIME(v) ((v) << UX_CLASS_AUDIO20_DRD_CONTROL_RELEASE_TIME_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_UNDERFLOW_POS (12) +#define UX_CLASS_AUDIO20_DRD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DRD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_DRD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_OVERFLOW_POS (14) +#define UX_CLASS_AUDIO20_DRD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DRD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_DRD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_DRD_CONTROL_OVERFLOW_POS) + +/* Define Audio Class processing unit descriptor (PUD, bNrInPins=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_PROCESSING_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + USHORT wProcessType; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; + USHORT bmControls; + UCHAR iProcessing; +} UX_CLASS_AUDIO20_AC_PROCESSING_UNIT_DESCRIPTOR, UX_CLASS_AUDIO20_AC_PUD; + +/* PDU::bmaControls. */ +#define UX_CLASS_AUDIO20_PDU_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_PDU_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_PDU_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_PDU_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_PDU_CONTROL_ENABLE_POS) + +/* Define Audio Class up/down processing unit descriptor (PUD, bNrInPins=1, bNrModes=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_UP_DOWN_PROCESSING_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + USHORT wProcessType; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; + USHORT bmControls; + UCHAR iProcessing; + UCHAR bNrModes; + UCHAR daModes[4 * 1]; +} UX_CLASS_AUDIO20_AC_UP_DOWN_PROCESSING_UNIT_DESCRIPTOR, UX_CLASS_AUDIO20_AC_UDD; + +/* UDD::bmaControls. */ +#define UX_CLASS_AUDIO20_UDD_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_UDD_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_UDD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_UDD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_MODE_SELECT_POS (2) +#define UX_CLASS_AUDIO20_UDD_CONTROL_MODE_SELECT_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_UDD_CONTROL_MODE_SELECT_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_MODE_SELECT(v) ((v) << UX_CLASS_AUDIO20_UDD_CONTROL_MODE_SELECT_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_CLUSTER_POS (4) +#define UX_CLASS_AUDIO20_UDD_CONTROL_CLUSTER_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_UDD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_CLUSTER(v) ((v) << UX_CLASS_AUDIO20_UDD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_UNDERFLOW_POS (6) +#define UX_CLASS_AUDIO20_UDD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_UDD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_UDD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_OVERFLOW_POS (8) +#define UX_CLASS_AUDIO20_UDD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_UDD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_UDD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_UDD_CONTROL_OVERFLOW_POS) + +/* Define Audio Class dolby prologic processing unit descriptor (DPD, bNrInPins=1, bNrModes=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_DOLBY_PROCESSING_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + USHORT wProcessType; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; + USHORT bmControls; + UCHAR iProcessing; + UCHAR bNrModes; + UCHAR daModes[4 * 1]; +} UX_CLASS_AUDIO20_AC_DOLBY_PROCESSING_UNIT_DESCRIPTOR, UX_CLASS_AUDIO20_AC_DPD; + +/* DPD::bmaControls. */ +#define UX_CLASS_AUDIO20_DPD_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_DPD_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DPD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_DPD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_MODE_SELECT_POS (2) +#define UX_CLASS_AUDIO20_DPD_CONTROL_MODE_SELECT_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DPD_CONTROL_MODE_SELECT_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_MODE_SELECT(v) ((v) << UX_CLASS_AUDIO20_DPD_CONTROL_MODE_SELECT_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_CLUSTER_POS (4) +#define UX_CLASS_AUDIO20_DPD_CONTROL_CLUSTER_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DPD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_CLUSTER(v) ((v) << UX_CLASS_AUDIO20_DPD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_UNDERFLOW_POS (6) +#define UX_CLASS_AUDIO20_DPD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DPD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_DPD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_OVERFLOW_POS (8) +#define UX_CLASS_AUDIO20_DPD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DPD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_DPD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_DPD_CONTROL_OVERFLOW_POS) + +/* Define Audio Class Stereo Extender (ST_EXT) Processing Unit Descriptor. */ +typedef UX_CLASS_AUDIO20_AC_PUD UX_CLASS_AUDIO20_AC_STEREO_EXT_PROCESSING_UNIT_DESCRIPTOR; +typedef UX_CLASS_AUDIO20_AC_PUD UX_CLASS_AUDIO20_AC_ST_EXTD; + +/* ST_EXTD::bmaControls. */ +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_MODE_SELECT_POS (2) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_MODE_SELECT_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_MODE_SELECT_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_MODE_SELECT(v) ((v) << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_MODE_SELECT_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_CLUSTER_POS (4) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_CLUSTER_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_CLUSTER(v) ((v) << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_UNDERFLOW_POS (6) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_OVERFLOW_POS (8) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_ST_EXTD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_ST_EXTD_CONTROL_OVERFLOW_POS) + +/* Define Audio Class extension unit descriptor (XUD, bNrInPins=1). */ + +typedef struct UX_CLASS_AUDIO20_AC_EXTENSION_UNIT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bUnitID; + USHORT wExtensionCode; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; + USHORT bmControls; + UCHAR iExtension; +} UX_CLASS_AUDIO20_AC_EXTENSION_UNIT_DESCRIPTOR, UX_CLASS_AUDIO20_AC_XUD; + +/* XUD::bmaControls. */ +#define UX_CLASS_AUDIO20_XUD_CONTROL_ENABLE_POS (0) +#define UX_CLASS_AUDIO20_XUD_CONTROL_ENABLE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_XUD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_XUD_CONTROL_ENABLE(v) ((v) << UX_CLASS_AUDIO20_XUD_CONTROL_ENABLE_POS) +#define UX_CLASS_AUDIO20_XUD_CONTROL_CLUSTER_POS (2) +#define UX_CLASS_AUDIO20_XUD_CONTROL_CLUSTER_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_XUD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_XUD_CONTROL_CLUSTER(v) ((v) << UX_CLASS_AUDIO20_XUD_CONTROL_CLUSTER_POS) +#define UX_CLASS_AUDIO20_XUD_CONTROL_UNDERFLOW_POS (4) +#define UX_CLASS_AUDIO20_XUD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_XUD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_XUD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_XUD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_XUD_CONTROL_OVERFLOW_POS (6) +#define UX_CLASS_AUDIO20_XUD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_XUD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_XUD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_XUD_CONTROL_OVERFLOW_POS) + +/* Audio class-specific AS interface descriptor. */ + +typedef struct UX_CLASS_AUDIO20_AS_INTERFACE_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bTerminalLink; + UCHAR bmControls; + UCHAR bFormatType; + UCHAR bmFormats[4]; + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; +} UX_CLASS_AUDIO20_AS_INTERFACE_DESCRIPTOR, UX_CLASS_AUDIO20_AS_IFACED; + +/* AS interface (AS_INTERFACE)::bmaControls. */ +#define UX_CLASS_AUDIO20_AS_IFACED_CONTROL_ACTIVE_ALT_POS (0) +#define UX_CLASS_AUDIO20_AS_IFACED_CONTROL_ACTIVE_ALT_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_AS_IFACED_CONTROL_ACTIVE_ALT_POS) +#define UX_CLASS_AUDIO20_AS_IFACED_CONTROL_ACTIVE_ALT(v) ((v) << UX_CLASS_AUDIO20_AS_IFACED_CONTROL_ACTIVE_ALT_POS) +#define UX_CLASS_AUDIO20_AS_IFACED_CONTROL_VALID_ALT_POS (2) +#define UX_CLASS_AUDIO20_AS_IFACED_CONTROL_VALID_ALT_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_AS_IFACED_CONTROL_VALID_ALT_POS) +#define UX_CLASS_AUDIO20_AS_IFACED_CONTROL_VALID_ALT(v) ((v) << UX_CLASS_AUDIO20_AS_IFACED_CONTROL_VALID_ALT_POS) + + +/* Audio class-specific AS encoder descriptor. */ + +typedef struct UX_CLASS_AUDIO20_AS_ENCODER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bEncoderID; + UCHAR bEncoder; + UCHAR unknown[3]; /* These 3 bytes are not described in spec (UAC 2.0, May 31, 2006)? */ + ULONG bmControls; + UCHAR iParam1; + UCHAR iParam2; + UCHAR iParam3; + UCHAR iParam4; + UCHAR iParam5; + UCHAR iParam6; + UCHAR iParam7; + UCHAR iParam8; + UCHAR iEncoder; +} UX_CLASS_AUDIO20_AS_ENCODER_DESCRIPTOR, UX_CLASS_AUDIO20_AS_ENCD; + +/* AS ENCODER::bmaControls. */ +#define UX_CLASS_AUDIO20_ENCD_CONTROL_BIT_RATE_POS (0) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_BIT_RATE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_BIT_RATE_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_BIT_RATE(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_BIT_RATE_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_QUALITY_POS (2) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_QUALITY_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_QUALITY_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_QUALITY(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_QUALITY_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_VBR_POS (4) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_VBR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_VBR_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_VBR(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_VBR_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_TYPE_POS (6) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_TYPE_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_TYPE_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_TYPE(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_TYPE_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_UNDERFLOW_POS (8) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_OVERFLOW_POS (10) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_ENCODER_ERROR_POS (12) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_ENCODER_ERROR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_ENCODER_ERROR_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_ENCODER_ERROR(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_ENCODER_ERROR_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM1_POS (14) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM1_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM1_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM1(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM1_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM2_POS (16) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM2_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM2_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM2(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM2_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM3_POS (18) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM3_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM3_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM3(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM3_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM4_POS (20) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM4_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM4_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM4(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM4_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM5_POS (22) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM5_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM5_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM5(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM5_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM6_POS (24) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM6_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM6_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM6(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM6_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM7_POS (26) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM7_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM7_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM7(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM7_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM8_POS (28) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM8_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM8_POS) +#define UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM8(v) ((v) << UX_CLASS_AUDIO20_ENCD_CONTROL_PARAM8_POS) + + +/* Audio class-specific AS decoder descriptor. */ + +/* Audio class-specific AS MPEG decoder descriptor. */ + +typedef struct UX_CLASS_AUDIO20_AS_MPEG_DECODER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bDecoderID; + UCHAR bDecoder; + UCHAR bmMPEGCapabilities[2]; + UCHAR bmMPEGFeatures; + UCHAR bmControls; + UCHAR iDecoder; +} UX_CLASS_AUDIO20_AS_MPEG_DECODER_DESCRIPTOR, UX_CLASS_AUDIO20_AS_MPEG_DECD; + +/* MPEG DECODER::bmMPEGCapabilities. */ +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_LAYER_MASK (0x7u << 0) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_LAYER_I (0x1u << 0) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_LAYER_II (0x1u << 1) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_LAYER_III (0x1u << 2) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_MPEG1_ONLY (0x1u << 3) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_MPEG1_DUAL_CH (0x1u << 4) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_MPEG2_STEREO (0x1u << 5) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_MPEG2_7_1_CH (0x1u << 6) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_ADAPTIVE_MULTI_CH_PREDICT (0x1u << 7) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_MPEG2_MULTILINGUAL_MASK (0x3u << 8) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_MPEG2_MULTI_NOT_SUPPORT (0x0u << 8) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_MPEG2_MULTI_FS (0x1u << 8) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_MPEG2_MULTI_FS_HALF_FS (0x3u << 8) +#define UX_CLASS_AUDIO20_MPEG_DECD_CAP_SUPPORT_HALF_FS (0x1u << 10) + +/* MPEG DECODER::bmMPEGFeatures. */ +#define UX_CLASS_AUDIO20_MPEG_DECD_FEAT_IDYN_RNG_CTRL_MASK (0x3u << 4) /* Internal Dynamic Range Control */ +#define UX_CLASS_AUDIO20_MPEG_DECD_FEAT_IDYN_RNG_CTRL_NOT_SUP (0x0u << 4) /* Not support */ +#define UX_CLASS_AUDIO20_MPEG_DECD_FEAT_IDYN_RNG_CTRL_NOT_SCAL (0x1u << 4) /* Not scalable */ +#define UX_CLASS_AUDIO20_MPEG_DECD_FEAT_IDYN_RNG_CTRL_SCAL_COMMON (0x2u << 4) /* Common boost and cut scaling value */ +#define UX_CLASS_AUDIO20_MPEG_DECD_FEAT_IDYN_RNG_CTRL_SCAL_SEPARA (0x3u << 4) /* Separate boost and cut scaling value */ + +/* MPEG DECODER::bmControls. */ +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_UNDERFLOW_POS (0) +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_OVERFLOW_POS (2) +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_DECODER_ERROR_POS (4) +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_DECODER_ERROR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_DECODER_ERROR_POS) +#define UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_DECODER_ERROR(v) ((v) << UX_CLASS_AUDIO20_MPEG_DECD_CONTROL_DECODER_ERROR_POS) + +/* Audio class-specific AS AC-3 decoder descriptor. */ + +typedef struct UX_CLASS_AUDIO20_AS_AC3_DECODER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bDecoderID; + UCHAR bDecoder; + UCHAR bmBSID[4]; + UCHAR bmAC3Features; + UCHAR bmControls; + UCHAR iDecoder; +} UX_CLASS_AUDIO20_AS_AC3_DECODER_DESCRIPTOR, UX_CLASS_AUDIO20_AS_AC3_DECD; + +/* AC3 DECODER::bmAC3Features. */ +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_RF_MODE (0x1u << 0) +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_LINE_MODE (0x1u << 1) +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_CUSTOM0_MODE (0x1u << 2) +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_CUSTOM1_MODE (0x1u << 3) +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_IDYN_RNG_CTRL_MASK (0x3u << 4) /* Internal Dynamic Range Control */ +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_IDYN_RNG_CTRL_NOT_SUP (0x0u << 4) /* Not support */ +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_IDYN_RNG_CTRL_NOT_SCAL (0x3u << 4) /* Not scalable */ +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_IDYN_RNG_CTRL_SCAL_COMMON (0x3u << 4) /* Common boost and cut scaling value */ +#define UX_CLASS_AUDIO20_AC3_DECD_FEAT_IDYN_RNG_CTRL_SCAL_SEPARATE (0x3u << 4) /* Separate boost and cut scaling value */ + +/* AC3 DECODER::bmControls. */ +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_UNDERFLOW_POS (0) +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_AC3_DECD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_AC3_DECD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_OVERFLOW_POS (2) +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_AC3_DECD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_AC3_DECD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_DECODER_ERROR_POS (4) +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_DECODER_ERROR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_AC3_DECD_CONTROL_DECODER_ERROR_POS) +#define UX_CLASS_AUDIO20_AC3_DECD_CONTROL_DECODER_ERROR(v) ((v) << UX_CLASS_AUDIO20_AC3_DECD_CONTROL_DECODER_ERROR_POS) + +/* Audio class-specific AS WMA decoder descriptor. */ + +typedef struct UX_CLASS_AUDIO20_AS_WMA_DECODER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bDecoderID; + UCHAR bDecoder; + UCHAR bmWMAProfile[2]; + UCHAR bmControls; + UCHAR iDecoder; +} UX_CLASS_AUDIO20_AS_WMA_DECODER_DESCRIPTOR, UX_CLASS_AUDIO20_AS_WMA_DECD; + +/* WMA DECODER::bmWMAProfile. */ +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_1_L1 (1u << 0) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_2_L2 (1u << 1) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_3_L3 (1u << 2) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_OTHER_L (1u << 3) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_SPEECH_1_S1 (1u << 4) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_SPEECH_2_S2 (1u << 5) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_PRO_1_M1 (1u << 6) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_PRO_2_M2 (1u << 7) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_PRO_3_M3 (1u << 8) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_PRO_OTHER_M (1u << 9) +#define UX_CLASS_AUDIO20_WMA_DECD_PROFILE_LOSSLESS_SUPPORT (1u << 10) + +/* WMA DECODER::bmControls. */ +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_UNDERFLOW_POS (0) +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_WMA_DECD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_WMA_DECD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_OVERFLOW_POS (2) +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_WMA_DECD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_WMA_DECD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_DECODER_ERROR_POS (4) +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_DECODER_ERROR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_WMA_DECD_CONTROL_DECODER_ERROR_POS) +#define UX_CLASS_AUDIO20_WMA_DECD_CONTROL_DECODER_ERROR(v) ((v) << UX_CLASS_AUDIO20_WMA_DECD_CONTROL_DECODER_ERROR_POS) + +/* Audio class-specific AS DTS decoder descriptor. */ + +typedef struct UX_CLASS_AUDIO20_AS_DTS_DECODER_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bDecoderID; + UCHAR bDecoder; + UCHAR bmCapabilities; + UCHAR bmControls; + UCHAR iDecoder; +} UX_CLASS_AUDIO20_AS_DTS_DECODER_DESCRIPTOR, UX_CLASS_AUDIO20_AS_DTS_DECD; + +/* DTS DECODER::bmCapabilities. */ +#define UX_CLASS_AUDIO20_DTS_DECD_CAP_CORE (0x1u << 0) +#define UX_CLASS_AUDIO20_DTS_DECD_CAP_LOSSLESS (0x1u << 1) +#define UX_CLASS_AUDIO20_DTS_DECD_CAP_LBR (0x1u << 2) +#define UX_CLASS_AUDIO20_DTS_DECD_CAP_MULTI_STREAM_MIX (0x1u << 3) +#define UX_CLASS_AUDIO20_DTS_DECD_CAP_DUAL_DECODE (0x1u << 4) + +/* DTS DECODER::bmControls. */ +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_UNDERFLOW_POS (2) +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_UNDERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DTS_DECD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_UNDERFLOW(v) ((v) << UX_CLASS_AUDIO20_DTS_DECD_CONTROL_UNDERFLOW_POS) +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_OVERFLOW_POS (4) +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_OVERFLOW_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DTS_DECD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_OVERFLOW(v) ((v) << UX_CLASS_AUDIO20_DTS_DECD_CONTROL_OVERFLOW_POS) +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_DECODER_ERROR_POS (6) +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_DECODER_ERROR_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_DTS_DECD_CONTROL_DECODER_ERROR_POS) +#define UX_CLASS_AUDIO20_DTS_DECD_CONTROL_DECODER_ERROR(v) ((v) << UX_CLASS_AUDIO20_DTS_DECD_CONTROL_DECODER_ERROR_POS) + + +/* Audio class-specific isochronous audio data endpoint descriptor (EPD). */ +typedef struct UX_CLASS_AUDIO20_ENDPOINT_DESCRIPTOR_STRUCT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bmAttributes; + UCHAR bmControls; + UCHAR bLockDelayUnits; + USHORT wLockDelay; +} UX_CLASS_AUDIO20_ENDPOINT_DESCRIPTOR, UX_CLASS_AUDIO20_EPD; + +/* EPD::bmAttributes. */ +#define UX_CLASS_AUDIO20_EPD_ATTR_MAX_PACKET_SIZE_ONLY (0x1u << 7) + +/* EPD::bmControls. */ +#define UX_CLASS_AUDIO20_EPD_CONTROL_PITCH_POS (0) +#define UX_CLASS_AUDIO20_EPD_CONTROL_PITCH_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_EPD_CONTROL_PITCH_POS) +#define UX_CLASS_AUDIO20_EPD_CONTROL_PITCH(v) ((v) << UX_CLASS_AUDIO20_EPD_CONTROL_PITCH_POS) +#define UX_CLASS_AUDIO20_EPD_CONTROL_OVERRUN_POS (2) +#define UX_CLASS_AUDIO20_EPD_CONTROL_OVERRUN_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_EPD_CONTROL_OVERRUN_POS) +#define UX_CLASS_AUDIO20_EPD_CONTROL_OVERRUN(v) ((v) << UX_CLASS_AUDIO20_EPD_CONTROL_OVERRUN_POS) +#define UX_CLASS_AUDIO20_EPD_CONTROL_UNDERRUN_POS (4) +#define UX_CLASS_AUDIO20_EPD_CONTROL_UNDERRUN_MASK (UX_CLASS_AUDIO20_CONTROL_MASK << UX_CLASS_AUDIO20_EPD_CONTROL_UNDERRUN_POS) +#define UX_CLASS_AUDIO20_EPD_CONTROL_UNDERRUN(v) ((v) << UX_CLASS_AUDIO20_EPD_CONTROL_UNDERRUN_POS) + +/* EPD::bLockDelayUnits. */ +#define UX_CLASS_AUDIO20_EPD_LOCK_DELAY_UNITS_UNDEFINED 0 +#define UX_CLASS_AUDIO20_EPD_LOCK_DELAY_UNITS_MS 1 +#define UX_CLASS_AUDIO20_EPD_LOCK_DELAY_UNITS_DEC_PCM_SAMPLES 2 + + +/* Audio class control request layout. */ + +typedef struct UX_CLASS_AUDIO20_REQUEST_VALUE_CS_CN_STRUCT { + UCHAR channel_num; /* Channel Number (CN) */ + UCHAR control_sel; /* Control Selector (CS) */ +} UX_CLASS_AUDIO20_REQUEST_VALUE_CS_CN; + +typedef struct UX_CLASS_AUDIO20_REQUEST_VALUE_MIXER_STRUCT { + UCHAR mixer_ctrl_num; /* Mixer Control Number (MCN) */ + UCHAR control_sel; /* Control Selector (CS) */ +} UX_CLASS_AUDIO20_REQUEST_VALUE_MIXER, UX_CLASS_AUDIO20_REQUEST_VALUE_CS_MCN; + +typedef struct UX_CLASS_AUDIO20_REQUEST_VALUE_CONTROL_STRUCT { + UCHAR cn_mcn; /* CN/MCN */ + UCHAR cs; /* CS */ +} UX_CLASS_AUDIO20_REQUEST_VALUE_CONTROL; + +typedef struct UX_CLASS_AUDIO20_REQUEST_INDEX_EP_STRUCT { + UCHAR ep_addr; /* Endpoint Address */ + UCHAR reserved_zero; +} UX_CLASS_AUDIO20_REQUEST_INDEX_EP; + +typedef struct UX_CLASS_AUDIO20_REQUEST_INDEX_INTERFACE_STRUCT { + UCHAR iface_num; /* Interface number */ + UCHAR entity_id; +} UX_CLASS_AUDIO20_REQUEST_INDEX_INTERFACE; + +typedef struct UX_CLASS_AUDIO20_REQUEST_INDEX_CONTROL_STRUCT { + UCHAR ep_iface; /* Endpoint Address/Interface Number */ + UCHAR entity_id_zero; /* Entity ID/Zero */ +} UX_CLASS_AUDIO20_REQUEST_INDEX_CONTROL; + +typedef struct UX_CLASS_AUDIO20_REQUEST_STRUCT +{ + UCHAR bmRequestType; + UCHAR bRequest; + union UX_CLASS_AUDIO20_REQUEST_VALUE_UNION { + USHORT value; + UX_CLASS_AUDIO20_REQUEST_VALUE_CS_CN + control_cs_cn; + UX_CLASS_AUDIO20_REQUEST_VALUE_MIXER + control_mixer; + UX_CLASS_AUDIO20_REQUEST_VALUE_CONTROL + control; + USHORT mem_offset; + } wValue; + union UX_CLASS_AUDIO20_REQUEST_INDEX_UNION { + USHORT value; + UX_CLASS_AUDIO20_REQUEST_INDEX_EP + ep; + UX_CLASS_AUDIO20_REQUEST_INDEX_INTERFACE + iface; + UX_CLASS_AUDIO20_REQUEST_INDEX_CONTROL + control; + } wIndex; + USHORT wLength; +} UX_CLASS_AUDIO20_REQUEST; + +typedef struct UX_CLASS_AUDIO20_RANGE_1B_STRUCT +{ + UCHAR bMIN; + UCHAR bMAX; + UCHAR bRES; +} UX_CLASS_AUDIO20_RANGE_1B; + +typedef struct UX_CLASS_AUDIO20_RANGE_1B_BLOCK_STRUCT +{ + USHORT wNumSubRanges; + UX_CLASS_AUDIO20_RANGE_1B + aSubRange[1]; +} UX_CLASS_AUDIO20_RANGE_1B_BLOCK; + +typedef struct UX_CLASS_AUDIO20_RANGE_2B_STRUCT +{ + USHORT wMIN; + USHORT wMAX; + USHORT wRES; +} UX_CLASS_AUDIO20_RANGE_2B; + +typedef struct UX_CLASS_AUDIO20_RANGE_2B_BLOCK_STRUCT +{ + USHORT wNumSubRanges; + UX_CLASS_AUDIO20_RANGE_2B + aSubRange[1]; +} UX_CLASS_AUDIO20_RANGE_2B_BLOCK; + +typedef struct UX_CLASS_AUDIO20_RANGE_4B_STRUCT +{ + ULONG dMIN; + ULONG dMAX; + ULONG dRES; +} UX_CLASS_AUDIO20_RANGE_4B; + +typedef struct UX_CLASS_AUDIO20_RANGE_4B_BLOCK_STRUCT +{ + USHORT wNumSubRanges; + struct UX_CLASS_AUDIO20_RANGE_4B_UNALIGNED_STRUCT { + UCHAR dMIN[4]; + UCHAR dMAX[4]; + UCHAR dRES[4]; + } aSubRange[1]; /* Not 4-byte aligned. */ +} UX_CLASS_AUDIO20_RANGE_4B_BLOCK; + + +/* Audio Class 2.0 connector control CUR parameter block. */ + +typedef struct UX_CLASS_AUDIO20_CONNECTOR_CONTROL_CUR_PARAM_BLOCK_STRUCT +{ + UCHAR bNrChannels; + UCHAR bmChannelConfig[4]; + UCHAR iChannelNames; +} UX_CLASS_AUDIO20_CONNECTOR_CONTROL_CUR_PARAM_BLOCK; + +/* Audio Class 2.0 Graphic Equalizer Control CUR parameter block (NrBits=4). */ + +typedef struct UX_CLASS_AUDIO20_GEQ_CONTROL_CUR_PARAM_BLOCK_STRUCT +{ + ULONG bmBandsPresent; + UCHAR bCUR[4]; +} UX_CLASS_AUDIO20_GEQ_CONTROL_CUR_PARAM_BLOCK; + +/* Audio Class 2.0 Graphic Equalizer Control RANGE parameter block (NrBits=1). */ + +typedef struct UX_CLASS_AUDIO20_GEQ_CONTROL_RANGE_PARAM_BLOCK_STRUCT +{ + ULONG bmBandsPresent; + UX_CLASS_AUDIO20_RANGE_1B + aRNG[1]; +} UX_CLASS_AUDIO20_GEQ_CONTROL_RANGE_PARAM_BLOCK; + +/* Audio Class 2.0 Valid Alternate Settings Control CUR parameter block (bControlSize=1). */ + +typedef struct UX_CLASS_AUDIO20_VALID_ALT_SETT_CONTROL_CUR_PARAM_BLOCK_STRUCT +{ + UCHAR bControlSize; /* Number of bytes. */ + UCHAR bmValidAltSettings[1]; /* bControlSize bytes. */ +} UX_CLASS_AUDIO20_VALID_ALT_SETT_CONTROL_CUR_PARAM_BLOCK; + +/* Audio Class 2.0 High/Low Scaling Control CUR parameter block. */ + +typedef struct UX_CLASS_AUDIO20_HI_LO_SCALING_CONTROL_CUR_PARAM_BLOCK_STRUCT +{ + UCHAR bCUR_Lo; + UCHAR bCUR_Hi; +} UX_CLASS_AUDIO20_HI_LO_SCALING_CONTROL_CUR_PARAM_BLOCK; + +/* Audio Class 2.0 High/Low Scaling Control RANGE parameter block (wNumSubRanges=1). */ + +typedef struct UX_CLASS_AUDIO20_HI_LO_SCALING_CONTROL_RANGE_PARAM_BLOCK_STRUCT +{ + USHORT wNumSubRanges; + UX_CLASS_AUDIO20_RANGE_1B + aRNG[1]; +} UX_CLASS_AUDIO20_HI_LO_SCALING_CONTROL_RANGE_PARAM_BLOCK; + + +/* Audio Class 2.0 Interrupt Data Message Format. */ + +typedef struct UX_CLASS_AUDIO20_INT_MESSAGE_STRUCT +{ + UCHAR bInfo; + UCHAR bAttribute; + union UX_CLASS_AUDIO20_INT_MESSAGE_VALUE { + USHORT value; + UX_CLASS_AUDIO20_REQUEST_VALUE_CONTROL + control; + } wValue; + union UX_CLASS_AUDIO20_INT_MESSAGE_INDEX { + USHORT value; + UX_CLASS_AUDIO20_REQUEST_INDEX_CONTROL + control; + } wIndex; +} UX_CLASS_AUDIO20_INT_MESSAGE; + + +/* Audio Class 2.0 Type I Format Type Descriptor. */ + +typedef struct UX_CLASS_AUDIO20_TYPE_I_FORMAT_TYPE_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bFormatType; + UCHAR bSubslotSize; + UCHAR bBitResolution; +} UX_CLASS_AUDIO20_TYPE_I_FORMAT_TYPE; + +/* Audio Class 2.0 Type II Format Type Descriptor. */ + +typedef struct UX_CLASS_AUDIO20_TYPE_II_FORMAT_TYPE_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bFormatType; + USHORT wMaxBitRate; + USHORT wSlotsPerFrame; +} UX_CLASS_AUDIO20_TYPE_II_FORMAT_TYPE; + +/* Audio Class 2.0 Type III Format Type Descriptor. */ + +typedef struct UX_CLASS_AUDIO20_TYPE_III_FORMAT_TYPE_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bFormatType; + UCHAR bSubslotSize; + UCHAR bBitResolution; +} UX_CLASS_AUDIO20_TYPE_III_FORMAT_TYPE; + +/* Audio Class 2.0 Type IV Format Type Descriptor. */ + +typedef struct UX_CLASS_AUDIO20_TYPE_IV_FORMAT_TYPE_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bFormatType; +} UX_CLASS_AUDIO20_TYPE_IV_FORMAT_TYPE; + +/* Audio Class 2.0 Extended Type I Format Type Descriptor. */ + +typedef struct UX_CLASS_AUDIO20_EXT_TYPE_I_FORMAT_TYPE_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bFormatType; + UCHAR bSubslotSize; + UCHAR bBitResolution; + UCHAR bHeaderLength; + UCHAR bControlSize; + UCHAR bSideBandProtocol; +} UX_CLASS_AUDIO20_EXT_TYPE_I_FORMAT_TYPE; + +/* Audio Class 2.0 Extended Type II Format Type Descriptor. */ + +typedef struct UX_CLASS_AUDIO20_EXT_TYPE_II_FORMAT_TYPE_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bFormatType; + USHORT wMaxBitRate; + USHORT wSamplesPerFrame; + UCHAR bHeaderLength; + UCHAR bSideBandProtocol; +} UX_CLASS_AUDIO20_EXT_TYPE_II_FORMAT_TYPE; + +/* Audio Class 2.0 Extended Type III Format Type Descriptor. */ + +typedef struct UX_CLASS_AUDIO20_EXT_TYPE_III_FORMAT_TYPE_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + UCHAR bFormatType; + UCHAR bSubslotSize; + UCHAR bBitResolution; + UCHAR bHeaderLength; + UCHAR bSideBandProtocol; +} UX_CLASS_AUDIO20_EXT_TYPE_III_FORMAT_TYPE; + +/* Audio Class 2.0 Hi-Res Presentation TimeStamp Layout. */ + +typedef struct UX_CLASS_AUDIO20_HI_RES_PRESENTATION_TIMESTAMP_STRUCT +{ + UCHAR bmFlags; + UCHAR qNanoSeconds[8]; +} UX_CLASS_AUDIO20_HI_RES_PRESENTATION_TIMESTAMP; + +#define UX_CLASS_AUDIO20_HI_RES_PRESENTATION_TIMESTAMP_FLAG_VALID (1u << 31) + +#endif diff --git a/common/core/inc/ux_dcd_sim_slave.h b/common/core/inc/ux_dcd_sim_slave.h index dd2e8894..e7fb9dd0 100644 --- a/common/core/inc/ux_dcd_sim_slave.h +++ b/common/core/inc/ux_dcd_sim_slave.h @@ -168,7 +168,7 @@ UINT _ux_dcd_sim_slave_transfer_abort(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLA C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/core/inc/ux_device_class_dpump.h b/common/core/inc/ux_device_class_dpump.h index 659bdbaf..94633e6e 100644 --- a/common/core/inc/ux_device_class_dpump.h +++ b/common/core/inc/ux_device_class_dpump.h @@ -139,6 +139,6 @@ UINT _ux_device_class_dpump_change(UX_SLAVE_CLASS_COMMAND *command); C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/core/inc/ux_device_stack.h b/common/core/inc/ux_device_stack.h index 2b514dd2..a81ab9ef 100644 --- a/common/core/inc/ux_device_stack.h +++ b/common/core/inc/ux_device_stack.h @@ -25,7 +25,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_stack.h PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -49,6 +49,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -89,11 +93,11 @@ UINT _ux_device_stack_initialize(UCHAR * device_framework_high_speed, ULONG d UCHAR * string_framework, ULONG string_framework_length, UCHAR * language_id_framework, ULONG language_id_framework_length, UINT (*ux_system_slave_change_function)(ULONG)); -UINT _ux_device_stack_interface_delete(UX_SLAVE_INTERFACE *interface); +UINT _ux_device_stack_interface_delete(UX_SLAVE_INTERFACE *ux_interface); UINT _ux_device_stack_interface_get(UINT interface_value); UINT _ux_device_stack_interface_set(UCHAR * device_framework, ULONG device_framework_length, ULONG alternate_setting_value); -UINT _ux_device_stack_interface_start(UX_SLAVE_INTERFACE *interface); +UINT _ux_device_stack_interface_start(UX_SLAVE_INTERFACE *ux_interface); UINT _ux_device_stack_set_feature(ULONG request_type, ULONG request_value, ULONG request_index); UINT _ux_device_stack_transfer_all_request_abort(UX_SLAVE_ENDPOINT *endpoint, ULONG completion_code); UINT _ux_device_stack_transfer_request(UX_SLAVE_TRANSFER *transfer_request, ULONG slave_length, ULONG host_length); @@ -109,7 +113,7 @@ UINT _ux_device_stack_transfer_run(UX_SLAVE_TRANSFER *transfer_request, ULONG C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/core/inc/ux_hcd_sim_host.h b/common/core/inc/ux_hcd_sim_host.h index 4b43bdd7..2adf6746 100644 --- a/common/core/inc/ux_hcd_sim_host.h +++ b/common/core/inc/ux_hcd_sim_host.h @@ -272,7 +272,7 @@ UINT _ux_hcd_sim_host_transfer_run(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/core/inc/ux_host_class_dpump.h b/common/core/inc/ux_host_class_dpump.h index df5de875..cfb894f7 100644 --- a/common/core/inc/ux_host_class_dpump.h +++ b/common/core/inc/ux_host_class_dpump.h @@ -82,7 +82,7 @@ extern "C" { /* Define Data Pump Class string constants. */ -#define UX_HOST_CLASS_DPUMP_GENERIC_NAME "USB DPUMP" +#define UX_HOST_CLASS_DPUMP_GENERIC_NAME "USB DPUMP" /* Define R/W lock bits for standalone mode. */ @@ -113,6 +113,6 @@ UINT _ux_host_class_dpump_ioctl(UX_HOST_CLASS_DPUMP *dpump, ULONG ioctl_funct C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/core/inc/ux_host_stack.h b/common/core/inc/ux_host_stack.h index 06066325..6bb9891c 100644 --- a/common/core/inc/ux_host_stack.h +++ b/common/core/inc/ux_host_stack.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_host_stack.h PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -60,6 +60,11 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added standalone HUB, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -82,25 +87,26 @@ extern "C" { #define UX_HOST_STACK_ENUM_PORT_ENABLE (UX_STATE_STEP + 0) #define UX_HOST_STACK_ENUM_PORT_RESET (UX_STATE_STEP + 1) #define UX_HOST_STACK_ENUM_PORT_RESET_WAIT (UX_STATE_STEP + 2) -#define UX_HOST_STACK_ENUM_DEVICE_ADDR_SET (UX_STATE_STEP + 3) -#define UX_HOST_STACK_ENUM_DEVICE_ADDR_SENT (UX_STATE_STEP + 4) -#define UX_HOST_STACK_ENUM_DEVICE_DESCR_READ (UX_STATE_STEP + 5) -#define UX_HOST_STACK_ENUM_DEVICE_DESCR_PARSE (UX_STATE_STEP + 6) -#define UX_HOST_STACK_ENUM_CONFIG_DESCR_READ (UX_STATE_STEP + 7) -#define UX_HOST_STACK_ENUM_CONFIG_DESCR_PARSE (UX_STATE_STEP + 8) -#define UX_HOST_STACK_ENUM_CONFIG_DESCR_NEXT (UX_STATE_STEP + 9) -#define UX_HOST_STACK_ENUM_CONFIG_SET (UX_STATE_STEP + 10) -#define UX_HOST_STACK_ENUM_CONFIG_ACTIVATE (UX_STATE_STEP + 11) -#define UX_HOST_STACK_ENUM_ACTIVATE (UX_STATE_STEP + 12) -#define UX_HOST_STACK_ENUM_ACTIVATE_WAIT (UX_STATE_STEP + 13) -#define UX_HOST_STACK_ENUM_RETRY (UX_STATE_STEP + 14) -#define UX_HOST_STACK_ENUM_NEXT (UX_STATE_STEP + 15) -#define UX_HOST_STACK_ENUM_TRANS_LOCK_WAIT (UX_STATE_STEP + 16) -#define UX_HOST_STACK_ENUM_TRANS_WAIT (UX_STATE_STEP + 17) -#define UX_HOST_STACK_ENUM_WAIT (UX_STATE_STEP + 18) -#define UX_HOST_STACK_ENUM_FAIL (UX_STATE_STEP + 19) -#define UX_HOST_STACK_ENUM_DONE (UX_STATE_STEP + 20) -#define UX_HOST_STACK_ENUM_IDLE (UX_STATE_STEP + 21) +#define UX_HOST_STACK_ENUM_HUB_OPERATION_WAIT (UX_STATE_STEP + 3) +#define UX_HOST_STACK_ENUM_DEVICE_ADDR_SET (UX_STATE_STEP + 4) +#define UX_HOST_STACK_ENUM_DEVICE_ADDR_SENT (UX_STATE_STEP + 5) +#define UX_HOST_STACK_ENUM_DEVICE_DESCR_READ (UX_STATE_STEP + 6) +#define UX_HOST_STACK_ENUM_DEVICE_DESCR_PARSE (UX_STATE_STEP + 7) +#define UX_HOST_STACK_ENUM_CONFIG_DESCR_READ (UX_STATE_STEP + 8) +#define UX_HOST_STACK_ENUM_CONFIG_DESCR_PARSE (UX_STATE_STEP + 9) +#define UX_HOST_STACK_ENUM_CONFIG_DESCR_NEXT (UX_STATE_STEP + 10) +#define UX_HOST_STACK_ENUM_CONFIG_SET (UX_STATE_STEP + 11) +#define UX_HOST_STACK_ENUM_CONFIG_ACTIVATE (UX_STATE_STEP + 12) +#define UX_HOST_STACK_ENUM_ACTIVATE (UX_STATE_STEP + 13) +#define UX_HOST_STACK_ENUM_ACTIVATE_WAIT (UX_STATE_STEP + 14) +#define UX_HOST_STACK_ENUM_RETRY (UX_STATE_STEP + 15) +#define UX_HOST_STACK_ENUM_NEXT (UX_STATE_STEP + 16) +#define UX_HOST_STACK_ENUM_TRANS_LOCK_WAIT (UX_STATE_STEP + 17) +#define UX_HOST_STACK_ENUM_TRANS_WAIT (UX_STATE_STEP + 18) +#define UX_HOST_STACK_ENUM_WAIT (UX_STATE_STEP + 19) +#define UX_HOST_STACK_ENUM_FAIL (UX_STATE_STEP + 20) +#define UX_HOST_STACK_ENUM_DONE (UX_STATE_STEP + 21) +#define UX_HOST_STACK_ENUM_IDLE (UX_STATE_STEP + 22) /* Define Host Stack component function prototypes. */ @@ -117,7 +123,7 @@ UINT _ux_host_stack_bandwidth_check(UX_HCD *hcd, UX_ENDPOINT *endpoint); UX_HOST_CLASS * _ux_host_stack_class_call(UX_HOST_CLASS_COMMAND *class_command); UINT _ux_host_stack_class_device_scan(UX_DEVICE *device); -UINT _ux_host_stack_class_get(UCHAR *class_name, UX_HOST_CLASS **class); +UINT _ux_host_stack_class_get(UCHAR *class_name, UX_HOST_CLASS **ux_class); UINT _ux_host_stack_class_instance_destroy(UX_HOST_CLASS *class, VOID *class_instance); UINT _ux_host_stack_class_instance_create(UX_HOST_CLASS *class, VOID *class_instance); UINT _ux_host_stack_class_instance_get(UX_HOST_CLASS *class, UINT class_index, VOID **class_instance); @@ -132,7 +138,7 @@ UINT _ux_host_stack_configuration_instance_create(UX_CONFIGURATION *configura VOID _ux_host_stack_configuration_instance_delete(UX_CONFIGURATION *configuration); UINT _ux_host_stack_configuration_interface_get(UX_CONFIGURATION *configuration, UINT interface_index, UINT alternate_setting_index, - UX_INTERFACE **interface); + UX_INTERFACE **ux_interface); UINT _ux_host_stack_configuration_interface_scan(UX_CONFIGURATION *configuration); UINT _ux_host_stack_configuration_set(UX_CONFIGURATION *configuration); VOID _ux_host_stack_delay_ms(ULONG time); @@ -160,11 +166,11 @@ VOID _ux_host_stack_hcd_thread_entry(ULONG input); UINT _ux_host_stack_hcd_transfer_request(UX_TRANSFER *transfer_request); UINT _ux_host_stack_initialize(UINT (*ux_system_host_change_function)(ULONG, UX_HOST_CLASS *, VOID *)); UINT _ux_host_stack_uninitialize(VOID); -UINT _ux_host_stack_interface_endpoint_get(UX_INTERFACE *interface, UINT endpoint_index, UX_ENDPOINT **endpoint); -UINT _ux_host_stack_interface_instance_create(UX_INTERFACE *interface); -VOID _ux_host_stack_interface_instance_delete(UX_INTERFACE *interface); -UINT _ux_host_stack_interface_set(UX_INTERFACE *interface); -UINT _ux_host_stack_interface_setting_select(UX_INTERFACE *interface); +UINT _ux_host_stack_interface_endpoint_get(UX_INTERFACE *ux_interface, UINT endpoint_index, UX_ENDPOINT **endpoint); +UINT _ux_host_stack_interface_instance_create(UX_INTERFACE *ux_interface); +VOID _ux_host_stack_interface_instance_delete(UX_INTERFACE *ux_interface); +UINT _ux_host_stack_interface_set(UX_INTERFACE *ux_interface); +UINT _ux_host_stack_interface_setting_select(UX_INTERFACE *ux_interface); UINT _ux_host_stack_interfaces_scan(UX_CONFIGURATION *configuration, UCHAR * descriptor); VOID _ux_host_stack_new_configuration_create(UX_DEVICE *device, UX_CONFIGURATION *configuration); UX_DEVICE *_ux_host_stack_new_device_get(VOID); @@ -172,7 +178,7 @@ UINT _ux_host_stack_new_device_create(UX_HCD *hcd, UX_DEVICE *device_owner, UINT port_index, UINT device_speed, UINT port_max_power, UX_DEVICE **created_device); -UINT _ux_host_stack_new_endpoint_create(UX_INTERFACE *interface, UCHAR * interface_endpoint); +UINT _ux_host_stack_new_endpoint_create(UX_INTERFACE *ux_interface, UCHAR * interface_endpoint); UINT _ux_host_stack_new_interface_create(UX_CONFIGURATION *configuration, UCHAR * descriptor, ULONG length); VOID _ux_host_stack_rh_change_process(VOID); UINT _ux_host_stack_rh_device_extraction(UX_HCD *hcd, UINT port_index); @@ -192,7 +198,7 @@ UINT _ux_host_stack_transfer_run(UX_TRANSFER *transfer_request); C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/core/inc/ux_user_sample.h b/common/core/inc/ux_user_sample.h index 9005d351..0df602e1 100644 --- a/common/core/inc/ux_user_sample.h +++ b/common/core/inc/ux_user_sample.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* ux_user.h PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* */ /* AUTHOR */ /* */ @@ -78,6 +78,11 @@ /* added option to validate */ /* class code in enumeration, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added audio class features, */ +/* added device CDC_ACM and */ +/* printer write auto ZLP, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -88,6 +93,8 @@ /* Define various build options for the USBX port. The application should either make changes here by commenting or un-commenting the conditional compilation defined OR supply the defines though the compiler's equivalent of the -D option. */ + +/* Define USBX Generic Thread Stack Size. */ /* #define UX_THREAD_STACK_SIZE (2 * 1024) */ /* Define USBX Host Enum Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */ @@ -96,7 +103,7 @@ */ -/* Define USBX Host Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */ +/* Define USBX Host HCD Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */ /* #define UX_HOST_HCD_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE */ @@ -369,13 +376,22 @@ /* #define UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE */ +/* Defined, device HID interrupt OUT transfer is supported. */ + +/* #define UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT */ + /* defined, this macro enables device audio feedback endpoint support. */ /* #define UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT */ -/* Defined, device HID interrupt OUT transfer is supported. */ +/* Defined, class _write is pending ZLP automatically (complete transfer) after buffer is sent. */ -/* #define UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT */ +/* #define UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP */ +/* #define UX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP */ + +/* defined, this macro enables device audio interrupt endpoint support. */ + +/* define UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT */ /* Defined, this macro enables device bi-directional-endpoint support. */ @@ -402,6 +418,15 @@ /* #define UX_HOST_CLASS_HID_REPORT_TRANSFER_TIMEOUT 10000 */ +/* Defined, host audio UAC 2.0 is supported. */ +/* #define UX_HOST_CLASS_AUDIO_2_SUPPORT */ + +/* Defined, host audio optional feedback endpoint is supported. */ +/* #define UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT */ + +/* Defined, host audio optional interrupt endpoint is support. */ +/* #define UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT */ + /* Defined, this value will only enable the host side of usbx. */ /* #define UX_HOST_SIDE_ONLY */ diff --git a/common/core/inc/ux_utility.h b/common/core/inc/ux_utility.h index 3b25f701..39bd50da 100644 --- a/common/core/inc/ux_utility.h +++ b/common/core/inc/ux_utility.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_utility.h PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -53,6 +53,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added macros for RTOS calls,*/ +/* fixed OHCI PRSC issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -168,22 +172,50 @@ extern ALIGN_TYPE _ux_utility_time_elapsed(ALIGN_TYPE, ALIGN_TYPE); #if !defined(UX_STANDALONE) #define _ux_system_semaphore_create _ux_utility_semaphore_create -#define _ux_system_semaphore_create_rc _ux_utility_semaphore_create +#define _ux_system_semaphore_create_norc _ux_utility_semaphore_create +#define _ux_system_semaphore_created(sem) ((sem)->tx_semaphore_id != UX_EMPTY) +#define _ux_system_semaphore_get _ux_utility_semaphore_get +#define _ux_system_semaphore_get_norc _ux_utility_semaphore_get +#define _ux_system_semaphore_waiting(sem) ((sem)->tx_semaphore_count != 0) #define _ux_system_semaphore_delete _ux_utility_semaphore_delete -#define _ux_system_thread_create_rc _ux_utility_thread_create +#define _ux_system_semaphore_put _ux_utility_semaphore_put +#define _ux_system_thread_create _ux_utility_thread_create +#define _ux_system_thread_create_norc _ux_utility_thread_create +#define _ux_system_thread_created(t) ((t)->tx_thread_id != UX_EMPTY) +#define _ux_system_thread_delete _ux_utility_thread_delete #define _ux_system_mutex_create _ux_utility_mutex_create #define _ux_system_mutex_delete _ux_utility_mutex_delete #define _ux_system_mutex_off _ux_utility_mutex_off #define _ux_system_mutex_on _ux_utility_mutex_on +#define _ux_system_event_flags_create _ux_utility_event_flags_create +#define _ux_system_event_flags_created(e) ((e)->tx_event_flags_group_id != UX_EMPTY) +#define _ux_system_event_flags_delete _ux_utility_event_flags_delete +#define _ux_system_event_flags_get _ux_utility_event_flags_get +#define _ux_system_event_flags_set _ux_utility_event_flags_set +#define _ux_system_event_flags_set_rc _ux_utility_event_flags_set #else -#define _ux_system_semaphore_create(sem,name,cnt) do{}while(0) -#define _ux_system_semaphore_create_rc(sem,name,cnt) (UX_SUCCESS) -#define _ux_system_semaphore_delete _ux_utility_semaphore_delete -#define _ux_system_thread_create_rc(t,name,entry,entry_param,stack,stack_size,priority,preempt_threshold,time_slice,auto_start) (UX_SUCCESS) +#define _ux_system_semaphore_create(sem,name,cnt) (UX_SUCCESS) +#define _ux_system_semaphore_create_norc(sem,name,cnt) do{}while(0) +#define _ux_system_semaphore_created(sem) (UX_FALSE) +#define _ux_system_semaphore_get(sem,opt) (UX_SUCCESS) +#define _ux_system_semaphore_get_norc(sem,opt) do{}while(0) +#define _ux_system_semaphore_waiting(sem) (UX_FALSE) +#define _ux_system_semaphore_delete(sem) do{}while(0) +#define _ux_system_semaphore_put(sem) do{}while(0) +#define _ux_system_thread_create(t,name,entry,entry_param,stack,stack_size,priority,preempt_threshold,time_slice,auto_start) (UX_SUCCESS) +#define _ux_system_thread_create_norc(t,name,entry,entry_param,stack,stack_size,priority,preempt_threshold,time_slice,auto_start) do{}while(0) +#define _ux_system_thread_created(t) (UX_FALSE) +#define _ux_system_thread_delete(t) do{}while(0) #define _ux_system_mutex_create(mutex,name) do{}while(0) #define _ux_system_mutex_delete(mutex) do{}while(0) #define _ux_system_mutex_off(mutex) do{}while(0) #define _ux_system_mutex_on(mutex) do{}while(0) +#define _ux_system_event_flags_create(g,name) (UX_SUCCESS) +#define _ux_system_event_flags_created(e) (UX_FALSE) +#define _ux_system_event_flags_delete(g) do{}while(0) +#define _ux_system_event_flags_get(g,req,gopt,actual,wopt) (*actual = 0) +#define _ux_system_event_flags_set(g,flags,option) do{(void)flags;}while(0) +#define _ux_system_event_flags_set_rc(g,flags,option) (UX_SUCCESS) #endif #if !defined(UX_DEVICE_STANDALONE) @@ -277,9 +309,9 @@ extern ALIGN_TYPE _ux_utility_time_elapsed(ALIGN_TYPE, ALIGN_TYPE); #define _ux_host_mutex_delete(mutex) do{}while(0) #define _ux_host_mutex_off(mutex) do{}while(0) #define _ux_host_mutex_on(mutex) do{}while(0) -#define _ux_host_event_flags_create(g,name) do{}while(0) -#define _ux_host_event_flags_delete(g) do{}while(0) -#define _ux_host_event_flags_get(g,req,gopt,actual,wopt) do{}while(0) +#define _ux_host_event_flags_create(g,name) (UX_SUCCESS) +#define _ux_host_event_flags_delete(g) (UX_SUCCESS) +#define _ux_host_event_flags_get(g,req,gopt,actual,wopt) (UX_SUCCESS) #define _ux_host_event_flags_set(g,flags,option) do{}while(0) #define _ux_host_timer_create(t,name,func,arg,tick0,tick1,flag) (UX_SUCCESS) #define _ux_host_timer_delete(t) do{}while(0) diff --git a/common/core/src/ux_dcd_sim_slave_initialize_complete.c b/common/core/src/ux_dcd_sim_slave_initialize_complete.c index 02072d07..81a30dfd 100644 --- a/common/core/src/ux_dcd_sim_slave_initialize_complete.c +++ b/common/core/src/ux_dcd_sim_slave_initialize_complete.c @@ -142,7 +142,7 @@ UX_SLAVE_TRANSFER *transfer_request; device -> ux_slave_device_descriptor.bMaxPacketSize0; transfer_request -> ux_slave_transfer_request_transfer_length = device -> ux_slave_device_descriptor.bMaxPacketSize0; - + /* Attach the control endpoint to the transfer request. */ transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint; diff --git a/common/core/src/ux_device_class_dpump_activate.c b/common/core/src/ux_device_class_dpump_activate.c index e1987d93..80626d61 100644 --- a/common/core/src/ux_device_class_dpump_activate.c +++ b/common/core/src/ux_device_class_dpump_activate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,33 +69,37 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_activate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_CLASS_DPUMP *dpump; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_ENDPOINT *endpoint; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Store the class instance in the container. */ - dpump = (UX_SLAVE_CLASS_DPUMP *) class -> ux_slave_class_instance; + dpump = (UX_SLAVE_CLASS_DPUMP *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)dpump; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)dpump; /* Now the opposite, store the interface in the class instance. */ - dpump -> ux_slave_class_dpump_interface = interface; + dpump -> ux_slave_class_dpump_interface = interface_ptr; /* Locate the endpoints. Interrupt for Control and Bulk in/out for Data. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all endpoints. */ while (endpoint != UX_NULL) diff --git a/common/core/src/ux_device_class_dpump_change.c b/common/core/src/ux_device_class_dpump_change.c index eb3a4345..acad9cff 100644 --- a/common/core/src/ux_device_class_dpump_change.c +++ b/common/core/src/ux_device_class_dpump_change.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_change PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,35 +72,39 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_change(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_DPUMP *dpump; -UX_SLAVE_CLASS *class; -UX_SLAVE_ENDPOINT *endpoint; +UX_SLAVE_ENDPOINT *endpoint; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - dpump = (UX_SLAVE_CLASS_DPUMP *) class -> ux_slave_class_instance; + dpump = (UX_SLAVE_CLASS_DPUMP *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Locate the endpoints. Control and Bulk in/out for data. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Keep the alternate setting in the dpump structure. */ - dpump -> ux_slave_class_dpump_alternate_setting = interface -> ux_slave_interface_descriptor.bAlternateSetting; + dpump -> ux_slave_class_dpump_alternate_setting = interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting; /* If the interface to mount has a non zero alternate setting, the class is really active with the endpoints active. If the interface reverts to alternate setting 0, it needs to have the pending transactions terminated. */ - if (interface -> ux_slave_interface_descriptor.bAlternateSetting != 0) + if (interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting != 0) { /* Parse all endpoints. */ @@ -145,7 +149,7 @@ UX_SLAVE_ENDPOINT *endpoint; ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */ /* Keep the alternate setting in the dpump structure. */ - dpump -> ux_slave_class_dpump_alternate_setting = interface -> ux_slave_interface_descriptor.bAlternateSetting; + dpump -> ux_slave_class_dpump_alternate_setting = interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting; #if defined(UX_DEVICE_STANDALONE) diff --git a/common/core/src/ux_device_class_dpump_deactivate.c b/common/core/src/ux_device_class_dpump_deactivate.c index 188efe95..01310e83 100644 --- a/common/core/src/ux_device_class_dpump_deactivate.c +++ b/common/core/src/ux_device_class_dpump_deactivate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_deactivate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,28 +67,32 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_deactivate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_DPUMP *dpump; UX_SLAVE_ENDPOINT *endpoint_in; UX_SLAVE_ENDPOINT *endpoint_out; -UX_SLAVE_CLASS *class; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Store the class instance in the container. */ - dpump = (UX_SLAVE_CLASS_DPUMP *) class -> ux_slave_class_instance; + dpump = (UX_SLAVE_CLASS_DPUMP *) class_ptr -> ux_slave_class_instance; /* We need the interface to the class. */ - interface = dpump -> ux_slave_class_dpump_interface; + interface_ptr = dpump -> ux_slave_class_dpump_interface; /* Locate the endpoints. */ - endpoint_in = interface -> ux_slave_interface_first_endpoint; + endpoint_in = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) diff --git a/common/core/src/ux_device_class_dpump_initialize.c b/common/core/src/ux_device_class_dpump_initialize.c index 50f88e4b..adccf6df 100644 --- a/common/core/src/ux_device_class_dpump_initialize.c +++ b/common/core/src/ux_device_class_dpump_initialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_initialize PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,17 +66,21 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_dpump_initialize(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_DPUMP *dpump; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_DPUMP_PARAMETER *dpump_parameter; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Create an instance of the device dpump class. */ dpump = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_DPUMP)); @@ -86,7 +90,7 @@ UX_SLAVE_CLASS_DPUMP_PARAMETER *dpump_parameter; return(UX_MEMORY_INSUFFICIENT); /* Save the address of the DPUMP instance inside the DPUMP container. */ - class -> ux_slave_class_instance = (VOID *) dpump; + class_ptr -> ux_slave_class_instance = (VOID *) dpump; /* Get the pointer to the application parameters for the cdc class. */ dpump_parameter = command -> ux_slave_class_command_parameter; diff --git a/common/core/src/ux_device_class_dpump_thread.c b/common/core/src/ux_device_class_dpump_thread.c index a73496ef..df4d138e 100644 --- a/common/core/src/ux_device_class_dpump_thread.c +++ b/common/core/src/ux_device_class_dpump_thread.c @@ -37,7 +37,7 @@ VOID _ux_device_class_dpump_thread(ULONG dpump_class); /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dpump_thread PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,16 +79,20 @@ VOID _ux_device_class_dpump_thread(ULONG dpump_class); /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_device_class_dpump_thread(ULONG dpump_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_CLASS_DPUMP *dpump; UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; UX_SLAVE_ENDPOINT *endpoint_in; UX_SLAVE_ENDPOINT *endpoint_out; UINT status; @@ -99,19 +103,19 @@ ULONG length; { /* Cast properly the dpump instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, dpump_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, dpump_class) /* Get the dpump instance from this class container. */ - dpump = (UX_SLAVE_CLASS_DPUMP *) class -> ux_slave_class_instance; + dpump = (UX_SLAVE_CLASS_DPUMP *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; /* This is the first time we are activated. We need the interface to the class. */ - interface = dpump -> ux_slave_class_dpump_interface; + interface_ptr = dpump -> ux_slave_class_dpump_interface; /* Locate the endpoints. */ - endpoint_in = interface -> ux_slave_interface_first_endpoint; + endpoint_in = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) @@ -168,7 +172,7 @@ ULONG length; /* We need to suspend ourselves. We will be resumed by the device enumeration module. */ - _ux_device_thread_suspend(&class -> ux_slave_class_thread); + _ux_device_thread_suspend(&class_ptr -> ux_slave_class_thread); } } diff --git a/common/core/src/ux_device_stack_alternate_setting_get.c b/common/core/src/ux_device_stack_alternate_setting_get.c index 9e618089..bdbc0069 100644 --- a/common/core/src/ux_device_stack_alternate_setting_get.c +++ b/common/core/src/ux_device_stack_alternate_setting_get.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_alternate_setting_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,13 +70,17 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_alternate_setting_get(ULONG interface_value) { UX_SLAVE_TRANSFER *transfer_request; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_DEVICE *device; UX_SLAVE_ENDPOINT *endpoint; UINT status; @@ -93,18 +97,18 @@ UINT status; { /* Obtain the pointer to the first interface attached. */ - interface = device -> ux_slave_device_first_interface; + interface_ptr = device -> ux_slave_device_first_interface; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Start parsing each interface. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) #else - if (interface != UX_NULL) + if (interface_ptr != UX_NULL) #endif { /* Check if this is the interface we have an inquiry for. */ - if (interface -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value) + if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value) { /* Get the control endpoint of the device. */ @@ -115,7 +119,7 @@ UINT status; /* Set the value of the alternate setting in the buffer. */ *transfer_request -> ux_slave_transfer_request_data_pointer = - (UCHAR) interface -> ux_slave_interface_descriptor.bAlternateSetting; + (UCHAR) interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting; /* Setup the length appropriately. */ transfer_request -> ux_slave_transfer_request_requested_length = 1; @@ -132,7 +136,7 @@ UINT status; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Get the next interface. */ - interface = interface -> ux_slave_interface_next_interface; + interface_ptr = interface_ptr -> ux_slave_interface_next_interface; #endif } } diff --git a/common/core/src/ux_device_stack_alternate_setting_set.c b/common/core/src/ux_device_stack_alternate_setting_set.c index e4ad4439..95efe9ee 100644 --- a/common/core/src/ux_device_stack_alternate_setting_set.c +++ b/common/core/src/ux_device_stack_alternate_setting_set.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_alternate_setting_set PORTABLE C */ -/* 6.1.9 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,13 +81,17 @@ /* 10-15-2021 Chaoqiong Xiao Modified comment(s), */ /* calculated payload size, */ /* resulting in version 6.1.9 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_alternate_setting_set(ULONG interface_value, ULONG alternate_setting_value) { UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; #if !defined(UX_DEVICE_ALTERNATE_SETTING_SUPPORT_DISABLE) UX_SLAVE_DCD *dcd; UX_SLAVE_TRANSFER *transfer_request; @@ -102,7 +106,7 @@ UX_SLAVE_ENDPOINT *next_endpoint; UX_SLAVE_ENDPOINT *endpoint_link; ULONG endpoints_pool_number; UX_SLAVE_CLASS_COMMAND class_command; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UINT status; ULONG max_transfer_length, n_trans; #endif @@ -118,40 +122,40 @@ ULONG max_transfer_length, n_trans; return(UX_FUNCTION_NOT_SUPPORTED); /* Find the current interface. */ - interface = device -> ux_slave_device_first_interface; + interface_ptr = device -> ux_slave_device_first_interface; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Scan all interfaces if any. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { - if (interface -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value) + if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value) break; else - interface = interface -> ux_slave_interface_next_interface; + interface_ptr = interface_ptr -> ux_slave_interface_next_interface; } #else - if (interface -> ux_slave_interface_descriptor.bInterfaceNumber != interface_value) - interface = UX_NULL; + if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceNumber != interface_value) + interface_ptr = UX_NULL; #endif /* We must have found the interface pointer for the interface value requested by the caller. */ - if (interface == UX_NULL) + if (interface_ptr == UX_NULL) { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_INTERFACE_HANDLE_UNKNOWN); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface, 0, 0, UX_TRACE_ERRORS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface_ptr, 0, 0, UX_TRACE_ERRORS, 0, 0) return(UX_INTERFACE_HANDLE_UNKNOWN); } /* If the host is requesting a change of alternate setting to the current one, we do not need to do any work. */ - if (interface -> ux_slave_interface_descriptor.bAlternateSetting == alternate_setting_value) + if (interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting == alternate_setting_value) return(UX_SUCCESS); #if defined(UX_DEVICE_ALTERNATE_SETTING_SUPPORT_DISABLE) @@ -160,7 +164,7 @@ ULONG max_transfer_length, n_trans; _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_FUNCTION_NOT_SUPPORTED); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, interface, 0, 0, UX_TRACE_ERRORS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, interface_ptr, 0, 0, UX_TRACE_ERRORS, 0, 0) return(UX_FUNCTION_NOT_SUPPORTED); #else @@ -230,7 +234,7 @@ ULONG max_transfer_length, n_trans; /* We have found the right interface and alternate setting. Before we mount all the endpoints for this interface, we need to unmount the endpoints associated with the previous alternate setting. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; while (endpoint != UX_NULL) { @@ -257,7 +261,7 @@ ULONG max_transfer_length, n_trans; } /* Now clear the interface endpoint entry. */ - interface -> ux_slave_interface_first_endpoint = UX_NULL; + interface_ptr -> ux_slave_interface_first_endpoint = UX_NULL; /* Point beyond the interface descriptor. */ device_framework_length -= (ULONG) *device_framework; @@ -344,7 +348,7 @@ ULONG max_transfer_length, n_trans; transfer_request -> ux_slave_transfer_request_timeout = UX_WAIT_FOREVER; /* Attach the interface to the endpoint. */ - endpoint -> ux_slave_endpoint_interface = interface; + endpoint -> ux_slave_endpoint_interface = interface_ptr; /* Attach the device to the endpoint. */ endpoint -> ux_slave_endpoint_device = device; @@ -362,15 +366,15 @@ ULONG max_transfer_length, n_trans; } /* Attach this endpoint to the end of the endpoint chain. */ - if (interface -> ux_slave_interface_first_endpoint == UX_NULL) + if (interface_ptr -> ux_slave_interface_first_endpoint == UX_NULL) { - interface -> ux_slave_interface_first_endpoint = endpoint; + interface_ptr -> ux_slave_interface_first_endpoint = endpoint; } else { /* Multiple endpoints exist, so find the end of the chain. */ - endpoint_link = interface -> ux_slave_interface_first_endpoint; + endpoint_link = interface_ptr -> ux_slave_interface_first_endpoint; while (endpoint_link -> ux_slave_endpoint_next_endpoint != UX_NULL) endpoint_link = endpoint_link -> ux_slave_endpoint_next_endpoint; endpoint_link -> ux_slave_endpoint_next_endpoint = endpoint; @@ -403,13 +407,13 @@ ULONG max_transfer_length, n_trans; } /* The interface descriptor in the current class must be changed to the new alternate setting. */ - _ux_utility_memory_copy(&interface -> ux_slave_interface_descriptor, &interface_descriptor, sizeof(UX_INTERFACE_DESCRIPTOR)); /* Use case of memcpy is verified. */ + _ux_utility_memory_copy(&interface_ptr -> ux_slave_interface_descriptor, &interface_descriptor, sizeof(UX_INTERFACE_DESCRIPTOR)); /* Use case of memcpy is verified. */ /* Get the class for the interface. */ - class = _ux_system_slave -> ux_system_slave_interface_class_array[interface -> ux_slave_interface_descriptor.bInterfaceNumber]; + class_ptr = _ux_system_slave -> ux_system_slave_interface_class_array[interface_ptr -> ux_slave_interface_descriptor.bInterfaceNumber]; /* Check if class driver is available. */ - if (class == UX_NULL || class -> ux_slave_class_status == UX_UNUSED) + if (class_ptr == UX_NULL || class_ptr -> ux_slave_class_status == UX_UNUSED) { return (UX_NO_CLASS_MATCH); @@ -418,16 +422,16 @@ ULONG max_transfer_length, n_trans; /* The interface attached to this configuration must be changed at the class level. */ class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_CHANGE; - class_command.ux_slave_class_command_interface = (VOID *) interface; + class_command.ux_slave_class_command_interface = (VOID *) interface_ptr; /* And store it. */ - class_command.ux_slave_class_command_class_ptr = class; + class_command.ux_slave_class_command_class_ptr = class_ptr; /* We can now memorize the interface pointer associated with this class. */ - class -> ux_slave_class_interface = interface; + class_ptr -> ux_slave_class_interface = interface_ptr; /* We have found a potential candidate. Call this registered class entry function to change the alternate setting. */ - status = class -> ux_slave_class_entry_function(&class_command); + status = class_ptr -> ux_slave_class_entry_function(&class_command); /* We are done here. */ return(status); diff --git a/common/core/src/ux_device_stack_clear_feature.c b/common/core/src/ux_device_stack_clear_feature.c index 5d078b0c..3443f05b 100644 --- a/common/core/src/ux_device_stack_clear_feature.c +++ b/common/core/src/ux_device_stack_clear_feature.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_clear_feature PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,10 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_clear_feature(ULONG request_type, ULONG request_value, ULONG request_index) @@ -78,7 +82,7 @@ UINT _ux_device_stack_clear_feature(ULONG request_type, ULONG request_value, UL UX_SLAVE_DCD *dcd; UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_ENDPOINT *endpoint_target; @@ -127,15 +131,15 @@ UX_SLAVE_ENDPOINT *endpoint_target; /* The only clear feature for endpoint is ENDPOINT_STALL. This clears the endpoint of the stall situation and resets its data toggle. We need to find the endpoint through the interface(s). */ - interface = device -> ux_slave_device_first_interface; + interface_ptr = device -> ux_slave_device_first_interface; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { #endif /* Get the first endpoint for this interface. */ - endpoint_target = interface -> ux_slave_interface_first_endpoint; + endpoint_target = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all the endpoints. */ while (endpoint_target != UX_NULL) @@ -161,7 +165,7 @@ UX_SLAVE_ENDPOINT *endpoint_target; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Next interface. */ - interface = interface -> ux_slave_interface_next_interface; + interface_ptr = interface_ptr -> ux_slave_interface_next_interface; } #endif diff --git a/common/core/src/ux_device_stack_configuration_set.c b/common/core/src/ux_device_stack_configuration_set.c index 7723c75c..545a73e9 100644 --- a/common/core/src/ux_device_stack_configuration_set.c +++ b/common/core/src/ux_device_stack_configuration_set.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_configuration_set PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -76,6 +76,10 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_configuration_set(ULONG configuration_value) @@ -88,7 +92,7 @@ ULONG descriptor_length; UCHAR descriptor_type; UX_CONFIGURATION_DESCRIPTOR configuration_descriptor = { 0 }; UX_INTERFACE_DESCRIPTOR interface_descriptor; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 UX_SLAVE_INTERFACE *next_interface; #endif @@ -165,19 +169,19 @@ ULONG class_index; { /* Get the pointer to the first interface. */ - interface = device -> ux_slave_device_first_interface; + interface_ptr = device -> ux_slave_device_first_interface; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Deactivate all the interfaces if any. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { #endif /* Build all the fields of the Class Command. */ class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_DEACTIVATE; - class_command.ux_slave_class_command_interface = (VOID *) interface; + class_command.ux_slave_class_command_interface = (VOID *) interface_ptr; /* Get the pointer to the class container of this interface. */ - class_inst = interface -> ux_slave_interface_class; + class_inst = interface_ptr -> ux_slave_interface_class; /* Store the class container. */ class_command.ux_slave_class_command_class_ptr = class_inst; @@ -190,15 +194,15 @@ ULONG class_index; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Get the next interface. */ - next_interface = interface -> ux_slave_interface_next_interface; + next_interface = interface_ptr -> ux_slave_interface_next_interface; #endif /* Remove the interface and all endpoints associated with it. */ - _ux_device_stack_interface_delete(interface); + _ux_device_stack_interface_delete(interface_ptr); #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Now we refresh the interface pointer. */ - interface = next_interface; + interface_ptr = next_interface; } #endif diff --git a/common/core/src/ux_device_stack_control_request_process.c b/common/core/src/ux_device_stack_control_request_process.c index 8b9e9a28..82729c2b 100644 --- a/common/core/src/ux_device_stack_control_request_process.c +++ b/common/core/src/ux_device_stack_control_request_process.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_control_request_process PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -87,6 +87,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added printer support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_control_request_process(UX_SLAVE_TRANSFER *transfer_request) @@ -94,7 +98,7 @@ UINT _ux_device_stack_control_request_process(UX_SLAVE_TRANSFER *transfer_reque UX_SLAVE_DCD *dcd; UX_SLAVE_DEVICE *device; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_COMMAND class_command; ULONG request_type; ULONG request; @@ -196,10 +200,10 @@ ULONG application_data_length; { /* Get the class for the interface. */ - class = _ux_system_slave -> ux_system_slave_interface_class_array[class_index]; + class_ptr = _ux_system_slave -> ux_system_slave_interface_class_array[class_index]; /* If class is not ready, try next. */ - if (class == UX_NULL) + if (class_ptr == UX_NULL) continue; /* Is the request target to an interface? */ @@ -213,17 +217,17 @@ ULONG application_data_length; wIndex is interface index (for recommended index sequence the interface number is same as interface index inside configuration). */ if (((request_index & 0xFF) != class_index) || - ((class -> ux_slave_class_interface -> ux_slave_interface_descriptor.bInterfaceClass == 0x07) && + ((class_ptr -> ux_slave_class_interface -> ux_slave_interface_descriptor.bInterfaceClass == 0x07) && (request == 0x00) && *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_INDEX + 1) != class_index)) continue; } /* Memorize the class in the command. */ - class_command.ux_slave_class_command_class_ptr = class; + class_command.ux_slave_class_command_class_ptr = class_ptr; /* We have found a potential candidate. Call this registered class entry function. */ - status = class -> ux_slave_class_entry_function(&class_command); + status = class_ptr -> ux_slave_class_entry_function(&class_command); /* The status simply tells us if the registered class handled the command - if there was an issue processing the command, it would've diff --git a/common/core/src/ux_device_stack_disconnect.c b/common/core/src/ux_device_stack_disconnect.c index eac6fc05..b7c7b46c 100644 --- a/common/core/src/ux_device_stack_disconnect.c +++ b/common/core/src/ux_device_stack_disconnect.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_disconnect PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,10 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_disconnect(VOID) @@ -80,11 +84,11 @@ UINT _ux_device_stack_disconnect(VOID) UX_SLAVE_DCD *dcd; UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 UX_SLAVE_INTERFACE *next_interface; #endif -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_COMMAND class_command; UINT status = UX_ERROR; @@ -105,41 +109,41 @@ UINT status = UX_ERROR; if (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED) { /* Get the pointer to the first interface. */ - interface = device -> ux_slave_device_first_interface; + interface_ptr = device -> ux_slave_device_first_interface; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Parse all the interfaces if any. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { #endif /* Build all the fields of the Class Command. */ class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_DEACTIVATE; - class_command.ux_slave_class_command_interface = (VOID *) interface; + class_command.ux_slave_class_command_interface = (VOID *) interface_ptr; /* Get the pointer to the class container of this interface. */ - class = interface -> ux_slave_interface_class; + class_ptr = interface_ptr -> ux_slave_interface_class; /* Store the class container. */ - class_command.ux_slave_class_command_class_ptr = class; + class_command.ux_slave_class_command_class_ptr = class_ptr; /* If there is a class container for this instance, deactivate it. */ - if (class != UX_NULL) + if (class_ptr != UX_NULL) /* Call the class with the DEACTIVATE signal. */ - class -> ux_slave_class_entry_function(&class_command); + class_ptr -> ux_slave_class_entry_function(&class_command); #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Get the next interface. */ - next_interface = interface -> ux_slave_interface_next_interface; + next_interface = interface_ptr -> ux_slave_interface_next_interface; #endif /* Remove the interface and all endpoints associated with it. */ - _ux_device_stack_interface_delete(interface); + _ux_device_stack_interface_delete(interface_ptr); #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Now we refresh the interface pointer. */ - interface = next_interface; + interface_ptr = next_interface; } #endif diff --git a/common/core/src/ux_device_stack_interface_delete.c b/common/core/src/ux_device_stack_interface_delete.c index 3b61df49..07ade0ef 100644 --- a/common/core/src/ux_device_stack_interface_delete.c +++ b/common/core/src/ux_device_stack_interface_delete.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_interface_delete PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,9 +69,13 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ -UINT _ux_device_stack_interface_delete(UX_SLAVE_INTERFACE *interface) +UINT _ux_device_stack_interface_delete(UX_SLAVE_INTERFACE *interface_ptr) { UX_SLAVE_DCD *dcd; @@ -80,16 +84,16 @@ UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_ENDPOINT *next_endpoint; /* If trace is enabled, register this object. */ - UX_TRACE_OBJECT_UNREGISTER(interface); + UX_TRACE_OBJECT_UNREGISTER(interface_ptr); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_INTERFACE_DELETE, interface, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_INTERFACE_DELETE, interface_ptr, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0) /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; /* Find the first endpoints associated with this interface. */ - next_endpoint = interface -> ux_slave_interface_first_endpoint; + next_endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all the endpoints. */ while (next_endpoint != UX_NULL) @@ -119,14 +123,14 @@ UX_SLAVE_ENDPOINT *next_endpoint; /* It's always from first one (to delete). */ /* Rebuild the first link. */ - device -> ux_slave_device_first_interface = interface -> ux_slave_interface_next_interface; + device -> ux_slave_device_first_interface = interface_ptr -> ux_slave_interface_next_interface; /* The interface is removed from the link, its memory must be cleaned and returned to the pool. */ - interface -> ux_slave_interface_class = UX_NULL; - interface -> ux_slave_interface_class_instance = UX_NULL; - interface -> ux_slave_interface_next_interface = UX_NULL; - interface -> ux_slave_interface_first_endpoint = UX_NULL; - interface -> ux_slave_interface_status = UX_UNUSED; + interface_ptr -> ux_slave_interface_class = UX_NULL; + interface_ptr -> ux_slave_interface_class_instance = UX_NULL; + interface_ptr -> ux_slave_interface_next_interface = UX_NULL; + interface_ptr -> ux_slave_interface_first_endpoint = UX_NULL; + interface_ptr -> ux_slave_interface_status = UX_UNUSED; /* Return successful completion. */ return(UX_SUCCESS); diff --git a/common/core/src/ux_device_stack_interface_get.c b/common/core/src/ux_device_stack_interface_get.c index 112ac8ed..f1e366a5 100644 --- a/common/core/src/ux_device_stack_interface_get.c +++ b/common/core/src/ux_device_stack_interface_get.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_interface_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,10 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_interface_get(UINT interface_value) @@ -78,7 +82,7 @@ UINT _ux_device_stack_interface_get(UINT interface_value) UX_SLAVE_DCD *dcd; UX_SLAVE_TRANSFER *transfer_request; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_DEVICE *device; UX_SLAVE_ENDPOINT *endpoint; UINT status; @@ -101,16 +105,16 @@ UINT status; { /* Get the pointer to the first interface. */ - interface = device -> ux_slave_device_first_interface; + interface_ptr = device -> ux_slave_device_first_interface; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Parse the interfaces if any. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { #endif /* Check if this is the interface we have an inquiry for. */ - if (interface -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value) + if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value) { /* Get the pointer to the transfer request associated with the endpoint. */ @@ -118,7 +122,7 @@ UINT status; /* Set the value of the alternate setting in the buffer. */ *transfer_request -> ux_slave_transfer_request_data_pointer = - (UCHAR) interface -> ux_slave_interface_descriptor.bAlternateSetting; + (UCHAR) interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting; /* Setup the length appropriately. */ transfer_request -> ux_slave_transfer_request_requested_length = 1; @@ -135,7 +139,7 @@ UINT status; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Get the next interface. */ - interface = interface -> ux_slave_interface_next_interface; + interface_ptr = interface_ptr -> ux_slave_interface_next_interface; } #endif diff --git a/common/core/src/ux_device_stack_interface_set.c b/common/core/src/ux_device_stack_interface_set.c index 45b2e295..b93e0a21 100644 --- a/common/core/src/ux_device_stack_interface_set.c +++ b/common/core/src/ux_device_stack_interface_set.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_interface_set PORTABLE C */ -/* 6.1.9 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,6 +79,10 @@ /* 10-15-2021 Chaoqiong Xiao Modified comment(s), */ /* calculated payload size, */ /* resulting in version 6.1.9 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_interface_set(UCHAR * device_framework, ULONG device_framework_length, @@ -88,7 +92,7 @@ UINT _ux_device_stack_interface_set(UCHAR * device_framework, ULONG device_fram UX_SLAVE_DCD *dcd; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 UX_SLAVE_INTERFACE *interface_link; ULONG interfaces_pool_number; @@ -114,18 +118,18 @@ ULONG max_transfer_length, n_trans; /* Find a free interface in the pool and hook it to the existing interface. */ - interface = device -> ux_slave_device_interfaces_pool; + interface_ptr = device -> ux_slave_device_interfaces_pool; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 interfaces_pool_number = device -> ux_slave_device_interfaces_pool_number; while (interfaces_pool_number != 0) { /* Check if this interface is free. */ - if (interface -> ux_slave_interface_status == UX_UNUSED) + if (interface_ptr -> ux_slave_interface_status == UX_UNUSED) break; /* Try the next interface. */ - interface++; + interface_ptr++; /* Decrement the number of interfaces left to scan in the pool. */ interfaces_pool_number--; @@ -137,22 +141,22 @@ ULONG max_transfer_length, n_trans; #else /* Check if this interface is free. */ - if (interface -> ux_slave_interface_status != UX_UNUSED) + if (interface_ptr -> ux_slave_interface_status != UX_UNUSED) return(UX_MEMORY_INSUFFICIENT); #endif /* Mark this interface as used now. */ - interface -> ux_slave_interface_status = UX_USED; + interface_ptr -> ux_slave_interface_status = UX_USED; /* If trace is enabled, register this object. */ - UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, interface, 0, 0, 0) + UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, interface_ptr, 0, 0, 0) /* Parse the descriptor in something more readable. */ _ux_utility_descriptor_parse(device_framework, _ux_system_interface_descriptor_structure, UX_INTERFACE_DESCRIPTOR_ENTRIES, - (UCHAR *) &interface -> ux_slave_interface_descriptor); + (UCHAR *) &interface_ptr -> ux_slave_interface_descriptor); #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 @@ -160,7 +164,7 @@ ULONG max_transfer_length, n_trans; if (device -> ux_slave_device_first_interface == UX_NULL) { - device -> ux_slave_device_first_interface = interface; + device -> ux_slave_device_first_interface = interface_ptr; } else { @@ -168,12 +172,12 @@ ULONG max_transfer_length, n_trans; interface_link = device -> ux_slave_device_first_interface; while (interface_link -> ux_slave_interface_next_interface != UX_NULL) interface_link = interface_link -> ux_slave_interface_next_interface; - interface_link -> ux_slave_interface_next_interface = interface; + interface_link -> ux_slave_interface_next_interface = interface_ptr; } #else /* It must be very first one. */ - device -> ux_slave_device_first_interface = interface; + device -> ux_slave_device_first_interface = interface_ptr; #endif /* Point beyond the interface descriptor. */ @@ -261,7 +265,7 @@ ULONG max_transfer_length, n_trans; transfer_request -> ux_slave_transfer_request_timeout = UX_WAIT_FOREVER; /* Attach the interface to the endpoint. */ - endpoint -> ux_slave_endpoint_interface = interface; + endpoint -> ux_slave_endpoint_interface = interface_ptr; /* Attach the device to the endpoint. */ endpoint -> ux_slave_endpoint_device = device; @@ -279,15 +283,15 @@ ULONG max_transfer_length, n_trans; } /* Attach this endpoint to the end of the endpoint chain. */ - if (interface -> ux_slave_interface_first_endpoint == UX_NULL) + if (interface_ptr -> ux_slave_interface_first_endpoint == UX_NULL) { - interface -> ux_slave_interface_first_endpoint = endpoint; + interface_ptr -> ux_slave_interface_first_endpoint = endpoint; } else { /* Multiple endpoints exist, so find the end of the chain. */ - endpoint_link = interface -> ux_slave_interface_first_endpoint; + endpoint_link = interface_ptr -> ux_slave_interface_first_endpoint; while (endpoint_link -> ux_slave_endpoint_next_endpoint != UX_NULL) endpoint_link = endpoint_link -> ux_slave_endpoint_next_endpoint; endpoint_link -> ux_slave_endpoint_next_endpoint = endpoint; @@ -300,7 +304,7 @@ ULONG max_transfer_length, n_trans; /* If the descriptor is a configuration or interface, we have parsed and mounted all endpoints. The interface attached to this configuration must be started at the class level. */ - status = _ux_device_stack_interface_start(interface); + status = _ux_device_stack_interface_start(interface_ptr); /* Return the status to the caller. */ return(status); @@ -318,7 +322,7 @@ ULONG max_transfer_length, n_trans; /* The interface attached to this configuration must be started at the class level. */ - status = _ux_device_stack_interface_start(interface); + status = _ux_device_stack_interface_start(interface_ptr); /* Return the status to the caller. */ return(status); diff --git a/common/core/src/ux_device_stack_interface_start.c b/common/core/src/ux_device_stack_interface_start.c index 1b8edc71..e5dc8d74 100644 --- a/common/core/src/ux_device_stack_interface_start.c +++ b/common/core/src/ux_device_stack_interface_start.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_interface_start PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,22 +68,26 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ -UINT _ux_device_stack_interface_start(UX_SLAVE_INTERFACE *interface) +UINT _ux_device_stack_interface_start(UX_SLAVE_INTERFACE *interface_ptr) { UX_SLAVE_DEVICE *device; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UINT status; UX_SLAVE_CLASS_COMMAND class_command; /* Get the class for the interface. */ - class = _ux_system_slave -> ux_system_slave_interface_class_array[interface -> ux_slave_interface_descriptor.bInterfaceNumber]; + class_ptr = _ux_system_slave -> ux_system_slave_interface_class_array[interface_ptr -> ux_slave_interface_descriptor.bInterfaceNumber]; /* Check if class driver is available. */ - if (class == UX_NULL) + if (class_ptr == UX_NULL) /* There is no class driver supported. */ return (UX_NO_CLASS_MATCH); @@ -93,35 +97,35 @@ UX_SLAVE_CLASS_COMMAND class_command; /* Build all the fields of the Class Command. */ class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_QUERY; - class_command.ux_slave_class_command_interface = (VOID *)interface; - class_command.ux_slave_class_command_class = interface -> ux_slave_interface_descriptor.bInterfaceClass; - class_command.ux_slave_class_command_subclass = interface -> ux_slave_interface_descriptor.bInterfaceSubClass; - class_command.ux_slave_class_command_protocol = interface -> ux_slave_interface_descriptor.bInterfaceProtocol; + class_command.ux_slave_class_command_interface = (VOID *)interface_ptr; + class_command.ux_slave_class_command_class = interface_ptr -> ux_slave_interface_descriptor.bInterfaceClass; + class_command.ux_slave_class_command_subclass = interface_ptr -> ux_slave_interface_descriptor.bInterfaceSubClass; + class_command.ux_slave_class_command_protocol = interface_ptr -> ux_slave_interface_descriptor.bInterfaceProtocol; class_command.ux_slave_class_command_vid = device -> ux_slave_device_descriptor.idVendor; class_command.ux_slave_class_command_pid = device -> ux_slave_device_descriptor.idProduct; /* We can now memorize the interface pointer associated with this class. */ - class -> ux_slave_class_interface = interface; + class_ptr -> ux_slave_class_interface = interface_ptr; /* We have found a potential candidate. Call this registered class entry function. */ - status = class -> ux_slave_class_entry_function(&class_command); + status = class_ptr -> ux_slave_class_entry_function(&class_command); /* The status tells us if the registered class wants to own this class. */ if (status == UX_SUCCESS) { /* Store the class container. */ - class_command.ux_slave_class_command_class_ptr = class; + class_command.ux_slave_class_command_class_ptr = class_ptr; /* Store the command. */ class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_ACTIVATE; /* Activate the class. */ - status = class -> ux_slave_class_entry_function(&class_command); + status = class_ptr -> ux_slave_class_entry_function(&class_command); /* If the class was successfully activated, set the class for the interface. */ if(status == UX_SUCCESS) - interface -> ux_slave_interface_class = class; + interface_ptr -> ux_slave_interface_class = class_ptr; return(status); } diff --git a/common/core/src/ux_device_stack_set_feature.c b/common/core/src/ux_device_stack_set_feature.c index 53f1ba95..5b3b5b98 100644 --- a/common/core/src/ux_device_stack_set_feature.c +++ b/common/core/src/ux_device_stack_set_feature.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_set_feature PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,6 +72,10 @@ /* definitions, stalled on not */ /* supported device requests, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_stack_set_feature(ULONG request_type, ULONG request_value, ULONG request_index) @@ -79,7 +83,7 @@ UINT _ux_device_stack_set_feature(ULONG request_type, ULONG request_value, ULON UX_SLAVE_DCD *dcd; UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_ENDPOINT *endpoint_target; @@ -155,14 +159,14 @@ UX_SLAVE_ENDPOINT *endpoint_target; /* The only set feature for endpoint is ENDPOINT_STALL. This forces the endpoint to the stall situation. We need to find the endpoint through the interface(s). */ - interface = device -> ux_slave_device_first_interface; + interface_ptr = device -> ux_slave_device_first_interface; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { #endif /* Get the first endpoint for this interface. */ - endpoint_target = interface -> ux_slave_interface_first_endpoint; + endpoint_target = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all the endpoints. */ while (endpoint_target != UX_NULL) @@ -185,7 +189,7 @@ UX_SLAVE_ENDPOINT *endpoint_target; #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1 /* Next interface. */ - interface = interface -> ux_slave_interface_next_interface; + interface_ptr = interface_ptr -> ux_slave_interface_next_interface; } #endif diff --git a/common/core/src/ux_hcd_sim_host_request_isochronous_transfer.c b/common/core/src/ux_hcd_sim_host_request_isochronous_transfer.c index 86fd6dc9..7b80a2c2 100644 --- a/common/core/src/ux_hcd_sim_host_request_isochronous_transfer.c +++ b/common/core/src/ux_hcd_sim_host_request_isochronous_transfer.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_sim_host_request_isochronous_transfer PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,6 +74,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed partial transfer, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_sim_host_request_isochronous_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request) @@ -170,15 +173,15 @@ ULONG n_trans, packet_size; data_td -> ux_sim_host_iso_td_buffer = data_pointer; /* Update the length of the transfer for this TD. */ - data_td -> ux_sim_host_iso_td_length = isoch_packet_payload_length; + data_td -> ux_sim_host_iso_td_length = UX_MIN(transfer_request_payload_length, isoch_packet_payload_length); /* Attach the endpoint and transfer request to the TD. */ data_td -> ux_sim_host_iso_td_transfer_request = transfer_request; data_td -> ux_sim_host_iso_td_ed = ed; /* Adjust the data payload length and the data payload pointer. */ - transfer_request_payload_length -= isoch_packet_payload_length; - data_pointer += isoch_packet_payload_length; + transfer_request_payload_length -= data_td -> ux_sim_host_iso_td_length; + data_pointer += data_td -> ux_sim_host_iso_td_length; /* Prepare the next frame for the next TD in advance. */ current_frame_number++; diff --git a/common/core/src/ux_hcd_sim_host_transaction_schedule.c b/common/core/src/ux_hcd_sim_host_transaction_schedule.c index 4fb6f5aa..9dc534ed 100644 --- a/common/core/src/ux_hcd_sim_host_transaction_schedule.c +++ b/common/core/src/ux_hcd_sim_host_transaction_schedule.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_sim_host_transaction_schedule PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -91,6 +91,11 @@ /* before semaphore wakeup to */ /* avoid a race condition, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* refined device ZLP flow, */ +/* adjusted control request */ +/* data length handling, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_sim_host_transaction_schedule(UX_HCD_SIM_HOST *hcd_sim_host, UX_HCD_SIM_HOST_ED *ed) @@ -174,8 +179,11 @@ UX_SLAVE_DCD *dcd; /* For control transfer, stall is for protocol error and it's cleared any time when SETUP is received */ slave_ed -> ux_sim_slave_ed_status &= ~(ULONG)UX_DCD_SIM_SLAVE_ED_STATUS_STALLED; - /* Set the length to the setup transaction buffer. */ - slave_transfer_request -> ux_slave_transfer_request_actual_length = td -> ux_sim_host_td_length; + /* Validate the length to the setup transaction buffer. */ + UX_ASSERT(td -> ux_sim_host_td_length == 8); + + /* Reset actual data length (not including SETUP received) so far. */ + slave_transfer_request -> ux_slave_transfer_request_actual_length = 0; /* Move the buffer from the host TD to the device TD. */ _ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_setup, @@ -216,9 +224,6 @@ UX_SLAVE_DCD *dcd; slave_transfer_request -> ux_slave_transfer_request_requested_length = UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH; } - /* Reset what we have received so far. */ - slave_transfer_request -> ux_slave_transfer_request_actual_length = 0; - /* And reprogram the current buffer address to the beginning of the buffer. */ slave_transfer_request -> ux_slave_transfer_request_current_data_pointer = slave_transfer_request -> ux_slave_transfer_request_data_pointer; @@ -404,17 +409,22 @@ UX_SLAVE_DCD *dcd; else transaction_length = td -> ux_sim_host_td_length; - if (td -> ux_sim_host_td_direction == UX_HCD_SIM_HOST_TD_OUT) + if (transaction_length) + { + if (td -> ux_sim_host_td_direction == UX_HCD_SIM_HOST_TD_OUT) - /* Send the requested host data to the device. */ - _ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_current_data_pointer, td -> ux_sim_host_td_buffer, - transaction_length); /* Use case of memcpy is verified. */ + /* Send the requested host data to the device. */ + _ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_current_data_pointer, + td -> ux_sim_host_td_buffer, + transaction_length); /* Use case of memcpy is verified. */ - else + else - /* Send the requested host data to the device. */ - _ux_utility_memory_copy(td -> ux_sim_host_td_buffer, slave_transfer_request -> ux_slave_transfer_request_current_data_pointer, - transaction_length); /* Use case of memcpy is verified. */ + /* Send the requested host data to the device. */ + _ux_utility_memory_copy(td -> ux_sim_host_td_buffer, + slave_transfer_request -> ux_slave_transfer_request_current_data_pointer, + transaction_length); /* Use case of memcpy is verified. */ + } /* Update buffers. */ td -> ux_sim_host_td_buffer += transaction_length; @@ -454,12 +464,11 @@ UX_SLAVE_DCD *dcd; wake_host = UX_TRUE; wake_slave = UX_TRUE; } - else if ((slave_transfer_request -> ux_slave_transfer_request_actual_length == slave_transfer_request -> ux_slave_transfer_request_requested_length && - slave_transfer_request -> ux_slave_transfer_request_force_zlp == UX_TRUE) || - (transaction_length == 0) || - (transaction_length % slave_endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize)) + else if ((transaction_length == 0) || + (transaction_length % slave_endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize)) { + /* Host got ZLP or short packet. */ wake_host = UX_TRUE; wake_slave = UX_TRUE; } @@ -471,8 +480,15 @@ UX_SLAVE_DCD *dcd; wake_host = UX_TRUE; /* Is the slaves's transfer completed? */ - if (slave_transfer_request -> ux_slave_transfer_request_actual_length == slave_transfer_request -> ux_slave_transfer_request_requested_length) - wake_slave = UX_TRUE; + if (slave_transfer_request -> ux_slave_transfer_request_actual_length == + slave_transfer_request -> ux_slave_transfer_request_requested_length) + { + if (slave_transfer_request -> ux_slave_transfer_request_requested_length == 0 || + slave_transfer_request -> ux_slave_transfer_request_force_zlp == 0) + wake_slave = UX_TRUE; + else + slave_transfer_request -> ux_slave_transfer_request_force_zlp = 0; + } } if (wake_slave == UX_TRUE) diff --git a/common/core/src/ux_host_class_dpump_activate.c b/common/core/src/ux_host_class_dpump_activate.c index fa281ee9..bfd7633b 100644 --- a/common/core/src/ux_host_class_dpump_activate.c +++ b/common/core/src/ux_host_class_dpump_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_dpump_activate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,19 +78,23 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_dpump_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_DPUMP *dpump; UINT status; /* The data pump is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Obtain memory for this class instance. */ dpump = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_DPUMP)); @@ -101,13 +105,13 @@ UINT status; dpump -> ux_host_class_dpump_class = command -> ux_host_class_command_class_ptr; /* Store the interface container into the dpump class instance. */ - dpump -> ux_host_class_dpump_interface = interface; + dpump -> ux_host_class_dpump_interface = interface_ptr; /* Store the device container into the dpump class instance. */ - dpump -> ux_host_class_dpump_device = interface -> ux_interface_configuration -> ux_configuration_device; + dpump -> ux_host_class_dpump_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) dpump; + interface_ptr -> ux_interface_class_instance = (VOID *) dpump; /* Create this class instance. */ _ux_host_stack_class_instance_create(dpump -> ux_host_class_dpump_class, (VOID *) dpump); diff --git a/common/core/src/ux_host_class_dpump_ioctl.c b/common/core/src/ux_host_class_dpump_ioctl.c index acc728de..7b0d5260 100644 --- a/common/core/src/ux_host_class_dpump_ioctl.c +++ b/common/core/src/ux_host_class_dpump_ioctl.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_dpump_ioctl PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_dpump_ioctl(UX_HOST_CLASS_DPUMP *dpump, ULONG ioctl_function, @@ -78,7 +82,7 @@ UINT _ux_host_class_dpump_ioctl(UX_HOST_CLASS_DPUMP *dpump, ULONG ioctl_functio { UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UINT status; /* Ensure the instance is valid. */ @@ -104,8 +108,8 @@ UINT status; /* The parameter value has the alternate setting number. We need to scan the entire device framework. Only one configuration for data pump device framework. */ - interface = dpump -> ux_host_class_dpump_interface; - configuration = interface -> ux_interface_configuration; + interface_ptr = dpump -> ux_host_class_dpump_interface; + configuration = interface_ptr -> ux_interface_configuration; /* Do some verification just in case ! */ if (configuration == UX_NULL) @@ -118,25 +122,25 @@ UINT status; } /* Point to the first interface. */ - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; /* Loop on all interfaces and alternate settings for this device in search of the right alternate setting. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* Check the alternate setting. */ - if (interface -> ux_interface_descriptor.bAlternateSetting == (ULONG) (ALIGN_TYPE) parameter) + if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == (ULONG) (ALIGN_TYPE) parameter) { /* We have found the alternate setting. Select it now. */ - status = _ux_host_stack_interface_setting_select(interface); + status = _ux_host_stack_interface_setting_select(interface_ptr); /* We are done here. */ return(status); } /* Next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } /* We come here when the alternate setting was not found. */ diff --git a/common/core/src/ux_host_stack_configuration_instance_create.c b/common/core/src/ux_host_stack_configuration_instance_create.c index 26834b30..678b5b5b 100644 --- a/common/core/src/ux_host_stack_configuration_instance_create.c +++ b/common/core/src/ux_host_stack_configuration_instance_create.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_configuration_instance_create PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,29 +68,33 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_configuration_instance_create(UX_CONFIGURATION *configuration) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UINT status; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_CONFIGURATION_INSTANCE_CREATE, configuration, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) /* Obtain the first interface for this configuration. */ - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; /* Each selected alternate setting 0 for each interface must be created. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* Check if we are dealing with the first alternate setting. */ - if (interface -> ux_interface_descriptor.bAlternateSetting == 0) + if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0) { /* Create the interface. */ - status = _ux_host_stack_interface_instance_create(interface); + status = _ux_host_stack_interface_instance_create(interface_ptr); /* Check status, the controller may have refused the endpoint creation. */ if (status != UX_SUCCESS) @@ -101,7 +105,7 @@ UINT status; } /* Next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } /* Return successful completion. */ diff --git a/common/core/src/ux_host_stack_configuration_instance_delete.c b/common/core/src/ux_host_stack_configuration_instance_delete.c index 64d9e25c..9413c697 100644 --- a/common/core/src/ux_host_stack_configuration_instance_delete.c +++ b/common/core/src/ux_host_stack_configuration_instance_delete.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_configuration_instance_delete PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,40 +68,44 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_host_stack_configuration_instance_delete(UX_CONFIGURATION *configuration) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; ULONG current_alternate_setting; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_CONFIGURATION_INSTANCE_DELETE, configuration, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) /* Obtain the first interface for this configuration. */ - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; /* In order to keep the compiler happy, we reset the alternate setting. */ current_alternate_setting = 0; /* Each selected alternate setting for each interface must be deleted. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* If this is the first alternate setting, the current alternate setting is maintained here. */ - if (interface -> ux_interface_descriptor.bAlternateSetting == 0) + if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0) { - current_alternate_setting = interface -> ux_interface_current_alternate_setting; + current_alternate_setting = interface_ptr -> ux_interface_current_alternate_setting; } - if (interface -> ux_interface_descriptor.bAlternateSetting == current_alternate_setting) + if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == current_alternate_setting) { - _ux_host_stack_interface_instance_delete(interface); + _ux_host_stack_interface_instance_delete(interface_ptr); } - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } return; diff --git a/common/core/src/ux_host_stack_configuration_interface_get.c b/common/core/src/ux_host_stack_configuration_interface_get.c index 77e760c6..90b41e42 100644 --- a/common/core/src/ux_host_stack_configuration_interface_get.c +++ b/common/core/src/ux_host_stack_configuration_interface_get.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_configuration_interface_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,11 +73,15 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_configuration_interface_get(UX_CONFIGURATION *configuration, UINT interface_index, UINT alternate_setting_index, - UX_INTERFACE **interface) + UX_INTERFACE **ux_interface) { UINT current_interface_number; @@ -128,7 +132,7 @@ UX_INTERFACE *current_interface; /* We have found the right interface/alternate setting combination. Set the interface return pointer. */ - *interface = current_interface; + *ux_interface = current_interface; /* Return success to caller. */ return(UX_SUCCESS); @@ -153,7 +157,7 @@ UX_INTERFACE *current_interface; _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_INTERFACE_HANDLE_UNKNOWN); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface, 0, 0, UX_TRACE_ERRORS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, ux_interface, 0, 0, UX_TRACE_ERRORS, 0, 0) return(UX_INTERFACE_HANDLE_UNKNOWN); } @@ -177,7 +181,7 @@ UX_INTERFACE *current_interface; _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_INTERFACE_HANDLE_UNKNOWN); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface, 0, 0, UX_TRACE_ERRORS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, ux_interface, 0, 0, UX_TRACE_ERRORS, 0, 0) /* Didn't find the right interface/alternate setting, return an error! */ return(UX_INTERFACE_HANDLE_UNKNOWN); diff --git a/common/core/src/ux_host_stack_configuration_interface_scan.c b/common/core/src/ux_host_stack_configuration_interface_scan.c index d8195968..8b75b9aa 100644 --- a/common/core/src/ux_host_stack_configuration_interface_scan.c +++ b/common/core/src/ux_host_stack_configuration_interface_scan.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_configuration_interface_scan PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,14 +73,18 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_configuration_interface_scan(UX_CONFIGURATION *configuration) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UINT nb_class_owners; -UX_HOST_CLASS *class; +UX_HOST_CLASS *class_ptr; UX_HOST_CLASS_COMMAND class_command; UINT status; @@ -89,42 +93,42 @@ UINT status; nb_class_owners = 0; /* Get the first interface container for this configuration. */ - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; /* We now scan all the alternate settings 0 for each of the interfaces. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* Is there a default interface? */ - if(interface -> ux_interface_descriptor.bAlternateSetting == 0) + if(interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0) { /* We have a default interface for this configuration. Call each class with the class\subclass\protocol. We include the IAD for the cdc classes. */ class_command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY; - class_command.ux_host_class_command_container = (VOID *)interface; + class_command.ux_host_class_command_container = (VOID *)interface_ptr; class_command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP; - class_command.ux_host_class_command_class = interface -> ux_interface_descriptor.bInterfaceClass; - class_command.ux_host_class_command_subclass = interface -> ux_interface_descriptor.bInterfaceSubClass; - class_command.ux_host_class_command_protocol = interface -> ux_interface_descriptor.bInterfaceProtocol; - class_command.ux_host_class_command_iad_class = interface -> ux_interface_iad_class ; - class_command.ux_host_class_command_iad_subclass = interface -> ux_interface_iad_subclass; - class_command.ux_host_class_command_iad_protocol = interface -> ux_interface_iad_protocol; + class_command.ux_host_class_command_class = interface_ptr -> ux_interface_descriptor.bInterfaceClass; + class_command.ux_host_class_command_subclass = interface_ptr -> ux_interface_descriptor.bInterfaceSubClass; + class_command.ux_host_class_command_protocol = interface_ptr -> ux_interface_descriptor.bInterfaceProtocol; + class_command.ux_host_class_command_iad_class = interface_ptr -> ux_interface_iad_class ; + class_command.ux_host_class_command_iad_subclass = interface_ptr -> ux_interface_iad_subclass; + class_command.ux_host_class_command_iad_protocol = interface_ptr -> ux_interface_iad_protocol; - class = _ux_host_stack_class_call(&class_command); + class_ptr = _ux_host_stack_class_call(&class_command); /* On return, either we have found a class or the interface is still an orphan. */ - if (class != UX_NULL) + if (class_ptr != UX_NULL) { /* There is a class. */ nb_class_owners++; - interface -> ux_interface_class = class; + interface_ptr -> ux_interface_class = class_ptr; } } /* point to the next interface until end of the list. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } #if defined(UX_HOST_STANDALONE) @@ -151,34 +155,34 @@ UINT status; /* The device is in the CONFIGURED state, we have to call each of the classes again with an ACTIVATE signal. */ - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* Is there a default interface? */ - if (interface -> ux_interface_descriptor.bAlternateSetting == 0) + if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0) { /* We have found the default interface. If this interface is owned, activate its class. */ class_command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_ACTIVATE; - class_command.ux_host_class_command_container = (VOID *) interface; + class_command.ux_host_class_command_container = (VOID *) interface_ptr; - if (interface -> ux_interface_class != UX_NULL) + if (interface_ptr -> ux_interface_class != UX_NULL) { /* Save the class in the command container */ - class_command.ux_host_class_command_class_ptr = interface -> ux_interface_class; + class_command.ux_host_class_command_class_ptr = interface_ptr -> ux_interface_class; /* Send the ACTIVATE command to the class */ - status = interface -> ux_interface_class -> ux_host_class_entry_function(&class_command); + status = interface_ptr -> ux_interface_class -> ux_host_class_entry_function(&class_command); } } /* Point to the next interface until end of the list. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } } } diff --git a/common/core/src/ux_host_stack_device_configuration_deactivate.c b/common/core/src/ux_host_stack_device_configuration_deactivate.c index 36b338ea..ca25fccd 100644 --- a/common/core/src/ux_host_stack_device_configuration_deactivate.c +++ b/common/core/src/ux_host_stack_device_configuration_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_device_configuration_deactivate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,6 +77,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_device_configuration_deactivate(UX_DEVICE *device) @@ -87,7 +91,7 @@ UX_INTERRUPT_SAVE_AREA #endif UX_HOST_CLASS_COMMAND command; UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UINT status; @@ -158,25 +162,25 @@ UINT status; /* If device configured configuration must be activated. */ /* We have the correct configuration, search the interface(s). */ - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; /* Loop to perform the search. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* Check if an instance of the interface is present. */ - if (interface -> ux_interface_class_instance != UX_NULL) + if (interface_ptr -> ux_interface_class_instance != UX_NULL) { /* We need to stop the class instance for the device. */ - command.ux_host_class_command_instance = interface -> ux_interface_class_instance; + command.ux_host_class_command_instance = interface_ptr -> ux_interface_class_instance; /* Call the class. */ - interface -> ux_interface_class -> ux_host_class_entry_function(&command); + interface_ptr -> ux_interface_class -> ux_host_class_entry_function(&command); } /* Move to next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } /* The device can now be un-configured. */ diff --git a/common/core/src/ux_host_stack_device_configuration_reset.c b/common/core/src/ux_host_stack_device_configuration_reset.c index 2db43548..5a2bf659 100644 --- a/common/core/src/ux_host_stack_device_configuration_reset.c +++ b/common/core/src/ux_host_stack_device_configuration_reset.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_device_configuration_reset PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -58,7 +58,6 @@ /* */ /* CALLED BY */ /* */ -/* Application */ /* USBX Components */ /* */ /* RELEASE HISTORY */ @@ -76,6 +75,10 @@ /* fixed device state support, */ /* reset device power source, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* reset shared device config */ +/* descriptor for enum scan, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_device_configuration_reset(UX_DEVICE *device) @@ -109,6 +112,14 @@ UINT status; /* No configuration is selected now. */ device -> ux_device_current_configuration = UX_NULL; + /* Packed descriptor are not valid now. */ + if (device -> ux_device_packed_configuration) + { + _ux_utility_memory_free(device -> ux_device_packed_configuration); + device -> ux_device_packed_configuration = UX_NULL; + device -> ux_device_packed_configuration_keep_count = 0; + } + /* Set state of device to ADDRESSED. */ device -> ux_device_state = UX_DEVICE_ADDRESSED; diff --git a/common/core/src/ux_host_stack_device_descriptor_read.c b/common/core/src/ux_host_stack_device_descriptor_read.c index 97e039ba..392e5877 100644 --- a/common/core/src/ux_host_stack_device_descriptor_read.c +++ b/common/core/src/ux_host_stack_device_descriptor_read.c @@ -167,7 +167,7 @@ UX_ENDPOINT *control_endpoint; #endif /* Update the max packet size value for the endpoint. */ - control_endpoint -> ux_endpoint_descriptor.wMaxPacketSize = device -> ux_device_descriptor.bMaxPacketSize0; + control_endpoint -> ux_endpoint_descriptor.wMaxPacketSize = device -> ux_device_descriptor.bMaxPacketSize0; /* Create a transfer_request for the GET_DESCRIPTOR request. This time, we have the complete length */ transfer_request -> ux_transfer_request_data_pointer = descriptor; @@ -206,7 +206,7 @@ UX_ENDPOINT *control_endpoint; _ux_utility_memory_free(descriptor); /* Return completion status. */ - return(status); + return(status); #endif } diff --git a/common/core/src/ux_host_stack_device_remove.c b/common/core/src/ux_host_stack_device_remove.c index 510111e0..758bf9a6 100644 --- a/common/core/src/ux_host_stack_device_remove.c +++ b/common/core/src/ux_host_stack_device_remove.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_device_remove PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_device_remove(UX_HCD *hcd, UX_DEVICE *parent, UINT port_index) @@ -90,7 +94,7 @@ ULONG container_index; #endif UX_DEVICE *device; UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_COMMAND command; /* We need to find the device descriptor for the removed device. We can find it @@ -176,25 +180,25 @@ UX_HOST_CLASS_COMMAND command; { /* We have the correct configuration, search the interface(s). */ - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; /* Loop to perform the search. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* Check if an instance of the interface is present. */ - if (interface -> ux_interface_class_instance != UX_NULL) + if (interface_ptr -> ux_interface_class_instance != UX_NULL) { /* We need to stop the class instance for the device. */ - command.ux_host_class_command_instance = interface -> ux_interface_class_instance; + command.ux_host_class_command_instance = interface_ptr -> ux_interface_class_instance; /* Call the class. */ - interface -> ux_interface_class -> ux_host_class_entry_function(&command); + interface_ptr -> ux_interface_class -> ux_host_class_entry_function(&command); } /* Move to next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } } } diff --git a/common/core/src/ux_host_stack_device_resources_free.c b/common/core/src/ux_host_stack_device_resources_free.c index 0be0fc72..0920c139 100644 --- a/common/core/src/ux_host_stack_device_resources_free.c +++ b/common/core/src/ux_host_stack_device_resources_free.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_device_resources_free PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,13 +81,20 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* fixed standalone enum free, */ +/* freed shared device config */ +/* descriptor for enum scan, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_device_resources_free(UX_DEVICE *device) { UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *endpoint; VOID *container; ULONG current_alternate_setting; @@ -96,6 +103,9 @@ UX_HCD *hcd; UINT device_address_byte_index; UINT device_address_bit_index; UCHAR device_address_byte; +#endif +#if defined(UX_HOST_STANDALONE) +UX_DEVICE *enum_next; #endif /* If trace is enabled, insert this event into the trace buffer. */ @@ -145,26 +155,26 @@ UCHAR device_address_byte; { /* We have the correct configuration, search the interface(s). */ - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; /* Parse all the interfaces. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* The alternate setting 0 has the selected alternate setting value. */ - if (interface -> ux_interface_descriptor.bAlternateSetting == 0) - current_alternate_setting = interface -> ux_interface_current_alternate_setting; + if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0) + current_alternate_setting = interface_ptr -> ux_interface_current_alternate_setting; /* If this is the selected interface, we need to free all the endpoints attached to the alternate setting for this interface. */ - endpoint = interface -> ux_interface_first_endpoint; + endpoint = interface_ptr -> ux_interface_first_endpoint; /* Parse all the endpoints. */ while (endpoint != UX_NULL) { /* Check if this is the selected interface. */ - if (interface -> ux_interface_descriptor.bAlternateSetting == current_alternate_setting) + if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == current_alternate_setting) { /* Delete the endpoint instance first. */ @@ -183,10 +193,10 @@ UCHAR device_address_byte; /* Memorize the interface container address. */ - container = (VOID *) interface; + container = (VOID *) interface_ptr; /* Get the next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; /* Delete the interface container. */ _ux_utility_memory_free(container); @@ -202,6 +212,14 @@ UCHAR device_address_byte; _ux_utility_memory_free(container); } + /* If there was a copy of packed descriptor, free it. */ + if (device -> ux_device_packed_configuration) + { + _ux_utility_memory_free(device -> ux_device_packed_configuration); + + /* Pointer and keep count is set NULL later while reseting instance memory. */ + } + /* We need the HCD address for the control endpoint removal and to free the device address. */ hcd = UX_DEVICE_HCD_GET(device); @@ -250,7 +268,14 @@ UCHAR device_address_byte; _ux_host_semaphore_delete(&device -> ux_device_protection_semaphore); /* Now this device can be free and its container return to the pool. */ +#if defined(UX_HOST_STANDALONE) + enum_next = device -> ux_device_enum_next; _ux_utility_memory_set(device, 0, sizeof(UX_DEVICE)); /* Use case of memset is verified. */ + device -> ux_device_enum_next = enum_next; +#else + + _ux_utility_memory_set(device, 0, sizeof(UX_DEVICE)); /* Use case of memset is verified. */ +#endif /* Mark the device handle as unused. */ device -> ux_device_handle = UX_UNUSED; diff --git a/common/core/src/ux_host_stack_endpoint_instance_create.c b/common/core/src/ux_host_stack_endpoint_instance_create.c index 2a76e0f2..85d100f9 100644 --- a/common/core/src/ux_host_stack_endpoint_instance_create.c +++ b/common/core/src/ux_host_stack_endpoint_instance_create.c @@ -154,6 +154,8 @@ UCHAR endpoint_type; /* If trace is enabled, register this object. */ UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_ENDPOINT, endpoint, 0, 0, 0) + /* By default transfer request contained is for endpoint itself. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_endpoint = endpoint; } /* Return completion status. */ diff --git a/common/core/src/ux_host_stack_hcd_thread_entry.c b/common/core/src/ux_host_stack_hcd_thread_entry.c index 2ae43a18..652035b8 100755 --- a/common/core/src/ux_host_stack_hcd_thread_entry.c +++ b/common/core/src/ux_host_stack_hcd_thread_entry.c @@ -45,7 +45,7 @@ /* The HCD thread is initialized at the system level and the thread */ /* entry routine is invoked right away. This thread suspends until */ /* one of the HCD resumes it due to HCD activities. */ -/* */ +/* */ /* It's for RTOS mode. */ /* */ /* INPUT */ diff --git a/common/core/src/ux_host_stack_hnp_polling_thread_entry.c b/common/core/src/ux_host_stack_hnp_polling_thread_entry.c index 2f72fa77..ab35b682 100644 --- a/common/core/src/ux_host_stack_hnp_polling_thread_entry.c +++ b/common/core/src/ux_host_stack_hnp_polling_thread_entry.c @@ -178,7 +178,7 @@ UINT status; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; /* Protect the control endpoint semaphore here. It will be unprotected in the - transfer request function. */ + transfer request function. */ status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); /* Perform a GET_STATUS on this device to see if it wants to become the host. */ diff --git a/common/core/src/ux_host_stack_interface_endpoint_get.c b/common/core/src/ux_host_stack_interface_endpoint_get.c index 237babc5..c0390731 100644 --- a/common/core/src/ux_host_stack_interface_endpoint_get.c +++ b/common/core/src/ux_host_stack_interface_endpoint_get.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_interface_endpoint_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,32 +70,36 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ -UINT _ux_host_stack_interface_endpoint_get(UX_INTERFACE *interface, UINT endpoint_index, UX_ENDPOINT **endpoint) +UINT _ux_host_stack_interface_endpoint_get(UX_INTERFACE *interface_ptr, UINT endpoint_index, UX_ENDPOINT **endpoint) { UINT current_endpoint_index; UX_ENDPOINT *current_endpoint; /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_ENDPOINT_GET, interface, endpoint_index, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_ENDPOINT_GET, interface_ptr, endpoint_index, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) /* Do a sanity check on the interface handle. */ - if (interface -> ux_interface_handle != (ULONG) (ALIGN_TYPE) interface) + if (interface_ptr -> ux_interface_handle != (ULONG) (ALIGN_TYPE) interface_ptr) { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_INTERFACE_HANDLE_UNKNOWN); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface, 0, 0, UX_TRACE_ERRORS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface_ptr, 0, 0, UX_TRACE_ERRORS, 0, 0) return(UX_INTERFACE_HANDLE_UNKNOWN); } /* Start with the endpoint attached to the interface. */ - current_endpoint = interface -> ux_interface_first_endpoint; + current_endpoint = interface_ptr -> ux_interface_first_endpoint; /* The first endpoint has the index 0. */ current_endpoint_index = 0; diff --git a/common/core/src/ux_host_stack_interface_instance_create.c b/common/core/src/ux_host_stack_interface_instance_create.c index 57cd956d..d09e69f7 100644 --- a/common/core/src/ux_host_stack_interface_instance_create.c +++ b/common/core/src/ux_host_stack_interface_instance_create.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_interface_instance_create PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,19 +67,23 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ -UINT _ux_host_stack_interface_instance_create(UX_INTERFACE *interface) +UINT _ux_host_stack_interface_instance_create(UX_INTERFACE *interface_ptr) { UX_ENDPOINT *endpoint; UINT status; /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_INSTANCE_CREATE, interface, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_INSTANCE_CREATE, interface_ptr, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) /* Obtain the first endpoint for this alternate setting. */ - endpoint = interface -> ux_interface_first_endpoint; + endpoint = interface_ptr -> ux_interface_first_endpoint; /* Loop to create each endpoint. */ while (endpoint != UX_NULL) @@ -99,7 +103,7 @@ UINT status; } /* If trace is enabled, register this object. */ - UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, interface, 0, 0, 0); + UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, interface_ptr, 0, 0, 0); /* Return completion status. */ return(UX_SUCCESS); diff --git a/common/core/src/ux_host_stack_interface_instance_delete.c b/common/core/src/ux_host_stack_interface_instance_delete.c index 4ecbef62..6b0edbe5 100644 --- a/common/core/src/ux_host_stack_interface_instance_delete.c +++ b/common/core/src/ux_host_stack_interface_instance_delete.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_interface_instance_delete PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,21 +68,25 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ -VOID _ux_host_stack_interface_instance_delete(UX_INTERFACE *interface) +VOID _ux_host_stack_interface_instance_delete(UX_INTERFACE *interface_ptr) { UX_ENDPOINT *endpoint; /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_INSTANCE_DELETE, interface, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_INSTANCE_DELETE, interface_ptr, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) /* If trace is enabled, register this object. */ - UX_TRACE_OBJECT_UNREGISTER(interface); + UX_TRACE_OBJECT_UNREGISTER(interface_ptr); /* Obtain the first endpoint for this alternate setting. */ - endpoint = interface -> ux_interface_first_endpoint; + endpoint = interface_ptr -> ux_interface_first_endpoint; /* Loop to delete each endpoint. */ while (endpoint != UX_NULL) diff --git a/common/core/src/ux_host_stack_interface_set.c b/common/core/src/ux_host_stack_interface_set.c index d87da200..6bdc50af 100644 --- a/common/core/src/ux_host_stack_interface_set.c +++ b/common/core/src/ux_host_stack_interface_set.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_interface_set PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,9 +70,13 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ -UINT _ux_host_stack_interface_set(UX_INTERFACE *interface) +UINT _ux_host_stack_interface_set(UX_INTERFACE *interface_ptr) { UX_DEVICE *device; @@ -82,12 +86,12 @@ UINT status; UX_ENDPOINT *control_endpoint; /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_SET, interface, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_SET, interface_ptr, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) /* Retrieve the pointer to the control endpoint and its transfer_request. From the interface we go back to the configuration, then the device. The device contains the default control endpoint container. */ - configuration = interface -> ux_interface_configuration; + configuration = interface_ptr -> ux_interface_configuration; device = configuration -> ux_configuration_device; control_endpoint = &device -> ux_device_control_endpoint; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; @@ -96,8 +100,8 @@ UX_ENDPOINT *control_endpoint; transfer_request -> ux_transfer_request_requested_length = 0; transfer_request -> ux_transfer_request_function = UX_SET_INTERFACE; transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE; - transfer_request -> ux_transfer_request_index = (USHORT) interface -> ux_interface_descriptor.bInterfaceNumber; - transfer_request -> ux_transfer_request_value = (USHORT) interface -> ux_interface_descriptor.bAlternateSetting; + transfer_request -> ux_transfer_request_index = (USHORT) interface_ptr -> ux_interface_descriptor.bInterfaceNumber; + transfer_request -> ux_transfer_request_value = (USHORT) interface_ptr -> ux_interface_descriptor.bAlternateSetting; /* Send request. */ status = _ux_host_stack_transfer_request(transfer_request); diff --git a/common/core/src/ux_host_stack_interface_setting_select.c b/common/core/src/ux_host_stack_interface_setting_select.c index 145fce63..663cacd8 100644 --- a/common/core/src/ux_host_stack_interface_setting_select.c +++ b/common/core/src/ux_host_stack_interface_setting_select.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_interface_setting_select PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -57,6 +57,8 @@ /* _ux_host_stack_interface_instance_create Create interface instance */ /* _ux_host_stack_interface_instance_delete Delete interface instance */ /* _ux_host_stack_interface_set Set interface instance */ +/* _ux_host_semaphore_get Get semaphore */ +/* _ux_host_semaphore_put Put semaphore */ /* */ /* CALLED BY */ /* */ @@ -70,9 +72,12 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* protected control request, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ -UINT _ux_host_stack_interface_setting_select(UX_INTERFACE *interface) +UINT _ux_host_stack_interface_setting_select(UX_INTERFACE *interface_ptr) { UX_CONFIGURATION *configuration; @@ -84,22 +89,22 @@ UINT current_alternate_setting; UINT status; /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_SETTING_SELECT, interface, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_SETTING_SELECT, interface_ptr, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) /* Check this alternate setting container. It must be valid before we continue. */ - if (interface -> ux_interface_handle != (ULONG) (ALIGN_TYPE) interface) + if (interface_ptr -> ux_interface_handle != (ULONG) (ALIGN_TYPE) interface_ptr) { /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface, 0, 0, UX_TRACE_ERRORS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface_ptr, 0, 0, UX_TRACE_ERRORS, 0, 0) return(UX_INTERFACE_HANDLE_UNKNOWN); } /* From the interface, get the configuration container and the first interface hooked to this configuration. */ - configuration = interface -> ux_interface_configuration; - current_interface_number = interface -> ux_interface_descriptor.bInterfaceNumber; + configuration = interface_ptr -> ux_interface_configuration; + current_interface_number = interface_ptr -> ux_interface_descriptor.bInterfaceNumber; current_interface = configuration -> ux_configuration_first_interface; /* Remember the main interface to store the next alternate setting. We set the main interface @@ -157,17 +162,17 @@ UINT status; } /* Remember the new alternate setting. */ - main_interface -> ux_interface_current_alternate_setting = interface -> ux_interface_descriptor.bAlternateSetting; + main_interface -> ux_interface_current_alternate_setting = interface_ptr -> ux_interface_descriptor.bAlternateSetting; /* Now, the interface must be created with the new alternate setting. */ - status = _ux_host_stack_interface_instance_create(interface); + status = _ux_host_stack_interface_instance_create(interface_ptr); /* If we could not create it, we return to the default one. */ if (status != UX_SUCCESS) { /* Then delete the failed interface. */ - _ux_host_stack_interface_instance_delete(interface); + _ux_host_stack_interface_instance_delete(interface_ptr); /* Error, reset the main interface alternate setting to the default. */ main_interface -> ux_interface_current_alternate_setting = current_alternate_setting; @@ -179,8 +184,14 @@ UINT status; return(status); } + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_host_semaphore_get(&configuration -> ux_configuration_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + return(status); + /* Issue a SET_INTERFACE command to the target device. */ - status = _ux_host_stack_interface_set(interface); + status = _ux_host_stack_interface_set(interface_ptr); /* Check completion status. */ if (status != UX_SUCCESS) @@ -190,12 +201,13 @@ UINT status; main_interface -> ux_interface_current_alternate_setting = current_alternate_setting; /* Delete the current interface. */ - _ux_host_stack_interface_instance_delete(interface); + _ux_host_stack_interface_instance_delete(interface_ptr); /* Re-create the previous interface with the old alternate setting. */ _ux_host_stack_interface_instance_create(previous_interface); /* Return error status. */ + _ux_host_semaphore_put(&configuration -> ux_configuration_device -> ux_device_protection_semaphore); return(status); } diff --git a/common/core/src/ux_host_stack_new_device_create.c b/common/core/src/ux_host_stack_new_device_create.c index 2fd5ebec..442b32e2 100644 --- a/common/core/src/ux_host_stack_new_device_create.c +++ b/common/core/src/ux_host_stack_new_device_create.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_new_device_create PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -106,6 +106,10 @@ /* added standalone support, */ /* reset device power source, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* freed shared device config */ +/* descriptor after enum scan, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_new_device_create(UX_HCD *hcd, UX_DEVICE *device_owner, @@ -276,6 +280,15 @@ UX_ENDPOINT *control_endpoint; { status = _ux_host_stack_class_interface_scan(device); + + } + + /* Check if there is unnecessary resource to free. */ + if (device -> ux_device_packed_configuration && + device -> ux_device_packed_configuration_keep_count == 0) + { + _ux_utility_memory_free(device -> ux_device_packed_configuration); + device -> ux_device_packed_configuration = UX_NULL; } /* If trace is enabled, register this object. */ diff --git a/common/core/src/ux_host_stack_new_device_get.c b/common/core/src/ux_host_stack_new_device_get.c index 62d5e4cb..19c37247 100644 --- a/common/core/src/ux_host_stack_new_device_get.c +++ b/common/core/src/ux_host_stack_new_device_get.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_new_device_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,6 +69,9 @@ /* definitions, verified */ /* memset and memcpy cases, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed standalone enum init, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UX_DEVICE *_ux_host_stack_new_device_get(VOID) @@ -78,7 +81,9 @@ UX_DEVICE *_ux_host_stack_new_device_get(VOID) ULONG container_index; #endif UX_DEVICE *device; - +#if defined(UX_HOST_STANDALONE) +UX_DEVICE *enum_next; +#endif /* Start with the first device. */ device = _ux_system_host -> ux_system_host_device_array; @@ -96,8 +101,17 @@ UX_DEVICE *device; if (device -> ux_device_handle == UX_UNUSED) { +#if defined(UX_HOST_STANDALONE) + + /* Reset the entire entry except enum link. */ + enum_next = device -> ux_device_enum_next; + _ux_utility_memory_set(device, 0, sizeof(UX_DEVICE)); /* Use case of memset is verified. */ + device -> ux_device_enum_next = enum_next; +#else + /* Reset the entire entry. */ _ux_utility_memory_set(device, 0, sizeof(UX_DEVICE)); /* Use case of memset is verified. */ +#endif /* This entry is now used. */ device -> ux_device_handle = UX_USED; diff --git a/common/core/src/ux_host_stack_new_endpoint_create.c b/common/core/src/ux_host_stack_new_endpoint_create.c index 539871a7..7fa52072 100644 --- a/common/core/src/ux_host_stack_new_endpoint_create.c +++ b/common/core/src/ux_host_stack_new_endpoint_create.c @@ -83,7 +83,7 @@ /* resulting in version 6.1.11 */ /* */ /**************************************************************************/ -UINT _ux_host_stack_new_endpoint_create(UX_INTERFACE *interface, +UINT _ux_host_stack_new_endpoint_create(UX_INTERFACE *interface_ptr, UCHAR * interface_endpoint) { @@ -99,7 +99,7 @@ ULONG n_tran; return(UX_MEMORY_INSUFFICIENT); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_NEW_ENDPOINT_CREATE, interface, endpoint, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_NEW_ENDPOINT_CREATE, interface_ptr, endpoint, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) /* Save the endpoint handle in the container, this is for ensuring the endpoint container is not corrupted. */ @@ -110,7 +110,7 @@ ULONG n_tran; endpoint -> ux_endpoint_transfer_request.ux_transfer_request_endpoint = endpoint; /* Save the pointer to the device. This is useful for the HCD layer. */ - endpoint -> ux_endpoint_device = interface -> ux_interface_configuration -> ux_configuration_device; + endpoint -> ux_endpoint_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* Parse the interface descriptor and make it machine independent. */ _ux_utility_descriptor_parse(interface_endpoint, @@ -173,7 +173,7 @@ ULONG n_tran; return(UX_DESCRIPTOR_CORRUPTED); } if ((endpoint_type == UX_ISOCHRONOUS_ENDPOINT) || - (interface -> ux_interface_configuration -> ux_configuration_device + (interface_ptr -> ux_interface_configuration -> ux_configuration_device -> ux_device_speed == UX_HIGH_SPEED_DEVICE) ) { @@ -194,22 +194,22 @@ ULONG n_tran; /* The interface that owns this endpoint is memorized in the endpoint container itself, easier for back chaining. */ - endpoint -> ux_endpoint_interface = interface; + endpoint -> ux_endpoint_interface = interface_ptr; /* There is 2 cases for the creation of the endpoint descriptor if this is the first one, the endpoint descriptor is hooked to the interface. If it is not the first one, the endpoint is hooked to the end of the chain of endpoints. */ - if (interface -> ux_interface_first_endpoint == UX_NULL) + if (interface_ptr -> ux_interface_first_endpoint == UX_NULL) { - interface -> ux_interface_first_endpoint = endpoint; + interface_ptr -> ux_interface_first_endpoint = endpoint; } else { - list_endpoint = interface -> ux_interface_first_endpoint; + list_endpoint = interface_ptr -> ux_interface_first_endpoint; /* Traverse the list until the end. */ while (list_endpoint -> ux_endpoint_next_endpoint != UX_NULL) diff --git a/common/core/src/ux_host_stack_new_interface_create.c b/common/core/src/ux_host_stack_new_interface_create.c index 0d152528..20788555 100644 --- a/common/core/src/ux_host_stack_new_interface_create.c +++ b/common/core/src/ux_host_stack_new_interface_create.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_new_interface_create PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_new_interface_create(UX_CONFIGURATION *configuration, @@ -87,7 +91,7 @@ UINT _ux_host_stack_new_interface_create(UX_CONFIGURATION *configuration, { UX_INTERFACE *list_interface; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UINT number_endpoints; UINT descriptor_length; UINT descriptor_type; @@ -95,30 +99,30 @@ UINT status; UCHAR *this_interface_descriptor; /* Obtain memory for storing this new interface. */ - interface = (UX_INTERFACE *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_INTERFACE)); + interface_ptr = (UX_INTERFACE *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_INTERFACE)); /* If no memory left, exit with error. */ - if (interface == UX_NULL) + if (interface_ptr == UX_NULL) return(UX_MEMORY_INSUFFICIENT); /* Save the interface handle in the container, this is for ensuring the interface container is not corrupted. */ - interface -> ux_interface_handle = (ULONG) (ALIGN_TYPE) interface; + interface_ptr -> ux_interface_handle = (ULONG) (ALIGN_TYPE) interface_ptr; /* Parse the interface descriptor and make it machine independent. */ _ux_utility_descriptor_parse(descriptor, _ux_system_interface_descriptor_structure, UX_INTERFACE_DESCRIPTOR_ENTRIES, - (UCHAR *) &interface -> ux_interface_descriptor); + (UCHAR *) &interface_ptr -> ux_interface_descriptor); /* The configuration that owns this interface is memorized in the interface container itself, easier for back chaining. */ - interface -> ux_interface_configuration = configuration; + interface_ptr -> ux_interface_configuration = configuration; /* If the interface belongs to an IAD, remember the IAD Class/SubClass/Protocol. */ - interface -> ux_interface_iad_class = configuration -> ux_configuration_iad_class; - interface -> ux_interface_iad_subclass = configuration -> ux_configuration_iad_subclass; - interface -> ux_interface_iad_protocol = configuration -> ux_configuration_iad_protocol; + interface_ptr -> ux_interface_iad_class = configuration -> ux_configuration_iad_class; + interface_ptr -> ux_interface_iad_subclass = configuration -> ux_configuration_iad_subclass; + interface_ptr -> ux_interface_iad_protocol = configuration -> ux_configuration_iad_protocol; /* There is 2 cases for the creation of the interface descriptor if this is the first one, the interface descriptor is hooked @@ -126,7 +130,7 @@ UCHAR *this_interface_descriptor; is hooked to the end of the chain of interfaces. */ if (configuration -> ux_configuration_first_interface == UX_NULL) { - configuration -> ux_configuration_first_interface = interface; + configuration -> ux_configuration_first_interface = interface_ptr; } else { @@ -141,13 +145,13 @@ UCHAR *this_interface_descriptor; } /* Hook the interface. */ - list_interface -> ux_interface_next_interface = interface; + list_interface -> ux_interface_next_interface = interface_ptr; } /* Traverse the interface in search of all endpoints that belong to it. We need the length remaining in the descriptor and the number of endpoints reported for this interface. */ - number_endpoints = interface -> ux_interface_descriptor.bNumEndpoints; + number_endpoints = interface_ptr -> ux_interface_descriptor.bNumEndpoints; this_interface_descriptor = descriptor; @@ -176,7 +180,7 @@ UCHAR *this_interface_descriptor; { /* We have found an endpoint descriptor for this interface. */ - status = _ux_host_stack_new_endpoint_create(interface, descriptor); + status = _ux_host_stack_new_endpoint_create(interface_ptr, descriptor); /* Check return status. */ if(status != UX_SUCCESS) diff --git a/common/core/src/ux_host_stack_tasks_run.c b/common/core/src/ux_host_stack_tasks_run.c index 8e592618..a867411c 100644 --- a/common/core/src/ux_host_stack_tasks_run.c +++ b/common/core/src/ux_host_stack_tasks_run.c @@ -44,7 +44,7 @@ static inline VOID _ux_host_stack_pending_transfers_run(VOID); /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_tasks_run PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -100,6 +100,11 @@ static inline VOID _ux_host_stack_pending_transfers_run(VOID); /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone hub, */ +/* used shared descriptor in */ +/* device instance for enum, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_stack_tasks_run(VOID) @@ -311,6 +316,14 @@ static inline VOID _ux_host_stack_device_enumerated(UX_DEVICE *device) UX_DEVICE_HCD_GET(device), UX_DEVICE_PARENT_GET(device), UX_DEVICE_PORT_LOCATION_GET(device), 0); + /* Check if there is unnecessary resource to free. */ + if (device -> ux_device_packed_configuration && + device -> ux_device_packed_configuration_keep_count == 0) + { + _ux_utility_memory_free(device -> ux_device_packed_configuration); + device -> ux_device_packed_configuration = UX_NULL; + } + /* Reset enumeration state. */ device -> ux_device_enum_state = UX_STATE_IDLE; @@ -449,9 +462,12 @@ UCHAR *buffer; switch (device -> ux_device_enum_state) { case UX_STATE_RESET: + + /* Reset retry counts. */ + device -> ux_device_enum_retry = UX_RH_ENUMERATION_RETRY; + device -> ux_device_enum_state = UX_HOST_STACK_ENUM_PORT_ENABLE; device -> ux_device_enum_next_state = UX_HOST_STACK_ENUM_PORT_ENABLE; - device -> ux_device_enum_retry = UX_RH_ENUMERATION_RETRY; device -> ux_device_enum_port_status = UX_PS_CCS; /* Fall through. */ @@ -460,19 +476,25 @@ UCHAR *buffer; /* Lock enumeration any way. */ _ux_system_host -> ux_system_host_enum_lock = device; - /* For device connected to roohub, we may need port enable (OHCI). */ #if UX_MAX_DEVICES > 1 if (UX_DEVICE_PARENT_IS_HUB(device)) + { + + /* Issue a port reset on hub side. */ + device -> ux_device_flags |= UX_DEVICE_FLAG_RESET; + device -> ux_device_enum_state = UX_HOST_STACK_ENUM_HUB_OPERATION_WAIT; + return; + } #endif + + /* For device connected to roohub, we may need port enable (OHCI). */ + status = _ux_host_stack_rh_port_enable(device); + if (status == UX_PORT_INDEX_UNKNOWN) { - status = _ux_host_stack_rh_port_enable(device); - if (status == UX_PORT_INDEX_UNKNOWN) - { - /* No retry, enumeration fail. */ - device -> ux_device_enum_state = UX_HOST_STACK_ENUM_FAIL; - continue; - } + /* No retry, enumeration fail. */ + device -> ux_device_enum_state = UX_HOST_STACK_ENUM_FAIL; + continue; } /* Wait a while after port connection. */ @@ -483,15 +505,15 @@ UCHAR *buffer; UX_MS_TO_TICK_NON_ZERO(UX_RH_ENUMERATION_RETRY_DELAY); continue; - case UX_HOST_STACK_ENUM_PORT_RESET: - #if UX_MAX_DEVICES > 1 - if (UX_DEVICE_PARENT_IS_HUB(device)) - { - /* NOTE: need hub support. */ - } + case UX_HOST_STACK_ENUM_HUB_OPERATION_WAIT: + + /* Keep waiting, state is changed in hub tasks. */ + return; #endif + case UX_HOST_STACK_ENUM_PORT_RESET: + /* Reset may blocking, wait the reset done. */ /* Fall through. */ case UX_HOST_STACK_ENUM_PORT_RESET_WAIT: @@ -532,12 +554,6 @@ UCHAR *buffer; (UCHAR)(1u << ((device -> ux_device_address-1) & 7u)); } #endif -#if UX_MAX_DEVICES > 1 - if (UX_DEVICE_PARENT_IS_HUB(device)) - { - /* NOTE: need hub support. */ - } -#endif /* Get port status. */ status = _ux_host_stack_rh_port_status_get(device); @@ -922,7 +938,8 @@ UCHAR *buffer; case UX_HOST_STACK_ENUM_TRANS_WAIT: /* Poll transfer task. */ - status = _ux_host_stack_transfer_run(device -> ux_device_enum_trans); + trans = device -> ux_device_enum_trans; + status = _ux_host_stack_transfer_run(trans); /* Transfer done - next state. */ if (status == UX_STATE_NEXT || status == UX_STATE_IDLE) @@ -936,6 +953,16 @@ UCHAR *buffer; { /* No retry, fail. */ + if (trans -> ux_transfer_request_data_pointer) + { + _ux_utility_memory_free(trans -> ux_transfer_request_data_pointer); + trans -> ux_transfer_request_data_pointer = UX_NULL; + } + if (device -> ux_device_enum_next_state == UX_HOST_STACK_ENUM_CONFIG_DESCR_PARSE) + { + _ux_utility_memory_free(device -> ux_device_enum_inst.ptr); + device -> ux_device_enum_inst.ptr = UX_NULL; + } device -> ux_device_enum_state = UX_HOST_STACK_ENUM_FAIL; continue; } @@ -943,6 +970,16 @@ UCHAR *buffer; { /* Error, retry. */ + if (trans -> ux_transfer_request_data_pointer) + { + _ux_utility_memory_free(trans -> ux_transfer_request_data_pointer); + trans -> ux_transfer_request_data_pointer = UX_NULL; + } + if (device -> ux_device_enum_next_state == UX_HOST_STACK_ENUM_CONFIG_DESCR_PARSE) + { + _ux_utility_memory_free(device -> ux_device_enum_inst.ptr); + device -> ux_device_enum_inst.ptr = UX_NULL; + } device -> ux_device_enum_state = UX_HOST_STACK_ENUM_RETRY; continue; } @@ -989,6 +1026,14 @@ UCHAR *buffer; { device -> ux_device_enum_retry --; + /* Check if there is unnecessary resource to free. */ + if (device -> ux_device_packed_configuration && + device -> ux_device_packed_configuration_keep_count == 0) + { + _ux_utility_memory_free(device -> ux_device_packed_configuration); + device -> ux_device_packed_configuration = UX_NULL; + } + /* Start from port enable delay. */ device -> ux_device_enum_next_state = UX_HOST_STACK_ENUM_PORT_RESET; device -> ux_device_enum_state = UX_HOST_STACK_ENUM_WAIT; diff --git a/common/core/src/ux_utility_string_length_check.c b/common/core/src/ux_utility_string_length_check.c index f4a2a0a9..f561e619 100644 --- a/common/core/src/ux_utility_string_length_check.c +++ b/common/core/src/ux_utility_string_length_check.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_utility_string_length_check PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -46,6 +46,9 @@ /* On success the actual length of C string is written back to UINT */ /* variable pointed by string_length_ptr (if not NULL). */ /* Otherwise the variable keeps untouched. */ +/* */ +/* Note NULL terminator is not counted in string length */ +/* (same as C strlen). */ /* */ /* INPUT */ /* */ @@ -74,6 +77,8 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_utility_string_length_check(UCHAR *string, UINT *string_length_ptr, UINT max_string_length) diff --git a/common/usbx_device_classes/CMakeLists.txt b/common/usbx_device_classes/CMakeLists.txt index d4dbe5cd..f3c38671 100644 --- a/common/usbx_device_classes/CMakeLists.txt +++ b/common/usbx_device_classes/CMakeLists.txt @@ -12,6 +12,8 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_thread_entry.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_frame_write.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_initialize.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_interrupt_send.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_interrupt_thread_entry.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_ioctl.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_frame_free.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_frame_get.c @@ -90,9 +92,11 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_initialize.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_interrupt_thread.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_read.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_read_run.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_receiver_event_free.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_receiver_event_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_receiver_initialize.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_receiver_tasks_run.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_receiver_thread.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_receiver_uninitialize.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_report_get.c diff --git a/common/usbx_device_classes/inc/ux_device_class_audio.h b/common/usbx_device_classes/inc/ux_device_class_audio.h index 6959a7c3..8ce47fa0 100644 --- a/common/usbx_device_classes/inc/ux_device_class_audio.h +++ b/common/usbx_device_classes/inc/ux_device_class_audio.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_audio.h PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -56,6 +56,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added interrupt support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -76,6 +79,13 @@ extern "C" { /* Compile option: if defined, audio feedback endpoint is supported. */ /* #define UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT */ +/* Compile option: if defined, audio interrupt endpoint is supported. */ +/* #define UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT */ + + +/* Define Audio Class OS related constants. */ +#define UX_DEVICE_CLASS_AUDIO_FEEDBACK_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE +#define UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE /* Define Audio Class function (AF) constants. */ @@ -345,6 +355,11 @@ typedef struct UX_DEVICE_CLASS_AUDIO_PARAMETER_STRUCT ULONG ux_device_class_audio_parameter_streams_nb; UX_DEVICE_CLASS_AUDIO_STREAM_PARAMETER *ux_device_class_audio_parameter_streams; + +#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) + ULONG ux_device_class_audio_parameter_status_size; + ULONG ux_device_class_audio_parameter_status_queue_size; +#endif } UX_DEVICE_CLASS_AUDIO_PARAMETER; @@ -400,6 +415,22 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STRUCT ULONG ux_device_class_audio_streams_nb; UX_DEVICE_CLASS_AUDIO_STREAM *ux_device_class_audio_streams; + +#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) + UX_SLAVE_ENDPOINT *ux_device_class_audio_interrupt; + + ULONG ux_device_class_audio_status_size; /* in Bytes. */ + ULONG ux_device_class_audio_status_queue_bytes;/* in Bytes. */ + ULONG ux_device_class_audio_status_queued; /* in Bytes. */ + UCHAR *ux_device_class_audio_status_queue; /* in Bytes. */ + UCHAR *ux_device_class_audio_status_head; + UCHAR *ux_device_class_audio_status_tail; + +#if !defined(UX_DEVICE_STANDALONE) + UX_SEMAPHORE ux_device_class_audio_status_semaphore; + UX_MUTEX ux_device_class_audio_status_mutex; +#endif +#endif } UX_DEVICE_CLASS_AUDIO; @@ -442,6 +473,9 @@ UINT _ux_device_class_audio_feedback_set(UX_DEVICE_CLASS_AUDIO_STREAM *audio, UINT _ux_device_class_audio_feedback_get(UX_DEVICE_CLASS_AUDIO_STREAM *audio, UCHAR *encoded_feedback); ULONG _ux_device_class_audio_speed_get(UX_DEVICE_CLASS_AUDIO_STREAM *audio); +VOID _ux_device_class_audio_interrupt_thread_entry(ULONG audio_inst); +UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHAR *int_data); + /* Define Device Class Audio API prototypes. */ @@ -474,6 +508,8 @@ ULONG _ux_device_class_audio_speed_get(UX_DEVICE_CLASS_AUDIO_STREAM *audio); #define ux_device_class_audio_feedback_get _ux_device_class_audio_feedback_get #define ux_device_class_audio_feedback_set _ux_device_class_audio_feedback_set +#define ux_device_class_audio_interrupt_send _ux_device_class_audio_interrupt_send + /* Determine if a C++ compiler is being used. If so, complete the standard C conditional started above. */ #ifdef __cplusplus diff --git a/common/usbx_device_classes/inc/ux_device_class_audio10.h b/common/usbx_device_classes/inc/ux_device_class_audio10.h index 6e6c000b..d366ef2e 100644 --- a/common/usbx_device_classes/inc/ux_device_class_audio10.h +++ b/common/usbx_device_classes/inc/ux_device_class_audio10.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_audio10.h PORTABLE C */ -/* 6.1.8 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -50,6 +50,9 @@ /* added extern "C" keyword */ /* for compatibility with C++, */ /* resulting in version 6.1.8 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added sampling control, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -131,6 +134,13 @@ extern "C" { #define UX_DEVICE_CLASS_AUDIO10_FU_LOUNDNESS_CONTROL 0x0A +/* Define Audio Class specific endpoint control selectors. */ + +#define UX_DEVICE_CLASS_AUDIO10_EP_CONTROL_UNDEFINED 0x00 +#define UX_DEVICE_CLASS_AUDIO10_EP_SAMPLING_FREQ_CONTROL 0x01 +#define UX_DEVICE_CLASS_AUDIO10_EP_PITCH_CONTROL 0x02 + + /* Define Audio Class encoding format types. */ #define UX_DEVICE_CLASS_AUDIO10_FORMAT_PCM 1 @@ -351,10 +361,13 @@ typedef struct UX_DEVICE_CLASS_AUDIO10_AS_DATA_ENDPOINT_DESCRIPTOR_STRUCT typedef struct UX_DEVICE_CLASS_AUDIO10_CONTROL_STRUCT { - ULONG ux_device_class_audio10_control_fu_id; - ULONG ux_device_class_audio10_control_changed; + ULONG ux_device_class_audio10_control_ep_addr; /* Endpoint address for sampling frequencies control. */ + UCHAR *ux_device_class_audio10_control_sam_freq_types;/* Format Type I Descriptor - bSamFreqType and followings. */ + ULONG ux_device_class_audio10_control_sam_freq; /* Current sampling frequency. */ + + ULONG ux_device_class_audio10_control_fu_id; USHORT ux_device_class_audio10_control_mute[1]; SHORT ux_device_class_audio10_control_volume_min[1]; SHORT ux_device_class_audio10_control_volume_max[1]; @@ -362,8 +375,9 @@ typedef struct UX_DEVICE_CLASS_AUDIO10_CONTROL_STRUCT SHORT ux_device_class_audio10_control_volume[1]; } UX_DEVICE_CLASS_AUDIO10_CONTROL; -#define UX_DEVICE_CLASS_AUDIO10_CONTROL_MUTE_CHANGED 1 -#define UX_DEVICE_CLASS_AUDIO10_CONTROL_VOLUME_CHANGED 2 +#define UX_DEVICE_CLASS_AUDIO10_CONTROL_MUTE_CHANGED 1u +#define UX_DEVICE_CLASS_AUDIO10_CONTROL_VOLUME_CHANGED 2u +#define UX_DEVICE_CLASS_AUDIO20_CONTROL_FREQUENCY_CHANGED 4u typedef struct UX_DEVICE_CLASS_AUDIO10_CONTROL_GROUP_STRUCT { diff --git a/common/usbx_device_classes/inc/ux_device_class_audio20.h b/common/usbx_device_classes/inc/ux_device_class_audio20.h index 0f444458..aa7cc4f8 100644 --- a/common/usbx_device_classes/inc/ux_device_class_audio20.h +++ b/common/usbx_device_classes/inc/ux_device_class_audio20.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_audio20.h PORTABLE C */ -/* 6.1.8 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -50,6 +50,11 @@ /* added extern "C" keyword */ /* for compatibility with C++, */ /* resulting in version 6.1.8 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added support of multiple */ +/* sampling frequencies, */ +/* added clock multiplier DEFs,*/ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -139,6 +144,14 @@ extern "C" { #define UX_DEVICE_CLASS_AUDIO20_CX_CONTROL_UNDEFINED 0x00 #define UX_DEVICE_CLASS_AUDIO20_CX_CLOCK_SELECTOR_CONTROL 0x01 + +/* Define Audio Class specific clock multiplier control selectors. */ + + +#define UX_DEVICE_CLASS_AUDIO20_CM_CONTROL_UNDEFINED 0x00 +#define UX_DEVICE_CLASS_AUDIO20_CM_NUMERATOR_CONTROL 0x01 +#define UX_DEVICE_CLASS_AUDIO20_CM_DENOMINATOR_CONTROL 0x02 + /* Define Audio Class specific terminal control selectors. */ #define UX_DEVICE_CLASS_AUDIO20_TE_CONTROL_UNDEFINED 0x00 @@ -406,12 +419,14 @@ typedef struct UX_DEVICE_CLASS_AUDIO20_AS_DATA_ENDPOINT_DESCRIPTOR_STRUCT typedef struct UX_DEVICE_CLASS_AUDIO20_CONTROL_STRUCT { - ULONG ux_device_class_audio20_control_cs_id; - ULONG ux_device_class_audio20_control_fu_id; - ULONG ux_device_class_audio20_control_sampling_frequency; - ULONG ux_device_class_audio20_control_changed; + ULONG ux_device_class_audio20_control_cs_id; + ULONG ux_device_class_audio20_control_sampling_frequency; /* Set to 0 to customize frequencies (with following two fields). */ + ULONG ux_device_class_audio20_control_sampling_frequency_cur; /* Current selected frequency. */ + UCHAR *ux_device_class_audio20_control_sampling_frequency_range; /* UAC 2.0 Layer 3 parameter block of RANGE. */ + + ULONG ux_device_class_audio20_control_fu_id; USHORT ux_device_class_audio20_control_mute[1]; SHORT ux_device_class_audio20_control_volume_min[1]; SHORT ux_device_class_audio20_control_volume_max[1]; @@ -419,8 +434,9 @@ typedef struct UX_DEVICE_CLASS_AUDIO20_CONTROL_STRUCT SHORT ux_device_class_audio20_control_volume[1]; } UX_DEVICE_CLASS_AUDIO20_CONTROL; -#define UX_DEVICE_CLASS_AUDIO20_CONTROL_MUTE_CHANGED 1 -#define UX_DEVICE_CLASS_AUDIO20_CONTROL_VOLUME_CHANGED 2 +#define UX_DEVICE_CLASS_AUDIO20_CONTROL_MUTE_CHANGED 1u +#define UX_DEVICE_CLASS_AUDIO20_CONTROL_VOLUME_CHANGED 2u +#define UX_DEVICE_CLASS_AUDIO20_CONTROL_FREQUENCY_CHANGED 4u typedef struct UX_DEVICE_CLASS_AUDIO20_CONTROL_GROUP_STRUCT { diff --git a/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h b/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h index c71165a5..8d50cf23 100644 --- a/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h +++ b/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h @@ -24,7 +24,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_cdc_acm.h PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -55,6 +55,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added write auto ZLP, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -71,6 +74,9 @@ extern "C" { #endif +/* Defined, _write is pending ZLP automatically (complete transfer) after buffer is sent. */ + +/* #define UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP */ /* Define CDC Class USB Class constants. */ #define UX_SLAVE_CLASS_CDC_ACM_CLASS 10 @@ -187,6 +193,7 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_STRUCT UCHAR *ux_device_class_cdc_acm_write_buffer; ULONG ux_device_class_cdc_acm_write_transfer_length; + ULONG ux_device_class_cdc_acm_write_host_length; ULONG ux_device_class_cdc_acm_write_requested_length; ULONG ux_device_class_cdc_acm_write_actual_length; UINT ux_device_class_cdc_acm_write_status; @@ -318,7 +325,7 @@ UINT _ux_device_class_cdc_acm_tasks_run(VOID *instance); /* Define Device CDC Class API prototypes. */ #define ux_device_class_cdc_acm_entry _ux_device_class_cdc_acm_entry -#define ux_device_class_cdc_acm_read _ux_device_class_cdc_acm_read +#define ux_device_class_cdc_acm_read _ux_device_class_cdc_acm_read #define ux_device_class_cdc_acm_write _ux_device_class_cdc_acm_write #define ux_device_class_cdc_acm_ioctl _ux_device_class_cdc_acm_ioctl #define ux_device_class_cdc_acm_write_with_callback _ux_device_class_cdc_acm_write_with_callback diff --git a/common/usbx_device_classes/inc/ux_device_class_dfu.h b/common/usbx_device_classes/inc/ux_device_class_dfu.h index f6cf1a61..20b307e7 100644 --- a/common/usbx_device_classes/inc/ux_device_class_dfu.h +++ b/common/usbx_device_classes/inc/ux_device_class_dfu.h @@ -24,7 +24,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_dfu.h PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -57,6 +57,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added macros for req types, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -90,6 +93,9 @@ extern "C" { #define UX_DEVICE_CLASS_DFU_MODE_DFU 2 +/* Device DFU bmRequestType. */ +#define UX_DEVICE_CLASS_DFU_REQTYPE_INTERFACE_SET (UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE) /* 00100001b, 0x21 */ +#define UX_DEVICE_CLASS_DFU_REQTYPE_INTERFACE_GET (UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE) /* 10100001b, 0xA1 */ /* Device DFU Requests */ diff --git a/common/usbx_device_classes/inc/ux_device_class_hid.h b/common/usbx_device_classes/inc/ux_device_class_hid.h index 47eb842d..c171db62 100644 --- a/common/usbx_device_classes/inc/ux_device_class_hid.h +++ b/common/usbx_device_classes/inc/ux_device_class_hid.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_hid.h PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -61,6 +61,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* added receiver callback, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone int out, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -121,6 +124,16 @@ extern "C" { #define UX_DEVICE_CLASS_HID_PROTOCOL_BOOT 0 #define UX_DEVICE_CLASS_HID_PROTOCOL_REPORT 1 +/* Define HID standalone read/receiver states. */ + +#define UX_DEVICE_CLASS_HID_READ_START (UX_STATE_STEP + 1) +#define UX_DEVICE_CLASS_HID_READ_WAIT (UX_STATE_STEP + 2) + +#define UX_DEVICE_CLASS_HID_RECEIVER_START (UX_STATE_STEP + 3) +#define UX_DEVICE_CLASS_HID_RECEIVER_WAIT (UX_STATE_STEP + 4) +#define UX_DEVICE_CLASS_HID_RECEIVER_ERROR (UX_STATE_STEP + 5) + + /* Define HID event info structure. */ #ifndef UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH @@ -196,10 +209,11 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT UX_MUTEX ux_device_class_hid_read_mutex; #else UCHAR *ux_device_class_hid_read_buffer; - UCHAR ux_device_class_hid_read_requested_length; - UCHAR ux_device_class_hid_read_actual_length; - UCHAR ux_device_class_hid_read_transfer_length; + ULONG ux_device_class_hid_read_requested_length; + ULONG ux_device_class_hid_read_actual_length; + ULONG ux_device_class_hid_read_transfer_length; UINT ux_device_class_hid_read_state; + UINT ux_device_class_hid_read_status; #endif #endif @@ -233,7 +247,7 @@ typedef struct UX_DEVICE_CLASS_HID_RECEIVER_STRUCT #if !defined(UX_DEVICE_STANDALONE) UX_THREAD ux_device_class_hid_receiver_thread; #else - VOID (*ux_device_class_hid_receiver_tasks_run)(struct UX_SLAVE_CLASS_HID_STRUCT *hid); + UINT (*ux_device_class_hid_receiver_tasks_run)(struct UX_SLAVE_CLASS_HID_STRUCT *hid); #endif } UX_DEVICE_CLASS_HID_RECEIVER; @@ -294,6 +308,10 @@ UINT _ux_device_class_hid_receiver_event_get(UX_SLAVE_CLASS_HID *hid, UX_DEVICE_CLASS_HID_RECEIVED_EVENT *event); UINT _ux_device_class_hid_receiver_event_free(UX_SLAVE_CLASS_HID *hid); +UINT _ux_device_class_hid_read_run(UX_SLAVE_CLASS_HID *hid, + UCHAR *buffer, ULONG requested_length, + ULONG *actual_length); +UINT _ux_device_class_hid_receiver_tasks_run(UX_SLAVE_CLASS_HID *hid); /* Define Device HID Class API prototypes. */ @@ -306,6 +324,7 @@ UINT _ux_device_class_hid_receiver_event_free(UX_SLAVE_CLASS_HID *hid); #define ux_device_class_hid_protocol_get(hid) (hid -> ux_device_class_hid_protocol) #define ux_device_class_hid_read _ux_device_class_hid_read +#define ux_device_class_hid_read_run _ux_device_class_hid_read_run #define ux_device_class_hid_receiver_initialize _ux_device_class_hid_receiver_initialize #define ux_device_class_hid_receiver_event_get _ux_device_class_hid_receiver_event_get diff --git a/common/usbx_device_classes/inc/ux_device_class_printer.h b/common/usbx_device_classes/inc/ux_device_class_printer.h index 6f29b935..a77aff51 100644 --- a/common/usbx_device_classes/inc/ux_device_class_printer.h +++ b/common/usbx_device_classes/inc/ux_device_class_printer.h @@ -24,7 +24,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_printer.h PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -42,6 +42,8 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -58,6 +60,10 @@ extern "C" { #endif +/* Defined, _write is pending ZLP automatically (complete transfer) after buffer is sent. */ + +/* #define UX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP */ + /* Define Printer Class USB Class constants. */ #define UX_DEVICE_CLASS_PRINTER_CLASS 7 diff --git a/common/usbx_device_classes/src/ux_device_class_audio10_control_process.c b/common/usbx_device_classes/src/ux_device_class_audio10_control_process.c index d2d9190f..f38e9ccd 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio10_control_process.c +++ b/common/usbx_device_classes/src/ux_device_class_audio10_control_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio10_control_process PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,6 +81,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added sampling control, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio10_control_process(UX_DEVICE_CLASS_AUDIO *audio, @@ -90,10 +93,13 @@ UINT _ux_device_class_audio10_control_process(UX_DEVICE_CLASS_AUDIO *audio, UX_SLAVE_ENDPOINT *endpoint; UX_DEVICE_CLASS_AUDIO10_CONTROL *control; UCHAR request; -UCHAR unit_id; +UCHAR request_type; +UCHAR unit_id, ep_addr; UCHAR control_selector; UCHAR channel_number; ULONG request_length; +UCHAR *desc; +ULONG sam, min, max, pos; ULONG i; @@ -103,7 +109,9 @@ ULONG i; /* Extract all necessary fields of the request. */ request = *(transfer -> ux_slave_transfer_request_setup + UX_DEVICE_CLASS_AUDIO_REQUEST_REQUEST); + request_type = *(transfer -> ux_slave_transfer_request_setup + UX_DEVICE_CLASS_AUDIO_REQUEST_REQUEST_TYPE); unit_id = *(transfer -> ux_slave_transfer_request_setup + UX_DEVICE_CLASS_AUDIO_REQUEST_ENEITY_ID); + ep_addr = *(transfer -> ux_slave_transfer_request_setup + UX_DEVICE_CLASS_AUDIO_REQUEST_ENDPOINT); control_selector = *(transfer -> ux_slave_transfer_request_setup + UX_DEVICE_CLASS_AUDIO_REQUEST_CONTROL_SELECTOR); channel_number = *(transfer -> ux_slave_transfer_request_setup + UX_DEVICE_CLASS_AUDIO_REQUEST_CHANNEL_NUMBER); request_length = _ux_utility_short_get(transfer -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH); @@ -116,8 +124,91 @@ ULONG i; /* Reset change map. */ control -> ux_device_class_audio10_control_changed = 0; + /* We handle endpoint requests. */ + if ((request_type & UX_REQUEST_TARGET) == UX_REQUEST_TARGET_ENDPOINT && + ep_addr == control -> ux_device_class_audio10_control_ep_addr) + { + + /* Handle the request. */ + switch(request) + { + case UX_DEVICE_CLASS_AUDIO10_SET_CUR: + + /* Only sampling frequency control is supported. */ + if (control_selector != UX_DEVICE_CLASS_AUDIO10_EP_SAMPLING_FREQ_CONTROL) + break; + + /* Length check. */ + if (request_length != 3) + break; + + /* If frequencies not specified, no modification accepted. */ + if (control -> ux_device_class_audio10_control_sam_freq_types == UX_NULL) + return(UX_SUCCESS); + + /* Check sampling frequency types (UAC 1.0 Format Type I : bSamFreqType ..) for MIN and MAX. */ + desc = control -> ux_device_class_audio10_control_sam_freq_types; + if (desc[0] == 0) + { + min = ((ULONG)desc[1]) | ((ULONG)desc[2] << 8) | ((ULONG)desc[3] << 16); + max = ((ULONG)desc[4]) | ((ULONG)desc[5] << 8) | ((ULONG)desc[6] << 16); + } + else + { + min = 0xFFFFFFFF; + max = 0x00000000; + for (pos = 1; + pos < (ULONG)desc[0] * 3 + 1; /* Calculate from byte, no overflow. */ + pos += 3) + { + sam = (ULONG)desc[pos + 0] | ((ULONG)desc[pos + 1] << 8) | ((ULONG)desc[pos + 2] << 16); + if (sam > max) + max = sam; + if (sam < min) + min = sam; + } + } + + /* Accept frequency any way. + * If it's not in range, round to min or max. + * If it's in range it's not rounded, application should check and round it. */ + sam = ((ULONG)transfer -> ux_slave_transfer_request_data_pointer[0] ) | + ((ULONG)transfer -> ux_slave_transfer_request_data_pointer[1] << 8) | + ((ULONG)transfer -> ux_slave_transfer_request_data_pointer[2] << 16); + if (sam < min) + sam = min; + if (sam > max) + sam = max; + control -> ux_device_class_audio10_control_sam_freq = sam; + control -> ux_device_class_audio10_control_changed = UX_DEVICE_CLASS_AUDIO20_CONTROL_FREQUENCY_CHANGED; + return(UX_SUCCESS); + + case UX_DEVICE_CLASS_AUDIO10_GET_CUR: + + /* Sampling frequency control is supported. */ + if (control_selector != UX_DEVICE_CLASS_AUDIO10_EP_SAMPLING_FREQ_CONTROL) + break; + + /* Check host buffer. */ + if (request_length < 3) + break; + + /* Put sample frequency. */ + sam = control -> ux_device_class_audio10_control_sam_freq; + transfer -> ux_slave_transfer_request_data_pointer[0] = UX_DW0(sam); + transfer -> ux_slave_transfer_request_data_pointer[1] = UX_DW1(sam); + transfer -> ux_slave_transfer_request_data_pointer[2] = UX_DW2(sam); + _ux_device_stack_transfer_request(transfer, 3, request_length); + return(UX_SUCCESS); + + default: + break; + } + } + /* We handle feature unit requests. */ - if (unit_id == control -> ux_device_class_audio10_control_fu_id) + if ((request_type & UX_REQUEST_TARGET) == UX_REQUEST_TARGET_INTERFACE && + unit_id == control -> ux_device_class_audio10_control_fu_id) { /* Handle the request. */ diff --git a/common/usbx_device_classes/src/ux_device_class_audio20_control_process.c b/common/usbx_device_classes/src/ux_device_class_audio20_control_process.c index 78f7629d..c98e5fa8 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio20_control_process.c +++ b/common/usbx_device_classes/src/ux_device_class_audio20_control_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio20_control_process PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -61,7 +61,9 @@ /* */ /* _ux_utility_short_get Get 2-byte value from buffer */ /* _ux_utility_short_put Put 2-byte value to buffer */ +/* _ux_utility_long_get Get 4-byte value from buffer */ /* _ux_utility_long_put Put 4-byte value to buffer */ +/* _ux_utility_memory_copy Copy memory */ /* _ux_device_stack_transfer_request Issue a transfer request */ /* _ux_device_stack_endpoint_stall Endpoint stall */ /* */ @@ -83,6 +85,10 @@ /* allowed answer length only */ /* when requesting range, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added support of multiple */ +/* sampling frequencies, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio20_control_process(UX_DEVICE_CLASS_AUDIO *audio, @@ -98,7 +104,9 @@ UCHAR unit_id; UCHAR control_selector; UCHAR channel_number; ULONG request_length; +ULONG data_length; ULONG i; +ULONG n_sub, pos, min, max, res, freq; /* Get instances. */ @@ -129,6 +137,62 @@ ULONG i; * The Sampling Frequency Control must support the CUR and RANGE(MIN, MAX, RES) attributes. */ + /* Sampling frequency control, SET request. */ + if ((request_type & UX_REQUEST_DIRECTION) == UX_REQUEST_OUT && + (control_selector == UX_DEVICE_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL)) + { + switch(request) + { + case UX_DEVICE_CLASS_AUDIO20_CUR: + + /* Check request parameter. */ + if (request_length != 4) + break; + + /* Check if multiple frequency supported. */ + if (control -> ux_device_class_audio20_control_sampling_frequency != 0) + break; + + /* Sanity check. */ + UX_ASSERT(control -> ux_device_class_audio20_control_sampling_frequency_range != UX_NULL); + + /* Get wNumSubRanges. */ + n_sub = _ux_utility_short_get(control -> ux_device_class_audio20_control_sampling_frequency_range); + + /* Get first RES. */ + res = _ux_utility_long_get(control -> ux_device_class_audio20_control_sampling_frequency_range + 2 + 8); + + /* Check if it's fixed single frequency. */ + if (n_sub <= 1 && res == 0) + break; + + /* Get frequency to set. */ + freq = _ux_utility_long_get(transfer -> ux_slave_transfer_request_data_pointer); + + /* Check if frequency to set is inside range. */ + for (pos = 2; pos < (2 + n_sub * 12); pos += 12) + { + min = _ux_utility_long_get(control -> ux_device_class_audio20_control_sampling_frequency_range + pos); + max = _ux_utility_long_get(control -> ux_device_class_audio20_control_sampling_frequency_range + pos + 4); + if (freq >= min && freq <= max) + { + + /* SET_CUR is accepted. */ + if (control -> ux_device_class_audio20_control_sampling_frequency_cur != freq) + { + control -> ux_device_class_audio20_control_sampling_frequency_cur = freq; + control -> ux_device_class_audio20_control_changed = UX_DEVICE_CLASS_AUDIO20_CONTROL_FREQUENCY_CHANGED; + } + return(UX_SUCCESS); + } + } + break; + + default: + break; + } + } + /* We just support sampling frequency control, GET request. */ if ((request_type & UX_REQUEST_DIRECTION) == UX_REQUEST_IN && (control_selector == UX_DEVICE_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL)) @@ -142,10 +206,11 @@ ULONG i; if (request_length < 4) break; - /* Send sampling frequency. - * We only support one here (from extension data). - */ - _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer, control -> ux_device_class_audio20_control_sampling_frequency); + /* Send sampling frequency. */ + if (control -> ux_device_class_audio20_control_sampling_frequency) + _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer, control -> ux_device_class_audio20_control_sampling_frequency); + else + _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer, control -> ux_device_class_audio20_control_sampling_frequency_cur); _ux_device_stack_transfer_request(transfer, 4, request_length); return(UX_SUCCESS); @@ -155,18 +220,45 @@ ULONG i; if (request_length < 2) break; - /* Send range parameters. - * We only support one here (from extension data). - * wNumSubRanges : 1 - * dMIN : sampling frequency - * dMAX : sampling frequency - * dRES : 1 - */ - _ux_utility_short_put(transfer -> ux_slave_transfer_request_data_pointer, 1); - _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer + 2, control -> ux_device_class_audio20_control_sampling_frequency); - _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer + 6, control -> ux_device_class_audio20_control_sampling_frequency); - _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer + 10, 0); - _ux_device_stack_transfer_request(transfer, UX_MIN(14, request_length), request_length); + if (control -> ux_device_class_audio20_control_sampling_frequency == 0) + { + + /* Send range parameters, RANGE is customized. */ + UX_ASSERT(control -> ux_device_class_audio20_control_sampling_frequency_range != UX_NULL); + + /* Get wNumSubRanges. */ + n_sub = _ux_utility_short_get(control -> ux_device_class_audio20_control_sampling_frequency_range); + UX_ASSERT(n_sub > 0); + + /* Calculate length, n_sub is 16-bit width, result not overflows ULONG. */ + data_length = 2 + n_sub * 12; + UX_ASSERT(data_length <= UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH); + + /* Copy data. */ + data_length = UX_MIN(data_length, request_length); + _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer, + control -> ux_device_class_audio20_control_sampling_frequency_range, + data_length); /* Use case of memcpy is verified. */ + } + else + { + + /* Send range parameters. + * We only support one here (from extension data). + * wNumSubRanges : 1 + * dMIN : sampling frequency + * dMAX : sampling frequency + * dRES : 1 + */ + _ux_utility_short_put(transfer -> ux_slave_transfer_request_data_pointer, 1); + _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer + 2, control -> ux_device_class_audio20_control_sampling_frequency); + _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer + 6, control -> ux_device_class_audio20_control_sampling_frequency); + _ux_utility_long_put(transfer -> ux_slave_transfer_request_data_pointer + 10, 0); + data_length = UX_MIN(14, request_length); + } + + /* Send data. */ + _ux_device_stack_transfer_request(transfer, data_length, request_length); return(UX_SUCCESS); default: diff --git a/common/usbx_device_classes/src/ux_device_class_audio_activate.c b/common/usbx_device_classes/src/ux_device_class_audio_activate.c index 9ef36699..53163cfe 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_activate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -65,53 +65,67 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added interrupt support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_activate(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *audio_interface; UX_SLAVE_INTERFACE *control_interface; UX_SLAVE_INTERFACE *stream_interface; UX_DEVICE_CLASS_AUDIO *audio; UX_DEVICE_CLASS_AUDIO_STREAM *stream; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *audio_class; ULONG stream_index; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + audio_class = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - audio = (UX_DEVICE_CLASS_AUDIO *) class -> ux_slave_class_instance; + audio = (UX_DEVICE_CLASS_AUDIO *) audio_class -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + audio_interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Get the device instance. */ device = &_ux_system_slave -> ux_system_slave_device; audio -> ux_device_class_audio_device = device; /* We only support audio interface here. */ - if (interface -> ux_slave_interface_descriptor.bInterfaceClass != UX_DEVICE_CLASS_AUDIO_CLASS) + if (audio_interface -> ux_slave_interface_descriptor.bInterfaceClass != UX_DEVICE_CLASS_AUDIO_CLASS) return(UX_NO_CLASS_MATCH); /* It's control interface? */ - if (interface -> ux_slave_interface_descriptor.bInterfaceSubClass == UX_DEVICE_CLASS_AUDIO_SUBCLASS_CONTROL) + if (audio_interface -> ux_slave_interface_descriptor.bInterfaceSubClass == UX_DEVICE_CLASS_AUDIO_SUBCLASS_CONTROL) { /* Store the interface in the class instance. */ - audio -> ux_device_class_audio_interface = interface; + audio -> ux_device_class_audio_interface = audio_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)audio; + audio_interface -> ux_slave_interface_class_instance = (VOID *)audio; + +#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) + + /* Find interrupt endpoint (only endpoint in this AC interface). */ + audio -> ux_device_class_audio_interrupt = audio_interface -> ux_slave_interface_first_endpoint; + audio -> ux_device_class_audio_status_queued = 0; + audio -> ux_device_class_audio_status_head = audio -> ux_device_class_audio_status_queue; + audio -> ux_device_class_audio_status_tail = audio -> ux_device_class_audio_status_queue; +#endif } else { /* It's streaming interface. */ - stream_interface = interface; + stream_interface = audio_interface; /* Separate driver for each interface (IAD not used)? */ if (audio -> ux_device_class_audio_interface == UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_audio_change.c b/common/usbx_device_classes/src/ux_device_class_audio_change.c index c2389e32..35d4a3ae 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_change.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_change.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_change PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,12 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* rx full packet for */ +/* feedback, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_change(UX_SLAVE_CLASS_COMMAND *command) @@ -82,8 +88,8 @@ UINT _ux_device_class_audio_change(UX_SLAVE_CLASS_COMMAND *command) UX_DEVICE_CLASS_AUDIO *audio; UX_DEVICE_CLASS_AUDIO_STREAM *stream; -UX_SLAVE_CLASS *class; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_CLASS *class_ptr; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_ENDPOINT *endpoint; UCHAR *frame_buffer; ULONG stream_index; @@ -91,20 +97,20 @@ ULONG endpoint_dir; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - audio = (UX_DEVICE_CLASS_AUDIO *) class -> ux_slave_class_instance; + audio = (UX_DEVICE_CLASS_AUDIO *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Get the interface number (base 0). */ if (audio -> ux_device_class_audio_interface) { /* If IAD used, calculate stream index based on interface number. */ - stream_index = interface -> ux_slave_interface_descriptor.bInterfaceNumber; + stream_index = interface_ptr -> ux_slave_interface_descriptor.bInterfaceNumber; stream_index -= audio -> ux_device_class_audio_interface -> ux_slave_interface_descriptor.bInterfaceNumber; stream_index --; } @@ -117,16 +123,16 @@ ULONG endpoint_dir; stream = &audio -> ux_device_class_audio_streams[stream_index]; /* Update the interface. */ - stream -> ux_device_class_audio_stream_interface = interface; + stream -> ux_device_class_audio_stream_interface = interface_ptr; /* If the interface to mount has a non zero alternate setting, the class is really active with the endpoints active. If the interface reverts to alternate setting 0, it needs to have the pending transactions terminated. */ - if (interface -> ux_slave_interface_descriptor.bAlternateSetting != 0) + if (interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting != 0) { /* Locate the endpoints. ISO IN(write)/OUT(read) for Streaming Interface. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all endpoints. */ #if defined(UX_DEVICE_STANDALONE) @@ -187,9 +193,12 @@ ULONG endpoint_dir; return(UX_MEMORY_INSUFFICIENT); } - /* Set request length. */ + /* Set request length, uses full packet for OUT to avoid possible overflow. */ endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_requested_length = - (_ux_system_slave -> ux_system_slave_speed == UX_HIGH_SPEED_DEVICE) ? 4 : 3; + endpoint_dir == UX_ENDPOINT_OUT ? + endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_transfer_length : + ((_ux_system_slave -> ux_system_slave_speed == UX_HIGH_SPEED_DEVICE) ? + UX_FEEDBACK_SIZE_HIGH_SPEED : UX_FEEDBACK_SIZE_FULL_SPEED); /* Save it. */ stream -> ux_device_class_audio_stream_feedback = endpoint; @@ -259,7 +268,7 @@ ULONG endpoint_dir; /* Invoke stream change callback. */ if (stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_change) - stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_change(stream, interface -> ux_slave_interface_descriptor.bAlternateSetting); + stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_change(stream, interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting); /* Return completion status. */ return(UX_SUCCESS); diff --git a/common/usbx_device_classes/src/ux_device_class_audio_control_request.c b/common/usbx_device_classes/src/ux_device_class_audio_control_request.c index 7ee5bb93..8da8a1b2 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_control_request.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_control_request PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -74,15 +78,15 @@ UINT _ux_device_class_audio_control_request(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_DEVICE_CLASS_AUDIO *audio; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the audio instance from this class container. */ - audio = (UX_DEVICE_CLASS_AUDIO *) class -> ux_slave_class_instance; + audio = (UX_DEVICE_CLASS_AUDIO *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; diff --git a/common/usbx_device_classes/src/ux_device_class_audio_deactivate.c b/common/usbx_device_classes/src/ux_device_class_audio_deactivate.c index 8c6460b9..5e6bba98 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_deactivate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_deactivate(UX_SLAVE_CLASS_COMMAND *command) @@ -75,15 +79,15 @@ UINT _ux_device_class_audio_deactivate(UX_SLAVE_CLASS_COMMAND *command) UX_DEVICE_CLASS_AUDIO *audio; UX_DEVICE_CLASS_AUDIO_STREAM *stream; UX_SLAVE_ENDPOINT *endpoint; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UINT i; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - audio = (UX_DEVICE_CLASS_AUDIO *) class -> ux_slave_class_instance; + audio = (UX_DEVICE_CLASS_AUDIO *) class_ptr -> ux_slave_class_instance; /* Stop pending streams. */ stream = audio -> ux_device_class_audio_streams; diff --git a/common/usbx_device_classes/src/ux_device_class_audio_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_entry.c index 39cd9082..cc2e1643 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_entry.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_entry.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_entry PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,6 +74,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* returned request status, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_entry(UX_SLAVE_CLASS_COMMAND *command) @@ -146,10 +149,7 @@ UINT status; case UX_SLAVE_CLASS_COMMAND_REQUEST: /* The request command is used when the host sends a command on the control endpoint. */ - _ux_device_class_audio_control_request(command); - - /* Return the completion status. */ - return(UX_SUCCESS); + return _ux_device_class_audio_control_request(command); default: diff --git a/common/usbx_device_classes/src/ux_device_class_audio_initialize.c b/common/usbx_device_classes/src/ux_device_class_audio_initialize.c index 88e6fef2..4887494f 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added interrupt support, */ +/* refined internal logic, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -94,14 +98,14 @@ UX_DEVICE_CLASS_AUDIO *audio; UX_DEVICE_CLASS_AUDIO_PARAMETER *audio_parameter; UX_DEVICE_CLASS_AUDIO_STREAM *stream; UX_DEVICE_CLASS_AUDIO_STREAM_PARAMETER *stream_parameter; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *audio_class; ULONG memory_size; ULONG streams_size; ULONG i; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + audio_class = command -> ux_slave_class_command_class_ptr; /* Get the pointer to the application parameters for the audio class. */ audio_parameter = (UX_DEVICE_CLASS_AUDIO_PARAMETER *)command -> ux_slave_class_command_parameter; @@ -129,6 +133,94 @@ ULONG i; if (audio == UX_NULL) return(UX_MEMORY_INSUFFICIENT); +#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) + + /* Create resources for interrupt endpoint support. */ + + /* Get status data size. */ + audio -> ux_device_class_audio_status_size = + audio_parameter -> ux_device_class_audio_parameter_status_size; + + /* Calculate queue size in bytes. */ + if (UX_OVERFLOW_CHECK_MULV_ULONG( + audio_parameter -> ux_device_class_audio_parameter_status_queue_size, + audio_parameter -> ux_device_class_audio_parameter_status_size)) + { + _ux_utility_memory_free(audio); + return(UX_MATH_OVERFLOW); + } + memory_size = audio_parameter -> ux_device_class_audio_parameter_status_queue_size * + audio_parameter -> ux_device_class_audio_parameter_status_size; + audio -> ux_device_class_audio_status_queue_bytes = memory_size; + +#if defined(UX_DEVICE_STANDALONE) +#else + if (UX_OVERFLOW_CHECK_ADD_ULONG(memory_size, UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE)) + { + _ux_utility_memory_free(audio); + return(UX_MATH_OVERFLOW); + } + memory_size += UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE; + + audio_class -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, memory_size); + if (audio_class -> ux_slave_class_thread_stack == UX_NULL) + status = UX_MEMORY_INSUFFICIENT; + + if (status == UX_SUCCESS) + { + status = _ux_device_thread_create(&audio_class -> ux_slave_class_thread, + "ux_device_class_audio_status_thread", + _ux_device_class_audio_interrupt_thread_entry, (ULONG)(ALIGN_TYPE)audio, + audio_class -> ux_slave_class_thread_stack, + UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE, + UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, + UX_NO_TIME_SLICE, UX_DONT_START); + if (status == UX_SUCCESS) + { + UX_THREAD_EXTENSION_PTR_SET(&(audio_class -> ux_slave_class_thread), audio) + + status = _ux_device_semaphore_create(&audio -> ux_device_class_audio_status_semaphore, + "ux_device_class_audio_status_semaphore", 0); + if (status == UX_SUCCESS) + { + status = _ux_device_mutex_create(&audio -> ux_device_class_audio_status_mutex, + "ux_device_class_audio_status_mutex"); + if (status != UX_SUCCESS) + status = UX_MUTEX_ERROR; + + if (status != UX_SUCCESS) + _ux_device_semaphore_delete(&audio -> ux_device_class_audio_status_semaphore); + } + else + status = UX_SEMAPHORE_ERROR; + + if (status != UX_SUCCESS) + _ux_device_thread_delete(&audio_class -> ux_slave_class_thread); + } + else + status = UX_THREAD_ERROR; + + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(audio_class -> ux_slave_class_thread_stack); + audio_class -> ux_slave_class_thread_stack = UX_NULL; + } + } + + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(audio); + return(status); + } + + /* Status queue locates right after status stack. */ + audio -> ux_device_class_audio_status_queue = + (UCHAR *)audio_class -> ux_slave_class_thread_stack + + UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE; +#endif + +#endif + /* Save streams. */ if (streams_size) { @@ -178,7 +270,7 @@ ULONG i; /* Create memory block for streaming thread stack in addition. */ if (stream_parameter -> ux_device_class_audio_stream_parameter_thread_stack_size == 0) - memory_size = UX_THREAD_STACK_SIZE; + memory_size = UX_DEVICE_CLASS_AUDIO_FEEDBACK_THREAD_STACK_SIZE; else memory_size = stream_parameter -> ux_device_class_audio_stream_parameter_thread_stack_size; stream -> ux_device_class_audio_stream_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, memory_size); @@ -199,7 +291,11 @@ ULONG i; /* Check for successful allocation. */ if (status != UX_SUCCESS) + { + _ux_utility_memory_free(stream -> ux_device_class_audio_stream_thread_stack); + stream -> ux_device_class_audio_stream_thread_stack = UX_NULL; break; + } UX_THREAD_EXTENSION_PTR_SET(&(stream -> ux_device_class_audio_stream_thread), stream) @@ -232,7 +328,11 @@ ULONG i; /* Check for successful allocation. */ if (status != UX_SUCCESS) + { + _ux_utility_memory_free(stream -> ux_device_class_audio_stream_feedback_thread_stack); + stream -> ux_device_class_audio_stream_feedback_thread_stack = UX_NULL; break; + } UX_THREAD_EXTENSION_PTR_SET(&(stream -> ux_device_class_audio_stream_feedback_thread), stream) } @@ -255,10 +355,10 @@ ULONG i; { /* Save the address of the Audio instance inside the Audio container. */ - class -> ux_slave_class_instance = (VOID *) audio; + audio_class -> ux_slave_class_instance = (VOID *) audio; /* Link to class instance. */ - audio -> ux_device_class_audio_class = class; + audio -> ux_device_class_audio_class = audio_class; /* Save callbacks. */ _ux_utility_memory_copy(&audio -> ux_device_class_audio_callbacks, @@ -277,19 +377,34 @@ ULONG i; for (i = 0; i < audio -> ux_device_class_audio_streams_nb; i ++) { #if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) - if (stream -> ux_device_class_audio_stream_feedback_thread.tx_thread_id) - _ux_utility_thread_delete(&stream -> ux_device_class_audio_stream_feedback_thread); if (stream -> ux_device_class_audio_stream_feedback_thread_stack) + { + _ux_device_thread_delete(&stream -> ux_device_class_audio_stream_feedback_thread); _ux_utility_memory_free(stream -> ux_device_class_audio_stream_feedback_thread_stack); + } #endif - if (stream -> ux_device_class_audio_stream_thread.tx_thread_id) - _ux_device_thread_delete(&stream -> ux_device_class_audio_stream_thread); if (stream -> ux_device_class_audio_stream_thread_stack) + { + _ux_device_thread_delete(&stream -> ux_device_class_audio_stream_thread); _ux_utility_memory_free(stream -> ux_device_class_audio_stream_thread_stack); + } if (stream -> ux_device_class_audio_stream_buffer) _ux_utility_memory_free(stream -> ux_device_class_audio_stream_buffer); stream ++; } +#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) +#if defined(UX_DEVICE_STANDALONE) +#else + if (audio_class -> ux_slave_class_thread_stack) + { + _ux_device_thread_delete(&audio_class -> ux_slave_class_thread); + _ux_utility_memory_free(audio_class -> ux_slave_class_thread_stack); + + _ux_device_semaphore_delete(&audio -> ux_device_class_audio_status_semaphore); + _ux_device_mutex_delete(&audio -> ux_device_class_audio_status_mutex); + } +#endif +#endif _ux_utility_memory_free(audio); return(status); diff --git a/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c new file mode 100644 index 00000000..72c51fba --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c @@ -0,0 +1,173 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_audio.h" +#include "ux_device_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_audio_interrupt_send PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function queues audio interrupt data. */ +/* */ +/* Note the interrupt data size is predefined on initialization: */ +/* - for Audio 1.0 interrupt status word is 2 bytes */ +/* - for Audio 2.0 interrupt data message is 6 bytes */ +/* */ +/* INPUT */ +/* */ +/* audio Address of audio instance */ +/* int_data Interrupt data (2 or 6 bytes) */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHAR *int_data) +{ +#if !defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) + UX_PARAMETER_NOT_USED(audio); + UX_PARAMETER_NOT_USED(int_data); + return(UX_FUNCTION_NOT_SUPPORTED); +#else +#if defined(UX_DEVICE_STANDALONE) + UX_PARAMETER_NOT_USED(audio); + UX_PARAMETER_NOT_USED(int_data); + return(UX_FUNCTION_NOT_SUPPORTED); +#else + +UX_SLAVE_DEVICE *device; +UX_SLAVE_ENDPOINT *endpoint; +UCHAR *buff, *end; +ULONG size; +ULONG i; + + /* Get the pointer to the device. */ + device = &_ux_system_slave -> ux_system_slave_device; + + /* As long as the device is in the CONFIGURED state. */ + if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) + { + + /* Cannot proceed with command, the interface is down. */ + return(UX_CONFIGURATION_HANDLE_UNKNOWN); + } + + /* Check if endpoint is available. */ + endpoint = audio -> ux_device_class_audio_interrupt; + if (endpoint == UX_NULL) + return(UX_FUNCTION_NOT_SUPPORTED); + + /* Get interrupt data size. */ + size = audio -> ux_device_class_audio_status_size; + + /* Protect queue status. */ + _ux_device_mutex_on(&audio -> ux_device_class_audio_status_mutex); + + /* Check if data exist. */ + buff = audio -> ux_device_class_audio_status_tail; + end = audio -> ux_device_class_audio_status_queue + audio -> ux_device_class_audio_status_queue_bytes; + for (i = 0; i < audio -> ux_device_class_audio_status_queued; i += size) + { + + /* Check if data match. */ + if (_ux_utility_memory_compare(buff, int_data, size) == UX_SUCCESS) + { + + /* Already queued. */ + _ux_device_mutex_off(&audio -> ux_device_class_audio_status_mutex); + return(UX_SUCCESS); + } + + /* Next saved data. */ + buff += size; + if (buff >= end) + buff = audio -> ux_device_class_audio_status_queue; + } + + /* No data match before buff achieve head. */ + UX_ASSERT(buff == audio -> ux_device_class_audio_status_head); + + /* If no free space, return busy (pending). */ + if (audio -> ux_device_class_audio_status_queued >= + audio -> ux_device_class_audio_status_queue_bytes) + { + + /* No queue space, pending. */ + _ux_device_mutex_off(&audio -> ux_device_class_audio_status_mutex); + return(UX_BUSY); + } + + /* Copy data to head. */ + _ux_utility_memory_copy(buff, int_data, size); /* Use case of memcpy is verified. */ + + /* Move head. */ + buff += size; + if (buff >= end) + buff = audio -> ux_device_class_audio_status_queue; + audio -> ux_device_class_audio_status_head = buff; + + /* Add to queued bytes. */ + audio -> ux_device_class_audio_status_queued += size; + + /* Unprotect queue status. */ + _ux_device_mutex_off(&audio -> ux_device_class_audio_status_mutex); + + /* Notify status thread to issue interrupt request. */ + _ux_device_semaphore_put(&audio -> ux_device_class_audio_status_semaphore); + + /* Resume interrupt thread. */ + _ux_device_thread_resume(&audio -> ux_device_class_audio_class -> ux_slave_class_thread); + + /* Return success. */ + return(UX_SUCCESS); +#endif +#endif +} diff --git a/common/usbx_device_classes/src/ux_device_class_audio_interrupt_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_thread_entry.c new file mode 100644 index 00000000..ba223e0b --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_thread_entry.c @@ -0,0 +1,157 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_audio.h" +#include "ux_device_stack.h" + + +#if !defined(UX_DEVICE_STANDALONE) && defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_audio_interrupt_thread_entry PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is thread of INTERRUPT IN from the Audio class. */ +/* */ +/* It's for RTOS mode. */ +/* */ +/* INPUT */ +/* */ +/* audio Address of audio instance */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _ux_system_error_handler System error trap */ +/* _ux_device_thread_suspend Suspend thread used */ +/* _ux_device_stack_transfer_request Issue transfer request */ +/* _ux_utility_memory_copy Copy data */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +VOID _ux_device_class_audio_interrupt_thread_entry(ULONG audio_inst) +{ + +UINT status; +UX_DEVICE_CLASS_AUDIO *audio; +UX_SLAVE_DEVICE *device; +UX_SLAVE_ENDPOINT *endpoint; +UX_SLAVE_TRANSFER *transfer; +ULONG size; +UCHAR *buff; + + + /* Get Audio class instance. */ + UX_THREAD_EXTENSION_PTR_GET(audio, UX_DEVICE_CLASS_AUDIO, audio_inst) + + /* Get stack device instance. */ + device = audio -> ux_device_class_audio_device; + + /* This thread runs forever but can be suspended or resumed. */ + while(1) + { + while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED) + { + + /* Get endpoint instance. */ + endpoint = audio -> ux_device_class_audio_interrupt; + + /* Endpoint not available, maybe it's alternate setting 0. */ + if (endpoint == UX_NULL) + break; + + /* Get transfer instance. */ + transfer = &endpoint -> ux_slave_endpoint_transfer_request; + + /* Get semaphore before start transfer. */ + status = _ux_device_semaphore_get(&audio -> ux_device_class_audio_status_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + + /* Error notification! */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_SEMAPHORE_ERROR); + break; + } + + /* Get interrupt data size. */ + size = audio -> ux_device_class_audio_status_size; + UX_ASSERT(size <= transfer -> ux_slave_transfer_request_transfer_length); + + /* Copy data in tail. */ + buff = audio -> ux_device_class_audio_status_tail; + _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer, + buff, size); /* Use case of memcpy is verified. */ + + /* Start frame transfer anyway. */ + status = _ux_device_stack_transfer_request(transfer, size, size); + + /* Check transfer status. */ + if (status != UX_SUCCESS) + { + + /* Error notification! */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR); + break; + } + + /* Calculate next tail. */ + buff += size; + if (buff >= (audio -> ux_device_class_audio_status_queue + audio -> ux_device_class_audio_status_queue_bytes)) + buff = audio -> ux_device_class_audio_status_queue; + + /* Update queue status. */ + _ux_device_mutex_on(&audio -> ux_device_class_audio_status_mutex); + audio -> ux_device_class_audio_status_tail = buff; + audio -> ux_device_class_audio_status_queued -= size; + _ux_device_mutex_off(&audio -> ux_device_class_audio_status_mutex); + + } /* while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED) */ + + /* We need to suspend ourselves. We will be resumed by the device enumeration module or when a change of alternate setting happens. */ + _ux_device_thread_suspend(&audio -> ux_device_class_audio_class -> ux_slave_class_thread); + } +} +#endif diff --git a/common/usbx_device_classes/src/ux_device_class_audio_unitialize.c b/common/usbx_device_classes/src/ux_device_class_audio_unitialize.c index ca1da22d..495e9a8e 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio_unitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_audio_unitialize.c @@ -82,15 +82,15 @@ UINT _ux_device_class_audio_uninitialize(UX_SLAVE_CLASS_COMMAND *command) UX_DEVICE_CLASS_AUDIO *audio; UX_DEVICE_CLASS_AUDIO_STREAM *stream; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *audio_class; ULONG i; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + audio_class = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - audio = (UX_DEVICE_CLASS_AUDIO *) class -> ux_slave_class_instance; + audio = (UX_DEVICE_CLASS_AUDIO *) audio_class -> ux_slave_class_instance; /* Sanity check. */ if (audio != UX_NULL) @@ -114,9 +114,20 @@ ULONG i; _ux_utility_memory_free(stream -> ux_device_class_audio_stream_buffer); /* Next stream instance. */ - stream++; + stream ++; } +#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) +#if !defined(UX_DEVICE_STANDALONE) + _ux_device_thread_delete(&audio_class -> ux_slave_class_thread); + _ux_utility_memory_free(audio_class -> ux_slave_class_thread_stack); + + _ux_device_semaphore_delete(&audio -> ux_device_class_audio_status_semaphore); + _ux_device_mutex_delete(&audio -> ux_device_class_audio_status_mutex); +#else +#endif +#endif + /* Free the audio instance with controls and streams. */ _ux_utility_memory_free(audio); } diff --git a/common/usbx_device_classes/src/ux_device_class_ccid_activate.c b/common/usbx_device_classes/src/ux_device_class_ccid_activate.c index 096efec6..0568a7ef 100644 --- a/common/usbx_device_classes/src/ux_device_class_ccid_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_ccid_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_ccid_activate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -63,14 +63,18 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_ccid_activate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; -UX_DEVICE_CLASS_CCID *ccid; +UX_SLAVE_INTERFACE *ccid_interface; UX_SLAVE_CLASS *ccid_class; +UX_DEVICE_CLASS_CCID *ccid; UX_SLAVE_ENDPOINT *endpoint; ULONG endpoint_type; UINT i; @@ -82,17 +86,17 @@ UINT i; ccid = (UX_DEVICE_CLASS_CCID *) ccid_class -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + ccid_interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)ccid; + ccid_interface -> ux_slave_interface_class_instance = (VOID *)ccid; /* Now the opposite, store the interface in the class instance. */ - ccid -> ux_device_class_ccid_interface = interface; + ccid -> ux_device_class_ccid_interface = ccid_interface; /* Save endpoints. */ ccid -> ux_device_class_ccid_endpoint_notify = UX_NULL; - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = ccid_interface -> ux_slave_interface_first_endpoint; while(endpoint) { endpoint_type = endpoint -> ux_slave_endpoint_descriptor.bmAttributes; diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_activate.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_activate.c index 50791fd1..e06f7349 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_activate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -65,29 +65,33 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_activate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_CDC_ACM *cdc_acm; -UX_SLAVE_CLASS *class; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class -> ux_slave_class_instance; + cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)cdc_acm; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)cdc_acm; /* Now the opposite, store the interface in the class instance. */ - cdc_acm -> ux_slave_class_cdc_acm_interface = interface; + cdc_acm -> ux_slave_class_cdc_acm_interface = interface_ptr; /* If there is a activate function call it. */ if (cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_instance_activate != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c index 81b591cd..36d1acaf 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_bulkin_thread PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -87,6 +87,11 @@ /* used whole buffer for write,*/ /* refined macros names, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added auto ZLP support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_device_class_cdc_acm_bulkin_thread(ULONG cdc_acm_class) @@ -95,11 +100,12 @@ VOID _ux_device_class_cdc_acm_bulkin_thread(ULONG cdc_acm_class) UX_SLAVE_CLASS_CDC_ACM *cdc_acm; UX_SLAVE_DEVICE *device; UX_SLAVE_ENDPOINT *endpoint; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; UINT status; ULONG actual_flags; ULONG transfer_length; +ULONG host_length; ULONG total_length; ULONG sent_length; @@ -111,10 +117,10 @@ ULONG sent_length; device = &_ux_system_slave -> ux_system_slave_device; /* This is the first time we are activated. We need the interface to the class. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) @@ -162,6 +168,7 @@ ULONG sent_length; { /* We should send the total length. But we may have a case of ZLP. */ + host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; while (total_length) { @@ -172,17 +179,29 @@ ULONG sent_length; transfer_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; else + { /* We can send everything. */ transfer_length = total_length; +#if !defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP) + + /* Assume expected length matches length to send. */ + host_length = total_length; +#else + + /* Assume expected more to let stack append ZLP if needed. */ + host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; +#endif + } + /* Copy the payload locally. */ _ux_utility_memory_copy (transfer_request -> ux_slave_transfer_request_data_pointer, cdc_acm -> ux_slave_class_cdc_acm_callback_current_data_pointer, transfer_length); /* Use case of memcpy is verified. */ /* Send the acm payload to the host. */ - status = _ux_device_stack_transfer_request(transfer_request, transfer_length, transfer_length); + status = _ux_device_stack_transfer_request(transfer_request, transfer_length, host_length); /* Check the status. */ if (status != UX_SUCCESS) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c index d904a7b6..736cff86 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_bulkout_thread PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,6 +79,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_device_class_cdc_acm_bulkout_thread(ULONG cdc_acm_class) @@ -87,7 +91,7 @@ VOID _ux_device_class_cdc_acm_bulkout_thread(ULONG cdc_acm_class) UX_SLAVE_CLASS_CDC_ACM *cdc_acm; UX_SLAVE_DEVICE *device; UX_SLAVE_ENDPOINT *endpoint; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; UINT status; @@ -98,10 +102,10 @@ UINT status; device = &_ux_system_slave -> ux_system_slave_device; /* This is the first time we are activated. We need the interface to the class. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if OUT we have the correct endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_OUT) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_control_request.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_control_request.c index 5fd1d1c5..661258a5 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_control_request.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_control_request PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,12 +67,16 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_control_request(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_CDC_ACM *cdc_acm; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; ULONG request; @@ -81,10 +85,10 @@ ULONG request_length; ULONG transmit_length; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class -> ux_slave_class_instance; + cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_deactivate.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_deactivate.c index eeafcb64..19624b42 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_deactivate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,28 +67,32 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_deactivate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_CDC_ACM *cdc_acm; UX_SLAVE_ENDPOINT *endpoint_in; UX_SLAVE_ENDPOINT *endpoint_out; -UX_SLAVE_CLASS *class; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class -> ux_slave_class_instance; + cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class_ptr -> ux_slave_class_instance; /* We need the interface to the class. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint_in = interface -> ux_slave_interface_first_endpoint; + endpoint_in = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c index 7d39b0b0..3b207d9a 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -83,6 +83,10 @@ /* resulting in version 6.1.10 */ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -90,13 +94,13 @@ UINT _ux_device_class_cdc_acm_initialize(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_CLASS_CDC_ACM *cdc_acm; UX_SLAVE_CLASS_CDC_ACM_PARAMETER *cdc_acm_parameter; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; #if !defined(UX_DEVICE_STANDALONE) UINT status; #endif /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Create an instance of the device cdc_acm class. */ cdc_acm = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_CDC_ACM)); @@ -106,7 +110,7 @@ UINT status; return(UX_MEMORY_INSUFFICIENT); /* Save the address of the CDC instance inside the CDC container. */ - class -> ux_slave_class_instance = (VOID *) cdc_acm; + class_ptr -> ux_slave_class_instance = (VOID *) cdc_acm; /* Get the pointer to the application parameters for the cdc_acm class. */ cdc_acm_parameter = command -> ux_slave_class_command_parameter; @@ -148,7 +152,7 @@ UINT status; /* Return fatal error. */ return(UX_MUTEX_ERROR); } - + #endif /* Update the line coding fields with default values. */ @@ -162,7 +166,7 @@ UINT status; #if defined(UX_DEVICE_STANDALONE) /* Set task function. */ - class -> ux_slave_class_task_function = _ux_device_class_cdc_acm_tasks_run; + class_ptr -> ux_slave_class_task_function = _ux_device_class_cdc_acm_tasks_run; #else /* We need to prepare the 2 threads for sending and receiving. */ diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_ioctl.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_ioctl.c index 4ac932cc..e8503fee 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_ioctl.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_ioctl.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_ioctl PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -92,6 +92,10 @@ /* added standalone support, */ /* fixed aborting return code, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_ioctl(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, ULONG ioctl_function, @@ -105,7 +109,7 @@ UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER *line_state; UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER *callback; #endif UX_SLAVE_ENDPOINT *endpoint; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; /* Let's be optimist ! */ @@ -168,10 +172,10 @@ UX_SLAVE_TRANSFER *transfer_request; case UX_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE: /* Get the interface from the instance. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* What direction ? */ switch( (ULONG) (ALIGN_TYPE) parameter) @@ -208,7 +212,7 @@ UX_SLAVE_TRANSFER *transfer_request; /* Get the transfer request associated with the endpoint. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; - + #if defined(UX_DEVICE_STANDALONE) /* Abort the transfer. */ @@ -225,7 +229,7 @@ UX_SLAVE_TRANSFER *transfer_request; /* Abort the transfer. */ _ux_device_stack_transfer_abort(transfer_request, UX_ABORTED); - + } #endif break; @@ -234,10 +238,10 @@ UX_SLAVE_TRANSFER *transfer_request; case UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_WRITE_TIMEOUT: /* Get the interface from the instance. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* If it's reading timeout but endpoint is OUT, it should be the next one. */ if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != @@ -269,7 +273,7 @@ UX_SLAVE_TRANSFER *transfer_request; /* Properly cast the parameter pointer. */ callback = (UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER *) parameter; - + /* Save the callback function for write. */ cdc_acm -> ux_device_class_cdc_acm_write_callback = callback -> ux_device_class_cdc_acm_parameter_write_callback; @@ -296,10 +300,10 @@ UX_SLAVE_TRANSFER *transfer_request; { /* Get the interface from the instance. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Get the transfer request associated with the endpoint. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; @@ -336,7 +340,7 @@ UX_SLAVE_TRANSFER *transfer_request; break; #endif - + default: /* Error trap. */ diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c index d9bc65f9..6b8e0cd1 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_read PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -86,6 +86,10 @@ /* resulting in version 6.1.10 */ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_read(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer, @@ -94,7 +98,7 @@ UINT _ux_device_class_cdc_acm_read(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffe UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; UINT status= UX_SUCCESS; ULONG local_requested_length; @@ -130,10 +134,10 @@ ULONG local_requested_length; } /* This is the first time we are activated. We need the interface to the class. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if OUT we have the correct endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_OUT) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c index 0c156de5..63c4e8f6 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c @@ -40,7 +40,7 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_tasks_run PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,11 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* supported write auto ZLP, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_tasks_run(VOID *instance) @@ -125,16 +130,16 @@ static inline VOID _ux_device_class_cdc_acm_transmission_read_run(UX_SLAVE_CLASS UINT status; UX_SLAVE_ENDPOINT *endpoint; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; ULONG max_transfer_length; /* Get the interface to the class. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if OUT we have the correct endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_OUT) @@ -205,7 +210,7 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS UINT status; UX_SLAVE_ENDPOINT *endpoint; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; UINT zlp = UX_FALSE; ULONG requested_length; @@ -216,10 +221,10 @@ ULONG requested_length; return; /* We need the interface to the class. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) @@ -239,6 +244,7 @@ ULONG requested_length; cdc_acm -> ux_device_class_cdc_acm_write_state = UX_DEVICE_CLASS_CDC_ACM_WRITE_START; cdc_acm -> ux_device_class_cdc_acm_write_status = UX_TRANSFER_NO_ANSWER; cdc_acm -> ux_device_class_cdc_acm_write_actual_length = 0; + cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; if (cdc_acm -> ux_device_class_cdc_acm_write_requested_length == 0) zlp = UX_TRUE; @@ -271,10 +277,22 @@ ULONG requested_length; UX_SLAVE_REQUEST_DATA_MAX_LENGTH; else + { /* We can proceed with the demanded length. */ cdc_acm -> ux_device_class_cdc_acm_write_transfer_length = requested_length; +#if !defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP) + + /* Assume expected length matches length to send. */ + cdc_acm -> ux_device_class_cdc_acm_write_host_length = requested_length; +#else + + /* Assume expected more to let stack append ZLP if needed. */ + cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; +#endif + } + /* On a out, we copy the buffer to the caller. Not very efficient but it makes the API easier. */ _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer, @@ -291,7 +309,7 @@ ULONG requested_length; /* Send the request to the device controller. */ status = _ux_device_stack_transfer_run(transfer_request, cdc_acm -> ux_device_class_cdc_acm_write_transfer_length, - cdc_acm -> ux_device_class_cdc_acm_write_transfer_length); + cdc_acm -> ux_device_class_cdc_acm_write_host_length); /* Error case. */ if (status < UX_STATE_NEXT) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c index 3dbe41c8..5f09cc40 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_uninitialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,19 +78,23 @@ /* resulting in version 6.1.10 */ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_uninitialize(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_CDC_ACM *cdc_acm; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class -> ux_slave_class_instance; + cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class_ptr -> ux_slave_class_instance; /* Sanity check. */ if (cdc_acm != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write.c index e4f04bb8..be1c8906 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_write PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -51,7 +51,8 @@ /* cdc_acm Address of cdc_acm class */ /* instance */ /* buffer Pointer to data to write */ -/* requested_length Length of bytes to write */ +/* requested_length Length of bytes to write, */ +/* set to 0 to issue ZLP */ /* actual_length Pointer to save number of */ /* bytes written */ /* */ @@ -82,10 +83,15 @@ /* 10-15-2021 Chaoqiong Xiao Modified comment(s), */ /* fixed compile issue, */ /* resulting in version 6.1.9 */ -/* 01-31-2022x Chaoqiong Xiao Modified comment(s), */ +/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.10 */ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added auto ZLP support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_write(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer, @@ -94,9 +100,10 @@ UINT _ux_device_class_cdc_acm_write(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buff UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; ULONG local_requested_length; +ULONG local_host_length; UINT status = 0; /* If trace is enabled, insert this event into the trace buffer. */ @@ -129,10 +136,10 @@ UINT status = 0; } /* We need the interface to the class. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) @@ -169,6 +176,7 @@ UINT status = 0; else { /* Check if we need more transactions. */ + local_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED && requested_length != 0) { @@ -179,9 +187,21 @@ UINT status = 0; local_requested_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; else - + { + /* We can proceed with the demanded length. */ local_requested_length = requested_length; + +#if !defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP) + + /* Assume the length match expectation. */ + local_host_length = requested_length; +#else + + /* Assume expecting more, so ZLP is appended in stack. */ + local_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; +#endif + } /* On a out, we copy the buffer to the caller. Not very efficient but it makes the API easier. */ @@ -189,7 +209,7 @@ UINT status = 0; buffer, local_requested_length); /* Use case of memcpy is verified. */ /* Send the request to the device controller. */ - status = _ux_device_stack_transfer_request(transfer_request, local_requested_length, local_requested_length); + status = _ux_device_stack_transfer_request(transfer_request, local_requested_length, local_host_length); /* Check the status */ if (status == UX_SUCCESS) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c index 30baac5b..630bea7d 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_write_run PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,11 @@ /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added auto ZLP support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, @@ -86,7 +91,7 @@ UINT _ux_device_class_cdc_acm_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_TRANSFER *transfer_request; UINT zlp = UX_FALSE; UINT status = 0; @@ -124,10 +129,10 @@ UINT status = 0; } /* We need the interface to the class. */ - interface = cdc_acm -> ux_slave_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_slave_class_cdc_acm_interface; /* Locate the endpoints. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) @@ -149,6 +154,7 @@ UINT status = 0; cdc_acm -> ux_device_class_cdc_acm_write_buffer = buffer; cdc_acm -> ux_device_class_cdc_acm_write_requested_length = requested_length; cdc_acm -> ux_device_class_cdc_acm_write_actual_length = 0; + cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; if (requested_length == 0) zlp = UX_TRUE; @@ -176,10 +182,23 @@ UINT status = 0; UX_SLAVE_REQUEST_DATA_MAX_LENGTH; else + { /* We can proceed with the demanded length. */ cdc_acm -> ux_device_class_cdc_acm_write_transfer_length = requested_length; +#if !defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP) + + /* Assume expected length and transfer length match. */ + cdc_acm -> ux_device_class_cdc_acm_write_host_length = requested_length; +#else + + /* Assume expected more than transfer to let stack append ZLP if needed. */ + cdc_acm -> ux_device_class_cdc_acm_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; +#endif + } + + /* On a out, we copy the buffer to the caller. Not very efficient but it makes the API easier. */ _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer, @@ -196,7 +215,7 @@ UINT status = 0; /* Send the request to the device controller. */ status = _ux_device_stack_transfer_run(transfer_request, cdc_acm -> ux_device_class_cdc_acm_write_transfer_length, - cdc_acm -> ux_device_class_cdc_acm_write_transfer_length); + cdc_acm -> ux_device_class_cdc_acm_write_host_length); /* Error case. */ if (status < UX_STATE_NEXT) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_activate.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_activate.c index c34d8d9b..26de96ae 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_activate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -87,34 +91,34 @@ UINT _ux_device_class_cdc_ecm_activate(UX_SLAVE_CLASS_COMMAND *command) return(UX_FUNCTION_NOT_SUPPORTED); #else -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; -UX_SLAVE_CLASS *class; UX_SLAVE_ENDPOINT *endpoint; ULONG physical_address_msw; ULONG physical_address_lsw; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class -> ux_slave_class_instance; + cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Check if this is the Control or Data interface. */ if (command -> ux_slave_class_command_class == UX_DEVICE_CLASS_CDC_ECM_CLASS_COMMUNICATION_CONTROL) { /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)cdc_ecm; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)cdc_ecm; /* Now the opposite, store the interface in the class instance. */ - cdc_ecm -> ux_slave_class_cdc_ecm_interface = interface; + cdc_ecm -> ux_slave_class_cdc_ecm_interface = interface_ptr; /* Locate the interrupt endpoint. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all endpoints. */ while (endpoint != UX_NULL) @@ -150,7 +154,7 @@ ULONG physical_address_lsw; else /* This is the DATA Class, only store the cdc_ecm instance in the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)cdc_ecm; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)cdc_ecm; /* Reset the CDC ECM alternate setting to 0. */ cdc_ecm -> ux_slave_class_cdc_ecm_current_alternate_setting = 0; @@ -165,11 +169,11 @@ ULONG physical_address_lsw; /* Does the data class have bulk endpoint declared ? If yes we need to start link. If not, the host will change the alternate setting at a later stage. */ - if (interface -> ux_slave_interface_descriptor.bNumEndpoints != 0) + if (interface_ptr -> ux_slave_interface_descriptor.bNumEndpoints != 0) { /* Locate the endpoints. Control and Bulk in/out for Data Interface. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all endpoints. */ while (endpoint != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c index 6cec5f30..a30a9bda 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c @@ -88,7 +88,7 @@ VOID _ux_device_class_cdc_ecm_bulkin_thread(ULONG cdc_ecm_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; @@ -99,10 +99,10 @@ UCHAR *packet_header; ULONG transfer_length; /* Cast properly the cdc_ecm instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, cdc_ecm_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, cdc_ecm_class) /* Get the cdc_ecm instance from this class container. */ - cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class -> ux_slave_class_instance; + cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c index c584e416..6b0ba9fc 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c @@ -88,7 +88,7 @@ VOID _ux_device_class_cdc_ecm_bulkout_thread(ULONG cdc_ecm_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; @@ -97,10 +97,10 @@ NX_PACKET *packet; ULONG ip_given_length; /* Cast properly the cdc_ecm instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, cdc_ecm_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, cdc_ecm_class) /* Get the cdc_ecm instance from this class container. */ - cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class -> ux_slave_class_instance; + cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_change.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_change.c index 1bf8717c..7d16c444 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_change.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_change.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_change PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,32 +81,36 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_change(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; -UX_SLAVE_CLASS *class; UX_SLAVE_ENDPOINT *endpoint; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class -> ux_slave_class_instance; + cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Locate the endpoints. Control and Bulk in/out for Data Interface. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* If the interface to mount has a non zero alternate setting, the class is really active with the endpoints active. If the interface reverts to alternate setting 0, it needs to have the pending transactions terminated. */ - if (interface -> ux_slave_interface_descriptor.bAlternateSetting != 0) + if (interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting != 0) { /* Parse all endpoints. */ @@ -198,7 +202,7 @@ UX_SLAVE_ENDPOINT *endpoint; } /* Set the CDC ECM alternate setting to the new one. */ - cdc_ecm -> ux_slave_class_cdc_ecm_current_alternate_setting = interface -> ux_slave_interface_descriptor.bAlternateSetting; + cdc_ecm -> ux_slave_class_cdc_ecm_current_alternate_setting = interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ECM_CHANGE, cdc_ecm, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_control_request.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_control_request.c index a42445be..db152f03 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_control_request.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_control_request PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,6 +66,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -75,7 +79,7 @@ UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; ULONG request; ULONG request_value; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; /* Get the pointer to the device. */ @@ -89,10 +93,10 @@ UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; request_value = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE); /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the cdc_ecm instance from this class container. */ - cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class -> ux_slave_class_instance; + cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance; /* Here we proceed only the standard request we know of at the device level. */ switch (request) diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_deactivate.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_deactivate.c index d09fec13..f179494c 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_deactivate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,30 +75,34 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_deactivate(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; -UX_SLAVE_INTERFACE *interface; -UX_SLAVE_CLASS *class; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class -> ux_slave_class_instance; + cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. Normally the interface can be derived from the class instance but since CDC_ECM has 2 interfaces and we only store the Control interface in the class container, we used the class_command pointer to retrieve the correct interface which issued the deactivation. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Check if this is the Control or Data interface. We only need to dismount the link and abort the transfer once for the 2 classes. */ - if (interface -> ux_slave_interface_descriptor.bInterfaceClass == UX_DEVICE_CLASS_CDC_ECM_CLASS_COMMUNICATION_CONTROL) + if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceClass == UX_DEVICE_CLASS_CDC_ECM_CLASS_COMMUNICATION_CONTROL) { /* Is the link state up? */ diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c index 4f937085..f1723be2 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c @@ -34,7 +34,7 @@ UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -85,6 +85,10 @@ UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -96,12 +100,12 @@ UINT _ux_device_class_cdc_ecm_initialize(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; UX_SLAVE_CLASS_CDC_ECM_PARAMETER *cdc_ecm_parameter; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UINT status; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Create an instance of the device cdc_ecm class. */ cdc_ecm = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_CDC_ECM)); @@ -178,14 +182,14 @@ UINT status; { status = _ux_device_thread_create(&cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread , "ux_slave_class_cdc_ecm_interrupt_thread", _ux_device_class_cdc_ecm_interrupt_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack , + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack , UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); if (status != UX_SUCCESS) status = (UX_THREAD_ERROR); } - UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread), class_ptr) /* Check the creation of this thread. */ if (status == UX_SUCCESS) @@ -196,7 +200,7 @@ UINT status; does not start until we have a instance of the class. */ status = _ux_device_thread_create(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread , "ux_slave_class_cdc_ecm_bulkout_thread", _ux_device_class_cdc_ecm_bulkout_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack , + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack , UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); if (status != UX_SUCCESS) @@ -204,14 +208,14 @@ UINT status; else { - UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread), class_ptr) /* Bulk endpoint treatment needs to be running in a different thread. So start a new thread. We pass a pointer to the cdc_ecm instance to the new thread. This thread does not start until we have a instance of the class. */ status = _ux_device_thread_create(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread , "ux_slave_class_cdc_ecm_bulkin_thread", _ux_device_class_cdc_ecm_bulkin_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack , + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack , UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); if (status != UX_SUCCESS) @@ -219,7 +223,7 @@ UINT status; else { - UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread), class_ptr) /* Create a event flag group for the cdc_ecm class to synchronize with the event interrupt thread. */ status = _ux_utility_event_flags_create(&cdc_ecm -> ux_slave_class_cdc_ecm_event_flags_group, "ux_device_class_cdc_ecm_event_flag"); @@ -229,7 +233,7 @@ UINT status; { /* Save the address of the CDC_ECM instance inside the CDC_ECM container. */ - class -> ux_slave_class_instance = (VOID *) cdc_ecm; + class_ptr -> ux_slave_class_instance = (VOID *) cdc_ecm; /* Get the pointer to the application parameters for the cdc_ecm class. */ cdc_ecm_parameter = command -> ux_slave_class_command_parameter; diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_interrupt_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_interrupt_thread.c index dceef3f0..d88a5d83 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_interrupt_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_interrupt_thread.c @@ -85,7 +85,7 @@ VOID _ux_device_class_cdc_ecm_interrupt_thread(ULONG cdc_ecm_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; @@ -94,10 +94,10 @@ ULONG actual_flags; UCHAR *notification_buffer; /* Cast properly the cdc_ecm instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, cdc_ecm_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, cdc_ecm_class) /* Get the cdc_ecm instance from this class container. */ - cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class -> ux_slave_class_instance; + cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c index 0ed95e76..c429632f 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_ecm_uninitialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,20 +78,24 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_ecm_uninitialize(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_CDC_ECM *cdc_ecm; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class -> ux_slave_class_instance; + cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance; /* Sanity check. */ if (cdc_ecm != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_activate.c b/common/usbx_device_classes/src/ux_device_class_dfu_activate.c index efe5bab9..13753433 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dfu_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -76,29 +76,33 @@ /* resulting in version 6.1.6 */ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_dfu_activate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_DFU *dfu; -UX_SLAVE_CLASS *class; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - dfu = (UX_SLAVE_CLASS_DFU *) class -> ux_slave_class_instance; + dfu = (UX_SLAVE_CLASS_DFU *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)dfu; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)dfu; /* Now the opposite, store the interface in the class instance. */ - dfu -> ux_slave_class_dfu_interface = interface; + dfu -> ux_slave_class_dfu_interface = interface_ptr; /* Check the protocol activation field to determine in which state of the DFU class we are. */ diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_control_request.c b/common/usbx_device_classes/src/ux_device_class_dfu_control_request.c index 2bc5ce30..680a0c15 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_control_request.c @@ -40,7 +40,7 @@ static inline VOID _ux_device_class_dfu_status_get(UX_SLAVE_CLASS_DFU *, /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dfu_control_request PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -92,6 +92,14 @@ static inline VOID _ux_device_class_dfu_status_get(UX_SLAVE_CLASS_DFU *, /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* checked r/w callback status,*/ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added UPLOAD length check */ +/* in _UPLOAD_IDLE state, */ +/* added DNLOAD REQ */ +/* validation, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_dfu_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -99,10 +107,11 @@ UINT _ux_device_class_dfu_control_request(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_DFU *dfu; ULONG request; +ULONG request_type; ULONG request_value; ULONG request_length; ULONG actual_length; @@ -116,10 +125,10 @@ ULONG media_status; device = &_ux_system_slave -> ux_system_slave_device; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the storage instance from this class container. */ - dfu = (UX_SLAVE_CLASS_DFU *) class -> ux_slave_class_instance; + dfu = (UX_SLAVE_CLASS_DFU *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the transfer request associated with the control endpoint. */ transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request; @@ -143,6 +152,7 @@ ULONG media_status; /* Extract all necessary fields of the request. */ request = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST); + request_type = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST_TYPE); /* Pickup the request wValue. */ request_value = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE); @@ -287,8 +297,20 @@ ULONG media_status; case UX_SLAVE_CLASS_DFU_COMMAND_DOWNLOAD : + /* Command verify: check bmRequestType and data length. */ + if ((request_type != UX_DEVICE_CLASS_DFU_REQTYPE_INTERFACE_SET) || + (request_length != transfer_request -> ux_slave_transfer_request_actual_length)) + { + + /* Zero length download is not accepted. Stall the endpoint. */ + _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); + + /* In the system, state the DFU state machine to dfu ERROR. */ + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_ERROR; + } + /* We received a DOWNLOAD command. Check the length field of the request. It cannot be 0. */ - if (request_length == 0) + else if (request_length == 0) { /* Zero length download is not accepted. Stall the endpoint. */ @@ -540,9 +562,21 @@ ULONG media_status; case UX_SLAVE_CLASS_DFU_COMMAND_DOWNLOAD : + /* Command verify: check bmRequestType and data length. */ + if ((request_type != UX_DEVICE_CLASS_DFU_REQTYPE_INTERFACE_SET) || + (request_length != transfer_request -> ux_slave_transfer_request_actual_length)) + { + + /* Zero length download is not accepted. Stall the endpoint. */ + _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); + + /* In the system, state the DFU state machine to dfu ERROR. */ + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_ERROR; + } + /* We received a DOWNLOAD command. Check the length field of the request. If it is 0, we are done with the transfer. */ - if (request_length == 0) + else if (request_length == 0) { /* Send the notification of end of download to application. */ @@ -795,7 +829,7 @@ ULONG media_status; break; #ifndef UX_DEVICE_CLASS_DFU_UPLOAD_DISABLE - case UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_UPLOAD_IDLE: + case UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_UPLOAD_IDLE: /* bitCanUpload == 1. */ /* Here we process only the request we can accept in the DFU mode UPLOAD IDLE state. */ switch (request) @@ -803,6 +837,14 @@ ULONG media_status; case UX_SLAVE_CLASS_DFU_COMMAND_UPLOAD: + /* Check if length > wTransferSize (we can support max of control buffer size). */ + if (request_length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH) + { + _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_ERROR; + break; + } + /* Length 0 case undefined, just keep state. */ if (request_length == 0) break; diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_deactivate.c b/common/usbx_device_classes/src/ux_device_class_dfu_deactivate.c index dfc42d5e..2c610174 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dfu_deactivate PORTABLE C */ -/* 6.1.6 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,20 +69,24 @@ /* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ /* removed endpoints aborting, */ /* resulting in version 6.1.6 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_dfu_deactivate(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_DFU *dfu; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - dfu = (UX_SLAVE_CLASS_DFU *) class -> ux_slave_class_instance; + dfu = (UX_SLAVE_CLASS_DFU *) class_ptr -> ux_slave_class_instance; /* If there is a deactivate function call it. */ if (dfu -> ux_slave_class_dfu_instance_deactivate != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_initialize.c b/common/usbx_device_classes/src/ux_device_class_dfu_initialize.c index 7a6cb2a8..3de361f5 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dfu_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -83,6 +83,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_dfu_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -90,7 +94,7 @@ UINT _ux_device_class_dfu_initialize(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_CLASS_DFU *dfu; UX_SLAVE_CLASS_DFU_PARAMETER *dfu_parameter; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UINT status = UX_DESCRIPTOR_CORRUPTED; UX_DFU_FUNCTIONAL_DESCRIPTOR dfu_functional_descriptor; UCHAR *dfu_framework; @@ -99,7 +103,7 @@ UCHAR descriptor_type; ULONG descriptor_length; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Create an instance of the device dfu class. */ dfu = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_DFU)); @@ -109,7 +113,7 @@ ULONG descriptor_length; return(UX_MEMORY_INSUFFICIENT); /* Save the address of the DFU instance inside the DFU container. */ - class -> ux_slave_class_instance = (VOID *) dfu; + class_ptr -> ux_slave_class_instance = (VOID *) dfu; /* Get the pointer to the application parameters for the dfu class. */ dfu_parameter = command -> ux_slave_class_command_parameter; @@ -196,7 +200,7 @@ ULONG descriptor_length; /* Check status. */ if (status != UX_SUCCESS) status = UX_EVENT_ERROR; - + /* Allocate some memory for the dfu thread stack. */ if (status == UX_SUCCESS) { @@ -213,7 +217,7 @@ ULONG descriptor_length; { status = _ux_device_thread_create(&dfu -> ux_slave_class_dfu_thread , "ux_slave_class_dfu_thread", _ux_device_class_dfu_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) dfu -> ux_slave_class_dfu_thread_stack, + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) dfu -> ux_slave_class_dfu_thread_stack, UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_AUTO_START); @@ -222,11 +226,11 @@ ULONG descriptor_length; status = UX_THREAD_ERROR; } - UX_THREAD_EXTENSION_PTR_SET(&(dfu -> ux_slave_class_dfu_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(dfu -> ux_slave_class_dfu_thread), class_ptr) #else /* Set task function. */ - class -> ux_slave_class_task_function = _ux_device_class_dfu_tasks_run; + class_ptr -> ux_slave_class_task_function = _ux_device_class_dfu_tasks_run; #endif /* Return completion status. */ @@ -245,7 +249,7 @@ ULONG descriptor_length; #endif /* Detach from container and free instance memory. */ - class -> ux_slave_class_instance = UX_NULL; + class_ptr -> ux_slave_class_instance = UX_NULL; _ux_utility_memory_free(dfu); return(status); diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_thread.c b/common/usbx_device_classes/src/ux_device_class_dfu_thread.c index 69bb2cbd..f3241270 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_thread.c @@ -83,17 +83,17 @@ VOID _ux_device_class_dfu_thread(ULONG dfu_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_DFU *dfu; UX_SLAVE_DCD *dcd; UINT status; ULONG actual_flags; /* Cast properly the dfu instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, dfu_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, dfu_class) /* Get the dfu instance from this class container. */ - dfu = (UX_SLAVE_CLASS_DFU *) class -> ux_slave_class_instance; + dfu = (UX_SLAVE_CLASS_DFU *) class_ptr -> ux_slave_class_instance; /* This thread runs forever. */ while(1) diff --git a/common/usbx_device_classes/src/ux_device_class_hid_activate.c b/common/usbx_device_classes/src/ux_device_class_hid_activate.c index 29317a13..c731e95d 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,14 +77,21 @@ /* added interrupt OUT support,*/ /* added packet size assert, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone receiver, */ +/* fixed standalone tx length, */ +/* fixed standalone EP IN init,*/ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_activate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_HID *hid; -UX_SLAVE_CLASS *class_inst; UX_SLAVE_ENDPOINT *endpoint_interrupt; UX_SLAVE_ENDPOINT *endpoint_in = UX_NULL; #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) @@ -92,22 +99,22 @@ UX_SLAVE_ENDPOINT *endpoint_out = UX_NULL; #endif /* Get the class container. */ - class_inst = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - hid = (UX_SLAVE_CLASS_HID *) class_inst -> ux_slave_class_instance; + hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)hid; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)hid; /* Now the opposite, store the interface in the class instance. */ - hid -> ux_slave_class_hid_interface = interface; + hid -> ux_slave_class_hid_interface = interface_ptr; /* Locate the endpoints. */ - endpoint_interrupt = interface -> ux_slave_interface_first_endpoint; + endpoint_interrupt = interface_ptr -> ux_slave_interface_first_endpoint; /* Check if interrupt IN endpoint exists. */ while (endpoint_interrupt != UX_NULL) @@ -180,6 +187,10 @@ UX_SLAVE_ENDPOINT *endpoint_out = UX_NULL; /* Resume thread. */ _ux_utility_thread_resume(&hid -> ux_device_class_hid_receiver -> ux_device_class_hid_receiver_thread); +#else + + /* Setup read state for receiver. */ + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_RECEIVER_START; #endif } #endif @@ -187,14 +198,15 @@ UX_SLAVE_ENDPOINT *endpoint_out = UX_NULL; #if !defined(UX_DEVICE_STANDALONE) /* Resume thread. */ - _ux_device_thread_resume(&class_inst -> ux_slave_class_thread); + _ux_device_thread_resume(&class_ptr -> ux_slave_class_thread); #else /* Reset event buffered for background transfer. */ _ux_utility_memory_set((VOID *)&hid -> ux_device_class_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); /* Use case of memset is verified. */ hid -> ux_device_class_hid_event.ux_device_class_hid_event_length = - endpoint_interrupt -> ux_slave_endpoint_descriptor.wMaxPacketSize; + endpoint_in -> ux_slave_endpoint_transfer_request. + ux_slave_transfer_request_transfer_length; /* Reset event sending state. */ hid -> ux_device_class_hid_event_state = UX_STATE_RESET; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c index b37d531e..4d04c38b 100755 --- a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_control_request PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -86,6 +86,10 @@ /* resulting in version 6.1.10 */ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -93,7 +97,7 @@ UINT _ux_device_class_hid_control_request(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; ULONG request; ULONG request_value; ULONG request_index; @@ -118,10 +122,10 @@ UX_SLAVE_CLASS_HID *hid; duration = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE + 1); /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the storage instance from this class container. */ - hid = (UX_SLAVE_CLASS_HID *) class -> ux_slave_class_instance; + hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; /* Here we proceed only the standard request we know of at the device level. */ switch (request) diff --git a/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c b/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c index 0e5a0af9..9abc45cf 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_deactivate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,19 +66,23 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_deactivate(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_HID *hid; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - hid = (UX_SLAVE_CLASS_HID *) class -> ux_slave_class_instance; + hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; /* Terminate the transactions pending on the endpoints. */ _ux_device_stack_transfer_all_request_abort(hid -> ux_device_class_hid_interrupt_endpoint, UX_TRANSFER_BUS_RESET); diff --git a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c index 341228ec..22f8e46b 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,11 @@ /* resulting in version 6.1.10 */ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone receiver, */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -87,12 +92,12 @@ UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_CLASS_HID *hid; UX_SLAVE_CLASS_HID_PARAMETER *hid_parameter; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UINT status = UX_SUCCESS; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Create an instance of the device hid class. */ hid = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_HID)); @@ -102,31 +107,31 @@ UINT status = UX_SUCCESS; return(UX_MEMORY_INSUFFICIENT); /* Save the address of the HID instance inside the HID container. */ - class -> ux_slave_class_instance = (VOID *) hid; + class_ptr -> ux_slave_class_instance = (VOID *) hid; #if !defined(UX_DEVICE_STANDALONE) /* Allocate some memory for the thread stack. */ - class -> ux_slave_class_thread_stack = + class_ptr -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE); /* Check for successful allocation. */ - if (class -> ux_slave_class_thread_stack == UX_NULL) + if (class_ptr -> ux_slave_class_thread_stack == UX_NULL) status = UX_MEMORY_INSUFFICIENT; /* This instance needs to be running in a different thread. So start a new thread. We pass a pointer to the class to the new thread. This thread does not start until we have a instance of the class. */ if (status == UX_SUCCESS) - status = _ux_device_thread_create(&class -> ux_slave_class_thread, "ux_slave_hid_thread", + status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_hid_thread", _ux_device_class_hid_interrupt_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) class -> ux_slave_class_thread_stack, + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) class_ptr -> ux_slave_class_thread_stack, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); #else /* Set task function. */ - class -> ux_slave_class_task_function = _ux_device_class_hid_tasks_run; + class_ptr -> ux_slave_class_task_function = _ux_device_class_hid_tasks_run; #endif /* Check the creation of this thread. */ @@ -134,7 +139,7 @@ UINT status = UX_SUCCESS; { #if !defined(UX_DEVICE_STANDALONE) - UX_THREAD_EXTENSION_PTR_SET(&(class -> ux_slave_class_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(class_ptr -> ux_slave_class_thread), class_ptr) #endif /* Get the pointer to the application parameters for the hid class. */ @@ -169,18 +174,19 @@ UINT status = UX_SUCCESS; /* By default no event wait timeout. */ hid -> ux_device_class_hid_event_wait_timeout = UX_WAIT_FOREVER; -#if defined(UX_DEVICE_STANDALONE) - - return(UX_SUCCESS); -#else +#if !defined(UX_DEVICE_STANDALONE) /* Create a event flag group for the hid class to synchronize with the event interrupt thread. */ status = _ux_utility_event_flags_create(&hid -> ux_device_class_hid_event_flags_group, "ux_device_class_hid_event_flag"); /* Check status. */ - if (status == UX_SUCCESS) + if (status != UX_SUCCESS) + status = UX_EVENT_ERROR; + else +#endif { #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) + #if !defined(UX_DEVICE_STANDALONE) /* Create a mutex for reading reentry check. */ @@ -221,14 +227,10 @@ UINT status = UX_SUCCESS; #endif } - else - - /* It's event error. */ - status = UX_EVENT_ERROR; /* Free allocated event array memory. */ _ux_utility_memory_free(hid -> ux_device_class_hid_event_array); -#endif + } else status = UX_MEMORY_INSUFFICIENT; @@ -236,7 +238,7 @@ UINT status = UX_SUCCESS; #if !defined(UX_DEVICE_STANDALONE) /* Delete thread. */ - _ux_device_thread_delete(&class -> ux_slave_class_thread); + _ux_device_thread_delete(&class_ptr -> ux_slave_class_thread); #endif } else @@ -245,12 +247,12 @@ UINT status = UX_SUCCESS; #if !defined(UX_DEVICE_STANDALONE) /* Free stack. */ - if (class -> ux_slave_class_thread_stack) - _ux_utility_memory_free(class -> ux_slave_class_thread_stack); + if (class_ptr -> ux_slave_class_thread_stack) + _ux_utility_memory_free(class_ptr -> ux_slave_class_thread_stack); #endif /* Unmount instance. */ - class -> ux_slave_class_instance = UX_NULL; + class_ptr -> ux_slave_class_instance = UX_NULL; /* Free HID instance. */ _ux_utility_memory_free(hid); diff --git a/common/usbx_device_classes/src/ux_device_class_hid_interrupt_thread.c b/common/usbx_device_classes/src/ux_device_class_hid_interrupt_thread.c index 9d684546..0cd80c0f 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_interrupt_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_interrupt_thread.c @@ -89,7 +89,7 @@ VOID _ux_device_class_hid_interrupt_thread(ULONG hid_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_HID *hid; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request_in; @@ -100,10 +100,10 @@ ULONG actual_flags; /* Cast properly the hid instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, hid_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, hid_class) /* Get the hid instance from this class container. */ - hid = (UX_SLAVE_CLASS_HID *) class -> ux_slave_class_instance; + hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; @@ -197,7 +197,7 @@ ULONG actual_flags; } /* We need to suspend ourselves. We will be resumed by the device enumeration module. */ - _ux_device_thread_suspend(&class -> ux_slave_class_thread); + _ux_device_thread_suspend(&class_ptr -> ux_slave_class_thread); } } #endif diff --git a/common/usbx_device_classes/src/ux_device_class_hid_read.c b/common/usbx_device_classes/src/ux_device_class_hid_read.c index 9fe986a4..b847a1f0 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_read.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_read.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_read PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,7 @@ /* */ /* This function reads from the HID class. */ /* This function must not be used with receiver related functions. */ +/* This function is for RTOS mode. */ /* */ /* INPUT */ /* */ @@ -67,7 +68,7 @@ /* */ /* CALLED BY */ /* */ -/* ThreadX */ +/* Application */ /* */ /* RELEASE HISTORY */ /* */ @@ -77,6 +78,8 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_read(UX_SLAVE_CLASS_HID *hid, UCHAR *buffer, diff --git a/common/usbx_device_classes/src/ux_device_class_hid_read_run.c b/common/usbx_device_classes/src/ux_device_class_hid_read_run.c new file mode 100644 index 00000000..d0ace70f --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_hid_read_run.c @@ -0,0 +1,255 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device HID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_hid.h" +#include "ux_device_stack.h" + + +#if defined(UX_DEVICE_STANDALONE) +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_read_run PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function reads from the HID class. */ +/* This function must not be used with receiver related functions. */ +/* This function is for standalone mode. */ +/* */ +/* INPUT */ +/* */ +/* hid Address of hid class */ +/* instance */ +/* buffer Pointer to buffer to save */ +/* received data */ +/* requested_length Length of bytes to read */ +/* actual_length Pointer to save number of */ +/* bytes read */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _ux_device_stack_transfer_request Transfer request */ +/* _ux_utility_memory_copy Copy memory */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_device_class_hid_read_run(UX_SLAVE_CLASS_HID *hid, UCHAR *buffer, + ULONG requested_length, ULONG *actual_length) +{ +#if !defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) + UX_PARAMETER_NOT_USED(hid); + UX_PARAMETER_NOT_USED(buffer); + UX_PARAMETER_NOT_USED(requested_length); + UX_PARAMETER_NOT_USED(actual_length); + return(UX_FUNCTION_NOT_SUPPORTED); +#else + +UX_SLAVE_ENDPOINT *endpoint; +UX_SLAVE_DEVICE *device; +UX_SLAVE_TRANSFER *transfer_request; +UINT read_state; +UINT status= UX_SUCCESS; + + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_READ, hid, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) + + /* Get the pointer to the device. */ + device = &_ux_system_slave -> ux_system_slave_device; + + /* As long as the device is in the CONFIGURED state. */ + if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONFIGURATION_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0) + + /* Cannot proceed with command, the interface is down. */ + hid -> ux_device_class_hid_read_state = UX_STATE_RESET; + hid -> ux_device_class_hid_read_status = UX_CONFIGURATION_HANDLE_UNKNOWN; + return(UX_STATE_EXIT); + } + + /* Locate the endpoint. */ + endpoint = hid -> ux_device_class_hid_read_endpoint; + + /* Check endpoint. If NULL, we have not yet received the proper SET_INTERFACE command. */ + if (endpoint == UX_NULL) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN); + + hid -> ux_device_class_hid_read_state = UX_STATE_RESET; + hid -> ux_device_class_hid_read_status = UX_CONFIGURATION_HANDLE_UNKNOWN; + return(UX_STATE_EXIT); + } + + /* All HID reading are on the endpoint OUT, from the host. */ + transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; + + /* Handle state cases. */ + read_state = hid -> ux_device_class_hid_read_state; + switch(read_state) + { + case UX_STATE_RESET: + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_READ_START; + hid -> ux_device_class_hid_read_status = UX_TRANSFER_NO_ANSWER; + hid -> ux_device_class_hid_read_buffer = buffer; + hid -> ux_device_class_hid_read_requested_length = requested_length; + hid -> ux_device_class_hid_read_actual_length = 0; + + /* Fall through. */ + case UX_DEVICE_CLASS_HID_READ_START: + + /* Get remaining requested length. */ + requested_length = hid -> ux_device_class_hid_read_requested_length - + hid -> ux_device_class_hid_read_actual_length; + + /* There is no remaining, we are done. */ + if (requested_length == 0) + { + *actual_length = hid -> ux_device_class_hid_read_actual_length; + hid -> ux_device_class_hid_read_state = UX_STATE_RESET; + hid -> ux_device_class_hid_read_status = UX_SUCCESS; + return(UX_STATE_NEXT); + } + + /* Check if we have enough in the local buffer. */ + if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH) + + /* We have too much to transfer. */ + hid -> ux_device_class_hid_read_transfer_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; + + else + + /* We can proceed with the demanded length. */ + hid -> ux_device_class_hid_read_transfer_length = requested_length; + + /* Next state. */ + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_READ_WAIT; + UX_SLAVE_TRANSFER_STATE_RESET(transfer_request); + + /* Fall through. */ + case UX_DEVICE_CLASS_HID_READ_WAIT: + + /* Send the request to the device controller. */ + status = _ux_device_stack_transfer_run(transfer_request, + hid -> ux_device_class_hid_read_transfer_length, + hid -> ux_device_class_hid_read_transfer_length); + + /* Error case. */ + if (status < UX_STATE_NEXT) + { + + hid -> ux_device_class_hid_read_state = UX_STATE_RESET; + hid -> ux_device_class_hid_read_status = + transfer_request -> ux_slave_transfer_request_completion_code; + return(UX_STATE_EXIT); + } + + /* Success case. */ + if (status == UX_STATE_NEXT) + { + + /* We need to copy the buffer locally. */ + _ux_utility_memory_copy(hid -> ux_device_class_hid_read_buffer, + transfer_request -> ux_slave_transfer_request_data_pointer, + transfer_request -> ux_slave_transfer_request_actual_length); /* Use case of memcpy is verified. */ + + /* Next buffer address. */ + hid -> ux_device_class_hid_read_buffer += + transfer_request -> ux_slave_transfer_request_actual_length; + + /* Set the length actually received. */ + hid -> ux_device_class_hid_read_actual_length += + transfer_request -> ux_slave_transfer_request_actual_length; + + /* Last transfer status. */ + hid -> ux_device_class_hid_read_status = + transfer_request -> ux_slave_transfer_request_completion_code; + + /* Update actual length. */ + *actual_length = hid -> ux_device_class_hid_read_actual_length; + + /* Check short packet. */ + if (transfer_request -> ux_slave_transfer_request_actual_length < + transfer_request -> ux_slave_transfer_request_requested_length) + { + + /* It's done. */ + hid -> ux_device_class_hid_read_state = UX_STATE_RESET; + return(UX_STATE_NEXT); + } + + /* Next state. */ + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_READ_START; + } + + /* Keep waiting. */ + return(UX_STATE_WAIT); + + /* Receiver running states. */ + case UX_DEVICE_CLASS_HID_RECEIVER_START: /* Fall through. */ + case UX_DEVICE_CLASS_HID_RECEIVER_WAIT: /* Fall through. */ + case UX_DEVICE_CLASS_HID_RECEIVER_ERROR: + + /* Receiver running. */ + return(UX_STATE_ERROR); + + default: /* Error. */ + hid -> ux_device_class_hid_read_status = UX_INVALID_STATE; + hid -> ux_device_class_hid_read_state = UX_STATE_RESET; + break; + } + + /* Error case. */ + return(UX_STATE_EXIT); +#endif +} +#endif diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_get.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_get.c index d701267a..dde2a419 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_get.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_event_get.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_receiver_event_get PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +68,9 @@ /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* cleaned compile with TRACE, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_receiver_event_get(UX_SLAVE_CLASS_HID *hid, @@ -85,7 +88,7 @@ UX_DEVICE_CLASS_HID_RECEIVED_EVENT *pos; /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_RECEIVER_EVENT_GET, hid, event, wait_option, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_RECEIVER_EVENT_GET, hid, event, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0) /* Get receiver. */ receiver = hid -> ux_device_class_hid_receiver; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_initialize.c index 5c4f76dc..de5dbe7d 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_receiver_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_receiver_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,6 +74,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* added receiver callback, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone receiver, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_receiver_initialize(UX_SLAVE_CLASS_HID *hid, @@ -90,7 +93,9 @@ ULONG memory_size; ULONG events_size; UCHAR *memory_receiver; UCHAR *memory_events; +#if !defined(UX_DEVICE_STANDALONE) UCHAR *memory_stack; +#endif UINT status = UX_SUCCESS; @@ -120,8 +125,12 @@ UINT status = UX_SUCCESS; memory_receiver = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, memory_size); if (memory_receiver == UX_NULL) return(UX_MEMORY_INSUFFICIENT); +#if !defined(UX_DEVICE_STANDALONE) memory_stack = memory_receiver + sizeof(UX_DEVICE_CLASS_HID_RECEIVER); memory_events = memory_stack + UX_DEVICE_CLASS_HID_RECEIVER_THREAD_STACK_SIZE; +#else + memory_events = memory_receiver + sizeof(UX_DEVICE_CLASS_HID_RECEIVER); +#endif /* Store receiver instance pointer. */ (*receiver) = (UX_DEVICE_CLASS_HID_RECEIVER *)memory_receiver; @@ -147,7 +156,8 @@ UINT status = UX_SUCCESS; #if !defined(UX_DEVICE_STANDALONE) UX_THREAD_EXTENSION_PTR_SET(&((*receiver) -> ux_device_class_hid_receiver_thread), hid) #else - /* TODO: initialize read state for receiver. */ + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_RECEIVER_START; + (*receiver) -> ux_device_class_hid_receiver_tasks_run = _ux_device_class_hid_receiver_tasks_run; #endif /* Initialize event buffer size. */ diff --git a/common/usbx_device_classes/src/ux_device_class_hid_receiver_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_hid_receiver_tasks_run.c new file mode 100644 index 00000000..0f5dda2a --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_hid_receiver_tasks_run.c @@ -0,0 +1,194 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device HID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_hid.h" +#include "ux_device_stack.h" + + +#if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) && defined(UX_DEVICE_STANDALONE) +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_receiver_tasks_run PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is task function of the hid interrupt OUT endpoint. */ +/* It's for standalone mode. */ +/* */ +/* INPUT */ +/* */ +/* hid HID instance */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _ux_device_stack_transfer_run Request transfer */ +/* _ux_utility_memory_copy Copy memory */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Device HID */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_device_class_hid_receiver_tasks_run(UX_SLAVE_CLASS_HID *hid) +{ + +UX_SLAVE_DEVICE *device; +UX_DEVICE_CLASS_HID_RECEIVER *receiver; +UX_DEVICE_CLASS_HID_RECEIVED_EVENT *pos; +UCHAR *next_pos; +UX_SLAVE_ENDPOINT *endpoint; +UX_SLAVE_TRANSFER *transfer; +UINT status; +UCHAR *buffer; +ULONG temp; + + + /* Get the pointer to the device. */ + device = &_ux_system_slave -> ux_system_slave_device; + + /* Check device state. */ + if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) + return(UX_STATE_EXIT); + + /* Get receiver instance. */ + receiver = hid -> ux_device_class_hid_receiver; + if (receiver == UX_NULL) + return(UX_STATE_EXIT); + + /* Get endpoint. */ + endpoint = hid -> ux_device_class_hid_read_endpoint; + if (endpoint == UX_NULL) + return(UX_STATE_EXIT); + + /* Event buffer available, issue request to get data. */ + transfer = &endpoint -> ux_slave_endpoint_transfer_request; + + /* Run read/receiver states. */ + switch(hid -> ux_device_class_hid_read_state) + { + case UX_DEVICE_CLASS_HID_RECEIVER_START: + + /* Check if there is buffer available. */ + pos = receiver -> ux_device_class_hid_receiver_event_save_pos; + if (pos -> ux_device_class_hid_received_event_length != 0) + { + + /* Buffer is full, keep waiting. */ + return(UX_STATE_IDLE); + } + + /* Set request length. */ + hid -> ux_device_class_hid_read_requested_length = + receiver -> ux_device_class_hid_receiver_event_buffer_size; + + /* Move state. */ + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_RECEIVER_WAIT; + + /* Fall through. */ + case UX_DEVICE_CLASS_HID_RECEIVER_WAIT: + + /* Send the request to the device controller. */ + status = _ux_device_stack_transfer_run(transfer, + hid -> ux_device_class_hid_read_requested_length, + hid -> ux_device_class_hid_read_requested_length); + + /* Error case. */ + if (status < UX_STATE_NEXT) + { + + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_RECEIVER_ERROR; + hid -> ux_device_class_hid_read_status = + transfer -> ux_slave_transfer_request_completion_code; + return(UX_STATE_ERROR); + } + + /* Success case. */ + if (status == UX_STATE_NEXT) + { + + /* Ignore ZLP case. */ + if (transfer -> ux_slave_transfer_request_actual_length == 0) + { + + /* Restart receiving. */ + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_RECEIVER_START; + return(UX_STATE_NEXT); + } + + /* Save received event data and length. */ + pos = receiver -> ux_device_class_hid_receiver_event_save_pos; + buffer = (UCHAR *)&pos -> ux_device_class_hid_received_event_data; + temp = transfer -> ux_slave_transfer_request_actual_length; + _ux_utility_memory_copy(buffer, + transfer -> ux_slave_transfer_request_data_pointer, + temp); /* Use case of memcpy is verified. */ + + /* Advance the save position. */ + next_pos = (UCHAR *)pos + receiver -> ux_device_class_hid_receiver_event_buffer_size + sizeof(ULONG); + if (next_pos >= (UCHAR *)receiver -> ux_device_class_hid_receiver_events_end) + next_pos = (UCHAR *)receiver -> ux_device_class_hid_receiver_events; + receiver -> ux_device_class_hid_receiver_event_save_pos = (UX_DEVICE_CLASS_HID_RECEIVED_EVENT *)next_pos; + + /* Save received data length (it's valid now). */ + pos -> ux_device_class_hid_received_event_length = temp; + + /* Notify application that a event is received. */ + if (receiver -> ux_device_class_hid_receiver_event_callback) + receiver -> ux_device_class_hid_receiver_event_callback(hid); + + /* Restart receiving. */ + hid -> ux_device_class_hid_read_state = UX_DEVICE_CLASS_HID_RECEIVER_START; + return(UX_STATE_NEXT); + } + + /* Keep waiting. */ + return(UX_STATE_WAIT); + + default: /* Nothing to do by default. */ + break; + } + + /* Task is idle. */ + return(UX_STATE_IDLE); +} +#endif diff --git a/common/usbx_device_classes/src/ux_device_class_hid_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_hid_uninitialize.c index 46adf95d..afb662a8 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_uninitialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_hid_uninitialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,28 +74,32 @@ /* resulting in version 6.1.10 */ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_hid_uninitialize(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_HID *hid; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - hid = (UX_SLAVE_CLASS_HID *) class -> ux_slave_class_instance; + hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; #if !defined(UX_DEVICE_STANDALONE) /* Remove HID thread. */ - _ux_device_thread_delete(&class -> ux_slave_class_thread); + _ux_device_thread_delete(&class_ptr -> ux_slave_class_thread); /* Remove the thread used by HID. */ - _ux_utility_memory_free(class -> ux_slave_class_thread_stack); + _ux_utility_memory_free(class_ptr -> ux_slave_class_thread_stack); /* Delete the event flag group for the hid class. */ _ux_device_event_flags_delete(&hid -> ux_device_class_hid_event_flags_group); diff --git a/common/usbx_device_classes/src/ux_device_class_pima_activate.c b/common/usbx_device_classes/src/ux_device_class_pima_activate.c index faae5076..7c73659f 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_activate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,36 +72,40 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_activate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_PIMA *pima; -UX_SLAVE_CLASS *class; UX_SLAVE_ENDPOINT *endpoint_in; UX_SLAVE_ENDPOINT *endpoint_out; UX_SLAVE_ENDPOINT *endpoint_interrupt; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Store the class instance in the container. */ - pima = (UX_SLAVE_CLASS_PIMA *) class -> ux_slave_class_instance; + pima = (UX_SLAVE_CLASS_PIMA *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)pima; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)pima; /* Now the opposite, store the interface in the class instance. */ - pima -> ux_slave_class_pima_interface = interface; + pima -> ux_slave_class_pima_interface = interface_ptr; /* Locate the endpoints. */ - endpoint_in = interface -> ux_slave_interface_first_endpoint; + endpoint_in = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT) @@ -138,7 +142,7 @@ UX_SLAVE_ENDPOINT *endpoint_interrupt; pima -> ux_device_class_pima_device_status = UX_DEVICE_CLASS_PIMA_RC_OK; /* Resume thread. */ - _ux_device_thread_resume(&class -> ux_slave_class_thread); + _ux_device_thread_resume(&class_ptr -> ux_slave_class_thread); /* If there is a activate function call it. */ if (pima -> ux_device_class_pima_instance_activate != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_pima_control_request.c b/common/usbx_device_classes/src/ux_device_class_pima_control_request.c index 26e29b90..31bb3c58 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_control_request.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_control_request PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* improved request handling, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -82,7 +86,7 @@ UX_SLAVE_DCD *dcd; UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; ULONG request; ULONG request_length; ULONG length; @@ -105,10 +109,10 @@ ULONG transaction_id; request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH); /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the storage instance from this class container. */ - pima = (UX_SLAVE_CLASS_PIMA *) class -> ux_slave_class_instance; + pima = (UX_SLAVE_CLASS_PIMA *) class_ptr -> ux_slave_class_instance; /* Here we proceed only the standard request we know of at the device level. */ switch (request) diff --git a/common/usbx_device_classes/src/ux_device_class_pima_deactivate.c b/common/usbx_device_classes/src/ux_device_class_pima_deactivate.c index 48a80ca9..7bf3fd30 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_deactivate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,19 +66,23 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_deactivate(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_PIMA *pima; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Store the class instance in the container. */ - pima = (UX_SLAVE_CLASS_PIMA *) class -> ux_slave_class_instance; + pima = (UX_SLAVE_CLASS_PIMA *) class_ptr -> ux_slave_class_instance; /* Terminate the transactions pending on the endpoints. */ _ux_device_stack_transfer_all_request_abort(pima -> ux_device_class_pima_bulk_in_endpoint, UX_TRANSFER_BUS_RESET); diff --git a/common/usbx_device_classes/src/ux_device_class_pima_initialize.c b/common/usbx_device_classes/src/ux_device_class_pima_initialize.c index 8916010e..e268c62d 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,6 +77,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -88,10 +92,10 @@ UINT _ux_device_class_pima_initialize(UX_SLAVE_CLASS_COMMAND *command) UINT status; UX_SLAVE_CLASS_PIMA *pima; UX_SLAVE_CLASS_PIMA_PARAMETER *pima_parameter; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Create an instance of the device pima class. */ pima = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_PIMA)); @@ -101,14 +105,14 @@ UX_SLAVE_CLASS *class; return(UX_MEMORY_INSUFFICIENT); /* Save the address of the PIMA instance inside the PIMA container. */ - class -> ux_slave_class_instance = (VOID *) pima; + class_ptr -> ux_slave_class_instance = (VOID *) pima; /* Allocate some memory for the thread stack. */ - class -> ux_slave_class_thread_stack = + class_ptr -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE); /* Check for successful allocation. */ - if (class -> ux_slave_class_thread_stack == UX_NULL) + if (class_ptr -> ux_slave_class_thread_stack == UX_NULL) status = UX_MEMORY_INSUFFICIENT; else status = UX_SUCCESS; @@ -118,9 +122,9 @@ UX_SLAVE_CLASS *class; does not start until we have a instance of the class. */ if (status == UX_SUCCESS) { - status = _ux_device_thread_create(&class -> ux_slave_class_thread, "ux_slave_class_thread", + status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_class_thread", _ux_device_class_pima_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) class -> ux_slave_class_thread_stack, + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) class_ptr -> ux_slave_class_thread_stack, UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); @@ -129,7 +133,7 @@ UX_SLAVE_CLASS *class; status = UX_THREAD_ERROR; } - UX_THREAD_EXTENSION_PTR_SET(&(class -> ux_slave_class_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(class_ptr -> ux_slave_class_thread), class_ptr) /* There is error, free resources and return error. */ if (status != UX_SUCCESS) @@ -138,11 +142,11 @@ UX_SLAVE_CLASS *class; /* The last resource, thread is not created or created error, no need to free. */ - if (class -> ux_slave_class_thread_stack) - _ux_utility_memory_free(class -> ux_slave_class_thread_stack); + if (class_ptr -> ux_slave_class_thread_stack) + _ux_utility_memory_free(class_ptr -> ux_slave_class_thread_stack); /* Detach instance and free memory. */ - class -> ux_slave_class_instance = UX_NULL; + class_ptr -> ux_slave_class_instance = UX_NULL; _ux_utility_memory_free(pima); /* Return completion status. */ diff --git a/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c b/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c index cac838ee..68da7f74 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_interrupt_thread PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,6 +81,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed event message size, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_device_class_pima_interrupt_thread(ULONG pima_class) @@ -167,8 +170,8 @@ UCHAR *buffer; _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_2, pima_event.ux_device_class_pima_event_parameter_3); /* Send the request to the device controller. */ - status = _ux_device_stack_transfer_request(transfer_request_in, UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH + 1, UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH); - + status = _ux_device_stack_transfer_request(transfer_request_in, UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH, UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH); + /* Check error code. */ if (status != UX_SUCCESS) diff --git a/common/usbx_device_classes/src/ux_device_class_pima_storage_info_get.c b/common/usbx_device_classes/src/ux_device_class_pima_storage_info_get.c index ebf6ce0f..ef078d69 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_storage_info_get.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_storage_info_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_pima_storage_info_get PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,6 +74,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* improved sanity checks, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added no-callback handling, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_pima_storage_info_get(UX_SLAVE_CLASS_PIMA *pima, ULONG storage_id) @@ -95,8 +98,16 @@ UCHAR *storage_info_pointer; storage_info = transfer_request -> ux_slave_transfer_request_data_pointer; /* Update the storage information. We get the volatile parameters from the application. */ - status = pima -> ux_device_class_pima_storage_info_get(pima, storage_id); - + if (pima -> ux_device_class_pima_storage_info_get) + status = pima -> ux_device_class_pima_storage_info_get(pima, storage_id); + else + { + if (storage_id == pima -> ux_device_class_pima_storage_id) + status = UX_SUCCESS; + else + status = UX_DEVICE_CLASS_PIMA_RC_INVALID_STORAGE_ID; + } + /* Check for error. */ if (status != UX_SUCCESS) diff --git a/common/usbx_device_classes/src/ux_device_class_pima_thread.c b/common/usbx_device_classes/src/ux_device_class_pima_thread.c index 249ccb3a..94a2113f 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_thread.c @@ -129,7 +129,7 @@ VOID _ux_device_class_pima_thread(ULONG pima_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_PIMA *pima; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; @@ -142,10 +142,10 @@ UINT status; /* Cast properly the pima instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, pima_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, pima_class) /* Get the pima instance from this class container. */ - pima = (UX_SLAVE_CLASS_PIMA *) class -> ux_slave_class_instance; + pima = (UX_SLAVE_CLASS_PIMA *) class_ptr -> ux_slave_class_instance; /* Allocate some memory for the thread stack. */ pima -> ux_device_class_pima_interrupt_thread_stack = @@ -491,7 +491,7 @@ UINT status; } /* We need to suspend ourselves. We will be resumed by the device enumeration module. */ - _ux_device_thread_suspend(&class -> ux_slave_class_thread); + _ux_device_thread_suspend(&class_ptr -> ux_slave_class_thread); } } #endif diff --git a/common/usbx_device_classes/src/ux_device_class_printer_activate.c b/common/usbx_device_classes/src/ux_device_class_printer_activate.c index dcc90752..f004d660 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -64,14 +64,18 @@ /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_activate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; -UX_DEVICE_CLASS_PRINTER *printer; +UX_SLAVE_INTERFACE *printer_interface; UX_SLAVE_CLASS *printer_class; +UX_DEVICE_CLASS_PRINTER *printer; UX_SLAVE_ENDPOINT *endpoint; /* Get the class container. */ @@ -81,18 +85,18 @@ UX_SLAVE_ENDPOINT *endpoint; printer = (UX_DEVICE_CLASS_PRINTER *) printer_class -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + printer_interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)printer; + printer_interface -> ux_slave_interface_class_instance = (VOID *)printer; /* Now the opposite, store the interface in the class instance. */ - printer -> ux_device_class_printer_interface = interface; + printer -> ux_device_class_printer_interface = printer_interface; /* Save endpoints for future use. */ printer -> ux_device_class_printer_endpoint_in = UX_NULL; printer -> ux_device_class_printer_endpoint_out = UX_NULL; - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = printer_interface -> ux_slave_interface_first_endpoint; while(endpoint) { if (endpoint -> ux_slave_endpoint_descriptor.bmAttributes == UX_BULK_ENDPOINT) diff --git a/common/usbx_device_classes/src/ux_device_class_printer_control_request.c b/common/usbx_device_classes/src/ux_device_class_printer_control_request.c index 3a424f19..9df6fd8d 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_control_request.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_control_request PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,13 +69,17 @@ /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_control_request(UX_SLAVE_CLASS_COMMAND *command) { UX_DEVICE_CLASS_PRINTER *printer; UX_SLAVE_CLASS *printer_class; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *printer_interface; UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; ULONG request; @@ -96,7 +100,7 @@ UCHAR found; printer = (UX_DEVICE_CLASS_PRINTER *) printer_class -> ux_slave_class_instance; /* Get the interface. */ - interface = printer_class -> ux_slave_class_interface; + printer_interface = printer_class -> ux_slave_class_interface; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; @@ -127,7 +131,7 @@ UCHAR found; - wIndex_high == interface (already checked before entry, index of interface should equal to interface number) - wIndex_low == alternate */ - if (index_low != (UCHAR)interface -> ux_slave_interface_descriptor.bAlternateSetting) + if (index_low != (UCHAR)printer_interface -> ux_slave_interface_descriptor.bAlternateSetting) return(UX_ERROR); /* Check config index. */ diff --git a/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c index 9905f2aa..1ff77aae 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_uninitialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,19 +68,23 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND *command) { UX_DEVICE_CLASS_PRINTER *printer; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - printer = (UX_DEVICE_CLASS_PRINTER *) class -> ux_slave_class_instance; + printer = (UX_DEVICE_CLASS_PRINTER *) class_ptr -> ux_slave_class_instance; /* Sanity check. */ if (printer != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_printer_write.c b/common/usbx_device_classes/src/ux_device_class_printer_write.c index 5b1a595a..2c109583 100644 --- a/common/usbx_device_classes/src/ux_device_class_printer_write.c +++ b/common/usbx_device_classes/src/ux_device_class_printer_write.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_printer_write PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -48,7 +48,8 @@ /* printer Address of printer class */ /* instance */ /* buffer Pointer to data to write */ -/* requested_length Length of bytes to write */ +/* requested_length Length of bytes to write, */ +/* set to 0 to issue ZLP */ /* actual_length Pointer to save number of */ /* bytes written */ /* */ @@ -75,6 +76,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added auto ZLP support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_printer_write(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer, @@ -85,6 +89,7 @@ UX_SLAVE_ENDPOINT *endpoint; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; ULONG local_requested_length; +ULONG local_host_length; UINT status = 0; /* If trace is enabled, insert this event into the trace buffer. */ @@ -138,6 +143,7 @@ UINT status = 0; } /* Check if we need more transactions. */ + local_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED && requested_length != 0) { @@ -149,10 +155,22 @@ UINT status = 0; local_requested_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH; else + { /* We can proceed with the demanded length. */ local_requested_length = requested_length; +#if !defined(UX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP) + + /* Assume expected length matches. */ + local_host_length = requested_length; +#else + + /* Assume expected more so stack appends ZLP if needed. */ + local_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1; +#endif + } + /* On a out, we copy the buffer to the caller. Not very efficient but it makes the API easier. */ _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer, @@ -160,7 +178,7 @@ UINT status = 0; /* Send the request to the device controller. */ status = _ux_device_stack_transfer_request(transfer_request, - local_requested_length, local_requested_length); + local_requested_length, local_host_length); /* Check the status */ if (status == UX_SUCCESS) diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_activate.c b/common/usbx_device_classes/src/ux_device_class_rndis_activate.c index 3e0c266b..c8e3f0c0 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_rndis_activate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_rndis_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -84,31 +88,31 @@ UINT _ux_device_class_rndis_activate(UX_SLAVE_CLASS_COMMAND *command) return(UX_FUNCTION_NOT_SUPPORTED); #else -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_RNDIS *rndis; -UX_SLAVE_CLASS *class; UX_SLAVE_ENDPOINT *endpoint; ULONG physical_address_msw; ULONG physical_address_lsw; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - rndis = (UX_SLAVE_CLASS_RNDIS *) class -> ux_slave_class_instance; + rndis = (UX_SLAVE_CLASS_RNDIS *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Check if this is the Control or Data interface. */ if (command -> ux_slave_class_command_class == UX_DEVICE_CLASS_RNDIS_CLASS_COMMUNICATION_CONTROL) { /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)rndis; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)rndis; /* Now the opposite, store the interface in the class instance. */ - rndis -> ux_slave_class_rndis_interface = interface; + rndis -> ux_slave_class_rndis_interface = interface_ptr; /* If there is a activate function call it. */ if (rndis -> ux_slave_class_rndis_parameter.ux_slave_class_rndis_instance_activate != UX_NULL) @@ -119,10 +123,10 @@ ULONG physical_address_lsw; else /* This is the DATA Class, only store the rndis instance in the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)rndis; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)rndis; /* Locate the endpoints. Interrupt for Control and Bulk in/out for Data. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all endpoints. */ while (endpoint != UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c index 1dbb7001..be900a96 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c @@ -90,7 +90,7 @@ VOID _ux_device_class_rndis_bulkin_thread(ULONG rndis_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_RNDIS *rndis; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; @@ -101,10 +101,10 @@ UCHAR *packet_header; ULONG transfer_length; /* Cast properly the rndis instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, rndis_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, rndis_class) /* Get the rndis instance from this class container. */ - rndis = (UX_SLAVE_CLASS_RNDIS *) class -> ux_slave_class_instance; + rndis = (UX_SLAVE_CLASS_RNDIS *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c index 4647933b..a569e5f5 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c @@ -89,7 +89,7 @@ VOID _ux_device_class_rndis_bulkout_thread(ULONG rndis_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_RNDIS *rndis; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; @@ -99,10 +99,10 @@ ULONG ip_given_length; ULONG packet_payload; /* Cast properly the rndis instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, rndis_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, rndis_class) /* Get the rndis instance from this class container. */ - rndis = (UX_SLAVE_CLASS_RNDIS *) class -> ux_slave_class_instance; + rndis = (UX_SLAVE_CLASS_RNDIS *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_control_request.c b/common/usbx_device_classes/src/ux_device_class_rndis_control_request.c index 2e4de2d7..be0a300d 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_control_request.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_rndis_control_request PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -89,6 +89,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_rndis_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -100,7 +104,7 @@ UX_SLAVE_DEVICE *device; ULONG request; ULONG request_length; ULONG rndis_command; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_RNDIS *rndis; /* Get the pointer to the device. */ @@ -114,10 +118,10 @@ UX_SLAVE_CLASS_RNDIS *rndis; request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH); /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the rndis instance from this class container. */ - rndis = (UX_SLAVE_CLASS_RNDIS *) class -> ux_slave_class_instance; + rndis = (UX_SLAVE_CLASS_RNDIS *) class_ptr -> ux_slave_class_instance; /* Here we proceed only the standard request we know of at the device level. */ switch (request) diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_deactivate.c b/common/usbx_device_classes/src/ux_device_class_rndis_deactivate.c index 466e52a3..bc22a8b0 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_rndis_deactivate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,30 +78,34 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_rndis_deactivate(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_RNDIS *rndis; -UX_SLAVE_INTERFACE *interface; -UX_SLAVE_CLASS *class; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - rndis = (UX_SLAVE_CLASS_RNDIS *) class -> ux_slave_class_instance; + rndis = (UX_SLAVE_CLASS_RNDIS *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. Normally the interface can be derived from the class instance but since RNDIS has 2 interfaces and we only store the Control interface in the class container, we used the class_command pointer to retrieve the correct interface which issued the deactivation. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Check if this is the Control or Data interface. We only need to dismount the link and abort the transfer once for the 2 classes. */ - if (interface -> ux_slave_interface_descriptor.bInterfaceClass == UX_DEVICE_CLASS_RNDIS_CLASS_COMMUNICATION_CONTROL) + if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceClass == UX_DEVICE_CLASS_RNDIS_CLASS_COMMUNICATION_CONTROL) { /* Declare the link to be down. That may need to change later to make it dependant on the diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c b/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c index f795b098..8af77324 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c @@ -78,7 +78,7 @@ ULONG ux_device_class_rndis_oid_supported_list[UX_DEVICE_CLASS_RNDIS_OID_SUPPORT /* FUNCTION RELEASE */ /* */ /* _ux_device_class_rndis_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -132,6 +132,10 @@ ULONG ux_device_class_rndis_oid_supported_list[UX_DEVICE_CLASS_RNDIS_OID_SUPPORT /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_rndis_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -143,11 +147,11 @@ UINT _ux_device_class_rndis_initialize(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_CLASS_RNDIS *rndis; UX_SLAVE_CLASS_RNDIS_PARAMETER *rndis_parameter; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UINT status; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Create an instance of the device rndis class. */ rndis = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_RNDIS)); @@ -157,7 +161,7 @@ UINT status; return(UX_MEMORY_INSUFFICIENT); /* Save the address of the RNDIS instance inside the RNDIS container. */ - class -> ux_slave_class_instance = (VOID *) rndis; + class_ptr -> ux_slave_class_instance = (VOID *) rndis; /* Get the pointer to the application parameters for the rndis class. */ rndis_parameter = command -> ux_slave_class_command_parameter; @@ -211,7 +215,7 @@ UINT status; { status = _ux_device_thread_create(&rndis -> ux_slave_class_rndis_interrupt_thread , "ux_slave_class_rndis_interrupt_thread", _ux_device_class_rndis_interrupt_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) rndis -> ux_slave_class_rndis_interrupt_thread_stack , + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) rndis -> ux_slave_class_rndis_interrupt_thread_stack , UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); @@ -220,7 +224,7 @@ UINT status; status = UX_THREAD_ERROR; } - UX_THREAD_EXTENSION_PTR_SET(&(rndis -> ux_slave_class_rndis_interrupt_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(rndis -> ux_slave_class_rndis_interrupt_thread), class_ptr) /* Allocate some memory for the bulk out thread stack. */ if (status == UX_SUCCESS) @@ -240,7 +244,7 @@ UINT status; { status = _ux_device_thread_create(&rndis -> ux_slave_class_rndis_bulkout_thread , "ux_slave_class_rndis_bulkout_thread", _ux_device_class_rndis_bulkout_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) rndis -> ux_slave_class_rndis_bulkout_thread_stack , + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) rndis -> ux_slave_class_rndis_bulkout_thread_stack , UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); @@ -249,7 +253,7 @@ UINT status; status = UX_THREAD_ERROR; } - UX_THREAD_EXTENSION_PTR_SET(&(rndis -> ux_slave_class_rndis_bulkout_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(rndis -> ux_slave_class_rndis_bulkout_thread), class_ptr) /* Allocate some memory for the bulk in thread stack. */ if (status == UX_SUCCESS) @@ -269,7 +273,7 @@ UINT status; { status = _ux_device_thread_create(&rndis -> ux_slave_class_rndis_bulkin_thread , "ux_slave_class_rndis_bulkin_thread", _ux_device_class_rndis_bulkin_thread, - (ULONG) (ALIGN_TYPE) class, (VOID *) rndis -> ux_slave_class_rndis_bulkin_thread_stack , + (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) rndis -> ux_slave_class_rndis_bulkin_thread_stack , UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); @@ -278,7 +282,7 @@ UINT status; status = UX_THREAD_ERROR; } - UX_THREAD_EXTENSION_PTR_SET(&(rndis -> ux_slave_class_rndis_bulkin_thread), class) + UX_THREAD_EXTENSION_PTR_SET(&(rndis -> ux_slave_class_rndis_bulkin_thread), class_ptr) /* Create a event flag group for the rndis class to synchronize with the event interrupt thread. */ if (status == UX_SUCCESS) diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_interrupt_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_interrupt_thread.c index 9352afaa..8d9b3f5a 100644 --- a/common/usbx_device_classes/src/ux_device_class_rndis_interrupt_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_rndis_interrupt_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_rndis_interrupt_thread PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,23 +79,27 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_device_class_rndis_interrupt_thread(ULONG rndis_class) { -UX_SLAVE_CLASS *class; -UX_SLAVE_CLASS_RNDIS *rndis; +UX_SLAVE_CLASS *class_ptr; +UX_SLAVE_CLASS_RNDIS *rndis; UX_SLAVE_DEVICE *device; UX_SLAVE_TRANSFER *transfer_request; UINT status; ULONG actual_flags; /* Cast properly the rndis instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, rndis_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, rndis_class) /* Get the rndis instance from this class container. */ - rndis = (UX_SLAVE_CLASS_RNDIS *) class -> ux_slave_class_instance; + rndis = (UX_SLAVE_CLASS_RNDIS *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; diff --git a/common/usbx_device_classes/src/ux_device_class_storage_activate.c b/common/usbx_device_classes/src/ux_device_class_storage_activate.c index fcb732c6..e0762300 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,45 +70,49 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_activate(UX_SLAVE_CLASS_COMMAND *command) { UINT status = UX_SUCCESS; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_STORAGE *storage; -UX_SLAVE_CLASS *class_inst; #if defined(UX_DEVICE_STANDALONE) UX_SLAVE_ENDPOINT *endpoint; #endif /* Get the class container. */ - class_inst = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - storage = (UX_SLAVE_CLASS_STORAGE *)class_inst -> ux_slave_class_instance; + storage = (UX_SLAVE_CLASS_STORAGE *)class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)storage; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)storage; /* Now the opposite, store the interface in the class instance. */ - storage -> ux_slave_class_storage_interface = interface; + storage -> ux_slave_class_storage_interface = interface_ptr; #if !defined(UX_DEVICE_STANDALONE) /* Resume thread. */ - _ux_device_thread_resume(&class_inst -> ux_slave_class_thread); + _ux_device_thread_resume(&class_ptr -> ux_slave_class_thread); #else /* Locate the endpoints. */ /* Check the first endpoint direction, if IN we have the correct endpoint. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) { diff --git a/common/usbx_device_classes/src/ux_device_class_storage_control_request.c b/common/usbx_device_classes/src/ux_device_class_storage_control_request.c index 7b695d99..ffca3b11 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_control_request.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_control_request PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -76,6 +76,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -83,13 +87,13 @@ UINT _ux_device_class_storage_control_request(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; ULONG request; ULONG request_value; ULONG request_length; UX_SLAVE_CLASS_STORAGE *storage; #if !defined(UX_DEVICE_STANDALONE) -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; #endif UX_SLAVE_ENDPOINT *endpoint_in; UX_SLAVE_ENDPOINT *endpoint_out; @@ -111,10 +115,10 @@ UX_SLAVE_ENDPOINT *endpoint_out; return(UX_ERROR); /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the storage instance from this class container. */ - storage = (UX_SLAVE_CLASS_STORAGE *) class -> ux_slave_class_instance; + storage = (UX_SLAVE_CLASS_STORAGE *) class_ptr -> ux_slave_class_instance; /* Here we proceed only the standard request we know of at the device level. */ switch (request) @@ -132,10 +136,10 @@ UX_SLAVE_ENDPOINT *endpoint_out; #else /* We need the interface to the class. */ - interface = storage -> ux_slave_class_storage_interface; - + interface_ptr = storage -> ux_slave_class_storage_interface; + /* Locate the endpoints. */ - endpoint_in = interface -> ux_slave_interface_first_endpoint; + endpoint_in = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) @@ -154,7 +158,7 @@ UX_SLAVE_ENDPOINT *endpoint_out; endpoint_out = endpoint_in -> ux_slave_endpoint_next_endpoint; } #endif - + /* First cancel any transfer on the endpoint OUT, from the host. */ transfer_request = &endpoint_out -> ux_slave_endpoint_transfer_request; _ux_device_stack_transfer_abort(transfer_request, UX_TRANSFER_APPLICATION_RESET); diff --git a/common/usbx_device_classes/src/ux_device_class_storage_deactivate.c b/common/usbx_device_classes/src/ux_device_class_storage_deactivate.c index beee747e..3592ce51 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_deactivate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_deactivate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_deactivate(UX_SLAVE_CLASS_COMMAND *command) @@ -78,13 +82,13 @@ UINT _ux_device_class_storage_deactivate(UX_SLAVE_CLASS_COMMAND *command) UX_SLAVE_CLASS_STORAGE *storage; UX_SLAVE_ENDPOINT *endpoint_in; UX_SLAVE_ENDPOINT *endpoint_out; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - storage = (UX_SLAVE_CLASS_STORAGE *)class -> ux_slave_class_instance; + storage = (UX_SLAVE_CLASS_STORAGE *)class_ptr -> ux_slave_class_instance; #if defined(UX_DEVICE_STANDALONE) diff --git a/common/usbx_device_classes/src/ux_device_class_storage_inquiry.c b/common/usbx_device_classes/src/ux_device_class_storage_inquiry.c index 71f4e73d..d266e67d 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_inquiry.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_inquiry.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_inquiry PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -88,6 +88,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* updated dCSWDataResidue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_inquiry(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, @@ -195,7 +198,7 @@ UCHAR *inquiry_buffer; break; default: - + #if !defined(UX_DEVICE_STANDALONE) /* The page code is not supported. */ _ux_device_stack_endpoint_stall(endpoint_in); @@ -238,6 +241,7 @@ UCHAR *inquiry_buffer; /* Check length. */ if (storage -> ux_slave_class_storage_host_length != inquiry_length) { + storage -> ux_slave_class_storage_csw_residue = storage -> ux_slave_class_storage_host_length - inquiry_length; _ux_device_stack_endpoint_stall(endpoint_in); } #endif diff --git a/common/usbx_device_classes/src/ux_device_class_storage_thread.c b/common/usbx_device_classes/src/ux_device_class_storage_thread.c index 9bf65ffe..0ff75a75 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_thread.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_thread PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -123,16 +123,20 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_device_class_storage_thread(ULONG storage_class) { -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_CLASS_STORAGE *storage; UX_SLAVE_TRANSFER *transfer_request; UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_ENDPOINT *endpoint_in; UX_SLAVE_ENDPOINT *endpoint_out; UINT status; @@ -148,10 +152,10 @@ UCHAR *cbw_cb; { /* Cast properly the storage instance. */ - UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, storage_class) + UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, storage_class) /* Get the storage instance from this class container. */ - storage = (UX_SLAVE_CLASS_STORAGE *) class -> ux_slave_class_instance; + storage = (UX_SLAVE_CLASS_STORAGE *) class_ptr -> ux_slave_class_instance; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; @@ -161,13 +165,13 @@ UCHAR *cbw_cb; { /* We are activated. We need the interface to the class. */ - interface = storage -> ux_slave_class_storage_interface; + interface_ptr = storage -> ux_slave_class_storage_interface; /* We assume the worst situation. */ status = UX_ERROR; /* Locate the endpoints. */ - endpoint_in = interface -> ux_slave_interface_first_endpoint; + endpoint_in = interface_ptr -> ux_slave_interface_first_endpoint; /* Check the endpoint direction, if IN we have the correct endpoint. */ if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) @@ -458,7 +462,7 @@ UCHAR *cbw_cb; /* We need to suspend ourselves. We will be resumed by the device enumeration module. */ - _ux_device_thread_suspend(&class -> ux_slave_class_thread); + _ux_device_thread_suspend(&class_ptr -> ux_slave_class_thread); } } #endif diff --git a/common/usbx_device_classes/src/ux_device_class_storage_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_storage_uninitialize.c index 61cb4d7d..5931caf2 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_uninitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_uninitialize.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_uninitialize PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,30 +71,34 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_storage_uninitialize(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_CLASS_STORAGE *storage; -UX_SLAVE_CLASS *class; +UX_SLAVE_CLASS *class_ptr; /* Get the class container. */ - class = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - storage = (UX_SLAVE_CLASS_STORAGE *) class -> ux_slave_class_instance; + storage = (UX_SLAVE_CLASS_STORAGE *) class_ptr -> ux_slave_class_instance; /* Sanity check. */ if (storage != UX_NULL) { /* Remove STORAGE thread. */ - _ux_device_thread_delete(&class -> ux_slave_class_thread); + _ux_device_thread_delete(&class_ptr -> ux_slave_class_thread); #if !(defined(UX_DEVICE_STANDALONE) || defined(UX_STANDALONE)) /* Remove the thread used by STORAGE. */ - _ux_utility_memory_free(class -> ux_slave_class_thread_stack); + _ux_utility_memory_free(class_ptr -> ux_slave_class_thread_stack); #endif /* Free the resources. */ diff --git a/common/usbx_device_classes/src/ux_device_class_storage_write.c b/common/usbx_device_classes/src/ux_device_class_storage_write.c index 50edd817..59343ba4 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_write.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_write.c @@ -294,7 +294,7 @@ ULONG done_length; /* Now we set the CSW with success. */ storage -> ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PASSED; - + /* Return completion status. */ return(status); } diff --git a/common/usbx_device_classes/src/ux_device_class_video_activate.c b/common/usbx_device_classes/src/ux_device_class_video_activate.c index 07681fbb..80e71f62 100644 --- a/common/usbx_device_classes/src/ux_device_class_video_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_video_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_video_activate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -63,53 +63,57 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_video_activate(UX_SLAVE_CLASS_COMMAND *command) { UX_SLAVE_DEVICE *device; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_INTERFACE *interface_ptr; +UX_SLAVE_CLASS *class_ptr; UX_SLAVE_INTERFACE *control_interface; UX_SLAVE_INTERFACE *stream_interface; UX_DEVICE_CLASS_VIDEO *video; UX_DEVICE_CLASS_VIDEO_STREAM *stream; -UX_SLAVE_CLASS *class_inst; ULONG stream_index; /* Get the class container. */ - class_inst = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - video = (UX_DEVICE_CLASS_VIDEO *) class_inst -> ux_slave_class_instance; + video = (UX_DEVICE_CLASS_VIDEO *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Get the device instance. */ device = &_ux_system_slave -> ux_system_slave_device; video -> ux_device_class_video_device = device; /* We only support video interface here. */ - if (interface -> ux_slave_interface_descriptor.bInterfaceClass != UX_DEVICE_CLASS_VIDEO_CLASS) + if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceClass != UX_DEVICE_CLASS_VIDEO_CLASS) return(UX_NO_CLASS_MATCH); /* It's control interface? */ - if (interface -> ux_slave_interface_descriptor.bInterfaceSubClass == UX_DEVICE_CLASS_VIDEO_SUBCLASS_CONTROL) + if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceSubClass == UX_DEVICE_CLASS_VIDEO_SUBCLASS_CONTROL) { /* Store the interface in the class instance. */ - video -> ux_device_class_video_interface = interface; + video -> ux_device_class_video_interface = interface_ptr; /* Store the class instance into the interface. */ - interface -> ux_slave_interface_class_instance = (VOID *)video; + interface_ptr -> ux_slave_interface_class_instance = (VOID *)video; } else { /* It's streaming interface. */ - stream_interface = interface; + stream_interface = interface_ptr; /* Separate driver for each interface (IAD not used)? */ if (video -> ux_device_class_video_interface == UX_NULL) diff --git a/common/usbx_device_classes/src/ux_device_class_video_change.c b/common/usbx_device_classes/src/ux_device_class_video_change.c index 723773e1..199fcc62 100644 --- a/common/usbx_device_classes/src/ux_device_class_video_change.c +++ b/common/usbx_device_classes/src/ux_device_class_video_change.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_video_change PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -63,6 +63,10 @@ /* DATE NAME DESCRIPTION */ /* */ /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_device_class_video_change(UX_SLAVE_CLASS_COMMAND *command) @@ -70,28 +74,28 @@ UINT _ux_device_class_video_change(UX_SLAVE_CLASS_COMMAND *command) UX_DEVICE_CLASS_VIDEO *video; UX_DEVICE_CLASS_VIDEO_STREAM *stream; -UX_SLAVE_CLASS *class_inst; -UX_SLAVE_INTERFACE *interface; +UX_SLAVE_CLASS *class_ptr; +UX_SLAVE_INTERFACE *interface_ptr; UX_SLAVE_ENDPOINT *endpoint; UCHAR *payload_buffer; ULONG stream_index; /* Get the class container. */ - class_inst = command -> ux_slave_class_command_class_ptr; + class_ptr = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ - video = (UX_DEVICE_CLASS_VIDEO *) class_inst -> ux_slave_class_instance; + video = (UX_DEVICE_CLASS_VIDEO *) class_ptr -> ux_slave_class_instance; /* Get the interface that owns this instance. */ - interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; + interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; /* Get the interface number (base 0). */ if (video -> ux_device_class_video_interface) { /* If IAD used, calculate stream index based on interface number. */ - stream_index = interface -> ux_slave_interface_descriptor.bInterfaceNumber; + stream_index = interface_ptr -> ux_slave_interface_descriptor.bInterfaceNumber; stream_index -= video -> ux_device_class_video_interface -> ux_slave_interface_descriptor.bInterfaceNumber; stream_index --; } @@ -104,16 +108,16 @@ ULONG stream_index; stream = &video -> ux_device_class_video_streams[stream_index]; /* Update the interface. */ - stream -> ux_device_class_video_stream_interface = interface; + stream -> ux_device_class_video_stream_interface = interface_ptr; /* If the interface to mount has a non zero alternate setting, the class is really active with the endpoints active. If the interface reverts to alternate setting 0, it needs to have the pending transactions terminated. */ - if (interface -> ux_slave_interface_descriptor.bAlternateSetting != 0) + if (interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting != 0) { /* Locate the endpoints. ISO IN/OUT for Streaming Interface. */ - endpoint = interface -> ux_slave_interface_first_endpoint; + endpoint = interface_ptr -> ux_slave_interface_first_endpoint; /* Parse all endpoints. */ stream -> ux_device_class_video_stream_endpoint = UX_NULL; @@ -184,7 +188,7 @@ ULONG stream_index; /* Invoke stream change callback. */ if (stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_change) - stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_change(stream, interface -> ux_slave_interface_descriptor.bAlternateSetting); + stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_change(stream, interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting); /* Return completion status. */ return(UX_SUCCESS); diff --git a/common/usbx_host_classes/CMakeLists.txt b/common/usbx_host_classes/CMakeLists.txt index 48ac6b1a..47420899 100644 --- a/common/usbx_host_classes/CMakeLists.txt +++ b/common/usbx_host_classes/CMakeLists.txt @@ -16,15 +16,27 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_alternate_setting_locate.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_configure.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_control_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_control_request.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_control_value_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_control_value_set.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_deactivate.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_descriptor_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_descriptors_parse.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_device_controls_list_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_device_type_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_endpoints_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_entity_control_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_entity_control_value_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_entity_control_value_set.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_entry.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_feedback_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_feedback_set.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_feedback_transfer_completed.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_interrupt_notification.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_interrupt_start.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_raw_sampling_parse.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_read.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_stop.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_streaming_sampling_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_streaming_sampling_set.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_audio_streaming_terminal_get.c @@ -140,6 +152,7 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hub_port_reset.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hub_ports_power.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hub_status_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hub_tasks_run.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hub_transfer_request_completed.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_pima_activate.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_pima_command.c diff --git a/common/usbx_host_classes/inc/ux_host_class_audio.h b/common/usbx_host_classes/inc/ux_host_class_audio.h index 476bd7b9..a21adcdc 100644 --- a/common/usbx_host_classes/inc/ux_host_class_audio.h +++ b/common/usbx_host_classes/inc/ux_host_class_audio.h @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Audio Class */ /** */ @@ -21,25 +21,25 @@ /**************************************************************************/ -/**************************************************************************/ -/* */ -/* COMPONENT DEFINITION RELEASE */ -/* */ -/* ux_host_class_audio.h PORTABLE C */ -/* 6.1.8 */ +/**************************************************************************/ +/* */ +/* COMPONENT DEFINITION RELEASE */ +/* */ +/* ux_host_class_audio.h PORTABLE C */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ +/* */ /* This file contains all the header and extern functions used by the */ -/* USBX audio class. */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* USBX audio class. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* used UX prefix to refer to */ @@ -50,39 +50,79 @@ /* added extern "C" keyword */ /* for compatibility with C++, */ /* resulting in version 6.1.8 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added interrupt support, */ +/* used interface protocol, */ +/* protect reentry with mutex, */ +/* added feedback support, */ +/* added Audio 2.0 support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ #ifndef UX_HOST_CLASS_AUDIO_H #define UX_HOST_CLASS_AUDIO_H -/* Determine if a C++ compiler is being used. If so, ensure that standard - C is used to process the API information. */ +/* Determine if a C++ compiler is being used. If so, ensure that standard + C is used to process the API information. */ -#ifdef __cplusplus +#ifdef __cplusplus -/* Yes, C++ compiler is present. Use standard C. */ -extern "C" { +/* Yes, C++ compiler is present. Use standard C. */ +extern "C" { -#endif +#endif + +/* Defined, it enables UAC 2.0 support. */ +/* #define UX_HOST_CLASS_AUDIO_2_SUPPORT */ + +/* Defined, it enables feedback endpoint support. */ +/* #define UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT */ + +/* Defined, it enables optional interrupt endpoint support. */ +/* #define UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT */ +/* Defined, it disables control_get/value_get/value_set and related code (to optimize code size). */ +/* #define UX_HOST_CLASS_AUDIO_DISABLE_CONTROLS */ + +#include "ux_class_audio10.h" +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) +#include "ux_class_audio20.h" +#endif /* Define Audio Class main constants. */ -#define UX_HOST_CLASS_AUDIO_CLASS_TRANSFER_TIMEOUT 30 +#define UX_HOST_CLASS_AUDIO_CLASS_TRANSFER_TIMEOUT 30 + #define UX_HOST_CLASS_AUDIO_CLASS 1 #define UX_HOST_CLASS_AUDIO_SUBCLASS_UNDEFINED 0 #define UX_HOST_CLASS_AUDIO_SUBCLASS_CONTROL 1 #define UX_HOST_CLASS_AUDIO_SUBCLASS_STREAMING 2 #define UX_HOST_CLASS_AUDIO_SUBCLASS_MIDI_STREAMING 3 #define UX_HOST_CLASS_AUDIO_PROTOCOL_UNDEFINED 0 - +#define UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_01_00 0x00 +#define UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00 0x20 +#define UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_03_00 0x30 +#define UX_HOST_CLASS_AUDIO_PROTOCOL_AF_VERSION_01_00 UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_01_00 +#define UX_HOST_CLASS_AUDIO_PROTOCOL_AF_VERSION_02_00 UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00 +#define UX_HOST_CLASS_AUDIO_PROTOCOL_AF_VERSION_03_00 UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_03_00 + +#define UX_HOST_CLASS_AUDIO_FUNCTION UX_HOST_CLASS_AUDIO_CLASS +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_UNDEFINED 0x00 +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_FULL_ADC_3_0 0x01 +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_GENERIC_I_O 0x20 +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_HEADPHONE 0x21 +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_SPEAKER 0x22 +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_MICROPHONE 0x23 +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_HEADSET 0x24 +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_HEADSET_ADAPTER 0x25 +#define UX_HOST_CLASS_AUDIO_FUNCTION_SUBCLASS_SPEAKERPHONE 0x26 /* Define Audio Class main descriptor types. */ #define UX_HOST_CLASS_AUDIO_CS_UNDEFINED 0x20 #define UX_HOST_CLASS_AUDIO_CS_DEVICE 0x21 -#define UX_HOST_CLASS_AUDIO_CS_CONFIGURATION 0x22 +#define UX_HOST_CLASS_AUDIO_CS_CONFIGURATION 0x22 #define UX_HOST_CLASS_AUDIO_CS_STRING 0x23 #define UX_HOST_CLASS_AUDIO_CS_INTERFACE 0x24 #define UX_HOST_CLASS_AUDIO_CS_ENDPOINT 0x25 @@ -198,24 +238,41 @@ extern "C" { /* Define Audio Class telephony terminal types. */ -#define UX_HOST_CLASS_AUDIO_TELEPHONTY_UNDEFINED 0x0400 -#define UX_HOST_CLASS_AUDIO_PHONE_LINE 0x0401 -#define UX_HOST_CLASS_AUDIO_TELEPHONE 0x0402 -#define UX_HOST_CLASS_AUDIO_DOWN_LINE_PHONE 0x0403 +#define UX_HOST_CLASS_AUDIO_TELEPHONTY_UNDEFINED 0x0500 +#define UX_HOST_CLASS_AUDIO_PHONE_LINE 0x0501 +#define UX_HOST_CLASS_AUDIO_TELEPHONE 0x0502 +#define UX_HOST_CLASS_AUDIO_DOWN_LINE_PHONE 0x0503 +/* Define Audio Class external terminal types. */ /* Define Audio Class encoding format types. */ +/* Audio 1.0 Format Type Codes. */ #define UX_HOST_CLASS_AUDIO_FORMAT_TYPE_UNDEFINED 0 #define UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I 1 #define UX_HOST_CLASS_AUDIO_FORMAT_TYPE_II 2 #define UX_HOST_CLASS_AUDIO_FORMAT_TYPE_III 3 +/* Audio 1.0 CS AS Interface Descriptor Type I wFormatTag. */ #define UX_HOST_CLASS_AUDIO_FORMAT_PCM 1 #define UX_HOST_CLASS_AUDIO_FORMAT_PCM8 2 #define UX_HOST_CLASS_AUDIO_FORMAT_IEEE_FLOAT 3 #define UX_HOST_CLASS_AUDIO_FORMAT_ALAW 4 #define UX_HOST_CLASS_AUDIO_FORMAT_MULAW 5 +/* Audio 1.0 CS AS Interface Descriptor Type II wFormatTag. */ +#define UX_HOST_CLASS_AUDIO_FORMAT_TYPE_II_UNDEFINED 0x1000 +#define UX_HOST_CLASS_AUDIO_FORMAT_MPEG 0x1001 +#define UX_HOST_CLASS_AUDIO_FORMAT_AC_3 0x1002 +/* Audio 1.0 CS AS Interface Descriptor Type III wFormatTag. */ +#define UX_HOST_CLASS_AUDIO_FORMAT_TYPE_III_UNDEFINED 0x2000 +#define UX_HOST_CLASS_AUDIO_FORMAT_IEC1937_AC_3 0x2001 +#define UX_HOST_CLASS_AUDIO_FORMAT_IEC1937_MPEG_1_LAYER_1 0x2002 +#define UX_HOST_CLASS_AUDIO_FORMAT_IEC1937_MPEG_1_L2_3_MPEG_2_NOEXT 0x2003 +#define UX_HOST_CLASS_AUDIO_FORMAT_IEC1937_MPEG_2_EXT 0x2004 +#define UX_HOST_CLASS_AUDIO_FORMAT_IEC1937_MPEG_2_LAYER_1_LS 0x2005 +#define UX_HOST_CLASS_AUDIO_FORMAT_IEC1937_MPEG_2_LAYER_2_3_LS 0x2006 + +/* Audio 1.0 descriptor structs. */ #define UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_ENTRIES 8 #define UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH 8 @@ -332,34 +389,98 @@ typedef struct UX_HOST_CLASS_AUDIO_STREAMING_ENDPOINT_DESCRIPTOR_STRUCT } UX_HOST_CLASS_AUDIO_STREAMING_ENDPOINT_DESCRIPTOR; +/* Define Audio Class audio control (AC) instance structure. */ +typedef struct UX_HOST_CLASS_AUDIO_AC_STRUCT +{ + + /* Common fields for _AUDIO and _AUDIO_AC, + * check pointed interface subclass (_ux_host_class_audio_subclass_get()) to + * see remaining fields after interface pointer. */ + struct UX_HOST_CLASS_AUDIO_STRUCT + *ux_host_class_audio_next_instance; + UX_HOST_CLASS *ux_host_class_audio_class; + UX_INTERFACE *ux_host_class_audio_interface; + + UX_DEVICE *ux_host_class_audio_device; + UCHAR * ux_host_class_audio_configuration_descriptor; + ULONG ux_host_class_audio_configuration_descriptor_length; + + /* Fields for _AUDIO_CONTROL_BLOCK (control instance). */ + UX_ENDPOINT *ux_host_class_audio_interrupt_endpoint; + VOID (*ux_host_class_audio_interrupt_callback)(struct UX_HOST_CLASS_AUDIO_AC_STRUCT*ac, UCHAR*msg, ULONG len, VOID*arg); + VOID *ux_host_class_audio_interrupt_callback_arg; + UINT ux_host_class_audio_interrupt_started; + + UINT ux_host_class_audio_as_count; + struct UX_HOST_CLASS_AUDIO_STRUCT + *ux_host_class_audio_as[2]; /* By default allocate 2, actual length depends on _audio_as_count. */ +} UX_HOST_CLASS_AUDIO_AC; + /* Define Audio Class instance structure. */ typedef struct UX_HOST_CLASS_AUDIO_STRUCT { - struct UX_HOST_CLASS_AUDIO_STRUCT + /* Common fields for _AUDIO and _AUDIO_AC, + * check pointed interface subclass (_ux_host_class_audio_subclass_get()) to + * see remaining fields after interface pointer. */ + struct UX_HOST_CLASS_AUDIO_STRUCT *ux_host_class_audio_next_instance; UX_HOST_CLASS *ux_host_class_audio_class; - UX_DEVICE *ux_host_class_audio_device; UX_INTERFACE *ux_host_class_audio_streaming_interface; + + UX_DEVICE *ux_host_class_audio_device; + UCHAR * ux_host_class_audio_configuration_descriptor; + ULONG ux_host_class_audio_configuration_descriptor_length; + + /* Fields for _AUDIO (streaming instance). */ ULONG ux_host_class_audio_control_interface_number; + UCHAR *ux_host_class_audio_sampling_descriptor; /* UAC1.0: FormatTypeI Descriptor, UAC2.0: Clock Source Descriptor. */ UX_ENDPOINT *ux_host_class_audio_isochronous_endpoint; - struct UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST_STRUCT +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + UX_ENDPOINT *ux_host_class_audio_feedback_endpoint; + UCHAR ux_host_class_audio_feedback_buffer[4]; /* USB 2.0: feedback fits into 3(FS) or 4(HS). */ +#endif +#if defined(UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT) + UX_HOST_CLASS_AUDIO_AC + *ux_host_class_audio_ac; +#endif + struct UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST_STRUCT *ux_host_class_audio_head_transfer_request; - struct UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST_STRUCT + struct UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST_STRUCT *ux_host_class_audio_tail_transfer_request; UINT ux_host_class_audio_state; ULONG ux_host_class_audio_terminal_link; ULONG ux_host_class_audio_type; - UCHAR * ux_host_class_audio_configuration_descriptor; - ULONG ux_host_class_audio_configuration_descriptor_length; + ULONG ux_host_class_audio_packet_size; + ULONG ux_host_class_audio_packet_freq; + ULONG ux_host_class_audio_packet_fraction; +#if !defined(UX_HOST_CLASS_AUDIO_DISABLE_CONTROLS) ULONG ux_host_class_audio_feature_unit_id; UINT ux_host_class_audio_channels; ULONG ux_host_class_audio_channel_control[UX_HOST_CLASS_AUDIO_MAX_CHANNEL]; - UCHAR ux_host_class_audio_name[UX_HOST_CLASS_AUDIO_NAME_LENGTH]; - UX_SEMAPHORE ux_host_class_audio_semaphore; +#endif + UX_MUTEX ux_host_class_audio_mutex; } UX_HOST_CLASS_AUDIO; +#define _ux_host_class_audio_interface_get(a) (((UX_HOST_CLASS_AUDIO*)(a))->ux_host_class_audio_streaming_interface->ux_interface_descriptor.bInterfaceNumber) +#define _ux_host_class_audio_protocol_get(a) (((UX_HOST_CLASS_AUDIO*)(a))->ux_host_class_audio_streaming_interface->ux_interface_descriptor.bInterfaceProtocol) +#define _ux_host_class_audio_subclass_get(a) (((UX_HOST_CLASS_AUDIO*)(a))->ux_host_class_audio_streaming_interface->ux_interface_descriptor.bInterfaceSubClass) + +#define _ux_host_class_audio_speed_get(a) ((a)->ux_host_class_audio_device->ux_device_speed) +#define _ux_host_class_audio_type_get(a) ((a)->ux_host_class_audio_type) +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) +#define _ux_host_class_audio_feedback_supported(a) ((a)->ux_host_class_audio_feedback_endpoint) +#else +#define _ux_host_class_audio_feedback_supported(a) (UX_FALSE) +#endif +#define _ux_host_class_audio_control_interface_get(a) ((a)->ux_host_class_audio_control_interface_number) +#define _ux_host_class_audio_terminal_link_get(a) ((a)->ux_host_class_audio_terminal_link) +#define _ux_host_class_audio_packet_size_get(a) ((a)->ux_host_class_audio_packet_size) +#define _ux_host_class_audio_packet_freq_get(a) ((a)->ux_host_class_audio_packet_freq) +#define _ux_host_class_audio_packet_fraction_get(a) ((a)->ux_host_class_audio_packet_fraction) +#define _ux_host_class_audio_max_packet_size_get(a) ((a)->ux_host_class_audio_isochronous_endpoint->ux_endpoint_transfer_request.ux_transfer_request_packet_length) + /* Define Audio Class isochronous USB transfer request structure. */ @@ -367,14 +488,15 @@ typedef struct UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST_STRUCT { ULONG ux_host_class_audio_transfer_request_status; - UCHAR * ux_host_class_audio_transfer_request_data_pointer; + UCHAR *ux_host_class_audio_transfer_request_data_pointer; ULONG ux_host_class_audio_transfer_request_requested_length; + ULONG ux_host_class_audio_transfer_request_packet_size; /* Actual packet size to use. */ ULONG ux_host_class_audio_transfer_request_actual_length; VOID (*ux_host_class_audio_transfer_request_completion_function) (struct UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST_STRUCT *); UX_SEMAPHORE ux_host_class_audio_transfer_request_semaphore; VOID *ux_host_class_audio_transfer_request_class_instance; UINT ux_host_class_audio_transfer_request_completion_code; - struct UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST_STRUCT + struct UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST_STRUCT *ux_host_class_audio_transfer_request_next_audio_transfer_request; UX_TRANSFER ux_host_class_audio_transfer_request; } UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST; @@ -391,6 +513,9 @@ typedef struct UX_HOST_CLASS_AUDIO_CONTROL_STRUCT ULONG ux_host_class_audio_control_max; ULONG ux_host_class_audio_control_res; ULONG ux_host_class_audio_control_cur; + + ULONG ux_host_class_audio_control_entity; /* Entity ID. */ + ULONG ux_host_class_audio_control_size; /* Size of value in 1,2 or 4 bytes. */ } UX_HOST_CLASS_AUDIO_CONTROL; @@ -422,6 +547,14 @@ typedef struct UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS_STRUCT ULONG ux_host_class_audio_sampling_characteristics_frequency_low; ULONG ux_host_class_audio_sampling_characteristics_frequency_high; ULONG ux_host_class_audio_sampling_characteristics_resolution; + + /* UAC 1.0, must be 1s. UAC 2.0, from actual audio schematic. */ + ULONG ux_host_class_audio_sampling_characteristics_clock_mul; + ULONG ux_host_class_audio_sampling_characteristics_clock_div; + + /* UAC 1.0, format type I descriptor for futher operations. */ + /* UAC 2.0, clock source descriptor (CSD) for futher operations. */ + UCHAR *ux_host_class_audio_sampling_characteristics_descriptor; } UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS; @@ -447,7 +580,45 @@ UINT _ux_host_class_audio_transfer_request(UX_HOST_CLASS_AUDIO *audio, UX_HOS VOID _ux_host_class_audio_transfer_request_completed(UX_TRANSFER *transfer_request); UINT _ux_host_class_audio_write(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *audio_transfer_request); -/* Define Asix Class API prototypes. */ +UINT _ux_host_class_audio_control_request(UX_HOST_CLASS_AUDIO *audio, + UINT streaming_control, + UINT request_type, UINT request, + UINT request_value, + UINT spec_id, + UCHAR *parameter, ULONG parameter_size, ULONG *actual_size); + +UINT _ux_host_class_audio_descriptors_parse(UX_HOST_CLASS_AUDIO *audio, + UINT(*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UCHAR *packed_endpoint_descriptor, + UCHAR *packed_audio_descriptor), + VOID* arg); + +UINT _ux_host_class_audio_raw_sampling_parse(UX_HOST_CLASS_AUDIO *audio, + UINT(*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr), + VOID* arg); + +UINT _ux_host_class_audio_stop(UX_HOST_CLASS_AUDIO *audio); + +VOID _ux_host_class_audio_feedback_transfer_completed(UX_TRANSFER *transfer_request); + +UINT _ux_host_class_audio_feedback_get(UX_HOST_CLASS_AUDIO *audio, UCHAR *feedback); +UINT _ux_host_class_audio_feedback_set(UX_HOST_CLASS_AUDIO *audio, UCHAR *feedback); + +UINT _ux_host_class_audio_entity_control_get(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control); +UINT _ux_host_class_audio_entity_control_value_get(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control); +UINT _ux_host_class_audio_entity_control_value_set(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control); + +UINT _ux_host_class_audio_interrupt_start(UX_HOST_CLASS_AUDIO_AC *audio, + VOID(*callback_function)(UX_HOST_CLASS_AUDIO_AC *audio, + UCHAR *message, ULONG length, + VOID *arg), + VOID *arg); +VOID _ux_host_class_audio_interrupt_notification(UX_TRANSFER *transfer_request); + +/* Define Audio Class API prototypes. */ #define ux_host_class_audio_entry _ux_host_class_audio_entry #define ux_host_class_audio_control_get _ux_host_class_audio_control_get @@ -459,11 +630,44 @@ UINT _ux_host_class_audio_write(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUD #define ux_host_class_audio_streaming_terminal_get _ux_host_class_audio_streaming_terminal_get #define ux_host_class_audio_write _ux_host_class_audio_write -/* Determine if a C++ compiler is being used. If so, complete the standard - C conditional started above. */ +#define ux_host_class_audio_type_get _ux_host_class_audio_type_get +#define ux_host_class_audio_speed_get _ux_host_class_audio_speed_get +#define ux_host_class_audio_protocol_get _ux_host_class_audio_protocol_get +#define ux_host_class_audio_subclass_get _ux_host_class_audio_subclass_get +#define ux_host_class_audio_feedback_supported _ux_host_class_audio_feedback_supported + +#define ux_host_class_audio_interface_get _ux_host_class_audio_interface_get +#define ux_host_class_audio_control_interface_get _ux_host_class_audio_control_interface_get +#define ux_host_class_audio_terminal_link_get _ux_host_class_audio_terminal_link_get + +#define ux_host_class_audio_max_packet_size_get _ux_host_class_audio_max_packet_size_get +#define ux_host_class_audio_packet_size_get _ux_host_class_audio_packet_size_get +#define ux_host_class_audio_packet_freq_get _ux_host_class_audio_packet_freq_get +#define ux_host_class_audio_packet_fraction_get _ux_host_class_audio_packet_fraction_get + +#define ux_host_class_audio_feedback_get _ux_host_class_audio_feedback_get +#define ux_host_class_audio_feedback_set _ux_host_class_audio_feedback_set + +#define ux_host_class_audio_control_request _ux_host_class_audio_control_request + +#define ux_host_class_audio_descriptors_parse _ux_host_class_audio_descriptors_parse + +#define ux_host_class_audio_entity_control_get _ux_host_class_audio_entity_control_get +#define ux_host_class_audio_entity_control_value_get _ux_host_class_audio_entity_control_value_get +#define ux_host_class_audio_entity_control_value_set _ux_host_class_audio_entity_control_value_set + +#define ux_host_class_audio_raw_sampling_parse _ux_host_class_audio_raw_sampling_parse +#define ux_host_class_audio_raw_sampling_start _ux_host_class_audio_streaming_sampling_set + +#define ux_host_class_audio_stop _ux_host_class_audio_stop + +#define ux_host_class_audio_interrupt_start _ux_host_class_audio_interrupt_start + +/* Determine if a C++ compiler is being used. If so, complete the standard + C conditional started above. */ #ifdef __cplusplus -} -#endif +} +#endif #endif diff --git a/common/usbx_host_classes/inc/ux_host_class_cdc_acm.h b/common/usbx_host_classes/inc/ux_host_class_cdc_acm.h index da5389c2..1dc6d747 100644 --- a/common/usbx_host_classes/inc/ux_host_class_cdc_acm.h +++ b/common/usbx_host_classes/inc/ux_host_class_cdc_acm.h @@ -378,11 +378,11 @@ VOID _ux_host_class_cdc_acm_transmission_callback(UX_TRANSFER *transfer_request #define ux_host_class_cdc_acm_reception_stop _ux_host_class_cdc_acm_reception_stop #define ux_host_class_cdc_acm_write_with_callback _ux_host_class_cdc_acm_write_with_callback - + /* Determine if a C++ compiler is being used. If so, complete the standard C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h b/common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h index e8843927..b8051751 100644 --- a/common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h +++ b/common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h @@ -260,7 +260,7 @@ VOID _ux_host_class_hid_keyboard_tasks_run(UX_HOST_CLASS_HID_CLIENT *client); C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/usbx_host_classes/inc/ux_host_class_hid_mouse.h b/common/usbx_host_classes/inc/ux_host_class_hid_mouse.h index d2340aec..11ddda08 100644 --- a/common/usbx_host_classes/inc/ux_host_class_hid_mouse.h +++ b/common/usbx_host_classes/inc/ux_host_class_hid_mouse.h @@ -96,7 +96,7 @@ typedef struct UX_HOST_CLASS_HID_MOUSE_STRUCT ULONG ux_host_class_hid_mouse_state; UX_HOST_CLASS_HID *ux_host_class_hid_mouse_hid; - USHORT ux_host_class_hid_mouse_id; + USHORT ux_host_class_hid_mouse_id; SLONG ux_host_class_hid_mouse_x_position; SLONG ux_host_class_hid_mouse_y_position; ULONG ux_host_class_hid_mouse_buttons; @@ -105,7 +105,7 @@ typedef struct UX_HOST_CLASS_HID_MOUSE_STRUCT UINT ux_host_class_hid_mouse_enum_state; UINT ux_host_class_hid_mouse_status; #endif - + } UX_HOST_CLASS_HID_MOUSE; typedef struct UX_HOST_CLASS_HID_CLIENT_MOUSE_STRUCT @@ -139,6 +139,6 @@ UINT _ux_host_class_hid_mouse_wheel_get(UX_HOST_CLASS_HID_MOUSE *mouse_instance C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/usbx_host_classes/inc/ux_host_class_hub.h b/common/usbx_host_classes/inc/ux_host_class_hub.h index 7611dece..20f3b9fe 100644 --- a/common/usbx_host_classes/inc/ux_host_class_hub.h +++ b/common/usbx_host_classes/inc/ux_host_class_hub.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_host_class_hub.h PORTABLE C */ -/* 6.1.8 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -47,6 +47,9 @@ /* added extern "C" keyword */ /* for compatibility with C++, */ /* resulting in version 6.1.8 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -125,11 +128,11 @@ extern "C" { /* Define HUB Class port change constants. */ -#define UX_HOST_CLASS_HUB_PORT_CHANGE_CONNECTION 0x00001 -#define UX_HOST_CLASS_HUB_PORT_CHANGE_ENABLE 0x00002 -#define UX_HOST_CLASS_HUB_PORT_CHANGE_SUSPEND 0x00004 -#define UX_HOST_CLASS_HUB_PORT_CHANGE_OVER_CURRENT 0x00008 -#define UX_HOST_CLASS_HUB_PORT_CHANGE_RESET 0x00010 +#define UX_HOST_CLASS_HUB_PORT_CHANGE_CONNECTION 0x00001u +#define UX_HOST_CLASS_HUB_PORT_CHANGE_ENABLE 0x00002u +#define UX_HOST_CLASS_HUB_PORT_CHANGE_SUSPEND 0x00004u +#define UX_HOST_CLASS_HUB_PORT_CHANGE_OVER_CURRENT 0x00008u +#define UX_HOST_CLASS_HUB_PORT_CHANGE_RESET 0x00010u /* Define HUB Class other constants. */ @@ -150,6 +153,38 @@ extern "C" { #define UX_MAX_HUB_PORTS 15 + +/* Define HUB state machine states. */ + +#define UX_HOST_CLASS_HUB_ENUM_GET_STATUS (UX_STATE_STEP + 0) +#define UX_HOST_CLASS_HUB_ENUM_POWER_CHECK (UX_STATE_STEP + 1) +#define UX_HOST_CLASS_HUB_ENUM_SET_CONFIG (UX_STATE_STEP + 2) +#define UX_HOST_CLASS_HUB_ENUM_SET_CONFIG_DONE (UX_STATE_STEP + 3) +#define UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC (UX_STATE_STEP + 4) +#define UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC_DONE (UX_STATE_STEP + 5) +#define UX_HOST_CLASS_HUB_ENUM_PORT_POWER (UX_STATE_STEP + 6) +#define UX_HOST_CLASS_HUB_ENUM_PORT_POWER_DELAY (UX_STATE_STEP + 7) +#define UX_HOST_CLASS_HUB_ENUM_PORT_POWER_ON (UX_STATE_STEP + 8) +#define UX_HOST_CLASS_HUB_ENUM_PORT_NEXT (UX_STATE_STEP + 9) +#define UX_HOST_CLASS_HUB_ENUM_INTERRUPT_START (UX_STATE_STEP + 10) +#define UX_HOST_CLASS_HUB_ENUM_DONE (UX_STATE_STEP + 11) +#define UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT (UX_STATE_STEP + 12) +#define UX_HOST_CLASS_HUB_ENUM_DELAY_WAIT (UX_STATE_STEP + 13) + +#define UX_HOST_CLASS_HUB_CHANGE_CHECK (UX_STATE_STEP + 0) +#define UX_HOST_CLASS_HUB_CHANGE_NEXT (UX_STATE_STEP + 1) +#define UX_HOST_CLASS_HUB_RESET (UX_STATE_STEP + 2) +#define UX_HOST_CLASS_HUB_STATUS_GET (UX_STATE_STEP + 3) +#define UX_HOST_CLASS_HUB_STATUS_GET_DONE (UX_STATE_STEP + 4) +#define UX_HOST_CLASS_HUB_STATUS_PROCESS (UX_STATE_STEP + 5) +#define UX_HOST_CLASS_HUB_RESET_PROCESS (UX_STATE_STEP + 6) +#define UX_HOST_CLASS_HUB_CONNECT_PROCESS (UX_STATE_STEP + 7) +#define UX_HOST_CLASS_HUB_DISC_DISABLED (UX_STATE_STEP + 8) +#define UX_HOST_CLASS_HUB_DISC_CLEAR_1 (UX_STATE_STEP + 9) +#define UX_HOST_CLASS_HUB_TRANS_WAIT (UX_STATE_STEP + 10) +#define UX_HOST_CLASS_HUB_DELAY_WAIT (UX_STATE_STEP + 11) + + typedef struct UX_HUB_DESCRIPTOR_STRUCT { @@ -177,13 +212,28 @@ typedef struct UX_HOST_CLASS_HUB_STRUCT UX_INTERFACE *ux_host_class_hub_interface; UINT ux_host_class_hub_instance_status; UINT ux_host_class_hub_state; - UINT ux_host_class_hub_enumeration_retry_count; UINT ux_host_class_hub_change_semaphore; struct UX_HUB_DESCRIPTOR_STRUCT ux_host_class_hub_descriptor; UINT ux_host_class_hub_port_state; UINT ux_host_class_hub_port_power; +#if defined(UX_HOST_STANDALONE) + UINT ux_host_class_hub_run_status; + UCHAR *ux_host_class_hub_allocated; + UX_TRANSFER *ux_host_class_hub_transfer; + + USHORT ux_host_class_hub_run_port_change; + USHORT ux_host_class_hub_run_port_status; + + ULONG ux_host_class_hub_wait_start; + ULONG ux_host_class_hub_wait_ms; + + UCHAR ux_host_class_hub_enum_state; + UCHAR ux_host_class_hub_run_state; + UCHAR ux_host_class_hub_next_state; + UCHAR ux_host_class_hub_run_port; +#endif } UX_HOST_CLASS_HUB; @@ -210,6 +260,8 @@ UINT _ux_host_class_hub_ports_power(UX_HOST_CLASS_HUB *hub); UINT _ux_host_class_hub_status_get(UX_HOST_CLASS_HUB *hub, UINT port, USHORT *port_status, USHORT *port_change); VOID _ux_host_class_hub_transfer_request_completed(UX_TRANSFER *transfer_request); +UINT _ux_host_class_hub_tasks_run(UX_HOST_CLASS *hub_class); + /* Determine if a C++ compiler is being used. If so, complete the standard C conditional started above. */ #ifdef __cplusplus diff --git a/common/usbx_host_classes/inc/ux_host_class_pima.h b/common/usbx_host_classes/inc/ux_host_class_pima.h index f5555527..9d1ca3bd 100644 --- a/common/usbx_host_classes/inc/ux_host_class_pima.h +++ b/common/usbx_host_classes/inc/ux_host_class_pima.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_host_class_pima.h PORTABLE C */ -/* 6.1.8 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -50,6 +50,9 @@ /* added extern "C" keyword */ /* for compatibility with C++, */ /* resulting in version 6.1.8 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved internal checks, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -78,8 +81,11 @@ extern "C" { #define UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH 256 #define UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH 64 #define UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS 64 -#define UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH (UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS * sizeof(ULONG)) -#define UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH_ASSERT UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_MULC_ULONG(sizeof(ULONG), UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS), UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH_calc_ovf) +#if (UX_OVERFLOW_CHECK_ADD_ULONG(UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS, 1) || \ + UX_OVERFLOW_CHECK_MULC_ULONG(UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS + 1, 4)) +#error UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS too large, please decrease +#endif +#define UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH ((UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS + 1) * 4) #define UX_HOST_CLASS_PIMA_MAX_PAYLOAD 1024 #define UX_HOST_CLASS_PIMA_ZLP_NONE 0 #define UX_HOST_CLASS_PIMA_ZLP_IN 1 @@ -444,10 +450,10 @@ typedef struct UX_HOST_CLASS_PIMA_OBJECT_STRUCT ULONG ux_host_class_pima_object_association_type; ULONG ux_host_class_pima_object_association_desc; ULONG ux_host_class_pima_object_sequence_number; - UCHAR ux_host_class_pima_object_filename[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; + UCHAR ux_host_class_pima_object_filename[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; /* Null terminated unicode string. */ UCHAR ux_host_class_pima_object_capture_date[UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH]; UCHAR ux_host_class_pima_object_modification_date[UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH]; - UCHAR ux_host_class_pima_object_keywords[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; + UCHAR ux_host_class_pima_object_keywords[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; /* Null terminated unicode string. */ ULONG ux_host_class_pima_object_state; ULONG ux_host_class_pima_object_offset; ULONG ux_host_class_pima_object_transfer_status; @@ -471,17 +477,17 @@ typedef struct UX_HOST_CLASS_PIMA_DEVICE_STRUCT ULONG ux_host_class_pima_device_standard_version; ULONG ux_host_class_pima_device_vendor_extension_id; ULONG ux_host_class_pima_device_vendor_extension_version; - UCHAR ux_host_class_pima_device_vendor_extension_desc[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; + UCHAR ux_host_class_pima_device_vendor_extension_desc[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; /* Null terminated unicode string. */ ULONG ux_host_class_pima_device_functional_mode; UCHAR ux_host_class_pima_device_operations_supported[UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH]; UCHAR ux_host_class_pima_device_events_supported[UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH]; UCHAR ux_host_class_pima_device_properties_supported[UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH]; UCHAR ux_host_class_pima_device_capture_formats[UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH]; UCHAR ux_host_class_pima_device_image_formats[UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH]; - UCHAR ux_host_class_pima_device_manufacturer[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; + UCHAR ux_host_class_pima_device_manufacturer[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; /* Null terminated unicode string. */ UCHAR ux_host_class_pima_device_model[UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH]; UCHAR ux_host_class_pima_device_version[UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH]; - UCHAR ux_host_class_pima_device_serial_number[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; + UCHAR ux_host_class_pima_device_serial_number[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; /* Null terminated unicode string. */ } UX_HOST_CLASS_PIMA_DEVICE; @@ -506,8 +512,8 @@ typedef struct UX_HOST_CLASS_PIMA_STORAGE_STRUCT ULONG ux_host_class_pima_storage_free_space_bytes_low; ULONG ux_host_class_pima_storage_free_space_bytes_high; ULONG ux_host_class_pima_storage_free_space_images; - UCHAR ux_host_class_pima_storage_description[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; - UCHAR ux_host_class_pima_storage_volume_label[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; + UCHAR ux_host_class_pima_storage_description[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; /* Null terminated unicode string. */ + UCHAR ux_host_class_pima_storage_volume_label[UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH]; /* Null terminated unicode string. */ } UX_HOST_CLASS_PIMA_STORAGE; @@ -578,7 +584,6 @@ UINT _ux_host_class_pima_device_info_get(UX_HOST_CLASS_PIMA *pima, #define ux_host_class_pima_object_delete _ux_host_class_pima_object_delete #define ux_host_class_pima_object_transfer_abort _ux_host_class_pima_object_transfer_abort #define ux_host_class_pima_object_close _ux_host_class_pima_object_close -#define ux_host_class_pima_num_objects_get _ux_host_class_pima_num_objects_get #define ux_host_class_pima_session_open _ux_host_class_pima_session_open #define ux_host_class_pima_session_close _ux_host_class_pima_session_close #define ux_host_class_pima_storage_ids_get _ux_host_class_pima_storage_ids_get diff --git a/common/usbx_host_classes/inc/ux_host_class_printer.h b/common/usbx_host_classes/inc/ux_host_class_printer.h index ccdd0c34..d91ea73c 100644 --- a/common/usbx_host_classes/inc/ux_host_class_printer.h +++ b/common/usbx_host_classes/inc/ux_host_class_printer.h @@ -97,7 +97,7 @@ extern "C" { /* Define Printer Class string constants. */ -#define UX_HOST_CLASS_PRINTER_GENERIC_NAME "USB PRINTER" +#define UX_HOST_CLASS_PRINTER_GENERIC_NAME "USB PRINTER" /* Define Printer flag constants. */ diff --git a/common/usbx_host_classes/inc/ux_host_class_storage.h b/common/usbx_host_classes/inc/ux_host_class_storage.h index e961f722..80822565 100755 --- a/common/usbx_host_classes/inc/ux_host_class_storage.h +++ b/common/usbx_host_classes/inc/ux_host_class_storage.h @@ -696,6 +696,6 @@ UINT _ux_host_class_storage_read_write_run(UX_HOST_CLASS_STORAGE *storage, C conditional started above. */ #ifdef __cplusplus } -#endif +#endif #endif diff --git a/common/usbx_host_classes/src/ux_host_class_audio_activate.c b/common/usbx_host_classes/src/ux_host_class_audio_activate.c index 82a2800e..7e2d3704 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_activate.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Audio Class */ /** */ @@ -30,76 +30,264 @@ #include "ux_host_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_audio_activate PORTABLE C */ -/* 6.1.10 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_activate PORTABLE C */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ +/* */ /* This function activates the audio class. It may be called twice by */ -/* the same device if there is a audio control interface to this */ -/* device. */ -/* */ -/* INPUT */ -/* */ -/* command Pointer to command */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ -/* _ux_host_class_audio_configure Configure the audio class */ -/* _ux_host_class_audio_descriptor_get Get audio descriptor */ -/* _ux_host_class_audio_device_controls_list_get Get controls list */ -/* _ux_host_class_audio_device_type_get Get device type */ -/* _ux_host_class_audio_streaming_terminal_get Get streaming terminal */ -/* _ux_host_stack_class_instance_create Create class instance */ -/* _ux_host_stack_class_instance_destroy Destroy class instance */ -/* _ux_utility_memory_allocate Allocate a memory block */ -/* _ux_host_semaphore_create Create protection semaphore */ -/* */ -/* CALLED BY */ -/* */ -/* Audio Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* the same device if there is a audio control interface to this */ +/* device. */ +/* */ +/* INPUT */ +/* */ +/* command Pointer to command */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_class_audio_configure Configure the audio class */ +/* _ux_host_class_audio_descriptor_get Get audio descriptor */ +/* _ux_host_class_audio_device_controls_list_get Get controls list */ +/* _ux_host_class_audio_device_type_get Get device type */ +/* _ux_host_class_audio_streaming_terminal_get Get streaming terminal */ +/* _ux_host_stack_class_instance_create Create class instance */ +/* _ux_host_stack_class_instance_destroy Destroy class instance */ +/* _ux_utility_memory_allocate Allocate a memory block */ +/* _ux_host_mutex_create Create protection mutex */ +/* */ +/* CALLED BY */ +/* */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added interrupt support, */ +/* protect reentry with mutex, */ +/* added feedback support, */ +/* refined error handling, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_AUDIO *audio; +#if defined(UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT) +UX_HOST_CLASS_AUDIO_AC *ac; +UX_ENDPOINT *endp; +UX_TRANSFER *trans; +UCHAR *desc; +UCHAR *iad; +UCHAR *uac10_ifd; +UCHAR *uac10_acd; +UCHAR desc_type; +UCHAR desc_length; +ULONG pos; +ULONG as_count; +#endif UINT status; /* The audio is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Check the subclass of the new device. If it is a Audio Control Interface, we don't need to create an instance of this function. When we get the streaming interface, we will search the audio control interface for the device. */ - if (interface -> ux_interface_descriptor.bInterfaceSubClass == UX_HOST_CLASS_AUDIO_SUBCLASS_CONTROL) + if (interface_ptr -> ux_interface_descriptor.bInterfaceSubClass == UX_HOST_CLASS_AUDIO_SUBCLASS_CONTROL) + { +#if defined(UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT) + + /* Allocate memory for AC instance. */ + ac = (UX_HOST_CLASS_AUDIO_AC *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_AUDIO_AC)); + if (ac == UX_NULL) + return(UX_MEMORY_INSUFFICIENT); + + /* Get descriptor to check AC/AS interfaces layouts. */ + ac -> ux_host_class_audio_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; + status = _ux_host_class_audio_descriptor_get((UX_HOST_CLASS_AUDIO *)ac); + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(ac); + return(status); + } + + /* Search for IAD or UAC1.0 AC header descriptor. */ + as_count = 0; + iad = UX_NULL; + uac10_acd = UX_NULL; + desc = ac -> ux_host_class_audio_configuration_descriptor; + for (pos = 0; pos < ac -> ux_host_class_audio_configuration_descriptor_length;) + { + + /* Get bLength@0, bDescriptorType@1. */ + desc_length = *(desc); + desc_type = *(desc + 1); + + /* Check length error. */ + if (desc_length < 2) + { + _ux_utility_memory_free(ac); + return(UX_DESCRIPTOR_CORRUPTED); + } + + /* Check descriptor type. */ + switch(desc_type) + { + case UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ITEM: + + /* Check bFirstInterface@2, must match AC interface if exist. */ + if (desc[2] == interface_ptr -> ux_interface_descriptor.bInterfaceNumber) + iad = desc; + break; + + case UX_INTERFACE_DESCRIPTOR_ITEM: + + /* Check bInterfaceNumber@2, if no IAD. */ + if (desc[2] == interface_ptr -> ux_interface_descriptor.bInterfaceNumber) + uac10_ifd = desc; + else + uac10_ifd = UX_NULL; + break; + + case UX_HOST_CLASS_AUDIO_CS_INTERFACE: + + /* Check bDescriptorSubtype@3, if inside correct interface. */ + if (uac10_ifd) + { + if (desc[2] == UX_HOST_CLASS_AUDIO_CS_HEADER) + uac10_acd = desc; + } + break; + + default: + break; + + } /* switch(desc_type) */ + + /* Check if IAD exists. */ + if (iad) + { + + /* In this case, bFirstInterface@2 is AC, followed ASes. */ + /* Use bInterfaceCount@3. */ + as_count = (ULONG)iad[3] - 1; + break; + } + + /* Check if AC header exists. */ + if (uac10_acd) + { + + /* In this case, bInCollection@7 is AS count. */ + as_count = (ULONG)uac10_acd[7]; + break; + } + + /* Move pos and descriptor pointer. */ + pos += desc_length; + desc += desc_length; + } + + /* If there are too many ASes, reallocate memory. */ + if (as_count > 2) + { + _ux_utility_memory_free(ac); + + /* as_count - 2 < 255 - 2, so (as_count - 2) * sizeof(UX_HOST_CLASS_AUDIO*) does not overflow. */ + /* sizeof(UX_HOST_CLASS_AUDIO_AC) is not big (< 255), total memory size calculation does not overflow. */ + ac = (UX_HOST_CLASS_AUDIO_AC *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, + sizeof(UX_HOST_CLASS_AUDIO_AC) + (as_count - 2) * sizeof(UX_HOST_CLASS_AUDIO*)); + if (ac == UX_NULL) + return(UX_MEMORY_INSUFFICIENT); + } + + /* Get interrupt endpoint. */ + endp = interface_ptr -> ux_interface_first_endpoint; + while(endp) + { + if (((endp -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == + UX_INTERRUPT_ENDPOINT) && + ((endp -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION))) + { + ac -> ux_host_class_audio_interrupt_endpoint = endp; + trans = &endp -> ux_endpoint_transfer_request; + + /* Allocate buffer. */ + trans -> ux_transfer_request_data_pointer = + _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + trans -> ux_transfer_request_packet_length); + if (trans -> ux_transfer_request_data_pointer == UX_NULL) + { + _ux_utility_memory_free(ac); + return(UX_MEMORY_INSUFFICIENT); + } + + /* This transfer always have the IN direction. */ + trans -> ux_transfer_request_type = UX_REQUEST_IN; + + /* This transfer always try read a full packet. */ + trans -> ux_transfer_request_requested_length = + trans -> ux_transfer_request_packet_length; + + break; + } + endp = endp -> ux_endpoint_next_endpoint; + } + + /* If there is no interrupt endpoint, that's fine. */ + /* Fill the fields. */ + ac -> ux_host_class_audio_class = command -> ux_host_class_command_class_ptr; + ac -> ux_host_class_audio_interface = interface_ptr; + ac -> ux_host_class_audio_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; + + ac -> ux_host_class_audio_configuration_descriptor = ac -> ux_host_class_audio_device -> ux_device_packed_configuration; + ac -> ux_host_class_audio_configuration_descriptor_length = interface_ptr -> ux_interface_configuration -> ux_configuration_descriptor.wTotalLength; + ac -> ux_host_class_audio_as_count = as_count; + + /* Link to interface and class. */ + interface_ptr -> ux_interface_class_instance = (VOID *)ac; + _ux_host_stack_class_instance_create(ac -> ux_host_class_audio_class, (VOID *)ac); + + /* If all is fine and the AC is mounted, we may need to inform the application + if a function has been programmed in the system structure. */ + if (_ux_system_host -> ux_system_host_change_function != UX_NULL) + _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, ac -> ux_host_class_audio_class, (VOID *) ac); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_ACTIVATE, ac, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) + + /* If trace is enabled, register this object. */ + UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, ac, 0, 0, 0) +#endif + return(UX_SUCCESS); - + } + /* Obtain memory for this class instance. */ audio = (UX_HOST_CLASS_AUDIO *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_AUDIO)); if (audio == UX_NULL) @@ -109,106 +297,139 @@ UINT status; audio -> ux_host_class_audio_class = command -> ux_host_class_command_class_ptr; /* Store the interface container into the audio class instance. */ - audio -> ux_host_class_audio_streaming_interface = interface; + audio -> ux_host_class_audio_streaming_interface = interface_ptr; /* Store the device container into the audio class instance. */ - audio -> ux_host_class_audio_device = interface -> ux_interface_configuration -> ux_configuration_device; - - /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) audio; + audio -> ux_host_class_audio_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) audio; + interface_ptr -> ux_interface_class_instance = (VOID *) audio; /* Create this class instance. */ _ux_host_stack_class_instance_create(audio -> ux_host_class_audio_class, (VOID *) audio); - - /* Configure the audio. */ - status = _ux_host_class_audio_configure(audio); - if (status != UX_SUCCESS) - { - - /* Error, destroy the class instance. */ - _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); - /* Return the error. */ - return(status); - } + /* Configure the audio. */ + status = _ux_host_class_audio_configure(audio); /* Get the audio descriptor (all the class specific stuff) and memorize them as we will need these descriptors to change settings. */ - status = _ux_host_class_audio_descriptor_get(audio); - if (status != UX_SUCCESS) - { - - /* Error, destroy the class instance. */ - _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); - - /* Return the error. */ - return(status); - } + if (status == UX_SUCCESS) + status = _ux_host_class_audio_descriptor_get(audio); /* Locate the audio device streaming terminal. */ - status = _ux_host_class_audio_streaming_terminal_get(audio); - if (status != UX_SUCCESS) - { + if (status == UX_SUCCESS) + status = _ux_host_class_audio_streaming_terminal_get(audio); - /* Error, destroy the class instance. */ - _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); + /* Get the audio device type. Here we only support input and output devices. */ + if (status == UX_SUCCESS) + status = _ux_host_class_audio_device_type_get(audio); - /* Return the error. */ - return(status); - } + /* Get the audio device controls. */ +#if !defined(UX_HOST_CLASS_AUDIO_DISABLE_CONTROLS) + if (status == UX_SUCCESS) + status = _ux_host_class_audio_device_controls_list_get(audio); +#endif - /* Get the audio device type. Here we only support input and output devices. */ - status = _ux_host_class_audio_device_type_get(audio); - if (status != UX_SUCCESS) + /* Create the mutex to protect multiple threads from accessing the same + audio instance. */ + if (status == UX_SUCCESS) { + status = _ux_host_mutex_create(&audio -> ux_host_class_audio_mutex, "ux_hot_class_audio_mutex"); + if (status != UX_SUCCESS) + status = UX_MUTEX_ERROR; + } - /* Error, destroy the class instance. */ - _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); +#if defined(UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT) - /* Return the error. */ - return(status); + /* Find AC and link them. */ + ac = (UX_HOST_CLASS_AUDIO_AC *)audio -> ux_host_class_audio_class -> ux_host_class_first_instance; + while(ac) + { + + /* Check interface number to see if it's right AC. */ + if (audio -> ux_host_class_audio_control_interface_number == + ac -> ux_host_class_audio_interface -> ux_interface_descriptor.bInterfaceNumber) + { + + /* Save AS to AC controlled list. */ + for (pos = 0; pos < ac -> ux_host_class_audio_as_count; pos ++) + { + if (ac -> ux_host_class_audio_as[pos] == UX_NULL) + { + + /* This AC is for current AS. */ + audio -> ux_host_class_audio_ac = ac; + ac -> ux_host_class_audio_as[pos] = audio; + break; + } + } + + /* If there is no place for AS, something wrong. */ + if (pos >= ac -> ux_host_class_audio_as_count) + { + status = UX_DESCRIPTOR_CORRUPTED; + break; + } + } + + /* If AC is found and linked, done. */ + if (audio -> ux_host_class_audio_ac != UX_NULL) + break; + + /* If there is error, break. */ + if (status != UX_SUCCESS) + break; + + /* Check next AC/AS. */ + ac = (UX_HOST_CLASS_AUDIO_AC *)ac -> ux_host_class_audio_next_instance; } +#endif - /* Get the audio device controls. */ - status = _ux_host_class_audio_device_controls_list_get(audio); - if (status != UX_SUCCESS) + /* Activate is done success. */ + if (status == UX_SUCCESS) { - /* Error, destroy the class instance. */ - _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); + /* Mark the audio as live now. */ + audio -> ux_host_class_audio_state = UX_HOST_CLASS_INSTANCE_LIVE; - /* Return the error. */ - return(status); - } + /* If all is fine and the device is mounted, we may need to inform the application + if a function has been programmed in the system structure. */ + if (_ux_system_host -> ux_system_host_change_function != UX_NULL) + { - /* Create the semaphore to protect multiple threads from accessing the same - audio instance. */ - status = _ux_host_semaphore_create(&audio -> ux_host_class_audio_semaphore, "ux_hot_class_audio_semaphore", 1); - if (status != UX_SUCCESS) - return(UX_SEMAPHORE_ERROR); + /* Call system change function. */ + _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, audio -> ux_host_class_audio_class, (VOID *) audio); + } - /* Mark the audio as live now. */ - audio -> ux_host_class_audio_state = UX_HOST_CLASS_INSTANCE_LIVE; + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_ACTIVATE, audio, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) - /* If all is fine and the device is mounted, we may need to inform the application - if a function has been programmed in the system structure. */ - if ((status == UX_SUCCESS) && (_ux_system_host -> ux_system_host_change_function != UX_NULL)) - { - - /* Call system change function. */ - _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, audio -> ux_host_class_audio_class, (VOID *) audio); + /* If trace is enabled, register this object. */ + UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, audio, 0, 0, 0) + + /* Return completion status. */ + return(UX_SUCCESS); } + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, status); + /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_ACTIVATE, audio, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, status, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) - /* If trace is enabled, register this object. */ - UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, audio, 0, 0, 0) + /* Error, destroy the class instance. */ + _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); - /* Return completion status. */ - return(status); -} + /* Free resources. */ +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + if (audio -> ux_host_class_audio_feedback_endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer) + _ux_utility_memory_free(audio -> ux_host_class_audio_feedback_endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer); +#endif + _ux_utility_memory_free(audio); + + /* Unlink instance from interface. */ + interface_ptr -> ux_interface_class_instance = UX_NULL; + /* Return the error. */ + return(status); +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c b/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c index f8dde681..258fa64b 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c @@ -30,12 +30,20 @@ #include "ux_host_stack.h" +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) +static inline UINT _ux_host_class_audio_alternate_setting_locate_2( + UX_HOST_CLASS_AUDIO *audio, + UX_HOST_CLASS_AUDIO_SAMPLING *audio_sampling, + UINT *alternate_setting); +#endif + + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_alternate_setting_locate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,12 +79,18 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ -/* */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added audio 2.0 support, */ +/* resulting in version 6.1.12 */ /**************************************************************************/ UINT _ux_host_class_audio_alternate_setting_locate(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_SAMPLING *audio_sampling, UINT *alternate_setting) { +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + return(_ux_host_class_audio_alternate_setting_locate_2(audio, audio_sampling, alternate_setting)); +#else + UCHAR * descriptor; UX_INTERFACE_DESCRIPTOR interface_descriptor; UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR audio_interface_descriptor; @@ -191,6 +205,7 @@ UINT specific_frequency_count; { /* We have found the right alternate setting. */ + audio -> ux_host_class_audio_sampling_descriptor = descriptor; return(UX_SUCCESS); } } @@ -211,6 +226,7 @@ UINT specific_frequency_count; { /* We have found the right alternate setting. */ + audio -> ux_host_class_audio_sampling_descriptor = descriptor; return(UX_SUCCESS); } } @@ -242,5 +258,106 @@ UINT specific_frequency_count; /* We get here when either the report descriptor has a problem or we could not find the right audio device. */ return(UX_NO_ALTERNATE_SETTING); +#endif } +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) +struct UX_HOST_CLASS_AUDIO_ALT_LOCATE_PARSER { + UX_HOST_CLASS_AUDIO_SAMPLING *sampling; + UCHAR *clock_descriptor; + ULONG alt; + UINT status; +}; +static UINT _ux_host_class_audio_alt_locate_parse(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr) +{ +struct UX_HOST_CLASS_AUDIO_ALT_LOCATE_PARSER *parser = (struct UX_HOST_CLASS_AUDIO_ALT_LOCATE_PARSER *)arg; +UX_HOST_CLASS_AUDIO_SAMPLING *sampling = parser -> sampling; +ULONG frequency_low, frequency_high; + + /* Check bNrChannels. */ + if (sampling -> ux_host_class_audio_sampling_channels != + sam_attr -> ux_host_class_audio_sampling_characteristics_channels) + return(0); + + /* Check bBitResolution. */ + if (sampling -> ux_host_class_audio_sampling_resolution != + sam_attr -> ux_host_class_audio_sampling_characteristics_resolution) + return(0); + + /* Calculate frequency low. */ + frequency_low = sam_attr -> ux_host_class_audio_sampling_characteristics_frequency_low; + if (UX_OVERFLOW_CHECK_MULV_ULONG(frequency_low, sam_attr -> ux_host_class_audio_sampling_characteristics_clock_mul)) + { + + /* Math error. */ + parser -> status = UX_MATH_OVERFLOW; + return(1); + } + frequency_low *= sam_attr -> ux_host_class_audio_sampling_characteristics_clock_mul; + frequency_low /= sam_attr -> ux_host_class_audio_sampling_characteristics_clock_div; + + /* Calculate frequency high. */ + frequency_high = sam_attr -> ux_host_class_audio_sampling_characteristics_frequency_high; + if (UX_OVERFLOW_CHECK_MULV_ULONG(frequency_high, sam_attr -> ux_host_class_audio_sampling_characteristics_clock_mul)) + { + + /* Math error. */ + parser -> status = UX_MATH_OVERFLOW; + return(1); + } + frequency_high *= sam_attr -> ux_host_class_audio_sampling_characteristics_clock_mul; + frequency_high /= sam_attr -> ux_host_class_audio_sampling_characteristics_clock_div; + + /* Check frequency in [low, high]. */ + if ((frequency_low <= sampling -> ux_host_class_audio_sampling_frequency) && + (frequency_high >= sampling -> ux_host_class_audio_sampling_frequency)) + { + + /* Save bAlternateSetting @ 3. */ + parser -> alt = (ULONG)packed_interface_descriptor[3]; + + /* Save UAC 1.0 FormatTypeI or UAC 2.0 CSD. */ + parser -> clock_descriptor = + sam_attr -> ux_host_class_audio_sampling_characteristics_descriptor; + return(1); + } + + /* Continue parsing. */ + return(0); +} +static inline UINT _ux_host_class_audio_alternate_setting_locate_2( + UX_HOST_CLASS_AUDIO *audio, + UX_HOST_CLASS_AUDIO_SAMPLING *audio_sampling, + UINT *alternate_setting) +{ +struct UX_HOST_CLASS_AUDIO_ALT_LOCATE_PARSER parser; +UINT status; + + /* Parse specific sampling setting to get alt setting. */ + parser.sampling = audio_sampling; + parser.clock_descriptor = UX_NULL; + parser.alt = 0xFF; + parser.status = UX_SUCCESS; + status = _ux_host_class_audio_raw_sampling_parse(audio, _ux_host_class_audio_alt_locate_parse, (VOID*)&parser); + + /* Check descriptor error. */ + if (status != UX_SUCCESS) + return(status); + + /* Check if valid alternate setting is found. */ + if (parser.alt == 0xFF) + { + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_NO_ALTERNATE_SETTING, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + return(UX_NO_ALTERNATE_SETTING); + } + + /* Save alternate setting. */ + *alternate_setting = parser.alt; + audio -> ux_host_class_audio_sampling_descriptor = parser.clock_descriptor; + return(parser.status); +} +#endif diff --git a/common/usbx_host_classes/src/ux_host_class_audio_control_get.c b/common/usbx_host_classes/src/ux_host_class_audio_control_get.c index 6da35058..f468d8ae 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_control_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_control_get.c @@ -35,16 +35,27 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_control_get PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function obtains the static values for a single audio control */ -/* on either the master channel or a specific channel. */ +/* This function obtains the static feature values for a single audio */ +/* control on either the master channel or a specific channel. */ /* */ +/* Note only control value of BYTE, WORD and DWORD (<4) is supported. */ +/* E.g., Graphic Equalizer Control is not supported. */ +/* */ +/* Note only first RANGE of a list is returned. */ +/* */ +/* Note it's not recommended for supporting audio device with complex */ +/* pinout scheme, where ux_host_class_audio_descriptors_parse can be */ +/* used to build audio pinout scheme, and settings can be changed by */ +/* ux_host_class_audio_control_request or ux_host_class_audio_feature */ +/* functions. */ +/* */ /* INPUT */ /* */ /* audio Pointer to audio class */ @@ -60,6 +71,8 @@ /* _ux_host_stack_transfer_request Process transfer request */ /* _ux_host_semaphore_get Get semaphore */ /* _ux_host_semaphore_put Release semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ /* _ux_utility_memory_allocate Allocate memory block */ /* _ux_utility_memory_free Release memory block */ /* _ux_utility_short_get Read 16-bit value */ @@ -82,10 +95,19 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added audio 2.0 support, */ +/* protect reentry with mutex, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_control_get(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control) { +#if defined(UX_HOST_CLASS_AUDIO_DISABLE_CONTROLS) + UX_PARAMETER_NOT_USED(audio); + UX_PARAMETER_NOT_USED(audio_control); + return(UX_FUNCTION_NOT_SUPPORTED); +#else UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; @@ -95,7 +117,7 @@ UCHAR * control_buffer; /* Ensure the instance is valid. */ if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) - { + { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); @@ -107,114 +129,225 @@ UCHAR * control_buffer; } /* Protect thread reentry to this instance. */ - status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_semaphore, UX_WAIT_FOREVER); - if (status != UX_SUCCESS) - return(status); + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); /* We need to get the default control endpoint transfer request pointer. */ control_endpoint = &audio -> ux_host_class_audio_device -> ux_device_control_endpoint; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; - /* Need to allocate memory for the control buffer. */ - control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 2); - if (control_buffer == UX_NULL) - { - - /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); - - /* Return an error. */ - return(UX_MEMORY_INSUFFICIENT); - } - - /* Protect the control endpoint semaphore here. It will be unprotected in the + /* Protect the control endpoint semaphore here. It will be unprotected in the transfer request function. */ status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); /* Check for status. */ if (status != UX_SUCCESS) - - /* Something went wrong. */ - return(status); - - /* Create a transfer request for the GET_MIN request. */ - transfer_request -> ux_transfer_request_data_pointer = control_buffer; - transfer_request -> ux_transfer_request_requested_length = 2; - transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_AUDIO_GET_MIN; - transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; - transfer_request -> ux_transfer_request_value = audio_control -> ux_host_class_audio_control_channel | (audio_control -> ux_host_class_audio_control << 8); - transfer_request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (audio -> ux_host_class_audio_feature_unit_id << 8); - - /* Send request to HCD layer. */ - status = _ux_host_stack_transfer_request(transfer_request); - - /* Check for correct transfer and entire control buffer returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == 2)) { - /* Update the MIN static value for the caller. */ - audio_control -> ux_host_class_audio_control_min = _ux_utility_short_get(control_buffer); - } - else - { - - /* Free the previous control buffer. */ - _ux_utility_memory_free(control_buffer); - - /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); - - /* Return completion status. */ - return(UX_TRANSFER_ERROR); + /* Something went wrong. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); } - /* Create a transfer request for the GET_MAX request. */ - transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_AUDIO_GET_MAX; - - /* Send request to HCD layer. */ - status = _ux_host_stack_transfer_request(transfer_request); - - /* Check for correct transfer and entire control buffer returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == 2)) +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + if (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) { - - /* Update the MAX static value for the caller. */ - audio_control -> ux_host_class_audio_control_max = _ux_utility_short_get(control_buffer); + /* Size RANGE Size + D1..0: Mute 1 2+1*3=5 + D3..2: Volume 2 2+2*3=8 + D5..4: Bass 1 + D7..6: Mid 1 + D9..8: Treble 1 + D11..10: Graphic Equalizer 4+NrBits + D13..12: Automatic Gain 1 + D15..14: Delay 4 2+4*3=14 + D17..16: Bass Boost 1 + D19..18: Loudness 1 + D21..20: Input Gain 2 + D23..22: Input Gain Pad 2 + D25..24: Phase Inverter 1 + D27..26: Underflow 1 + D29..28: Overflow 1 + */ + + /* Need to allocate enough memory for the control buffer. */ + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 16); + if (control_buffer == UX_NULL) + { + + /* Return an error. */ + _ux_host_semaphore_put(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_MEMORY_INSUFFICIENT); + } + + /* Create a transfer request for the GET RANGE request. */ + transfer_request -> ux_transfer_request_data_pointer = control_buffer; + transfer_request -> ux_transfer_request_requested_length = 16; + transfer_request -> ux_transfer_request_function = UX_CLASS_AUDIO20_RANGE; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer_request -> ux_transfer_request_value = audio_control -> ux_host_class_audio_control_channel | (audio_control -> ux_host_class_audio_control << 8); + transfer_request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (audio -> ux_host_class_audio_feature_unit_id << 8); + + /* Send request to HCD layer. */ + status = _ux_host_stack_transfer_request(transfer_request); + + /* Check request status code. */ + if (status == UX_SUCCESS) + { + + /* Check returned length for parameter layouts. */ + switch(transfer_request -> ux_transfer_request_actual_length) + { + + /* Layout 3: wNumSubranges, dMIN, dMAX, dRES. */ + case 14: + audio_control -> ux_host_class_audio_control_min = _ux_utility_long_get(control_buffer + 2); + audio_control -> ux_host_class_audio_control_max = _ux_utility_long_get(control_buffer + 6); + audio_control -> ux_host_class_audio_control_res = _ux_utility_long_get(control_buffer + 10); + break; + + /* Layout 2: wNumSubranges, wMIN, wMAX, wRES. */ + case 8: + audio_control -> ux_host_class_audio_control_min = _ux_utility_short_get(control_buffer + 2); + audio_control -> ux_host_class_audio_control_max = _ux_utility_short_get(control_buffer + 4); + audio_control -> ux_host_class_audio_control_res = _ux_utility_short_get(control_buffer + 6); + break; + + /* Layout 1: wNumSubranges, bMIN, bMAX, bRES. */ + case 5: + audio_control -> ux_host_class_audio_control_min = *(control_buffer + 2); + audio_control -> ux_host_class_audio_control_max = *(control_buffer + 3); + audio_control -> ux_host_class_audio_control_res = *(control_buffer + 4); + break; + + /* Invalid data. */ + default: + status = UX_ERROR; + break; + } + } } - else + else +#endif { - /* Free the previous control buffer. */ - _ux_utility_memory_free(control_buffer); - - /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); - - /* Return completion status. */ - return(UX_TRANSFER_ERROR); - } - - /* Create a transfer request for the GET_RES request. */ - transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_AUDIO_GET_RES; - - /* Send request to HCD layer. */ - status = _ux_host_stack_transfer_request(transfer_request); - - /* Check for correct transfer and entire control buffer returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == 2)) - { - - /* Update the RES static value for the caller. */ - audio_control -> ux_host_class_audio_control_res = _ux_utility_short_get(control_buffer); + /* Size + D0: Mute 1 + D1: Volume 2 + D2: Bass 1 + D3: Mid 1 + D4: Treble 1 + D5: Graphic Equalizer 4+NrBits + D6: Automatic Gain 1 + D7: Delay 2 + D8: Bass Boost 1 + D9: Loudness 1 + */ + + /* Need to allocate memory for the control buffer. */ + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); + if (control_buffer == UX_NULL) + { + + /* Return an error. */ + _ux_host_semaphore_put(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_MEMORY_INSUFFICIENT); + } + + /* The buffer should be aligned. Returned data is little endian so DWord can be used + to copy any returned data of BYTE/WORD/DWORD. */ + + /* Create a transfer request for the GET_MIN request. */ + transfer_request -> ux_transfer_request_data_pointer = control_buffer; + transfer_request -> ux_transfer_request_requested_length = 4; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer_request -> ux_transfer_request_value = audio_control -> ux_host_class_audio_control_channel | (audio_control -> ux_host_class_audio_control << 8); + transfer_request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (audio -> ux_host_class_audio_feature_unit_id << 8); + transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_AUDIO_GET_MIN; + + /* Send request to HCD layer. */ + * (ULONG *)control_buffer = 0; + status = _ux_host_stack_transfer_request(transfer_request); + + /* Check for correct transfer and entire control buffer returned. + * Start GET_MAX request. */ + if (status == UX_SUCCESS) + { + + /* Update the MIN static value for the caller. */ + audio_control -> ux_host_class_audio_control_min = _ux_utility_long_get(control_buffer); + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } + + /* Create a transfer request for the GET_MAX request. */ + transfer_request -> ux_transfer_request_data_pointer = control_buffer; + transfer_request -> ux_transfer_request_requested_length = 4; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer_request -> ux_transfer_request_value = audio_control -> ux_host_class_audio_control_channel | (audio_control -> ux_host_class_audio_control << 8); + transfer_request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (audio -> ux_host_class_audio_feature_unit_id << 8); + transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_AUDIO_GET_MAX; + + /* Send request to HCD layer. */ + * (ULONG *)control_buffer = 0; + status = _ux_host_stack_transfer_request(transfer_request); + } + + /* Check for correct transfer and entire control buffer returned. + * Start GET_RES request. */ + if (status == UX_SUCCESS) + { + + /* Update the MAX static value for the caller. */ + audio_control -> ux_host_class_audio_control_max = _ux_utility_long_get(control_buffer); + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } + + /* Create a transfer request for the GET_RES request. */ + transfer_request -> ux_transfer_request_data_pointer = control_buffer; + transfer_request -> ux_transfer_request_requested_length = 4; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer_request -> ux_transfer_request_value = audio_control -> ux_host_class_audio_control_channel | (audio_control -> ux_host_class_audio_control << 8); + transfer_request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (audio -> ux_host_class_audio_feature_unit_id << 8); + transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_AUDIO_GET_RES; + + /* Send request to HCD layer. */ + * (ULONG *)control_buffer = 0; + status = _ux_host_stack_transfer_request(transfer_request); + } + + /* Check for correct transfer and entire control buffer returned. */ + if (status == UX_SUCCESS) + { + + /* Update the RES static value for the caller. */ + audio_control -> ux_host_class_audio_control_res = _ux_utility_long_get(control_buffer); + } } /* Free all used resources. */ _ux_utility_memory_free(control_buffer); /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return completion status. */ return(status); +#endif } - diff --git a/common/usbx_host_classes/src/ux_host_class_audio_control_request.c b/common/usbx_host_classes/src/ux_host_class_audio_control_request.c new file mode 100644 index 00000000..7f040f28 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_control_request.c @@ -0,0 +1,169 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_control_request PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function issue audio specific control request. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* streaming_control 0 for control requests */ +/* 1 for streaming requests */ +/* request_type bmRequestType */ +/* request bRequest */ +/* request_value wValue can be: */ +/* (CS << 8) | CN or */ +/* (ICN << 8) | OCN or */ +/* (MU_MIXER_CONTROL << 8) | MCN */ +/* or other specific value. */ +/* spec_id Entity/Language ID (if used) */ +/* parameter Pointer to request parameters */ +/* parameter_size Request parameters length */ +/* actual_size Actual processed size */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_class_instance_verify Verify instance is valid */ +/* _ux_host_stack_transfer_request Process transfer request */ +/* _ux_host_semaphore_get Get semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_control_request(UX_HOST_CLASS_AUDIO *audio, + UINT streaming_control, + UINT request_type, UINT request, + UINT request_value, + UINT spec_id, + UCHAR *parameter, ULONG parameter_size, ULONG *actual_size) +{ + +UX_ENDPOINT *control_endpoint; +UX_TRANSFER *transfer_request; +ULONG request_index = 0; +UINT status; + + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Check request settings. */ + switch(request_type & UX_REQUEST_TARGET) + { + case UX_REQUEST_TARGET_INTERFACE: + request_index = streaming_control ? + audio -> ux_host_class_audio_streaming_interface -> ux_interface_descriptor.bInterfaceNumber : + audio -> ux_host_class_audio_control_interface_number; + break; + case UX_REQUEST_TARGET_ENDPOINT: + request_index = audio -> ux_host_class_audio_isochronous_endpoint -> ux_endpoint_descriptor.bEndpointAddress; + break; + default: + return(UX_INVALID_PARAMETER); + } + + /* Protect thread reentry to this instance. */ + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); + + /* We need to get the default control endpoint transfer request pointer. */ + control_endpoint = &audio -> ux_host_class_audio_device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + + /* Check for status. */ + if (status != UX_SUCCESS) + { + /* Something went wrong. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } + + /* Create a transfer request for the specific setting. */ + transfer_request -> ux_transfer_request_data_pointer = parameter; + transfer_request -> ux_transfer_request_requested_length = parameter_size; + transfer_request -> ux_transfer_request_function = request; + transfer_request -> ux_transfer_request_type = request_type; + transfer_request -> ux_transfer_request_value = request_value; + transfer_request -> ux_transfer_request_index = request_index | (spec_id << 8); + + /* Send request to HCD layer. */ + status = _ux_host_stack_transfer_request(transfer_request); + + /* Save actual size. */ + if (actual_size) + *actual_size = transfer_request -> ux_transfer_request_actual_length; + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return completion status. */ + return(status); +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_control_value_get.c b/common/usbx_host_classes/src/ux_host_class_audio_control_value_get.c index ecc4d9e3..3318f3c3 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_control_value_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_control_value_get.c @@ -35,16 +35,25 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_control_value_get PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function obtains the dynamic values for a single audio control */ -/* on either the master channel or a specific channel. */ +/* This function obtains the dynamic feature values for a single audio */ +/* control on either the master channel or a specific channel. */ /* */ +/* Note only control value of BYTE, WORD and DWORD (<4) is supported. */ +/* E.g., Graphic Equalizer Control is not supported. */ +/* */ +/* Note it's not recommended for supporting audio device with complex */ +/* pinout scheme, where ux_host_class_audio_descriptors_parse can be */ +/* used to build audio pinout scheme, and settings can be changed by */ +/* ux_host_class_audio_control_request or ux_host_class_audio_feature */ +/* functions. */ +/* */ /* INPUT */ /* */ /* audio Pointer to audio class */ @@ -59,7 +68,8 @@ /* _ux_host_stack_class_instance_verify Verify instance is valid */ /* _ux_host_stack_transfer_request Process transfer request */ /* _ux_host_semaphore_get Get semaphore */ -/* _ux_host_semaphore_put Release semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ /* _ux_utility_memory_allocate Allocate memory block */ /* _ux_utility_memory_free Release memory block */ /* _ux_utility_short_get Read 16-bit value */ @@ -81,10 +91,22 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added audio 2.0 support, */ +/* protect reentry with mutex, */ +/* fixed error return code, */ +/* fixed EP0 protection, */ +/* supported more selectors, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_control_value_get(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control) { +#if defined(UX_HOST_CLASS_AUDIO_DISABLE_CONTROLS) + UX_PARAMETER_NOT_USED(audio); + UX_PARAMETER_NOT_USED(audio_control); + return(UX_FUNCTION_NOT_SUPPORTED); +#else UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; @@ -108,28 +130,52 @@ UCHAR * control_buffer; } /* Protect thread reentry to this instance. */ - status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_semaphore, UX_WAIT_FOREVER); + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); /* We need to get the default control endpoint transfer request pointer. */ control_endpoint = &audio -> ux_host_class_audio_device -> ux_device_control_endpoint; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; /* Need to allocate memory for the control_buffer. */ - control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 2); + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); if (control_buffer == UX_NULL) { /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return error. */ return(UX_MEMORY_INSUFFICIENT); } + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + + /* Check for status. */ + if (status != UX_SUCCESS) + { + + /* Something went wrong. */ + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } + + /* The buffer should be aligned. Returned data is little endian so DWord can be used + to copy any returned data of BYTE/WORD/DWORD. */ + * (ULONG *)control_buffer = 0; + /* Create a transfer request for the GET_CUR_buffer request. */ transfer_request -> ux_transfer_request_data_pointer = control_buffer; - transfer_request -> ux_transfer_request_requested_length = 2; + transfer_request -> ux_transfer_request_requested_length = 4; +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + transfer_request -> ux_transfer_request_function = (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) ? + UX_CLASS_AUDIO20_CUR : + UX_HOST_CLASS_AUDIO_GET_CUR; +#else transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_AUDIO_GET_CUR; +#endif transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; transfer_request -> ux_transfer_request_value = audio_control -> ux_host_class_audio_control_channel | (audio_control -> ux_host_class_audio_control << 8); transfer_request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (audio -> ux_host_class_audio_feature_unit_id << 8); @@ -138,20 +184,20 @@ UCHAR * control_buffer; status = _ux_host_stack_transfer_request(transfer_request); /* Check for correct transfer and entire control buffer returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == 2)) + if (status == UX_SUCCESS) { /* Update the CUR static value for the caller. */ - audio_control -> ux_host_class_audio_control_cur = _ux_utility_short_get(control_buffer); + audio_control -> ux_host_class_audio_control_cur = _ux_utility_long_get(control_buffer); } /* Free all used resources. */ _ux_utility_memory_free(control_buffer); /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return completion status. */ return(status); +#endif } - diff --git a/common/usbx_host_classes/src/ux_host_class_audio_control_value_set.c b/common/usbx_host_classes/src/ux_host_class_audio_control_value_set.c index 164f0465..84d13c2d 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_control_value_set.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_control_value_set.c @@ -35,16 +35,25 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_control_value_set PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function updates the dynamic values for a single audio control */ -/* on either the master channel or a specific channel. */ +/* This function updates the dynamic feature values for a single audio */ +/* control on either the master channel or a specific channel. */ /* */ +/* Note only control value of BYTE, WORD and DWORD (<4) is supported. */ +/* E.g., Graphic Equalizer Control is not supported. */ +/* */ +/* Note it's not recommended for supporting audio device with complex */ +/* pinout scheme, where ux_host_class_audio_descriptors_parse can be */ +/* used to build audio pinout scheme, and settings can be changed by */ +/* ux_host_class_audio_control_request or ux_host_class_audio_feature */ +/* functions. */ +/* */ /* INPUT */ /* */ /* audio Pointer to audio class */ @@ -60,6 +69,8 @@ /* _ux_host_stack_transfer_request Process transfer request */ /* _ux_host_semaphore_get Get semaphore */ /* _ux_host_semaphore_put Release semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ /* _ux_utility_memory_allocate Allocate memory block */ /* _ux_utility_memory_free Release memory block */ /* _ux_utility_short_put Write 16-bit value */ @@ -82,10 +93,21 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added audio 2.0 support, */ +/* protect reentry with mutex, */ +/* fixed error return code, */ +/* supported more selectors, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_control_value_set(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control) { +#if defined(UX_HOST_CLASS_AUDIO_DISABLE_CONTROLS) + UX_PARAMETER_NOT_USED(audio); + UX_PARAMETER_NOT_USED(audio_control); + return(UX_FUNCTION_NOT_SUPPORTED); +#else UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; @@ -106,43 +128,124 @@ UCHAR * control_buffer; } /* Protect thread reentry to this instance. */ - status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_semaphore, UX_WAIT_FOREVER); - if (status != UX_SUCCESS) - return(status); + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); /* We need to get the default control endpoint transfer request pointer. */ control_endpoint = &audio -> ux_host_class_audio_device -> ux_device_control_endpoint; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; /* Need to allocate memory for the control buffer. */ - control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 2); + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); if (control_buffer == UX_NULL) { /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return an error. */ return(UX_MEMORY_INSUFFICIENT); } - /* Update the control buffer with the current control value. */ - _ux_utility_short_put(control_buffer, (USHORT) audio_control -> ux_host_class_audio_control_cur); - /* Protect the control endpoint semaphore here. It will be unprotected in the transfer request function. */ status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); /* Check for status. */ if (status != UX_SUCCESS) - + { + /* Something went wrong. */ + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); return(status); - - /* Create a transfer request for the SET_CUR_buffer request. */ + } + + /* The buffer should be aligned. Returned data is little endian so DWord can be used + to copy any returned data of BYTE/WORD/DWORD. */ + _ux_utility_long_put(control_buffer, audio_control -> ux_host_class_audio_control_cur); + +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + if (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) + { + + /* Size RANGE Size + D1..0: Mute 1 2+1*3=5 + D3..2: Volume 2 2+2*3=8 + D5..4: Bass 1 + D7..6: Mid 1 + D9..8: Treble 1 + D11..10: Graphic Equalizer 4+NrBits + D13..12: Automatic Gain 1 + D15..14: Delay 4 2+4*3=14 + D17..16: Bass Boost 1 + D19..18: Loudness 1 + D21..20: Input Gain 2 + D23..22: Input Gain Pad 2 + D25..24: Phase Inverter 1 + D27..26: Underflow 1 + D29..28: Overflow 1 + */ + if (audio_control -> ux_host_class_audio_control == UX_CLASS_AUDIO20_FU_DELAY_CONTROL) + transfer_request -> ux_transfer_request_requested_length = 4; + else if ((audio_control -> ux_host_class_audio_control == UX_CLASS_AUDIO20_FU_VOLUME_CONTROL) || + (audio_control -> ux_host_class_audio_control == UX_CLASS_AUDIO20_FU_INPUT_GAIN_CONTROL) || + (audio_control -> ux_host_class_audio_control == UX_CLASS_AUDIO20_FU_INPUT_GAIN_PAD_CONTROL)) + transfer_request -> ux_transfer_request_requested_length = 2; + else if ((audio_control -> ux_host_class_audio_control != UX_CLASS_AUDIO20_FU_GRAPHIC_EQUALIZER_CONTROL) && + (audio_control -> ux_host_class_audio_control <= 14)) + transfer_request -> ux_transfer_request_requested_length = 1; + else + { + + /* Something went wrong. */ + _ux_utility_memory_free(control_buffer); + _ux_host_semaphore_put(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_INVALID_PARAMETER); + } + } + else +#endif + { + + /* Size + D0: Mute 1 + D1: Volume 2 + D2: Bass 1 + D3: Mid 1 + D4: Treble 1 + D5: Graphic Equalizer 4+NrBits + D6: Automatic Gain 1 + D7: Delay 2 + D8: Bass Boost 1 + D9: Loudness 1 + */ + if ((audio_control -> ux_host_class_audio_control == UX_HOST_CLASS_AUDIO_MUTE_CONTROL) || + (audio_control -> ux_host_class_audio_control == UX_HOST_CLASS_AUDIO_DELAY_CONTROL)) + transfer_request -> ux_transfer_request_requested_length = 2; + else if ((audio_control -> ux_host_class_audio_control <= 9) && + (audio_control -> ux_host_class_audio_control != UX_HOST_CLASS_AUDIO_GRAPHIC_EQUALIZER_CONTROL)) + transfer_request -> ux_transfer_request_requested_length = 1; + else + { + + /* Something went wrong. */ + _ux_utility_memory_free(control_buffer); + _ux_host_semaphore_put(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_INVALID_PARAMETER); + } + } + + /* Create a transfer request for the SET_CUR request. */ transfer_request -> ux_transfer_request_data_pointer = control_buffer; - transfer_request -> ux_transfer_request_requested_length = 2; +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + transfer_request -> ux_transfer_request_function = (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) ? + UX_CLASS_AUDIO20_CUR : + UX_HOST_CLASS_AUDIO_SET_CUR; +#else transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_AUDIO_SET_CUR; +#endif transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; transfer_request -> ux_transfer_request_value = audio_control -> ux_host_class_audio_control_channel | (audio_control -> ux_host_class_audio_control << 8); transfer_request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (audio -> ux_host_class_audio_feature_unit_id << 8); @@ -154,9 +257,9 @@ UCHAR * control_buffer; _ux_utility_memory_free(control_buffer); /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return completion status. */ return(status); +#endif } - diff --git a/common/usbx_host_classes/src/ux_host_class_audio_deactivate.c b/common/usbx_host_classes/src/ux_host_class_audio_deactivate.c index 85513026..2cfd15df 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_deactivate.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_deactivate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_deactivate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -58,8 +58,8 @@ /* */ /* _ux_host_stack_class_instance_destroy Destroy class instance */ /* _ux_host_stack_endpoint_transfer_abort Abort outstanding transfer */ -/* _ux_host_semaphore_get Get semaphore */ -/* _ux_host_semaphore_delete Delete semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_delete Delete mutex */ /* _ux_utility_memory_free Release memory block */ /* */ /* CALLED BY */ @@ -76,39 +76,75 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added interrupt support, */ +/* protect reentry with mutex, */ +/* added feedback support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_deactivate(UX_HOST_CLASS_COMMAND *command) { UX_HOST_CLASS_AUDIO *audio; -UINT status; +#if defined(UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT) +UX_HOST_CLASS_AUDIO_AC *ac; +#endif /* Get the instance for this class. */ - audio= (UX_HOST_CLASS_AUDIO *) command -> ux_host_class_command_instance; + audio = (UX_HOST_CLASS_AUDIO *) command -> ux_host_class_command_instance; - /* The audio is being shut down. */ - audio -> ux_host_class_audio_state = UX_HOST_CLASS_INSTANCE_SHUTDOWN; +#if defined(UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT) + if (_ux_host_class_audio_subclass_get(audio) == UX_HOST_CLASS_AUDIO_SUBCLASS_CONTROL) + { + ac = (UX_HOST_CLASS_AUDIO_AC *)audio; + + /* Stop interrupt and free allocated buffer for it. */ + if (ac -> ux_host_class_audio_interrupt_endpoint) + { + _ux_host_stack_endpoint_transfer_abort(ac -> ux_host_class_audio_interrupt_endpoint); + _ux_utility_memory_free(ac -> ux_host_class_audio_interrupt_endpoint -> + ux_endpoint_transfer_request.ux_transfer_request_data_pointer); + } + + /* The enumeration thread needs to sleep a while to allow the application or the class that may be using + endpoints to exit properly. */ + _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM); + + /* Destroy the instance. */ + _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); + } + else +#endif + { - /* Protect thread reentry to this instance. */ - status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_semaphore, UX_WAIT_FOREVER); - if (status != UX_SUCCESS) + /* The audio is being shut down. */ + audio -> ux_host_class_audio_state = UX_HOST_CLASS_INSTANCE_SHUTDOWN; - /* Return error. */ - return(status); - - /* We need to abort transactions on the iso out pipe. */ - _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_isochronous_endpoint); + /* Protect thread reentry to this instance. */ + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); + + /* We need to abort transactions on the iso pipe. */ + if (audio -> ux_host_class_audio_isochronous_endpoint) + _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_isochronous_endpoint); +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + if (audio -> ux_host_class_audio_feedback_endpoint) + { + _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_feedback_endpoint); + _ux_utility_memory_free(audio -> ux_host_class_audio_feedback_endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer); + } +#endif - /* The enumeration thread needs to sleep a while to allow the application or the class that may be using - endpoints to exit properly. */ - _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM); + /* The enumeration thread needs to sleep a while to allow the application or the class that may be using + endpoints to exit properly. */ + _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM); - /* Destroy the instance. */ - _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); + /* Destroy the instance. */ + _ux_host_stack_class_instance_destroy(audio -> ux_host_class_audio_class, (VOID *) audio); - /* Destroy the semaphore. */ - _ux_host_semaphore_delete(&audio -> ux_host_class_audio_semaphore); + /* Destroy the semaphore. */ + _ux_host_mutex_delete(&audio -> ux_host_class_audio_mutex); + } /* Before we free the device resources, we need to inform the application that the device is removed. */ diff --git a/common/usbx_host_classes/src/ux_host_class_audio_descriptor_get.c b/common/usbx_host_classes/src/ux_host_class_audio_descriptor_get.c index caf8d46d..14fa20b2 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_descriptor_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_descriptor_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_descriptor_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,31 +72,56 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used shared device config */ +/* descriptor for enum scan, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_descriptor_get(UX_HOST_CLASS_AUDIO *audio) { +UX_DEVICE *device; +UX_CONFIGURATION *configuration; UCHAR * descriptor; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; -UX_CONFIGURATION configuration; UINT status; ULONG total_configuration_length; + /* Get device, current configuration. */ + device = audio -> ux_host_class_audio_device; + configuration = device -> ux_device_current_configuration; + + /* Check if descriptor is previously saved. */ + if (device -> ux_device_packed_configuration != UX_NULL) + { + audio -> ux_host_class_audio_configuration_descriptor = + device -> ux_device_packed_configuration; + audio -> ux_host_class_audio_configuration_descriptor_length = + configuration -> ux_configuration_descriptor.wTotalLength; + + /* Descriptor must be kept after enum. */ + device -> ux_device_packed_configuration_keep_count ++; + return(UX_SUCCESS); + } + + /* Get total length of configuration descriptors. */ + total_configuration_length = configuration -> ux_configuration_descriptor.wTotalLength; + /* We need to get the default control endpoint transfer request pointer. */ - control_endpoint = &audio -> ux_host_class_audio_device -> ux_device_control_endpoint; + control_endpoint = &device -> ux_device_control_endpoint; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; /* Need to allocate memory for the descriptor. */ - descriptor = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_CONFIGURATION_DESCRIPTOR_LENGTH); + descriptor = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, total_configuration_length); if (descriptor == UX_NULL) return(UX_MEMORY_INSUFFICIENT); /* Create a transfer request for the GET_DESCRIPTOR request. */ transfer_request -> ux_transfer_request_data_pointer = descriptor; - transfer_request -> ux_transfer_request_requested_length = UX_CONFIGURATION_DESCRIPTOR_LENGTH; + transfer_request -> ux_transfer_request_requested_length = total_configuration_length; transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR; transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; transfer_request -> ux_transfer_request_value = UX_CONFIGURATION_DESCRIPTOR_ITEM << 8; @@ -106,49 +131,22 @@ ULONG total_configuration_length; status = _ux_host_stack_transfer_request(transfer_request); /* Check for correct transfer and entire descriptor returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == UX_CONFIGURATION_DESCRIPTOR_LENGTH)) + if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == total_configuration_length)) { - /* The descriptor is in a packed format, parse it locally. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_configuration_descriptor_structure, - UX_CONFIGURATION_DESCRIPTOR_ENTRIES, (UCHAR *) &configuration.ux_configuration_descriptor); - - /* Now we have the configuration descriptor which will tell us how many - bytes there are in the entire descriptor. */ - total_configuration_length = configuration.ux_configuration_descriptor.wTotalLength; - - /* Free the previous descriptor. */ - _ux_utility_memory_free(descriptor); - - /* Allocate enough memory to read all descriptors attached - to this configuration. */ - descriptor = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, total_configuration_length); - if (descriptor == UX_NULL) - return(UX_MEMORY_INSUFFICIENT); - - /* Set the length we need to retrieve. */ - transfer_request -> ux_transfer_request_requested_length = total_configuration_length; - - /* And reprogram the descriptor buffer address. */ - transfer_request -> ux_transfer_request_data_pointer = descriptor; - - /* Send request to HCD layer. */ - status = _ux_host_stack_transfer_request(transfer_request); - - /* Check for correct transfer and entire descriptor returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == total_configuration_length)) - { + /* Save the address of the entire configuration descriptor of the audio device. */ + audio -> ux_host_class_audio_configuration_descriptor = descriptor; - /* Save the address of the entire configuration descriptor of the audio device. */ - audio -> ux_host_class_audio_configuration_descriptor = descriptor; + /* Save the length of the entire descriptor too. */ + audio -> ux_host_class_audio_configuration_descriptor_length = total_configuration_length; - /* Save the length of the entire descriptor too. */ - audio -> ux_host_class_audio_configuration_descriptor_length = total_configuration_length; + /* Keep descriptor to be shared for this device. */ + device -> ux_device_packed_configuration = descriptor; + device -> ux_device_packed_configuration_keep_count ++; - /* We do not free the resource for the descriptor until the device is - plugged out. */ - return(UX_SUCCESS); - } + /* We do not free the resource for the descriptor until the device is + plugged out. */ + return(UX_SUCCESS); } /* Free all used resources. */ diff --git a/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c b/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c new file mode 100644 index 00000000..cf8e3269 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c @@ -0,0 +1,206 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_descriptors_parse PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function parsees all interface descriptors and their audio */ +/* class specific descriptors relates to current audio instance. */ +/* */ +/* The function scans the device configuration descriptor. Once the */ +/* interface descriptors of the audio instance are found, each audio */ +/* class descriptors belong to the interface are passed to parse */ +/* function for caller one by one to parse. The interface descriptor */ +/* is also passed to provide more information. Another pointer to */ +/* arguments is also available as parse function parameter for caller */ +/* to pass necessary caller specific data to process in parse function.*/ +/* */ +/* The descriptor parsing can be terminated by returning non-zero */ +/* code in parse function. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio instance */ +/* parse_function Parse function for each */ +/* audio class descriptor */ +/* arg Parse function argument */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* CALLED BY */ +/* */ +/* Audio Class */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_descriptors_parse(UX_HOST_CLASS_AUDIO *audio, + UINT(*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UCHAR *packed_endpoint_descriptor, + UCHAR *packed_audio_descriptor), + VOID* arg) +{ + +UCHAR *descriptor; +UCHAR *interface_descriptor; +UCHAR *endpoint_descriptor; +ULONG ac_interface, as_interface; +ULONG total_descriptor_length; +ULONG descriptor_length; +ULONG descriptor_type; +UINT status; + + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Device state check. */ + if (audio -> ux_host_class_audio_device -> ux_device_state != UX_DEVICE_CONFIGURED) + return(UX_INVALID_STATE); + + /* Get the descriptor to the selected format. */ + descriptor = audio -> ux_host_class_audio_configuration_descriptor; + total_descriptor_length = audio -> ux_host_class_audio_configuration_descriptor_length; + + /* Get target interface number of control/streaming. */ + ac_interface = audio -> ux_host_class_audio_control_interface_number; + as_interface = audio -> ux_host_class_audio_streaming_interface -> ux_interface_descriptor.bInterfaceNumber; + + /* Haven't found interface, endpoint yet. */ + interface_descriptor = UX_NULL; + endpoint_descriptor = UX_NULL; + + /* Scan the descriptor for the Audio Control/Streaming interface. */ + while (total_descriptor_length) + { + + /* Gather the length, type and subtype of the descriptor. */ + descriptor_length = *descriptor; + descriptor_type = *(descriptor + 1); + + /* Make sure this descriptor has at least the minimum length. */ + if (descriptor_length < 3) + return(UX_DESCRIPTOR_CORRUPTED); + + /* Process relative to descriptor type. */ + switch (descriptor_type) + { + + case UX_INTERFACE_DESCRIPTOR_ITEM: + + /* Ensure we have the correct interface for Audio Control/Streaming. */ + if (descriptor[2] == ac_interface || descriptor[2] == as_interface) + { + + /* Mark we have found it. */ + interface_descriptor = descriptor; + } + else + { + + /* Haven't found it. */ + interface_descriptor = UX_NULL; + } + break; + + case UX_ENDPOINT_DESCRIPTOR_ITEM: + + /* Log endpoint descriptor for following CS_ENDPOINT. */ + endpoint_descriptor = descriptor; + break; + + case UX_HOST_CLASS_AUDIO_CS_ENDPOINT: + case UX_HOST_CLASS_AUDIO_CS_INTERFACE: + + /* Have we found the audio interface yet? */ + if (interface_descriptor != UX_NULL) + { + + /* Yes, parse the audio specific descriptor. */ + status = parse_function(arg, interface_descriptor, endpoint_descriptor, descriptor); + + /* Terminate the parsing if status is not 0. */ + if (status) + { + + /* Parsing terminated by user, it's OK. */ + return(UX_SUCCESS); + } + } + break; + + default: + break; + } + + /* Verify if the descriptor is still valid. */ + if (descriptor_length > total_descriptor_length) + return(UX_DESCRIPTOR_CORRUPTED); + + /* Jump to the next descriptor if we have not reached the end. */ + descriptor += descriptor_length; + + /* And adjust the length left to parse in the descriptor. */ + total_descriptor_length -= descriptor_length; + } + + /* We get here when all descriptors scanned. */ + return(UX_SUCCESS); +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_device_controls_list_get.c b/common/usbx_host_classes/src/ux_host_class_audio_device_controls_list_get.c index dd851657..2803a9cb 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_device_controls_list_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_device_controls_list_get.c @@ -30,19 +30,21 @@ #include "ux_host_stack.h" +#if !defined(UX_HOST_CLASS_AUDIO_DISABLE_CONTROLS) /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_device_controls_list_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* This function obtains the controls for the audio device. */ +/* This function obtains the controls of first found feature unit */ +/* for the audio device. */ /* */ /* INPUT */ /* */ @@ -69,16 +71,18 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added audio 2.0 support, */ +/* internal clean up, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_device_controls_list_get(UX_HOST_CLASS_AUDIO *audio) { UCHAR * descriptor; -UX_INTERFACE_DESCRIPTOR interface_descriptor; -UX_HOST_CLASS_AUDIO_INPUT_TERMINAL_DESCRIPTOR input_interface_descriptor; -UX_HOST_CLASS_AUDIO_FEATURE_UNIT_DESCRIPTOR feature_unit_interface_descriptor; ULONG total_descriptor_length; +ULONG ac_interface; ULONG descriptor_length; ULONG descriptor_type; ULONG descriptor_subtype; @@ -86,12 +90,16 @@ ULONG descriptor_found; ULONG control_size_bytes; UCHAR * control_bit_map_address; ULONG channel_number; +ULONG itt_nb_channels; /* Get the descriptor to the entire configuration */ descriptor = audio -> ux_host_class_audio_configuration_descriptor; total_descriptor_length = audio -> ux_host_class_audio_configuration_descriptor_length; - + + /* Get AC interface number. */ + ac_interface = audio -> ux_host_class_audio_control_interface_number; + /* Default is Interface descriptor not yet found. */ descriptor_found = UX_FALSE; @@ -121,16 +129,10 @@ ULONG channel_number; switch(descriptor_type) { - case UX_INTERFACE_DESCRIPTOR_ITEM: - /* Parse the interface descriptor and make it machine independent. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_interface_descriptor_structure, - UX_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &interface_descriptor); - - /* Ensure we have the correct interface for Audio streaming. */ - if ((interface_descriptor.bInterfaceClass == UX_HOST_CLASS_AUDIO_CLASS) && - (interface_descriptor.bInterfaceSubClass == UX_HOST_CLASS_AUDIO_SUBCLASS_CONTROL)) + /* Ensure we have the correct AC interface for Audio streaming. */ + if (ac_interface == descriptor[2]) /* Mark we have found it. */ descriptor_found = UX_TRUE; @@ -138,7 +140,6 @@ ULONG channel_number; descriptor_found = UX_FALSE; break; - case UX_HOST_CLASS_AUDIO_CS_INTERFACE: @@ -151,34 +152,53 @@ ULONG channel_number; { case UX_HOST_CLASS_AUDIO_CS_INPUT_TERMINAL: - - /* Make the descriptor machine independent. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_class_audio_input_terminal_descriptor_structure, - UX_HOST_CLASS_AUDIO_INPUT_TERMINAL_DESCRIPTOR_ENTRIES, (UCHAR *) &input_interface_descriptor); - + +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + if (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) + { + + /* Get bNrChannels @ 8. */ + itt_nb_channels = descriptor[8]; + } + else +#endif + { + + /* Get bNrChannels @ 7. */ + itt_nb_channels = descriptor[7]; + } + /* Get the number of channels and check for maximum allowed. */ - if (input_interface_descriptor.bNrChannels > UX_HOST_CLASS_AUDIO_MAX_CHANNEL) - audio -> ux_host_class_audio_channels = UX_HOST_CLASS_AUDIO_MAX_CHANNEL; + if (itt_nb_channels > UX_HOST_CLASS_AUDIO_MAX_CHANNEL) + audio -> ux_host_class_audio_channels = UX_HOST_CLASS_AUDIO_MAX_CHANNEL; else - audio -> ux_host_class_audio_channels = input_interface_descriptor.bNrChannels; + audio -> ux_host_class_audio_channels = itt_nb_channels; break; - case UX_HOST_CLASS_AUDIO_CS_FEATURE_UNIT: - /* Make the descriptor machine independent. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_class_audio_feature_unit_descriptor_structure, - UX_HOST_CLASS_AUDIO_FEATURE_UNIT_DESCRIPTOR_ENTRIES, (UCHAR *) &feature_unit_interface_descriptor); - - /* Store the Feature Unit ID, used to set/get the audio controls. */ - audio -> ux_host_class_audio_feature_unit_id = feature_unit_interface_descriptor.bUnitID; + /* Store the Feature Unit ID @ 3, used to set/get the audio controls. */ + audio -> ux_host_class_audio_feature_unit_id = descriptor[3]; + +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + + /* Audio 2.0 control size is fixed to 4 (bytes), controls start from @ 5. */ + if (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) + { + control_size_bytes = 4; + control_bit_map_address = (UCHAR *) &descriptor[5]; + } + else +#endif + { + + /* Get the size of each control in bytes @ 5. */ + control_size_bytes = descriptor[5]; + + /* Get the address of the first control bit map @ 6. */ + control_bit_map_address = (UCHAR *) &descriptor[6]; + } - /* Get the size of each control in bytes. */ - control_size_bytes = feature_unit_interface_descriptor.bControlSize; - - /* Get the address of the first control bit map. */ - control_bit_map_address = (UCHAR *) &feature_unit_interface_descriptor.bmaControls; - /* Walk all the controls and retrieve them one by one. */ for (channel_number = 0; channel_number < audio -> ux_host_class_audio_channels; channel_number++) { @@ -252,4 +272,4 @@ ULONG channel_number; not find the right audio device. */ return(UX_HOST_CLASS_AUDIO_WRONG_TYPE); } - +#endif diff --git a/common/usbx_host_classes/src/ux_host_class_audio_device_type_get.c b/common/usbx_host_classes/src/ux_host_class_audio_device_type_get.c index 7ac539ff..c0fe1af4 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_device_type_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_device_type_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_device_type_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,21 +67,25 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* removed protocol store, */ +/* added audio 2.0 support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_device_type_get(UX_HOST_CLASS_AUDIO *audio) { -UCHAR * descriptor; -UX_INTERFACE_DESCRIPTOR interface_descriptor; -UX_HOST_CLASS_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR output_interface_descriptor; -UX_HOST_CLASS_AUDIO_INPUT_TERMINAL_DESCRIPTOR input_interface_descriptor; +UCHAR *iad; +UCHAR *descriptor; +UCHAR *interface_descriptor; ULONG total_descriptor_length; ULONG descriptor_length; ULONG descriptor_type; ULONG descriptor_subtype; ULONG descriptor_found; - +ULONG interface_number; +UINT i; /* Get the descriptor to the entire configuration. */ descriptor = audio -> ux_host_class_audio_configuration_descriptor; @@ -89,6 +93,10 @@ ULONG descriptor_found; /* Default is Interface descriptor not yet found. */ descriptor_found = UX_FALSE; + iad = UX_NULL; + interface_descriptor = UX_NULL; + interface_number = audio -> ux_host_class_audio_streaming_interface + -> ux_interface_descriptor.bInterfaceNumber; /* Scan the descriptor for the Audio Streaming interface. */ while (total_descriptor_length) @@ -116,80 +124,111 @@ ULONG descriptor_found; switch (descriptor_type) { + /* There is IAD in case UAC 1.0 with IAD or UAC 2.0/3.0. */ + case UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ITEM: - case UX_INTERFACE_DESCRIPTOR_ITEM: + /* Ensure we have the correct IAD that includes the interface. */ + if ((descriptor[4] == UX_HOST_CLASS_AUDIO_CLASS) && + (descriptor[2] <= interface_number) && + (descriptor[2] + descriptor[3] > interface_number)) + { + iad = descriptor; + + /* Control interface must be the first interface (UAC 2.0/3.0). */ + audio -> ux_host_class_audio_control_interface_number = descriptor[2]; + } + else + iad = UX_NULL; + break; - /* Parse the interface descriptor and make it machine independent. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_interface_descriptor_structure, - UX_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &interface_descriptor); + case UX_INTERFACE_DESCRIPTOR_ITEM: /* Ensure we have the correct interface for Audio Control. */ - if ((interface_descriptor.bInterfaceClass == UX_HOST_CLASS_AUDIO_CLASS) && - (interface_descriptor.bInterfaceSubClass == UX_HOST_CLASS_AUDIO_SUBCLASS_CONTROL)) + if ((descriptor[5] == UX_HOST_CLASS_AUDIO_CLASS) && + (descriptor[6] == UX_HOST_CLASS_AUDIO_SUBCLASS_CONTROL)) + interface_descriptor = descriptor; + else { - - /* Mark we have found it. */ - descriptor_found = UX_TRUE; - - /* Get the interface number of this descriptor and save it in the audio - instance. This will be useful to program the audio controls. */ - audio -> ux_host_class_audio_control_interface_number = interface_descriptor.bInterfaceNumber; + interface_descriptor = UX_NULL; + descriptor_found = UX_FALSE; } - else + + /* Check IAD. */ + if (iad) { - descriptor_found = UX_FALSE; + /* Check if interface is out of IAD. */ + if ((iad[2] > interface_descriptor[2]) || + (iad[2] + iad[3] <= interface_descriptor[2])) + iad = UX_NULL; } break; - case UX_HOST_CLASS_AUDIO_CS_INTERFACE: /* First make sure we have found the correct generic interface descriptor. */ - if (descriptor_found == UX_TRUE) + if (interface_descriptor != UX_NULL) { /* Check the sub type. */ switch (descriptor_subtype) { + /* UAC 1.0, AC interface contains AS interface information. */ + case UX_HOST_CLASS_AUDIO_CS_HEADER: - case UX_HOST_CLASS_AUDIO_CS_INPUT_TERMINAL: - - /* Make the descriptor machine independent. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_class_audio_input_terminal_descriptor_structure, - UX_HOST_CLASS_AUDIO_INPUT_TERMINAL_DESCRIPTOR_ENTRIES, (UCHAR *) &input_interface_descriptor); - - /* Make sure we have the right terminal link. */ - if (input_interface_descriptor.bTerminalID == audio -> ux_host_class_audio_terminal_link) + if (interface_descriptor[7] == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_01_00) { - audio -> ux_host_class_audio_type = UX_HOST_CLASS_AUDIO_OUTPUT; - - /* Return successful completion. */ - return(UX_SUCCESS); + /* Check baInterfaceNr@8 to see if it's the right interface. */ + for (i = 0; i < descriptor[7]; i ++) + { + if (descriptor[8 + i] == interface_number) + { + descriptor_found = UX_TRUE; + break; + } + } } + else if (iad) + { + /* UAC 2.0 or 3.0 IAD first interface indicates AC. */ + descriptor_found = UX_TRUE; + } break; + case UX_HOST_CLASS_AUDIO_CS_INPUT_TERMINAL: case UX_HOST_CLASS_AUDIO_CS_OUTPUT_TERMINAL: - /* Make the descriptor machine independent. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_class_audio_output_terminal_descriptor_structure, - UX_HOST_CLASS_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR_ENTRIES, (UCHAR *) &output_interface_descriptor); - - /* Make sure we have the right terminal link. */ - if (output_interface_descriptor.bTerminalID == audio -> ux_host_class_audio_terminal_link) + /* Ensure it's right AC ITT/OTT. */ + if (descriptor_found) { - audio -> ux_host_class_audio_type = UX_HOST_CLASS_AUDIO_INPUT; + /* In UAC 1.0/2.0/3.0, bTerminalID at 3, wTerminalType at 4. */ + if (descriptor[3] == audio -> ux_host_class_audio_terminal_link) + { - /* Return successful completion. */ - return(UX_SUCCESS); + /* Connect to ITT, it's output, connect to OTT it's input. */ + if (descriptor_subtype == UX_HOST_CLASS_AUDIO_CS_INPUT_TERMINAL) + audio -> ux_host_class_audio_type = UX_HOST_CLASS_AUDIO_OUTPUT; + else + audio -> ux_host_class_audio_type = UX_HOST_CLASS_AUDIO_INPUT; + + /* Return successful completion. */ + return(UX_SUCCESS); + } } + break; + + default: + break; } } break; + + default: + break; } /* Verify if the descriptor is still valid. */ diff --git a/common/usbx_host_classes/src/ux_host_class_audio_endpoints_get.c b/common/usbx_host_classes/src/ux_host_class_audio_endpoints_get.c index f1cee1cb..29892249 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_endpoints_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_endpoints_get.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Audio Class */ /** */ @@ -30,43 +30,48 @@ #include "ux_host_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_audio_endpoints_get PORTABLE C */ -/* 6.1 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_endpoints_get PORTABLE C */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function searches for the handle of the isochronous endpoints. */ -/* */ -/* INPUT */ -/* */ -/* audio Pointer to audio class */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ -/* _ux_host_stack_interface_endpoint_get Get interface endpoint */ -/* */ -/* CALLED BY */ -/* */ -/* Audio Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* This function searches for the handle of the isochronous endpoints. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_interface_endpoint_get Get interface endpoint */ +/* */ +/* CALLED BY */ +/* */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* saved transfer direction, */ +/* added feedback support, */ +/* refined ISO support logic, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_endpoints_get(UX_HOST_CLASS_AUDIO *audio) @@ -75,12 +80,21 @@ UINT _ux_host_class_audio_endpoints_get(UX_HOST_CLASS_AUDIO *audio) UINT status; UINT endpoint_index; UX_ENDPOINT *endpoint; +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) +UX_TRANSFER *transfer; +ULONG packet_length; +#endif + /* Reset endpoints. */ + audio -> ux_host_class_audio_isochronous_endpoint = UX_NULL; +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + audio -> ux_host_class_audio_feedback_endpoint = UX_NULL; +#endif /* Search the ISO OUT endpoint. It is attached to the interface container. */ for (endpoint_index = 0; endpoint_index < audio -> ux_host_class_audio_streaming_interface -> ux_interface_descriptor.bNumEndpoints; endpoint_index++) - { + { /* Get interface endpoint. */ status = _ux_host_stack_interface_endpoint_get(audio -> ux_host_class_audio_streaming_interface, endpoint_index, &endpoint); @@ -89,22 +103,47 @@ UX_ENDPOINT *endpoint; if (status == UX_SUCCESS) { - /* Check if endpoint is iso and OUT. */ - if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT) && - ((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_ISOCHRONOUS_ENDPOINT)) + /* Check if endpoint is ISO. */ + if ((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_ISOCHRONOUS_ENDPOINT) { - /* We have found the bulk endpoint, save it. */ - audio -> ux_host_class_audio_isochronous_endpoint = endpoint; - break; + /* Check endpoint direction. */ + if ((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT) + { + + /* We have found the ISO OUT endpoint. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_type = UX_REQUEST_OUT; + + /* For OUTPUT, it's data endpoint, else feedback. */ + if (audio -> ux_host_class_audio_type == UX_HOST_CLASS_AUDIO_OUTPUT) + audio -> ux_host_class_audio_isochronous_endpoint = endpoint; +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + else + audio -> ux_host_class_audio_feedback_endpoint = endpoint; +#endif + } + else + { + + /* We have found the ISO IN endpoint. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_type = UX_REQUEST_IN; + + /* For INPUT, it's data endpoint, else feedback. */ + if (audio -> ux_host_class_audio_type == UX_HOST_CLASS_AUDIO_INPUT) + audio -> ux_host_class_audio_isochronous_endpoint = endpoint; +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + else + audio -> ux_host_class_audio_feedback_endpoint = endpoint; +#endif + } } - } - } + } + } /* The isochronous endpoint is mandatory. If we didn't find it, return an error. */ if (audio -> ux_host_class_audio_isochronous_endpoint == UX_NULL) { - + /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN); @@ -113,8 +152,60 @@ UX_ENDPOINT *endpoint; return(UX_ENDPOINT_HANDLE_UNKNOWN); } - - /* Return successful status. */ + +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + + /* With feedback, allocate buffer for packed feedback data. */ + if (audio -> ux_host_class_audio_feedback_endpoint) + { + + /* Get transfer. */ + endpoint = audio -> ux_host_class_audio_feedback_endpoint; + transfer = &endpoint -> ux_endpoint_transfer_request; + + /* Allocate buffer for feedback transfer (minimum 4 to fill both FS and HS). */ + packet_length = transfer -> ux_transfer_request_packet_length; + if (packet_length < sizeof(audio -> ux_host_class_audio_feedback_buffer)) + packet_length = sizeof(audio -> ux_host_class_audio_feedback_buffer); + transfer -> ux_transfer_request_data_pointer = _ux_utility_memory_allocate( + UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, + packet_length); + if (transfer -> ux_transfer_request_data_pointer == UX_NULL) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_MEMORY_INSUFFICIENT); + } + else + { + + /* Sync previous feedback data. */ + _ux_utility_memory_copy(transfer -> ux_transfer_request_data_pointer, + audio -> ux_host_class_audio_feedback_buffer, + sizeof(audio -> ux_host_class_audio_feedback_buffer)); /* Use case of memcpy is verified. */ + } + + /* Fill the transfer request with all the required fields. */ + transfer -> ux_transfer_request_endpoint = audio -> ux_host_class_audio_feedback_endpoint; + transfer -> ux_transfer_request_requested_length = (endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) ? + transfer -> ux_transfer_request_packet_length : + ((_ux_host_class_audio_speed_get(audio) == UX_HIGH_SPEED_DEVICE) ? + UX_FEEDBACK_SIZE_HIGH_SPEED : UX_FEEDBACK_SIZE_FULL_SPEED); + transfer -> ux_transfer_request_completion_function = _ux_host_class_audio_feedback_transfer_completed; + transfer -> ux_transfer_request_class_instance = audio; + + /* Start feedback transfer in background. */ + status = _ux_host_stack_transfer_request(transfer); + if (status != UX_SUCCESS) + return(status); + } +#endif + + /* Return successful status. */ return(UX_SUCCESS); } - diff --git a/common/usbx_host_classes/src/ux_host_class_audio_entity_control_get.c b/common/usbx_host_classes/src/ux_host_class_audio_entity_control_get.c new file mode 100644 index 00000000..22f06182 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_entity_control_get.c @@ -0,0 +1,336 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_entity_control_get PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function obtains the static values for a single audio control */ +/* control on either the master channel or a specific channel. */ +/* */ +/* Note only control value of BYTE, WORD and DWORD (<4) is supported. */ +/* E.g., Graphic Equalizer Control is not supported. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* audio_control Pointer to audio control */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_class_instance_verify Verify instance is valid */ +/* _ux_host_stack_transfer_request Process transfer request */ +/* _ux_host_semaphore_get Get semaphore */ +/* _ux_host_semaphore_put Release semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ +/* _ux_utility_memory_allocate Allocate memory block */ +/* _ux_utility_memory_free Release memory block */ +/* _ux_utility_short_get Read 16-bit value */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_entity_control_get(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control) +{ + +UINT status; +UCHAR * control_buffer; +ULONG actual_size; +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) +ULONG n_subs, sub, pos, min, max, res, size; +#endif + + + /* Validate control size. */ + if (audio_control -> ux_host_class_audio_control_size > 4) + return(UX_INVALID_PARAMETER); + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Protect thread reentry to this instance. */ + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); + +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + if (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) + { + + /* Need to allocate enough memory for the control buffer. */ + /* Max RANGE size (single item): 2+4*3=14. */ + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 16); + if (control_buffer == UX_NULL) + { + + /* Return an error. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_MEMORY_INSUFFICIENT); + } + + /* Issue GET RANGE request. */ + status = _ux_host_class_audio_control_request(audio, 0, + UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE, + UX_CLASS_AUDIO20_RANGE, + audio_control -> ux_host_class_audio_control_channel | + (audio_control -> ux_host_class_audio_control << 8), + audio_control -> ux_host_class_audio_control_entity, + control_buffer, 16, &actual_size); + + /* Check request status code. */ + if (status == UX_SUCCESS) + { + + /* Check returned size. */ + if (actual_size < 2) + { + + /* Return an error. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + _ux_utility_memory_free(control_buffer); + return(UX_TRANSFER_ERROR); + } + + /* Check wNumSubRanges. */ + n_subs = _ux_utility_short_get(control_buffer); + if (n_subs > 1) + { + + /* wNumSubRanges is short, control size max 4, no overflow. */ + size = 2 + n_subs * audio_control -> ux_host_class_audio_control_size; + if (size > 16) + { + + /* Issue GET RANGE again with larger buffer. */ + _ux_utility_memory_free(control_buffer); + control_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, size); + if (control_buffer == UX_NULL) + { + + /* Return an error. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_MEMORY_INSUFFICIENT); + } + + /* Issue GET RANGE request. */ + status = _ux_host_class_audio_control_request(audio, 0, + UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE, + UX_CLASS_AUDIO20_RANGE, + audio_control -> ux_host_class_audio_control_channel | + (audio_control -> ux_host_class_audio_control << 8), + audio_control -> ux_host_class_audio_control_entity, + control_buffer, size, &actual_size); + + if ((status != UX_SUCCESS) || (actual_size != size)) + { + + /* Return an error. */ + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_TRANSFER_ERROR); + } + } + } + + /* Parse returned values. */ + audio_control -> ux_host_class_audio_control_max = 0; + audio_control -> ux_host_class_audio_control_min = 0xFFFFFFFF; + audio_control -> ux_host_class_audio_control_res = 0; + pos = 2; + for (sub = 0; sub < n_subs; sub ++) + { + + /* Get MIN, MAX and POS. */ + switch(audio_control -> ux_host_class_audio_control_size) + { + case 1: + min = *(control_buffer + pos); + pos ++; + max = *(control_buffer + pos); + pos ++; + res = *(control_buffer + pos); + pos ++; + break; + + case 2: + min = _ux_utility_short_get(control_buffer + pos); + pos += 2; + max = _ux_utility_short_get(control_buffer + pos); + pos += 2; + res = _ux_utility_short_get(control_buffer + pos); + pos += 2; + break; + + default: + min = _ux_utility_long_get(control_buffer + pos); + pos += 4; + max = _ux_utility_long_get(control_buffer + pos); + pos += 4; + res = _ux_utility_long_get(control_buffer + pos); + pos += 4; + break; + } + + /* Keep MAX. */ + if (audio_control -> ux_host_class_audio_control_max < max) + audio_control -> ux_host_class_audio_control_max = max; + + /* Keep MIN. */ + if (audio_control -> ux_host_class_audio_control_min > min) + audio_control -> ux_host_class_audio_control_min = min; + + /* If there is RES, keep the min of RES. */ + if (audio_control -> ux_host_class_audio_control_res == 0) + audio_control -> ux_host_class_audio_control_res = res; + else if (res < audio_control -> ux_host_class_audio_control_res) + audio_control -> ux_host_class_audio_control_res = res; + } + + /* If there is list of RANGEs and no RES, guess it (average of max-min). */ + if (n_subs > 1 && audio_control -> ux_host_class_audio_control_res == 0) + { + audio_control -> ux_host_class_audio_control_res = + (audio_control -> ux_host_class_audio_control_max - + audio_control -> ux_host_class_audio_control_min) / n_subs; + } + } + } + else +#endif + { + + /* Need to allocate memory for the control buffer, max DWORD (4). */ + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); + if (control_buffer == UX_NULL) + { + + /* Return an error. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_MEMORY_INSUFFICIENT); + } + + /* Issue GET_MIN request. */ + * (ULONG *)control_buffer = 0; + status = _ux_host_class_audio_control_request(audio, 0, + UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE, + UX_HOST_CLASS_AUDIO_GET_MIN, + audio_control -> ux_host_class_audio_control_channel | + (audio_control -> ux_host_class_audio_control << 8), + audio_control -> ux_host_class_audio_control_entity, + control_buffer, 4, &actual_size); + + /* Check for correct transfer and entire control buffer returned. + * Start GET_MAX request. */ + if (status == UX_SUCCESS) + { + + /* Update the MIN static value for the caller. */ + audio_control -> ux_host_class_audio_control_min = _ux_utility_long_get(control_buffer); + + /* Issue GET_MAX request. */ + * (ULONG *)control_buffer = 0; + status = _ux_host_class_audio_control_request(audio, 0, + UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE, + UX_HOST_CLASS_AUDIO_GET_MAX, + audio_control -> ux_host_class_audio_control_channel | + (audio_control -> ux_host_class_audio_control << 8), + audio_control -> ux_host_class_audio_control_entity, + control_buffer, 4, &actual_size); + } + + /* Check for correct transfer and entire control buffer returned. + * Start GET_RES request. */ + if (status == UX_SUCCESS) + { + + /* Update the MAX static value for the caller. */ + audio_control -> ux_host_class_audio_control_max = _ux_utility_long_get(control_buffer); + + /* Issue GET_RES request. */ + * (ULONG *)control_buffer = 0; + status = _ux_host_class_audio_control_request(audio, 0, + UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE, + UX_HOST_CLASS_AUDIO_GET_RES, + audio_control -> ux_host_class_audio_control_channel | + (audio_control -> ux_host_class_audio_control << 8), + audio_control -> ux_host_class_audio_control_entity, + control_buffer, 4, &actual_size); + } + + /* Check for correct transfer and entire control buffer returned. */ + if (status == UX_SUCCESS) + { + + /* Update the RES static value for the caller. */ + audio_control -> ux_host_class_audio_control_res = _ux_utility_long_get(control_buffer); + } + } + + /* Free all used resources. */ + _ux_utility_memory_free(control_buffer); + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return completion status. */ + return(status); +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_entity_control_value_get.c b/common/usbx_host_classes/src/ux_host_class_audio_entity_control_value_get.c new file mode 100644 index 00000000..76524374 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_entity_control_value_get.c @@ -0,0 +1,153 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_entity_control_value_get PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function obtains the dynamic values for a single audio */ +/* control on either the master channel or a specific channel. */ +/* */ +/* Note only control value of BYTE, WORD and DWORD (<4) is supported. */ +/* E.g., Graphic Equalizer Control is not supported. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* audio_control Pointer to audio control */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_class_instance_verify Verify instance is valid */ +/* _ux_host_class_audio_control_request Issue audio control request */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ +/* _ux_utility_memory_allocate Allocate memory block */ +/* _ux_utility_memory_free Release memory block */ +/* _ux_utility_long_get Read 32-bit value */ +/* */ +/* CALLED BY */ +/* */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_entity_control_value_get(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control) +{ + +UINT status; +UCHAR *control_buffer; +ULONG actual_size; + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_CONTROL_VALUE_GET, audio, audio_control -> ux_host_class_audio_control_entity, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Protect thread reentry to this instance. */ + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); + + /* Need to allocate memory for the control_buffer. */ + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); + if (control_buffer == UX_NULL) + { + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return error. */ + return(UX_MEMORY_INSUFFICIENT); + } + + /* The buffer should be aligned. Returned data is little endian so DWord can be used + to copy any returned data of BYTE/WORD/DWORD. */ + * (ULONG *)control_buffer = 0; + + /* Issue GET CUR request. */ + status = _ux_host_class_audio_control_request(audio, 0, + UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE, +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) ? + UX_CLASS_AUDIO20_CUR : UX_HOST_CLASS_AUDIO_GET_CUR, +#else + UX_HOST_CLASS_AUDIO_GET_CUR, +#endif + audio_control -> ux_host_class_audio_control_channel | + (audio_control -> ux_host_class_audio_control << 8), + audio_control -> ux_host_class_audio_control_entity, + control_buffer, 4, &actual_size); + + /* Check for correct transfer and entire control buffer returned. */ + if (status == UX_SUCCESS) + { + + /* Update the CUR static value for the caller. */ + audio_control -> ux_host_class_audio_control_cur = _ux_utility_long_get(control_buffer); + } + + /* Free all used resources. */ + _ux_utility_memory_free(control_buffer); + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return completion status. */ + return(status); +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_entity_control_value_set.c b/common/usbx_host_classes/src/ux_host_class_audio_entity_control_value_set.c new file mode 100644 index 00000000..f846e533 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_entity_control_value_set.c @@ -0,0 +1,143 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_entity_control_value_set PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function updates the dynamic values for a single audio */ +/* control on either the master channel or a specific channel. */ +/* */ +/* Note only control value of BYTE, WORD and DWORD (<4) is supported. */ +/* E.g., Graphic Equalizer Control is not supported. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* audio_control Pointer to audio control */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_class_instance_verify Verify instance is valid */ +/* _ux_host_class_audio_control_request Issue audio transfer request */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ +/* _ux_utility_memory_allocate Allocate memory block */ +/* _ux_utility_memory_free Release memory block */ +/* _ux_utility_long_put Write 32-bit value */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_entity_control_value_set(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_CONTROL *audio_control) +{ + +UINT status; +UCHAR *control_buffer; +ULONG actual_size; + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_CONTROL_VALUE_SET, audio, audio_control -> ux_host_class_audio_control_entity, audio_control -> ux_host_class_audio_control_cur, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Protect thread reentry to this instance. */ + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); + + /* Need to allocate memory for the control buffer. */ + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); + if (control_buffer == UX_NULL) + { + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return an error. */ + return(UX_MEMORY_INSUFFICIENT); + } + + /* The buffer should be aligned. Returned data is little endian so DWord can be used + to copy any returned data of BYTE/WORD/DWORD. */ + _ux_utility_long_put(control_buffer, audio_control -> ux_host_class_audio_control_cur); + + /* Issue SET CUR request. */ + status = _ux_host_class_audio_control_request(audio, 0, + UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE, +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) ? + UX_CLASS_AUDIO20_CUR : UX_HOST_CLASS_AUDIO_SET_CUR, +#else + UX_HOST_CLASS_AUDIO_SET_CUR, +#endif + audio_control -> ux_host_class_audio_control_channel | + (audio_control -> ux_host_class_audio_control << 8), + audio_control -> ux_host_class_audio_control_entity, + control_buffer, audio_control -> ux_host_class_audio_control_size, &actual_size); + + /* Free all used resources. */ + _ux_utility_memory_free(control_buffer); + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return completion status. */ + return(status); +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_entry.c b/common/usbx_host_classes/src/ux_host_class_audio_entry.c index fca6b3af..0c8ec460 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_entry.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_entry.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_entry PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added audio 2.0 support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_entry(UX_HOST_CLASS_COMMAND *command) @@ -90,7 +93,14 @@ UINT status; /* The query command is used to let the stack enumeration process know if we want to own this device or not. */ if ((command -> ux_host_class_command_usage == UX_HOST_CLASS_COMMAND_USAGE_CSP) && - (command -> ux_host_class_command_class == UX_HOST_CLASS_AUDIO_CLASS)) + (command -> ux_host_class_command_class == UX_HOST_CLASS_AUDIO_CLASS) && +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + ((command -> ux_host_class_command_protocol == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_01_00) || + (command -> ux_host_class_command_protocol == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00)) +#else + (command -> ux_host_class_command_protocol == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_01_00) +#endif + ) return(UX_SUCCESS); else return(UX_NO_CLASS_MATCH); diff --git a/common/usbx_host_classes/src/ux_host_class_audio_feedback_get.c b/common/usbx_host_classes/src/ux_host_class_audio_feedback_get.c new file mode 100644 index 00000000..78cfea0b --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_feedback_get.c @@ -0,0 +1,100 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_feedback_get PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function copies packed feedback data to given buffer. */ +/* Note high speed data size is 4 and full speed data size is 3 bytes. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* feedback Pointer to buffer to fill */ +/* packed feedback data */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_feedback_get(UX_HOST_CLASS_AUDIO *audio, UCHAR *feedback) +{ +#if !defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + UX_PARAMETER_NOT_USED(audio); + UX_PARAMETER_NOT_USED(feedback); + return(UX_FUNCTION_NOT_SUPPORTED); +#else + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + feedback[0] = audio -> ux_host_class_audio_feedback_buffer[0]; + feedback[1] = audio -> ux_host_class_audio_feedback_buffer[1]; + feedback[2] = audio -> ux_host_class_audio_feedback_buffer[2]; + if (_ux_host_class_audio_speed_get(audio) == UX_HIGH_SPEED_DEVICE) + feedback[3] = audio -> ux_host_class_audio_feedback_buffer[3]; + return(UX_SUCCESS); +#endif +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_feedback_set.c b/common/usbx_host_classes/src/ux_host_class_audio_feedback_set.c new file mode 100644 index 00000000..bc61c2ca --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_feedback_set.c @@ -0,0 +1,117 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_feedback_set PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function copies packed feedback data from given buffer. */ +/* Note high speed data size is 4 and full speed data size is 3 bytes. */ +/* */ +/* Note if feedback is supported this function can work even there is */ +/* no interface alternate setting selected. This way the default */ +/* feedback data can be set before streaming starts. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* feedback Pointer to packed feedback */ +/* data to copy */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_feedback_set(UX_HOST_CLASS_AUDIO *audio, UCHAR *feedback) +{ +#if !defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + UX_PARAMETER_NOT_USED(audio); + UX_PARAMETER_NOT_USED(feedback); + return(UX_FUNCTION_NOT_SUPPORTED); +#else +UX_ENDPOINT *endpoint; +UX_TRANSFER *transfer; + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + audio -> ux_host_class_audio_feedback_buffer[0] = feedback[0]; + audio -> ux_host_class_audio_feedback_buffer[1] = feedback[1]; + audio -> ux_host_class_audio_feedback_buffer[2] = feedback[2]; + if (_ux_host_class_audio_speed_get(audio) == UX_HIGH_SPEED_DEVICE) + audio -> ux_host_class_audio_feedback_buffer[3] = feedback[3]; + + /* Sync with transfer buffer. */ + endpoint = audio -> ux_host_class_audio_feedback_endpoint; + if (endpoint) + { + transfer = &endpoint -> ux_endpoint_transfer_request; + _ux_utility_memory_copy(transfer -> ux_transfer_request_data_pointer, + audio -> ux_host_class_audio_feedback_buffer, + sizeof(audio -> ux_host_class_audio_feedback_buffer)); /* Use case of memcpy is verified. */ + } + + return(UX_SUCCESS); +#endif +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_feedback_transfer_completed.c b/common/usbx_host_classes/src/ux_host_class_audio_feedback_transfer_completed.c new file mode 100644 index 00000000..22b49a3e --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_feedback_transfer_completed.c @@ -0,0 +1,95 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_feedback_transfer_completed PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function receives a completion call back on a isoch transfer */ +/* request. */ +/* */ +/* INPUT */ +/* */ +/* transfer_request Pointer to transfer request */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* */ +/* CALLED BY */ +/* */ +/* HCD */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +VOID _ux_host_class_audio_feedback_transfer_completed(UX_TRANSFER *transfer_request) +{ +UX_HOST_CLASS_AUDIO *audio; +UX_ENDPOINT *endpoint; +ULONG endpoint_dir; + + /* Check status. */ + if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS) + return; + + /* Sync with feedback buffer. */ + audio = (UX_HOST_CLASS_AUDIO *) transfer_request -> ux_transfer_request_class_instance; + endpoint = transfer_request -> ux_transfer_request_endpoint; + endpoint_dir = endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION; + if (endpoint_dir == UX_ENDPOINT_IN) + { + _ux_utility_memory_copy(audio -> ux_host_class_audio_feedback_buffer, + transfer_request -> ux_transfer_request_data_pointer, + sizeof(audio -> ux_host_class_audio_feedback_buffer)); /* Use case of memcpy is verified. */ + } + + /* Issue another request again. */ + _ux_host_stack_transfer_request(transfer_request); +} +#endif diff --git a/common/usbx_host_classes/src/ux_host_class_audio_interrupt_notification.c b/common/usbx_host_classes/src/ux_host_class_audio_interrupt_notification.c new file mode 100644 index 00000000..15005f96 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_interrupt_notification.c @@ -0,0 +1,96 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_interrupt_notification PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function receives a completion callback on a interrupt */ +/* transfer request. */ +/* */ +/* INPUT */ +/* */ +/* transfer_request Pointer to transfer request */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* (ux_host_class_audio_interrupt_callback) */ +/* App notification callback */ +/* _ux_host_stack_transfer_request Issue the transfer request */ +/* */ +/* CALLED BY */ +/* */ +/* HCD */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +VOID _ux_host_class_audio_interrupt_notification(UX_TRANSFER *transfer_request) +{ + +UX_HOST_CLASS_AUDIO_AC *ac; + + /* Check status. */ + if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS) + return; + + /* Get AC instance. */ + ac = (UX_HOST_CLASS_AUDIO_AC *)transfer_request -> ux_transfer_request_class_instance; + + /* Invoke application callback. */ + if (ac -> ux_host_class_audio_interrupt_callback) + { + ac -> ux_host_class_audio_interrupt_callback(ac, + transfer_request -> ux_transfer_request_data_pointer, + transfer_request -> ux_transfer_request_actual_length, + ac -> ux_host_class_audio_interrupt_callback_arg); + } + + /* Issue another request again. */ + _ux_host_stack_transfer_request(transfer_request); +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_interrupt_start.c b/common/usbx_host_classes/src/ux_host_class_audio_interrupt_start.c new file mode 100644 index 00000000..11b9eddd --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_interrupt_start.c @@ -0,0 +1,140 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_interrupt_start PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function starts audio control (AC) interface interrupt */ +/* message polling. */ +/* */ +/* Note it should be called after audio control instance is activated */ +/* and should be called only once before the instance is deactivated. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio control (AC) */ +/* instance */ +/* callback_function Callback function invoked on */ +/* interrupt message reception */ +/* arg Callback argument passed to */ +/* callback function */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_class_instance_verify Verify instance is valid */ +/* _ux_host_stack_transfer_request Process transfer request */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_interrupt_start(UX_HOST_CLASS_AUDIO_AC *audio, + VOID(*callback_function)(UX_HOST_CLASS_AUDIO_AC *audio, + UCHAR *message, ULONG length, + VOID *arg), + VOID *arg) +{ +#if !defined(UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT) + UX_PARAMETER_NOT_USED(audio); + UX_PARAMETER_NOT_USED(callback_function); + UX_PARAMETER_NOT_USED(arg); + return(UX_FUNCTION_NOT_SUPPORTED); +#else +UX_ENDPOINT *endpoint; +UX_TRANSFER *transfer; +UINT status; + + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Ensure endpoint is valid. */ + endpoint = audio -> ux_host_class_audio_interrupt_endpoint; + if (endpoint == UX_NULL) + return(UX_FUNCTION_NOT_SUPPORTED); + + /* Check if interrupt started. */ + if (audio -> ux_host_class_audio_interrupt_started) + return(UX_ALREADY_ACTIVATED); + + /* Set application callback and its argument. */ + audio -> ux_host_class_audio_interrupt_callback_arg = arg; + audio -> ux_host_class_audio_interrupt_callback = callback_function; + + /* Get the transfer request. */ + transfer = &endpoint -> ux_endpoint_transfer_request; + + /* Save class instance to issue this transfer. */ + transfer -> ux_transfer_request_class_instance = (VOID *)audio; + + /* Save transfer complete callback. */ + transfer -> ux_transfer_request_completion_function = _ux_host_class_audio_interrupt_notification; + + /* The transfer on the interrupt endpoint can be started. */ + status = _ux_host_stack_transfer_request(transfer); + if (status == UX_SUCCESS) + audio -> ux_host_class_audio_interrupt_started = UX_TRUE; + + /* Return completion status. */ + return(status); +#endif +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c b/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c new file mode 100644 index 00000000..62407e9c --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c @@ -0,0 +1,747 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +struct UX_HOST_CLASS_AUDIO10_SAM_PARSER { + UINT (*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr + ); + UCHAR *arg; + UX_HOST_CLASS_AUDIO + *audio; +}; +struct UX_HOST_CLASS_AUDIO20_SAM_PARSER { + UINT (*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr + ); + UCHAR *arg; + UX_HOST_CLASS_AUDIO + *audio; + UCHAR *as_header; + UINT status; +}; + + +static UINT _ux_host_class_audio10_sam_parse_func(VOID *arg, + UCHAR *packed_interface_descriptor, + UCHAR *packed_endpoint_descriptor, + UCHAR *packed_audio_descriptor); +static inline UINT _ux_host_class_audio10_sampling_parse(UX_HOST_CLASS_AUDIO *audio, + UINT(*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr), + VOID* arg); +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) +static UINT _ux_host_class_audio20_sam_parse_func(VOID *arg, + UCHAR *packed_interface_descriptor, + UCHAR *packed_endpoint_descriptor, + UCHAR *packed_audio_descriptor); + +static inline UINT _ux_host_class_audio20_sampling_parse(UX_HOST_CLASS_AUDIO *audio, + UINT(*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr), + VOID* arg); +#endif + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_raw_sampling_parse PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function parses all possible RAW (PCM like) sampling */ +/* characteristics for current clock source and clock selector */ +/* settings. */ +/* */ +/* For sampling characteristics of different clock settings, */ +/* use ux_host_class_audio_descriptors_parse to get their IDs and */ +/* use _ux_host_class_audio_control_request to change settings. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* parse_function Pointer to parse function, */ +/* returns 0 to continue parse, */ +/* others to terminate parse. */ +/* arg Pointer to parse arguments */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_class_instance_verify Verify instance is valid */ +/* _ux_host_semaphore_get Get semaphore */ +/* _ux_host_semaphore_put Put semaphore */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_raw_sampling_parse(UX_HOST_CLASS_AUDIO *audio, + UINT(*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr), + VOID* arg) +{ + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + if (_ux_host_class_audio_protocol_get(audio) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00) + return(_ux_host_class_audio20_sampling_parse(audio, parse_function, arg)); +#endif + + return(_ux_host_class_audio10_sampling_parse(audio, parse_function, arg)); +} + +static UINT _ux_host_class_audio10_sam_parse_func(VOID *arg, + UCHAR *packed_interface_descriptor, + UCHAR *packed_endpoint_descriptor, + UCHAR *packed_audio_descriptor) +{ +struct UX_HOST_CLASS_AUDIO10_SAM_PARSER *parser = (struct UX_HOST_CLASS_AUDIO10_SAM_PARSER *)arg; +UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr; +ULONG n, offset; +UINT status; + + UX_PARAMETER_NOT_USED(packed_endpoint_descriptor); + + /* Check bInterfaceNumber @ 2. */ + if (packed_interface_descriptor[2] != + parser -> audio -> ux_host_class_audio_streaming_interface -> + ux_interface_descriptor.bInterfaceNumber) + return(0); + + /* Check bDescriptorType @ 1. */ + if (packed_audio_descriptor[1] != UX_HOST_CLASS_AUDIO_CS_INTERFACE) + return(0); + + /* Check bDescriptorSubType @ 2. */ + if (packed_audio_descriptor[2] != UX_HOST_CLASS_AUDIO_CS_FORMAT_TYPE) + return(0); + + /* Check bFormatType @ 3. */ + if (packed_audio_descriptor[3] != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I) + return(0); + + /* Get bNrChannels @ 4. */ + sam_attr.ux_host_class_audio_sampling_characteristics_channels = packed_audio_descriptor[4]; + + /* Get bBitResolution @ 6. */ + sam_attr.ux_host_class_audio_sampling_characteristics_resolution = packed_audio_descriptor[6]; + + /* No clock ID (set to 0), no mul, div (set to 1). */ + sam_attr.ux_host_class_audio_sampling_characteristics_descriptor = packed_audio_descriptor; + sam_attr.ux_host_class_audio_sampling_characteristics_clock_mul = 1; + sam_attr.ux_host_class_audio_sampling_characteristics_clock_div = 1; + + /* Check bSamFreqType @ 7. */ + if (packed_audio_descriptor[7] == 0) + { + + /* Continuous, get dLowSamFreq and dHighSamFreq. */ + sam_attr.ux_host_class_audio_sampling_characteristics_frequency_low = + ((ULONG)packed_audio_descriptor[8]) + + ((ULONG)packed_audio_descriptor[9] << 8) + + ((ULONG)packed_audio_descriptor[10] << 16); + sam_attr.ux_host_class_audio_sampling_characteristics_frequency_high = + ((ULONG)packed_audio_descriptor[11]) + + ((ULONG)packed_audio_descriptor[12] << 8) + + ((ULONG)packed_audio_descriptor[13] << 16); + + /* Parse this sampling characteristic. */ + status = parser->parse_function(parser->arg, packed_interface_descriptor, &sam_attr); + return(status); + } + else + { + + /* Parse list of sampling characteristics. */ + for (n = 0, offset = 8; + n < packed_audio_descriptor[7]; + n ++, offset += 3) + { + sam_attr.ux_host_class_audio_sampling_characteristics_frequency_low = + ((ULONG)packed_audio_descriptor[offset]) + + ((ULONG)packed_audio_descriptor[offset+1] << 8) + + ((ULONG)packed_audio_descriptor[offset+2] << 16); + + /* Not range, frequency high = low. */ + sam_attr.ux_host_class_audio_sampling_characteristics_frequency_high = + sam_attr.ux_host_class_audio_sampling_characteristics_frequency_low; + + /* Parse this sampling characteristic. */ + status = parser->parse_function(parser->arg, packed_interface_descriptor, &sam_attr); + + /* If status is not 0, it terminate parsing. */ + if (status != 0) + return(status); + } + } + return(0); +} + +static inline UINT _ux_host_class_audio10_sampling_parse(UX_HOST_CLASS_AUDIO *audio, + UINT(*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr), + VOID* arg) +{ + +struct UX_HOST_CLASS_AUDIO10_SAM_PARSER parser; + + /* No need to protect thread reentry to this instance (no requests). */ + + parser.parse_function = parse_function; + parser.arg = arg; + parser.audio = audio; + return(_ux_host_class_audio_descriptors_parse(audio, + _ux_host_class_audio10_sam_parse_func, (VOID *)&parser)); +} + +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) +struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT +{ + UCHAR *descriptor; + UCHAR interface_num; + UCHAR subtype; + UCHAR id; +}; +static UINT _ux_host_class_audio_ac_find_parse(VOID *arg, + UCHAR *packed_interface_descriptor, + UCHAR *packed_endpoint_descriptor, + UCHAR *packed_audio_descriptor) +{ +struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *finder = (struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *)arg; + + UX_PARAMETER_NOT_USED(packed_endpoint_descriptor); + + /* Check interface number (bInterfaceNumber @ 2). */ + if (packed_interface_descriptor[2] != finder -> interface_num) + return(0); + + /* Check bDescriptorType @ 1. */ + if (packed_audio_descriptor[1] != UX_HOST_CLASS_AUDIO_CS_INTERFACE) + return(0); + + /* Get finding data. */ + finder = (struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *)arg; + + /* Check bDescriptorSubType @ 2. */ + if (packed_audio_descriptor[2] != finder -> subtype) + return(0); + + /* Check bEntityID @ 3. */ + if (packed_audio_descriptor[3] != finder -> id) + return(0); + + /* Found it, break parsing loop. */ + finder -> descriptor = packed_audio_descriptor; + return(1); +} +static UCHAR *_ux_host_class_audio_ac_find(UX_HOST_CLASS_AUDIO *audio, UCHAR subtype, UCHAR id) +{ + +struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT finder; +UINT status; + + finder.descriptor = UX_NULL; + finder.interface_num = (UCHAR)audio -> ux_host_class_audio_control_interface_number; + finder.subtype = subtype; + finder.id = id; + status = _ux_host_class_audio_descriptors_parse(audio, + _ux_host_class_audio_ac_find_parse, + &finder); + if (status != UX_SUCCESS) + return(UX_NULL); + return(finder.descriptor); +} + +static inline UINT _ux_host_class_audio20_clock_get(UX_HOST_CLASS_AUDIO *audio, + UCHAR terminal_link, + UCHAR **csd, ULONG *clk_numerator, ULONG *clk_denominator) +{ + +UX_DEVICE *device; +UX_ENDPOINT *endpoint; +UX_TRANSFER *request; +UCHAR *control_buffer = UX_NULL; +UCHAR *descriptor; +UCHAR id; +ULONG numerator = 1, denominator = 1; +UCHAR scan_round = 0; +UINT status; + + if (audio -> ux_host_class_audio_type == UX_HOST_CLASS_AUDIO_INPUT) + { + + /* If audio input, streaming is from output terminal (OT). */ + descriptor = _ux_host_class_audio_ac_find(audio, + UX_CLASS_AUDIO20_AC_OUTPUT_TERMINAL, + (UCHAR)terminal_link); + if (descriptor == UX_NULL) + return(UX_DESCRIPTOR_CORRUPTED); + + /* Get OTD::bCSourceID @ 8. */ + id = descriptor[8]; + } + else + { + + /* If audio output, streaming is to input terminal (IT). */ + descriptor = _ux_host_class_audio_ac_find(audio, + UX_CLASS_AUDIO20_AC_INPUT_TERMINAL, + (UCHAR)terminal_link); + if (descriptor == UX_NULL) + return(UX_DESCRIPTOR_CORRUPTED); + + /* Get ITD::bCSourceID @ 7. */ + id = descriptor[7]; + } + + /* Get control endpoint and request, for possible control requests. */ + device = audio -> ux_host_class_audio_device; + endpoint = &device -> ux_device_control_endpoint; + request = &endpoint -> ux_endpoint_transfer_request; + + /* Get clock source descriptor. */ + do + { + + /* Try to find ClockSource CSD. */ + descriptor = _ux_host_class_audio_ac_find(audio, + UX_CLASS_AUDIO20_AC_CLOCK_SOURCE, id); + if (descriptor != UX_NULL) + { + + /* Finally we get clock source. */ + *csd = descriptor; + *clk_numerator = numerator; + *clk_denominator = denominator; + status = UX_SUCCESS; + break; + } + + /* Try to find ClockMultiplier CMD. */ + descriptor = _ux_host_class_audio_ac_find(audio, + UX_CLASS_AUDIO20_AC_CLOCK_MULTIPLIER, id); + if (descriptor != UX_NULL) + { + + /* Get numerator, denominator. */ + + /* Allocate buffer for requests. */ + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); + if (control_buffer == UX_NULL) + { + + /* Unprotect device control. */ + status = UX_MEMORY_INSUFFICIENT; + break; + } + + /* Protect device control endpoint. */ + status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + status = UX_SEMAPHORE_ERROR; + break; + } + + /* Create a transfer request for the GET_CUR LAYOUT 2 request. */ + request -> ux_transfer_request_data_pointer = control_buffer; + request -> ux_transfer_request_requested_length = 2; + request -> ux_transfer_request_function = UX_CLASS_AUDIO20_CUR; + request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + request -> ux_transfer_request_value = 0 | (UX_CLASS_AUDIO20_CM_NUMERATOR_CONTROL << 8); + request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | ((ULONG)id << 8); + *(ULONG *)control_buffer = 0; + status = _ux_host_stack_transfer_request(request); + if ((status != UX_SUCCESS) || + (request -> ux_transfer_request_actual_length != 2) || + (*(ULONG *)control_buffer == 0)) + { + status = UX_TRANSFER_ERROR; + break; + } + + /* Update numerator. */ + numerator *= *(ULONG *)control_buffer; + + /* Protect device control endpoint. */ + status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + status = UX_SEMAPHORE_ERROR; + break; + } + + /* Create a transfer request for the GET_CUR request. */ + request -> ux_transfer_request_data_pointer = control_buffer; + request -> ux_transfer_request_requested_length = 2; + request -> ux_transfer_request_function = UX_CLASS_AUDIO20_CUR; + request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + request -> ux_transfer_request_value = 0 | (UX_CLASS_AUDIO20_CM_DENOMINATOR_CONTROL << 8); + request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | ((ULONG)id << 8); + *(ULONG *)control_buffer = 0; + status = _ux_host_stack_transfer_request(request); + if ((status != UX_SUCCESS) || + (request -> ux_transfer_request_actual_length != 2) || + (*(ULONG *)control_buffer == 0)) + { + status = UX_TRANSFER_ERROR; + break; + } + + /* Update denominator. */ + denominator *= *(ULONG *)control_buffer; + + /* Get CMD::bCSourceID @ 4. */ + id = descriptor[4]; + + /* Next round of scan. */ + scan_round ++; + continue; + } + + /* Try to find ClockSelector CSD. */ + descriptor = _ux_host_class_audio_ac_find(audio, + UX_CLASS_AUDIO20_AC_CLOCK_SELECTOR, id); + if (descriptor != UX_NULL) + { + + /* Get current selected InPin. */ + + /* Allocate buffer for requests. */ + if (control_buffer == UX_NULL) + { + control_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); + if (control_buffer == UX_NULL) + { + + /* Unprotect device control. */ + status = UX_MEMORY_INSUFFICIENT; + break; + } + } + + /* Protect device control endpoint. */ + status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + status = UX_SEMAPHORE_ERROR; + break; + } + + /* Create a transfer request for the GET_CUR LAYOUT 1 request. */ + request -> ux_transfer_request_data_pointer = control_buffer; + request -> ux_transfer_request_requested_length = 1; + request -> ux_transfer_request_function = UX_CLASS_AUDIO20_CUR; + request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + request -> ux_transfer_request_value = 0 | (UX_CLASS_AUDIO20_CX_CLOCK_SELECTOR_CONTROL << 8); + request -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | ((ULONG)id << 8); + *(ULONG *)control_buffer = 0; + status = _ux_host_stack_transfer_request(request); + if ((status != UX_SUCCESS) || + (request -> ux_transfer_request_actual_length != 1) || + (*(ULONG *)control_buffer == 0)) + { + status = UX_TRANSFER_ERROR; + break; + } + + /* Update id from CSD::baCSourceID @ 5. */ + id = descriptor[5 + *(ULONG *)control_buffer - 1]; + + /* Next round of scan. */ + scan_round ++; + continue; + } + + /* Nothing found!!! */ + status = UX_DESCRIPTOR_CORRUPTED; + } while(status == UX_SUCCESS); + + /* Free allocated resources. */ + if (control_buffer) + _ux_utility_memory_free(control_buffer); + + /* Return with status. */ + return(status); +} + +static UINT _ux_host_class_audio20_sam_parse_func(VOID *arg, + UCHAR *packed_interface_descriptor, + UCHAR *packed_endpoint_descriptor, + UCHAR *packed_audio_descriptor) +{ + +struct UX_HOST_CLASS_AUDIO20_SAM_PARSER *parser = (struct UX_HOST_CLASS_AUDIO20_SAM_PARSER *)arg; +UX_HOST_CLASS_AUDIO *audio = parser -> audio; + +UCHAR *csd; +ULONG clk_id, clk_mul = 1, clk_div = 1; +UINT status; +UX_DEVICE *device; +UX_ENDPOINT *endpoint; +UX_TRANSFER *transfer; +UCHAR *buffer; +ULONG n_sub, param_len, offset; +UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr; + + UX_PARAMETER_NOT_USED(packed_endpoint_descriptor); + + /* Check bInterfaceNumber @ 2 to confirm inside AS. */ + if (packed_interface_descriptor[2] != + audio -> ux_host_class_audio_streaming_interface -> + ux_interface_descriptor.bInterfaceNumber) + return(0); + + /* Check bDescriptorType @ 1 to confirm AS CS descriptor. */ + if (packed_audio_descriptor[1] != UX_CLASS_AUDIO20_CS_INTERFACE) + return(0); + + /* Check bDescriptorSubType@2 to confirm AS_HEADER. */ + if (packed_audio_descriptor[2] == UX_CLASS_AUDIO20_AS_GENERAL) + { + + /* Save AS_HEADER for future use. */ + parser -> as_header = packed_audio_descriptor; + return(0); + } + + /* Check bDescriptorSubType@2, bFormatType@3 to confirm FORMAT_TYPE_I. */ + if (packed_audio_descriptor[2] != UX_CLASS_AUDIO20_AS_FORMAT_TYPE) + return(0); + if (packed_audio_descriptor[3] != UX_CLASS_AUDIO20_FORMAT_TYPE_I) + return(0); + + /* Save FORMAT_TYPE_I::bBitResolution@5. */ + sam_attr.ux_host_class_audio_sampling_characteristics_resolution = packed_audio_descriptor[5]; + + /* If AS_HEADER is not ready, fail. */ + if (parser -> as_header == UX_NULL) + { + parser -> status = UX_DESCRIPTOR_CORRUPTED; + return(1); + } + + /* Check AS_HEADER::bTerminalLink@3 to find frequencies. */ + status = _ux_host_class_audio20_clock_get(audio, parser -> as_header[3], + &csd, &clk_mul, &clk_div); + if (status != UX_SUCCESS) + { + parser -> status = status; + return(1); + } + + /* Get CSD::bClockID@3. */ + clk_id = csd[3]; + + /* Issue GET_RANGE to get sampling frequency. */ + + /* Get device, endpoint, transfer. */ + device = audio -> ux_host_class_audio_device; + endpoint = &device -> ux_device_control_endpoint; + transfer = &endpoint -> ux_endpoint_transfer_request; + + /* Allocate buffer for GET_RANGE. */ + buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, 2); + if (buffer == UX_NULL) + { + parser -> status = UX_MEMORY_INSUFFICIENT; + return(1); + } + + /* Protect control transfer. */ + parser -> status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (parser -> status != UX_SUCCESS) + { + _ux_utility_memory_free(buffer); + return(1); + } + + /* Issue GET_RANGE request. */ + transfer -> ux_transfer_request_data_pointer = buffer; + transfer -> ux_transfer_request_requested_length = 2; + transfer -> ux_transfer_request_function = UX_CLASS_AUDIO20_RANGE; + transfer -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer -> ux_transfer_request_value = 0 | (UX_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL << 8); + transfer -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (clk_id << 8); + parser -> status = _ux_host_stack_transfer_request(transfer); + + /* Get wNumSubRanges. */ + n_sub = (ULONG)(*(USHORT *)buffer); + _ux_utility_memory_free(buffer); + + /* Check errors. */ + if (parser -> status != UX_SUCCESS) + return(1); + if (n_sub == 0) + { + parser -> status = UX_TRANSFER_ERROR; + return(1); + } + + /* Calculate parameter length, with overflow check. */ + param_len = n_sub * (4 * 3); + if (param_len > 0xFFFF) + { + parser -> status = UX_MATH_OVERFLOW; + return(1); + } + param_len += 2; + if (param_len > 0xFFFF) + { + parser -> status = UX_MATH_OVERFLOW; + return(1); + } + + /* Allocate buffer for GET_RANGE. */ + buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, param_len); + if (buffer == UX_NULL) + { + parser -> status = UX_MEMORY_INSUFFICIENT; + return(1); + } + + /* Protect control transfer. */ + parser -> status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (parser -> status != UX_SUCCESS) + { + _ux_utility_memory_free(buffer); + return(1); + } + + /* Issue GET_RANGE request. */ + transfer -> ux_transfer_request_data_pointer = buffer; + transfer -> ux_transfer_request_requested_length = param_len; + transfer -> ux_transfer_request_function = UX_CLASS_AUDIO20_RANGE; + transfer -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer -> ux_transfer_request_value = 0 | (UX_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL << 8); + transfer -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | (clk_id << 8); + parser -> status = _ux_host_stack_transfer_request(transfer); + if (parser -> status != UX_SUCCESS) + { + _ux_utility_memory_free(buffer); + return(1); + } + + /* Save AS_HEADER::bNrChannels@10. */ + sam_attr.ux_host_class_audio_sampling_characteristics_channels = parser -> as_header[10]; + + /* Save CSD. */ + sam_attr.ux_host_class_audio_sampling_characteristics_descriptor = csd; + + /* Parse ranges. */ + for (offset = 2; offset < param_len; offset += (4*3)) + { + + /* Save dMIN, dMAX. */ + sam_attr.ux_host_class_audio_sampling_characteristics_frequency_low = + _ux_utility_long_get(buffer + offset); + sam_attr.ux_host_class_audio_sampling_characteristics_frequency_high = + _ux_utility_long_get(buffer + offset + 4); + + /* Save MUL, DIV. */ + sam_attr.ux_host_class_audio_sampling_characteristics_clock_mul = clk_mul; + sam_attr.ux_host_class_audio_sampling_characteristics_clock_div = clk_div; + + /* Parse frequency. */ + status = parser -> parse_function(parser -> arg, packed_interface_descriptor, &sam_attr); + if (status) + { + _ux_utility_memory_free(buffer); + return(status); + } + } + _ux_utility_memory_free(buffer); + + /* Continue parsing. */ + return(0); +} +static inline UINT _ux_host_class_audio20_sampling_parse(UX_HOST_CLASS_AUDIO *audio, + UINT(*parse_function)(VOID *arg, + UCHAR *packed_interface_descriptor, + UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *sam_attr), + VOID* arg) +{ +struct UX_HOST_CLASS_AUDIO20_SAM_PARSER parser; +UINT status; + + /* Run parse process. */ + parser.parse_function = parse_function; + parser.arg = arg; + parser.audio = audio; + parser.as_header = UX_NULL; + parser.status = UX_SUCCESS; + status = _ux_host_class_audio_descriptors_parse(audio, + _ux_host_class_audio20_sam_parse_func, (VOID *)&parser); + + /* Return parser status. */ + if (status == UX_SUCCESS) + return(parser.status); + + /* Return parsing error status. */ + return(status); +} +#endif /* defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) */ diff --git a/common/usbx_host_classes/src/ux_host_class_audio_read.c b/common/usbx_host_classes/src/ux_host_class_audio_read.c index a44c9d7a..920ba9f8 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_read.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_read.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_read PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -43,6 +43,9 @@ /* DESCRIPTION */ /* */ /* This function reads from the audio streaming interface. */ +/* */ +/* Note the request buffer should be ready for at least one packet, */ +/* and request length is always limited to one packet size. */ /* */ /* INPUT */ /* */ @@ -57,8 +60,8 @@ /* */ /* _ux_host_class_audio_transfer_request Audio transfer request */ /* _ux_host_stack_class_instance_verify Verify instance is valid */ -/* _ux_host_semaphore_get Get semaphore */ -/* _ux_host_semaphore_put Put semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ /* */ /* CALLED BY */ /* */ @@ -82,12 +85,19 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* refined packet size manage, */ +/* protect reentry with mutex, */ +/* refined transfer implement, */ +/* fixed error return code, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_read(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *audio_transfer_request) { UINT status; +ULONG mps; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_READ, audio, audio_transfer_request -> ux_host_class_audio_transfer_request_data_pointer, @@ -107,19 +117,14 @@ UINT status; } /* Protect thread reentry to this instance. */ - status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_semaphore, UX_WAIT_FOREVER); - if (status != UX_SUCCESS) - return(status); + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); - /* By default the transmission will be successful. */ - status = UX_SUCCESS; - /* Ensure we have a selected interface that allows isoch transmission. */ if (audio -> ux_host_class_audio_isochronous_endpoint -> ux_endpoint_descriptor.wMaxPacketSize == 0) { /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_AUDIO_WRONG_INTERFACE); @@ -127,28 +132,19 @@ UINT status; /* Return error status. */ return(UX_HOST_CLASS_AUDIO_WRONG_INTERFACE); } - - /* Hook the audio transfer request to the chain of transfer requests in the audio instance. */ - audio_transfer_request -> ux_host_class_audio_transfer_request_next_audio_transfer_request = audio -> ux_host_class_audio_tail_transfer_request; - audio -> ux_host_class_audio_tail_transfer_request = audio_transfer_request; - - /* Check if this is the first time we have had a transfer request, if so update the head as well. */ - if (audio -> ux_host_class_audio_head_transfer_request == UX_NULL) - audio -> ux_host_class_audio_head_transfer_request = audio_transfer_request; /* For audio in, we read packets at a time, so the transfer request size is the size of the - endpoint. */ - audio_transfer_request -> ux_host_class_audio_transfer_request_requested_length = - audio -> ux_host_class_audio_isochronous_endpoint -> - ux_endpoint_transfer_request.ux_transfer_request_packet_length; + endpoint max packet size. */ + mps = _ux_host_class_audio_max_packet_size_get(audio); + audio_transfer_request -> ux_host_class_audio_transfer_request_packet_size = mps; + audio_transfer_request -> ux_host_class_audio_transfer_request_requested_length = mps; /* Ask the stack to hook this transfer request to the iso ED. */ status = _ux_host_class_audio_transfer_request(audio, audio_transfer_request); /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_audio_stop.c b/common/usbx_host_classes/src/ux_host_class_audio_stop.c new file mode 100644 index 00000000..0b8791c6 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_audio_stop.c @@ -0,0 +1,169 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Audio Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_audio.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_stop PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function stops the audio streaming (select alt interface 0). */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_endpoint_transfer_abort */ +/* Abort transfer */ +/* _ux_host_stack_interface_setting_select */ +/* Select interface */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_audio_stop(UX_HOST_CLASS_AUDIO *audio) +{ + +UINT status; +UX_CONFIGURATION *configuration; +UX_INTERFACE *interface_ptr; +UINT streaming_interface; + + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Protect thread reentry to this instance. */ + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); + + /* Get the interface number of the audio streaming interface. */ + streaming_interface = audio -> ux_host_class_audio_streaming_interface -> ux_interface_descriptor.bInterfaceNumber; + + /* We need to abort transactions on the ISO pipes. */ + if (audio -> ux_host_class_audio_isochronous_endpoint != UX_NULL) + { + + /* Abort the iso transfer. */ + _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_isochronous_endpoint); + } + +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + if (audio -> ux_host_class_audio_feedback_endpoint) + _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_feedback_endpoint); +#endif + + /* We found the alternate setting for the sampling values demanded, now we need + to search its container. */ + configuration = audio -> ux_host_class_audio_streaming_interface -> ux_interface_configuration; + interface_ptr = configuration -> ux_configuration_first_interface; + + /* Scan all interfaces. */ + while (interface_ptr != UX_NULL) + { + + /* We search for both the right interface and alternate setting. */ + if ((interface_ptr -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && + (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0)) + { + + /* We have found the right interface/alternate setting combination + The stack will select it for us. */ + status = _ux_host_stack_interface_setting_select(interface_ptr); + + /* If the alternate setting for the streaming interface could be selected, we memorize it. */ + if (status == UX_SUCCESS) + { + + /* Memorize the interface. */ + audio -> ux_host_class_audio_streaming_interface = interface_ptr; + + /* There is no endpoint for the alternate setting 0. */ + _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_isochronous_endpoint); + audio -> ux_host_class_audio_isochronous_endpoint = UX_NULL; +#if defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT) + if (audio -> ux_host_class_audio_feedback_endpoint) + { + _ux_host_stack_endpoint_transfer_abort(audio -> ux_host_class_audio_feedback_endpoint); + audio -> ux_host_class_audio_feedback_endpoint = UX_NULL; + } +#endif + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return successful completion. */ + return(UX_SUCCESS); + } + } + + /* Move to next interface. */ + interface_ptr = interface_ptr -> ux_interface_next_interface; + } + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return failed completion status. */ + return(UX_NO_ALTERNATE_SETTING); +} diff --git a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c index 5c8ca146..d5fbf64d 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_streaming_sampling_get PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,8 @@ /* */ /* This function obtains successive sampling characteristics for the */ /* audio streaming channel. */ +/* */ +/* Note only Audio 1.0 and RAW (PCM like) format is supported. */ /* */ /* INPUT */ /* */ @@ -58,8 +60,8 @@ /* */ /* _ux_host_stack_class_instance_verify Verify instance is valid */ /* _ux_utility_descriptor_parse Parse the descriptor */ -/* _ux_host_semaphore_get Get semaphore */ -/* _ux_host_semaphore_put Put semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Put mutex */ /* */ /* CALLED BY */ /* */ @@ -79,12 +81,15 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* protect reentry with mutex, */ +/* fixed error return code, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_streaming_sampling_get(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *audio_sampling) { -UINT status; UCHAR * descriptor; UX_INTERFACE_DESCRIPTOR interface_descriptor; UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR audio_interface_descriptor; @@ -115,9 +120,7 @@ UINT previous_match_found; } /* Protect thread reentry to this instance. */ - status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_semaphore, UX_WAIT_FOREVER); - if (status != UX_SUCCESS) - return(status); + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); /* Reset the match flag. */ previous_match_found = UX_FALSE; @@ -149,7 +152,7 @@ UINT previous_match_found; UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); return(UX_DESCRIPTOR_CORRUPTED); } @@ -231,7 +234,7 @@ UINT previous_match_found; audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_high = audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low; /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* We have found the first streaming characteristics. */ return(UX_SUCCESS); @@ -299,7 +302,7 @@ UINT previous_match_found; audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_high = lower_frequency; /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return successful completion. */ return(UX_SUCCESS); @@ -337,7 +340,7 @@ UINT previous_match_found; audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_high = higher_frequency; /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return successful completion. */ return(UX_SUCCESS); @@ -353,7 +356,7 @@ UINT previous_match_found; audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_high = lower_frequency; /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return successful completion. */ return(UX_SUCCESS); @@ -375,7 +378,7 @@ UINT previous_match_found; UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); return(UX_DESCRIPTOR_CORRUPTED); } @@ -388,7 +391,7 @@ UINT previous_match_found; } /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_NO_ALTERNATE_SETTING); diff --git a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_set.c b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_set.c index 75819fd8..244451cd 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_set.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_set.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Audio Class */ /** */ @@ -30,50 +30,53 @@ #include "ux_host_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_audio_streaming_sampling_set PORTABLE C */ -/* 6.1.11 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_streaming_sampling_set PORTABLE C */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ +/* */ /* This function selects the right alternate setting for the audio */ -/* streaming interface based on the sampling values specified by the */ -/* user. */ -/* */ -/* INPUT */ -/* */ -/* audio Pointer to audio class */ -/* audio_sampling Pointer to audio sampling */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ +/* streaming interface based on the RAW (PCM like) sampling values */ +/* specified by the user, and send sampling frequency requests to */ +/* select expected sample rate (if necessary). */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* audio_sampling Pointer to audio sampling */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ /* _ux_host_class_audio_alternate_setting_locate */ -/* Locate alternate setting */ -/* _ux_host_stack_class_instance_verify Verify instance is valid */ -/* _ux_host_stack_interface_endpoint_get Get interface endpoint */ -/* _ux_host_stack_interface_setting_select Select interface */ -/* _ux_host_semaphore_get Get semaphore */ -/* _ux_host_semaphore_put Put semaphore */ -/* */ -/* CALLED BY */ -/* */ -/* Application */ -/* Audio Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* Locate alternate setting */ +/* _ux_host_stack_class_instance_verify Verify instance is valid */ +/* _ux_host_stack_interface_endpoint_get Get interface endpoint */ +/* _ux_host_stack_interface_setting_select Select interface */ +/* _ux_host_semaphore_get Get semaphore */ +/* _ux_host_semaphore_put Put semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ @@ -83,6 +86,16 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* added audio 2.0 support, */ +/* internal clean up, */ +/* set sample rate if needed, */ +/* protect reentry with mutex, */ +/* fixed error return code, */ +/* used endpoints get API, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_streaming_sampling_set(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_SAMPLING *audio_sampling) @@ -90,11 +103,16 @@ UINT _ux_host_class_audio_streaming_sampling_set(UX_HOST_CLASS_AUDIO *audio, UX UINT status; UINT alternate_setting; -ULONG endpoint_index; UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; -UX_ENDPOINT *endpoint; +UX_INTERFACE *interface_ptr; UINT streaming_interface; +UCHAR *descriptor; +ULONG set_frequency; +UCHAR *control_buffer; +UX_DEVICE *device; +UX_TRANSFER *transfer; +ULONG frequency = 0; +ULONG res_bytes; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_STREAMING_SAMPLING_SET, audio, audio_sampling, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) @@ -104,9 +122,7 @@ UINT streaming_interface; return(UX_HOST_CLASS_INSTANCE_UNKNOWN); /* Protect thread reentry to this instance. */ - status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_semaphore, UX_WAIT_FOREVER); - if (status != UX_SUCCESS) - return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); /* Find the correct alternate setting for the sampling desired. */ status = _ux_host_class_audio_alternate_setting_locate(audio, audio_sampling, &alternate_setting); @@ -114,74 +130,243 @@ UINT streaming_interface; /* Did we find the alternate setting? */ if (status != UX_SUCCESS) { - + /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); return(status); } - /* We found the alternate setting for the sampling values demanded, now we need + /* We found the alternate setting for the sampling values demanded, now we need to search its container. */ configuration = audio -> ux_host_class_audio_streaming_interface -> ux_interface_configuration; - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; streaming_interface = audio -> ux_host_class_audio_streaming_interface -> ux_interface_descriptor.bInterfaceNumber; + device = audio -> ux_host_class_audio_device; /* Scan all interfaces. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* We search for both the right interface and alternate setting. */ - if ((interface -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && - (interface -> ux_interface_descriptor.bAlternateSetting == alternate_setting)) + if ((interface_ptr -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && + (interface_ptr -> ux_interface_descriptor.bAlternateSetting == alternate_setting)) { - - /* We have found the right interface/alternate setting combination + + /* We have found the right interface/alternate setting combination The stack will select it for us. */ - status = _ux_host_stack_interface_setting_select(interface); - + status = _ux_host_stack_interface_setting_select(interface_ptr); + /* If the alternate setting for the streaming interface could be selected, we memorize it. */ if (status == UX_SUCCESS) { /* Memorize the interface. */ - audio -> ux_host_class_audio_streaming_interface = interface; + audio -> ux_host_class_audio_streaming_interface = interface_ptr; - /* We need to research the isoch endpoint now. */ - for (endpoint_index = 0; endpoint_index < interface -> ux_interface_descriptor.bNumEndpoints; endpoint_index++) - { + /* Get streaming endpoints. */ + status = _ux_host_class_audio_endpoints_get(audio); + if (status != UX_SUCCESS) + { - /* Get the list of endpoints one by one. */ - status = _ux_host_stack_interface_endpoint_get(audio -> ux_host_class_audio_streaming_interface, - endpoint_index, &endpoint); + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } - /* Check completion status. */ - if (status == UX_SUCCESS) + /* Check if clock frequency needs modification through requests. */ + set_frequency = UX_TRUE; + descriptor = audio -> ux_host_class_audio_sampling_descriptor; +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + if (_ux_host_class_audio_protocol_get(audio) != UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_01_00) + { + + /* Check CSD::bmControls@5.0~1. */ + /* If not programmable, no need to set. */ + if ((descriptor[5] & UX_CLASS_AUDIO20_CONTROL_MASK) != + UX_CLASS_AUDIO20_CONTROL_PROGRAMMABLE) + set_frequency = UX_FALSE; + } + else +#endif + { + + /* Check FormatTypeI::bSamFreqType@7, tSamFreq@8, tSamFreq@11. */ + /* If there is only one frequency, no need to set. */ + if ((descriptor[7] == 1) || ((descriptor[7] == 0) && + (descriptor[8] == descriptor[11]) && + (descriptor[9] == descriptor[12]) && + (descriptor[10] == descriptor[13]))) + set_frequency = UX_FALSE; + } + + /* Send requests to set frequency. */ + if (set_frequency) + { + + /* Allocate buffer. */ + control_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, 4); + if (control_buffer == UX_NULL) { + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(UX_MEMORY_INSUFFICIENT); + } - /* Check if endpoint is ISOCH, regardless of the direction. */ - if ((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_ISOCHRONOUS_ENDPOINT) + /* Get control transfer. */ + transfer = &device -> ux_device_control_endpoint.ux_endpoint_transfer_request; + + /* Set data to send. */ + control_buffer[0] = (UCHAR)UX_DW0(audio_sampling -> ux_host_class_audio_sampling_frequency); + control_buffer[1] = (UCHAR)UX_DW1(audio_sampling -> ux_host_class_audio_sampling_frequency); + control_buffer[2] = (UCHAR)UX_DW2(audio_sampling -> ux_host_class_audio_sampling_frequency); + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } + +#if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) + if (_ux_host_class_audio_protocol_get(audio) != UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_01_00) + { + + /* Set last byte. */ + control_buffer[3] = (UCHAR)UX_DW3(audio_sampling -> ux_host_class_audio_sampling_frequency); + + /* Create a transfer request for the CUR request. */ + transfer -> ux_transfer_request_data_pointer = control_buffer; + transfer -> ux_transfer_request_requested_length = 4; + transfer -> ux_transfer_request_function = UX_CLASS_AUDIO20_CUR; + transfer -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TARGET_INTERFACE | UX_REQUEST_TYPE_CLASS; + transfer -> ux_transfer_request_value = UX_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL << 8; + transfer -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | ((UINT)descriptor[3] << 8); + status = _ux_host_stack_transfer_request(transfer); + if (status != UX_SUCCESS) { + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } + + /* Issue CUR request. */ + status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } - /* We have found the isoch endpoint, save it. */ - audio -> ux_host_class_audio_isochronous_endpoint = endpoint; + /* Create a transfer request for the CUR request. */ + transfer -> ux_transfer_request_data_pointer = control_buffer; + transfer -> ux_transfer_request_requested_length = 4; + transfer -> ux_transfer_request_function = UX_CLASS_AUDIO20_CUR; + transfer -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TARGET_INTERFACE | UX_REQUEST_TYPE_CLASS; + transfer -> ux_transfer_request_value = UX_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL << 8; + transfer -> ux_transfer_request_index = audio -> ux_host_class_audio_control_interface_number | ((UINT)descriptor[3] << 8); + status = _ux_host_stack_transfer_request(transfer); + } + else +#endif + { - /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + /* Create a transfer request for the SET_CUR request. */ + transfer -> ux_transfer_request_data_pointer = control_buffer; + transfer -> ux_transfer_request_requested_length = 3; + transfer -> ux_transfer_request_function = UX_CLASS_AUDIO10_SET_CUR; + transfer -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TARGET_ENDPOINT | UX_REQUEST_TYPE_CLASS; + transfer -> ux_transfer_request_value = UX_CLASS_AUDIO10_EP_SAMPLING_FREQ_CONTROL << 8; + transfer -> ux_transfer_request_index = audio -> ux_host_class_audio_isochronous_endpoint -> ux_endpoint_descriptor.bEndpointAddress; + status = _ux_host_stack_transfer_request(transfer); + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); + } - /* Return successful completion. */ - return(UX_SUCCESS); + /* Issue GET_CUR request. */ + status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + _ux_utility_memory_free(control_buffer); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + return(status); } - } - } + + /* Create a transfer request for the GET_CUR request. */ + transfer -> ux_transfer_request_data_pointer = control_buffer; + transfer -> ux_transfer_request_requested_length = 3; + transfer -> ux_transfer_request_function = UX_CLASS_AUDIO10_GET_CUR; + transfer -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TARGET_ENDPOINT | UX_REQUEST_TYPE_CLASS; + transfer -> ux_transfer_request_value = UX_CLASS_AUDIO10_EP_SAMPLING_FREQ_CONTROL << 8; + transfer -> ux_transfer_request_index = audio -> ux_host_class_audio_isochronous_endpoint -> ux_endpoint_descriptor.bEndpointAddress; + status = _ux_host_stack_transfer_request(transfer); + } + + /* Free buffer. */ + _ux_utility_memory_free(control_buffer); + + /* Check frequency. */ + if (status == UX_SUCCESS) + { + frequency = _ux_utility_long_get(control_buffer); + if (audio_sampling -> ux_host_class_audio_sampling_frequency != frequency) + status = UX_HOST_CLASS_AUDIO_WRONG_FREQUENCY; + } + } + + /* Update packet processing parameters. */ + audio -> ux_host_class_audio_packet_freq = + (device -> ux_device_speed == UX_HIGH_SPEED_DEVICE) ? + 8000 : 1000; + audio -> ux_host_class_audio_packet_freq <<= + audio -> ux_host_class_audio_isochronous_endpoint -> + ux_endpoint_descriptor.bInterval - 1; /* Max 8000 << 15, no overflow. */ + res_bytes = audio_sampling -> ux_host_class_audio_sampling_resolution; + if (UX_OVERFLOW_CHECK_ADD_ULONG(res_bytes, 7)) + status = UX_MATH_OVERFLOW; + if (status == UX_SUCCESS) + { + res_bytes += 7; + res_bytes >>= 3; + + frequency = audio_sampling -> ux_host_class_audio_sampling_frequency; + if (UX_OVERFLOW_CHECK_MULV_ULONG(frequency, audio_sampling -> ux_host_class_audio_sampling_channels)) + status = UX_MATH_OVERFLOW; + } + if (status == UX_SUCCESS) + { + frequency *= audio_sampling -> ux_host_class_audio_sampling_channels; + if (UX_OVERFLOW_CHECK_MULV_ULONG(frequency, res_bytes)) + status = UX_MATH_OVERFLOW; + } + if (status == UX_SUCCESS) + { + frequency *= res_bytes; + audio -> ux_host_class_audio_packet_fraction = + frequency % audio -> ux_host_class_audio_packet_freq; + audio -> ux_host_class_audio_packet_size = + frequency / audio -> ux_host_class_audio_packet_freq; + } + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + /* Return completion status. */ + return(status); } } /* Move to next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } - + /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_NO_ALTERNATE_SETTING); @@ -192,4 +377,3 @@ UINT streaming_interface; /* We get here if we could not get the right alternate setting. */ return(UX_NO_ALTERNATE_SETTING); } - diff --git a/common/usbx_host_classes/src/ux_host_class_audio_transfer_request.c b/common/usbx_host_classes/src/ux_host_class_audio_transfer_request.c index 0a76bd4a..98cf1160 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_transfer_request.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_transfer_request.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_transfer_request PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,37 +69,55 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* refined transfer implement, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_transfer_request(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *audio_transfer_request) { +UX_INTERRUPT_SAVE_AREA UINT status; UX_TRANSFER *transfer_request; - /* The transfer request is embedded in the application transfer request. */ transfer_request = &audio_transfer_request -> ux_host_class_audio_transfer_request; - /* Select the direction. We do this by taking the endpoint direction. */ - transfer_request -> ux_transfer_request_type = audio -> ux_host_class_audio_isochronous_endpoint -> - ux_endpoint_descriptor.bEndpointAddress&UX_REQUEST_DIRECTION; + /* Saved the direction, by taking the endpoint transfer direction. */ + transfer_request -> ux_transfer_request_type = + audio -> ux_host_class_audio_isochronous_endpoint -> + ux_endpoint_transfer_request.ux_transfer_request_type; /* Fill the transfer request with all the required fields. */ - transfer_request -> ux_transfer_request_endpoint = audio -> ux_host_class_audio_isochronous_endpoint; - transfer_request -> ux_transfer_request_data_pointer = audio_transfer_request -> ux_host_class_audio_transfer_request_data_pointer; - transfer_request -> ux_transfer_request_requested_length = audio_transfer_request -> ux_host_class_audio_transfer_request_requested_length; - transfer_request -> ux_transfer_request_completion_function = _ux_host_class_audio_transfer_request_completed; - transfer_request -> ux_transfer_request_class_instance = audio; + transfer_request -> ux_transfer_request_endpoint = audio -> ux_host_class_audio_isochronous_endpoint; + transfer_request -> ux_transfer_request_data_pointer = audio_transfer_request -> ux_host_class_audio_transfer_request_data_pointer; + transfer_request -> ux_transfer_request_requested_length = audio_transfer_request -> ux_host_class_audio_transfer_request_requested_length; + transfer_request -> ux_transfer_request_packet_length = audio_transfer_request -> ux_host_class_audio_transfer_request_packet_size; + transfer_request -> ux_transfer_request_completion_function = _ux_host_class_audio_transfer_request_completed; + transfer_request -> ux_transfer_request_class_instance = audio; + transfer_request -> ux_transfer_request_next_transfer_request = UX_NULL; /* Add one by one. */ /* We memorize the application transfer request in the local transfer request. */ transfer_request -> ux_transfer_request_user_specific = (VOID *) audio_transfer_request; - /* Transfer the transfer request. */ + UX_DISABLE + + /* Hook the audio transfer request to the chain of transfer requests in the audio instance. */ + audio_transfer_request -> ux_host_class_audio_transfer_request_next_audio_transfer_request = + audio -> ux_host_class_audio_tail_transfer_request; + audio -> ux_host_class_audio_tail_transfer_request = audio_transfer_request; + + /* Check if this is the first time we have had a transfer request, if so update the head as well. */ + if (audio -> ux_host_class_audio_head_transfer_request == UX_NULL) + audio -> ux_host_class_audio_head_transfer_request = audio_transfer_request; + + UX_RESTORE + + /* Transfer the transfer request (queued in lower level). */ status = _ux_host_stack_transfer_request(transfer_request); /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_audio_write.c b/common/usbx_host_classes/src/ux_host_class_audio_write.c index 3ae59bc7..51ea4ea3 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_write.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_write.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_write PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -43,6 +43,9 @@ /* DESCRIPTION */ /* */ /* This function writes to the audio streaming interface. */ +/* */ +/* Note the request packet size should not exceed endpoint max packet */ +/* size, and the request length should be aligned with packet size. */ /* */ /* INPUT */ /* */ @@ -57,8 +60,8 @@ /* */ /* _ux_host_class_audio_transfer_request Start audio transfer request */ /* _ux_host_stack_class_instance_verify Verify instance is valid */ -/* _ux_host_semaphore_get Get semaphore */ -/* _ux_host_semaphore_put Put semaphore */ +/* _ux_host_mutex_on Get mutex */ +/* _ux_host_mutex_off Release mutex */ /* */ /* CALLED BY */ /* */ @@ -78,12 +81,19 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* refined packet size manage, */ +/* protect reentry with mutex, */ +/* refined transfer implement, */ +/* fixed error return code, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_write(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *audio_transfer_request) { UINT status; +ULONG mps; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_WRITE, audio, audio_transfer_request -> ux_host_class_audio_transfer_request_data_pointer, @@ -103,19 +113,14 @@ UINT status; } /* Protect thread reentry to this instance. */ - status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_semaphore, UX_WAIT_FOREVER); - if (status != UX_SUCCESS) - return(status); + _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); - /* By default the transmission will be successful. */ - status = UX_SUCCESS; - /* Ensure we have a selected interface that allows isoch transmission. */ if (audio -> ux_host_class_audio_isochronous_endpoint -> ux_endpoint_descriptor.wMaxPacketSize == 0) { /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_AUDIO_WRONG_INTERFACE); @@ -123,23 +128,19 @@ UINT status; /* Return error status. */ return(UX_HOST_CLASS_AUDIO_WRONG_INTERFACE); } - - /* Hook the audio transfer request to the chain of transfer requests in the audio instance. - We hook the transfer request to the tail transfer request. */ - audio_transfer_request -> ux_host_class_audio_transfer_request_next_audio_transfer_request = audio -> ux_host_class_audio_tail_transfer_request; - audio -> ux_host_class_audio_tail_transfer_request = audio_transfer_request; - /* Check if this is the first time we have a transfer request, if so update the head as well. */ - if (audio -> ux_host_class_audio_head_transfer_request == UX_NULL) - audio -> ux_host_class_audio_head_transfer_request = audio_transfer_request; + /* Correct packet size to apply (not exceeding endpoint max packet size). */ + mps = _ux_host_class_audio_max_packet_size_get(audio); + if ((audio_transfer_request -> ux_host_class_audio_transfer_request_packet_size == 0) || + (audio_transfer_request -> ux_host_class_audio_transfer_request_packet_size > mps)) + audio_transfer_request -> ux_host_class_audio_transfer_request_packet_size = mps; - /* Ask the stack to hook this transfer request to the iso ED. */ + /* Ask the stack to hook this transfer request to the iso ED. */ status = _ux_host_class_audio_transfer_request(audio, audio_transfer_request); /* Unprotect thread reentry to this instance. */ - _ux_host_semaphore_put(&audio -> ux_host_class_audio_semaphore); + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_acm_activate.c b/common/usbx_host_classes/src/ux_host_class_cdc_acm_activate.c index d0c27362..83dc55c6 100644 --- a/common/usbx_host_classes/src/ux_host_class_cdc_acm_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_cdc_acm_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_cdc_acm_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,12 +82,17 @@ /* used defined line coding */ /* instead of magic number, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved error handling, */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_cdc_acm_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_CDC_ACM *cdc_acm; UINT status; #if defined(UX_HOST_STANDALONE) @@ -103,7 +108,7 @@ UX_HOST_CLASS_CDC_ACM_LINE_STATE line_state; /* The CDC ACM class is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Obtain memory for this class instance. */ cdc_acm = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, sizeof(UX_HOST_CLASS_CDC_ACM)); @@ -133,13 +138,13 @@ UX_HOST_CLASS_CDC_ACM_LINE_STATE line_state; cdc_acm -> ux_host_class_cdc_acm_class = command -> ux_host_class_command_class_ptr; /* Store the interface container into the cdc_acm class instance. */ - cdc_acm -> ux_host_class_cdc_acm_interface = interface; + cdc_acm -> ux_host_class_cdc_acm_interface = interface_ptr; /* Store the device container into the cdc_acm class instance. */ - cdc_acm -> ux_host_class_cdc_acm_device = interface -> ux_interface_configuration -> ux_configuration_device; + cdc_acm -> ux_host_class_cdc_acm_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) cdc_acm; + interface_ptr -> ux_interface_class_instance = (VOID *) cdc_acm; /* Create this class instance. */ _ux_host_stack_class_instance_create(cdc_acm -> ux_host_class_cdc_acm_class, (VOID *) cdc_acm); @@ -149,98 +154,101 @@ UX_HOST_CLASS_CDC_ACM_LINE_STATE line_state; /* Get the cdc_acm endpoint(s). Depending on the interface type, we will need to search for Bulk Out and Bulk In endpoints and the optional interrupt endpoint. */ status = _ux_host_class_cdc_acm_endpoints_get(cdc_acm); + if (status == UX_SUCCESS) + { - /* Mark the cdc_acm as mounting. */ - cdc_acm -> ux_host_class_cdc_acm_state = UX_HOST_CLASS_INSTANCE_MOUNTING; + /* Mark the cdc_acm as mounting. */ + cdc_acm -> ux_host_class_cdc_acm_state = UX_HOST_CLASS_INSTANCE_MOUNTING; - /* If we have the Control Class, we process default setup command sequence. */ - if (interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS) - { + /* If we have the Control Class, we process default setup command sequence. */ + if (interface_ptr -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS) + { - /* Get descriptors to see capabilities. */ + /* Get descriptors to see capabilities. */ - /* Get default control transfer. */ - control_endpoint = &cdc_acm -> ux_host_class_cdc_acm_device -> ux_device_control_endpoint; - transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + /* Get default control transfer. */ + control_endpoint = &cdc_acm -> ux_host_class_cdc_acm_device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; - /* Allocate memory for the descriptors. */ - descriptors_length = interface -> ux_interface_configuration -> - ux_configuration_descriptor.wTotalLength; - cdc_acm -> ux_host_class_cdc_acm_allocated = - _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, - descriptors_length); - if (cdc_acm -> ux_host_class_cdc_acm_allocated != UX_NULL) - { + /* Allocate memory for the descriptors. */ + descriptors_length = interface_ptr -> ux_interface_configuration -> + ux_configuration_descriptor.wTotalLength; + cdc_acm -> ux_host_class_cdc_acm_allocated = + _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, + descriptors_length); + if (cdc_acm -> ux_host_class_cdc_acm_allocated != UX_NULL) + { - transfer_request -> ux_transfer_request_data_pointer = - cdc_acm -> ux_host_class_cdc_acm_allocated; + transfer_request -> ux_transfer_request_data_pointer = + cdc_acm -> ux_host_class_cdc_acm_allocated; - /* Create transfer for GET_DESCRIPTOR. */ - transfer_request -> ux_transfer_request_requested_length = descriptors_length; - transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR; - transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; - transfer_request -> ux_transfer_request_value = UX_CONFIGURATION_DESCRIPTOR_ITEM << 8; - transfer_request -> ux_transfer_request_index = 0; - UX_TRANSFER_STATE_RESET(transfer_request); + /* Create transfer for GET_DESCRIPTOR. */ + transfer_request -> ux_transfer_request_requested_length = descriptors_length; + transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; + transfer_request -> ux_transfer_request_value = UX_CONFIGURATION_DESCRIPTOR_ITEM << 8; + transfer_request -> ux_transfer_request_index = 0; + UX_TRANSFER_STATE_RESET(transfer_request); - /* Set state to wait and next is "next". */ - cdc_acm -> ux_host_class_cdc_acm_cmd_state = UX_STATE_WAIT; - cdc_acm -> ux_host_class_cdc_acm_next_state = UX_STATE_NEXT; + /* Set state to wait and next is "next". */ + cdc_acm -> ux_host_class_cdc_acm_cmd_state = UX_STATE_WAIT; + cdc_acm -> ux_host_class_cdc_acm_next_state = UX_STATE_NEXT; - /* ACTIVATE_WAIT will be processed to finish next steps. */ - return(UX_SUCCESS); + /* ACTIVATE_WAIT will be processed to finish next steps. */ + return(UX_SUCCESS); + } + else + status = UX_MEMORY_INSUFFICIENT; } else - status = UX_MEMORY_INSUFFICIENT; - } - else - { - - /* We scan CDC ACM instances to find the master instance. */ - /* Get class. */ - cdc_acm_class = cdc_acm -> ux_host_class_cdc_acm_class; + { - /* Get first instance linked to the class. */ - cdc_acm_inst = (UX_HOST_CLASS_CDC_ACM *)cdc_acm_class -> ux_host_class_first_instance; + /* We scan CDC ACM instances to find the master instance. */ + /* Get class. */ + cdc_acm_class = cdc_acm -> ux_host_class_cdc_acm_class; - /* Scan all instances. */ - while(cdc_acm_inst) - { + /* Get first instance linked to the class. */ + cdc_acm_inst = (UX_HOST_CLASS_CDC_ACM *)cdc_acm_class -> ux_host_class_first_instance; - /* If this data interface is inside the associate list, link it. */ - if (cdc_acm_inst -> ux_host_class_cdc_acm_interfaces_bitmap & - (1ul << interface -> ux_interface_descriptor.bInterfaceNumber)) + /* Scan all instances. */ + while(cdc_acm_inst) { - /* Save control instance and we are done. */ - cdc_acm -> ux_host_class_cdc_acm_control = cdc_acm_inst; - break; - } + /* If this data interface is inside the associate list, link it. */ + if (cdc_acm_inst -> ux_host_class_cdc_acm_interfaces_bitmap & + (1ul << interface_ptr -> ux_interface_descriptor.bInterfaceNumber)) + { - /* Next instance. */ - cdc_acm_inst = cdc_acm_inst -> ux_host_class_cdc_acm_next_instance; - } + /* Save control instance and we are done. */ + cdc_acm -> ux_host_class_cdc_acm_control = cdc_acm_inst; + break; + } - /* Mark the cdc_acm as live now. Both interfaces need to be live. */ - cdc_acm -> ux_host_class_cdc_acm_state = UX_HOST_CLASS_INSTANCE_LIVE; + /* Next instance. */ + cdc_acm_inst = cdc_acm_inst -> ux_host_class_cdc_acm_next_instance; + } - /* If all is fine and the device is mounted, we may need to inform the application - if a function has been programmed in the system structure. */ - if (_ux_system_host -> ux_system_host_change_function != UX_NULL) - { + /* Mark the cdc_acm as live now. Both interfaces need to be live. */ + cdc_acm -> ux_host_class_cdc_acm_state = UX_HOST_CLASS_INSTANCE_LIVE; - /* Call system change function. */ - _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, cdc_acm -> ux_host_class_cdc_acm_class, (VOID *) cdc_acm); - } + /* If all is fine and the device is mounted, we may need to inform the application + if a function has been programmed in the system structure. */ + if (_ux_system_host -> ux_system_host_change_function != UX_NULL) + { + + /* Call system change function. */ + _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, cdc_acm -> ux_host_class_cdc_acm_class, (VOID *) cdc_acm); + } - /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_CDC_ACM_ACTIVATE, cdc_acm, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_CDC_ACM_ACTIVATE, cdc_acm, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) - /* If trace is enabled, register this object. */ - UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, cdc_acm, 0, 0, 0) + /* If trace is enabled, register this object. */ + UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, cdc_acm, 0, 0, 0) - /* We are done success. */ - return(UX_SUCCESS); + /* We are done success. */ + return(UX_SUCCESS); + } } #else @@ -355,7 +363,7 @@ UX_HOST_CLASS_CDC_ACM_LINE_STATE line_state; #endif /* Unmount instance. */ - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr -> ux_interface_class_instance = UX_NULL; /* Free instance. */ _ux_utility_memory_free(cdc_acm); diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_acm_entry.c b/common/usbx_host_classes/src/ux_host_class_cdc_acm_entry.c index 1f7cf015..e126decb 100644 --- a/common/usbx_host_classes/src/ux_host_class_cdc_acm_entry.c +++ b/common/usbx_host_classes/src/ux_host_class_cdc_acm_entry.c @@ -52,7 +52,7 @@ static inline UINT _ux_host_class_cdc_acm_activate_wait(UX_HOST_CLASS_COMMAND * /* FUNCTION RELEASE */ /* */ /* _ux_host_class_cdc_acm_entry PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -95,6 +95,10 @@ static inline UINT _ux_host_class_cdc_acm_activate_wait(UX_HOST_CLASS_COMMAND * /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_cdc_acm_entry(UX_HOST_CLASS_COMMAND *command) @@ -184,7 +188,7 @@ static inline VOID _ux_host_class_cdc_acm_descriptors_parse(UX_HOST_CLASS_CDC_A UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UCHAR *descriptor; ULONG total_descriptor_length; UCHAR descriptor_length; @@ -209,7 +213,7 @@ UCHAR offset; } /* Get the interface. */ - interface = cdc_acm -> ux_host_class_cdc_acm_interface; + interface_ptr = cdc_acm -> ux_host_class_cdc_acm_interface; /* Parse the descriptor. */ total_descriptor_length = transfer_request -> ux_transfer_request_actual_length; @@ -238,7 +242,7 @@ UCHAR offset; case UX_INTERFACE_DESCRIPTOR_ITEM: /* Check if interface is what we expected. */ - if (interface -> ux_interface_descriptor.bInterfaceNumber == descriptor_byte2) + if (interface_ptr -> ux_interface_descriptor.bInterfaceNumber == descriptor_byte2) { /* Mark found. */ @@ -331,7 +335,7 @@ static inline UINT _ux_host_class_cdc_acm_activate_wait(UX_HOST_CLASS_COMMAND * UX_HOST_CLASS *cdc_acm_class; UX_HOST_CLASS_CDC_ACM *cdc_acm_inst; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_CDC_ACM *cdc_acm; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer; @@ -341,8 +345,8 @@ UINT status; ULONG tick, diff; /* Get the instance for this class. */ - interface = (UX_INTERFACE *)command -> ux_host_class_command_container; - cdc_acm = (UX_HOST_CLASS_CDC_ACM *) interface -> ux_interface_class_instance; + interface_ptr = (UX_INTERFACE *)command -> ux_host_class_command_container; + cdc_acm = (UX_HOST_CLASS_CDC_ACM *) interface_ptr -> ux_interface_class_instance; /* Run initialize state machine. */ switch(cdc_acm -> ux_host_class_cdc_acm_cmd_state) @@ -500,11 +504,11 @@ ULONG tick, diff; { /* Get interface of the instance. */ - interface = cdc_acm_inst -> ux_host_class_cdc_acm_interface; + interface_ptr = cdc_acm_inst -> ux_host_class_cdc_acm_interface; /* If this data interface is inside the associate list, link it. */ if (cdc_acm -> ux_host_class_cdc_acm_interfaces_bitmap & - (1ul << interface -> ux_interface_descriptor.bInterfaceNumber)) + (1ul << interface_ptr -> ux_interface_descriptor.bInterfaceNumber)) { /* Save control instance and we are done. */ @@ -556,8 +560,8 @@ ULONG tick, diff; _ux_host_stack_class_instance_destroy(cdc_acm -> ux_host_class_cdc_acm_class, (VOID *) cdc_acm); /* Unmount instance. */ - interface = cdc_acm -> ux_host_class_cdc_acm_interface; - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr = cdc_acm -> ux_host_class_cdc_acm_interface; + interface_ptr -> ux_interface_class_instance = UX_NULL; /* Free instance. */ _ux_utility_memory_free(cdc_acm); diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_acm_write.c b/common/usbx_host_classes/src/ux_host_class_cdc_acm_write.c index 8e0a7869..be58e0f0 100644 --- a/common/usbx_host_classes/src/ux_host_class_cdc_acm_write.c +++ b/common/usbx_host_classes/src/ux_host_class_cdc_acm_write.c @@ -122,7 +122,7 @@ ULONG transfer_flags; return(UX_HOST_CLASS_INSTANCE_UNKNOWN); } - + #if defined(UX_HOST_STANDALONE) if (cdc_acm -> ux_host_class_cdc_acm_write_state == UX_STATE_WAIT) return(UX_BUSY); @@ -134,7 +134,7 @@ ULONG transfer_flags; /* Get the pointer to the bulk out endpoint transfer request. */ transfer_request = &cdc_acm -> ux_host_class_cdc_acm_bulk_out_endpoint -> ux_endpoint_transfer_request; - + #if defined(UX_HOST_STANDALONE) /* Enable auto wait. */ @@ -163,7 +163,7 @@ ULONG transfer_flags; /* If the transfer is successful, we need to wait for the transfer request to be completed. */ if (status == UX_SUCCESS) { - + #if !defined(UX_HOST_STANDALONE) /* Wait for the completion of the transfer request. */ status = _ux_host_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, @@ -191,7 +191,7 @@ ULONG transfer_flags; /* There was an error, return to the caller. */ return(UX_TRANSFER_TIMEOUT); - } + } #endif } else diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c index 8c495347..3d1dfde8 100644 --- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c @@ -37,7 +37,7 @@ UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT /* FUNCTION RELEASE */ /* */ /* _ux_host_class_cdc_ecm_activate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -96,12 +96,16 @@ UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_cdc_ecm_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_CDC_ECM *cdc_ecm; UINT status; UX_TRANSFER *transfer_request; @@ -112,10 +116,10 @@ UX_INTERFACE *cur_interface; /* The CDC ECM class is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Is this the control interface? */ - if (interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS) + if (interface_ptr -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS) { /* We ignore the control interface. All activation is performed when @@ -132,23 +136,23 @@ UX_INTERFACE *cur_interface; cdc_ecm -> ux_host_class_cdc_ecm_class = command -> ux_host_class_command_class_ptr; /* Store the device container into the cdc_ecm class instance. */ - cdc_ecm -> ux_host_class_cdc_ecm_device = interface -> ux_interface_configuration -> ux_configuration_device; + cdc_ecm -> ux_host_class_cdc_ecm_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* Store the interface container into the cdc_acm class instance. */ - cdc_ecm -> ux_host_class_cdc_ecm_interface_data = interface; + cdc_ecm -> ux_host_class_cdc_ecm_interface_data = interface_ptr; /* We need to link the data and control interfaces together. In order to do this, we first need to find the control interface. Per the spec, it should be behind this one. */ /* Set the current interface to the second interface. */ - cur_interface = interface -> ux_interface_configuration -> ux_configuration_first_interface; + cur_interface = interface_ptr -> ux_interface_configuration -> ux_configuration_first_interface; /* Initialize to null. */ control_interface = UX_NULL; /* Loop through all the interfaces until we find the current data interface. */ - while (cur_interface != interface) + while (cur_interface != interface_ptr) { /* Is this a control interface? */ @@ -289,7 +293,7 @@ UX_INTERFACE *cur_interface; cdc_ecm -> ux_host_class_cdc_ecm_state = UX_HOST_CLASS_INSTANCE_LIVE; /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) cdc_ecm; + interface_ptr -> ux_interface_class_instance = (VOID *) cdc_ecm; /* Create this class instance. */ _ux_host_stack_class_instance_create(cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm); @@ -339,7 +343,7 @@ UX_INTERFACE *cur_interface; _ux_host_stack_class_instance_destroy(cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm); /* Unmount instance. */ - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr -> ux_interface_class_instance = UX_NULL; } /* Delete CDC-ECM thread. */ diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c index cad6b7b8..6a65d57d 100644 --- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c +++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_cdc_ecm_mac_address_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* checked MAC string length, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_cdc_ecm_mac_address_get(UX_HOST_CLASS_CDC_ECM *cdc_ecm) @@ -205,12 +208,13 @@ UCHAR element_hexa_lower; if (status == UX_SUCCESS) { - /* Translate from Unicode to string. Length is in the first byte. We must take away 2 from it - and divide by 2 to find the right asciiz length. */ + /* Translate from Unicode to string. Length is in the first byte followed type. + We must take away 2 from it and divide by 2 to find the right ascii length. */ string_length = (ULONG) *mac_address_string; - /* Check the length of the mac address Unicode string. */ - if (string_length > 26) + /* Check the length of the MAC address Unicode string + (length or 1B + type of 1B + string or 12*2B). */ + if (string_length != 26) { /* Error trap. */ @@ -224,9 +228,9 @@ UCHAR element_hexa_lower; /* No error in length, decode the string. */ string_length -=2; - string_length = string_length/2; + string_length = string_length / 2; - /* Now we have a string of 12 hexa ASCII digits to be translated into 6 hexa digit bytes. + /* Now we have a string of 12 hex ASCII digits to be translated into 6 hex digit bytes. and copy into the node ID. */ for (string_index = 0; string_index < string_length; string_index++) { @@ -234,7 +238,7 @@ UCHAR element_hexa_lower; /* Get the upper element from the ASCII string. */ element_content = *(mac_address_string + (string_index * 2) + 2); - /* We have a valid element content. Turn it into a hexa decimal value. Note + /* We have a valid element content. Turn it into a hex decimal value. Note that only hex digits are allowed. */ if (element_content <= '9') @@ -285,7 +289,7 @@ UCHAR element_hexa_lower; *(cdc_ecm -> ux_host_class_cdc_ecm_node_id + string_index / 2) = (UCHAR)(element_hexa_upper << 4 | element_hexa_lower); /* Skip the lower nibble. */ - string_index++; + string_index ++; } @@ -332,17 +336,3 @@ UCHAR element_hexa_lower; return(UX_DESCRIPTOR_CORRUPTED); } - - - - - - - - - - - - - - diff --git a/common/usbx_host_classes/src/ux_host_class_hid_activate.c b/common/usbx_host_classes/src/ux_host_class_hid_activate.c index 481abd28..2306e0dc 100644 --- a/common/usbx_host_classes/src/ux_host_class_hid_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_hid_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hid_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,19 +79,23 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hid_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_HID *hid; UINT status; /* The HID is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Instantiate this HID class */ hid = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY,sizeof(UX_HOST_CLASS_HID)); @@ -102,13 +106,13 @@ UINT status; hid -> ux_host_class_hid_class = command -> ux_host_class_command_class_ptr; /* Store the interface container into the HID class instance. */ - hid -> ux_host_class_hid_interface = interface; + hid -> ux_host_class_hid_interface = interface_ptr; /* Store the device container into the HID class instance. */ - hid -> ux_host_class_hid_device = interface -> ux_interface_configuration -> ux_configuration_device; + hid -> ux_host_class_hid_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) hid; + interface_ptr -> ux_interface_class_instance = (VOID *) hid; /* Create this class instance. */ _ux_host_stack_class_instance_create(command -> ux_host_class_command_class_ptr, (VOID *) hid); @@ -196,7 +200,7 @@ UINT status; _ux_host_stack_class_instance_destroy(hid -> ux_host_class_hid_class, (VOID *) hid); /* Unmount instance. */ - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr -> ux_interface_class_instance = UX_NULL; /* Free instance. */ _ux_utility_memory_free(hid); diff --git a/common/usbx_host_classes/src/ux_host_class_hid_client_register.c b/common/usbx_host_classes/src/ux_host_class_hid_client_register.c index df7c3cec..680efa87 100644 --- a/common/usbx_host_classes/src/ux_host_class_hid_client_register.c +++ b/common/usbx_host_classes/src/ux_host_class_hid_client_register.c @@ -36,7 +36,7 @@ UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_MULC_ULONG(UX_HOST_CLASS_HID_MAX_CLIEN /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hid_client_register PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -87,13 +87,17 @@ UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_MULC_ULONG(UX_HOST_CLASS_HID_MAX_CLIEN /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hid_client_register(UCHAR *hid_client_name, UINT (*hid_client_handler)(struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *)) { -UX_HOST_CLASS *class; +UX_HOST_CLASS *class_ptr; ULONG hid_client_index; UINT status; UX_HOST_CLASS_HID_CLIENT *hid_client; @@ -108,7 +112,7 @@ UINT client_name_length = 0; return(status); /* We need to locate our class container. */ - status = _ux_host_stack_class_get(_ux_system_host_class_hid_name, &class); + status = _ux_host_stack_class_get(_ux_system_host_class_hid_name, &class_ptr); /* If we cannot get the class container, it means the HID class was not registered. */ if (status != UX_SUCCESS) @@ -116,22 +120,22 @@ UINT client_name_length = 0; /* From the class container, we get the client pointer which has the list of HID clients. If the pointer is NULL, the client list was not assigned. */ - if (class -> ux_host_class_client == UX_NULL) + if (class_ptr -> ux_host_class_client == UX_NULL) { /* Allocate memory for the class client. * Allocate size overflow static checked outside the function. */ - class -> ux_host_class_client = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, + class_ptr -> ux_host_class_client = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_HID_CLIENT)*UX_HOST_CLASS_HID_MAX_CLIENTS); /* Check for successful allocation. */ - if (class -> ux_host_class_client == UX_NULL) + if (class_ptr -> ux_host_class_client == UX_NULL) return(UX_MEMORY_INSUFFICIENT); } /* De-reference the client pointer into a HID client array pointer. */ - hid_client = (UX_HOST_CLASS_HID_CLIENT *) class -> ux_host_class_client; + hid_client = (UX_HOST_CLASS_HID_CLIENT *) class_ptr -> ux_host_class_client; /* We need to parse the HID client handler table to find an empty spot. */ for (hid_client_index = 0; hid_client_index < UX_HOST_CLASS_HID_MAX_CLIENTS; hid_client_index++) diff --git a/common/usbx_host_classes/src/ux_host_class_hid_descriptor_parse.c b/common/usbx_host_classes/src/ux_host_class_hid_descriptor_parse.c index 5df4c057..f9fd61ef 100644 --- a/common/usbx_host_classes/src/ux_host_class_hid_descriptor_parse.c +++ b/common/usbx_host_classes/src/ux_host_class_hid_descriptor_parse.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hid_descriptor_parse PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,14 +72,19 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used shared device config */ +/* descriptor for enum scan, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hid_descriptor_parse(UX_HOST_CLASS_HID *hid) { +UX_DEVICE *device; +UX_CONFIGURATION *configuration; UCHAR *descriptor; UCHAR *start_descriptor; -UX_CONFIGURATION_DESCRIPTOR configuration_descriptor; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; UX_HID_DESCRIPTOR hid_descriptor; @@ -90,154 +95,143 @@ UINT descriptor_length; UINT descriptor_type; ULONG current_interface; - /* We need to get the default control endpoint transfer request pointer. */ - control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint; - transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + /* Get device, current configuration. */ + device = hid -> ux_host_class_hid_device; + configuration = device -> ux_device_current_configuration; + total_configuration_length = configuration -> ux_configuration_descriptor.wTotalLength; - /* Need to allocate memory for the descriptor. Since we do not know the size of the - descriptor, we first read the first bytes. */ - descriptor = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_CONFIGURATION_DESCRIPTOR_LENGTH); - if (descriptor == UX_NULL) - return(UX_MEMORY_INSUFFICIENT); - - /* Memorize the descriptor start address. */ - start_descriptor = descriptor; - - /* Reset the current interface to keep compiler warnings happy. */ - current_interface = 0; - - /* Create a transfer request for the GET_DESCRIPTOR request. */ - transfer_request -> ux_transfer_request_data_pointer = descriptor; - transfer_request -> ux_transfer_request_requested_length = UX_CONFIGURATION_DESCRIPTOR_LENGTH; - transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR; - transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; - transfer_request -> ux_transfer_request_value = UX_CONFIGURATION_DESCRIPTOR_ITEM << 8; - transfer_request -> ux_transfer_request_index = 0; - - /* Send request to HCD layer. */ - status = _ux_host_stack_transfer_request(transfer_request); - - /* Check for correct transfer and entire descriptor returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == UX_CONFIGURATION_DESCRIPTOR_LENGTH)) + /* Check if descriptor is previously saved. */ + if (device -> ux_device_packed_configuration != UX_NULL) + { + start_descriptor = device -> ux_device_packed_configuration; + descriptor = start_descriptor; + status = UX_SUCCESS; + } + else { - /* Parse the descriptor so that we can read the total length. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_configuration_descriptor_structure, - UX_CONFIGURATION_DESCRIPTOR_ENTRIES, (UCHAR *) &configuration_descriptor); - - /* We don't need this descriptor now. */ - _ux_utility_memory_free(descriptor); + /* We need to get the default control endpoint transfer request pointer. */ + control_endpoint = &device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; - /* Reallocate the memory necessary for the reading the entire descriptor. */ - total_configuration_length = configuration_descriptor.wTotalLength; + /* Need to allocate memory for the descriptor. Since we do not know the size of the + descriptor, we first read the first bytes. */ descriptor = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, total_configuration_length); - if(descriptor == UX_NULL) + if (descriptor == UX_NULL) return(UX_MEMORY_INSUFFICIENT); - - /* Save this descriptor address. */ + + /* Memorize the descriptor start address. */ start_descriptor = descriptor; - /* Read the descriptor again with the correct length this time. */ + /* Create a transfer request for the GET_DESCRIPTOR request. */ + transfer_request -> ux_transfer_request_data_pointer = descriptor; transfer_request -> ux_transfer_request_requested_length = total_configuration_length; - - /* Since the address of the descriptor may have changed, reprogram it. */ - transfer_request -> ux_transfer_request_data_pointer = descriptor; + transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; + transfer_request -> ux_transfer_request_value = UX_CONFIGURATION_DESCRIPTOR_ITEM << 8; + transfer_request -> ux_transfer_request_index = 0; /* Send request to HCD layer. */ status = _ux_host_stack_transfer_request(transfer_request); - /* Check for correct transfer and entire descriptor returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == configuration_descriptor.wTotalLength)) - { + /* Check descriptor length. */ + if (transfer_request -> ux_transfer_request_actual_length != total_configuration_length) + status = UX_DESCRIPTOR_CORRUPTED; + } + + /* Reset the current interface to keep compiler warnings happy. */ + current_interface = 0; - /* The HID descriptor is embedded within the configuration descriptor. We parse the - entire descriptor to locate the HID portion. */ - while (total_configuration_length) + /* Check for correct transfer and entire descriptor returned. */ + if (status == UX_SUCCESS) + { + + /* The HID descriptor is embedded within the configuration descriptor. We parse the + entire descriptor to locate the HID portion. */ + while (total_configuration_length) + { + + /* Gather the length and type of the descriptor. */ + descriptor_length = *descriptor; + descriptor_type = *(descriptor + 1); + + /* Make sure this descriptor has at least the minimum length. */ + if (descriptor_length < 3) { - - /* Gather the length and type of the descriptor. */ - descriptor_length = *descriptor; - descriptor_type = *(descriptor + 1); - - /* Make sure this descriptor has at least the minimum length. */ - if (descriptor_length < 3) - { - /* Error trap. */ - _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); - /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) - /* Error, release the memory and return an error. */ - _ux_utility_memory_free(start_descriptor); + /* Error, release the memory and return an error. */ + _ux_utility_memory_free(start_descriptor); - return(UX_DESCRIPTOR_CORRUPTED); - } + return(UX_DESCRIPTOR_CORRUPTED); + } - /* Check the type for an interface descriptor. */ - if (descriptor_type == UX_INTERFACE_DESCRIPTOR_ITEM) - { + /* Check the type for an interface descriptor. */ + if (descriptor_type == UX_INTERFACE_DESCRIPTOR_ITEM) + { - /* Parse the interface descriptor and make it machine independent. */ - _ux_utility_descriptor_parse(descriptor, - _ux_system_interface_descriptor_structure, - UX_INTERFACE_DESCRIPTOR_ENTRIES, - (UCHAR *) &interface_descriptor); + /* Parse the interface descriptor and make it machine independent. */ + _ux_utility_descriptor_parse(descriptor, + _ux_system_interface_descriptor_structure, + UX_INTERFACE_DESCRIPTOR_ENTRIES, + (UCHAR *) &interface_descriptor); - /* Memorize the interface we are scanning. */ - current_interface = interface_descriptor.bInterfaceNumber; + /* Memorize the interface we are scanning. */ + current_interface = interface_descriptor.bInterfaceNumber; + } + + /* Check the type for an interface descriptor. */ + /* Check if the descriptor belongs to interface attached to this instance. */ + if (descriptor_type == UX_HOST_CLASS_HID_DESCRIPTOR) + { - } - - /* Check the type for an interface descriptor. */ - /* Check if the descriptor belongs to interface attached to this instance. */ - if (descriptor_type == UX_HOST_CLASS_HID_DESCRIPTOR) + /* Ensure this interface is the one we need to scan. */ + if (current_interface == hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber) { - /* Ensure this interface is the one we need to scan. */ - if (current_interface == hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber) - { + /* Obtain the length of the HID descriptor. We need to make machine + independent first. */ + _ux_utility_descriptor_parse(descriptor, _ux_system_hid_descriptor_structure, + UX_HID_DESCRIPTOR_ENTRIES, (UCHAR *) &hid_descriptor); - /* Obtain the length of the HID descriptor. We need to make machine - independent first. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_hid_descriptor_structure, - UX_HID_DESCRIPTOR_ENTRIES, (UCHAR *) &hid_descriptor); - - /* We have found the hid descriptor. Now we should get the HID report descriptor. */ - status = _ux_host_class_hid_report_descriptor_get(hid, hid_descriptor.wItemLength); - - /* Release the memory. */ - _ux_utility_memory_free(start_descriptor); + /* We have found the hid descriptor. Now we should get the HID report descriptor. */ + status = _ux_host_class_hid_report_descriptor_get(hid, hid_descriptor.wItemLength); + + /* No release, the memory will be released after all interface scan done(enumeration done). */ + device -> ux_device_packed_configuration = start_descriptor; + + /* Return completion status. */ + return(status); + } + } - /* Return completion status. */ - return(status); - } - } - - /* Verify if the descriptor is still valid. */ - if (descriptor_length > total_configuration_length) - { + /* Verify if the descriptor is still valid. */ + if (descriptor_length > total_configuration_length) + { - /* Error trap. */ - _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); - /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) - /* Release the memory. */ - _ux_utility_memory_free(start_descriptor); + /* Release the memory. */ + _ux_utility_memory_free(start_descriptor); - /* Return an error. */ - return(UX_DESCRIPTOR_CORRUPTED); - } - - /* Jump to the next descriptor if we have not reached the end. */ - descriptor += descriptor_length; - - /* And adjust the length left to parse in the descriptor. */ - total_configuration_length -= descriptor_length; + /* Return an error. */ + return(UX_DESCRIPTOR_CORRUPTED); } + + /* Jump to the next descriptor if we have not reached the end. */ + descriptor += descriptor_length; + + /* And adjust the length left to parse in the descriptor. */ + total_configuration_length -= descriptor_length; } } @@ -245,10 +239,11 @@ ULONG current_interface; _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, start_descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) /* Free all used resources. */ - _ux_utility_memory_free(start_descriptor); + if (device -> ux_device_packed_configuration == UX_NULL) + _ux_utility_memory_free(start_descriptor); /* Return an error. */ return(UX_DESCRIPTOR_CORRUPTED); diff --git a/common/usbx_host_classes/src/ux_host_class_hid_entry.c b/common/usbx_host_classes/src/ux_host_class_hid_entry.c index 01c23a31..e9fe33ea 100644 --- a/common/usbx_host_classes/src/ux_host_class_hid_entry.c +++ b/common/usbx_host_classes/src/ux_host_class_hid_entry.c @@ -51,7 +51,7 @@ static inline UINT _ux_host_class_hid_activate_wait(UX_HOST_CLASS_COMMAND *comma /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hid_entry PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -92,6 +92,11 @@ static inline UINT _ux_host_class_hid_activate_wait(UX_HOST_CLASS_COMMAND *comma /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed uninited variable, */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hid_entry(UX_HOST_CLASS_COMMAND *command) @@ -186,7 +191,7 @@ UX_HOST_CLASS_HID_CLIENT_COMMAND client_command; #if defined(UX_HOST_STANDALONE) static inline VOID _ux_host_class_hid_descriptor_read(UX_HOST_CLASS_HID *hid) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_CONFIGURATION *configuration; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; @@ -196,8 +201,8 @@ UX_TRANSFER *transfer_request; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; /* Need to allocate memory for the descriptor. */ - interface = hid -> ux_host_class_hid_interface; - configuration = interface -> ux_interface_configuration; + interface_ptr = hid -> ux_host_class_hid_interface; + configuration = interface_ptr -> ux_interface_configuration; hid -> ux_host_class_hid_allocated = _ux_utility_memory_allocate( UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, configuration -> ux_configuration_descriptor.wTotalLength); @@ -355,7 +360,7 @@ UX_TRANSFER *transfer; UCHAR *descriptor; ULONG length; UX_HOST_CLASS_HID_ITEM item; -UINT status; +UINT status = UX_SUCCESS; /* Get transfer. */ device = hid -> ux_host_class_hid_device; @@ -487,15 +492,15 @@ UINT status; static inline UINT _ux_host_class_hid_activate_wait(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer; UX_HOST_CLASS_HID *hid; UINT status; /* Get the instance for this class. */ - interface = (UX_INTERFACE *)command -> ux_host_class_command_container; - hid = (UX_HOST_CLASS_HID *) interface -> ux_interface_class_instance; + interface_ptr = (UX_INTERFACE *)command -> ux_host_class_command_container; + hid = (UX_HOST_CLASS_HID *) interface_ptr -> ux_interface_class_instance; /* Run initialize state machine. */ switch(hid -> ux_host_class_hid_enum_state) @@ -579,7 +584,7 @@ UINT status; _ux_host_stack_class_instance_destroy(hid -> ux_host_class_hid_class, (VOID *) hid); /* Unmount instance. */ - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr -> ux_interface_class_instance = UX_NULL; /* Free memory. */ if (hid -> ux_host_class_hid_allocated) diff --git a/common/usbx_host_classes/src/ux_host_class_hid_interrupt_endpoint_search.c b/common/usbx_host_classes/src/ux_host_class_hid_interrupt_endpoint_search.c index 96770dad..1651cbec 100644 --- a/common/usbx_host_classes/src/ux_host_class_hid_interrupt_endpoint_search.c +++ b/common/usbx_host_classes/src/ux_host_class_hid_interrupt_endpoint_search.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hid_interrupt_endpoint_search PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,20 +75,24 @@ /* added interrupt OUT support,*/ /* added timeout initialize, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hid_interrupt_endpoint_search(UX_HOST_CLASS_HID *hid) { UINT status = UX_ENDPOINT_HANDLE_UNKNOWN; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *endpoint; UX_TRANSFER *transfer_request; /* Search the interrupt endpoint. It is attached to the interface container. */ - interface = hid -> ux_host_class_hid_interface; - endpoint = interface -> ux_interface_first_endpoint; + interface_ptr = hid -> ux_host_class_hid_interface; + endpoint = interface_ptr -> ux_interface_first_endpoint; while(endpoint != UX_NULL) { diff --git a/common/usbx_host_classes/src/ux_host_class_hid_report_set_run.c b/common/usbx_host_classes/src/ux_host_class_hid_report_set_run.c index a89fbf91..6d6edf9e 100644 --- a/common/usbx_host_classes/src/ux_host_class_hid_report_set_run.c +++ b/common/usbx_host_classes/src/ux_host_class_hid_report_set_run.c @@ -42,7 +42,7 @@ extern UINT ux_host_class_hid_report_set_buffer_allocate( /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hid_report_set_run PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,9 @@ extern UINT ux_host_class_hid_report_set_buffer_allocate( /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added interrupt OUT support,*/ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS_HID_CLIENT_REPORT *client_report) @@ -129,9 +132,23 @@ UINT status; return(UX_STATE_EXIT); } - /* We need to get the default control endpoint transfer request pointer. */ - control_endpoint = &device -> ux_device_control_endpoint; - transfer_request = &control_endpoint -> ux_endpoint_transfer_request; +#if defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT) + + /* Check if there is an interrupt OUT endpoint. */ + if (hid -> ux_host_class_hid_interrupt_out_endpoint != UX_NULL) + { + + /* Transfer the report by using the interrupt OUT endpoint. */ + transfer_request = &hid -> ux_host_class_hid_interrupt_out_endpoint -> ux_endpoint_transfer_request; + } + else +#endif + { + + /* We need to get the default control endpoint transfer request pointer. */ + control_endpoint = &device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + } /* Waiting transfer done. */ if (hid -> ux_host_class_hid_cmd_state == UX_STATE_WAIT) diff --git a/common/usbx_host_classes/src/ux_host_class_hub_activate.c b/common/usbx_host_classes/src/ux_host_class_hub_activate.c index 4707578a..e8a9bac3 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -84,6 +84,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hub_activate(UX_HOST_CLASS_COMMAND *command) @@ -113,13 +116,32 @@ UINT status; /* Store the class container into this instance. */ hub -> ux_host_class_hub_class = command -> ux_host_class_command_class_ptr; - /* Store the class container into this instance. */ - hub -> ux_host_class_hub_class = command -> ux_host_class_command_class_ptr; - /* Store the device container instance in the HUB instance, this is for the class instance when it needs to talk to the USBX stack. */ hub -> ux_host_class_hub_device = device; +#if defined(UX_HOST_STANDALONE) + + /* Store the instance in the device container, this is for the USBX stack + when it needs to invoke the class. */ + device -> ux_device_class_instance = (VOID *) hub; + + /* Store the hub interface. */ + hub -> ux_host_class_hub_interface = device -> + ux_device_first_configuration -> ux_configuration_first_interface; + + /* Store the class task function. */ + hub -> ux_host_class_hub_class -> ux_host_class_task_function = _ux_host_class_hub_tasks_run; + + /* During activation and tasks, control transfer is used for requests. */ + hub -> ux_host_class_hub_transfer = &device -> ux_device_control_endpoint.ux_endpoint_transfer_request; + + /* The HUB is configured and activated in ACTIVATE_WAIT. */ + hub -> ux_host_class_hub_run_status = UX_SUCCESS; + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_GET_STATUS; + status = UX_SUCCESS; +#else + /* Configure the HUB. */ status = _ux_host_class_hub_configure(hub); if (status == UX_SUCCESS) @@ -175,7 +197,8 @@ UINT status; /* If trace is enabled, register this object. */ UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, hub, 0, 0, 0) +#endif + /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_hub_change_detect.c b/common/usbx_host_classes/src/ux_host_class_hub_change_detect.c index a2b4bcc5..2e34cb4e 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_change_detect.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_change_detect.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_change_detect PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,9 @@ /* */ /* This function is called by the enumeration thread when there has */ /* been activity on the HUB. */ +/* */ +/* In standalone mode there is nothing to do here, activities are */ +/* processed in hub tasks function. */ /* */ /* INPUT */ /* */ @@ -70,10 +73,17 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_host_class_hub_change_detect(VOID) { +#if defined(UX_HOST_STANDALONE) + + /* Things are done in hub task nothing to do here. */ +#else UX_HOST_CLASS *class; UX_HOST_CLASS_HUB *hub; @@ -116,5 +126,5 @@ UINT class_index; /* We have parsed all the HUB instances. */ return; +#endif } - diff --git a/common/usbx_host_classes/src/ux_host_class_hub_deactivate.c b/common/usbx_host_classes/src/ux_host_class_hub_deactivate.c index 68a45b07..c64859a8 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_deactivate.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_deactivate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_deactivate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -81,6 +81,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hub_deactivate(UX_HOST_CLASS_COMMAND *command) @@ -121,9 +124,6 @@ UINT port_index; it must be freed. First get the transfer request. */ transfer_request = &hub -> ux_host_class_hub_interrupt_endpoint -> ux_endpoint_transfer_request; - /* Abort the data transfer on the interrupt endpoint. */ - _ux_host_stack_endpoint_transfer_abort(hub -> ux_host_class_hub_interrupt_endpoint); - /* The enumeration thread needs to sleep a while to allow the application or the class that may be using endpoints to exit properly. */ _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM); @@ -131,6 +131,11 @@ UINT port_index; /* Then de allocate the memory. */ _ux_utility_memory_free(transfer_request -> ux_transfer_request_data_pointer); +#if defined(UX_HOST_STANDALONE) + if (hub -> ux_host_class_hub_allocated) + _ux_utility_memory_free(hub -> ux_host_class_hub_allocated); +#endif + /* Destroy the instance. */ _ux_host_stack_class_instance_destroy(hub -> ux_host_class_hub_class, (VOID *) hub); diff --git a/common/usbx_host_classes/src/ux_host_class_hub_descriptor_get.c b/common/usbx_host_classes/src/ux_host_class_hub_descriptor_get.c index 115bc6c6..d1584543 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_descriptor_get.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_descriptor_get.c @@ -30,12 +30,106 @@ #include "ux_host_stack.h" +#if UX_MAX_DEVICES > 1 + +#if defined(UX_HOST_STANDALONE) +UINT _ux_host_class_hub_descriptor_parse(UX_HOST_CLASS_HUB *hub, UCHAR *descriptor); +UINT +#else +static inline UINT +#endif +_ux_host_class_hub_descriptor_parse(UX_HOST_CLASS_HUB *hub, UCHAR *descriptor) +{ +UINT status = UX_SUCCESS; +ULONG tt_protocols; /* (bDeviceProtocol << 8) | bInterfaceProtocol */ +ULONG port_index; + + /* Parse the device descriptor and create the local descriptor. */ + _ux_utility_descriptor_parse(descriptor, _ux_system_hub_descriptor_structure, UX_HUB_DESCRIPTOR_ENTRIES, + (UCHAR *) &hub -> ux_host_class_hub_descriptor); + + /* Check the protocol used by the HUB. This will indicate if the HUB supports multiple TTs in high speed mode. */ + tt_protocols = (hub -> ux_host_class_hub_device -> ux_device_descriptor.bDeviceProtocol << 8) | + hub -> ux_host_class_hub_interface -> ux_interface_descriptor.bInterfaceProtocol; + switch(tt_protocols) + { + + /* 1. A hub operating at full-/low-speed has a device descriptor with a bDeviceProtocol field set to zero(0) + * and an interface descriptor with a bInterfaceProtocol field set to zero(0). + */ + case (UX_HOST_CLASS_HUB_PROTOCOL_FS << 8): + + /* In the case of full speed hub, there are no TTs to declare */ + break; + + /* 2. A hub that has a single TT must set the bDeviceProtocol field of the device descriptor to one(1) and + * the interface descriptor bInterfaceProtocol field set to 0. + * 3. A multiple TT hub must set the bDeviceProtocol field of the device descriptor to two (2). + * The first interface descriptor has the bInterfaceProtocol field set to one(1). + */ + case (UX_HOST_CLASS_HUB_PROTOCOL_SINGLE_TT << 8): /* Fall through. */ + case (UX_HOST_CLASS_HUB_PROTOCOL_MULTIPLE_TT << 8) | UX_HOST_CLASS_HUB_PROTOCOL_SINGLE_TT: + + /* Single TT hub or single TT interface. */ + /* Check if current setting supports this Hub. */ + if (hub -> ux_host_class_hub_descriptor.bNbPorts > UX_MAX_TT) + { + + status = UX_TOO_MANY_HUB_PORTS; + break; + } + + /* In a single TT state, all the downstream ports report to the same + TT and share the 1.1 USB segment bandwidth. This is a very crude + but working method, we simply set all the ports bits to the first + TT. */ + hub -> ux_host_class_hub_device -> ux_device_hub_tt[0].ux_hub_tt_port_mapping = UX_TT_MASK; + hub -> ux_host_class_hub_device -> ux_device_hub_tt[0].ux_hub_tt_max_bandwidth = UX_TT_BANDWIDTH; + break; + + /* 3. A multiple TT hub must set the bDeviceProtocol field of the device descriptor to two (2). + * The first interface descriptor has the bInterfaceProtocol field set to one(1). + * Such a hub also has a second interface descriptor where the bInterfaceProtocol is set to two(2). + */ + case (UX_HOST_CLASS_HUB_PROTOCOL_MULTIPLE_TT << 8) | UX_HOST_CLASS_HUB_PROTOCOL_MULTIPLE_TT: + + /* Multiple TTs. */ + /* Check if current setting supports this Hub. */ + if (hub -> ux_host_class_hub_descriptor.bNbPorts > UX_MAX_TT) + { + + status = UX_TOO_MANY_HUB_PORTS; + break; + } + + /* In the case of multiple TTs, each downstream port can sustain the USB 1.1 + max bandwidth and therefore we allocate one TT per port with that bandwidth. */ + for (port_index = 0; port_index < hub -> ux_host_class_hub_descriptor.bNbPorts; port_index++) + { + + hub -> ux_host_class_hub_device -> ux_device_hub_tt[port_index].ux_hub_tt_port_mapping = (ULONG)(1 << port_index); + hub -> ux_host_class_hub_device -> ux_device_hub_tt[port_index].ux_hub_tt_max_bandwidth = UX_TT_BANDWIDTH; + } + break; + + default: /* Invalid bDeviceProtocol and bInterfaceProtocol pair. */ + + /* We should never get here. In this case the protocol value of the HUB is illegal. */ + status = UX_DESCRIPTOR_CORRUPTED; + } + + /* Return status. */ + return(status); +} +#endif + + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_descriptor_get PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,6 +171,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* improved protocol handling, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hub_descriptor_get(UX_HOST_CLASS_HUB *hub) @@ -86,10 +183,6 @@ UCHAR *descriptor; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; UINT status; -#if UX_MAX_DEVICES > 1 -ULONG tt_protocols; /* (bDeviceProtocol << 8) | bInterfaceProtocol */ -ULONG port_index; -#endif /* We need to get the default control endpoint transfer request pointer. */ @@ -109,6 +202,17 @@ ULONG port_index; transfer_request -> ux_transfer_request_value = (UX_HUB_DESCRIPTOR_ITEM << 8); transfer_request -> ux_transfer_request_index = 0; +#if defined(UX_HOST_STANDALONE) + + /* Save allocated buffer pointer. */ + hub -> ux_host_class_hub_allocated = descriptor; + + /* Link to running transfer. */ + UX_TRANSFER_STATE_RESET(transfer_request); + hub -> ux_host_class_hub_transfer = transfer_request; + status = UX_SUCCESS; +#else + /* Send request to HCD layer. */ status = _ux_host_stack_transfer_request(transfer_request); @@ -121,98 +225,17 @@ ULONG port_index; { #if UX_MAX_DEVICES > 1 - /* Parse the device descriptor and create the local descriptor. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_hub_descriptor_structure, UX_HUB_DESCRIPTOR_ENTRIES, - (UCHAR *) &hub -> ux_host_class_hub_descriptor); - - /* Check the protocol used by the HUB. This will indicate if the HUB supports multiple TTs in high speed mode. */ - tt_protocols = (hub -> ux_host_class_hub_device -> ux_device_descriptor.bDeviceProtocol << 8) | - hub -> ux_host_class_hub_interface -> ux_interface_descriptor.bInterfaceProtocol; - switch(tt_protocols) + status = _ux_host_class_hub_descriptor_parse(hub, descriptor); + if (status != UX_SUCCESS) { - /* 1. A hub operating at full-/low-speed has a device descriptor with a bDeviceProtocol field set to zero(0) - * and an interface descriptor with a bInterfaceProtocol field set to zero(0). - */ - case (UX_HOST_CLASS_HUB_PROTOCOL_FS << 8): - - /* In the case of full speed hub, there are no TTs to declare */ - break; - - /* 2. A hub that has a single TT must set the bDeviceProtocol field of the device descriptor to one(1) and - * the interface descriptor bInterfaceProtocol field set to 0. - * 3. A multiple TT hub must set the bDeviceProtocol field of the device descriptor to two (2). - * The first interface descriptor has the bInterfaceProtocol field set to one(1). - */ - case (UX_HOST_CLASS_HUB_PROTOCOL_SINGLE_TT << 8): /* Fall through. */ - case (UX_HOST_CLASS_HUB_PROTOCOL_MULTIPLE_TT << 8) | UX_HOST_CLASS_HUB_PROTOCOL_SINGLE_TT: - - /* Single TT hub or single TT interface. */ - /* Check if current setting supports this Hub. */ - if (hub -> ux_host_class_hub_descriptor.bNbPorts > UX_MAX_TT) - { - - /* Error trap. */ - _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HUB, UX_TOO_MANY_HUB_PORTS); - - /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TOO_MANY_HUB_PORTS, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) - - status = UX_TOO_MANY_HUB_PORTS; - break; - } - - /* In a single TT state, all the downstream ports report to the same - TT and share the 1.1 USB segment bandwidth. This is a very crude - but working method, we simply set all the ports bits to the first - TT. */ - hub -> ux_host_class_hub_device -> ux_device_hub_tt[0].ux_hub_tt_port_mapping = UX_TT_MASK; - hub -> ux_host_class_hub_device -> ux_device_hub_tt[0].ux_hub_tt_max_bandwidth = UX_TT_BANDWIDTH; - break; - - /* 3. A multiple TT hub must set the bDeviceProtocol field of the device descriptor to two (2). - * The first interface descriptor has the bInterfaceProtocol field set to one(1). - * Such a hub also has a second interface descriptor where the bInterfaceProtocol is set to two(2). - */ - case (UX_HOST_CLASS_HUB_PROTOCOL_MULTIPLE_TT << 8) | UX_HOST_CLASS_HUB_PROTOCOL_MULTIPLE_TT: - - /* Multiple TTs. */ - /* Check if current setting supports this Hub. */ - if (hub -> ux_host_class_hub_descriptor.bNbPorts > UX_MAX_TT) - { - - /* Error trap. */ - _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HUB, UX_TOO_MANY_HUB_PORTS); - - /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TOO_MANY_HUB_PORTS, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) - - status = UX_TOO_MANY_HUB_PORTS; - break; - } - - /* In the case of multiple TTs, each downstream port can sustain the USB 1.1 - max bandwidth and therefore we allocate one TT per port with that bandwidth. */ - for (port_index = 0; port_index < hub -> ux_host_class_hub_descriptor.bNbPorts; port_index++) - { - - hub -> ux_host_class_hub_device -> ux_device_hub_tt[port_index].ux_hub_tt_port_mapping = (ULONG)(1 << port_index); - hub -> ux_host_class_hub_device -> ux_device_hub_tt[port_index].ux_hub_tt_max_bandwidth = UX_TT_BANDWIDTH; - } - break; - - default: /* Invalid bDeviceProtocol and bInterfaceProtocol pair. */ - /* Error trap. */ - _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HUB, UX_DESCRIPTOR_CORRUPTED); + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HUB, status); /* If trace is enabled, insert this event into the trace buffer. */ - UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) - - /* We should never get here. In this case the protocol value of the HUB is illegal. */ - status = UX_DESCRIPTOR_CORRUPTED; + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, status, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) } -#endif /* #if UX_MAX_DEVICES > 1 */ +#endif } else { @@ -230,6 +253,7 @@ ULONG port_index; /* Free the memory for the descriptor. */ _ux_utility_memory_free(descriptor); +#endif /* Return completion status. */ return(status); diff --git a/common/usbx_host_classes/src/ux_host_class_hub_entry.c b/common/usbx_host_classes/src/ux_host_class_hub_entry.c index d6fbccbf..abc47704 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_entry.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_entry.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** HUB Class */ /** */ @@ -30,48 +30,57 @@ #include "ux_host_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_hub_entry PORTABLE C */ -/* 6.1 */ +#if defined(UX_HOST_STANDALONE) +extern UINT _ux_host_class_hub_descriptor_parse(UX_HOST_CLASS_HUB *hub, UCHAR *descriptor); +static inline UINT _ux_host_class_hub_activate_wait(UX_HOST_CLASS_COMMAND *command); +#endif + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_hub_entry PORTABLE C */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function is the entry point of the HUB class. It will be */ -/* called by the USBX stack enumeration module when there is a new */ -/* device on the bus or when there is a device extraction. */ -/* */ -/* INPUT */ -/* */ -/* command Pointer to command */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ -/* _ux_host_class_hub_activate Activate HUB class */ -/* _ux_host_class_hub_deactivate Deactivate HUB class */ -/* */ -/* CALLED BY */ -/* */ -/* Host Stack */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* This function is the entry point of the HUB class. It will be */ +/* called by the USBX stack enumeration module when there is a new */ +/* device on the bus or when there is a device extraction. */ +/* */ +/* INPUT */ +/* */ +/* command Pointer to command */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_class_hub_activate Activate HUB class */ +/* _ux_host_class_hub_deactivate Deactivate HUB class */ +/* */ +/* CALLED BY */ +/* */ +/* Host Stack */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* used query usage of device */ /* ClassSubclassProtocol, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1 */ /* */ /**************************************************************************/ UINT _ux_host_class_hub_entry(UX_HOST_CLASS_COMMAND *command) @@ -91,11 +100,11 @@ UINT status; this device or not. */ if ((command -> ux_host_class_command_usage == UX_HOST_CLASS_COMMAND_USAGE_DCSP) && (command -> ux_host_class_command_class == UX_HOST_CLASS_HUB_CLASS)) - return(UX_SUCCESS); - else - return(UX_NO_CLASS_MATCH); - - + return(UX_SUCCESS); + else + return(UX_NO_CLASS_MATCH); + + case UX_HOST_CLASS_COMMAND_ACTIVATE: /* The activate command is used when the device inserted has found a parent and @@ -105,10 +114,15 @@ UINT status; /* Return completion status. */ return(status); +#if defined(UX_HOST_STANDALONE) + case UX_HOST_CLASS_COMMAND_ACTIVATE_WAIT: + status = _ux_host_class_hub_activate_wait(command); + return(status); +#endif case UX_HOST_CLASS_COMMAND_DEACTIVATE: - /* The deactivate command is used when the device has been extracted either + /* The deactivate command is used when the device has been extracted either directly or when its parents has been extracted */ status = _ux_host_class_hub_deactivate(command); @@ -125,5 +139,358 @@ UINT status; /* Return error status. */ return(UX_FUNCTION_NOT_SUPPORTED); - } + } +} + +#if defined(UX_HOST_STANDALONE) +#define UX_HOST_STACK_ENUM_TRANS_ERROR(t) ( \ + (t)->ux_transfer_request_completion_code != UX_SUCCESS || \ + (t)->ux_transfer_request_actual_length != \ + (t)->ux_transfer_request_requested_length) + +static inline UINT _ux_host_class_hub_enum_get_status(UX_HOST_CLASS_HUB *hub, UX_TRANSFER *trans) +{ + hub -> ux_host_class_hub_allocated = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, 2); + if (hub -> ux_host_class_hub_allocated == UX_NULL) + return(UX_MEMORY_INSUFFICIENT); + + trans -> ux_transfer_request_requested_length = 2; + trans -> ux_transfer_request_data_pointer = hub -> ux_host_class_hub_allocated; + trans -> ux_transfer_request_function = UX_GET_STATUS; + trans -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; + trans -> ux_transfer_request_value = 0; + trans -> ux_transfer_request_index = 0; + return(UX_SUCCESS); +} +static inline VOID _ux_host_class_hub_enum_set_config(UX_HOST_CLASS_HUB *hub, UX_TRANSFER *trans, UX_CONFIGURATION *configuration) +{ + UX_PARAMETER_NOT_USED(hub); + trans -> ux_transfer_request_requested_length = 0; + trans -> ux_transfer_request_function = UX_SET_CONFIGURATION; + trans -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; + trans -> ux_transfer_request_value = (USHORT) configuration -> ux_configuration_descriptor.bConfigurationValue; + trans -> ux_transfer_request_index = 0; +} +static inline UINT _ux_host_class_hub_activate_wait(UX_HOST_CLASS_COMMAND *command) +{ +UX_DEVICE *device; +UX_ENDPOINT *ep0; +UX_TRANSFER *trans0, *trans; +UX_HOST_CLASS_HUB *hub; +UINT status; +ULONG current_ms, elapsed_ms; + + /* Get the instance for this class. */ + device = (UX_DEVICE *)command -> ux_host_class_command_container; + hub = (UX_HOST_CLASS_HUB *) device -> ux_device_class_instance; + + /* Get endpoint 0 and transfer request. */ + ep0 = &device -> ux_device_control_endpoint; + trans0 = &ep0 -> ux_endpoint_transfer_request; + + /* Get current transfer request. */ + trans = hub -> ux_host_class_hub_transfer; + + /* Immediate state change: continue. + Wait/pending state : return. */ + while(1) + { + + /* Run initialize state machine. */ + switch(hub -> ux_host_class_hub_enum_state) + { + + case UX_HOST_CLASS_HUB_ENUM_GET_STATUS : + status = _ux_host_class_hub_enum_get_status(hub, trans0); + if (status != UX_SUCCESS) + { + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + hub -> ux_host_class_hub_run_status = status; + continue; + } + + UX_TRANSFER_STATE_RESET(trans0); + hub -> ux_host_class_hub_transfer = trans0; + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_ENUM_POWER_CHECK; + continue; + + case UX_HOST_CLASS_HUB_ENUM_POWER_CHECK : + + /* Transfer request error check. */ + if (UX_HOST_STACK_ENUM_TRANS_ERROR(trans)) + { + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + hub -> ux_host_class_hub_run_status = UX_CONNECTION_INCOMPATIBLE; + continue; + } + + /* Save power source setting. */ + if (hub -> ux_host_class_hub_allocated[0] & UX_STATUS_DEVICE_SELF_POWERED) + device -> ux_device_power_source = UX_DEVICE_SELF_POWERED; + else + device -> ux_device_power_source = UX_DEVICE_BUS_POWERED; + + /* Free allocated buffer. */ + _ux_utility_memory_free(hub -> ux_host_class_hub_allocated); + hub -> ux_host_class_hub_allocated = UX_NULL; + +#if UX_MAX_DEVICES > 1 + + /* Check the HUB power source and check the parent power source. */ + if (device -> ux_device_power_source == UX_DEVICE_BUS_POWERED) + { + + /* Check parent power. */ + if (device -> ux_device_parent != UX_NULL) + { + if (device -> ux_device_parent -> ux_device_power_source == UX_DEVICE_BUS_POWERED) + { + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + hub -> ux_host_class_hub_run_status = UX_CONNECTION_INCOMPATIBLE; + continue; + } + } + } +#endif + /* Fall through. */ + case UX_HOST_CLASS_HUB_ENUM_SET_CONFIG : + _ux_host_class_hub_enum_set_config(hub, trans0, + device -> ux_device_first_configuration); + + UX_TRANSFER_STATE_RESET(trans0); + hub -> ux_host_class_hub_transfer = trans0; + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_ENUM_SET_CONFIG_DONE; + continue; + + case UX_HOST_CLASS_HUB_ENUM_SET_CONFIG_DONE : + + /* Transfer request error check. */ + if (UX_HOST_STACK_ENUM_TRANS_ERROR(trans)) + { + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + hub -> ux_host_class_hub_run_status = UX_CONNECTION_INCOMPATIBLE; + continue; + } + + /* Create configuration instance. */ + status = _ux_host_stack_configuration_instance_create(device -> ux_device_first_configuration); + if (status != UX_SUCCESS) + { + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + hub -> ux_host_class_hub_run_status = status; + continue; + } + + /* Change device state. */ + device -> ux_device_state = UX_DEVICE_CONFIGURED; + device -> ux_device_current_configuration = device -> ux_device_first_configuration; + + /* Fall through. */ + case UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC : + status = _ux_host_class_hub_descriptor_get(hub); + if (UX_SUCCESS != status) + { + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + hub -> ux_host_class_hub_run_status = status; + continue; + } + + /* Request already updated, to transfer state. */ + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC_DONE; + continue; + + case UX_HOST_CLASS_HUB_ENUM_GET_HUB_DESC_DONE: + + /* Transfer request error check. */ + if (UX_HOST_STACK_ENUM_TRANS_ERROR(trans)) + { + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + hub -> ux_host_class_hub_run_status = UX_DESCRIPTOR_CORRUPTED; + continue; + } + + /* Parse descriptor. */ + status = _ux_host_class_hub_descriptor_parse(hub, hub -> ux_host_class_hub_allocated); + if (status != UX_SUCCESS) + { + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + hub -> ux_host_class_hub_run_status = status; + continue; + } + + /* Free the allocated descriptor. */ + _ux_utility_memory_free(hub -> ux_host_class_hub_allocated); + hub -> ux_host_class_hub_allocated = UX_NULL; + + /* Initialize for port power ON. */ + hub -> ux_host_class_hub_run_port = 1; + + /* Fall through. */ + case UX_HOST_CLASS_HUB_ENUM_PORT_POWER : + + /* Prepare for SetPortFeature(POWER). */ + status = _ux_host_class_hub_feature(hub, + hub -> ux_host_class_hub_run_port, + UX_SET_FEATURE, UX_HOST_CLASS_HUB_PORT_POWER); + + /* Request already updated, to transfer state. */ + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_ENUM_PORT_POWER_DELAY; + continue; + + case UX_HOST_CLASS_HUB_ENUM_PORT_POWER_DELAY : + + /* Transfer request error check. */ + if (UX_HOST_STACK_ENUM_TRANS_ERROR(trans)) + { + + /* Set the HUB status to not powered. */ + hub -> ux_host_class_hub_port_power &= + (UINT)~(1u << hub -> ux_host_class_hub_run_port); + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_PORT_NEXT; + continue; + } + + /* Delay a while (as described by hub descriptor). */ + hub -> ux_host_class_hub_wait_start = _ux_utility_time_get(); + hub -> ux_host_class_hub_wait_ms = hub -> ux_host_class_hub_descriptor.bPwrOn2PwrGood; + + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_ENUM_PORT_POWER_ON; + continue; + + case UX_HOST_CLASS_HUB_ENUM_PORT_POWER_ON: + hub -> ux_host_class_hub_port_power |= (UINT)(1u << hub -> ux_host_class_hub_run_port); + + /* Fall through. */ + case UX_HOST_CLASS_HUB_ENUM_PORT_NEXT : + + /* Check if the last port is powered. */ + if (hub -> ux_host_class_hub_run_port < + hub -> ux_host_class_hub_descriptor.bNbPorts) + { + + /* Start another port power. */ + hub -> ux_host_class_hub_run_port ++; + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_PORT_POWER; + continue; + } + + /* All port is powered. */ + + /* Fall through. */ + case UX_HOST_CLASS_HUB_ENUM_INTERRUPT_START : + status = _ux_host_class_hub_interrupt_endpoint_start(hub); + if (status != UX_SUCCESS) + hub -> ux_host_class_hub_run_status = status; + + /* Fall through. */ + case UX_HOST_CLASS_HUB_ENUM_DONE : + + /* Free buffer allocated while enumerating. */ + if (hub -> ux_host_class_hub_allocated) + { + _ux_utility_memory_free(hub -> ux_host_class_hub_allocated); + hub -> ux_host_class_hub_allocated = UX_NULL; + } + + /* Error cases. */ + if (hub -> ux_host_class_hub_run_status != UX_SUCCESS) + { + + /* Unlink from device. */ + device -> ux_device_class_instance = UX_NULL; + + /* Free hub. */ + _ux_utility_memory_free(hub); + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, hub -> ux_host_class_hub_run_status); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, hub -> ux_host_class_hub_run_status, hub, 0, 0, UX_TRACE_ERRORS, 0, 0) + + /* To error state. */ + hub -> ux_host_class_hub_enum_state = UX_STATE_ERROR; + return(UX_STATE_ERROR); + } + + /* Done success. */ + + /* Create this class instance. */ + _ux_host_stack_class_instance_create(hub -> ux_host_class_hub_class, (VOID *) hub); + + /* Store the instance in the device container, this is for the USBX stack + when it needs to invoke the class. */ + device -> ux_device_class_instance = (VOID *) hub; + + /* Mark the HUB as live now. */ + hub -> ux_host_class_hub_state = UX_HOST_CLASS_INSTANCE_LIVE; + + /* If all is fine and the device is mounted, we may need to inform the application + if a function has been programmed in the system structure. */ + if (_ux_system_host -> ux_system_host_change_function != UX_NULL) + { + + /* Call system change function. */ + _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, hub -> ux_host_class_hub_class, (VOID *) hub); + } + + /* Next state: CHANGE_CHECK. */ + hub -> ux_host_class_hub_enum_state = UX_STATE_IDLE; + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_CHANGE_CHECK; + hub -> ux_host_class_hub_run_port = 0; + + /* Done activate. */ + return(UX_STATE_NEXT); + + case UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT: + + /* Poll transfer task. */ + status = _ux_host_stack_transfer_run(hub -> ux_host_class_hub_transfer); + hub -> ux_host_class_hub_run_status = hub -> ux_host_class_hub_transfer -> + ux_transfer_request_completion_code; + + /* Transfer done - next state. */ + if (status == UX_STATE_NEXT || status == UX_STATE_IDLE) + { + hub -> ux_host_class_hub_enum_state = hub -> ux_host_class_hub_next_state; + continue; + } + + /* Check error. */ + if (status < UX_STATE_NEXT) + { + + /* Fail. */ + hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_DONE; + continue; + } + + /* Transfer in progress, wait. */ + return(UX_STATE_WAIT); + + case UX_HOST_CLASS_HUB_ENUM_DELAY_WAIT: + current_ms = _ux_utility_time_get(); + elapsed_ms = _ux_utility_time_elapsed(current_ms, + hub -> ux_host_class_hub_wait_start); + if (elapsed_ms < hub -> ux_host_class_hub_wait_ms) + { + + /* Keep waiting. */ + return(UX_STATE_WAIT); + } + + /* Next state. */ + hub -> ux_host_class_hub_enum_state = hub -> ux_host_class_hub_next_state; + continue; + + default: + return(UX_STATE_NEXT); + } + } } +#endif diff --git a/common/usbx_host_classes/src/ux_host_class_hub_feature.c b/common/usbx_host_classes/src/ux_host_class_hub_feature.c index 1e739793..5c429a5b 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_feature.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_feature.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_feature PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,10 @@ /* */ /* This function will send a command to the HUB on a specific port. */ /* The commands can be SET_FEATURE or CLEAR_FEATURE. */ +/* */ +/* In standalone mode, this functioin prepares the control transfer */ +/* request context of specific command, for host stack transfer */ +/* function to process, in next steps. */ /* */ /* INPUT */ /* */ @@ -71,6 +75,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hub_feature(UX_HOST_CLASS_HUB *hub, UINT port, UINT command, UINT function) @@ -99,10 +106,17 @@ UINT status; transfer_request -> ux_transfer_request_value = function; transfer_request -> ux_transfer_request_index = port; +#if defined(UX_HOST_STANDALONE) + + /* Reset transfer state for _run. */ + UX_TRANSFER_STATE_RESET(transfer_request); + status = UX_SUCCESS; +#else + /* Send request to HCD layer. */ status = _ux_host_stack_transfer_request(transfer_request); - +#endif + /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_hub_interrupt_endpoint_start.c b/common/usbx_host_classes/src/ux_host_class_hub_interrupt_endpoint_start.c index fd08cfa8..7dc5b6f0 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_interrupt_endpoint_start.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_interrupt_endpoint_start.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_interrupt_endpoint_start PORTABLE C */ -/* 6.1.9 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,6 +77,9 @@ /* use pre-calculated value */ /* instead of wMaxPacketSize, */ /* resulting in version 6.1.9 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added timeout value init, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hub_interrupt_endpoint_start(UX_HOST_CLASS_HUB *hub) @@ -103,6 +106,9 @@ UX_TRANSFER *transfer_request; transfer_request -> ux_transfer_request_requested_length = transfer_request -> ux_transfer_request_packet_length; transfer_request -> ux_transfer_request_actual_length = 0; + /* Set timeout - wait forever. */ + transfer_request -> ux_transfer_request_timeout_value = UX_WAIT_FOREVER; + /* Since this transfer_request has a callback, we need the HUB instance to be stored in the transfer request. */ transfer_request -> ux_transfer_request_class_instance = (VOID *) hub; diff --git a/common/usbx_host_classes/src/ux_host_class_hub_port_change_connection_process.c b/common/usbx_host_classes/src/ux_host_class_hub_port_change_connection_process.c index db704f89..7e9897fa 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_port_change_connection_process.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_port_change_connection_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_port_change_connection_process PORTABLE C */ -/* 6.1.4 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -85,19 +85,24 @@ /* added disconnection check */ /* in enumeration retries, */ /* resulting in version 6.1.4 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_host_class_hub_port_change_connection_process(UX_HOST_CLASS_HUB *hub, UINT port, UINT port_status) { +UX_HCD *hcd; +#if !defined(UX_HOST_STANDALONE) UX_DEVICE *device = UX_NULL; UINT device_speed; UINT device_enumeration_retry; USHORT port_power; UINT status; -UX_HCD *hcd; USHORT local_port_status; USHORT local_port_change; +#endif /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_HUB_PORT_CHANGE_CONNECTION_PROCESS, hub, port, port_status, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) @@ -117,14 +122,18 @@ USHORT local_port_change; { /* There was a device attached previously. Perform a removal. */ - status = _ux_host_stack_device_remove(hcd, hub -> ux_host_class_hub_device, port); + _ux_host_stack_device_remove(hcd, hub -> ux_host_class_hub_device, port); } else /* Mark device connection. */ hub -> ux_host_class_hub_port_state |= (UINT)(1 << port); - + +#if defined(UX_HOST_STANDALONE) + /* Port operations are done outside. */ +#else + /* Tell the hub to clear the change bit for this port so that we do not process the same change event again. */ _ux_host_class_hub_feature(hub, port, UX_CLEAR_FEATURE, UX_HOST_CLASS_HUB_C_PORT_CONNECTION); @@ -235,6 +244,7 @@ USHORT local_port_change; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DEVICE_ENUMERATION_FAILURE, port, 0, 0, UX_TRACE_ERRORS, 0, 0) +#endif } else { @@ -246,9 +256,13 @@ USHORT local_port_change; hub -> ux_host_class_hub_port_state &= (UINT)~(1 << port); /* We get here when there is a device extraction. */ - status = _ux_host_stack_device_remove(hcd, hub -> ux_host_class_hub_device, port); + _ux_host_stack_device_remove(hcd, hub -> ux_host_class_hub_device, port); } +#if defined(UX_HOST_STANDALONE) + /* Port operations are done outside. */ +#else + /* The port should be disabled now. Power is still applied. */ status = _ux_host_class_hub_feature(hub, port, UX_CLEAR_FEATURE, UX_HOST_CLASS_HUB_PORT_ENABLE); @@ -257,6 +271,7 @@ USHORT local_port_change; /* We must clear the connection change condition so that we don't get awaken again. */ _ux_host_class_hub_feature(hub, port, UX_CLEAR_FEATURE, UX_HOST_CLASS_HUB_C_PORT_CONNECTION); +#endif } /* Return to caller. */ diff --git a/common/usbx_host_classes/src/ux_host_class_hub_status_get.c b/common/usbx_host_classes/src/ux_host_class_hub_status_get.c index d942346c..abf84d9e 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_status_get.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_status_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_status_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,11 @@ /* */ /* This function will do a GET_STATUS from the HUB. This function */ /* retrieves the current status and the changed bits. */ +/* */ +/* In standalone mode, this functioin prepares the control transfer */ +/* request data memory and request context of specific command, for */ +/* host stack transfer function to process, in next steps. The */ +/* allocated memory must be freed after transfer request is processed. */ /* */ /* INPUT */ /* */ @@ -74,12 +79,15 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_hub_status_get(UX_HOST_CLASS_HUB *hub, UINT port, USHORT *port_status, USHORT *port_change) { -UCHAR *port_data; +UCHAR *port_data; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; UINT target; @@ -95,7 +103,7 @@ UINT status; target = UX_REQUEST_TARGET_DEVICE; else target = UX_REQUEST_TARGET_OTHER; - + /* Allocate a buffer for the port status and change: 2 words. */ port_data = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4); if(port_data == UX_NULL) @@ -109,6 +117,20 @@ UINT status; transfer_request -> ux_transfer_request_value = 0; transfer_request -> ux_transfer_request_index = port; +#if defined(UX_HOST_STANDALONE) + + /* No status change change copy. */ + UX_PARAMETER_NOT_USED(port_status); + UX_PARAMETER_NOT_USED(port_change); + + /* Save allocated buffer. */ + hub -> ux_host_class_hub_allocated = port_data; + + /* Reset transfer state for _run. */ + UX_TRANSFER_STATE_RESET(transfer_request); + status = UX_SUCCESS; +#else + /* Send request to HCD layer. */ status = _ux_host_stack_transfer_request(transfer_request); @@ -135,7 +157,8 @@ UINT status; /* Free the buffer resource now. */ _ux_utility_memory_free(port_data); +#endif + /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c b/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c new file mode 100644 index 00000000..c0363f33 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c @@ -0,0 +1,446 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** HUB Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_hub.h" +#include "ux_host_stack.h" + + +#if defined(UX_HOST_STANDALONE) + + +static inline VOID _ux_host_class_hub_inst_tasks_run(UX_HOST_CLASS_HUB *hub); + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_hub_tasks_run PORTABLE C */ +/* 6.1.12 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function runs HUB background tasks. */ +/* */ +/* This function is for standalone mode. */ +/* */ +/* INPUT */ +/* */ +/* hub Pointer to HUB instance */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_class_hub_port_change_connection_process */ +/* Process connection */ +/* _ux_host_class_hub_port_change_enable_process */ +/* Enable process */ +/* _ux_host_class_hub_port_change_over_current_process */ +/* Change over current process */ +/* _ux_host_class_hub_port_change_reset_process */ +/* Reset process */ +/* _ux_host_class_hub_port_change_suspend_process */ +/* Suspend process */ +/* _ux_host_class_hub_feature Prepare feature request */ +/* _ux_host_class_hub_status_get Prepare get status request */ +/* _ux_utility_short_get Get 16-bit word */ +/* _ux_utility_memory_free Memory free */ +/* _ux_host_stack_new_device_create Obtain a free device instance */ +/* _ux_host_stack_transfer_run Process the transfer */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Host Stack */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_hub_tasks_run(UX_HOST_CLASS *hub_class) +{ +UX_HOST_CLASS_HUB *hub; + + /* Validate class entry. */ + if (hub_class -> ux_host_class_status != UX_USED || + hub_class -> ux_host_class_entry_function != _ux_host_class_hub_entry) + return(UX_STATE_IDLE); + + /* Run for class instances. */ + hub = (UX_HOST_CLASS_HUB *)hub_class -> ux_host_class_first_instance; + while(hub) + { + + /* Run tasks for each HUB instance. */ + _ux_host_class_hub_inst_tasks_run(hub); + hub = hub -> ux_host_class_hub_next_instance; + } + return(UX_STATE_WAIT); +} + +/* Return non-zero if there is change. */ +static inline UCHAR _ux_host_class_hub_change_check(UX_HOST_CLASS_HUB *hub) +{ +UX_ENDPOINT *endpoint = hub -> ux_host_class_hub_interrupt_endpoint; +UX_TRANSFER *transfer = &endpoint -> ux_endpoint_transfer_request; +UCHAR *buffer = transfer -> ux_transfer_request_data_pointer; +UCHAR byte_i = (UCHAR)(hub -> ux_host_class_hub_run_port >> 3); +UCHAR bit_i = (UCHAR)(hub -> ux_host_class_hub_run_port & 0x7u); +UCHAR res = (UCHAR)(buffer[byte_i] & (1u << bit_i)); + buffer[byte_i] = (UCHAR)(buffer[byte_i] & ~(1u << bit_i)); + return(res); +} +static inline VOID _ux_host_class_hub_status_process(UX_HOST_CLASS_HUB *hub, UINT port) +{ +USHORT port_status = hub -> ux_host_class_hub_run_port_status; +USHORT port_change = hub -> ux_host_class_hub_run_port_change; + + /* Next port, if all changes handled. */ + if (port_change == 0) + { + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_CHANGE_NEXT; + return; + } + + if (port_change & UX_HOST_CLASS_HUB_PORT_CHANGE_OVER_CURRENT) + { + hub -> ux_host_class_hub_run_port_change = (USHORT) + (hub -> ux_host_class_hub_run_port_change & + ~UX_HOST_CLASS_HUB_PORT_CHANGE_OVER_CURRENT); + _ux_host_class_hub_port_change_over_current_process(hub, port, port_status); + + /* Next: wait transfer done, then check change again. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_STATUS_PROCESS; + return; + } + if (port_change & UX_HOST_CLASS_HUB_PORT_CHANGE_ENABLE) + { + hub -> ux_host_class_hub_run_port_change = (USHORT) + (hub -> ux_host_class_hub_run_port_change & + ~UX_HOST_CLASS_HUB_PORT_CHANGE_ENABLE); + _ux_host_class_hub_port_change_enable_process(hub, port, port_status); + + /* Next: wait transfer done, then check change again. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_STATUS_PROCESS; + return; + } + if (port_change & UX_HOST_CLASS_HUB_PORT_CHANGE_SUSPEND) + { + hub -> ux_host_class_hub_run_port_change = (USHORT) + (hub -> ux_host_class_hub_run_port_change & + ~UX_HOST_CLASS_HUB_PORT_CHANGE_SUSPEND); + _ux_host_class_hub_port_change_suspend_process(hub, port, port_status); + + /* Next: wait transfer done, then check change again. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_STATUS_PROCESS; + return; + } + if (port_change & UX_HOST_CLASS_HUB_PORT_CHANGE_RESET) + { + hub -> ux_host_class_hub_run_port_change = (USHORT) + (hub -> ux_host_class_hub_run_port_change & + ~UX_HOST_CLASS_HUB_PORT_CHANGE_RESET); + _ux_host_class_hub_port_change_reset_process(hub, port, port_status); + + /* Next: wait transfer done, then process reset + (get status and update enum device). */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_RESET_PROCESS; + return; + } + if (port_change & UX_HOST_CLASS_HUB_PORT_CHANGE_CONNECTION) + { + hub -> ux_host_class_hub_run_port_change = (USHORT) + (hub -> ux_host_class_hub_run_port_change & + ~UX_HOST_CLASS_HUB_PORT_CHANGE_CONNECTION); + _ux_host_class_hub_port_change_connection_process(hub, port, port_status); + + if (hub -> ux_host_class_hub_port_state & (1u << port)) + { + + /* Next: clear c_connection, then process connect. */ + _ux_host_class_hub_feature(hub, port, UX_CLEAR_FEATURE, UX_HOST_CLASS_HUB_C_PORT_CONNECTION); + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_CONNECT_PROCESS; + return; + } + + /* Disable port, then clear c_enable, c_connection. */ + _ux_host_class_hub_feature(hub, port, UX_CLEAR_FEATURE, UX_HOST_CLASS_HUB_PORT_ENABLE); + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_DISC_DISABLED; + return; + } +} +static inline VOID _ux_host_class_hub_inst_tasks_run(UX_HOST_CLASS_HUB *hub) +{ +UX_DEVICE *device; +UX_DEVICE *hub_device = hub -> ux_host_class_hub_device; +UX_ENDPOINT *ep0 = &hub_device -> ux_device_control_endpoint; +UX_TRANSFER *trans0 = &ep0 -> ux_endpoint_transfer_request; +UINT status; + + /* Task runs when hub is live. */ + if (hub -> ux_host_class_hub_state != UX_HOST_CLASS_INSTANCE_LIVE) + return; + + while(1) + { + + /* Immediate state change: continue. + Wait/pending state : return. */ + switch(hub -> ux_host_class_hub_run_state) + { + + case UX_HOST_CLASS_HUB_CHANGE_CHECK : + + /* Check if current port has changes. */ + if (_ux_host_class_hub_change_check(hub)) + { + if (hub -> ux_host_class_hub_run_port == 0) + { + + /* Device state change. */ + /* There is nothing handled now. */ + + /* Next state: try next, port 1. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_CHANGE_NEXT; + continue; + } + + /* Port state change. */ + /* Next: read status. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_STATUS_GET; + continue; + } + + /* No change detected, + * still need to check if there is enumeration reset request. */ + device = _ux_system_host -> ux_system_host_enum_device; + while(device != UX_NULL) + { + + /* Check if a device is waiting on the port for reset. */ + if ((device -> ux_device_flags & UX_DEVICE_FLAG_RESET) && + (device -> ux_device_parent == hub_device) && + (device -> ux_device_port_location == hub -> ux_host_class_hub_run_port)) + { + device -> ux_device_flags &= ~UX_DEVICE_FLAG_RESET; + break; + } + + /* Next enumerating device. */ + device = device -> ux_device_enum_next; + } + if (device) + { + + /* Next: reset then check port status ... */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_RESET; + continue; + } + + /* No change, try next port. */ + + /* Fall through. */ + case UX_HOST_CLASS_HUB_CHANGE_NEXT : + if (hub -> ux_host_class_hub_run_port < + hub -> ux_host_class_hub_descriptor.bNbPorts) + { + + /* Check next port. */ + hub -> ux_host_class_hub_run_port ++; + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_CHANGE_CHECK; + continue; + } + + /* All ports checked, next round. */ + hub -> ux_host_class_hub_run_port = 0; + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_CHANGE_CHECK; + return; + + case UX_HOST_CLASS_HUB_RESET : + status = _ux_host_class_hub_feature(hub, hub -> ux_host_class_hub_run_port, + UX_SET_FEATURE, UX_HOST_CLASS_HUB_PORT_RESET); + + /* Next: check another port, actions are taken on C_RESET detection. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_CHANGE_NEXT; + continue; + + case UX_HOST_CLASS_HUB_STATUS_GET : + status = _ux_host_class_hub_status_get(hub, hub -> ux_host_class_hub_run_port, UX_NULL, UX_NULL); + + if (status != UX_SUCCESS) + { + + /* Fail, retry. */ + hub -> ux_host_class_hub_run_port = 0; + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_CHANGE_CHECK; + return; + } + hub -> ux_host_class_hub_transfer = trans0; + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_STATUS_GET_DONE; + continue; + + case UX_HOST_CLASS_HUB_STATUS_GET_DONE: + + /* Store status change for later usage. */ + hub -> ux_host_class_hub_run_port_status = (USHORT) + _ux_utility_short_get(hub -> ux_host_class_hub_allocated); + hub -> ux_host_class_hub_run_port_change = (USHORT) + _ux_utility_short_get(hub -> ux_host_class_hub_allocated + 2); + + /* Free allocated buffer. */ + _ux_utility_memory_free(hub -> ux_host_class_hub_allocated); + hub -> ux_host_class_hub_allocated = UX_NULL; + + /* Fall through. */ + case UX_HOST_CLASS_HUB_STATUS_PROCESS : + _ux_host_class_hub_status_process(hub, hub -> ux_host_class_hub_run_port); + hub -> ux_host_class_hub_transfer = trans0; + continue; + + case UX_HOST_CLASS_HUB_CONNECT_PROCESS: + + status = _ux_host_stack_new_device_create(UX_DEVICE_HCD_GET(hub_device), + hub_device, hub -> ux_host_class_hub_run_port, + UX_FULL_SPEED_DEVICE, UX_MAX_SELF_POWER, + &device); + if (status == UX_SUCCESS) + { + + /* Put device in enumeration list. */ + device -> ux_device_flags |= UX_DEVICE_FLAG_ENUM; + } + + /* Try next port. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_CHANGE_NEXT; + return; + + case UX_HOST_CLASS_HUB_DISC_DISABLED: + + /* Next: clear C_ENABLE, then clear C_CONNECTION. */ + _ux_host_class_hub_feature(hub, hub -> ux_host_class_hub_run_port, UX_CLEAR_FEATURE, UX_HOST_CLASS_HUB_C_PORT_ENABLE); + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_DISC_CLEAR_1; + continue; + + case UX_HOST_CLASS_HUB_DISC_CLEAR_1: + + /* Next: clear C_CONNECTION, then next port. */ + _ux_host_class_hub_feature(hub, hub -> ux_host_class_hub_run_port, UX_CLEAR_FEATURE, UX_HOST_CLASS_HUB_C_PORT_CONNECTION); + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_TRANS_WAIT; + hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_CHANGE_NEXT; + continue; + + case UX_HOST_CLASS_HUB_RESET_PROCESS : + + /* Find enum device, update enum port status, state -> ADDR_SET. */ + device = _ux_system_host -> ux_system_host_enum_device; + while(device != UX_NULL) + { + + /* If there is a device connected to the port, put its state to ADDR_SET. */ + if ((device -> ux_device_parent == hub -> ux_host_class_hub_device) && + (device -> ux_device_port_location == hub -> ux_host_class_hub_run_port)) + { + + /* Save status and speed. */ + device -> ux_device_enum_port_status = (UCHAR)hub -> ux_host_class_hub_run_port_status; + + /* Return device address to 0. */ + if (device -> ux_device_address) + { + + /* Free the address. */ + UX_DEVICE_HCD_GET(device) -> + ux_hcd_address[(device -> ux_device_address-1) >> 3] &= + (UCHAR)(1u << ((device -> ux_device_address-1) & 7u)); + } + + /* Wait a while and set address. */ + device -> ux_device_enum_next_state = UX_HOST_STACK_ENUM_DEVICE_ADDR_SET; + device -> ux_device_enum_state = UX_HOST_STACK_ENUM_WAIT; + device -> ux_device_enum_wait_start = _ux_utility_time_get(); + device -> ux_device_enum_wait_ms = UX_MS_TO_TICK_NON_ZERO(2); + break; + } + + /* Next device. */ + device = device -> ux_device_enum_next; + } + + /* Reset processed check other status. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_STATUS_PROCESS; + continue; + + case UX_HOST_CLASS_HUB_TRANS_WAIT : + + /* Poll transfer task. */ + status = _ux_host_stack_transfer_run(hub -> ux_host_class_hub_transfer); + + /* Transfer done - next state. */ + if (status == UX_STATE_NEXT || status == UX_STATE_IDLE) + { + hub -> ux_host_class_hub_run_state = hub -> ux_host_class_hub_next_state; + continue; + } + + /* Check error. */ + if (status < UX_STATE_NEXT) + { + + /* Fail, just check next port. */ + hub -> ux_host_class_hub_run_state = UX_HOST_CLASS_HUB_CHANGE_NEXT; + hub -> ux_host_class_hub_run_status = + hub -> ux_host_class_hub_transfer -> + ux_transfer_request_completion_code; + continue; + } + + /* Transfer in progress, wait. */ + return; + + default: + break; + } + } +} +#endif diff --git a/common/usbx_host_classes/src/ux_host_class_hub_transfer_request_completed.c b/common/usbx_host_classes/src/ux_host_class_hub_transfer_request_completed.c index 79eb1fb7..6d0f8c6b 100644 --- a/common/usbx_host_classes/src/ux_host_class_hub_transfer_request_completed.c +++ b/common/usbx_host_classes/src/ux_host_class_hub_transfer_request_completed.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_hub_transfer_request_completed PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -51,9 +51,12 @@ /* thread. We post a signal to the topology thread to wake up and */ /* treat these changes on the HUB status. */ /* */ -/* The interrupt pipe is not reactivated here. We will do this when */ -/* the topology thread has investigated the reason of the transfer */ -/* completion. */ +/* In RTOS mode, the interrupt pipe is not reactivated here. We will */ +/* do this when the topology thread has investigated the reason of the */ +/* transfer completion. */ +/* */ +/* In standalone mode, the interrupt pipe is reactivated here. The */ +/* bitmap in buffer is examined in hub tasks function. */ /* */ /* INPUT */ /* */ @@ -81,6 +84,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added standalone support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_host_class_hub_transfer_request_completed(UX_TRANSFER *transfer_request) @@ -109,7 +115,7 @@ UX_HOST_CLASS_HUB *hub; { - /* Reactivate the HID interrupt pipe. */ + /* Reactivate the HUB interrupt pipe. */ _ux_host_stack_transfer_request(transfer_request); /* We do not proceed. */ @@ -117,14 +123,20 @@ UX_HOST_CLASS_HUB *hub; } } +#if defined(UX_HOST_STANDALONE) + + /* Reactivate the HUB interrupt pipe. */ + _ux_host_stack_transfer_request(transfer_request); +#else + /* We need to memorize which HUB instance has received a change signal. */ hub -> ux_host_class_hub_change_semaphore++; /* Now we can set the semaphore, the enum thread will wake up and will call the HUB instance which has a status change. */ _ux_host_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore); +#endif /* Return to caller. */ return; } - diff --git a/common/usbx_host_classes/src/ux_host_class_pima_activate.c b/common/usbx_host_classes/src/ux_host_class_pima_activate.c index bbeda727..77556afd 100644 --- a/common/usbx_host_classes/src/ux_host_class_pima_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_pima_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_pima_activate PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,18 +72,22 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_pima_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; -UX_HOST_CLASS_PIMA *pima; -UINT status; +UX_INTERFACE *interface_ptr; +UX_HOST_CLASS_PIMA *pima; +UINT status; /* The PIMA class is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Obtain memory for this class instance. */ pima = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_PIMA)); @@ -114,13 +118,13 @@ UINT status; pima -> ux_host_class_pima_class = command -> ux_host_class_command_class_ptr; /* Store the interface container into the pima class instance. */ - pima -> ux_host_class_pima_interface = interface; + pima -> ux_host_class_pima_interface = interface_ptr; /* Store the device container into the pima class instance. */ - pima -> ux_host_class_pima_device = interface -> ux_interface_configuration -> ux_configuration_device; + pima -> ux_host_class_pima_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) pima; + interface_ptr -> ux_interface_class_instance = (VOID *) pima; /* Create this class instance. */ _ux_host_stack_class_instance_create(pima -> ux_host_class_pima_class, (VOID *) pima); @@ -163,7 +167,7 @@ UINT status; if (pima -> ux_host_class_pima_event_buffer) { _ux_host_stack_class_instance_destroy(pima -> ux_host_class_pima_class, (VOID *) pima); - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr -> ux_interface_class_instance = UX_NULL; _ux_utility_memory_free(pima -> ux_host_class_pima_event_buffer); } diff --git a/common/usbx_host_classes/src/ux_host_class_pima_device_info_get.c b/common/usbx_host_classes/src/ux_host_class_pima_device_info_get.c index 7d704741..7ad7def6 100644 --- a/common/usbx_host_classes/src/ux_host_class_pima_device_info_get.c +++ b/common/usbx_host_classes/src/ux_host_class_pima_device_info_get.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** PIMA Class */ /** */ @@ -30,55 +30,58 @@ #include "ux_host_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_pima_device_info_get PORTABLE C */ -/* 6.1 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_pima_device_info_get PORTABLE C */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function gets the device information block. */ -/* */ -/* INPUT */ -/* */ -/* pima Pointer to pima class */ -/* pima_device Device structure to fill */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ +/* */ +/* This function gets the device information block. */ +/* */ +/* INPUT */ +/* */ +/* pima Pointer to pima class */ +/* pima_device Device structure to fill */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ /* _ux_host_class_pima_command Pima command function */ -/* _ux_utility_descriptor_parse Unpack descriptor */ -/* _ux_utility_memory_allocate Allocate memory */ +/* _ux_utility_descriptor_parse Unpack descriptor */ +/* _ux_utility_memory_allocate Allocate memory */ /* _ux_utility_memory_copy Copy memory */ -/* _ux_utility_memory_free Free allocated memory */ +/* _ux_utility_memory_free Free allocated memory */ /* _ux_utility_short_get Get 16-bit value */ /* _ux_utility_long_get Get 32-bit value */ -/* */ -/* CALLED BY */ -/* */ -/* USB application */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* CALLED BY */ +/* */ +/* USB application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed DeviceInfo extract, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ -UINT _ux_host_class_pima_device_info_get(UX_HOST_CLASS_PIMA *pima, +UINT _ux_host_class_pima_device_info_get(UX_HOST_CLASS_PIMA *pima, UX_HOST_CLASS_PIMA_DEVICE *pima_device) { @@ -94,7 +97,7 @@ UINT status; /* Issue command to get the device info. no parameter. */ command.ux_host_class_pima_command_nb_parameters = 0; - + /* Other parameters unused. */ command.ux_host_class_pima_command_parameter_1 = 0; command.ux_host_class_pima_command_parameter_2 = 0; @@ -111,159 +114,164 @@ UINT status; return(UX_MEMORY_INSUFFICIENT); /* Issue the command. */ - status = _ux_host_class_pima_command(pima, &command, UX_HOST_CLASS_PIMA_DATA_PHASE_IN , device_buffer, + status = _ux_host_class_pima_command(pima, &command, UX_HOST_CLASS_PIMA_DATA_PHASE_IN , device_buffer, UX_HOST_CLASS_PIMA_DEVICE_MAX_LENGTH, UX_HOST_CLASS_PIMA_DEVICE_MAX_LENGTH); /* Check the result. If the result is OK, the device info block was read properly. */ if (status == UX_SUCCESS) { - /* Read and store the Standard Version field. */ - pima_device -> ux_host_class_pima_device_standard_version = _ux_utility_short_get(device_buffer + + /* Read and store the Standard Version field (2). */ + pima_device -> ux_host_class_pima_device_standard_version = _ux_utility_short_get(device_buffer + UX_HOST_CLASS_PIMA_DEVICE_STANDARD_VERSION); - - /* Read and store the Vendor Extension ID . */ - pima_device -> ux_host_class_pima_device_vendor_extension_id = _ux_utility_long_get(device_buffer + + + /* Read and store the Vendor Extension ID (4). */ + pima_device -> ux_host_class_pima_device_vendor_extension_id = _ux_utility_long_get(device_buffer + UX_HOST_CLASS_PIMA_DEVICE_VENDOR_EXTENSION_ID); - - /* Read and store the Vendor Extension Version . */ - pima_device -> ux_host_class_pima_device_vendor_extension_version = _ux_utility_long_get(device_buffer + + + /* Read and store the Vendor Extension Version (2). */ + pima_device -> ux_host_class_pima_device_vendor_extension_version = _ux_utility_long_get(device_buffer + UX_HOST_CLASS_PIMA_DEVICE_VENDOR_EXTENSION_VERSION); - - /* Copy the vendor extension descriptor. */ + /* Copy the vendor extension descriptor (String). */ device_pointer = device_buffer + UX_HOST_CLASS_PIMA_DEVICE_VENDOR_EXTENSION_DESC; - - /* Get the unicode string length. */ + + /* Get the unicode string length in chars. */ unicode_string_length = (ULONG) *device_pointer; /* Check if the string can fit in our buffer. */ - if (unicode_string_length > UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH) + if (unicode_string_length > UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH / 2) /* Return error. */ status = UX_MEMORY_INSUFFICIENT; - + /* Is there enough space? */ if (status == UX_SUCCESS) { - /* Copy that string into the object description field. */ - _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_vendor_extension_desc, device_pointer, unicode_string_length); /* Use case of memcpy is verified. */ + /* Copy that unicode string (with null ending) into the object description field. */ + _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_vendor_extension_desc, device_pointer + 1, unicode_string_length << 1); /* Use case of memcpy is verified. */ /* Point to the next field. */ - device_pointer += unicode_string_length + 1; + device_pointer += 1 + (unicode_string_length << 1); - /* Read and store the Functional Mode. */ + /* Read and store the Functional Mode (2). */ pima_device -> ux_host_class_pima_device_functional_mode = _ux_utility_short_get(device_pointer); - /* Point to the next field. */ + /* Point to the next field (OperationsSupported OperationCode Array of 16-bit). */ device_pointer += sizeof(USHORT); - - /* Get the number of elements in array and compute total length. */ - array_length = (ULONG)sizeof(ULONG) + (_ux_utility_long_get(device_pointer) * 2); - - /* Ensure the array can fit in our buffer. */ - if (array_length > UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH) - /* Return error. */ - status = UX_MEMORY_INSUFFICIENT; + /* Get the number of elements in array and compute total length. */ + array_length = _ux_utility_long_get(device_pointer); + + if (array_length > (UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH - sizeof(ULONG)) / 2) + status = UX_MEMORY_INSUFFICIENT; + else + { + array_length <<= 1; + array_length += sizeof(ULONG); + } } /* Is there enough space? */ if (status == UX_SUCCESS) { - /* Copy the array of supported operations. */ + /* Copy the array of supported operations (OperationCode). */ _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_operations_supported, device_pointer, array_length); /* Use case of memcpy is verified. */ - /* Point to the next field. */ + /* Point to the next field (EventsSupported EventCode Array of 16-bit). */ device_pointer += array_length; /* Get the number of elements in array and compute total length. */ - array_length = (ULONG)sizeof(ULONG) + (_ux_utility_long_get(device_pointer) * 2); - - /* Ensure the array can fit in our buffer. */ - if (array_length > UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH) - - /* Return overflow error. */ - status = UX_MEMORY_INSUFFICIENT; + array_length = _ux_utility_long_get(device_pointer); + if (array_length > (UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH - sizeof(ULONG)) / 2) + status = UX_MEMORY_INSUFFICIENT; + else + { + array_length <<= 1; + array_length += sizeof(ULONG); + } } /* Is there enough space? */ if (status == UX_SUCCESS) { - /* Copy the array of events supported. */ + /* Copy the array of events supported (EventCode). */ _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_events_supported, device_pointer, array_length); /* Use case of memcpy is verified. */ - /* Point to the next field. */ + /* Point to the next field (DevicePropertiesSupported DevicePropCode Array of 16-bit). */ device_pointer += array_length; /* Get the number of elements in array and compute total length. */ - array_length = (ULONG)sizeof(ULONG) + (_ux_utility_long_get(device_pointer) * 2); - - /* Ensure the array can fit in our buffer. */ - if (array_length > UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH) - - /* Return overflow error. */ - status = UX_MEMORY_INSUFFICIENT; + array_length = _ux_utility_long_get(device_pointer); + if (array_length > (UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH - sizeof(ULONG)) / 2) + status = UX_MEMORY_INSUFFICIENT; + else + { + array_length <<= 1; + array_length += sizeof(ULONG); + } } /* Is there enough space? */ if (status == UX_SUCCESS) { - /* Copy the array of device properties. */ + /* Copy the array of device properties (DevicePropCode). */ _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_properties_supported, device_pointer, array_length); /* Use case of memcpy is verified. */ - /* Point to the next field. */ + /* Point to the next field (CaptureFormats ObjectFormatCode Array of 16-bit). */ device_pointer += array_length; /* Get the number of elements in array and compute total length. */ - array_length = (ULONG)sizeof(ULONG) + (_ux_utility_long_get(device_pointer) * 2); - - /* Ensure the array can fit in our buffer. */ - if (array_length > UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH) - - /* Return overflow error. */ - status = UX_MEMORY_INSUFFICIENT; + array_length = _ux_utility_long_get(device_pointer); + if (array_length > (UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH - sizeof(ULONG)) / 2) + status = UX_MEMORY_INSUFFICIENT; + else + { + array_length <<= 1; + array_length += sizeof(ULONG); + } } /* Is there enough space? */ if (status == UX_SUCCESS) { - /* Copy the array of capture formats. */ + /* Copy the array of capture formats (CaptureFormats ObjectFormatCode). */ _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_capture_formats, device_pointer, array_length); /* Use case of memcpy is verified. */ - /* Point to the next field. */ + /* Point to the next field (ImageFormats ObjectFormatCode Array of 16-bit). */ device_pointer += array_length; /* Get the number of elements in array and compute total length. */ - array_length = (ULONG)sizeof(ULONG) + (_ux_utility_long_get(device_pointer) * 2); - - /* Ensure the array can fit in our buffer. */ - if (array_length > UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH) - - /* Return overflow error. */ - status = UX_MEMORY_INSUFFICIENT; + array_length = _ux_utility_long_get(device_pointer); + if (array_length > (UX_HOST_CLASS_PIMA_ARRAY_MAX_LENGTH - sizeof(ULONG)) / 2) + status = UX_MEMORY_INSUFFICIENT; + else + { + array_length <<= 1; + array_length += sizeof(ULONG); + } } /* Is there enough space? */ if (status == UX_SUCCESS) { - /* Copy the array of supported operations. */ + /* Copy the array of supported operations (ImageFormats ObjectFormatCode). */ _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_image_formats, device_pointer, array_length); /* Use case of memcpy is verified. */ - /* Point to the next field. */ + /* Point to the next field (Manufacturer String). */ device_pointer += array_length; /* Get the unicode string length. */ unicode_string_length = (ULONG) *device_pointer; /* Ensure the string can fit in our buffer. */ - if (unicode_string_length > UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH) + if (unicode_string_length > UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH / 2) /* Return overflow error. */ status = UX_MEMORY_INSUFFICIENT; @@ -273,17 +281,17 @@ UINT status; if (status == UX_SUCCESS) { - /* Copy that string into the manufacturer field. */ - _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_manufacturer, device_pointer, unicode_string_length); /* Use case of memcpy is verified. */ + /* Copy that string into the manufacturer field (Manufacturer String). */ + _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_manufacturer, device_pointer + 1, unicode_string_length << 1); /* Use case of memcpy is verified. */ + + /* Point to the next field (Model String). */ + device_pointer += (unicode_string_length << 1) + 1; - /* Point to the next field. */ - device_pointer += unicode_string_length + 1; - /* Get the unicode string length. */ unicode_string_length = (ULONG) *device_pointer ; /* Ensure the string can fit in our buffer. */ - if (unicode_string_length > UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH) + if (unicode_string_length > UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH / 2) /* Return overflow error. */ status = UX_MEMORY_INSUFFICIENT; @@ -293,17 +301,17 @@ UINT status; if (status == UX_SUCCESS) { - /* Copy that string into the model date field. */ - _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_model, device_pointer, unicode_string_length); /* Use case of memcpy is verified. */ + /* Copy that string into the model date field (Model String). */ + _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_model, device_pointer + 1, unicode_string_length << 1); /* Use case of memcpy is verified. */ - /* Point to the next field. */ - device_pointer += unicode_string_length + 1; + /* Point to the next field (DeviceVersion String). */ + device_pointer += (unicode_string_length << 1) + 1; /* Get the unicode string length. */ unicode_string_length = (ULONG) *device_pointer ; /* Ensure the string can fit in our buffer. */ - if (unicode_string_length > UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH) + if (unicode_string_length > UX_HOST_CLASS_PIMA_DATE_TIME_STRING_MAX_LENGTH / 2) /* Return overflow error. */ status = UX_MEMORY_INSUFFICIENT; @@ -313,17 +321,17 @@ UINT status; if (status == UX_SUCCESS) { - /* Copy that string into the version field. */ - _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_version, device_pointer, unicode_string_length); /* Use case of memcpy is verified. */ + /* Copy that string into the version field (DeviceVersion String). */ + _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_version, device_pointer + 1, unicode_string_length << 1); /* Use case of memcpy is verified. */ - /* Point to the next field. */ - device_pointer += unicode_string_length + 1; + /* Point to the next field (SerialNumber String). */ + device_pointer += (unicode_string_length << 1) + 1; /* Get the unicode string length. */ unicode_string_length = (ULONG) *device_pointer ; /* Ensure the string can fit in our buffer. */ - if (unicode_string_length > UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH) + if (unicode_string_length > UX_HOST_CLASS_PIMA_UNICODE_MAX_LENGTH / 2) /* Return overflow error. */ status = UX_MEMORY_INSUFFICIENT; @@ -332,8 +340,8 @@ UINT status; /* Is there enough space? */ if (status == UX_SUCCESS) - /* Copy that string into the serial number field. */ - _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_serial_number, device_pointer, unicode_string_length); /* Use case of memcpy is verified. */ + /* Copy that string into the serial number field (SerialNumber String). */ + _ux_utility_memory_copy(pima_device -> ux_host_class_pima_device_serial_number, device_pointer + 1, unicode_string_length << 1); /* Use case of memcpy is verified. */ else { @@ -346,10 +354,9 @@ UINT status; } } - /* Free the original object info buffer. */ + /* Free the original object info buffer. */ _ux_utility_memory_free(device_buffer); - + /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_pima_object_handles_get.c b/common/usbx_host_classes/src/ux_host_class_pima_object_handles_get.c index 353ec6e6..948272cd 100644 --- a/common/usbx_host_classes/src/ux_host_class_pima_object_handles_get.c +++ b/common/usbx_host_classes/src/ux_host_class_pima_object_handles_get.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** PIMA Class */ /** */ @@ -30,56 +30,59 @@ #include "ux_host_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_pima_object_handles_get PORTABLE C */ -/* 6.1 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_pima_object_handles_get PORTABLE C */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function gets a list if the current valid Storage IDS. There */ -/* is one Storage ID for each valid logical store. */ -/* */ -/* INPUT */ -/* */ -/* pima Pointer to pima class */ -/* pima_session Pointer to pima session */ -/* object_handles_array Pointer to store handles */ -/* object_handles_length Length of arrays */ -/* object_format_code Object Format Code */ -/* object_handle_association Object Handle */ -/* Association */ -/* */ -/* The 2 last parameter are optional and should be set to 0 if not */ -/* used. */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ +/* */ +/* This function gets a list if the current valid Storage IDS. There */ +/* is one Storage ID for each valid logical store. */ +/* */ +/* INPUT */ +/* */ +/* pima Pointer to pima class */ +/* pima_session Pointer to pima session */ +/* object_handles_array Pointer to store handles */ +/* object_handles_length Array length in handles */ +/* object_format_code Object Format Code */ +/* object_handle_association Object Handle */ +/* Association */ +/* */ +/* The 2 last parameter are optional and should be set to 0 if not */ +/* used. */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ /* _ux_host_class_pima_command Pima command function */ /* _ux_utility_long_get Get 32 bit value */ -/* _ux_utility_memory_allocate Allocate some memory */ -/* _ux_utility_memory_free Free some memory */ -/* */ -/* CALLED BY */ -/* */ -/* USB application */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* _ux_utility_memory_allocate Allocate some memory */ +/* _ux_utility_memory_free Free some memory */ +/* */ +/* CALLED BY */ +/* */ +/* USB application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved num objects check, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_pima_object_handles_get(UX_HOST_CLASS_PIMA *pima, UX_HOST_CLASS_PIMA_SESSION *pima_session, @@ -103,28 +106,28 @@ UINT status; return (UX_HOST_CLASS_PIMA_RC_SESSION_NOT_OPEN); /* Check the number of handles and compare with the size of the array given by the user. */ - if ((pima_session -> ux_host_class_pima_session_nb_objects * sizeof(ULONG)) > object_handles_length) + if (pima_session -> ux_host_class_pima_session_nb_objects > object_handles_length) return(UX_MEMORY_INSUFFICIENT); /* Issue command to get the storage IDs. 3 parameters. */ command.ux_host_class_pima_command_nb_parameters = 3; - + /* Parameter 1 is the Storage ID. */ command.ux_host_class_pima_command_parameter_1 = storage_id; - + /* Parameter 2 is optional. It is the Object Format Code. */ command.ux_host_class_pima_command_parameter_2 = object_format_code; - + /* Parameter 3 is optional. It is the object handle association. */ command.ux_host_class_pima_command_parameter_3 = object_handle_association; - + /* Other parameters unused. */ command.ux_host_class_pima_command_parameter_4 = 0; command.ux_host_class_pima_command_parameter_5 = 0; /* Then set the command to GET_STORAGE_IDS. */ command.ux_host_class_pima_command_operation_code = UX_HOST_CLASS_PIMA_OC_GET_OBJECT_HANDLES; - + /* Calculate the length the raw array. We multiply the number of handles by the size on the handle and add a ULONG for the number of handles stored at the beginning of the array. */ status = UX_SUCCESS; @@ -151,16 +154,16 @@ UINT status; /* Read the number of Object handles in the returned array. */ nb_object_handles = _ux_utility_long_get(object_handles_array_raw); - + /* Save the number of object handles. */ pima_session -> ux_host_class_pima_session_nb_objects = nb_object_handles; /* Check if the user gave us enough memory. */ - if ((nb_object_handles * sizeof(ULONG)) > object_handles_length) - + if (nb_object_handles > object_handles_length) + /* No, not enough memory to store the array. */ return(UX_MEMORY_INSUFFICIENT); - + /* Unpack all object handles. */ for(count_object_handles = 0; count_object_handles < nb_object_handles; count_object_handles++) @@ -171,8 +174,7 @@ UINT status; /* Free the original raw array. */ _ux_utility_memory_free(object_handles_array_raw); - + /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_pima_read.c b/common/usbx_host_classes/src/ux_host_class_pima_read.c index 79b00b48..82348633 100644 --- a/common/usbx_host_classes/src/ux_host_class_pima_read.c +++ b/common/usbx_host_classes/src/ux_host_class_pima_read.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_pima_read PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -48,6 +48,8 @@ /* */ /* This function reads a data payload from the Pima device. This */ /* function first read a header followed by some data. */ +/* */ +/* Note header only transfer and partial transfer is not accepted. */ /* */ /* INPUT */ /* */ @@ -90,6 +92,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved length checks, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_pima_read(UX_HOST_CLASS_PIMA *pima, UCHAR *data_pointer, @@ -164,6 +169,11 @@ ULONG payload_length; /* Get the expected length from the header. */ header_length = _ux_utility_long_get(ptp_payload + UX_HOST_CLASS_PIMA_DATA_HEADER_LENGTH); + /* Device reported data length should be equal or more than this packet + * (and UX_HOST_CLASS_PIMA_DATA_HEADER_LENGTH). */ + if (header_length < transfer_request -> ux_transfer_request_actual_length) + return(UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR); + /* Check for remainder in last packet. */ if ((header_length % pima -> ux_host_class_pima_bulk_in_endpoint -> ux_endpoint_descriptor.wMaxPacketSize) == 0) @@ -175,7 +185,7 @@ ULONG payload_length; pima -> ux_host_class_pima_zlp_flag = UX_HOST_CLASS_PIMA_ZLP_NONE; /* The length returned should be smaller than the length requested. */ - if ((header_length - UX_HOST_CLASS_PIMA_DATA_HEADER_SIZE)> data_length) + if ((header_length - UX_HOST_CLASS_PIMA_DATA_HEADER_SIZE) > data_length) return(UX_ERROR); /* We may have had data in the first packet, if so adjust the data_length. */ diff --git a/common/usbx_host_classes/src/ux_host_class_pima_storage_ids_get.c b/common/usbx_host_classes/src/ux_host_class_pima_storage_ids_get.c index 72798be8..f8868f91 100644 --- a/common/usbx_host_classes/src/ux_host_class_pima_storage_ids_get.c +++ b/common/usbx_host_classes/src/ux_host_class_pima_storage_ids_get.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** PIMA Class */ /** */ @@ -29,50 +29,55 @@ #include "ux_host_class_pima.h" #include "ux_host_stack.h" -UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH_ASSERT -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_pima_storage_ids_get PORTABLE C */ -/* 6.1 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_pima_storage_ids_get PORTABLE C */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function gets a list if the current valid Storage IDS. There */ -/* is one Storage ID for each valid logical store. */ -/* */ -/* INPUT */ -/* */ -/* pima Pointer to pima class */ -/* pima_session Pointer to pima session */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ +/* */ +/* This function gets a list if the current valid Storage IDS. There */ +/* is one Storage ID for each valid logical store. */ +/* */ +/* INPUT */ +/* */ +/* pima Pointer to pima class */ +/* pima_session Pointer to pima session */ +/* storage_ids_array Pointer to buffer to */ +/* fill storage IDs */ +/* storage_id_length Array length in N of IDs */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ /* _ux_host_class_pima_command Pima command function */ /* _ux_utility_memory_allocate Allocate memory */ /* _ux_utility_memory_free Free memory */ /* _ux_utility_long_get Get 32-bit value */ -/* */ -/* CALLED BY */ -/* */ -/* USB application */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* CALLED BY */ +/* */ +/* USB application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved array size check, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_pima_storage_ids_get(UX_HOST_CLASS_PIMA *pima, UX_HOST_CLASS_PIMA_SESSION *pima_session, @@ -105,20 +110,20 @@ ULONG nb_storage_ids; command.ux_host_class_pima_command_parameter_3 = 0; command.ux_host_class_pima_command_parameter_4 = 0; command.ux_host_class_pima_command_parameter_5 = 0; - + /* Then set the command to GET_STORAGE_IDS. */ command.ux_host_class_pima_command_operation_code = UX_HOST_CLASS_PIMA_OC_GET_STORAGE_IDS; /* Allocate some DMA safe memory for receiving the IDs. - * UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH_ASSERT checks if calculation of - * UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH is OK. + * UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH = (UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS + 1) * 4, + * it is checked no calculation overflow. */ storage_ids = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH); if (storage_ids == UX_NULL) return(UX_MEMORY_INSUFFICIENT); /* Issue the command. */ - status = _ux_host_class_pima_command(pima, &command, UX_HOST_CLASS_PIMA_DATA_PHASE_IN , storage_ids, + status = _ux_host_class_pima_command(pima, &command, UX_HOST_CLASS_PIMA_DATA_PHASE_IN , storage_ids, UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH, UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH); /* Check the result. If OK, the storage ID array is returned properly. */ @@ -127,22 +132,22 @@ ULONG nb_storage_ids; /* Read the number of Storage IDs in the returned array. */ nb_storage_ids = _ux_utility_long_get(storage_ids); - + /* Ensure we do read the array beyond the allocated memory. */ - if (((nb_storage_ids + 1) * sizeof(ULONG)) > UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH) + if (nb_storage_ids > UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS) /* If we get here we should probably increase the value for UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH */ - nb_storage_ids = (UX_HOST_CLASS_PIMA_STORAGE_IDS_LENGTH / sizeof(ULONG)) - 1; + nb_storage_ids = UX_HOST_CLASS_PIMA_MAX_STORAGE_IDS; /* Save the number of storage IDs. */ pima_session -> ux_host_class_pima_session_nb_storage_ids = nb_storage_ids; /* Check if the user gave us enough memory. */ - if ((nb_storage_ids * sizeof(ULONG)) > storage_id_length) - + if (nb_storage_ids > storage_id_length) + /* No, not enough memory to store the array. */ return(UX_MEMORY_INSUFFICIENT); - + /* Unpack all storage IDS. */ for(count_storage_ids = 0; count_storage_ids < nb_storage_ids; count_storage_ids++) @@ -153,8 +158,7 @@ ULONG nb_storage_ids; /* Free the original storage ID buffer. */ _ux_utility_memory_free(storage_ids); - + /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_printer_activate.c b/common/usbx_host_classes/src/ux_host_class_printer_activate.c index 4a82ec76..3af30076 100644 --- a/common/usbx_host_classes/src/ux_host_class_printer_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_printer_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_printer_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,12 +77,16 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_printer_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_PRINTER *printer; #if !defined(UX_HOST_STANDALONE) UINT status; @@ -91,7 +95,7 @@ UINT status; /* The printer is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Obtain memory for this class instance. */ printer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_PRINTER)); @@ -102,13 +106,13 @@ UINT status; printer -> ux_host_class_printer_class = command -> ux_host_class_command_class_ptr; /* Store the interface container into the printer class instance. */ - printer -> ux_host_class_printer_interface = interface; + printer -> ux_host_class_printer_interface = interface_ptr; /* Store the device container into the printer class instance. */ - printer -> ux_host_class_printer_device = interface -> ux_interface_configuration -> ux_configuration_device; + printer -> ux_host_class_printer_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) printer; + interface_ptr -> ux_interface_class_instance = (VOID *) printer; /* Create this class instance. */ _ux_host_stack_class_instance_create(printer -> ux_host_class_printer_class, (VOID *) printer); @@ -168,7 +172,7 @@ UINT status; /* On error, free resources. */ _ux_host_stack_class_instance_destroy(printer -> ux_host_class_printer_class, (VOID *) printer); - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr -> ux_interface_class_instance = UX_NULL; _ux_utility_memory_free(printer); /* Return completion status. */ diff --git a/common/usbx_host_classes/src/ux_host_class_printer_device_id_get.c b/common/usbx_host_classes/src/ux_host_class_printer_device_id_get.c index b7478417..8d69bb5f 100644 --- a/common/usbx_host_classes/src/ux_host_class_printer_device_id_get.c +++ b/common/usbx_host_classes/src/ux_host_class_printer_device_id_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_printer_device_id_get PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,6 +79,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_printer_device_id_get(UX_HOST_CLASS_PRINTER *printer, UCHAR *descriptor_buffer, ULONG length) @@ -86,7 +90,7 @@ UINT _ux_host_class_printer_device_id_get(UX_HOST_CLASS_PRINTER *printer, UCHAR #if defined(UX_HOST_STANDALONE) UX_INTERRUPT_SAVE_AREA #endif -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; UINT status; @@ -130,7 +134,7 @@ UINT status; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; /* Need interface for wIndex. */ - interface = printer -> ux_host_class_printer_interface; + interface_ptr = printer -> ux_host_class_printer_interface; /* Create a transfer request for the GET_DEVICE_ID request. */ transfer_request -> ux_transfer_request_data_pointer = descriptor_buffer; @@ -138,8 +142,8 @@ UINT status; transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_PRINTER_GET_DEVICE_ID; transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; transfer_request -> ux_transfer_request_value = 0; /* Do not support multiple configuration for now. */ - transfer_request -> ux_transfer_request_index = (interface -> ux_interface_descriptor.bInterfaceNumber << 8) | - (interface -> ux_interface_descriptor.bAlternateSetting ); + transfer_request -> ux_transfer_request_index = (interface_ptr -> ux_interface_descriptor.bInterfaceNumber << 8) | + (interface_ptr -> ux_interface_descriptor.bAlternateSetting ); #if defined(UX_HOST_STANDALONE) diff --git a/common/usbx_host_classes/src/ux_host_class_printer_entry.c b/common/usbx_host_classes/src/ux_host_class_printer_entry.c index f6a774d3..3075b3e0 100644 --- a/common/usbx_host_classes/src/ux_host_class_printer_entry.c +++ b/common/usbx_host_classes/src/ux_host_class_printer_entry.c @@ -50,7 +50,7 @@ static inline UINT _ux_host_class_printer_activate_wait(UX_HOST_CLASS_COMMAND *c /* FUNCTION RELEASE */ /* */ /* _ux_host_class_printer_entry PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -88,6 +88,11 @@ static inline UINT _ux_host_class_printer_activate_wait(UX_HOST_CLASS_COMMAND *c /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* removed compile warning, */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_printer_entry(UX_HOST_CLASS_COMMAND *command) @@ -143,20 +148,20 @@ UINT status; #if defined(UX_HOST_STANDALONE) static inline UINT _ux_host_class_printer_activate_wait(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_PRINTER *printer; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer; UINT status; /* Get the instance for this class. */ - interface = (UX_INTERFACE *)command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *)command -> ux_host_class_command_container; /* Sanity check. */ - if (interface == UX_NULL) + if (interface_ptr == UX_NULL) return(UX_STATE_EXIT); - printer = (UX_HOST_CLASS_PRINTER *) interface -> ux_interface_class_instance; + printer = (UX_HOST_CLASS_PRINTER *) interface_ptr -> ux_interface_class_instance; /* Sanity check. */ if (printer == UX_NULL) @@ -250,7 +255,7 @@ UINT status; /* On error, free resources. */ _ux_host_stack_class_instance_destroy( printer -> ux_host_class_printer_class, (VOID *) printer); - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr -> ux_interface_class_instance = UX_NULL; _ux_utility_memory_free(printer); return(UX_STATE_ERROR); } @@ -280,9 +285,10 @@ UINT status; return(UX_STATE_NEXT); default: /* reset, idle, error ... */ - return(UX_STATE_NEXT); + break; } + /* Just next phase. */ return(UX_STATE_NEXT); } #endif diff --git a/common/usbx_host_classes/src/ux_host_class_printer_name_get.c b/common/usbx_host_classes/src/ux_host_class_printer_name_get.c index 6e74d7f4..19334bbc 100644 --- a/common/usbx_host_classes/src/ux_host_class_printer_name_get.c +++ b/common/usbx_host_classes/src/ux_host_class_printer_name_get.c @@ -125,7 +125,7 @@ UINT printer_name_length; /* FUNCTION RELEASE */ /* */ /* _ux_host_class_printer_name_get PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -172,13 +172,17 @@ UINT printer_name_length; /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_printer_name_get(UX_HOST_CLASS_PRINTER *printer) { UCHAR * descriptor_buffer; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; #if !defined(UX_HOST_STANDALONE) @@ -198,7 +202,7 @@ UINT status; return(UX_MEMORY_INSUFFICIENT); /* Need interface for wIndex. */ - interface = printer -> ux_host_class_printer_interface; + interface_ptr = printer -> ux_host_class_printer_interface; /* Create a transfer request for the GET_DEVICE_ID request. */ transfer_request -> ux_transfer_request_data_pointer = descriptor_buffer; @@ -206,8 +210,8 @@ UINT status; transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_PRINTER_GET_DEVICE_ID; transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; transfer_request -> ux_transfer_request_value = 0; /* Do not support multiple configuration for now. */ - transfer_request -> ux_transfer_request_index = (interface -> ux_interface_descriptor.bInterfaceNumber << 8) | - (interface -> ux_interface_descriptor.bAlternateSetting ); + transfer_request -> ux_transfer_request_index = (interface_ptr -> ux_interface_descriptor.bInterfaceNumber << 8) | + (interface_ptr -> ux_interface_descriptor.bAlternateSetting ); #if defined(UX_HOST_STANDALONE) printer -> ux_host_class_printer_allocated = descriptor_buffer; @@ -224,7 +228,7 @@ UINT status; _ux_host_class_printer_name_parse(printer, descriptor_buffer, UX_HOST_CLASS_PRINTER_DESCRIPTOR_LENGTH); - } + } /* Free all used resources. */ _ux_utility_memory_free(descriptor_buffer); diff --git a/common/usbx_host_classes/src/ux_host_class_printer_soft_reset.c b/common/usbx_host_classes/src/ux_host_class_printer_soft_reset.c index 5faab001..c341155f 100644 --- a/common/usbx_host_classes/src/ux_host_class_printer_soft_reset.c +++ b/common/usbx_host_classes/src/ux_host_class_printer_soft_reset.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_printer_soft_reset PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,6 +77,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_printer_soft_reset(UX_HOST_CLASS_PRINTER *printer) @@ -84,7 +88,7 @@ UINT _ux_host_class_printer_soft_reset(UX_HOST_CLASS_PRINTER *printer) #if defined(UX_HOST_STANDALONE) UX_INTERRUPT_SAVE_AREA #endif -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; UINT status; @@ -142,7 +146,7 @@ UINT status; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; /* Need interface for wIndex. */ - interface = printer -> ux_host_class_printer_interface; + interface_ptr = printer -> ux_host_class_printer_interface; /* Create a transfer_request for the SOFT_RESET request. */ transfer_request -> ux_transfer_request_data_pointer = UX_NULL; @@ -150,7 +154,7 @@ UINT status; transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_PRINTER_SOFT_RESET; transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; transfer_request -> ux_transfer_request_value = 0; - transfer_request -> ux_transfer_request_index = interface -> ux_interface_descriptor.bInterfaceNumber; + transfer_request -> ux_transfer_request_index = interface_ptr -> ux_interface_descriptor.bInterfaceNumber; #if defined(UX_HOST_STANDALONE) diff --git a/common/usbx_host_classes/src/ux_host_class_printer_status_get.c b/common/usbx_host_classes/src/ux_host_class_printer_status_get.c index 4d813dd1..80a519e2 100644 --- a/common/usbx_host_classes/src/ux_host_class_printer_status_get.c +++ b/common/usbx_host_classes/src/ux_host_class_printer_status_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_printer_status_get PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_printer_status_get(UX_HOST_CLASS_PRINTER *printer, ULONG *printer_status) @@ -89,7 +93,7 @@ UINT _ux_host_class_printer_status_get(UX_HOST_CLASS_PRINTER *printer, ULONG *p #if defined(UX_HOST_STANDALONE) UX_INTERRUPT_SAVE_AREA #endif -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; UINT status; @@ -152,7 +156,7 @@ UCHAR * printer_status_buffer; } /* Need interface for wIndex. */ - interface = printer -> ux_host_class_printer_interface; + interface_ptr = printer -> ux_host_class_printer_interface; /* Create a transfer_request for the GET_STATUS request. */ transfer_request -> ux_transfer_request_data_pointer = printer_status_buffer; @@ -160,7 +164,7 @@ UCHAR * printer_status_buffer; transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_PRINTER_GET_STATUS; transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; transfer_request -> ux_transfer_request_value = 0; - transfer_request -> ux_transfer_request_index = interface -> ux_interface_descriptor.bInterfaceNumber; + transfer_request -> ux_transfer_request_index = interface_ptr -> ux_interface_descriptor.bInterfaceNumber; #if defined(UX_HOST_STANDALONE) diff --git a/common/usbx_host_classes/src/ux_host_class_printer_write.c b/common/usbx_host_classes/src/ux_host_class_printer_write.c index b3bb58ce..c757f388 100644 --- a/common/usbx_host_classes/src/ux_host_class_printer_write.c +++ b/common/usbx_host_classes/src/ux_host_class_printer_write.c @@ -95,7 +95,7 @@ ULONG transfer_flags; UX_TRANSFER *transfer_request; UINT status; ULONG transfer_request_length; - + /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_PRINTER_WRITE, printer, data_pointer, requested_length, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) @@ -136,7 +136,7 @@ ULONG transfer_request_length; /* Get the pointer to the bulk out endpoint transfer request. */ transfer_request = &printer -> ux_host_class_printer_bulk_out_endpoint -> ux_endpoint_transfer_request; - + #if defined(UX_HOST_STANDALONE) /* Enable blocking transfer flags. */ @@ -166,7 +166,7 @@ ULONG transfer_request_length; if (status == UX_SUCCESS) { #if !defined(UX_HOST_STANDALONE) - + /* Wait for the completion of the transfer request. */ status = _ux_host_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, UX_MS_TO_TICK(UX_HOST_CLASS_PRINTER_CLASS_TRANSFER_TIMEOUT)); diff --git a/common/usbx_host_classes/src/ux_host_class_storage_activate.c b/common/usbx_host_classes/src/ux_host_class_storage_activate.c index db824dca..f8ff0a14 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_activate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_storage_activate PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,19 +77,23 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* added standalone support. */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_storage_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_STORAGE *storage; UINT status; /* The storage is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Obtain memory for this class instance. The memory used MUST BE allocated from a CACHE SAFE memory since the buffer for the CSW is an array contained within each storage instance. */ @@ -101,16 +105,16 @@ UINT status; storage -> ux_host_class_storage_class = command -> ux_host_class_command_class_ptr; /* Store the interface container into the storage class instance. */ - storage -> ux_host_class_storage_interface = interface; + storage -> ux_host_class_storage_interface = interface_ptr; /* Store the device container into the storage class instance. */ - storage -> ux_host_class_storage_device = interface -> ux_interface_configuration -> ux_configuration_device; + storage -> ux_host_class_storage_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* Create this class instance. */ _ux_host_stack_class_instance_create(command -> ux_host_class_command_class_ptr, (VOID *) storage); /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) storage; + interface_ptr -> ux_interface_class_instance = (VOID *) storage; #if defined(UX_HOST_STANDALONE) @@ -162,7 +166,7 @@ UINT status; _ux_host_stack_class_instance_destroy(storage -> ux_host_class_storage_class, (VOID *) storage); /* This instance of the device must also be removed in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) UX_NULL; + interface_ptr -> ux_interface_class_instance = (VOID *) UX_NULL; /* Free memory for class instance. */ _ux_utility_memory_free(storage); diff --git a/common/usbx_host_classes/src/ux_host_class_storage_device_initialize.c b/common/usbx_host_classes/src/ux_host_class_storage_device_initialize.c index 13f8fbdc..595fef29 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_device_initialize.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_device_initialize.c @@ -220,7 +220,7 @@ UINT inst_index; _ux_system_host -> ux_system_host_change_function(UX_STORAGE_MEDIA_INSERTION, storage -> ux_host_class_storage_class, (VOID *) storage_media); } - + /* Media inserted in slot, done. */ break; } diff --git a/common/usbx_host_classes/src/ux_host_class_storage_driver_entry.c b/common/usbx_host_classes/src/ux_host_class_storage_driver_entry.c index 4d7fc2ae..c16e27f5 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_driver_entry.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_driver_entry.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Storage Class */ /** */ @@ -49,9 +49,6 @@ #define UX_MEDIA FX_MEDIA VOID _ux_host_class_storage_driver_entry(UX_MEDIA *media); -/* Partition is not managed. */ -#define _ux_host_class_storage_media_partition_start(m) (0) - /* FX driver is available to support FX as external module. */ #ifndef UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE #define UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE @@ -59,9 +56,6 @@ VOID _ux_host_class_storage_driver_entry(UX_MEDIA *media); #endif #else -/* Partition is mounted in UX. */ -#define _ux_host_class_storage_media_partition_start(m) (m)->ux_host_class_storage_media_partition_start - /* FX driver is used for RTOS mode by default. */ #ifndef UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE #define UX_HOST_CLASS_STORAGE_DRIVER_ENTRY_ENABLE @@ -75,13 +69,13 @@ VOID _ux_host_class_storage_driver_entry(UX_MEDIA *media); /* FUNCTION RELEASE */ /* */ /* _ux_host_class_storage_driver_entry PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ +/* */ /* This function is the entry point for the FileX file system. All */ /* FileX driver I/O calls are are multiplexed here and rerouted to */ /* the proper USB storage class functions. */ @@ -91,52 +85,49 @@ VOID _ux_host_class_storage_driver_entry(UX_MEDIA *media); /* flow, and can be directly used in application after mounted. */ /* */ /* When the entry is for no FX mode (FX in external module, and USBX */ -/* is compiled without FileX integration), it is an example without */ +/* is compiled without FileX integration), it is an example with */ /* disk partition support. In this case the FX media does not operate */ /* inside the storage flow. Actions are taken when application mounts */ /* media to FX_MEDIA and then have access to media APIs. */ /* */ -/* In no FX mode demo, it assumes whole media is managed (start from */ -/* sector 0) without partitions. */ +/* In no FX mode demo, it assumes media is managed with partition */ +/* start from sector address of FX_MEDIA::fx_media_reserved_for_user. */ /* */ /* The following links are not initialized in no FX mode, they must be */ /* initialized before using the entry in no FX mode: */ -/* - FX_MEDIA::fx_media_driver_info Pointer to storage instance */ /* - FX_MEDIA::fx_media_reserved_for_user */ -/* Pointer to the mounted media */ -/* instance */ +/* Partition start sector inside */ +/* the whole storage media, must */ +/* set before media open */ +/* - FX_MEDIA::fx_media_driver_info Pointer to storage media, */ +/* assigned while calling media */ +/* open (fx_media_open) */ +/* */ +/* INPUT */ +/* */ +/* media FileX media pointer */ +/* */ +/* OUTPUT */ /* */ -/* To support partitions in no FX mode, new struct should be created */ -/* to include storage media and partition information, the sample code */ -/* must be modified to use such a struct to access partitions, and */ -/* partitions must be scanned outside in application to fill related */ -/* fields in such a struct. */ +/* None */ +/* */ +/* CALLS */ /* */ -/* INPUT */ -/* */ -/* media FileX media pointer */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ /* _ux_host_class_storage_sense_code_translate */ -/* Translate error status codes */ -/* _ux_host_class_storage_media_read Read sector(s) */ -/* _ux_host_class_storage_media_write Write sector(s) */ -/* _ux_host_semaphore_get Get protection semaphore */ -/* _ux_host_semaphore_put Release protection semaphore */ -/* */ -/* CALLED BY */ -/* */ -/* FileX */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* Translate error status codes */ +/* _ux_host_class_storage_media_read Read sector(s) */ +/* _ux_host_class_storage_media_write Write sector(s) */ +/* _ux_host_semaphore_get Get protection semaphore */ +/* _ux_host_semaphore_put Release protection semaphore */ +/* */ +/* CALLED BY */ +/* */ +/* FileX */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* added option to disable FX */ @@ -148,6 +139,9 @@ VOID _ux_host_class_storage_driver_entry(UX_MEDIA *media); /* added implement to support */ /* external FX mode, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved external FX mode, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_host_class_storage_driver_entry(FX_MEDIA *media) @@ -156,14 +150,20 @@ VOID _ux_host_class_storage_driver_entry(FX_MEDIA *media) UINT status; UX_HOST_CLASS_STORAGE *storage; UX_HOST_CLASS_STORAGE_MEDIA *storage_media; - +ULONG partition_start; - /* Get the pointer to the storage instance. */ - storage = (UX_HOST_CLASS_STORAGE *) media -> fx_media_driver_info; - /* Get the pointer to the media instance. */ + /* Get the pointers to the instances and partition start. */ +#if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) + storage = (UX_HOST_CLASS_STORAGE *) media -> fx_media_driver_info; storage_media = (UX_HOST_CLASS_STORAGE_MEDIA *) media -> fx_media_reserved_for_user; - + partition_start = storage_media -> ux_host_class_storage_media_partition_start; +#else + storage_media = (UX_HOST_CLASS_STORAGE_MEDIA *) media -> fx_media_driver_info; + storage = storage_media -> ux_host_class_storage_media_storage; + partition_start = (ULONG) media -> fx_media_reserved_for_user; +#endif + /* Ensure the instance is valid. */ if ((storage -> ux_host_class_storage_state != UX_HOST_CLASS_INSTANCE_LIVE) && (storage -> ux_host_class_storage_state != UX_HOST_CLASS_INSTANCE_MOUNTING)) @@ -199,13 +199,13 @@ UX_HOST_CLASS_STORAGE_MEDIA *storage_media; /* Restore the LUN number from the media instance. */ storage -> ux_host_class_storage_lun = storage_media -> ux_host_class_storage_media_lun; - + /* And the sector size. */ storage -> ux_host_class_storage_sector_size = storage_media -> ux_host_class_storage_media_sector_size; - + #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX) - + /* Restore current used last sector number. */ storage -> ux_host_class_storage_last_sector_number = storage_media -> ux_host_class_storage_media_number_sectors - 1; @@ -219,8 +219,7 @@ UX_HOST_CLASS_STORAGE_MEDIA *storage_media; /* Read one or more sectors. */ status = _ux_host_class_storage_media_read(storage, - media -> fx_media_driver_logical_sector + - _ux_host_class_storage_media_partition_start(storage_media), + media -> fx_media_driver_logical_sector + partition_start, media -> fx_media_driver_sectors, media -> fx_media_driver_buffer); @@ -240,14 +239,13 @@ UX_HOST_CLASS_STORAGE_MEDIA *storage_media; _ux_host_class_storage_sense_code_translate(storage, status); } break; - + case FX_DRIVER_WRITE: /* Write one or more sectors. */ status = _ux_host_class_storage_media_write(storage, - media -> fx_media_driver_logical_sector + - _ux_host_class_storage_media_partition_start(storage_media), + media -> fx_media_driver_logical_sector + partition_start, media -> fx_media_driver_sectors, media -> fx_media_driver_buffer); @@ -291,10 +289,10 @@ UX_HOST_CLASS_STORAGE_MEDIA *storage_media; _ux_host_class_storage_media_check(storage); #endif - /* Check for media protection. We must do this operation here because FileX clears all the + /* Check for media protection. We must do this operation here because FileX clears all the media fields before init. */ if (storage -> ux_host_class_storage_write_protected_media == UX_TRUE) - + /* The media is Write Protected. We tell FileX. */ media -> fx_media_driver_write_protect = UX_TRUE; @@ -314,9 +312,8 @@ UX_HOST_CLASS_STORAGE_MEDIA *storage_media; /* Read the media boot sector. */ status = _ux_host_class_storage_media_read(storage, - _ux_host_class_storage_media_partition_start(storage_media), 1, - media -> fx_media_driver_buffer); - + partition_start, 1, media -> fx_media_driver_buffer); + /* Check completion status. */ if (status == UX_SUCCESS) media -> fx_media_driver_status = FX_SUCCESS; @@ -333,14 +330,13 @@ UX_HOST_CLASS_STORAGE_MEDIA *storage_media; _ux_host_class_storage_sense_code_translate(storage,status); } break; - + case FX_DRIVER_BOOT_WRITE: /* Write the boot sector. */ status = _ux_host_class_storage_media_write(storage, - _ux_host_class_storage_media_partition_start(storage_media), 1, - media -> fx_media_driver_buffer); + partition_start, 1, media -> fx_media_driver_buffer); /* Check completion status. */ if (status == UX_SUCCESS) diff --git a/common/usbx_host_classes/src/ux_host_class_storage_media_get.c b/common/usbx_host_classes/src/ux_host_class_storage_media_get.c index 57cbaad3..13c2a4c8 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_media_get.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_media_get.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_storage_media_get PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,6 +74,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined media to search, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* cleared CSTAT warning, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_storage_media_get(UX_HOST_CLASS_STORAGE *storage, @@ -88,6 +91,7 @@ UINT _ux_host_class_storage_media_get(UX_HOST_CLASS_STORAGE *storage, #else UX_HOST_CLASS_STORAGE_MEDIA *storage_medias; +UX_HOST_CLASS_STORAGE_MEDIA *storage_media_inst; UX_HOST_CLASS *class_inst; UINT scan_index; @@ -105,23 +109,26 @@ UINT scan_index; /* Search media to find the right one. */ for(scan_index = 0; scan_index < UX_HOST_CLASS_STORAGE_MAX_MEDIA; scan_index ++) { + storage_media_inst = &storage_medias[scan_index]; /* Skip storage media not used. */ - if (storage_medias[scan_index].ux_host_class_storage_media_status != UX_USED) + if (storage_media_inst -> ux_host_class_storage_media_status != UX_USED) continue; /* Skip storage media not belong to the storage. */ - if (storage_medias[scan_index].ux_host_class_storage_media_storage != storage) + if (storage_media_inst -> ux_host_class_storage_media_storage != storage) continue; /* Skip storage media with different LUN. */ - if (storage_medias[scan_index].ux_host_class_storage_media_lun != media_lun) + if (storage_media_inst -> ux_host_class_storage_media_lun != media_lun) continue; /* Store the media instance. */ - *storage_media = &storage_medias[scan_index]; + { + *storage_media = storage_media_inst; return(UX_SUCCESS); } + } /* Media not found. */ return(UX_ERROR); diff --git a/common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c b/common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c index 7a6d021c..80fe330f 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c @@ -53,7 +53,7 @@ static inline UINT _ux_host_class_storage_transport_sense_check(UX_HOST_CLASS_ST /* FUNCTION RELEASE */ /* */ /* _ux_host_class_storage_tasks_run PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -95,6 +95,10 @@ static inline UINT _ux_host_class_storage_transport_sense_check(UX_HOST_CLASS_ST /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_storage_tasks_run(UX_HOST_CLASS *storage_class) @@ -127,7 +131,7 @@ UCHAR state; ULONG tick_now, tick_elapsed; UINT status; UX_TRANSFER *trans; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; /* If storage not live, start initialize. */ if (storage -> ux_host_class_storage_state == UX_HOST_CLASS_INSTANCE_MOUNTING) @@ -202,10 +206,10 @@ UX_INTERFACE *interface; { /* This fails storage activation. */ - interface = storage -> ux_host_class_storage_interface; + interface_ptr = storage -> ux_host_class_storage_interface; _ux_host_stack_class_instance_destroy( storage -> ux_host_class_storage_class, (VOID *) storage); - interface -> ux_interface_class_instance = (VOID *) UX_NULL; + interface_ptr -> ux_interface_class_instance = (VOID *) UX_NULL; _ux_utility_memory_free(storage); return; } diff --git a/common/usbx_host_classes/src/ux_host_class_storage_transport_run.c b/common/usbx_host_classes/src/ux_host_class_storage_transport_run.c index 927a0994..26a09ee8 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_transport_run.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_transport_run.c @@ -63,7 +63,7 @@ static inline VOID _ux_host_class_storage_transport_ep_reset(UX_HOST_CLASS_STORA /* FUNCTION RELEASE */ /* */ /* _ux_host_class_storage_transport_run PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -97,6 +97,10 @@ static inline VOID _ux_host_class_storage_transport_ep_reset(UX_HOST_CLASS_STORA /* DATE NAME DESCRIPTION */ /* */ /* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_storage_transport_run(UX_HOST_CLASS_STORAGE *storage) @@ -577,12 +581,12 @@ UCHAR csw_status; } static inline VOID _ux_host_class_storage_transport_ms_reset(UX_HOST_CLASS_STORAGE *storage) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *endpoint; UX_TRANSFER *trans; /* Prepare MSReset() */ - interface = storage -> ux_host_class_storage_interface; + interface_ptr = storage -> ux_host_class_storage_interface; endpoint = &storage -> ux_host_class_storage_device -> ux_device_control_endpoint; trans = &endpoint -> ux_endpoint_transfer_request; @@ -592,7 +596,7 @@ UX_TRANSFER *trans; trans -> ux_transfer_request_function = UX_HOST_CLASS_STORAGE_RESET; trans -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; trans -> ux_transfer_request_value = 0; - trans -> ux_transfer_request_index = interface -> ux_interface_descriptor.bInterfaceNumber; + trans -> ux_transfer_request_index = interface_ptr -> ux_interface_descriptor.bInterfaceNumber; UX_TRANSFER_STATE_RESET(trans); storage -> ux_host_class_storage_trans = trans; diff --git a/common/usbx_host_classes/src/ux_host_class_video_activate.c b/common/usbx_host_classes/src/ux_host_class_video_activate.c index 7a703678..66e5aff8 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_activate.c +++ b/common/usbx_host_classes/src/ux_host_class_video_activate.c @@ -159,7 +159,7 @@ UCHAR *baInterfaceNr; /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_activate PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -213,12 +213,16 @@ UCHAR *baInterfaceNr; /* internal clean up, */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_activate(UX_HOST_CLASS_COMMAND *command) { -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_HOST_CLASS_VIDEO *video; UINT status; UX_HOST_CLASS_VIDEO_DESCRIPTORS_PARSER parser; @@ -226,12 +230,12 @@ UX_HOST_CLASS_VIDEO_DESCRIPTORS_PARSER parser; /* The video is always activated by the interface descriptor and not the device descriptor. */ - interface = (UX_INTERFACE *) command -> ux_host_class_command_container; + interface_ptr = (UX_INTERFACE *) command -> ux_host_class_command_container; /* Check the subclass of the new device. If it is a Video Control Interface, we don't need to create an instance of this function. When we get the streaming interface, we will search the video control interface for the device. */ - if (interface -> ux_interface_descriptor.bInterfaceSubClass == UX_HOST_CLASS_VIDEO_SUBCLASS_CONTROL) + if (interface_ptr -> ux_interface_descriptor.bInterfaceSubClass == UX_HOST_CLASS_VIDEO_SUBCLASS_CONTROL) return(UX_SUCCESS); /* Obtain memory for this class instance. */ @@ -243,13 +247,13 @@ UX_HOST_CLASS_VIDEO_DESCRIPTORS_PARSER parser; video -> ux_host_class_video_class = command -> ux_host_class_command_class_ptr; /* Store the interface container into the video class instance. */ - video -> ux_host_class_video_streaming_interface = interface; + video -> ux_host_class_video_streaming_interface = interface_ptr; /* Store the device container into the video class instance. */ - video -> ux_host_class_video_device = interface -> ux_interface_configuration -> ux_configuration_device; + video -> ux_host_class_video_device = interface_ptr -> ux_interface_configuration -> ux_configuration_device; /* This instance of the device must also be stored in the interface container. */ - interface -> ux_interface_class_instance = (VOID *) video; + interface_ptr -> ux_interface_class_instance = (VOID *) video; /* Create this class instance. */ _ux_host_stack_class_instance_create(video -> ux_host_class_video_class, (VOID *) video); @@ -332,7 +336,7 @@ UX_HOST_CLASS_VIDEO_DESCRIPTORS_PARSER parser; _ux_host_stack_class_instance_destroy(video -> ux_host_class_video_class, (VOID *) video); /* This instance of the device must also be cleared in the interface container. */ - interface -> ux_interface_class_instance = UX_NULL; + interface_ptr -> ux_interface_class_instance = UX_NULL; /* Free instance memory. */ _ux_utility_memory_free(video); diff --git a/common/usbx_host_classes/src/ux_host_class_video_alternate_setting_locate.c b/common/usbx_host_classes/src/ux_host_class_video_alternate_setting_locate.c index 8d67b008..34fc4244 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_alternate_setting_locate.c +++ b/common/usbx_host_classes/src/ux_host_class_video_alternate_setting_locate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_alternate_setting_locate PORTABLE C */ -/* 6.1.9 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,13 +73,17 @@ /* use pre-calculated value */ /* instead of wMaxPacketSize, */ /* resulting in version 6.1.9 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_alternate_setting_locate(UX_HOST_CLASS_VIDEO *video, UINT max_payload_size, UINT *alternate_setting) { UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *endpoint; UINT streaming_interface; UINT payload_size; @@ -88,22 +92,22 @@ UINT alternate_setting_found; configuration = video -> ux_host_class_video_streaming_interface -> ux_interface_configuration; - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; streaming_interface = video -> ux_host_class_video_streaming_interface -> ux_interface_descriptor.bInterfaceNumber; alternate_setting_found = UX_FALSE; /* Scan all interfaces. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* Search for the streaming interface with a endpoint. */ - if ((interface -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && - (interface -> ux_interface_first_endpoint != 0)) + if ((interface_ptr -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && + (interface_ptr -> ux_interface_first_endpoint != 0)) { /* Get the max packet size of the endpoint. */ - endpoint = interface -> ux_interface_first_endpoint; + endpoint = interface_ptr -> ux_interface_first_endpoint; payload_size = endpoint -> ux_endpoint_transfer_request.ux_transfer_request_packet_length; /* Check if the payload size is equal or greater than the required payload size. */ @@ -119,7 +123,7 @@ UINT alternate_setting_found; current_payload_size = payload_size; /* Save the found alternate setting number. */ - *alternate_setting = interface -> ux_interface_descriptor.bAlternateSetting; + *alternate_setting = interface_ptr -> ux_interface_descriptor.bAlternateSetting; } else { @@ -132,14 +136,14 @@ UINT alternate_setting_found; current_payload_size = payload_size; /* Save the found alternate setting number. */ - *alternate_setting = interface -> ux_interface_descriptor.bAlternateSetting; + *alternate_setting = interface_ptr -> ux_interface_descriptor.bAlternateSetting; } } } } /* Move to next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } /* Check if we found the alternate setting. */ diff --git a/common/usbx_host_classes/src/ux_host_class_video_channel_start.c b/common/usbx_host_classes/src/ux_host_class_video_channel_start.c index 45ee47b2..77df194e 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_channel_start.c +++ b/common/usbx_host_classes/src/ux_host_class_video_channel_start.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_channel_start PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -88,6 +88,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_channel_start(UX_HOST_CLASS_VIDEO *video, UX_HOST_CLASS_VIDEO_PARAMETER_CHANNEL *video_parameter) @@ -99,7 +103,7 @@ UINT status; UCHAR *control_buffer; UINT alternate_setting; UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UX_ENDPOINT *endpoint; ULONG endpoint_index; UINT streaming_interface; @@ -207,31 +211,31 @@ UINT max_payload_size; /* Now the Commit has been done, the alternate setting can be requested. */ /* We found the alternate setting for the sampling values demanded, now we need to search its container. */ - configuration = video -> ux_host_class_video_streaming_interface -> ux_interface_configuration; - interface = configuration -> ux_configuration_first_interface; + configuration = video -> ux_host_class_video_streaming_interface -> ux_interface_configuration; + interface_ptr = configuration -> ux_configuration_first_interface; /* Scan all interfaces. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* We search for both the right interface and alternate setting. */ - if ((interface -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && - (interface -> ux_interface_descriptor.bAlternateSetting == alternate_setting)) + if ((interface_ptr -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && + (interface_ptr -> ux_interface_descriptor.bAlternateSetting == alternate_setting)) { /* We have found the right interface/alternate setting combination The stack will select it for us. */ - status = _ux_host_stack_interface_setting_select(interface); + status = _ux_host_stack_interface_setting_select(interface_ptr); /* If the alternate setting for the streaming interface could be selected, we memorize it. */ if (status == UX_SUCCESS) { /* Memorize the interface. */ - video -> ux_host_class_video_streaming_interface = interface; + video -> ux_host_class_video_streaming_interface = interface_ptr; /* We need to research the isoch endpoint now. */ - for (endpoint_index = 0; endpoint_index < interface -> ux_interface_descriptor.bNumEndpoints; endpoint_index++) + for (endpoint_index = 0; endpoint_index < interface_ptr -> ux_interface_descriptor.bNumEndpoints; endpoint_index++) { /* Get the list of endpoints one by one. */ @@ -248,12 +252,12 @@ UINT max_payload_size; /* We have found the isoch endpoint, save it. */ video -> ux_host_class_video_isochronous_endpoint = endpoint; - + /* Save the max payload size. It's not exceeding endpoint bandwidth since the interface alternate setting is located by max payload size. */ video -> ux_host_class_video_current_max_payload_size = max_payload_size; - + /* Free all used resources. */ _ux_utility_memory_free(control_buffer); @@ -269,7 +273,7 @@ UINT max_payload_size; } /* Move to next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } } } diff --git a/common/usbx_host_classes/src/ux_host_class_video_control_request.c b/common/usbx_host_classes/src/ux_host_class_video_control_request.c index df942c27..9f07375f 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_control_request.c +++ b/common/usbx_host_classes/src/ux_host_class_video_control_request.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_control_request PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,10 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_control_request(UX_HOST_CLASS_VIDEO *video, @@ -93,7 +97,7 @@ UX_TRANSFER *transfer_request; UINT status; UCHAR *control_buffer; UCHAR request_direction; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UCHAR interface_number; @@ -155,8 +159,8 @@ UCHAR interface_number; { /* Only one streaming interface is supported now. */ - interface = video -> ux_host_class_video_streaming_interface; - interface_number = (UCHAR)interface -> ux_interface_descriptor.bInterfaceNumber; + interface_ptr = video -> ux_host_class_video_streaming_interface; + interface_number = (UCHAR)interface_ptr -> ux_interface_descriptor.bInterfaceNumber; } /* Create a transfer request for the request. */ diff --git a/common/usbx_host_classes/src/ux_host_class_video_descriptor_get.c b/common/usbx_host_classes/src/ux_host_class_video_descriptor_get.c index 2bf28a7d..3f38d8fc 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_descriptor_get.c +++ b/common/usbx_host_classes/src/ux_host_class_video_descriptor_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_descriptor_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,31 +72,55 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used shared device config */ +/* descriptor for enum scan, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_descriptor_get(UX_HOST_CLASS_VIDEO *video) { +UX_DEVICE *device; +UX_CONFIGURATION *configuration; UCHAR * descriptor; UX_ENDPOINT *control_endpoint; UX_TRANSFER *transfer_request; -UX_CONFIGURATION configuration; UINT status; ULONG total_configuration_length; + /* Get device, current configuration. */ + device = video -> ux_host_class_video_device; + configuration = device -> ux_device_current_configuration; + + /* Check if descriptor is previously saved. */ + if (device -> ux_device_packed_configuration != UX_NULL) + { + video -> ux_host_class_video_configuration_descriptor = + device -> ux_device_packed_configuration; + video -> ux_host_class_video_configuration_descriptor_length = + configuration -> ux_configuration_descriptor.wTotalLength; + + /* Descriptor must be kept after enum. */ + device -> ux_device_packed_configuration_keep_count ++; + return(UX_SUCCESS); + } + + /* Get total length of configuration descriptors. */ + total_configuration_length = configuration -> ux_configuration_descriptor.wTotalLength; /* We need to get the default control endpoint transfer request pointer. */ - control_endpoint = &video -> ux_host_class_video_device -> ux_device_control_endpoint; + control_endpoint = &device -> ux_device_control_endpoint; transfer_request = &control_endpoint -> ux_endpoint_transfer_request; /* Need to allocate memory for the descriptor. */ - descriptor = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_CONFIGURATION_DESCRIPTOR_LENGTH); + descriptor = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, total_configuration_length); if (descriptor == UX_NULL) return(UX_MEMORY_INSUFFICIENT); /* Create a transfer request for the GET_DESCRIPTOR request. */ transfer_request -> ux_transfer_request_data_pointer = descriptor; - transfer_request -> ux_transfer_request_requested_length = UX_CONFIGURATION_DESCRIPTOR_LENGTH; + transfer_request -> ux_transfer_request_requested_length = total_configuration_length; transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR; transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; transfer_request -> ux_transfer_request_value = UX_CONFIGURATION_DESCRIPTOR_ITEM << 8; @@ -106,49 +130,22 @@ ULONG total_configuration_length; status = _ux_host_stack_transfer_request(transfer_request); /* Check for correct transfer and entire descriptor returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == UX_CONFIGURATION_DESCRIPTOR_LENGTH)) + if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == total_configuration_length)) { - /* The descriptor is in a packed format, parse it locally. */ - _ux_utility_descriptor_parse(descriptor, _ux_system_configuration_descriptor_structure, - UX_CONFIGURATION_DESCRIPTOR_ENTRIES, (UCHAR *) &configuration.ux_configuration_descriptor); - - /* Now we have the configuration descriptor which will tell us how many - bytes there are in the entire descriptor. */ - total_configuration_length = configuration.ux_configuration_descriptor.wTotalLength; - - /* Free the previous descriptor. */ - _ux_utility_memory_free(descriptor); - - /* Allocate enough memory to read all descriptors attached - to this configuration. We will save it until the class is unmounted. */ - descriptor = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, total_configuration_length); - if (descriptor == UX_NULL) - return(UX_MEMORY_INSUFFICIENT); + /* Save the address of the entire configuration descriptor of the video device. */ + video -> ux_host_class_video_configuration_descriptor = descriptor; - /* Set the length we need to retrieve. */ - transfer_request -> ux_transfer_request_requested_length = total_configuration_length; + /* Save the length of the entire descriptor too. */ + video -> ux_host_class_video_configuration_descriptor_length = total_configuration_length; - /* And reprogram the descriptor buffer address. */ - transfer_request -> ux_transfer_request_data_pointer = descriptor; + /* Keep descriptor to be shared for this device. */ + device -> ux_device_packed_configuration = descriptor; + device -> ux_device_packed_configuration_keep_count ++; - /* Send request to HCD layer. */ - status = _ux_host_stack_transfer_request(transfer_request); - - /* Check for correct transfer and entire descriptor returned. */ - if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == total_configuration_length)) - { - - /* Save the address of the entire configuration descriptor of the video device. */ - video -> ux_host_class_video_configuration_descriptor = descriptor; - - /* Save the length of the entire descriptor too. */ - video -> ux_host_class_video_configuration_descriptor_length = total_configuration_length; - - /* We do not free the resource for the descriptor until the device is - plugged out. */ - return(UX_SUCCESS); - } + /* We do not free the resource for the descriptor until the device is + plugged out. */ + return(UX_SUCCESS); } /* Free all used resources. */ @@ -157,4 +154,3 @@ ULONG total_configuration_length; /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_video_entities_parse.c b/common/usbx_host_classes/src/ux_host_class_video_entities_parse.c index e628c6ff..cf361f6b 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_entities_parse.c +++ b/common/usbx_host_classes/src/ux_host_class_video_entities_parse.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_entities_parse PORTABLE C */ -/* 6.1.8 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,10 @@ /* 08-02-2021 Wen Wang Modified comment(s), */ /* fixed spelling error, */ /* resulting in version 6.1.8 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_entities_parse(UX_HOST_CLASS_VIDEO *video, @@ -93,7 +97,7 @@ UINT _ux_host_class_video_entities_parse(UX_HOST_CLASS_VIDEO *video, UCHAR *descriptor; UCHAR *interface_descriptor; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; ULONG total_descriptor_length; ULONG descriptor_length; ULONG descriptor_type; @@ -145,8 +149,8 @@ UINT status; { /* VideoStreaming interface, currently only one supported. */ - interface = video -> ux_host_class_video_streaming_interface; - if (descriptor[2] == interface -> ux_interface_descriptor.bInterfaceNumber) + interface_ptr = video -> ux_host_class_video_streaming_interface; + if (descriptor[2] == interface_ptr -> ux_interface_descriptor.bInterfaceNumber) /* Mark we have found it. */ interface_descriptor = descriptor; diff --git a/common/usbx_host_classes/src/ux_host_class_video_ioctl.c b/common/usbx_host_classes/src/ux_host_class_video_ioctl.c index b77715dd..352835cd 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_ioctl.c +++ b/common/usbx_host_classes/src/ux_host_class_video_ioctl.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_ioctl PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,6 +79,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* reset indexes of requests */ +/* ring when it is aborted, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_ioctl(UX_HOST_CLASS_VIDEO *video, ULONG ioctl_function, @@ -195,6 +199,10 @@ UX_HOST_CLASS_VIDEO_PARAMETER_FRAME_INTERVAL *interval_parameter; /* We need to abort transactions on the bulk In pipe. */ _ux_host_stack_endpoint_transfer_abort(video -> ux_host_class_video_isochronous_endpoint); + + /* All linked requests are aborted, reset indexes. */ + video -> ux_host_class_video_transfer_request_start_index = 0; + video -> ux_host_class_video_transfer_request_end_index = 0; /* Status is successful. */ status = UX_SUCCESS; diff --git a/common/usbx_host_classes/src/ux_host_class_video_stop.c b/common/usbx_host_classes/src/ux_host_class_video_stop.c index ba4328cf..22d19f78 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_stop.c +++ b/common/usbx_host_classes/src/ux_host_class_video_stop.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_stop PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,10 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed parameter/variable */ +/* names conflict C++ keyword, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_stop(UX_HOST_CLASS_VIDEO *video) @@ -85,7 +89,7 @@ UINT _ux_host_class_video_stop(UX_HOST_CLASS_VIDEO *video) UINT status; UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; +UX_INTERFACE *interface_ptr; UINT streaming_interface; @@ -106,27 +110,27 @@ UINT streaming_interface; /* We found the alternate setting for the sampling values demanded, now we need to search its container. */ configuration = video -> ux_host_class_video_streaming_interface -> ux_interface_configuration; - interface = configuration -> ux_configuration_first_interface; + interface_ptr = configuration -> ux_configuration_first_interface; /* Scan all interfaces. */ - while (interface != UX_NULL) + while (interface_ptr != UX_NULL) { /* We search for both the right interface and alternate setting. */ - if ((interface -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && - (interface -> ux_interface_descriptor.bAlternateSetting == 0)) + if ((interface_ptr -> ux_interface_descriptor.bInterfaceNumber == streaming_interface) && + (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0)) { /* We have found the right interface/alternate setting combination The stack will select it for us. */ - status = _ux_host_stack_interface_setting_select(interface); + status = _ux_host_stack_interface_setting_select(interface_ptr); /* If the alternate setting for the streaming interface could be selected, we memorize it. */ if (status == UX_SUCCESS) { /* Memorize the interface. */ - video -> ux_host_class_video_streaming_interface = interface; + video -> ux_host_class_video_streaming_interface = interface_ptr; /* There is no endpoint for the alternate setting 0. */ video -> ux_host_class_video_isochronous_endpoint = UX_NULL; @@ -140,7 +144,7 @@ UINT streaming_interface; } /* Move to next interface. */ - interface = interface -> ux_interface_next_interface; + interface_ptr = interface_ptr -> ux_interface_next_interface; } /* Unprotect thread reentry to this instance. */ diff --git a/common/usbx_host_classes/src/ux_host_class_video_transfer_buffer_add.c b/common/usbx_host_classes/src/ux_host_class_video_transfer_buffer_add.c index a30d72b9..62d9ccbc 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_transfer_buffer_add.c +++ b/common/usbx_host_classes/src/ux_host_class_video_transfer_buffer_add.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_transfer_buffer_add PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -85,6 +85,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* set pending on endpoint, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_transfer_buffer_add(UX_HOST_CLASS_VIDEO *video, UCHAR* buffer) @@ -92,6 +95,7 @@ UINT _ux_host_class_video_transfer_buffer_add(UX_HOST_CLASS_VIDEO *video, UCHAR UINT status; UX_TRANSFER *transfer_request; +UX_ENDPOINT *endpoint; ULONG transfer_index; ULONG packet_size; @@ -113,9 +117,12 @@ ULONG packet_size; if (status != UX_SUCCESS) return(status); + /* Get endpoint. */ + endpoint = video -> ux_host_class_video_isochronous_endpoint; + /* Ensure we have a selected interface that allows isoch transmission. */ - if ((video -> ux_host_class_video_isochronous_endpoint == UX_NULL) || - (video -> ux_host_class_video_isochronous_endpoint -> ux_endpoint_descriptor.wMaxPacketSize == 0)) + if ((endpoint == UX_NULL) || + (endpoint -> ux_endpoint_descriptor.wMaxPacketSize == 0)) { /* Unprotect thread reentry to this instance. */ @@ -146,14 +153,14 @@ ULONG packet_size; video->ux_host_class_video_transfer_request_start_index = transfer_index; /* Select the direction. We do this by taking the endpoint direction. */ - transfer_request -> ux_transfer_request_type = video -> ux_host_class_video_isochronous_endpoint -> - ux_endpoint_descriptor.bEndpointAddress & UX_REQUEST_DIRECTION; + transfer_request -> ux_transfer_request_type = endpoint -> + ux_endpoint_descriptor.bEndpointAddress & UX_REQUEST_DIRECTION; /* Calculate packet size. */ packet_size = video -> ux_host_class_video_current_max_payload_size; /* Fill the transfer request with all the required fields. */ - transfer_request -> ux_transfer_request_endpoint = video -> ux_host_class_video_isochronous_endpoint; + transfer_request -> ux_transfer_request_endpoint = endpoint; transfer_request -> ux_transfer_request_data_pointer = buffer; transfer_request -> ux_transfer_request_requested_length = packet_size; transfer_request -> ux_transfer_request_completion_function = _ux_host_class_video_transfer_request_callback; @@ -162,6 +169,9 @@ ULONG packet_size; /* Add single transfer. */ transfer_request -> ux_transfer_request_next_transfer_request = UX_NULL; + /* Set endpoint to pending state, for callback and abort to check. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_completion_code = UX_TRANSFER_STATUS_PENDING; + /* Transfer the transfer request. */ status = _ux_host_stack_transfer_request(transfer_request); @@ -171,4 +181,3 @@ ULONG packet_size; /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_video_transfer_buffers_add.c b/common/usbx_host_classes/src/ux_host_class_video_transfer_buffers_add.c index bfa1ffdb..4a5bbbb4 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_transfer_buffers_add.c +++ b/common/usbx_host_classes/src/ux_host_class_video_transfer_buffers_add.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_transfer_buffers_add PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -94,6 +94,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* set pending on endpoint, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_transfer_buffers_add(UX_HOST_CLASS_VIDEO *video, UCHAR** buffers, ULONG num_buffers) @@ -102,6 +105,7 @@ UINT _ux_host_class_video_transfer_buffers_add(UX_HOST_CLASS_VIDEO *video, UCHA UINT status; UX_TRANSFER *transfer_request; UX_TRANSFER *previous_transfer; +UX_ENDPOINT *endpoint; ULONG transfer_index; ULONG packet_size; UINT i; @@ -122,9 +126,12 @@ UINT i; if (status != UX_SUCCESS) return(status); + /* Get endpoint. */ + endpoint = video -> ux_host_class_video_isochronous_endpoint; + /* Ensure we have a selected interface that allows isoch transmission. */ - if ((video -> ux_host_class_video_isochronous_endpoint == UX_NULL) || - (video -> ux_host_class_video_isochronous_endpoint -> ux_endpoint_descriptor.wMaxPacketSize == 0)) + if ((endpoint == UX_NULL) || + (endpoint -> ux_endpoint_descriptor.wMaxPacketSize == 0)) { /* Unprotect thread reentry to this instance. */ @@ -177,11 +184,11 @@ UINT i; transfer_request = &video->ux_host_class_video_transfer_requests[transfer_index]; /* Select the direction. We do this by taking the endpoint direction. */ - transfer_request -> ux_transfer_request_type = video -> ux_host_class_video_isochronous_endpoint -> - ux_endpoint_descriptor.bEndpointAddress & UX_REQUEST_DIRECTION; + transfer_request -> ux_transfer_request_type = endpoint -> + ux_endpoint_descriptor.bEndpointAddress & UX_REQUEST_DIRECTION; /* Fill the transfer request with all the required fields. */ - transfer_request -> ux_transfer_request_endpoint = video -> ux_host_class_video_isochronous_endpoint; + transfer_request -> ux_transfer_request_endpoint = endpoint; transfer_request -> ux_transfer_request_data_pointer = buffers[i]; transfer_request -> ux_transfer_request_requested_length = packet_size; transfer_request -> ux_transfer_request_completion_function = _ux_host_class_video_transfer_request_callback; @@ -207,7 +214,10 @@ UINT i; transfer_request = &video -> ux_host_class_video_transfer_requests[video->ux_host_class_video_transfer_request_start_index]; /* Move request index. */ - video->ux_host_class_video_transfer_request_start_index = transfer_index; + video -> ux_host_class_video_transfer_request_start_index = transfer_index; + + /* Set endpoint to pending state, for callback and abort to check. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_completion_code = UX_TRANSFER_STATUS_PENDING; /* Transfer the transfer request (list). */ status = _ux_host_stack_transfer_request(transfer_request); @@ -218,4 +228,3 @@ UINT i; /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_video_transfer_request.c b/common/usbx_host_classes/src/ux_host_class_video_transfer_request.c index 8c18beca..bfa1d8eb 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_transfer_request.c +++ b/common/usbx_host_classes/src/ux_host_class_video_transfer_request.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_transfer_request PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* set pending on endpoint, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_host_class_video_transfer_request(UX_HOST_CLASS_VIDEO *video, @@ -80,6 +83,7 @@ UINT _ux_host_class_video_transfer_request(UX_HOST_CLASS_VIDEO *video, { UINT status; +UX_ENDPOINT *endpoint; UX_TRANSFER *transfer_list; UX_TRANSFER *transfer_request; UX_TRANSFER *previous_transfer; @@ -87,6 +91,9 @@ UX_TRANSFER *previous_transfer; /* Get transfer request list head. */ transfer_list = &video_transfer_request -> ux_host_class_video_transfer_request; + /* Get endpoint. */ + endpoint = video -> ux_host_class_video_isochronous_endpoint; + /* Process the transfer request list (if multiple found). */ previous_transfer = UX_NULL; while(video_transfer_request) @@ -100,7 +107,7 @@ UX_TRANSFER *previous_transfer; ux_endpoint_descriptor.bEndpointAddress & UX_REQUEST_DIRECTION; /* Fill the transfer request with all the required fields. */ - transfer_request -> ux_transfer_request_endpoint = video -> ux_host_class_video_isochronous_endpoint; + transfer_request -> ux_transfer_request_endpoint = endpoint; transfer_request -> ux_transfer_request_data_pointer = video_transfer_request -> ux_host_class_video_transfer_request_data_pointer; transfer_request -> ux_transfer_request_requested_length = video_transfer_request -> ux_host_class_video_transfer_request_requested_length; transfer_request -> ux_transfer_request_completion_function = _ux_host_class_video_transfer_request_completed; @@ -123,10 +130,12 @@ UX_TRANSFER *previous_transfer; video_transfer_request = video_transfer_request -> ux_host_class_video_transfer_request_next_video_transfer_request; } + /* Set endpoint status to pending, for callback and abort to check. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_completion_code = UX_TRANSFER_STATUS_PENDING; + /* Transfer the transfer request (list). */ status = _ux_host_stack_transfer_request(transfer_list); /* Return completion status. */ return(status); } - diff --git a/common/usbx_host_classes/src/ux_host_class_video_transfer_request_callback.c b/common/usbx_host_classes/src/ux_host_class_video_transfer_request_callback.c index 764daa93..4ed67e3d 100644 --- a/common/usbx_host_classes/src/ux_host_class_video_transfer_request_callback.c +++ b/common/usbx_host_classes/src/ux_host_class_video_transfer_request_callback.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_video_transfer_request_callback PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,12 +69,16 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* checked pending state, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_host_class_video_transfer_request_callback(UX_TRANSFER *transfer_request) { UX_HOST_CLASS_VIDEO *video; +UX_ENDPOINT *endpoint; ULONG transfer_index; @@ -85,6 +89,11 @@ ULONG transfer_index; if (video == UX_NULL) return; + /* Check endpoint status. */ + endpoint = video -> ux_host_class_video_isochronous_endpoint; + if (endpoint -> ux_endpoint_transfer_request.ux_transfer_request_completion_code != UX_TRANSFER_STATUS_PENDING) + return; + /* The caller's transfer request needs to be updated. */ transfer_index = video -> ux_host_class_video_transfer_request_end_index; transfer_index++; @@ -101,4 +110,3 @@ ULONG transfer_index; /* Return to caller. */ return; } - diff --git a/common/usbx_host_controllers/inc/ux_hcd_ohci.h b/common/usbx_host_controllers/inc/ux_hcd_ohci.h index f42a0db6..acfb4e41 100755 --- a/common/usbx_host_controllers/inc/ux_hcd_ohci.h +++ b/common/usbx_host_controllers/inc/ux_hcd_ohci.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_hcd_ohci.h PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -53,6 +53,9 @@ /* 01-31-2022 Xiuwen Cai Modified comment(s), */ /* fixed HcPeriodicStart value,*/ /* resulting in version 6.1.10 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed OHCI PRSC issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -225,6 +228,9 @@ extern "C" { #define UX_OHCI_ERROR_BUFFER_UNDERRUN 0x0d #define UX_OHCI_NOT_ACCESSED 0x0e +#define UX_OHCI_PRSC_EVENT 0x1u + +#define UX_OHCI_PRSC_EVENT_TIMEOUT 100 /* Define OHCI HCCA structure. */ @@ -260,6 +266,8 @@ typedef struct UX_HCD_OHCI_STRUCT *ux_hcd_ohci_td_list; struct UX_OHCI_ISO_TD_STRUCT *ux_hcd_ohci_iso_td_list; + UX_EVENT_FLAGS_GROUP + ux_hcd_ohci_event_flags_group; } UX_HCD_OHCI; diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c b/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c index f7827a71..2c5fc4d7 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_hsisochronous_tds_process PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved uframe handling, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UX_EHCI_HSISO_TD* _ux_hcd_ehci_hsisochronous_tds_process( @@ -220,9 +223,19 @@ UINT i; fr_td -> ux_ehci_hsiso_td_frload = (UCHAR)(fr_td -> ux_ehci_hsiso_td_frload & ~(1u << frindex)); ed -> ux_ehci_hsiso_ed_frload = (USHORT)(ed -> ux_ehci_hsiso_ed_frload & ~(1u << frindex)); + /* HC processed. */ + ed -> ux_ehci_hsiso_ed_fr_hc ++; + + /* Unlink it from iTD. */ + fr_td -> ux_ehci_hsiso_td_fr_transfer[frindex & 1u] = UX_NULL; + /* Handle the request. */ transfer = ed -> ux_ehci_hsiso_ed_transfer_head; + /* If there is no transfer linked to, just ignore it. */ + if (transfer == UX_NULL) + break; + /* Convert error code to completion code. */ if (control & UX_EHCI_HSISO_STATUS_DATA_BUFFER_ERR) transfer -> ux_transfer_request_completion_code = UX_TRANSFER_BUFFER_OVERFLOW; @@ -241,12 +254,6 @@ UINT i; /* Save to actual length. */ transfer -> ux_transfer_request_actual_length = trans_bytes; - /* HC processed. */ - ed -> ux_ehci_hsiso_ed_fr_hc ++; - - /* Unlink it from iTD. */ - fr_td -> ux_ehci_hsiso_td_fr_transfer[frindex & 1u] = UX_NULL; - /* Unlink it from request list head. */ ed -> ux_ehci_hsiso_ed_transfer_head = transfer -> ux_transfer_request_next_transfer_request; @@ -446,6 +453,14 @@ UINT i; } /* if (ed -> ux_ehci_hsiso_ed_transfer_first_new) */ + /* If there is no transfer, need start again any way. */ + if (ed -> ux_ehci_hsiso_ed_frload == 0) + { + ed -> ux_ehci_hsiso_ed_frstart = 0xFF; + ed -> ux_ehci_hsiso_ed_fr_sw = 0; + ed -> ux_ehci_hsiso_ed_fr_hc = 0; + } + /* Return next iTD in scan list. */ return(next_scan_td); } diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_request_isochronous_transfer.c b/common/usbx_host_controllers/src/ux_hcd_ehci_request_isochronous_transfer.c index d3df1796..bbdf0f93 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_request_isochronous_transfer.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_request_isochronous_transfer.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_request_isochronous_transfer PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -86,6 +86,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved iso start up, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ehci_request_isochronous_transfer(UX_HCD_EHCI *hcd_ehci, UX_TRANSFER *transfer_request) @@ -141,6 +144,8 @@ UCHAR start = UX_FALSE; if (ied -> ux_ehci_hsiso_ed_frstart == 0xFF) { ied -> ux_ehci_hsiso_ed_frstart = 0xFE; + ied -> ux_ehci_hsiso_ed_fr_sw = 0; + ied -> ux_ehci_hsiso_ed_fr_hc = 0; start = UX_TRUE; } } diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c b/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c index f2df19a2..24d821d9 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_transfer_abort PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved iso abort support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ehci_transfer_abort(UX_HCD_EHCI *hcd_ehci,UX_TRANSFER *transfer_request) @@ -90,10 +93,15 @@ UINT _ux_hcd_ehci_transfer_abort(UX_HCD_EHCI *hcd_ehci,UX_TRANSFER *transfer_re UX_ENDPOINT *endpoint; UX_EHCI_HSISO_ED *ied; UX_EHCI_PERIODIC_LINK_POINTER lp; +UX_EHCI_HSISO_TD *fr_td; UX_TRANSFER **list_head; UX_TRANSFER *transfer; ULONG max_load_count; -ULONG remain_count; +ULONG frindex; +ULONG fr_start; +ULONG fr_req; +ULONG first_new_aborted = 1; + UX_PARAMETER_NOT_USED(hcd_ehci); @@ -145,19 +153,49 @@ ULONG remain_count; (*list_head) == transfer_request) { *list_head = UX_NULL; - remain_count = 0; + + /* Clear controls any way. */ + for (frindex = 0; frindex < 4; frindex ++) + { + + /* Get actual iTD used and clear controls. */ + fr_td = ied -> ux_ehci_hsiso_ed_fr_td[frindex]; + fr_td -> ux_ehci_hsiso_td_control[(frindex << 1)] &= ~UX_EHCI_HSISO_STATUS_ACTIVE; + fr_td -> ux_ehci_hsiso_td_control[(frindex << 1) + 1] &= ~UX_EHCI_HSISO_STATUS_ACTIVE; + fr_td -> ux_ehci_hsiso_td_frload = 0; + fr_td -> ux_ehci_hsiso_td_fr_transfer[0] = UX_NULL; + fr_td -> ux_ehci_hsiso_td_fr_transfer[1] = UX_NULL; + } + + /* Transfer needs restart. */ + ied -> ux_ehci_hsiso_ed_frstart = 0xFF; + ied -> ux_ehci_hsiso_ed_fr_hc = 0; + ied -> ux_ehci_hsiso_ed_fr_sw = 0; + ied -> ux_ehci_hsiso_ed_transfer_tail = UX_NULL; + ied -> ux_ehci_hsiso_ed_transfer_first_new = UX_NULL; + ied -> ux_ehci_hsiso_ed_frload = 0; } else { - /* At least one request remains. */ - remain_count = 1; + /* At least one request remains (no restart). */ + + /* Get the next micro-frame index. */ + fr_start = (ULONG)ied -> ux_ehci_hsiso_ed_fr_hc << ied -> ux_ehci_hsiso_ed_frinterval_shift; + fr_start += ied -> ux_ehci_hsiso_ed_frstart; + fr_start &= 0x7u; - /* Remove it and transfers after it. */ + /* First request micro-frame index offset is 0. */ + fr_req = 0; + + /* Remove the transfer and transfers after it. */ transfer = (*list_head) -> ux_transfer_request_next_transfer_request; while(transfer) { + /* Check next micro-frame index. */ + fr_req += ied -> ux_ehci_hsiso_ed_frinterval; + /* If next is transfer we expect, remove from it. */ if (transfer -> ux_transfer_request_next_transfer_request == transfer_request) { @@ -167,18 +205,32 @@ ULONG remain_count; break; } + /* If that's first new, it means first new is in remained list. */ + if (transfer == ied -> ux_ehci_hsiso_ed_transfer_first_new) + first_new_aborted = 0; + /* Next transfer. */ transfer = transfer -> ux_transfer_request_next_transfer_request; + } - /* Remain plus one. */ - remain_count ++; + /* If first new is removed, set to null. */ + if (first_new_aborted) + ied -> ux_ehci_hsiso_ed_transfer_first_new = UX_NULL; + + /* If some micro-frames are removed, modify control. */ + for (; fr_req < max_load_count; fr_req += ied -> ux_ehci_hsiso_ed_frinterval) + { + frindex = fr_start + fr_req; + frindex &= 0x7u; + + /* Get actual iTD used and clear control. */ + fr_td = ied -> ux_ehci_hsiso_ed_fr_td[frindex >> 1]; + fr_td -> ux_ehci_hsiso_td_frload &= (UCHAR)~(1u << frindex); + fr_td -> ux_ehci_hsiso_td_control[frindex] &= ~UX_EHCI_HSISO_STATUS_ACTIVE; + fr_td -> ux_ehci_hsiso_td_fr_transfer[frindex & 1u] = UX_NULL; } } - /* Wait a while so background transfer completed. */ - if (remain_count < max_load_count) - _ux_utility_delay_ms(1); - /* Release the periodic table. */ _ux_host_mutex_off(&hcd_ehci -> ux_hcd_ehci_periodic_mutex); } diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_asynchronous_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ohci_asynchronous_endpoint_create.c index 497707c4..5918950a 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_asynchronous_endpoint_create.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_asynchronous_endpoint_create.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_asynchronous_endpoint_create PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed an addressing issue, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed addressing issues, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ohci_asynchronous_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint) @@ -139,7 +142,7 @@ ULONG ohci_register; head_ed = (UX_OHCI_ED *) _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_CONTROL_HEAD_ED); ed -> ux_ohci_ed_next_ed = head_ed; - _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_CONTROL_HEAD_ED, (ULONG) ed); + _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_CONTROL_HEAD_ED, (ULONG) _ux_utility_physical_address(ed)); ohci_register = _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_CONTROL); ohci_register |= OHCI_HC_CR_CLE; _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_CONTROL, ohci_register); @@ -150,7 +153,7 @@ ULONG ohci_register; head_ed = (UX_OHCI_ED *) _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_BULK_HEAD_ED); ed -> ux_ohci_ed_next_ed = head_ed; - _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_BULK_HEAD_ED, (ULONG) ed); + _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_BULK_HEAD_ED, (ULONG) _ux_utility_physical_address(ed)); ohci_register = _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_CONTROL); ohci_register |= OHCI_HC_CR_BLE; _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_CONTROL, ohci_register); @@ -165,7 +168,7 @@ ULONG ohci_register; inserted ED. */ if (head_ed != UX_NULL) { - head_ed = _ux_utility_physical_address(head_ed); + head_ed = _ux_utility_virtual_address(head_ed); head_ed -> ux_ohci_ed_previous_ed = ed; } diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_done_queue_process.c b/common/usbx_host_controllers/src/ux_hcd_ohci_done_queue_process.c index 48bd7d75..4391be11 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_done_queue_process.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_done_queue_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_done_queue_process PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -83,6 +83,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed an addressing issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_hcd_ohci_done_queue_process(UX_HCD_OHCI *hcd_ohci) @@ -117,7 +120,7 @@ ULONG current_frame; td = next_td; next_td = _ux_utility_virtual_address(td -> ux_ohci_td_next_td); - td -> ux_ohci_td_next_td = previous_td; + td -> ux_ohci_td_next_td = _ux_utility_physical_address(previous_td); previous_td = td; } @@ -333,7 +336,7 @@ ULONG current_frame; td -> ux_ohci_td_status = UX_UNUSED; /* And continue the TD loop. */ - td = td -> ux_ohci_td_next_td; + td = _ux_utility_virtual_address(td -> ux_ohci_td_next_td); } /* The OHCI controller is now ready to receive the next done queue. We need to diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_initialize.c b/common/usbx_host_controllers/src/ux_hcd_ohci_initialize.c index b8400c2b..cfd5078e 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_initialize.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_initialize.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -85,6 +85,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed OHCI PRSC issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ohci_initialize(UX_HCD *hcd) @@ -232,6 +235,11 @@ UINT status; hcd -> ux_hcd_nb_root_hubs = UX_MAX_ROOTHUB_PORT; hcd_ohci -> ux_hcd_ohci_nb_root_hubs = hcd -> ux_hcd_nb_root_hubs; + /* Create HCD event flags */ + status = _ux_host_event_flags_create(&hcd_ohci -> ux_hcd_ohci_event_flags_group, "ux_hcd_ohci_event_flags_group"); + if (status != UX_SUCCESS) + return(status); + /* All ports must now be powered to pick up device insertion. */ _ux_hcd_ohci_power_root_hubs(hcd_ohci); diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_handler.c b/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_handler.c index 7d3486f5..5894e57f 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_handler.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_handler.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_interrupt_handler PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed OHCI PRSC issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_hcd_ohci_interrupt_handler(VOID) @@ -164,9 +167,14 @@ ULONG port_index; root_hub_thread_wakeup ++; } - /* Clear the root hub interrupt signal. We do not turn off Port Reset status change here. - This will be done when the root hub requests a Port Reset. */ - _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index, (OHCI_HC_PS_CSC | OHCI_HC_PS_PESC | OHCI_HC_PS_PSSC | OHCI_HC_PS_OCIC )); + if (ohci_register_port_status & OHCI_HC_PS_PRSC) + { + _ux_host_event_flags_set(&hcd_ohci -> ux_hcd_ohci_event_flags_group, UX_OHCI_PRSC_EVENT, UX_OR); + } + + /* Clear the root hub interrupt signal. */ + _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index, + (OHCI_HC_PS_CSC | OHCI_HC_PS_PESC | OHCI_HC_PS_PSSC | OHCI_HC_PS_OCIC | OHCI_HC_PS_PRSC)); } /* We only wake up the root hub thread if there has been device insertion/extraction. */ diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_port_reset.c b/common/usbx_host_controllers/src/ux_hcd_ohci_port_reset.c index 654347a8..42ecc3b7 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_port_reset.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_port_reset.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_port_reset PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,14 +70,17 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed OHCI PRSC issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ohci_port_reset(UX_HCD_OHCI *hcd_ohci, ULONG port_index) { ULONG ohci_register_port_status; -UINT index_loop; - +UINT status; +ULONG actual_flags = 0; /* Check to see if this port is valid on this controller. */ if (hcd_ohci -> ux_hcd_ohci_nb_root_hubs < port_index) @@ -112,29 +115,12 @@ UINT index_loop; /* Now we can safely issue a RESET command to this port. */ _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index, OHCI_HC_PS_PRS); - /* Normally, a port reset lasts for around 10ms. When the reset is completed - the controller will set the PRSC bit. We need to invert this bit by rewriting - a 1 to the PRSC field. */ - for (index_loop = 0; index_loop < UX_OHCI_PORT_RESET_RETRY; index_loop++) - { - - /* Perform the necessary delay to let the port reset properly. */ - _ux_utility_delay_ms(UX_OHCI_PORT_RESET_DELAY); - - /* Read the root HUB status change register. */ - ohci_register_port_status = _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index); - - /* Reset completed? */ - if (ohci_register_port_status & OHCI_HC_PS_PRSC) - { - - /* The reset phase is complete, rewrite that bit to clear it and - return to the root HUB driver. */ - _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index, OHCI_HC_PS_PRSC); - - /* Return successful completion. */ - return(UX_SUCCESS); - } + /* Wait for the port reset complete event */ + status = _ux_host_event_flags_get(&hcd_ohci -> ux_hcd_ohci_event_flags_group, + (UX_OHCI_PRSC_EVENT), UX_OR_CLEAR, &actual_flags, + UX_MS_TO_TICK(UX_OHCI_PRSC_EVENT_TIMEOUT)); + if ((status != UX_NO_EVENTS) && (actual_flags & UX_OHCI_PRSC_EVENT)) { + return(UX_SUCCESS); } /* If trace is enabled, insert this event into the trace buffer. */ diff --git a/common/usbx_network/inc/ux_network_driver.h b/common/usbx_network/inc/ux_network_driver.h index 2efb15b9..42022de7 100644 --- a/common/usbx_network/inc/ux_network_driver.h +++ b/common/usbx_network/inc/ux_network_driver.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_network_driver.h PORTABLE C */ -/* 6.1.8 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -48,6 +48,9 @@ /* added extern "C" keyword */ /* for compatibility with C++, */ /* resulting in version 6.1.8 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed ipv6 support issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -75,7 +78,7 @@ extern "C" { #define NX_ETHERNET_ARP 0x0806 #define NX_ETHERNET_RARP 0x0835 #define NX_ETHERNET_IP 0x0800 -#define NX_ETHERNET_IPV6 0x08DD +#define NX_ETHERNET_IPV6 0x86DD #define NX_ETHERNET_MTU 1514 typedef struct USB_NETWORK_DEVICE_STRUCT diff --git a/common/usbx_network/src/ux_network_driver.c b/common/usbx_network/src/ux_network_driver.c index d5c9bd5c..f72ae33f 100644 --- a/common/usbx_network/src/ux_network_driver.c +++ b/common/usbx_network/src/ux_network_driver.c @@ -398,7 +398,7 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device; /* FUNCTION RELEASE */ /* */ /* _ux_network_driver_entry PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -435,6 +435,9 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device; /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed ipv6 support issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -623,22 +626,20 @@ UINT i; } else { -#ifdef FEATURE_NX_IPV6 if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) -#endif /* FEATURE_NX_IPV6 */ *(ethernet_frame_ptr+3) |= NX_ETHERNET_IP; #ifdef FEATURE_NX_IPV6 else if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) - *(ethernet_frame_ptr+3) |= NX_ETHERNET_IPV6; + *(ethernet_frame_ptr+3) |= NX_ETHERNET_IPV6; +#endif /* FEATURE_NX_IPV6 */ else { /* Unknown IP version */ /* free the packet that we will not send */ - nx_packet_release(packet_ptr); + nx_packet_transmit_release(packet_ptr); nx_ip_driver -> nx_ip_driver_status = NX_NOT_SUCCESSFUL; break; } -#endif /* FEATURE_NX_IPV6 */ } /* Endian swapping if NX_LITTLE_ENDIAN is defined. */ @@ -722,10 +723,7 @@ UINT i; /* Invalid driver request. */ nx_ip_driver -> nx_ip_driver_status = NX_UNHANDLED_COMMAND; - - /* Return the link status in the supplied return pointer. */ - if(nx_ip_driver -> nx_ip_driver_return_ptr) - *(nx_ip_driver -> nx_ip_driver_return_ptr) = (ULONG)0; + break; } } @@ -740,7 +738,7 @@ UINT i; /* FUNCTION RELEASE */ /* */ /* _ux_network_driver_packet_received PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -775,6 +773,9 @@ UINT i; /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed ipv6 support issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -810,7 +811,11 @@ NX_IP *nx_ip; switch (packet_type) { case NX_ETHERNET_IP : - +#ifdef FEATURE_NX_IPV6 + /* fallthrough */ + case NX_ETHERNET_IPV6 : +#endif /* FEATURE_NX_IPV6 */ + /* Note: The length reported by some Ethernet hardware includes bytes after the packet as well as the Ethernet header. In some cases, the actual packet length after the Ethernet header should diff --git a/common/usbx_pictbridge/inc/ux_pictbridge.h b/common/usbx_pictbridge/inc/ux_pictbridge.h index 4fef28d9..f86232bb 100644 --- a/common/usbx_pictbridge/inc/ux_pictbridge.h +++ b/common/usbx_pictbridge/inc/ux_pictbridge.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_pictbridge.h PORTABLE C */ -/* 6.1.8 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -50,6 +50,9 @@ /* added extern "C" keyword */ /* for compatibility with C++, */ /* resulting in version 6.1.8 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added magic number defines, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ @@ -98,6 +101,8 @@ struct UX_PICTBRIDGE_STRUCT; #define UX_PICTBRIDGE_MAX_PIMA_OBJECT_BUFFER 1024 #define UX_PICTBRIDGE_MAX_EVENT_NUMBER 8 #define UX_PICTBRIDGE_MAX_DEVINFO_ARRAY_SIZE 16 +#define UX_PICTBRIDGE_MAX_NUMBER_STORAGE_IDS 64 +#define UX_PICTBRIDGE_MAX_NUMBER_OBJECT_HANDLES 64 #define UX_PICTBRIDGE_OBJECT_SCRIPT 0x3002 #define UX_PICTBRIDGE_THREAD_STACK_SIZE 2048 #define UX_PICTBRIDGE_THREAD_PRIORITY_CLASS 20 @@ -636,8 +641,8 @@ typedef struct UX_PICTBRIDGE_STRUCT { VOID *ux_pictbridge_pima; - ULONG ux_pictbridge_storage_ids[64]; - ULONG ux_pictbridge_object_handles_array[64]; + ULONG ux_pictbridge_storage_ids[UX_PICTBRIDGE_MAX_NUMBER_STORAGE_IDS]; + ULONG ux_pictbridge_object_handles_array[UX_PICTBRIDGE_MAX_NUMBER_OBJECT_HANDLES]; UX_PICTBRIDGE_EVENT ux_pictbridge_event_array[UX_PICTBRIDGE_MAX_EVENT_NUMBER]; UX_PICTBRIDGE_EVENT *ux_pictbridge_event_array_head; UX_PICTBRIDGE_EVENT *ux_pictbridge_event_array_tail; diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_abortjob.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_abortjob.c index 58b576d0..b407ea9e 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_abortjob.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_abortjob.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_api_abort_job PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* */ /* AUTHOR */ /* */ @@ -70,6 +70,9 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_api_abort_job(UX_PICTBRIDGE *pictbridge) @@ -85,7 +88,7 @@ ULONG actual_flags; return(status); /* We should wait for the host to send a script with the response. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_ABORT_JOB, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_ABORT_JOB, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); /* Check status. */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_capability.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_capability.c index c1c2f49d..ed281122 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_capability.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_capability.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_api_capability PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -59,7 +59,7 @@ /* */ /* _ux_utility_delay_ms Delay ms */ /* _ux_pictbridge_dps_client_input_object_prepare */ -/* _ux_utility_event_flags_get */ +/* _ux_system_event_flags_get */ /* */ /* CALLED BY */ /* */ @@ -75,6 +75,9 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_api_capability(UX_PICTBRIDGE *pictbridge, ULONG capability_code, @@ -95,7 +98,7 @@ ULONG actual_flags; return(status); /* We should wait for the host to send a script with the response. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_CAPABILITY, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_CAPABILITY, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); /* Check status. */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_configure_print_service.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_configure_print_service.c index 5db16a3d..64e4d404 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_configure_print_service.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_configure_print_service.c @@ -36,7 +36,7 @@ /* */ /* _ux_pictbridge_dpsclient_api_configure_print_service */ /* PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* */ /* AUTHOR */ /* */ @@ -73,6 +73,9 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_api_configure_print_service(UX_PICTBRIDGE *pictbridge) @@ -91,7 +94,7 @@ ULONG actual_flags; return(status); /* We should wait for the host to send a script with the response. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_CONFIGURE_PRINT_SERVICE, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_CONFIGURE_PRINT_SERVICE, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); /* Check status. */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_continuejob.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_continuejob.c index c25e96de..1223e615 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_continuejob.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_continuejob.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_api_continue_job PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,6 +69,9 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_api_continue_job(UX_PICTBRIDGE *pictbridge) @@ -84,7 +87,7 @@ ULONG actual_flags; return(status); /* We should wait for the host to send a script with the response. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_CONTINUE_JOB, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_CONTINUE_JOB, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); /* Check status. */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_device_status.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_device_status.c index 97cf773f..ea6c3f9d 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_device_status.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_device_status.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_api_device_status PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* */ /* AUTHOR */ /* */ @@ -71,6 +71,9 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_api_device_status(UX_PICTBRIDGE *pictbridge) @@ -89,7 +92,7 @@ ULONG actual_flags; return(status); /* We should wait for the host to send a script with the response. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_DEVICE_STATUS, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_DEVICE_STATUS, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); /* Check status. */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_startjob.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_startjob.c index 2158552b..9f303355 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_startjob.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_api_startjob.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_api_start_job PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* */ /* AUTHOR */ /* */ @@ -70,6 +70,9 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_api_start_job(UX_PICTBRIDGE *pictbridge) @@ -85,7 +88,7 @@ ULONG actual_flags; return(status); /* We should wait for the host to send a script with the response. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_START_JOB, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_START_JOB, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); /* Check status. */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_input_object_prepare.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_input_object_prepare.c index ab83b674..ded0ca9f 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_input_object_prepare.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_input_object_prepare.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_input_object_prepare PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,10 @@ /* refer to TX symbols instead */ /* of using them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* cleared compile warning, */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_input_object_prepare(UX_PICTBRIDGE *pictbridge, @@ -96,13 +100,15 @@ ULONG actual_flags; pictbridge -> ux_pictbridge_host_client_state_machine |= UX_PICTBRIDGE_STATE_MACHINE_CLIENT_REQUEST_PENDING; /* We should wait for the state machine to allow our operation. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); /* Check status. */ if (status != UX_SUCCESS) return(UX_EVENT_ERROR); + /* Status good means flag match, no need to check variable again, mark it unused. */ + (void)actual_flags; } /* Change the state machine to client request. */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_data_get.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_data_get.c index bfb94082..c1829a0a 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_data_get.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_data_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_object_data_get PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,9 @@ /* 04-25-2022 Yajun Xia Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_object_data_get(UX_SLAVE_CLASS_PIMA *pima, ULONG object_handle, UCHAR *object_buffer, ULONG object_offset, @@ -118,7 +121,7 @@ UINT status; if (pictbridge -> ux_pictbridge_host_client_state_machine & UX_PICTBRIDGE_STATE_MACHINE_CLIENT_REQUEST_PENDING) /* Yes we are pending, send an event to release the pending request. */ - _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_OR); + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_OR); /* Since we are in host request, this indicates we are done with the cycle. */ pictbridge -> ux_pictbridge_host_client_state_machine = UX_PICTBRIDGE_STATE_MACHINE_IDLE; diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_data_send.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_data_send.c index adcf7439..2d95b699 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_data_send.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_data_send.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_object_data_send PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,9 @@ /* refer to TX symbols instead */ /* of using them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_object_data_send(UX_SLAVE_CLASS_PIMA *pima, ULONG object_handle, @@ -224,7 +227,7 @@ UCHAR *pima_object_buffer; } /* Send event to the application. */ - _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, event_flag, UX_OR); + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, event_flag, UX_OR); } @@ -232,7 +235,7 @@ UCHAR *pima_object_buffer; { /* We have an error of some kind. Wake up the application with error event. */ - _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_ERROR, UX_OR); + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_ERROR, UX_OR); } diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_info_get.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_info_get.c index 3bbc9b43..6c59b366 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_info_get.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_info_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_object_info_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,6 +66,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* added no-callback handling, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_object_info_get(UX_SLAVE_CLASS_PIMA *pima, ULONG object_handle, @@ -75,7 +78,6 @@ UINT _ux_pictbridge_dpsclient_object_info_get(UX_SLAVE_CLASS_PIMA *pima, ULONG UX_PICTBRIDGE *pictbridge; UX_SLAVE_CLASS_PIMA_OBJECT *object_info; - /* Get the pointer to the Pictbridge instance. */ pictbridge = (UX_PICTBRIDGE *)pima -> ux_device_class_pima_application; @@ -89,11 +91,28 @@ UX_SLAVE_CLASS_PIMA_OBJECT *object_info; else object_info = (UX_SLAVE_CLASS_PIMA_OBJECT *) pictbridge -> ux_pictbridge_object_client; } - else + { + + /* Get the object info from the application (if there is callback). */ + if (pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object_info_get) + return pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object_info_get(pima, object_handle, object); + else + { + + /* Get the object info from job. */ + object_info = pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object; + + /* Object info not available. */ + if (object_info == UX_NULL) + { - /* Get the object info from the application. */ - return pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object_info_get(pima, object_handle, object); + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_PICTBRIDGE_ERROR_NO_VALID_OBJECT_INFO); + return(UX_PICTBRIDGE_ERROR_NO_VALID_OBJECT_INFO); + } + } + } /* Return the pointer to this object. */ *object = object_info; diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_info_send.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_info_send.c index cf4317d1..89d6b14c 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_info_send.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_object_info_send.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_object_info_send PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* refer to TX symbols instead */ /* of using them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed string length check, */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_object_info_send(UX_SLAVE_CLASS_PIMA *pima, UX_SLAVE_CLASS_PIMA_OBJECT *object, @@ -108,7 +112,7 @@ UINT length, length1; { /* Yes this is a script. We need to search for the HDISCVRY.DPS file name. - Get the file name length (without null-terminator). */ + Get the file name length (with null-terminator). */ length1 = (UINT)(*object_info -> ux_device_class_pima_object_filename); /* Now, compare it to the HDISCVRY.DPS file name. Check length first. */ @@ -118,7 +122,7 @@ UINT length, length1; /* Invalidate length, on error it's untouched. */ length = UX_PICTBRIDGE_MAX_FILE_NAME_SIZE + 1; _ux_utility_string_length_check(_ux_pictbridge_hdiscovery_name, &length, UX_PICTBRIDGE_MAX_FILE_NAME_SIZE); - if (length == length1) + if ((length + 1) == length1) { /* Get the file name in a ascii format (with null-terminator). */ @@ -134,7 +138,7 @@ UINT length, length1; pictbridge -> ux_pictbridge_discovery_state = UX_PICTBRIDGE_DPSCLIENT_DISCOVERY_COMPLETE; /* Set an event flag if the application is listening. */ - _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_DISCOVERY, UX_OR); + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_DISCOVERY, UX_OR); /* There is no object during the discovery cycle. */ return(UX_SUCCESS); diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_start.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_start.c index ab7e7ff9..6a1128c9 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_start.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_start.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_start PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,9 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpsclient_start(UX_PICTBRIDGE *pictbridge) @@ -129,7 +132,7 @@ UX_SLAVE_CLASS_PIMA_OBJECT *object_info; /* Create a event flag group for the client to communicate with the application. */ if (status == UX_SUCCESS) { - status = _ux_utility_event_flags_create(&pictbridge -> ux_pictbridge_event_flags_group, "ux_pictbridge_client_event_flag"); + status = _ux_system_event_flags_create(&pictbridge -> ux_pictbridge_event_flags_group, "ux_pictbridge_client_event_flag"); /* Check status. */ if (status != UX_SUCCESS) @@ -141,7 +144,7 @@ UX_SLAVE_CLASS_PIMA_OBJECT *object_info; /* Create the semaphore to wake up the thread. */ if (status == UX_SUCCESS) { - status = _ux_utility_semaphore_create(&pictbridge -> ux_pictbridge_notification_semaphore, "ux_pictbridge_client_semaphore", 0); + status = _ux_system_semaphore_create(&pictbridge -> ux_pictbridge_notification_semaphore, "ux_pictbridge_client_semaphore", 0); if (status != UX_SUCCESS) /* Do not proceed if error. */ @@ -164,7 +167,7 @@ UX_SLAVE_CLASS_PIMA_OBJECT *object_info; /* Create the pictbridge class thread. */ if (status == UX_SUCCESS) { - status = _ux_utility_thread_create(&pictbridge -> ux_pictbridge_thread, + status = _ux_system_thread_create(&pictbridge -> ux_pictbridge_thread, "ux_pictbridge_thread", _ux_pictbridge_dpsclient_thread, (ULONG)(ALIGN_TYPE) pictbridge, pictbridge -> ux_pictbridge_thread_stack, @@ -241,14 +244,14 @@ UX_SLAVE_CLASS_PIMA_OBJECT *object_info; { /* Free resources allocated so far. */ - if (pictbridge -> ux_pictbridge_thread.tx_thread_id != UX_EMPTY) - _ux_utility_thread_delete(&pictbridge -> ux_pictbridge_thread); + if (_ux_system_thread_created(&pictbridge -> ux_pictbridge_thread)) + _ux_system_thread_delete(&pictbridge -> ux_pictbridge_thread); if (pictbridge -> ux_pictbridge_thread_stack) _ux_utility_memory_free(pictbridge -> ux_pictbridge_thread_stack); - if (pictbridge -> ux_pictbridge_notification_semaphore.tx_semaphore_id != UX_EMPTY) - _ux_utility_semaphore_delete(&pictbridge -> ux_pictbridge_notification_semaphore); - if (pictbridge -> ux_pictbridge_event_flags_group.tx_event_flags_group_id != UX_EMPTY) - _ux_utility_event_flags_delete(&pictbridge -> ux_pictbridge_event_flags_group); + if (_ux_system_semaphore_created(&pictbridge -> ux_pictbridge_notification_semaphore)) + _ux_system_semaphore_delete(&pictbridge -> ux_pictbridge_notification_semaphore); + if (_ux_system_event_flags_created(&pictbridge -> ux_pictbridge_event_flags_group)) + _ux_system_event_flags_delete(&pictbridge -> ux_pictbridge_event_flags_group); if (pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object) { _ux_utility_memory_free(pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object); diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_thread.c b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_thread.c index bdb2f47d..cf2faab6 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_thread.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpsclient_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpsclient_thread PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,9 @@ /* refer to TX symbols instead */ /* of using them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_pictbridge_dpsclient_thread(ULONG parameter) @@ -96,7 +99,7 @@ UX_SLAVE_CLASS_PIMA_OBJECT *pima_object; _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, status); /* We should wait for the host to send a script with a command. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, (UX_PICTBRIDGE_EVENT_FLAG_NOTIFY_JOB_STATUS | + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, (UX_PICTBRIDGE_EVENT_FLAG_NOTIFY_JOB_STATUS | UX_PICTBRIDGE_EVENT_FLAG_NOTIFY_DEVICE_STATUS), UX_OR_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_input_object_send.c b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_input_object_send.c index b22c6782..8d9def9b 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_input_object_send.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_input_object_send.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpshost_input_object_send PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,10 @@ /* refer to TX symbols instead */ /* of using them directly, */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* cleared compile warning, */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpshost_input_object_send(UX_PICTBRIDGE *pictbridge, ULONG input_function) @@ -93,7 +97,7 @@ ULONG actual_flags; pictbridge -> ux_pictbridge_host_client_state_machine |= UX_PICTBRIDGE_STATE_MACHINE_HOST_REQUEST_PENDING; /* Wait for the client event pending request to be completed. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); @@ -103,7 +107,9 @@ ULONG actual_flags; /* Check status. */ if (status != UX_SUCCESS) return(UX_ERROR); - + + /* Status good means flag match, no need to check variable again, mark it unused. */ + (void)actual_flags; } /* Change state machine to host request pending. */ @@ -198,7 +204,7 @@ ULONG actual_flags; { /* Yes, so we need to set the event that advertise the completion of the host request. */ - _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND); @@ -233,7 +239,7 @@ ULONG actual_flags; { /* Yes, so we need to set the event that advertise the completion of the host request. */ - status = _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND); @@ -261,7 +267,7 @@ ULONG actual_flags; { /* Yes, so we need to set the event that advertise the completion of the host request. */ - status = _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND); @@ -310,7 +316,7 @@ ULONG actual_flags; { /* Yes, so we need to set the event that advertise the completion of the host request. */ - status = _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND); @@ -340,7 +346,7 @@ ULONG actual_flags; { /* Yes, so we need to set the event that advertise the completion of the host request. */ - status = _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND); @@ -363,7 +369,7 @@ ULONG actual_flags; { /* Yes, so we need to set the event that advertise the completion of the host request. */ - status = _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, + _ux_system_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND); diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_notification_callback.c b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_notification_callback.c index ba8d0ef6..142fb145 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_notification_callback.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_notification_callback.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpshost_notification_callback PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_pictbridge_dpshost_notification_callback(UX_HOST_CLASS_PIMA_EVENT *pima_event) @@ -112,7 +115,7 @@ UX_PICTBRIDGE_EVENT *pictbridge_event; pictbridge -> ux_pictbridge_event_array_head = pictbridge_next_event; /* Wake up the Pictbridge notification handler thread. */ - _ux_utility_semaphore_put(&pictbridge -> ux_pictbridge_notification_semaphore); + _ux_system_semaphore_put(&pictbridge -> ux_pictbridge_notification_semaphore); /* We are done. */ return; diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_object_get.c b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_object_get.c index 53b76645..aea776d2 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_object_get.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_object_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpshost_object_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed string length check, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpshost_object_get(UX_PICTBRIDGE *pictbridge, ULONG object_handle) @@ -107,7 +110,7 @@ UINT length, length1; { /* Yes this is a script. We need to search for the DREQUEST.DPS file name. - Get the file name length (without null-terminator). */ + Get the file name length (with null-terminator). */ length1 = (UINT)(*pima_object -> ux_host_class_pima_object_filename); /* Check the file name from this script. It should be in the form DREQUEST.DPS. */ @@ -117,7 +120,7 @@ UINT length, length1; /* Invalidate length, on error it's untouched. */ length = UX_PICTBRIDGE_MAX_FILE_NAME_SIZE + 1; _ux_utility_string_length_check(_ux_pictbridge_drequest_name, &length, UX_PICTBRIDGE_MAX_FILE_NAME_SIZE); - if (length == length1) + if ((length + 1) == length1) { /* Get the file name in a ascii format (with null-terminator). */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_response_get.c b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_response_get.c index 91777cab..7b094e0e 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_response_get.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_response_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpshost_response_get PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,6 +66,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed string length check, */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpshost_response_get(UX_PICTBRIDGE *pictbridge) @@ -93,7 +97,7 @@ UINT length, length1; pima_object = (UX_HOST_CLASS_PIMA_OBJECT *) pictbridge -> ux_pictbridge_object_host; /* Wait for the semaphore to be put by the root hub or a regular hub. */ - _ux_utility_semaphore_get(&pictbridge -> ux_pictbridge_notification_semaphore, UX_WAIT_FOREVER); + _ux_system_semaphore_get_norc(&pictbridge -> ux_pictbridge_notification_semaphore, UX_WAIT_FOREVER); /* Check if there is an event. Normally there should be at least one since we got awaken. */ if (pictbridge -> ux_pictbridge_event_array_tail != pictbridge -> ux_pictbridge_event_array_head) @@ -155,7 +159,7 @@ UINT length, length1; { /* Yes this is a script. We need to search for the DRSPONSE.DPS file name. - Get the file name length (without null-terminator). */ + Get the file name length (with null-terminator). */ length1 = (UINT)(*pima_object -> ux_host_class_pima_object_filename); /* Check the file name from this script. It should be in the form DRSPONSE.DPS. */ @@ -165,7 +169,7 @@ UINT length, length1; /* Invalidate length, on error it's untouched. */ length = UX_PICTBRIDGE_MAX_FILE_NAME_SIZE + 1; _ux_utility_string_length_check(_ux_pictbridge_drsponse_name, &length, UX_PICTBRIDGE_MAX_FILE_NAME_SIZE); - if (length == length1) + if ((length + 1) == length1) { /* Get the file name in a ascii format (with null-terminator). */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_start.c b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_start.c index ac9933dd..1cd5476f 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_start.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_start.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpshost_start PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,6 +72,12 @@ /* 04-25-2022 Yajun Xia Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed string length check, */ +/* fixed possible overflow, */ +/* used define instead of num, */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_dpshost_start(UX_PICTBRIDGE *pictbridge, UX_HOST_CLASS_PIMA *pima) @@ -148,7 +154,7 @@ UINT length, length1; pictbridge -> ux_pictbridge_host_client_state_machine = UX_PICTBRIDGE_STATE_MACHINE_IDLE; /* Create the semaphore to wake up the thread. */ - status = _ux_utility_semaphore_create(&pictbridge -> ux_pictbridge_notification_semaphore, "ux_pictbridge_notification_semaphore", 0); + status = _ux_system_semaphore_create(&pictbridge -> ux_pictbridge_notification_semaphore, "ux_pictbridge_notification_semaphore", 0); if (status != UX_SUCCESS) status = (UX_SEMAPHORE_ERROR); } @@ -171,7 +177,7 @@ UINT length, length1; { /* Create the pictbridge class thread. */ - status = _ux_utility_thread_create(&pictbridge -> ux_pictbridge_thread, + status = _ux_system_thread_create(&pictbridge -> ux_pictbridge_thread, "ux_pictbridge_thread", _ux_pictbridge_dpshost_thread, (ULONG)(ALIGN_TYPE) pictbridge, pictbridge -> ux_pictbridge_thread_stack, @@ -192,16 +198,16 @@ UINT length, length1; { /* Check and free pictbridge -> ux_pictbridge_thread. */ - if (pictbridge -> ux_pictbridge_thread.tx_thread_id != UX_EMPTY) - _ux_utility_thread_delete(&pictbridge -> ux_pictbridge_thread); + if (_ux_system_thread_created(&pictbridge -> ux_pictbridge_thread)) + _ux_system_thread_delete(&pictbridge -> ux_pictbridge_thread); /* Check and free pictbridge -> ux_pictbridge_thread_stack. */ if (pictbridge -> ux_pictbridge_thread_stack) _ux_utility_memory_free(pictbridge -> ux_pictbridge_thread_stack); /* Check and free pictbridge -> ux_pictbridge_notification_semaphore. */ - if (pictbridge -> ux_pictbridge_notification_semaphore.tx_semaphore_id != UX_EMPTY) - _ux_utility_semaphore_delete(&pictbridge -> ux_pictbridge_notification_semaphore); + if (_ux_system_semaphore_created(&pictbridge -> ux_pictbridge_notification_semaphore)) + _ux_system_semaphore_delete(&pictbridge -> ux_pictbridge_notification_semaphore); /* Check and free pictbridge -> ux_pictbridge_device. */ if (pictbridge -> ux_pictbridge_device) @@ -253,7 +259,7 @@ UINT length, length1; /* Get the number of storage IDs. */ status = _ux_host_class_pima_storage_ids_get(pima, pima_session, pictbridge -> ux_pictbridge_storage_ids, - 64); + UX_PICTBRIDGE_MAX_NUMBER_STORAGE_IDS); if (status != UX_SUCCESS) { /* Close the pima session. */ @@ -286,9 +292,13 @@ UINT length, length1; } /* Get the array of objects handles on the container. */ + if (pima_session -> ux_host_class_pima_session_nb_objects > UX_PICTBRIDGE_MAX_NUMBER_OBJECT_HANDLES) + length = UX_PICTBRIDGE_MAX_NUMBER_OBJECT_HANDLES; + else + length = pima_session -> ux_host_class_pima_session_nb_objects; status = _ux_host_class_pima_object_handles_get(pima, pima_session, pictbridge -> ux_pictbridge_object_handles_array, - 4 * pima_session -> ux_host_class_pima_session_nb_objects, + length, UX_PICTBRIDGE_ALL_CONTAINERS, UX_PICTBRIDGE_OBJECT_SCRIPT, 0); if (status != UX_SUCCESS) { @@ -314,13 +324,12 @@ UINT length, length1; return(UX_PICTBRIDGE_ERROR_INVALID_OBJECT_HANDLE ); } - /* Check if this is a script. */ if (pima_object -> ux_host_class_pima_object_format == UX_HOST_CLASS_PIMA_OFC_SCRIPT) { /* Yes this is a script. We need to search for the DDISCVRY.DPS file name. - Get the file name length (without null-terminator). */ + Get the file name length (with null-terminator). */ length1 = (UINT)(*pima_object -> ux_host_class_pima_object_filename); /* Now, compare it to the DDISCVRY.DPS file name. Check length first (excluding null-terminator). */ @@ -330,7 +339,7 @@ UINT length, length1; /* Invalidate length, on error it's untouched. */ length = UX_PICTBRIDGE_MAX_FILE_NAME_SIZE + 1; _ux_utility_string_length_check(_ux_pictbridge_ddiscovery_name, &length, UX_PICTBRIDGE_MAX_FILE_NAME_SIZE); - if (length == length1) + if ((length + 1) == length1) { /* Get the file name in a ascii format (with null-terminator). */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_thread.c b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_thread.c index 88c3ac99..fbdf4b1e 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_dpshost_thread.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_dpshost_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_dpshost_thread PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,10 @@ /* 04-25-2022 Yajun Xia Modified comment(s), */ /* internal clean up, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* cleared compile warning, */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_pictbridge_dpshost_thread(ULONG parameter) @@ -91,7 +95,7 @@ UINT status; { /* Wait for the semaphore to be put by the root hub or a regular hub. */ - _ux_utility_semaphore_get(&pictbridge -> ux_pictbridge_notification_semaphore, UX_WAIT_FOREVER); + _ux_system_semaphore_get_norc(&pictbridge -> ux_pictbridge_notification_semaphore, UX_WAIT_FOREVER); /* Check if there is an event. Normally there should be at least one since we got awaken. */ if (pictbridge -> ux_pictbridge_event_array_tail != pictbridge -> ux_pictbridge_event_array_head) @@ -126,7 +130,7 @@ UINT status; pictbridge -> ux_pictbridge_host_client_state_machine |= UX_PICTBRIDGE_STATE_MACHINE_CLIENT_REQUEST_PENDING; /* Wait for the host pending request to be completed. */ - status = _ux_utility_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, + status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT); @@ -137,7 +141,8 @@ UINT status; if (status != UX_SUCCESS) break; - + /* Status good means flag match, no need to check variable again, mark it unused. */ + (void)actual_flags; } /* Change the state machine to client request being executed. */ @@ -151,7 +156,7 @@ UINT status; { /* Yes, so we need to set the event that advertise the completion of the host request. */ - status = _ux_utility_event_flags_set(&pictbridge -> ux_pictbridge_event_flags_group, + status = _ux_system_event_flags_set_rc(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY, UX_AND); /* Check status. */ diff --git a/common/usbx_pictbridge/src/ux_pictbridge_xml_function_input_startjob.c b/common/usbx_pictbridge/src/ux_pictbridge_xml_function_input_startjob.c index c8c2a8df..d20b7dfb 100644 --- a/common/usbx_pictbridge/src/ux_pictbridge_xml_function_input_startjob.c +++ b/common/usbx_pictbridge/src/ux_pictbridge_xml_function_input_startjob.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_pictbridge_xml_function_input_startjob PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* */ /* */ /* AUTHOR */ @@ -70,6 +70,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* used macros for RTOS calls, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_pictbridge_xml_function_input_startjob(UX_PICTBRIDGE *pictbridge, @@ -111,7 +114,7 @@ UX_PICTBRIDGE_EVENT *pictbridge_event; pictbridge -> ux_pictbridge_event_array_head = pictbridge_next_event; /* Wake up the Pictbridge notification handler thread. */ - _ux_utility_semaphore_put(&pictbridge -> ux_pictbridge_notification_semaphore); + _ux_system_semaphore_put(&pictbridge -> ux_pictbridge_notification_semaphore); /* This function never fails. */ return(UX_SUCCESS); diff --git a/ports/arm9/gnu/inc/ux_port.h b/ports/arm9/gnu/inc/ux_port.h index 5d4e701c..28c881bc 100644 --- a/ports/arm9/gnu/inc/ux_port.h +++ b/ports/arm9/gnu/inc/ux_port.h @@ -239,7 +239,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/arm9/iar/inc/ux_port.h b/ports/arm9/iar/inc/ux_port.h index d1dba2a0..2a5e11e6 100644 --- a/ports/arm9/iar/inc/ux_port.h +++ b/ports/arm9/iar/inc/ux_port.h @@ -246,7 +246,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a15/gnu/inc/ux_port.h b/ports/cortex_a15/gnu/inc/ux_port.h index ecd5f98c..d9ea85a9 100644 --- a/ports/cortex_a15/gnu/inc/ux_port.h +++ b/ports/cortex_a15/gnu/inc/ux_port.h @@ -235,7 +235,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A15/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A15/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a5/gnu/inc/ux_port.h b/ports/cortex_a5/gnu/inc/ux_port.h index 4e2f3e68..742ad9bf 100644 --- a/ports/cortex_a5/gnu/inc/ux_port.h +++ b/ports/cortex_a5/gnu/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a5/iar/inc/ux_port.h b/ports/cortex_a5/iar/inc/ux_port.h index 40f22e65..54c8d5cb 100644 --- a/ports/cortex_a5/iar/inc/ux_port.h +++ b/ports/cortex_a5/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a5x/ac6/inc/ux_port.h b/ports/cortex_a5x/ac6/inc/ux_port.h index a482d2a1..1c677a54 100644 --- a/ports/cortex_a5x/ac6/inc/ux_port.h +++ b/ports/cortex_a5x/ac6/inc/ux_port.h @@ -259,7 +259,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5x/AC6 Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5x/AC6 Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a7/gnu/inc/ux_port.h b/ports/cortex_a7/gnu/inc/ux_port.h index c2f16da4..c937a33a 100644 --- a/ports/cortex_a7/gnu/inc/ux_port.h +++ b/ports/cortex_a7/gnu/inc/ux_port.h @@ -246,7 +246,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A7/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A7/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a7/iar/inc/ux_port.h b/ports/cortex_a7/iar/inc/ux_port.h index 14a9a986..3ef6d481 100644 --- a/ports/cortex_a7/iar/inc/ux_port.h +++ b/ports/cortex_a7/iar/inc/ux_port.h @@ -246,7 +246,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A7/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A7/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a8/gnu/inc/ux_port.h b/ports/cortex_a8/gnu/inc/ux_port.h index c18e3302..9453e58a 100644 --- a/ports/cortex_a8/gnu/inc/ux_port.h +++ b/ports/cortex_a8/gnu/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A8/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A8/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a8/iar/inc/ux_port.h b/ports/cortex_a8/iar/inc/ux_port.h index 10ef85a0..7a0ee0d8 100644 --- a/ports/cortex_a8/iar/inc/ux_port.h +++ b/ports/cortex_a8/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A8/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A8/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a9/gnu/inc/ux_port.h b/ports/cortex_a9/gnu/inc/ux_port.h index 5eec14e2..7af6f395 100644 --- a/ports/cortex_a9/gnu/inc/ux_port.h +++ b/ports/cortex_a9/gnu/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_a9/iar/inc/ux_port.h b/ports/cortex_a9/iar/inc/ux_port.h index d05f01e0..2564a8ac 100644 --- a/ports/cortex_a9/iar/inc/ux_port.h +++ b/ports/cortex_a9/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_m0/gnu/inc/ux_port.h b/ports/cortex_m0/gnu/inc/ux_port.h index 97f6d965..b22c35bf 100644 --- a/ports/cortex_m0/gnu/inc/ux_port.h +++ b/ports/cortex_m0/gnu/inc/ux_port.h @@ -240,7 +240,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M0/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M0/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_m0/iar/inc/ux_port.h b/ports/cortex_m0/iar/inc/ux_port.h index 05f25f86..b1d10d56 100644 --- a/ports/cortex_m0/iar/inc/ux_port.h +++ b/ports/cortex_m0/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M0/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M0/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_m3/gnu/inc/ux_port.h b/ports/cortex_m3/gnu/inc/ux_port.h index 6ea912d6..11ddb422 100644 --- a/ports/cortex_m3/gnu/inc/ux_port.h +++ b/ports/cortex_m3/gnu/inc/ux_port.h @@ -240,7 +240,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M3/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M3/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_m3/iar/inc/ux_port.h b/ports/cortex_m3/iar/inc/ux_port.h index 3e921dcf..d3807aee 100644 --- a/ports/cortex_m3/iar/inc/ux_port.h +++ b/ports/cortex_m3/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M3/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M3/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_m4/gnu/inc/ux_port.h b/ports/cortex_m4/gnu/inc/ux_port.h index 7432a848..7113f32d 100644 --- a/ports/cortex_m4/gnu/inc/ux_port.h +++ b/ports/cortex_m4/gnu/inc/ux_port.h @@ -240,7 +240,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M4/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M4/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_m4/iar/inc/ux_port.h b/ports/cortex_m4/iar/inc/ux_port.h index 22994f92..28f56e76 100644 --- a/ports/cortex_m4/iar/inc/ux_port.h +++ b/ports/cortex_m4/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M4/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M4/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_m7/gnu/inc/ux_port.h b/ports/cortex_m7/gnu/inc/ux_port.h index 8474d809..62e95678 100644 --- a/ports/cortex_m7/gnu/inc/ux_port.h +++ b/ports/cortex_m7/gnu/inc/ux_port.h @@ -240,7 +240,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M7/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M7/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_m7/iar/inc/ux_port.h b/ports/cortex_m7/iar/inc/ux_port.h index 4fb4b5d5..dd8f8925 100644 --- a/ports/cortex_m7/iar/inc/ux_port.h +++ b/ports/cortex_m7/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M7/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M7/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_r4/gnu/inc/ux_port.h b/ports/cortex_r4/gnu/inc/ux_port.h index 40ee7c0f..09c11308 100644 --- a/ports/cortex_r4/gnu/inc/ux_port.h +++ b/ports/cortex_r4/gnu/inc/ux_port.h @@ -238,7 +238,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R4/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R4/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_r4/iar/inc/ux_port.h b/ports/cortex_r4/iar/inc/ux_port.h index c12fff66..932e71a6 100644 --- a/ports/cortex_r4/iar/inc/ux_port.h +++ b/ports/cortex_r4/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R4/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R4/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_r5/gnu/inc/ux_port.h b/ports/cortex_r5/gnu/inc/ux_port.h index a6576988..6654a7b4 100644 --- a/ports/cortex_r5/gnu/inc/ux_port.h +++ b/ports/cortex_r5/gnu/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R5/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R5/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/cortex_r5/iar/inc/ux_port.h b/ports/cortex_r5/iar/inc/ux_port.h index f900373b..03829ebb 100644 --- a/ports/cortex_r5/iar/inc/ux_port.h +++ b/ports/cortex_r5/iar/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R5/IAR Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R5/IAR Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/generic/inc/ux_port.h b/ports/generic/inc/ux_port.h index 9b940b94..4973c2a2 100644 --- a/ports/generic/inc/ux_port.h +++ b/ports/generic/inc/ux_port.h @@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Generic Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Generic Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif diff --git a/ports/linux/gnu/inc/ux_port.h b/ports/linux/gnu/inc/ux_port.h index 692fed08..0ebd9239 100644 --- a/ports/linux/gnu/inc/ux_port.h +++ b/ports/linux/gnu/inc/ux_port.h @@ -244,7 +244,7 @@ ULONG outpl(ULONG,ULONG); #ifdef UX_SYSTEM_INIT CHAR _ux_version_id[] = - "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Linux/GNU Version 6.1.11 *"; + "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Linux/GNU Version 6.1.12 *"; #else extern CHAR _ux_version_id[]; #endif