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.3.0        */
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 /*  10-31-2023     Chaoqiong Xiao           Modified comment(s),          */
80 /*                                            added a new mode to manage  */
81 /*                                            endpoint buffer in classes, */
82 /*                                            resulting in version 6.3.0  */
83 /*                                                                        */
84 /**************************************************************************/
_ux_device_class_dpump_change(UX_SLAVE_CLASS_COMMAND * command)85 UINT  _ux_device_class_dpump_change(UX_SLAVE_CLASS_COMMAND *command)
86 {
87 
88 UX_SLAVE_INTERFACE                      *interface_ptr;
89 UX_SLAVE_CLASS                          *class_ptr;
90 UX_SLAVE_CLASS_DPUMP                    *dpump;
91 UX_SLAVE_ENDPOINT                       *endpoint;
92 
93     /* Get the class container.  */
94     class_ptr =  command -> ux_slave_class_command_class_ptr;
95 
96     /* Get the class instance in the container.  */
97     dpump = (UX_SLAVE_CLASS_DPUMP *) class_ptr -> ux_slave_class_instance;
98 
99     /* Get the interface that owns this instance.  */
100     interface_ptr =  (UX_SLAVE_INTERFACE  *) command -> ux_slave_class_command_interface;
101 
102     /* Locate the endpoints.  Control and Bulk in/out for data.  */
103     endpoint =  interface_ptr -> ux_slave_interface_first_endpoint;
104 
105     /* Keep the alternate setting in the dpump structure. */
106     dpump -> ux_slave_class_dpump_alternate_setting =  interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting;
107 
108     /* If the interface to mount has a non zero alternate setting, the class is really active with
109        the endpoints active.  If the interface reverts to alternate setting 0, it needs to have
110        the pending transactions terminated.  */
111     if (interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting != 0)
112     {
113 
114         /* Parse all endpoints.  */
115         while (endpoint != UX_NULL)
116         {
117 
118             /* Check the endpoint direction, and type.  */
119             if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN)
120             {
121 
122                 /* Look at type.  */
123                 if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
124 
125                     /* We have found the bulk in endpoint, save it.  */
126                     dpump -> ux_slave_class_dpump_bulkin_endpoint =  endpoint;
127 #if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
128                     endpoint -> ux_slave_endpoint_transfer_request.
129                             ux_slave_transfer_request_data_pointer =
130                                     UX_DEVICE_CLASS_DPUMP_WRITE_BUFFER(dpump);
131 #endif
132             }
133             else
134             {
135                 /* Look at type for out endpoint.  */
136                 if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
137 
138                     /* We have found the bulk out endpoint, save it.  */
139                     dpump -> ux_slave_class_dpump_bulkout_endpoint =  endpoint;
140 #if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
141                     endpoint -> ux_slave_endpoint_transfer_request.
142                             ux_slave_transfer_request_data_pointer =
143                                     UX_DEVICE_CLASS_DPUMP_READ_BUFFER(dpump);
144 #endif
145             }
146 
147             /* Next endpoint.  */
148             endpoint =  endpoint -> ux_slave_endpoint_next_endpoint;
149         }
150 
151 
152         /* Now check if all endpoints have been found.  */
153         if (dpump -> ux_slave_class_dpump_bulkout_endpoint == UX_NULL || dpump -> ux_slave_class_dpump_bulkin_endpoint == UX_NULL)
154 
155             /* Not all endpoints have been found. Major error, do not proceed.  */
156             return(UX_ERROR);
157 
158         /* Reset the endpoint buffers.  */
159         _ux_utility_memory_set(dpump -> ux_slave_class_dpump_bulkout_endpoint -> ux_slave_endpoint_transfer_request.
160                                         ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */
161         _ux_utility_memory_set(dpump -> ux_slave_class_dpump_bulkin_endpoint -> ux_slave_endpoint_transfer_request.
162                                         ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH); /* Use case of memset is verified. */
163 
164         /* Keep the alternate setting in the dpump structure. */
165         dpump -> ux_slave_class_dpump_alternate_setting =  interface_ptr -> ux_slave_interface_descriptor.bAlternateSetting;
166 
167 #if defined(UX_DEVICE_STANDALONE)
168 
169         /* Reset read/write states.  */
170         dpump -> ux_device_class_dpump_read_state = 0;
171         dpump -> ux_device_class_dpump_write_state = 0;
172 #endif
173 
174         /* If there is an activate function call it.  */
175         if (dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate != UX_NULL)
176 
177             /* Invoke the application.  */
178             dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate(dpump);
179     }
180     else
181     {
182 
183         /* In this case, we are reverting to the Alternate Setting 0.  We need to terminate the pending transactions.  */
184         /* Terminate the transactions pending on the endpoints (bulk in, bulk out).  */
185         _ux_device_stack_transfer_all_request_abort(dpump -> ux_slave_class_dpump_bulkin_endpoint, UX_TRANSFER_APPLICATION_RESET);
186         _ux_device_stack_transfer_all_request_abort(dpump -> ux_slave_class_dpump_bulkout_endpoint, UX_TRANSFER_APPLICATION_RESET);
187 
188     }
189 
190     /* If trace is enabled, insert this event into the trace buffer.  */
191     UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_DPUMP_CHANGE, dpump, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
192 
193     /* If trace is enabled, register this object.  */
194     UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, dpump, 0, 0, 0)
195 
196     /* Return completion status.  */
197     return(UX_SUCCESS);
198 }
199 
200