diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-24 00:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-24 00:12:35 +0000 |
commit | 482368b1a8e45430672c58c9a42e7d2004367126 (patch) | |
tree | ce2a1a567d4d62dee7c2e71a46a99cf72cf1d606 /drivers/acorn | |
parent | e4d0251c6f56ab2e191afb70f80f382793e23f74 (diff) |
Merge with 2.3.47. Guys, this is buggy as shit. You've been warned.
Diffstat (limited to 'drivers/acorn')
-rw-r--r-- | drivers/acorn/block/fd1772.c | 8 | ||||
-rw-r--r-- | drivers/acorn/block/mfmhd.c | 6 | ||||
-rw-r--r-- | drivers/acorn/char/keyb_ps2.c | 3 | ||||
-rw-r--r-- | drivers/acorn/net/ether1.c | 214 | ||||
-rw-r--r-- | drivers/acorn/net/ether1.h | 7 | ||||
-rw-r--r-- | drivers/acorn/net/ether3.c | 224 | ||||
-rw-r--r-- | drivers/acorn/net/ether3.h | 9 | ||||
-rw-r--r-- | drivers/acorn/net/etherh.c | 61 |
8 files changed, 248 insertions, 284 deletions
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c index 54ed9ac6b..95836eb29 100644 --- a/drivers/acorn/block/fd1772.c +++ b/drivers/acorn/block/fd1772.c @@ -591,7 +591,7 @@ static void fd_error(void) { printk("FDC1772: fd_error\n"); /*panic("fd1772: fd_error"); *//* DAG tmp */ - if (!CURRENT) + if (QUEUE_EMPTY) return; CURRENT->errors++; if (CURRENT->errors >= MAX_ERRORS) { @@ -1230,14 +1230,14 @@ static void redo_fd_request(void) DPRINT(("redo_fd_request: CURRENT=%08lx CURRENT->rq_dev=%04x CURRENT->sector=%ld\n", (unsigned long) CURRENT, CURRENT ? CURRENT->rq_dev : 0, - CURRENT ? CURRENT->sector : 0)); + !QUEUE_EMPTY ? CURRENT->sector : 0)); - if (CURRENT && CURRENT->rq_status == RQ_INACTIVE) + if (!QUEUE_EMPTY && CURRENT->rq_status == RQ_INACTIVE) goto the_end; repeat: - if (!CURRENT) + if (QUEUE_EMPTY) goto the_end; if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c index d30251fbb..0d65a1493 100644 --- a/drivers/acorn/block/mfmhd.c +++ b/drivers/acorn/block/mfmhd.c @@ -758,7 +758,7 @@ static void request_done(int uptodate) /* No - its the end of the line */ /* end_request's should have happened at the end of sector DMAs */ /* Turns Drive LEDs off - may slow it down? */ - if (!CURRENT) + if (QUEUE_EMPTY) issue_command(CMD_CKV, block, 2); Busy = 0; @@ -891,7 +891,7 @@ static void mfm_request(void) { DBG("mfm_request CURRENT=%p Busy=%d\n", CURRENT, Busy); - if (!CURRENT) { + if (QUEUE_EMPTY) { DBG("mfm_request: Exited due to NULL Current 1\n"); return; } @@ -918,7 +918,7 @@ static void mfm_request(void) DBG("mfm_request: before INIT_REQUEST\n"); - if (!CURRENT) { + if (QUEUE_EMPTY) { printk("mfm_request: Exiting due to !CURRENT (pre)\n"); CLEAR_INTR; Busy = 0; diff --git a/drivers/acorn/char/keyb_ps2.c b/drivers/acorn/char/keyb_ps2.c index d915a4291..306feb2e9 100644 --- a/drivers/acorn/char/keyb_ps2.c +++ b/drivers/acorn/char/keyb_ps2.c @@ -28,6 +28,7 @@ #include <asm/iomd.h> #include <asm/system.h> +extern struct tasklet_struct keyboard_tasklet; extern void kbd_reset_kdown(void); int kbd_read_mask; @@ -318,7 +319,7 @@ static void ps2kbd_rx(int irq, void *dev_id, struct pt_regs *regs) while (inb(IOMD_KCTRL) & (1 << 5)) handle_rawcode(inb(IOMD_KARTRX)); - mark_bh(KEYBOARD_BH); + tasklet_schedule(&keyboard_tasklet); } static void ps2kbd_tx(int irq, void *dev_id, struct pt_regs *regs) diff --git a/drivers/acorn/net/ether1.c b/drivers/acorn/net/ether1.c index 5c8b0e26d..7a12ee4a9 100644 --- a/drivers/acorn/net/ether1.c +++ b/drivers/acorn/net/ether1.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/drivers/net/ether1.c * - * (C) Copyright 1996,1997,1998 Russell King + * (C) Copyright 1996-2000 Russell King * * Acorn ether1 driver (82586 chip) * for Acorn machines @@ -28,6 +28,7 @@ * TDR now only reports failure when chip reports non-zero * TDR time-distance. * 1.05 RMK 31/12/1997 Removed calls to dev_tint for 2.1 + * 1.06 RMK 10/02/2000 Updated for 2.3.43 */ #include <linux/module.h> @@ -64,9 +65,16 @@ static unsigned int net_debug = NET_DEBUG; #define RX_AREA_START 0x05000 #define RX_AREA_END 0x0fc00 -#define tx_done(dev) 0 +static int ether1_open(struct net_device *dev); +static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev); +static void ether1_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static int ether1_close(struct net_device *dev); +static struct enet_statistics *ether1_getstats(struct net_device *dev); +static void ether1_setmulticastlist(struct net_device *dev); +static void ether1_timeout(struct net_device *dev); + /* ------------------------------------------------------------------------- */ -static char *version = "ether1 ethernet driver (c) 1995 Russell King v1.05\n"; +static char *version = "ether1 ethernet driver (c) 2000 Russell King v1.06\n"; #define BUS_16 16 #define BUS_8 8 @@ -636,12 +644,12 @@ ether1_probe1(struct net_device *dev) if (net_debug && version_printed++ == 0) printk (KERN_INFO "%s", version); - printk (KERN_INFO "%s: ether1 found [%d, %04lx, %d]", dev->name, priv->bus_type, - dev->base_addr, dev->irq); - request_region (dev->base_addr, 16, "ether1"); request_region (dev->base_addr + 0x800, 4096, "ether1(ram)"); + printk (KERN_INFO "%s: ether1 at %lx, IRQ%d, ether address ", + dev->name, dev->base_addr, dev->irq); + for (i = 0; i < 6; i++) printk (i==0?" %02x":i==5?":%02x\n":":%02x", dev->dev_addr[i]); @@ -650,11 +658,13 @@ ether1_probe1(struct net_device *dev) return 1; } - dev->open = ether1_open; - dev->stop = ether1_close; + dev->open = ether1_open; + dev->stop = ether1_close; dev->hard_start_xmit = ether1_sendpacket; - dev->get_stats = ether1_getstats; + dev->get_stats = ether1_getstats; dev->set_multicast_list = ether1_setmulticastlist; + dev->tx_timeout = ether1_timeout; + dev->watchdog_timeo = 5 * HZ / 100; /* Fill in the fields of the device structure with ethernet values */ ether_setup (dev); @@ -727,38 +737,18 @@ ether1_txalloc (struct net_device *dev, int size) return start; } -static void -ether1_restart (struct net_device *dev, char *reason) -{ - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; - priv->stats.tx_errors ++; - - if (reason) - printk (KERN_WARNING "%s: %s - resetting device\n", dev->name, reason); - else - printk (" - resetting device\n"); - - ether1_reset (dev); - - dev->start = 0; - dev->tbusy = 0; - - if (ether1_init_for_open (dev)) - printk (KERN_ERR "%s: unable to restart interface\n", dev->name); - - dev->start = 1; -} - static int ether1_open (struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; - if (request_irq (dev->irq, ether1_interrupt, 0, "ether1", dev)) - return -EAGAIN; - MOD_INC_USE_COUNT; + if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev)) { + MOD_DEC_USE_COUNT; + return -EAGAIN; + } + memset (&priv->stats, 0, sizeof (struct enet_statistics)); if (ether1_init_for_open (dev)) { @@ -767,95 +757,94 @@ ether1_open (struct net_device *dev) return -EAGAIN; } - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; + netif_start_queue(dev); return 0; } -static int -ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) +static void +ether1_timeout(struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; - if (priv->restart) - ether1_restart (dev, NULL); - - if (dev->tbusy) { - /* - * If we get here, some higher level has decided that we are broken. - * There should really be a "kick me" function call instead. - */ - int tickssofar = jiffies - dev->trans_start; + printk(KERN_WARNING "%s: transmit timeout, network cable problem?\n", + dev->name); + printk(KERN_WARNING "%s: resetting device\n", dev->name); - if (tickssofar < 5) - return 1; - - /* Try to restart the adapter. */ - ether1_restart (dev, "transmit timeout, network cable problem?"); - dev->trans_start = jiffies; - } + ether1_reset (dev); - /* - * Block a timer-based transmit from overlapping. This could better be - * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. - */ - if (test_and_set_bit (0, (void *)&dev->tbusy) != 0) - printk (KERN_WARNING "%s: transmitter access conflict.\n", dev->name); - else { - int len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; - int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr; - unsigned long flags; - tx_t tx; - tbd_t tbd; - nop_t nop; - - /* - * insert packet followed by a nop - */ - txaddr = ether1_txalloc (dev, TX_SIZE); - tbdaddr = ether1_txalloc (dev, TBD_SIZE); - dataddr = ether1_txalloc (dev, len); - nopaddr = ether1_txalloc (dev, NOP_SIZE); - - tx.tx_status = 0; - tx.tx_command = CMD_TX | CMD_INTR; - tx.tx_link = nopaddr; - tx.tx_tbdoffset = tbdaddr; - tbd.tbd_opts = TBD_EOL | len; - tbd.tbd_link = I82586_NULL; - tbd.tbd_bufl = dataddr; - tbd.tbd_bufh = 0; - nop.nop_status = 0; - nop.nop_command = CMD_NOP; - nop.nop_link = nopaddr; + if (ether1_init_for_open (dev)) + printk (KERN_ERR "%s: unable to restart interface\n", dev->name); - save_flags_cli (flags); - ether1_writebuffer (dev, &tx, txaddr, TX_SIZE); - ether1_writebuffer (dev, &tbd, tbdaddr, TBD_SIZE); - ether1_writebuffer (dev, skb->data, dataddr, len); - ether1_writebuffer (dev, &nop, nopaddr, NOP_SIZE); - tmp = priv->tx_link; - priv->tx_link = nopaddr; + priv->stats.tx_errors++; + netif_wake_queue(dev); +} - /* now reset the previous nop pointer */ - ether1_outw (dev, txaddr, tmp, nop_t, nop_link, NORMALIRQS); +static int +ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) +{ + struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + int len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; + int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr; + unsigned long flags; + tx_t tx; + tbd_t tbd; + nop_t nop; - restore_flags (flags); + if (priv->restart) { + printk(KERN_WARNING "%s: resetting device\n", dev->name); - /* handle transmit */ - dev->trans_start = jiffies; + ether1_reset(dev); - /* check to see if we have room for a full sized ether frame */ - tmp = priv->tx_head; - tst = ether1_txalloc (dev, TX_SIZE + TBD_SIZE + NOP_SIZE + ETH_FRAME_LEN); - priv->tx_head = tmp; - if (tst != -1) - dev->tbusy = 0; + if (ether1_init_for_open(dev)) + printk(KERN_ERR "%s: unable to restart interface\n", dev->name); } + + /* + * insert packet followed by a nop + */ + txaddr = ether1_txalloc (dev, TX_SIZE); + tbdaddr = ether1_txalloc (dev, TBD_SIZE); + dataddr = ether1_txalloc (dev, len); + nopaddr = ether1_txalloc (dev, NOP_SIZE); + + tx.tx_status = 0; + tx.tx_command = CMD_TX | CMD_INTR; + tx.tx_link = nopaddr; + tx.tx_tbdoffset = tbdaddr; + tbd.tbd_opts = TBD_EOL | len; + tbd.tbd_link = I82586_NULL; + tbd.tbd_bufl = dataddr; + tbd.tbd_bufh = 0; + nop.nop_status = 0; + nop.nop_command = CMD_NOP; + nop.nop_link = nopaddr; + + save_flags_cli(flags); + ether1_writebuffer (dev, &tx, txaddr, TX_SIZE); + ether1_writebuffer (dev, &tbd, tbdaddr, TBD_SIZE); + ether1_writebuffer (dev, skb->data, dataddr, len); + ether1_writebuffer (dev, &nop, nopaddr, NOP_SIZE); + tmp = priv->tx_link; + priv->tx_link = nopaddr; + + /* now reset the previous nop pointer */ + ether1_outw (dev, txaddr, tmp, nop_t, nop_link, NORMALIRQS); + + restore_flags(flags); + + /* handle transmit */ + dev->trans_start = jiffies; + + /* check to see if we have room for a full sized ether frame */ + tmp = priv->tx_head; + tst = ether1_txalloc (dev, TX_SIZE + TBD_SIZE + NOP_SIZE + ETH_FRAME_LEN); + priv->tx_head = tmp; dev_kfree_skb (skb); + if (tst == -1) + netif_stop_queue(dev); + return 0; } @@ -957,9 +946,7 @@ again: tst = ether1_txalloc (dev, TX_SIZE + TBD_SIZE + NOP_SIZE + ETH_FRAME_LEN); priv->tx_head = caddr; if (tst != -1) - dev->tbusy = 0; - - mark_bh (NET_BH); + netif_wake_queue(dev); } static void @@ -1024,8 +1011,6 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs) struct ether1_priv *priv = (struct ether1_priv *)dev->priv; int status; - dev->interrupt = 1; - status = ether1_inw (dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS); if (status) { @@ -1065,8 +1050,6 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs) } } else outb (CTRL_ACK, REG_CONTROL); - - dev->interrupt = 0; } static int @@ -1076,9 +1059,6 @@ ether1_close (struct net_device *dev) free_irq(dev->irq, dev); - dev->start = 0; - dev->tbusy = 0; - MOD_DEC_USE_COUNT; return 0; @@ -1110,7 +1090,7 @@ ether1_setmulticastlist (struct net_device *dev) static struct ether_dev { struct expansion_card *ec; char name[9]; - struct net_device dev; + struct net_device dev; } ether_devs[MAX_ECARDS]; int diff --git a/drivers/acorn/net/ether1.h b/drivers/acorn/net/ether1.h index 53f2cd8bf..db64114f1 100644 --- a/drivers/acorn/net/ether1.h +++ b/drivers/acorn/net/ether1.h @@ -43,13 +43,6 @@ struct ether1_priv { unsigned char restart : 1; }; -static int ether1_open (struct net_device *dev); -static int ether1_sendpacket (struct sk_buff *skb, struct net_device *dev); -static void ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs); -static int ether1_close (struct net_device *dev); -static struct enet_statistics *ether1_getstats (struct net_device *dev); -static void ether1_setmulticastlist (struct net_device *dev); - #define I82586_NULL (-1) typedef struct { /* tdr */ diff --git a/drivers/acorn/net/ether3.c b/drivers/acorn/net/ether3.c index 3b30dc5b4..03cc064c4 100644 --- a/drivers/acorn/net/ether3.c +++ b/drivers/acorn/net/ether3.c @@ -36,9 +36,10 @@ * 1.14 RMK 07/01/1998 Added initial code for ETHERB addressing. * 1.15 RMK 30/04/1999 More fixes to the transmit routine for buggy * hardware. + * 1.16 RMK 10/02/2000 Updated for 2.3.43 */ -static char *version = "ether3 ethernet driver (c) 1995-1999 R.M.King v1.15\n"; +static char *version = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.16\n"; #include <linux/module.h> #include <linux/kernel.h> @@ -74,9 +75,17 @@ static const card_ids __init ether3_cids[] = { { 0xffff, 0xffff } }; -static void ether3_setmulticastlist(struct net_device *dev); -static int ether3_rx(struct net_device *dev, struct dev_priv *priv, unsigned int maxcnt); -static void ether3_tx(struct net_device *dev, struct dev_priv *priv); +static void ether3_setmulticastlist(struct net_device *dev); +static int ether3_rx(struct net_device *dev, struct dev_priv *priv, unsigned int maxcnt); +static void ether3_tx(struct net_device *dev, struct dev_priv *priv); +static int ether3_probe1 (struct net_device *dev); +static int ether3_open (struct net_device *dev); +static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); +static void ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs); +static int ether3_close (struct net_device *dev); +static struct enet_statistics *ether3_getstats (struct net_device *dev); +static void ether3_setmulticastlist (struct net_device *dev); +static void ether3_timeout(struct net_device *dev); #define BUS_16 2 #define BUS_8 1 @@ -406,6 +415,7 @@ ether3_probe1(struct net_device *dev) static unsigned version_printed = 0; struct dev_priv *priv; unsigned int i, bus_type, error = ENODEV; + const char *name = "ether3"; if (net_debug && version_printed++ == 0) printk(version); @@ -421,7 +431,7 @@ ether3_probe1(struct net_device *dev) priv = (struct dev_priv *) dev->priv; memset(priv, 0, sizeof(struct dev_priv)); - request_region(dev->base_addr, 128, "ether3"); + request_region(dev->base_addr, 128, name); /* Reset card... */ @@ -443,33 +453,38 @@ ether3_probe1(struct net_device *dev) switch (bus_type) { case BUS_UNKNOWN: - printk(KERN_ERR "%s: unable to identify podule bus width\n", dev->name); + printk(KERN_ERR "%s: unable to identify bus width\n", dev->name); goto failed; case BUS_8: - printk(KERN_ERR "%s: ether3 found, but is an unsupported 8-bit card\n", dev->name); + printk(KERN_ERR "%s: %s found, but is an unsupported " + "8-bit card\n", dev->name, name); goto failed; default: break; } - printk("%s: ether3 found at %lx, IRQ%d, ether address ", dev->name, dev->base_addr, dev->irq); + printk("%s: %s at %lx, IRQ%d, ether address ", + dev->name, name, dev->base_addr, dev->irq); for (i = 0; i < 6; i++) printk(i == 5 ? "%2.2x\n" : "%2.2x:", dev->dev_addr[i]); - if (!ether3_init_2(dev)) { - dev->open = ether3_open; - dev->stop = ether3_close; - dev->hard_start_xmit = ether3_sendpacket; - dev->get_stats = ether3_getstats; - dev->set_multicast_list = ether3_setmulticastlist; + if (ether3_init_2(dev)) + goto failed; - /* Fill in the fields of the device structure with ethernet values. */ - ether_setup(dev); + dev->open = ether3_open; + dev->stop = ether3_close; + dev->hard_start_xmit = ether3_sendpacket; + dev->get_stats = ether3_getstats; + dev->set_multicast_list = ether3_setmulticastlist; + dev->tx_timeout = ether3_timeout; + dev->watchdog_timeo = 5 * HZ / 100; - return 0; - } + /* Fill in the fields of the device structure with ethernet values. */ + ether_setup(dev); + + return 0; failed: kfree(dev->priv); @@ -535,12 +550,10 @@ ether3_open(struct net_device *dev) return -EAGAIN; } - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; - ether3_init_for_open(dev); + netif_start_queue(dev); + return 0; } @@ -552,8 +565,7 @@ ether3_close(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); disable_irq(dev->irq); @@ -602,6 +614,34 @@ static void ether3_setmulticastlist(struct net_device *dev) ether3_outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); } +static void +ether3_timeout(struct net_device *dev) +{ + struct dev_priv *priv = (struct dev_priv *)dev->priv; + unsigned long flags; + + del_timer(&priv->timer); + + save_flags_cli(flags); + printk(KERN_ERR "%s: transmit timed out, network cable problem?\n", dev->name); + printk(KERN_ERR "%s: state: { status=%04X cfg1=%04X cfg2=%04X }\n", dev->name, + ether3_inw(REG_STATUS), ether3_inw(REG_CONFIG1), ether3_inw(REG_CONFIG2)); + printk(KERN_ERR "%s: { rpr=%04X rea=%04X tpr=%04X }\n", dev->name, + ether3_inw(REG_RECVPTR), ether3_inw(REG_RECVEND), ether3_inw(REG_TRANSMITPTR)); + printk(KERN_ERR "%s: tx head=%X tx tail=%X\n", dev->name, + priv->tx_head, priv->tx_tail); + ether3_setbuffer(dev, buffer_read, priv->tx_tail); + printk(KERN_ERR "%s: packet status = %08X\n", dev->name, ether3_readlong(dev)); + restore_flags(flags); + + priv->regs.config2 |= CFG2_CTRLO; + priv->stats.tx_errors += 1; + ether3_outw(priv->regs.config2, REG_CONFIG2); + priv->tx_head = priv->tx_tail = 0; + + netif_wake_queue(dev); +} + /* * Transmit a packet */ @@ -609,102 +649,61 @@ static int ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; -retry: - if (!dev->tbusy) { - /* Block a timer-based transmit from overlapping. This could better be - * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. - */ - if (!test_and_set_bit(0, (void *)&dev->tbusy)) { - unsigned long flags; - unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - unsigned int ptr, next_ptr; - - length = (length + 1) & ~1; - - if (priv->broken) { - dev_kfree_skb(skb); - priv->stats.tx_dropped ++; - dev->tbusy = 0; - return 0; - } + unsigned long flags; + unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + unsigned int ptr, next_ptr; - next_ptr = (priv->tx_head + 1) & 15; + length = (length + 1) & ~1; - save_flags_cli(flags); + if (priv->broken) { + dev_kfree_skb(skb); + priv->stats.tx_dropped ++; + netif_start_queue(dev); + return 0; + } - if (priv->tx_tail == next_ptr) { - restore_flags(flags); - return 1; /* unable to queue */ - } + next_ptr = (priv->tx_head + 1) & 15; - dev->trans_start = jiffies; - ptr = 0x600 * priv->tx_head; - priv->tx_head = next_ptr; - next_ptr *= 0x600; + save_flags_cli(flags); -#define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS) + if (priv->tx_tail == next_ptr) { + restore_flags(flags); + return 1; /* unable to queue */ + } - ether3_setbuffer(dev, buffer_write, next_ptr); - ether3_writelong(dev, 0); - ether3_setbuffer(dev, buffer_write, ptr); - ether3_writelong(dev, 0); - ether3_writebuffer(dev, skb->data, length); - ether3_writeword(dev, htons(next_ptr)); - ether3_writeword(dev, TXHDR_CHAINCONTINUE >> 16); - ether3_setbuffer(dev, buffer_write, ptr); - ether3_writeword(dev, htons((ptr + length + 4))); - ether3_writeword(dev, TXHDR_FLAGS >> 16); - ether3_ledon(dev, priv); - - if (!(ether3_inw(REG_STATUS) & STAT_TXON)) { - ether3_outw(ptr, REG_TRANSMITPTR); - ether3_outw(priv->regs.command | CMD_TXON, REG_COMMAND); - } + dev->trans_start = jiffies; + ptr = 0x600 * priv->tx_head; + priv->tx_head = next_ptr; + next_ptr *= 0x600; - next_ptr = (priv->tx_head + 1) & 15; - if (priv->tx_tail != next_ptr) - dev->tbusy = 0; +#define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS) - restore_flags(flags); + ether3_setbuffer(dev, buffer_write, next_ptr); + ether3_writelong(dev, 0); + ether3_setbuffer(dev, buffer_write, ptr); + ether3_writelong(dev, 0); + ether3_writebuffer(dev, skb->data, length); + ether3_writeword(dev, htons(next_ptr)); + ether3_writeword(dev, TXHDR_CHAINCONTINUE >> 16); + ether3_setbuffer(dev, buffer_write, ptr); + ether3_writeword(dev, htons((ptr + length + 4))); + ether3_writeword(dev, TXHDR_FLAGS >> 16); + ether3_ledon(dev, priv); - dev_kfree_skb(skb); + if (!(ether3_inw(REG_STATUS) & STAT_TXON)) { + ether3_outw(ptr, REG_TRANSMITPTR); + ether3_outw(priv->regs.command | CMD_TXON, REG_COMMAND); + } - return 0; - } else { - printk("%s: transmitter access conflict.\n", dev->name); - return 1; - } - } else { - /* If we get here, some higher level has decided we are broken. - * There should really be a "kick me" function call instead. - */ - int tickssofar = jiffies - dev->trans_start; - unsigned long flags; + next_ptr = (priv->tx_head + 1) & 15; + restore_flags(flags); - if (tickssofar < 5) - return 1; - del_timer(&priv->timer); - - save_flags_cli(flags); - printk(KERN_ERR "%s: transmit timed out, network cable problem?\n", dev->name); - printk(KERN_ERR "%s: state: { status=%04X cfg1=%04X cfg2=%04X }\n", dev->name, - ether3_inw(REG_STATUS), ether3_inw(REG_CONFIG1), ether3_inw(REG_CONFIG2)); - printk(KERN_ERR "%s: { rpr=%04X rea=%04X tpr=%04X }\n", dev->name, - ether3_inw(REG_RECVPTR), ether3_inw(REG_RECVEND), ether3_inw(REG_TRANSMITPTR)); - printk(KERN_ERR "%s: tx head=%X tx tail=%X\n", dev->name, - priv->tx_head, priv->tx_tail); - ether3_setbuffer(dev, buffer_read, priv->tx_tail); - printk(KERN_ERR "%s: packet status = %08X\n", dev->name, ether3_readlong(dev)); - restore_flags(flags); + dev_kfree_skb(skb); - dev->tbusy = 0; - priv->regs.config2 |= CFG2_CTRLO; - priv->stats.tx_errors += 1; - ether3_outw(priv->regs.config2, REG_CONFIG2); - dev->trans_start = jiffies; - priv->tx_head = priv->tx_tail = 0; - goto retry; - } + if (priv->tx_tail == next_ptr) + netif_stop_queue(dev); + + return 0; } static void @@ -721,8 +720,6 @@ ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs) priv = (struct dev_priv *)dev->priv; - dev->interrupt = 1; - status = ether3_inw(REG_STATUS); if (status & STAT_INTRX) { @@ -735,8 +732,6 @@ ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs) ether3_tx(dev, priv); } - dev->interrupt = 0; - #if NET_DEBUG > 1 if(net_debug & DEBUG_INT) printk("done\n"); @@ -904,8 +899,7 @@ ether3_tx(struct net_device *dev, struct dev_priv *priv) if (priv->tx_tail != tx_tail) { priv->tx_tail = tx_tail; - dev->tbusy = 0; - mark_bh(NET_BH); /* Inform upper layers. */ + netif_wake_queue(dev); } } @@ -914,7 +908,7 @@ ether3_tx(struct net_device *dev, struct dev_priv *priv) static struct ether_dev { struct expansion_card *ec; char name[9]; - struct net_device dev; + struct net_device dev; } ether_devs[MAX_ECARDS]; int diff --git a/drivers/acorn/net/ether3.h b/drivers/acorn/net/ether3.h index ee4802b2d..45dfd82a1 100644 --- a/drivers/acorn/net/ether3.h +++ b/drivers/acorn/net/ether3.h @@ -159,13 +159,4 @@ struct dev_priv { int broken; /* 0 = ok, 1 = something went wrong */ }; -extern int ether3_probe (struct net_device *dev); -static int ether3_probe1 (struct net_device *dev); -static int ether3_open (struct net_device *dev); -static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); -static void ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs); -static int ether3_close (struct net_device *dev); -static struct enet_statistics *ether3_getstats (struct net_device *dev); -static void ether3_setmulticastlist (struct net_device *dev); - #endif diff --git a/drivers/acorn/net/etherh.c b/drivers/acorn/net/etherh.c index 0610005d1..71dcbbdbc 100644 --- a/drivers/acorn/net/etherh.c +++ b/drivers/acorn/net/etherh.c @@ -13,6 +13,7 @@ * RMK 1.03 Added support for EtherLan500 cards * 23-11-1997 RMK 1.04 Added media autodetection * 16-04-1998 RMK 1.05 Improved media autodetection + * 10-02-2000 RMK 1.06 Updated for 2.3.43 * * Insmod Module Parameters * ------------------------ @@ -61,7 +62,7 @@ static const card_ids __init etherh_cids[] = { MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("i3 EtherH driver"); -static char *version = "etherh [500/600/600A] ethernet driver (c) 1998 R.M.King v1.05\n"; +static char *version = "etherh [500/600/600A] ethernet driver (c) 2000 R.M.King v1.06\n"; #define ETHERH500_DATAPORT 0x200 /* MEMC */ #define ETHERH500_NS8390 0x000 /* MEMC */ @@ -190,8 +191,8 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf if (ei_status.dmaing) { printk ("%s: DMAing conflict in etherh_block_input: " - " DMAstat %d irqlock %d intr %ld\n", dev->name, - ei_status.dmaing, ei_status.irqlock, dev->interrupt); + " DMAstat %d irqlock %d\n", dev->name, + ei_status.dmaing, ei_status.irqlock); return; } @@ -248,8 +249,8 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int if (ei_status.dmaing) { printk ("%s: DMAing conflict in etherh_block_input: " - " DMAstat %d irqlock %d intr %ld\n", dev->name, - ei_status.dmaing, ei_status.irqlock, dev->interrupt); + " DMAstat %d irqlock %d\n", dev->name, + ei_status.dmaing, ei_status.irqlock); return; } @@ -287,8 +288,8 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p if (ei_status.dmaing) { printk ("%s: DMAing conflict in etherh_get_header: " - " DMAstat %d irqlock %d intr %ld\n", dev->name, - ei_status.dmaing, ei_status.irqlock, dev->interrupt); + " DMAstat %d irqlock %d\n", dev->name, + ei_status.dmaing, ei_status.irqlock); return; } @@ -359,6 +360,7 @@ etherh_probe1(struct net_device *dev) unsigned int addr, i, reg0, tmp; const char *dev_type; const char *if_type; + const char *name = "etherh"; addr = dev->base_addr; @@ -367,13 +369,13 @@ etherh_probe1(struct net_device *dev) switch (dev->mem_end) { case PROD_I3_ETHERLAN500: - dev_type = "500 "; + dev_type = "500"; break; case PROD_I3_ETHERLAN600: - dev_type = "600 "; + dev_type = "600"; break; case PROD_I3_ETHERLAN600A: - dev_type = "600A "; + dev_type = "600A"; break; default: dev_type = ""; @@ -382,7 +384,8 @@ etherh_probe1(struct net_device *dev) reg0 = inb (addr); if (reg0 == 0xff) { if (net_debug & DEBUG_INIT) - printk ("%s: etherh error: NS8390 command register wrong\n", dev->name); + printk("%s: %s error: NS8390 command register wrong\n", + dev->name, name); return -ENODEV; } @@ -393,34 +396,35 @@ etherh_probe1(struct net_device *dev) inb (addr + EN0_COUNTER0); if (inb (addr + EN0_COUNTER0) != 0) { if (net_debug & DEBUG_INIT) - printk ("%s: etherh error: NS8390 not found\n", dev->name); + printk("%s: %s error: NS8390 not found\n", + dev->name, name); outb (reg0, addr); outb (tmp, addr + 13); return -ENODEV; } - if (ethdev_init (dev)) + if (ethdev_init(dev)) return -ENOMEM; - request_region (addr, 16, "etherh"); + request_region(addr, 16, name); - printk("%s: etherh %sfound at %lx, IRQ%d, ether address ", - dev->name, dev_type, dev->base_addr, dev->irq); + printk("%s: %s %s at %lx, IRQ%d, ether address ", + dev->name, name, dev_type, dev->base_addr, dev->irq); for (i = 0; i < 6; i++) printk (i == 5 ? "%2.2x " : "%2.2x:", dev->dev_addr[i]); - ei_status.name = "etherh"; - ei_status.word16 = 1; - ei_status.tx_start_page = ETHERH_TX_START_PAGE; - ei_status.rx_start_page = ei_status.tx_start_page + TX_PAGES; - ei_status.stop_page = ETHERH_STOP_PAGE; - ei_status.reset_8390 = etherh_reset; - ei_status.block_input = etherh_block_input; - ei_status.block_output = etherh_block_output; - ei_status.get_8390_hdr = etherh_get_header; - dev->open = etherh_open; - dev->stop = etherh_close; + ei_status.name = name; + ei_status.word16 = 1; + ei_status.tx_start_page = ETHERH_TX_START_PAGE; + ei_status.rx_start_page = ei_status.tx_start_page + TX_PAGES; + ei_status.stop_page = ETHERH_STOP_PAGE; + ei_status.reset_8390 = etherh_reset; + ei_status.block_input = etherh_block_input; + ei_status.block_output = etherh_block_output; + ei_status.get_8390_hdr = etherh_get_header; + dev->open = etherh_open; + dev->stop = etherh_close; /* select 10bT */ ei_status.interface_num = 0; @@ -567,7 +571,8 @@ init_all_cards(void) my_ethers[i] = dev; if (register_netdev(dev) != 0) { - printk (KERN_WARNING "No etherh card found at %08lX\n", dev->base_addr); + printk(KERN_ERR "No etherh card found at %08lX\n", + dev->base_addr); if (ec[i]) { ecard_release(ec[i]); ec[i] = NULL; |