1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** PIMA Class */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28 #include "ux_host_class_pima.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_pima_object_handles_get PORTABLE C */
37 /* 6.1.12 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function gets a list if the current valid Storage IDS. There */
45 /* is one Storage ID for each valid logical store. */
46 /* */
47 /* INPUT */
48 /* */
49 /* pima Pointer to pima class */
50 /* pima_session Pointer to pima session */
51 /* object_handles_array Pointer to store handles */
52 /* object_handles_length Array length in handles */
53 /* object_format_code Object Format Code */
54 /* object_handle_association Object Handle */
55 /* Association */
56 /* */
57 /* The 2 last parameter are optional and should be set to 0 if not */
58 /* used. */
59 /* */
60 /* OUTPUT */
61 /* */
62 /* Completion Status */
63 /* */
64 /* CALLS */
65 /* */
66 /* _ux_host_class_pima_command Pima command function */
67 /* _ux_utility_long_get Get 32 bit value */
68 /* _ux_utility_memory_allocate Allocate some memory */
69 /* _ux_utility_memory_free Free some memory */
70 /* */
71 /* CALLED BY */
72 /* */
73 /* USB application */
74 /* */
75 /* RELEASE HISTORY */
76 /* */
77 /* DATE NAME DESCRIPTION */
78 /* */
79 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
80 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
81 /* resulting in version 6.1 */
82 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
83 /* improved num objects check, */
84 /* resulting in version 6.1.12 */
85 /* */
86 /**************************************************************************/
_ux_host_class_pima_object_handles_get(UX_HOST_CLASS_PIMA * pima,UX_HOST_CLASS_PIMA_SESSION * pima_session,ULONG * object_handles_array,ULONG object_handles_length,ULONG storage_id,ULONG object_format_code,ULONG object_handle_association)87 UINT _ux_host_class_pima_object_handles_get(UX_HOST_CLASS_PIMA *pima, UX_HOST_CLASS_PIMA_SESSION *pima_session,
88 ULONG *object_handles_array, ULONG object_handles_length,
89 ULONG storage_id, ULONG object_format_code, ULONG object_handle_association)
90 {
91
92 UX_HOST_CLASS_PIMA_COMMAND command;
93 UCHAR *object_handles_array_raw;
94 ULONG object_handle_length_raw;
95 ULONG count_object_handles;
96 ULONG nb_object_handles;
97 UINT status;
98
99 /* Check if this session is valid or not. */
100 if (pima_session -> ux_host_class_pima_session_magic != UX_HOST_CLASS_PIMA_MAGIC_NUMBER)
101 return (UX_HOST_CLASS_PIMA_RC_SESSION_NOT_OPEN);
102
103 /* Check if this session is opened or not. */
104 if (pima_session -> ux_host_class_pima_session_state != UX_HOST_CLASS_PIMA_SESSION_STATE_OPENED)
105 return (UX_HOST_CLASS_PIMA_RC_SESSION_NOT_OPEN);
106
107 /* Check the number of handles and compare with the size of the array given by the user. */
108 if (pima_session -> ux_host_class_pima_session_nb_objects > object_handles_length)
109 return(UX_MEMORY_INSUFFICIENT);
110
111 /* Issue command to get the storage IDs. 3 parameters. */
112 command.ux_host_class_pima_command_nb_parameters = 3;
113
114 /* Parameter 1 is the Storage ID. */
115 command.ux_host_class_pima_command_parameter_1 = storage_id;
116
117 /* Parameter 2 is optional. It is the Object Format Code. */
118 command.ux_host_class_pima_command_parameter_2 = object_format_code;
119
120 /* Parameter 3 is optional. It is the object handle association. */
121 command.ux_host_class_pima_command_parameter_3 = object_handle_association;
122
123 /* Other parameters unused. */
124 command.ux_host_class_pima_command_parameter_4 = 0;
125 command.ux_host_class_pima_command_parameter_5 = 0;
126
127 /* Then set the command to GET_STORAGE_IDS. */
128 command.ux_host_class_pima_command_operation_code = UX_HOST_CLASS_PIMA_OC_GET_OBJECT_HANDLES;
129
130 /* Calculate the length the raw array. We multiply the number of handles by the size on the handle and
131 add a ULONG for the number of handles stored at the beginning of the array. */
132 status = UX_SUCCESS;
133 object_handle_length_raw = 0;
134 UX_UTILITY_ADD_SAFE(pima_session -> ux_host_class_pima_session_nb_objects, 1, object_handle_length_raw, status);
135 if (status != UX_SUCCESS)
136 return(status);
137 UX_UTILITY_MULC_SAFE(object_handle_length_raw, (ULONG)sizeof(ULONG), object_handle_length_raw, status);
138 if (status != UX_SUCCESS)
139 return(status);
140
141 /* Allocate some DMA safe memory for receiving the handles */
142 object_handles_array_raw = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, object_handle_length_raw);
143 if (object_handles_array_raw == UX_NULL)
144 return(UX_MEMORY_INSUFFICIENT);
145
146 /* Issue the command. */
147 status = _ux_host_class_pima_command(pima, &command, UX_HOST_CLASS_PIMA_DATA_PHASE_IN , object_handles_array_raw,
148 object_handle_length_raw, object_handle_length_raw);
149
150 /* Check the result. If OK, the object handles array is returned properly. */
151 if (status == UX_SUCCESS)
152 {
153
154 /* Read the number of Object handles in the returned array. */
155 nb_object_handles = _ux_utility_long_get(object_handles_array_raw);
156
157 /* Save the number of object handles. */
158 pima_session -> ux_host_class_pima_session_nb_objects = nb_object_handles;
159
160 /* Check if the user gave us enough memory. */
161 if (nb_object_handles > object_handles_length)
162
163 /* No, not enough memory to store the array. */
164 return(UX_MEMORY_INSUFFICIENT);
165
166 /* Unpack all object handles. */
167 for(count_object_handles = 0; count_object_handles < nb_object_handles; count_object_handles++)
168
169 /* Unpack one object handle at a time */
170 *(object_handles_array + count_object_handles) = _ux_utility_long_get(object_handles_array_raw + sizeof(ULONG) +
171 (count_object_handles * sizeof(ULONG)));
172 }
173
174 /* Free the original raw array. */
175 _ux_utility_memory_free(object_handles_array_raw);
176
177 /* Return completion status. */
178 return(status);
179 }
180
181 /**************************************************************************/
182 /* */
183 /* FUNCTION RELEASE */
184 /* */
185 /* _uxe_host_class_pima_object_handles_get PORTABLE C */
186 /* 6.3.0 */
187 /* AUTHOR */
188 /* */
189 /* Yajun Xia, Microsoft Corporation */
190 /* */
191 /* DESCRIPTION */
192 /* */
193 /* This function checks errors in pima object handles get function */
194 /* call. */
195 /* */
196 /* INPUT */
197 /* */
198 /* pima Pointer to pima class */
199 /* pima_session Pointer to pima session */
200 /* object_handles_array Pointer to store handles */
201 /* object_handles_length Array length in handles */
202 /* object_format_code Object Format Code */
203 /* object_handle_association Object Handle */
204 /* Association */
205 /* */
206 /* The 2 last parameter are optional and should be set to 0 if not */
207 /* used. */
208 /* */
209 /* OUTPUT */
210 /* */
211 /* Completion Status */
212 /* */
213 /* CALLS */
214 /* */
215 /* _ux_host_class_pima_object_handles_get Get object handles */
216 /* */
217 /* CALLED BY */
218 /* */
219 /* USB application */
220 /* */
221 /* RELEASE HISTORY */
222 /* */
223 /* DATE NAME DESCRIPTION */
224 /* */
225 /* 10-31-2023 Yajun xia Initial Version 6.3.0 */
226 /* */
227 /**************************************************************************/
_uxe_host_class_pima_object_handles_get(UX_HOST_CLASS_PIMA * pima,UX_HOST_CLASS_PIMA_SESSION * pima_session,ULONG * object_handles_array,ULONG object_handles_length,ULONG storage_id,ULONG object_format_code,ULONG object_handle_association)228 UINT _uxe_host_class_pima_object_handles_get(UX_HOST_CLASS_PIMA *pima, UX_HOST_CLASS_PIMA_SESSION *pima_session,
229 ULONG *object_handles_array, ULONG object_handles_length,
230 ULONG storage_id, ULONG object_format_code, ULONG object_handle_association)
231 {
232
233 /* Sanity checks. */
234 if ((pima == UX_NULL) || (pima_session == UX_NULL) || (object_handles_array == UX_NULL) || (object_handles_length == 0))
235 return(UX_INVALID_PARAMETER);
236
237 /* Call the actual function. */
238 return(_ux_host_class_pima_object_handles_get(pima, pima_session, object_handles_array, object_handles_length,
239 storage_id, object_format_code, object_handle_association));
240 }