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 /**   Device Stack                                                        */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define UX_SOURCE_CODE
24 
25 
26 /* Include necessary system files.  */
27 
28 #include "ux_api.h"
29 #include "ux_device_stack.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _ux_device_stack_disconnect                         PORTABLE C      */
37 /*                                                           6.1.12       */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Chaoqiong Xiao, Microsoft Corporation                               */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function is called when the device gets disconnected from the  */
45 /*    host. All the device resources are freed.                           */
46 /*                                                                        */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    None                                                                */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    Completion Status                                                   */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    (ux_slave_class_entry_function)       Device class entry function   */
59 /*    (ux_slave_dcd_function)               DCD dispatch function         */
60 /*    _ux_device_stack_interface_delete     Delete interface              */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    Application                                                         */
65 /*    Device Stack                                                        */
66 /*                                                                        */
67 /*  RELEASE HISTORY                                                       */
68 /*                                                                        */
69 /*    DATE              NAME                      DESCRIPTION             */
70 /*                                                                        */
71 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
72 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
73 /*                                            optimized based on compile  */
74 /*                                            definitions,                */
75 /*                                            resulting in version 6.1    */
76 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
77 /*                                            fixed parameter/variable    */
78 /*                                            names conflict C++ keyword, */
79 /*                                            resulting in version 6.1.12 */
80 /*                                                                        */
81 /**************************************************************************/
_ux_device_stack_disconnect(VOID)82 UINT  _ux_device_stack_disconnect(VOID)
83 {
84 
85 UX_SLAVE_DCD                *dcd;
86 UX_SLAVE_DEVICE             *device;
87 UX_SLAVE_INTERFACE          *interface_ptr;
88 #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1
89 UX_SLAVE_INTERFACE          *next_interface;
90 #endif
91 UX_SLAVE_CLASS              *class_ptr;
92 UX_SLAVE_CLASS_COMMAND      class_command;
93 UINT                        status = UX_ERROR;
94 
95     /* Get the pointer to the DCD.  */
96     dcd =  &_ux_system_slave -> ux_system_slave_dcd;
97 
98     /* Get the pointer to the device.  */
99     device =  &_ux_system_slave -> ux_system_slave_device;
100 
101     /* If trace is enabled, insert this event into the trace buffer.  */
102     UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_DISCONNECT, device, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
103 
104     /* If trace is enabled, register this object.  */
105     UX_TRACE_OBJECT_UNREGISTER(device);
106 
107     /* If the device was in the configured state, there may be interfaces
108        attached to the configuration.  */
109     if (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
110     {
111         /* Get the pointer to the first interface.  */
112         interface_ptr =  device -> ux_slave_device_first_interface;
113 
114 #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1
115         /* Parse all the interfaces if any.  */
116         while (interface_ptr != UX_NULL)
117         {
118 #endif
119 
120             /* Build all the fields of the Class Command.  */
121             class_command.ux_slave_class_command_request =   UX_SLAVE_CLASS_COMMAND_DEACTIVATE;
122             class_command.ux_slave_class_command_interface =  (VOID *) interface_ptr;
123 
124             /* Get the pointer to the class container of this interface.  */
125             class_ptr =  interface_ptr -> ux_slave_interface_class;
126 
127             /* Store the class container. */
128             class_command.ux_slave_class_command_class_ptr =  class_ptr;
129 
130             /* If there is a class container for this instance, deactivate it.  */
131             if (class_ptr != UX_NULL)
132 
133                 /* Call the class with the DEACTIVATE signal.  */
134                 class_ptr -> ux_slave_class_entry_function(&class_command);
135 
136 #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1
137             /* Get the next interface.  */
138             next_interface =  interface_ptr -> ux_slave_interface_next_interface;
139 #endif
140 
141             /* Remove the interface and all endpoints associated with it.  */
142             _ux_device_stack_interface_delete(interface_ptr);
143 
144 #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1
145             /* Now we refresh the interface pointer.  */
146             interface_ptr =  next_interface;
147         }
148 #endif
149 
150         /* Mark the device as attached now.  */
151         device -> ux_slave_device_state =  UX_DEVICE_ATTACHED;
152     }
153 
154     /* If the device was attached, we need to destroy the control endpoint.  */
155     if (device -> ux_slave_device_state == UX_DEVICE_ATTACHED)
156 
157         /* Now we can destroy the default control endpoint.  */
158         status =  dcd -> ux_slave_dcd_function(dcd, UX_DCD_DESTROY_ENDPOINT,
159                                 (VOID *) &device -> ux_slave_device_control_endpoint);
160 
161     /* We are reverting to configuration 0.  */
162     device -> ux_slave_device_configuration_selected =  0;
163 
164     /* Set the device to be non attached.  */
165     device -> ux_slave_device_state =  UX_DEVICE_RESET;
166 
167     /* Check the status change callback.  */
168     if(_ux_system_slave -> ux_system_slave_change_function != UX_NULL)
169     {
170 
171         /* Inform the application if a callback function was programmed.  */
172         _ux_system_slave -> ux_system_slave_change_function(UX_DEVICE_REMOVED);
173     }
174 
175     /* Return the status to the caller.  */
176     return(status);
177 }
178 
179