GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_cdc_ecm_deactivate.c Lines: 35 35 100.0 %
Date: 2026-03-06 18:57:10 Branches: 14 14 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
/**************************************************************************/
15
/**                                                                       */
16
/** USBX Component                                                        */
17
/**                                                                       */
18
/**   CDC ECM Class                                                       */
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_class_cdc_ecm.h"
30
#include "ux_host_stack.h"
31
32
33
#if !defined(UX_HOST_STANDALONE)
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _ux_host_class_cdc_ecm_deactivate                   PORTABLE C      */
39
/*                                                           6.2.0        */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Chaoqiong Xiao, Microsoft Corporation                               */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    This function is called when this instance of the cdc_ecm has been  */
47
/*    removed from the bus either directly or indirectly. The bulk in\out */
48
/*    and interrupt pipes will be destroyed and the instance              */
49
/*    removed.                                                            */
50
/*                                                                        */
51
/*  INPUT                                                                 */
52
/*                                                                        */
53
/*    command                           CDC ECM class command pointer     */
54
/*                                                                        */
55
/*  OUTPUT                                                                */
56
/*                                                                        */
57
/*    Completion Status                                                   */
58
/*                                                                        */
59
/*  CALLS                                                                 */
60
/*                                                                        */
61
/*    _ux_host_stack_class_instance_destroy Destroy the class instance    */
62
/*    _ux_host_stack_endpoint_transfer_abort Abort endpoint transfer      */
63
/*    _ux_utility_memory_free               Free memory block             */
64
/*    _ux_host_semaphore_get                Get protection semaphore      */
65
/*    _ux_host_semaphore_delete             Delete protection semaphore   */
66
/*                                                                        */
67
/*  CALLED BY                                                             */
68
/*                                                                        */
69
/*    _ux_host_class_cdc_ecm_entry       Entry of cdc_ecm class           */
70
/*                                                                        */
71
/**************************************************************************/
72
53
UINT  _ux_host_class_cdc_ecm_deactivate(UX_HOST_CLASS_COMMAND *command)
73
{
74
75
UX_INTERRUPT_SAVE_AREA
76
77
UX_HOST_CLASS_CDC_ECM       *cdc_ecm;
78
UX_TRANSFER                 *transfer_request;
79
80
    /* This must be the data interface, since the control interface doesn't have
81
       a class instance.  */
82
83
    /* Get the control instance for this class.  */
84
53
    cdc_ecm =  (UX_HOST_CLASS_CDC_ECM *) command -> ux_host_class_command_instance;
85
86
    /* The cdc_ecm is being shut down.  */
87
53
    cdc_ecm -> ux_host_class_cdc_ecm_state =  UX_HOST_CLASS_INSTANCE_SHUTDOWN;
88
89
    /* If the interrupt endpoint is defined, abort transfers so the link state
90
       doesn't change.  */
91
53
    if (cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint != UX_NULL)
92
    {
93
94
        /* Get the transfer request.  */
95
50
        transfer_request =  &cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint -> ux_endpoint_transfer_request;
96
97
        /* Abort any transfers.  */
98
50
        _ux_host_stack_transfer_request_abort(transfer_request);
99
    }
100
101
    /* Check if link was up to see if we should clean the transmit queue. If
102
       the link is pending down, that means the CDC-ECM thread is in the process
103
       of cleaning the transmit queue.  */
104
53
    if (cdc_ecm -> ux_host_class_cdc_ecm_link_state == UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP)
105
106
40
        _ux_host_class_cdc_ecm_transmit_queue_clean(cdc_ecm);
107
108
    /* Get the bulk in transfer request.  */
109
53
    transfer_request =  &cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_endpoint -> ux_endpoint_transfer_request;
110
111
    /* Now abort all transfers. It's possible we're executing right before the transfer
112
       is armed. If this is the case, then the transfer will not be aborted if we do the abort right now; instead,
113
       we should wait until after the transfer is armed. We must look at the CDC-ECM thread's state.  */
114
115
    /* Disable interrupts while we check the link state and possibly set our state.  */
116
53
    UX_DISABLE
117
118
    /* Is it in the process of checking the link state and arming the transfer?  */
119
53
    if (cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_check_and_arm_in_process == UX_TRUE)
120
    {
121
122
        /* Yes. We must wait for it to finish arming the transfer.  */
123
124
        /* Let the CDC-ECM thread know we're waiting so it can wake us up.  */
125
1
        cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish =  UX_TRUE;
126
127
        /* Restore interrupts.  */
128
1
        UX_RESTORE
129
130
        /* Wait for the transfer to be armed, or possibly an error. The CDC-ECM thread will wake us up.  */
131
1
        _ux_host_semaphore_get_norc(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish_semaphore, UX_WAIT_FOREVER);
132
133
        /* We're no longer waiting.  */
134
1
        cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish =  UX_FALSE;
135
    }
136
    else
137
    {
138
139
        /* Restore interrupts.  */
140
52
        UX_RESTORE
141
    }
142
143
    /* Now we can abort the transfer.  */
144
53
    _ux_host_stack_transfer_request_abort(transfer_request);
145
146
    /* De-register this interface to the NetX USB interface broker.  */
147
53
    _ux_network_driver_deactivate((VOID *) cdc_ecm, cdc_ecm -> ux_host_class_cdc_ecm_network_handle);
148
149
    /* Destroy the control instance.  */
150
53
    _ux_host_stack_class_instance_destroy(cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
151
152
    /* Now wait for all threads to leave the instance before freeing the resources.  */
153
53
    _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM);
154
155
    /* Free the memory used by the interrupt endpoint.  */
156
53
    if (cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint != UX_NULL)
157
50
        _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer);
158
159
    /* Destroy the link monitoring thread. We should do this before destroying
160
       the notification semaphore so that it does not run due to semaphore deletion.  */
161
53
    _ux_utility_thread_delete(&cdc_ecm -> ux_host_class_cdc_ecm_thread);
162
163
    /* Free the CDC-ECM thread's stack memory.  */
164
53
    _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_thread_stack);
165
166
    /* Destroy the bulk semaphores.  */
167
53
    _ux_host_semaphore_delete(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_out_transfer_waiting_for_check_and_arm_to_finish_semaphore);
168
53
    _ux_host_semaphore_delete(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish_semaphore);
169
170
    /* Destroy the notification semaphore.  */
171
53
    _ux_host_semaphore_delete(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore);
172
173
#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
174
175
    /* Free packet transmission memories.  */
176
53
    if (cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer)
177
3
        _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer);
178
53
    if (cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer)
179
1
        _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer);
180
#endif
181
182
    /* Before we free the device resources, we need to inform the application
183
        that the device is removed.  */
184
53
    if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
185
186
        /* Inform the application the device is removed.  */
187
48
        _ux_system_host -> ux_system_host_change_function(UX_DEVICE_REMOVAL, cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
188
189
    /* If trace is enabled, insert this event into the trace buffer.  */
190
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_CDC_ECM_DEACTIVATE, cdc_ecm, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
191
192
    /* If trace is enabled, unregister this object.  */
193
    UX_TRACE_OBJECT_UNREGISTER(cdc_ecm);
194
195
    /* Free the cdc_ecm control instance memory.  */
196
53
    _ux_utility_memory_free(cdc_ecm);
197
198
    /* Return successful status.  */
199
53
    return(UX_SUCCESS);
200
}
201
#endif