1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_host_config.h"
10 #include "fsl_common.h"
11 #include "usb_host.h"
12 #include "usb_host_hci.h"
13 #include "usb_host_devices.h"
14 #include "fsl_device_registers.h"
15 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
16 #include "fsl_cache.h"
17 #endif
18
19 /*******************************************************************************
20 * Definitions
21 ******************************************************************************/
22
23 /* Component ID definition, used by tools. */
24 #ifndef FSL_COMPONENT_ID
25 #define FSL_COMPONENT_ID "middleware.usb.host_stack"
26 #endif
27
28 #if defined __CORTEX_M && (__CORTEX_M == 7U)
29 #if (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
30 #warning USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE is not supported.
31 #endif
32 #endif
33
34 /*******************************************************************************
35 * Prototypes
36 ******************************************************************************/
37 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
38
39 #include "usb_host_hub.h"
40 #include "usb_host_hub_app.h"
41 #endif
42
43 /*!
44 * @brief get the idle host instance.
45 *
46 * @return host instance pointer.
47 */
48 static usb_host_instance_t *USB_HostGetInstance(void);
49
50 /*!
51 * @brief release host instance.
52 *
53 * @param hostInstance host instance pointer.
54 */
55 static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance);
56
57 /*!
58 * @brief get the khci/ehci interface.
59 *
60 * @param controllerId controller id.
61 * @param controllerTable return controller interface structure.
62 */
63 static void USB_HostGetControllerInterface(uint8_t controllerId,
64 const usb_host_controller_interface_t **controllerTable);
65
66 /*******************************************************************************
67 * Variables
68 ******************************************************************************/
69 /*! @brief USB host instance resource */
70 usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST];
71
72 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
73 #include "usb_host_ehci.h"
74 static const usb_host_controller_interface_t s_EhciInterface = {
75 USB_HostEhciCreate, USB_HostEhciDestory, USB_HostEhciOpenPipe, USB_HostEhciClosePipe,
76 USB_HostEhciWritePipe, USB_HostEhciReadpipe, USB_HostEhciIoctl,
77 };
78 #endif /* USB_HOST_CONFIG_EHCI */
79
80 #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
81 #include "usb_host_khci.h"
82 static const usb_host_controller_interface_t s_KhciInterface = {
83 USB_HostKhciCreate, USB_HostKhciDestory, USB_HostKhciOpenPipe, USB_HostKhciClosePipe,
84 USB_HostKhciWritePipe, USB_HostKhciReadpipe, USB_HostKciIoctl,
85 };
86 #endif /* USB_HOST_CONFIG_KHCI */
87
88 #if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
89 #include "usb_host_ohci.h"
90 static const usb_host_controller_interface_t s_OhciInterface = {
91 USB_HostOhciCreate, USB_HostOhciDestory, USB_HostOhciOpenPipe, USB_HostOhciClosePipe,
92 USB_HostOhciWritePipe, USB_HostOhciReadPipe, USB_HostOhciIoctl,
93 };
94 #endif /* USB_HOST_CONFIG_OHCI */
95
96 #if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
97 #include "usb_host_ip3516hs.h"
98 static const usb_host_controller_interface_t s_Ip3516HsInterface = {
99 USB_HostIp3516HsCreate, USB_HostIp3516HsDestory, USB_HostIp3516HsOpenPipe, USB_HostIp3516HsClosePipe,
100 USB_HostIp3516HsWritePipe, USB_HostIp3516HsReadPipe, USB_HostIp3516HsIoctl,
101 };
102 #endif /* USB_HOST_CONFIG_IP3516HS */
103
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)104 USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
105 static uint8_t s_Setupbuffer[USB_HOST_CONFIG_MAX_HOST][USB_HOST_CONFIG_MAX_TRANSFERS][USB_DATA_ALIGN_SIZE_MULTIPLE(8)];
106 /*******************************************************************************
107 * Code
108 ******************************************************************************/
109
110 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
111 /*FUNCTION*----------------------------------------------------------------
112 *
113 * Function Name : usb_test_mode_init
114 * Returned Value : None
115 * Comments :
116 * This function is called by common class to initialize the class driver. It
117 * is called in response to a select interface call by application
118 *
119 *END*--------------------------------------------------------------------*/
120 usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle)
121 {
122 #if (((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) || \
123 ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS)))
124 usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
125 usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
126 #endif
127 uint32_t productId;
128 uint32_t vendorId;
129
130 (void)usb_echo("usb host test init\r\n");
131 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDevicePID, &productId);
132 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceVID, &vendorId);
133 (void)usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId);
134
135 if ((productId != 0x0200U) && (productId != 0x0101U) && (productId != 0x0102U) && (productId != 0x0103U) &&
136 (productId != 0x0104U) && (productId != 0x0105U) && (productId != 0x0106U) && (productId != 0x0107U) &&
137 (productId != 0x0108U))
138 {
139 (void)usb_echo("Unsupported Device\r\n");
140 }
141
142 if (productId == 0x0200U)
143 {
144 (void)usb_echo("PET test device attached\r\n");
145 }
146 else
147 {
148 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
149 if (hostInstance->controllerTable == &s_EhciInterface)
150 {
151 (void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
152 (void *)deviceHandle);
153 }
154 #elif ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
155 if (hostInstance->controllerTable == &s_Ip3516HsInterface)
156 {
157 (void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
158 (void *)deviceHandle);
159 }
160 #endif
161 }
162
163 return kStatus_USB_Success;
164 }
165 #endif
166
USB_HostGetInstance(void)167 static usb_host_instance_t *USB_HostGetInstance(void)
168 {
169 uint8_t i = 0;
170 uint32_t index = 0;
171 void *temp;
172 OSA_SR_ALLOC();
173 OSA_ENTER_CRITICAL();
174 for (; i < (uint8_t)USB_HOST_CONFIG_MAX_HOST; i++)
175 {
176 if (g_UsbHostInstance[i].occupied != 1U)
177 {
178 uint8_t *buffer = (uint8_t *)&g_UsbHostInstance[i];
179 for (uint32_t j = 0U; j < sizeof(usb_host_instance_t); j++)
180 {
181 buffer[j] = 0x00U;
182 }
183 g_UsbHostInstance[i].occupied = 1;
184 OSA_EXIT_CRITICAL();
185 for (index = 0; index < (uint32_t)USB_HOST_CONFIG_MAX_TRANSFERS; ++index)
186 {
187 temp = (void *)&(s_Setupbuffer[i][index][0]);
188 g_UsbHostInstance[i].transferList[index].setupPacket = (usb_setup_struct_t *)temp;
189 }
190 return &g_UsbHostInstance[i];
191 }
192 }
193 OSA_EXIT_CRITICAL();
194 return NULL;
195 }
196
USB_HostReleaseInstance(usb_host_instance_t * hostInstance)197 static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance)
198 {
199 OSA_SR_ALLOC();
200 OSA_ENTER_CRITICAL();
201 hostInstance->occupied = 0;
202 OSA_EXIT_CRITICAL();
203 }
204
USB_HostGetControllerInterface(uint8_t controllerId,const usb_host_controller_interface_t ** controllerTable)205 static void USB_HostGetControllerInterface(uint8_t controllerId,
206 const usb_host_controller_interface_t **controllerTable)
207 {
208 #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
209 if (controllerId == (uint8_t)kUSB_ControllerKhci0)
210 {
211 *controllerTable = &s_KhciInterface;
212 }
213 #endif /* USB_HOST_CONFIG_KHCI */
214
215 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
216 if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1))
217 {
218 *controllerTable = &s_EhciInterface;
219 }
220 #endif /* USB_HOST_CONFIG_EHCI */
221
222 #if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
223 if (controllerId == (uint8_t)kUSB_ControllerOhci0)
224 {
225 *controllerTable = &s_OhciInterface;
226 }
227 #endif /* USB_HOST_CONFIG_OHCI */
228
229 #if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
230 if (controllerId == (uint8_t)kUSB_ControllerIp3516Hs0)
231 {
232 *controllerTable = &s_Ip3516HsInterface;
233 }
234 #endif /* USB_HOST_CONFIG_IP3516HS */
235 }
236
USB_HostInit(uint8_t controllerId,usb_host_handle * hostHandle,host_callback_t callbackFn)237 usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn)
238 {
239 usb_status_t status = kStatus_USB_Success;
240 usb_host_instance_t *hostInstance = NULL;
241 usb_host_transfer_t *transferPrev = NULL;
242 uint8_t i = 0;
243
244 hostInstance = USB_HostGetInstance(); /* get one host instance */
245 if (hostInstance == NULL)
246 {
247 return kStatus_USB_InvalidHandle;
248 }
249
250 /* get khci/ehci API table */
251 USB_HostGetControllerInterface(controllerId, &hostInstance->controllerTable);
252 if (hostInstance->controllerTable == NULL)
253 {
254 USB_HostReleaseInstance(hostInstance);
255 return kStatus_USB_ControllerNotFound;
256 }
257
258 /* judge the controller interface one time at here */
259 if ((hostInstance->controllerTable->controllerCreate == NULL) ||
260 (hostInstance->controllerTable->controllerDestory == NULL) ||
261 (hostInstance->controllerTable->controllerOpenPipe == NULL) ||
262 (hostInstance->controllerTable->controllerClosePipe == NULL) ||
263 (hostInstance->controllerTable->controllerWritePipe == NULL) ||
264 (hostInstance->controllerTable->controllerReadPipe == NULL) ||
265 (hostInstance->controllerTable->controllerIoctl == NULL))
266 {
267 return kStatus_USB_Error;
268 }
269
270 /* HOST instance init*/
271 hostInstance->controllerId = controllerId;
272 hostInstance->deviceCallback = callbackFn;
273 hostInstance->deviceList = NULL;
274 hostInstance->hostMutex = (osa_mutex_handle_t)(&hostInstance->mutexBuffer[0]);
275 if (KOSA_StatusSuccess != OSA_MutexCreate(hostInstance->hostMutex))
276 {
277 USB_HostReleaseInstance(hostInstance);
278 #ifdef HOST_ECHO
279 usb_echo("host init: create host mutex fail\r\n");
280 #endif
281 return kStatus_USB_Error;
282 }
283
284 /* initialize transfer list */
285
286 hostInstance->transferHead = &hostInstance->transferList[0];
287 transferPrev = hostInstance->transferHead;
288 for (i = 1; i < USB_HOST_CONFIG_MAX_TRANSFERS; ++i)
289 {
290 transferPrev->next = &hostInstance->transferList[i];
291 transferPrev = transferPrev->next;
292 }
293
294 /* controller create, the callbackFn is initialized in USB_HostGetControllerInterface */
295 status =
296 hostInstance->controllerTable->controllerCreate(controllerId, hostInstance, &(hostInstance->controllerHandle));
297 if ((status != kStatus_USB_Success) || (hostInstance->controllerHandle == NULL))
298 {
299 (void)OSA_MutexDestroy(hostInstance->hostMutex);
300 USB_HostReleaseInstance(hostInstance);
301 #ifdef HOST_ECHO
302 usb_echo("host init: controller init fail\r\n");
303 #endif
304 return kStatus_USB_Error;
305 }
306
307 *hostHandle = hostInstance;
308 return kStatus_USB_Success;
309 }
310
USB_HostDeinit(usb_host_handle hostHandle)311 usb_status_t USB_HostDeinit(usb_host_handle hostHandle)
312 {
313 usb_status_t status = kStatus_USB_Success;
314 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
315 usb_host_device_instance_t *deviceInstance = NULL;
316
317 if (hostHandle == NULL)
318 {
319 return kStatus_USB_InvalidHandle;
320 }
321
322 /* device list detach */
323 deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
324 while (deviceInstance != NULL)
325 {
326 deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
327 (void)USB_HostDetachDeviceInternal(hostHandle, deviceInstance);
328 }
329
330 /* controller instance destroy, the callbackFn is initialized in USB_HostGetControllerInterface */
331 status = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle);
332 hostInstance->controllerHandle = NULL;
333 if (status != kStatus_USB_Success)
334 {
335 #ifdef HOST_ECHO
336 usb_echo("host controller destroy fail\r\n");
337 #endif
338 }
339
340 /* resource release */
341 if (NULL != hostInstance->hostMutex)
342 {
343 (void)OSA_MutexDestroy(hostInstance->hostMutex);
344 hostInstance->hostMutex = NULL;
345 }
346 USB_HostReleaseInstance(hostInstance);
347
348 return status;
349 }
350
USB_HostOpenPipe(usb_host_handle hostHandle,usb_host_pipe_handle * pipeHandle,usb_host_pipe_init_t * pipeInit)351 usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
352 usb_host_pipe_handle *pipeHandle,
353 usb_host_pipe_init_t *pipeInit)
354 {
355 usb_status_t status = kStatus_USB_Success;
356 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
357
358 if ((hostHandle == NULL) || (pipeInit == NULL))
359 {
360 return kStatus_USB_InvalidHandle;
361 }
362
363 /* call controller open pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
364 status = hostInstance->controllerTable->controllerOpenPipe(hostInstance->controllerHandle, pipeHandle, pipeInit);
365
366 return status;
367 }
368
USB_HostClosePipe(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle)369 usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle)
370 {
371 usb_status_t status = kStatus_USB_Success;
372 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
373
374 if ((hostHandle == NULL) || (pipeHandle == NULL))
375 {
376 return kStatus_USB_InvalidHandle;
377 }
378
379 /* call controller close pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
380 status = hostInstance->controllerTable->controllerClosePipe(hostInstance->controllerHandle, pipeHandle);
381
382 return status;
383 }
384
USB_HostSend(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)385 usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
386 {
387 usb_status_t status = kStatus_USB_Success;
388 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
389
390 if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
391 {
392 return kStatus_USB_InvalidHandle;
393 }
394
395 /* initialize transfer */
396 transfer->transferSofar = 0;
397 transfer->direction = USB_OUT;
398
399 (void)USB_HostLock(); /* This api can be called by host task and app task */
400 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
401 */
402 #if 0
403 if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
404 {
405 USB_HostUnlock();
406 return status;
407 }
408 #endif
409 /* call controller write pipe interface */
410 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
411 if (transfer->transferLength > 0)
412 {
413 DCACHE_CleanByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
414 }
415 #endif
416 /* the callbackFn is initialized in USB_HostGetControllerInterface */
417 status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
418
419 (void)USB_HostUnlock();
420 return status;
421 }
422
USB_HostSendSetup(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)423 usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
424 usb_host_pipe_handle pipeHandle,
425 usb_host_transfer_t *transfer)
426 {
427 usb_status_t status = kStatus_USB_Success;
428 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
429
430 if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
431 {
432 return kStatus_USB_InvalidHandle;
433 }
434
435 /* initialize transfer */
436 transfer->transferSofar = 0;
437 transfer->next = NULL;
438 transfer->setupStatus = 0;
439 if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
440 {
441 transfer->direction = USB_IN;
442 }
443 else
444 {
445 transfer->direction = USB_OUT;
446 }
447
448 (void)USB_HostLock(); /* This API can be called by host task and application task */
449 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
450 */
451 #if 0
452 if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
453 {
454 USB_HostUnlock();
455 return status;
456 }
457 #endif
458 /* call controller write pipe interface */
459 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
460 DCACHE_CleanByRange((uint32_t)&transfer->setupPacket->bmRequestType, sizeof(usb_setup_struct_t));
461 if (transfer->transferLength > 0)
462 {
463 DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
464 }
465 #endif
466 /* the callbackFn is initialized in USB_HostGetControllerInterface */
467 status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
468
469 (void)USB_HostUnlock();
470 return status;
471 }
472
USB_HostRecv(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)473 usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
474 {
475 usb_status_t status = kStatus_USB_Success;
476 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
477
478 if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
479 {
480 return kStatus_USB_InvalidHandle;
481 }
482
483 /* initialize transfer */
484 transfer->transferSofar = 0;
485 transfer->direction = USB_IN;
486
487 (void)USB_HostLock(); /* This API can be called by host task and application task */
488 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
489 */
490 #if 0
491 if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
492 {
493 USB_HostUnlock();
494 return status;
495 }
496 #endif
497
498 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
499 if (transfer->transferLength > 0)
500 {
501 DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
502 }
503 #endif
504 /* the callbackFn is initialized in USB_HostGetControllerInterface */
505 status = hostInstance->controllerTable->controllerReadPipe(hostInstance->controllerHandle, pipeHandle, transfer);
506
507 (void)USB_HostUnlock();
508 return status;
509 }
510
USB_HostCancelTransfer(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)511 usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
512 usb_host_pipe_handle pipeHandle,
513 usb_host_transfer_t *transfer)
514 {
515 usb_status_t status = kStatus_USB_Success;
516 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
517 usb_host_cancel_param_t cancelParam;
518
519 if ((hostHandle == NULL) || (pipeHandle == NULL))
520 {
521 return kStatus_USB_InvalidHandle;
522 }
523
524 /* initialize cancel parameter */
525 cancelParam.pipeHandle = pipeHandle;
526 cancelParam.transfer = transfer;
527
528 /* USB_HostLock(); This api can be called by host task and app task */
529 /* the callbackFn is initialized in USB_HostGetControllerInterface */
530 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostCancelTransfer,
531 &cancelParam);
532 /* USB_HostUnlock(); */
533
534 return status;
535 }
536
USB_HostMallocTransfer(usb_host_handle hostHandle,usb_host_transfer_t ** transfer)537 usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfer_t **transfer)
538 {
539 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
540
541 if ((hostHandle == NULL) || (transfer == NULL))
542 {
543 return kStatus_USB_InvalidHandle;
544 }
545
546 /* get one from the transfer_head */
547 (void)USB_HostLock();
548 if (hostInstance->transferHead != NULL)
549 {
550 *transfer = hostInstance->transferHead;
551 hostInstance->transferHead = hostInstance->transferHead->next;
552 (void)USB_HostUnlock();
553 return kStatus_USB_Success;
554 }
555 else
556 {
557 *transfer = NULL;
558 (void)USB_HostUnlock();
559 return kStatus_USB_Error;
560 }
561 }
562
USB_HostFreeTransfer(usb_host_handle hostHandle,usb_host_transfer_t * transfer)563 usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_t *transfer)
564 {
565 usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
566
567 if (hostHandle == NULL)
568 {
569 return kStatus_USB_InvalidHandle;
570 }
571 if (transfer == NULL)
572 {
573 return kStatus_USB_Success;
574 }
575
576 /* release one to the transfer_head */
577 (void)USB_HostLock();
578 transfer->next = hostInstance->transferHead;
579 hostInstance->transferHead = transfer;
580 (void)USB_HostUnlock();
581 return kStatus_USB_Success;
582 }
583
USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,uint32_t infoCode,uint32_t * infoValue)584 usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,
585 uint32_t infoCode,
586 uint32_t *infoValue)
587 {
588 usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
589 uint32_t *temp;
590 usb_host_dev_info_t devInfo;
591 if ((deviceHandle == NULL) || (infoValue == NULL))
592 {
593 return kStatus_USB_InvalidParameter;
594 }
595 devInfo = (usb_host_dev_info_t)infoCode;
596 switch (devInfo)
597 {
598 case kUSB_HostGetDeviceAddress: /* device address */
599
600 *infoValue = (uint32_t)deviceInstance->setAddress;
601 break;
602
603 case kUSB_HostGetDeviceControlPipe: /* device control pipe */
604 temp = (uint32_t *)deviceInstance->controlPipe;
605 *infoValue = (uint32_t)temp;
606 break;
607
608 case kUSB_HostGetHostHandle: /* device host handle */
609 temp = (uint32_t *)deviceInstance->hostHandle;
610 *infoValue = (uint32_t)temp;
611 break;
612
613 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
614 case kUSB_HostGetDeviceHubNumber: /* device hub address */
615 *infoValue = (uint32_t)deviceInstance->hubNumber;
616 break;
617
618 case kUSB_HostGetDevicePortNumber: /* device port no */
619 *infoValue = (uint32_t)deviceInstance->portNumber;
620 break;
621
622 case kUSB_HostGetDeviceLevel: /* device level */
623 *infoValue = (uint32_t)deviceInstance->level;
624 break;
625
626 case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
627 *infoValue = (uint32_t)deviceInstance->hsHubNumber;
628 break;
629
630 case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
631 *infoValue = (uint32_t)deviceInstance->hsHubPort;
632 break;
633
634 case kUSB_HostGetHubThinkTime: /* device hub think time */
635 *infoValue = USB_HostHubGetTotalThinkTime(deviceInstance->hostHandle, deviceInstance->hubNumber);
636 break;
637 #else
638 case kUSB_HostGetDeviceHubNumber: /* device hub address */
639 case kUSB_HostGetDevicePortNumber: /* device port no */
640 case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
641 case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
642 case kUSB_HostGetHubThinkTime: /* device hub think time */
643 *infoValue = 0;
644 break;
645 case kUSB_HostGetDeviceLevel: /* device level */
646 *infoValue = 1;
647 break;
648 #endif /* USB_HOST_CONFIG_HUB */
649
650 case kUSB_HostGetDeviceSpeed: /* device speed */
651 *infoValue = (uint32_t)deviceInstance->speed;
652 break;
653
654 case kUSB_HostGetDevicePID: /* device pid */
655 *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idProduct);
656 break;
657
658 case kUSB_HostGetDeviceVID: /* device vid */
659 *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idVendor);
660 break;
661
662 case kUSB_HostGetDeviceConfigIndex: /* device config index */
663 *infoValue = (uint32_t)deviceInstance->configurationValue - 1U;
664 break;
665
666 case kUSB_HostGetConfigurationDes: /* configuration descriptor pointer */
667 *infoValue = (uint32_t)deviceInstance->configurationDesc;
668 break;
669
670 case kUSB_HostGetConfigurationLength: /* configuration descriptor length */
671 *infoValue = (uint32_t)deviceInstance->configurationLen;
672 break;
673
674 default:
675 /*no action*/
676 break;
677 }
678
679 return kStatus_USB_Success;
680 }
681
USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,uint8_t alternateSetting,usb_host_interface_t * interface)682 usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,
683 uint8_t alternateSetting,
684 usb_host_interface_t *interface)
685 {
686 uint32_t endPosition;
687 usb_descriptor_union_t *unionDes;
688 usb_host_ep_t *epParse;
689 void *temp;
690 if (interfaceHandle == NULL)
691 {
692 return kStatus_USB_InvalidHandle;
693 }
694
695 if (alternateSetting == 0U)
696 {
697 return kStatus_USB_InvalidParameter;
698 }
699
700 /* parse configuration descriptor */
701 temp = (void *)((usb_host_interface_t *)interfaceHandle)->interfaceExtension;
702 unionDes = (usb_descriptor_union_t *)temp; /* interface extend descriptor start */
703 endPosition =
704 (uint32_t)unionDes +
705 ((usb_host_interface_t *)interfaceHandle)->interfaceExtensionLength; /* interface extend descriptor end */
706
707 /* search for the alternate setting interface descriptor */
708 while ((uint32_t)unionDes < endPosition)
709 {
710 if (unionDes->interface.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
711 {
712 if (unionDes->interface.bAlternateSetting == alternateSetting)
713 {
714 break;
715 }
716 else
717 {
718 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
719 }
720 }
721 else
722 {
723 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
724 }
725 }
726 if ((uint32_t)unionDes >= endPosition)
727 {
728 return kStatus_USB_Error;
729 }
730
731 /* initialize interface handle structure instance */
732 interface->interfaceDesc = &unionDes->interface;
733 interface->alternateSettingNumber = 0U;
734 interface->epCount = 0U;
735 interface->interfaceExtension = NULL;
736 interface->interfaceExtensionLength = 0U;
737 interface->interfaceIndex = unionDes->interface.bInterfaceNumber;
738
739 /* search for endpoint descriptor start position */
740 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
741 while ((uint32_t)unionDes < endPosition)
742 {
743 if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
744 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
745 {
746 if (interface->interfaceExtension == NULL)
747 {
748 interface->interfaceExtension = (uint8_t *)unionDes;
749 }
750 interface->interfaceExtensionLength += unionDes->common.bLength;
751 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
752 }
753 else
754 {
755 break;
756 }
757 }
758
759 /* parse endpoint descriptor */
760 if (interface->interfaceDesc->bNumEndpoints != 0U)
761 {
762 if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
763 (interface->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
764 {
765 #ifdef HOST_ECHO
766 usb_echo("interface descriptor error\n");
767 #endif
768 return kStatus_USB_Error;
769 }
770 for (; interface->epCount < interface->interfaceDesc->bNumEndpoints; (interface->epCount)++)
771 {
772 if (((uint32_t)unionDes >= endPosition) ||
773 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
774 {
775 #ifdef HOST_ECHO
776 usb_echo("endpoint descriptor error\n");
777 #endif
778 return kStatus_USB_Error;
779 }
780 epParse = (usb_host_ep_t *)&interface->epList[interface->epCount];
781 temp = (void *)unionDes;
782 epParse->epDesc = (usb_descriptor_endpoint_t *)temp;
783 epParse->epExtensionLength = 0;
784 epParse->epExtension = NULL;
785 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
786 while ((uint32_t)unionDes < endPosition)
787 {
788 if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
789 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
790 {
791 if (epParse->epExtension == NULL)
792 {
793 epParse->epExtension = (uint8_t *)unionDes;
794 }
795 epParse->epExtensionLength += unionDes->common.bLength;
796 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
797 }
798 else
799 {
800 break;
801 }
802 }
803 }
804 }
805
806 return kStatus_USB_Success;
807 }
808
USB_HostGetVersion(uint32_t * version)809 void USB_HostGetVersion(uint32_t *version)
810 {
811 if (NULL != version)
812 {
813 *version =
814 (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
815 }
816 }
817
818 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
819 /* Send BUS or specific device suspend request */
USB_HostSuspendDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle)820 usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
821 {
822 usb_host_instance_t *hostInstance;
823 usb_host_device_instance_t *deviceInstance;
824 usb_status_t status = kStatus_USB_Error;
825 usb_host_bus_control_t type = kUSB_HostBusSuspend;
826
827 if (hostHandle == NULL)
828 {
829 return kStatus_USB_InvalidHandle;
830 }
831 hostInstance = (usb_host_instance_t *)hostHandle;
832
833 hostInstance->suspendedDevice = (void *)deviceHandle;
834
835 if (NULL == deviceHandle)
836 {
837 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
838 status = USB_HostHubSuspendDevice(hostInstance);
839 #else
840 /* the callbackFn is initialized in USB_HostGetControllerInterface */
841 status =
842 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
843 #endif
844 }
845 else
846 {
847 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
848 deviceInstance = (usb_host_device_instance_t *)deviceHandle;
849 if (0U == deviceInstance->hubNumber)
850 {
851 #endif
852 if (hostInstance->deviceList == deviceHandle)
853 {
854 /* the callbackFn is initialized in USB_HostGetControllerInterface */
855 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
856 kUSB_HostBusControl, &type);
857 }
858 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
859 }
860 else
861 {
862 if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle))
863 {
864 status = USB_HostHubSuspendDevice(hostInstance);
865 }
866 }
867 #endif
868 }
869 if (kStatus_USB_Error == status)
870 {
871 hostInstance->suspendedDevice = NULL;
872 }
873 return status;
874 }
875
876 /* Send BUS or specific device resume request */
USB_HostResumeDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle)877 usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
878 {
879 usb_host_instance_t *hostInstance;
880 usb_host_device_instance_t *deviceInstance;
881 usb_status_t status = kStatus_USB_Error;
882 usb_host_bus_control_t type = kUSB_HostBusResume;
883
884 if (hostHandle == NULL)
885 {
886 return kStatus_USB_InvalidHandle;
887 }
888 hostInstance = (usb_host_instance_t *)hostHandle;
889
890 if (hostInstance->suspendedDevice != deviceHandle)
891 {
892 return kStatus_USB_InvalidParameter;
893 }
894 hostInstance->suspendedDevice = (void *)deviceHandle;
895
896 if (NULL == deviceHandle)
897 {
898 /* the callbackFn is initialized in USB_HostGetControllerInterface */
899 status =
900 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
901 }
902 else
903 {
904 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
905 deviceInstance = (usb_host_device_instance_t *)deviceHandle;
906 if (0U == deviceInstance->hubNumber)
907 {
908 #endif
909 if (hostInstance->deviceList == deviceHandle)
910 {
911 /* the callbackFn is initialized in USB_HostGetControllerInterface */
912 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
913 kUSB_HostBusControl, &type);
914 }
915 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
916 }
917 else
918 {
919 if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle))
920 {
921 status = USB_HostHubResumeDevice(hostInstance);
922 }
923 }
924 #endif
925 }
926
927 return status;
928 }
929 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
930 /* Send BUS or specific device suspend request */
USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle,uint8_t sleepType)931 usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
932 usb_device_handle deviceHandle,
933 uint8_t sleepType)
934 {
935 usb_host_instance_t *hostInstance;
936 usb_status_t status = kStatus_USB_Error;
937 usb_host_bus_control_t type = kUSB_HostBusL1Sleep;
938
939 if (hostHandle == NULL)
940 {
941 return kStatus_USB_InvalidHandle;
942 }
943 hostInstance = (usb_host_instance_t *)hostHandle;
944
945 hostInstance->suspendedDevice = (void *)deviceHandle;
946
947 if (1U == sleepType)
948 {
949 /*#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))*/
950 /*To do, incomplete hub L1 suspend device*/
951 /*#else*/
952 /* the callbackFn is initialized in USB_HostGetControllerInterface */
953 status =
954 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
955 /*#endif*/
956 }
957 else
958 {
959 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
960 /*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
961 #endif
962 if (hostInstance->deviceList == deviceHandle)
963 {
964 /* the callbackFn is initialized in USB_HostGetControllerInterface */
965 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
966 &type);
967 }
968 }
969 if (kStatus_USB_Error == status)
970 {
971 hostInstance->suspendedDevice = NULL;
972 }
973 return status;
974 }
975 /* Send BUS or specific device suspend request */
USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle,uint8_t * lpmParam)976 usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam)
977 {
978 usb_host_instance_t *hostInstance;
979 usb_status_t status = kStatus_USB_Error;
980
981 if (hostHandle == NULL)
982 {
983 return kStatus_USB_InvalidHandle;
984 }
985 hostInstance = (usb_host_instance_t *)hostHandle;
986 /* the callbackFn is initialized in USB_HostGetControllerInterface */
987 status =
988 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostL1Config, lpmParam);
989
990 return status;
991 }
992
993 /* Send BUS or specific device resume request */
USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle,uint8_t sleepType)994 usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,
995 usb_device_handle deviceHandle,
996 uint8_t sleepType)
997 {
998 usb_host_instance_t *hostInstance;
999
1000 usb_status_t status = kStatus_USB_Error;
1001 usb_host_bus_control_t type = kUSB_HostBusL1Resume;
1002
1003 if (hostHandle == NULL)
1004 {
1005 return kStatus_USB_InvalidHandle;
1006 }
1007 hostInstance = (usb_host_instance_t *)hostHandle;
1008
1009 if (1U == sleepType)
1010 {
1011 /* the callbackFn is initialized in USB_HostGetControllerInterface */
1012 status =
1013 hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
1014 }
1015 else
1016 {
1017 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1018 /*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
1019
1020 #endif
1021 if (hostInstance->deviceList == deviceHandle)
1022 {
1023 /* the callbackFn is initialized in USB_HostGetControllerInterface */
1024 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
1025 &type);
1026 }
1027 }
1028
1029 return status;
1030 }
1031 #endif
1032 /* Update HW tick(unit is ms) */
USB_HostUpdateHwTick(usb_host_handle hostHandle,uint64_t tick)1033 usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t tick)
1034 {
1035 usb_host_instance_t *hostInstance;
1036 usb_status_t status = kStatus_USB_Success;
1037
1038 if (hostHandle == NULL)
1039 {
1040 return kStatus_USB_InvalidHandle;
1041 }
1042 hostInstance = (usb_host_instance_t *)hostHandle;
1043
1044 hostInstance->hwTick = tick;
1045
1046 return status;
1047 }
1048 #endif
1049
1050 #if ((defined(USB_HOST_CONFIG_BATTERY_CHARGER)) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U))
USB_HostSetChargerType(usb_host_handle hostHandle,uint8_t type)1051 usb_status_t USB_HostSetChargerType(usb_host_handle hostHandle, uint8_t type)
1052 {
1053 usb_host_instance_t *hostInstance;
1054
1055 if (hostHandle == NULL)
1056 {
1057 return kStatus_USB_InvalidHandle;
1058 }
1059 hostInstance = (usb_host_instance_t *)hostHandle;
1060 return hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostSetChargerType,
1061 &type);
1062 }
1063 #endif
1064