From 18d42fe077ac05891df9ee9aac2312469ed0154e Mon Sep 17 00:00:00 2001 From: uestczyh222 Date: Thu, 14 Dec 2017 03:14:44 +0800 Subject: [PATCH] [Components][USBHOST]Core OK --- components/drivers/include/drivers/usb_host.h | 76 +++++++-- components/drivers/usb/usbhost/class/mass.c | 89 +++++----- components/drivers/usb/usbhost/class/mass.h | 18 +- components/drivers/usb/usbhost/class/udisk.c | 8 +- components/drivers/usb/usbhost/core/core.c | 157 ++++++++++++++---- components/drivers/usb/usbhost/core/hub.c | 157 ++++++++++++++---- components/drivers/usb/usbhost/core/usbhost.c | 2 +- 7 files changed, 361 insertions(+), 146 deletions(-) diff --git a/components/drivers/include/drivers/usb_host.h b/components/drivers/include/drivers/usb_host.h index a79254c9b..92adaa3d4 100644 --- a/components/drivers/include/drivers/usb_host.h +++ b/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 + diff --git a/components/drivers/usb/usbhost/class/mass.c b/components/drivers/usb/usbhost/class/mass.c index 845aeb235..2d29c6354 100644 --- a/components/drivers/usb/usbhost/class/mass.c +++ b/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); diff --git a/components/drivers/usb/usbhost/class/mass.h b/components/drivers/usb/usbhost/class/mass.h index 5965640cf..38cdb3239 100644 --- a/components/drivers/usb/usbhost/class/mass.h +++ b/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 diff --git a/components/drivers/usb/usbhost/class/udisk.c b/components/drivers/usb/usbhost/class/udisk.c index 77478554d..e762f2173 100644 --- a/components/drivers/usb/usbhost/class/udisk.c +++ b/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; diff --git a/components/drivers/usb/usbhost/core/core.c b/components/drivers/usb/usbhost/core/core.c index 2401552b4..482a36867 100644 --- a/components/drivers/usb/usbhost/core/core.c +++ b/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; icfg_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; icfg_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; +} diff --git a/components/drivers/usb/usbhost/core/hub.c b/components/drivers/usb/usbhost/core/hub.c index 16a20d885..0f14acdd2 100644 --- a/components/drivers/usb/usbhost/core/hub.c +++ b/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; ichild[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; inum_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); diff --git a/components/drivers/usb/usbhost/core/usbhost.c b/components/drivers/usb/usbhost/core/usbhost.c index 17e34474f..15ac0b76c 100644 --- a/components/drivers/usb/usbhost/core/usbhost.c +++ b/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(); -- GitLab