patch-2.3.45 linux/drivers/net/pcmcia/smc91c92_cs.c

Next file: linux/drivers/net/pcmcia/tulip_cb.c
Previous file: linux/drivers/net/pcmcia/nmclan_cs.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.44/linux/drivers/net/pcmcia/smc91c92_cs.c linux/drivers/net/pcmcia/smc91c92_cs.c
@@ -125,6 +125,8 @@
     u_short			media_status;
     u_short			fast_poll;
     u_long			last_rx;
+    
+    spinlock_t			lock;
 };
 
 /* Special definitions for Megahertz multifunction cards */
@@ -281,6 +283,7 @@
 static int smc91c92_event(event_t event, int priority,
 			  event_callback_args_t *args);
 
+static void smc91c92_tx_timeout (struct net_device *dev);
 static int smc91c92_open(struct net_device *dev);
 static int smc91c92_close(struct net_device *dev);
 static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -379,9 +382,12 @@
     dev->init = &smc91c92_init;
     dev->open = &smc91c92_open;
     dev->stop = &smc91c92_close;
-    dev->tbusy = 1;
+    dev->tx_timeout = smc91c92_tx_timeout;
+    dev->watchdog_timeo = TX_TIMEOUT;
     dev->priv = link->priv = link->irq.Instance = smc;
     
+    netif_start_queue (dev);
+    
     /* Register with Card Services */
     link->next = dev_list;
     dev_list = link;
@@ -663,7 +669,7 @@
     struct smc_private *smc = link->priv;
     struct net_device *dev = &smc->dev;
     ioaddr_t ioaddr = dev->base_addr;
-    int i, wait, loop;
+    int i, wait=0, loop;
     unsigned int addr;
 
     /* Read Ethernet address from Serial EEPROM */
@@ -775,7 +781,7 @@
     struct smc_private *smc = link->priv;
     struct net_device *dev = &smc->dev;
     static ioaddr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-    int i, j;
+    int i=0, j;
     
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
@@ -977,7 +983,7 @@
 	dev->if_port = if_port;
     else
 	printk(KERN_NOTICE "smc91c92_cs: invalid if_port requested\n");
-    dev->tbusy = 0;
+    netif_start_queue (dev);
     
     if (register_netdev(dev) != 0) {
 	printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
@@ -1106,8 +1112,7 @@
     case CS_EVENT_CARD_REMOVAL:
 	link->state &= ~DEV_PRESENT;
 	if (link->state & DEV_CONFIG) {
-	    dev->tbusy = 1;
-	    dev->start = 0;
+	    netif_stop_queue (dev);
 	    link->release.expires = jiffies + HZ/20;
 	    link->state |= DEV_RELEASE_PENDING;
 	    add_timer(&link->release);
@@ -1123,7 +1128,7 @@
     case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
 	    if (link->open) {
-		dev->tbusy = 1; dev->start = 0;
+		netif_stop_queue (dev);
 	    }
 	    CardServices(ReleaseConfiguration, link->handle);
 	}
@@ -1147,7 +1152,7 @@
 	    }
 	    if (link->open) {
 		smc_reset(dev);
-		dev->tbusy = 0;	dev->start = 1;
+		netif_start_queue (dev);
 	    }
 	}
 	break;
@@ -1201,7 +1206,7 @@
     link->open++;
     MOD_INC_USE_COUNT;
     
-    dev->interrupt = 0; dev->tbusy = 0; dev->start = 1;
+    netif_start_queue (dev);
     smc->saved_skb = 0;
     smc->packets_waiting = 0;
     
@@ -1225,8 +1230,7 @@
     DEBUG(0, "%s: smc91c92_close(), status %4.4x.\n",
 	  dev->name, inw(ioaddr + BANK_SELECT));
     
-    dev->tbusy = 1;
-    dev->start = 0;
+    netif_stop_queue (dev);
     
     /* Shut off all interrupts, and turn off the Tx and Rx sections.
        Don't bother to check for chip present. */
@@ -1240,7 +1244,7 @@
     SMC_SELECT_BANK( 1 );
     outw(CTL_POWERDOWN, ioaddr + CONTROL  );
     
-    link->open--; dev->start = 0;
+    link->open--;
     del_timer(&smc->media);
     if (link->state & DEV_STALE_CONFIG) {
 	link->release.expires = jiffies + HZ/20;
@@ -1281,7 +1285,7 @@
 	       " failed, status %#2.2x.\n", dev->name, packet_no);
 	dev_kfree_skb (skb);
 	smc->saved_skb = NULL;
-	dev->tbusy = 0;
+	netif_start_queue (dev);
 	return;
     }
     
@@ -1329,12 +1333,30 @@
     smc->saved_skb = NULL;
     dev_kfree_skb (skb);
     dev->trans_start = jiffies;
-    dev->tbusy = 0;
+    netif_start_queue (dev);
     return;
 }
 
 /*====================================================================*/
 
+static void smc91c92_tx_timeout (struct net_device *dev)
+{
+	struct smc_private *smc = dev->priv;
+	ioaddr_t ioaddr = dev->base_addr;
+
+	printk (KERN_NOTICE "%s: SMC91c92 transmit timed out, "
+		"Tx_status %2.2x status %4.4x.\n",
+		dev->name, inw (ioaddr) & 0xff, inw (ioaddr + 2));
+	smc->stats.tx_errors++;
+	smc_reset (dev);
+	dev->trans_start = jiffies;
+	smc->saved_skb = NULL;
+	netif_start_queue (dev);
+}
+
+
+/*====================================================================*/
+
 static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     struct smc_private *smc = dev->priv;
@@ -1342,29 +1364,10 @@
     unsigned short num_pages;
     short time_out, ir;
     
-    /* Transmitter timeout, serious problems. */
-    if (dev->tbusy) {
-	int tickssofar = jiffies - dev->trans_start;
-	if (tickssofar < TX_TIMEOUT)
-	    return 1;
-	printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
-	       "Tx_status %2.2x status %4.4x.\n",
-	       dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
-	smc->stats.tx_errors++;
-	smc_reset(dev);
-	dev->trans_start = jiffies;
-	dev->tbusy = 0;
-	smc->saved_skb = NULL;
-    }
-
     DEBUG(2, "%s: smc91c92_start_xmit(length = %d) called,"
 	  " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
-    
-    /* Avoid timer-based retransmission conflicts. */
-    if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
-	printk(KERN_ERR "%s: transmitter access conflict.\n", dev->name);
-	return 1;
-    }
+
+    netif_stop_queue (dev);
     
     if ( smc->saved_skb) {
 	/* THIS SHOULD NEVER HAPPEN. */
@@ -1500,18 +1503,13 @@
     u_short saved_bank, saved_pointer, mask, status;
     char bogus_cnt = INTR_WORK;		/* Work we are willing to do. */
 
-    if ((smc == NULL) || !dev->start)
+    if (smc == NULL)
 	return;
     ioaddr = dev->base_addr;
     
-#ifdef PCMCIA_DEBUG
-    if (dev->interrupt) {
-	printk(KERN_ERR "%s: re-entering the interrupt handler.\n",
-	       dev->name);
-	return;
-    }
-    dev->interrupt = 1;
+    spin_lock (&smc->lock);
 
+#ifdef PCMCIA_DEBUG
     DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
 	  irq, ioaddr);
 #endif
@@ -1569,7 +1567,7 @@
 	    mask |= ( IM_TX_EMPTY_INT | IM_TX_INT );
 	    
 	    /* and let the card send more packets to me */
-	    mark_bh( NET_BH );
+	    netif_wake_queue (dev);
 	}
 	if (status & IM_RX_OVRN_INT) {
 	    smc->stats.rx_errors++;
@@ -1588,8 +1586,9 @@
     outw(saved_pointer, ioaddr + POINTER);
     SMC_SELECT_BANK( saved_bank );
 
+    spin_unlock (&smc->lock);
+
 #ifdef PCMCIA_DEBUG
-    dev->interrupt = 0;
     DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
 #endif
 
@@ -1913,8 +1912,10 @@
     ioaddr_t ioaddr = dev->base_addr;
     u_short i, media, saved_bank;
 
+#if 0
     if (dev->start == 0) goto reschedule;
-    
+#endif
+
     saved_bank = inw(ioaddr + BANK_SELECT);
     SMC_SELECT_BANK(2);
     i = inw(ioaddr + INTERRUPT);

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