1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
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 /*  RELEASE HISTORY                                                       */
72 /*                                                                        */
73 /*    DATE              NAME                      DESCRIPTION             */
74 /*                                                                        */
75 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
76 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
77 /*                                            used UX prefix to refer to  */
78 /*                                            TX symbols instead of using */
79 /*                                            them directly,              */
80 /*                                            resulting in version 6.1    */
81 /*  02-02-2021     Xiuwen Cai               Modified comment(s), added    */
82 /*                                            compile option for using    */
83 /*                                            packet pool from NetX,      */
84 /*                                            resulting in version 6.1.4  */
85 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
86 /*                                            refined macros names,       */
87 /*                                            resulting in version 6.1.10 */
88 /*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
89 /*                                            internal clean up,          */
90 /*                                            fixed standalone compile,   */
91 /*                                            resulting in version 6.1.11 */
92 /*  10-31-2022     Chaoqiong Xiao           Modified comment(s),          */
93 /*                                            deprecated ECM pool option, */
94 /*                                            supported NX packet chain,  */
95 /*                                            resulting in version 6.2.0  */
96 /*                                                                        */
97 /**************************************************************************/
_ux_host_class_cdc_ecm_deactivate(UX_HOST_CLASS_COMMAND * command)98 UINT  _ux_host_class_cdc_ecm_deactivate(UX_HOST_CLASS_COMMAND *command)
99 {
100 
101 UX_INTERRUPT_SAVE_AREA
102 
103 UX_HOST_CLASS_CDC_ECM       *cdc_ecm;
104 UX_TRANSFER                 *transfer_request;
105 
106     /* This must be the data interface, since the control interface doesn't have
107        a class instance.  */
108 
109     /* Get the control instance for this class.  */
110     cdc_ecm =  (UX_HOST_CLASS_CDC_ECM *) command -> ux_host_class_command_instance;
111 
112     /* The cdc_ecm is being shut down.  */
113     cdc_ecm -> ux_host_class_cdc_ecm_state =  UX_HOST_CLASS_INSTANCE_SHUTDOWN;
114 
115     /* If the interrupt endpoint is defined, abort transfers so the link state
116        doesn't change.  */
117     if (cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint != UX_NULL)
118     {
119 
120         /* Get the transfer request.  */
121         transfer_request =  &cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint -> ux_endpoint_transfer_request;
122 
123         /* Abort any transfers.  */
124         _ux_host_stack_transfer_request_abort(transfer_request);
125     }
126 
127     /* Check if link was up to see if we should clean the transmit queue. If
128        the link is pending down, that means the CDC-ECM thread is in the process
129        of cleaning the transmit queue.  */
130     if (cdc_ecm -> ux_host_class_cdc_ecm_link_state == UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP)
131 
132         _ux_host_class_cdc_ecm_transmit_queue_clean(cdc_ecm);
133 
134     /* Get the bulk in transfer request.  */
135     transfer_request =  &cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_endpoint -> ux_endpoint_transfer_request;
136 
137     /* Now abort all transfers. It's possible we're executing right before the transfer
138        is armed. If this is the case, then the transfer will not be aborted if we do the abort right now; instead,
139        we should wait until after the transfer is armed. We must look at the CDC-ECM thread's state.  */
140 
141     /* Disable interrupts while we check the link state and possibly set our state.  */
142     UX_DISABLE
143 
144     /* Is it in the process of checking the link state and arming the transfer?  */
145     if (cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_check_and_arm_in_process == UX_TRUE)
146     {
147 
148         /* Yes. We must wait for it to finish arming the transfer.  */
149 
150         /* Let the CDC-ECM thread know we're waiting so it can wake us up.  */
151         cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish =  UX_TRUE;
152 
153         /* Restore interrupts.  */
154         UX_RESTORE
155 
156         /* Wait for the transfer to be armed, or possibly an error. The CDC-ECM thread will wake us up.  */
157         _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);
158 
159         /* We're no longer waiting.  */
160         cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish =  UX_FALSE;
161     }
162     else
163     {
164 
165         /* Restore interrupts.  */
166         UX_RESTORE
167     }
168 
169     /* Now we can abort the transfer.  */
170     _ux_host_stack_transfer_request_abort(transfer_request);
171 
172     /* De-register this interface to the NetX USB interface broker.  */
173     _ux_network_driver_deactivate((VOID *) cdc_ecm, cdc_ecm -> ux_host_class_cdc_ecm_network_handle);
174 
175     /* Destroy the control instance.  */
176     _ux_host_stack_class_instance_destroy(cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
177 
178     /* Now wait for all threads to leave the instance before freeing the resources.  */
179     _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM);
180 
181     /* Free the memory used by the interrupt endpoint.  */
182     if (cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint != UX_NULL)
183         _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer);
184 
185     /* Destroy the link monitoring thread. We should do this before destroying
186        the notification semaphore so that it does not run due to semaphore deletion.  */
187     _ux_utility_thread_delete(&cdc_ecm -> ux_host_class_cdc_ecm_thread);
188 
189     /* Free the CDC-ECM thread's stack memory.  */
190     _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_thread_stack);
191 
192     /* Destroy the bulk semaphores.  */
193     _ux_host_semaphore_delete(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_out_transfer_waiting_for_check_and_arm_to_finish_semaphore);
194     _ux_host_semaphore_delete(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish_semaphore);
195 
196     /* Destroy the notification semaphore.  */
197     _ux_host_semaphore_delete(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore);
198 
199 #ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
200 
201     /* Free packet transmission memories.  */
202     if (cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer)
203         _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer);
204     if (cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer)
205         _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer);
206 #endif
207 
208     /* Before we free the device resources, we need to inform the application
209         that the device is removed.  */
210     if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
211 
212         /* Inform the application the device is removed.  */
213         _ux_system_host -> ux_system_host_change_function(UX_DEVICE_REMOVAL, cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
214 
215     /* If trace is enabled, insert this event into the trace buffer.  */
216     UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_CDC_ECM_DEACTIVATE, cdc_ecm, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
217 
218     /* If trace is enabled, unregister this object.  */
219     UX_TRACE_OBJECT_UNREGISTER(cdc_ecm);
220 
221     /* Free the cdc_ecm control instance memory.  */
222     _ux_utility_memory_free(cdc_ecm);
223 
224     /* Return successful status.  */
225     return(UX_SUCCESS);
226 }
227 #endif
228