cherry-embedded / CherryUSB

CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP
https://cherryusb.readthedocs.io/
Apache License 2.0
1.21k stars 256 forks source link

usb_hc_dwc2.c 文件中出现异常时没有释放锁导致死锁 #75

Closed supf1994 closed 1 year ago

supf1994 commented 1 year ago

在 usb_hc_dwc2.c 文件下的 usbh_submit_urb函数中 ` int usbh_submit_urb(struct usbh_urb urb) { struct dwc2_pipe chan; size_t flags; int ret = 0;

if (!urb) {
    return -EINVAL;
}

chan = urb->pipe;

if (!chan) {
    return -EINVAL;
}

/* dma addr must be aligned 4 bytes */
if ((((uint32_t)urb->setup) & 0x03) || (((uint32_t)urb->transfer_buffer) & 0x03)) {
    return -EINVAL;
}

flags = usb_osal_enter_critical_section();

if (!chan->hport->connected) {
    return -ENODEV;
}

if (chan->urb) {
    return -EBUSY;
}

chan->waiter = false;
chan->xfrd = 0;
chan->urb = urb;
urb->errorcode = -EBUSY;
urb->actual_length = 0;

if (urb->timeout > 0) {
    chan->waiter = true;
}
usb_osal_leave_critical_section(flags);

switch (chan->ep_type) {
    case USB_ENDPOINT_TYPE_CONTROL:
        chan->ep0_state = DWC2_EP0_STATE_SETUP;
        dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
        break;
    case USB_ENDPOINT_TYPE_BULK:
    case USB_ENDPOINT_TYPE_INTERRUPT:
        dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
        break;
    case USB_ENDPOINT_TYPE_ISOCHRONOUS:
        chan->iso_frame_idx = 0;
        dwc2_iso_pipe_init(chan, &urb->iso_packet[chan->iso_frame_idx]);
        break;
    default:
        break;
}
if (urb->timeout > 0) {
    /* wait until timeout or sem give */
    ret = usb_osal_sem_take(chan->waitsem, urb->timeout);
    if (ret < 0) {
        goto errout_timeout;
    }

    ret = urb->errorcode;
}
return ret;

errout_timeout: chan->waiter = false; usbh_kill_urb(urb); return ret; } ` if (!chan->hport->connected) 和 if (urb->timeout > 0)条件下不会调用 usb_osal_leave_critical_section(flags); ,导致在某些异常情况下死锁

sakumisu commented 1 year ago

已修正