[RFC] Specify/support PROTO_NONE for CDC ACM serial dongles

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux