From 3575b0fdc9e90c906234b31693cd68791b7c5b64 Mon Sep 17 00:00:00 2001 From: thewon Date: Tue, 6 Jul 2021 16:53:29 +0800 Subject: [PATCH] optimize stm32 usbhost driver --- bsp/stm32/libraries/HAL_Drivers/drv_usbh.c | 89 +++++++++++++------ .../drivers/include/drivers/usb_common.h | 5 +- components/drivers/include/drivers/usb_host.h | 19 +++- components/drivers/usb/usbhost/class/mass.c | 11 ++- components/drivers/usb/usbhost/class/udisk.c | 32 +++++-- components/drivers/usb/usbhost/core/driver.c | 13 ++- components/drivers/usb/usbhost/core/hub.c | 8 +- .../drivers/usb/usbhost/core/usbhost_core.c | 77 +++++++++++----- 8 files changed, 189 insertions(+), 65 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usbh.c b/bsp/stm32/libraries/HAL_Drivers/drv_usbh.c index 9486e1a56d..522b210e1f 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_usbh.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usbh.c @@ -7,6 +7,8 @@ * Date Author Notes * 2017-10-30 ZYH the first version * 2019-12-19 tyustli port to stm32 series + * 2021-07-03 THEWON optimize hcd state + * and fix timeout & nak error */ #include "drv_usbh.h" #include "board.h" @@ -59,13 +61,18 @@ static rt_err_t drv_reset_port(rt_uint8_t port) static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts) { int timeout = timeouts; + int size = 0; + rt_tick_t tick; + rt_err_t result; while (1) { if (!connect_status) { - return -1; + result = -RT_EIO; + break; } + rt_thread_mdelay(1); rt_completion_init(&urb_completion); HAL_HCD_HC_SubmitRequest(&stm32_hhcd_fs, pipe->pipe_index, @@ -75,24 +82,40 @@ static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbyte buffer, nbytes, 0); - rt_completion_wait(&urb_completion, timeout); - rt_thread_mdelay(1); - if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_NAK) + result = rt_completion_wait(&urb_completion, timeout); + if (result == -RT_ETIMEOUT) { + connect_status = RT_FALSE; + result = -RT_ETIMEOUT; + break; + } + else if (result != RT_EOK) { - RT_DEBUG_LOG(RT_DEBUG_USB, ("nak\n")); - if (pipe->ep.bmAttributes == USB_EP_ATTR_INT) + connect_status = RT_FALSE; + result = -RT_ERROR; + break; + } + tick = rt_tick_get(); + while(HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_NAK) + { + if ((rt_tick_get() - tick) >= RT_TICK_PER_SECOND * 5) { - rt_thread_delay((pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) > 0 ? (pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) : 1); + break; } - HAL_HCD_HC_Halt(&stm32_hhcd_fs, pipe->pipe_index); - HAL_HCD_HC_Init(&stm32_hhcd_fs, - pipe->pipe_index, - pipe->ep.bEndpointAddress, - pipe->inst->address, - USB_OTG_SPEED_FULL, - pipe->ep.bmAttributes, - pipe->ep.wMaxPacketSize); - continue; + else + { + rt_thread_yield(); + } + } + + if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_IDLE) + { + rt_thread_mdelay(1); + } + else if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_NAK) + { + RT_DEBUG_LOG(RT_DEBUG_USB, ("nak\n")); + result = -RT_ETIMEOUT; + break; } else if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_STALL) { @@ -102,9 +125,14 @@ static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbyte { pipe->callback(pipe); } - return -1; + result = -RT_ERROR; + break; + } + else if (HAL_HCD_HC_GetURBState(&stm32_hhcd_fs, pipe->pipe_index) == URB_NOTREADY) + { + rt_thread_mdelay(1); } - else if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == URB_ERROR) + else if (HAL_HCD_HC_GetURBState(&stm32_hhcd_fs, pipe->pipe_index) == URB_ERROR) { RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n")); pipe->status = UPIPE_STATUS_ERROR; @@ -112,9 +140,10 @@ static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbyte { pipe->callback(pipe); } - return -1; + result = -RT_ERROR; + break; } - else if(URB_DONE == HAL_HCD_HC_GetURBState(&stm32_hhcd_fs, pipe->pipe_index)) + else if(HAL_HCD_HC_GetURBState(&stm32_hhcd_fs, pipe->pipe_index) == URB_DONE) { RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n")); pipe->status = UPIPE_STATUS_OK; @@ -122,19 +151,29 @@ static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbyte { pipe->callback(pipe); } - size_t size = HAL_HCD_HC_GetXferCount(&stm32_hhcd_fs, pipe->pipe_index); + size = HAL_HCD_HC_GetXferCount(&stm32_hhcd_fs, pipe->pipe_index); if (pipe->ep.bEndpointAddress & 0x80) { - return size; } else if (pipe->ep.bEndpointAddress & 0x00) { - return size; } - return nbytes; + else + { + size = nbytes; + } + result = RT_EOK; + break; } + } - continue; + if (result == RT_EOK) + { + return size; + } + else + { + return result; } } diff --git a/components/drivers/include/drivers/usb_common.h b/components/drivers/include/drivers/usb_common.h index 920a85e61b..2c83a18a5f 100644 --- a/components/drivers/include/drivers/usb_common.h +++ b/components/drivers/include/drivers/usb_common.h @@ -8,6 +8,8 @@ * 2012-10-01 Yi Qiu first version * 2013-04-26 aozima add DEVICEQUALIFIER support. * 2017-11-15 ZYH fix ep0 transform error + * 2021-07-03 THEWON optimize struct uinstance + * and change some return value to negtive */ #ifndef __USB_COMMON_H__ @@ -288,6 +290,7 @@ struct udevice_descriptor rt_uint8_t iProduct; rt_uint8_t iSerialNumber; rt_uint8_t bNumConfigurations; + rt_uint8_t data[0]; }; typedef struct udevice_descriptor* udev_desc_t; @@ -301,7 +304,7 @@ struct uconfig_descriptor rt_uint8_t iConfiguration; rt_uint8_t bmAttributes; rt_uint8_t MaxPower; - rt_uint8_t data[2048]; + rt_uint8_t data[0]; }; typedef struct uconfig_descriptor* ucfg_desc_t; diff --git a/components/drivers/include/drivers/usb_host.h b/components/drivers/include/drivers/usb_host.h index 2031e2cdc0..d0c9d897a1 100644 --- a/components/drivers/include/drivers/usb_host.h +++ b/components/drivers/include/drivers/usb_host.h @@ -6,6 +6,9 @@ * Change Logs: * Date Author Notes * 2011-3-12 Yi Qiu first version + * 2021-07-03 THEWON optimize struct uinstance + * and usbhost lock & sutup_xfer timeout retry + * and change some return value to negtive */ #ifndef __RT_USB_HOST_H__ @@ -66,7 +69,7 @@ struct uinstance { struct rt_device parent; - struct udevice_descriptor dev_desc; + udev_desc_t dev_desc; ucfg_desc_t cfg_desc; struct uhcd *hcd; @@ -120,6 +123,7 @@ struct uhub rt_uint8_t buffer[8]; struct uinstance* self; struct uhcd *hcd; + rt_mutex_t usbh_lock; }; typedef struct uhub* uhub_t; @@ -234,7 +238,7 @@ rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe, uinst_t inst *pipe = (upipe_t)rt_malloc(sizeof(struct upipe)); if(*pipe == RT_NULL) { - return RT_ERROR; + return -RT_ERROR; } rt_memset(*pipe,0,sizeof(struct upipe)); (*pipe)->inst = inst; @@ -257,7 +261,16 @@ rt_inline rt_err_t rt_usb_hcd_free_pipe(uhcd_t hcd, upipe_t pipe) 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); + int tout_retry = 0; + rt_err_t ret = RT_EOK; + + do { + ret = hcd->ops->pipe_xfer(pipe, USBH_PID_SETUP, (void *)setup, 8, timeout); + tout_retry++; + timeout *= 3; + } while(ret == -RT_ETIMEOUT && tout_retry < 3); + + return ret; } #ifdef __cplusplus diff --git a/components/drivers/usb/usbhost/class/mass.c b/components/drivers/usb/usbhost/class/mass.c index abd89a5efc..72b076b638 100644 --- a/components/drivers/usb/usbhost/class/mass.c +++ b/components/drivers/usb/usbhost/class/mass.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2011-12-12 Yi Qiu first version + * 2021-07-03 THEWON change some return value to negtive */ #include @@ -63,7 +64,6 @@ static rt_err_t _pipe_check(struct uhintf* intf, upipe_t pipe) if(ret != RT_EOK) return ret; } - rt_thread_delay(50); rt_kprintf("pipes1 0x%x, 0x%x\n", stor->pipe_in, stor->pipe_out); @@ -100,6 +100,7 @@ static rt_err_t rt_usb_bulk_only_xfer(struct uhintf* intf, upipe_t pipe; struct ustorage_csw csw; ustor_t stor; + static int wr_delay = 1; RT_ASSERT(cmd != RT_NULL); @@ -126,12 +127,17 @@ static rt_err_t rt_usb_bulk_only_xfer(struct uhintf* intf, { pipe = (cmd->dflags == CBWFLAGS_DIR_IN) ? stor->pipe_in : stor->pipe_out; + rt_thread_mdelay(wr_delay); size = rt_usb_hcd_pipe_xfer(pipe->inst->hcd, pipe, (void*)buffer, cmd->xfer_len, timeout); if(size != cmd->xfer_len) { rt_kprintf("request size %d, transfer size %d\n", cmd->xfer_len, size); + if (wr_delay < 5) + { + wr_delay += 2; + } break; } } @@ -587,9 +593,8 @@ static rt_err_t rt_usbh_storage_enable(void* arg) /* should implement as callback */ ret = rt_udisk_run(intf); - if(ret != RT_EOK) return ret; - return RT_EOK; + return ret; } /** diff --git a/components/drivers/usb/usbhost/class/udisk.c b/components/drivers/usb/usbhost/class/udisk.c index 8be311e657..576d12da4e 100644 --- a/components/drivers/usb/usbhost/class/udisk.c +++ b/components/drivers/usb/usbhost/class/udisk.c @@ -6,6 +6,9 @@ * Change Logs: * Date Author Notes * 2011-12-12 Yi Qiu first version + * 2021-07-03 THEWON optimize rt_udisk_run + * and change some return value to negtive + * and usbhost lock */ #include @@ -80,9 +83,17 @@ static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer, data = (struct ustor_data*)dev->user_data; intf = data->intf; + if (intf->device->parent_hub->is_roothub) + { + rt_mutex_take(intf->device->parent_hub->usbh_lock, RT_WAITING_FOREVER); + } ret = rt_usbh_storage_read10(intf, (rt_uint8_t*)buffer, pos, size, timeout); + if (intf->device->parent_hub->is_roothub) + { + rt_mutex_release(intf->device->parent_hub->usbh_lock); + } if (ret != RT_EOK) { rt_kprintf("usb mass_storage read failed\n"); @@ -118,8 +129,17 @@ static rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buff data = (struct ustor_data*)dev->user_data; intf = data->intf; + if (intf->device->parent_hub->is_roothub) + { + rt_mutex_take(intf->device->parent_hub->usbh_lock, RT_WAITING_FOREVER); + } ret = rt_usbh_storage_write10(intf, (rt_uint8_t*)buffer, pos, size, timeout); + + if (intf->device->parent_hub->is_roothub) + { + rt_mutex_release(intf->device->parent_hub->usbh_lock); + } if (ret != RT_EOK) { rt_kprintf("usb mass_storage write %d sector failed\n", size); @@ -189,7 +209,7 @@ rt_err_t rt_udisk_run(struct uhintf* intf) char dname[8]; char sname[8]; rt_uint8_t max_lun, *sector, sense[18], inquiry[36]; - struct dfs_partition part[MAX_PARTITION_COUNT]; + struct dfs_partition part; ustor_t stor; /* check parameter */ @@ -218,7 +238,6 @@ rt_err_t rt_udisk_run(struct uhintf* intf) if(ret != RT_EOK) return ret; } - /* reset pipe out endpoint */ if(stor->pipe_out->status == UPIPE_STATUS_STALL) { @@ -277,15 +296,15 @@ rt_err_t rt_udisk_run(struct uhintf* intf) stor->capicity[1] = uswap_32(stor->capicity[1]); stor->capicity[0] += 1; - RT_DEBUG_LOG(RT_DEBUG_USB, ("capicity %d, block size %d\n", + RT_DEBUG_LOG(RT_DEBUG_USB, ("blocks %d, block size %d\n", stor->capicity[0], stor->capicity[1])); /* get the first sector to read partition table */ - sector = (rt_uint8_t*) rt_malloc (SECTOR_SIZE); + sector = (rt_uint8_t*)rt_malloc(SECTOR_SIZE); if (sector == RT_NULL) { rt_kprintf("allocate partition sector buffer failed\n"); - return -RT_ERROR; + return -RT_ENOMEM; } rt_memset(sector, 0, SECTOR_SIZE); @@ -307,7 +326,7 @@ rt_err_t rt_udisk_run(struct uhintf* intf) for(i=0; iudisk_id = udisk_get_id(); rt_snprintf(dname, 6, "ud%d-%d", data->udisk_id, i); rt_snprintf(sname, 8, "sem_ud%d", i); + data->part = part; data->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); /* register sdcard device */ diff --git a/components/drivers/usb/usbhost/core/driver.c b/components/drivers/usb/usbhost/core/driver.c index 6dad1409a0..3e5f67b340 100644 --- a/components/drivers/usb/usbhost/core/driver.c +++ b/components/drivers/usb/usbhost/core/driver.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2011-03-12 Yi Qiu first version + * 2021-07-03 THEWON change some return value to negtive */ #include @@ -75,9 +76,11 @@ rt_err_t rt_usbh_class_driver_enable(ucd_t drv, void* args) RT_ASSERT(drv != RT_NULL); if(drv->enable != RT_NULL) - drv->enable(args); + { + return drv->enable(args); + } - return RT_EOK; + return -RT_EEMPTY; } /** @@ -93,9 +96,11 @@ rt_err_t rt_usbh_class_driver_disable(ucd_t drv, void* args) RT_ASSERT(drv != RT_NULL); if(drv->disable != RT_NULL) - drv->disable(args); + { + return drv->disable(args); + } - return RT_EOK; + return -RT_EEMPTY; } diff --git a/components/drivers/usb/usbhost/core/hub.c b/components/drivers/usb/usbhost/core/hub.c index b6381ec300..8f8a5c329f 100644 --- a/components/drivers/usb/usbhost/core/hub.c +++ b/components/drivers/usb/usbhost/core/hub.c @@ -6,6 +6,8 @@ * Change Logs: * Date Author Notes * 2011-12-12 Yi Qiu first version + * 2021-07-03 THEWON change some return value to negtive + * and usbhost lock */ #include @@ -74,7 +76,7 @@ static rt_err_t root_hub_ctrl(struct uhcd *hcd, rt_uint16_t port, rt_uint8_t cmd } break; default: - return RT_ERROR; + return -RT_ERROR; } return RT_EOK; } @@ -575,7 +577,7 @@ static rt_err_t rt_usbh_hub_enable(void *arg) pipe_in = rt_usb_instance_find_pipe(device,ep_desc->bEndpointAddress); if(pipe_in == RT_NULL) { - return RT_ERROR; + return -RT_ERROR; } rt_usb_pipe_add_callback(pipe_in,rt_usbh_hub_irq); } @@ -660,7 +662,9 @@ static void rt_usbh_hub_thread_entry(void* parameter) switch (msg.type) { case USB_MSG_CONNECT_CHANGE: + rt_mutex_take(root_hub.usbh_lock, RT_WAITING_FOREVER); rt_usbh_hub_port_change(msg.content.hub); + rt_mutex_release(root_hub.usbh_lock); break; case USB_MSG_CALLBACK: /* invoke callback */ diff --git a/components/drivers/usb/usbhost/core/usbhost_core.c b/components/drivers/usb/usbhost/core/usbhost_core.c index 71fe3b8b3f..9f3306c1f2 100644 --- a/components/drivers/usb/usbhost/core/usbhost_core.c +++ b/components/drivers/usb/usbhost/core/usbhost_core.c @@ -6,6 +6,9 @@ * Change Logs: * Date Author Notes * 2011-12-12 Yi Qiu first version + * 2021-07-03 THEWON optimize struct uinstance + * and rt_usb_hcd_pipe_xfer add timeout retry + * and change some return value to negtive */ #include @@ -86,7 +89,7 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) { int i = 0; rt_err_t ret = RT_EOK; - struct uconfig_descriptor cfg_desc; + ucfg_desc_t cfg_desc; udev_desc_t dev_desc; uintf_desc_t intf_desc; uep_desc_t ep_desc; @@ -96,9 +99,6 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) 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; @@ -108,10 +108,13 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) RT_DEBUG_LOG(RT_DEBUG_USB, ("start enumnation\n")); /* get device descriptor head */ + dev_desc = (udev_desc_t)rt_malloc(sizeof(struct udevice_descriptor)); + rt_memset(dev_desc, 0, sizeof(struct udevice_descriptor)); ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8); if(ret != RT_EOK) { rt_kprintf("get device descriptor head failed\n"); + rt_free(dev_desc); return ret; } @@ -124,6 +127,7 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) if(ret != RT_EOK) { rt_kprintf("set device address failed\n"); + rt_free(dev_desc); return ret; } /* free address 0 ep0 pipe*/ @@ -132,8 +136,8 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in); /* set device max packet size */ - ep0_out_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0; - ep0_in_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0; + ep0_out_desc.wMaxPacketSize = dev_desc->bMaxPacketSize0; + ep0_in_desc.wMaxPacketSize = dev_desc->bMaxPacketSize0; /* alloc true address ep0 pipe*/ rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc); @@ -142,10 +146,21 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) dev_desc->bLength)); /* get full device descriptor again */ + device->dev_desc = (udev_desc_t)rt_malloc(dev_desc->bLength); + if(device->dev_desc == RT_NULL) + { + rt_free(dev_desc); + return -RT_ENOMEM; + } + rt_memset(device->cfg_desc, 0, dev_desc->bLength); + ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength); + rt_free(dev_desc); if(ret != RT_EOK) { rt_kprintf("get full device descriptor failed\n"); + rt_free(device->dev_desc); + device->dev_desc = RT_NULL; return ret; } @@ -153,27 +168,34 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) RT_DEBUG_LOG(RT_DEBUG_USB, ("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); + cfg_desc = (ucfg_desc_t)rt_malloc(sizeof(struct uconfig_descriptor)); + rt_memset(cfg_desc, 0, sizeof(struct uconfig_descriptor)); + ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, cfg_desc, sizeof(struct uconfig_descriptor)); if(ret != RT_EOK) { rt_kprintf("get configuration descriptor head failed\n"); + rt_free(cfg_desc); return ret; } /* alloc memory for configuration descriptor */ - device->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength); + device->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc->wTotalLength); if(device->cfg_desc == RT_NULL) { - return RT_ENOMEM; + rt_free(cfg_desc); + return -RT_ENOMEM; } - rt_memset(device->cfg_desc, 0, cfg_desc.wTotalLength); + rt_memset(device->cfg_desc, 0, cfg_desc->wTotalLength); /* get full configuration descriptor */ ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, - device->cfg_desc, cfg_desc.wTotalLength); + device->cfg_desc, cfg_desc->wTotalLength); + rt_free(cfg_desc); if(ret != RT_EOK) { rt_kprintf("get full configuration descriptor failed\n"); + rt_free(device->cfg_desc); + device->cfg_desc = RT_NULL; return ret; } @@ -181,15 +203,19 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) ret = rt_usbh_set_configure(device, 1); if(ret != RT_EOK) { + rt_free(device->cfg_desc); + device->cfg_desc = RT_NULL; return ret; } - for(i=0; icfg_desc->bNumInterfaces; i++) + for(i = 0; i < device->cfg_desc->bNumInterfaces; i++) { /* get interface descriptor through configuration descriptor */ ret = rt_usbh_get_interface_descriptor(device->cfg_desc, i, &intf_desc); if(ret != RT_EOK) { rt_kprintf("rt_usb_get_interface_descriptor error\n"); + rt_free(device->cfg_desc); + device->cfg_desc = RT_NULL; return -RT_ERROR; } @@ -205,14 +231,18 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) if(rt_usb_hcd_alloc_pipe(device->hcd, &pipe, device, ep_desc) != RT_EOK) { rt_kprintf("alloc pipe failed\n"); - return RT_ERROR; + rt_free(device->cfg_desc); + device->cfg_desc = RT_NULL; + return -RT_ERROR; } rt_usb_instance_add_pipe(device,pipe); } else { rt_kprintf("get endpoint desc failed\n"); - return RT_ERROR; + rt_free(device->cfg_desc); + device->cfg_desc = RT_NULL; + return -RT_ERROR; } } /* find driver by class code found in interface descriptor */ @@ -225,7 +255,9 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device) device->intf[i] = (struct uhintf*)rt_malloc(sizeof(struct uhintf)); if(device->intf[i] == RT_NULL) { - return RT_ENOMEM; + rt_free(device->cfg_desc); + device->cfg_desc = RT_NULL; + return -RT_ENOMEM; } device->intf[i]->drv = drv; device->intf[i]->device = device; @@ -282,6 +314,9 @@ rt_err_t rt_usbh_detach_instance(uinst_t device) } rt_free(device->cfg_desc); } + if (device->dev_desc) { + rt_free(device->dev_desc); + } rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out); rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in); @@ -332,7 +367,7 @@ rt_err_t rt_usbh_get_descriptor(uinst_t device, rt_uint8_t type, void* buffer, } } } - return RT_ERROR; + return -RT_ERROR; } /** @@ -360,7 +395,7 @@ rt_err_t rt_usbh_set_address(uinst_t device) if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) { - return RT_ERROR; + return -RT_ERROR; } if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) == 0) { @@ -395,11 +430,11 @@ rt_err_t rt_usbh_set_configure(uinst_t device, int config) if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) { - return RT_ERROR; + 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_ERROR; } return RT_EOK; } @@ -429,7 +464,7 @@ rt_err_t rt_usbh_set_interface(uinst_t device, int intf) if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) { - return RT_ERROR; + return -RT_ERROR; } return RT_EOK; @@ -460,7 +495,7 @@ rt_err_t rt_usbh_clear_feature(uinst_t device, int endpoint, int feature) if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) { - return RT_ERROR; + return -RT_ERROR; } return RT_EOK; -- Gitee