diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2005-09-26 16:22:45 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 19:47:41 -0400 |
commit | d09d36a91c70cb3cc609d693bf6a7e7a266ff9e6 (patch) | |
tree | 4a41ade8dc775ea6dc9154bc4fe006f75557f579 | |
parent | b13296c6617f22e8c0174a7af32780617db0e680 (diff) |
[PATCH] USB: usb_bulk_message() handles interrupts endpoints
Because there is no bulk_interrupt_message() routine and no
USBDEVFS_INTERRUPT ioctl, people have been forced to abuse the
usb_bulk_message() routine and USBDEVFS_BULK by using them for interrupt
transfers as well as bulk transfers.
This patch (as567) formalizes this practice and adds code to
usb_bulk_message() for detecting when the target is really an interrupt
endpoint. If it is, the routine submits an interrupt URB (using the
default interval) instead of a bulk URB. In theory this should help HCDs
that don't like it when people try to mix transfer types, queuing both
periodic and non-periodic types for the same endpoint.
Not fully tested -- I don't have any programs that use USBDEVFS_BULK for
interrupt transfers -- but it compiles okay and normal bulk messages work
as well as before.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/message.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
-rw-r--r-- | drivers/usb/core/message.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index ebf59ea99263..574d0d4b3401 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -187,21 +187,37 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u | |||
187 | * If a thread in your driver uses this call, make sure your disconnect() | 187 | * If a thread in your driver uses this call, make sure your disconnect() |
188 | * method can wait for it to complete. Since you don't have a handle on | 188 | * method can wait for it to complete. Since you don't have a handle on |
189 | * the URB used, you can't cancel the request. | 189 | * the URB used, you can't cancel the request. |
190 | * | ||
191 | * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT | ||
192 | * ioctl, users are forced to abuse this routine by using it to submit | ||
193 | * URBs for interrupt endpoints. We will take the liberty of creating | ||
194 | * an interrupt URB (with the default interval) if the target is an | ||
195 | * interrupt endpoint. | ||
190 | */ | 196 | */ |
191 | int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, | 197 | int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, |
192 | void *data, int len, int *actual_length, int timeout) | 198 | void *data, int len, int *actual_length, int timeout) |
193 | { | 199 | { |
194 | struct urb *urb; | 200 | struct urb *urb; |
201 | struct usb_host_endpoint *ep; | ||
195 | 202 | ||
196 | if (len < 0) | 203 | ep = (usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out) |
204 | [usb_pipeendpoint(pipe)]; | ||
205 | if (!ep || len < 0) | ||
197 | return -EINVAL; | 206 | return -EINVAL; |
198 | 207 | ||
199 | urb=usb_alloc_urb(0, GFP_KERNEL); | 208 | urb = usb_alloc_urb(0, GFP_KERNEL); |
200 | if (!urb) | 209 | if (!urb) |
201 | return -ENOMEM; | 210 | return -ENOMEM; |
202 | 211 | ||
203 | usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, | 212 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
204 | usb_api_blocking_completion, NULL); | 213 | USB_ENDPOINT_XFER_INT) { |
214 | pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); | ||
215 | usb_fill_int_urb(urb, usb_dev, pipe, data, len, | ||
216 | usb_api_blocking_completion, NULL, | ||
217 | ep->desc.bInterval); | ||
218 | } else | ||
219 | usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, | ||
220 | usb_api_blocking_completion, NULL); | ||
205 | 221 | ||
206 | return usb_start_wait_urb(urb, timeout, actual_length); | 222 | return usb_start_wait_urb(urb, timeout, actual_length); |
207 | } | 223 | } |