# USB CDC device not recognized

## fernan82

Hello,

I have a custom USB CDC device that uses Microchip's PIC18LF14K50 MCU w/ USB module. According to Microchip it should be supported by the kernel drivers and I found some posts that state that on Ubuntu it gets automatically detected as /dev/ttyACM0. However, with all the USB serial drivers compiled as modules it doesn't get detected in my system. I can see it listed in lsusb's output but no device nodes are created and cat /proc/tty/driver/usbserial doesn't show anything for it.

I managed to get it working by modifyng the Simple USB Serial driver and adding my device vendor and product ID to the list. This creates two device nodes when I connect the device: /dev/ttyUSB0 and /dev/ttyUSB1. Why does it create two nodes? Only /dev/ttyUSB1 seems to work to an extent, I can echo commands to it and the device responds correctly. But the client application for the device was written for Windows on .NET and when I try to run it under Mono it throws an exception when I try to open the serial port (IOException with "invalid argument" message). I found out that this is not a problem with Mono but with the driver as it doesn't implement certain features. I tried modifying some of the other drivers with the same results.

So basicly my questions is, how can I get the device to be recognized automatically without having to modify the drivers as it does for Ubuntu users? Hopefully once I get that it'll have loaded the right driver that should work fine with Mono's SerialPort class.

----------

## tomtom69

Looks like the VID:PID is not handled by the drivers of your kernel.

What is the output of lsusb and the relevant part for this device of lsusb -v?

----------

## NeddySeagoon

fernan82,

As well as posting the Vendor and Device IDs for the device, make friends with wgetpaste and share your kernel .config file.

As its a CDC device, as well an the USB Serial driver, you will need the right CDC kernel module.

There are two serial ports an one is used for the data stream and looks to all intents like a Hayes modem, the other is for meta data about the serial link.

----------

## fernan82

Thanks for replying and sorry I took so long. 

On another laptop using a similar configuration but with the 3.16.1 kernel from upstream it works as expected, it creates a single ttyACM0 device and everything works as it should. I found posts gooing back to 2007 saying that's how it should work so I would think it should work with any recent kernel. I got all USB serial drivers compiled as modules.

Here's the lsusb output:

```

Bus 005 Device 002: ID 04d8:000a Microchip Technology, Inc. CDC RS-232 Emulation Device

```

And I always get HTTP/400 (BAD REQUEST) when I use wgetpaste from this network but here's the kernel config:

http://bpaste.net/show/782faf5bd9e1

----------

## fernan82

It seems it has something to do with Gentoo's Linux dynamic and persistent device naming patch.

I just build the 3.14.14-gentoo kernel with the same .config file. I copied the config file and run make to get the new configuration options, took all the defaults, interrupted the build and ran make menuconfig, disabled the dynamic and persistent device naming option, built it and booted the new kernel and plugged the device and it was properly detected and created a single ttyACM0 node.

There's only  one small problem. My application uses .NET SerialPort class to enumerate the serial interfaces and it looks like Mono's implementation of this class simply returns all ttyUSB* and ttyS* devices. I've been playing with udev rules to get it to use that name but I can't get it to work.

Among others I've tried:

```

ATTR{idVendor}=="04d8", NAME="ttyUSB1"

ATTR{idVendor}=="04d8", ATTR{idProduct}=="000a", NAME="ttyUSB1"

KERNEL=="ttyACM0", NAME="ttyUSB1"

```

I've run udevadm control --reload-rules after every rule change and here's the output of udevadm info -a -p $(udevadm info -q path -n /dev/ttyACM0)

```

Udevadm info starts with the device specified by the devpath and then

walks up the chain of parent devices. It prints for every device

found, all possible attributes in the udev rules key format.

A rule to match, can be composed by the attributes of the device

and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:12.0/usb3/3-1/3-1:1.0/tty/ttyACM0':

    KERNEL=="ttyACM0"

    SUBSYSTEM=="tty"

    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:12.0/usb3/3-1/3-1:1.0':

    KERNELS=="3-1:1.0"

    SUBSYSTEMS=="usb"

    DRIVERS=="cdc_acm"

    ATTRS{bInterfaceClass}=="02"

    ATTRS{bmCapabilities}=="2"

    ATTRS{bInterfaceSubClass}=="02"

    ATTRS{bInterfaceProtocol}=="01"

    ATTRS{bNumEndpoints}=="01"

    ATTRS{supports_autosuspend}=="1"

    ATTRS{bAlternateSetting}==" 0"

    ATTRS{bInterfaceNumber}=="00"

  looking at parent device '/devices/pci0000:00/0000:00:12.0/usb3/3-1':

    KERNELS=="3-1"

    SUBSYSTEMS=="usb"

    DRIVERS=="usb"

    ATTRS{bDeviceSubClass}=="00"

    ATTRS{bDeviceProtocol}=="00"

    ATTRS{devpath}=="1"

    ATTRS{idVendor}=="04d8"

    ATTRS{speed}=="12"

    ATTRS{bNumInterfaces}==" 2"

    ATTRS{bConfigurationValue}=="1"

    ATTRS{bMaxPacketSize0}=="8"

    ATTRS{busnum}=="3"

    ATTRS{devnum}=="14"

    ATTRS{configuration}==""

    ATTRS{bMaxPower}=="100mA"

    ATTRS{authorized}=="1"

    ATTRS{bmAttributes}=="c0"

    ATTRS{bNumConfigurations}=="1"

    ATTRS{maxchild}=="0"

    ATTRS{bcdDevice}=="0100"

    ATTRS{avoid_reset_quirk}=="0"

    ATTRS{quirks}=="0x0"

    ATTRS{version}==" 2.00"

    ATTRS{urbnum}=="14"

    ATTRS{ltm_capable}=="no"

    ATTRS{manufacturer}=="Microchip Technology Inc."

    ATTRS{removable}=="unknown"

    ATTRS{idProduct}=="000a"

    ATTRS{bDeviceClass}=="02"

    ATTRS{product}=="CDC RS-232 Emulation Device"

  looking at parent device '/devices/pci0000:00/0000:00:12.0/usb3':

    KERNELS=="usb3"

    SUBSYSTEMS=="usb"

    DRIVERS=="usb"

    ATTRS{bDeviceSubClass}=="00"

    ATTRS{bDeviceProtocol}=="00"

    ATTRS{devpath}=="0"

    ATTRS{idVendor}=="1d6b"

    ATTRS{speed}=="12"

    ATTRS{bNumInterfaces}==" 1"

    ATTRS{bConfigurationValue}=="1"

    ATTRS{bMaxPacketSize0}=="64"

    ATTRS{authorized_default}=="1"

    ATTRS{busnum}=="3"

    ATTRS{devnum}=="1"

    ATTRS{configuration}==""

    ATTRS{bMaxPower}=="0mA"

    ATTRS{authorized}=="1"

    ATTRS{bmAttributes}=="e0"

    ATTRS{bNumConfigurations}=="1"

    ATTRS{maxchild}=="4"

    ATTRS{bcdDevice}=="0312"

    ATTRS{avoid_reset_quirk}=="0"

    ATTRS{quirks}=="0x0"

    ATTRS{serial}=="0000:00:12.0"

    ATTRS{version}==" 1.10"

    ATTRS{urbnum}=="360"

    ATTRS{ltm_capable}=="no"

    ATTRS{manufacturer}=="Linux 3.12.21-gentoo-r1 ohci_hcd"

    ATTRS{removable}=="unknown"

    ATTRS{idProduct}=="0001"

    ATTRS{bDeviceClass}=="09"

    ATTRS{product}=="OHCI PCI host controller"

  looking at parent device '/devices/pci0000:00/0000:00:12.0':

    KERNELS=="0000:00:12.0"

    SUBSYSTEMS=="pci"

    DRIVERS=="ohci-pci"

    ATTRS{irq}=="18"

    ATTRS{subsystem_vendor}=="0x1025"

    ATTRS{broken_parity_status}=="0"

    ATTRS{class}=="0x0c0310"

    ATTRS{consistent_dma_mask_bits}=="32"

    ATTRS{dma_mask_bits}=="32"

    ATTRS{local_cpus}=="3"

    ATTRS{device}=="0x7807"

    ATTRS{enable}=="1"

    ATTRS{msi_bus}==""

    ATTRS{local_cpulist}=="0-1"

    ATTRS{vendor}=="0x1022"

    ATTRS{subsystem_device}=="0x080d"

    ATTRS{numa_node}=="-1"

  looking at parent device '/devices/pci0000:00':

    KERNELS=="pci0000:00"

    SUBSYSTEMS==""

    DRIVERS==""

```

As a workaround I can create a symlink manually or through an init script but then the application will always see the device even when not plugged in.Last edited by fernan82 on Thu Aug 28, 2014 9:55 pm; edited 1 time in total

----------

## fernan82

I've also just rebuilt my old kernel (3.12.21) with the persistent device naming option disabled and it also works fine so it's definitely this gentoo option that broke it.

I still need help setting the udev rule for this device.

Thank you

----------

