PATCH: Update lp486e for 2.5

From: Alan Cox (alan@lxorguk.ukuu.org.uk)
Date: Mon Apr 07 2003 - 19:25:09 EST


diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.67/drivers/net/lp486e.c linux-2.5.67-ac1/drivers/net/lp486e.c
--- linux-2.5.67/drivers/net/lp486e.c 2003-02-10 18:38:11.000000000 +0000
+++ linux-2.5.67-ac1/drivers/net/lp486e.c 2003-04-07 19:14:53.000000000 +0100
@@ -56,7 +56,7 @@
 All other communication is through memory!
 */
 
-#define SLOW_DOWN_IO udelay(5);
+#define SLOW_DOWN_IO udelay(5)
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -195,7 +195,7 @@
 typedef u32 phys_addr;
 
 static inline phys_addr
-va_to_pa(volatile void *x) {
+va_to_pa(void *x) {
         return x ? virt_to_bus(x) : I596_NULL;
 }
 
@@ -341,14 +341,15 @@
         unsigned long tdr_stat; /* directly follows tdr */
 
         int last_restart;
- volatile struct i596_rbd *rbd_list;
- volatile struct i596_rbd *rbd_tail;
- volatile struct i596_rfd *rx_tail;
- volatile struct i596_cmd *cmd_tail;
- volatile struct i596_cmd *cmd_head;
+ struct i596_rbd *rbd_list;
+ struct i596_rbd *rbd_tail;
+ struct i596_rfd *rx_tail;
+ struct i596_cmd *cmd_tail;
+ struct i596_cmd *cmd_head;
         int cmd_backlog;
         unsigned long last_cmd;
         struct net_device_stats stats;
+ spinlock_t cmd_lock;
 };
 
 static char init_setup[14] = {
@@ -386,7 +387,7 @@
 
 static int
 i596_timeout(struct net_device *dev, char *msg, int ct) {
- volatile struct i596_private *lp;
+ struct i596_private *lp;
         int boguscnt = ct;
 
         lp = (struct i596_private *) dev->priv;
@@ -398,13 +399,14 @@
                         return 1;
                 }
                 udelay(5);
+ barrier();
         }
         return 0;
 }
 
 static inline int
 init_rx_bufs(struct net_device *dev, int num) {
- volatile struct i596_private *lp;
+ struct i596_private *lp;
         struct i596_rfd *rfd;
         int i;
         // struct i596_rbd *rbd;
@@ -517,8 +519,8 @@
 /* selftest or dump */
 static void
 i596_port_do(struct net_device *dev, int portcmd, char *cmdname) {
- volatile struct i596_private *lp = dev->priv;
- volatile u16 *outp;
+ struct i596_private *lp = dev->priv;
+ u16 *outp;
         int i, m;
 
         memset((void *)&(lp->dump), 0, sizeof(struct i596_dump));
@@ -541,7 +543,7 @@
 
 static int
 i596_scp_setup(struct net_device *dev) {
- volatile struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->priv;
         int boguscnt;
 
         /* Setup SCP, ISCP, SCB */
@@ -608,6 +610,7 @@
                         return 1;
                 }
                 udelay(5);
+ barrier();
         }
         /* I find here boguscnt==100, so no delay was required. */
 
@@ -616,7 +619,7 @@
 
 static int
 init_i596(struct net_device *dev) {
- volatile struct i596_private *lp;
+ struct i596_private *lp;
 
         if (i596_scp_setup(dev))
                 return 1;
@@ -641,6 +644,8 @@
         lp->scb.command = RX_START;
         CA();
 
+ barrier();
+
         if (lp->scb.command && i596_timeout(dev, "Receive Unit start", 100))
                 return 1;
 
@@ -649,7 +654,7 @@
 
 /* Receive a single frame */
 static inline int
-i596_rx_one(struct net_device *dev, volatile struct i596_private *lp,
+i596_rx_one(struct net_device *dev, struct i596_private *lp,
             struct i596_rfd *rfd, int *frames) {
 
         if (rfd->stat & RFD_STAT_OK) {
@@ -703,14 +708,14 @@
 
 static int
 i596_rx(struct net_device *dev) {
- volatile struct i596_private *lp = (struct i596_private *) dev->priv;
+ struct i596_private *lp = (struct i596_private *) dev->priv;
         struct i596_rfd *rfd;
         int frames = 0;
 
         while (1) {
                 rfd = pa_to_va(lp->scb.pa_rfd);
                 if (!rfd) {
- printk("i596_rx: NULL rfd?\n");
+ printk(KERN_ERR "i596_rx: NULL rfd?\n");
                         return 0;
                 }
 #if 1
@@ -725,6 +730,7 @@
                 lp->rx_tail->cmd = 0;
                 lp->rx_tail = rfd;
                 lp->scb.pa_rfd = rfd->pa_next;
+ barrier();
         }
 
         return frames;
@@ -732,7 +738,7 @@
 
 static void
 i596_cleanup_cmd(struct net_device *dev) {
- volatile struct i596_private *lp;
+ struct i596_private *lp;
         struct i596_cmd *cmd;
 
         lp = (struct i596_private *) dev->priv;
@@ -770,6 +776,7 @@
                                 break;
                         }
                 }
+ barrier();
         }
 
         if (lp->scb.command && i596_timeout(dev, "i596_cleanup_cmd", 100))
@@ -778,9 +785,7 @@
         lp->scb.pa_cmd = va_to_pa(lp->cmd_head);
 }
 
-static inline void
-i596_reset(struct net_device *dev,
- volatile struct i596_private *lp, int ioaddr) {
+static void i596_reset(struct net_device *dev, struct i596_private *lp, int ioaddr) {
 
         if (lp->scb.command && i596_timeout(dev, "i596_reset", 100))
                 ;
@@ -789,7 +794,8 @@
 
         lp->scb.command = CUC_ABORT | RX_ABORT;
         CA();
-
+ barrier();
+
         /* wait for shutdown */
         if (lp->scb.command && i596_timeout(dev, "i596_reset(2)", 400))
                 ;
@@ -803,7 +809,7 @@
 }
 
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) {
- volatile struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->priv;
         int ioaddr = dev->base_addr;
         unsigned long flags;
 
@@ -811,8 +817,8 @@
         cmd->command |= (CMD_EOL | CMD_INTR);
         cmd->pa_next = I596_NULL;
 
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&lp->cmd_lock, flags);
+
         if (lp->cmd_head) {
                 lp->cmd_tail->pa_next = va_to_pa(cmd);
         } else {
@@ -827,64 +833,45 @@
         lp->cmd_backlog++;
 
         lp->cmd_head = pa_to_va(lp->scb.pa_cmd);
- restore_flags(flags);
+ spin_unlock_irqrestore(&lp->cmd_lock, flags);
 
         if (lp->cmd_backlog > 16) {
                 int tickssofar = jiffies - lp->last_cmd;
- if (tickssofar < 25) return;
+ if (tickssofar < HZ/4)
+ return;
 
- printk("%s: command unit timed out, status resetting.\n",
- dev->name);
+ printk(KERN_WARNING "%s: command unit timed out, status resetting.\n", dev->name);
                 i596_reset(dev, lp, ioaddr);
         }
 }
 
-static int
-i596_open(struct net_device *dev) {
+static int i596_open(struct net_device *dev)
+{
         int i;
 
         i = request_irq(dev->irq, &i596_interrupt, SA_SHIRQ, dev->name, dev);
         if (i) {
- printk("%s: IRQ %d not free\n", dev->name, dev->irq);
+ printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
                 return i;
         }
 
         if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE)
- printk("%s: only able to allocate %d receive buffers\n",
- dev->name, i);
+ printk(KERN_ERR "%s: only able to allocate %d receive buffers\n", dev->name, i);
 
         if (i < 4) {
-// release buffers
                 free_irq(dev->irq, dev);
                 return -EAGAIN;
         }
-
         netif_start_queue(dev);
-
         init_i596(dev);
-
         return 0; /* Always succeed */
 }
 
-static int
-i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
- volatile struct i596_private *lp = dev->priv;
+static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
+ struct i596_private *lp = dev->priv;
         struct tx_cmd *tx_cmd;
         short length;
 
- /* If some higher level thinks we've missed a tx-done interrupt
- we are passed NULL. n.b. dev_tint handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- printk ("What about dev_tint\n");
- /* dev_tint(dev); */
- return 0;
- }
-
- /* shouldn't happen */
- if (skb->len <= 0)
- return 0;
-
         length = skb->len;
         
         if (length < ETH_ZLEN) {
@@ -896,14 +883,10 @@
         
         dev->trans_start = jiffies;
 
- tx_cmd = (struct tx_cmd *)
- kmalloc ((sizeof (struct tx_cmd)
- + sizeof (struct i596_tbd)), GFP_ATOMIC);
+ tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
         if (tx_cmd == NULL) {
- printk ("%s: i596_xmit Memory squeeze, dropping packet.\n",
- dev->name);
+ printk(KERN_WARNING "%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
                 lp->stats.tx_dropped++;
-
                 dev_kfree_skb (skb);
         } else {
                 struct i596_tbd *tx_cmd_tbd;
@@ -934,11 +917,11 @@
 
 static void
 i596_tx_timeout (struct net_device *dev) {
- volatile struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->priv;
         int ioaddr = dev->base_addr;
 
         /* Transmitter timeout, serious problems. */
- printk ("%s: transmit timed out, status resetting.\n", dev->name);
+ printk(KERN_WARNING "%s: transmit timed out, status resetting.\n", dev->name);
         lp->stats.tx_errors++;
 
         /* Try to restart the adaptor */
@@ -957,8 +940,8 @@
         netif_wake_queue(dev);
 }
 
-static void
-print_eth(char *add) {
+static void print_eth(char *add)
+{
         int i;
 
         printk ("Dest ");
@@ -975,9 +958,8 @@
                 (unsigned char) add[12], (unsigned char) add[13]);
 }
 
-int __init
-lp486e_probe(struct net_device *dev) {
- volatile struct i596_private *lp;
+int __init lp486e_probe(struct net_device *dev) {
+ struct i596_private *lp;
         unsigned char eth_addr[6] = { 0, 0xaa, 0, 0, 0, 0 };
         unsigned char *bios;
         int i, j;
@@ -996,14 +978,14 @@
         /*
          * Allocate working memory, 16-byte aligned
          */
- dev->mem_start = (unsigned long)
- kmalloc(sizeof(struct i596_private) + 0x0f, GFP_KERNEL);
+ dev->mem_start = (unsigned long) kmalloc(sizeof(struct i596_private) + 0x0f, GFP_KERNEL);
         if (!dev->mem_start)
                 goto err_out;
         dev->priv = (void *)((dev->mem_start + 0xf) & 0xfffffff0);
         lp = (struct i596_private *) dev->priv;
         memset((void *)lp, 0, sizeof(struct i596_private));
-
+ spin_lock_init(&lp->cmd_lock);
+
         /*
          * Do we really have this thing?
          */
@@ -1071,14 +1053,16 @@
 
 static inline void
 i596_handle_CU_completion(struct net_device *dev,
- volatile struct i596_private *lp,
+ struct i596_private *lp,
                           unsigned short status,
                           unsigned short *ack_cmdp) {
- volatile struct i596_cmd *cmd;
+ struct i596_cmd *cmd;
         int frames_out = 0;
         int commands_done = 0;
         int cmd_val;
+ unsigned long flags;
 
+ spin_lock_irqsave(&lp->cmd_lock, flags);
         cmd = lp->cmd_head;
 
         while (lp->cmd_head && (lp->cmd_head->status & CMD_STAT_C)) {
@@ -1160,31 +1144,29 @@
                         lp->last_cmd = jiffies;
                         
                 }
+ barrier();
         }
 
         cmd = lp->cmd_head;
         while (cmd && (cmd != lp->cmd_tail)) {
                 cmd->command &= 0x1fff;
                 cmd = pa_to_va(cmd->pa_next);
+ barrier();
         }
 
         if (lp->cmd_head)
                 *ack_cmdp |= CUC_START;
         lp->scb.pa_cmd = va_to_pa(lp->cmd_head);
+ spin_unlock_irqrestore(&lp->cmd_lock, flags);
 }
 
 static void
 i596_interrupt (int irq, void *dev_instance, struct pt_regs *regs) {
         struct net_device *dev = (struct net_device *) dev_instance;
- volatile struct i596_private *lp;
+ struct i596_private *lp;
         unsigned short status, ack_cmd = 0;
         int frames_in = 0;
 
- if (dev == NULL) {
- printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
         lp = (struct i596_private *) dev->priv;
 
         /*
@@ -1251,7 +1233,7 @@
 }
 
 static int i596_close(struct net_device *dev) {
- volatile struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->priv;
 
         netif_stop_queue(dev);
 
@@ -1284,7 +1266,7 @@
 */
 
 static void set_multicast_list(struct net_device *dev) {
- volatile struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->priv;
         struct i596_cmd *cmd;
 
         if (i596_debug > 1)
@@ -1294,12 +1276,9 @@
         if (dev->mc_count > 0) {
                 struct dev_mc_list *dmi;
                 char *cp;
- cmd = (struct i596_cmd *)
- kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6,
- GFP_ATOMIC);
+ cmd = (struct i596_cmd *)kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
                 if (cmd == NULL) {
- printk ("%s: set_multicast Memory squeeze.\n",
- dev->name);
+ printk (KERN_ERR "%s: set_multicast Memory squeeze.\n", dev->name);
                         return;
                 }
                 cmd->command = CmdMulticastList;
@@ -1316,8 +1295,7 @@
                 if (lp->set_conf.pa_next != I596_NULL) {
                         return;
                 }
- if (dev->mc_count == 0 &&
- !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
+ if (dev->mc_count == 0 && !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
                         if (dev->flags & IFF_ALLMULTI)
                                 dev->flags |= IFF_PROMISC;
                         lp->i596_config[8] &= ~0x01;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Apr 07 2003 - 22:00:33 EST