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)81 UINT  _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