serialport/serialport-rs

UsbPorts are detected as PciPorts on Raspberry Pi 4b

Closed this issue · 9 comments

Hey, I know that is a very bad issue, I'm sorry. When I run code like this

serialport::available_ports()?
        .into_iter()
        .filter_map(|p| {
            debug!("found device: {p:?}");
            match &p.port_type {
                SerialPortType::UsbPort(info) => {
                    if (info.vid, info.pid) == (VENDOR_ID, PRODUCT_ID) {
                        debug!("It's compatible");
                        return Some(p.port_name);
                    }
                }
                // ...
            }
        }//...

on my Laptop, everything works as expected. But when I connect that very same USB device to a Raspberry Pi 4b with a vanilla Raspbian (Bullseye), it is detected with SerialPortType::PciPort. This makes it very hard to find the correct device, and requires communication attempts. Coincidentally, all devices I have, use an FTDI chip, so I cannot tell whether this is FTDI specific or not.

Hello @KnorrFG, I'm sorry to hear that. Unfortunately, I have no Raspberry Pi 4B at hand and when I run our example list_ports on a Raspberry Pi 3+ running Raspian Buster and an FTDI FT232RL attached, it gives me the following output:

$ cargo run --example list_ports
   Compiling serialport v4.2.1 (/[...]/serialport-rs)
[...]
Found 2 ports:
  /dev/ttyAMA0
    Type: Unknown
  /dev/ttyUSB0
    Type: USB
    VID:0403 PID:6001
     Serial Number: FTFOOBAR
      Manufacturer: Future Technology Devices International, Ltd
           Product: FT232 Serial (UART) IC

Which release of serialport-rs are you using on your device? Did you build on the Raspberry Pi or did you cross-compile? Could you please share your output of list_ports?

Hey, thanks for your answer. I currently don't have access to my Pi, I'll test that tomorrow and post the results

So, I've got access to my pi again. I'm using serialport 4.2.0 on the project. But I just cloned the master branch to my raspi, and ran the list_ports example, and this is the output:

Found 3 ports:
  /dev/ttyUSB0
    Type: PCI
  /dev/ttyUSB1
    Type: PCI
  /dev/ttyAMA0
    Type: Unknown

So neither the library version nor the fact I'm cross compiling are the reason for the problem. Btw, I use a Debian-Bullseye Docker container for cross compiling, and I'm using the armv7-unknown-linux-gnueabihf target.

Thank you for the information and for checking this out. I upgraded my Raspberry Pi 3+ to Bullseye meanwhile and interestingly, USB ports are actually shown as USB ports there.

May be the 4B report these devices differently, there is an issue with permissions, or ... Let's dig deeper. I instrumented the port type determination in a first step towards finding the difference in https://github.com/sirhcel/serialport-rs/tree/log-udev-device. The instrumented output of list_ports in my case looks like:

$ export RUST_LOG=trace
$ cargo run --example list_ports
[...]
[2023-07-05T09:03:09Z TRACE serialport::posix::enumerate] port_type: properties: [
        "\"CURRENT_TAGS\" = \":systemd:\", ",
        "\"DEVLINKS\" = \"/dev/serial0 /dev/ttyRS485\", ",
        "\"DEVNAME\" = \"/dev/ttyAMA0\", ",
        "\"DEVPATH\" = \"/devices/platform/soc/3f201000.serial/tty/ttyAMA0\", ",
        "\"ID_MM_CANDIDATE\" = \"1\", ",
        "\"MAJOR\" = \"204\", ",
        "\"MINOR\" = \"64\", ",
        "\"SUBSYSTEM\" = \"tty\", ",
        "\"TAGS\" = \":systemd:\", ",
        "\"USEC_INITIALIZED\" = \"11665767\", ",
    ]
[2023-07-05T09:03:09Z TRACE serialport::posix::enumerate] port_type: properties: [
        "\"CURRENT_TAGS\" = \":systemd:\", ",
        "\"DEVLINKS\" = \"/dev/serial/by-path/platform-3f980000.usb-usb-0:1.3:1.0-port0 /dev/serial/by-id/usb-FTDI_TTL232R-3V3_[...]-if00-port0\", ",
        "\"DEVNAME\" = \"/dev/ttyUSB0\", ",
        "\"DEVPATH\" = \"/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3:1.0/ttyUSB0/tty/ttyUSB0\", ",
        "\"ID_BUS\" = \"usb\", ",
        "\"ID_MM_CANDIDATE\" = \"1\", ",
        "\"ID_MODEL\" = \"TTL232R-3V3\", ",
        "\"ID_MODEL_ENC\" = \"TTL232R-3V3\", ",
        "\"ID_MODEL_ID\" = \"6001\", ",
        "\"ID_PATH\" = \"platform-3f980000.usb-usb-0:1.3:1.0\", ",
        "\"ID_PATH_TAG\" = \"platform-3f980000_usb-usb-0_1_3_1_0\", ",
        "\"ID_REVISION\" = \"0600\", ",
        "\"ID_SERIAL\" = \"FTDI_TTL232R-3V3_[...]\", ",
        "\"ID_SERIAL_SHORT\" = \"[...]\", ",
        "\"ID_TYPE\" = \"generic\", ",
        "\"ID_USB_DRIVER\" = \"ftdi_sio\", ",
        "\"ID_USB_INTERFACES\" = \":ffffff:\", ",
        "\"ID_USB_INTERFACE_NUM\" = \"00\", ",
        "\"ID_USB_MODEL\" = \"TTL232R-3V3\", ",
        "\"ID_USB_MODEL_ENC\" = \"TTL232R-3V3\", ",
        "\"ID_USB_MODEL_ID\" = \"6001\", ",
        "\"ID_USB_REVISION\" = \"0600\", ",
        "\"ID_USB_SERIAL\" = \"FTDI_TTL232R-3V3_[...]\", ",
        "\"ID_USB_SERIAL_SHORT\" = \"[...]\", ",
        "\"ID_USB_TYPE\" = \"generic\", ",
        "\"ID_USB_VENDOR\" = \"FTDI\", ",
        "\"ID_USB_VENDOR_ENC\" = \"FTDI\", ",
        "\"ID_USB_VENDOR_ID\" = \"0403\", ",
        "\"ID_VENDOR\" = \"FTDI\", ",
        "\"ID_VENDOR_ENC\" = \"FTDI\", ",
        "\"ID_VENDOR_ID\" = \"0403\", ",
        "\"MAJOR\" = \"188\", ",
        "\"MINOR\" = \"0\", ",
        "\"SUBSYSTEM\" = \"tty\", ",
        "\"TAGS\" = \":systemd:\", ",
        "\"USEC_INITIALIZED\" = \"4570376904\", ",
    ]
Found 2 ports:
  /dev/ttyAMA0
    Type: Unknown
  /dev/ttyUSB0
    Type: USB
    VID:0403 PID:6001
     Serial Number: [...]
      Manufacturer: FTDI
           Product: TTL232R-3V3

Could you please run the example from this branch on your system?

What are the actual permissions to the USB serial devices on your system? And does your actual user has the required ones? In my case, this looks as follows:

$ ls -l /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0 Jul  5 08:57 /dev/ttyUSB0
$ id
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),104(input),106(render),108(netdev),997(gpio),998(i2c),999(spi)

Is there anything interesting reported by dmesg when plugging in the device? My log excerpt looks as follows:

$ dmesg
[...]
[ 4567.962112] ftdi_sio ttyUSB0: FTDI USB Serial Device converter now disconnected from ttyUSB0
[ 4567.962213] ftdi_sio 1-1.3:1.0: device disconnected
[ 4570.053038] usb 1-1.3: new full-speed USB device number 7 using dwc2
[ 4570.190806] usb 1-1.3: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00
[ 4570.190823] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 4570.190831] usb 1-1.3: Product: TTL232R-3V3
[ 4570.190837] usb 1-1.3: Manufacturer: FTDI
[ 4570.190842] usb 1-1.3: SerialNumber: FT[...]
[ 4570.193913] ftdi_sio 1-1.3:1.0: FTDI USB Serial Device converter detected
[ 4570.194078] usb 1-1.3: Detected FT232RL
[ 4570.195927] usb 1-1.3: FTDI USB Serial Device converter now attached to ttyUSB0

Running your example produces:

[2023-07-05T09:39:11Z TRACE serialport::posix::enumerate] port_type: properties: [
        "\"CURRENT_TAGS\" = \":systemd:\", ",
        "\"DEVLINKS\" = \"/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.2.3:1.0-port0\", ",
        "\"DEVNAME\" = \"/dev/ttyUSB0\", ",
        "\"DEVPATH\" = \"/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.0/ttyUSB0/tty/ttyUSB0\", ",
        "\"ID_BUS\" = \"pci\", ",
        "\"ID_MM_CANDIDATE\" = \"1\", ",
        "\"ID_MODEL_FROM_DATABASE\" = \"VL805 USB 3.0 Host Controller\", ",
        "\"ID_MODEL_ID\" = \"0x3483\", ",
        "\"ID_PATH\" = \"platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.2.3:1.0\", ",
        "\"ID_PATH_TAG\" = \"platform-fd500000_pcie-pci-0000_01_00_0-usb-0_1_2_3_1_0\", ",
        "\"ID_PCI_CLASS_FROM_DATABASE\" = \"Serial bus controller\", ",
        "\"ID_PCI_INTERFACE_FROM_DATABASE\" = \"XHCI\", ",
        "\"ID_PCI_SUBCLASS_FROM_DATABASE\" = \"USB controller\", ",
        "\"ID_USB_DRIVER\" = \"ftdi_sio\", ",
        "\"ID_USB_INTERFACES\" = \":ffffff:\", ",
        "\"ID_USB_INTERFACE_NUM\" = \"00\", ",
        "\"ID_USB_MODEL\" = \"uFR_Classic_CS_Plus\", ",
        "\"ID_USB_MODEL_ENC\" = \"uFR\\\\x20Classic\\\\x20CS\\\\x20Plus\", ",
        "\"ID_USB_MODEL_ID\" = \"6001\", ",
        "\"ID_USB_REVISION\" = \"0600\", ",
        "\"ID_USB_SERIAL\" = \"Digital_Logic_uFR_Classic_CS_Plus_A688FFTP\", ",
        "\"ID_USB_SERIAL_SHORT\" = \"A688FFTP\", ",
        "\"ID_USB_TYPE\" = \"generic\", ",
        "\"ID_USB_VENDOR\" = \"Digital_Logic\", ",
        "\"ID_USB_VENDOR_ENC\" = \"Digital\\\\x20Logic\", ",
        "\"ID_USB_VENDOR_ID\" = \"0403\", ",
        "\"ID_VENDOR_FROM_DATABASE\" = \"VIA Technologies, Inc.\", ",
        "\"ID_VENDOR_ID\" = \"0x1106\", ",
        "\"MAJOR\" = \"188\", ",
        "\"MINOR\" = \"0\", ",
        "\"SUBSYSTEM\" = \"tty\", ",
        "\"TAGS\" = \":systemd:\", ",
        "\"USEC_INITIALIZED\" = \"9731457\", ",
    ]
[2023-07-05T09:39:11Z TRACE serialport::posix::enumerate] port_type: properties: [
        "\"CURRENT_TAGS\" = \":systemd:\", ",
        "\"DEVLINKS\" = \"/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.2.4:1.0-port0\", ",
        "\"DEVNAME\" = \"/dev/ttyUSB1\", ",
        "\"DEVPATH\" = \"/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4:1.0/ttyUSB1/tty/ttyUSB1\", ",
        "\"ID_BUS\" = \"pci\", ",
        "\"ID_MM_CANDIDATE\" = \"1\", ",
        "\"ID_MODEL_FROM_DATABASE\" = \"VL805 USB 3.0 Host Controller\", ",
        "\"ID_MODEL_ID\" = \"0x3483\", ",
        "\"ID_PATH\" = \"platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.2.4:1.0\", ",
        "\"ID_PATH_TAG\" = \"platform-fd500000_pcie-pci-0000_01_00_0-usb-0_1_2_4_1_0\", ",
        "\"ID_PCI_CLASS_FROM_DATABASE\" = \"Serial bus controller\", ",
        "\"ID_PCI_INTERFACE_FROM_DATABASE\" = \"XHCI\", ",
        "\"ID_PCI_SUBCLASS_FROM_DATABASE\" = \"USB controller\", ",
        "\"ID_USB_DRIVER\" = \"ftdi_sio\", ",
        "\"ID_USB_INTERFACES\" = \":ffffff:\", ",
        "\"ID_USB_INTERFACE_NUM\" = \"00\", ",
        "\"ID_USB_MODEL\" = \"FT230X_Basic_UART\", ",
        "\"ID_USB_MODEL_ENC\" = \"FT230X\\\\x20Basic\\\\x20UART\", ",
        "\"ID_USB_MODEL_ID\" = \"6015\", ",
        "\"ID_USB_REVISION\" = \"1000\", ",
        "\"ID_USB_SERIAL\" = \"FTDI_FT230X_Basic_UART_DT04MNS6\", ",
        "\"ID_USB_SERIAL_SHORT\" = \"DT04MNS6\", ",
        "\"ID_USB_TYPE\" = \"generic\", ",
        "\"ID_USB_VENDOR\" = \"FTDI\", ",
        "\"ID_USB_VENDOR_ENC\" = \"FTDI\", ",
        "\"ID_USB_VENDOR_ID\" = \"0403\", ",
        "\"ID_VENDOR_FROM_DATABASE\" = \"VIA Technologies, Inc.\", ",
        "\"ID_VENDOR_ID\" = \"0x1106\", ",
        "\"MAJOR\" = \"188\", ",
        "\"MINOR\" = \"1\", ",
        "\"SUBSYSTEM\" = \"tty\", ",
        "\"TAGS\" = \":systemd:\", ",
        "\"USEC_INITIALIZED\" = \"10322718\", ",
    ]
[2023-07-05T09:39:11Z TRACE serialport::posix::enumerate] port_type: properties: [
        "\"CURRENT_TAGS\" = \":systemd:\", ",
        "\"DEVLINKS\" = \"/dev/serial1\", ",
        "\"DEVNAME\" = \"/dev/ttyAMA0\", ",
        "\"DEVPATH\" = \"/devices/platform/soc/fe201000.serial/tty/ttyAMA0\", ",
        "\"ID_MM_CANDIDATE\" = \"1\", ",
        "\"MAJOR\" = \"204\", ",
        "\"MINOR\" = \"64\", ",
        "\"SUBSYSTEM\" = \"tty\", ",
        "\"TAGS\" = \":systemd:\", ",
        "\"USEC_INITIALIZED\" = \"6465160\", ",
    ]
Found 3 ports:
  /dev/ttyUSB0
    Type: PCI
  /dev/ttyUSB1
    Type: PCI
  /dev/ttyAMA0
    Type: Unknown

Regarding the permissions:

$ ll /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0 Jul  3 17:22 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 Jul  3 17:22 /dev/ttyUSB1

$ id
uid=1000(neuro) gid=1000(neuro) groups=1000(neuro),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),104(input),106(render),108(netdev),117(lpadmin),997(gpio),998(i2c),999(spi)

This was printed by journalctl -f after plugging the first device:

Jul 05 11:42:08 raspberrypi kernel: usb 1-1.2.3: new full-speed USB device number 11 using xhci_hcd
Jul 05 11:42:08 raspberrypi kernel: usb 1-1.2.3: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00
Jul 05 11:42:08 raspberrypi kernel: usb 1-1.2.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jul 05 11:42:08 raspberrypi kernel: usb 1-1.2.3: Product: uFR Classic CS Plus
Jul 05 11:42:08 raspberrypi kernel: usb 1-1.2.3: Manufacturer: Digital Logic
Jul 05 11:42:08 raspberrypi kernel: usb 1-1.2.3: SerialNumber: A688FFTP
Jul 05 11:42:08 raspberrypi kernel: ftdi_sio 1-1.2.3:1.0: FTDI USB Serial Device converter detected
Jul 05 11:42:08 raspberrypi kernel: usb 1-1.2.3: Detected FT232R
Jul 05 11:42:08 raspberrypi kernel: usb 1-1.2.3: FTDI USB Serial Device converter now attached to ttyUSB0
Jul 05 11:42:08 raspberrypi mtp-probe[6619]: checking bus 1, device 11: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.3"
Jul 05 11:42:08 raspberrypi mtp-probe[6619]: bus: 1, device: 11 was not an MTP device
Jul 05 11:42:08 raspberrypi mtp-probe[6650]: checking bus 1, device 11: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.3"
Jul 05 11:42:08 raspberrypi mtp-probe[6650]: bus: 1, device: 11 was not an MTP device
Jul 05 11:42:10 raspberrypi ModemManager[527]: <info>  [base-manager] couldn't check support for device '/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.3': not supported by any plugin

and this was printed after plugging the 2nd device

Jul 05 11:43:05 raspberrypi kernel: usb 1-1.2.4: new full-speed USB device number 12 using xhci_hcd
Jul 05 11:43:05 raspberrypi kernel: usb 1-1.2.4: New USB device found, idVendor=0403, idProduct=6015, bcdDevice=10.00
Jul 05 11:43:05 raspberrypi kernel: usb 1-1.2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jul 05 11:43:05 raspberrypi kernel: usb 1-1.2.4: Product: FT230X Basic UART
Jul 05 11:43:05 raspberrypi kernel: usb 1-1.2.4: Manufacturer: FTDI
Jul 05 11:43:05 raspberrypi kernel: usb 1-1.2.4: SerialNumber: DT04MNS6
Jul 05 11:43:05 raspberrypi kernel: ftdi_sio 1-1.2.4:1.0: FTDI USB Serial Device converter detected
Jul 05 11:43:05 raspberrypi kernel: usb 1-1.2.4: Detected FT-X
Jul 05 11:43:05 raspberrypi kernel: usb 1-1.2.4: FTDI USB Serial Device converter now attached to ttyUSB1
Jul 05 11:43:05 raspberrypi mtp-probe[6656]: checking bus 1, device 12: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4"
Jul 05 11:43:05 raspberrypi mtp-probe[6656]: bus: 1, device: 12 was not an MTP device
Jul 05 11:43:06 raspberrypi mtp-probe[6687]: checking bus 1, device 12: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4"
Jul 05 11:43:06 raspberrypi mtp-probe[6687]: bus: 1, device: 12 was not an MTP device
Jul 05 11:43:08 raspberrypi ModemManager[527]: <info>  [base-manager] couldn't check support for device '/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4': not supported by any plugin

Hope you can extract more insights from that than me ^^

I'm experiencing the same issue (also on a Raspberry Pi 4B).

After looking into this some more and asking for help in the Raspberry Pi Forums, I realized, that all required information is in that output, it's just named differently, and the ID_BUS reports the wrong value. I also checked udev versions. On the pi it's 247, and on my laptop it's 253. I didn't manage to find changelogs for udev that document any type of api change, but maybe some it's possible to adjust the "parsing" logic based on the udev version?

The reason it works on the 3b is that the 3b has its usb chip wired via usb and the 4b has its usb chip wired via PCI.

@sirhcel I'd be willing to try to fix this. I'm not familiar with libudev though. It seems the general problem is that ID_BUS, reports the bus that is closest to the chip, instead of the furthest one. I'd simply patch it to check whether certain alternative fields are available when something other than usb is reported, and return a UsbPort with the mappings:

vid: ID_USB_VENDOR_ID,
pid: IS_USB_MODEL_ID,
manufacturer: ID_USB_VENDOR,
product: ID_USB_MODEL,

while interface and serialnumber would stay identical. Would you accept such a PR?

Thank you very much for your initiative and your workaround! :) I tried to look into the decision-making of libudev when it comes to declaring the device as USB or PCI but got lost in my first attempt.

I came to the same conclusion as you with #113 and like your workaround there: It allows us to address this issue in a timely manner through serialport-rs and even when libudev gets a fix for it one day, it will not interfere with it.