1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** USBX Component */
17 /** */
18 /** Device Stack */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define UX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "ux_api.h"
29 #include "ux_device_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_device_stack_get_status PORTABLE C */
37 /* 6.1.6 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function obtains the status of a USB component of the device */
45 /* such as device or endpoint. */
46 /* */
47 /* INPUT */
48 /* */
49 /* request_type Request type */
50 /* request_index Request index */
51 /* request_length Request length */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* Completion Status */
56 /* */
57 /* CALLS */
58 /* */
59 /* _ux_device_stack_transfer_request Transfer request */
60 /* (ux_slave_dcd_function) DCD dispatch function */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Device Stack */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
71 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* 04-02-2021 Chaoqiong Xiao Modified comment(s), */
74 /* supported bi-dir-endpoints, */
75 /* resulting in version 6.1.6 */
76 /* */
77 /**************************************************************************/
_ux_device_stack_get_status(ULONG request_type,ULONG request_index,ULONG request_length)78 UINT _ux_device_stack_get_status(ULONG request_type, ULONG request_index, ULONG request_length)
79 {
80
81 UX_SLAVE_DCD *dcd;
82 UX_SLAVE_TRANSFER *transfer_request;
83 UX_SLAVE_DEVICE *device;
84 UX_SLAVE_ENDPOINT *endpoint;
85 UINT status;
86 ULONG data_length;
87
88 UX_PARAMETER_NOT_USED(request_length);
89
90 /* If trace is enabled, insert this event into the trace buffer. */
91 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_GET_STATUS, request_type, request_index, request_length, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
92
93 /* Get the pointer to the DCD. */
94 dcd = &_ux_system_slave -> ux_system_slave_dcd;
95
96 /* Get the pointer to the device. */
97 device = &_ux_system_slave -> ux_system_slave_device;
98
99 /* Get the control endpoint for the device. */
100 endpoint = &device -> ux_slave_device_control_endpoint;
101
102 /* Get the pointer to the transfer request associated with the endpoint. */
103 transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
104
105 /* Reset the status buffer. */
106 *transfer_request -> ux_slave_transfer_request_data_pointer = 0;
107 *(transfer_request -> ux_slave_transfer_request_data_pointer + 1) = 0;
108
109 /* The default length for GET_STATUS is 2, except for OTG get Status. */
110 data_length = 2;
111
112 /* The status can be for either the device or the endpoint. */
113 switch (request_type & UX_REQUEST_TARGET)
114 {
115
116 case UX_REQUEST_TARGET_DEVICE:
117
118 /* When the device is probed, it is either for the power/remote capabilities or OTG role swap.
119 We differentiate with the Windex, 0 or OTG status Selector. */
120 if (request_index == UX_OTG_STATUS_SELECTOR)
121 {
122
123 /* Set the data length to 1. */
124 data_length = 1;
125
126 #ifdef UX_OTG_SUPPORT
127 /* Store the Role Swap flag. */
128 *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_otg -> ux_system_otg_slave_role_swap_flag;
129 #endif
130
131 }
132 else
133 {
134
135 /* Store the current power state in the status buffer. */
136 if (_ux_system_slave -> ux_system_slave_power_state == UX_DEVICE_SELF_POWERED)
137 *transfer_request -> ux_slave_transfer_request_data_pointer = 1;
138
139 /* Store the remote wakeup capability state in the status buffer. */
140
141 if (_ux_system_slave -> ux_system_slave_remote_wakeup_enabled)
142 *transfer_request -> ux_slave_transfer_request_data_pointer |= 2;
143 }
144
145 break;
146
147 case UX_REQUEST_TARGET_ENDPOINT:
148
149 #ifndef UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT
150
151 /* This feature returns the halt state of a specific endpoint. The endpoint index
152 is used to retrieve the endpoint container. */
153 status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_ENDPOINT_STATUS, (VOID *)(ALIGN_TYPE)(request_index & (UINT)~UX_ENDPOINT_DIRECTION));
154 #else
155
156 /* This feature returns the halt state of a specific endpoint. The endpoint address
157 is used to retrieve the endpoint container. */
158 status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_ENDPOINT_STATUS, (VOID *)(ALIGN_TYPE)(request_index));
159 #endif
160
161 /* Check the status. We may have a unknown endpoint. */
162 if (status != UX_ERROR)
163 {
164
165 if (status == UX_TRUE)
166 *transfer_request -> ux_slave_transfer_request_data_pointer = 1;
167 }
168 else
169 {
170
171 /* We stall the command. Endpoint is wrong. */
172 dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
173
174 /* No more work to do here. The command failed but the upper layer does not depend on it. */
175 return(UX_SUCCESS);
176 }
177 break;
178
179 default:
180
181 /* We stall the command. */
182 dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
183
184 /* No more work to do here. The command failed but the upper layer does not depend on it. */
185 return(UX_SUCCESS);
186 }
187
188 /* Set the phase of the transfer to data out. */
189 transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
190
191 /* Send the descriptor with the appropriate length to the host. */
192 status = _ux_device_stack_transfer_request(transfer_request, data_length, data_length);
193
194 /* Return the function status. */
195 return(status);
196 }
197
198