diff --git a/components/drivers/include/drivers/usb_device.h b/components/drivers/include/drivers/usb_device.h index f0e0989ce5fd1b8064a1664a4d3c7711a3580154..2f464def3ff2329fdc1a677ebd43abeecbbbb50b 100644 --- a/components/drivers/include/drivers/usb_device.h +++ b/components/drivers/include/drivers/usb_device.h @@ -146,6 +146,11 @@ enum udev_msg_type USB_MSG_DATA_NOTIFY, USB_MSG_SOF, USB_MSG_RESET, + /* we don't need to add a "PLUG_IN" event because after the cable is + * plugged in(before any SETUP) the classed have nothing to do. If the host + * is ready, it will send RESET and we will have USB_MSG_RESET. So, a RESET + * should reset and run the class while plug_in is not. */ + USB_MSG_PLUG_OUT, }; typedef enum udev_msg_type udev_msg_type; diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/core.c index 45264033a98cbd4a7d4a552aef12ad6381c5adc4..48fc69895c53ef5a2b7e20503bc78b6384dd39c3 100644 --- a/components/drivers/usb/usbdevice/core/core.c +++ b/components/drivers/usb/usbdevice/core/core.c @@ -667,13 +667,13 @@ rt_err_t _sof_notify(udevice_t device) } /** - * This function will reset all class. + * This function will stop all class. * * @param device the usb device object. * * @return RT_EOK. */ -rt_err_t _reset_notify(udevice_t device) +rt_err_t _stop_notify(udevice_t device) { struct rt_list_node *i; uclass_t cls; @@ -681,13 +681,38 @@ rt_err_t _reset_notify(udevice_t device) RT_ASSERT(device != RT_NULL); /* to notity every class that sof event comes */ - for (i=device->curr_cfg->cls_list.next; - i!=&device->curr_cfg->cls_list; i=i->next) + for (i = device->curr_cfg->cls_list.next; + i != &device->curr_cfg->cls_list; + i = i->next) { cls = (uclass_t)rt_list_entry(i, struct uclass, list); if(cls->ops->stop != RT_NULL) cls->ops->stop(device, cls); + } + + return RT_EOK; +} + +/** + * This function will run all class. + * + * @param device the usb device object. + * + * @return RT_EOK. + */ +rt_err_t _run_notify(udevice_t device) +{ + struct rt_list_node *i; + uclass_t cls; + + RT_ASSERT(device != RT_NULL); + /* to notity every class that sof event comes */ + for (i = device->curr_cfg->cls_list.next; + i != &device->curr_cfg->cls_list; + i = i->next) + { + cls = (uclass_t)rt_list_entry(i, struct uclass, list); if(cls->ops->run != RT_NULL) cls->ops->run(device, cls); } @@ -695,6 +720,26 @@ rt_err_t _reset_notify(udevice_t device) return RT_EOK; } +/** + * This function will reset all class. + * + * @param device the usb device object. + * + * @return RT_EOK. + */ +rt_err_t _reset_notify(udevice_t device) +{ + struct rt_list_node *i; + uclass_t cls; + + RT_ASSERT(device != RT_NULL); + + _stop_notify(); + _run_notify(); + + return RT_EOK; +} + /** * This function will create an usb device object. * @@ -1402,6 +1447,10 @@ static void rt_usbd_thread_entry(void* parameter) _sof_notify(device); break; case USB_MSG_DATA_NOTIFY: + /* some buggy drivers will have USB_MSG_DATA_NOTIFY before the core + * got configured. */ + if (device->state != USB_STATE_CONFIGURED) + break; ep = rt_usbd_find_endpoint(device, &cls, msg.content.ep_msg.ep_addr); if(ep != RT_NULL) ep->handler(device, cls, msg.content.ep_msg.size); @@ -1415,6 +1464,9 @@ static void rt_usbd_thread_entry(void* parameter) if (device->state == USB_STATE_ADDRESS) _reset_notify(device); break; + case USB_MSG_PLUG_OUT: + _stop_notify(device); + break; default: rt_kprintf("unknown msg type\n"); break;