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 /** Host Stack */
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_stack.h"
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _ux_host_stack_hcd_register PORTABLE C */
36 /* 6.1 */
37 /* AUTHOR */
38 /* */
39 /* Chaoqiong Xiao, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function registers a USB controller driver with the USBX stack */
44 /* and invokes the HCD driver's initialization function. */
45 /* */
46 /* Note: The C string of hcd_name must be NULL-terminated and the */
47 /* length of it (without the NULL-terminator itself) must be no larger */
48 /* than UX_MAX_HCD_NAME_LENGTH. */
49 /* */
50 /* INPUT */
51 /* */
52 /* hcd_name Name of HCD to register */
53 /* hcd_entry_function Entry function of HCD driver */
54 /* hcd_param1 Parameter 1 of HCD */
55 /* hcd_param2 Parameter 2 of HCD */
56 /* */
57 /* OUTPUT */
58 /* */
59 /* Completion Status */
60 /* */
61 /* */
62 /* CALLS */
63 /* */
64 /* _ux_utility_string_length_check Check and return C string */
65 /* length if no error */
66 /* _ux_utility_memory_copy Copy name into HCD structure */
67 /* (hcd_init_function) Init function of HCD driver */
68 /* */
69 /* CALLED BY */
70 /* */
71 /* Application */
72 /* */
73 /* RELEASE HISTORY */
74 /* */
75 /* DATE NAME DESCRIPTION */
76 /* */
77 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
78 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
79 /* optimized based on compile */
80 /* definitions, verified */
81 /* memset and memcpy cases, */
82 /* resulting in version 6.1 */
83 /* */
84 /**************************************************************************/
_ux_host_stack_hcd_register(UCHAR * hcd_name,UINT (* hcd_init_function)(struct UX_HCD_STRUCT *),ULONG hcd_param1,ULONG hcd_param2)85 UINT _ux_host_stack_hcd_register(UCHAR *hcd_name,
86 UINT (*hcd_init_function)(struct UX_HCD_STRUCT *), ULONG hcd_param1, ULONG hcd_param2)
87 {
88
89 UX_HCD *hcd;
90 UINT status;
91 #if !defined(UX_NAME_REFERENCED_BY_POINTER)
92 UINT hcd_name_length = 0;
93 #endif
94 #if UX_MAX_HCD > 1
95 ULONG hcd_index;
96 #endif
97
98
99
100 /* If trace is enabled, insert this event into the trace buffer. */
101 UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_HCD_REGISTER, hcd_name, hcd_param1, hcd_param2, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
102
103 #if !defined(UX_NAME_REFERENCED_BY_POINTER)
104 /* Get the length of the class name (exclude null-terminator). */
105 status = _ux_utility_string_length_check(hcd_name, &hcd_name_length, UX_MAX_HCD_NAME_LENGTH);
106 if (status)
107 return(status);
108 #endif
109
110 /* Get HCD. */
111 hcd = _ux_system_host -> ux_system_host_hcd_array;
112
113 #if UX_MAX_HCD > 1
114 /* We need to parse the controller driver table to find an empty spot. */
115 for(hcd_index = 0; hcd_index < _ux_system_host -> ux_system_host_max_hcd; hcd_index++)
116 {
117 #endif
118
119 /* Is this slot available? */
120 if(hcd -> ux_hcd_status == UX_UNUSED)
121 {
122
123 /* Yes, setup the new HCD entry. */
124
125 #if defined(UX_NAME_REFERENCED_BY_POINTER)
126 hcd -> ux_hcd_name = (const UCHAR *)hcd_name;
127 #else
128
129 /* Initialize the array of the new controller with its name (include null-terminator). */
130 _ux_utility_memory_copy(hcd -> ux_hcd_name, hcd_name, hcd_name_length + 1); /* Use case of memcpy is verified. */
131 #endif
132
133 /* Store the hardware resources of the controller */
134 hcd -> ux_hcd_io = hcd_param1;
135 hcd -> ux_hcd_irq = hcd_param2;
136
137 /* This controller is now used */
138 hcd -> ux_hcd_status = UX_USED;
139
140 /* And we have one new controller registered. */
141 _ux_system_host -> ux_system_host_registered_hcd++;
142
143 /* We are now calling the HCD driver initialization. */
144 status = hcd_init_function(hcd);
145
146 /* Return the completion status to the caller. */
147 return(status);
148 }
149 #if UX_MAX_HCD > 1
150 /* Try the next HCD structure */
151 hcd++;
152 }
153 #endif
154
155 /* We have exhausted the array of the HCDs, return an error. */
156 return(UX_MEMORY_INSUFFICIENT);
157 }
158
159
160 /**************************************************************************/
161 /* */
162 /* FUNCTION RELEASE */
163 /* */
164 /* _uxe_host_stack_hcd_register PORTABLE C */
165 /* 6.3.0 */
166 /* AUTHOR */
167 /* */
168 /* Chaoqiong Xiao, Microsoft Corporation */
169 /* */
170 /* DESCRIPTION */
171 /* */
172 /* This function checks errors in host stack HCD register function */
173 /* call. */
174 /* */
175 /* INPUT */
176 /* */
177 /* endpoint Endpoint to abort transfer */
178 /* */
179 /* OUTPUT */
180 /* */
181 /* None */
182 /* */
183 /* CALLS */
184 /* */
185 /* _ux_host_stack_hcd_register HCD register */
186 /* */
187 /* CALLED BY */
188 /* */
189 /* Application */
190 /* */
191 /* RELEASE HISTORY */
192 /* */
193 /* DATE NAME DESCRIPTION */
194 /* */
195 /* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */
196 /* */
197 /**************************************************************************/
_uxe_host_stack_hcd_register(UCHAR * hcd_name,UINT (* hcd_init_function)(struct UX_HCD_STRUCT *),ULONG hcd_param1,ULONG hcd_param2)198 UINT _uxe_host_stack_hcd_register(UCHAR *hcd_name,
199 UINT (*hcd_init_function)(struct UX_HCD_STRUCT *), ULONG hcd_param1, ULONG hcd_param2)
200 {
201
202 /* Sanity check. */
203 if ((hcd_name == UX_NULL) || (hcd_init_function == UX_NULL))
204 return(UX_INVALID_PARAMETER);
205
206 /* Invoke HCD register function. */
207 return(_ux_host_stack_hcd_register(hcd_name, hcd_init_function, hcd_param1, hcd_param2));
208 }
209