GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_device_classes/src/ux_device_class_cdc_ecm_change.c Lines: 33 33 100.0 %
Date: 2024-12-12 17:16:36 Branches: 18 18 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
/** USBX Component                                                        */
14
/**                                                                       */
15
/**   Device CDC_ECM Class                                                */
16
/**                                                                       */
17
/**************************************************************************/
18
/**************************************************************************/
19
20
#define UX_SOURCE_CODE
21
22
23
/* Include necessary system files.  */
24
25
#include "ux_api.h"
26
#include "ux_device_class_cdc_ecm.h"
27
#include "ux_device_stack.h"
28
29
30
/**************************************************************************/
31
/*                                                                        */
32
/*  FUNCTION                                               RELEASE        */
33
/*                                                                        */
34
/*    _ux_device_class_cdc_ecm_change                     PORTABLE C      */
35
/*                                                           6.3.0        */
36
/*  AUTHOR                                                                */
37
/*                                                                        */
38
/*    Chaoqiong Xiao, Microsoft Corporation                               */
39
/*                                                                        */
40
/*  DESCRIPTION                                                           */
41
/*                                                                        */
42
/*    This function changes the interface of the CDC_ECM device           */
43
/*                                                                        */
44
/*  INPUT                                                                 */
45
/*                                                                        */
46
/*    command                           Pointer to cdc_ecm command        */
47
/*                                                                        */
48
/*  OUTPUT                                                                */
49
/*                                                                        */
50
/*    Completion Status                                                   */
51
/*                                                                        */
52
/*  CALLS                                                                 */
53
/*                                                                        */
54
/*    _ux_network_driver_link_up            Link status up                */
55
/*    _ux_network_driver_link_down          Link status down              */
56
/*    _ux_utility_memory_set                Set memory                    */
57
/*    _ux_device_thread_resume              Resume thread                 */
58
/*    _ux_device_event_flags_set            Set event flags               */
59
/*    _ux_device_stack_transfer_all_request_abort                         */
60
/*                                          Abort transfer                */
61
/*                                                                        */
62
/*  CALLED BY                                                             */
63
/*                                                                        */
64
/*    USBX Source Code                                                    */
65
/*                                                                        */
66
/*  RELEASE HISTORY                                                       */
67
/*                                                                        */
68
/*    DATE              NAME                      DESCRIPTION             */
69
/*                                                                        */
70
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
71
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
72
/*                                            verified memset and memcpy  */
73
/*                                            cases, used UX prefix to    */
74
/*                                            refer to TX symbols instead */
75
/*                                            of using them directly,     */
76
/*                                            resulting in version 6.1    */
77
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
78
/*                                            refined macros names,       */
79
/*                                            resulting in version 6.1.10 */
80
/*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
81
/*                                            fixed standalone compile,   */
82
/*                                            resulting in version 6.1.11 */
83
/*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
84
/*                                            fixed parameter/variable    */
85
/*                                            names conflict C++ keyword, */
86
/*                                            resulting in version 6.1.12 */
87
/*  10-31-2023     Chaoqiong Xiao           Modified comment(s),          */
88
/*                                            added zero copy support,    */
89
/*                                            added a new mode to manage  */
90
/*                                            endpoint buffer in classes, */
91
/*                                            resulting in version 6.3.0  */
92
/*                                                                        */
93
/**************************************************************************/
94
101
UINT  _ux_device_class_cdc_ecm_change(UX_SLAVE_CLASS_COMMAND *command)
95
{
96
97
UX_SLAVE_INTERFACE                      *interface_ptr;
98
UX_SLAVE_CLASS                          *class_ptr;
99
UX_SLAVE_CLASS_CDC_ECM                  *cdc_ecm;
100
UX_SLAVE_ENDPOINT                       *endpoint;
101
102
    /* Get the class container.  */
103
101
    class_ptr =  command -> ux_slave_class_command_class_ptr;
104
105
    /* Get the class instance in the container.  */
106
101
    cdc_ecm = (UX_SLAVE_CLASS_CDC_ECM *) class_ptr -> ux_slave_class_instance;
107
108
    /* Get the interface that owns this instance.  */
109
101
    interface_ptr =  (UX_SLAVE_INTERFACE  *) command -> ux_slave_class_command_interface;
110
111
    /* Locate the endpoints.  Control and Bulk in/out for Data Interface.  */
112
101
    endpoint =  interface_ptr -> ux_slave_interface_first_endpoint;
113
114
    /* If the interface to mount has a non zero alternate setting, the class is really active with
115
       the endpoints active.  If the interface reverts to alternate setting 0, it needs to have
116
       the pending transactions terminated.  */
117
101
    if (interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting != 0)
118
    {
119
120
        /* Parse all endpoints.  */
121
299
        while (endpoint != UX_NULL)
122
        {
123
124
            /* Check the endpoint direction, and type.  */
125
200
            if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN)
126
            {
127
128
                /* Look at type.  */
129
100
                if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
130
131
                    /* We have found the bulk in endpoint, save it.  */
132
96
                    cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_endpoint =  endpoint;
133
#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && !defined(UX_DEVICE_CLASS_CDC_ECM_ZERO_COPY)
134
                    endpoint -> ux_slave_endpoint_transfer_request.
135
                        ux_slave_transfer_request_data_pointer =
136
                                UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER(cdc_ecm);
137
#endif
138
            }
139
            else
140
            {
141
                /* Look at type for out endpoint.  */
142
100
                if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
143
144
                    /* We have found the bulk out endpoint, save it.  */
145
96
                    cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint =  endpoint;
146
#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && !defined(UX_DEVICE_CLASS_CDC_ECM_ZERO_COPY)
147
                    endpoint -> ux_slave_endpoint_transfer_request.
148
                        ux_slave_transfer_request_data_pointer =
149
                                UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER(cdc_ecm);
150
#endif
151
            }
152
153
            /* Next endpoint.  */
154
200
            endpoint =  endpoint -> ux_slave_endpoint_next_endpoint;
155
        }
156
157
        /* Now check if all endpoints have been found.  */
158

99
        if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint == UX_NULL || cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_endpoint == UX_NULL)
159
160
            /* Not all endpoints have been found. Major error, do not proceed.  */
161
6
            return(UX_ERROR);
162
163
        /* Declare the link to be up. */
164
93
        cdc_ecm -> ux_slave_class_cdc_ecm_link_state = UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP;
165
166
        /* Communicate the state with the network driver.  */
167
93
        _ux_network_driver_link_up(cdc_ecm -> ux_slave_class_cdc_ecm_network_handle);
168
169
#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ECM_ZERO_COPY)
170
171
        /* There is no endpoint buffer.  */
172
#else
173
174
        /* Reset the endpoint buffers.  */
175
93
        _ux_utility_memory_set(cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint -> ux_slave_endpoint_transfer_request.
176
                                        ux_slave_transfer_request_data_pointer, 0, UX_DEVICE_CLASS_CDC_ECM_BULKOUT_BUFFER_SIZE); /* Use case of memset is verified. */
177
93
        _ux_utility_memory_set(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_endpoint -> ux_slave_endpoint_transfer_request.
178
                                        ux_slave_transfer_request_data_pointer, 0, UX_DEVICE_CLASS_CDC_ECM_BULKIN_BUFFER_SIZE); /* Use case of memset is verified. */
179
#endif
180
181
        /* Resume the endpoint threads.  */
182
93
        _ux_device_thread_resume(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_thread);
183
93
        _ux_device_thread_resume(&cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread);
184
185
        /* Wake up the Interrupt thread and send a network notification to the host.  */
186
93
        _ux_device_event_flags_set(&cdc_ecm -> ux_slave_class_cdc_ecm_event_flags_group, UX_DEVICE_CLASS_CDC_ECM_NETWORK_NOTIFICATION_EVENT, UX_OR);
187
188
        /* If there is an activate function call it.  */
189
93
        if (cdc_ecm -> ux_slave_class_cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_activate != UX_NULL)
190
191
            /* Invoke the application.  */
192
89
            cdc_ecm -> ux_slave_class_cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_activate(cdc_ecm);
193
    }
194
    else
195
    {
196
197
        /* In this case, we are reverting to the Alternate Setting 0.  */
198
199
        /* Declare the link to be down.  */
200
2
        cdc_ecm -> ux_slave_class_cdc_ecm_link_state = UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_DOWN;
201
202
        /* Communicate the state with the network driver.  */
203
2
        _ux_network_driver_link_down(cdc_ecm -> ux_slave_class_cdc_ecm_network_handle);
204
205
        /* Terminate the transactions pending on the bulk in endpoint.  If there is a transfer on the
206
           bulk out endpoint, we simply let it finish and let NetX throw it away.  */
207
2
        _ux_device_stack_transfer_all_request_abort(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_endpoint, UX_TRANSFER_APPLICATION_RESET);
208
209
        /* Notify the thread waiting for network notification events. In this case,
210
           the event is that the link state has been switched to down.  */
211
2
        _ux_device_event_flags_set(&cdc_ecm -> ux_slave_class_cdc_ecm_event_flags_group, UX_DEVICE_CLASS_CDC_ECM_NETWORK_NOTIFICATION_EVENT, UX_OR);
212
213
        /* Wake up the bulk in thread so that it can clean up the xmit queue.  */
214
2
        _ux_device_event_flags_set(&cdc_ecm -> ux_slave_class_cdc_ecm_event_flags_group, UX_DEVICE_CLASS_CDC_ECM_NEW_DEVICE_STATE_CHANGE_EVENT, UX_OR);
215
216
        /* If there is a deactivate function call it.  */
217
2
        if (cdc_ecm -> ux_slave_class_cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_deactivate != UX_NULL)
218
219
            /* Invoke the application.  */
220
1
            cdc_ecm -> ux_slave_class_cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_deactivate(cdc_ecm);
221
    }
222
223
    /* Set the CDC ECM alternate setting to the new one.  */
224
95
    cdc_ecm -> ux_slave_class_cdc_ecm_current_alternate_setting = interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting;
225
226
    /* If trace is enabled, insert this event into the trace buffer.  */
227
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ECM_CHANGE, cdc_ecm, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
228
229
    /* If trace is enabled, register this object.  */
230
    UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, cdc_ecm, 0, 0, 0)
231
232
    /* Return completion status.  */
233
95
    return(UX_SUCCESS);
234
}
235