lkml.org 
[lkml]   [2000]   [Feb]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectPATCH: Out-of-sync dirty pointer with 2.3.44 and epic100
Jani,

Can you tell me if the attached patch, against 2.3.44, fixes the
problem?

Regards,

Jeff






--
Jeff Garzik | "Vegetarian" is the Indian word
Building 1024 | for 'lousy hunter.'
MandrakeSoft, Inc. |Index: drivers/net/epic100.c
===================================================================
RCS file: /g/cvslan/linux_2_3/drivers/net/epic100.c,v
retrieving revision 1.1.1.7
retrieving revision 1.1.1.7.12.3
diff -u -r1.1.1.7 -r1.1.1.7.12.3
--- drivers/net/epic100.c 2000/02/10 22:10:27 1.1.1.7
+++ drivers/net/epic100.c 2000/02/13 17:37:10 1.1.1.7.12.3
@@ -79,7 +79,6 @@
MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(rx_copybreak, "i");
MODULE_PARM(max_interrupt_work, "i");
-#define DEV_FREE_SKB(skb) dev_kfree_skb(skb);

/* The I/O extent. */
#define EPIC_TOTAL_SIZE 0x100
@@ -425,6 +424,8 @@
dev->do_ioctl = &mii_ioctl;
dev->tx_timeout = epic_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
+
+ netif_stop_queue (dev);

return dev;
}
@@ -527,13 +528,15 @@
int mii_reg5;
ep->full_duplex = ep->force_fd;

+ MOD_INC_USE_COUNT;
+
/* Soft reset the chip. */
outl(0x4001, ioaddr + GENCTL);

- if (request_irq(dev->irq, &epic_interrupt, SA_SHIRQ, "SMC EPIC/100", dev))
- return -EAGAIN;
-
- MOD_INC_USE_COUNT;
+ if (request_irq(dev->irq, &epic_interrupt, SA_SHIRQ, "SMC EPIC/100", dev)) {
+ MOD_DEC_USE_COUNT;
+ return -EBUSY;
+ }

epic_init_ring(dev);

@@ -581,8 +584,6 @@
set_rx_mode(dev);
outl(0x000A, ioaddr + COMMAND);

- netif_start_queue(dev);
-
/* Enable interrupts by setting the interrupt mask. */
outl((ep->chip_id == 6 ? PCIBusErr175 : PCIBusErr170)
| CntFull | TxUnderrun | TxDone
@@ -595,10 +596,12 @@
dev->name, ioaddr, dev->irq, inl(ioaddr + GENCTL),
ep->full_duplex ? "full" : "half");

+ netif_start_queue(dev);
+
/* Set the timer to switch to check for link beat and perhaps switch
to an alternate media type. */
init_timer(&ep->timer);
- ep->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */
+ ep->timer.expires = RUN_AT(3*HZ); /* 3 sec. */
ep->timer.data = (unsigned long)dev;
ep->timer.function = &epic_timer; /* timer handler */
add_timer(&ep->timer);
@@ -613,6 +616,8 @@
long ioaddr = dev->base_addr;
struct epic_private *ep = (struct epic_private *)dev->priv;

+ netif_stop_queue (dev);
+
/* Disable interrupts by clearing the interrupt mask. */
outl(0x00000000, ioaddr + INTMASK);
/* Stop the chip's Tx and Rx DMA processes. */
@@ -671,11 +676,13 @@
| CntFull | TxUnderrun | TxDone
| RxError | RxOverflow | RxFull | RxHeader | RxDone,
ioaddr + INTMASK);
+
+ netif_start_queue (dev);
+
printk(KERN_DEBUG "%s: epic_restart() done, cmd status %4.4x, ctl %4.4x"
" interrupt %4.4x.\n",
dev->name, inl(ioaddr + COMMAND), inl(ioaddr + GENCTL),
inl(ioaddr + INTSTAT));
- return;
}

static void epic_timer(unsigned long data)
@@ -738,7 +745,8 @@

dev->trans_start = jiffies;
ep->stats.tx_errors++;
- return;
+
+ netif_start_queue (dev);
}

/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
@@ -790,6 +798,8 @@
int entry;
u32 flag;

+ netif_stop_queue (dev);
+
/* Caution: the write order is important here, set the base address
with the "ownership" bits last. */

@@ -806,13 +816,10 @@

if (ep->cur_tx - ep->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
flag = 0x10; /* No interrupt */
- netif_start_queue(dev);
} else if (ep->cur_tx - ep->dirty_tx == TX_RING_SIZE/2) {
flag = 0x14; /* Tx-done intr. */
- netif_start_queue(dev);
} else if (ep->cur_tx - ep->dirty_tx < TX_RING_SIZE - 2) {
flag = 0x10; /* No Tx-done intr. */
- netif_start_queue(dev);
} else {
/* Leave room for two additional entries. */
flag = 0x14; /* Tx-done intr. */
@@ -826,6 +833,10 @@
outl(0x0004, dev->base_addr + COMMAND);

dev->trans_start = jiffies;
+
+ if (! ep->tx_full)
+ netif_start_queue (dev);
+
if (epic_debug > 4)
printk(KERN_DEBUG "%s: Queued Tx packet size %d to slot %d, "
"flag %2.2x Tx status %8.8x.\n",
@@ -895,7 +906,7 @@
}

/* Free the original skb. */
- DEV_FREE_SKB(ep->tx_skbuff[entry]);
+ dev_kfree_skb_irq(ep->tx_skbuff[entry]);
ep->tx_skbuff[entry] = 0;
}

@@ -912,8 +923,12 @@
dirty_tx > ep->cur_tx - TX_RING_SIZE + 2) {
/* The ring is no longer full, clear tbusy. */
ep->tx_full = 0;
- netif_wake_queue (dev);
}
+
+ if (ep->tx_full)
+ netif_stop_queue (dev);
+ else
+ netif_wake_queue (dev);

ep->dirty_tx = dirty_tx;
}
@@ -1073,12 +1088,12 @@
ep->rx_ring[i].buflength = 0;
ep->rx_ring[i].bufaddr = 0xBADF00D0; /* An invalid address. */
if (skb) {
- DEV_FREE_SKB(skb);
+ dev_kfree_skb(skb);
}
}
for (i = 0; i < TX_RING_SIZE; i++) {
if (ep->tx_skbuff[i])
- DEV_FREE_SKB(ep->tx_skbuff[i]);
+ dev_kfree_skb(ep->tx_skbuff[i]);
ep->tx_skbuff[i] = 0;
}

@@ -1224,13 +1239,14 @@
struct net_device *dev;
u16 dev_id;
u32 io;
- u8 bus, devfn, irq;
+ u8 irq;
struct pci_dev *pdev;

if (loc->bus != LOC_PCI) return NULL;
pdev = pci_find_slot (loc->b.pci.bus, loc->b.pci.devfn);
if (!pdev) return NULL;
- printk(KERN_DEBUG "epic_attach(bus %d, function %d)\n", bus, devfn);
+ printk(KERN_DEBUG "epic_attach(bus %d, function %d)\n",
+ pdev->bus->number, pdev->devfn);
io = pdev->resource[0].start;
irq = pdev->irq;
dev_id = pdev->device;
@@ -1241,7 +1257,7 @@
io == 0 ? "I/O address" : "IRQ");
return NULL;
}
- dev = epic_probe1(bus, devfn, io, irq, 2, -1);
+ dev = epic_probe1(pdev, io, irq, 2, -1);
if (dev) {
dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
strcpy(node->dev_name, dev->name);
\
 
 \ /
  Last update: 2005-03-22 13:56    [W:0.071 / U:0.124 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site