GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_device_remove.c Lines: 31 31 100.0 %
Date: 2026-03-06 18:57:10 Branches: 22 22 100.0 %

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_device_remove                        PORTABLE C      */
37
/*                                                           6.1.12       */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Chaoqiong Xiao, Microsoft Corporation                               */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function will remove a USB device from the bus.                */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    HCD                                   Pointer to the HCD            */
49
/*    parent                                The parent device address     */
50
/*    port_index                            Index of the port on which the*/
51
/*                                            change of status occurred   */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    Completion Status                                                   */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _ux_host_stack_device_resources_free  Free all device resources     */
60
/*                                                                        */
61
/*  CALLED BY                                                             */
62
/*                                                                        */
63
/*    USBX Components                                                     */
64
/*                                                                        */
65
/**************************************************************************/
66
1294
UINT  _ux_host_stack_device_remove(UX_HCD *hcd, UX_DEVICE *parent, UINT port_index)
67
{
68
69
#if UX_MAX_DEVICES > 1
70
ULONG                       container_index;
71
#endif
72
UX_DEVICE                   *device;
73
UX_CONFIGURATION            *configuration;
74
UX_INTERFACE                *interface_ptr;
75
UX_HOST_CLASS_COMMAND       command;
76
77
    /* We need to find the device descriptor for the removed device. We can find it
78
       with the parent device and the port it was attached to. Start with the first device.  */
79
1294
    device =  _ux_system_host -> ux_system_host_device_array;
80
81
#if UX_MAX_DEVICES > 1
82
    /* Start at the beginning of the list.  */
83
1294
    container_index =  0;
84
85
    /* Search the list until the end.  */
86
1363
    while (container_index++ < _ux_system_host -> ux_system_host_max_devices)
87
    {
88
89
        /* Until we have found a used entry.  */
90
1356
        if (device -> ux_device_handle != UX_UNUSED)
91
        {
92
93
            /* Check for the parent device and the port location and the controller.  */
94
1312
            if( UX_DEVICE_PARENT_MATCH(device, parent) &&
95
1291
                UX_DEVICE_PORT_LOCATION_MATCH(device, port_index) &&
96
1289
                UX_DEVICE_HCD_MATCH(device, hcd))
97
1287
                break;
98
        }
99
100
        /* Move to the next device entry.  */
101
69
        device++;
102
    }
103
104
    /* Device not found.  */
105
1294
    if (container_index > _ux_system_host -> ux_system_host_max_devices)
106
#else
107
    UX_PARAMETER_NOT_USED(parent);
108
    UX_PARAMETER_NOT_USED(port_index);
109
110
    /* Device is available and HCD is expected.  */
111
    if (device -> ux_device_handle == UX_UNUSED ||
112
        !UX_DEVICE_HCD_MATCH(device, hcd))
113
#endif
114
    {
115
116
        /* Error trap. */
117
7
        _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DEVICE_HANDLE_UNKNOWN);
118
119
        /* If trace is enabled, insert this event into the trace buffer.  */
120
        UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DEVICE_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
121
122
        /* We get here when we could not find the device.  */
123
7
        return(UX_DEVICE_HANDLE_UNKNOWN);
124
    }
125
126
    /* If trace is enabled, insert this event into the trace buffer.  */
127
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_REMOVE, hcd, parent, port_index, device, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
128
129
    /* If trace is enabled, unregister this object.  */
130
    UX_TRACE_OBJECT_UNREGISTER(device);
131
132
    /* We have found the device to be removed. */
133
1287
    device -> ux_device_state = UX_DEVICE_REMOVED;
134
135
    /* We have found the device to be removed. Initialize the class
136
        command with the generic parameters.  */
137
1287
    command.ux_host_class_command_request =  UX_HOST_CLASS_COMMAND_DEACTIVATE;
138
139
    /* The device may have a class associated with the device container or its interfaces.  */
140
1287
    if (device -> ux_device_class_instance != UX_NULL)
141
    {
142
143
        /* We need to stop the class instance for the device.  */
144
38
        command.ux_host_class_command_instance =  device -> ux_device_class_instance;
145
146
        /* Call the class.  */
147
38
        device -> ux_device_class -> ux_host_class_entry_function(&command);
148
    }
149
    else
150
    {
151
152
        /* Search for the active configuration.  */
153
1249
        configuration =  device -> ux_device_current_configuration;
154
155
        /* If configuration is activated.  */
156
1249
        if (configuration != UX_NULL)
157
        {
158
159
            /* We have the correct configuration, search the interface(s).  */
160
629
            interface_ptr =  configuration -> ux_configuration_first_interface;
161
162
            /* Loop to perform the search.  */
163
2030
            while (interface_ptr != UX_NULL)
164
            {
165
166
                /* Check if an instance of the interface is present.  */
167
1407
                if (interface_ptr -> ux_interface_class_instance != UX_NULL)
168
                {
169
170
                    /* We need to stop the class instance for the device.  */
171
456
                    command.ux_host_class_command_instance =  interface_ptr -> ux_interface_class_instance;
172
173
                    /* Call the class.  */
174
456
                    interface_ptr -> ux_interface_class -> ux_host_class_entry_function(&command);
175
                }
176
177
                /* Move to next interface.  */
178
1401
                interface_ptr =  interface_ptr -> ux_interface_next_interface;
179
            }
180
        }
181
    }
182
183
    /* Notify application for disconnection of existing physical device.  */
184
1281
    if (_ux_system_host -> ux_system_host_change_function)
185
    {
186
1150
        _ux_system_host -> ux_system_host_change_function(UX_DEVICE_DISCONNECTION, UX_NULL, (VOID*)device);
187
    }
188
189
    /* Now all the resources for this device must be free.  */
190
1281
    _ux_host_stack_device_resources_free(device);
191
192
    /* Decrement the number of devices on this bus.  */
193
1278
    hcd -> ux_hcd_nb_devices--;
194
195
    /* We are done with this device removal.  */
196
1278
    return(UX_SUCCESS);
197
}