GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_interface_setting_select.c Lines: 36 40 90.0 %
Date: 2026-03-06 18:57:10 Branches: 14 16 87.5 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
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_interface_setting_select             PORTABLE C      */
37
/*                                                           6.1.12       */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Chaoqiong Xiao, Microsoft Corporation                               */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function selects a specific alternate setting for a given      */
45
/*    interface belonging to the selected configuration.                  */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    interface                             Pointer to interface          */
50
/*                                                                        */
51
/*  OUTPUT                                                                */
52
/*                                                                        */
53
/*    Completion Status                                                   */
54
/*                                                                        */
55
/*  CALLS                                                                 */
56
/*                                                                        */
57
/*    _ux_host_stack_interface_instance_create  Create interface instance */
58
/*    _ux_host_stack_interface_instance_delete  Delete interface instance */
59
/*    _ux_host_stack_interface_set              Set interface instance    */
60
/*    _ux_host_semaphore_get                    Get semaphore             */
61
/*    _ux_host_semaphore_put                    Put semaphore             */
62
/*                                                                        */
63
/*  CALLED BY                                                             */
64
/*                                                                        */
65
/*    Application                                                         */
66
/*    USBX Components                                                     */
67
/*                                                                        */
68
/**************************************************************************/
69
168
UINT  _ux_host_stack_interface_setting_select(UX_INTERFACE *interface_ptr)
70
{
71
72
UX_CONFIGURATION    *configuration;
73
UX_INTERFACE        *current_interface;
74
UX_INTERFACE        *previous_interface;
75
UX_INTERFACE        *main_interface;
76
UINT                current_interface_number;
77
UINT                current_alternate_setting;
78
UINT                status;
79
80
    /* If trace is enabled, insert this event into the trace buffer.  */
81
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_INTERFACE_SETTING_SELECT, interface_ptr, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
82
83
    /* Check this alternate setting container. It must be valid before
84
       we continue.  */
85
168
    if (interface_ptr -> ux_interface_handle != (ULONG) (ALIGN_TYPE) interface_ptr)
86
    {
87
        /* If trace is enabled, insert this event into the trace buffer.  */
88
        UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface_ptr, 0, 0, UX_TRACE_ERRORS, 0, 0)
89
90
1
        return(UX_INTERFACE_HANDLE_UNKNOWN);
91
    }
92
93
    /* From the interface, get the configuration container and the first
94
       interface hooked to this configuration.  */
95
167
    configuration =             interface_ptr -> ux_interface_configuration;
96
167
    current_interface_number =  interface_ptr -> ux_interface_descriptor.bInterfaceNumber;
97
167
    current_interface =         configuration -> ux_configuration_first_interface;
98
99
    /* Remember the main interface to store the next alternate setting.  We set the main interface
100
       to the first interface to keep the compiler happy. */
101
167
    main_interface =  current_interface;
102
103
    /* In order to keep the compiler happy, we reset the alternate setting.  */
104
167
    current_alternate_setting =  0;
105
167
    previous_interface = UX_NULL;
106
107
    /* Search for the current alternate setting for this interface.
108
       All its endpoints will need to be destroyed.
109
       Since interfaces in the parent configuration should be linked together
110
       in correct way, just find it in while loop.
111
     */
112
    while (1)
113
    {
114
115
        /* Try to locate the first interface container in the interface chain which
116
           has the same interface number as the one supplied by the caller.  */
117
355
        if (current_interface -> ux_interface_descriptor.bInterfaceNumber == current_interface_number)
118
        {
119
120
            /* The alternate setting 0 of this interface has the current selected
121
               alternate setting.  */
122
192
            if (current_interface -> ux_interface_descriptor.bAlternateSetting == 0)
123
            {
124
125
                /* Set the alternate setting.  */
126
167
                current_alternate_setting =  current_interface -> ux_interface_current_alternate_setting;
127
128
                /* Remember the main interface to store the next alternate setting.  */
129
167
                main_interface =  current_interface;
130
131
            }
132
133
            /* See if the current alternate setting matches that of the interface alternate setting.  */
134
192
            if (current_alternate_setting == current_interface -> ux_interface_descriptor.bAlternateSetting)
135
            {
136
137
                /* Yes, save the current alternate setting.  */
138
167
                previous_interface = current_interface;
139
140
                /* Then delete the current interface.  */
141
167
                _ux_host_stack_interface_instance_delete(current_interface);
142
143
                /* We are done in this loop.  */
144
167
                break;
145
146
            }
147
        }
148
149
        /* Move to the next interface. */
150
188
        current_interface =  current_interface -> ux_interface_next_interface;
151
    }
152
153
    /* Remember the new alternate setting.  */
154
167
    main_interface -> ux_interface_current_alternate_setting =  interface_ptr -> ux_interface_descriptor.bAlternateSetting;
155
156
    /* Now, the interface must be created with the new alternate setting.  */
157
167
    status =  _ux_host_stack_interface_instance_create(interface_ptr);
158
159
    /* If we could not create it, we return to the default one.  */
160
167
    if (status != UX_SUCCESS)
161
    {
162
163
        /* Then delete the failed interface.  */
164
10
        _ux_host_stack_interface_instance_delete(interface_ptr);
165
166
        /* Error, reset the main interface alternate setting to the default.  */
167
10
        main_interface -> ux_interface_current_alternate_setting =  current_alternate_setting;
168
169
        /* Re-create the previous interface with the old alternate setting.  */
170
10
        _ux_host_stack_interface_instance_create(previous_interface);
171
172
        /* Return error status.  */
173
10
        return(status);
174
    }
175
176
    /* Protect the control endpoint semaphore here.  It will be unprotected in the
177
       transfer request function.  */
178
157
    status =  _ux_host_semaphore_get(&configuration -> ux_configuration_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
179
157
    if (status != UX_SUCCESS)
180
1
        return(status);
181
182
    /* Issue a SET_INTERFACE command to the target device.  */
183
156
    status =  _ux_host_stack_interface_set(interface_ptr);
184
185
    /* Check completion status.  */
186
156
    if (status != UX_SUCCESS)
187
    {
188
189
        /* Error, reset the main interface alternate setting to the default.  */
190
14
        main_interface -> ux_interface_current_alternate_setting =  current_alternate_setting;
191
192
        /* Delete the current interface.  */
193
14
        _ux_host_stack_interface_instance_delete(interface_ptr);
194
195
        /* Re-create the previous interface with the old alternate setting.  */
196
14
        _ux_host_stack_interface_instance_create(previous_interface);
197
198
        /* Return error status.  */
199
14
        _ux_host_semaphore_put(&configuration -> ux_configuration_device -> ux_device_protection_semaphore);
200
14
        return(status);
201
    }
202
203
    /* Return to caller.  */
204
142
    return(status);
205
}
206
207
208
/**************************************************************************/
209
/*                                                                        */
210
/*  FUNCTION                                               RELEASE        */
211
/*                                                                        */
212
/*    _uxe_host_stack_interface_setting_select            PORTABLE C      */
213
/*                                                           6.3.0        */
214
/*  AUTHOR                                                                */
215
/*                                                                        */
216
/*    Chaoqiong Xiao, Microsoft Corporation                               */
217
/*                                                                        */
218
/*  DESCRIPTION                                                           */
219
/*                                                                        */
220
/*    This function checks errors in host stack interface select function */
221
/*    call.                                                               */
222
/*                                                                        */
223
/*  INPUT                                                                 */
224
/*                                                                        */
225
/*    interface_ptr                         Pointer to interface          */
226
/*                                                                        */
227
/*  OUTPUT                                                                */
228
/*                                                                        */
229
/*    None                                                                */
230
/*                                                                        */
231
/*  CALLS                                                                 */
232
/*                                                                        */
233
/*    _ux_host_stack_interface_setting_select                             */
234
/*                                          Interface setting select      */
235
/*                                                                        */
236
/*  CALLED BY                                                             */
237
/*                                                                        */
238
/*    Application                                                         */
239
/*                                                                        */
240
/**************************************************************************/
241
UINT  _uxe_host_stack_interface_setting_select(UX_INTERFACE *interface_ptr)
242
{
243
244
    /* Sanity check.  */
245
    if (interface_ptr == UX_NULL)
246
        return(UX_INVALID_PARAMETER);
247
248
    /* Invoke interface setting select function.  */
249
    return(_ux_host_stack_interface_setting_select(interface_ptr));
250
}