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