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