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