linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH  v3] fix mceusb endpoint type identification/handling
@ 2014-04-24 14:16 Matt DeVillier
  0 siblings, 0 replies; only message in thread
From: Matt DeVillier @ 2014-04-24 14:16 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

From: Matt DeVillier <matt.devillier@gmail.com>

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.

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: Sean Young <sean@mess.org>
-
This is a continuation of the work started in patch #21648
Patch compiled and tested against linux-media git master. Backported and tested 
against 3.14.1 stable as well.
v3 corrects formatting issues which prevented the patch from being applied
with 'git am,' and replaces a few complex conditionals with inline functions 
for improved clarity.
---
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 5d8f3d4..74721cc 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;
+				mce_dbg(&intf->dev, "acceptable bulk inbound endpoint found\n");
+			} else if (usb_endpoint_is_int_in(ep)) {
+				ep_in = ep;
+				ep_in->bInterval = 1;
+				mce_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;
+				mce_dbg(&intf->dev, "acceptable bulk outbound endpoint found\n");
+			} else if (usb_endpoint_is_int_out(ep)) {
+				ep_out = ep;
+				ep_out->bInterval = 1;
+				mce_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);

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2014-04-24 14:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-24 14:16 [PATCH v3] fix mceusb endpoint type identification/handling Matt DeVillier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).