patch-2.4.0-test11 linux/drivers/usb/acm.c

Next file: linux/drivers/usb/audio.c
Previous file: linux/drivers/usb/Config.in
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test10/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
@@ -477,114 +477,113 @@
  * USB probe and disconnect routines.
  */
 
-static void *acm_probe(struct usb_device *dev, unsigned int ifnum)
+static void *acm_probe(struct usb_device *dev, unsigned int ifnum,
+		       const struct usb_device_id *id)
 {
 	struct acm *acm;
 	struct usb_config_descriptor *cfacm;
 	struct usb_interface_descriptor *ifcom, *ifdata;
 	struct usb_endpoint_descriptor *epctrl, *epread, *epwrite;
-	int readsize, ctrlsize, minor, i;
+	int readsize, ctrlsize, minor;
 	unsigned char *buf;
 
-	if (dev->descriptor.bDeviceClass != 2 || dev->descriptor.bDeviceSubClass != 0
+	/* Since 0 is treated as a wildcard by the USB pattern matching,
+	   we explicitly check bDeviceSubClass and bDeviceProtocol
+	   here. */
+	if (dev->descriptor.bDeviceSubClass != 0
 		|| dev->descriptor.bDeviceProtocol != 0) return NULL;
 
-	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+	cfacm = dev->actconfig;
 
-		cfacm = dev->config + i;
+	dbg("probing config %d", cfacm->bConfigurationValue);
 
-		dbg("probing config %d", cfacm->bConfigurationValue);
-
-		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) {
-			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 ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
-		   (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
-		   ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
-			continue;
-
-		if ((epread->bEndpointAddress & 0x80) != 0x80) {
-			epread = ifdata->endpoint + 1;
-			epwrite = ifdata->endpoint + 0;
-		}
-
-		usb_set_configuration(dev, cfacm->bConfigurationValue);
-
-		for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
-		if (acm_table[minor]) {
-			err("no more free acm devices");
-			return NULL;
-		}
-
-		if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
-			err("out of memory");
+	if (cfacm->bNumInterfaces != 2 || 
+	    usb_interface_claimed(cfacm->interface + 0) ||
+	    usb_interface_claimed(cfacm->interface + 1))
+		return NULL;
+
+	ifcom = cfacm->interface[0].altsetting + 0;
+	ifdata = cfacm->interface[1].altsetting + 0;
+
+	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)
 			return NULL;
-		}
-		memset(acm, 0, sizeof(struct acm));
+	}
 
-		ctrlsize = epctrl->wMaxPacketSize;
-		readsize = epread->wMaxPacketSize;
-		acm->writesize = epwrite->wMaxPacketSize;
-		acm->iface = cfacm->interface;
-		acm->minor = minor;
-		acm->dev = dev;
-
-		acm->tqueue.routine = acm_softint;
-		acm->tqueue.data = acm;
-
-		if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
-			err("out of memory");
-			kfree(acm);
+	if (ifcom->bInterfaceClass != 2 || ifcom->bInterfaceSubClass != 2 ||
+	    ifcom->bInterfaceProtocol != 1 || ifcom->bNumEndpoints != 1)
 			return NULL;
-		}
 
-		FILL_INT_URB(&acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
-			buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
+	epctrl = ifcom->endpoint + 0;
+	epread = ifdata->endpoint + 0;
+	epwrite = ifdata->endpoint + 1;
+
+	if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
+	    (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
+	    ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
+		return NULL;
+
+	if ((epread->bEndpointAddress & 0x80) != 0x80) {
+		epread = ifdata->endpoint + 1;
+		epwrite = ifdata->endpoint + 0;
+	}
 
-		FILL_BULK_URB(&acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
-			buf += ctrlsize, readsize, acm_read_bulk, acm);
-		acm->readurb.transfer_flags |= USB_NO_FSBR;
+	usb_set_configuration(dev, cfacm->bConfigurationValue);
 
-		FILL_BULK_URB(&acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
-			buf += readsize, acm->writesize, acm_write_bulk, acm);
-		acm->writeurb.transfer_flags |= USB_NO_FSBR;
-	
-		printk(KERN_INFO "ttyACM%d: USB ACM device\n", minor);
+	for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
+	if (acm_table[minor]) {
+		err("no more free acm devices");
+		return NULL;
+	}
 
-		acm_set_control(acm, acm->ctrlout);
+	if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
+		err("out of memory");
+		return NULL;
+	}
+	memset(acm, 0, sizeof(struct acm));
 
-		acm->line.speed = cpu_to_le32(9600);
-		acm->line.databits = 8;
-		acm_set_line(acm, &acm->line);
+	ctrlsize = epctrl->wMaxPacketSize;
+	readsize = epread->wMaxPacketSize;
+	acm->writesize = epwrite->wMaxPacketSize;
+	acm->iface = cfacm->interface;
+	acm->minor = minor;
+	acm->dev = dev;
 
-		usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
-		usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
+	acm->tqueue.routine = acm_softint;
+	acm->tqueue.data = acm;
 
-		tty_register_devfs(&acm_tty_driver, 0, minor);
-		return acm_table[minor] = acm;
+	if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
+		err("out of memory");
+		kfree(acm);
+		return NULL;
 	}
 
-	return NULL;
+	FILL_INT_URB(&acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
+		buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
+
+	FILL_BULK_URB(&acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
+		buf += ctrlsize, readsize, acm_read_bulk, acm);
+	acm->readurb.transfer_flags |= USB_NO_FSBR;
+
+	FILL_BULK_URB(&acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
+		buf += readsize, acm->writesize, acm_write_bulk, acm);
+	acm->writeurb.transfer_flags |= USB_NO_FSBR;
+
+	printk(KERN_INFO "ttyACM%d: USB ACM device\n", minor);
+
+	acm_set_control(acm, acm->ctrlout);
+
+	acm->line.speed = cpu_to_le32(9600);
+	acm->line.databits = 8;
+	acm_set_line(acm, &acm->line);
+
+	usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
+	usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
+
+	tty_register_devfs(&acm_tty_driver, 0, minor);
+	return acm_table[minor] = acm;
 }
 
 static void acm_disconnect(struct usb_device *dev, void *ptr)
@@ -622,10 +621,19 @@
  * USB driver structure.
  */
 
+static struct usb_device_id acm_ids [] = {
+    { bDeviceClass: 2},
+    { bInterfaceClass: 2, bInterfaceSubClass: 2, bInterfaceProtocol: 1},
+    { }						/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, acm_ids);
+
 static struct usb_driver acm_driver = {
 	name:		"acm",
 	probe:		acm_probe,
-	disconnect:	acm_disconnect
+	disconnect:	acm_disconnect,
+	id_table:	acm_ids,
 };
 
 /*

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