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