1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-present Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Host Stack */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define UX_SOURCE_CODE
#include "ux_api.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_stack_hcd_unregister PORTABLE C */
/* 6.1.2 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function unregisters a USB host controller driver (HCD) with */
/* the USBX stack, removes all devices rooted from that controller and */
/* disable/stop the controller. */
/* */
/* INPUT */
/* */
/* hcd_name Name of HCD to unregister */
/* hcd_param1 Parameter 1 of HCD */
/* hcd_param2 Parameter 2 of HCD */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* UX_SUCCESS HCD unregistered, related */
/* devices removed and hardware */
/* disabled/stopped success */
/* UX_ERROR HCD not found */
/* */
/* CALLS */
/* */
/* _ux_utility_string_length_check Check and return C string */
/* length if no error */
/* _ux_utility_memory_compare Memory compare */
/* (ux_hcd_entry_function) HCD dispatch entry function */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/**************************************************************************/
UINT _ux_host_stack_hcd_unregister(UCHAR *hcd_name,
ULONG hcd_param1, ULONG hcd_param2)
{
UINT status;
UX_DEVICE *device;
UX_HCD *hcd;
#if UX_MAX_CLASS_DRIVER > 1 || UX_MAX_DEVICES > 1
ULONG scan_index;
#endif
#if !defined(UX_NAME_REFERENCED_BY_POINTER)
UINT hcd_name_length = 0;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_HCD_UNREGISTER, hcd_name, hcd_param1, hcd_param2, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
#if !defined(UX_NAME_REFERENCED_BY_POINTER)
/* Get the length of the class name (exclude null-terminator). */
status = _ux_utility_string_length_check(hcd_name,
&hcd_name_length, UX_MAX_HCD_NAME_LENGTH);
if (status)
return(status);
#endif
/* Get first HCD. */
hcd = _ux_system_host -> ux_system_host_hcd_array;
/* Default to not found status. */
status = UX_FALSE;
#if UX_MAX_CLASS_DRIVER > 1
/* We need to parse the controller driver table to find an empty spot. */
for (scan_index = 0;
scan_index < UX_SYSTEM_HOST_MAX_HCD_GET();
scan_index++)
{
#endif
/* Is this slot available and saved hcd_parameters match? */
if (hcd -> ux_hcd_status != UX_UNUSED &&
hcd -> ux_hcd_io == hcd_param1 &&
hcd -> ux_hcd_irq == hcd_param2)
{
/* Yes, compare the name (with null terminator). */
status = ux_utility_name_match(hcd -> ux_hcd_name,
hcd_name, hcd_name_length + 1);
#if UX_MAX_CLASS_DRIVER > 1
/* Break if name match (found HCD). */
if (status == UX_TRUE)
break;
#endif
}
#if UX_MAX_CLASS_DRIVER > 1
/* Try the next HCD structure */
hcd ++;
}
#endif
/* No valid HCD found. */
if (status != UX_TRUE)
return(UX_ERROR);
/* Now disable controller. */
hcd -> ux_hcd_entry_function(hcd, UX_HCD_UNINITIALIZE, UX_NULL);
/* Get first device. */
device = _ux_system_host -> ux_system_host_device_array;
#if UX_MAX_DEVICES > 1
/* Remove all devices connected to the controller. */
for (scan_index = 0;
scan_index < _ux_system_host -> ux_system_host_max_devices;
scan_index ++)
{
#else
/* No device. */
if (device -> ux_device_handle == UX_UNUSED)
return(UX_SUCCESS);
#endif
/* Is this device on the HCD root hub? */
if (UX_DEVICE_HCD_MATCH(device, hcd) &&
UX_DEVICE_PARENT_IS_ROOTHUB(device))
{
/* Remove the device (and downstream things connected to it). */
_ux_host_stack_device_remove(hcd, UX_DEVICE_PARENT_GET(device),
UX_DEVICE_PORT_LOCATION_GET(device));
/* The device has been removed, so the port is free again. */
hcd -> ux_hcd_rh_device_connection &= (ULONG)
~(1 << device -> ux_device_port_location);
}
#if UX_MAX_DEVICES > 1
/* Try the next device. */
device ++;
}
#endif
/* And we have one new controller unregistered. */
_ux_system_host -> ux_system_host_registered_hcd --;
return(UX_SUCCESS);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _uxe_host_stack_hcd_unregister PORTABLE C */
/* 6.3.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks errors in host stack HCD unregister function */
/* call. */
/* */
/* INPUT */
/* */
/* hcd_name Name of HCD to unregister */
/* hcd_param1 Parameter 1 of HCD */
/* hcd_param2 Parameter 2 of HCD */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_host_stack_hcd_unregister HCD unregister */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/**************************************************************************/
UINT _uxe_host_stack_hcd_unregister(UCHAR *hcd_name,
ULONG hcd_param1, ULONG hcd_param2)
{
/* Sanity check. */
if (hcd_name == UX_NULL)
return(UX_INVALID_PARAMETER);
/* Invoke HCD unregister function. */
return(_ux_host_stack_hcd_unregister(hcd_name, hcd_param1, hcd_param2));
}
|