summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqiuyiuestc <[email protected]>2013-06-12 16:29:57 -0700
committerqiuyiuestc <[email protected]>2013-06-12 16:29:57 -0700
commit4cdb0154ba7418df177f4d6a9afd1fc1be6aa0ae (patch)
treed6f373e6ff7433321838e0efd2db9ee6b9aaa128
parent4807145a7138bf7f2509b4c197f6119a81b10b69 (diff)
parentb02993c9895d34e84f2dbf156ee274ad6abf84c0 (diff)
Merge pull request #100 from grissiom/usb-plug
usb: add USB_MSG_PLUG_OUT event
-rw-r--r--components/drivers/include/drivers/usb_device.h5
-rw-r--r--components/drivers/usb/usbdevice/core/core.c60
2 files changed, 61 insertions, 4 deletions
diff --git a/components/drivers/include/drivers/usb_device.h b/components/drivers/include/drivers/usb_device.h
index f0e0989ce5..2f464def3f 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 45264033a9..48fc69895c 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);
}
@@ -696,6 +721,26 @@ rt_err_t _reset_notify(udevice_t device)
}
/**
+ * 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.
*
* @param ustring the usb string array to contain string descriptor.
@@ -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;