diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index 7c1929b15..5b95413b1 100644 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -107,9 +107,14 @@ menu "Using USB" default n if RT_USING_USB_HOST - config RT_USBH_ADK - bool "Enable connected with Android by ADK USB" + config RT_USBH_MSTORAGE + bool "Enable Udisk Drivers" default n + if RT_USBH_MSTORAGE + config UDISK_MOUNTPOINT + string "Udisk mount dir" + default "/" + endif endif config RT_USING_USB_DEVICE bool "Using USB device" diff --git a/components/drivers/include/drivers/usb_host.h b/components/drivers/include/drivers/usb_host.h index 0e6c21432..92adaa3d4 100644 --- a/components/drivers/include/drivers/usb_host.h +++ b/components/drivers/include/drivers/usb_host.h @@ -37,17 +37,21 @@ extern "C" { #define USB_HUB_PORT_NUM 0x04 #define SIZEOF_USB_REQUEST 0x08 -#define DEV_STATUS_IDLE 0x00 -#define DEV_STATUS_BUSY 0x01 -#define DEV_STATUS_ERROR 0x02 +#define DEV_STATUS_IDLE 0x00 +#define DEV_STATUS_BUSY 0x01 +#define DEV_STATUS_ERROR 0x02 #define UPIPE_STATUS_OK 0x00 #define UPIPE_STATUS_STALL 0x01 #define UPIPE_STATUS_ERROR 0x02 +#define USBH_PID_SETUP 0x00 +#define USBH_PID_DATA 0x01 + struct uhcd; -struct uintf; +struct uhintf; struct uhub; +struct upipe; struct uclass_driver { @@ -74,10 +78,16 @@ typedef struct uprotocal* uprotocal_t; struct uinstance { + struct rt_device parent; + struct udevice_descriptor dev_desc; ucfg_desc_t cfg_desc; struct uhcd *hcd; + struct upipe * pipe_ep0_out; + struct upipe * pipe_ep0_in; + rt_list_t pipe; + rt_uint8_t status; rt_uint8_t type; rt_uint8_t index; @@ -86,12 +96,12 @@ struct uinstance rt_uint8_t max_packet_size; rt_uint8_t port; - struct uhub* parent; - struct uintf* intf[USB_MAX_INTERFACE]; + struct uhub* parent_hub; + struct uhintf* intf[USB_MAX_INTERFACE]; }; typedef struct uinstance* uinst_t; -struct uintf +struct uhintf { struct uinstance* device; uintf_desc_t intf_desc; @@ -102,9 +112,11 @@ struct uintf struct upipe { + rt_list_t list; + rt_uint8_t pipe_index; rt_uint32_t status; struct uendpoint_descriptor ep; - struct uintf* intf; + uinst_t inst; func_callback callback; void* user_data; }; @@ -118,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; @@ -127,23 +139,18 @@ typedef struct uhub* uhub_t; struct uhcd_ops { - int (*ctl_xfer)(struct uinstance* inst, ureq_t setup, void* buffer, int nbytes, - int timeout); - int (*bulk_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout); - int (*int_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout); - int (*iso_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout); - - rt_err_t (*alloc_pipe)(struct upipe** pipe, struct uintf* intf, uep_desc_t ep, - func_callback callback); - rt_err_t (*free_pipe)(upipe_t pipe); - rt_err_t (*hub_ctrl)(rt_uint16_t port, rt_uint8_t cmd, void *args); + 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 (*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; - struct uhcd_ops* ops; - struct uhub* roothub; + uhcd_ops_t ops; + rt_uint8_t num_ports; + uhub_t roothub; }; typedef struct uhcd* uhcd_t; @@ -171,22 +178,19 @@ 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); +rt_err_t rt_usbh_get_descriptor(struct uinstance* device, rt_uint8_t type, void* buffer, int nbytes); rt_err_t rt_usbh_set_configure(struct uinstance* device, int config); rt_err_t rt_usbh_set_address(struct uinstance* device); rt_err_t rt_usbh_set_interface(struct uinstance* device, int intf); rt_err_t rt_usbh_clear_feature(struct uinstance* device, int endpoint, int feature); -rt_err_t rt_usbh_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, - uintf_desc_t* intf_desc); -rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num, - uep_desc_t* ep_desc); +rt_err_t rt_usbh_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, uintf_desc_t* intf_desc); +rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num, uep_desc_t* ep_desc); /* usb class driver interface */ rt_err_t rt_usbh_class_driver_init(void); @@ -197,26 +201,17 @@ rt_err_t rt_usbh_class_driver_disable(ucd_t drv, void* args); ucd_t rt_usbh_class_driver_find(int class_code, int subclass_code); /* usb class driver implement */ -ucd_t rt_usbh_class_driver_hid(void); ucd_t rt_usbh_class_driver_hub(void); ucd_t rt_usbh_class_driver_storage(void); -ucd_t rt_usbh_class_driver_adk(void); -/* usb hid protocal implement */ -uprotocal_t rt_usbh_hid_protocal_kbd(void); -uprotocal_t rt_usbh_hid_protocal_mouse(void); -/* usb adk class driver interface */ -rt_err_t rt_usbh_adk_set_string(const char* manufacturer, const char* model, - const char* description, const char* version, const char* uri, - const char* serial); /* 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, @@ -224,58 +219,59 @@ 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); -/* usb host controller driver interface */ -rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe, - struct uintf* intf, uep_desc_t ep, func_callback callback) -{ - if(intf == RT_NULL) return -RT_EIO; - return hcd->ops->alloc_pipe(pipe, intf, ep, callback); +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_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) +{ + *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_bulk_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, - int nbytes, int 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) { - if(pipe == RT_NULL) return -1; - if(pipe->intf == RT_NULL) return -1; - if(pipe->intf->device == RT_NULL) return -1; - if(pipe->intf->device->status == DEV_STATUS_IDLE) - return -1; - - return hcd->ops->bulk_xfer(pipe, buffer, nbytes, timeout); -} - -rt_inline int rt_usb_hcd_control_xfer(uhcd_t hcd, struct uinstance* device, ureq_t setup, - void* buffer, int nbytes, int timeout) -{ - if(device->status == DEV_STATUS_IDLE) return -1; - - return hcd->ops->ctl_xfer(device, setup, buffer, nbytes, timeout); -} - -rt_inline int rt_usb_hcd_int_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, - int nbytes, int timeout) -{ - if(pipe == RT_NULL) return -1; - if(pipe->intf == RT_NULL) return -1; - if(pipe->intf->device == RT_NULL) return -1; - if(pipe->intf->device->status == DEV_STATUS_IDLE) - return -1; - - return hcd->ops->int_xfer(pipe, buffer, nbytes, timeout); -} - -rt_inline rt_err_t rt_usb_hcd_hub_control(uhcd_t hcd, rt_uint16_t port, - rt_uint8_t cmd, void *args) -{ - return hcd->ops->hub_ctrl(port, cmd, args); + return hcd->ops->pipe_xfer(pipe, USBH_PID_SETUP, (void *)setup, 8, timeout); } #ifdef __cplusplus @@ -284,3 +280,4 @@ rt_inline rt_err_t rt_usb_hcd_hub_control(uhcd_t hcd, rt_uint16_t port, #endif + diff --git a/components/drivers/usb/usbhost/SConscript b/components/drivers/usb/usbhost/SConscript index e8ba3c4a8..b12adfc5a 100644 --- a/components/drivers/usb/usbhost/SConscript +++ b/components/drivers/usb/usbhost/SConscript @@ -29,6 +29,6 @@ if GetDepend('RT_USBH_HID_KEYBOARD'): CPPPATH = [cwd, cwd + '/class', cwd + '/core', \ cwd + '/include', cwd + '../../../include'] -group = DefineGroup('rt_usbh', src, depend = ['RT_USING_USBH'], CPPPATH = CPPPATH) +group = DefineGroup('rt_usbh', src, depend = ['RT_USING_USB_HOST'], CPPPATH = CPPPATH) Return('group') diff --git a/components/drivers/usb/usbhost/class/mass.c b/components/drivers/usb/usbhost/class/mass.c index 845aeb235..ff52f8d6f 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; @@ -59,11 +59,14 @@ static rt_err_t _pipe_check(struct uintf* intf, upipe_t pipe) rt_kprintf("pipe status error\n"); return -RT_EIO; } + if(pipe->status == UPIPE_STATUS_STALL) + { + /* clear the pipe stall status */ + ret = rt_usbh_clear_feature(device, pipe->ep.bEndpointAddress, + USB_FEATURE_ENDPOINT_HALT); + if(ret != RT_EOK) return ret; + } - /* clear the pipe stall status */ - ret = rt_usbh_clear_feature(device, pipe->ep.bEndpointAddress, - USB_FEATURE_ENDPOINT_HALT); - if(ret != RT_EOK) return ret; rt_thread_delay(50); @@ -74,7 +77,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 +96,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 +119,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 +130,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 +141,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 +175,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 +190,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 +212,24 @@ 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 = 0; + setup.wLength = 1; /* 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) + { + return -RT_EIO; + } + if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, max_lun, 1, timeout) != 1) + { + return -RT_EIO; + } + if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) != 0) + { + return -RT_EIO; + } return RT_EOK; } @@ -228,7 +240,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,14 +262,19 @@ 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; + } + if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) != 0) + { + return -RT_EIO; + } return RT_EOK; } @@ -271,7 +288,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 +334,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 +378,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 +414,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 +450,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; @@ -455,7 +472,7 @@ rt_err_t rt_usbh_storage_inquiry(struct uintf* intf, rt_uint8_t* buffer) cmd.xfer_len = 36; cmd.dflags = CBWFLAGS_DIR_IN; cmd.lun = 0; - cmd.cb_len = 12; + cmd.cb_len = 6;//12 cmd.cb[0] = SCSI_INQUIRY_CMD; cmd.cb[4] = 36; @@ -470,7 +487,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 +529,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 +573,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 +607,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,23 +621,9 @@ 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); - - /* free interface instance */ - if(intf != RT_NULL) rt_free(intf); - return RT_EOK; } 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..6a4e02fa9 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; @@ -141,7 +141,7 @@ static rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buff * * @return the error code, RT_EOK on successfully. */ -static rt_err_t rt_udisk_control(rt_device_t dev, rt_uint8_t cmd, void *args) +static rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args) { ustor_t stor; struct ustor_data* data; @@ -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; @@ -203,14 +203,21 @@ rt_err_t rt_udisk_run(struct uintf* intf) rt_usbh_clear_feature(intf->device, 0, USB_FEATURE_ENDPOINT_HALT); /* reset pipe in endpoint */ - ret = rt_usbh_clear_feature(intf->device, + if(stor->pipe_in->status == UPIPE_STATUS_STALL) + { + ret = rt_usbh_clear_feature(intf->device, stor->pipe_in->ep.bEndpointAddress, USB_FEATURE_ENDPOINT_HALT); - if(ret != RT_EOK) return ret; + if(ret != RT_EOK) return ret; + } + /* reset pipe out endpoint */ - ret = rt_usbh_clear_feature(intf->device, - stor->pipe_out->ep.bEndpointAddress, USB_FEATURE_ENDPOINT_HALT); - if(ret != RT_EOK) return ret; + if(stor->pipe_out->status == UPIPE_STATUS_STALL) + { + ret = rt_usbh_clear_feature(intf->device, + stor->pipe_out->ep.bEndpointAddress, USB_FEATURE_ENDPOINT_HALT); + if(ret != RT_EOK) return ret; + } while((ret = rt_usbh_storage_inquiry(intf, inquiry)) != RT_EOK) { @@ -223,7 +230,7 @@ rt_err_t rt_udisk_run(struct uintf* intf) } i = 0; - + /* wait device ready */ while((ret = rt_usbh_storage_test_unit_ready(intf)) != RT_EOK) { @@ -382,7 +389,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..854c3815a 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, + 0x00, + 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, + 0x00, + 0x00, +}; rt_err_t rt_usbh_attatch_instance(uinst_t device) { int i = 0; @@ -82,12 +103,21 @@ 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*/ + ep0_out_desc.wMaxPacketSize = 8; + ep0_in_desc.wMaxPacketSize = 8; + 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")); @@ -99,6 +129,10 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) return ret; } + /* reset bus */ + rt_usbh_hub_reset_port(device->parent_hub, device->port); + rt_thread_delay(2); + rt_usbh_hub_clear_port_feature(device->parent_hub, i + 1, PORT_FEAT_C_CONNECTION); /* set device address */ ret = rt_usbh_set_address(device); if(ret != RT_EOK) @@ -106,16 +140,23 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) rt_kprintf("set device address failed\n"); return ret; } - + /* 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); + /* set device max packet size */ - device->max_packet_size = device->dev_desc.bMaxPacketSize0; - + ep0_out_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0; + ep0_in_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0; + + /* alloc 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); RT_DEBUG_LOG(RT_DEBUG_USB, ("get device descriptor length %d\n", dev_desc->bLength)); /* get full device descriptor again */ - ret = rt_usbh_get_descriptor - (device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength); + ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength); if(ret != RT_EOK) { rt_kprintf("get full device descriptor failed\n"); @@ -148,8 +189,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 */ @@ -163,7 +206,25 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) RT_DEBUG_LOG(RT_DEBUG_USB, ("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 +232,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 +266,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 +274,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; @@ -226,8 +283,19 @@ 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]); + rt_free(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); + + while(device->pipe.next!= &device->pipe) + { + l = device->pipe.next; + rt_list_remove(l); + 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 +326,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 +362,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; + 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; + } - rt_thread_delay(50); - - device->address = device->index; - return RT_EOK; } @@ -319,9 +397,14 @@ 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; + } + if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) != 0) + { + return RT_ERROR; + } return RT_EOK; } @@ -348,8 +431,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 +462,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 +534,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 +564,25 @@ 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; + rt_uint8_t * pbuffer = (rt_uint8_t *)buffer; + do + { + RT_DEBUG_LOG(RT_DEBUG_USB,("pipe transform remain size,: %d\n", remain_size)); + send_size = (remain_size > pipe->ep.wMaxPacketSize) ? pipe->ep.wMaxPacketSize : remain_size; + if(hcd->ops->pipe_xfer(pipe, USBH_PID_DATA, pbuffer, send_size, timeout) == send_size) + { + remain_size -= send_size; + pbuffer += 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 24ce980bb..56e40bb0d 100644 --- a/components/drivers/usb/usbhost/core/hub.c +++ b/components/drivers/usb/usbhost/core/hub.c @@ -25,10 +25,99 @@ #include #include -#define USB_THREAD_STACK_SIZE 2048 +#define USB_THREAD_STACK_SIZE 4096 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 @@ -40,8 +129,7 @@ static struct uclass_driver hub_driver; * * @return the error code, RT_EOK on successfully. */ -rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer, - rt_size_t nbytes) +rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer, rt_size_t nbytes) { struct urequest setup; int timeout = 100; @@ -49,16 +137,20 @@ rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer /* parameter check */ RT_ASSERT(device != RT_NULL); - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_DEVICE; + setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; setup.bRequest = USB_REQ_GET_DESCRIPTOR; setup.wIndex = 0; setup.wLength = nbytes; setup.wValue = USB_DESC_TYPE_HUB << 8; - if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, nbytes, - timeout) == nbytes) return RT_EOK; - else return -RT_FALSE; + 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) + { + return RT_EOK; + } + } + return -RT_FALSE; } /** @@ -70,25 +162,27 @@ rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer * * @return the error code, RT_EOK on successfully. */ -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) { struct urequest setup; int timeout = 100; - int length = 4; /* parameter check */ RT_ASSERT(device != RT_NULL); - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_DEVICE; + setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; setup.bRequest = USB_REQ_GET_STATUS; setup.wIndex = 0; - setup.wLength = length; + setup.wLength = 4; setup.wValue = 0; - - if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, length, - timeout) == length) return RT_EOK; - else return -RT_FALSE; + 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, 4, timeout) == 4) + { + return RT_EOK; + } + } + return -RT_FALSE; } /** @@ -101,12 +195,10 @@ rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint8_t* buffer) * * @return the error code, RT_EOK on successfully. */ -rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port, - rt_uint8_t* buffer) +rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port, rt_uint32_t* buffer) { struct urequest setup; int timeout = 100; - int length = 4; /* parameter check */ RT_ASSERT(hub != RT_NULL); @@ -114,21 +206,25 @@ rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port, /* 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; } - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_OTHER; + setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_OTHER; setup.bRequest = USB_REQ_GET_STATUS; setup.wIndex = port; setup.wLength = 4; setup.wValue = 0; - if(rt_usb_hcd_control_xfer(hub->hcd, hub->self, &setup, buffer, - length, timeout) == timeout) return RT_EOK; - else return -RT_FALSE; + if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) + { + if(rt_usb_hcd_pipe_xfer(hub->hcd, hub->self->pipe_ep0_in, buffer, 4, timeout) == 4) + { + return RT_EOK; + } + } + return -RT_FALSE; } /** @@ -141,8 +237,7 @@ rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port, * * @return the error code, RT_EOK on successfully. */ -rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port, - rt_uint16_t feature) +rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port, rt_uint16_t feature) { struct urequest setup; int timeout = 100; @@ -153,7 +248,7 @@ rt_err_t rt_usbh_hub_clear_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_CLEAR_PORT_FEATURE, + root_hub_ctrl(hub->hcd, port, RH_CLEAR_PORT_FEATURE, (void*)feature); return RT_EOK; } @@ -165,9 +260,11 @@ rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port, setup.wLength = 0; setup.wValue = feature; - if(rt_usb_hcd_control_xfer(hub->hcd, hub->self, &setup, RT_NULL, 0, - timeout) == 0) return RT_EOK; - else return -RT_FALSE; + if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) + { + return RT_EOK; + } + return -RT_FALSE; } /** @@ -192,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; } @@ -204,8 +301,10 @@ rt_err_t rt_usbh_hub_set_port_feature(uhub_t hub, rt_uint16_t port, setup.wLength = 0; setup.wValue = feature; - if(rt_usb_hcd_control_xfer(hub->hcd, hub->self, &setup, RT_NULL, 0, - timeout) == 0) return RT_EOK; + if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) + { + return RT_EOK; + } else return -RT_FALSE; } @@ -233,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; } @@ -266,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 */ device->speed = (pstatus & PORT_LSDA) ? 1 : 0; - device->parent = hub; + device->parent_hub = hub; device->hcd = hub->hcd; hub->child[i] = device; @@ -365,32 +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 uintf* 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_DEBUG_LOG(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_int_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); } /** @@ -401,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; @@ -408,9 +505,9 @@ static rt_err_t rt_usbh_hub_enable(void *arg) uep_desc_t ep_desc; uhub_t hub; struct uinstance* device; - struct uintf* intf = (struct uintf*)arg; + struct uhintf* intf = (struct uhintf*)arg; + upipe_t pipe_in; int timeout = 300; - /* paremeter check */ RT_ASSERT(intf != RT_NULL); @@ -474,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; } @@ -501,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) @@ -601,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 dcfdf6a12..15ac0b76c 100644 --- a/components/drivers/usb/usbhost/core/usbhost.c +++ b/components/drivers/usb/usbhost/core/usbhost.c @@ -40,9 +40,6 @@ rt_err_t rt_usb_host_init(void) { ucd_t drv; rt_device_t uhc; -#ifdef RT_USBH_HID - uprotocal_t protocal; -#endif uhc = rt_device_find(USB_HOST_CONTROLLER_NAME); if(uhc == RT_NULL) @@ -52,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(); @@ -63,30 +60,6 @@ rt_err_t rt_usb_host_init(void) rt_usbh_class_driver_register(drv); #endif -#ifdef RT_USBH_HID - /* register hid class driver */ - drv = rt_usbh_class_driver_hid(); - rt_usbh_class_driver_register(drv); - -#ifdef RT_USBH_HID_KEYBOARD - /* register hid keyboard protocal */ - protocal = rt_usbh_hid_protocal_kbd(); - rt_usbh_hid_protocal_register(protocal); -#endif - -#ifdef RT_USBH_HID_MOUSE - /* register hid mouse protocal */ - protocal = rt_usbh_hid_protocal_mouse(); - rt_usbh_hid_protocal_register(protocal); -#endif -#endif - -#ifdef RT_USBH_ADK - /* register adk class driver */ - drv = rt_usbh_class_driver_adk(); - rt_usbh_class_driver_register(drv); -#endif - /* register hub class driver */ drv = rt_usbh_class_driver_hub(); rt_usbh_class_driver_register(drv);