patch-2.3.47 linux/drivers/usb/acm.c

Next file: linux/drivers/usb/hid.c
Previous file: linux/drivers/usb/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.46/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
@@ -1,5 +1,5 @@
 /*
- * acm.c  Version 0.15
+ * acm.c  Version 0.16
  *
  * Copyright (c) 1999 Armin Fuerst	<fuerst@in.tum.de>
  * Copyright (c) 1999 Pavel Machek	<pavel@suse.cz>
@@ -18,6 +18,7 @@
  *	v0.13 - added termios, added hangup
  *	v0.14 - sized down struct acm
  *	v0.15 - fixed flow control again - characters could be lost
+ *	v0.16 - added code for modems with swapped data and control interfaces
  */
 
 /*
@@ -473,29 +474,34 @@
 	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
 
 		cfacm = dev->config + i;
-		dbg("probing config %d", cfacm->bConfigurationValue);
 
-		ifcom = cfacm->interface[0].altsetting + 0;
-		if (ifcom->bInterfaceClass != 2 || ifcom->bInterfaceSubClass != 2 ||
-		    ifcom->bInterfaceProtocol != 1 || ifcom->bNumEndpoints != 1)
-			continue;
+		dbg("probing config %d", cfacm->bConfigurationValue);
 
-		epctrl = ifcom->endpoint + 0;
-		if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3)
+		if (cfacm->bNumInterfaces != 2 || 
+		    usb_interface_claimed(cfacm->interface + 0) ||
+		    usb_interface_claimed(cfacm->interface + 1))
 			continue;
 
+		ifcom = cfacm->interface[0].altsetting + 0;
 		ifdata = cfacm->interface[1].altsetting + 0;
-		if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints != 2)
-			continue;
 
-		if (usb_interface_claimed(cfacm->interface + 0) ||
-		    usb_interface_claimed(cfacm->interface + 1))
+		if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints != 2) {
+			ifcom = cfacm->interface[1].altsetting + 0;
+			ifdata = cfacm->interface[0].altsetting + 0;
+			if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints != 2)
+				continue;
+		}
+
+		if (ifcom->bInterfaceClass != 2 || ifcom->bInterfaceSubClass != 2 ||
+		    ifcom->bInterfaceProtocol != 1 || ifcom->bNumEndpoints != 1)
 			continue;
 
+		epctrl = ifcom->endpoint + 0;
 		epread = ifdata->endpoint + 0;
 		epwrite = ifdata->endpoint + 1;
 
-		if ((epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
+		if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
+		   (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
 		   ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
 			continue;
 
@@ -640,17 +646,13 @@
  * Init / cleanup.
  */
 
-#ifdef MODULE
-void cleanup_module(void)
+static void __exit usb_acm_cleanup(void)
 {
 	usb_deregister(&acm_driver);
 	tty_unregister_driver(&acm_tty_driver);
 }
 
-int init_module(void)
-#else
-int usb_acm_init(void)
-#endif
+static int __init usb_acm_init(void)
 {
 	acm_tty_driver.init_termios =		tty_std_termios;
 	acm_tty_driver.init_termios.c_cflag =	B9600 | CS8 | CREAD | HUPCL | CLOCAL;
@@ -666,4 +668,5 @@
 	return 0;
 }
 
-__initcall(usb_acm_init);
+module_init(usb_acm_init);
+module_exit(usb_acm_cleanup);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)