PROBLEM: USB ACM device does not work

From: Arseniy Lartsev
Date: Sun Jun 28 2009 - 15:29:56 EST


I've got a piece of hardware (this one:
http://masterkit.ru/main/set.php?num=1153) which acts like an USB ACM
device and is handeled by the cdc_acm module. /dev/ttyACM0 does appear
but any attempt to write something to the device with a simple
"echo something >/dev/ttyACM0" fails with "Invalid argument" error.

The reason is that the driver calls usb_submit_urb in acm_start_wb()
but doesn't set interval in the urb structure, so it remains zero and
causes usb_submit_urb to return -EINVAL. Reading from device also does
not work due to the same problem in acm_rx_tasklet().

After setting urb interval to 128, this particular device works fine
for me (though I'm not sure that it's a right solution in general).

Corresponding patch (against 2.6.30) is:

--- linux-2.6.30.orig/drivers/usb/class/cdc-acm.c
+++ linux-2.6.30/drivers/usb/class/cdc-acm.c
@@ -182,6 +182,7 @@ static int acm_start_wb(struct acm *acm,
wb->urb->transfer_dma = wb->dmah;
wb->urb->transfer_buffer_length = wb->len;
wb->urb->dev = acm->dev;
+ wb->urb->interval = 128;

if ((rc = usb_submit_urb(wb->urb, GFP_ATOMIC)) < 0) {
dbg("usb_submit_urb(write bulk) failed: %d", rc);
@@ -453,6 +454,7 @@ urbs:
acm_read_bulk, rcv);
rcv->urb->transfer_dma = buf->dma;
rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ rcv->urb->interval = 128;

/* This shouldn't kill the driver as unsuccessful URBs are returned to the
free-urbs-pool and resubmited ASAP */

Attachment: signature.asc
Description: This is a digitally signed message part.