GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_new_interface_create.c Lines: 36 36 100.0 %
Date: 2024-12-12 17:16:36 Branches: 22 22 100.0 %

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_new_interface_create                 PORTABLE C      */
36
/*                                                           6.1.12       */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Chaoqiong Xiao, Microsoft Corporation                               */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This function creates a new interface for the current configuration */
44
/*    scanned. A device has at least 1 alternate setting per interface    */
45
/*    which is the default one.                                           */
46
/*                                                                        */
47
/*    The interface is hooked to the configuration that owns it.          */
48
/*                                                                        */
49
/*    From the interface descriptor, all the endpoints are hooked but     */
50
/*    not activated.                                                      */
51
/*                                                                        */
52
/*  INPUT                                                                 */
53
/*                                                                        */
54
/*    configuration                         Configuration container that  */
55
/*                                            owns this interface         */
56
/*    interface_pointer                     Pointer to a unparsed         */
57
/*                                            interface descriptor        */
58
/*    length                                Length remaining in this      */
59
/*                                            descriptor                  */
60
/*                                                                        */
61
/*  OUTPUT                                                                */
62
/*                                                                        */
63
/*    Completion Status                                                   */
64
/*                                                                        */
65
/*  CALLS                                                                 */
66
/*                                                                        */
67
/*    _ux_host_stack_new_endpoint_create    Create new endpoint           */
68
/*    _ux_utility_descriptor_parse          Parse the descriptor          */
69
/*    _ux_utility_memory_allocate           Allocate memory block         */
70
/*                                                                        */
71
/*  CALLED BY                                                             */
72
/*                                                                        */
73
/*    USBX Components                                                     */
74
/*                                                                        */
75
/*  RELEASE HISTORY                                                       */
76
/*                                                                        */
77
/*    DATE              NAME                      DESCRIPTION             */
78
/*                                                                        */
79
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
80
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
81
/*                                            resulting in version 6.1    */
82
/*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
83
/*                                            fixed parameter/variable    */
84
/*                                            names conflict C++ keyword, */
85
/*                                            resulting in version 6.1.12 */
86
/*                                                                        */
87
/**************************************************************************/
88
1972
UINT  _ux_host_stack_new_interface_create(UX_CONFIGURATION *configuration,
89
                                            UCHAR * descriptor, ULONG length)
90
{
91
92
UX_INTERFACE        *list_interface;
93
UX_INTERFACE        *interface_ptr;
94
UINT                number_endpoints;
95
UINT                descriptor_length;
96
UINT                descriptor_type;
97
UINT                status;
98
UCHAR               *this_interface_descriptor;
99
100
    /* Obtain memory for storing this new interface.  */
101
1972
    interface_ptr =  (UX_INTERFACE *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_INTERFACE));
102
103
    /* If no memory left, exit with error.  */
104
1972
    if (interface_ptr == UX_NULL)
105
3
        return(UX_MEMORY_INSUFFICIENT);
106
107
    /* Save the interface handle in the container, this is for ensuring the
108
       interface container is not corrupted.  */
109
1969
    interface_ptr -> ux_interface_handle =  (ULONG) (ALIGN_TYPE) interface_ptr;
110
111
    /* Parse the interface descriptor and make it machine independent.  */
112
1969
    _ux_utility_descriptor_parse(descriptor,
113
                            _ux_system_interface_descriptor_structure,
114
                            UX_INTERFACE_DESCRIPTOR_ENTRIES,
115
1969
                            (UCHAR *) &interface_ptr -> ux_interface_descriptor);
116
117
    /* The configuration that owns this interface is memorized in the
118
       interface container itself, easier for back chaining.  */
119
1969
    interface_ptr -> ux_interface_configuration =  configuration;
120
121
    /* If the interface belongs to an IAD, remember the IAD Class/SubClass/Protocol.  */
122
1969
    interface_ptr -> ux_interface_iad_class    = configuration -> ux_configuration_iad_class;
123
1969
    interface_ptr -> ux_interface_iad_subclass = configuration -> ux_configuration_iad_subclass;
124
1969
    interface_ptr -> ux_interface_iad_protocol = configuration -> ux_configuration_iad_protocol;
125
126
    /* There is 2 cases for the creation of the interface descriptor
127
       if this is the first one, the interface descriptor is hooked
128
       to the configuration. If it is not the first one, the interface
129
       is hooked to the end of the chain of interfaces.  */
130
1969
    if (configuration -> ux_configuration_first_interface == UX_NULL)
131
    {
132
1048
        configuration -> ux_configuration_first_interface =  interface_ptr;
133
    }
134
    else
135
    {
136
137
921
        list_interface =  configuration -> ux_configuration_first_interface;
138
139
        /* Traverse the list until we reach the end */
140
1397
        while (list_interface -> ux_interface_next_interface != UX_NULL)
141
        {
142
143
476
            list_interface =  list_interface -> ux_interface_next_interface;
144
        }
145
146
        /* Hook the interface.  */
147
921
        list_interface -> ux_interface_next_interface =  interface_ptr;
148
    }
149
150
    /* Traverse the interface in search of all endpoints that belong to it.
151
       We need the length remaining in the descriptor and the number of endpoints
152
       reported for this interface.  */
153
1969
    number_endpoints =  interface_ptr -> ux_interface_descriptor.bNumEndpoints;
154
155
1969
    this_interface_descriptor = descriptor;
156
157

8037
    while (length && (number_endpoints != 0))
158
    {
159
160
        /* Gather the length and type of the descriptor.  */
161
6186
        descriptor_length =  *descriptor;
162
6186
        descriptor_type =    *(descriptor+1);
163
164
        /* make sure this descriptor has at least the minimum length.  */
165
6186
        if (descriptor_length < 3)
166
        {
167
168
            /* Error trap. */
169
3
            _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DESCRIPTOR_CORRUPTED);
170
171
            /* If trace is enabled, insert this event into the trace buffer.  */
172
            UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
173
174
3
            return(UX_DESCRIPTOR_CORRUPTED);
175
        }
176
177
        /* Check the type for an interface descriptor.  */
178
6183
        if (descriptor_type == UX_ENDPOINT_DESCRIPTOR_ITEM)
179
        {
180
181
            /* We have found an endpoint descriptor for this interface.  */
182
2707
            status =  _ux_host_stack_new_endpoint_create(interface_ptr, descriptor);
183
184
            /* Check return status.  */
185
2707
            if(status != UX_SUCCESS)
186
109
                return(status);
187
188
2598
            number_endpoints--;
189
        }
190
191
        /* Verify if the descriptor is still valid, or we moved to next interface.  */
192

6074
        if ((descriptor_length > length) || (descriptor_type == UX_INTERFACE_DESCRIPTOR_ITEM && descriptor != this_interface_descriptor))
193
        {
194
195
            /* Error trap. */
196
6
            _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DESCRIPTOR_CORRUPTED);
197
198
            /* If trace is enabled, insert this event into the trace buffer.  */
199
            UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
200
201
6
            return(UX_DESCRIPTOR_CORRUPTED);
202
        }
203
204
        /* Jump to the next descriptor if we have not reached the end.  */
205
6068
        descriptor +=  descriptor_length;
206
6068
        length -=  descriptor_length;
207
    }
208
209
    /* Return success!  */
210
1851
    return(UX_SUCCESS);
211
}
212