patch-2.4.0-test10 linux/drivers/net/wavelan.c

Next file: linux/drivers/net/wavelan.p.h
Previous file: linux/drivers/net/wan/sdlamain.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test9/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
@@ -173,37 +173,29 @@
 /*------------------------------------------------------------------*/
 /*
  * Disable interrupts on the WaveLAN hardware.
+ * (called by wv_82586_stop())
  */
 static inline void wv_ints_off(device * dev)
 {
 	net_local *lp = (net_local *) dev->priv;
 	unsigned long ioaddr = dev->base_addr;
-	unsigned long flags;
-
-	wv_splhi(lp, &flags);
 	
 	lp->hacr &= ~HACR_INTRON;
 	hacr_write(ioaddr, lp->hacr);
-
-	wv_splx(lp, &flags);
 }				/* wv_ints_off */
 
 /*------------------------------------------------------------------*/
 /*
  * Enable interrupts on the WaveLAN hardware.
+ * (called by wv_hw_reset())
  */
 static inline void wv_ints_on(device * dev)
 {
 	net_local *lp = (net_local *) dev->priv;
 	unsigned long ioaddr = dev->base_addr;
-	unsigned long flags;
-
-	wv_splhi(lp, &flags);
 
 	lp->hacr |= HACR_INTRON;
 	hacr_write(ioaddr, lp->hacr);
-
-	wv_splx(lp, &flags);
 }				/* wv_ints_on */
 
 /******************* MODEM MANAGEMENT SUBROUTINES *******************/
@@ -871,14 +863,18 @@
 static inline void wv_82586_reconfig(device * dev)
 {
 	net_local *lp = (net_local *) dev->priv;
+	unsigned long flags;
 
 	/* Arm the flag, will be cleard in wv_82586_config() */
 	lp->reconfig_82586 = 1;
 
 	/* Check if we can do it now ! */
-	if((netif_running(dev)) && !(netif_queue_stopped(dev)))
+	if((netif_running(dev)) && !(netif_queue_stopped(dev))) {
+		wv_splhi(lp, &flags);
 		/* May fail */
 		wv_82586_config(dev);
+		wv_splx(lp, &flags);
+	}
 	else {
 #ifdef DEBUG_CONFIG_INFO
 		printk(KERN_DEBUG
@@ -2806,6 +2802,7 @@
 static int wavelan_packet_xmit(struct sk_buff *skb, device * dev)
 {
 	net_local *lp = (net_local *) dev->priv;
+	unsigned long flags;
 
 #ifdef DEBUG_TX_TRACE
 	printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
@@ -2822,7 +2819,9 @@
 	 * we can do it now.
 	 */
 	if (lp->reconfig_82586) {
+		wv_splhi(lp, &flags);
 		wv_82586_config(dev);
+		wv_splx(lp, &flags);
 		/* Check that we can continue */
 		if (lp->tx_n_in_use == (NTXBLOCKS - 1))
 			return 1;
@@ -3369,21 +3368,17 @@
 	ac_ias_t ias;		/* IA-setup action */
 	ac_mcs_t mcs;		/* Multicast setup */
 	struct dev_mc_list *dmi;
-	unsigned long flags;
 
 #ifdef DEBUG_CONFIG_TRACE
 	printk(KERN_DEBUG "%s: ->wv_82586_config()\n", dev->name);
 #endif
 
-	wv_splhi(lp, &flags);
-	
 	/* Check nothing bad has happened */
 	if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
 #ifdef DEBUG_CONFIG_ERROR
 		printk(KERN_INFO "%s: wv_82586_config(): Tx queue full.\n",
 		       dev->name);
 #endif
-		wv_splx(lp, &flags);
 		return;
 	}
 
@@ -3524,8 +3519,6 @@
 	if (lp->tx_n_in_use == (NTXBLOCKS - 1))
 		netif_stop_queue(dev);
 
-	wv_splx(lp, &flags);
-
 #ifdef DEBUG_CONFIG_TRACE
 	printk(KERN_DEBUG "%s: <-wv_82586_config()\n", dev->name);
 #endif
@@ -3535,6 +3528,7 @@
 /*
  * This routine, called by wavelan_close(), gracefully stops the 
  * WaveLAN controller (i82586).
+ * (called by wavelan_close())
  */
 static inline void wv_82586_stop(device * dev)
 {
@@ -3571,6 +3565,7 @@
  *	3. Reset & Configure LAN controller (using wv_82586_start)
  *	4. Start the LAN controller's command unit
  *	5. Start the LAN controller's receive unit
+ * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open())
  */
 static int wv_hw_reset(device * dev)
 {
@@ -3676,16 +3671,18 @@
 	lp = (net_local *) dev->priv;
 	ioaddr = dev->base_addr;
 
-#ifdef DEBUG_INTERRUPT_ERROR
-	/* Check state of our spinlock (it should be cleared) */
+#ifdef DEBUG_INTERRUPT_INFO
+	/* Check state of our spinlock */
 	if(spin_is_locked(&lp->spinlock))
-		printk(KERN_INFO
+		printk(KERN_DEBUG
 		       "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
 		       dev->name);
 #endif
 
-	/* Prevent reentrancy. It is safe because wv_splhi disable interrupts
-	 * before aquiring the spinlock */
+	/* Prevent reentrancy. We need to do that because we may have
+	 * multiple interrupt handler running concurrently.
+	 * It is safe because wv_splhi() disables interrupts before acquiring
+	 * the spinlock. */
 	spin_lock(&lp->spinlock);
 
 	/* Check modem interupt */
@@ -3712,6 +3709,7 @@
 		       "%s: wavelan_interrupt(): interrupt not coming from i82586\n",
 		       dev->name);
 #endif
+		spin_unlock (&lp->spinlock);
 		return;
 	}
 
@@ -3752,9 +3750,6 @@
 		wv_receive(dev);
 	}
 
-	/* Release spinlock here so that wv_hw_reset() can grab it */
-	spin_unlock (&lp->spinlock);
-
 	/* Check the state of the command unit. */
 	if (((status & SCB_ST_CNA) == SCB_ST_CNA) ||
 	    (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) &&
@@ -3779,6 +3774,9 @@
 		wv_hw_reset(dev);
 	}
 
+	/* Release spinlock */
+	spin_unlock (&lp->spinlock);
+
 #ifdef DEBUG_INTERRUPT_TRACE
 	printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
 #endif
@@ -3806,14 +3804,13 @@
 	       dev->name);
 #endif
 
-	wv_splhi(lp, &flags);
-
 	/* Check that we came here for something */
 	if (lp->tx_n_in_use <= 0) {
-		wv_splx(lp, &flags);
 		return;
 	}
 
+	wv_splhi(lp, &flags);
+
 	/* Try to see if some buffers are not free (in case we missed
 	 * an interrupt */
 	nreaped = wv_complete(dev, ioaddr, lp);
@@ -3910,6 +3907,7 @@
 		       "%s: wavelan_open(): impossible to start the card\n",
 		       dev->name);
 #endif
+		wv_splx(lp, &flags);
 		return -EAGAIN;
 	}
 	wv_splx(lp, &flags);
@@ -3929,6 +3927,9 @@
  */
 static int wavelan_close(device * dev)
 {
+	net_local *lp = (net_local *) dev->priv;
+	unsigned long flags;
+
 #ifdef DEBUG_CALLBACK_TRACE
 	printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
 	       (unsigned int) dev);
@@ -3939,7 +3940,9 @@
 	/*
 	 * Flush the Tx and disable Rx.
 	 */
+	wv_splhi(lp, &flags);
 	wv_82586_stop(dev);
+	wv_splx(lp, &flags);
 
 	free_irq(dev->irq, dev);
 
@@ -3965,7 +3968,7 @@
 	net_local *lp;
 
 #ifdef DEBUG_CALLBACK_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%x)\n",
+	printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n",
 	       dev->name, (unsigned int) dev, ioaddr);
 #endif
 

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