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 /** Utility */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28
29
30 /**************************************************************************/
31 /* */
32 /* FUNCTION RELEASE */
33 /* */
34 /* _ux_utility_descriptor_parse PORTABLE C */
35 /* 6.3.0 */
36 /* AUTHOR */
37 /* */
38 /* Chaoqiong Xiao, Microsoft Corporation */
39 /* */
40 /* DESCRIPTION */
41 /* */
42 /* This function will unpack a USB descriptor from the bus into a */
43 /* memory aligned structure. */
44 /* */
45 /* INPUT */
46 /* */
47 /* raw_descriptor Pointer to packed descriptor */
48 /* descriptor_structure Components of the descriptor */
49 /* descriptor_entries Number of entries in the */
50 /* descriptor */
51 /* descriptor Pointer to the unpacked */
52 /* descriptor */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* None */
57 /* */
58 /* CALLS */
59 /* */
60 /* _ux_utility_long_get Get 32-bit value */
61 /* _ux_utility_short_get Get 16-bit value */
62 /* */
63 /* CALLED BY */
64 /* */
65 /* USBX Components */
66 /* */
67 /* RELEASE HISTORY */
68 /* */
69 /* DATE NAME DESCRIPTION */
70 /* */
71 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
72 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
73 /* resulting in version 6.1 */
74 /* 10-31-2023 Chaoqiong Xiao Modified comment(s), */
75 /* optimized USB descriptors, */
76 /* resulting in version 6.3.0 */
77 /* */
78 /**************************************************************************/
_ux_utility_descriptor_parse(UCHAR * raw_descriptor,UCHAR * descriptor_structure,UINT descriptor_entries,UCHAR * descriptor)79 VOID _ux_utility_descriptor_parse(UCHAR * raw_descriptor, UCHAR * descriptor_structure,
80 UINT descriptor_entries, UCHAR * descriptor)
81 {
82
83 /* Loop on all the entries in this descriptor. */
84 while(descriptor_entries--)
85 {
86
87 /* Get the length of that component. */
88 switch(*descriptor_structure++)
89 {
90
91 /* Check the size then build the component from the source and
92 insert it into the target descriptor. */
93 case 4:
94
95 /* Padding zeros so address is aligned. */
96 while((ALIGN_TYPE) descriptor & 3u)
97 *descriptor++ = 0;
98
99 /* Save the DW. */
100 *((ULONG *) descriptor) = _ux_utility_long_get(raw_descriptor);
101 raw_descriptor += 4;
102 descriptor += 4;
103 break;
104
105 case 2:
106
107 /* Padding zeros so address is aligned. */
108 while((ALIGN_TYPE) descriptor & 1u)
109 *descriptor++ = 0;
110
111 /* Save the word. */
112 *((USHORT *) descriptor) = (USHORT) _ux_utility_short_get(raw_descriptor);
113 raw_descriptor += 2;
114 descriptor += 2;
115 break;
116
117 default:
118
119 /* Save the byte. */
120 *((UCHAR *) descriptor) = (UCHAR) *raw_descriptor;
121 raw_descriptor++;
122 descriptor ++;
123 }
124 }
125
126 /* Return to caller. */
127 return;
128 }
129
130 /**************************************************************************/
131 /* */
132 /* FUNCTION RELEASE */
133 /* */
134 /* _ux_utility_descriptor_parse_size PORTABLE C */
135 /* 6.3.0 */
136 /* AUTHOR */
137 /* */
138 /* Chaoqiong Xiao, Microsoft Corporation */
139 /* */
140 /* DESCRIPTION */
141 /* */
142 /* This function will calculate the size of a parsed USB descriptor. */
143 /* */
144 /* INPUT */
145 /* */
146 /* descriptor_structure Components of the descriptor */
147 /* descriptor_entries Number of entries in the */
148 /* descriptor */
149 /* size_align_mask Size alignment mask */
150 /* */
151 /* OUTPUT */
152 /* */
153 /* size Size of the parsed descriptor */
154 /* */
155 /* CALLS */
156 /* */
157 /* None */
158 /* */
159 /* CALLED BY */
160 /* */
161 /* USBX Components */
162 /* */
163 /* RELEASE HISTORY */
164 /* */
165 /* DATE NAME DESCRIPTION */
166 /* */
167 /* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */
168 /* */
169 /**************************************************************************/
_ux_utility_descriptor_parse_size(UCHAR * descriptor_structure,UINT descriptor_entries,UINT size_align_mask)170 ULONG _ux_utility_descriptor_parse_size(UCHAR * descriptor_structure, UINT descriptor_entries, UINT size_align_mask)
171 {
172
173 ULONG size = 0;
174 ULONG entry_size;
175
176 /* Loop on all the entries in this descriptor. */
177 while(descriptor_entries--)
178 {
179
180 /* Get entry size. */
181 entry_size = (ULONG)*descriptor_structure ++;
182
183 /* Check the size then build the component from the source and
184 insert it into the target descriptor. */
185 switch(entry_size)
186 {
187
188 case 4: /* Fall through. */
189 case 2:
190
191 /* Padding zeros so address is aligned. */
192 while(size & (entry_size - 1))
193 size++;
194
195 /* Add to the size. */
196 size += entry_size;
197 break;
198
199 case 1:
200
201 /* Add to the size. */
202 size += 1;
203 break;
204
205 default:
206
207 /* Invalid entry size. */
208 return(0);
209 }
210 }
211
212 /* Align the size. */
213 size = (size + size_align_mask) & (~size_align_mask);
214
215 /* Return the size. */
216 return(size);
217 }
218