patch-2.4.23 linux-2.4.23/drivers/net/wan/n2.c
Next file: linux-2.4.23/drivers/net/wan/sdla_chdlc.c
Previous file: linux-2.4.23/drivers/net/wan/lmc/lmc_proto.c
Back to the patch index
Back to the overall index
- Lines: 246
- Date:
2003-11-28 10:26:20.000000000 -0800
- Orig file:
linux-2.4.22/drivers/net/wan/n2.c
- Orig date:
2003-06-13 07:51:35.000000000 -0700
diff -urN linux-2.4.22/drivers/net/wan/n2.c linux-2.4.23/drivers/net/wan/n2.c
@@ -1,12 +1,11 @@
/*
* SDL Inc. RISCom/N2 synchronous serial card driver for Linux
*
- * Copyright (C) 1998-2002 Krzysztof Halasa <khc@pm.waw.pl>
+ * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl>
*
* This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
*
* For information see http://hq.pm.waw.pl/hdlc/
*
@@ -34,14 +33,21 @@
#include "hd64570.h"
-static const char* version = "SDL RISCom/N2 driver version: 1.10";
+static const char* version = "SDL RISCom/N2 driver version: 1.14";
static const char* devname = "RISCom/N2";
#define USE_WINDOWSIZE 16384
#define USE_BUS16BITS 1
#define CLOCK_BASE 9830400 /* 9.8304 MHz */
-
+#define MAX_PAGES 16 /* 16 RAM pages at max */
+#define MAX_RAM_SIZE 0x80000 /* 512 KB */
+#if MAX_RAM_SIZE > MAX_PAGES * USE_WINDOWSIZE
+#undef MAX_RAM_SIZE
+#define MAX_RAM_SIZE (MAX_PAGES * USE_WINDOWSIZE)
+#endif
#define N2_IOPORTS 0x10
+#define NEED_DETECT_RAM
+#define MAX_TX_BUFFERS 10
static char *hw = NULL; /* pointer to hw=xxx command line string */
@@ -86,16 +92,16 @@
struct card_s *card;
spinlock_t lock; /* TX lock */
sync_serial_settings settings;
+ int valid; /* port enabled */
+ int rxpart; /* partial frame received, next frame invalid*/
unsigned short encoding;
unsigned short parity;
+ u16 rxin; /* rx ring buffer 'in' pointer */
+ u16 txin; /* tx ring buffer 'in' and 'last' pointers */
+ u16 txlast;
u8 rxs, txs, tmc; /* SCA registers */
- u8 valid; /* port enabled */
u8 phy_node; /* physical port # - 0 or 1 */
u8 log_node; /* logical port # */
- u8 rxin; /* rx ring buffer 'in' pointer */
- u8 txin; /* tx ring buffer 'in' and 'last' pointers */
- u8 txlast;
- u8 rxpart; /* partial frame received, next frame invalid*/
}port_t;
@@ -106,8 +112,9 @@
u32 ram_size; /* number of bytes */
u16 io; /* IO Base address */
u16 buff_offset; /* offset of first buffer of first channel */
+ u16 rx_ring_buffers; /* number of buffers in a ring */
+ u16 tx_ring_buffers;
u8 irq; /* IRQ (3-15) */
- u8 ring_buffers; /* number of buffers in a ring */
port_t ports[2];
struct card_s *next_card;
@@ -216,7 +223,7 @@
MOD_INC_USE_COUNT;
mcr &= port->phy_node ? ~DTR_PORT1 : ~DTR_PORT0; /* set DTR ON */
outb(mcr, io + N2_MCR);
-
+
outb(inb(io + N2_PCR) | PCR_ENWIN, io + N2_PCR); /* open window */
outb(inb(io + N2_PSR) | PSR_DMAEN, io + N2_PSR); /* enable dma */
sca_open(hdlc);
@@ -297,62 +304,6 @@
-static u8 n2_count_page(card_t *card)
-{
- u8 page;
- int i, bcount = USE_WINDOWSIZE, wcount = USE_WINDOWSIZE/2;
- u16 *dp = (u16*)card->winbase;
- u8 *bp = (u8*)card->winbase;
- u8 psr = inb(card->io + N2_PSR) & PSR_WINBITS;
-
-
- for (page = 0; page < 16; page++) {
- outb(psr | page, card->io + N2_PSR); /* select a page */
- writeb(page, dp);
- if (readb(dp) != page)
- break; /* If can't read back, no good memory */
-
- outb(psr, card->io + N2_PSR); /* goto page 0 */
- if (readb(dp))
- break; /* If page 0 changed, then wrapped around */
-
- outb(psr | page, card->io + N2_PSR); /* select page again */
-
- /* first do byte tests */
- for (i = 0; i < bcount; i++)
- writeb(i, bp + i);
- for (i = 0; i < bcount; i++)
- if (readb(bp + i) != (i & 0xff))
- return 0;
-
- for (i = 0; i < bcount; i++)
- writeb(~i, bp + i);
- for (i = 0; i < bcount; i++)
- if (readb(bp + i) != (~i & 0xff))
- return 0;
-
- /* next do 16-bit tests */
- for (i = 0; i < wcount; i++)
- writew(0x55AA, dp + i);
- for (i = 0; i < wcount; i++)
- if (readw(dp + i) != 0x55AA)
- return 0;
-
- for (i = 0; i < wcount; i++)
- writew(0xAA55, dp + i);
- for (i = 0; i < wcount; i++)
- if (readw(dp + i) != 0xAA55)
- return 0;
-
- for (i = 0; i < wcount; i++)
- writew(page, dp + i);
- }
-
- return page;
-}
-
-
-
static void n2_destroy_card(card_t *card)
{
int cnt;
@@ -376,11 +327,12 @@
-static int n2_run(unsigned long io, unsigned long irq, unsigned long winbase,
- long valid0, long valid1)
+static int __init n2_run(unsigned long io, unsigned long irq,
+ unsigned long winbase, long valid0, long valid1)
{
card_t *card;
u8 cnt, pcr;
+ int i;
if (io < 0x200 || io > 0x3FF || (io % N2_IOPORTS) != 0) {
printk(KERN_ERR "n2: invalid I/O port value\n");
@@ -391,7 +343,7 @@
printk(KERN_ERR "n2: invalid IRQ value\n");
return -ENODEV;
}
-
+
if (winbase < 0xA0000 || winbase > 0xFFFFF || (winbase & 0xFFF) != 0) {
printk(KERN_ERR "n2: invalid RAM value\n");
return -ENODEV;
@@ -451,25 +403,27 @@
pcr = PCR_ENWIN | PCR_VPM | (USE_BUS16BITS ? PCR_BUS16 : 0);
outb(pcr, io + N2_PCR);
- cnt = n2_count_page(card);
- if (!cnt) {
- printk(KERN_ERR "n2: memory test failed.\n");
- n2_destroy_card(card);
- return -EIO;
- }
+ card->ram_size = sca_detect_ram(card, card->winbase, MAX_RAM_SIZE);
- card->ram_size = cnt * USE_WINDOWSIZE;
+ /* number of TX + RX buffers for one port */
+ i = card->ram_size / ((valid0 + valid1) * (sizeof(pkt_desc) +
+ HDLC_MAX_MRU));
- /* 4 rings required for 2 ports, 2 rings for one port */
- card->ring_buffers = card->ram_size /
- ((valid0 + valid1) * 2 * (sizeof(pkt_desc) + HDLC_MAX_MRU));
+ card->tx_ring_buffers = min(i / 2, MAX_TX_BUFFERS);
+ card->rx_ring_buffers = i - card->tx_ring_buffers;
- card->buff_offset = (valid0 + valid1) * 2 * (sizeof(pkt_desc))
- * card->ring_buffers;
+ card->buff_offset = (valid0 + valid1) * sizeof(pkt_desc) *
+ (card->tx_ring_buffers + card->rx_ring_buffers);
printk(KERN_DEBUG "n2: RISCom/N2 %u KB RAM, IRQ%u, "
- "using %u packets rings\n", card->ram_size / 1024, card->irq,
- card->ring_buffers);
+ "using %u TX + %u RX packets rings\n", card->ram_size / 1024,
+ card->irq, card->tx_ring_buffers, card->rx_ring_buffers);
+
+ if (card->tx_ring_buffers < 1) {
+ printk(KERN_ERR "n2: RAM test failed\n");
+ n2_destroy_card(card);
+ return -EIO;
+ }
pcr |= PCR_RUNSCA; /* run SCA */
outb(pcr, io + N2_PCR);
@@ -531,7 +485,7 @@
return -ENOSYS; /* no parameters specified, abort */
}
- printk(KERN_INFO "%s (SCA-%s)\n", version, sca_version);
+ printk(KERN_INFO "%s\n", version);
do {
unsigned long io, irq, ram;
@@ -558,7 +512,7 @@
break;
hw++;
}
-
+
if (!valid[0] && !valid[1])
break; /* at least one port must be used */
@@ -566,7 +520,7 @@
n2_run(io, irq, ram, valid[0], valid[1]);
if (*hw == '\x0')
- return 0;
+ return first_card ? 0 : -ENOSYS;
}while(*hw++ == ':');
printk(KERN_ERR "n2: invalid hardware parameters\n");
@@ -602,6 +556,6 @@
MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
MODULE_DESCRIPTION("RISCom/N2 serial port driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_PARM(hw, "s"); /* hw=io,irq,ram,ports:io,irq,... */
EXPORT_NO_SYMBOLS;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)