diff options
author | Matt DeVillier <matt.devillier@gmail.com> | 2014-04-24 11:16:31 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-05-25 15:49:35 -0300 |
commit | 0cacb46ace1f433f0ab02af10686f6dc50b5d268 (patch) | |
tree | e285cc455ce30780dd67c2ff1bae4c87e83b84ad /drivers/media | |
parent | 44f83144ca81fa8cf1c2114afe01c4bedae40fae (diff) | |
download | linux-0cacb46ace1f433f0ab02af10686f6dc50b5d268.tar.bz2 |
[media] fix mceusb endpoint type identification/handling
Change the I/O endpoint handling of the mceusb driver to respect the endpoint
type reported by device (bulk/interrupt), rather than treating all endpoints
as type interrupt, which breaks devices using bulk endpoints when connected
to a xhci controller. Accordingly, change the function calls to initialize
an endpoint's transfer pipe and urb handlers to use the correct function based
on the endpoint type.
[m.chehab@samsung.com: Fix merge conflicts and compilation breakage]
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/rc/mceusb.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 5d8f3d40d820..d5c1df3c9db1 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -747,11 +747,19 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data, } /* outbound data */ - pipe = usb_sndintpipe(ir->usbdev, - ir->usb_ep_out->bEndpointAddress); - usb_fill_int_urb(async_urb, ir->usbdev, pipe, - async_buf, size, mce_async_callback, - ir, ir->usb_ep_out->bInterval); + if (usb_endpoint_xfer_int(ir->usb_ep_out)) { + pipe = usb_sndintpipe(ir->usbdev, + ir->usb_ep_out->bEndpointAddress); + usb_fill_int_urb(async_urb, ir->usbdev, pipe, async_buf, + size, mce_async_callback, ir, + ir->usb_ep_out->bInterval); + } else { + pipe = usb_sndbulkpipe(ir->usbdev, + ir->usb_ep_out->bEndpointAddress); + usb_fill_bulk_urb(async_urb, ir->usbdev, pipe, + async_buf, size, mce_async_callback, + ir); + } memcpy(async_buf, data, size); } else if (urb_type == MCEUSB_RX) { @@ -1269,32 +1277,26 @@ static int mceusb_dev_probe(struct usb_interface *intf, for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { ep = &idesc->endpoint[i].desc; - if ((ep_in == NULL) - && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - == USB_DIR_IN) - && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_BULK) - || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_INT))) { - - ep_in = ep; - ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; - ep_in->bInterval = 1; - dev_dbg(&intf->dev, "acceptable inbound endpoint found"); + if (ep_in == NULL) { + if (usb_endpoint_is_bulk_in(ep)) { + ep_in = ep; + dev_dbg(&intf->dev, "acceptable bulk inbound endpoint found\n"); + } else if (usb_endpoint_is_int_in(ep)) { + ep_in = ep; + ep_in->bInterval = 1; + dev_dbg(&intf->dev, "acceptable interrupt inbound endpoint found\n"); + } } - if ((ep_out == NULL) - && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - == USB_DIR_OUT) - && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_BULK) - || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_INT))) { - - ep_out = ep; - ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; - ep_out->bInterval = 1; - dev_dbg(&intf->dev, "acceptable outbound endpoint found"); + if (ep_out == NULL) { + if (usb_endpoint_is_bulk_out(ep)) { + ep_out = ep; + dev_dbg(&intf->dev, "acceptable bulk outbound endpoint found\n"); + } else if (usb_endpoint_is_int_out(ep)) { + ep_out = ep; + ep_out->bInterval = 1; + dev_dbg(&intf->dev, "acceptable interrupt outbound endpoint found\n"); + } } } if (ep_in == NULL) { @@ -1302,7 +1304,10 @@ static int mceusb_dev_probe(struct usb_interface *intf, return -ENODEV; } - pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); + if (usb_endpoint_xfer_int(ep_in)) + pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); + else + pipe = usb_rcvbulkpipe(dev, ep_in->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); |