lkml.org 
[lkml]   [1999]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
SubjectUpdate to 2.3.28's serial driver
From
Hi Linus,

Enclosed please find an update to the serial driver. I'd appreciate it
if you would apply this to your sources. Enhancements here include:

* Removal of backwards compatibility gunk for compiling this
driver with older kernel versions. (For people who wish to
use this driver with older kernels, they should grab the
stand-alone serial driver, found at my serial web page
<http://web.mit.edu/tytso/www/linux/serial>.)

This should make Linus happy since none of the compatibility
gunk is in his tree; it's been moved out to serial_compat.h in
the stand-alone driver distribution.

* Add support for using the magic sysreq feature when using a
serial console; it is accessed using by an RS-232 break
signal.

* Add support for a number of new PCI serial boards, including
from SIIG, Chase Research, and Computune.

* Add support for GSC-bus attached serial devices (for the HP
PA-RISC port).

* Some UART's lock up when the 16C950 test writes to the LSR
register. Move the 16C950 test after the StarTech test to
avoid locking up these older UART's.

* request_irq() is now passed a non-NULL dev_id, to facilitate
sharing IRQ's.

Thanks!!

- Ted


Patch generated: on Wed Nov 17 15:03:45 EST 1999 by tytso@universal.thunk.org
against Linux version 2.3.28

===================================================================
RCS file: drivers/char/RCS/serial.c,v
retrieving revision 1.1
diff -u -r1.1 drivers/char/serial.c
--- drivers/char/serial.c 1999/11/17 03:03:11 1.1
+++ drivers/char/serial.c 1999/11/17 20:03:06
@@ -44,6 +44,9 @@
* int rs_init(void);
*/

+static char *serial_version = "4.91";
+static char *serial_revdate = "1999-11-17";
+
/*
* Serial driver configuration section. Here are the various options:
*
@@ -88,8 +91,13 @@

#if (defined(CONFIG_PCI) && (LINUX_VERSION_CODE >= 131072))
#define ENABLE_SERIAL_PCI
+#ifndef CONFIG_SERIAL_SHARE_IRQ
#define CONFIG_SERIAL_SHARE_IRQ
#endif
+#ifndef CONFIG_SERIAL_MANY_PORTS
+#define CONFIG_SERIAL_MANY_PORTS
+#endif
+#endif

/* Set of debugging defines */

@@ -98,6 +106,7 @@
#undef SERIAL_DEBUG_FLOW
#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
#undef SERIAL_DEBUG_PCI
+#undef SERIAL_DEBUG_AUTOCONF

/* Sanity checks */

@@ -119,10 +128,9 @@
#define RS_STROBE_TIME (10*HZ)
#define RS_ISR_PASS_LIMIT 256

-#define IRQ_T(state) \
- ((state->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
-
+#if (defined(__i386__) && (CPU==386 || CPU==486))
#define SERIAL_INLINE
+#endif

#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
@@ -146,12 +154,14 @@
#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif
+#include <linux/module.h>
#else /* !NEW_MODULES */
#ifdef MODVERSIONS
#define MODULE
#endif
-#endif /* NEW_MODULES */
#include <linux/module.h>
+#endif /* NEW_MODULES */
+
#include <linux/types.h>
#ifdef LOCAL_HEADERS
#include "serial_local.h"
@@ -160,7 +170,7 @@
#include <linux/serialP.h>
#include <linux/serial_reg.h>
#include <asm/serial.h>
-static char *serial_version = "4.30";
+#define LOCAL_VERSTRING ""
#endif

#include <linux/errno.h>
@@ -177,10 +187,11 @@
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/malloc.h>
-#if (LINUX_VERSION_CODE >= 131343) /* 2.1.15 -- XX get correct version */
+#if (LINUX_VERSION_CODE >= 131343)
#include <linux/init.h>
-#else
-#define __initfunc(x) x
+#endif
+#if (LINUX_VERSION_CODE >= 131336)
+#include <asm/uaccess.h>
#endif
#include <linux/delay.h>
#ifdef CONFIG_SERIAL_CONSOLE
@@ -190,6 +201,14 @@
#include <linux/pci.h>
#endif

+/*
+ * All of the compatibilty code so we can compile serial.c against
+ * older kernels is hidden in serial_compat.h
+ */
+#if (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
+#include "serial_compat.h"
+#endif
+
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -203,6 +222,8 @@

#ifdef SERIAL_INLINE
#define _INLINE_ inline
+#else
+#define _INLINE_
#endif

static char *serial_name = "Serial driver";
@@ -233,6 +254,7 @@
static int IRQ_timeout[NR_IRQS];
#ifdef CONFIG_SERIAL_CONSOLE
static struct console sercons;
+static unsigned long break_pressed; /* break, really ... */
#endif

static unsigned detect_uart_irq (struct serial_state * state);
@@ -274,7 +296,11 @@
#define NR_PCI_BOARDS 8
static struct pci_board_inst serial_pci_board[NR_PCI_BOARDS];
static int serial_pci_board_idx = 0;
+#ifdef PCI_NUM_RESOURCES
#define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start)
+#else
+#define PCI_BASE_ADDRESS(dev, r) ((dev)->base_address[r])
+#endif
#endif /* ENABLE_SERIAL_PCI */

static struct tty_struct *serial_table[NR_PORTS];
@@ -301,87 +327,6 @@
static struct semaphore tmp_buf_sem = MUTEX;
#endif

-/*
- * Provide backwards compatibility for kernels prior to 2.1.XX.
- */
-#if (LINUX_VERSION_CODE < 0x20000)
-typedef dev_t kdev_t;
-#endif
-
-#if (LINUX_VERSION_CODE < 0x02017E)
-static signed long schedule_timeout(signed long timeout)
-{
- unsigned long expire;
-
- expire = timeout + jiffies;
-
- current->timeout = jiffies + timeout;
- schedule();
-
- timeout = expire - jiffies;
- return timeout < 0 ? 0 : timeout;
-}
-#endif
-
-#ifndef time_after
-#define time_after(a,b) ((long)(b) - (long)(a) < 0)
-#endif
-
-#if (LINUX_VERSION_CODE < 0x020100)
-static inline int irq_cannonicalize(int irq)
-{
- return ((irq == 2) ? 9 : irq);
-}
-#endif
-
-#if (LINUX_VERSION_CODE < 131336)
-static int copy_from_user(void *to, const void *from_user, unsigned long len)
-{
- int error;
-
- error = verify_area(VERIFY_READ, from_user, len);
- if (error)
- return len;
- memcpy_fromfs(to, from_user, len);
- return 0;
-}
-
-static int copy_to_user(void *to_user, const void *from, unsigned long len)
-{
- int error;
-
- error = verify_area(VERIFY_WRITE, to_user, len);
- if (error)
- return len;
- memcpy_tofs(to_user, from, len);
- return 0;
-}
-
-static inline int signal_pending(struct task_struct *p)
-{
- return (p->signal & (~p->blocked != 0));
-}
-
-#else
-#include <asm/uaccess.h>
-#endif
-
-#ifdef CAP_SYS_ADMIN
-#define serial_isroot() (capable(CAP_SYS_ADMIN))
-#else
-#define serial_isroot() (suser())
-#endif
-
-#if (LINUX_VERSION_CODE < 131394) /* 2.1.66 */
-#define test_and_clear_bit(x,y) clear_bit(x,y)
-
-static inline void remove_bh(int nr)
-{
- bh_base[nr] = NULL;
- bh_mask &= ~(1 << nr);
-}
-#endif
-

static inline int serial_paranoia_check(struct async_struct *info,
kdev_t device, const char *routine)
@@ -404,78 +349,63 @@
return 0;
}

-static inline unsigned int serial_in(struct async_struct *info, int offset)
+static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
{
+ switch (info->io_type) {
#ifdef CONFIG_HUB6
- if (info->hub6) {
- outb(info->hub6 - 1 + offset, info->port);
- return inb(info->port+1);
- } else
+ case SERIAL_IO_HUB6:
+ outb(info->hub6 - 1 + offset, info->port);
+ return inb(info->port+1);
#endif
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
- if (info->iomem_base)
- return readb(info->iomem_base + (offset<<info->iomem_reg_shift));
- else
+ case SERIAL_IO_MEM:
+ return readb(info->iomem_base +
+ (offset<<info->iomem_reg_shift));
+#endif
+#ifdef CONFIG_SERIAL_GSC
+ case SERIAL_IO_GSC:
+ return gsc_readb(info->iomem_base + offset);
#endif
- return inb(info->port + offset);
+ default:
+ return inb(info->port + offset);
+ }
}

-static inline unsigned int serial_inp(struct async_struct *info, int offset)
+static _INLINE_ void serial_out(struct async_struct *info, int offset,
+ int value)
{
+ switch (info->io_type) {
#ifdef CONFIG_HUB6
- if (info->hub6) {
- outb(info->hub6 - 1 + offset, info->port);
- return inb_p(info->port+1);
- } else
+ case SERIAL_IO_HUB6:
+ outb(info->hub6 - 1 + offset, info->port);
+ outb(value, info->port+1);
+ break;
#endif
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
- if (info->iomem_base)
- return readb(info->iomem_base + (offset<<info->iomem_reg_shift));
- else
+ case SERIAL_IO_MEM:
+ writeb(value, info->iomem_base +
+ (offset<<info->iomem_reg_shift));
+ break;
#endif
-#ifdef CONFIG_SERIAL_NOPAUSE_IO
- return inb(info->port + offset);
-#else
- return inb_p(info->port + offset);
+#ifdef CONFIG_SERIAL_GSC
+ case SERIAL_IO_GSC:
+ gsc_writeb(value, info->iomem_base + offset);
+ break;
#endif
+ default:
+ outb(value, info->port+offset);
+ }
}

-static inline void serial_out(struct async_struct *info, int offset, int value)
-{
-#ifdef CONFIG_HUB6
- if (info->hub6) {
- outb(info->hub6 - 1 + offset, info->port);
- outb(value, info->port+1);
- } else
-#endif
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
- if (info->iomem_base)
- writeb(value, info->iomem_base + (offset<<info->iomem_reg_shift));
- else
-#endif
- outb(value, info->port+offset);
-}
+/*
+ * We used to support using pause I/O for certain machines. We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(info, offset) serial_in(info, offset)
+#define serial_outp(info, offset, value) serial_out(info, offset, value)

-static inline void serial_outp(struct async_struct *info, int offset,
- int value)
-{
-#ifdef CONFIG_HUB6
- if (info->hub6) {
- outb(info->hub6 - 1 + offset, info->port);
- outb_p(value, info->port+1);
- } else
-#endif
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
- if (info->iomem_base)
- writeb(value, info->iomem_base + (offset<<info->iomem_reg_shift));
- else
-#endif
-#ifdef CONFIG_SERIAL_NOPAUSE_IO
- outb(value, info->port+offset);
-#else
- outb_p(value, info->port+offset);
-#endif
-}

/*
* For the 16C950
@@ -579,7 +509,7 @@
}

static _INLINE_ void receive_chars(struct async_struct *info,
- int *status)
+ int *status, struct pt_regs * regs)
{
struct tty_struct *tty = info->tty;
unsigned char ch;
@@ -590,7 +520,7 @@
do {
ch = serial_inp(info, UART_RX);
if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- break;
+ goto ignore_char;
*tty->flip.char_buf_ptr = ch;
icount->rx++;

@@ -629,6 +559,15 @@
#ifdef SERIAL_DEBUG_INTR
printk("handling break....");
#endif
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+ if (info->line == sercons.index) {
+ if (!break_pressed) {
+ break_pressed = jiffies;
+ goto ignore_char;
+ }
+ break_pressed = 0;
+ }
+#endif
*tty->flip.flag_buf_ptr = TTY_BREAK;
if (info->flags & ASYNC_SAK)
do_SAK(tty);
@@ -642,14 +581,25 @@
* reported immediately, and doesn't
* affect the current character
*/
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- tty->flip.count++;
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- *tty->flip.flag_buf_ptr = TTY_OVERRUN;
- }
+ tty->flip.count++;
+ tty->flip.flag_buf_ptr++;
+ tty->flip.char_buf_ptr++;
+ *tty->flip.flag_buf_ptr = TTY_OVERRUN;
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+ goto ignore_char;
+ }
+ }
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+ if (break_pressed && info->line == sercons.index) {
+ if (ch != 0 &&
+ time_before(jiffies, break_pressed + HZ*5)) {
+ handle_sysrq(ch, regs, NULL, NULL);
+ break_pressed = 0;
+ goto ignore_char;
}
+ break_pressed = 0;
}
+#endif
tty->flip.flag_buf_ptr++;
tty->flip.char_buf_ptr++;
tty->flip.count++;
@@ -819,7 +769,7 @@
printk("status = %x...", status);
#endif
if (status & UART_LSR_DR)
- receive_chars(info, &status);
+ receive_chars(info, &status, regs);
check_modem_status(info);
if (status & UART_LSR_THRE)
transmit_chars(info, 0);
@@ -883,7 +833,7 @@
printk("status = %x...", status);
#endif
if (status & UART_LSR_DR)
- receive_chars(info, &status);
+ receive_chars(info, &status, regs);
check_modem_status(info);
if (status & UART_LSR_THRE)
transmit_chars(info, 0);
@@ -946,7 +896,7 @@
printk("status = %x...", status);
#endif
if (status & UART_LSR_DR)
- receive_chars(info, &status);
+ receive_chars(info, &status, regs);
check_modem_status(info);
if (status & UART_LSR_THRE)
transmit_chars(info, 0);
@@ -1041,7 +991,7 @@
unsigned long flags;

if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
- for (i=1; i < NR_IRQS; i++) {
+ for (i=0; i < NR_IRQS; i++) {
info = IRQ_ports[i];
if (!info)
continue;
@@ -1228,7 +1178,7 @@
*/
if (serial_inp(info, UART_LSR) == 0xff) {
printk("LSR safety check engaged!\n");
- if (serial_isroot()) {
+ if (capable(CAP_SYS_ADMIN)) {
if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
} else
@@ -1243,7 +1193,7 @@
!IRQ_ports[state->irq]->next_port)) {
if (IRQ_ports[state->irq]) {
#ifdef CONFIG_SERIAL_SHARE_IRQ
- free_irq(state->irq, NULL);
+ free_irq(state->irq, &IRQ_ports[state->irq]);
#ifdef CONFIG_SERIAL_MULTIPORT
if (rs_multiport[state->irq].port1)
handler = rs_interrupt_multi;
@@ -1257,10 +1207,10 @@
} else
handler = rs_interrupt_single;

- retval = request_irq(state->irq, handler, IRQ_T(state),
- "serial", NULL);
+ retval = request_irq(state->irq, handler, SA_SHIRQ,
+ "serial", &IRQ_ports[state->irq]);
if (retval) {
- if (serial_isroot()) {
+ if (capable(CAP_SYS_ADMIN)) {
if (info->tty)
set_bit(TTY_IO_ERROR,
&info->tty->flags);
@@ -1409,15 +1359,16 @@
if (state->irq && (!IRQ_ports[state->irq] ||
!IRQ_ports[state->irq]->next_port)) {
if (IRQ_ports[state->irq]) {
- free_irq(state->irq, NULL);
+ free_irq(state->irq, &IRQ_ports[state->irq]);
retval = request_irq(state->irq, rs_interrupt_single,
- IRQ_T(state), "serial", NULL);
+ SA_SHIRQ, "serial",
+ &IRQ_ports[state->irq]);

if (retval)
printk("serial shutdown: request_irq: error %d"
" Couldn't reacquire IRQ.\n", retval);
} else
- free_irq(state->irq, NULL);
+ free_irq(state->irq, &IRQ_ports[state->irq]);
}

if (info->xmit_buf) {
@@ -1445,8 +1396,11 @@
serial_outp(info, UART_MCR, info->MCR);

/* disable FIFO's */
- serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
+ serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
+ UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT));
+ serial_outp(info, UART_FCR, 0);
+
(void)serial_in(info, UART_RX); /* read data port to reset things */

if (info->tty)
@@ -1922,6 +1876,7 @@
tmp.closing_wait = state->closing_wait;
tmp.custom_divisor = state->custom_divisor;
tmp.hub6 = state->hub6;
+ tmp.io_type = state->io_type;
if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
return -EFAULT;
return 0;
@@ -1944,7 +1899,7 @@
change_port = (new_serial.port != state->port) ||
(new_serial.hub6 != state->hub6);

- if (!serial_isroot()) {
+ if (!capable(CAP_SYS_ADMIN)) {
if (change_irq || change_port ||
(new_serial.baud_base != state->baud_base) ||
(new_serial.type != state->type) ||
@@ -1963,7 +1918,7 @@

new_serial.irq = irq_cannonicalize(new_serial.irq);

- if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) ||
+ if ((new_serial.irq >= NR_IRQS) ||
(new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
(new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
(new_serial.type == PORT_STARTECH)) {
@@ -1973,7 +1928,7 @@
if ((new_serial.type != state->type) ||
(new_serial.xmit_fifo_size <= 0))
new_serial.xmit_fifo_size =
- uart_config[state->type].dfl_xmit_fifo_size;
+ uart_config[new_serial.type].dfl_xmit_fifo_size;

/* Make sure address is not already in use */
if (new_serial.type) {
@@ -1998,17 +1953,17 @@
info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
(info->flags & ASYNC_INTERNAL_FLAGS));
state->custom_divisor = new_serial.custom_divisor;
- state->type = new_serial.type;
state->close_delay = new_serial.close_delay * HZ/100;
state->closing_wait = new_serial.closing_wait * HZ/100;
-#if (LINUX_VERSION_CODE > 0x200100)
+#if (LINUX_VERSION_CODE > 0x20100)
info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
#endif
info->xmit_fifo_size = state->xmit_fifo_size =
new_serial.xmit_fifo_size;

- if (state->type != PORT_UNKNOWN && state->port)
+ if ((state->type != PORT_UNKNOWN) && state->port)
release_region(state->port,8);
+ state->type = new_serial.type;
if (change_port || change_irq) {
/*
* We need to shutdown the serial port at the old
@@ -2018,6 +1973,10 @@
state->irq = new_serial.irq;
info->port = state->port = new_serial.port;
info->hub6 = state->hub6 = new_serial.hub6;
+ if (info->hub6)
+ info->io_type = state->io_type = SERIAL_IO_HUB6;
+ else if (info->io_type == SERIAL_IO_HUB6)
+ info->io_type = state->io_type = SERIAL_IO_PORT;
}
if ((state->type != PORT_UNKNOWN) && state->port)
request_region(state->port,8,"serial(set)");
@@ -2068,6 +2027,18 @@
status = serial_in(info, UART_LSR);
restore_flags(flags);
result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
+
+ /*
+ * If we're about to load something into the transmit
+ * register, we'll pretend the transmitter isn't empty to
+ * avoid a race condition (depending on when the transmit
+ * interrupt happens).
+ */
+ if (info->x_char ||
+ ((info->xmit_cnt > 0) && !info->tty->stopped &&
+ !info->tty->hw_stopped))
+ result &= TIOCSER_TEMT;
+
if (copy_to_user(value, &result, sizeof(int)))
return -EFAULT;
return 0;
@@ -2162,7 +2133,7 @@
{
int retval;

- if (!serial_isroot())
+ if (!capable(CAP_SYS_ADMIN))
return -EPERM;

if (info->state->count > 1)
@@ -2265,7 +2236,7 @@
int retval;
void (*handler)(int, void *, struct pt_regs *);

- if (!serial_isroot())
+ if (!capable(CAP_SYS_ADMIN))
return -EPERM;
state = info->state;

@@ -2318,14 +2289,14 @@

if (IRQ_ports[state->irq]->next_port &&
(was_multi != now_multi)) {
- free_irq(state->irq, NULL);
+ free_irq(state->irq, &IRQ_ports[state->irq]);
if (now_multi)
handler = rs_interrupt_multi;
else
handler = rs_interrupt;

- retval = request_irq(state->irq, handler, IRQ_T(state),
- "serial", NULL);
+ retval = request_irq(state->irq, handler, SA_SHIRQ,
+ "serial", &IRQ_ports[state->irq]);
if (retval) {
printk("Couldn't reallocate serial interrupt "
"driver!!\n");
@@ -2652,7 +2623,7 @@
info->tty = 0;
if (info->blocked_open) {
if (info->close_delay) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(info->close_delay);
}
wake_up_interruptible(&info->open_wait);
@@ -2716,14 +2687,14 @@
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
#endif
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(char_time);
if (signal_pending(current))
break;
if (timeout && time_after(jiffies, orig_jiffies + timeout))
break;
}
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
#endif
@@ -2759,11 +2730,7 @@
static int block_til_ready(struct tty_struct *tty, struct file * filp,
struct async_struct *info)
{
-#ifdef DECLARE_WAITQUEUE
DECLARE_WAITQUEUE(wait, current);
-#else
- struct wait_queue wait = { current, NULL };
-#endif
struct serial_state *state = info->state;
int retval;
int do_clocal = 0, extra_count = 0;
@@ -2880,7 +2847,7 @@
#endif
schedule();
}
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
if (extra_count)
state->count++;
@@ -2912,14 +2879,13 @@
return -ENOMEM;
}
memset(info, 0, sizeof(struct async_struct));
-#ifdef DECLARE_WAITQUEUE
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
init_waitqueue_head(&info->delta_msr_wait);
-#endif
info->magic = SERIAL_MAGIC;
info->port = sstate->port;
info->flags = sstate->flags;
+ info->io_type = sstate->io_type;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
info->iomem_base = sstate->iomem_base;
info->iomem_reg_shift = sstate->iomem_reg_shift;
@@ -3126,7 +3092,8 @@
int i, len = 0, l;
off_t begin = 0;

- len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
+ len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",
+ serial_version, LOCAL_VERSTRING, serial_revdate);
for (i = 0; i < NR_PORTS && len < 4000; i++) {
l = line_info(page + len, &rs_table[i]);
len += l;
@@ -3160,7 +3127,8 @@
*/
static _INLINE_ void show_serial_version(void)
{
- printk(KERN_INFO "%s version %s with", serial_name, serial_version);
+ printk(KERN_INFO "%s version %s%s (%s) with", serial_name,
+ serial_version, LOCAL_VERSTRING, serial_revdate);
#ifdef CONFIG_HUB6
printk(" HUB-6");
#define SERIAL_OPT
@@ -3298,11 +3266,11 @@
}

/*
- * This is a helper routine to autodetect StarTech/Exar UART's. When
- * this function is called we know it is at least a StarTech 16650 V2,
- * but it might be one of several StarTech UARTs, or one of its
- * clones. (We treat the broken original StarTech 16650 V1 as a
- * 16550A, and why not? Startech doesn't seem to even acknowledge its
+ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
+ * When this function is called we know it is at least a StarTech
+ * 16650 V2, but it might be one of several StarTech UARTs, or one of
+ * its clones. (We treat the broken original StarTech 16650 V1 as a
+ * 16550, and why not? Startech doesn't seem to even acknowledge its
* existence.)
*
* What evil have men's minds wrought...
@@ -3311,39 +3279,48 @@
struct serial_state *state,
unsigned long flags)
{
- unsigned char scratch, status1, status2, old_fctr, old_emsr;
+ unsigned char scratch, scratch2, scratch3;

/*
- * Here we check for the XR16C85x family. We do this by
- * checking for to see if we can replace the scratch register
- * with the receive FIFO count register.
+ * First we check to see if it's an Oxford Semiconductor UART.
*
- * XXX I don't have one of these chips, but it should also be
- * possible to check for them by setting DLL and DLM to 0, and
- * then reading back DLL and DLM. If the DLM reads back as
- * 0x10, then the UART is a XR16C850 and the DLL contains the
- * chip revision.
- */
- old_fctr = serial_inp(info, UART_FCTR);
- serial_outp(info, UART_FCTR, old_fctr | UART_FCTR_SCR_SWAP);
- old_emsr = serial_inp(info, UART_EMSR);
- serial_outp(info, UART_EMSR, 0x00);
- serial_outp(info, UART_LCR, 0x00);
- scratch = serial_in(info, UART_SCR);
- serial_outp(info, UART_SCR, 0xa5);
- status1 = serial_in(info, UART_SCR);
- serial_outp(info, UART_SCR, 0x5a);
- status2 = serial_in(info, UART_SCR);
- serial_outp(info, UART_SCR, scratch);
- if ((status1 != 0xa5) || (status2 != 0x5a)) {
- serial_outp(info, UART_LCR, 0xBF);
- serial_outp(info, UART_FCTR, old_fctr | UART_FCTR_SCR_SWAP);
- serial_outp(info, UART_EMSR, old_emsr);
- serial_outp(info, UART_FCTR, old_fctr);
+ * If we have to do this here because some non-National
+ * Semiconductor clone chips lock up if you try writing to the
+ * LSR register (which serial_icr_read does)
+ */
+ if (state->type == PORT_16550A) {
+ /* Check for Oxford Semiconductor 16C950 */
+ scratch = serial_icr_read(info, UART_ID1);
+ scratch2 = serial_icr_read(info, UART_ID2);
+ scratch3 = serial_icr_read(info, UART_ID3);
+
+ if (scratch == 0x16 && scratch2 == 0xC9 &&
+ (scratch3 == 0x50 || scratch3 == 0x52 ||
+ scratch3 == 0x54)) {
+ state->type = PORT_16C950;
+ state->revision = serial_icr_read(info, UART_REV);
+ return;
+ }
+ }
+
+ /*
+ * We check for a XR16C850 by setting DLL and DLM to 0, and
+ * then reading back DLL and DLM. If DLM reads back 0x10,
+ * then the UART is a XR16C850 and the DLL contains the chip
+ * revision. If DLM reads back 0x14, then the UART is a
+ * XR16C854.
+ *
+ */
+ serial_outp(info, UART_LCR, UART_LCR_DLAB);
+ serial_outp(info, UART_DLL, 0);
+ serial_outp(info, UART_DLM, 0);
+ state->revision = serial_inp(info, UART_DLL);
+ scratch = serial_inp(info, UART_DLM);
+ serial_outp(info, UART_LCR, 0);
+ if (scratch == 0x10 || scratch == 0x14) {
state->type = PORT_16850;
return;
}
- serial_outp(info, UART_IER, old_fctr);

/*
* We distinguish between the '654 and the '650 by counting
@@ -3368,10 +3345,16 @@
static void autoconfig(struct serial_state * state)
{
unsigned char status1, status2, scratch, scratch2, scratch3;
+ unsigned char save_lcr, save_mcr;
struct async_struct *info, scr_info;
unsigned long flags;

state->type = PORT_UNKNOWN;
+
+#ifdef SERIAL_DEBUG_AUTOCONF
+ printk("Testing ttyS%d (0x%04x, 0x%04x)...\n", state->line,
+ state->port, (unsigned) state->iomem_base);
+#endif

if (!CONFIGURED_SERIAL_PORT(state))
return;
@@ -3385,6 +3368,7 @@
#ifdef CONFIG_HUB6
info->hub6 = state->hub6;
#endif
+ info->io_type = state->io_type;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
info->iomem_base = state->iomem_base;
info->iomem_reg_shift = state->iomem_reg_shift;
@@ -3405,15 +3389,29 @@
*/
scratch = serial_inp(info, UART_IER);
serial_outp(info, UART_IER, 0);
+#ifdef __i386__
outb(0xff, 0x080);
+#endif
scratch2 = serial_inp(info, UART_IER);
+ serial_outp(info, UART_IER, 0x0F);
+#ifdef __i386__
+ outb(0, 0x080);
+#endif
+ scratch3 = serial_inp(info, UART_IER);
serial_outp(info, UART_IER, scratch);
- if (scratch2) {
+ if (scratch2 || scratch3 != 0x0F) {
+#ifdef SERIAL_DEBUG_AUTOCONF
+ printk("serial: ttyS%d: simple autoconfig failed\n",
+ state->line);
+#endif
restore_flags(flags);
return; /* We failed; there's nothing here */
}
}

+ save_mcr = serial_in(info, UART_MCR);
+ save_lcr = serial_in(info, UART_LCR);
+
/*
* Check to see if a UART is really there. Certain broken
* internal modems based on the Rockwell chipset fail this
@@ -3424,18 +3422,18 @@
* that conflicts with COM 1-4 --- we hope!
*/
if (!(state->flags & ASYNC_SKIP_TEST)) {
- scratch = serial_inp(info, UART_MCR);
- serial_outp(info, UART_MCR, UART_MCR_LOOP | scratch);
serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
status1 = serial_inp(info, UART_MSR) & 0xF0;
- serial_outp(info, UART_MCR, scratch);
+ serial_outp(info, UART_MCR, save_mcr);
if (status1 != 0x90) {
+#ifdef SERIAL_DEBUG_AUTOCONF
+ printk("serial: ttyS%d: no UART loopback failed\n",
+ state->line);
+#endif
restore_flags(flags);
return;
}
- }
-
- scratch2 = serial_in(info, UART_LCR);
+ }
serial_outp(info, UART_LCR, 0xBF); /* set up for StarTech test */
serial_outp(info, UART_EFR, 0); /* EFR is the same as FCR */
serial_outp(info, UART_LCR, 0);
@@ -3456,21 +3454,6 @@
break;
}
if (state->type == PORT_16550A) {
- /* Check for Oxford Semiconductor 16C950 */
- unsigned char scratch4;
-
- scratch = serial_icr_read(info, UART_ID1);
- scratch4 = serial_icr_read(info, UART_ID2);
- scratch3 = serial_icr_read(info, UART_ID3);
-
- if (scratch == 0x16 && scratch4 == 0xC9 &&
- (scratch3 == 0x50 || scratch3 == 0x52 ||
- scratch3 == 0x54)) {
- state->type = PORT_16C950;
- state->revision = serial_icr_read(info, UART_REV);
- }
- }
- if (state->type == PORT_16550A) {
/* Check for Startech UART's */
serial_outp(info, UART_LCR, UART_LCR_DLAB);
if (serial_in(info, UART_EFR) == 0) {
@@ -3483,7 +3466,7 @@
}
if (state->type == PORT_16550A) {
/* Check for TI 16750 */
- serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB);
+ serial_outp(info, UART_LCR, save_lcr | UART_LCR_DLAB);
serial_outp(info, UART_FCR,
UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
scratch = serial_in(info, UART_IIR) >> 5;
@@ -3504,7 +3487,7 @@
}
serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
}
- serial_outp(info, UART_LCR, scratch2);
+ serial_outp(info, UART_LCR, save_lcr);
if (state->type == PORT_16450) {
scratch = serial_in(info, UART_SCR);
serial_outp(info, UART_SCR, 0xa5);
@@ -3529,9 +3512,11 @@
/*
* Reset the UART.
*/
- serial_outp(info, UART_MCR, 0x00 | ALPHA_KLUDGE_MCR); /* Don't ask */
- serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
+ serial_outp(info, UART_MCR, save_mcr);
+ serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
+ UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT));
+ serial_outp(info, UART_FCR, 0);
(void)serial_in(info, UART_RX);
serial_outp(info, UART_IER, 0);

@@ -3562,11 +3547,11 @@
*
* Note that __init is a no-op if MODULE is defined; we depend on this.
*/
-static void __init pci_plx9050_fn(struct pci_dev *dev,
+static int __init pci_plx9050_fn(struct pci_dev *dev,
struct pci_board *board,
int enable)
{
- u8 data, *p;
+ u8 data, *p, scratch;

pci_read_config_byte(dev, PCI_COMMAND, &data);

@@ -3576,12 +3561,94 @@

/* enable/disable interrupts */
p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80);
- writel(enable ? 0x41 : 0x00, p + 0x4c);
+ if (board->vendor == PCI_VENDOR_ID_PANACOM) {
+ scratch = readl(p + 0x4c);
+ if (enable)
+ scratch |= 0x40;
+ else
+ scratch &= ~0x40;
+ writel(scratch, p + 0x4c);
+ } else
+ writel(enable ? 0x41 : 0x00, p + 0x4c);
iounmap(p);

if (!enable)
pci_write_config_byte(dev, PCI_COMMAND,
data & ~PCI_COMMAND_MEMORY);
+ return 0;
+}
+
+/*
+ * SIIG serial cards have an PCI interface chip which also controls
+ * the UART clocking frequency. Each UART can be clocked independently
+ * (except cards equiped with 4 UARTs) and initial clocking settings
+ * are stored in the EEPROM chip. It can cause problems because this
+ * version of serial driver doesn't support differently clocked UART's
+ * on single PCI card. To prevent this, initialization functions set
+ * high frequency clocking for all UART's on given card. It is safe (I
+ * hope) because it doesn't touch EEPROM settings to prevent conflicts
+ * with other OSes (like M$ DOS).
+ *
+ * SIIG support added by Andrey Panin <pazke@mail.tp.ru>, 10/1999
+ *
+ * There is two family of SIIG serial cards with different PCI
+ * interface chip and different configuration methods:
+ * - 10x cards have control registers in IO and/or memory space;
+ * - 20x cards have control registers in standard PCI configuration space.
+ */
+
+#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
+
+static int __init pci_siig10x_fn(struct pci_dev *dev,
+ struct pci_board *board,
+ int enable)
+{
+ u16 data, *p;
+
+ if (!enable) return 0;
+
+ p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80);
+
+ switch (dev->device & 0xfff8) {
+ case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */
+ data = 0xffdf;
+ break;
+ case PCI_DEVICE_ID_SIIG_2S_10x: /* 2S, 2S1P */
+ data = 0xf7ff;
+ break;
+ default: /* 1S1P, 4S */
+ data = 0xfffb;
+ break;
+ }
+
+ writew(readw(p + 0x28) & data, p + 0x28);
+ iounmap(p);
+ return 0;
+}
+
+#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
+
+static int __init pci_siig20x_fn(struct pci_dev *dev,
+ struct pci_board *board,
+ int enable)
+{
+ u8 data;
+
+ if (!enable) return 0;
+
+ /* Change clock frequency for the first UART. */
+ pci_read_config_byte(dev, 0x6f, &data);
+ pci_write_config_byte(dev, 0x6f, data & 0xef);
+
+ /* If this card has 2 UART, we have to do the same with second UART. */
+ if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
+ ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
+ pci_read_config_byte(dev, 0x73, &data);
+ pci_write_config_byte(dev, 0x73, data & 0xef);
+ }
+ return 0;
}

/*
@@ -3592,9 +3659,9 @@
/*
* Vendor ID, Device ID,
* Subvendor ID, Subdevice ID,
- * Number of Ports, Base (Maximum) Baud Rate,
- * Offset of register holding Uart register offset
- * Mask to apply to above register's value
+ * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
+ * Offset to get to next UART's registers
+ * Register shift to use for memory-mapped I/O
*/
{ PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
PCI_SUBVENDOR_ID_CONNECT_TECH,
@@ -3677,7 +3744,7 @@
SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 115200 },
{ PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 8, 115200 },
+ SPCI_FL_BASE2, 8, 115200 },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 115200 },
@@ -3691,12 +3758,226 @@
0x400, 7, pci_plx9050_fn },
{ PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE2 | SPCI_FL_IOMEM, 4, 921600,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,
0x400, 7, pci_plx9050_fn },
{ PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE2 | SPCI_FL_IOMEM, 2, 921600,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,
0x400, 7, pci_plx9050_fn },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST4,
+ SPCI_FL_BASE2, 4, 460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST8,
+ SPCI_FL_BASE2, 8, 460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST16,
+ SPCI_FL_BASE2, 16, 460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC,
+ SPCI_FL_BASE2, 16, 460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+ PCI_SUBDEVICE_ID_CHASE_PCIRAS4,
+ SPCI_FL_BASE2, 4, 460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+ PCI_SUBDEVICE_ID_CHASE_PCIRAS8,
+ SPCI_FL_BASE2, 8, 460800 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE1, 4, 115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE1, 2, 115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE1, 8, 115200 },
+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE1, 8, 115200 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
+ SPCI_FL_BASE0 , 4, 115200 },
+ { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
+ SPCI_FL_BASE0 , 4, 921600 },
+ { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 , 2, 921600 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_SERIAL,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2, 1, 460800,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2, 1, 460800,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2, 1, 460800,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2, 1, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2, 1, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2, 1, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,
+ 0, 0, pci_siig10x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0, 1, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600,
+ 0, 0, pci_siig20x_fn },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600,
+ 0, 0, pci_siig20x_fn },
+ /* Computone devices submitted by Doug McNash dmcnash@computone.com */
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
+ SPCI_FL_IOMEM | SPCI_FL_BASE0, 4, 921600,
+ 0x40, 2, NULL, 0x200 },
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
+ SPCI_FL_IOMEM | SPCI_FL_BASE0, 8, 921600,
+ 0x40, 2, NULL, 0x200 },
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
+ SPCI_FL_IOMEM | SPCI_FL_BASE0, 6, 921600,
+ 0x40, 2, NULL, 0x200 },
+ /*
+ * Untested PCI modems, sent in from various folks...
+ */
+ /* at+t zoom 56K faxmodem, from dougd@shieldsbag.com */
+ { PCI_VENDOR_ID_ATT, 0x442,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE1, 1, 115200 },
+ /* at&t unknown modem, from jimd@esoft.com */
+ { PCI_VENDOR_ID_ATT, 0x480,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE1, 1, 115200 },
+ /* Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> */
+ { PCI_VENDOR_ID_ROCKWELL, 0x1004,
+ 0x1048, 0x1500,
+ SPCI_FL_BASE1, 1, 115200 },
+ /* 3Com US Robotics 56k* Voice Internal PCI, model# 2884 */
+ /* from evidal@iti.upv.es */
+ /* XXX complete guess this may not work!!! */
+ { PCI_VENDOR_ID_USR, 0x1006,
+ 0x12b9, 0x0060,
+ SPCI_FL_BASE1 | SPCI_FL_IOMEM, 1, 115200 },
{ 0, }
};

@@ -3767,18 +4048,22 @@
* Run the initialization function, if any
*/
if (board->init_fn)
- (board->init_fn)(dev, board, 1);
+ if ((board->init_fn)(dev, board, 1) != 0)
+ continue;

/*
* Register the serial board in the array so we can
* shutdown the board later, if necessary.
*/
+ if (serial_pci_board_idx >= NR_PCI_BOARDS)
+ continue;
serial_pci_board[serial_pci_board_idx].board = board;
serial_pci_board[serial_pci_board_idx].dev = dev;
serial_pci_board_idx++;

base_idx = board->flags & SPCI_FL_BASE_MASK;
- port = PCI_BASE_ADDRESS(dev, base_idx);
+ port = PCI_BASE_ADDRESS(dev, base_idx) +
+ board->first_uart_offset;
if (board->flags & SPCI_FL_IOMEM)
port &= PCI_BASE_ADDRESS_MEM_MASK;
else
@@ -3829,6 +4114,7 @@
fake_state.port = port;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
if (board->flags & SPCI_FL_IOMEM) {
+ fake_state.io_type = SERIAL_IO_MEM;
fake_state.iomem_base =
ioremap(port, board->uart_offset);
fake_state.iomem_reg_shift = board->reg_shift;
@@ -3869,6 +4155,16 @@
dualsp_serial_init ();
#endif

+ if (timer_table[RS_TIMER].fn) {
+ printk("RS_TIMER already set, another serial driver "
+ "already loaded?\n");
+#ifdef MODULE
+ printk("Can't load serial driver module over built-in "
+ "serial driver\n");
+#endif
+ return -EBUSY;
+ }
+
init_bh(SERIAL_BH, do_serial_bh);
timer_table[RS_TIMER].fn = rs_timer;
timer_table[RS_TIMER].expires = 0;
@@ -3974,6 +4270,8 @@
state->icount.frame = state->icount.parity = 0;
state->icount.overrun = state->icount.brk = 0;
state->irq = irq_cannonicalize(state->irq);
+ if (state->hub6)
+ state->io_type = SERIAL_IO_HUB6;
if (state->port && check_region(state->port,8))
continue;
if (state->flags & ASYNC_BOOT_AUTOCONF)
@@ -4035,10 +4333,13 @@
state->irq = req->irq;
state->port = req->port;
state->flags = req->flags;
+ state->io_type = req->io_type;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
state->iomem_base = req->iomem_base;
state->iomem_reg_shift = req->iomem_reg_shift;
#endif
+ if (req->baud_base)
+ state->baud_base = req->baud_base;

autoconfig(state);
if (state->type == PORT_UNKNOWN) {
@@ -4103,13 +4404,12 @@
restore_flags(flags);

for (i = 0; i < NR_PORTS; i++) {
+ if ((info = rs_table[i].info)) {
+ rs_table[i].info = NULL;
+ kfree_s(info, sizeof(struct async_struct));
+ }
if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port)
release_region(rs_table[i].port, 8);
- info = rs_table[i].info;
- if (info) {
- rs_table[i].info = NULL;
- kfree_s(info, sizeof(struct async_struct));
- }
#if defined(ENABLE_SERIAL_PCI) && defined (CONFIG_SERIAL_PCI_MEMMAPPED)
if (rs_table[i].iomem_base)
iounmap(rs_table[i].iomem_base);
@@ -4140,20 +4440,20 @@

#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)

+static struct async_struct async_sercons;
+
/*
* Wait for transmitter & holding register to empty
*/
-static inline void wait_for_xmitr(struct serial_state *ser)
+static inline void wait_for_xmitr(struct async_struct *info)
{
- int lsr;
unsigned int tmout = 1000000;

- do {
- lsr = inb(ser->port + UART_LSR);
- if (--tmout == 0) break;
- } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
+ while (--tmout &&
+ ((serial_in(info, UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY));
}

+
/*
* Print a string to the serial port trying not to disturb
* any possible real use of the port...
@@ -4161,31 +4461,30 @@
static void serial_console_write(struct console *co, const char *s,
unsigned count)
{
- struct serial_state *ser;
+ static struct async_struct *info = &async_sercons;
int ier;
unsigned i;

- ser = rs_table + co->index;
/*
* First save the IER then disable the interrupts
*/
- ier = inb(ser->port + UART_IER);
- outb(0x00, ser->port + UART_IER);
+ ier = serial_in(info, UART_IER);
+ serial_out(info, UART_IER, 0x00);

/*
* Now, do each character
*/
for (i = 0; i < count; i++, s++) {
- wait_for_xmitr(ser);
+ wait_for_xmitr(info);

/*
* Send the character out.
* If a LF, also do CR...
*/
- outb(*s, ser->port + UART_TX);
+ serial_out(info, UART_TX, *s);
if (*s == 10) {
- wait_for_xmitr(ser);
- outb(13, ser->port + UART_TX);
+ wait_for_xmitr(info);
+ serial_out(info, UART_TX, 13);
}
}

@@ -4193,8 +4492,8 @@
* Finally, Wait for transmitter & holding register to empty
* and restore the IER
*/
- wait_for_xmitr(ser);
- outb(ier, ser->port + UART_IER);
+ wait_for_xmitr(info);
+ serial_out(info, UART_IER, ier);
}

/*
@@ -4202,30 +4501,26 @@
*/
static int serial_console_wait_key(struct console *co)
{
- struct serial_state *ser;
- int ier;
- int lsr;
- int c;
+ static struct async_struct *info;
+ int ier, c;

- ser = rs_table + co->index;
+ info = &async_sercons;

/*
* First save the IER then disable the interrupts so
* that the real driver for the port does not get the
* character.
*/
- ier = inb(ser->port + UART_IER);
- outb(0x00, ser->port + UART_IER);
-
- do {
- lsr = inb(ser->port + UART_LSR);
- } while (!(lsr & UART_LSR_DR));
- c = inb(ser->port + UART_RX);
+ ier = serial_in(info, UART_IER);
+ serial_out(info, UART_IER, 0x00);
+
+ while ((serial_in(info, UART_LSR) & UART_LSR_DR) == 0);
+ c = serial_in(info, UART_RX);

/*
* Restore the interrupts
*/
- outb(ier, ser->port + UART_IER);
+ serial_out(info, UART_IER, ier);

return c;
}
@@ -4243,7 +4538,8 @@
*/
static int __init serial_console_setup(struct console *co, char *options)
{
- struct serial_state *ser;
+ static struct async_struct *info;
+ struct serial_state *state;
unsigned cval;
int baud = 9600;
int bits = 8;
@@ -4251,6 +4547,9 @@
int cflag = CREAD | HUPCL | CLOCAL;
int quot = 0;
char *s;
+#if defined(CONFIG_KDB)
+ extern int kdb_port;
+#endif

if (options) {
baud = simple_strtoul(options, NULL, 10);
@@ -4313,8 +4612,21 @@
/*
* Divisor, bytesize and parity
*/
- ser = rs_table + co->index;
- quot = ser->baud_base / baud;
+ state = rs_table + co->index;
+ info = &async_sercons;
+ info->magic = SERIAL_MAGIC;
+ info->state = state;
+ info->port = state->port;
+ info->flags = state->flags;
+#ifdef CONFIG_HUB6
+ info->hub6 = state->hub6;
+#endif
+ info->io_type = state->io_type;
+#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
+ info->iomem_base = state->iomem_base;
+ info->iomem_reg_shift = state->iomem_reg_shift;
+#endif
+ quot = state->baud_base / baud;
cval = cflag & (CSIZE | CSTOPB);
#if defined(__powerpc__) || defined(__alpha__)
cval >>= 8;
@@ -4330,18 +4642,27 @@
* Disable UART interrupts, set DTR and RTS high
* and set speed.
*/
- outb(cval | UART_LCR_DLAB, ser->port + UART_LCR); /* set DLAB */
- outb(quot & 0xff, ser->port + UART_DLL); /* LS of divisor */
- outb(quot >> 8, ser->port + UART_DLM); /* MS of divisor */
- outb(cval, ser->port + UART_LCR); /* reset DLAB */
- outb(0, ser->port + UART_IER);
- outb(UART_MCR_DTR | UART_MCR_RTS, ser->port + UART_MCR);
+ serial_out(info, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
+ serial_out(info, UART_DLL, quot & 0xff); /* LS of divisor */
+ serial_out(info, UART_DLM, quot >> 8); /* MS of divisor */
+ serial_out(info, UART_LCR, cval); /* reset DLAB */
+ serial_out(info, UART_IER, 0);
+ serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);

/*
* If we read 0xff from the LSR, there is no UART here.
*/
- if (inb(ser->port + UART_LSR) == 0xff)
+ if (serial_in(info, UART_LSR) == 0xff)
return -1;
+
+#if defined(CONFIG_KDB)
+ /*
+ * Remember I/O port for kdb
+ */
+ if (kdb_port == 0 )
+ kdb_port = ser->port;
+#endif /* CONFIG_KDB */
+
return 0;
}

===================================================================
RCS file: include/linux/RCS/serial.h,v
retrieving revision 1.1
diff -u -r1.1 include/linux/serial.h
--- include/linux/serial.h 1999/11/17 03:03:11 1.1
+++ include/linux/serial.h 1999/11/17 20:03:06
@@ -20,7 +20,8 @@
int custom_divisor;
int baud_base;
unsigned short close_delay;
- char reserved_char[2];
+ char io_type;
+ char reserved_char[1];
int hub6;
unsigned short closing_wait; /* time to wait before closing */
unsigned short closing_wait2; /* no longer used... */
@@ -37,20 +38,6 @@
#define ASYNC_CLOSING_WAIT_NONE 65535

/*
- * The size of the serial xmit buffer is 1 page, or 4096 bytes
- */
-#define SERIAL_XMIT_SIZE 4096
-
-/*
- * Counters of the input lines (CTS, DSR, RI, CD) interrupts
- */
-struct async_icount {
- __u32 cts, dsr, rng, dcd, tx, rx;
- __u32 frame, parity, overrun, brk;
- __u32 buf_overrun;
-};
-
-/*
* These are the supported serial types.
*/
#define PORT_UNKNOWN 0
@@ -67,6 +54,11 @@
#define PORT_16654 11
#define PORT_16850 12
#define PORT_MAX 12
+
+#define SERIAL_IO_PORT 0
+#define SERIAL_IO_HUB6 1
+#define SERIAL_IO_MEM 2
+#define SERIAL_IO_GSC 3

struct serial_uart_config {
char *name;
===================================================================
RCS file: include/linux/RCS/serialP.h,v
retrieving revision 1.1
diff -u -r1.1 include/linux/serialP.h
--- include/linux/serialP.h 1999/11/17 03:03:11 1.1
+++ include/linux/serialP.h 1999/11/17 20:03:06
@@ -19,11 +19,18 @@
* For definitions of the flags field, see tty.h
*/

-#include <linux/config.h>
#include <linux/termios.h>
#include <linux/tqueue.h>
#include <linux/wait.h>

+/*
+ * Counters of the input lines (CTS, DSR, RI, CD) interrupts
+ */
+struct async_icount {
+ __u32 cts, dsr, rng, dcd, tx, rx;
+ __u32 frame, parity, overrun, brk;
+ __u32 buf_overrun;
+};

struct serial_state {
int magic;
@@ -45,6 +52,7 @@
struct async_icount icount;
struct termios normal_termios;
struct termios callout_termios;
+ int io_type;
struct async_struct *info;
};

@@ -80,6 +88,7 @@
int xmit_cnt;
u8 *iomem_base;
u16 iomem_reg_shift;
+ int io_type;
struct tq_struct tqueue;
#ifdef DECLARE_WAITQUEUE
wait_queue_head_t open_wait;
@@ -99,6 +108,10 @@
#define SERIAL_MAGIC 0x5301
#define SSTATE_MAGIC 0x5302

+/*
+ * The size of the serial xmit buffer is 1 page, or 4096 bytes
+ */
+#define SERIAL_XMIT_SIZE 4096

/*
* Events are used to schedule things to happen at timer-interrupt
@@ -132,7 +145,6 @@
#define ALPHA_KLUDGE_MCR 0
#endif

-#ifdef CONFIG_PCI
/*
* Structures and definitions for PCI support
*/
@@ -147,8 +159,9 @@
int base_baud;
int uart_offset;
int reg_shift;
- void (*init_fn)(struct pci_dev *dev, struct pci_board *board,
+ int (*init_fn)(struct pci_dev *dev, struct pci_board *board,
int enable);
+ int first_uart_offset;
};

struct pci_board_inst {
@@ -158,7 +171,6 @@

#ifndef PCI_ANY_ID
#define PCI_ANY_ID (~0)
-#endif
#endif

#define SPCI_FL_BASE_MASK 0x0007
===================================================================
RCS file: include/linux/RCS/serial_reg.h,v
retrieving revision 1.1
diff -u -r1.1 include/linux/serial_reg.h
===================================================================
RCS file: include/linux/RCS/pci_ids.h,v
retrieving revision 1.1
diff -u -r1.1 include/linux/pci_ids.h
--- include/linux/pci_ids.h 1999/11/17 03:03:11 1.1
+++ include/linux/pci_ids.h 1999/11/17 03:11:48
@@ -434,6 +434,10 @@
#define PCI_VENDOR_ID_LEADTEK 0x107d
#define PCI_DEVICE_ID_LEADTEK_805 0x0000

+#define PCI_VENDOR_ID_INTERPHASE 0x107e
+#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004
+#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005
+
#define PCI_VENDOR_ID_CONTAQ 0x1080
#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600
#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693
@@ -783,6 +787,7 @@
#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
+#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004

#define PCI_VENDOR_ID_AURAVISION 0x11d1
#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7
@@ -874,9 +879,13 @@
#define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI 0x5000
#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371

+#define PCI_VENDOR_ID_ROCKWELL 0x127A
+
#define PCI_VENDOR_ID_ALTEON 0x12ae
#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001

+#define PCI_VENDOR_ID_USR 0x12B9
+
#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232 0x0002
@@ -893,30 +902,65 @@
#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018

+#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8 0x0021
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16 0x0011
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC 0x0041
+#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D
+#define PCI_SUBDEVICE_ID_CHASE_PCIRAS4 0xF001
+#define PCI_SUBDEVICE_ID_CHASE_PCIRAS8 0xF010
+
#define PCI_VENDOR_ID_CBOARDS 0x1307
#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001

#define PCI_VENDOR_ID_SIIG 0x131f
+#define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000
+#define PCI_DEVICE_ID_SIIG_1S_10x_650 0x1001
+#define PCI_DEVICE_ID_SIIG_1S_10x_850 0x1002
#define PCI_DEVICE_ID_SIIG_1S1P_10x_550 0x1010
#define PCI_DEVICE_ID_SIIG_1S1P_10x_650 0x1011
#define PCI_DEVICE_ID_SIIG_1S1P_10x_850 0x1012
#define PCI_DEVICE_ID_SIIG_1P_10x 0x1020
#define PCI_DEVICE_ID_SIIG_2P_10x 0x1021
+#define PCI_DEVICE_ID_SIIG_2S_10x_550 0x1030
+#define PCI_DEVICE_ID_SIIG_2S_10x_650 0x1031
+#define PCI_DEVICE_ID_SIIG_2S_10x_850 0x1032
#define PCI_DEVICE_ID_SIIG_2S1P_10x_550 0x1034
#define PCI_DEVICE_ID_SIIG_2S1P_10x_650 0x1035
#define PCI_DEVICE_ID_SIIG_2S1P_10x_850 0x1036
+#define PCI_DEVICE_ID_SIIG_4S_10x_550 0x1050
+#define PCI_DEVICE_ID_SIIG_4S_10x_650 0x1051
+#define PCI_DEVICE_ID_SIIG_4S_10x_850 0x1052
+#define PCI_DEVICE_ID_SIIG_1S_20x_550 0x2000
+#define PCI_DEVICE_ID_SIIG_1S_20x_650 0x2001
+#define PCI_DEVICE_ID_SIIG_1S_20x_850 0x2002
#define PCI_DEVICE_ID_SIIG_1P_20x 0x2020
#define PCI_DEVICE_ID_SIIG_2P_20x 0x2021
+#define PCI_DEVICE_ID_SIIG_2S_20x_550 0x2030
+#define PCI_DEVICE_ID_SIIG_2S_20x_650 0x2031
+#define PCI_DEVICE_ID_SIIG_2S_20x_850 0x2032
#define PCI_DEVICE_ID_SIIG_2P1S_20x_550 0x2040
#define PCI_DEVICE_ID_SIIG_2P1S_20x_650 0x2041
#define PCI_DEVICE_ID_SIIG_2P1S_20x_850 0x2042
#define PCI_DEVICE_ID_SIIG_1S1P_20x_550 0x2010
#define PCI_DEVICE_ID_SIIG_1S1P_20x_650 0x2011
#define PCI_DEVICE_ID_SIIG_1S1P_20x_850 0x2012
+#define PCI_DEVICE_ID_SIIG_4S_20x_550 0x2050
+#define PCI_DEVICE_ID_SIIG_4S_20x_650 0x2051
+#define PCI_DEVICE_ID_SIIG_4S_20x_850 0x2052
#define PCI_DEVICE_ID_SIIG_2S1P_20x_550 0x2060
#define PCI_DEVICE_ID_SIIG_2S1P_20x_650 0x2061
#define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062

+#define PCI_VENDOR_ID_QUATECH 0x135C
+#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010
+#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020
+#define PCI_DEVICE_ID_QUATECH_DSC200 0x0030
+#define PCI_DEVICE_ID_QUATECH_QSC200 0x0040
+#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050
+#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060
+
#define PCI_VENDOR_ID_SEALEVEL 0x135e
#define PCI_DEVICE_ID_SEALEVEL_U530 0x7101
#define PCI_DEVICE_ID_SEALEVEL_UCOMM2 0x7201
@@ -929,11 +973,18 @@
#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a

#define PCI_VENDOR_ID_LAVA 0x1407
+#define PCI_DEVICE_ID_LAVA_DUAL_SERIAL 0x0100
#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000
#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */
#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */
#define PCI_DEVICE_ID_LAVA_BOCA_IOPPAR 0x8800

+#define PCI_VENDOR_ID_TIMEDIA 0x1409
+#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168
+
+#define PCI_VENDOR_ID_OXSEMI 0x1415
+#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
+
#define PCI_VENDOR_ID_PANACOM 0x14d4
#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402
@@ -1022,8 +1073,6 @@
#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
-#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
-#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291

#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180
#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181
@@ -1034,6 +1083,14 @@
#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca

+#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
+#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291
+#define PCI_DEVICE_ID_COMPUTONE_PG 0x0302
+#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG4 0x0001
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG8 0x0002
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003
+
#define PCI_VENDOR_ID_KTI 0x8e2e
#define PCI_DEVICE_ID_KTI_ET32P2 0x3000

@@ -1099,15 +1156,4 @@
#define PCI_DEVICE_ID_ARK_STINGARK 0xa099
#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1

-#define PCI_VENDOR_ID_INTERPHASE 0x107e
-#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004
-#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005
-
-#define PCI_VENDOR_ID_INTERPHASE 0x107e
-#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004
-#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005
-
-#define PCI_VENDOR_ID_INTERPHASE 0x107e
-#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004
-#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005

===================================================================
RCS file: drivers/acorn/char/RCS/serial-card.c,v
retrieving revision 1.1
diff -u -r1.1 drivers/acorn/char/serial-card.c
--- drivers/acorn/char/serial-card.c 1999/11/17 03:03:11 1.1
+++ drivers/acorn/char/serial-card.c 1999/11/17 03:11:48
@@ -55,6 +55,8 @@
{
struct serial_struct req;

+ memset(&req, 0, sizeof(serial_struct));
+
req.baud_base = MY_BAUD_BASE;
req.irq = irq;
req.port = port;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:55    [W:0.073 / U:0.080 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site