/* Don't use this function from within an interrupt context, like a bottom half handler. If you need an asynchronous message, or need to send a message from within interrupt context, use usb_submit_urb() If a thread in your driver uses this call, make sure your disconnect() method can wait for it to complete. Since you don't have a handle on the URB used, you can't cancel the request.  */
int usb_bulk_msg(struct usb_host_virt_dev *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout)
/* Don't use this function from within an interrupt context, like a bottom half handler. If you need an asynchronous message, or need to send a message from within interrupt context, use usb_submit_urb() If a thread in your driver uses this call, make sure your disconnect() method can wait for it to complete. Since you don't have a handle on the URB used, you can't cancel the request.  */
int usb_bulk_msg(struct usb_host_virt_dev *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout)
{
    if (usb_dev == NULL || data == NULL || len < 0)
    {
        return -EINVAL;
    }
    return _usb_internal_bulk_msg(usb_dev,
                                  pipe,
                                  data,
                                  len,
                                  actual_length,
                                  timeout);
}