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 /** USBX Component */
15 /** */
16 /** Device DPUMP Class */
17 /** */
18 /**************************************************************************/
19 /**************************************************************************/
20
21 #define UX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "ux_api.h"
27 #include "ux_device_class_dpump.h"
28 #include "ux_device_stack.h"
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _ux_device_class_dpump_change PORTABLE C */
36 /* 6.1.12 */
37 /* AUTHOR */
38 /* */
39 /* Chaoqiong Xiao, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function changes the interface of the DPUMP device */
44 /* */
45 /* INPUT */
46 /* */
47 /* command Pointer to dpump command */
48 /* */
49 /* OUTPUT */
50 /* */
51 /* Completion Status */
52 /* */
53 /* CALLS */
54 /* */
55 /* _ux_utility_memory_set Set memory */
56 /* _ux_device_stack_transfer_all_request_abort */
57 /* Abort request */
58 /* */
59 /* CALLED BY */
60 /* */
61 /* USBX Source Code */
62 /* */
63 /* RELEASE HISTORY */
64 /* */
65 /* DATE NAME DESCRIPTION */
66 /* */
67 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
68 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
69 /* verified memset and memcpy */
70 /* cases, */
71 /* resulting in version 6.1 */
72 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
73 /* added standalone support, */
74 /* resulting in version 6.1.10 */
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_class_dpump_change(UX_SLAVE_CLASS_COMMAND * command)81 UINT _ux_device_class_dpump_change(UX_SLAVE_CLASS_COMMAND *command)
82 {
83
84 UX_SLAVE_INTERFACE *interface_ptr;
85 UX_SLAVE_CLASS *class_ptr;
86 UX_SLAVE_CLASS_DPUMP *dpump;
87 UX_SLAVE_ENDPOINT *endpoint;
88
89 /* Get the class container. */
90 class_ptr = command -> ux_slave_class_command_class_ptr;
91
92 /* Get the class instance in the container. */
93 dpump = (UX_SLAVE_CLASS_DPUMP *) class_ptr -> ux_slave_class_instance;
94
95 /* Get the interface that owns this instance. */
96 interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface;
97
98 /* Locate the endpoints. Control and Bulk in/out for data. */
99 endpoint = interface_ptr -> ux_slave_interface_first_endpoint;
100
101 /* Keep the alternate setting in the dpump structure. */
102 dpump -> ux_slave_class_dpump_alternate_setting = interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting;
103
104 /* If the interface to mount has a non zero alternate setting, the class is really active with
105 the endpoints active. If the interface reverts to alternate setting 0, it needs to have
106 the pending transactions terminated. */
107 if (interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting != 0)
108 {
109
110 /* Parse all endpoints. */
111 while (endpoint != UX_NULL)
112 {
113
114 /* Check the endpoint direction, and type. */
115 if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN)
116 {
117
118 /* Look at type. */
119 if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
120
121 /* We have found the bulk in endpoint, save it. */
122 dpump -> ux_slave_class_dpump_bulkin_endpoint = endpoint;
123
124 }
125 else
126 {
127 /* Look at type for out endpoint. */
128 if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
129
130 /* We have found the bulk out endpoint, save it. */
131 dpump -> ux_slave_class_dpump_bulkout_endpoint = endpoint;
132 }
133
134 /* Next endpoint. */
135 endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
136 }
137
138
139 /* Now check if all endpoints have been found. */
140 if (dpump -> ux_slave_class_dpump_bulkout_endpoint == UX_NULL || dpump -> ux_slave_class_dpump_bulkin_endpoint == UX_NULL)
141
142 /* Not all endpoints have been found. Major error, do not proceed. */
143 return(UX_ERROR);
144
145 /* Reset the endpoint buffers. */
146 _ux_utility_memory_set(dpump -> ux_slave_class_dpump_bulkout_endpoint -> ux_slave_endpoint_transfer_request.
147 ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */
148 _ux_utility_memory_set(dpump -> ux_slave_class_dpump_bulkin_endpoint -> ux_slave_endpoint_transfer_request.
149 ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */
150
151 /* Keep the alternate setting in the dpump structure. */
152 dpump -> ux_slave_class_dpump_alternate_setting = interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting;
153
154 #if defined(UX_DEVICE_STANDALONE)
155
156 /* Reset read/write states. */
157 dpump -> ux_device_class_dpump_read_state = 0;
158 dpump -> ux_device_class_dpump_write_state = 0;
159 #endif
160
161 /* If there is an activate function call it. */
162 if (dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate != UX_NULL)
163
164 /* Invoke the application. */
165 dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate(dpump);
166 }
167 else
168 {
169
170 /* In this case, we are reverting to the Alternate Setting 0. We need to terminate the pending transactions. */
171 /* Terminate the transactions pending on the endpoints (bulk in, bulk out). */
172 _ux_device_stack_transfer_all_request_abort(dpump -> ux_slave_class_dpump_bulkin_endpoint, UX_TRANSFER_APPLICATION_RESET);
173 _ux_device_stack_transfer_all_request_abort(dpump -> ux_slave_class_dpump_bulkout_endpoint, UX_TRANSFER_APPLICATION_RESET);
174
175 }
176
177 /* If trace is enabled, insert this event into the trace buffer. */
178 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_DPUMP_CHANGE, dpump, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
179
180 /* If trace is enabled, register this object. */
181 UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, dpump, 0, 0, 0)
182
183 /* Return completion status. */
184 return(UX_SUCCESS);
185 }
186
187