GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c Lines: 61 61 100.0 %
Date: 2026-03-06 18:57:10 Branches: 32 32 100.0 %

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
/** USBX Component                                                        */
15
/**                                                                       */
16
/**   Device CDC_ECM Class                                                */
17
/**                                                                       */
18
/**************************************************************************/
19
/**************************************************************************/
20
21
#define UX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "ux_api.h"
27
#include "ux_device_class_cdc_ecm.h"
28
#include "ux_device_stack.h"
29
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _ux_device_class_cdc_ecm_initialize                 PORTABLE C      */
36
/*                                                           6.3.0        */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Chaoqiong Xiao, Microsoft Corporation                               */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This function initializes the USB CDC_ECM device.                   */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    command                               Pointer to cdc_ecm command    */
48
/*                                                                        */
49
/*  OUTPUT                                                                */
50
/*                                                                        */
51
/*    Completion Status                                                   */
52
/*                                                                        */
53
/*  CALLS                                                                 */
54
/*                                                                        */
55
/*    _ux_utility_memory_allocate           Allocate memory               */
56
/*    _ux_utility_memory_free               Free memory                   */
57
/*    _ux_utility_mutex_create              Create Mutex                  */
58
/*    _ux_device_mutex_delete               Delete Mutex                  */
59
/*    _ux_utility_event_flags_create        Create Flag group             */
60
/*    _ux_utility_event_flags_delete        Delete Flag group             */
61
/*    _ux_device_thread_create              Create Thread                 */
62
/*    _ux_device_thread_delete              Delete Thread                 */
63
/*                                                                        */
64
/*  CALLED BY                                                             */
65
/*                                                                        */
66
/*    USBX Source Code                                                    */
67
/*                                                                        */
68
/**************************************************************************/
69
65
UINT  _ux_device_class_cdc_ecm_initialize(UX_SLAVE_CLASS_COMMAND *command)
70
{
71
#if defined(UX_DEVICE_STANDALONE)
72
    UX_PARAMETER_NOT_USED(command);
73
    return(UX_FUNCTION_NOT_SUPPORTED);
74
#else
75
76
UX_SLAVE_CLASS_CDC_ECM                          *cdc_ecm;
77
UX_SLAVE_CLASS_CDC_ECM_PARAMETER                *cdc_ecm_parameter;
78
UX_SLAVE_CLASS                                  *class_ptr;
79
UINT                                            status;
80
81
82
    /* Get the class container.  */
83
65
    class_ptr =  command -> ux_slave_class_command_class_ptr;
84
85
    /* Create an instance of the device cdc_ecm class.  */
86
65
    cdc_ecm =  _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_CDC_ECM));
87
88
    /* Check for successful allocation.  */
89
65
    if (cdc_ecm == UX_NULL)
90
1
        return(UX_MEMORY_INSUFFICIENT);
91
92
    /* Create a mutex to protect the CDC_ECM thread and the application messing up the transmit queue.  */
93
64
    status =  _ux_utility_mutex_create(&cdc_ecm -> ux_slave_class_cdc_ecm_mutex, "ux_slave_class_cdc_ecm_mutex");
94
64
    if (status != UX_SUCCESS)
95
    {
96
1
        _ux_utility_memory_free(cdc_ecm);
97
1
        return(UX_MUTEX_ERROR);
98
    }
99
100
    /* Assume good result.  */
101
63
    status = UX_SUCCESS;
102
103
#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
104
105
    /* Allocate buffer for endpoints.  */
106
    UX_ASSERT(!UX_DEVICE_CLASS_CDC_ECM_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW);
107
    cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer =
108
            _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY,
109
                                        UX_DEVICE_CLASS_CDC_ECM_ENDPOINT_BUFFER_SIZE);
110
    if (cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer == UX_NULL)
111
        status = (UX_MEMORY_INSUFFICIENT);
112
#endif
113
114
    /* Allocate some memory for the bulk out thread stack. */
115
63
    cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack =
116
63
            _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE);
117
63
    if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack == UX_NULL)
118
1
        status = (UX_MEMORY_INSUFFICIENT);
119
120
    /* Allocate some memory for the interrupt thread stack. */
121
63
    if (status == UX_SUCCESS)
122
    {
123
62
        cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack =
124
62
                _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE);
125
126
        /* Check for successful allocation.  */
127
62
        if (cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack  == UX_NULL)
128
1
            status = (UX_MEMORY_INSUFFICIENT);
129
    }
130
131
    /* Allocate some memory for the bulk in thread stack. */
132
63
    if (status == UX_SUCCESS)
133
    {
134
61
        cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack =
135
61
                _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE);
136
137
        /* Check for successful allocation.  */
138
61
        if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack == UX_NULL)
139
1
            status = (UX_MEMORY_INSUFFICIENT);
140
    }
141
142
    /* Interrupt endpoint treatment needs to be running in a different thread. So start
143
       a new thread. We pass a pointer to the cdc_ecm instance to the new thread.  This thread
144
       does not start until we have a instance of the class. */
145
63
    if (status == UX_SUCCESS)
146
    {
147
60
        status =  _ux_device_thread_create(&cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread , "ux_slave_class_cdc_ecm_interrupt_thread",
148
                    _ux_device_class_cdc_ecm_interrupt_thread,
149
60
                    (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack ,
150
                    UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS,
151
                    UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START);
152
60
        if (status != UX_SUCCESS)
153
1
            status = (UX_THREAD_ERROR);
154
    }
155
156
    UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread), class_ptr)
157
158
    /* Check the creation of this thread.  */
159
63
    if (status == UX_SUCCESS)
160
    {
161
162
        /* Bulk endpoint treatment needs to be running in a different thread. So start
163
        a new thread. We pass a pointer to the cdc_ecm instance to the new thread.  This thread
164
        does not start until we have a instance of the class. */
165
59
        status =  _ux_device_thread_create(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread , "ux_slave_class_cdc_ecm_bulkout_thread",
166
                    _ux_device_class_cdc_ecm_bulkout_thread,
167
59
                    (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack ,
168
                    UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS,
169
                    UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START);
170
59
        if (status != UX_SUCCESS)
171
1
            status = (UX_THREAD_ERROR);
172
        else
173
        {
174
175
            UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread), class_ptr)
176
177
            /* Bulk endpoint treatment needs to be running in a different thread. So start
178
            a new thread. We pass a pointer to the cdc_ecm instance to the new thread.  This thread
179
            does not start until we have a instance of the class. */
180
58
            status =  _ux_device_thread_create(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread , "ux_slave_class_cdc_ecm_bulkin_thread",
181
                        _ux_device_class_cdc_ecm_bulkin_thread,
182
58
                        (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack ,
183
                        UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS,
184
                        UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START);
185
58
            if (status != UX_SUCCESS)
186
1
                status = (UX_THREAD_ERROR);
187
            else
188
            {
189
190
                UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread), class_ptr)
191
192
                /* Create a event flag group for the cdc_ecm class to synchronize with the event interrupt thread.  */
193
57
                status =  _ux_utility_event_flags_create(&cdc_ecm -> ux_slave_class_cdc_ecm_event_flags_group, "ux_device_class_cdc_ecm_event_flag");
194
57
                if (status != UX_SUCCESS)
195
1
                    status = (UX_EVENT_ERROR);
196
                else
197
                {
198
199
                    /* Save the address of the CDC_ECM instance inside the CDC_ECM container.  */
200
56
                    class_ptr -> ux_slave_class_instance = (VOID *) cdc_ecm;
201
202
                    /* Get the pointer to the application parameters for the cdc_ecm class.  */
203
56
                    cdc_ecm_parameter =  command -> ux_slave_class_command_parameter;
204
205
                    /* Store the start and stop signals if needed by the application.  */
206
56
                    cdc_ecm -> ux_slave_class_cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_activate = cdc_ecm_parameter -> ux_slave_class_cdc_ecm_instance_activate;
207
56
                    cdc_ecm -> ux_slave_class_cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_deactivate = cdc_ecm_parameter -> ux_slave_class_cdc_ecm_instance_deactivate;
208
209
                    /* Copy the local node ID.  */
210
56
                    _ux_utility_memory_copy(cdc_ecm -> ux_slave_class_cdc_ecm_local_node_id, cdc_ecm_parameter -> ux_slave_class_cdc_ecm_parameter_local_node_id,
211
                                            UX_DEVICE_CLASS_CDC_ECM_NODE_ID_LENGTH); /* Use case of memcpy is verified. */
212
213
                    /* Copy the remote node ID.  */
214
56
                    _ux_utility_memory_copy(cdc_ecm -> ux_slave_class_cdc_ecm_remote_node_id, cdc_ecm_parameter -> ux_slave_class_cdc_ecm_parameter_remote_node_id,
215
                                            UX_DEVICE_CLASS_CDC_ECM_NODE_ID_LENGTH); /* Use case of memcpy is verified. */
216
217
                    /* Store the rest of the parameters as they are in the local instance.  */
218
56
                    _ux_utility_memory_copy(&cdc_ecm -> ux_slave_class_cdc_ecm_parameter, cdc_ecm_parameter, sizeof (UX_SLAVE_CLASS_CDC_ECM_PARAMETER)); /* Use case of memcpy is verified. */
219
220
56
                    return(UX_SUCCESS);
221
                }
222
223
1
                _ux_device_thread_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread);
224
            }
225
226
2
            _ux_device_thread_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread);
227
        }
228
229
3
        _ux_device_thread_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread);
230
    }
231
232
    /* Free allocated resources.  */
233
234
7
    if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack)
235
4
        _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack);
236
7
    if (cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack)
237
5
        _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack);
238
7
    if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack)
239
6
        _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread_stack);
240
#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
241
    if (cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer)
242
        _ux_utility_memory_free(cdc_ecm -> ux_device_class_cdc_ecm_endpoint_buffer);
243
#endif
244
7
    _ux_device_mutex_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_mutex);
245
7
    _ux_utility_memory_free(cdc_ecm);
246
247
    /* Return completion status.  */
248
7
    return(status);
249
#endif
250
}