--- usbnet.c.orig	Wed Mar 14 23:43:36 2001
+++ usbnet.c	Thu Mar 15 00:13:35 2001
@@ -119,6 +119,9 @@
 #define	CONTROL_TIMEOUT_MS	(500)			/* msec */
 #define CONTROL_TIMEOUT_JIFFIES ((CONTROL_TIMEOUT_MS * HZ)/1000)
 
+// between wakeups
+#define UNLINK_TIMEOUT_JIFFIES ((3  /*ms*/ * HZ)/1000)
+
 /*-------------------------------------------------------------------------*/
 
 // list of all devices we manage
@@ -297,7 +300,6 @@
 	description:	"Linux Device",
 	// no reset defined (yet?)
 	// no check_connect needed!
-	flags:		FLAG_FRAMING,
 	in: 2, out: 1,
 	epsize:	64,
 };
@@ -842,6 +844,9 @@
 		devdbg (dev, "frame <rx h %d p %d id %d", header->hdr_len,
 			header->packet_len, header->packet_id);
 #endif
+	} else {
+			// we trust the network statck to remove
+			// the extra byte we may have appended
 	}
 
 	if (skb->len) {
@@ -996,10 +1001,11 @@
 	temp = unlink_urbs (&dev->txq) + unlink_urbs (&dev->rxq);
 
 	// maybe wait for deletions to finish.
-	// FIXME -- use "while (!done)" for paranoia
-	if (temp) {
+	while (skb_queue_len (&dev->rxq)
+		&& skb_queue_len (&dev->done)
+		&& skb_queue_len (&dev->txq)) {
 		current->state = TASK_UNINTERRUPTIBLE;
-		schedule ();
+		schedule_timeout (UNLINK_TIMEOUT_JIFFIES);
 		dbg ("waited for %d urb completions", temp);
 	}
 	dev->wait = 0;
@@ -1060,6 +1066,7 @@
 	struct usbnet		*dev = data;
 
 	usb_clear_halt( dev->udev, usb_sndbulkpipe (dev->udev, dev->driver_info->out));
+	netif_wake_queue (&dev->net);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1078,11 +1085,12 @@
 		} else {
 			printk("Cannot clear TX stall\n");
 		}
+	} else {
+		netif_wake_queue (&dev->net);
 	}
 	urb->dev = 0;
 	entry->state = tx_done;
 	defer_bh (dev, skb);
-	netif_wake_queue (&dev->net);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1148,15 +1156,6 @@
 
 	flags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
 
-	if (skb_shared (skb)) {
-		struct sk_buff	*skb2;
-		skb2 = skb_unshare (skb, flags);
-		if (!skb2) {
-			dbg ("can't unshare skb");
-			goto drop;
-		}
-		skb = skb2;
-	}
 	if (info->flags & FLAG_FRAMING) {
 		struct sk_buff	*skb2;
 		skb2 = fixup_skb (skb, flags);
@@ -1186,10 +1185,18 @@
 			*skb_put (skb, 1) = PAD_BYTE;
 		trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer);
 	} else if ((length % EP_SIZE (dev)) == 0) {
-		// FIXME: adding a zero length packet would be better.
-		// Linux seems to drop this byte though ...
-		skb->len++;
-	}
+			if (skb_shared (skb)) {
+				struct sk_buff *skb2;
+				skb2 = skb_unshare (skb, flags);
+				if (!skb2) {
+					usb_free_urb (urb);
+					dbg ("can't unshare skb");
+					goto drop;
+				}
+				skb = skb2;
+			}
+			skb->len++;
+		}
 
 	FILL_BULK_URB (urb, dev->udev,
 			usb_sndbulkpipe (dev->udev, info->out),

