GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_hub_deactivate.c Lines: 17 17 100.0 %
Date: 2026-03-06 18:57:10 Branches: 6 6 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
/**   HUB Class                                                           */
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_class_hub.h"
30
#include "ux_host_stack.h"
31
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _ux_host_class_hub_deactivate                       PORTABLE C      */
38
/*                                                           6.3.0        */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Chaoqiong Xiao, Microsoft Corporation                               */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function is called when this instance of the HUB has been      */
46
/*    removed from the bus either directly or indirectly. The interrupt   */
47
/*    pipe will be destroyed and the instance removed.                    */
48
/*                                                                        */
49
/*  INPUT                                                                 */
50
/*                                                                        */
51
/*    command                               Pointer to class command      */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    Completion Status                                                   */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _ux_host_stack_class_instance_destroy Destroy class instance        */
60
/*    _ux_host_stack_device_remove          Remove device                 */
61
/*    _ux_host_stack_endpoint_transfer_abort                              */
62
/*                                          Abort transfer                */
63
/*    _ux_utility_memory_free               Release memory block          */
64
/*    _ux_host_semaphore_get                Get semaphore                 */
65
/*    _ux_host_semaphore_put                Release semaphore             */
66
/*    _ux_utility_thread_schedule_other     Schedule other threads        */
67
/*                                                                        */
68
/*  CALLED BY                                                             */
69
/*                                                                        */
70
/*    HUB Class                                                           */
71
/*                                                                        */
72
/**************************************************************************/
73
36
UINT  _ux_host_class_hub_deactivate(UX_HOST_CLASS_COMMAND *command)
74
{
75
76
UX_HOST_CLASS_HUB       *hub;
77
UX_HCD                  *hcd;
78
36
UX_TRANSFER             *transfer_request = UX_NULL;
79
UINT                    port_index;
80
81
82
    /* Get the instance to the class.  */
83
36
    hub =  (UX_HOST_CLASS_HUB *) command -> ux_host_class_command_instance;
84
85
    /* Get the HCD used by this instance.  */
86
36
    hcd = UX_DEVICE_HCD_GET(hub -> ux_host_class_hub_device);
87
88
    /* The HUB is being shut down.  */
89
36
    hub -> ux_host_class_hub_state =  UX_HOST_CLASS_INSTANCE_SHUTDOWN;
90
91
    /* We need to abort transactions on the interrupt pipe.  */
92
#if defined(UX_HOST_STANDALONE)
93
    if (hub -> ux_host_class_hub_interrupt_endpoint)
94
#endif
95
    {
96
36
        _ux_host_stack_endpoint_transfer_abort(hub -> ux_host_class_hub_interrupt_endpoint);
97
98
        /* If the Hub class instance has a interrupt pipe with a data payload associated with it
99
           it must be freed.  First get the transfer request. */
100
36
        transfer_request =  &hub -> ux_host_class_hub_interrupt_endpoint -> ux_endpoint_transfer_request;
101
    }
102
103
    /* Each device which is downstream on the HUB ports must be removed.  */
104
108
    for (port_index = 1; port_index <= hub -> ux_host_class_hub_descriptor.bNbPorts; port_index++)
105
    {
106
107
        /* Is there a device on this port?  */
108
72
        if (hub -> ux_host_class_hub_port_state & (1UL << port_index))
109
        {
110
111
            /* The stack will remove the device and its resources.  */
112
12
            _ux_host_stack_device_remove(hcd, hub -> ux_host_class_hub_device, port_index);
113
        }
114
    }
115
116
117
    /* The enumeration thread needs to sleep a while to allow the application or the class that may be using
118
       endpoints to exit properly.  */
119
36
    _ux_host_thread_schedule_other(UX_THREAD_PRIORITY_ENUM);
120
121
    /* Then de allocate the memory.  */
122
#if defined(UX_HOST_STANDALONE)
123
    if (transfer_request)
124
#endif
125
36
    _ux_utility_memory_free(transfer_request -> ux_transfer_request_data_pointer);
126
127
#if defined(UX_HOST_STANDALONE)
128
    if (hub -> ux_host_class_hub_allocated)
129
    {
130
        _ux_utility_memory_free(hub -> ux_host_class_hub_allocated);
131
    }
132
#endif
133
134
    /* Destroy the instance.  */
135
36
    _ux_host_stack_class_instance_destroy(hub -> ux_host_class_hub_class, (VOID *) hub);
136
137
    /* Before we free the device resources, we need to inform the application
138
        that the device is removed.  */
139
36
    if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
140
    {
141
142
        /* Inform the application the device is removed.  */
143
35
        _ux_system_host -> ux_system_host_change_function(UX_DEVICE_REMOVAL, hub -> ux_host_class_hub_class, (VOID *) hub);
144
    }
145
146
    /* If trace is enabled, insert this event into the trace buffer.  */
147
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_HUB_DEACTIVATE, hub, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
148
149
    /* If trace is enabled, register this object.  */
150
    UX_TRACE_OBJECT_UNREGISTER(hub);
151
152
#if defined(UX_HOST_STANDALONE)
153
154
    /* Unlink from device class instance.  */
155
    hub -> ux_host_class_hub_device -> ux_device_class_instance =  (VOID *) hub;
156
#endif
157
158
    /* Free the memory block used by the class.  */
159
36
    _ux_utility_memory_free(hub);
160
161
    /* Return successful completion.  */
162
36
    return(UX_SUCCESS);
163
}