diff options
Diffstat (limited to 'common/core')
20 files changed, 839 insertions, 223 deletions
diff --git a/common/core/CMakeLists.txt b/common/core/CMakeLists.txt index 85f1b85..8b1796f 100644 --- a/common/core/CMakeLists.txt +++ b/common/core/CMakeLists.txt @@ -104,14 +104,18 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_instance_create.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_instance_delete.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_interface_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_interface_scan.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_set.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_delay_ms.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_address_set.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_configuration_activate.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_configuration_deactivate.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_configuration_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_configuration_reset.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_configuration_select.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_descriptor_read.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_string_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_remove.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_resources_free.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_endpoint_instance_create.c diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h index 872f6cc..7932d79 100644..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.3 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,16 @@ /* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ /* added BOS support, */ /* resulting in version 6.1.3 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added configuration activate*/ +/* and deactivate support, */ +/* added host printer get */ +/* device ID support, */ +/* added host device string */ +/* descriptor get support, */ +/* added events for device */ +/* connection/disconnection, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ @@ -205,7 +215,7 @@ typedef signed char SCHAR; #define AZURE_RTOS_USBX #define USBX_MAJOR_VERSION 6 #define USBX_MINOR_VERSION 1 -#define USBX_PATCH_VERSION 3 +#define USBX_PATCH_VERSION 4 /* Macros for concatenating tokens, where UX_CONCATn concatenates n tokens. */ @@ -395,6 +405,9 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_TRACE_HOST_STACK_HCD_UNREGISTER (UX_TRACE_HOST_STACK_EVENTS_BASE + 35) /* I1 = hcd name , I2 = parameter 1 , I3 = parameter 2 */ #define UX_TRACE_HOST_STACK_CLASS_REGISTER (UX_TRACE_HOST_STACK_EVENTS_BASE + 36) /* I1 = class name , I2 = entry function */ #define UX_TRACE_HOST_STACK_CLASS_UNREGISTER (UX_TRACE_HOST_STACK_EVENTS_BASE + 37) /* I1 = class entry */ +#define UX_TRACE_HOST_STACK_DEVICE_STRING_GET (UX_TRACE_HOST_STACK_EVENTS_BASE + 38) /* I1 = device , I2 = buffer , I3 = length , I4 = (langID<<16) | index */ +#define UX_TRACE_HOST_STACK_DEVICE_CONFIGURATION_ACTIVATE (UX_TRACE_HOST_STACK_EVENTS_BASE + 39) /* I1 = device , I2 = configuration */ +#define UX_TRACE_HOST_STACK_DEVICE_CONFIGURATION_DEACTIVATE (UX_TRACE_HOST_STACK_EVENTS_BASE + 40) /* I1 = device , I2 = configuration */ /* Define the USBX host class events. */ @@ -490,6 +503,7 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_TRACE_HOST_CLASS_PRINTER_WRITE (UX_TRACE_HOST_CLASS_EVENTS_BASE + 104) /* I1 = class instance , I2 = data pointer , I3 = requested length */ #define UX_TRACE_HOST_CLASS_PRINTER_SOFT_RESET (UX_TRACE_HOST_CLASS_EVENTS_BASE + 105) /* I1 = class instance */ #define UX_TRACE_HOST_CLASS_PRINTER_STATUS_GET (UX_TRACE_HOST_CLASS_EVENTS_BASE + 106) /* I1 = class instance , I2 = printer status */ +#define UX_TRACE_HOST_CLASS_PRINTER_DEVICE_ID_GET (UX_TRACE_HOST_CLASS_EVENTS_BASE + 107) /* I1 = class instance , I2 = printer , I3 = data pointer , I4 = buffer length */ #define UX_TRACE_HOST_CLASS_PROLIFIC_ACTIVATE (UX_TRACE_HOST_CLASS_EVENTS_BASE + 110) /* I1 = class instance */ #define UX_TRACE_HOST_CLASS_PROLIFIC_DEACTIVATE (UX_TRACE_HOST_CLASS_EVENTS_BASE + 111) /* I1 = class instance */ @@ -1019,12 +1033,20 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_TRANSFER_PHASE_STATUS_IN 4 #define UX_TRANSFER_PHASE_STATUS_OUT 5 -#define UX_DEVICE_INSERTION 1 -#define UX_DEVICE_REMOVAL 2 -#define UX_HID_CLIENT_INSERTION 3 -#define UX_HID_CLIENT_REMOVAL 4 -#define UX_STORAGE_MEDIA_INSERTION 5 -#define UX_STORAGE_MEDIA_REMOVAL 6 + +/* Host change callback events : _callback(event, *class, *instance) */ + +#define UX_DEVICE_INSERTION 0x01u +#define UX_DEVICE_REMOVAL 0x02u +#define UX_HID_CLIENT_INSERTION 0x03u +#define UX_HID_CLIENT_REMOVAL 0x04u +#define UX_STORAGE_MEDIA_INSERTION 0x05u +#define UX_STORAGE_MEDIA_REMOVAL 0x06u + +/* Host change callback events : _callback(event, NULL, *device_instance) */ + +#define UX_DEVICE_CONNECTION 0x81u +#define UX_DEVICE_DISCONNECTION 0x82u /* Define USBX transfer request status constants. */ @@ -1135,6 +1157,7 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL #define UX_MEMORY_CORRUPTED 0x19 #define UX_MEMORY_ARRAY_FULL 0x1a #define UX_FATAL_ERROR 0x1b +#define UX_ALREADY_ACTIVATED 0x1c #define UX_TRANSFER_STALLED 0x21 #define UX_TRANSFER_NO_ANSWER 0x22 @@ -1588,7 +1611,8 @@ typedef struct UX_DEVICE_STRUCT ULONG ux_device_address; ULONG ux_device_speed; ULONG ux_device_power_source; - UINT ux_device_current_configuration; + struct UX_CONFIGURATION_STRUCT + *ux_device_current_configuration; UX_SEMAPHORE ux_device_protection_semaphore; struct UX_HOST_CLASS_STRUCT *ux_device_class; @@ -2232,9 +2256,12 @@ typedef struct UX_HOST_CLASS_DPUMP_STRUCT #define ux_host_stack_class_register _ux_host_stack_class_register #define ux_host_stack_class_unregister _ux_host_stack_class_unregister #define ux_host_stack_configuration_interface_get _ux_host_stack_configuration_interface_get +#define ux_host_stack_device_configuration_activate _ux_host_stack_device_configuration_activate +#define ux_host_stack_device_configuration_deactivate _ux_host_stack_device_configuration_deactivate #define ux_host_stack_device_configuration_get _ux_host_stack_device_configuration_get #define ux_host_stack_device_configuration_select _ux_host_stack_device_configuration_select #define ux_host_stack_device_get _ux_host_stack_device_get +#define ux_host_stack_device_string_get _ux_host_stack_device_string_get #define ux_host_stack_endpoint_transfer_abort _ux_host_stack_endpoint_transfer_abort #define ux_host_stack_hcd_register _ux_host_stack_hcd_register #define ux_host_stack_hcd_unregister _ux_host_stack_hcd_unregister @@ -2303,9 +2330,12 @@ UINT ux_host_stack_class_register(UCHAR *class_name, UINT (*class_entry_funct 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 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); UINT ux_host_stack_device_configuration_select(UX_CONFIGURATION *configuration); UINT ux_host_stack_device_get(ULONG device_index, UX_DEVICE **device); +UINT ux_host_stack_device_string_get(UX_DEVICE *device, UCHAR *descriptor_buffer, ULONG length, ULONG language_id, ULONG string_index); UINT ux_host_stack_endpoint_transfer_abort(UX_ENDPOINT *endpoint); UINT ux_host_stack_hcd_register(UCHAR *hcd_name, UINT (*hcd_initialize_function)(struct UX_HCD_STRUCT *), ULONG hcd_param1, ULONG hcd_param2); UINT ux_host_stack_hcd_unregister(UCHAR *hcd_name, ULONG hcd_param1, ULONG hcd_param2); diff --git a/common/core/inc/ux_host_stack.h b/common/core/inc/ux_host_stack.h index e17f9f1..a8bc131 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 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -46,6 +46,13 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added configuration activate*/ +/* and deactivate support, */ +/* added host device string */ +/* descriptor get support, */ +/* updated internal function, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ @@ -83,15 +90,19 @@ VOID _ux_host_stack_configuration_instance_delete(UX_CONFIGURATION *configura UINT _ux_host_stack_configuration_interface_get(UX_CONFIGURATION *configuration, UINT interface_index, UINT alternate_setting_index, UX_INTERFACE **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); UINT _ux_host_stack_device_address_set(UX_DEVICE *device); +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); UINT _ux_host_stack_device_configuration_select(UX_CONFIGURATION *configuration); UINT _ux_host_stack_device_configuration_reset(UX_DEVICE *device); UINT _ux_host_stack_device_descriptor_read(UX_DEVICE *device); UINT _ux_host_stack_device_get(ULONG device_index, UX_DEVICE **device); +UINT _ux_host_stack_device_string_get(UX_DEVICE *device, UCHAR *descriptor_buffer, ULONG length, ULONG language_id, ULONG string_index); UINT _ux_host_stack_device_remove(UX_HCD *hcd, UX_DEVICE *parent, UINT port_index); UINT _ux_host_stack_device_resources_free(UX_DEVICE *device); UINT _ux_host_stack_endpoint_instance_create(UX_ENDPOINT *endpoint); @@ -116,7 +127,8 @@ VOID _ux_host_stack_new_configuration_create(UX_DEVICE *device, UX_CONFIGURAT UX_DEVICE *_ux_host_stack_new_device_get(VOID); UINT _ux_host_stack_new_device_create(UX_HCD *hcd, UX_DEVICE *device_owner, UINT port_index, UINT device_speed, - UINT port_max_power); + 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_interface_create(UX_CONFIGURATION *configuration, UCHAR * descriptor, ULONG length); VOID _ux_host_stack_rh_change_process(VOID); diff --git a/common/core/inc/ux_user_sample.h b/common/core/inc/ux_user_sample.h index 7f046fb..ea139cf 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 */ +/* 6.1.4 */ /* */ /* AUTHOR */ /* */ @@ -47,6 +47,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 02-02-2021 Xiuwen Cai Modified comment(s), added */ +/* compile option for using */ +/* packet pool from NetX, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ @@ -260,6 +264,17 @@ /* #define UX_HOST_CLASS_CDC_ECM_PACKET_POOL_WAIT 10 */ /* Defined, this value represents the number of milliseconds to wait for packet + pool availability checking loop. + The default is 100 milliseconds. +*/ + +/* #define UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT 10 */ + +/* Defined, this enables CDC ECM class to use the packet pool from NetX instance. */ + +/* #define UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX */ + +/* Defined, this value represents the number of milliseconds to wait for packet allocation until invoking the application's error callback and retrying. */ diff --git a/common/core/src/ux_host_stack_class_interface_scan.c b/common/core/src/ux_host_stack_class_interface_scan.c index 62b39e8..85a6348 100644 --- a/common/core/src/ux_host_stack_class_interface_scan.c +++ b/common/core/src/ux_host_stack_class_interface_scan.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_class_interface_scan PORTABLE C */ -/* 6.1 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -83,20 +83,18 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* used internal function call */ +/* to scan interfaces, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ UINT _ux_host_stack_class_interface_scan(UX_DEVICE *device) { UX_CONFIGURATION *configuration; -UX_INTERFACE *interface; -UINT nb_class_owners; -UX_HOST_CLASS *class; -UX_HOST_CLASS_COMMAND class_command; UINT status; - /* Initialize class owners to 0. */ - nb_class_owners = 0; /* Get the 1st and only configuration. If the device has multiple configurations, we simply use the first one as default. */ @@ -104,94 +102,9 @@ UINT status; if (configuration == UX_NULL) return(UX_ERROR); - /* Get the first interface container for this configuration. */ - interface = configuration -> ux_configuration_first_interface; + /* Scan interfaces for this configuration. */ + status = _ux_host_stack_configuration_interface_scan(configuration); - /* We now scan all the alternate settings 0 for each of the interfaces. */ - while (interface != UX_NULL) - { - - /* Is there a default interface? */ - if(interface -> 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_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 = _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) - { - - /* There is a class. */ - nb_class_owners++; - interface -> ux_interface_class = class; - } - } - - /* point to the next interface until end of the list. */ - interface = interface -> ux_interface_next_interface; - } - - /* Assume no classes. */ - status = UX_NO_CLASS_MATCH; - - /* Check the number of class owner found. */ - if (nb_class_owners != 0) - { - - /* If we have found one or more classes for any of the interfaces, - we can safely do a SET_CONFIGURATION of the device. */ - status = _ux_host_stack_device_configuration_select(configuration); - - /* Check the completion status. */ - if (status == UX_SUCCESS) - { - - /* 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; - - while (interface != UX_NULL) - { - - /* Is there a default interface? */ - if (interface -> 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; - - if (interface -> ux_interface_class != UX_NULL) - { - - /* Save the class in the command container */ - class_command.ux_host_class_command_class_ptr = interface -> ux_interface_class; - - /* Send the ACTIVATE command to the class */ - status = interface -> 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; - } - } - } - /* Return operation result. */ return(status); } diff --git a/common/core/src/ux_host_stack_configuration_interface_scan.c b/common/core/src/ux_host_stack_configuration_interface_scan.c new file mode 100644 index 0000000..6f83f3e --- /dev/null +++ b/common/core/src/ux_host_stack_configuration_interface_scan.c @@ -0,0 +1,179 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Host Stack */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_stack_configuration_interface_scan PORTABLE C */ +/* 6.1.4 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function will scan all default interfaces for a specific */ +/* configuration and call the registered class with the */ +/* Class/SubClass/Protocol of the interface. */ +/* */ +/* INPUT */ +/* */ +/* configuration Configuration pointer */ +/* */ +/* OUTPUT */ +/* */ +/* Result of operation */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_class_call Call class command */ +/* _ux_host_stack_device_configuration_select */ +/* Select configuration */ +/* _ux_host_stack_class_call Call class from host stack */ +/* (ux_host_class_entry_function) Class entry function */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Components */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 02-02-2021 Chaoqiong Xiao Initial Version 6.1.4 */ +/* */ +/**************************************************************************/ +UINT _ux_host_stack_configuration_interface_scan(UX_CONFIGURATION *configuration) +{ + +UX_INTERFACE *interface; +UINT nb_class_owners; +UX_HOST_CLASS *class; +UX_HOST_CLASS_COMMAND class_command; +UINT status; + + + /* Initialize class owners to 0. */ + nb_class_owners = 0; + + /* Get the first interface container for this configuration. */ + interface = configuration -> ux_configuration_first_interface; + + /* We now scan all the alternate settings 0 for each of the interfaces. */ + while (interface != UX_NULL) + { + + /* Is there a default interface? */ + if(interface -> 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_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 = _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) + { + + /* There is a class. */ + nb_class_owners++; + interface -> ux_interface_class = class; + } + } + + /* point to the next interface until end of the list. */ + interface = interface -> ux_interface_next_interface; + } + + /* Assume no classes. */ + status = UX_NO_CLASS_MATCH; + + /* Check the number of class owner found. */ + if (nb_class_owners != 0) + { + + /* If we have found one or more classes for any of the interfaces, + we can safely do a SET_CONFIGURATION of the device. */ + status = _ux_host_stack_device_configuration_select(configuration); + + /* Check the completion status. */ + if (status == UX_SUCCESS) + { + + /* 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; + + while (interface != UX_NULL) + { + + /* Is there a default interface? */ + if (interface -> 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; + + if (interface -> ux_interface_class != UX_NULL) + { + + /* Save the class in the command container */ + class_command.ux_host_class_command_class_ptr = interface -> ux_interface_class; + + /* Send the ACTIVATE command to the class */ + status = interface -> 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; + } + } + } + + /* Return operation result. */ + return(status); +} + diff --git a/common/core/src/ux_host_stack_configuration_set.c b/common/core/src/ux_host_stack_configuration_set.c index 26312d0..4ffba3e 100644 --- a/common/core/src/ux_host_stack_configuration_set.c +++ b/common/core/src/ux_host_stack_configuration_set.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_configuration_set PORTABLE C */ -/* 6.1 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,10 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* used pointer for current */ +/* selected configuration, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ UINT _ux_host_stack_configuration_set(UX_CONFIGURATION *configuration) @@ -150,7 +154,7 @@ UX_HCD *hcd; device -> ux_device_state = UX_DEVICE_CONFIGURED; /* Store the new configuration value in the device container. */ - device -> ux_device_current_configuration = configuration -> ux_configuration_descriptor.bConfigurationValue; + device -> ux_device_current_configuration = configuration; } /* Return status to caller. */ diff --git a/common/core/src/ux_host_stack_device_configuration_activate.c b/common/core/src/ux_host_stack_device_configuration_activate.c new file mode 100644 index 0000000..47f659a --- /dev/null +++ b/common/core/src/ux_host_stack_device_configuration_activate.c @@ -0,0 +1,137 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Host Stack */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_stack_device_configuration_activate PORTABLE C */ +/* 6.1.4 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function selects a specific configuration for a device. */ +/* When this configuration is set to the device, by default all the */ +/* device interface and their associated alternate setting 0 is */ +/* activated on the device. */ +/* */ +/* INPUT */ +/* */ +/* configuration Pointer to configuration */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_utility_semaphore_get Get semaphore */ +/* _ux_utility_semaphore_put Put semaphore */ +/* _ux_host_stack_configuration_interface_scan Scan and activate */ +/* interfaces */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* USBX Components */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 02-02-2021 Chaoqiong Xiao Initial Version 6.1.4 */ +/* */ +/**************************************************************************/ +UINT _ux_host_stack_device_configuration_activate(UX_CONFIGURATION *configuration) +{ + +UX_DEVICE *device; +UINT status; + + + /* Check for validity of the configuration handle. */ + if (configuration -> ux_configuration_handle != (ULONG) (ALIGN_TYPE) configuration) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, 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, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_CONFIGURATION_HANDLE_UNKNOWN); + } + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_CONFIGURATION_ACTIVATE, device, configuration, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) + + /* Get the device container for this configuration. */ + device = configuration -> ux_configuration_device; + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_utility_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + + /* Check for status. */ + if (status != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_SEMAPHORE_ERROR); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_SEMAPHORE_ERROR, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_SEMAPHORE_ERROR); + } + + /* Check for the state of the device . If the device is already configured, + we need to cancel the existing configuration before enabling this one. */ + if (device -> ux_device_state == UX_DEVICE_CONFIGURED) + { + + /* If this configuration is already activated, we are good, + otherwise report error. */ + status = (device -> ux_device_current_configuration == configuration) ? + UX_SUCCESS : UX_ALREADY_ACTIVATED; + _ux_utility_semaphore_put(&device -> ux_device_protection_semaphore); + return(status); + } + + /* Scan and activate the interfaces. */ + status = _ux_host_stack_configuration_interface_scan(configuration); + + /* Return completion status. */ + return(status); +} diff --git a/common/core/src/ux_host_stack_device_configuration_deactivate.c b/common/core/src/ux_host_stack_device_configuration_deactivate.c new file mode 100644 index 0000000..384b556 --- /dev/null +++ b/common/core/src/ux_host_stack_device_configuration_deactivate.c @@ -0,0 +1,160 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Host Stack */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_stack_device_configuration_deactivate PORTABLE C */ +/* 6.1.4 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function deactivate current configuration for a device. */ +/* When this configuration is deactivated, all the device interfaces */ +/* are deactivated on the device. */ +/* */ +/* INPUT */ +/* */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_utility_semaphore_get Get semaphore */ +/* _ux_utility_semaphore_put Put semaphore */ +/* (ux_host_class_entry_function) Class entry function */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* USBX Components */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 02-02-2021 Chaoqiong Xiao Initial Version 6.1.4 */ +/* */ +/**************************************************************************/ +UINT _ux_host_stack_device_configuration_deactivate(UX_DEVICE *device) +{ + +UX_HOST_CLASS_COMMAND command; +UX_CONFIGURATION *configuration; +UX_INTERFACE *interface; +UINT status; + + + /* Do a sanity check on the device handle. */ + if (device -> ux_device_handle != (ULONG) (ALIGN_TYPE) device) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DEVICE_HANDLE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DEVICE_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_DEVICE_HANDLE_UNKNOWN); + } + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_CONFIGURATION_DEACTIVATE, device, configuration, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0) + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_utility_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + + /* Check for status. */ + if (status != UX_SUCCESS) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_SEMAPHORE_ERROR); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_SEMAPHORE_ERROR, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_SEMAPHORE_ERROR); + } + + /* Get the configuration. */ + configuration = device -> ux_device_current_configuration; + + /* Check for the state of the device, if not configured, we are done. */ + if (device -> ux_device_state != UX_DEVICE_CONFIGURED) + { + _ux_utility_semaphore_put(&device -> ux_device_protection_semaphore); + return(UX_SUCCESS); + } + + /* Deactivate classes by command. */ + command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_DEACTIVATE; + + /* Search for the active configuration. */ + configuration = device -> ux_device_current_configuration; + + /* If device configured configuration must be activated. */ + + /* We have the correct configuration, search the interface(s). */ + interface = configuration -> ux_configuration_first_interface; + + /* Loop to perform the search. */ + while (interface != UX_NULL) + { + + /* Check if an instance of the interface is present. */ + if (interface -> 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; + + /* Call the class. */ + interface -> ux_interface_class -> ux_host_class_entry_function(&command); + } + + /* Move to next interface. */ + interface = interface -> ux_interface_next_interface; + } + + /* The device can now be un-configured. */ + status = _ux_host_stack_device_configuration_reset(device); + + /* Return completion status. */ + return(status); +} 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 b340d75..20aa20d 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 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +68,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* used pointer for current */ +/* selected configuration, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ UINT _ux_host_stack_device_configuration_reset(UX_DEVICE *device) @@ -92,20 +96,15 @@ UINT status; { /* The device is configured. Get the first configuration pointer. */ - current_configuration = device -> ux_device_first_configuration; - - /* Traverse the configuration list until we find the right one. */ - while (current_configuration -> ux_configuration_descriptor.bConfigurationValue != - device -> ux_device_current_configuration) - { - - current_configuration = current_configuration -> ux_configuration_next_configuration; - } + current_configuration = device -> ux_device_current_configuration; /* Deselect this instance */ _ux_host_stack_configuration_instance_delete(current_configuration); } + /* No configuration is selected now. */ + device -> ux_device_current_configuration = UX_NULL; + /* Set state of device to ATTACHED. */ device -> ux_device_state = UX_DEVICE_ATTACHED; diff --git a/common/core/src/ux_host_stack_device_configuration_select.c b/common/core/src/ux_host_stack_device_configuration_select.c index dd8224a..80597dc 100644 --- a/common/core/src/ux_host_stack_device_configuration_select.c +++ b/common/core/src/ux_host_stack_device_configuration_select.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_device_configuration_select PORTABLE C */ -/* 6.1 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,10 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* used pointer for current */ +/* selected configuration, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ UINT _ux_host_stack_device_configuration_select(UX_CONFIGURATION *configuration) @@ -112,15 +116,7 @@ UINT status; { /* The device is configured. Get the first configuration pointer. */ - current_configuration = device -> ux_device_first_configuration; - - /* Traverse the configuration list until we find the right one. */ - while (current_configuration -> ux_configuration_descriptor.bConfigurationValue != - device -> ux_device_current_configuration) - { - - current_configuration = current_configuration -> ux_configuration_next_configuration; - } + current_configuration = device -> ux_device_current_configuration; /* Deselect this instance */ _ux_host_stack_configuration_instance_delete(current_configuration); diff --git a/common/core/src/ux_host_stack_device_remove.c b/common/core/src/ux_host_stack_device_remove.c index 020c900..1a46658 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 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,12 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* used pointer for current */ +/* selected configuration, */ +/* added notification for */ +/* device disconnection, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ UINT _ux_host_stack_device_remove(UX_HCD *hcd, UX_DEVICE *parent, UINT port_index) @@ -160,46 +166,42 @@ UX_HOST_CLASS_COMMAND command; { /* Search for the active configuration. */ - configuration = device -> ux_device_first_configuration; + configuration = device -> ux_device_current_configuration; - /* Parse the interface(s) for this device in search of the classes - who own this device. */ - while (configuration != UX_NULL) + /* If configuration is activated. */ + if (configuration != UX_NULL) { - /* Is this the correct configuration? */ - if (configuration -> ux_configuration_descriptor.bConfigurationValue == - device -> ux_device_current_configuration) - { + /* We have the correct configuration, search the interface(s). */ + interface = configuration -> ux_configuration_first_interface; - /* We have the correct configuration, search the interface(s). */ - interface = configuration -> ux_configuration_first_interface; + /* Loop to perform the search. */ + while (interface != UX_NULL) + { - /* Loop to perform the search. */ - while (interface != UX_NULL) + /* Check if an instance of the interface is present. */ + if (interface -> ux_interface_class_instance != UX_NULL) { - /* Check if an instance of the interface is present. */ - if (interface -> 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; + /* We need to stop the class instance for the device. */ + command.ux_host_class_command_instance = interface -> ux_interface_class_instance; - /* Call the class. */ - interface -> ux_interface_class -> ux_host_class_entry_function(&command); - } - - /* Move to next interface. */ - interface = interface -> ux_interface_next_interface; + /* Call the class. */ + interface -> ux_interface_class -> ux_host_class_entry_function(&command); } - } - /* Move to next configuration in the list. */ - configuration = configuration -> ux_configuration_next_configuration; + /* Move to next interface. */ + interface = interface -> ux_interface_next_interface; + } } } + /* Notify application for disconnection of existing physical device. */ + if (_ux_system_host -> ux_system_host_change_function) + { + _ux_system_host -> ux_system_host_change_function(UX_DEVICE_DISCONNECTION, UX_NULL, (VOID*)device); + } + /* Now all the resources for this device must be free. */ _ux_host_stack_device_resources_free(device); diff --git a/common/core/src/ux_host_stack_device_string_get.c b/common/core/src/ux_host_stack_device_string_get.c new file mode 100644 index 0000000..90274ab --- /dev/null +++ b/common/core/src/ux_host_stack_device_string_get.c @@ -0,0 +1,126 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/** Host Stack */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_printer.h" +#include "ux_host_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_stack_device_string_get PORTABLE C */ +/* 6.1.4 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function obtains the device string descriptor. */ +/* */ +/* INPUT */ +/* */ +/* device Pointer to device instance */ +/* descriptor_buffer Pointer to a buffer to fill */ +/* LANGID or STRING descriptor */ +/* length Length of buffer */ +/* language_id 0 to obtain LANGID descriptor */ +/* valid language ID to obtain */ +/* string descriptor */ +/* string_index Index of the string */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_transfer_request Process transfer request */ +/* _ux_utility_semaphore_get Get Semaphore */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 02-02-2021 Chaoqiong Xiao Initial Version 6.1.4 */ +/* */ +/**************************************************************************/ +UINT _ux_host_stack_device_string_get(UX_DEVICE *device, UCHAR *descriptor_buffer, ULONG length, ULONG language_id, ULONG string_index) +{ +UX_ENDPOINT *control_endpoint; +UX_TRANSFER *transfer_request; +UINT status; + + + /* Do a sanity check on the device handle. */ + if (device -> ux_device_handle != (ULONG) (ALIGN_TYPE) device) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DEVICE_HANDLE_UNKNOWN); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DEVICE_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_DEVICE_HANDLE_UNKNOWN); + } + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_STRING_GET, device, descriptor_buffer, length, (language_id << 16) | string_index, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_utility_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + + /* Check for status. */ + if (status != UX_SUCCESS) + return(UX_SEMAPHORE_ERROR); + + /* 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; + + /* Create a transfer request for the GET_DEVICE_ID request. */ + transfer_request -> ux_transfer_request_data_pointer = descriptor_buffer; + transfer_request -> ux_transfer_request_requested_length = 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_STRING_DESCRIPTOR_ITEM << 8) | string_index; + transfer_request -> ux_transfer_request_index = (language_id); + + /* Send request to HCD layer. */ + status = _ux_host_stack_transfer_request(transfer_request); + + /* Return completion status. */ + return(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 bc0042e..bc0042e 100644..100755 --- a/common/core/src/ux_host_stack_hcd_thread_entry.c +++ b/common/core/src/ux_host_stack_hcd_thread_entry.c diff --git a/common/core/src/ux_host_stack_hcd_unregister.c b/common/core/src/ux_host_stack_hcd_unregister.c index 277cf1a..277cf1a 100644..100755 --- a/common/core/src/ux_host_stack_hcd_unregister.c +++ b/common/core/src/ux_host_stack_hcd_unregister.c 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 d185cdf..e57bca6 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 @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_hnp_polling_thread_entry PORTABLE C */ -/* 6.1 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -76,6 +76,10 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* used pointer for current */ +/* selected configuration, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ VOID _ux_host_stack_hnp_polling_thread_entry(ULONG argument) @@ -153,73 +157,58 @@ UINT status; /* We have a device on a OTG port. But is it a OTG HNP capable device ? We need to parse the configuration until we find the one current. */ - configuration = device -> ux_device_first_configuration; + configuration = device -> ux_device_current_configuration; - /* Are we at the of the configuration list ? */ - while (configuration != UX_NULL) + /* Check for OTG HNP support. */ + if (configuration -> ux_configuration_otg_capabilities & UX_OTG_HNP_SUPPORT) { - - /* Is this the current configuration ? */ - if (configuration -> ux_configuration_descriptor.bConfigurationValue == - device -> ux_device_current_configuration) - { - - /* Check for OTG HNP support. */ - if (configuration -> ux_configuration_otg_capabilities & UX_OTG_HNP_SUPPORT) - { - - /* Allocate memory for the OTG status. */ - otg_status = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 16); - - /* Check for status. */ - if (otg_status == UX_NULL) - return; - - /* Retrieve the control endpoint and the transfer request associated with it. */ - control_endpoint = &device -> ux_device_control_endpoint; - transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + + /* Allocate memory for the OTG status. */ + otg_status = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 16); - /* Protect the control endpoint semaphore here. It will be unprotected in the - transfer request function. */ - status = _ux_utility_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + /* Check for status. */ + if (otg_status == UX_NULL) + return; + + /* Retrieve the control endpoint and the transfer request associated with it. */ + control_endpoint = &device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; - /* Perform a GET_STATUS on this device to see if it wants to become the host. */ - /* Create a transfer_request for the SET_CONFIGURATION request. No data for this request. */ - transfer_request -> ux_transfer_request_data_pointer = otg_status; - transfer_request -> ux_transfer_request_requested_length = 1; - transfer_request -> ux_transfer_request_function = UX_GET_STATUS; - transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; - transfer_request -> ux_transfer_request_value = 0; - transfer_request -> ux_transfer_request_index = UX_OTG_STATUS_SELECTOR; - - /* Send request to HCD layer. */ - status = _ux_host_stack_transfer_request(transfer_request); - - /* Check completion status. */ - if(status == UX_SUCCESS && transfer_request -> ux_transfer_request_actual_length == 1) - { - - /* We have an answer from the device. Check the HNP flag. */ - if (*otg_status & UX_OTG_HOST_REQUEST_FLAG) - { + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_utility_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); - /* The device has requested a Host swap. Initiate the command and perform the - stopping of the host. */ - _ux_host_stack_role_swap(device); - } - - } - - /* Free all used resources. */ - _ux_utility_memory_free(otg_status); + /* Perform a GET_STATUS on this device to see if it wants to become the host. */ + /* Create a transfer_request for the SET_CONFIGURATION request. No data for this request. */ + transfer_request -> ux_transfer_request_data_pointer = otg_status; + transfer_request -> ux_transfer_request_requested_length = 1; + transfer_request -> ux_transfer_request_function = UX_GET_STATUS; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE; + transfer_request -> ux_transfer_request_value = 0; + transfer_request -> ux_transfer_request_index = UX_OTG_STATUS_SELECTOR; + + /* Send request to HCD layer. */ + status = _ux_host_stack_transfer_request(transfer_request); + + /* Check completion status. */ + if(status == UX_SUCCESS && transfer_request -> ux_transfer_request_actual_length == 1) + { + + /* We have an answer from the device. Check the HNP flag. */ + if (*otg_status & UX_OTG_HOST_REQUEST_FLAG) + { + /* The device has requested a Host swap. Initiate the command and perform the + stopping of the host. */ + _ux_host_stack_role_swap(device); } + } + + /* Free all used resources. */ + _ux_utility_memory_free(otg_status); - /* Move to next configuration in the list. */ - configuration = configuration -> ux_configuration_next_configuration; - - } + } } } 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 af6a109..e9ee549 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 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -59,6 +59,8 @@ /* without creating an */ /* OVER_CURRENT condition on */ /* the bus */ +/* created_device Destination to fill created */ +/* device instance */ /* */ /* OUTPUT */ /* */ @@ -96,11 +98,16 @@ /* optimized based on compile */ /* definitions, */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added a new parameter to */ +/* return created device, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ UINT _ux_host_stack_new_device_create(UX_HCD *hcd, UX_DEVICE *device_owner, UINT port_index, UINT device_speed, - UINT port_max_power) + UINT port_max_power, + UX_DEVICE **created_device) { UX_DEVICE *device; @@ -138,6 +145,9 @@ UX_ENDPOINT *control_endpoint; return(UX_TOO_MANY_DEVICES); } + /* Store the device instance. */ + *created_device = device; + /* Increment the number of devices on this bus. */ hcd -> ux_hcd_nb_devices++; diff --git a/common/core/src/ux_host_stack_rh_change_process.c b/common/core/src/ux_host_stack_rh_change_process.c index ccce8e8..ccce8e8 100644..100755 --- a/common/core/src/ux_host_stack_rh_change_process.c +++ b/common/core/src/ux_host_stack_rh_change_process.c diff --git a/common/core/src/ux_host_stack_rh_device_insertion.c b/common/core/src/ux_host_stack_rh_device_insertion.c index a30ed4a..6e33f47 100644 --- a/common/core/src/ux_host_stack_rh_device_insertion.c +++ b/common/core/src/ux_host_stack_rh_device_insertion.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_stack_rh_device_insertion PORTABLE C */ -/* 6.1 */ +/* 6.1.4 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,11 +73,20 @@ /* checked HCD status before */ /* retrying enumeration, */ /* resulting in version 6.1 */ +/* 02-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* handled more fail cases, */ +/* updated internal call, */ +/* added notification for */ +/* device connection, */ +/* added disconnection check */ +/* in enumeration retries, */ +/* resulting in version 6.1.4 */ /* */ /**************************************************************************/ UINT _ux_host_stack_rh_device_insertion(UX_HCD *hcd, UINT port_index) { +UX_DEVICE *device; UINT index_loop; UINT device_speed; ULONG port_status; @@ -125,12 +134,20 @@ UINT status; return(UX_DEVICE_ENUMERATION_FAILURE); } + /* Check if device is still connected. */ + if ((port_status & UX_PS_CCS) == 0) + { + + /* Device disconnected during enumeration retries. */ + return(UX_DEVICE_ENUMERATION_FAILURE); + } + /* Set the device speed. */ device_speed = port_status >> UX_PS_DS; /* Ask the USB stack to enumerate this device. A root hub is considered self powered. */ - status = _ux_host_stack_new_device_create(hcd, UX_NULL, port_index, device_speed, UX_MAX_SELF_POWER); + status = _ux_host_stack_new_device_create(hcd, UX_NULL, port_index, device_speed, UX_MAX_SELF_POWER, &device); /* Check return status. */ if (status == UX_SUCCESS) @@ -143,6 +160,12 @@ UINT status; function again */ hcd -> ux_hcd_rh_device_connection |= (ULONG)(1 << port_index); + /* If the device instance is ready, notify application for connection. */ + if (_ux_system_host -> ux_system_host_change_function) + { + _ux_system_host -> ux_system_host_change_function(UX_DEVICE_CONNECTION, UX_NULL, (VOID*)device); + } + /* Return success to the caller. */ return(UX_SUCCESS); } @@ -153,10 +176,18 @@ UINT status; if (hcd -> ux_hcd_status != UX_HCD_STATUS_OPERATIONAL) return(UX_CONTROLLER_DEAD); + /* No retry if there are too many devices. */ + if (status == UX_TOO_MANY_DEVICES) + break; + + /* No retry if there is no class found. */ + if (status == UX_NO_CLASS_MATCH) + break; + /* Simulate remove to free allocated resources if retry. */ if (index_loop < UX_RH_ENUMERATION_RETRY - 1) - _ux_host_stack_device_remove(hcd, UX_NULL, port_index); - } + _ux_host_stack_device_remove(hcd, UX_NULL, port_index); + } } /* We get here if something did not go well. Either the port did not respond @@ -165,10 +196,19 @@ UINT status; _ux_utility_delay_ms(UX_RH_ENUMERATION_RETRY_DELAY); } - /* If we get here, the device did not enumerate completely. The device is still attached to the root - hub and therefore there is a physical connection with a unenumerated device. */ + /* If we get here, the device did not enumerate completely. + The device is still attached to the root hub and therefore + there could be a physical connection with a unconfigured device. */ hcd -> ux_hcd_rh_device_connection |= (ULONG)(1 << port_index); + /* Notify application for a physical connection failed to be enumed. + Device instance NULL indicates too many devices. + Device state unconfigured indicates enumeration fail. */ + if (_ux_system_host -> ux_system_host_change_function) + { + _ux_system_host -> ux_system_host_change_function(UX_DEVICE_CONNECTION, UX_NULL, (VOID*)device); + } + /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE); diff --git a/common/core/src/ux_utility_delay_ms.c b/common/core/src/ux_utility_delay_ms.c index e996b04..e996b04 100644..100755 --- a/common/core/src/ux_utility_delay_ms.c +++ b/common/core/src/ux_utility_delay_ms.c |
