fix mceusb endpoint type identification/handling
Subsystems (2)
PATCH v3 1/1 fix mceusb endpoint type identification/handling
From: Matt DeVillier <[email protected]>
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.
-
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.
---
drivers/media/rc/mceusb.c +35 -30
@@ -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 );