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 CCID 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_ccid.h"
28 #include "ux_device_stack.h"
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _ux_device_class_ccid_activate PORTABLE C */
36 /* 6.3.0 */
37 /* AUTHOR */
38 /* */
39 /* Chaoqiong Xiao, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function activates the USB CCID device. */
44 /* */
45 /* INPUT */
46 /* */
47 /* command Pointer to ccid command */
48 /* */
49 /* OUTPUT */
50 /* */
51 /* Completion Status */
52 /* */
53 /* CALLS */
54 /* */
55 /* None */
56 /* */
57 /* CALLED BY */
58 /* */
59 /* USBX Device CCID */
60 /* */
61 /* RELEASE HISTORY */
62 /* */
63 /* DATE NAME DESCRIPTION */
64 /* */
65 /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
66 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
67 /* fixed parameter/variable */
68 /* names conflict C++ keyword, */
69 /* resulting in version 6.1.12 */
70 /* 03-08-2023 Chaoqiong Xiao Modified comment(s), */
71 /* added standalone support, */
72 /* resulting in version 6.2.1 */
73 /* 10-31-2023 Chaoqiong Xiao Modified comment(s), */
74 /* added a new mode to manage */
75 /* endpoint buffer in classes, */
76 /* resulting in version 6.3.0 */
77 /* */
78 /**************************************************************************/
_ux_device_class_ccid_activate(UX_SLAVE_CLASS_COMMAND * command)79 UINT _ux_device_class_ccid_activate(UX_SLAVE_CLASS_COMMAND *command)
80 {
81
82 UX_SLAVE_INTERFACE *ccid_interface;
83 UX_SLAVE_CLASS *ccid_class;
84 UX_DEVICE_CLASS_CCID *ccid;
85 UX_SLAVE_ENDPOINT *endpoint;
86 ULONG endpoint_type;
87 #if !defined(UX_DEVICE_STANDALONE)
88 UINT i;
89 #endif
90
91 /* Get the class container. */
92 ccid_class = command -> ux_slave_class_command_class_ptr;
93
94 /* Get the class instance in the container. */
95 ccid = (UX_DEVICE_CLASS_CCID *) ccid_class -> ux_slave_class_instance;
96
97 /* Get the interface that owns this instance. */
98 ccid_interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface;
99
100 /* Store the class instance into the interface. */
101 ccid_interface -> ux_slave_interface_class_instance = (VOID *)ccid;
102
103 /* Now the opposite, store the interface in the class instance. */
104 ccid -> ux_device_class_ccid_interface = ccid_interface;
105
106 /* Save endpoints. */
107 ccid -> ux_device_class_ccid_endpoint_notify = UX_NULL;
108 endpoint = ccid_interface -> ux_slave_interface_first_endpoint;
109 while(endpoint)
110 {
111 endpoint_type = endpoint -> ux_slave_endpoint_descriptor.bmAttributes;
112 endpoint_type &= UX_MASK_ENDPOINT_TYPE;
113 if (endpoint_type == UX_INTERRUPT_ENDPOINT)
114 {
115 ccid -> ux_device_class_ccid_endpoint_notify = endpoint;
116 #if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
117 endpoint -> ux_slave_endpoint_transfer_request.
118 ux_slave_transfer_request_data_pointer =
119 UX_DEVICE_CLASS_CCID_INTERRUPTIN_BUFFER(ccid);
120 #endif
121 }
122 if (endpoint_type == UX_BULK_ENDPOINT)
123 {
124 if (endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_IN)
125 {
126 ccid -> ux_device_class_ccid_endpoint_in = 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_CCID_BULKIN_BUFFER(ccid);
131 #endif
132 }
133 else
134 {
135 ccid -> ux_device_class_ccid_endpoint_out = endpoint;
136 #if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1
137 endpoint -> ux_slave_endpoint_transfer_request.
138 ux_slave_transfer_request_data_pointer =
139 UX_DEVICE_CLASS_CCID_BULKOUT_BUFFER(ccid);
140 #endif
141 }
142 }
143 endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
144 }
145
146 #if defined(UX_DEVICE_STANDALONE)
147
148 /* Initialize slots (optimized for 1 slot). */
149 ccid -> ux_device_class_ccid_slots -> ux_device_class_ccid_slot_runner = -1;
150 ccid -> ux_device_class_ccid_slots -> ux_device_class_ccid_slot_icc_status =
151 UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT;
152
153 /* Initialize task states. */
154 ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_START;
155 ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_IDLE;
156 ccid -> ux_device_class_ccid_notify_state = UX_DEVICE_CLASS_CCID_NOTIFY_IDLE;
157
158 /* Initialize runner task state (optimized for 1 slot). */
159 ccid -> ux_device_class_ccid_runners -> ux_device_class_ccid_runner_state = UX_DEVICE_CLASS_CCID_RUNNER_IDLE;
160 #else
161
162 /* Initialize slots. */
163 for (i = 0;
164 i < ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_slots;
165 i ++)
166 {
167 ccid -> ux_device_class_ccid_slots[i].ux_device_class_ccid_slot_runner = -1;
168 ccid -> ux_device_class_ccid_slots[i].ux_device_class_ccid_slot_icc_status =
169 UX_DEVICE_CLASS_CCID_ICC_NOT_PRESENT;
170 }
171
172 /* Activate thread for Bulk-OUT command messages. */
173 _ux_device_thread_resume(&ccid -> ux_device_class_ccid_thread);
174
175 /* Activate thread for Interrupt-IN notification messages. */
176 _ux_device_thread_resume(&ccid -> ux_device_class_ccid_notify_thread);
177
178 /* Activate threads for runners. */
179 for (i = 0;
180 i < ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_max_n_busy_slots;
181 i ++)
182 {
183 _ux_device_thread_resume(&ccid -> ux_device_class_ccid_runners[i].
184 ux_device_class_ccid_runner_thread);
185 }
186 #endif
187
188 /* If there is a activate function call it. */
189 if (ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_instance_activate != UX_NULL)
190 {
191
192 /* Invoke the application callback. */
193 ccid -> ux_device_class_ccid_parameter.ux_device_class_ccid_instance_activate(ccid);
194 }
195
196 /* If trace is enabled, insert this event into the trace buffer. */
197 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CCID_ACTIVATE, ccid, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
198
199 /* If trace is enabled, register this object. */
200 UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, ccid, 0, 0, 0)
201
202 /* Return completion status. */
203 return(UX_SUCCESS);
204 }
205