<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">ChangeSet 1.1250, 2003/06/18 16:55:03-07:00, petkan@users.sourceforge.net

[PATCH] USB: pegasus patch

  better EPIPE handling, ethtool improvements, and
  another attempt to fix HOME_PNA support was made.
  HP added as a vendor and device ID.


 drivers/usb/pegasus.c |   75 ++++++++++++++++++++++++++++++++++++++------------
 drivers/usb/pegasus.h |    3 ++
 2 files changed, 60 insertions(+), 18 deletions(-)


diff -Nru a/drivers/usb/pegasus.c b/drivers/usb/pegasus.c
--- a/drivers/usb/pegasus.c	Wed Jun 18 17:35:06 2003
+++ b/drivers/usb/pegasus.c	Wed Jun 18 17:35:06 2003
@@ -42,7 +42,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.4.30 (2003/04/01)"
+#define DRIVER_VERSION "v0.4.32 (2003/06/06)"
 #define DRIVER_AUTHOR "Petko Manolov &lt;petkan@users.sourceforge.net&gt;"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -582,18 +582,34 @@
 static void write_bulk_callback(struct urb *urb)
 {
 	pegasus_t *pegasus = urb-&gt;context;
+	struct net_device *net = pegasus-&gt;net;
 
 	if (!pegasus || !(pegasus-&gt;flags &amp; PEGASUS_RUNNING))
 		return;
 
-	if (!netif_device_present(pegasus-&gt;net))
+	if (!netif_device_present(net))
 		return;
 
-	if (urb-&gt;status)
-		info("%s: TX status %d", pegasus-&gt;net-&gt;name, urb-&gt;status);
+	switch (urb-&gt;status) {
+	case -EPIPE:
+		/* FIXME schedule_work() to clear the tx halt */
+		netif_stop_queue(net);
+		warn("%s: no tx stall recovery", net-&gt;name);
+		return;
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		dbg("%s: tx unlink, %d", net-&gt;name, urb-&gt;status);
+		return;
+	default:
+		info("%s: TX status %d", net-&gt;name, urb-&gt;status);
+		/* FALL THROUGH */
+	case 0:
+		break;
+	}
 
-	pegasus-&gt;net-&gt;trans_start = jiffies;
-	netif_wake_queue(pegasus-&gt;net);
+	net-&gt;trans_start = jiffies;
+	netif_wake_queue(net);
 }
 
 #ifdef	PEGASUS_USE_INTR
@@ -665,9 +681,16 @@
 		      write_bulk_callback, pegasus);
 	pegasus-&gt;tx_urb-&gt;transfer_buffer_length = count;
 	if ((res = usb_submit_urb(pegasus-&gt;tx_urb))) {
-		warn("failed tx_urb %d", res);
-		pegasus-&gt;stats.tx_errors++;
-		netif_start_queue(net);
+		switch (res) {
+		case -EPIPE:	/* stall, or disconnect from TT */
+			/* cleanup should already have been scheduled */
+			break;
+		case -ENODEV:	/* disconnect() upcoming */
+			break;
+		default:
+			pegasus-&gt;stats.tx_errors++;
+			netif_start_queue(net);
+		}
 	} else {
 		pegasus-&gt;stats.tx_packets++;
 		pegasus-&gt;stats.tx_bytes += skb-&gt;len;
@@ -793,11 +816,16 @@
 	switch (ethcmd) {
 	/* get driver-specific version/etc. info */
 	case ETHTOOL_GDRVINFO:{
-			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+			struct ethtool_drvinfo info;
+
+			memset (&amp;info, 0, sizeof info);
+			info.cmd = ETHTOOL_GDRVINFO;
 			strncpy(info.driver, driver_name,
 				sizeof (info.driver) - 1);
 			strncpy(info.version, DRIVER_VERSION,
 				sizeof (info.version) - 1);
+			usb_make_path(pegasus-&gt;usb, info.bus_info,
+			              sizeof info.bus_info);
 			if (copy_to_user(useraddr, &amp;info, sizeof (info)))
 				return -EFAULT;
 			return 0;
@@ -860,20 +888,23 @@
 {
 	pegasus_t *pegasus;
 	int cmd;
-	char tmp[128];
 
 	pegasus = net-&gt;priv;
 	if (get_user(cmd, (int *) uaddr))
 		return -EFAULT;
 	switch (cmd) {
 	case ETHTOOL_GDRVINFO:{
-			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+			struct ethtool_drvinfo info;
+
+			memset (&amp;info, 0, sizeof info);
+			info.cmd = ETHTOOL_GDRVINFO;
+			strncpy(info.driver, driver_name,
+			        sizeof (info.driver) - 1);
 			strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
 			strncpy(info.version, DRIVER_VERSION,
-				ETHTOOL_BUSINFO_LEN);
-			sprintf(tmp, "usb%d:%d", pegasus-&gt;usb-&gt;bus-&gt;busnum,
-				pegasus-&gt;usb-&gt;devnum);
-			strncpy(info.bus_info, tmp, ETHTOOL_BUSINFO_LEN);
+				sizeof (info.version) - 1);
+			usb_make_path(pegasus-&gt;usb, info.bus_info,
+			              sizeof (info.bus_info) -1);
 			if (copy_to_user(uaddr, &amp;info, sizeof(info)))
 				return -EFAULT;
 			return 0;
@@ -881,6 +912,7 @@
 	case ETHTOOL_GSET:{
 			struct ethtool_cmd ecmd;
 			short lpa, bmcr;
+			u8 port;
 
 			if (copy_from_user(&amp;ecmd, uaddr, sizeof(ecmd)))
 				return -EFAULT;
@@ -890,7 +922,11 @@
 					  SUPPORTED_100baseT_Full |
 					  SUPPORTED_Autoneg |
 					  SUPPORTED_TP | SUPPORTED_MII);
-			ecmd.port = PORT_TP;
+			get_registers(pegasus, Reg7b, 1, &amp;port);
+			if (port == 0)
+				ecmd.port = PORT_MII;
+			else
+				ecmd.port = PORT_TP;
 			ecmd.transceiver = XCVR_INTERNAL;
 			ecmd.phy_address = pegasus-&gt;phy;
 			read_mii_word(pegasus, pegasus-&gt;phy, MII_BMCR, &amp;bmcr);
@@ -1013,7 +1049,10 @@
 	set_register(pegasus, Reg1d, 0);
 	set_register(pegasus, Reg7b, 1);
 	mdelay(100);
-	set_register(pegasus, Reg7b, 2);
+	if ((pegasus-&gt;features &amp; HAS_HOME_PNA) &amp;&amp; mii_mode)
+		set_register(pegasus, Reg7b, 0);
+	else
+		set_register(pegasus, Reg7b, 2);
 	
 	set_register(pegasus, 0x83, data);
 	get_registers(pegasus, 0x83, 1, &amp;data);
diff -Nru a/drivers/usb/pegasus.h b/drivers/usb/pegasus.h
--- a/drivers/usb/pegasus.h	Wed Jun 18 17:35:06 2003
+++ b/drivers/usb/pegasus.h	Wed Jun 18 17:35:06 2003
@@ -127,6 +127,7 @@
 #define VENDOR_ELCON		0x0db7
 #define	VENDOR_ELSA		0x05cc
 #define	VENDOR_HAWKING		0x0e66
+#define	VENDOR_HP		0x03f0
 #define	VENDOR_IODATA		0x04bb
 #define	VENDOR_KINGSTON		0x0951
 #define	VENDOR_LANEED		0x056e
@@ -219,6 +220,8 @@
 PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
 		DEFAULT_GPIO_RESET )
</pre></body></html>