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 /**************************************************************************/
15 /** */
16 /** USBX Component */
17 /** */
18 /** PIMA Class */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23
24 /* Include necessary system files. */
25
26 #define UX_SOURCE_CODE
27
28 #include "ux_api.h"
29 #include "ux_host_class_pima.h"
30 #include "ux_host_stack.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _ux_host_class_pima_object_handles_get PORTABLE C */
38 /* 6.1.12 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function gets a list if the current valid Storage IDS. There */
46 /* is one Storage ID for each valid logical store. */
47 /* */
48 /* INPUT */
49 /* */
50 /* pima Pointer to pima class */
51 /* pima_session Pointer to pima session */
52 /* object_handles_array Pointer to store handles */
53 /* object_handles_length Array length in handles */
54 /* object_format_code Object Format Code */
55 /* object_handle_association Object Handle */
56 /* Association */
57 /* */
58 /* The 2 last parameter are optional and should be set to 0 if not */
59 /* used. */
60 /* */
61 /* OUTPUT */
62 /* */
63 /* Completion Status */
64 /* */
65 /* CALLS */
66 /* */
67 /* _ux_host_class_pima_command Pima command function */
68 /* _ux_utility_long_get Get 32 bit value */
69 /* _ux_utility_memory_allocate Allocate some memory */
70 /* _ux_utility_memory_free Free some memory */
71 /* */
72 /* CALLED BY */
73 /* */
74 /* USB application */
75 /* */
76 /* RELEASE HISTORY */
77 /* */
78 /* DATE NAME DESCRIPTION */
79 /* */
80 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
81 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
82 /* resulting in version 6.1 */
83 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
84 /* improved num objects check, */
85 /* resulting in version 6.1.12 */
86 /* */
87 /**************************************************************************/
_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)88 UINT _ux_host_class_pima_object_handles_get(UX_HOST_CLASS_PIMA *pima, UX_HOST_CLASS_PIMA_SESSION *pima_session,
89 ULONG *object_handles_array, ULONG object_handles_length,
90 ULONG storage_id, ULONG object_format_code, ULONG object_handle_association)
91 {
92
93 UX_HOST_CLASS_PIMA_COMMAND command;
94 UCHAR *object_handles_array_raw;
95 ULONG object_handle_length_raw;
96 ULONG count_object_handles;
97 ULONG nb_object_handles;
98 UINT status;
99
100 /* Check if this session is valid or not. */
101 if (pima_session -> ux_host_class_pima_session_magic != UX_HOST_CLASS_PIMA_MAGIC_NUMBER)
102 return (UX_HOST_CLASS_PIMA_RC_SESSION_NOT_OPEN);
103
104 /* Check if this session is opened or not. */
105 if (pima_session -> ux_host_class_pima_session_state != UX_HOST_CLASS_PIMA_SESSION_STATE_OPENED)
106 return (UX_HOST_CLASS_PIMA_RC_SESSION_NOT_OPEN);
107
108 /* Check the number of handles and compare with the size of the array given by the user. */
109 if (pima_session -> ux_host_class_pima_session_nb_objects > object_handles_length)
110 return(UX_MEMORY_INSUFFICIENT);
111
112 /* Issue command to get the storage IDs. 3 parameters. */
113 command.ux_host_class_pima_command_nb_parameters = 3;
114
115 /* Parameter 1 is the Storage ID. */
116 command.ux_host_class_pima_command_parameter_1 = storage_id;
117
118 /* Parameter 2 is optional. It is the Object Format Code. */
119 command.ux_host_class_pima_command_parameter_2 = object_format_code;
120
121 /* Parameter 3 is optional. It is the object handle association. */
122 command.ux_host_class_pima_command_parameter_3 = object_handle_association;
123
124 /* Other parameters unused. */
125 command.ux_host_class_pima_command_parameter_4 = 0;
126 command.ux_host_class_pima_command_parameter_5 = 0;
127
128 /* Then set the command to GET_STORAGE_IDS. */
129 command.ux_host_class_pima_command_operation_code = UX_HOST_CLASS_PIMA_OC_GET_OBJECT_HANDLES;
130
131 /* Calculate the length the raw array. We multiply the number of handles by the size on the handle and
132 add a ULONG for the number of handles stored at the beginning of the array. */
133 status = UX_SUCCESS;
134 object_handle_length_raw = 0;
135 UX_UTILITY_ADD_SAFE(pima_session -> ux_host_class_pima_session_nb_objects, 1, object_handle_length_raw, status);
136 if (status != UX_SUCCESS)
137 return(status);
138 UX_UTILITY_MULC_SAFE(object_handle_length_raw, (ULONG)sizeof(ULONG), object_handle_length_raw, status);
139 if (status != UX_SUCCESS)
140 return(status);
141
142 /* Allocate some DMA safe memory for receiving the handles */
143 object_handles_array_raw = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, object_handle_length_raw);
144 if (object_handles_array_raw == UX_NULL)
145 return(UX_MEMORY_INSUFFICIENT);
146
147 /* Issue the command. */
148 status = _ux_host_class_pima_command(pima, &command, UX_HOST_CLASS_PIMA_DATA_PHASE_IN , object_handles_array_raw,
149 object_handle_length_raw, object_handle_length_raw);
150
151 /* Check the result. If OK, the object handles array is returned properly. */
152 if (status == UX_SUCCESS)
153 {
154
155 /* Read the number of Object handles in the returned array. */
156 nb_object_handles = _ux_utility_long_get(object_handles_array_raw);
157
158 /* Save the number of object handles. */
159 pima_session -> ux_host_class_pima_session_nb_objects = nb_object_handles;
160
161 /* Check if the user gave us enough memory. */
162 if (nb_object_handles > object_handles_length)
163
164 /* No, not enough memory to store the array. */
165 return(UX_MEMORY_INSUFFICIENT);
166
167 /* Unpack all object handles. */
168 for(count_object_handles = 0; count_object_handles < nb_object_handles; count_object_handles++)
169
170 /* Unpack one object handle at a time */
171 *(object_handles_array + count_object_handles) = _ux_utility_long_get(object_handles_array_raw + sizeof(ULONG) +
172 (count_object_handles * sizeof(ULONG)));
173 }
174
175 /* Free the original raw array. */
176 _ux_utility_memory_free(object_handles_array_raw);
177
178 /* Return completion status. */
179 return(status);
180 }
181