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 /**   PIMA 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_pima.h"
30 #include "ux_host_stack.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _ux_host_class_pima_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 pima 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 removed.     */
48 /*                                                                        */
49 /*  INPUT                                                                 */
50 /*                                                                        */
51 /*    command                                PIMA   class command pointer */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    Completion Status                                                   */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    _ux_host_stack_class_instance_destroy Destroy the class instance    */
60 /*    _ux_host_stack_endpoint_transfer_abort Abort endpoint transfer      */
61 /*    _ux_utility_memory_free               Free memory block             */
62 /*    _ux_host_semaphore_get                Get protection semaphore      */
63 /*    _ux_host_semaphore_delete             Delete protection semaphore   */
64 /*                                                                        */
65 /*  CALLED BY                                                             */
66 /*                                                                        */
67 /*    _ux_host_class_pima_entry                Entry of pima class        */
68 /*                                                                        */
69 /*  RELEASE HISTORY                                                       */
70 /*                                                                        */
71 /*    DATE              NAME                      DESCRIPTION             */
72 /*                                                                        */
73 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
74 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
75 /*                                            resulting in version 6.1    */
76 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
77 /*                                            refined macros names,       */
78 /*                                            resulting in version 6.1.10 */
79 /*                                                                        */
80 /**************************************************************************/
_ux_host_class_pima_deactivate(UX_HOST_CLASS_COMMAND * command)81 UINT  _ux_host_class_pima_deactivate(UX_HOST_CLASS_COMMAND *command)
82 {
83 
84 UX_HOST_CLASS_PIMA              *pima;
85 UX_HOST_CLASS_PIMA_SESSION      *pima_session;
86 UX_TRANSFER                     *transfer_request;
87 UINT                            status;
88 
89 
90     /* Get the instance for this class.  */
91     pima =  (UX_HOST_CLASS_PIMA *) command -> ux_host_class_command_instance;
92 
93     /* The pima is being shut down.  */
94     pima -> ux_host_class_pima_state =  UX_HOST_CLASS_INSTANCE_SHUTDOWN;
95 
96     /* Protect thread reentry to this instance.  */
97     status =  _ux_host_semaphore_get(&pima -> ux_host_class_pima_semaphore, UX_WAIT_FOREVER);
98     if (status != UX_SUCCESS)
99 
100         /* Return error. */
101         return(status);
102 
103     /* We come to this point when the device has been extracted. So there may have been a transaction
104        being scheduled. We make sure the transaction has been completed by the controller driver.
105        When the device is extracted, the controller tries multiple times the transaction and retires it
106        with a DEVICE_NOT_RESPONDING error code.
107 
108        First we take care of endpoint IN.  */
109     transfer_request =  &pima -> ux_host_class_pima_bulk_in_endpoint -> ux_endpoint_transfer_request;
110     if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
111 
112         /* We need to abort transactions on the bulk In pipe.  */
113         _ux_host_stack_endpoint_transfer_abort(pima -> ux_host_class_pima_bulk_in_endpoint);
114 
115 
116     /* Then endpoint OUT.  */
117     transfer_request =  &pima -> ux_host_class_pima_bulk_out_endpoint -> ux_endpoint_transfer_request;
118     if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
119 
120         /* We need to abort transactions on the bulk Out pipe.  We normally don't need that anymore. */
121         _ux_host_stack_endpoint_transfer_abort(pima -> ux_host_class_pima_bulk_out_endpoint);
122 
123 
124     /* Then interrupt endpoint.  */
125     transfer_request =  &pima -> ux_host_class_pima_interrupt_endpoint -> ux_endpoint_transfer_request;
126     if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
127 
128         /* We need to abort transactions on the Interrupt pipe.  */
129         _ux_host_stack_endpoint_transfer_abort(pima -> ux_host_class_pima_interrupt_endpoint);
130 
131     /* The enumeration thread needs to sleep a while to allow the application or the class that may be using
132        endpoints to exit properly.  */
133     _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM);
134 
135     /* Free the header container buffer.  */
136     if (pima -> ux_host_class_pima_container != UX_NULL)
137         _ux_utility_memory_free(pima -> ux_host_class_pima_container);
138 
139     /* Free the event data buffer.  */
140     if (pima -> ux_host_class_pima_event_buffer != UX_NULL)
141         _ux_utility_memory_free(pima -> ux_host_class_pima_event_buffer);
142 
143     /* Get the pointer to the PIMA session.  */
144     pima_session = pima -> ux_host_class_pima_session;
145 
146     /* Was there a PIMA session ?  */
147     if(pima_session != UX_NULL)
148     {
149         /* Clean the PIMA session and free the storage ID buffer in the session if it is opened.  */
150         if ((pima_session -> ux_host_class_pima_session_magic == UX_HOST_CLASS_PIMA_MAGIC_NUMBER) &&
151             (pima_session -> ux_host_class_pima_session_state == UX_HOST_CLASS_PIMA_SESSION_STATE_OPENED))
152 
153         {
154 
155             /* Reset the magic field.  */
156             pima_session -> ux_host_class_pima_session_magic =  0;
157 
158             /* Declare the session closed.  */
159             pima_session -> ux_host_class_pima_session_state = UX_HOST_CLASS_PIMA_SESSION_STATE_CLOSED;
160 
161         }
162     }
163 
164     /* Destroy the instance.  */
165     _ux_host_stack_class_instance_destroy(pima -> ux_host_class_pima_class, (VOID *) pima);
166 
167     /* Destroy the semaphore.  */
168     _ux_host_semaphore_delete(&pima -> ux_host_class_pima_semaphore);
169 
170     /* Before we free the device resources, we need to inform the application
171         that the device is removed.  */
172     if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
173     {
174 
175         /* Inform the application the device is removed.  */
176         _ux_system_host -> ux_system_host_change_function(UX_DEVICE_REMOVAL, pima -> ux_host_class_pima_class, (VOID *) pima);
177     }
178 
179     /* If trace is enabled, insert this event into the trace buffer.  */
180     UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_PIMA_DEACTIVATE, pima, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
181 
182     /* If trace is enabled, register this object.  */
183     UX_TRACE_OBJECT_UNREGISTER(pima);
184 
185     /* Free the pima instance memory.  */
186     _ux_utility_memory_free(pima);
187 
188     /* Return successful status.  */
189     return(UX_SUCCESS);
190 }
191 
192