cherry-embedded / CherryUSB

CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP
https://cherryusb.cherry-embedded.org
Apache License 2.0
1.3k stars 277 forks source link

USB Host MSC class driver fails if device does not respond to Get Max LUN request #259

Closed dkonigsberg closed 1 month ago

dkonigsberg commented 1 month ago

描述一下这个bug / Describe the bug

This issue occurs within the USB Host class driver for MSC (mass storage) devices: https://github.com/cherry-embedded/CherryUSB/blob/master/class/msc/usbh_msc.c#L279

In the usbh_msc_connect() function, a call is made to usbh_msc_get_maxlun() which attempts to perform a "Get Max LUN" request on the USB device. If this request fails, the class driver will not load and the device will not be usable.

On some USB storage devices, this command fails with a USB_ERR_STALL, and thus those devices cannot be used with CherryUSB.

However, according to the USB Mass Storage Class Bulk-Only Transport specification: https://www.usb.org/sites/default/files/usbmassbulk_10.pdf (Page 7, section "3.2 Get Max LUN") "Devices that do not support multiple LUNs may STALL this command."

In other words, a stall error in response to this request should not cause the MSC connect function to fail.

Changing the error handling around usbh_msc_get_maxlun() as follows, fixes the issue:

    ret = usbh_msc_get_maxlun(msc_class, g_msc_buf[msc_class->sdchar - 'a']);
    if (ret == -USB_ERR_STALL) {
        USB_LOG_INFO("Multiple LUNs not supported");
        g_msc_buf[msc_class->sdchar - 'a'][0] = 0;
    } else if (ret < 0) {
        return ret;
    }

    USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[msc_class->sdchar - 'a'][0] + 1);

复现步骤 / To Reproduce

Most USB thumbdrives I tested do not have this problem. However, I found one that does. It has a VID=0x058F and PID=0x6387 and was received as a freebie at a tech conference many years ago. However, just knowing that these things exist, makes me worried that an end-user might try to use one.

设备信息 / Target Device

STM32F446RE, DWC2 port, FreeRTOS

日志 / Log

[I/usbh_hub] New full-speed device on Bus 0, Hub 2, Port 1 connected
[I/usbh_core] New device found,idVendor:058f,idProduct:6387,bcdDevice:0102
[I/usbh_core] The device has 1 bNumConfigurations
[I/usbh_core] The device has 1 interfaces
[I/usbh_core] Enumeration success, start loading class driver
[I/usbh_core] Loading msc class driver
[E/usbh_hub] Port 1 enumerate fail

配置 / Configuration

No response

USB中断 / USB Interrupt

No response

缓存 / Cache

No response

商业 / Business

sakumisu commented 1 month ago

If device support only one lun also need support this command, this is the basic msc request.

sakumisu commented 1 month ago

https://github.com/cherry-embedded/CherryUSB/blob/a8ef0c4cac95a14d76f2c3be9c34c06dd441e7d4/class/msc/usbd_msc.c#L89

dkonigsberg commented 1 month ago

I did a little research to see how several other USB host stacks handle this situation. They all have slight differences in the comments or control flow, but none of them require a successful Get Max LUN request to attach an MSC device.

sakumisu commented 1 month ago

Thank you for such a detailed explanation,could you pr a patch for this?

sakumisu commented 1 month ago

Done