usb_host.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. /*
  2. * USB host core
  3. *
  4. * Copyright (c) 2020 Actions Corporation
  5. * Author: Jinang Lv <lvjinang@actions-semi.com>
  6. *
  7. * SPDX-License-Identifier: Apache-2.0
  8. */
  9. /**
  10. * @file
  11. * @brief USB host core layer
  12. *
  13. * NOTE:
  14. * 1. usb hub is NOT supported
  15. * 2. only ONE usb device is supported
  16. */
  17. #include <sys/byteorder.h>
  18. #include <drivers/gpio.h>
  19. #include <usb/usb_host.h>
  20. #include <logging/log.h>
  21. #define LOG_LEVEL CONFIG_SYS_LOG_USB_HOST_LEVEL
  22. LOG_MODULE_REGISTER(usb_host);
  23. #define DEVNUM_DEFAULT 1
  24. #define NO_OF_RH_PORTS 1
  25. #define PORT_RESET_TRIES 5
  26. #define SET_ADDRESS_TRIES 2
  27. #define GET_DESCRIPTOR_TRIES 2
  28. #define HUB_ROOT_RESET_TIME 50 /* times are in msec */
  29. #define HUB_SHORT_RESET_TIME 10
  30. #define HUB_BH_RESET_TIME 50
  31. #define HUB_LONG_RESET_TIME 200
  32. #define HUB_RESET_TIMEOUT 800
  33. static struct usb_device usbh_dev;
  34. static sys_slist_t usb_drivers;
  35. static void usbh_set_device_state(struct usb_device *udev,
  36. enum usb_device_state new_state)
  37. {
  38. unsigned int key;
  39. key = irq_lock();
  40. if (udev->state == USB_STATE_NOTATTACHED) {
  41. ; /* do nothing */
  42. } else {
  43. udev->state = new_state;
  44. }
  45. irq_unlock(key);
  46. }
  47. //should be defined in the file: board.h, Pay attention to the
  48. //conflict of pin use, for example, the pin may be used for key detection
  49. #define BOARD_USB_HOST_VBUS_EN_GPIO_NAME "GPIOB"
  50. #define BOARD_USB_HOST_VBUS_EN_GPIO 22 /* Vbus power en gpio for USB host */
  51. #define BOARD_USB_HOST_VBUS_EN_GPIO_VALUE 1 /* Value to enable */
  52. int usbh_vbus_set(bool on)
  53. {
  54. #ifdef BOARD_USB_HOST_VBUS_EN_GPIO_NAME
  55. static const struct device *usbh_gpio_dev;
  56. static u8_t usbh_gpio_value;
  57. u32_t value;
  58. int ret;
  59. if (usbh_gpio_dev == NULL) {
  60. usbh_gpio_dev = device_get_binding(BOARD_USB_HOST_VBUS_EN_GPIO_NAME);
  61. gpio_pin_configure(usbh_gpio_dev, BOARD_USB_HOST_VBUS_EN_GPIO,
  62. GPIO_OUTPUT);
  63. }
  64. value = BOARD_USB_HOST_VBUS_EN_GPIO_VALUE;
  65. if (!on) {
  66. value = !value;
  67. }
  68. /* already */
  69. if (value == usbh_gpio_value) {
  70. return 0;
  71. }
  72. usbh_gpio_value = value;
  73. ret = gpio_pin_set(usbh_gpio_dev, BOARD_USB_HOST_VBUS_EN_GPIO,
  74. value);
  75. if (ret) {
  76. return ret;
  77. }
  78. #endif
  79. return 0;
  80. }
  81. /* returns 0 if no match, 1 if match */
  82. static inline int usb_match_one_id_intf(const struct usb_if_descriptor *desc,
  83. const struct usb_device_id *id)
  84. {
  85. if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
  86. (id->bInterfaceClass != desc->bInterfaceClass)) {
  87. return 0;
  88. }
  89. if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
  90. (id->bInterfaceSubClass != desc->bInterfaceSubClass)) {
  91. return 0;
  92. }
  93. if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
  94. (id->bInterfaceProtocol != desc->bInterfaceProtocol)) {
  95. return 0;
  96. }
  97. return 1;
  98. }
  99. /* returns 0 if no match, 1 if match */
  100. static const inline struct usb_device_id *usb_match_id(
  101. struct usb_if_descriptor *desc,
  102. const struct usb_device_id *id)
  103. {
  104. for (; id->idVendor || id->idProduct || id->bDeviceClass ||
  105. id->bInterfaceClass || id->driver_info; id++) {
  106. if (usb_match_one_id_intf(desc, id)) {
  107. return id;
  108. }
  109. }
  110. return NULL;
  111. }
  112. static inline int usbh_probe_interface(struct usb_interface *intf)
  113. {
  114. const struct usb_device_id *id;
  115. struct usb_driver *driver;
  116. sys_snode_t *node;
  117. int ret;
  118. LOG_DBG("");
  119. if (sys_slist_is_empty(&usb_drivers)) {
  120. return -EINVAL;
  121. }
  122. node = sys_slist_peek_head(&usb_drivers);
  123. do {
  124. driver = CONTAINER_OF(node, struct usb_driver, node);
  125. id = usb_match_id(&intf->desc, driver->id_table);
  126. if (id) {
  127. intf->driver = driver; /* bind first */
  128. ret = driver->probe(intf, driver->id_table);
  129. if (ret) {
  130. intf->driver = NULL;
  131. return ret;
  132. }
  133. }
  134. node = sys_slist_peek_next(node);
  135. } while (node);
  136. return 0;
  137. }
  138. int usbh_submit_urb(struct usb_request *urb)
  139. {
  140. if (!urb || !urb->complete) {
  141. return -EINVAL;
  142. }
  143. if (usbh_dev.state < USB_STATE_UNAUTHENTICATED) {
  144. LOG_INF("%d", usbh_dev.state);
  145. return -ENODEV;
  146. }
  147. urb->status = -EBUSY;
  148. urb->actual = 0;
  149. return usb_hc_submit_urb(urb);
  150. }
  151. int usbh_cancel_urb(struct usb_request *urb)
  152. {
  153. unsigned int key = irq_lock();
  154. int ret = 0;
  155. if (urb->status != -EBUSY) {
  156. goto done;
  157. }
  158. /* canceled or timeout */
  159. urb->status = -ECONNRESET;
  160. ret = usb_hc_cancel_urb(urb);
  161. done:
  162. irq_unlock(key);
  163. return ret;
  164. }
  165. static void usbh_blocking_completion(struct usb_request *urb)
  166. {
  167. struct k_sem *sem = urb->context;
  168. k_sem_give(sem);
  169. }
  170. static inline int usbh_start_wait_urb(struct usb_request *urb, int timeout,
  171. u32_t *actual)
  172. {
  173. struct k_sem sem;
  174. int ret;
  175. k_sem_init(&sem, 0, 1);
  176. urb->complete = usbh_blocking_completion;
  177. urb->context = &sem;
  178. if (timeout == 0) {
  179. timeout = K_TICKS_FOREVER;
  180. }
  181. ret = usbh_submit_urb(urb);
  182. if (ret) {
  183. return ret;
  184. }
  185. /* Semaphore will be released by the transfer completion callback */
  186. ret = k_sem_take(&sem, K_MSEC(timeout));
  187. if (ret == -EAGAIN) {
  188. usbh_cancel_urb(urb);
  189. }
  190. if (actual) {
  191. *actual = urb->actual;
  192. }
  193. return urb->status;
  194. }
  195. int usbh_transfer_urb_sync(struct usb_request *urb)
  196. {
  197. return usbh_start_wait_urb(urb, K_TICKS_FOREVER, NULL);
  198. }
  199. int usbh_control_msg(unsigned char request, unsigned char requesttype,
  200. unsigned short value, unsigned short index,
  201. void *data, unsigned short size, int timeout)
  202. {
  203. struct usb_setup_packet setup_packet __aligned(2);
  204. struct usb_request urb;
  205. int length;
  206. int ret;
  207. /* set setup command */
  208. setup_packet.bmRequestType = requesttype;
  209. setup_packet.bRequest = request;
  210. setup_packet.wValue = sys_cpu_to_le16(value);
  211. setup_packet.wIndex = sys_cpu_to_le16(index);
  212. setup_packet.wLength = sys_cpu_to_le16(size);
  213. LOG_DBG("request: 0x%X, requesttype: 0x%X, " \
  214. "value 0x%X index 0x%X length 0x%X",
  215. request, requesttype, value, index, size);
  216. /* for data phase */
  217. if (USB_REQ_DIR_IN(requesttype)) {
  218. urb.ep = USB_CONTROL_IN_EP0;
  219. } else {
  220. urb.ep = USB_CONTROL_OUT_EP0;
  221. }
  222. urb.ep_type = USB_EP_CONTROL;
  223. urb.buf = data;
  224. urb.len = size;
  225. urb.setup_packet = (u8_t *)&setup_packet;
  226. ret = usbh_start_wait_urb(&urb, timeout, &length);
  227. if (ret < 0) {
  228. return ret;
  229. } else {
  230. return length;
  231. }
  232. }
  233. int usbh_bulk_msg(u8_t ep, void *data, int len, u32_t *actual, int timeout)
  234. {
  235. struct usb_request urb;
  236. urb.ep = ep;
  237. urb.ep_type = USB_EP_BULK;
  238. urb.buf = data;
  239. urb.len = len;
  240. return usbh_start_wait_urb(&urb, timeout, actual);
  241. }
  242. /* clear endpoint halt/stall condition */
  243. int usbh_clear_halt(u8_t ep)
  244. {
  245. int ret;
  246. LOG_DBG("0x%x", ep);
  247. ret = usbh_control_msg(USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
  248. USB_ENDPOINT_HALT, ep, NULL, 0,
  249. USB_CTRL_TIMEOUT);
  250. if (ret) {
  251. return ret;
  252. }
  253. return usb_hc_ep_reset(ep);
  254. }
  255. static inline int usbh_root_control(unsigned char request,
  256. unsigned char requesttype,
  257. unsigned short value, unsigned short index,
  258. void *data, unsigned short size,
  259. int timeout)
  260. {
  261. struct usb_setup_packet setup_packet __aligned(2);
  262. if (usbh_dev.state == USB_STATE_NOTATTACHED) {
  263. return -ENODEV;
  264. }
  265. /* set setup command */
  266. setup_packet.bmRequestType = requesttype;
  267. setup_packet.bRequest = request;
  268. setup_packet.wValue = sys_cpu_to_le16(value);
  269. setup_packet.wIndex = sys_cpu_to_le16(index);
  270. setup_packet.wLength = sys_cpu_to_le16(size);
  271. LOG_DBG("request: 0x%X, requesttype: 0x%X, " \
  272. "value 0x%X index 0x%X length 0x%X",
  273. request, requesttype, value, index, size);
  274. return usb_hc_root_control(data, size, &setup_packet, timeout);
  275. }
  276. static inline int clear_port_feature(int port, int feature)
  277. {
  278. return usbh_root_control(USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature,
  279. port, NULL, 0, USB_CTRL_TIMEOUT);
  280. }
  281. static inline int set_port_feature(int port, int feature)
  282. {
  283. return usbh_root_control(USB_REQ_SET_FEATURE, USB_RT_PORT, feature,
  284. port, NULL, 0, USB_CTRL_TIMEOUT);
  285. }
  286. static inline int hub_port_status(int port1, u16_t *status, u16_t *change)
  287. {
  288. int ret;
  289. struct usb_port_status portsts;
  290. ret = usbh_root_control(USB_REQ_GET_STATUS,
  291. USB_DIR_IN | USB_RT_PORT, 0, port1,
  292. &portsts, sizeof(portsts), USB_CTRL_TIMEOUT);
  293. if (ret < 4) {
  294. return ret;
  295. }
  296. *status = sys_le16_to_cpu(portsts.wPortStatus);
  297. *change = sys_le16_to_cpu(portsts.wPortChange);
  298. LOG_DBG("portstatus %x, change %x", *status, *change);
  299. return 0;
  300. }
  301. static inline int hub_port_wait_reset(int port1, int delay)
  302. {
  303. unsigned short portstatus = 0, portchange = 0;
  304. int delay_time, ret;
  305. for (delay_time = 0;
  306. delay_time < HUB_RESET_TIMEOUT;
  307. delay_time += delay) {
  308. /* wait to give the device a chance to reset */
  309. k_sleep(K_MSEC(delay));
  310. /* read and decode port status */
  311. ret = hub_port_status(port1, &portstatus, &portchange);
  312. if (ret < 0) {
  313. return ret;
  314. }
  315. /* The port state is unknown until the reset completes. */
  316. if (!(portstatus & USB_PORT_STAT_RESET)) {
  317. break;
  318. }
  319. }
  320. if ((portstatus & USB_PORT_STAT_RESET)) {
  321. return -EBUSY;
  322. }
  323. /* Device went away? */
  324. if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
  325. return -ENOTCONN;
  326. }
  327. if (!(portstatus & USB_PORT_STAT_ENABLE)) {
  328. return -EBUSY;
  329. }
  330. if (portstatus & USB_PORT_STAT_HIGH_SPEED) {
  331. usbh_dev.speed = USB_SPEED_HIGH;
  332. } else if (portstatus & USB_PORT_STAT_LOW_SPEED) {
  333. usbh_dev.speed = USB_SPEED_LOW;
  334. } else {
  335. usbh_dev.speed = USB_SPEED_FULL;
  336. }
  337. return 0;
  338. }
  339. static inline int hub_port_reset(int port1, int delay)
  340. {
  341. int i, status;
  342. LOG_DBG("");
  343. for (i = 0; i < PORT_RESET_TRIES; i++) {
  344. status = set_port_feature(port1, USB_PORT_FEAT_RESET);
  345. if (status < 0) {
  346. ;
  347. } else {
  348. status = hub_port_wait_reset(port1, delay);
  349. }
  350. if (status == 0) {
  351. k_sleep(K_MSEC(50));
  352. usbh_set_device_state(&usbh_dev, USB_STATE_DEFAULT);
  353. break;
  354. } else if (status == -ENOTCONN || status == -ENODEV) {
  355. clear_port_feature(port1, USB_PORT_FEAT_C_RESET);
  356. usbh_set_device_state(&usbh_dev, USB_STATE_NOTATTACHED);
  357. break;
  358. }
  359. }
  360. LOG_DBG("done");
  361. return status;
  362. }
  363. static inline int usbh_get_descriptor(unsigned char type,
  364. unsigned char index, void *buf, int size)
  365. {
  366. return usbh_control_msg(USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
  367. (type << 8) + index, 0,
  368. buf, size, USB_CTRL_TIMEOUT);
  369. }
  370. static inline int usbh_get_device_descriptor(int size)
  371. {
  372. LOG_DBG("%d", size);
  373. return usbh_get_descriptor(USB_DEVICE_DESC, 0, &usbh_dev.desc, size);
  374. }
  375. static inline int usbh_set_address(u8_t addr)
  376. {
  377. int ret;
  378. LOG_DBG("");
  379. usbh_dev.devnum = addr;
  380. ret = usbh_control_msg(USB_REQ_SET_ADDRESS, 0, addr, 0,
  381. NULL, 0, USB_CTRL_TIMEOUT);
  382. if (ret) {
  383. return ret;
  384. }
  385. return usb_hc_set_address(DEVNUM_DEFAULT);
  386. }
  387. static inline int usbh_parse_configuration(u8_t *buf, int len, int cfgidx)
  388. {
  389. struct usb_config *config = &usbh_dev.config;
  390. int index, ifno, epno, curr_if_num;
  391. struct usb_interface *intf = NULL;
  392. struct usb_desc_header *head;
  393. ARG_UNUSED(cfgidx);
  394. ifno = epno = curr_if_num = -1;
  395. config->no_of_if = 0;
  396. index = config->desc.bLength;
  397. head = (struct usb_desc_header *)&buf[index];
  398. while (index + 1 < len && head->bLength) {
  399. switch (head->bDescriptorType) {
  400. case USB_INTERFACE_DESC:
  401. if (head->bLength != USB_INTERFACE_DESC_SIZE) {
  402. LOG_ERR("intf %d %d", head->bDescriptorType,
  403. head->bLength);
  404. break;
  405. }
  406. if (index + USB_INTERFACE_DESC_SIZE > len) {
  407. LOG_ERR("intf overflow");
  408. break;
  409. }
  410. if (((struct usb_if_descriptor *) \
  411. head)->bInterfaceNumber != curr_if_num) {
  412. ifno = config->no_of_if;
  413. if (ifno >= USB_MAXINTERFACES) {
  414. LOG_ERR("Too many intf\n");
  415. /* try to go on with what we have */
  416. return -EINVAL;
  417. }
  418. intf = &config->intf[ifno];
  419. config->no_of_if++;
  420. memcpy(intf, head, USB_INTERFACE_DESC_SIZE);
  421. intf->no_of_ep = 0;
  422. intf->num_altsetting = 1;
  423. curr_if_num = intf->desc.bInterfaceNumber;
  424. } else {
  425. /* found alternate setting for the interface */
  426. if (ifno >= 0) {
  427. intf = &config->intf[ifno];
  428. intf->num_altsetting++;
  429. }
  430. }
  431. break;
  432. case USB_ENDPOINT_DESC:
  433. if (head->bLength != USB_ENDPOINT_DESC_SIZE) {
  434. LOG_ERR("endp %d %d", head->bDescriptorType,
  435. head->bLength);
  436. break;
  437. }
  438. if (index + USB_ENDPOINT_DESC_SIZE > len) {
  439. LOG_ERR("endp overflow");
  440. break;
  441. }
  442. if (ifno < 0) {
  443. LOG_ERR("endp out of order");
  444. break;
  445. }
  446. epno = config->intf[ifno].no_of_ep;
  447. intf = &config->intf[ifno];
  448. if (epno >= USB_MAXENDPOINTS) {
  449. LOG_ERR("intf %d has too many endp", ifno);
  450. return -EINVAL;
  451. }
  452. /* found an endpoint */
  453. intf->no_of_ep++;
  454. memcpy(&intf->ep_desc[epno], head,
  455. USB_ENDPOINT_DESC_SIZE);
  456. /* (u8_t *)(&((struct usb_ep_descriptor *)head->wMaxPacketSize)) */
  457. intf->ep_desc[epno].wMaxPacketSize = sys_get_le16(((u8_t *)head + 4));
  458. break;
  459. case USB_INTERFACE_ASSOC_DESC:
  460. default:
  461. if (head->bLength == 0) {
  462. return -EINVAL;
  463. }
  464. LOG_DBG("unknown : %x", head->bDescriptorType);
  465. break;
  466. }
  467. index += head->bLength;
  468. head = (struct usb_desc_header *)&buf[index];
  469. }
  470. return 0;
  471. }
  472. static inline int usbh_get_configuration(void)
  473. {
  474. u8_t *tmp = usbh_dev.config.rawdescriptors;
  475. u16_t length;
  476. int ret;
  477. LOG_DBG("");
  478. ret = usbh_get_descriptor(USB_CONFIGURATION_DESC, 0,
  479. &usbh_dev.config.desc, USB_CONFIGURATION_DESC_SIZE);
  480. if (ret < USB_CONFIGURATION_DESC_SIZE) {
  481. LOG_ERR("config: %d", ret);
  482. return -EIO;
  483. }
  484. length = sys_le16_to_cpu(usbh_dev.config.desc.wTotalLength);
  485. if (length > USB_RAW_DESCRIPTORS_SIZE) {
  486. LOG_WRN("long: %d", length);
  487. length = USB_RAW_DESCRIPTORS_SIZE;
  488. }
  489. ret = usbh_get_descriptor(USB_CONFIGURATION_DESC, 0, tmp, length);
  490. if (ret < 0) {
  491. LOG_ERR("all: %d", ret);
  492. return ret;
  493. }
  494. if (ret < length) {
  495. LOG_WRN("short: %d", ret);
  496. length = ret;
  497. }
  498. return usbh_parse_configuration(tmp, length, 0);
  499. }
  500. static inline int usbh_set_configuration(int configuration)
  501. {
  502. int ret;
  503. LOG_DBG("%d", configuration);
  504. ret = usbh_control_msg(USB_REQ_SET_CONFIGURATION, 0,
  505. configuration, 0, NULL, 0, USB_CTRL_TIMEOUT);
  506. if (ret) {
  507. LOG_ERR("%d", ret);
  508. return ret;
  509. }
  510. usbh_set_device_state(&usbh_dev, USB_STATE_CONFIGURED);
  511. return 0;
  512. }
  513. int usbh_enable_endpoint(struct usb_ep_descriptor *desc)
  514. {
  515. struct usb_hc_ep_cfg_data ep_cfg;
  516. int ret;
  517. LOG_DBG("0x%x", desc->bEndpointAddress);
  518. if (usbh_dev.state == USB_STATE_NOTATTACHED) {
  519. return -ENODEV;
  520. }
  521. ep_cfg.ep_addr = desc->bEndpointAddress;
  522. ep_cfg.ep_mps = desc->wMaxPacketSize;
  523. ep_cfg.ep_type = usb_endpoint_type(desc->bmAttributes);
  524. ret = usb_hc_ep_configure(&ep_cfg);
  525. if (ret) {
  526. LOG_ERR("configure ep%x: %d", ep_cfg.ep_addr, ret);
  527. return ret;
  528. }
  529. ret = usb_hc_ep_enable(ep_cfg.ep_addr);
  530. if (ret) {
  531. LOG_ERR("enable ep%x: %d", ep_cfg.ep_addr, ret);
  532. return ret;
  533. }
  534. return 0;
  535. }
  536. int usbh_disable_endpoint(struct usb_ep_descriptor *desc)
  537. {
  538. unsigned int key;
  539. int ret;
  540. LOG_DBG("0x%x", desc->bEndpointAddress);
  541. key = irq_lock();
  542. ret = usb_hc_ep_disable(desc->bEndpointAddress);
  543. irq_unlock(key);
  544. return ret;
  545. }
  546. int usbh_enable_interface(struct usb_interface *intf)
  547. {
  548. int i;
  549. for (i = 0; i < intf->no_of_ep; i++) {
  550. usbh_enable_endpoint(&intf->ep_desc[i]);
  551. }
  552. return 0;
  553. }
  554. int usbh_disable_interface(struct usb_interface *intf)
  555. {
  556. int i;
  557. for (i = 0; i < intf->no_of_ep; i++) {
  558. usbh_disable_endpoint(&intf->ep_desc[i]);
  559. }
  560. return 0;
  561. }
  562. /* Enable control EP */
  563. static inline int enable_ep0(u8_t mps)
  564. {
  565. struct usb_ep_descriptor desc;
  566. int ret;
  567. /* ep0-out */
  568. desc.bEndpointAddress = USB_CONTROL_OUT_EP0;
  569. desc.bmAttributes = USB_EP_CONTROL;
  570. desc.wMaxPacketSize = mps;
  571. ret = usbh_enable_endpoint(&desc);
  572. if (ret) {
  573. return ret;
  574. }
  575. /* ep0-in */
  576. desc.bEndpointAddress = USB_CONTROL_IN_EP0;
  577. usbh_enable_endpoint(&desc);
  578. if (ret) {
  579. return ret;
  580. }
  581. return ret;
  582. }
  583. /* Disable control EP */
  584. static inline int disable_ep0(void)
  585. {
  586. struct usb_ep_descriptor desc;
  587. desc.bEndpointAddress = USB_CONTROL_OUT_EP0;
  588. usbh_disable_endpoint(&desc);
  589. desc.bEndpointAddress = USB_CONTROL_IN_EP0;
  590. usbh_disable_endpoint(&desc);
  591. return 0;
  592. }
  593. static inline int usbh_enumerate_device(void)
  594. {
  595. struct usb_interface *intf;
  596. int ret;
  597. u8_t i;
  598. ret = usbh_get_configuration();
  599. if (ret) {
  600. return ret;
  601. }
  602. /* FIXME: get string descriptors */
  603. #if 0
  604. if (usbh_dev.desc.iManufacturer)
  605. usb_string(usbh_dev.desc.iManufacturer,
  606. usbh_dev.mf, sizeof(usbh_dev.mf));
  607. if (usbh_dev.desc.iProduct)
  608. usb_string(usbh_dev.desc.iProduct,
  609. usbh_dev.prod, sizeof(usbh_dev.prod));
  610. if (usbh_dev.desc.iSerialNumber)
  611. usb_string(usbh_dev.desc.iSerialNumber,
  612. usbh_dev.serial, sizeof(usbh_dev.serial));
  613. LOG_DBG("mf: %s, prod: %s, sn: %s",
  614. usbh_dev.mf, usbh_dev.prod, usbh_dev.serial);
  615. #endif
  616. ret = usbh_set_configuration(usbh_dev.config.desc.bConfigurationValue);
  617. if (ret) {
  618. return ret;
  619. }
  620. for (i = 0; i < usbh_dev.config.no_of_if; i++) {
  621. intf = &usbh_dev.config.intf[i];
  622. ret = usbh_probe_interface(intf);
  623. if (ret) {
  624. return ret;
  625. }
  626. }
  627. return 0;
  628. }
  629. static inline int hub_port_init(int port1)
  630. {
  631. int ret;
  632. LOG_DBG("");
  633. usbh_set_device_state(&usbh_dev, USB_STATE_POWERED);
  634. ret = hub_port_reset(port1, HUB_ROOT_RESET_TIME);
  635. if (ret) {
  636. LOG_ERR("reset: %d", ret);
  637. return ret;
  638. }
  639. LOG_INF("speed: %d", usbh_dev.speed);
  640. /* default bMaxPacketSize0: 64 */
  641. ret = enable_ep0(USB_MAX_CTRL_MPS);
  642. if (ret) {
  643. return ret;
  644. }
  645. ret = usbh_get_device_descriptor(64);
  646. if (ret < 8) {
  647. LOG_ERR("device desc(64): %d", ret);
  648. return -EIO;
  649. }
  650. if (usbh_dev.desc.bMaxPacketSize0 != USB_MAX_CTRL_MPS) {
  651. ret = enable_ep0(usbh_dev.desc.bMaxPacketSize0);
  652. if (ret) {
  653. return ret;
  654. }
  655. }
  656. ret = hub_port_reset(port1, HUB_ROOT_RESET_TIME);
  657. if (ret) {
  658. LOG_ERR("reset: %d", ret);
  659. return ret;
  660. }
  661. LOG_INF("speed: %d", usbh_dev.speed);
  662. ret = usbh_set_address(DEVNUM_DEFAULT);
  663. if (ret) {
  664. LOG_ERR("address: %d", ret);
  665. return ret;
  666. }
  667. usbh_set_device_state(&usbh_dev, USB_STATE_ADDRESS);
  668. /* Let the SET_ADDRESS settle */
  669. k_sleep(K_MSEC(10));
  670. ret = usbh_get_device_descriptor(USB_DEVICE_DESC_SIZE);
  671. if (ret < USB_DEVICE_DESC_SIZE) {
  672. LOG_ERR("device desc: %d", ret);
  673. return -EIO;
  674. }
  675. LOG_DBG("OK");
  676. return 0;
  677. }
  678. int usbh_prepare_scan(void)
  679. {
  680. usbh_dev.state = USB_STATE_ATTACHED;
  681. usbh_dev.scanning = 1;
  682. return usb_hc_enable();
  683. }
  684. int usbh_scan_device(void)
  685. {
  686. int ret;
  687. LOG_DBG("");
  688. ret = hub_port_init(NO_OF_RH_PORTS);
  689. if (ret) {
  690. goto error;
  691. }
  692. /* correct le values */
  693. usbh_dev.desc.bcdUSB = sys_le16_to_cpu(usbh_dev.desc.bcdUSB);
  694. usbh_dev.desc.idVendor = sys_le16_to_cpu(usbh_dev.desc.idVendor);
  695. usbh_dev.desc.idProduct = sys_le16_to_cpu(usbh_dev.desc.idProduct);
  696. usbh_dev.desc.bcdDevice = sys_le16_to_cpu(usbh_dev.desc.bcdDevice);
  697. LOG_DBG("bcdUSB: 0x%x, idVendor: 0x%x, idProduct: 0x%x\n",
  698. usbh_dev.desc.bcdUSB,
  699. usbh_dev.desc.idVendor,
  700. usbh_dev.desc.idProduct);
  701. ret = usbh_enumerate_device();
  702. if (ret) {
  703. goto error;
  704. }
  705. LOG_INF("enum done");
  706. usbh_dev.scanning = 0;
  707. return 0;
  708. error:
  709. usbh_vbus_set(false);
  710. LOG_ERR("failed");
  711. usbh_dev.scanning = 0;
  712. return ret;
  713. }
  714. int usbh_reset_device(void)
  715. {
  716. int ret;
  717. u8_t i;
  718. if (usbh_dev.state != USB_STATE_CONFIGURED) {
  719. return -ENODEV;
  720. }
  721. LOG_INF("");
  722. ret = hub_port_init(NO_OF_RH_PORTS);
  723. if (ret) {
  724. goto error;
  725. }
  726. /* set configuration */
  727. ret = usbh_set_configuration(usbh_dev.config.desc.bConfigurationValue);
  728. if (ret) {
  729. goto error;
  730. }
  731. for (i = 0; i < usbh_dev.config.no_of_if; i++) {
  732. struct usb_interface *intf = &usbh_dev.config.intf[i];
  733. if (intf->desc.bAlternateSetting == 0) {
  734. usbh_disable_interface(intf);
  735. usbh_enable_interface(intf);
  736. }
  737. }
  738. LOG_INF("done");
  739. return 0;
  740. error:
  741. /* upper layer should do disconnect or ... */
  742. return ret;
  743. }
  744. int usbh_disconnect(void)
  745. {
  746. struct usb_interface *intf;
  747. u8_t i;
  748. LOG_DBG("");
  749. usbh_set_device_state(&usbh_dev, USB_STATE_NOTATTACHED);
  750. disable_ep0();
  751. for (i = 0; i < usbh_dev.config.no_of_if; i++) {
  752. intf = &usbh_dev.config.intf[i];
  753. if (intf->driver) {
  754. intf->driver->disconnect(intf);
  755. intf->driver = NULL;
  756. }
  757. }
  758. if (usbh_dev.scanning == 1) {
  759. LOG_WRN("scanning");
  760. return -EAGAIN;
  761. }
  762. usb_hc_disable();
  763. /* USB_STATE_NOTATTACHED */
  764. memset(&usbh_dev, 0, sizeof(usbh_dev));
  765. LOG_INF("done");
  766. return 0;
  767. }
  768. bool usbh_is_scanning(void)
  769. {
  770. return usbh_dev.scanning;
  771. }
  772. int usbh_register_driver(struct usb_driver *driver)
  773. {
  774. sys_slist_append(&usb_drivers, &driver->node);
  775. return 0;
  776. }
  777. void usbh_unregister_driver(struct usb_driver *driver)
  778. {
  779. sys_slist_find_and_remove(&usb_drivers, &driver->node);
  780. }
  781. int usbh_fifo_control(bool enable)
  782. {
  783. return usb_hc_fifo_control(enable);
  784. }