patch-2.3.99-pre9 linux/drivers/usb/pegasus.c

Next file: linux/drivers/usb/printer.c
Previous file: linux/drivers/usb/ov511.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre8/linux/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c
@@ -16,7 +16,7 @@
 #include <linux/usb.h>
 
 
-static const char *version = __FILE__ ": v0.3.9 2000/04/11 Written by Petko Manolov (petkan@spct.net)\n";
+static const char *version = __FILE__ ": v0.3.12 2000/05/22 (C) 1999-2000 Petko Manolov (petkan@spct.net)\n";
 
 
 #define	PEGASUS_MTU		1500
@@ -24,12 +24,15 @@
 #define	SROM_WRITE		0x01
 #define	SROM_READ		0x02
 #define	PEGASUS_TX_TIMEOUT	(HZ*5)
+#define	PEGASUS_RESET		1
 #define	ALIGN(x)		x __attribute__((aligned(L1_CACHE_BYTES)))
 
+
 struct pegasus {
 	struct usb_device	*usb;
 	struct net_device	*net;
 	struct net_device_stats	stats;
+	int			flags;
 	spinlock_t		pegasus_lock;
 	struct urb		rx_urb, tx_urb, intr_urb;
 	unsigned char		ALIGN(rx_buff[PEGASUS_MAX_MTU]); 
@@ -44,9 +47,11 @@
 	void	*private;
 };
 
+
 static int loopback = 0;
 static int multicast_filter_limit = 32;
 
+
 MODULE_AUTHOR("Petko Manolov <petkan@spct.net>");
 MODULE_DESCRIPTION("ADMtek AN986 Pegasus USB Ethernet driver");
 MODULE_PARM(loopback, "i");
@@ -98,6 +103,7 @@
 	return 1;
 }
 
+
 static int pegasus_write_phy_word(struct usb_device *dev, __u8 index, __u16 regdata)
 {
 	int i;
@@ -115,6 +121,7 @@
 	return 1;
 }
 
+
 static int pegasus_rw_srom_word(struct usb_device *dev, __u8 index, __u16 *retdata, __u8 direction)
 {
 	int i;
@@ -134,6 +141,7 @@
 	return 1;
 }
 
+
 static int pegasus_get_node_id(struct usb_device *dev, __u8 *id)
 {
 	int i;
@@ -143,6 +151,7 @@
 	return 0;
 }
 
+
 static int pegasus_reset_mac(struct usb_device *dev)
 {
 	__u8 data = 0x8;
@@ -165,6 +174,7 @@
 	return 1;
 }
 
+
 static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
 {
 	__u16 partmedia, temp;
@@ -195,13 +205,14 @@
 
 	data[0] = 0xc9;
 	data[1] = (partmedia & 0x100) ? 0x30 : ((partmedia & 0x80) ? 0x10 : 0);
-	data[2] = (loopback & 1) ? 0x08 : 0x00;
+	data[2] = (loopback & 1) ? 0x09 : 0x01;
 
 	pegasus_set_registers(usb, 0, 3, data);
 
 	return 0;
 }
 
+
 static void pegasus_read_bulk(struct urb *urb)
 {
 	struct pegasus *pegasus = urb->context;
@@ -253,15 +264,16 @@
 		warn("(prb)failed rx_urb %d", res);
 }
 
+
 static void pegasus_irq(urb_t *urb)
 {
-	if(urb->status) {
-		__u8	*d = urb->transfer_buffer;
-		printk("txst0 %x, txst1 %x, rxst %x, rxlst0 %x, rxlst1 %x, wakest %x",
-			d[0], d[1], d[2], d[3], d[4], d[5]);
-	}
+	__u8	*d = urb->transfer_buffer;
+	
+	if ( d[0] )
+		dbg("txst0=0x%2x", d[0]);
 }
 
+
 static void pegasus_write_bulk(struct urb *urb)
 {
 	struct pegasus *pegasus = urb->context;
@@ -280,12 +292,15 @@
 	struct pegasus *pegasus = net->priv;
 
 	warn("%s: Tx timed out. Reseting...", net->name);
+	usb_unlink_urb(&pegasus->tx_urb);
 	pegasus->stats.tx_errors++;
 	net->trans_start = jiffies;
+	pegasus->flags |= PEGASUS_RESET;
 
 	netif_wake_queue(net);
 }
 
+
 static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
 {
 	struct pegasus	*pegasus = net->priv;
@@ -317,11 +332,13 @@
 	return 0;
 }
 
+
 static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
 {
 	return &((struct pegasus *)dev->priv)->stats;
 }
 
+
 static int pegasus_open(struct net_device *net)
 {
 	struct pegasus *pegasus = (struct pegasus *)net->priv;
@@ -334,8 +351,10 @@
 
 	if ((res = usb_submit_urb(&pegasus->rx_urb)))
 		warn("(open)failed rx_urb %d", res);
-
-/*	usb_submit_urb(&pegasus->intr_urb);*/
+		
+	if ((res = usb_submit_urb(&pegasus->intr_urb)))
+		warn("(open)failed intr_urb %d", res);
+		
 	netif_start_queue(net);
 
 	MOD_INC_USE_COUNT;
@@ -343,6 +362,7 @@
 	return 0;
 }
 
+
 static int pegasus_close(struct net_device *net)
 {
 	struct pegasus	*pegasus = net->priv;
@@ -351,13 +371,14 @@
 
 	usb_unlink_urb(&pegasus->rx_urb);
 	usb_unlink_urb(&pegasus->tx_urb);
-/*	usb_unlink_urb(&pegasus->intr_urb); */
+	usb_unlink_urb(&pegasus->intr_urb);
 
 	MOD_DEC_USE_COUNT;
 
 	return 0;
 }
 
+
 static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 {
 	__u16 *data = (__u16 *)&rq->ifr_data;
@@ -379,6 +400,7 @@
 	}
 }
 
+
 static void pegasus_set_rx_mode(struct net_device *net)
 {
 	struct pegasus *pegasus = net->priv;
@@ -400,6 +422,7 @@
 	netif_wake_queue(net);
 }
 
+
 static int check_device_ids( __u16 vendor, __u16 product )
 {
 	int i=0;
@@ -413,6 +436,7 @@
 	return	-1;
 }
 
+
 static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
 {
 	struct net_device *net;
@@ -463,7 +487,7 @@
 			pegasus->tx_buff, PEGASUS_MAX_MTU, pegasus_write_bulk,
 			pegasus);
 	FILL_INT_URB(&pegasus->intr_urb, dev, usb_rcvintpipe(dev, 3),
-			pegasus->intr_buff, 8, pegasus_irq, pegasus, 250);
+			pegasus->intr_buff, 8, pegasus_irq, pegasus, 500);
 
 
 	printk(KERN_INFO "%s: %s\n", net->name, usb_dev_id[dev_indx].name);
@@ -471,6 +495,7 @@
 	return pegasus;
 }
 
+
 static void pegasus_disconnect(struct usb_device *dev, void *ptr)
 {
 	struct pegasus *pegasus = ptr;
@@ -487,10 +512,11 @@
 
 	usb_unlink_urb(&pegasus->rx_urb);
 	usb_unlink_urb(&pegasus->tx_urb);
-/*	usb_unlink_urb(&pegasus->intr_urb);*/
+	usb_unlink_urb(&pegasus->intr_urb);
 
 	kfree(pegasus);
 }
+
 
 static struct usb_driver pegasus_driver = {
 	name:		"pegasus",

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