GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_hub_configure.c Lines: 31 31 100.0 %
Date: 2024-12-12 17:16:36 Branches: 14 14 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
/**   HUB Class                                                           */
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_class_hub.h"
29
#include "ux_host_stack.h"
30
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _ux_host_class_hub_configure                        PORTABLE C      */
37
/*                                                           6.1.11       */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Chaoqiong Xiao, Microsoft Corporation                               */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function calls the USBX stack to do a SET_CONFIGURATION to the */
45
/*    HUB. Once the HUB is configured, its interface will be activated    */
46
/*    and all the endpoints enumerated (1 interrupt endpoint in the case  */
47
/*    of the HUB).                                                        */
48
/*                                                                        */
49
/*  INPUT                                                                 */
50
/*                                                                        */
51
/*    hub                                   Pointer to HUB                */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    Completion Status                                                   */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _ux_host_stack_device_configuration_get Get device configuration    */
60
/*    _ux_host_stack_device_configuration_select                          */
61
/*                                          Select device configuration   */
62
/*    _ux_host_stack_configuration_interface_get                          */
63
/*                                          Get interface                 */
64
/*    _ux_host_stack_transfer_request       Process transfer request      */
65
/*    _ux_utility_memory_allocate           Allocate memory block         */
66
/*    _ux_utility_memory_free               Release memory block          */
67
/*                                                                        */
68
/*  CALLED BY                                                             */
69
/*                                                                        */
70
/*    HUB Class                                                           */
71
/*                                                                        */
72
/*  RELEASE HISTORY                                                       */
73
/*                                                                        */
74
/*    DATE              NAME                      DESCRIPTION             */
75
/*                                                                        */
76
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
77
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
78
/*                                            optimized based on compile  */
79
/*                                            definitions,                */
80
/*                                            resulting in version 6.1    */
81
/*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
82
/*                                            internal clean up,          */
83
/*                                            resulting in version 6.1.11 */
84
/*                                                                        */
85
/**************************************************************************/
86
71
UINT  _ux_host_class_hub_configure(UX_HOST_CLASS_HUB *hub)
87
{
88
89
UINT                    status;
90
UX_CONFIGURATION        *configuration;
91
UX_DEVICE               *device;
92
UX_ENDPOINT             *control_endpoint;
93
UCHAR                   *device_status_data;
94
UX_TRANSFER             *transfer_request;
95
#if UX_MAX_DEVICES > 1
96
UX_DEVICE               *parent_device;
97
#endif
98
99
100
    /* A HUB normally has one configuration. So retrieve the 1st configuration
101
       only.  */
102
71
    _ux_host_stack_device_configuration_get(hub -> ux_host_class_hub_device, 0, &configuration);
103
104
    /* Get the device container for this configuration.  */
105
71
    device =  configuration -> ux_configuration_device;
106
107
    /* To find the true source of the HUB power source, we need to do a GET_STATUS of
108
       the device.  */
109
71
    control_endpoint =  &device -> ux_device_control_endpoint;
110
71
    transfer_request =  &control_endpoint -> ux_endpoint_transfer_request;
111
112
    /* Allocate a buffer for the device status: 2 bytes.  */
113
71
    device_status_data =  _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 2);
114
71
    if (device_status_data == UX_NULL)
115
1
        return(UX_MEMORY_INSUFFICIENT);
116
117
    /* Create a transfer_request for the GET_STATUS request, 2 bytes are returned.  */
118
70
    transfer_request -> ux_transfer_request_requested_length =  2;
119
70
    transfer_request -> ux_transfer_request_data_pointer =      device_status_data;
120
70
    transfer_request -> ux_transfer_request_function =          UX_GET_STATUS;
121
70
    transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
122
70
    transfer_request -> ux_transfer_request_value =             0;
123
70
    transfer_request -> ux_transfer_request_index =             0;
124
125
    /* Send request to HCD layer.  */
126
70
    status =  _ux_host_stack_transfer_request(transfer_request);
127
128
    /* Check the status and the length of the data returned.  */
129

70
    if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == 2))
130
    {
131
132
        /* The data returned is good, now analyze power source.  */
133
66
        if (*device_status_data & UX_STATUS_DEVICE_SELF_POWERED)
134
30
            device -> ux_device_power_source =  UX_DEVICE_SELF_POWERED;
135
        else
136
36
            device -> ux_device_power_source =  UX_DEVICE_BUS_POWERED;
137
138
        /* Free the buffer resource now.  */
139
66
        _ux_utility_memory_free(device_status_data);
140
    }
141
    else
142
    {
143
144
        /* Free the buffer resource now.  */
145
4
        _ux_utility_memory_free(device_status_data);
146
147
        /* Error trap. */
148
4
        _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HUB, UX_CONNECTION_INCOMPATIBLE);
149
150
        /* If trace is enabled, insert this event into the trace buffer.  */
151
        UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONNECTION_INCOMPATIBLE, hub, 0, 0, UX_TRACE_ERRORS, 0, 0)
152
153
        /* Return an error.  */
154
4
        return(UX_CONNECTION_INCOMPATIBLE);
155
    }
156
157
#if UX_MAX_DEVICES > 1
158
    /* Check the HUB power source and check the parent power source for
159
       incompatible connections.  */
160
66
    if (hub -> ux_host_class_hub_device -> ux_device_power_source == UX_DEVICE_BUS_POWERED)
161
    {
162
163
        /* Get the parent container for this device.  */
164
36
        parent_device =  device -> ux_device_parent;
165
166
        /* If the device is NULL, the parent is the root HUB and we don't have to worry
167
           if the parent is not the root HUB, check for its power source.  */
168

36
        if ((parent_device != UX_NULL) && (parent_device -> ux_device_power_source == UX_DEVICE_BUS_POWERED))
169
        {
170
171
            /* Error trap. */
172
1
            _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HUB, UX_CONNECTION_INCOMPATIBLE);
173
174
            /* If trace is enabled, insert this event into the trace buffer.  */
175
            UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONNECTION_INCOMPATIBLE, hub, 0, 0, UX_TRACE_ERRORS, 0, 0)
176
177
1
            return(UX_CONNECTION_INCOMPATIBLE);
178
        }
179
    }
180
#endif
181
182
    /* We have the valid configuration. Ask the USBX stack to set this configuration.  */
183
65
    _ux_host_stack_device_configuration_select(configuration);
184
185
    /* If the operation went well, the HUB default alternate setting for the HUB interface is
186
       active and the interrupt endpoint is now enabled. We have to memorize the first interface
187
       since the interrupt endpoint is hooked to it. */
188
65
    status =  _ux_host_stack_configuration_interface_get(configuration, 0, 0, &hub -> ux_host_class_hub_interface);
189
190
    /* Return completion status.  */
191
65
    return(status);
192
}
193