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
Created attachment 559584 [details] strace -ttT -ff -o /tmp/setserial setserial /dev/ttyACM0
does this work in the latest update ? I added the patch referenced. If it works, I'll poke upstream about it again.
Created attachment 563856 [details] patch for cdc-acm.c from 2.6.42 kernel souces from F15
That's the patch that's in the latest update. Does it work ?
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
excellent. I'll poke upstream about it. thanks for testing.
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.
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
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