[LWN Logo]

Date:	Sun, 21 May 2000 01:05:00 -0400
To:	torvalds@transmeta.com
Subject: PATCH: Serial driver update, versus 2.3.99pre9-2
From:	tytso@mit.edu


Hi Linus,

Enclosed please find updates to the serial driver, versus Linux
2-3.99pre9-2.  Could you please apply these patches to the mainline?  
Thanks!!

The changes here are:

	* Fixed binary incompatibility problem introduced in 2.3.99pre2 for
		64-bit platforms (i.e. Alpha, et. al) 

	* When TIOCMIWAIT is called, turn on monitoring of status
	          interrupts so they are counted correctly.

	* Add a flag (ASYNC_BUGGY_UART) which skips some sanity checks
		in deference to buggy UARTs. (Warning!  If there isn't a
		UART at the port, this can cause kernel lockups.)

	* Pass the flag ASYNC_AUTOPROBE back to userland for ports which
	          were autodetected (i.e., via PCI or PNP code).  This
	          is needed by setserial so it knows which ports' state
	          needs to be saved.

	* Add generic autodetection for ISA PnP modems. 

	* Add support for a number of new cards: 
		RSA-DV II/S
		Megawolf Romulus PCI 
                VS SPCOM800 
                EKF Intel i960 serial boards 
                A variety of PnP boards. 

						- Ted


Patch generated: on Sun May 21 00:56:52 EDT 2000 by tytso@snap.thunk.org
against Linux version 2.3.99pre9-2
 
===================================================================
RCS file: drivers/char/RCS/serial.c,v
retrieving revision 1.1
diff -u -r1.1 drivers/char/serial.c
--- drivers/char/serial.c	2000/05/21 02:48:46	1.1
+++ drivers/char/serial.c	2000/05/21 04:30:25
@@ -43,13 +43,16 @@
  *	  few races on freeing buffers too.
  *	  Alan Modra <alan@linuxcare.com>
  *
+ *  5/00: Support for the RSA-DV II/S card added.
+ *	  Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
+ * 
  * This module exports the following rs232 io functions:
  *
  *	int rs_init(void);
  */
 
-static char *serial_version = "4.93";
-static char *serial_revdate = "2000-03-20";
+static char *serial_version = "4.95";
+static char *serial_revdate = "2000-05-21";
 
 /*
  * Serial driver configuration section.  Here are the various options:
@@ -134,6 +137,8 @@
 #endif
 #endif
 
+#define CONFIG_SERIAL_RSA
+
 #define RS_STROBE_TIME (10*HZ)
 #define RS_ISR_PASS_LIMIT 256
 
@@ -277,9 +282,20 @@
 		  UART_STARTECH }, 
 	{ "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
 		  UART_STARTECH },
+	{ "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO }, 
 	{ 0, 0}
 };
 
+#if defined(CONFIG_SERIAL_RSA) && defined(MODULE)
+
+#define PORT_RSA_MAX 4
+static int probe_rsa[PORT_RSA_MAX];
+static int force_rsa[PORT_RSA_MAX];
+
+MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+#endif /* CONFIG_SERIAL_RSA  */
+
 static struct serial_state rs_table[RS_TABLE_SIZE] = {
 	SERIAL_PORT_DFNS	/* Defined in serial.h */
 };
@@ -293,11 +309,8 @@
 static struct pci_board_inst	serial_pci_board[NR_PCI_BOARDS];
 static int serial_pci_board_idx = 0;
 #endif
-#ifndef PCI_BASE_ADDRESS
-#define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start)
-#define PCI_BASE_REGION_SIZE(dev, r) ((dev)->resource[r].end - \
-				      (dev)->resource[r].start)
-#define IS_PCI_REGION_IOPORT(dev, r) ((dev)->resource[r].flags & \
+#ifndef IS_PCI_REGION_IOPORT
+#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \
 				      IORESOURCE_IO)
 #endif
 #ifndef PCI_IRQ_RESOURCE
@@ -314,7 +327,8 @@
 #define ACTIVATE_FUNC(dev)  (dev->activate)
 #define DEACTIVATE_FUNC(dev)  (dev->deactivate)
 #endif
-	
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
 
 static struct tty_struct *serial_table[NR_PORTS];
 static struct termios *serial_termios[NR_PORTS];
@@ -1090,6 +1104,50 @@
 	IRQ_timeout[irq] = timeout ? timeout : 1;
 }
 
+#ifdef CONFIG_SERIAL_RSA
+/* Attempts to turn on the RSA FIFO.  Returns zero on failure */
+static int enable_rsa(struct async_struct *info)
+{
+	unsigned char mode;
+	int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	mode = serial_inp(info, UART_RSA_MSR);
+	result = mode & UART_RSA_MSR_FIFO;
+
+	if (!result) {
+		serial_outp(info, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
+		mode = serial_inp(info, UART_RSA_MSR);
+		result = mode & UART_RSA_MSR_FIFO;
+	}
+
+	restore_flags(flags);
+	return result;
+}
+
+/* Attempts to turn off the RSA FIFO.  Returns zero on failure */
+static int disable_rsa(struct async_struct *info)
+{
+	unsigned char mode;
+	int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	mode = serial_inp(info, UART_RSA_MSR);
+	result = !(mode & UART_RSA_MSR_FIFO);
+
+	if (!result) {
+		serial_outp(info, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
+		mode = serial_inp(info, UART_RSA_MSR);
+		result = !(mode & UART_RSA_MSR_FIFO);
+	}
+
+	restore_flags(flags);
+	return result;
+}
+#endif /* CONFIG_SERIAL_RSA */
+
 static int startup(struct async_struct * info)
 {
 	unsigned long flags;
@@ -1127,7 +1185,7 @@
 	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
 #endif
 
-	if (uart_config[info->state->type].flags & UART_STARTECH) {
+	if (uart_config[state->type].flags & UART_STARTECH) {
 		/* Wake up UART */
 		serial_outp(info, UART_LCR, 0xBF);
 		serial_outp(info, UART_EFR, UART_EFR_ECB);
@@ -1145,7 +1203,7 @@
 		/*
 		 * For a XR16C850, we need to set the trigger levels
 		 */
-		if (info->state->type == PORT_16850) {
+		if (state->type == PORT_16850) {
 			serial_outp(info, UART_FCTR, UART_FCTR_TRGD |
 					UART_FCTR_RX);
 			serial_outp(info, UART_TRG, UART_TRG_96);
@@ -1156,12 +1214,12 @@
 		serial_outp(info, UART_LCR, 0);
 	}
 
-	if (info->state->type == PORT_16750) {
+	if (state->type == PORT_16750) {
 		/* Wake up UART */
 		serial_outp(info, UART_IER, 0);
 	}
 
-	if (info->state->type == PORT_16C950) {
+	if (state->type == PORT_16C950) {
 		/* Wake up and initialize UART */
 		info->ACR = 0;
 		serial_outp(info, UART_LCR, 0xBF);
@@ -1174,6 +1232,20 @@
 		serial_outp(info, UART_LCR, 0);
 	}
 
+#ifdef CONFIG_SERIAL_RSA
+	/*
+	 * If this is an RSA port, see if we can kick it up to the
+	 * higher speed clock.
+	 */
+	if (state->type == PORT_RSA) {
+		if (state->baud_base != SERIAL_RSA_BAUD_BASE &&
+		    enable_rsa(info))
+			state->baud_base = SERIAL_RSA_BAUD_BASE;
+		if (state->baud_base == SERIAL_RSA_BAUD_BASE)
+			serial_outp(info, UART_RSA_FRR, 0);
+	}
+#endif
+
 	/*
 	 * Clear the FIFO buffers and disable them
 	 * (they will be reenabled in change_speed())
@@ -1199,7 +1271,8 @@
 	 * if it is, then bail out, because there's likely no UART
 	 * here.
 	 */
-	if (serial_inp(info, UART_LSR) == 0xff) {
+	if (!(info->flags & ASYNC_BUGGY_UART) &&
+	    (serial_inp(info, UART_LSR) == 0xff)) {
 		printk("LSR safety check engaged!\n");
 		if (capable(CAP_SYS_ADMIN)) {
 			if (info->tty)
@@ -1425,6 +1498,17 @@
 				     UART_FCR_CLEAR_XMIT));
 	serial_outp(info, UART_FCR, 0);
 
+#ifdef CONFIG_SERIAL_RSA
+	/*
+	 * Reset the RSA board back to 115kbps compat mode.
+	 */
+	if ((state->type == PORT_RSA) &&
+	    (state->baud_base == SERIAL_RSA_BAUD_BASE &&
+	     disable_rsa(info)))
+		state->baud_base = SERIAL_RSA_BAUD_BASE_LO;
+#endif
+	
+
 	(void)serial_in(info, UART_RX);    /* read data port to reset things */
 	
 	if (info->tty)
@@ -1522,6 +1606,12 @@
 	baud = tty_get_baud_rate(info->tty);
 	if (!baud)
 		baud = 9600;	/* B0 transition handled in rs_set_termios */
+#ifdef CONFIG_SERIAL_RSA
+	if ((info->state->type == PORT_RSA) &&
+	    (info->state->baud_base != SERIAL_RSA_BAUD_BASE) &&
+	    enable_rsa(info))
+		info->state->baud_base = SERIAL_RSA_BAUD_BASE;
+#endif
 	baud_base = info->state->baud_base;
 	if (info->state->type == PORT_16C950) {
 		if (baud <= baud_base)
@@ -1583,6 +1673,10 @@
 	if (uart_config[info->state->type].flags & UART_USE_FIFO) {
 		if ((info->state->baud_base / quot) < 2400)
 			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+#ifdef CONFIG_SERIAL_RSA
+		else if (info->state->type == PORT_RSA)
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
+#endif
 		else
 			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
 	}
@@ -1912,6 +2006,10 @@
 	tmp.type = state->type;
 	tmp.line = state->line;
 	tmp.port = state->port;
+	if (HIGH_BITS_OFFSET)
+		tmp.port_high = state->port >> HIGH_BITS_OFFSET;
+	else
+		tmp.port_high = 0;
 	tmp.irq = state->irq;
 	tmp.flags = state->flags;
 	tmp.xmit_fifo_size = state->xmit_fifo_size;
@@ -1933,14 +2031,19 @@
  	struct serial_state old_state, *state;
 	unsigned int		i,change_irq,change_port;
 	int 			retval = 0;
+	unsigned long		new_port;
 
 	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
 		return -EFAULT;
 	state = info->state;
 	old_state = *state;
-  
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += new_serial.port_high << HIGH_BITS_OFFSET;
+
 	change_irq = new_serial.irq != state->irq;
-	change_port = (new_serial.port != state->port) ||
+	change_port = (new_port != ((int) state->port)) ||
 		(new_serial.hub6 != state->hub6);
   
 	if (!capable(CAP_SYS_ADMIN)) {
@@ -1978,7 +2081,7 @@
 	if (new_serial.type) {
 		for (i = 0 ; i < NR_PORTS; i++)
 			if ((state != &rs_table[i]) &&
-			    (rs_table[i].port == new_serial.port) &&
+			    (rs_table[i].port == new_port) &&
 			    rs_table[i].type)
 				return -EADDRINUSE;
 	}
@@ -2005,8 +2108,14 @@
 	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) {
+#ifdef CONFIG_SERIAL_RSA
+		if (old_state.type == PORT_RSA)
+			release_region(state->port + UART_RSA_BASE, 16);
+		else
+#endif
 		release_region(state->port,8);
+	}
 	state->type = new_serial.type;
 	if (change_port || change_irq) {
 		/*
@@ -2015,15 +2124,22 @@
 		 */
 		shutdown(info);
 		state->irq = new_serial.irq;
-		info->port = state->port = new_serial.port;
+		info->port = state->port = new_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)");
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+#ifdef CONFIG_SERIAL_RSA
+		if (state->type == PORT_RSA)
+			request_region(state->port + UART_RSA_BASE,
+				       16, "serial_rsa(set)");
+		else
+#endif
+			request_region(state->port,8,"serial(set)");
+	}
 
 	
 check_and_exit:
@@ -2462,6 +2578,9 @@
 			/* note the counters on entry */
 			cprev = info->state->icount;
 			restore_flags(flags);
+			/* Force modem status interrupts on */
+			info->IER |= UART_IER_MSI;
+			serial_out(info, UART_IER, info->IER);
 			while (1) {
 				interruptible_sleep_on(&info->delta_msr_wait);
 				/* see if a signal did it */
@@ -3348,6 +3467,16 @@
 	 * LSR register (which serial_icr_read does)
 	 */
 	if (state->type == PORT_16550A) {
+		/*
+		 * EFR [4] must be set else this test fails
+		 *
+		 * This shouldn't be necessary, but Mike Hudson
+		 * (Exoray@isys.ca) claims that it's needed for 952
+		 * dual UART's (which are not recommended for new designs).
+		 */
+		serial_out(info, UART_LCR, 0xBF);
+		serial_out(info, UART_EFR, 0x10);
+		serial_out(info, UART_LCR, 0x00);
 		/* Check for Oxford Semiconductor 16C950 */
 		scratch = serial_icr_read(info, UART_ID1);
 		scratch2 = serial_icr_read(info, UART_ID2);
@@ -3434,7 +3563,8 @@
 
 	save_flags(flags); cli();
 	
-	if (!state->iomem_base) {
+	if (!(state->flags & ASYNC_BUGGY_UART) &&
+	    !state->iomem_base) {
 		/*
 		 * Do a simple existence test first; if we fail this,
 		 * there's no point trying anything else.
@@ -3459,8 +3589,9 @@
 		serial_outp(info, UART_IER, scratch);
 		if (scratch2 || scratch3 != 0x0F) {
 #ifdef SERIAL_DEBUG_AUTOCONF
-			printk("serial: ttyS%d: simple autoconfig failed\n",
-			       state->line);
+			printk("serial: ttyS%d: simple autoconfig failed "
+			       "(%02x, %02x)\n", state->line, 
+			       scratch2, scratch3);
 #endif
 			restore_flags(flags);
 			return;		/* We failed; there's nothing here */
@@ -3545,6 +3676,25 @@
 		}
 		serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
 	}
+#ifdef CONFIG_SERIAL_RSA
+	if (state->type == PORT_16550A) {
+		int i;
+
+		for (i = 0 ; i < PORT_RSA_MAX ; ++i) {
+			if (!probe_rsa[i] && !force_rsa[i])
+				break;
+			if (((probe_rsa[i] != state->port) ||
+			     check_region(state->port + UART_RSA_BASE, 16)) &&
+			    (force_rsa[i] != state->port))
+				continue;
+			if (!enable_rsa(info))
+				continue;
+			state->type = PORT_RSA;
+			state->baud_base = SERIAL_RSA_BAUD_BASE;
+			break;
+		}
+	}
+#endif
 	serial_outp(info, UART_LCR, save_lcr);
 	if (state->type == PORT_16450) {
 		scratch = serial_in(info, UART_SCR);
@@ -3564,12 +3714,23 @@
 		return;
 	}
 
-	if (info->port)
-		request_region(info->port,8,"serial(auto)");
+	if (info->port) {
+#ifdef CONFIG_SERIAL_RSA
+		if (state->type == PORT_RSA)
+			request_region(info->port + UART_RSA_BASE, 16,
+				       "serial_rsa(auto)");
+		else
+#endif
+			request_region(info->port,8,"serial(auto)");
+	}
 
 	/*
 	 * Reset the UART.
 	 */
+#ifdef CONFIG_SERIAL_RSA
+	if (state->type == PORT_RSA)
+		serial_outp(info, UART_RSA_FRR, 0);
+#endif
 	serial_outp(info, UART_MCR, save_mcr);
 	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
 				     UART_FCR_CLEAR_RCVR |
@@ -3614,7 +3775,7 @@
 
 static _INLINE_ int get_pci_port(struct pci_dev *dev,
 				  struct pci_board *board,
-				  struct serial_struct *state,
+				  struct serial_struct *req,
 				  int idx)
 {
 	unsigned long port;
@@ -3626,24 +3787,28 @@
 		base_idx += idx;
 
 	if (board->flags & SPCI_FL_REGION_SZ_CAP) {
-		max_port = PCI_BASE_REGION_SIZE(dev, base_idx) / 8;
+		max_port = pci_resource_len(dev, base_idx) / 8;
 		if (idx >= max_port)
 			return 1;
 	}
 			
-	port = PCI_BASE_ADDRESS(dev, base_idx) + board->first_uart_offset;
+	port = pci_resource_start(dev, base_idx) + board->first_uart_offset;
 
 	if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
 		port += idx * (board->uart_offset ? board->uart_offset : 8);
 
 	if (IS_PCI_REGION_IOPORT(dev, base_idx)) {
-		state->port = port;
+		req->port = port;
+		if (HIGH_BITS_OFFSET)
+			req->port_high = port >> HIGH_BITS_OFFSET;
+		else
+			req->port_high = 0;
 		return 0;
 	}
-	state->io_type = SERIAL_IO_MEM;
-	state->iomem_base = ioremap(port, board->uart_offset);
-	state->iomem_reg_shift = board->reg_shift;
-	state->port = 0;
+	req->io_type = SERIAL_IO_MEM;
+	req->iomem_base = ioremap(port, board->uart_offset);
+	req->iomem_reg_shift = board->reg_shift;
+	req->port = 0;
 	return 0;
 }
 
@@ -3670,23 +3835,28 @@
 				       struct pci_board *board)
 {
 	int k, line;
-	struct serial_struct fake_state;
+	struct serial_struct serial_req;
 	int base_baud;
 
        if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) {
-	       printk("SERIAL: PNP device '");
+	       printk("serial: PNP device '");
 	       printk_pnp_dev_id(board->vendor, board->device);
 	       printk("' prepare failed\n");
 	       return;
        }
 
        if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) {
-	       printk("SERIAL: PNP device '");
+	       printk("serial: PNP device '");
 	       printk_pnp_dev_id(board->vendor, board->device);
 	       printk("' activate failed\n");
 	       return;
        }
 
+       if (!(board->flags & SPCI_FL_ISPNP) && pci_enable_device(dev)) {
+	       printk("serial: PCI device enable failed\n");
+	       return;
+       }
+
 	/*
 	 * Run the initialization function, if any
 	 */
@@ -3710,18 +3880,18 @@
 	base_baud = board->base_baud;
 	if (!base_baud)
 		base_baud = BASE_BAUD;
-	memset(&fake_state, 0, sizeof(fake_state));
+	memset(&serial_req, 0, sizeof(serial_req));
 
 	for (k=0; k < board->num_ports; k++) {
-		fake_state.irq = get_pci_irq(dev, board, k);
-		if (get_pci_port(dev, board, &fake_state, k))
+		serial_req.irq = get_pci_irq(dev, board, k);
+		if (get_pci_port(dev, board, &serial_req, k))
 			break;
-		fake_state.flags = ASYNC_SKIP_TEST;
+		serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
 #ifdef SERIAL_DEBUG_PCI
 		printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
-		       fake_state.port, fake_state.irq, fake_state.io_type);
+		       serial_req.port, serial_req.irq, serial_req.io_type);
 #endif
-		line = register_serial(&fake_state);
+		line = register_serial(&serial_req);
 		if (line < 0)
 			break;
 		rs_table[line].baud_base = base_baud;
@@ -3742,28 +3912,45 @@
 #endif
 pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
 {
-	u8 data, *p, scratch;
+	u8 data, *p, irq_config;
+	int pci_config;
 
+	irq_config = 0x41;
+	pci_config = PCI_COMMAND_MEMORY;
+	if (dev->vendor == PCI_VENDOR_ID_PANACOM)
+		irq_config = 0x43;
+	if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
+	    (dev->device == PCI_VENDOR_ID_PLX_ROMULUS)) {
+		/*
+		 * As the megawolf cards have the int pins active
+		 * high, and have 2 UART chips, both ints must be
+		 * enabled on the 9050. Also, the UARTS are set in
+		 * 16450 mode by default, so we have to enable the
+		 * 16C950 'enhanced' mode so that we can use the deep
+		 * FIFOs
+		 */
+		irq_config = 0x5b;
+		pci_config = PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+	}
+	
 	pci_read_config_byte(dev, PCI_COMMAND, &data);
 
 	if (enable)
 		pci_write_config_byte(dev, PCI_COMMAND,
-				      data | PCI_COMMAND_MEMORY);
+				      data | pci_config);
 	
 	/* enable/disable interrupts */
-	p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80);
-	scratch = 0x41;
-	if (dev->vendor == PCI_VENDOR_ID_PANACOM)
-		scratch = 0x43;
-	writel(enable ? scratch : 0x00, (unsigned long)p + 0x4c);
+	p = ioremap(pci_resource_start(dev, 0), 0x80);
+	writel(enable ? irq_config : 0x00, (unsigned long)p + 0x4c);
 	iounmap(p);
 
 	if (!enable)
 		pci_write_config_byte(dev, PCI_COMMAND,
-				      data & ~PCI_COMMAND_MEMORY);
+				      data & ~pci_config);
 	return 0;
 }
 
+
 /*
  * SIIG serial cards have an PCI interface chip which also controls
  * the UART clocking frequency. Each UART can be clocked independently
@@ -3796,7 +3983,7 @@
 
        if (!enable) return 0;
 
-       p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80);
+       p = ioremap(pci_resource_start(dev, 0), 0x80);
 
        switch (dev->device & 0xfff8) {
                case PCI_DEVICE_ID_SIIG_1S_10x:         /* 1S */
@@ -3841,6 +4028,36 @@
        return 0;
 }
 
+/* Added for EKF Intel i960 serial boards */
+static int
+#ifndef MODULE
+__init
+#endif
+pci_inteli960ni_fn(struct pci_dev *dev,
+		   struct pci_board *board,
+		   int enable)
+{
+	unsigned long oldval;
+	
+	if (!(board->subdevice & 0x1000))
+		return(-1);
+
+	if (!enable) /* is there something to deinit? */
+		return(0);
+   
+#ifdef SERIAL_DEBUG_PCI
+	printk(KERN_DEBUG " Subsystem ID %lx (intel 960)\n",
+	       (unsigned long) board->subdevice);
+#endif
+	/* is firmware started? */
+	pci_read_config_dword(dev, 0x44, (void*) &oldval); 
+	if (oldval == 0x00001000L) { /* RESET value */ 
+		printk(KERN_DEBUG "Local i960 firmware missing");
+		return(-1); 
+	}
+	return(0);
+}
+
 
 /*
  * This is the configuration table for all of the PCI serial boards
@@ -3851,8 +4068,9 @@
 	 * Vendor ID, 	Device ID,
 	 * Subvendor ID,	Subdevice ID,
 	 * 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
+	 * Offset to get to next UART's registers,
+	 * Register shift to use for memory-mapped I/O,
+	 * Initialization function, first UART offset
 	 */
 	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
 		PCI_SUBVENDOR_ID_CONNECT_TECH,
@@ -3942,6 +4160,10 @@
 	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
 		PCI_ANY_ID, PCI_ANY_ID,
 		SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 },
+	/* VScom SPCOM800, from sl@s.pl */
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800, 
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE2, 8, 921600 },
 	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
 		PCI_SUBVENDOR_ID_KEYSPAN,
 		PCI_SUBDEVICE_ID_KEYSPAN_SX2,
@@ -3979,6 +4201,12 @@
 		PCI_SUBVENDOR_ID_CHASE_PCIRAS,
 		PCI_SUBDEVICE_ID_CHASE_PCIRAS8,
 		SPCI_FL_BASE2, 8, 460800 },
+	/* Megawolf Romulus PCI Serial Card, from Mike Hudson */
+	/* (Exoray@isys.ca) */
+	{	PCI_VENDOR_ID_PLX, PCI_VENDOR_ID_PLX_ROMULUS,
+		0x10b5, 0x106a,
+		SPCI_FL_BASE2, 4, 921600,
+		0x20, 2, pci_plx9050_fn, 0x03 },
 	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
 		PCI_ANY_ID, PCI_ANY_ID,
 		SPCI_FL_BASE1, 4, 115200 },
@@ -4164,7 +4392,7 @@
 		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 dougm@computone.com */
+	/* 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_BASE0, 4, 921600, /* IOMEM */
@@ -4198,6 +4426,11 @@
 	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
 		PCI_ANY_ID, PCI_ANY_ID,
 		SPCI_FL_BASE0, 4, 921600 },
+	/* EKF addition for i960 Boards form EKF with serial port */
+	{	PCI_VENDOR_ID_INTEL, 0x1960,
+		0xE4BF, PCI_ANY_ID,
+		SPCI_FL_BASE0, 32, 921600, /* max 256 ports */
+		8<<2, 2, pci_inteli960ni_fn, 0x10000},	  
 	/*
 	 * Untested PCI modems, sent in from various folks...
 	 */
@@ -4221,12 +4454,12 @@
 };
 
 /*
- * Given a complete unknown PCI device, try to use some hueristics to
+ * Given a complete unknown PCI device, try to use some heuristics to
  * guess what the configuration might be, based on the pitiful PCI
  * serial specs.  Returns 0 on success, 1 on failure.
  */
-static int _INLINE_ serial_guess_board(struct pci_dev *dev,
-				       struct pci_board *board)
+static int _INLINE_ serial_pci_guess_board(struct pci_dev *dev,
+					   struct pci_board *board)
 {
 	int	num_iomem = 0, num_port = 0, first_port = -1;
 	int	i;
@@ -4281,13 +4514,6 @@
 	printk(KERN_DEBUG "Entered probe_serial_pci()\n");
 #endif
   
-	if (!pcibios_present()) {
-#ifdef SERIAL_DEBUG_PCI
-		printk(KERN_DEBUG "Leaving probe_serial_pci() (no pcibios)\n");
-#endif
-		return;
-	}
-
 	pci_for_each_dev(dev) {
 		for (board = pci_boards; board->vendor; board++) {
 			if (board->vendor != (unsigned short) PCI_ANY_ID &&
@@ -4305,7 +4531,7 @@
 			break;
 		}
 	
-		if (board->vendor == 0 && serial_guess_board(dev, board))
+		if (board->vendor == 0 && serial_pci_guess_board(dev, board))
 			continue;
 		
 		start_pci_pnp_board(dev, board);
@@ -4322,13 +4548,13 @@
 #ifdef ENABLE_SERIAL_PNP
 
 static struct pci_board pnp_devices[] __initdata = {
-	/* Motorola VoiceSURFR 56K Modem */
-	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15F0), 0, 0,
-		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
 	/* Rockwell 56K ACF II Fax+Data+Voice Modem */
 	{	ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_NO_SHIRQ | SPCI_FL_PNPDEFAULT,
 		1, 115200 },
+	/* ASKEY 56K Plug&Play Modem */
+	{	ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x0000), 0, 0,
+		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
 	/* AZT3005 PnP SOUND DEVICE */
 	{	ISAPNP_VENDOR('A', 'Z', 'T'), ISAPNP_DEVICE(0x4001), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
@@ -4338,12 +4564,18 @@
 	/* Boca Research 33,600 ACF Modem */
 	{	ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x1400), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+	/* Davicom 33.6 PNP Modem */
+	{	ISAPNP_VENDOR('D', 'A', 'V'), ISAPNP_DEVICE(0x0336), 0, 0,
+		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
 	/* Creative Modem Blaster Flash56 DI5601-1 */
 	{	ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x1032), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
 	/* Creative Modem Blaster V.90 DI5660 */
 	{	ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x2001), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+	/* Motorola VoiceSURFR 56K Modem */
+	{	ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15F0), 0, 0,
+		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
 	/* Pace 56 Voice Internal Plug & Play Modem */
 	{	ISAPNP_VENDOR('P', 'M', 'C'), ISAPNP_DEVICE(0x2430), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
@@ -4356,6 +4588,9 @@
 	/* U.S. Robotics 56K FAX INT */
 	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3031), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+	/* U.S. Robotics 56k FAX INT */
+	{	ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3050), 0, 0,
+		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
 	/* Viking 56K FAX INT */
 	{	ISAPNP_VENDOR('R', 'S', 'S'), ISAPNP_DEVICE(0x0262), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
@@ -4373,6 +4608,10 @@
 	/* Generic 16550A-compatible COM port */
 	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0501), 0, 0,
 		SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+	/* Generic ISA PnP serial board */
+	{       0, 0, 0, 0,
+		SPCI_FL_BASE0 | SPCI_FL_NO_SHIRQ | SPCI_FL_PNPDEFAULT,
+		1, 115200 },
 	{	0, }
 };
 
@@ -4394,6 +4633,65 @@
 			irq->map = map;
 }
 
+static char *modem_names[] = {
+       "MODEM", "Modem", "modem", "FAX", "Fax", "fax",
+       "56K", "56k", "K56", "33.6", "28.8", "14.4",
+       "33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
+       "33600", "28800", "14400", "V.90", "V.34", "V.32", 0
+};
+
+static int check_name(char *name)
+{
+       char **tmp = modem_names;
+
+       while (*tmp) {
+               if (strstr(name, *tmp))
+                       return 1;
+               tmp++;
+       }
+       return 0;
+}
+
+/*
+ * Given a complete unknown ISA PnP device, try to use some heuristics to
+ * detect modems. Currently use such heuristic set:
+ *     - dev->name or dev->bus->name must contain "modem" substring;
+ *     - device must have only one IO region (8 byte long) with base adress
+ *       0x2e8, 0x3e8, 0x2f8 or 0x3f8.
+ *
+ * Such detection looks very ugly, but can detect at least some of numerous
+ * ISA PnP modems, alternatively we must hardcode all modems in pnp_devices[]
+ * table.
+ */
+static int _INLINE_ serial_pnp_guess_board(struct pci_dev *dev,
+                                          struct pci_board *board)
+{
+       struct isapnp_resources *res = (struct isapnp_resources *)dev->sysdata;
+       struct isapnp_resources *resa;
+
+       if (dev->active)
+               return 1;
+
+       if (!(check_name(dev->name) || check_name(dev->bus->name)))
+               return 1;
+
+       if (res->next)
+               return 1;
+
+       for (resa = res->alt; resa; resa = resa->alt) {
+               struct isapnp_port *port;
+               for (port = res->port; port; port = port->next)
+                       if ((port->size == 8) &&
+                           ((port->min == 0x2f8) ||
+                            (port->min == 0x3f8) ||
+                            (port->min == 0x2e8) ||
+                            (port->min == 0x3e8)))
+                               return 0;
+       }
+
+       return 1;
+}
+
 static void __init probe_serial_pnp(void)
 {
        struct pci_dev *dev = NULL;
@@ -4409,13 +4707,18 @@
                return;
        }
 
-       for (board = pnp_devices; board->vendor; board++) {
-               while ((dev = isapnp_find_dev(NULL, board->vendor,
-					     board->device, dev))) {
-			if (board->flags & SPCI_FL_NO_SHIRQ)
-				avoid_irq_share(dev);
-			start_pci_pnp_board(dev, board);
-               }
+       isapnp_for_each_dev(dev) {
+	       for (board = pnp_devices; board->vendor; board++)
+		       if ((dev->vendor == board->vendor) &&
+			   (dev->device == board->device))
+			       break;
+
+	       if (board->vendor == 0 && serial_pnp_guess_board(dev, board))
+		       continue;
+
+	       if (board->flags & SPCI_FL_NO_SHIRQ)
+		       avoid_irq_share(dev);
+	       start_pci_pnp_board(dev, board);
        }
 
 #ifdef SERIAL_DEBUG_PNP
@@ -4477,7 +4780,7 @@
 #if (LINUX_VERSION_CODE > 0x20100)
 	serial_driver.driver_name = "serial";
 #endif
-#ifdef CONFIG_DEVFS_FS
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
 	serial_driver.name = "tts/%d";
 #else
 	serial_driver.name = "ttyS";
@@ -4525,7 +4828,7 @@
 	 * major number and the subtype code.
 	 */
 	callout_driver = serial_driver;
-#ifdef CONFIG_DEVFS_FS
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
 	callout_driver.name = "cua/%d";
 #else
 	callout_driver.name = "cua";
@@ -4615,10 +4918,15 @@
 	unsigned long flags;
 	struct serial_state *state;
 	struct async_struct *info;
+	unsigned long port;
+
+	port = req->port;
+	if (HIGH_BITS_OFFSET)
+		port += req->port_high << HIGH_BITS_OFFSET;
 
 	save_flags(flags); cli();
 	for (i = 0; i < NR_PORTS; i++) {
-		if ((rs_table[i].port == req->port) &&
+		if ((rs_table[i].port == port) &&
 		    (rs_table[i].iomem_base == req->iomem_base))
 			break;
 	}
@@ -4636,11 +4944,11 @@
 	if (rs_table[i].count) {
 		restore_flags(flags);
 		printk("Couldn't configure serial #%d (port=%ld,irq=%d): "
-		       "device already open\n", i, req->port, req->irq);
+		       "device already open\n", i, port, req->irq);
 		return -1;
 	}
 	state->irq = req->irq;
-	state->port = req->port;
+	state->port = port;
 	state->flags = req->flags;
 	state->io_type = req->io_type;
 	state->iomem_base = req->iomem_base;
@@ -4648,7 +4956,7 @@
 	if (req->baud_base)
 		state->baud_base = req->baud_base;
 	if ((info = state->info) != NULL) {
-		info->port = req->port;
+		info->port = port;
 		info->flags = req->flags;
 		info->io_type = req->io_type;
 		info->iomem_base = req->iomem_base;
@@ -4721,10 +5029,10 @@
 	timer_table[RS_TIMER].expires = 0;
         remove_bh(SERIAL_BH);
 	if ((e1 = tty_unregister_driver(&serial_driver)))
-		printk("SERIAL: failed to unregister serial driver (%d)\n",
+		printk("serial: failed to unregister serial driver (%d)\n",
 		       e1);
 	if ((e2 = tty_unregister_driver(&callout_driver)))
-		printk("SERIAL: failed to unregister callout driver (%d)\n", 
+		printk("serial: failed to unregister callout driver (%d)\n", 
 		       e2);
 	restore_flags(flags);
 
@@ -4733,8 +5041,15 @@
 			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);
+		if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {
+#ifdef CONFIG_SERIAL_RSA
+			if (rs_table[i].type == PORT_RSA)
+				release_region(rs_table[i].port +
+					       UART_RSA_BASE, 16);
+			else
+#endif
+				release_region(rs_table[i].port, 8);
+		}
 #if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
 		if (rs_table[i].iomem_base)
 			iounmap(rs_table[i].iomem_base);
@@ -5023,6 +5338,6 @@
 
 /*
   Local variables:
-  compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce  -march=i686 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h   -DEXPORT_SYMTAB -c serial.c"
+  compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -D__SMP__ -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h   -DEXPORT_SYMTAB -c serial.c"
   End:
 */
===================================================================
RCS file: include/linux/RCS/serial.h,v
retrieving revision 1.1
diff -u -r1.1 include/linux/serial.h
--- include/linux/serial.h	2000/05/21 02:48:46	1.1
+++ include/linux/serial.h	2000/05/21 04:30:25
@@ -10,6 +10,7 @@
 #ifndef _LINUX_SERIAL_H
 #define _LINUX_SERIAL_H
 
+#ifdef __KERNEL__
 #include <asm/page.h>
 
 /*
@@ -27,10 +28,12 @@
  */
 #define SERIAL_XMIT_SIZE PAGE_SIZE
 
+#endif
+
 struct serial_struct {
 	int	type;
 	int	line;
-	unsigned long	port;
+	unsigned int	port;
 	int	irq;
 	int	flags;
 	int	xmit_fifo_size;
@@ -44,7 +47,8 @@
 	unsigned short	closing_wait2; /* no longer used... */
 	unsigned char	*iomem_base;
 	unsigned short	iomem_reg_shift;
-	int	reserved[2];
+	unsigned int	port_high;
+	int	reserved[1];
 };
 
 /*
@@ -70,7 +74,8 @@
 #define PORT_16C950	10	/* Oxford Semiconductor */
 #define PORT_16654	11
 #define PORT_16850	12
-#define PORT_MAX	12
+#define PORT_RSA	13	/* RSA-DV II/S card */
+#define PORT_MAX	13
 
 #define SERIAL_IO_PORT	0
 #define SERIAL_IO_HUB6	1
@@ -115,7 +120,10 @@
 
 #define ASYNC_LOW_LATENCY 0x2000 /* Request low latency behaviour */
 
-#define ASYNC_FLAGS	0x3FFF	/* Possible legal async flags */
+#define ASYNC_BUGGY_UART  0x4000 /* This is a buggy UART, skip some safety
+				  * checks.  Note: can be dangerous! */
+
+#define ASYNC_FLAGS	0x7FFF	/* Possible legal async flags */
 #define ASYNC_USR_MASK	0x3430	/* Legal flags that non-privileged
 				 * users can set or reset */
 
@@ -127,7 +135,9 @@
 #define ASYNC_CLOSING		0x08000000 /* Serial port is closing */
 #define ASYNC_CTS_FLOW		0x04000000 /* Do CTS flow control */
 #define ASYNC_CHECK_CD		0x02000000 /* i.e., CLOCAL */
-#define ASYNC_SHARE_IRQ		0x01000000 /* for multifunction cards */
+#define ASYNC_SHARE_IRQ		0x01000000 /* for multifunction cards
+					     --- no longer used */
+#define ASYNC_AUTOPROBE		0x00800000 /* Port was autoprobed */
 
 #define ASYNC_INTERNAL_FLAGS	0xFF000000 /* Internal flags */
 
===================================================================
RCS file: include/linux/RCS/serial_reg.h,v
retrieving revision 1.1
diff -u -r1.1 include/linux/serial_reg.h
--- include/linux/serial_reg.h	2000/05/21 02:48:46	1.1
+++ include/linux/serial_reg.h	2000/05/21 02:50:26
@@ -229,5 +229,54 @@
 #define UART_TRG_120	0x78
 #define UART_TRG_128	0x80
 
+/*
+ * These definitions are for the RSA-DV II/S card, from
+ *
+ * Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
+ */
+
+#define UART_RSA_BASE (-8)
+
+#define UART_RSA_MSR ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */
+
+#define UART_RSA_MSR_SWAP (1 << 0) /* Swap low/high 8 bytes in I/O port addr */
+#define UART_RSA_MSR_FIFO (1 << 2) /* Enable the external FIFO */
+#define UART_RSA_MSR_FLOW (1 << 3) /* Enable the auto RTS/CTS flow control */
+#define UART_RSA_MSR_ITYP (1 << 4) /* Level (1) / Edge triger (0) */
+
+#define UART_RSA_IER ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */
+
+#define UART_RSA_IER_Rx_FIFO_H (1 << 0) /* Enable Rx FIFO half full int. */
+#define UART_RSA_IER_Tx_FIFO_H (1 << 1) /* Enable Tx FIFO half full int. */
+#define UART_RSA_IER_Tx_FIFO_E (1 << 2) /* Enable Tx FIFO empty int. */
+#define UART_RSA_IER_Rx_TOUT (1 << 3) /* Enable char receive timeout int */
+#define UART_RSA_IER_TIMER (1 << 4) /* Enable timer interrupt */
+
+#define UART_RSA_SRR ((UART_RSA_BASE) + 2) /* IN: Status Read Register */
+
+#define UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0) /* Tx FIFO is not empty (1) */
+#define UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1) /* Tx FIFO is not half full (1) */
+#define UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2) /* Tx FIFO is not full (1) */
+#define UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3) /* Rx FIFO is not empty (1) */
+#define UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4) /* Rx FIFO is not half full (1) */
+#define UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5) /* Rx FIFO is not full (1) */
+#define UART_RSA_SRR_Rx_TOUT (1 << 6) /* Character reception timeout occured (1) */
+#define UART_RSA_SRR_TIMER (1 << 7) /* Timer interrupt occured */
+
+#define UART_RSA_FRR ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */
+
+#define UART_RSA_TIVSR ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */
+
+#define UART_RSA_TCR ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */
+
+#define UART_RSA_TCR_SWITCH (1 << 0) /* Timer on */
+
+/*
+ * The RSA DSV/II board has two fixed clock frequencies.  One is the
+ * standard rate, and the other is 8 times faster.
+ */
+#define SERIAL_RSA_BAUD_BASE (921600)
+#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8)
+
 #endif /* _LINUX_SERIAL_REG_H */
 
===================================================================
RCS file: include/linux/RCS/serialP.h,v
retrieving revision 1.1
diff -u -r1.1 include/linux/serialP.h
--- include/linux/serialP.h	2000/05/21 02:48:46	1.1
+++ include/linux/serialP.h	2000/05/21 04:30:47
@@ -24,6 +24,11 @@
 #include <linux/tqueue.h>
 #include <linux/circ_buf.h>
 #include <linux/wait.h>
+#if (LINUX_VERSION_CODE < 0x020300)
+/* Unfortunate, but Linux 2.2 needs async_icount defined here and
+ * it got moved in 2.3 */
+#include <linux/serial.h>
+#endif
 
 struct serial_state {
 	int	magic;
@@ -190,6 +195,9 @@
 /* Do not use irq sharing for this device */
 #define SPCI_FL_NO_SHIRQ	0x1000
 
-#define SPCI_FL_PNPDEFAULT	(SPCI_FL_IRQRESOURCE)
+/* This is a PNP device */
+#define SPCI_FL_ISPNP		0x2000
+
+#define SPCI_FL_PNPDEFAULT	(SPCI_FL_IRQRESOURCE|SPCI_FL_ISPNP)
 
 #endif /* _LINUX_SERIAL_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	2000/05/21 02:48:46	1.1
+++ include/linux/pci_ids.h	2000/05/21 02:49:45
@@ -542,6 +542,8 @@
 #define PCI_DEVICE_ID_DATABOOK_87144	0xb106
 
 #define PCI_VENDOR_ID_PLX		0x10b5
+#define PCI_VENDOR_ID_PLX_ROMULUS	0x106a
+#define PCI_DEVICE_ID_PLX_SPCOM800	0x1076
 #define PCI_DEVICE_ID_PLX_SPCOM200	0x1103
 #define PCI_DEVICE_ID_PLX_9050		0x9050
 #define PCI_DEVICE_ID_PLX_9060		0x9060

-
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/