/* Returns the number of bytes received on success, or else the status code returned by the underlying usb_control_msg() call.  */
s32 usb_get_descriptor(struct usb_host_virt_dev *dev, u8 type, u8 index, void *buf, s32 size)
/* Returns the number of bytes received on success, or else the status code returned by the underlying usb_control_msg() call.  */
s32 usb_get_descriptor(struct usb_host_virt_dev *dev, u8 type, u8 index, void *buf, s32 size)
{
    int i = 0;
    int result = 0;
    memset(buf, 0, size);
    for (i = 0; i < 3; ++i)
    {
        result = usb_control_msg(dev,
                                 usb_rcvctrlpipe(dev, 0),
                                 USB_REQ_GET_DESCRIPTOR,
                                 USB_DIR_IN,
                                 (type << 8) + index,
                                 0,
                                 buf,
                                 size,
                                 USB_CTRL_GET_TIMEOUT);
        if (result == 0 || result == -EPIPE)
        {
            hal_log_err("get_descriptor faile 1");
            continue;
        }
        if (result > 1 && ((u8 *)buf)[1] != type)
        {
            hal_log_err("get_descriptor faile 2");
            result = -EPROTO;
            continue;
        }
        break;
    }
    return result;
}