Bug 787607 - setserial /dev/ttyACM0 fails with "Cannot get serial info: Invalid argument"
Summary: setserial /dev/ttyACM0 fails with "Cannot get serial info: Invalid argument"
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Fedora
Classification: Fedora
Component: kernel
Version: 15
Hardware: x86_64
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Kernel Maintainer List
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2012-02-06 10:02 UTC by Frank Danapfel
Modified: 2012-02-25 09:53 UTC (History)
5 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2012-02-22 16:07:05 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
strace -ttT -ff -o /tmp/setserial setserial /dev/ttyACM0 (3.00 KB, text/plain)
2012-02-06 10:04 UTC, Frank Danapfel
no flags Details
patch for cdc-acm.c from 2.6.42 kernel souces from F15 (1.31 KB, patch)
2012-02-17 08:51 UTC, Frank Danapfel
no flags Details | Diff

Description Frank Danapfel 2012-02-06 10:02:06 UTC
Description of problem:
Trying to query configuration of serial devices using the "cdc_acm" kernel module (for example the Arduino Uno) using "setserial /dev/ttyACM0" fails with "Cannot get serial info: Invalid argument"

Version-Release number of selected component (if applicable):
kernel-2.6.41.10-3.fc15.x86_64
/lib/modules/2.6.41.10-3.fc15.x86_64/kernel/drivers/usb/class/cdc-acm.ko

How reproducible:
always

Steps to Reproduce:
1. attach device using the "cdc_acm" kernel module and check that /dev/ttyACM0 is present
2. setserial /dev/ttyACM0
  
Actual results:
# setserial /dev/ttyACM0 
Cannot get serial info: Invalid argument

Expected results:
command should return info about the current config of /dev/ttyACM0

Additional info:
A patch to fix this was apparently submitted on the "linux-usb" ML in 2008, but it looks like it never made it into the kernel: http://permalink.gmane.org/gmane.linux.usb.general/9236

Comment 1 Frank Danapfel 2012-02-06 10:04:28 UTC
Created attachment 559584 [details]
strace -ttT -ff -o /tmp/setserial setserial /dev/ttyACM0

Comment 2 Dave Jones 2012-02-17 04:18:57 UTC
does this work in the latest update ?
I added the patch referenced.  If it works, I'll poke upstream about it again.

Comment 3 Frank Danapfel 2012-02-17 08:51:46 UTC
Created attachment 563856 [details]
patch for cdc-acm.c from 2.6.42 kernel souces from F15

Comment 4 Dave Jones 2012-02-17 16:39:38 UTC
That's the patch that's in the latest update. Does it work ?

Comment 5 Frank Danapfel 2012-02-17 17:56:37 UTC
Yes, the patch works:

# uname -r
2.6.42.3-2.fc15.x86_64
# lsmod|grep -i acm
# sudo insmod rpmbuild/BUILD/kernel-2.6.42.fc15.new/drivers/usb/class/cdc-acm.ko
# lsmod|grep -i acm
cdc_acm                27935  0
# dmesg
... 
[71475.837970] usbcore: registered new interface driver cdc_acm
[71475.837972] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
(after plugging in the hardware (an Arduino Uno)
[71731.773090] usb 6-2: new full-speed USB device number 5 using uhci_hcd
[71731.958129] usb 6-2: New USB device found, idVendor=2341, idProduct=0001
[71731.958139] usb 6-2: New USB device strings: Mfr=1, Product=2, SerialNumber=220
[71731.958146] usb 6-2: Product: Arduino Uno
[71731.958151] usb 6-2: Manufacturer: Arduino (www.arduino.cc)
[71731.958157] usb 6-2: SerialNumber: 64932343638351A08180
[71731.963281] cdc_acm 6-2:1.0: ttyACM0: USB ACM device
# setserial /dev/ttyACM0 
/dev/ttyACM0, UART: unknown, Port: 0x0000, IRQ: 0, Flags: low_latency
$ setserial -g -a /dev/ttyACM0
/dev/ttyACM0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
        Baud_base: 9600, close_delay: 0, divisor: 0
        closing_wait: infinte
        Flags: spd_normal low_latency

Comment 6 Dave Jones 2012-02-17 22:07:33 UTC
excellent. I'll poke upstream about it.
thanks for testing.

Comment 7 Frank Danapfel 2012-02-18 13:18:42 UTC
Dave, thanks for taking care of this bug.

Unfortunately I now discovered that setting serial port parameters also doesn't work:

# setserial /dev/ttyACM0 spd_hi
Cannot set serial info: Invalid argument

# strace setserial /dev/ttyACM0 spd_hi
execve("/bin/setserial", ["setserial", "/dev/ttyACM0", "spd_hi"], [/* 66 vars */]) = 0
brk(0)                                  = 0x1ed1000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd9d311c000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=156038, ...}) = 0
mmap(NULL, 156038, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd9d30f5000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\24B\2262\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1947608, ...}) = 0
mmap(0x3296400000, 3769592, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3296400000
mprotect(0x329658e000, 2097152, PROT_NONE) = 0
mmap(0x329678e000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18e000) = 0x329678e000
mmap(0x3296793000, 21752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3296793000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd9d30f4000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd9d30f2000
arch_prctl(ARCH_SET_FS, 0x7fd9d30f2720) = 0
mprotect(0x329678e000, 16384, PROT_READ) = 0
mprotect(0x329621e000, 4096, PROT_READ) = 0
munmap(0x7fd9d30f5000, 156038)          = 0
open("/dev/ttyACM0", O_RDWR|O_NONBLOCK) = 3
ioctl(3, TIOCGSERIAL, 0x7fff692984e0)   = 0
ioctl(3, TIOCSSERIAL, 0x7fff69298530)   = -1 EINVAL (Invalid argument)
dup(2)                                  = 4
fcntl(4, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
brk(0)                                  = 0x1ed1000
brk(0x1ef2000)                          = 0x1ef2000
brk(0)                                  = 0x1ef2000
fstat(4, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd9d311b000
lseek(4, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
write(4, "Cannot set serial info: Invalid "..., 41Cannot set serial info: Invalid argument
) = 41
close(4)                                = 0
munmap(0x7fd9d311b000, 4096)            = 0
exit_group(1)                           = ?

Looks like the TIOCSSERIAL ioctl also isn't implemented in the driver.

In case you are wondering what I'm trying to achieve here: I'm working on a project where I use an Arduino as a USB to serial converter, and for that I need to talk to the Arduino and the serial device attached to it at a custom baudrate (31250 baud) which can't be simply set with "stty". So I would like to be able to set the "spd_cust" flag and a custom divisor for /dev/ttyACM0 to get it configured for that baudrate.

Comment 8 Dave Jones 2012-02-22 16:07:05 UTC
I think you're on your own here. I don't know enough about how this hardware works to even know if this is possible.

you could try cribbing from TIOCSSERIAL implementations from some of the other drivers maybe, but it's likely going to need you to experiment to get it right.

if you get really stuck, maybe bring it up with the driver authors on linux-usb.org

Comment 9 Frank Danapfel 2012-02-25 09:53:36 UTC
Dave, thanks for your help.

Since my knowledge about kernel module development is unfortunately very limited, I now asked on linux-usb about the possibilities for adding support for TIOCSSERIAL to cdc-acm: http://permalink.gmane.org/gmane.linux.usb.general/59199


Note You need to log in before you can comment on or make changes to this bug.