From: Matt DeVillier <matt.devillier@gmail.com>
To: Mauro Carvalho Chehab <m.chehab@samsung.com>
Cc: linux-media@vger.kernel.org
Subject: [PATCH v2] fix mceusb endpoint type identification/handling
Date: Wed, 23 Apr 2014 10:05:08 -0500 [thread overview]
Message-ID: <5357D6A4.4070008@gmail.com> (raw)
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.
v2 corrects some formatting issues (both with the patch itself and MUA), and
removes a small bug fix not relevant to the core patch functionality.
---
diff -up mceusb.c{.orig,}
--- mceusb.c.orig 2014-04-22 13:48:51.186259472 -0500
+++ mceusb.c 2014-04-23 09:51:50.060107612 -0500
@@ -747,11 +747,19 @@ 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 +1279,47 @@ 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) {
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 +1360,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;
reply other threads:[~2014-04-23 15:05 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5357D6A4.4070008@gmail.com \
--to=matt.devillier@gmail.com \
--cc=linux-media@vger.kernel.org \
--cc=m.chehab@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.