I'm working on a development board and both the boot loader (u-boot) and the kernel (f_acm.c) have support for serial console over USB. Both are implemented via CDC ACM. Whenever any of these devices enumerate, Network Manager sees a modem and sends AT commands to it, which tends to cause problems. I can't really fault Network Manager though, because in the USB device descriptor the linux gadget device and the u-boot device both claim to support AT v.25TER. static struct usb_interface_descriptor acm_control_interface_desc __initdata = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, /* .bInterfaceNumber = DYNAMIC */ .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, .bInterfaceProtocol = USB_CDC_ACM_PROTO_AT_V25TER, /* .iInterface = DYNAMIC */ }; This would also be a problem for anyone attempting to implement a serial dongle or terminal using only standard USB classes. Whats the best way to approach this? Make special udev rules? After reading the CDC doc, I had another thought: 4.4 Communication Interface Class Control Protocol Codes A communication control protocol is used by the USB host to control communication functions in the device or on the network. This specification defines code values for certain standard control protocols. It also reserves codes for additional standard or vendor-specific control protocols. If the Communication Class control model does not require a specific protocol, the value of 00h should be used. so why not use USB_CDC_PROTO_NONE? It still works with the usbser.sys windows driver. udev rules could later be written to not consider USB ACM devices that have PROTO_NONE as modems. [PATCH] Utilize PROTO_NONE for dumb ACM serial devices. CDC ACM specfies the protocol that can be used to send commands to the device. This includes options like AT, CDMA, 3G, etc. However, in the case of a CDC ACM gadget device, no AT commands are actually accepted. In fact, if the host believes that it is a modem, it will query it with AT commands. Utilize PROTO_NONE to attempt to differentiate ourselves as a dumb serial line. --- drivers/usb/class/cdc-acm.c | 4 ++++ drivers/usb/gadget/f_acm.c | 2 +- 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index b3d5a23..8098572 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1386,6 +1386,10 @@ static struct usb_device_id acm_ids[] = { quirk for this. */ }, + /* Control interface without command set */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, + USB_CDC_ACM_PROTO_NONE) }, + /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_ACM_PROTO_AT_V25TER) }, diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index c1d34df..f1293e0 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -106,7 +106,7 @@ static struct usb_interface_descriptor acm_control_interface_desc __initdata = { .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, - .bInterfaceProtocol = USB_CDC_ACM_PROTO_AT_V25TER, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, /* .iInterface = DYNAMIC */ }; -- 1.6.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html