浏览代码

[Components][USBHOST]Core OK

uestczyh222 7 年之前
父节点
当前提交
18d42fe077

+ 58 - 18
components/drivers/include/drivers/usb_host.h

@@ -49,8 +49,9 @@ extern "C" {
 #define USBH_PID_DATA                   0x01
 
 struct uhcd;
-struct uintf;
+struct uhintf;
 struct uhub;
+struct upipe;
 
 struct uclass_driver
 {
@@ -83,8 +84,9 @@ struct uinstance
     ucfg_desc_t cfg_desc;
     struct uhcd *hcd;
 
-    upipe_t pipe_ep0_out;
-    upipe_t pipe_ep0_in;
+    struct upipe * pipe_ep0_out;
+    struct upipe * pipe_ep0_in;
+    rt_list_t pipe;
 
     rt_uint8_t status;
     rt_uint8_t type;
@@ -110,10 +112,11 @@ struct uhintf
 
 struct upipe
 {
+    rt_list_t list;
     rt_uint8_t pipe_index;
     rt_uint32_t status;
     struct uendpoint_descriptor ep;
-    struct uhintf* intf;
+    uinst_t inst;
     func_callback callback;
     void* user_data;
 };
@@ -127,7 +130,7 @@ struct uhub
     struct uinstance* child[USB_HUB_PORT_NUM];        
 
     rt_bool_t is_roothub;
-    upipe_t pipe_in;
+
     rt_uint8_t buffer[8];    
     struct uinstance* self;
     struct uhcd *hcd;
@@ -136,15 +139,17 @@ typedef struct uhub* uhub_t;
 
 struct uhcd_ops
 {
+    rt_err_t    (*reset_port)   (rt_uint8_t port);
     int         (*pipe_xfer)    (upipe_t pipe, rt_uint8_t token, void* buffer, int nbytes, int timeout);
-    rt_err_t    (*alloc_pipe)   (struct upipe* pipe, uep_desc_t ep);
-    rt_err_t    (*free_pipe)    (upipe_t pipe);  
+    rt_err_t    (*open_pipe)    (upipe_t pipe);
+    rt_err_t    (*close_pipe)   (upipe_t pipe);  
 };
 typedef struct uhcd_ops* uhcd_ops_t;
 struct uhcd
 {
     struct rt_device parent;
     uhcd_ops_t ops;
+    rt_uint8_t num_ports;
     uhub_t roothub; 
 };
 typedef struct uhcd* uhcd_t;
@@ -173,10 +178,10 @@ typedef struct uhost_msg* uhost_msg_t;
 
 /* usb host system interface */
 rt_err_t rt_usb_host_init(void);
-void rt_usbh_hub_init(void);
+void rt_usbh_hub_init(struct uhcd *hcd);
 
 /* usb host core interface */
-struct uinstance* rt_usbh_alloc_instance(void);
+struct uinstance* rt_usbh_alloc_instance(uhcd_t uhcd);
 rt_err_t rt_usbh_attatch_instance(struct uinstance* device);
 rt_err_t rt_usbh_detach_instance(struct uinstance* device);
 rt_err_t rt_usbh_get_descriptor(struct uinstance* device, rt_uint8_t type, void* buffer, int nbytes);
@@ -204,9 +209,9 @@ ucd_t rt_usbh_class_driver_storage(void);
 /* usb hub interface */
 rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer, 
     rt_size_t size);
-rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint8_t* buffer);
+rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint32_t* buffer);
 rt_err_t rt_usbh_hub_get_port_status(uhub_t uhub, rt_uint16_t port, 
-    rt_uint8_t* buffer);
+    rt_uint32_t* buffer);
 rt_err_t rt_usbh_hub_clear_port_feature(uhub_t uhub, rt_uint16_t port, 
     rt_uint16_t feature);
 rt_err_t rt_usbh_hub_set_port_feature(uhub_t uhub, rt_uint16_t port, 
@@ -214,22 +219,56 @@ rt_err_t rt_usbh_hub_set_port_feature(uhub_t uhub, rt_uint16_t port,
 rt_err_t rt_usbh_hub_reset_port(uhub_t uhub, rt_uint16_t port);
 rt_err_t rt_usbh_event_signal(struct uhost_msg* msg);
 
+
+void rt_usbh_root_hub_connect_handler(struct uhcd *hcd, rt_uint8_t port, rt_bool_t isHS);
+void rt_usbh_root_hub_disconnect_handler(struct uhcd *hcd, rt_uint8_t port);
+
 /* usb host controller driver interface */
-rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t pipe, uep_desc_t ep)
+rt_inline rt_err_t rt_usb_instance_add_pipe(uinst_t inst, upipe_t pipe)
+{
+    RT_ASSERT(inst != RT_NULL);
+    RT_ASSERT(pipe != RT_NULL);
+    rt_list_insert_before(&inst->pipe, &pipe->list);
+    return RT_EOK;
+}
+rt_inline upipe_t rt_usb_instance_find_pipe(uinst_t inst,rt_uint8_t ep_address)
+{
+    rt_list_t * l;
+    for(l = inst->pipe.next;l != &inst->pipe;l = l->next)
+    {
+        if(rt_list_entry(l,struct upipe,list)->ep.bEndpointAddress == ep_address)
+        {
+            return rt_list_entry(l,struct upipe,list);
+        }
+    }
+    return RT_NULL;
+}
+rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe, uinst_t inst, uep_desc_t ep)
 {
-    return hcd->ops->alloc_pipe(pipe, ep);
+    *pipe = (upipe_t)rt_malloc(sizeof(struct upipe));
+    if(*pipe == RT_NULL)
+    {
+        return RT_ERROR;
+    }
+    rt_memset(*pipe,0,sizeof(struct upipe));
+    (*pipe)->inst = inst;
+    rt_memcpy(&(*pipe)->ep,ep,sizeof(struct uendpoint_descriptor));
+    return hcd->ops->open_pipe(*pipe);
+}
+rt_inline void rt_usb_pipe_add_callback(upipe_t pipe, func_callback callback)
+{
+    pipe->callback = callback;
 }
 
 rt_inline rt_err_t rt_usb_hcd_free_pipe(uhcd_t hcd, upipe_t pipe)
 {
     RT_ASSERT(pipe != RT_NULL);
-    return hcd->ops->free_pipe(pipe);
+    hcd->ops->close_pipe(pipe);
+    rt_free(pipe);
+    return RT_EOK;
 }
 
-rt_inline int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout)
-{
-    return hcd->ops->pipe_xfer(pipe, USBH_PID_DATA, buffer, nbytes, timeout);
-}
+int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout);
 rt_inline int rt_usb_hcd_setup_xfer(uhcd_t hcd, upipe_t pipe, ureq_t setup, int timeout)
 {
     return hcd->ops->pipe_xfer(pipe, USBH_PID_SETUP, (void *)setup, 8, timeout);
@@ -241,3 +280,4 @@ rt_inline int rt_usb_hcd_setup_xfer(uhcd_t hcd, upipe_t pipe, ureq_t setup, int
 
 #endif
 
+

+ 41 - 48
components/drivers/usb/usbhost/class/mass.c

@@ -18,8 +18,8 @@
 
 #ifdef RT_USBH_MSTORAGE
 
-extern rt_err_t rt_udisk_run(struct uintf* intf);
-extern rt_err_t rt_udisk_stop(struct uintf* intf);
+extern rt_err_t rt_udisk_run(struct uhintf* intf);
+extern rt_err_t rt_udisk_stop(struct uhintf* intf);
 
 static struct uclass_driver storage_driver;
 
@@ -31,7 +31,7 @@ static struct uclass_driver storage_driver;
  * 
  * @return the error code, RT_EOK on successfully.
  */
-static rt_err_t _pipe_check(struct uintf* intf, upipe_t pipe)
+static rt_err_t _pipe_check(struct uhintf* intf, upipe_t pipe)
 {
     struct uinstance* device;        
     rt_err_t ret;
@@ -74,7 +74,7 @@ static rt_err_t _pipe_check(struct uintf* intf, upipe_t pipe)
     RT_DEBUG_LOG(RT_DEBUG_USB, ("clean storage in pipe stall\n"));
 
     /* it should receive csw after clear the stall feature */
-    size = rt_usb_hcd_bulk_xfer(stor->pipe_in->intf->device->hcd, 
+    size = rt_usb_hcd_pipe_xfer(stor->pipe_in->inst->hcd, 
         stor->pipe_in, &csw, SIZEOF_CSW, 100);
     if(size != SIZEOF_CSW) 
     {
@@ -93,7 +93,7 @@ static rt_err_t _pipe_check(struct uintf* intf, upipe_t pipe)
  * 
  * @return the error code, RT_EOK on successfully.
  */
-static rt_err_t rt_usb_bulk_only_xfer(struct uintf* intf, 
+static rt_err_t rt_usb_bulk_only_xfer(struct uhintf* intf, 
     ustorage_cbw_t cmd, rt_uint8_t* buffer, int timeout)
 {
     rt_size_t size;
@@ -116,7 +116,7 @@ static rt_err_t rt_usb_bulk_only_xfer(struct uintf* intf,
     do
     {
         /* send the cbw */
-        size = rt_usb_hcd_bulk_xfer(intf->device->hcd, stor->pipe_out, 
+        size = rt_usb_hcd_pipe_xfer(stor->pipe_out->inst->hcd, stor->pipe_out, 
             cmd, SIZEOF_CBW, timeout);
         if(size != SIZEOF_CBW) 
         {
@@ -127,7 +127,7 @@ static rt_err_t rt_usb_bulk_only_xfer(struct uintf* intf,
         {
             pipe = (cmd->dflags == CBWFLAGS_DIR_IN) ? stor->pipe_in :
                 stor->pipe_out;
-            size = rt_usb_hcd_bulk_xfer(intf->device->hcd, pipe, (void*)buffer, 
+            size = rt_usb_hcd_pipe_xfer(pipe->inst->hcd, pipe, (void*)buffer, 
                 cmd->xfer_len, timeout);
             if(size != cmd->xfer_len)
             {
@@ -138,7 +138,7 @@ static rt_err_t rt_usb_bulk_only_xfer(struct uintf* intf,
         }
         
         /* receive the csw */
-        size = rt_usb_hcd_bulk_xfer(intf->device->hcd, stor->pipe_in, 
+        size = rt_usb_hcd_pipe_xfer(stor->pipe_in->inst->hcd, stor->pipe_in, 
             &csw, SIZEOF_CSW, timeout);
         if(size != SIZEOF_CSW) 
         {
@@ -172,7 +172,7 @@ static rt_err_t rt_usb_bulk_only_xfer(struct uintf* intf,
     
     if(csw.status != 0)
     {
-        rt_kprintf("csw status error\n");
+        rt_kprintf("csw status error:%d\n",csw.status);
         return -RT_ERROR;
     }
     
@@ -187,7 +187,7 @@ static rt_err_t rt_usb_bulk_only_xfer(struct uintf* intf,
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_usbh_storage_get_max_lun(struct uintf* intf, rt_uint8_t* max_lun)
+rt_err_t rt_usbh_storage_get_max_lun(struct uhintf* intf, rt_uint8_t* max_lun)
 {
     struct uinstance* device;    
     struct urequest setup;
@@ -209,15 +209,20 @@ rt_err_t rt_usbh_storage_get_max_lun(struct uintf* intf, rt_uint8_t* max_lun)
     /* construct the request */
     setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | 
         USB_REQ_TYPE_INTERFACE;
-    setup.request = USBREQ_GET_MAX_LUN;
-    setup.index = intf->intf_desc->bInterfaceNumber;
-    setup.length = 1;
-    setup.value = 0;
+    setup.bRequest = USBREQ_GET_MAX_LUN;
+    setup.wValue = intf->intf_desc->bInterfaceNumber;
+    setup.wIndex = 1;
+    setup.wLength = 0;
 
     /* do control transfer request */
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, max_lun, 1, 
-        timeout) != 1) return -RT_EIO;
-
+    if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8)
+    {
+        if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, max_lun, 1, timeout) != 1)
+        {
+            return -RT_EIO;
+        }
+        return -RT_EIO;
+    }
     return RT_EOK;
 }
 
@@ -228,7 +233,7 @@ rt_err_t rt_usbh_storage_get_max_lun(struct uintf* intf, rt_uint8_t* max_lun)
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_usbh_storage_reset(struct uintf* intf)
+rt_err_t rt_usbh_storage_reset(struct uhintf* intf)
 {
     struct urequest setup;
     struct uinstance* device;    
@@ -250,13 +255,15 @@ rt_err_t rt_usbh_storage_reset(struct uintf* intf)
     /* construct the request */
     setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | 
         USB_REQ_TYPE_INTERFACE;
-    setup.request = USBREQ_MASS_STORAGE_RESET;
-    setup.index = intf->intf_desc->bInterfaceNumber;
-    setup.length = 0;
-    setup.value = 0;
+    setup.bRequest = USBREQ_MASS_STORAGE_RESET;
+    setup.wIndex = intf->intf_desc->bInterfaceNumber;
+    setup.wLength = 0;
+    setup.wValue = 0;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, 
-        timeout) != 0) return -RT_EIO;
+    if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8)
+    {
+        return -RT_EIO;
+    }
     
     return RT_EOK;
 }
@@ -271,7 +278,7 @@ rt_err_t rt_usbh_storage_reset(struct uintf* intf)
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_usbh_storage_read10(struct uintf* intf, rt_uint8_t *buffer, 
+rt_err_t rt_usbh_storage_read10(struct uhintf* intf, rt_uint8_t *buffer, 
     rt_uint32_t sector, rt_size_t count, int timeout)
 {
     struct ustorage_cbw cmd;
@@ -317,7 +324,7 @@ rt_err_t rt_usbh_storage_read10(struct uintf* intf, rt_uint8_t *buffer,
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_usbh_storage_write10(struct uintf* intf, rt_uint8_t *buffer, 
+rt_err_t rt_usbh_storage_write10(struct uhintf* intf, rt_uint8_t *buffer, 
     rt_uint32_t sector, rt_size_t count, int timeout)
 {
     struct ustorage_cbw cmd;
@@ -361,7 +368,7 @@ rt_err_t rt_usbh_storage_write10(struct uintf* intf, rt_uint8_t *buffer,
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_usbh_storage_request_sense(struct uintf* intf, rt_uint8_t* buffer)
+rt_err_t rt_usbh_storage_request_sense(struct uhintf* intf, rt_uint8_t* buffer)
 {
     struct ustorage_cbw cmd;
     int timeout = 200;
@@ -397,7 +404,7 @@ rt_err_t rt_usbh_storage_request_sense(struct uintf* intf, rt_uint8_t* buffer)
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_usbh_storage_test_unit_ready(struct uintf* intf)
+rt_err_t rt_usbh_storage_test_unit_ready(struct uhintf* intf)
 {
     struct ustorage_cbw cmd;
     int timeout = 200;
@@ -433,7 +440,7 @@ rt_err_t rt_usbh_storage_test_unit_ready(struct uintf* intf)
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_usbh_storage_inquiry(struct uintf* intf, rt_uint8_t* buffer)
+rt_err_t rt_usbh_storage_inquiry(struct uhintf* intf, rt_uint8_t* buffer)
 {
     struct ustorage_cbw cmd;
     int timeout = 200;
@@ -470,7 +477,7 @@ rt_err_t rt_usbh_storage_inquiry(struct uintf* intf, rt_uint8_t* buffer)
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_usbh_storage_get_capacity(struct uintf* intf, rt_uint8_t* buffer)
+rt_err_t rt_usbh_storage_get_capacity(struct uhintf* intf, rt_uint8_t* buffer)
 {
     struct ustorage_cbw cmd;
     int timeout = 200;
@@ -512,7 +519,7 @@ static rt_err_t rt_usbh_storage_enable(void* arg)
     int i = 0;
     rt_err_t ret;    
     ustor_t stor;
-    struct uintf* intf = (struct uintf*)arg;
+    struct uhintf* intf = (struct uhintf*)arg;
 
     /* parameter check */
     if(intf == RT_NULL)
@@ -556,16 +563,12 @@ static rt_err_t rt_usbh_storage_enable(void* arg)
         if(ep_desc->bEndpointAddress & USB_DIR_IN)
         {
             /* alloc an in pipe for the storage instance */
-            ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &stor->pipe_in, 
-                intf, ep_desc, RT_NULL);
-            if(ret != RT_EOK) return ret;
+            stor->pipe_in = rt_usb_instance_find_pipe(intf->device,ep_desc->bEndpointAddress);
         }
         else
         {        
             /* alloc an output pipe for the storage instance */
-            ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &stor->pipe_out, 
-                intf, ep_desc, RT_NULL);            
-            if(ret != RT_EOK) return ret;
+            stor->pipe_out = rt_usb_instance_find_pipe(intf->device,ep_desc->bEndpointAddress);
         }
     }
 
@@ -594,7 +597,7 @@ static rt_err_t rt_usbh_storage_enable(void* arg)
 static rt_err_t rt_usbh_storage_disable(void* arg)
 {
     ustor_t stor;
-    struct uintf* intf = (struct uintf*)arg;
+    struct uhintf* intf = (struct uhintf*)arg;
 
     /* parameter check */
     RT_ASSERT(intf != RT_NULL);
@@ -608,16 +611,6 @@ static rt_err_t rt_usbh_storage_disable(void* arg)
 
     rt_udisk_stop(intf);
 
-    rt_kprintf("in 0x%x, out 0x%x\n", stor->pipe_in, 
-        stor->pipe_out);
-    
-    /* free in pipe */
-    if(stor->pipe_in != RT_NULL) 
-        rt_usb_hcd_free_pipe(intf->device->hcd, stor->pipe_in);    
-
-    /* free out pipe */
-    if(stor->pipe_out != RT_NULL)     
-        rt_usb_hcd_free_pipe(intf->device->hcd, stor->pipe_out);    
     
     /* free storage instance */
     if(stor != RT_NULL) rt_free(stor);

+ 9 - 9
components/drivers/usb/usbhost/class/mass.h

@@ -24,7 +24,7 @@
 struct ustor_data
 {
     struct dfs_partition part;
-    struct uintf* intf;
+    struct uhintf* intf;
     int udisk_id;
     const char path;
 };
@@ -40,15 +40,15 @@ struct ustor
 };    
 typedef struct ustor* ustor_t;
 
-rt_err_t rt_usbh_storage_get_max_lun(struct uintf* intf, rt_uint8_t* max_lun);
-rt_err_t rt_usbh_storage_reset(struct uintf* intf);
-rt_err_t rt_usbh_storage_read10(struct uintf* intf, rt_uint8_t *buffer, 
+rt_err_t rt_usbh_storage_get_max_lun(struct uhintf* intf, rt_uint8_t* max_lun);
+rt_err_t rt_usbh_storage_reset(struct uhintf* intf);
+rt_err_t rt_usbh_storage_read10(struct uhintf* intf, rt_uint8_t *buffer, 
     rt_uint32_t sector, rt_size_t count, int timeout);
-rt_err_t rt_usbh_storage_write10(struct uintf* intf, rt_uint8_t *buffer, 
+rt_err_t rt_usbh_storage_write10(struct uhintf* intf, rt_uint8_t *buffer, 
     rt_uint32_t sector, rt_size_t count, int timeout);
-rt_err_t rt_usbh_storage_request_sense(struct uintf* intf, rt_uint8_t* buffer);
-rt_err_t rt_usbh_storage_test_unit_ready(struct uintf* intf);
-rt_err_t rt_usbh_storage_inquiry(struct uintf* intf, rt_uint8_t* buffer);
-rt_err_t rt_usbh_storage_get_capacity(struct uintf* intf, rt_uint8_t* buffer);
+rt_err_t rt_usbh_storage_request_sense(struct uhintf* intf, rt_uint8_t* buffer);
+rt_err_t rt_usbh_storage_test_unit_ready(struct uhintf* intf);
+rt_err_t rt_usbh_storage_inquiry(struct uhintf* intf, rt_uint8_t* buffer);
+rt_err_t rt_usbh_storage_get_capacity(struct uhintf* intf, rt_uint8_t* buffer);
 
 #endif

+ 4 - 4
components/drivers/usb/usbhost/class/udisk.c

@@ -72,7 +72,7 @@ static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer,
     rt_size_t size)
 {
     rt_err_t ret;
-    struct uintf* intf;
+    struct uhintf* intf;
     struct ustor_data* data;
     int timeout = 500;
 
@@ -110,7 +110,7 @@ static rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buff
     rt_size_t size)
 {
     rt_err_t ret;
-    struct uintf* intf;
+    struct uhintf* intf;
     struct ustor_data* data;
     int timeout = 500;
 
@@ -174,7 +174,7 @@ static rt_err_t rt_udisk_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_udisk_run(struct uintf* intf)
+rt_err_t rt_udisk_run(struct uhintf* intf)
 {
     int i = 0;
     rt_err_t ret;
@@ -382,7 +382,7 @@ rt_err_t rt_udisk_run(struct uintf* intf)
  * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_udisk_stop(struct uintf* intf)
+rt_err_t rt_udisk_stop(struct uhintf* intf)
 {
     int i;
     ustor_t stor;    

+ 125 - 32
components/drivers/usb/usbhost/core/core.c

@@ -35,7 +35,7 @@ static struct uinstance dev[USB_MAX_DEVICE];
  *
  * @return the allocate instance on successful, or RT_NULL on failure.
  */
-uinst_t rt_usbh_alloc_instance(void)
+uinst_t rt_usbh_alloc_instance(uhcd_t uhcd)
 {
     int i;
 
@@ -54,7 +54,8 @@ uinst_t rt_usbh_alloc_instance(void)
         dev[i].index = i + 1;
         dev[i].address = 0;
         dev[i].max_packet_size = 0x8;
-
+        rt_list_init(&dev[i].pipe);
+        dev[i].hcd = uhcd;
         /* unlock scheduler */        
         rt_exit_critical();
         return &dev[i];
@@ -75,6 +76,26 @@ uinst_t rt_usbh_alloc_instance(void)
  * 
  * @return the error code, RT_EOK on successfully.
  */
+static struct uendpoint_descriptor ep0_out_desc = 
+{
+    /*endpoint descriptor*/
+    USB_DESC_LENGTH_ENDPOINT,
+    USB_DESC_TYPE_ENDPOINT,
+    0x00 | USB_DIR_OUT,
+    USB_EP_ATTR_CONTROL,
+    0x40,
+    0x00,
+};
+static struct uendpoint_descriptor ep0_in_desc = 
+{
+    /*endpoint descriptor*/
+    USB_DESC_LENGTH_ENDPOINT,
+    USB_DESC_TYPE_ENDPOINT,
+    0x00 | USB_DIR_IN,
+    USB_EP_ATTR_CONTROL,
+    0x40,
+    0x00,
+};
 rt_err_t rt_usbh_attatch_instance(uinst_t device)
 {
     int i = 0;
@@ -82,12 +103,18 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
     struct uconfig_descriptor cfg_desc;
     udev_desc_t dev_desc;
     uintf_desc_t intf_desc;
+    uep_desc_t ep_desc;
+    rt_uint8_t ep_index;
+    upipe_t pipe;
     ucd_t drv;
 
     RT_ASSERT(device != RT_NULL);
     
     rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor));
     dev_desc = &device->dev_desc;
+    /* alloc address 0 ep0 pipe*/
+    rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc);
+    rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc);
 
     RT_DEBUG_LOG(RT_DEBUG_USB, ("start enumnation\n"));
     
@@ -98,19 +125,25 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
         rt_kprintf("get device descriptor head failed\n");
         return ret;
     }
-    
+    //should reset bus
+    rt_usbh_hub_reset_port(device->parent_hub, device->port);
     /* set device address */
     ret = rt_usbh_set_address(device);
+    /* free address 0 ep0 pipe*/
+    rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out);
+    rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in);
     if(ret != RT_EOK)
     {
         rt_kprintf("set device address failed\n");
         return ret;
     }
-
+    /* free true address ep0 pipe*/
+    rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc);
+    rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc);
     /* set device max packet size */
     device->max_packet_size = device->dev_desc.bMaxPacketSize0;
 
-    RT_DEBUG_LOG(RT_DEBUG_USB, ("get device descriptor length %d\n",
+    RT_DEBUG_LOG(1, ("get device descriptor length %d\n",
                                 dev_desc->bLength));
     
     /* get full device descriptor again */
@@ -122,8 +155,8 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
         return ret;
     }
 
-    RT_DEBUG_LOG(RT_DEBUG_USB, ("Vendor ID 0x%x\n", dev_desc->idVendor));
-    RT_DEBUG_LOG(RT_DEBUG_USB, ("Product ID 0x%x\n", dev_desc->idProduct));
+    RT_DEBUG_LOG(1, ("Vendor ID 0x%x\n", dev_desc->idVendor));
+    RT_DEBUG_LOG(1, ("Product ID 0x%x\n", dev_desc->idProduct));
 
     /* get configuration descriptor head */
     ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, &cfg_desc, 18);
@@ -148,8 +181,10 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
 
     /* set configuration */
     ret = rt_usbh_set_configure(device, 1);
-    if(ret != RT_EOK) return ret;
-
+    if(ret != RT_EOK) 
+    {
+        return ret;
+    }
     for(i=0; i<device->cfg_desc->bNumInterfaces; i++)
     {        
         /* get interface descriptor through configuration descriptor */
@@ -160,10 +195,28 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
             return -RT_ERROR;
         }
 
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("interface class 0x%x, subclass 0x%x\n", 
+        RT_DEBUG_LOG(1, ("interface class 0x%x, subclass 0x%x\n", 
                                     intf_desc->bInterfaceClass,
                                     intf_desc->bInterfaceSubClass));
-
+        /* alloc pipe*/
+        for(ep_index = 0; ep_index < intf_desc->bNumEndpoints; ep_index++)
+        {
+            rt_usbh_get_endpoint_descriptor(intf_desc, ep_index, &ep_desc);
+            if(ep_desc != RT_NULL)
+            {
+                if(rt_usb_hcd_alloc_pipe(device->hcd, &pipe, device, ep_desc) != RT_EOK)
+                {
+                    rt_kprintf("alloc pipe failed\n");
+                    return RT_ERROR;
+                }
+                rt_usb_instance_add_pipe(device,pipe);
+            }
+            else
+            {
+                rt_kprintf("get endpoint desc failed\n");
+                return RT_ERROR;
+            }
+        }
         /* find driver by class code found in interface descriptor */
         drv = rt_usbh_class_driver_find(intf_desc->bInterfaceClass, 
             intf_desc->bInterfaceSubClass);
@@ -171,9 +224,7 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
         if(drv != RT_NULL)
         {
             /* allocate memory for interface device */
-            device->intf[i] = 
-                (struct uintf*)rt_malloc(sizeof(struct uintf));
-
+            device->intf[i] = (struct uhintf*)rt_malloc(sizeof(struct uhintf));
             device->intf[i]->drv = drv;
             device->intf[i]->device = device;
             device->intf[i]->intf_desc = intf_desc;
@@ -207,7 +258,7 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
 rt_err_t rt_usbh_detach_instance(uinst_t device)
 {
     int i = 0;
-
+    rt_list_t * l;
     if(device == RT_NULL) 
     {
         rt_kprintf("no usb instance to detach\n");
@@ -215,8 +266,6 @@ rt_err_t rt_usbh_detach_instance(uinst_t device)
     }
     
     /* free configration descriptor */
-    if(device->cfg_desc) rt_free(device->cfg_desc);
-    
     for(i=0; i<device->cfg_desc->bNumInterfaces; i++)
     {
         if(device->intf[i] == RT_NULL) continue;
@@ -227,7 +276,15 @@ rt_err_t rt_usbh_detach_instance(uinst_t device)
         RT_DEBUG_LOG(RT_DEBUG_USB, ("free interface instance %d\n", i));
         rt_usbh_class_driver_disable(device->intf[i]->drv, (void*)device->intf[i]);
     }
+    if(device->cfg_desc) rt_free(device->cfg_desc);
+    
+    rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out);
+    rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in);
     
+    for(l = device->pipe.next;l != &device->pipe;l = l->next)
+    {
+        rt_usb_hcd_free_pipe(device->hcd,rt_list_entry(l,struct upipe,list));
+    }
     rt_memset(device, 0, sizeof(struct uinstance));
     
     return RT_EOK;
@@ -258,9 +315,17 @@ rt_err_t rt_usbh_get_descriptor(uinst_t device, rt_uint8_t type, void* buffer,
     setup.wLength = nbytes;
     setup.wValue = type << 8;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, nbytes, 
-        timeout) != nbytes) return -RT_EIO;
-    else return RT_EOK;
+    if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
+    {
+        if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, nbytes, timeout) == nbytes)
+        {
+            if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0)
+            {
+                return RT_EOK;
+            }
+        }
+    }
+    return RT_ERROR;
 }
 
 /**
@@ -286,13 +351,15 @@ rt_err_t rt_usbh_set_address(uinst_t device)
     setup.wLength = 0;
     setup.wValue = device->index;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, 
-        timeout) != 0) return -RT_EIO;
-
-    rt_thread_delay(50);
+    if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8)
+    {
+        return RT_ERROR;
+    }
+    if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) == 0)
+    {
+        device->address = device->index;
+    }
 
-    device->address = device->index;
-    
     return RT_EOK;
 }
 
@@ -319,8 +386,10 @@ rt_err_t rt_usbh_set_configure(uinst_t device, int config)
     setup.wLength = 0;
     setup.wValue = config;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, 
-        timeout) != 0) return -RT_EIO;
+    if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8)
+    {
+        return RT_ERROR;
+    }
     
     return RT_EOK;    
 }
@@ -348,8 +417,10 @@ rt_err_t rt_usbh_set_interface(uinst_t device, int intf)
     setup.wLength = 0;
     setup.wValue = intf;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, 
-        timeout) != 0) return -RT_EIO;
+    if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8)
+    {
+        return RT_ERROR;
+    }
     
     return RT_EOK;    
 }
@@ -377,8 +448,10 @@ rt_err_t rt_usbh_clear_feature(uinst_t device, int endpoint, int feature)
     setup.wLength = 0;
     setup.wValue = feature;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, 
-        timeout) != 0) return -RT_EIO;
+    if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8)
+    {
+        return RT_ERROR;
+    }
     
     return RT_EOK;    
 }
@@ -447,6 +520,7 @@ rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num,
     /* check parameter */
     RT_ASSERT(intf_desc != RT_NULL);
     RT_ASSERT(num < intf_desc->bNumEndpoints);
+    *ep_desc = RT_NULL;
 
     ptr = (rt_uint32_t)intf_desc + intf_desc->bLength;
     while(count < intf_desc->bNumEndpoints)
@@ -476,3 +550,22 @@ rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num,
     return -RT_EIO;
 }
 
+int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout)
+{
+    rt_size_t remain_size;
+    rt_size_t send_size;
+    remain_size = nbytes;
+    do
+    {
+        send_size = (remain_size > pipe->ep.wMaxPacketSize) ? pipe->ep.wMaxPacketSize : remain_size;
+        if(hcd->ops->pipe_xfer(pipe, USBH_PID_DATA, buffer, send_size, timeout) == send_size)
+        {
+            remain_size -= send_size;
+        }
+        else
+        {
+            return 0;
+        }
+    }while(remain_size > 0);
+    return nbytes;
+}

+ 123 - 34
components/drivers/usb/usbhost/core/hub.c

@@ -29,6 +29,95 @@
 
 static struct rt_messagequeue *usb_mq;
 static struct uclass_driver hub_driver;
+static struct uhub root_hub;
+
+static rt_err_t root_hub_ctrl(struct uhcd *hcd, rt_uint16_t port, rt_uint8_t cmd, void *args)
+{
+    switch(cmd)
+    {
+    case RH_GET_PORT_STATUS:
+        (*(rt_uint32_t *)args) = hcd->roothub->port_status[port-1];
+        break;
+    case RH_SET_PORT_STATUS:
+        hcd->roothub->port_status[port-1] = (*(rt_uint32_t *)args);
+        break;
+    case RH_CLEAR_PORT_FEATURE:
+        switch(((rt_uint32_t)args))
+        {
+        case PORT_FEAT_C_CONNECTION:
+            hcd->roothub->port_status[port-1] &= ~PORT_CCSC;
+            break;
+        case PORT_FEAT_C_ENABLE:
+            hcd->roothub->port_status[port-1] &= ~PORT_PESC;
+            break;
+        case PORT_FEAT_C_SUSPEND:
+            hcd->roothub->port_status[port-1] &= ~PORT_PSSC;
+            break;
+        case PORT_FEAT_C_OVER_CURRENT:
+            hcd->roothub->port_status[port-1] &= ~PORT_POCIC;
+            break;
+        case PORT_FEAT_C_RESET:
+            hcd->roothub->port_status[port-1] &= ~PORT_PRSC;
+            break;
+        }
+        break;
+    case RH_SET_PORT_FEATURE:
+        switch((rt_uint32_t)args)
+        {
+        case PORT_FEAT_CONNECTION:
+            hcd->roothub->port_status[port-1] |= PORT_CCSC;
+            break;
+        case PORT_FEAT_ENABLE:
+            hcd->roothub->port_status[port-1] |= PORT_PESC;
+            break;
+        case PORT_FEAT_SUSPEND:
+            hcd->roothub->port_status[port-1] |= PORT_PSSC;
+            break;
+        case PORT_FEAT_OVER_CURRENT:
+            hcd->roothub->port_status[port-1] |= PORT_POCIC;
+            break;
+        case PORT_FEAT_RESET:
+            hcd->ops->reset_port(port);
+            break;
+        case PORT_FEAT_POWER:
+            break;
+        case PORT_FEAT_LOWSPEED:
+            break;
+        case PORT_FEAT_HIGHSPEED:
+            break;
+        }
+        break;
+    default:
+        return RT_ERROR;
+    }
+    return RT_EOK;
+} 
+void rt_usbh_root_hub_connect_handler(struct uhcd *hcd, rt_uint8_t port, rt_bool_t isHS)
+{
+    struct uhost_msg msg;
+    msg.type = USB_MSG_CONNECT_CHANGE;
+    msg.content.hub = hcd->roothub;
+    hcd->roothub->port_status[port - 1] |= PORT_CCS | PORT_CCSC;
+    if(isHS)
+    {
+        hcd->roothub->port_status[port - 1] &= ~PORT_LSDA;
+    }
+    else
+    {
+        hcd->roothub->port_status[port - 1] |= PORT_LSDA;
+    }
+    rt_usbh_event_signal(&msg);
+}
+
+void rt_usbh_root_hub_disconnect_handler(struct uhcd *hcd, rt_uint8_t port)
+{
+    struct uhost_msg msg;
+    msg.type = USB_MSG_CONNECT_CHANGE;
+    msg.content.hub = hcd->roothub;
+    hcd->roothub->port_status[port - 1] |= PORT_CCSC;
+    hcd->roothub->port_status[port - 1] &= ~PORT_CCS;
+    rt_usbh_event_signal(&msg);
+}
 
 /**
  * This function will do USB_REQ_GET_DESCRIPTOR bRequest for the device instance 
@@ -117,7 +206,7 @@ rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port, rt_uint32_t*
     /* get roothub port status */
     if(hub->is_roothub)
     {
-        rt_usb_hcd_hub_control(hub->hcd, port, RH_GET_PORT_STATUS, 
+        root_hub_ctrl(hub->hcd, port, RH_GET_PORT_STATUS, 
             (void*)buffer);
         return RT_EOK;
     }
@@ -159,7 +248,7 @@ rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port, rt_uint16_
     /* clear roothub feature */
     if(hub->is_roothub)
     {
-        rt_usb_hcd_hub_control(hub->hcd, port, RH_CLEAR_PORT_FEATURE, 
+        root_hub_ctrl(hub->hcd, port, RH_CLEAR_PORT_FEATURE, 
             (void*)feature);
         return RT_EOK;
     }
@@ -200,7 +289,7 @@ rt_err_t rt_usbh_hub_set_port_feature(uhub_t hub, rt_uint16_t port,
     /* clear roothub feature */
     if(hub->is_roothub)
     {
-        rt_usb_hcd_hub_control(hub->hcd, port, RH_SET_PORT_FEATURE, 
+        root_hub_ctrl(hub->hcd, port, RH_SET_PORT_FEATURE, 
             (void*)feature);
         return RT_EOK;
     }
@@ -243,7 +332,7 @@ rt_err_t rt_usbh_hub_reset_port(uhub_t hub, rt_uint16_t port)
 
     while(1)
     {
-        ret = rt_usbh_hub_get_port_status(hub, port, (rt_uint8_t*)&pstatus);
+        ret = rt_usbh_hub_get_port_status(hub, port, &pstatus);
         if(!(pstatus & PORT_PRS)) break;
     }
     
@@ -276,7 +365,7 @@ rt_err_t rt_usbh_hub_port_debounce(uhub_t hub, rt_uint16_t port)
 
     for(i=0; i<times; i++)
     {
-        ret = rt_usbh_hub_get_port_status(hub, port, (rt_uint8_t*)&pstatus);
+        ret = rt_usbh_hub_get_port_status(hub, port, &pstatus);
         if(ret != RT_EOK) return ret;
             
         if(!(pstatus & PORT_CCS)) 
@@ -318,10 +407,10 @@ static rt_err_t rt_usbh_hub_port_change(uhub_t hub)
         reconnect = RT_FALSE;
         
         /* get hub port status */
-        ret = rt_usbh_hub_get_port_status(hub, i + 1, (rt_uint8_t*)&pstatus);
+        ret = rt_usbh_hub_get_port_status(hub, i + 1, &pstatus);
         if(ret != RT_EOK) continue;
 
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("port %d status 0x%x\n", i, pstatus));
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("port %d status 0x%x\n", i + 1, pstatus));
 
         /* check port status change */
         if ((pstatus & PORT_CCSC)) 
@@ -339,14 +428,14 @@ static rt_err_t rt_usbh_hub_port_change(uhub_t hub)
         
         if(reconnect)
         {            
-            if(hub->child[i]->status != DEV_STATUS_IDLE) 
+            if(hub->child[i] != RT_NULL && hub->child[i]->status != DEV_STATUS_IDLE) 
                 rt_usbh_detach_instance(hub->child[i]);
             
             ret = rt_usbh_hub_port_debounce(hub, i + 1);
             if(ret != RT_EOK) continue;
             
             /* allocate an usb instance for new connected device */
-            device = rt_usbh_alloc_instance();
+            device = rt_usbh_alloc_instance(hub->hcd);
             if(device == RT_NULL) break;
             
             /* set usb device speed */
@@ -375,31 +464,29 @@ static rt_err_t rt_usbh_hub_port_change(uhub_t hub)
  */
 static void rt_usbh_hub_irq(void* context)
 {
-    upipe_t pipe; 
-    struct uhintf* intf;
+    upipe_t pipe;
     uhub_t hub;
     int timeout = 100;
     
     RT_ASSERT(context != RT_NULL);
     
     pipe = (upipe_t)context;
-    intf = pipe->intf;
-    hub = (uhub_t)intf->user_data;
+    hub = (uhub_t)pipe->user_data;
 
     if(pipe->status != UPIPE_STATUS_OK)
     {
-        rt_kprintf("hub irq error\n");
+        RT_DEBUG_LOG(RT_DEBUG_USB,("hub irq error\n"));
         return;
     }
     
     rt_usbh_hub_port_change(hub);
 
-    rt_kprintf("hub int xfer...\n");
+    rt_kprintf(RT_DEBUG_USB,("hub int xfer...\n"));
 
     /* parameter check */
-     RT_ASSERT(pipe->intf->device->hcd != RT_NULL);
+     RT_ASSERT(pipe->inst->hcd != RT_NULL);
     
-    rt_usb_hcd_pipe_xfer(intf->device->hcd, pipe, hub->buffer, pipe->ep.wMaxPacketSize, timeout);
+    rt_usb_hcd_pipe_xfer(hub->self->hcd, pipe, hub->buffer, pipe->ep.wMaxPacketSize, timeout);
 }
 
 /**
@@ -410,6 +497,7 @@ static void rt_usbh_hub_irq(void* context)
  * 
  * @return the error code, RT_EOK on successfully.
  */
+
 static rt_err_t rt_usbh_hub_enable(void *arg)
 {
     int i = 0;
@@ -418,8 +506,8 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
     uhub_t hub;
     struct uinstance* device;
     struct uhintf* intf = (struct uhintf*)arg;
+    upipe_t pipe_in;
     int timeout = 300;
-
     /* paremeter check */
     RT_ASSERT(intf != RT_NULL);
     
@@ -483,18 +571,21 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
         if(ep_desc->bEndpointAddress & USB_DIR_IN)
         {    
             /* allocate a pipe according to the endpoint type */
-            rt_usb_hcd_alloc_pipe(device->hcd, &hub->pipe_in, intf, 
-                ep_desc, rt_usbh_hub_irq);
+            pipe_in = rt_usb_instance_find_pipe(device,ep_desc->bEndpointAddress);
+            if(pipe_in == RT_NULL)
+            {
+                return RT_ERROR;
+            }
+            rt_usb_pipe_add_callback(pipe_in,rt_usbh_hub_irq);
         }
         else return -RT_ERROR;
     }
 
     /* parameter check */
-     RT_ASSERT(device->hcd != RT_NULL);
-    
-    rt_usb_hcd_int_xfer(device->hcd, hub->pipe_in, hub->buffer, 
-        hub->pipe_in->ep.wMaxPacketSize, timeout);
-    
+    RT_ASSERT(device->hcd != RT_NULL);
+    pipe_in->user_data = hub;
+    rt_usb_hcd_pipe_xfer(hub->hcd, pipe_in, hub->buffer, 
+        pipe_in->ep.wMaxPacketSize, timeout);
     return RT_EOK;
 }
 
@@ -510,20 +601,14 @@ static rt_err_t rt_usbh_hub_disable(void* arg)
 {
     int i;
     uhub_t hub;
-    struct uinstance* device;
-    struct uintf* intf = (struct uintf*)arg;
+    struct uhintf* intf = (struct uhintf*)arg;
 
     /* paremeter check */
     RT_ASSERT(intf != RT_NULL);
 
     RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbh_hub_stop\n"));
-
-    device = intf->device;
     hub = (uhub_t)intf->user_data;
 
-    if(hub->pipe_in != RT_NULL)
-        rt_usb_hcd_free_pipe(device->hcd, hub->pipe_in);
-
     for(i=0; i<hub->num_ports; i++)
     {
         if(hub->child[i] != RT_NULL)
@@ -610,10 +695,14 @@ rt_err_t rt_usbh_event_signal(struct uhost_msg* msg)
  * @return none.
  * 
  */
-void rt_usbh_hub_init(void)
+void rt_usbh_hub_init(uhcd_t hcd)
 {
     rt_thread_t thread;
-    
+    /* link root hub to hcd */
+    root_hub.is_roothub = RT_TRUE;
+    hcd->roothub = &root_hub;
+    root_hub.hcd = hcd;
+    root_hub.num_ports = hcd->num_ports;
     /* create usb message queue */
     usb_mq = rt_mq_create("usbh", 32, 16, RT_IPC_FLAG_FIFO);
     

+ 1 - 1
components/drivers/usb/usbhost/core/usbhost.c

@@ -49,7 +49,7 @@ rt_err_t rt_usb_host_init(void)
     }
 
     /* initialize usb hub */
-    rt_usbh_hub_init();
+    rt_usbh_hub_init((uhcd_t)uhc);
 
     /* initialize class driver */
     rt_usbh_class_driver_init();