usb_workq.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "usb_list.h"
  2. #include "usb_osal.h"
  3. #include "usb_workq.h"
  4. #include "usb_config.h"
  5. void usb_workqueue_submit(struct usb_workqueue *queue, struct usb_work *work, usb_worker_t worker, void *arg, uint32_t ticks)
  6. {
  7. uint32_t flags;
  8. flags = usb_osal_enter_critical_section();
  9. usb_dlist_remove(&work->list);
  10. work->worker = worker;
  11. work->arg = arg;
  12. if (ticks == 0) {
  13. usb_dlist_insert_after(&queue->work_list, &work->list);
  14. usb_osal_sem_give(queue->sem);
  15. }
  16. usb_osal_leave_critical_section(flags);
  17. }
  18. struct usb_workqueue g_hpworkq = { NULL };
  19. struct usb_workqueue g_lpworkq = { NULL };
  20. static void usbh_hpwork_thread(void *argument)
  21. {
  22. struct usb_work *work;
  23. uint32_t flags;
  24. int ret;
  25. struct usb_workqueue *queue = (struct usb_workqueue *)argument;
  26. while (1) {
  27. ret = usb_osal_sem_take(queue->sem);
  28. if (ret < 0) {
  29. continue;
  30. }
  31. flags = usb_osal_enter_critical_section();
  32. if (usb_dlist_isempty(&queue->work_list)) {
  33. usb_osal_leave_critical_section(flags);
  34. continue;
  35. }
  36. work = usb_dlist_first_entry(&queue->work_list, struct usb_work, list);
  37. usb_dlist_remove(&work->list);
  38. usb_osal_leave_critical_section(flags);
  39. work->worker(work->arg);
  40. }
  41. }
  42. static void usbh_lpwork_thread(void *argument)
  43. {
  44. struct usb_work *work;
  45. uint32_t flags;
  46. int ret;
  47. struct usb_workqueue *queue = (struct usb_workqueue *)argument;
  48. while (1) {
  49. ret = usb_osal_sem_take(queue->sem);
  50. if (ret < 0) {
  51. continue;
  52. }
  53. flags = usb_osal_enter_critical_section();
  54. if (usb_dlist_isempty(&queue->work_list)) {
  55. usb_osal_leave_critical_section(flags);
  56. continue;
  57. }
  58. work = usb_dlist_first_entry(&queue->work_list, struct usb_work, list);
  59. usb_dlist_remove(&work->list);
  60. usb_osal_leave_critical_section(flags);
  61. work->worker(work->arg);
  62. }
  63. }
  64. int usbh_workq_initialize(void)
  65. {
  66. g_hpworkq.sem = usb_osal_sem_create(0);
  67. if (g_hpworkq.sem == NULL) {
  68. return -1;
  69. }
  70. g_hpworkq.thread = usb_osal_thread_create("usbh_hpworkq", CONFIG_USBHOST_HPWORKQ_STACKSIZE, CONFIG_USBHOST_HPWORKQ_PRIO, usbh_hpwork_thread, &g_hpworkq);
  71. if (g_hpworkq.thread == NULL) {
  72. return -1;
  73. }
  74. g_lpworkq.sem = usb_osal_sem_create(0);
  75. if (g_lpworkq.sem == NULL) {
  76. return -1;
  77. }
  78. g_lpworkq.thread = usb_osal_thread_create("usbh_lpworkq", CONFIG_USBHOST_LPWORKQ_STACKSIZE, CONFIG_USBHOST_LPWORKQ_PRIO, usbh_lpwork_thread, &g_lpworkq);
  79. if (g_lpworkq.thread == NULL) {
  80. return -1;
  81. }
  82. return 0;
  83. }