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 /** Host Stack */
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_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_stack_rh_change_process PORTABLE C */
37 /* 6.1.2 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function checks for changes in topology in each of the */
45 /* installed HCDs. */
46 /* */
47 /* INPUT */
48 /* */
49 /* None */
50 /* */
51 /* OUTPUT */
52 /* */
53 /* None */
54 /* */
55 /* CALLS */
56 /* */
57 /* _ux_host_stack_rh_device_insertion Process device insertion */
58 /* _ux_host_stack_rh_device_extraction Process device extraction */
59 /* (ux_hcd_entry_function) HCD entry function */
60 /* */
61 /* CALLED BY */
62 /* */
63 /* USBX Components */
64 /* */
65 /* RELEASE HISTORY */
66 /* */
67 /* DATE NAME DESCRIPTION */
68 /* */
69 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
70 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
71 /* used new interrupt macros, */
72 /* resulting in version 6.1 */
73 /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */
74 /* fixed registered HCD scan, */
75 /* resulting in version 6.1.2 */
76 /* */
77 /**************************************************************************/
_ux_host_stack_rh_change_process(VOID)78 VOID _ux_host_stack_rh_change_process(VOID)
79 {
80
81 UX_HCD *hcd;
82 UINT hcd_index;
83 ULONG port_status;
84 UINT port_index;
85 UX_INTERRUPT_SAVE_AREA
86
87 /* This thread was maybe awaken by one or more HCD controllers. Check each
88 of the HCD to see where there has been a change of topology. */
89 for(hcd_index = 0; hcd_index < UX_SYSTEM_HOST_MAX_HCD_GET(); hcd_index++)
90 {
91
92 /* Pickup HCD pointer. */
93 hcd = &_ux_system_host -> ux_system_host_hcd_array[hcd_index];
94
95 /* Is this HCD operational? */
96 if (hcd -> ux_hcd_status == UX_HCD_STATUS_OPERATIONAL)
97 {
98
99 /* On each port of the root hub of the controller, get the port status */
100 for (port_index = 0; port_index < hcd -> ux_hcd_nb_root_hubs; port_index++)
101 {
102
103 /* Was there any activity on this port ? */
104 if (hcd -> ux_hcd_root_hub_signal[port_index] != 0)
105 {
106
107 /* If trace is enabled, insert this event into the trace buffer. */
108 UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_RH_CHANGE_PROCESS, port_index, 0, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
109
110 /* Reset that port activity signal. */
111 UX_DISABLE
112 hcd -> ux_hcd_root_hub_signal[port_index]--;
113 UX_RESTORE
114
115 /* Call HCD for port status. */
116 port_status = hcd -> ux_hcd_entry_function(hcd, UX_HCD_GET_PORT_STATUS, (VOID *)((ALIGN_TYPE)port_index));
117
118 /* Check return status. */
119 if (port_status != UX_PORT_INDEX_UNKNOWN)
120 {
121
122 /* The port_status value is valid and will tell us if there is
123 a device attached\detached on the downstream port. */
124 if (port_status & UX_PS_CCS)
125 {
126
127 /* There is a device attached to this port. Check if we know
128 about it. If not, this is a device insertion signal. */
129 if ((hcd -> ux_hcd_rh_device_connection & (ULONG)(1 << port_index)) == 0)
130 {
131
132 /* We have a simple device insertion, we have not lost any signals.
133 the root hub and the stack enumeration module are in synch. */
134 _ux_host_stack_rh_device_insertion(hcd,port_index);
135 }
136 else
137 {
138 /* We can get here when there has been multiple events on the hardware root hub
139 but we may have missed them of they were too close or the stack got too busy.
140 We check the number of events in the root hub signal. If it is not zero
141 we are out of synch, meaning we got a disconnection followed very quickly
142 by a insertion. */
143
144 if (hcd -> ux_hcd_root_hub_signal[port_index] != 0)
145 {
146
147 /* We need to get back in synch now. */
148 UX_DISABLE
149 hcd -> ux_hcd_root_hub_signal[port_index] = 0;
150 UX_RESTORE
151
152 /* First extract the device. */
153 _ux_host_stack_rh_device_extraction(hcd,port_index);
154
155 /* Now, insert it again. */
156 _ux_host_stack_rh_device_insertion(hcd,port_index);
157
158
159 }
160
161 }
162 }
163 else
164 {
165
166 /* There is no device attached to this port. Check if we know
167 about it. If not, this is a device removal signal. */
168 if ((hcd -> ux_hcd_rh_device_connection & (ULONG)(1 << port_index)) !=0)
169 {
170 _ux_host_stack_rh_device_extraction(hcd,port_index);
171 }
172 }
173 }
174 }
175 }
176 }
177 }
178 }
179
180