GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_interface_setting_select.c Lines: 36 40 90.0 %
Date: 2024-12-12 17:16:36 Branches: 14 16 87.5 %

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