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
- Lines: 236
- Date:
Tue May 23 08:22:22 2000
- Orig file:
v2.3.99-pre8/linux/drivers/usb/pegasus.c
- Orig date:
Thu May 11 15:30:08 2000
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)