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 /**   HID 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_hid.h"
30 #include "ux_host_stack.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _ux_host_class_hid_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 HID has been      */
46 /*    removed from the bus either directly or indirectly. The interrupt   */
47 /*    pipe will be destroyed and the instanced removed.                   */
48 /*                                                                        */
49 /*  INPUT                                                                 */
50 /*                                                                        */
51 /*    command                               Pointer to command            */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    Completion Status                                                   */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    (ux_host_class_hid_client_handler)    HID client handler            */
60 /*    _ux_host_class_hid_instance_clean     HID instance clean            */
61 /*    _ux_host_stack_class_instance_destroy Destroy the class instance    */
62 /*    _ux_host_stack_endpoint_transfer_abort                              */
63 /*                                          Abort transfer                */
64 /*    _ux_utility_memory_free               Release memory block          */
65 /*    _ux_host_semaphore_delete             Delete semaphore              */
66 /*    _ux_host_semaphore_get                Get semaphore                 */
67 /*    _ux_utility_thread_schedule_other     Schedule other threads        */
68 /*                                                                        */
69 /*  CALLED BY                                                             */
70 /*                                                                        */
71 /*    HID Class                                                           */
72 /*                                                                        */
73 /*  RELEASE HISTORY                                                       */
74 /*                                                                        */
75 /*    DATE              NAME                      DESCRIPTION             */
76 /*                                                                        */
77 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
78 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
79 /*                                            resulting in version 6.1    */
80 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
81 /*                                            added standalone support,   */
82 /*                                            resulting in version 6.1.10 */
83 /*                                                                        */
84 /**************************************************************************/
_ux_host_class_hid_deactivate(UX_HOST_CLASS_COMMAND * command)85 UINT  _ux_host_class_hid_deactivate(UX_HOST_CLASS_COMMAND *command)
86 {
87 
88 UX_HOST_CLASS_HID                   *hid;
89 UX_HOST_CLASS_HID_CLIENT_COMMAND    hid_client_command;
90 UX_TRANSFER                         *transfer_request;
91 #if !defined(UX_HOST_STANDALONE)
92 UINT                                status;
93 #endif
94 
95 
96     /* Get the instance for this class.  */
97     hid =  (UX_HOST_CLASS_HID *) command -> ux_host_class_command_instance;
98 
99     /* The HID is being shut down.  */
100     hid -> ux_host_class_hid_state =  UX_HOST_CLASS_INSTANCE_SHUTDOWN;
101 
102 #if !defined(UX_HOST_STANDALONE)
103 
104     /* Protect thread reentry to this instance.  */
105     status =  _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER);
106     if (status != UX_SUCCESS)
107 
108         /* Return error.  */
109         return(status);
110 #endif
111 
112 #if defined(UX_HOST_STANDALONE)
113     if (hid -> ux_host_class_hid_interrupt_endpoint)
114 #endif
115     {
116 
117         /* We need to abort transactions on the interrupt pipe.  */
118         _ux_host_stack_endpoint_transfer_abort(hid -> ux_host_class_hid_interrupt_endpoint);
119 
120         /* If the Hid class instance has a interrupt pipe with a data payload associated with it
121         it must be freed.  */
122         transfer_request =  &hid -> ux_host_class_hid_interrupt_endpoint -> ux_endpoint_transfer_request;
123 
124         /* Then de allocate the memory.  */
125         _ux_utility_memory_free(transfer_request -> ux_transfer_request_data_pointer);
126     }
127 
128 #if defined(UX_HOST_STANDALONE)
129     if (hid -> ux_host_class_hid_allocated)
130         _ux_utility_memory_free(hid -> ux_host_class_hid_allocated);
131 #endif
132 
133     /* We need to inform the HID client, if any, of the deactivation.  */
134     hid_client_command.ux_host_class_hid_client_command_instance =   (VOID *) hid;
135     hid_client_command.ux_host_class_hid_client_command_container =  (VOID *) hid -> ux_host_class_hid_class;
136     hid_client_command.ux_host_class_hid_client_command_request =    UX_HOST_CLASS_COMMAND_DEACTIVATE;
137 
138     /* Call the HID client with a deactivate command if there was a client registered.  */
139     if (hid -> ux_host_class_hid_client != UX_NULL)
140         hid -> ux_host_class_hid_client -> ux_host_class_hid_client_handler(&hid_client_command);
141 
142     /* Clean all the HID memory fields.  */
143     _ux_host_class_hid_instance_clean(hid);
144 
145     /* The enumeration thread needs to sleep a while to allow the application or the class that may be using
146        endpoints to exit properly.  */
147     _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM);
148 
149     /* Destroy the instance.  */
150     _ux_host_stack_class_instance_destroy(hid -> ux_host_class_hid_class, (VOID *) hid);
151 
152     /* Destroy the semaphore.  */
153     _ux_host_semaphore_delete(&hid -> ux_host_class_hid_semaphore);
154 
155     /* Before we free the device resources, we need to inform the application
156         that the device is removed.  */
157     if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
158     {
159 
160         /* Inform the application the device is removed.  */
161         _ux_system_host -> ux_system_host_change_function(UX_DEVICE_REMOVAL, hid -> ux_host_class_hid_class, (VOID *) hid);
162     }
163 
164     /* If trace is enabled, insert this event into the trace buffer.  */
165     UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_HID_DEACTIVATE, hid, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
166 
167     /* If trace is enabled, register this object.  */
168     UX_TRACE_OBJECT_UNREGISTER(hid);
169 
170     /* The HID is now free again.  */
171     _ux_utility_memory_free(hid);
172 
173     /* Return successful completion.  */
174     return(UX_SUCCESS);
175 }
176 
177