usb_host_hci.c 36 KB

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