patch-2.3.99-pre6 linux/drivers/net/cs89x0.c
Next file: linux/drivers/net/de4x5.c
Previous file: linux/drivers/net/arcnet/com90io.c
Back to the patch index
Back to the overall index
- Lines: 201
- Date:
Fri Apr 14 09:37:10 2000
- Orig file:
v2.3.99-pre5/linux/drivers/net/cs89x0.c
- Orig date:
Tue Mar 7 14:32:26 2000
diff -u --recursive --new-file v2.3.99-pre5/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
@@ -48,10 +48,23 @@
: Don't call netif_wake_queue() in net_send_packet()
: Fixed an out-of-mem bug in dma_rx()
: Updated Documentation/cs89x0.txt
+
+ Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre1
+ : Use skb_reserve to longword align IP header (two places)
+ : Remove a delay loop from dma_rx()
+ : Replace '100' with HZ
+ : Clean up a couple of skb API abuses
+ : Added 'cs89x0_dma=N' kernel boot option
+ : Correctly initialise lp->lock in non-module compile
+
+ Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre4-1
+ : MOD_INC/DEC race fix (see
+ : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html)
+
*/
static char *version =
-"cs89x0.c: (kernel 2.3.48) Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n";
+"cs89x0.c: v2.3.99-pre1-2 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n";
/* ======================= end of configuration ======================= */
@@ -121,7 +134,7 @@
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
#if DEBUGGING
-static unsigned int net_debug = 5;
+static unsigned int net_debug = DEBUGGING;
#else
#define net_debug 0 /* gcc will remove all the debug code for us */
#endif
@@ -190,6 +203,21 @@
/* Example routines you must write ;->. */
#define tx_done(dev) 1
+/*
+ * Permit 'cs89x0_dma=N' in the kernel boot environment
+ */
+#if !defined(MODULE) && (ALLOW_DMA != 0)
+static int g_cs89x0_dma;
+
+static int __init dma_fn(char *str)
+{
+ g_cs89x0_dma = simple_strtol(str,NULL,0);
+ return 1;
+}
+
+__setup("cs89x0_dma=", dma_fn);
+#endif /* !defined(MODULE) && (ALLOW_DMA != 0) */
+
/* Check for a network adaptor of this type, and return '0' iff one exists.
If dev->base_addr == 0, probe all likely locations.
@@ -318,7 +346,17 @@
retval = ENOMEM;
goto out;
}
- memset(dev->priv, 0, sizeof(struct net_local));
+ lp = (struct net_local *)dev->priv;
+ memset(lp, 0, sizeof(*lp));
+ spin_lock_init(&lp->lock);
+#if !defined(MODULE) && (ALLOW_DMA != 0)
+ if (g_cs89x0_dma)
+ {
+ lp->use_dma = 1;
+ lp->dma = g_cs89x0_dma;
+ lp->dmasize = 16; /* Could make this an option... */
+ }
+#endif
}
lp = (struct net_local *)dev->priv;
@@ -612,12 +650,6 @@
int status, length;
unsigned char *bp = lp->rx_dma_ptr;
- {
- int i;
- for (i = 0; i < 1000; i++)
- ;
- }
-
status = bp[0] + (bp[1]<<8);
length = bp[2] + (bp[3]<<8);
bp += 4;
@@ -632,7 +664,7 @@
}
/* Malloc up new buffer. */
- skb = alloc_skb(length, GFP_ATOMIC);
+ skb = dev_alloc_skb(length + 2);
if (skb == NULL) {
if (net_debug) /* I don't think we want to do this to a stressed system */
printk("%s: Memory squeeze, dropping packet.\n", dev->name);
@@ -645,8 +677,7 @@
lp->rx_dma_ptr = bp;
return;
}
-
- skb->len = length;
+ skb_reserve(skb, 2); /* longword align L3 header */
skb->dev = dev;
if (bp + length > lp->end_dma_buff) {
@@ -720,7 +751,7 @@
writereg(dev, PP_SelfCTL, selfcontrol);
/* Wait for the DC/DC converter to power up - 500ms */
- while (jiffies - timenow < 100)
+ while (jiffies - timenow < HZ)
;
}
@@ -914,6 +945,9 @@
struct net_local *lp = (struct net_local *)dev->priv;
int result = 0;
int i;
+ int ret;
+
+ MOD_INC_USE_COUNT;
if (dev->irq < 2) {
/* Allow interrupts to be generated by the chip */
@@ -938,13 +972,15 @@
writereg(dev, PP_BusCTL, 0); /* disable interrupts. */
if (net_debug)
printk("cs89x0: can't get an interrupt\n");
- return -EAGAIN;
+ ret = -EAGAIN;
+ goto bad_out;
}
} else {
if (((1 << dev->irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
- return -EAGAIN;
+ ret = -EAGAIN;
+ goto bad_out;
}
/* FIXME: Cirrus' release had this: */
writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
@@ -956,7 +992,8 @@
if (request_irq(dev->irq, &net_interrupt, 0, "cs89x0", dev)) {
if (net_debug)
printk("cs89x0: request_irq(%d) failed\n", dev->irq);
- return -EAGAIN;
+ ret = -EAGAIN;
+ goto bad_out;
}
}
@@ -1032,7 +1069,8 @@
#endif
writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
free_irq(dev->irq, dev);
- return -EAGAIN;
+ ret = -EAGAIN;
+ goto bad_out;
}
/* set the hardware to the configured choice */
@@ -1125,11 +1163,13 @@
| dma_busctl(dev)
#endif
);
- MOD_INC_USE_COUNT;
netif_start_queue(dev);
if (net_debug)
printk("cs89x0: net_open() succeeded\n");
return 0;
+bad_out:
+ MOD_DEC_USE_COUNT;
+ return ret;
}
static void net_timeout(struct net_device *dev)
@@ -1317,7 +1357,7 @@
}
/* Malloc up new buffer. */
- skb = alloc_skb(length, GFP_ATOMIC);
+ skb = dev_alloc_skb(length + 2);
if (skb == NULL) {
#if 0 /* Again, this seems a cruel thing to do */
printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
@@ -1325,10 +1365,10 @@
lp->stats.rx_dropped++;
return;
}
- skb->len = length;
+ skb_reserve(skb, 2); /* longword align L3 header */
skb->dev = dev;
- insw(ioaddr + RX_FRAME_PORT, skb->data, length >> 1);
+ insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1);
if (length & 1)
skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)