CDC on Linux

I have seen a few older posts on this, but nothing recent. Does CDC work with Linux, or is there something special that needs to be done?

My situation, I have CDC working fine between the FEZBit and Windows, but when I plug the FEZBit into my RPI it fails to register the port. Here are my dmesg logs:

[Sat Feb 13 14:41:13 2021] usb 1-1.1: new full-speed USB device number 11 using xhci_hcd
[Sat Feb 13 14:41:13 2021] usb 1-1.1: language id specifier not provided by device, defaulting to English
[Sat Feb 13 14:41:13 2021] usb 1-1.1: New USB device found, idVendor=1b9f, idProduct=f001, bcdDevice= 0.00
[Sat Feb 13 14:41:13 2021] usb 1-1.1: New USB device strings: Mfr=10, Product=11, SerialNumber=12
[Sat Feb 13 14:41:13 2021] usb 1-1.1: Product: FEZ Bit Server
[Sat Feb 13 14:41:13 2021] usb 1-1.1: Manufacturer: GHI Electronics
[Sat Feb 13 14:41:13 2021] usb 1-1.1: SerialNumber: FEZ Bit Server
[Sat Feb 13 14:41:13 2021] cdc_acm 1-1.1:1.0: Control and data interfaces are not separated!
[Sat Feb 13 14:41:13 2021] cdc_acm 1-1.1:1.0: This needs exactly 3 endpoints
[Sat Feb 13 14:41:13 2021] cdc_acm: probe of 1-1.1:1.0 failed with error -22

We have not tested linux but I am surprised it doesn’t work. This is standard CDC. I wonder what is different!

One thing I do see, is that the TinyCLR CDC is only defining 2 endpoints for the ACM profile, the bulk transfer IN and OUT endpoints. The CDC ACM spec states that 3 endpoints are required, what seems to be missing is the Interrupt IN endpoint.

That correlates with the dmesg log
[Sat Feb 13 14:41:13 2021] cdc_acm 1-1.1:1.0: Control and data interfaces are not separated!
[Sat Feb 13 14:41:13 2021] cdc_acm 1-1.1:1.0: This needs exactly 3 endpoints

It might be that Windows is more forgiving?

I spent a few minutes looking through the Linux CDC-ACM driver and I suspect from that the TinyCLR CDC-ACM implementation is not completely compliant.

Here is the relevant Linux driver code snippet
Linux CDC-ACM Driver Code

if (control_interface == data_interface) {
		/* some broken devices designed for windows work this way */
		dev_warn(&intf->dev,"Control and data interfaces are not separated!\n");
		combined_interfaces = 1;
		/* a popular other OS doesn't use it */
		quirks |= NO_CAP_LINE;
		if (data_interface->cur_altsetting->desc.bNumEndpoints != 3) {
			dev_err(&intf->dev, "This needs exactly 3 endpoints\n");
			return -EINVAL;
		}
look_for_collapsed_interface:
		res = usb_find_common_endpoints(data_interface->cur_altsetting,
				&epread, &epwrite, &epctrl, NULL);
		if (res)
			return res;

		goto made_compressed_probe;
	}

linux/errno-base.h at master · torvalds/linux (github.com)

#define	EINVAL		22	/* Invalid argument */