summaryrefslogtreecommitdiff
path: root/common/usbx_host_classes/src/ux_host_class_hub_status_get.c
blob: 14332c3b884c42fe54c94f4dd4a2e0b44ab8b5ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/***************************************************************************
 * Copyright (c) 2024 Microsoft Corporation
 * Copyright (c) 2026-present Eclipse ThreadX contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * SPDX-License-Identifier: MIT
 **************************************************************************/


/**************************************************************************/
/**************************************************************************/
/**                                                                       */
/** USBX Component                                                        */
/**                                                                       */
/**   HUB Class                                                           */
/**                                                                       */
/**************************************************************************/
/**************************************************************************/


/* Include necessary system files.  */

#define UX_SOURCE_CODE

#include "ux_api.h"
#include "ux_host_class_hub.h"
#include "ux_host_stack.h"


/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _ux_host_class_hub_status_get                       PORTABLE C      */
/*                                                           6.1.12       */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Chaoqiong Xiao, Microsoft Corporation                               */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function will do a GET_STATUS from the HUB. This function      */
/*    retrieves the current status and the changed bits.                  */
/*                                                                        */
/*    In standalone mode, this functioin prepares the control transfer    */
/*    request data memory and request context of specific command, for    */
/*    host stack transfer function to process, in next steps. The         */
/*    allocated memory must be freed after transfer request is processed. */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    hub                                   Pointer to HUB class          */
/*    port                                  Port of device                */
/*    port_status                           Destination for port status   */
/*    port_change                           Destination for port change   */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    Completion Status                                                   */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    _ux_host_stack_transfer_request       Process transfer request      */
/*    _ux_utility_memory_allocate           Allocate memory block         */
/*    _ux_utility_memory_free               Release memory block          */
/*    _ux_utility_short_get                 Get 16-bit word               */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    HUB Class                                                           */
/*                                                                        */
/**************************************************************************/
UINT  _ux_host_class_hub_status_get(UX_HOST_CLASS_HUB *hub, UINT port, USHORT *port_status, USHORT *port_change)
{

UCHAR           *port_data;
UX_ENDPOINT     *control_endpoint;
UX_TRANSFER     *transfer_request;
UINT            target;
UINT            status;


    /* We need to get the default control endpoint transfer request pointer.  */
    control_endpoint =  &hub -> ux_host_class_hub_device -> ux_device_control_endpoint;
    transfer_request =  &control_endpoint -> ux_endpoint_transfer_request;

    /* The target is DEVICE for the HUB and OTHER for the downstream ports.  */
    if (port == 0)
        target =  UX_REQUEST_TARGET_DEVICE;
    else
        target =  UX_REQUEST_TARGET_OTHER;

    /* Allocate a buffer for the port status and change: 2 words.  */
    port_data =  _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, 4);
    if(port_data == UX_NULL)
        return(UX_MEMORY_INSUFFICIENT);

    /* Create a transfer request for the GET_STATUS request.  */
    transfer_request -> ux_transfer_request_requested_length =  4;
    transfer_request -> ux_transfer_request_data_pointer =      port_data;
    transfer_request -> ux_transfer_request_function =          UX_HOST_CLASS_HUB_GET_STATUS;
    transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | target;
    transfer_request -> ux_transfer_request_value =             0;
    transfer_request -> ux_transfer_request_index =             port;

#if defined(UX_HOST_STANDALONE)

    /* No status change change copy.  */
    UX_PARAMETER_NOT_USED(port_status);
    UX_PARAMETER_NOT_USED(port_change);

    /* Save allocated buffer.  */
    hub -> ux_host_class_hub_allocated = port_data;

    /* Reset transfer state for _run.  */
    UX_TRANSFER_STATE_RESET(transfer_request);
    status = UX_SUCCESS;
#else

    /* Send request to HCD layer.  */
    status =  _ux_host_stack_transfer_request(transfer_request);

    /* Check for error and completion of the transfer.  */
    if (status == UX_SUCCESS)
    {

        if (transfer_request -> ux_transfer_request_actual_length == 4)
        {

            /* The 2 words are now in the buffer. We need to resolve their endianness
               and report them as separate items to the called.  */
            *port_status =  (USHORT)_ux_utility_short_get(port_data);
            *port_change =  (USHORT)_ux_utility_short_get(port_data+2);
        }
        else
        {

            /* Invalid length. Return error.  */
            status =  UX_TRANSFER_DATA_LESS_THAN_EXPECTED;
        }
    }

    /* Free the buffer resource now.  */
    _ux_utility_memory_free(port_data);

#endif

    /* Return completion status.  */
    return(status);
}