Skip to content

Commit

Permalink
USB: cdc-acm: work around some broken devices
Browse files Browse the repository at this point in the history
This patch introduces a work around for cdc-acm devices which are
low speed contrary to the specification, which requires bulk endpoints
which are banned in low speed and converted by usbcore to virtual
interrupt endpoints if they are used nevertheless.

Signed-off-by: Arseniy Lartsev <ars3n@yandex.ru>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Arseniy Lartsev authored and Greg Kroah-Hartman committed Jul 12, 2009
1 parent 89368d3 commit 5186ffe
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions drivers/usb/class/cdc-acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm)
struct acm_ru *rcv;
unsigned long flags;
unsigned char throttled;
struct usb_host_endpoint *ep;

dbg("Entering acm_rx_tasklet");

Expand Down Expand Up @@ -462,11 +463,20 @@ static void acm_rx_tasklet(unsigned long _acm)

rcv->buffer = buf;

usb_fill_bulk_urb(rcv->urb, acm->dev,
acm->rx_endpoint,
buf->base,
acm->readsize,
acm_read_bulk, rcv);
ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out)
[usb_pipeendpoint(acm->rx_endpoint)];
if (usb_endpoint_xfer_int(&ep->desc))
usb_fill_int_urb(rcv->urb, acm->dev,
acm->rx_endpoint,
buf->base,
acm->readsize,
acm_read_bulk, rcv, ep->desc.bInterval);
else
usb_fill_bulk_urb(rcv->urb, acm->dev,
acm->rx_endpoint,
buf->base,
acm->readsize,
acm_read_bulk, rcv);
rcv->urb->transfer_dma = buf->dma;
rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

Expand Down Expand Up @@ -1227,9 +1237,14 @@ static int acm_probe(struct usb_interface *intf,
goto alloc_fail7;
}

usb_fill_bulk_urb(snd->urb, usb_dev,
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
NULL, acm->writesize, acm_write_bulk, snd);
if (usb_endpoint_xfer_int(epwrite))
usb_fill_int_urb(snd->urb, usb_dev,
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
else
usb_fill_bulk_urb(snd->urb, usb_dev,
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
NULL, acm->writesize, acm_write_bulk, snd);
snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
snd->instance = acm;
}
Expand Down

0 comments on commit 5186ffe

Please sign in to comment.