linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH ] fix mceusb endpoint type identification/handling
@ 2014-04-22 22:49 Matt DeVillier
  2014-04-23 13:19 ` Sean Young
  0 siblings, 1 reply; 2+ messages in thread
From: Matt DeVillier @ 2014-04-22 22:49 UTC (permalink / raw)
  To: 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>
---
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.
---
--- mceusb.c.orig    2014-04-22 13:48:51.186259472 -0500
+++ mceusb.c    2014-04-22 14:46:12.378347584 -0500
@@ -747,11 +747,17 @@ static void mce_request_packet(struct mc
          }

          /* 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 ((ir->usb_ep_out->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+            == USB_ENDPOINT_XFER_INT) {
+            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) {
@@ -1271,38 +1277,48 @@ static int mceusb_dev_probe(struct usb_i

          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");
+            == USB_DIR_IN)) {
+
+            if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+                == USB_ENDPOINT_XFER_BULK) {
+
+                ep_in = ep;
+                mce_dbg(&intf->dev, "acceptable bulk inbound endpoint 
found\n");
+            } else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+                == USB_ENDPOINT_XFER_INT) {
+
+                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");
+            == USB_DIR_OUT)) {
+            if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+                == USB_ENDPOINT_XFER_BULK) {
+                ep_out = ep;
+                mce_dbg(&intf->dev, "acceptable bulk outbound endpoint 
found\n");
+            } else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+                == USB_ENDPOINT_XFER_INT) {
+                ep_out = ep;
+                ep_out->bInterval = 1;
+                mce_dbg(&intf->dev, "acceptable interrupt outbound 
endpoint found\n");
+            }
          }
      }
-    if (ep_in == NULL) {
+    if (ep_in == NULL || ep_out == NULL) {
          dev_dbg(&intf->dev, "inbound and/or endpoint not found");
          return -ENODEV;
      }

-    pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress);
+    if ((ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+        == USB_ENDPOINT_XFER_INT) {
+        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);
@@ -1343,8 +1359,14 @@ static int mceusb_dev_probe(struct usb_i
          goto rc_dev_fail;

      /* wire up inbound data handler */
-    usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
-                mceusb_dev_recv, ir, ep_in->bInterval);
+    if ((ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+        == USB_ENDPOINT_XFER_INT) {
+        usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
+                 mceusb_dev_recv, ir, ep_in->bInterval);
+    } else {
+        usb_fill_bulk_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
+                 mceusb_dev_recv, ir);
+    }
      ir->urb_in->transfer_dma = ir->dma_in;
      ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;




^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH ] fix mceusb endpoint type identification/handling
  2014-04-22 22:49 [PATCH ] fix mceusb endpoint type identification/handling Matt DeVillier
@ 2014-04-23 13:19 ` Sean Young
  0 siblings, 0 replies; 2+ messages in thread
From: Sean Young @ 2014-04-23 13:19 UTC (permalink / raw)
  To: Matt DeVillier; +Cc: linux-media

On Tue, Apr 22, 2014 at 05:49:03PM -0500, Matt DeVillier wrote:
> 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>
> ---
> 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.
> ---
> --- mceusb.c.orig    2014-04-22 13:48:51.186259472 -0500
> +++ mceusb.c    2014-04-22 14:46:12.378347584 -0500
> @@ -747,11 +747,17 @@ static void mce_request_packet(struct mc
>          }
> 
>          /* 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 ((ir->usb_ep_out->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
> +            == USB_ENDPOINT_XFER_INT) {
> +            pipe = usb_sndintpipe(ir->usbdev,
> ir->usb_ep_out->bEndpointAddress);

The lines are wrapped and tabs have been replaced with spaces; your mail
client messed with your patch.

See
https://www.kernel.org/doc/Documentation/email-clients.txt

> +            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) {
> @@ -1271,38 +1277,48 @@ static int mceusb_dev_probe(struct usb_i
> 
>          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");
> +            == USB_DIR_IN)) {
> +
> +            if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
> +                == USB_ENDPOINT_XFER_BULK) {
> +
> +                ep_in = ep;
> +                mce_dbg(&intf->dev, "acceptable bulk inbound
> endpoint found\n");
> +            } else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
> +                == USB_ENDPOINT_XFER_INT) {
> +
> +                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");
> +            == USB_DIR_OUT)) {
> +            if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
> +                == USB_ENDPOINT_XFER_BULK) {
> +                ep_out = ep;
> +                mce_dbg(&intf->dev, "acceptable bulk outbound
> endpoint found\n");
> +            } else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
> +                == USB_ENDPOINT_XFER_INT) {
> +                ep_out = ep;
> +                ep_out->bInterval = 1;
> +                mce_dbg(&intf->dev, "acceptable interrupt outbound
> endpoint found\n");
> +            }
>          }
>      }
> -    if (ep_in == NULL) {
> +    if (ep_in == NULL || ep_out == NULL) {

Although I think this is correct this is unrelated to the rest of the patch.

>          dev_dbg(&intf->dev, "inbound and/or endpoint not found");
>          return -ENODEV;
>      }
> 
> -    pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress);
> +    if ((ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
> +        == USB_ENDPOINT_XFER_INT) {
> +        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);
> @@ -1343,8 +1359,14 @@ static int mceusb_dev_probe(struct usb_i
>          goto rc_dev_fail;
> 
>      /* wire up inbound data handler */
> -    usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
> -                mceusb_dev_recv, ir, ep_in->bInterval);
> +    if ((ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
> +        == USB_ENDPOINT_XFER_INT) {
> +        usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
> +                 mceusb_dev_recv, ir, ep_in->bInterval);
> +    } else {
> +        usb_fill_bulk_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
> +                 mceusb_dev_recv, ir);
> +    }
>      ir->urb_in->transfer_dma = ir->dma_in;
>      ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

I've tested this patch and it does fix my mceusb device with bulk 
endpoints on xhci. So

Tested-by: Sean Young <sean@mess.org>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-04-23 13:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-22 22:49 [PATCH ] fix mceusb endpoint type identification/handling Matt DeVillier
2014-04-23 13:19 ` Sean Young

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).