patch-2.3.45 linux/drivers/net/pcmcia/3c574_cs.c
Next file: linux/drivers/net/pcmcia/3c575_cb.c
Previous file: linux/drivers/net/ni65.c
Back to the patch index
Back to the overall index
- Lines: 245
- Date:
Sun Feb 13 10:23:26 2000
- Orig file:
v2.3.44/linux/drivers/net/pcmcia/3c574_cs.c
- Orig date:
Fri Jan 21 18:19:16 2000
diff -u --recursive --new-file v2.3.44/linux/drivers/net/pcmcia/3c574_cs.c linux/drivers/net/pcmcia/3c574_cs.c
@@ -220,6 +220,7 @@
u_short media_status;
u_short fast_poll;
u_long last_irq;
+ spinlock_t lock;
};
/* Set iff a MII transceiver on any interface requires mdio preamble.
@@ -261,6 +262,7 @@
static int el3_close(struct net_device *dev);
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static void set_rx_mode(struct net_device *dev);
+static void el3_tx_timeout(struct net_device *dev);
static dev_info_t dev_info = "3c574_cs";
@@ -320,6 +322,8 @@
lp = kmalloc(sizeof(*lp), GFP_KERNEL);
if (!lp) return NULL;
memset(lp, 0, sizeof(*lp));
+
+ lp->lock = SPIN_LOCK_UNLOCKED;
link = &lp->link; dev = &lp->dev;
link->priv = dev->priv = link->irq.Instance = lp;
@@ -351,7 +355,10 @@
dev->init = &tc574_init;
dev->open = &el3_open;
dev->stop = &el3_close;
- dev->tbusy = 1;
+ dev->tx_timeout = el3_tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
+
+ netif_start_queue (dev);
/* Register with Card Services */
link->next = dev_list;
@@ -398,13 +405,12 @@
if (*linkp == NULL)
return;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&lp->lock, flags);
if (link->state & DEV_RELEASE_PENDING) {
del_timer(&link->release);
link->state &= ~DEV_RELEASE_PENDING;
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&lp->lock, flags);
if (link->state & DEV_CONFIG) {
tc574_release((u_long)link);
@@ -502,7 +508,7 @@
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
- dev->tbusy = 0;
+ netif_start_queue (dev);
if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
goto failed;
@@ -667,7 +673,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;
add_timer(&link->release);
}
@@ -682,7 +688,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);
}
@@ -695,7 +701,7 @@
CardServices(RequestConfiguration, link->handle, &link->conf);
if (link->open) {
tc574_reset(dev);
- dev->tbusy = 0; dev->start = 1;
+ netif_start_queue (dev);
}
}
break;
@@ -913,7 +919,7 @@
link->open++;
MOD_INC_USE_COUNT;
- dev->interrupt = 0; dev->tbusy = 0; dev->start = 1;
+ netif_start_queue (dev);
tc574_reset(dev);
lp->media.function = &media_check;
@@ -939,7 +945,7 @@
/* Issue TX_RESET and TX_START commands. */
wait_for_completion(dev, TxReset);
outw(TxEnable, ioaddr + EL3_CMD);
- dev->tbusy = 0;
+ netif_start_queue (dev);
}
static void pop_tx_status(struct net_device *dev)
@@ -972,22 +978,16 @@
long flags = 0;
#endif
- /* Transmitter timeout, serious problems. */
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- if (jiffies - dev->trans_start < TX_TIMEOUT)
- return 1;
- el3_tx_timeout(dev);
- }
-
DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
"status %4.4x.\n", dev->name, (long)skb->len,
inw(ioaddr + EL3_STATUS));
+ netif_stop_queue (dev);
+
#ifdef BROKEN_FEATURES
if (use_fifo_buffer) {
/* Avoid other accesses to the chip while RunnerWrCtrl is non-zero. */
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&lp->lock, flags);
outw((((skb->len + 7)>>2)<<1), ioaddr + RunnerWrCtrl);
DEBUG(0, "TxFree %x, tx length %x, RunnerWrCtrl is %4.4x.\n",
inw(ioaddr+TxFree), skb->len, inw(ioaddr+RunnerWrCtrl));
@@ -1009,7 +1009,7 @@
DEBUG(0, " RunnerWr/RdCtrl is %4.4x/%4.4x, TxFree %x.\n",
inw(ioaddr + RunnerWrCtrl), inw(ioaddr + RunnerRdCtrl),
inw(ioaddr + TxFree));
- restore_flags(flags);
+ spin_unlock_irqrestore (&lp->lock, flags);
}
#else
outw(skb->len, ioaddr + TX_FIFO);
@@ -1021,7 +1021,7 @@
/* TxFree appears only in Window 1, not offset 0x1c. */
if (inw(ioaddr + TxFree) > 1536) {
- dev->tbusy = 0;
+ netif_start_queue (dev);
} else
/* Interrupt us when the FIFO has room for max-sized packet.
The threshold is in units of dwords. */
@@ -1041,26 +1041,27 @@
ioaddr_t ioaddr, status;
int work_budget = max_interrupt_work;
- if ((lp == NULL) || !dev->start)
+ if (lp == NULL)
return;
+
+ spin_lock (&lp->lock);
+
ioaddr = dev->base_addr;
#ifdef PCMCIA_DEBUG
- if (test_and_set_bit(0, (void*)&dev->interrupt)) {
- printk(KERN_NOTICE "%s: re-entering the interrupt handler.\n",
- dev->name);
- return;
- }
DEBUG(3, "%s: interrupt, status %4.4x.\n",
dev->name, inw(ioaddr + EL3_STATUS));
#endif
while ((status = inw(ioaddr + EL3_STATUS)) &
(IntLatch | RxComplete | RxEarly | StatsFull)) {
+
+#if 0
if ((dev->start == 0) || ((status & 0xe000) != 0x2000)) {
DEBUG(1, "%s: Interrupt from dead card\n", dev->name);
break;
}
+#endif
if (status & RxComplete)
work_budget = el3_rx(dev, work_budget);
@@ -1069,8 +1070,9 @@
DEBUG(3, " TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
+ } else {
+ netif_stop_queue (dev);
}
if (status & TxComplete)
@@ -1120,9 +1122,9 @@
#ifdef PCMCIA_DEBUG
DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
dev->name, inw(ioaddr + EL3_STATUS));
- dev->interrupt = 0;
#endif
- return;
+
+ spin_unlock (&lp->lock);
}
/*
@@ -1138,7 +1140,9 @@
u_long flags;
u_short /* cable, */ media, partner;
+#if 0
if (dev->start == 0) goto reschedule;
+#endif
/* Check for pending interrupt with expired latency timer: with
this, we can limp along even if the interrupt is blocked */
@@ -1208,7 +1212,7 @@
{
struct el3_private *lp = (struct el3_private *)dev->priv;
- if (dev->start)
+ if (test_bit(LINK_STATE_START, &dev->state))
update_stats(dev);
return &lp->stats;
}
@@ -1404,6 +1408,8 @@
DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+ netif_stop_queue (dev);
+
if (DEV_OK(link)) {
/* Turn off statistics ASAP. We update lp->stats below. */
outw(StatsDisable, ioaddr + EL3_CMD);
@@ -1419,7 +1425,6 @@
}
link->open--;
- dev->start = 0;
del_timer(&lp->media);
if (link->state & DEV_STALE_CONFIG) {
link->release.expires = jiffies + HZ/20;
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen (who was at: [email protected])