GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_hcd_unregister.c Lines: 33 37 89.2 %
Date: 2026-03-06 18:57:10 Branches: 20 22 90.9 %

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