1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 13 /**************************************************************************/ 14 /**************************************************************************/ 15 /** */ 16 /** USBX Component */ 17 /** */ 18 /** Host Stack */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 24 /* Include necessary system files. */ 25 26 #define UX_SOURCE_CODE 27 28 #include "ux_api.h" 29 #include "ux_host_stack.h" 30 31 32 /**************************************************************************/ 33 /* */ 34 /* FUNCTION RELEASE */ 35 /* */ 36 /* _ux_host_stack_configuration_interface_scan PORTABLE C */ 37 /* 6.1.12 */ 38 /* AUTHOR */ 39 /* */ 40 /* Chaoqiong Xiao, Microsoft Corporation */ 41 /* */ 42 /* DESCRIPTION */ 43 /* */ 44 /* This function will scan all default interfaces for a specific */ 45 /* configuration and call the registered class with the */ 46 /* Class/SubClass/Protocol of the interface. */ 47 /* */ 48 /* INPUT */ 49 /* */ 50 /* configuration Configuration pointer */ 51 /* */ 52 /* OUTPUT */ 53 /* */ 54 /* Result of operation */ 55 /* */ 56 /* CALLS */ 57 /* */ 58 /* _ux_host_stack_class_call Call class command */ 59 /* _ux_host_stack_device_configuration_select */ 60 /* Select configuration */ 61 /* _ux_host_stack_class_call Call class from host stack */ 62 /* (ux_host_class_entry_function) Class entry function */ 63 /* */ 64 /* CALLED BY */ 65 /* */ 66 /* USBX Components */ 67 /* */ 68 /* RELEASE HISTORY */ 69 /* */ 70 /* DATE NAME DESCRIPTION */ 71 /* */ 72 /* 02-02-2021 Chaoqiong Xiao Initial Version 6.1.4 */ 73 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ 74 /* added standalone support, */ 75 /* resulting in version 6.1.10 */ 76 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ 77 /* fixed parameter/variable */ 78 /* names conflict C++ keyword, */ 79 /* resulting in version 6.1.12 */ 80 /* */ 81 /**************************************************************************/ _ux_host_stack_configuration_interface_scan(UX_CONFIGURATION * configuration)82UINT _ux_host_stack_configuration_interface_scan(UX_CONFIGURATION *configuration) 83 { 84 85 UX_INTERFACE *interface_ptr; 86 UINT nb_class_owners; 87 UX_HOST_CLASS *class_ptr; 88 UX_HOST_CLASS_COMMAND class_command; 89 UINT status; 90 91 92 /* Initialize class owners to 0. */ 93 nb_class_owners = 0; 94 95 /* Get the first interface container for this configuration. */ 96 interface_ptr = configuration -> ux_configuration_first_interface; 97 98 /* We now scan all the alternate settings 0 for each of the interfaces. */ 99 while (interface_ptr != UX_NULL) 100 { 101 102 /* Is there a default interface? */ 103 if(interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0) 104 { 105 106 /* We have a default interface for this configuration. Call each class 107 with the class\subclass\protocol. We include the IAD for the cdc classes. */ 108 class_command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY; 109 class_command.ux_host_class_command_container = (VOID *)interface_ptr; 110 class_command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP; 111 class_command.ux_host_class_command_class = interface_ptr -> ux_interface_descriptor.bInterfaceClass; 112 class_command.ux_host_class_command_subclass = interface_ptr -> ux_interface_descriptor.bInterfaceSubClass; 113 class_command.ux_host_class_command_protocol = interface_ptr -> ux_interface_descriptor.bInterfaceProtocol; 114 class_command.ux_host_class_command_iad_class = interface_ptr -> ux_interface_iad_class ; 115 class_command.ux_host_class_command_iad_subclass = interface_ptr -> ux_interface_iad_subclass; 116 class_command.ux_host_class_command_iad_protocol = interface_ptr -> ux_interface_iad_protocol; 117 118 class_ptr = _ux_host_stack_class_call(&class_command); 119 120 /* On return, either we have found a class or the interface is still an orphan. */ 121 if (class_ptr != UX_NULL) 122 { 123 124 /* There is a class. */ 125 nb_class_owners++; 126 interface_ptr -> ux_interface_class = class_ptr; 127 } 128 } 129 130 /* point to the next interface until end of the list. */ 131 interface_ptr = interface_ptr -> ux_interface_next_interface; 132 } 133 134 #if defined(UX_HOST_STANDALONE) 135 136 /* Activated later in state machine. */ 137 status = (nb_class_owners > 0) ? UX_SUCCESS : UX_NO_CLASS_MATCH; 138 return(status); 139 #else 140 141 /* Assume no classes. */ 142 status = UX_NO_CLASS_MATCH; 143 144 /* Check the number of class owner found. */ 145 if (nb_class_owners != 0) 146 { 147 148 /* If we have found one or more classes for any of the interfaces, 149 we can safely do a SET_CONFIGURATION of the device. */ 150 status = _ux_host_stack_device_configuration_select(configuration); 151 152 /* Check the completion status. */ 153 if (status == UX_SUCCESS) 154 { 155 156 /* The device is in the CONFIGURED state, we have to call each of the classes 157 again with an ACTIVATE signal. */ 158 interface_ptr = configuration -> ux_configuration_first_interface; 159 160 while (interface_ptr != UX_NULL) 161 { 162 163 /* Is there a default interface? */ 164 if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0) 165 { 166 167 /* We have found the default interface. If this interface is owned, 168 activate its class. */ 169 class_command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_ACTIVATE; 170 class_command.ux_host_class_command_container = (VOID *) interface_ptr; 171 172 if (interface_ptr -> ux_interface_class != UX_NULL) 173 { 174 175 /* Save the class in the command container */ 176 class_command.ux_host_class_command_class_ptr = interface_ptr -> ux_interface_class; 177 178 /* Send the ACTIVATE command to the class */ 179 status = interface_ptr -> ux_interface_class -> ux_host_class_entry_function(&class_command); 180 181 } 182 } 183 184 /* Point to the next interface until end of the list. */ 185 interface_ptr = interface_ptr -> ux_interface_next_interface; 186 } 187 } 188 } 189 190 /* Return operation result. */ 191 return(status); 192 #endif 193 } 194 195