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_device_configuration_select          PORTABLE C      */
37 /*                                                           6.1.10       */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Chaoqiong Xiao, Microsoft Corporation                               */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function selects a specific configuration for a device.        */
45 /*    When this configuration is set to the device, by default all the    */
46 /*    device interface and their associated alternate setting 0 is        */
47 /*    activated on the device. If the device/interface class driver       */
48 /*    wishes to change the setting of a particular interface, it needs    */
49 /*    to issue a select interface setting function.                       */
50 /*                                                                        */
51 /*  INPUT                                                                 */
52 /*                                                                        */
53 /*    configuration                          Pointer to configuration     */
54 /*                                                                        */
55 /*  OUTPUT                                                                */
56 /*                                                                        */
57 /*    Completion Status                                                   */
58 /*                                                                        */
59 /*  CALLS                                                                 */
60 /*                                                                        */
61 /*    _ux_host_stack_configuration_instance_create Create configuration   */
62 /*                                                   instance             */
63 /*    _ux_host_stack_configuration_instance_delete Delete configuration   */
64 /*                                                   instance             */
65 /*    _ux_host_stack_configuration_set             Set configuration      */
66 /*                                                                        */
67 /*  CALLED BY                                                             */
68 /*                                                                        */
69 /*    Application                                                         */
70 /*    USBX Components                                                     */
71 /*                                                                        */
72 /*  RELEASE HISTORY                                                       */
73 /*                                                                        */
74 /*    DATE              NAME                      DESCRIPTION             */
75 /*                                                                        */
76 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
77 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
78 /*                                            optimized based on compile  */
79 /*                                            definitions,                */
80 /*                                            resulting in version 6.1    */
81 /*  02-02-2021     Chaoqiong Xiao           Modified comment(s),          */
82 /*                                            used pointer for current    */
83 /*                                            selected configuration,     */
84 /*                                            resulting in version 6.1.4  */
85 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
86 /*                                            refine power usage check,   */
87 /*                                            resulting in version 6.1.10 */
88 /*                                                                        */
89 /**************************************************************************/
_ux_host_stack_device_configuration_select(UX_CONFIGURATION * configuration)90 UINT  _ux_host_stack_device_configuration_select(UX_CONFIGURATION *configuration)
91 {
92 
93 UX_DEVICE               *device;
94 UX_CONFIGURATION        *current_configuration;
95 UINT                    status;
96 
97     /* Check for validity of the configuration handle.  */
98     if (configuration -> ux_configuration_handle != (ULONG) (ALIGN_TYPE) configuration)
99     {
100 
101         /* Error trap. */
102         _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_CONFIGURATION_HANDLE_UNKNOWN);
103 
104         /* If trace is enabled, insert this event into the trace buffer.  */
105         UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONFIGURATION_HANDLE_UNKNOWN, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0)
106 
107         return(UX_CONFIGURATION_HANDLE_UNKNOWN);
108     }
109 
110     /* Get the device container for this configuration.  */
111     device =  configuration -> ux_configuration_device;
112 
113     /* If trace is enabled, insert this event into the trace buffer.  */
114     UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_CONFIGURATION_SELECT, device, configuration, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
115 
116     /* We need to check the amount of power the bus powered device is consuming
117        before switch configuration. Otherwise we may run the risk of
118        an over current fault. */
119     if (((configuration -> ux_configuration_descriptor.bmAttributes & UX_CONFIGURATION_DEVICE_SELF_POWERED) == 0) &&
120          (configuration -> ux_configuration_descriptor.MaxPower > UX_DEVICE_MAX_POWER_GET(device)))
121     {
122 
123         /* Error trap. */
124         _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_OVER_CURRENT_CONDITION);
125 
126         /* If trace is enabled, insert this event into the trace buffer.  */
127         UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_OVER_CURRENT_CONDITION, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0)
128 
129         return(UX_OVER_CURRENT_CONDITION);
130     }
131 
132     /* Check for the state of the device . If the device is already configured,
133        we need to cancel the existing configuration before enabling this one.   */
134     if (device -> ux_device_state == UX_DEVICE_CONFIGURED)
135     {
136 
137         /* The device is configured. Get the first configuration pointer.  */
138         current_configuration =  device -> ux_device_current_configuration;
139 
140         /* Deselect this instance */
141         _ux_host_stack_configuration_instance_delete(current_configuration);
142     }
143 
144     /* The device can now be configured.  */
145     status =  _ux_host_stack_configuration_set(configuration);
146     if (status != UX_SUCCESS)
147         return(status);
148 
149     /* Create the configuration instance.  */
150     status =  _ux_host_stack_configuration_instance_create(configuration);
151 
152     /* Return completion status.  */
153     return(status);
154 }
155 
156