fusb.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: fusb.c
  15. * Date: 2022-02-11 13:33:11
  16. * LastEditTime: 2022-02-18 09:22:06
  17. * Description:  This files is for implmentation of USB user API
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. * 1.0 Zhugengyu 2022/2/8 init commit
  23. */
  24. #include <string.h>
  25. #include "fdebug.h"
  26. #include "fsleep.h"
  27. #include "fusb_private.h"
  28. #include "fxhci.h"
  29. #define FUSB_DEBUG_TAG "FUSB"
  30. #define FUSB_ERROR(format, ...) FT_DEBUG_PRINT_E(FUSB_DEBUG_TAG, format, ##__VA_ARGS__)
  31. #define FUSB_WARN(format, ...) FT_DEBUG_PRINT_W(FUSB_DEBUG_TAG, format, ##__VA_ARGS__)
  32. #define FUSB_INFO(format, ...) FT_DEBUG_PRINT_I(FUSB_DEBUG_TAG, format, ##__VA_ARGS__)
  33. #define FUSB_DEBUG(format, ...) FT_DEBUG_PRINT_D(FUSB_DEBUG_TAG, format, ##__VA_ARGS__)
  34. #define FUSB_DR_DESC FUsbGenerateReqType(FUSB_REQ_DEVICE_TO_HOST, FUSB_REQ_TYPE_STANDARD, FUSB_REQ_RECP_DEV)
  35. /*
  36. * Certain Lexar / Micron USB 2.0 disks will fail the FUsbGetDescriptor(FUSB_DESC_TYPE_CONFIG)
  37. * call due to timing issues. Work around this by making extra attempts on
  38. * failure.
  39. */
  40. #define FUSB_GET_DESCRIPTOR_RETRIES 3
  41. /**
  42. * @name: FUsbCfgInitialize
  43. * @msg: 初始化USB实例
  44. * @return {FError} 初始化错误码
  45. * @param {FUsb} *instance, USB实例
  46. * @param {const FUsbConfig} *input_config, USB输入配置
  47. * @note 在PCIE模式下,USB Hc实例在PCIE总线发现控制器后创建
  48. */
  49. FError FUsbCfgInitialize(FUsb *instance, const FUsbConfig *input_config)
  50. {
  51. FASSERT(instance && input_config);
  52. FError ret = FUSB_SUCCESS;
  53. if (input_config != &instance->config)
  54. instance->config = *input_config;
  55. instance->hc = NULL; /* non usb host attached */
  56. /* create usb hc instance, which will be add as the head of hc list */
  57. if (NULL == FXhciHcInit(instance, instance->config.base_addr))
  58. ret = FUSB_ERR_ALLOCATE_FAIL;
  59. if (FUSB_SUCCESS == ret)
  60. {
  61. instance->is_ready = FT_COMPONENT_IS_READY;
  62. }
  63. return ret;
  64. }
  65. /**
  66. * @name: FUsbDeInitialize
  67. * @msg: 去初始化USB实例
  68. * @return {*}
  69. * @param {FUsb} *instance, USB实例
  70. */
  71. void FUsbDeInitialize(FUsb *instance)
  72. {
  73. FASSERT(instance);
  74. if (FT_COMPONENT_IS_READY != instance->is_ready)
  75. {
  76. FUSB_ERROR("USB not ready !!!");
  77. return;
  78. }
  79. instance->is_ready = 0;
  80. return;
  81. }
  82. /**
  83. * @name: FUsbPoll
  84. * @msg: 轮询所有的USB控制器连接的所有设备, 更新设备拓扑
  85. * @return {*}
  86. * @param {FUsb} *instance, USB实例
  87. */
  88. void FUsbPoll(FUsb *instance)
  89. {
  90. FASSERT(instance);
  91. if (FT_COMPONENT_IS_READY != instance->is_ready)
  92. {
  93. FUSB_ERROR("USB not ready !!!");
  94. return;
  95. }
  96. if (FUsbPollPrepare)
  97. FUsbPollPrepare(instance);
  98. FUsbHc *controller = instance->hc;
  99. if (controller != NULL)
  100. {
  101. int i;
  102. for (i = 0; i < FUSB_MAX_DEV_NUM; i++)
  103. {
  104. if (controller->devices[i] != NULL)
  105. {
  106. controller->devices[i]->poll(controller->devices[i]);
  107. }
  108. }
  109. }
  110. return;
  111. }
  112. /**
  113. * @name: FUsbExit
  114. * @msg: 关闭所有的USB控制器,移除所有连接的设备
  115. * @return {*}
  116. * @param {FUsb} *instance, USB实例
  117. */
  118. void FUsbExit(FUsb *instance)
  119. {
  120. FASSERT(instance);
  121. if (FT_COMPONENT_IS_READY != instance->is_ready)
  122. {
  123. FUSB_ERROR("USB not ready !!!");
  124. return;
  125. }
  126. if (FUsbExitPrepare)
  127. FUsbExitPrepare(instance);
  128. FUsbHc *controller = instance->hc;
  129. if (controller != NULL)
  130. {
  131. FASSERT(controller->shutdown);
  132. controller->shutdown(controller);
  133. FUSB_FREE(instance, instance->hc);
  134. instance->hc = NULL;
  135. }
  136. return;
  137. }
  138. /**
  139. * @name: FUsbMempAllocate
  140. * @msg: 从USB内存池分配一块内存,并清零分配的空间
  141. * @return {void *} 分配的内存空间,如果失败返回NULL
  142. * @param {FUsb} *instance, USB实例
  143. * @param {size_t} size, 请求分配的字节数
  144. * @param {size_t} align, 分配空间的对齐方式,起始地址按align字节对齐
  145. */
  146. void *FUsbMempAllocate(FUsb *instance, size_t size, size_t align)
  147. {
  148. FASSERT(instance);
  149. void *result = NULL;
  150. FUsbMemAllocator *allocator = &(instance->config.allocator);
  151. if (allocator->malloc_align)
  152. {
  153. result = allocator->malloc_align(size, align);
  154. }
  155. return result;
  156. }
  157. /**
  158. * @name: FUsbMempFree
  159. * @msg: 释放从USB内存池分配的空间
  160. * @return {*}
  161. * @param {FUsb} *instance, USB实例
  162. * @param {void} *ptr, 待释放空间的首地址
  163. */
  164. void FUsbMempFree(FUsb *instance, void *ptr)
  165. {
  166. FASSERT(instance);
  167. FUsbMemAllocator *allocator = &(instance->config.allocator);
  168. if ((NULL != ptr) && (allocator->free))
  169. {
  170. allocator->free(ptr);
  171. }
  172. return;
  173. }
  174. #ifdef FMEMP_TAG_DEBUG
  175. void *FUsbMempAllocateTag(FUsb *instance, size_t size, size_t align, const char *file, unsigned long line, const char *msg)
  176. {
  177. FASSERT(instance);
  178. void *result = NULL;
  179. FMemp *memp = &instance->memp;
  180. if (FUSB_DEFAULT_ALIGN == align)
  181. {
  182. result = FMempCallocTag(memp, 1, size, file, line, msg);
  183. }
  184. else
  185. {
  186. result = FMempMallocAlignTag(memp, size, align, file, line, msg);
  187. if (NULL != result)
  188. {
  189. memset(result, 0, size);
  190. }
  191. }
  192. return result;
  193. }
  194. void FUsbMempFreeTag(FUsb *instance, void *ptr)
  195. {
  196. FASSERT(instance);
  197. if (NULL != ptr)
  198. FMempFreeTag(&instance->memp, ptr);
  199. return;
  200. }
  201. #endif
  202. /**
  203. * @name: FUsbAllocateHc
  204. * @msg: 创建USB控制器实例,添加到USB实例的Hc链表中
  205. * @return {*}
  206. * @param {FUsb} *instance, USB实例
  207. */
  208. FUsbHc *FUsbAllocateHc(FUsb *instance)
  209. {
  210. FASSERT(instance);
  211. FUsbHc *controller = FUSB_ALLOCATE(instance, sizeof(FUsbHc), FUSB_DEFAULT_ALIGN);
  212. instance->hc = controller;
  213. return controller;
  214. }
  215. /**
  216. * @name: FUsbDetachHc
  217. * @msg: 删除USB控制器实例,从USB实例的Hc链表中删去
  218. * @return {*}
  219. * @param {FUsbHc} *controller, USB控制器实例
  220. */
  221. void FUsbDetachHc(FUsbHc *controller)
  222. {
  223. if (controller == NULL)
  224. return;
  225. FUsb *instance = controller->usb;
  226. FUsbDetachDev(controller, 0); /* tear down root hub tree */
  227. return;
  228. }
  229. /**
  230. * @name: FUsbFindValidInitFunc
  231. * @msg: 寻找特定USB设备的初始化函数
  232. * @return {*}
  233. * @param {FUsb} *instance, USB实例
  234. * @param {FUsbDevIndex} *index, 特定USB设备的索引
  235. */
  236. static FUsbDevInitHandler FUsbFindValidInitFunc(FUsb *instance, const FUsbDevIndex *index)
  237. {
  238. FASSERT(instance);
  239. u32 loop;
  240. FUsbDevInitFunc *func;
  241. FUsbDevInitHandler handler = NULL;
  242. for (loop = 0; loop < instance->dev_init_num; loop++)
  243. {
  244. func = &instance->dev_init[loop];
  245. if ((index->category == func->index.category) &&
  246. (index->class == func->index.class) &&
  247. (index->sub_class == func->index.sub_class) &&
  248. (index->protocol == func->index.protocol))
  249. {
  250. handler = func->handler;
  251. }
  252. }
  253. return handler;
  254. }
  255. /**
  256. * @name: FUsbAssignDevInitFunc
  257. * @msg: 指定特定USB设备的初始化函数,供创建USB设备实例时使用
  258. * @return {FError} 处理返回错误码
  259. * @param {FUsb} *instance, USB实例
  260. * @param {FUsbDevIndex} *index, 特定USB设备的索引
  261. * @param {FUsbDevInitHandler} handler, 特定USB设备的初始化函数
  262. */
  263. FError FUsbAssignDevInitFunc(FUsb *instance, const FUsbDevIndex *index, FUsbDevInitHandler handler)
  264. {
  265. FASSERT(instance && index && handler);
  266. if (FUSB_MAX_DEV_TYPE_NUM == instance->dev_init_num)
  267. return FUSB_ERR_INVALID_PARA;
  268. if (NULL != FUsbFindValidInitFunc(instance, index))
  269. {
  270. FUSB_WARN("Will remove device init for class 0x%x", index->class);
  271. }
  272. instance->dev_init[instance->dev_init_num].index = *index;
  273. instance->dev_init[instance->dev_init_num].handler = handler;
  274. instance->dev_init_num++;
  275. return FUSB_SUCCESS;
  276. }
  277. /**
  278. * @name: FUsbInitDevEntry
  279. * @msg: 初始化USB设备
  280. * @return {*}
  281. * @param {FUsbHc} *controller, USB Hc
  282. * @param {int} slot_id,slot号
  283. */
  284. FUsbDev *FUsbInitDevEntry(FUsbHc *controller, int slot_id)
  285. {
  286. FASSERT(controller && controller->usb);
  287. FASSERT(FUSB_SLOT_ID_VALID(slot_id));
  288. FUsb *instace = controller->usb;
  289. FUsbDev *dev = FUSB_ALLOCATE(instace, sizeof(FUsbDev), FUSB_DEFAULT_ALIGN);
  290. if (NULL == dev)
  291. {
  292. FUSB_ERROR("no memory to allocate device structure ");
  293. return NULL;
  294. }
  295. if (controller->devices[slot_id] != NULL)
  296. {
  297. FUSB_WARN("warning: device %d reassigned? ", slot_id);
  298. }
  299. controller->devices[slot_id] = dev;
  300. dev->controller = controller;
  301. dev->address = FUSB_NO_DEV_ADDR;
  302. dev->hub = FUSB_NO_HUB;
  303. dev->port = FUSB_NO_PORT;
  304. dev->init = FUsbNopDevInit;
  305. dev->init(controller->devices[slot_id]);
  306. return dev;
  307. }
  308. /**
  309. * @name: FUsbGetAllDevEntries
  310. * @msg: 获取USB控制器上连接的所有USB设备实例
  311. * @return {size_t} 实际获取的USB设备实例数目
  312. * @param {FUsbHc} *controller, USB控制器实例
  313. * @param {FUsbDev} *devs, 放置USB设备实例的缓冲区
  314. * @param {size_t} max_dev_num, 最多可以获取的USB设备实例数目
  315. */
  316. size_t FUsbGetAllDevEntries(FUsbHc *controller, FUsbDev *devs[], size_t max_dev_num)
  317. {
  318. FASSERT(controller && devs && max_dev_num > 0);
  319. size_t loop;
  320. size_t num = 0;
  321. /* loop over all dev address in case there are holes */
  322. for (loop = 0; loop < FUSB_MAX_DEV_NUM; loop++)
  323. {
  324. if (NULL != controller->devices[loop])
  325. {
  326. devs[num] = controller->devices[loop];
  327. num++;
  328. /* get at most max_dev_num device entry before exit */
  329. if (num >= max_dev_num)
  330. break;
  331. }
  332. }
  333. return num;
  334. }
  335. /**
  336. * @name: FUsbDecodeMaxPacketSz0
  337. * @msg: 根据USB设备速度,选择最大包长度
  338. * @return {*} 输出最大包长度
  339. * @param {FUsbSpeed} speed, USB设备速度类型
  340. * @param {u8} bMaxPacketSize0, 输入最大包长度
  341. */
  342. int FUsbDecodeMaxPacketSz0(FUsbSpeed speed, u8 bMaxPacketSize0)
  343. {
  344. switch (speed)
  345. {
  346. case FUSB_LOW_SPEED:
  347. if (bMaxPacketSize0 != 8)
  348. {
  349. FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0);
  350. bMaxPacketSize0 = 8;
  351. }
  352. return bMaxPacketSize0;
  353. case FUSB_FULL_SPEED:
  354. switch (bMaxPacketSize0)
  355. {
  356. case 8:
  357. case 16:
  358. case 32:
  359. case 64:
  360. return bMaxPacketSize0;
  361. default:
  362. FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0);
  363. return 8;
  364. }
  365. case FUSB_HIGH_SPEED:
  366. if (bMaxPacketSize0 != 64)
  367. {
  368. FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0);
  369. bMaxPacketSize0 = 64;
  370. }
  371. return bMaxPacketSize0;
  372. case FUSB_SUPER_SPEED:
  373. /* Intentional fallthrough */
  374. case FUSB_SUPER_SPEED_PLUS:
  375. if (bMaxPacketSize0 != 9)
  376. {
  377. FUSB_ERROR("Invalid MPS0: 0x%02x ", bMaxPacketSize0);
  378. bMaxPacketSize0 = 9;
  379. }
  380. return 1 << bMaxPacketSize0;
  381. default:
  382. return 8;
  383. }
  384. }
  385. /**
  386. * @name: FUsbSetFeature
  387. * @msg: 标准USB主机请求,使能设备/接口/端点的某个特性
  388. * @return {FUsbTransCode} 控制传输的返回值,小于0表示失败,大于0表示成功传输的字节数目
  389. * @param {FUsbDev} *dev, USB设备实例
  390. * @param {int} endp, 设备号(0x00)/接口号/端点号
  391. * @param {int} feature, 待使能的特性
  392. * @param {int} rtype, 请求类型,由FUsbGenerateReqType生成
  393. */
  394. FUsbTransCode FUsbSetFeature(FUsbDev *dev, int endp, int feature, int rtype)
  395. {
  396. FASSERT(dev && dev->controller && dev->controller->control);
  397. FUsbDevReq dr;
  398. dr.bmRequestType = rtype;
  399. dr.data_dir = FUSB_REQ_HOST_TO_DEVICE;
  400. dr.bRequest = FUSB_SET_FEATURE;
  401. dr.wValue = feature;
  402. dr.wIndex = endp;
  403. dr.wLength = 0;
  404. return dev->controller->control(dev, FUSB_OUT, sizeof(dr), &dr, 0, NULL);
  405. }
  406. /**
  407. * @name: FUsbGetStatus
  408. * @msg: 标准USB主机请求,获取设备/接口/端点的状态
  409. * @return {FUsbTransCode} 控制传输的返回值,小于0表示失败,大于0表示成功传输的字节数目
  410. * @param {FUsbDev} *dev, USB设备实例
  411. * @param {int} intf,设备号(0x00)/接口号/端点号
  412. * @param {int} rtype, 请求类型,由FUsbGenerateReqType生成
  413. * @param {int} len, Data Stage的数据长度
  414. * @param {void} *data, Data Stage的数据缓冲区
  415. */
  416. FUsbTransCode FUsbGetStatus(FUsbDev *dev, int intf, int rtype, int len, void *data)
  417. {
  418. FASSERT(dev && dev->controller && dev->controller->control);
  419. FUsbDevReq dr;
  420. dr.bmRequestType = rtype;
  421. dr.data_dir = FUSB_REQ_DEVICE_TO_HOST;
  422. dr.bRequest = FUSB_GET_STATUS;
  423. dr.wValue = 0;
  424. dr.wIndex = intf;
  425. dr.wLength = len;
  426. return dev->controller->control(dev, FUSB_IN, sizeof(dr), &dr, len, data);
  427. }
  428. /**
  429. * @name: FUsbGetDescriptor
  430. * @msg: 标准USB主机请求,获取指定描述符
  431. * @return {FUsbTransCode} 控制传输的返回值,小于0表示失败,大于0表示成功传输的字节数目
  432. * @param {FUsbDev} *dev, USB设备实例
  433. * @param {int} rtype, 请求类型,由FUsbGenerateReqType生成
  434. * @param {FUsbDescriptorType} desc_type, 描述符类型
  435. * @param {int} desc_idx, 描述符索引
  436. * @param {void} *data, Data Stage的数据缓冲区
  437. * @param {size_t} len, Data Stage的数据长度
  438. */
  439. FUsbTransCode FUsbGetDescriptor(FUsbDev *dev, int rtype, FUsbDescriptorType desc_type, int desc_idx, void *data,
  440. size_t len)
  441. {
  442. FASSERT(dev && dev->controller && dev->controller->control);
  443. FUsbDevReq dr;
  444. int fail_tries = 0;
  445. FUsbTransCode ret = FUSB_CC_ZERO_BYTES;
  446. while (fail_tries++ < FUSB_GET_DESCRIPTOR_RETRIES)
  447. {
  448. dr.bmRequestType = rtype;
  449. dr.bRequest = FUSB_GET_DESCRIPTOR;
  450. dr.wValue = desc_type << 8 | desc_idx;
  451. dr.wIndex = 0;
  452. dr.wLength = len;
  453. ret = dev->controller->control(dev, FUSB_IN,
  454. sizeof(dr), &dr, len, data);
  455. if (ret == (int)len)
  456. break;
  457. fsleep_microsec(10);
  458. }
  459. return ret;
  460. }
  461. /**
  462. * @name: FUsbGetStringDescriptor
  463. * @msg: USB主机请求,获取字符串描述符
  464. * @return {int} 控制传输的返回值,小于0表示失败,大于0表示成功传输的字节数目
  465. * @param {FUsbDev} *dev, USB设备实例
  466. * @param {int} rtype, 请求类型,由FUsbGenerateReqType生成
  467. * @param {int} desc_type, 描述符类型
  468. * @param {int} desc_idx, 描述符索引
  469. * @param {int} lang_id, 语言类型
  470. * @param {void} *data, Data Stage的数据缓冲区
  471. * @param {size_t} len, Data Stage的数据长度
  472. */
  473. FUsbTransCode FUsbGetStringDescriptor(FUsbDev *dev, int rtype, FUsbDescriptorType desc_type, int desc_idx, int lang_id, void *data, size_t len)
  474. {
  475. FASSERT(dev && dev->controller && dev->controller->control);
  476. FUsbDevReq dr;
  477. int fail_tries = 0;
  478. FUsbTransCode ret = FUSB_CC_ZERO_BYTES;
  479. while (fail_tries++ < FUSB_GET_DESCRIPTOR_RETRIES)
  480. {
  481. dr.bmRequestType = rtype;
  482. dr.bRequest = FUSB_GET_DESCRIPTOR;
  483. dr.wValue = desc_type << 8 | desc_idx;
  484. dr.wIndex = lang_id;
  485. dr.wLength = len;
  486. ret = dev->controller->control(dev, FUSB_IN, sizeof(dr), &dr, len, data);
  487. if (ret == (int)len)
  488. break;
  489. fsleep_microsec(10);
  490. }
  491. return ret;
  492. }
  493. /**
  494. * @name: FUsbSetConfiguration
  495. * @msg: 标准USB主机请求,设置配置值
  496. * @return {FUsbTransCode} 控制传输的返回值,小于0表示失败,大于0表示成功传输的字节数目
  497. * @param {FUsbDev} *dev, USB设备实例
  498. */
  499. FUsbTransCode FUsbSetConfiguration(FUsbDev *dev)
  500. {
  501. FASSERT(dev && dev->controller && dev->controller->control);
  502. FUsbDevReq dr;
  503. dr.bmRequestType = 0;
  504. dr.bRequest = FUSB_SET_CONFIGURATION;
  505. dr.wValue = dev->configuration->bConfigurationValue;
  506. dr.wIndex = 0;
  507. dr.wLength = 0;
  508. return dev->controller->control(dev, FUSB_OUT, sizeof(dr), &dr, 0, NULL);
  509. }
  510. /**
  511. * @name: FUsbClearFeature
  512. * @msg: 标准USB主机请求,去使能设备/接口/端点的某个特性
  513. * @return {FUsbTransCode} 控制传输的返回值,小于0表示失败,大于0表示成功传输的字节数目
  514. * @param {FUsbDev} *dev, USB设备实例
  515. * @param {int} endp, 设备号(0x00)/接口号/端点号
  516. * @param {int} feature,待去除的特性
  517. * @param {int} rtype, 请求类型,由FUsbGenerateReqType生成
  518. */
  519. FUsbTransCode FUsbClearFeature(FUsbDev *dev, int endp, int feature, int rtype)
  520. {
  521. FASSERT(dev && dev->controller && dev->controller->control);
  522. FUsbDevReq dr;
  523. dr.bmRequestType = rtype;
  524. dr.data_dir = FUSB_REQ_HOST_TO_DEVICE;
  525. dr.bRequest = FUSB_CLEAR_FEATURE;
  526. dr.wValue = feature;
  527. dr.wIndex = endp;
  528. dr.wLength = 0;
  529. return dev->controller->control(dev, FUSB_OUT, sizeof(dr), &dr, 0, NULL) < 0;
  530. }
  531. /**
  532. * @name: FUsbSpeedtoDefaultMaxPacketSz
  533. * @msg: 根据设备速度获取最大包长度
  534. * @return {int} 最大包长度
  535. * @param {FUsbSpeed} speed, 设备速度类型
  536. */
  537. int FUsbSpeedtoDefaultMaxPacketSz(FUsbSpeed speed)
  538. {
  539. switch (speed)
  540. {
  541. case FUSB_LOW_SPEED:
  542. return 8;
  543. case FUSB_FULL_SPEED:
  544. case FUSB_HIGH_SPEED:
  545. return 64;
  546. case FUSB_SUPER_SPEED:
  547. /* Intentional fallthrough */
  548. case FUSB_SUPER_SPEED_PLUS:
  549. default:
  550. return 512;
  551. }
  552. }
  553. /**
  554. * @name: FUsbDecodeInterval
  555. * @msg: 获取USB传输间隔时间
  556. * @return {int} 传输间隔时间, 0表示失败
  557. * @param {FUsbSpeed} speed, USB设备速度类型
  558. * @param {FUsbEpType} type, 端点类型
  559. * @param {unsigned char} bInterval, 设置的间隔时间
  560. */
  561. static int FUsbDecodeInterval(FUsbSpeed speed, const FUsbEpType type, const unsigned char bInterval)
  562. {
  563. /* Normalize bInterval to log2 of microframes */
  564. #define LOG2(a) ((sizeof(unsigned) << 3) - __builtin_clz(a) - 1)
  565. switch (speed)
  566. {
  567. case FUSB_LOW_SPEED:
  568. switch (type)
  569. {
  570. case FUSB_ISOCHRONOUS_EP:
  571. case FUSB_INTERRUPT_EP:
  572. return LOG2(bInterval) + 3;
  573. default:
  574. return 0;
  575. }
  576. case FUSB_FULL_SPEED:
  577. switch (type)
  578. {
  579. case FUSB_ISOCHRONOUS_EP:
  580. return (bInterval - 1) + 3;
  581. case FUSB_INTERRUPT_EP:
  582. return LOG2(bInterval) + 3;
  583. default:
  584. return 0;
  585. }
  586. case FUSB_HIGH_SPEED:
  587. switch (type)
  588. {
  589. case FUSB_ISOCHRONOUS_EP:
  590. case FUSB_INTERRUPT_EP:
  591. return bInterval - 1;
  592. default:
  593. return LOG2(bInterval);
  594. }
  595. case FUSB_SUPER_SPEED:
  596. /* Intentional fallthrough */
  597. case FUSB_SUPER_SPEED_PLUS:
  598. switch (type)
  599. {
  600. case FUSB_ISOCHRONOUS_EP:
  601. case FUSB_INTERRUPT_EP:
  602. return bInterval - 1;
  603. default:
  604. return 0;
  605. }
  606. default:
  607. return 0;
  608. }
  609. #undef LOG2
  610. }
  611. /**
  612. * @name: FUsbSetAddress
  613. * @msg: 获取USB设备的描述符信息,根据USB设备类型完成配置和初始化
  614. * @return {FUsbDevAddr} 为USB设备分配的地址,-1表示USB设备初始化失败
  615. * @param {FUsbHc} *controller, USB控制器实例
  616. * @param {FUsbSpeed} speed, USB设备速度类型
  617. * @param {int} hubport, USB设备连接的Hub端口号
  618. * @param {int} hubaddr, USB设备连接Hub的地址
  619. */
  620. static FUsbDevAddr FUsbSetAddress(FUsbHc *controller, FUsbSpeed speed, int hubport, int hubaddr)
  621. {
  622. FASSERT(controller);
  623. FUsbDev *dev = controller->set_address(controller, speed,
  624. hubport, hubaddr);
  625. FUsbDevIndex index;
  626. FUsbDevInitHandler init_handler = NULL;
  627. FUsb *instace = controller->usb;
  628. FASSERT(instace);
  629. if (NULL == dev)
  630. {
  631. FUSB_INFO("set_address failed ");
  632. return FUSB_NO_DEV_ADDR;
  633. }
  634. FASSERT(NULL == dev->descriptor);
  635. dev->descriptor = FUSB_ALLOCATE(instace, sizeof(*dev->descriptor), FUSB_DEFAULT_ALIGN);
  636. if ((NULL == dev->descriptor) || FUsbGetDescriptor(dev, FUSB_DR_DESC, FUSB_DESC_TYPE_DEVICE, 0,
  637. dev->descriptor, sizeof(*dev->descriptor)) != sizeof(*dev->descriptor))
  638. {
  639. FUSB_INFO("FUsbGetDescriptor(FUSB_DESC_TYPE_DEVICE) failed ");
  640. FUsbDetachDev(controller, dev->address);
  641. return FUSB_NO_DEV_ADDR;
  642. }
  643. FUSB_INFO("* found device (0x%04x:0x%04x, USB %x.%x, MPS0: %d) ",
  644. dev->descriptor->idVendor, dev->descriptor->idProduct,
  645. dev->descriptor->bcdUSB >> 8, dev->descriptor->bcdUSB & 0xff,
  646. dev->endpoints[0].maxpacketsize);
  647. FUSB_INFO("device has %d configurations ",
  648. dev->descriptor->bNumConfigurations);
  649. if (dev->descriptor->bNumConfigurations == 0)
  650. {
  651. /* device isn't usable */
  652. FUSB_INFO("... no usable configuration! ");
  653. FUsbDetachDev(controller, dev->address);
  654. return FUSB_NO_DEV_ADDR;
  655. }
  656. u16 buf[2];
  657. if (FUsbGetDescriptor(dev, FUSB_DR_DESC, FUSB_DESC_TYPE_CONFIG, 0, buf, sizeof(buf)) != sizeof(buf))
  658. {
  659. FUSB_INFO("first FUsbGetDescriptor(FUSB_DESC_TYPE_CONFIG) failed ");
  660. FUsbDetachDev(controller, dev->address);
  661. return FUSB_NO_DEV_ADDR;
  662. }
  663. /* workaround for some USB devices: wait until they're ready, or
  664. * they send a NAK when they're not allowed to do. 1ms is enough */
  665. fsleep_millisec(1);
  666. FASSERT(NULL == dev->configuration);
  667. dev->configuration = FUSB_ALLOCATE(instace, buf[1], FUSB_DEFAULT_ALIGN);
  668. if (NULL == dev->configuration)
  669. {
  670. FUSB_INFO("could not allocate %d bytes for FUSB_DESC_TYPE_CONFIG ", buf[1]);
  671. FUsbDetachDev(controller, dev->address);
  672. return FUSB_NO_DEV_ADDR;
  673. }
  674. if (FUsbGetDescriptor(dev, FUSB_DR_DESC, FUSB_DESC_TYPE_CONFIG, 0, dev->configuration,
  675. buf[1]) != buf[1])
  676. {
  677. FUSB_INFO("FUsbGetDescriptor(FUSB_DESC_TYPE_CONFIG) failed ");
  678. FUsbDetachDev(controller, dev->address);
  679. return FUSB_NO_DEV_ADDR;
  680. }
  681. FUsbConfigurationDescriptor *cd = dev->configuration;
  682. if (cd->wTotalLength != buf[1])
  683. {
  684. FUSB_INFO("configuration descriptor size changed, aborting ");
  685. FUsbDetachDev(controller, dev->address);
  686. return FUSB_NO_DEV_ADDR;
  687. }
  688. /*
  689. * If the device is not well known (ifnum == -1), we use the first
  690. * interface we encounter, as there was no need to implement something
  691. * else for the time being. If you need it, see the SetInterface and
  692. * GetInterface functions in the USB specification and set it yourself.
  693. */
  694. FUSB_INFO("device has %x interfaces ", cd->bNumInterfaces);
  695. u8 *end = (void *)dev->configuration + cd->wTotalLength;
  696. FUsbInterfaceDescriptor *intf;
  697. u8 *ptr;
  698. /* Find our interface (or the first good one if we don't know) */
  699. for (ptr = (void *)dev->configuration + sizeof(*cd);; ptr += ptr[0])
  700. {
  701. if (ptr + 2 > end || !ptr[0] || ptr + ptr[0] > end)
  702. {
  703. FUSB_INFO("Couldn't find usable FUSB_DESC_TYPE_INTERFACE ");
  704. FUsbDetachDev(controller, dev->address);
  705. return FUSB_NO_DEV_ADDR;
  706. }
  707. if (ptr[1] != FUSB_DESC_TYPE_INTERFACE)
  708. continue;
  709. intf = (void *)ptr;
  710. if (intf->bLength != sizeof(*intf))
  711. {
  712. FUSB_INFO("Skipping broken FUSB_DESC_TYPE_INTERFACE ");
  713. continue;
  714. }
  715. FUSB_INFO("Interface %d: class 0x%x, sub 0x%x. proto 0x%x ",
  716. intf->bInterfaceNumber, intf->bInterfaceClass,
  717. intf->bInterfaceSubClass, intf->bInterfaceProtocol);
  718. ptr += sizeof(*intf);
  719. break;
  720. }
  721. /* Gather up all endpoints belonging to this interface */
  722. dev->num_endp = 1;
  723. for (; ptr + 2 <= end && ptr[0] && ptr + ptr[0] <= end; ptr += ptr[0])
  724. {
  725. if (ptr[1] == FUSB_DESC_TYPE_INTERFACE || ptr[1] == FUSB_DESC_TYPE_CONFIG ||
  726. (size_t)dev->num_endp >= ARRAY_SIZE(dev->endpoints))
  727. break;
  728. if (ptr[1] != FUSB_DESC_TYPE_ENDPOINT)
  729. continue;
  730. FUsbEndpointDescriptor *desc = (void *)ptr;
  731. static const char *transfertypes[4] =
  732. {
  733. "control", "isochronous", "bulk", "interrupt"
  734. };
  735. FUSB_INFO(" #Endpoint %d (%s), max packet size %x, type %s ",
  736. desc->bEndpointAddress & 0x7f,
  737. (desc->bEndpointAddress & 0x80) ? "in" : "out",
  738. desc->wMaxPacketSize,
  739. transfertypes[desc->bmAttributes & 0x3]);
  740. FUsbEndpoint *ep = &dev->endpoints[dev->num_endp++];
  741. ep->dev = dev;
  742. ep->endpoint = desc->bEndpointAddress;
  743. ep->toggle = 0;
  744. ep->maxpacketsize = desc->wMaxPacketSize;
  745. ep->direction = (desc->bEndpointAddress & 0x80) ? FUSB_IN : FUSB_OUT;
  746. ep->type = desc->bmAttributes & 0x3;
  747. ep->interval = FUsbDecodeInterval(dev->speed, ep->type,
  748. desc->bInterval);
  749. }
  750. if ((controller->finish_device_config &&
  751. controller->finish_device_config(dev)) ||
  752. FUsbSetConfiguration(dev) < 0)
  753. {
  754. FUSB_INFO("Could not finalize device configuration ");
  755. FUsbDetachDev(controller, dev->address);
  756. return FUSB_NO_DEV_ADDR;
  757. }
  758. int class = dev->descriptor->bDeviceClass;
  759. if (class == 0)
  760. class = intf->bInterfaceClass;
  761. switch (class)
  762. {
  763. case FUSB_AUDIO_DEVICE:
  764. FUSB_INFO("Audio Class ");
  765. break;
  766. case FUSB_COMM_DEVICE:
  767. FUSB_INFO("Communication Class ");
  768. break;
  769. case FUSB_HID_DEVICE:
  770. FUSB_INFO("HID Class ");
  771. break;
  772. case FUSB_PHYSICAL_DEVICE:
  773. FUSB_INFO("Physical Class");
  774. break;
  775. case FUSB_IMAGE_DEVICE:
  776. FUSB_INFO("Camera Class ");
  777. break;
  778. case FUSB_PRINTER_DEVICE:
  779. FUSB_INFO("Printer Class");
  780. break;
  781. case FUSB_MASS_STORAGE_DEVICE:
  782. FUSB_INFO("Mass Storage Class ");
  783. break;
  784. case FUSB_HUB_DEVICE:
  785. FUSB_INFO("Hub Class ");
  786. break;
  787. default:
  788. FUSB_ERROR("Unsupported Class %x ", class);
  789. break;
  790. }
  791. index.category = FUSB_STANDARD_INTERFACE;
  792. index.class = class;
  793. index.sub_class = intf->bInterfaceSubClass;
  794. index.protocol = intf->bInterfaceProtocol;
  795. FUSB_INFO("class: 0x%x sub-class: 0x%x, protocol: 0x%x",
  796. index.class, index.sub_class, index.protocol);
  797. init_handler = FUsbFindValidInitFunc(instace, &index);
  798. if (NULL != init_handler)
  799. {
  800. dev->init = init_handler;
  801. dev->class = (FUsbDevClass)class;
  802. }
  803. else
  804. {
  805. FUSB_WARN("Init function for the device not found, use generic one instead !!!");
  806. dev->init = FUsbGenericDevInit;
  807. }
  808. return dev->address;
  809. }
  810. /**
  811. * @name: FUsbDetachDev
  812. * @msg: 从USB主机移除指定USB设备(USB设备驱动使用)
  813. * @return {*}
  814. * @param {FUsbHc} *controller, USB控制器实例
  815. * @param {int} devno, USB设备索引
  816. * @note Should be called by the hub drivers whenever a physical detach occurs
  817. * and can be called by USB class drivers if they are unsatisfied with a
  818. * malfunctioning device.
  819. */
  820. void FUsbDetachDev(FUsbHc *controller, int devno)
  821. {
  822. FUsb *instace = controller->usb;
  823. /* check if device exists, as we may have
  824. been called yet by the USB class driver */
  825. if (controller->devices[devno])
  826. {
  827. controller->devices[devno]->destroy(controller->devices[devno]);
  828. if (controller->destroy_device)
  829. controller->destroy_device(controller, devno);
  830. FUSB_FREE(instace, controller->devices[devno]->descriptor);
  831. controller->devices[devno]->descriptor = NULL;
  832. FUSB_FREE(instace, controller->devices[devno]->configuration);
  833. controller->devices[devno]->configuration = NULL;
  834. /* Tear down the device itself *after* destroy_device()
  835. * has had a chance to interrogate it. */
  836. FUSB_FREE(instace, controller->devices[devno]);
  837. controller->devices[devno] = NULL;
  838. }
  839. return;
  840. }
  841. /**
  842. * @name: FUsbAttachDev
  843. * @msg: 向USB主机添加USB设备(USB设备驱动使用)
  844. * @return {FUsbDevAddr} 分配的USB设备地址
  845. * @param {FUsbHc} *controller, USB控制器实例
  846. * @param {int} hubaddress, Hub地址
  847. * @param {int} port, 连接的Port
  848. * @param {FUsbSpeed} speed, USB设备的设置速度类型
  849. */
  850. FUsbDevAddr FUsbAttachDev(FUsbHc *controller, int hubaddress, int port, FUsbSpeed speed)
  851. {
  852. static const char *speeds[] = {"FULL", "LOW", "HIGH", "SUPER", "ULTRA-SUPER"};
  853. FUSB_INFO("%s-Speed Device ", ((size_t)speed < sizeof(speeds) / sizeof(char *))
  854. ? speeds[speed]
  855. : "Unkonwn");
  856. FUsbDevAddr newdev = FUsbSetAddress(controller, speed, port, hubaddress);
  857. if (newdev == FUSB_NO_DEV_ADDR)
  858. return FUSB_NO_DEV_ADDR;
  859. FUsbDev *newdev_t = controller->devices[newdev];
  860. /* determine responsible driver - current done in set_address */
  861. newdev_t->init(newdev_t);
  862. /* init() may have called FUsbDetachDev() yet, so check */
  863. return controller->devices[newdev] ? newdev : FUSB_NO_DEV_ADDR;
  864. }
  865. /**
  866. * @name: FUsbGenericDestory
  867. * @msg: 一般USB设备去初始化函数
  868. * @return {*}
  869. * @param {FUsbDev} *dev, USB设备实例
  870. */
  871. static void FUsbGenericDestory(FUsbDev *dev)
  872. {
  873. if (FUsbGenericRemove)
  874. FUsbGenericRemove(dev);
  875. return;
  876. }
  877. /**
  878. * @name: FUsbGenericDevInit
  879. * @msg: 默认的USB设备初始化函数
  880. * @return {*}
  881. * @param {FUsbDev} *dev, USB设备实例
  882. */
  883. void FUsbGenericDevInit(FUsbDev *dev)
  884. {
  885. dev->data = NULL;
  886. dev->destroy = FUsbGenericDestory;
  887. if (FUsbGenericCreate)
  888. FUsbGenericCreate(dev);
  889. if (dev->data == NULL)
  890. {
  891. FUSB_INFO("Detaching device not used by payload ");
  892. FUsbDetachDev(dev->controller, dev->address);
  893. }
  894. return;
  895. }