patch-2.4.0-test10 linux/drivers/usb/net1080.c

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

diff -u --recursive --new-file v2.4.0-test9/linux/drivers/usb/net1080.c linux/drivers/usb/net1080.c
@@ -45,16 +45,18 @@
 #include <linux/usb.h>
 
 
-static const struct product {
-	char	*name;
-	u16	idVendor;
-	u16	idProduct;
-} products [] = {
-	{ "NetChip TurboCONNECT", 0x0525, 0x1080 },	// reference
+static const struct usb_device_id	products [] = {
+	{		// reference design
+	    idProduct:		0x1080,
+	    idVendor:		0x0525,
+	    driver_info:	(unsigned long) "NetChip TurboCONNECT",
+	},
 	// Belkin, ...
-	{ 0, 0, 0 },			// END
+	{ },		// END
 };
 
+MODULE_DEVICE_TABLE (usb, products);
+
 static u8	node_id [ETH_ALEN];
 
 
@@ -91,6 +93,7 @@
 				+ (mtu) \
 				+ 1 \
 				+ sizeof (struct nc_trailer))
+#define MAX_PACKET	8191
 
 // zero means no timeout; else, how long a 64 byte bulk
 // read may be queued before HW flushes it.
@@ -132,7 +135,7 @@
 struct net1080 {
 	// housekeeping
 	struct usb_device	*udev;
-	const struct product	*prod_info;
+	const struct usb_device_id	*prod_info;
 	struct semaphore	mutex;
 	struct list_head	dev_list;
 	wait_queue_head_t	*wait;
@@ -422,7 +425,7 @@
 #endif
 
 	info ("%s: %s, port %c on USB %d dev %d, peer %sconnected",
-		dev->net.name, dev->prod_info->name,
+		dev->net.name, (char *) dev->prod_info->driver_info,
 		(status & STATUS_PORT_A) ? 'A' : 'B',
 		dev->udev->bus->busnum,
 		dev->udev->devnum,
@@ -443,7 +446,7 @@
 
 static int net1080_change_mtu (struct net_device *net, int new_mtu)
 {
-	if ((new_mtu < 0) || NC_MAX_PACKET (new_mtu) > 8191)
+	if ((new_mtu < 0) || NC_MAX_PACKET (new_mtu) > MAX_PACKET)
 		return -EINVAL;
 	net->mtu = new_mtu;
 	return 0;
@@ -518,8 +521,7 @@
 	entry->state = rx_done;
 	entry->urb = 0;
 
-	if ((urb->transfer_flags & USB_ASYNC_UNLINK) != 0
-			|| netif_queue_stopped (&dev->net)) {
+	if ((urb->transfer_flags & USB_ASYNC_UNLINK) != 0) {
 		dbg ("rx ... shutting down");
 		usb_free_urb (urb);
 		urb = 0;
@@ -528,12 +530,17 @@
 	switch (urb_status) {
 	    // success
 	    case 0:
-		if (skb->len & 0x01)
-			break;
-		entry->state = rx_cleanup;
-		dev->stats.rx_errors++;
-		dev->stats.rx_length_errors++;
-		dbg ("even rx len %d", skb->len);
+		if (!(skb->len & 0x01)) {
+			entry->state = rx_cleanup;
+			dev->stats.rx_errors++;
+			dev->stats.rx_length_errors++;
+			dbg ("even rx len %d", skb->len);
+		} else if (skb->len > MAX_PACKET) {
+			entry->state = rx_cleanup;
+			dev->stats.rx_errors++;
+			dev->stats.rx_frame_errors++;
+			dbg ("rx too big, %d", skb->len);
+		}
 		break;
 
 	    // hardware-reported interface shutdown ... which we
@@ -816,10 +823,18 @@
 	header = (struct nc_header *) skb->data;
 	le16_to_cpus (&header->hdr_len);
 	le16_to_cpus (&header->packet_len);
-	if (header->hdr_len < NC_MIN_HEADER) {
+	if (header->packet_len > MAX_PACKET) {
+		dev->stats.rx_frame_errors++;
+		dbg ("packet too big, %d", header->packet_len);
+		goto error;
+	} else if (header->hdr_len < NC_MIN_HEADER) {
 		dev->stats.rx_frame_errors++;
 		dbg ("header too short, %d", header->hdr_len);
 		goto error;
+	} else if (header->hdr_len > header->packet_len) {
+		dev->stats.rx_frame_errors++;
+		dbg ("header too big, %d packet %d", header->hdr_len, header->packet_len);
+		goto error;
 	} else if (header->hdr_len != sizeof *header) {
 		// out of band data for us?
 		dbg ("header OOB, %d bytes", header->hdr_len - NC_MIN_HEADER);
@@ -952,7 +967,7 @@
 	info ("%s: USB %d dev %d, %s, disconnected",
 		dev->net.name,
 		udev->bus->busnum, udev->devnum,
-		dev->prod_info->name);
+		(char *) dev->prod_info->driver_info);
 	
 	unregister_netdev (&dev->net);
 
@@ -973,24 +988,14 @@
 
 // precondition: never called in_interrupt
 
-static void *net1080_probe (struct usb_device *udev, unsigned ifnum)
+static void *
+net1080_bind (struct usb_device *udev, unsigned ifnum, const struct usb_device_id *prod)
 {
-	int			i;
 	struct net1080		*dev;
 	struct net_device 	*net;
 	struct usb_interface_descriptor	*interface;
 	int			retval;
 
-	for (i = 0; products [i].idVendor != 0; i++) {
-		if (products [i].idVendor != udev->descriptor.idVendor)
-			continue;
-		if (products [i].idProduct != udev->descriptor.idProduct)
-			continue;
-		break;
-	}
-	if (products [i].idVendor == 0)
-		return 0;
-	
 	// sanity check; expect dedicated interface/devices for now.
 	interface = &udev->actconfig->interface [ifnum].altsetting[0];
 	if (udev->descriptor.bNumConfigurations != 1
@@ -1013,7 +1018,7 @@
 	init_MUTEX_LOCKED (&dev->mutex);
 	usb_inc_dev_use (udev);
 	dev->udev = udev;
-	dev->prod_info = &products [i];
+	dev->prod_info = prod;
 	INIT_LIST_HEAD (&dev->dev_list);
 	skb_queue_head_init (&dev->rxq);
 	skb_queue_head_init (&dev->txq);
@@ -1067,7 +1072,8 @@
 
 static struct usb_driver net1080_driver = {
 	name:		"net1080",
-	probe:		net1080_probe,
+	id_table:	products,
+	bind:		net1080_bind,
 	disconnect:	net1080_disconnect,
 };
 

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