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