diff options
author | Matt DeVillier <matt.devillier@gmail.com> | 2014-04-24 10:16:31 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-05-25 14:49:35 -0400 |
commit | 0cacb46ace1f433f0ab02af10686f6dc50b5d268 (patch) | |
tree | e285cc455ce30780dd67c2ff1bae4c87e83b84ad | |
parent | 44f83144ca81fa8cf1c2114afe01c4bedae40fae (diff) |
[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>
-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, | |||
747 | } | 747 | } |
748 | 748 | ||
749 | /* outbound data */ | 749 | /* outbound data */ |
750 | pipe = usb_sndintpipe(ir->usbdev, | 750 | if (usb_endpoint_xfer_int(ir->usb_ep_out)) { |
751 | ir->usb_ep_out->bEndpointAddress); | 751 | pipe = usb_sndintpipe(ir->usbdev, |
752 | usb_fill_int_urb(async_urb, ir->usbdev, pipe, | 752 | ir->usb_ep_out->bEndpointAddress); |
753 | async_buf, size, mce_async_callback, | 753 | usb_fill_int_urb(async_urb, ir->usbdev, pipe, async_buf, |
754 | ir, ir->usb_ep_out->bInterval); | 754 | size, mce_async_callback, ir, |
755 | ir->usb_ep_out->bInterval); | ||
756 | } else { | ||
757 | pipe = usb_sndbulkpipe(ir->usbdev, | ||
758 | ir->usb_ep_out->bEndpointAddress); | ||
759 | usb_fill_bulk_urb(async_urb, ir->usbdev, pipe, | ||
760 | async_buf, size, mce_async_callback, | ||
761 | ir); | ||
762 | } | ||
755 | memcpy(async_buf, data, size); | 763 | memcpy(async_buf, data, size); |
756 | 764 | ||
757 | } else if (urb_type == MCEUSB_RX) { | 765 | } else if (urb_type == MCEUSB_RX) { |
@@ -1269,32 +1277,26 @@ static int mceusb_dev_probe(struct usb_interface *intf, | |||
1269 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { | 1277 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { |
1270 | ep = &idesc->endpoint[i].desc; | 1278 | ep = &idesc->endpoint[i].desc; |
1271 | 1279 | ||
1272 | if ((ep_in == NULL) | 1280 | if (ep_in == NULL) { |
1273 | && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 1281 | if (usb_endpoint_is_bulk_in(ep)) { |
1274 | == USB_DIR_IN) | 1282 | ep_in = ep; |
1275 | && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1283 | dev_dbg(&intf->dev, "acceptable bulk inbound endpoint found\n"); |
1276 | == USB_ENDPOINT_XFER_BULK) | 1284 | } else if (usb_endpoint_is_int_in(ep)) { |
1277 | || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1285 | ep_in = ep; |
1278 | == USB_ENDPOINT_XFER_INT))) { | 1286 | ep_in->bInterval = 1; |
1279 | 1287 | dev_dbg(&intf->dev, "acceptable interrupt inbound endpoint found\n"); | |
1280 | ep_in = ep; | 1288 | } |
1281 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; | ||
1282 | ep_in->bInterval = 1; | ||
1283 | dev_dbg(&intf->dev, "acceptable inbound endpoint found"); | ||
1284 | } | 1289 | } |
1285 | 1290 | ||
1286 | if ((ep_out == NULL) | 1291 | if (ep_out == NULL) { |
1287 | && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 1292 | if (usb_endpoint_is_bulk_out(ep)) { |
1288 | == USB_DIR_OUT) | 1293 | ep_out = ep; |
1289 | && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1294 | dev_dbg(&intf->dev, "acceptable bulk outbound endpoint found\n"); |
1290 | == USB_ENDPOINT_XFER_BULK) | 1295 | } else if (usb_endpoint_is_int_out(ep)) { |
1291 | || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1296 | ep_out = ep; |
1292 | == USB_ENDPOINT_XFER_INT))) { | 1297 | ep_out->bInterval = 1; |
1293 | 1298 | dev_dbg(&intf->dev, "acceptable interrupt outbound endpoint found\n"); | |
1294 | ep_out = ep; | 1299 | } |
1295 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; | ||
1296 | ep_out->bInterval = 1; | ||
1297 | dev_dbg(&intf->dev, "acceptable outbound endpoint found"); | ||
1298 | } | 1300 | } |
1299 | } | 1301 | } |
1300 | if (ep_in == NULL) { | 1302 | if (ep_in == NULL) { |
@@ -1302,7 +1304,10 @@ static int mceusb_dev_probe(struct usb_interface *intf, | |||
1302 | return -ENODEV; | 1304 | return -ENODEV; |
1303 | } | 1305 | } |
1304 | 1306 | ||
1305 | pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); | 1307 | if (usb_endpoint_xfer_int(ep_in)) |
1308 | pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); | ||
1309 | else | ||
1310 | pipe = usb_rcvbulkpipe(dev, ep_in->bEndpointAddress); | ||
1306 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 1311 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
1307 | 1312 | ||
1308 | ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); | 1313 | ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); |