Browse Source

Merge pull request #100 from grissiom/usb-plug

usb: add USB_MSG_PLUG_OUT event
qiuyiuestc 12 years ago
parent
commit
4cdb0154ba

+ 5 - 0
components/drivers/include/drivers/usb_device.h

@@ -146,6 +146,11 @@ enum udev_msg_type
     USB_MSG_DATA_NOTIFY,
     USB_MSG_DATA_NOTIFY,
     USB_MSG_SOF,
     USB_MSG_SOF,
     USB_MSG_RESET,
     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;
 typedef enum udev_msg_type udev_msg_type;
 
 

+ 56 - 4
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.
  * @param device the usb device object.
  *
  *
  * @return RT_EOK.
  * @return RT_EOK.
  */
  */
-rt_err_t _reset_notify(udevice_t device)
+rt_err_t _stop_notify(udevice_t device)
 {
 {
     struct rt_list_node *i;
     struct rt_list_node *i;
     uclass_t cls;
     uclass_t cls;
@@ -681,13 +681,38 @@ rt_err_t _reset_notify(udevice_t device)
     RT_ASSERT(device != RT_NULL);
     RT_ASSERT(device != RT_NULL);
 
 
     /* to notity every class that sof event comes */
     /* 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);
         cls = (uclass_t)rt_list_entry(i, struct uclass, list);
         if(cls->ops->stop != RT_NULL)
         if(cls->ops->stop != RT_NULL)
             cls->ops->stop(device, cls);
             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)
         if(cls->ops->run != RT_NULL)
             cls->ops->run(device, cls);
             cls->ops->run(device, cls);
     }
     }
@@ -695,6 +720,26 @@ rt_err_t _reset_notify(udevice_t device)
     return RT_EOK;
     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.
  * This function will create an usb device object.
  *
  *
@@ -1402,6 +1447,10 @@ static void rt_usbd_thread_entry(void* parameter)
             _sof_notify(device);
             _sof_notify(device);
             break;
             break;
         case USB_MSG_DATA_NOTIFY:
         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);
             ep = rt_usbd_find_endpoint(device, &cls, msg.content.ep_msg.ep_addr);
             if(ep != RT_NULL)
             if(ep != RT_NULL)
                 ep->handler(device, cls, msg.content.ep_msg.size);
                 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)
             if (device->state == USB_STATE_ADDRESS)
                 _reset_notify(device);
                 _reset_notify(device);
             break;
             break;
+        case USB_MSG_PLUG_OUT:
+            _stop_notify(device);
+            break;
         default:
         default:
             rt_kprintf("unknown msg type\n");
             rt_kprintf("unknown msg type\n");
             break;
             break;