/** * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion * @usb_dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @data: pointer to the data to send * @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred in bytes * @timeout: time in msecs to wait for the message to complete before * timing out (if 0 the wait is forever) * Context: !in_interrupt () * * This function sends a simple bulk message to a specified endpoint * and waits for the message to complete, or timeout. * * If successful, it returns 0, otherwise a negative error number. * The number of actual bytes transferred will be stored in the * actual_length paramater. * * 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. * * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT * ioctl, users are forced to abuse this routine by using it to submit * URBs for interrupt endpoints. We will take the liberty of creating * an interrupt URB (with the default interval) if the target is an * interrupt endpoint. */ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout) { struct urb *urb; struct usb_host_endpoint *ep; ep = (usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out) [usb_pipeendpoint(pipe)]; if (!ep || len < 0) return -EINVAL; urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); usb_fill_int_urb(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, NULL, ep->desc.bInterval); } else usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, NULL); return usb_start_wait_urb(urb, timeout, actual_length); }
/** * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion * @usb_dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @data: pointer to the data to send * @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred in bytes * @timeout: time in jiffies to wait for the message to complete before * timing out (if 0 the wait is forever) * Context: !in_interrupt () * * This function sends a simple bulk message to a specified endpoint * and waits for the message to complete, or timeout. * * If successful, it returns 0, otherwise a negative error number. * The number of actual bytes transferred will be stored in the * actual_length paramater. * * 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_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout) { struct urb *urb; if (len < 0) return -EINVAL; urb=usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, NULL); return usb_start_wait_urb(urb,timeout,actual_length); }
// returns status (negative) or length (positive) int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, struct usb_ctrlrequest *cmd, void *data, int len, int timeout) { struct urb *urb; int retv; int length; urb = usb_alloc_urb(0, GFP_NOIO); if (!urb) return -ENOMEM; usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, len, usb_api_blocking_completion, NULL); retv = usb_start_wait_urb(urb, timeout, &length); if (retv < 0) return retv; else return length; }