GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_device_remove.c Lines: 31 31 100.0 %
Date: 2024-12-12 17:16:36 Branches: 22 22 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** USBX Component                                                        */
16
/**                                                                       */
17
/**   Host Stack                                                          */
18
/**                                                                       */
19
/**************************************************************************/
20
/**************************************************************************/
21
22
23
/* Include necessary system files.  */
24
25
#define UX_SOURCE_CODE
26
27
#include "ux_api.h"
28
#include "ux_host_stack.h"
29
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _ux_host_stack_device_remove                        PORTABLE C      */
36
/*                                                           6.1.12       */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Chaoqiong Xiao, Microsoft Corporation                               */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This function will remove a USB device from the bus.                */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    HCD                                   Pointer to the HCD            */
48
/*    parent                                The parent device address     */
49
/*    port_index                            Index of the port on which the*/
50
/*                                            change of status occurred   */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    Completion Status                                                   */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    _ux_host_stack_device_resources_free  Free all device resources     */
59
/*                                                                        */
60
/*  CALLED BY                                                             */
61
/*                                                                        */
62
/*    USBX Components                                                     */
63
/*                                                                        */
64
/*  RELEASE HISTORY                                                       */
65
/*                                                                        */
66
/*    DATE              NAME                      DESCRIPTION             */
67
/*                                                                        */
68
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
69
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
70
/*                                            optimized based on compile  */
71
/*                                            definitions,                */
72
/*                                            resulting in version 6.1    */
73
/*  02-02-2021     Chaoqiong Xiao           Modified comment(s),          */
74
/*                                            used pointer for current    */
75
/*                                            selected configuration,     */
76
/*                                            added notification for      */
77
/*                                            device disconnection,       */
78
/*                                            resulting in version 6.1.4  */
79
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
80
/*                                            added standalone support,   */
81
/*                                            resulting in version 6.1.10 */
82
/*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
83
/*                                            fixed parameter/variable    */
84
/*                                            names conflict C++ keyword, */
85
/*                                            resulting in version 6.1.12 */
86
/*                                                                        */
87
/**************************************************************************/
88
1294
UINT  _ux_host_stack_device_remove(UX_HCD *hcd, UX_DEVICE *parent, UINT port_index)
89
{
90
91
#if UX_MAX_DEVICES > 1
92
ULONG                       container_index;
93
#endif
94
UX_DEVICE                   *device;
95
UX_CONFIGURATION            *configuration;
96
UX_INTERFACE                *interface_ptr;
97
UX_HOST_CLASS_COMMAND       command;
98
99
    /* We need to find the device descriptor for the removed device. We can find it
100
       with the parent device and the port it was attached to. Start with the first device.  */
101
1294
    device =  _ux_system_host -> ux_system_host_device_array;
102
103
#if UX_MAX_DEVICES > 1
104
    /* Start at the beginning of the list.  */
105
1294
    container_index =  0;
106
107
    /* Search the list until the end.  */
108
1363
    while (container_index++ < _ux_system_host -> ux_system_host_max_devices)
109
    {
110
111
        /* Until we have found a used entry.  */
112
1356
        if (device -> ux_device_handle != UX_UNUSED)
113
        {
114
115
            /* Check for the parent device and the port location and the controller.  */
116
1312
            if( UX_DEVICE_PARENT_MATCH(device, parent) &&
117
1291
                UX_DEVICE_PORT_LOCATION_MATCH(device, port_index) &&
118
1289
                UX_DEVICE_HCD_MATCH(device, hcd))
119
1287
                break;
120
        }
121
122
        /* Move to the next device entry.  */
123
69
        device++;
124
    }
125
126
    /* Device not found.  */
127
1294
    if (container_index > _ux_system_host -> ux_system_host_max_devices)
128
#else
129
    UX_PARAMETER_NOT_USED(parent);
130
    UX_PARAMETER_NOT_USED(port_index);
131
132
    /* Device is available and HCD is expected.  */
133
    if (device -> ux_device_handle == UX_UNUSED ||
134
        !UX_DEVICE_HCD_MATCH(device, hcd))
135
#endif
136
    {
137
138
        /* Error trap. */
139
7
        _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DEVICE_HANDLE_UNKNOWN);
140
141
        /* If trace is enabled, insert this event into the trace buffer.  */
142
        UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DEVICE_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
143
144
        /* We get here when we could not find the device.  */
145
7
        return(UX_DEVICE_HANDLE_UNKNOWN);
146
    }
147
148
    /* If trace is enabled, insert this event into the trace buffer.  */
149
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_REMOVE, hcd, parent, port_index, device, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
150
151
    /* If trace is enabled, unregister this object.  */
152
    UX_TRACE_OBJECT_UNREGISTER(device);
153
154
    /* We have found the device to be removed. */
155
1287
    device -> ux_device_state = UX_DEVICE_REMOVED;
156
157
    /* We have found the device to be removed. Initialize the class
158
        command with the generic parameters.  */
159
1287
    command.ux_host_class_command_request =  UX_HOST_CLASS_COMMAND_DEACTIVATE;
160
161
    /* The device may have a class associated with the device container or its interfaces.  */
162
1287
    if (device -> ux_device_class_instance != UX_NULL)
163
    {
164
165
        /* We need to stop the class instance for the device.  */
166
38
        command.ux_host_class_command_instance =  device -> ux_device_class_instance;
167
168
        /* Call the class.  */
169
38
        device -> ux_device_class -> ux_host_class_entry_function(&command);
170
    }
171
    else
172
    {
173
174
        /* Search for the active configuration.  */
175
1249
        configuration =  device -> ux_device_current_configuration;
176
177
        /* If configuration is activated.  */
178
1249
        if (configuration != UX_NULL)
179
        {
180
181
            /* We have the correct configuration, search the interface(s).  */
182
629
            interface_ptr =  configuration -> ux_configuration_first_interface;
183
184
            /* Loop to perform the search.  */
185
2030
            while (interface_ptr != UX_NULL)
186
            {
187
188
                /* Check if an instance of the interface is present.  */
189
1407
                if (interface_ptr -> ux_interface_class_instance != UX_NULL)
190
                {
191
192
                    /* We need to stop the class instance for the device.  */
193
456
                    command.ux_host_class_command_instance =  interface_ptr -> ux_interface_class_instance;
194
195
                    /* Call the class.  */
196
456
                    interface_ptr -> ux_interface_class -> ux_host_class_entry_function(&command);
197
                }
198
199
                /* Move to next interface.  */
200
1401
                interface_ptr =  interface_ptr -> ux_interface_next_interface;
201
            }
202
        }
203
    }
204
205
    /* Notify application for disconnection of existing physical device.  */
206
1281
    if (_ux_system_host -> ux_system_host_change_function)
207
    {
208
1150
        _ux_system_host -> ux_system_host_change_function(UX_DEVICE_DISCONNECTION, UX_NULL, (VOID*)device);
209
    }
210
211
    /* Now all the resources for this device must be free.  */
212
1281
    _ux_host_stack_device_resources_free(device);
213
214
    /* Decrement the number of devices on this bus.  */
215
1278
    hcd -> ux_hcd_nb_devices--;
216
217
    /* We are done with this device removal.  */
218
1278
    return(UX_SUCCESS);
219
}