USB: set the correct interval for interrupt URBs

This patch (as862) fixes a couple of bugs in the way usbcore handles
intervals for interrupt URBs. usb_interrupt_msg (and usb_bulk_msg for
backward compatibility) don't set the interval correctly for
high-speed devices. proc_do_submiturb() doesn't set it correctly when
a bulk URB is submitted to an interrupt endpoint.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by Alan Stern and committed by Greg Kroah-Hartman 97b9eb91 14360ab7

+13 -9
+6 -7
drivers/usb/core/devio.c
··· 912 912 struct async *as; 913 913 struct usb_ctrlrequest *dr = NULL; 914 914 unsigned int u, totlen, isofrmlen; 915 - int ret, interval = 0, ifnum = -1; 915 + int ret, ifnum = -1; 916 916 917 917 if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK| 918 918 URB_NO_FSBR|URB_ZERO_PACKET)) ··· 992 992 if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) 993 993 != USB_ENDPOINT_XFER_ISOC) 994 994 return -EINVAL; 995 - interval = 1 << min (15, ep->desc.bInterval - 1); 996 995 isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets; 997 996 if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) 998 997 return -ENOMEM; ··· 1020 1021 if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) 1021 1022 != USB_ENDPOINT_XFER_INT) 1022 1023 return -EINVAL; 1023 - if (ps->dev->speed == USB_SPEED_HIGH) 1024 - interval = 1 << min (15, ep->desc.bInterval - 1); 1025 - else 1026 - interval = ep->desc.bInterval; 1027 1024 if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) 1028 1025 return -EINVAL; 1029 1026 if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) ··· 1048 1053 as->urb->setup_packet = (unsigned char*)dr; 1049 1054 as->urb->start_frame = uurb->start_frame; 1050 1055 as->urb->number_of_packets = uurb->number_of_packets; 1051 - as->urb->interval = interval; 1056 + if (uurb->type == USBDEVFS_URB_TYPE_ISO || 1057 + ps->dev->speed == USB_SPEED_HIGH) 1058 + as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); 1059 + else 1060 + as->urb->interval = ep->desc.bInterval; 1052 1061 as->urb->context = as; 1053 1062 as->urb->complete = async_completed; 1054 1063 for (totlen = u = 0; u < uurb->number_of_packets; u++) {
+7 -2
drivers/usb/core/message.c
··· 221 221 222 222 if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 223 223 USB_ENDPOINT_XFER_INT) { 224 + int interval; 225 + 226 + if (usb_dev->speed == USB_SPEED_HIGH) 227 + interval = 1 << min(15, ep->desc.bInterval - 1); 228 + else 229 + interval = ep->desc.bInterval; 224 230 pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); 225 231 usb_fill_int_urb(urb, usb_dev, pipe, data, len, 226 - usb_api_blocking_completion, NULL, 227 - ep->desc.bInterval); 232 + usb_api_blocking_completion, NULL, interval); 228 233 } else 229 234 usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, 230 235 usb_api_blocking_completion, NULL);