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_set_feature                        PORTABLE C      */
37 /*                                                           6.1.12       */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Chaoqiong Xiao, Microsoft Corporation                               */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function sets a specific feature (Device, Interface,           */
45 /*    Endpoint ....).                                                     */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    request_type                          Request type                  */
50 /*    request_value                         Request value                 */
51 /*    request_index                         Request index                 */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    Completion Status                                                   */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    (ux_slave_dcd_function)               DCD controller function       */
60 /*                                                                        */
61 /*  CALLED BY                                                             */
62 /*                                                                        */
63 /*    Device Stack                                                        */
64 /*                                                                        */
65 /*  RELEASE HISTORY                                                       */
66 /*                                                                        */
67 /*    DATE              NAME                      DESCRIPTION             */
68 /*                                                                        */
69 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
70 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
71 /*                                            optimized based on compile  */
72 /*                                            definitions, stalled on not */
73 /*                                            supported device requests,  */
74 /*                                            resulting in version 6.1    */
75 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
76 /*                                            fixed parameter/variable    */
77 /*                                            names conflict C++ keyword, */
78 /*                                            resulting in version 6.1.12 */
79 /*                                                                        */
80 /**************************************************************************/
_ux_device_stack_set_feature(ULONG request_type,ULONG request_value,ULONG request_index)81 UINT  _ux_device_stack_set_feature(ULONG request_type, ULONG request_value, ULONG request_index)
82 {
83 
84 UX_SLAVE_DCD            *dcd;
85 UX_SLAVE_DEVICE         *device;
86 UX_SLAVE_INTERFACE      *interface_ptr;
87 UX_SLAVE_ENDPOINT       *endpoint;
88 UX_SLAVE_ENDPOINT       *endpoint_target;
89 
90     UX_PARAMETER_NOT_USED(request_value);
91 
92     /* If trace is enabled, insert this event into the trace buffer.  */
93     UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_SET_FEATURE, request_value, request_index, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
94 
95     /* Get the pointer to the DCD.  */
96     dcd =  &_ux_system_slave -> ux_system_slave_dcd;
97 
98     /* Get the pointer to the device.  */
99     device =  &_ux_system_slave -> ux_system_slave_device;
100 
101     /* Get the control endpoint for the device.  */
102     endpoint =  &device -> ux_slave_device_control_endpoint;
103 
104     /* The feature can be for either the device or the endpoint.  */
105     switch (request_type & UX_REQUEST_TARGET)
106     {
107 
108     case UX_REQUEST_TARGET_DEVICE:
109 
110         /* Check if we have a DEVICE_REMOTE_WAKEUP Feature.  */
111         if (request_value == UX_REQUEST_FEATURE_DEVICE_REMOTE_WAKEUP)
112         {
113 
114             /* Check if we have the capability. */
115             if (_ux_system_slave -> ux_system_slave_remote_wakeup_capability)
116             {
117 
118                 /* Enable the feature. */
119                 _ux_system_slave -> ux_system_slave_remote_wakeup_enabled = UX_TRUE;
120 
121                 /* OK. */
122                 return (UX_SUCCESS);
123             }
124             else
125 
126                 /* Protocol error. */
127                 return (UX_FUNCTION_NOT_SUPPORTED);
128         }
129 
130 #ifdef UX_OTG_SUPPORT
131         /* Check if we have a A_HNP_SUPPORT Feature. This is set when the Host is HNP capable. */
132         if (request_value == UX_OTG_FEATURE_A_HNP_SUPPORT)
133         {
134 
135             /* Store the A_HNP_SUPPORT flag.  */
136             _ux_system_otg -> ux_system_otg_slave_set_feature_flag |= UX_OTG_FEATURE_A_HNP_SUPPORT;
137 
138             /* OK.  */
139             return(UX_SUCCESS);
140         }
141 
142         /* Check if the host asks us to perform HNP.  If also we become the host.  */
143         if (request_value == UX_OTG_FEATURE_B_HNP_ENABLE)
144         {
145 
146             /* The ISR will pick up the suspend event and check if we need to become IDLE or HOST.  */
147             _ux_system_otg -> ux_system_otg_slave_set_feature_flag |= UX_OTG_FEATURE_B_HNP_ENABLE;
148 
149             /* OK.  */
150             return(UX_SUCCESS);
151         }
152 #endif
153 
154         /* Request value not supported.  */
155         return(UX_FUNCTION_NOT_SUPPORTED);
156 
157     case UX_REQUEST_TARGET_ENDPOINT:
158 
159         /* The only set feature for endpoint is ENDPOINT_STALL. This forces
160            the endpoint to the stall situation.
161            We need to find the endpoint through the interface(s). */
162         interface_ptr =  device -> ux_slave_device_first_interface;
163 
164 #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1
165         while (interface_ptr != UX_NULL)
166         {
167 #endif
168             /* Get the first endpoint for this interface.  */
169             endpoint_target =  interface_ptr -> ux_slave_interface_first_endpoint;
170 
171             /* Parse all the endpoints.  */
172             while (endpoint_target != UX_NULL)
173             {
174 
175                 /* Check the endpoint index.  */
176                 if (endpoint_target -> ux_slave_endpoint_descriptor.bEndpointAddress == request_index)
177                 {
178 
179                     /* Stall the endpoint.  */
180                     dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint_target);
181 
182                     /* Return the function status.  */
183                     return(UX_SUCCESS);
184                 }
185 
186                 /* Next endpoint.  */
187                 endpoint_target =  endpoint_target -> ux_slave_endpoint_next_endpoint;
188             }
189 
190 #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE) || UX_MAX_DEVICE_INTERFACES > 1
191             /* Next interface.  */
192             interface_ptr =  interface_ptr -> ux_slave_interface_next_interface;
193         }
194 #endif
195 
196         /* We get here when the endpoint is wrong. Should not happen though.  */
197         /* Intentionally fall through into the default case. */
198         /* fall through */
199     default:
200 
201         /* We stall the command.  */
202         dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
203 
204         /* No more work to do here.  The command failed but the upper layer does not depend on it.  */
205         return(UX_SUCCESS);
206     }
207 }
208