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 ACM 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_acm.h"
30 #include "ux_host_stack.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _ux_host_class_cdc_acm_deactivate                   PORTABLE C      */
38 /*                                                           6.1.10       */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Chaoqiong Xiao, Microsoft Corporation                               */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This function is called when this instance of the cdc_acm has been  */
46 /*    removed from the bus either directly or indirectly. The bulk in\out */
47 /*    and optional interrupt pipes will be destroyed and the instance     */
48 /*    removed.                                                            */
49 /*                                                                        */
50 /*  INPUT                                                                 */
51 /*                                                                        */
52 /*    command                               CDC ACM 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 /*    _ux_utility_thread_schedule_other     Schedule other threads        */
66 /*                                                                        */
67 /*  CALLED BY                                                             */
68 /*                                                                        */
69 /*    _ux_host_class_cdc_acm_entry          Entry of cdc_acm 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 /*                                            resulting in version 6.1    */
78 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
79 /*                                            added standalone support,   */
80 /*                                            resulting in version 6.1.10 */
81 /*                                                                        */
82 /**************************************************************************/
_ux_host_class_cdc_acm_deactivate(UX_HOST_CLASS_COMMAND * command)83 UINT  _ux_host_class_cdc_acm_deactivate(UX_HOST_CLASS_COMMAND *command)
84 {
85 
86 UX_HOST_CLASS_CDC_ACM       *cdc_acm;
87 UX_TRANSFER                 *transfer_request;
88 #if !defined(UX_HOST_STANDALONE)
89 UINT                        status;
90 #endif
91 
92     /* Get the instance for this class.  */
93     cdc_acm =  (UX_HOST_CLASS_CDC_ACM *) command -> ux_host_class_command_instance;
94 
95     /* The cdc_acm is being shut down.  */
96     cdc_acm -> ux_host_class_cdc_acm_state =  UX_HOST_CLASS_INSTANCE_SHUTDOWN;
97 
98 #if !defined(UX_HOST_STANDALONE)
99 
100     /* Protect thread reentry to this instance.  */
101     status =  _ux_host_semaphore_get(&cdc_acm -> ux_host_class_cdc_acm_semaphore, UX_WAIT_FOREVER);
102     if (status != UX_SUCCESS)
103 
104         /* Return error.  */
105         return(status);
106 #endif
107 
108     /* If we have the Control Class, we only unmount the interrupt endpoint if it is active.  */
109     if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
110     {
111 
112         /* If the interrupt endpoint is defined, clean any pending transfer.  */
113         if (cdc_acm -> ux_host_class_cdc_acm_interrupt_endpoint != UX_NULL)
114         {
115             transfer_request =  &cdc_acm -> ux_host_class_cdc_acm_interrupt_endpoint -> ux_endpoint_transfer_request;
116 
117             /* And abort any transfer.  */
118             _ux_host_stack_endpoint_transfer_abort(cdc_acm -> ux_host_class_cdc_acm_interrupt_endpoint);
119 
120             /* Free data buffer for the interrupt transfer.  */
121             _ux_utility_memory_free(transfer_request -> ux_transfer_request_data_pointer);
122         }
123     }
124     else
125     {
126 
127         /* We come to this point when the device has been extracted and this is the data class.
128            So there may have been a transaction being scheduled.
129            We make sure the transaction has been completed by the controller driver.
130            When the device is extracted, the controller tries multiple times the transaction and retires it
131            with a DEVICE_NOT_RESPONDING error code.
132 
133            First we take care of endpoint IN.  */
134         transfer_request =  &cdc_acm -> ux_host_class_cdc_acm_bulk_in_endpoint -> ux_endpoint_transfer_request;
135         if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
136 
137             /* We need to abort transactions on the bulk In pipe.  */
138             _ux_host_stack_endpoint_transfer_abort(cdc_acm -> ux_host_class_cdc_acm_bulk_in_endpoint);
139 
140         /* Then endpoint OUT.  */
141         transfer_request =  &cdc_acm -> ux_host_class_cdc_acm_bulk_out_endpoint -> ux_endpoint_transfer_request;
142         if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
143 
144             /* We need to abort transactions on the bulk Out pipe. */
145             _ux_host_stack_endpoint_transfer_abort(cdc_acm -> ux_host_class_cdc_acm_bulk_out_endpoint);
146 
147     }
148 
149 #if !defined(UX_HOST_STANDALONE)
150 
151     /* The enumeration thread needs to sleep a while to allow the application or the class that may be using
152        endpoints to exit properly.  */
153     _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM);
154 #else
155 
156     /* If there is allocated resource, free it.  */
157     if (cdc_acm -> ux_host_class_cdc_acm_allocated)
158     {
159         _ux_utility_memory_free(cdc_acm -> ux_host_class_cdc_acm_allocated);
160     }
161 #endif
162 
163     /* Destroy the instance.  */
164     _ux_host_stack_class_instance_destroy(cdc_acm -> ux_host_class_cdc_acm_class, (VOID *) cdc_acm);
165 
166 #if !defined(UX_HOST_STANDALONE)
167 
168     /* Destroy the semaphore.  */
169     _ux_host_semaphore_delete(&cdc_acm -> ux_host_class_cdc_acm_semaphore);
170 #endif
171 
172     /* Before we free the device resources, we need to inform the application
173         that the device is removed.  */
174     if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
175     {
176 
177         /* Inform the application the device is removed.  */
178         _ux_system_host -> ux_system_host_change_function(UX_DEVICE_REMOVAL, cdc_acm -> ux_host_class_cdc_acm_class, (VOID *) cdc_acm);
179     }
180 
181     /* Free the cdc_acm instance memory.  */
182     _ux_utility_memory_free(cdc_acm);
183 
184     /* If trace is enabled, insert this event into the trace buffer.  */
185     UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_CDC_ACM_DEACTIVATE, cdc_acm, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
186 
187     /* If trace is enabled, register this object.  */
188     UX_TRACE_OBJECT_UNREGISTER(cdc_acm);
189 
190     /* Return successful status.  */
191     return(UX_SUCCESS);
192 }
193 
194