Skip site navigation (1)Skip section navigation (2)
Date:      Sat,  5 Aug 2000 00:51:44 +0200 (CEST)
From:      frank@vogon.agala.net
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/20410: sio support for high speed NS16550A, ST16650A and TI16750 cards
Message-ID:  <20000804225144.0334446167@vogon.agala.net>

next in thread | raw e-mail | index | archive | help

>Number:         20410
>Category:       kern
>Synopsis:       sio support for high speed NS16550A, ST16650A and TI16750 cards
>Confidential:   yes
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Aug 04 16:00:03 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Frank J. Beckmann
>Release:        FreeBSD 4.1-STABLE i386
>Organization:
agala naga doron
>Environment:

FreeBSD 4.1-STABLE of 2000-08-04, and a high speed NS16550A, ST16650A or 
TI16750 card like the nice VScom 800 PRO or VScom 800/750 PRO from 
Vision Systems.

>Description:

The TI16750 and modern versions of the NS16550A support a higher clock
that makes 921600 bps possible. There are 16550A/16750 cards that support
up to 115200 bps, 230400 bps, 460800 bps or 921600 bps. Usually the
maximum speed is selectable per dip switch or eeprom. The sio driver
now supports this speeds, the flags for the device must match the
capabilities of the card.

The TI16750 supports RTS/CTS handshake in hardware and has 64 byte
fifos.

The ST16650A has a high speed mode with 460800 bps, the sio driver
now enables it. This is untested because i don't own a ST16650A.

You can now select any by the hardware supported baud rate.

The man page was a bit outdated, now it reflects reality (i hope).

>How-To-Repeat:

Try to use more than 115200 bps like it is needed for ISDN terminal
adapters or laser writers.

>Fix:


*** /usr/src/gnu/libexec/uucp/libunix/serial.c.orig	Sun Feb 27 23:10:04 2000
--- /usr/src/gnu/libexec/uucp/libunix/serial.c	Fri Aug  4 21:27:25 2000
***************
*** 920,927 ****
--- 920,945 ----
  #ifdef B115200
    { B115200, 115200 },
  #endif
+ #ifdef B153600
+   { B153600, 153600 },
+ #endif
+ #ifdef B184320
+   { B184320, 184320 },
+ #endif
  #ifdef B230400
    { B230400, 230400 },
+ #endif
+ #ifdef B276480
+   { B276480, 276480 },
+ #endif
+ #ifdef B307200
+   { B307200, 307200 },
+ #endif
+ #ifdef B460800
+   { B460800, 460800 },
+ #endif
+ #ifdef B921600
+   { B921600, 921600 },
  #endif
    { B0, 0 }
  };
*** /usr/src/share/man/man4/sio.4.orig	Fri Aug  4 21:18:00 2000
--- /usr/src/share/man/man4/sio.4	Fri Aug  4 21:17:38 2000
***************
*** 52,65 ****
  .Pp
  For AST compatible multiport cards with 4 ports:
  .Cd "options COM_MULTIPORT"
! .Cd "device sio4 at isa? port 0x2a0 flags 0x701"
! .Cd "device sio5 at isa? port 0x2a8 flags 0x701"
! .Cd "device sio6 at isa? port 0x2b0 flags 0x701"
  .Cd "device sio7 at isa? port 0x2b8 flags 0x701 irq 12"
  .Pp
  For Boca Board compatible multiport cards with 8 ports:
  .Cd "options COM_MULTIPORT"
! .Cd "device sio4 at isa? port 0x100 flags 0xb05"
  .Cd "..."
  .Cd "device sio11 at isa? port 0x138 flags 0xb05 irq 12"
  .Pp
--- 52,65 ----
  .Pp
  For AST compatible multiport cards with 4 ports:
  .Cd "options COM_MULTIPORT"
! .Cd "device sio4 at isa? port 0x2a0 flags 0x701 irq 12"
! .Cd "device sio5 at isa? port 0x2a8 flags 0x701 irq 12"
! .Cd "device sio6 at isa? port 0x2b0 flags 0x701 irq 12"
  .Cd "device sio7 at isa? port 0x2b8 flags 0x701 irq 12"
  .Pp
  For Boca Board compatible multiport cards with 8 ports:
  .Cd "options COM_MULTIPORT"
! .Cd "device sio4 at isa? port 0x100 flags 0xb05 irq 12"
  .Cd "..."
  .Cd "device sio11 at isa? port 0x138 flags 0xb05 irq 12"
  .Pp
***************
*** 69,95 ****
  .Pp
  Meaning of
  .Ar flags :
! .Bl -tag -offset indent -compact -width 0x000000
! .It 0x00001
  shared IRQs
! .It 0x00002
  disable FIFO
! .It 0x00004
  no AST/4 compatible IRQ control register
! .It 0x00008
  recover sooner from lost output interrupts
! .It 0x00010
  device is potential system console
! .It 0x00020
  device is forced to become system console
! .It 0x00040
  device is reserved for low-level IO (e. g. for remote kernel debugging)
! .It 0x00080
  use this port for remote kernel debugging
! .It 0x0 Ns Em ?? Ns 00
  minor number of master port
! .It 0x20000
! device is assumed to use a 16650A-type (extended FIFO) chip
  .El
  .Pp
  Minor numbering:
--- 69,105 ----
  .Pp
  Meaning of
  .Ar flags :
! .Bl -tag -offset indent -compact -width 0x00000000
! .It 0x00000001
  shared IRQs
! .It 0x00000002
  disable FIFO
! .It 0x00000004
  no AST/4 compatible IRQ control register
! .It 0x00000008
  recover sooner from lost output interrupts
! .It 0x00000010
  device is potential system console
! .It 0x00000020
  device is forced to become system console
! .It 0x00000040
  device is reserved for low-level IO (e. g. for remote kernel debugging)
! .It 0x00000080
  use this port for remote kernel debugging
! .It 0x0000 Ns Em ?? Ns 00
  minor number of master port
! .It 0x00010000
! device is assumed to use a TI16750-type (extended FIFO) chip
! .It 0x00020000
! device is assumed to use a ST16650A-type (extended FIFO) chip
! .It 0x00100000
! maximum line speed is 230400 bps (only NS16550A and TI16750)
! .It 0x00200000
! maximum line speed is 460800 bps (only NS16550A and TI16750)
! .It 0x00300000
! maximum line speed is 921600 bps (only NS16550A and TI16750)
! .It 0x Ns Em ?? Ns 000000
! fifo size of NS16550A compatible chip
  .El
  .Pp
  Minor numbering:
***************
*** 113,123 ****
  .Tn V.24 )
  communications interfaces.  The NS8250 and NS16450 have single character
  buffers, the NS16550A has 16 character FIFO input and output buffers.
  .Pp
! Input and output for each line may set to one of following baud rates;
! 50, 75, 110, 134.5, 150, 300, 600, 1200, 1800, 2400, 4800, 9600,
! 19200, 38400, 57600, or 115200. Your hardware may limit your baud
! rate choices.
  .Pp
  The driver supports `multiport' cards.
  Multiport cards are those that have one or more groups of ports
--- 123,134 ----
  .Tn V.24 )
  communications interfaces.  The NS8250 and NS16450 have single character
  buffers, the NS16550A has 16 character FIFO input and output buffers.
+ The ST16650A and the TI16750 have a buffer size of 32 respectively 64
+ characters.
  .Pp
! Input and output for each line may set to any by the hardware supported
! speed. The ST16650A supports up to 460800 bps, the NS16550A and the 
! TI16750 may support up to 921600 bps (see your hardware manual).
  .Pp
  The driver supports `multiport' cards.
  Multiport cards are those that have one or more groups of ports
***************
*** 160,171 ****
  The minor number of the device corresponding a master port
  for the group is encoded as a bitfield in the high byte.
  The same master port must be specified for all ports in a group.
- .Pp
- The
- .Em irq
- specification must be given for master ports
- and for ports that are not part of an IRQ sharing group,
- and not for other ports.
  .Pp
  In the synopsis,
  .Em flags 0x701
--- 171,176 ----
*** /usr/src/sys/isa/sio.c.orig	Fri Aug  4 20:38:54 2000
--- /usr/src/sys/isa/sio.c	Fri Aug  4 23:48:42 2000
***************
*** 128,139 ****
  #define	COM_LLCONSOLE(flags)	((flags) & 0x40)
  #define	COM_DEBUGGER(flags)	((flags) & 0x80)
  #define	COM_LOSESOUTINTS(flags)	((flags) & 0x08)
! #define	COM_NOFIFO(flags)		((flags) & 0x02)
! #define COM_ST16650A(flags)	((flags) & 0x20000)
! #define COM_C_NOPROBE		(0x40000)
! #define COM_NOPROBE(flags)	((flags) & COM_C_NOPROBE)
! #define COM_C_IIR_TXRDYBUG	(0x80000)
! #define COM_IIR_TXRDYBUG(flags)	((flags) & COM_C_IIR_TXRDYBUG)
  #define	COM_FIFOSIZE(flags)	(((flags) & 0xff000000) >> 24)
  
  #define	com_scr		7	/* scratch register for 16450-16550 (R/W) */
--- 128,141 ----
  #define	COM_LLCONSOLE(flags)	((flags) & 0x40)
  #define	COM_DEBUGGER(flags)	((flags) & 0x80)
  #define	COM_LOSESOUTINTS(flags)	((flags) & 0x08)
! #define	COM_NOFIFO(flags)	((flags) & 0x02)
! #define	COM_TL16750(flags)	((flags) & 0x10000)
! #define	COM_ST16650A(flags)	((flags) & 0x20000)
! #define	COM_C_NOPROBE		(0x40000)
! #define	COM_NOPROBE(flags)	((flags) & COM_C_NOPROBE)
! #define	COM_C_IIR_TXRDYBUG	(0x80000)
! #define	COM_IIR_TXRDYBUG(flags)	((flags) & COM_C_IIR_TXRDYBUG)
! #define	COM_CLOCK(flags)	(((flags) & 0x00300000) >> 20)
  #define	COM_FIFOSIZE(flags)	(((flags) & 0xff000000) >> 24)
  
  #define	com_scr		7	/* scratch register for 16450-16550 (R/W) */
***************
*** 206,211 ****
--- 208,214 ----
  	u_char	fifo_image;	/* copy of value written to FIFO */
  	bool_t	hasfifo;	/* nonzero for 16550 UARTs */
  	bool_t	st16650a;	/* Is a Startech 16650A or RTS/CTS compat */
+ 	bool_t	tl16750;	/* Is a Texas Instruments TL16750 */
  	bool_t	loses_outints;	/* nonzero if device loses output interrupts */
  	u_char	mcr_image;	/* copy of value written to MCR */
  #ifdef COM_MULTIPORT
***************
*** 218,223 ****
--- 221,227 ----
  	int	unit;		/* unit	number */
  	int	dtr_wait;	/* time to hold DTR down on close (* 1/hz) */
  	u_int	tx_fifo_size;
+ 	u_int	clock;		/* uart clock speed */
  	u_int	wopeners;	/* # processes waiting for DCD in open() */
  
  	/*
***************
*** 311,316 ****
--- 315,321 ----
  static	timeout_t comwakeup;
  static	void	disc_optim	__P((struct tty	*tp, struct termios *t,
  				     struct com_s *com));
+ static	int	getdivisor	__P((int clock, speed_t speed));
  
  #if NCARD > 0
  static	int	sio_pccard_attach __P((device_t dev));
***************
*** 419,446 ****
      = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle);
  static	int	sio_numunits;
  
- static	struct speedtab comspeedtab[] = {
- 	{ 0,		0 },
- 	{ 50,		COMBRD(50) },
- 	{ 75,		COMBRD(75) },
- 	{ 110,		COMBRD(110) },
- 	{ 134,		COMBRD(134) },
- 	{ 150,		COMBRD(150) },
- 	{ 200,		COMBRD(200) },
- 	{ 300,		COMBRD(300) },
- 	{ 600,		COMBRD(600) },
- 	{ 1200,		COMBRD(1200) },
- 	{ 1800,		COMBRD(1800) },
- 	{ 2400,		COMBRD(2400) },
- 	{ 4800,		COMBRD(4800) },
- 	{ 9600,		COMBRD(9600) },
- 	{ 19200,	COMBRD(19200) },
- 	{ 38400,	COMBRD(38400) },
- 	{ 57600,	COMBRD(57600) },
- 	{ 115200,	COMBRD(115200) },
- 	{ -1,		-1 }
- };
- 
  #ifdef COM_ESP
  /* XXX configure this properly. */
  static	Port_t	likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
--- 424,429 ----
***************
*** 448,453 ****
--- 431,476 ----
  #endif
  
  /*
+  * get divisor from speed
+  */
+ 
+ static int
+ getdivisor(int clock, speed_t speed)
+ {
+ 	int divisor;
+ 	speed_t diff, ldiff, udiff;
+ 
+ 	if (speed == 0)
+ 		return 0;
+ 	divisor = BPSDIV(clock, speed);
+ 	if (divisor == 0)
+ 		divisor = 1;
+ 	else if (divisor > 0xffff)
+ 		divisor = 0xffff;
+ 
+ 	/*
+ 	 * see if we got the requested speed
+ 	 */
+ 	if ((divisor == 0xffff) || (BPSDIVMOD(clock, speed) != 0)) {
+ 
+ 		/*
+ 		 * no, we didn't, now see if we are close enough
+ 		 */
+ 		udiff = BPSDIV(clock, divisor) - speed;
+ 		ldiff = speed - BPSDIV(clock, divisor + 1);
+ 		if ((ldiff < udiff) && (divisor < 0xffff)) {
+ 			diff = ldiff;
+ 			divisor++;
+ 		} else {
+ 			diff = udiff;
+ 		}
+ 		if ((diff > (10 * BPSDIV(clock, 1)) || (diff * 100 / speed) >= 1))
+ 			divisor = -1;
+ 	}
+ 	return divisor;
+ }
+ 
+ /*
   * handle sysctl read/write requests for console speed
   * 
   * In addition to setting comdefaultrate for I/O through /dev/console,
***************
*** 751,756 ****
--- 774,780 ----
  	u_long		xirq;
  	u_int		flags = device_get_flags(dev);
  	int		rid;
+ 	int		clock;
  	struct resource *port;
  
  	rid = xrid;
***************
*** 861,872 ****
  	 * XXX what about the UART bug avoided by waiting in comparam()?
  	 * We don't want to to wait long enough to drain at 2 bps.
  	 */
  	if (iobase == siocniobase)
  		DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
  	else {
  		sio_setreg(com, com_cfcr, CFCR_DLAB | CFCR_8BITS);
! 		sio_setreg(com, com_dlbl, COMBRD(SIO_TEST_SPEED) & 0xff);
! 		sio_setreg(com, com_dlbh, (u_int) COMBRD(SIO_TEST_SPEED) >> 8);
  		sio_setreg(com, com_cfcr, CFCR_8BITS);
  		DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
  	}
--- 885,902 ----
  	 * XXX what about the UART bug avoided by waiting in comparam()?
  	 * We don't want to to wait long enough to drain at 2 bps.
  	 */
+ 	if (COM_ST16650A(flags)) {
+ 		clock = STDSIOCLOCK * ST16650AMULT;
+ 		mcr_image |= MCR_HS;
+ 	} else {
+ 		clock = STDSIOCLOCK * (1 << COM_CLOCK(flags));
+ 	}
  	if (iobase == siocniobase)
  		DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
  	else {
  		sio_setreg(com, com_cfcr, CFCR_DLAB | CFCR_8BITS);
! 		sio_setreg(com, com_dlbl, BPSDIV(clock, SIO_TEST_SPEED) & 0xff);
! 		sio_setreg(com, com_dlbh, (u_int) BPSDIV(clock, SIO_TEST_SPEED) >> 8);
  		sio_setreg(com, com_cfcr, CFCR_8BITS);
  		DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
  	}
***************
*** 1142,1147 ****
--- 1172,1181 ----
  	com->tx_fifo_size = 1;
  	com->obufs[0].l_head = com->obuf1;
  	com->obufs[1].l_head = com->obuf2;
+ 	if (COM_ST16650A(flags))
+ 		com->clock = STDSIOCLOCK * ST16650AMULT;
+ 	else 
+ 		com->clock = STDSIOCLOCK * (1 << COM_CLOCK(flags));
  
  	com->data_port = iobase + com_data;
  	com->int_id_port = iobase + com_iir;
***************
*** 1214,1219 ****
--- 1248,1254 ----
  	sio_setreg(com, com_fifo, FIFO_ENABLE | FIFO_RX_HIGH);
  	DELAY(100);
  	com->st16650a = 0;
+ 	com->tl16750 = 0;
  	switch (inb(com->int_id_port) & IIR_FIFO_MASK) {
  	case FIFO_RX_LOW:
  		printf(" 16450");
***************
*** 1233,1238 ****
--- 1268,1277 ----
  				com->st16650a = 1;
  				com->tx_fifo_size = 32;
  				printf(" ST16650A");
+ 			} else if (COM_TL16750(flags)) {
+ 				com->tl16750 = 1;
+ 				com->tx_fifo_size = 64;
+ 				printf(" TL16750");
  			} else {
  				com->tx_fifo_size = COM_FIFOSIZE(flags);
  				printf(" 16550A");
***************
*** 1245,1251 ****
  				break;
  			}
  #endif
! 		if (!com->st16650a) {
  			if (!com->tx_fifo_size)
  				com->tx_fifo_size = 16;
  			else
--- 1284,1290 ----
  				break;
  			}
  #endif
! 		if (!com->st16650a && !com->tl16750) {
  			if (!com->tx_fifo_size)
  				com->tx_fifo_size = 16;
  			else
***************
*** 2297,2311 ****
  		t->c_ispeed = t->c_ospeed;
  
  	/* check requested parameters */
- 	divisor = ttspeedtab(t->c_ospeed, comspeedtab);
- 	if (divisor < 0 || (divisor > 0 && t->c_ispeed != t->c_ospeed))
- 		return (EINVAL);
- 
- 	/* parameters are OK, convert them to the com struct and the device */
  	unit = DEV_TO_UNIT(tp->t_dev);
  	com = com_addr(unit);
  	if (com == NULL)
  		return (ENODEV);
  	s = spltty();
  	if (divisor == 0)
  		(void)commctl(com, TIOCM_DTR, DMBIC);	/* hang up line */
--- 2336,2350 ----
  		t->c_ispeed = t->c_ospeed;
  
  	/* check requested parameters */
  	unit = DEV_TO_UNIT(tp->t_dev);
  	com = com_addr(unit);
  	if (com == NULL)
  		return (ENODEV);
+ 	divisor = getdivisor(com->clock, t->c_ospeed);
+ 	if (divisor < 0 || (divisor > 0 && t->c_ispeed != t->c_ospeed))
+ 		return (EINVAL);
+ 
+ 	/* parameters are OK, convert them to the com struct and the device */
  	s = spltty();
  	if (divisor == 0)
  		(void)commctl(com, TIOCM_DTR, DMBIC);	/* hang up line */
***************
*** 2334,2339 ****
--- 2373,2386 ----
  	if (cflag & CSTOPB)
  		cfcr |= CFCR_STOPB;
  
+ 	/*
+ 	 * This returns with interrupts disabled so that we can complete
+ 	 * the speed change atomically.  Keeping interrupts disabled is
+ 	 * especially important while com_data is hidden.
+ 	 */
+ 	(void) siosetwater(com, t->c_ispeed);
+ 	sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB);
+ 
  	if (com->hasfifo && divisor != 0) {
  		/*
  		 * Use a fifo trigger level low enough so that the input
***************
*** 2345,2350 ****
--- 2392,2399 ----
  		 */
  		com->fifo_image = t->c_ospeed <= 4800
  				  ? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_HIGH;
+ 		if (com->tl16750)
+ 			com->fifo_image |= FIFO_BIG;
  #ifdef COM_ESP
  		/*
  		 * The Hayes ESP card needs the fifo DMA mode bit set
***************
*** 2357,2371 ****
  		sio_setreg(com, com_fifo, com->fifo_image);
  	}
  
- 	/*
- 	 * This returns with interrupts disabled so that we can complete
- 	 * the speed change atomically.  Keeping interrupts disabled is
- 	 * especially important while com_data is hidden.
- 	 */
- 	(void) siosetwater(com, t->c_ispeed);
- 
  	if (divisor != 0) {
- 		sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB);
  		/*
  		 * Only set the divisor registers if they would change,
  		 * since on some 16550 incompatibles (UMC8669F), setting
--- 2406,2412 ----
***************
*** 2437,2442 ****
--- 2478,2494 ----
  		}
  	}
  
+ 	/*
+ 	 * Handle auto-RTS and auto-CTS in case of TL16C750
+ 	 */
+ 	if (com->tl16750) {
+ 		if ((cflag & CRTS_IFLOW) && (cflag & CCTS_OFLOW)) {
+ 			com->mcr_image |= MCR_AFE;
+ 		} else {
+ 			com->mcr_image &= ~MCR_AFE;
+ 		}
+ 	}
+ 
  	sio_setreg(com, com_cfcr, com->cfcr_image);
  
  	/* XXX shouldn't call functions while intrs are disabled. */
***************
*** 2836,2844 ****
  	u_char	mcr;
  };
  
! static speed_t siocngetspeed __P((Port_t, struct speedtab *));
  static void siocnclose	__P((struct siocnstate *sp, Port_t iobase));
! static void siocnopen	__P((struct siocnstate *sp, Port_t iobase, int speed));
  static void siocntxwait	__P((Port_t iobase));
  
  static cn_probe_t siocnprobe;
--- 2888,2897 ----
  	u_char	mcr;
  };
  
! static speed_t siocngetspeed __P((Port_t, int));
  static void siocnclose	__P((struct siocnstate *sp, Port_t iobase));
! static void siocnopen	__P((struct siocnstate *sp, Port_t iobase, int speed,
! 			     int clock));
  static void siocntxwait	__P((Port_t iobase));
  
  static cn_probe_t siocnprobe;
***************
*** 2884,2892 ****
   */
  
  static speed_t
! siocngetspeed(iobase, table)
  	Port_t iobase;
! 	struct speedtab *table;
  {
  	int	code;
  	u_char	dlbh;
--- 2937,2945 ----
   */
  
  static speed_t
! siocngetspeed(iobase, clock)
  	Port_t iobase;
! 	int clock;
  {
  	int	code;
  	u_char	dlbh;
***************
*** 2903,2920 ****
  
  	code = dlbh << 8 | dlbl;
  
! 	for (; table->sp_speed != -1; table++)
! 		if (table->sp_code == code)
! 			return (table->sp_speed);
! 
! 	return (0);	/* didn't match anything sane */
  }
  
  static void
! siocnopen(sp, iobase, speed)
  	struct siocnstate	*sp;
  	Port_t			iobase;
  	int			speed;
  {
  	int	divisor;
  	u_char	dlbh;
--- 2956,2973 ----
  
  	code = dlbh << 8 | dlbl;
  
! 	if (code == 0)
! 		return 0;
! 	else
! 		return BPSDIV(clock, code); /* BPSDIV works in both dirctions */
  }
  
  static void
! siocnopen(sp, iobase, speed, clock)
  	struct siocnstate	*sp;
  	Port_t			iobase;
  	int			speed;
+ 	int			clock;
  {
  	int	divisor;
  	u_char	dlbh;
***************
*** 2938,2944 ****
  	 * data input register.  This also reduces the effects of the
  	 * UMC8669F bug.
  	 */
! 	divisor = ttspeedtab(speed, comspeedtab);
  	dlbl = divisor & 0xFF;
  	if (sp->dlbl != dlbl)
  		outb(iobase + com_dlbl, dlbl);
--- 2991,2997 ----
  	 * data input register.  This also reduces the effects of the
  	 * UMC8669F bug.
  	 */
! 	divisor = getdivisor(clock, speed);
  	dlbl = divisor & 0xFF;
  	if (sp->dlbl != dlbl)
  		outb(iobase + com_dlbl, dlbl);
***************
*** 2985,2990 ****
--- 3038,3044 ----
  	u_char			cfcr;
  	int			s, unit;
  	struct siocnstate	sp;
+ 	int			clock;
  
  	/*
  	 * Find our first enabled console, if any.  If it is a high-level
***************
*** 3019,3026 ****
  				continue;
  			iobase = port;
  			s = spltty();
  			if (boothowto & RB_SERIAL) {
! 				boot_speed = siocngetspeed(iobase, comspeedtab);
  				if (boot_speed)
  					comdefaultrate = boot_speed;
  			}
--- 3073,3084 ----
  				continue;
  			iobase = port;
  			s = spltty();
+ 			if (COM_ST16650A(flags))
+ 				clock = STDSIOCLOCK * ST16650AMULT;
+ 			else
+ 				clock = STDSIOCLOCK * (1 << COM_CLOCK(flags));
  			if (boothowto & RB_SERIAL) {
! 				boot_speed = siocngetspeed(iobase, clock);
  				if (boot_speed)
  					comdefaultrate = boot_speed;
  			}
***************
*** 3037,3048 ****
  			cfcr = inb(iobase + com_cfcr);
  			outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
  			outb(iobase + com_dlbl,
! 			     COMBRD(comdefaultrate) & 0xff);
  			outb(iobase + com_dlbh,
! 			     (u_int) COMBRD(comdefaultrate) >> 8);
  			outb(iobase + com_cfcr, cfcr);
  
! 			siocnopen(&sp, iobase, comdefaultrate);
  
  			splx(s);
  			if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) {
--- 3095,3106 ----
  			cfcr = inb(iobase + com_cfcr);
  			outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
  			outb(iobase + com_dlbl,
! 			     BPSDIV(clock, comdefaultrate) & 0xff);
  			outb(iobase + com_dlbh,
! 			     (u_int) BPSDIV(clock, comdefaultrate) >> 8);
  			outb(iobase + com_cfcr, cfcr);
  
! 			siocnopen(&sp, iobase, comdefaultrate, clock);
  
  			splx(s);
  			if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) {
***************
*** 3092,3100 ****
  CONS_DRIVER(sio, NULL, NULL, NULL, siocngetc, siocncheckc, siocnputc, NULL);
  
  int
! siocnattach(port, speed)
  	int port;
  	int speed;
  {
  	int			s;
  	u_char			cfcr;
--- 3150,3159 ----
  CONS_DRIVER(sio, NULL, NULL, NULL, siocngetc, siocncheckc, siocnputc, NULL);
  
  int
! siocnattach(port, speed, clock)
  	int port;
  	int speed;
+ 	int clock;
  {
  	int			s;
  	u_char			cfcr;
***************
*** 3119,3130 ****
  	cfcr = inb(siocniobase + com_cfcr);
  	outb(siocniobase + com_cfcr, CFCR_DLAB | cfcr);
  	outb(siocniobase + com_dlbl,
! 	     COMBRD(comdefaultrate) & 0xff);
  	outb(siocniobase + com_dlbh,
! 	     (u_int) COMBRD(comdefaultrate) >> 8);
  	outb(siocniobase + com_cfcr, cfcr);
  
! 	siocnopen(&sp, siocniobase, comdefaultrate);
  	splx(s);
  
  	cn_tab = &sio_consdev;
--- 3178,3189 ----
  	cfcr = inb(siocniobase + com_cfcr);
  	outb(siocniobase + com_cfcr, CFCR_DLAB | cfcr);
  	outb(siocniobase + com_dlbl,
! 	     BPSDIV(clock, comdefaultrate) & 0xff);
  	outb(siocniobase + com_dlbh,
! 	     (u_int) BPSDIV(clock, comdefaultrate) >> 8);
  	outb(siocniobase + com_cfcr, cfcr);
  
! 	siocnopen(&sp, siocniobase, comdefaultrate, clock);
  	splx(s);
  
  	cn_tab = &sio_consdev;
***************
*** 3132,3140 ****
  }
  
  int
! siogdbattach(port, speed)
  	int port;
  	int speed;
  {
  	int			s;
  	u_char			cfcr;
--- 3191,3200 ----
  }
  
  int
! siogdbattach(port, speed, clock)
  	int port;
  	int speed;
+ 	int clock;
  {
  	int			s;
  	u_char			cfcr;
***************
*** 3157,3168 ****
  	cfcr = inb(siogdbiobase + com_cfcr);
  	outb(siogdbiobase + com_cfcr, CFCR_DLAB | cfcr);
  	outb(siogdbiobase + com_dlbl,
! 	     COMBRD(gdbdefaultrate) & 0xff);
  	outb(siogdbiobase + com_dlbh,
! 	     (u_int) COMBRD(gdbdefaultrate) >> 8);
  	outb(siogdbiobase + com_cfcr, cfcr);
  
! 	siocnopen(&sp, siogdbiobase, gdbdefaultrate);
  	splx(s);
  
  	return (0);
--- 3217,3228 ----
  	cfcr = inb(siogdbiobase + com_cfcr);
  	outb(siogdbiobase + com_cfcr, CFCR_DLAB | cfcr);
  	outb(siogdbiobase + com_dlbl,
! 	     BPSDIV(clock, gdbdefaultrate) & 0xff);
  	outb(siogdbiobase + com_dlbh,
! 	     (u_int) BPSDIV(clock, gdbdefaultrate) >> 8);
  	outb(siogdbiobase + com_cfcr, cfcr);
  
! 	siocnopen(&sp, siogdbiobase, gdbdefaultrate, clock);
  	splx(s);
  
  	return (0);
***************
*** 3185,3197 ****
  	Port_t	iobase;
  	int	s;
  	struct siocnstate	sp;
  
  	if (minor(dev) == siogdbunit)
  		iobase = siogdbiobase;
  	else
  		iobase = siocniobase;
  	s = spltty();
! 	siocnopen(&sp, iobase, comdefaultrate);
  	if (inb(iobase + com_lsr) & LSR_RXRDY)
  		c = inb(iobase + com_data);
  	else
--- 3245,3259 ----
  	Port_t	iobase;
  	int	s;
  	struct siocnstate	sp;
+ 	struct com_s		*com;
  
  	if (minor(dev) == siogdbunit)
  		iobase = siogdbiobase;
  	else
  		iobase = siocniobase;
+ 	com = com_addr(MINOR_TO_UNIT(minor(dev)));
  	s = spltty();
! 	siocnopen(&sp, iobase, comdefaultrate, com->clock);
  	if (inb(iobase + com_lsr) & LSR_RXRDY)
  		c = inb(iobase + com_data);
  	else
***************
*** 3210,3222 ****
  	Port_t	iobase;
  	int	s;
  	struct siocnstate	sp;
  
  	if (minor(dev) == siogdbunit)
  		iobase = siogdbiobase;
  	else
  		iobase = siocniobase;
  	s = spltty();
! 	siocnopen(&sp, iobase, comdefaultrate);
  	while (!(inb(iobase + com_lsr) & LSR_RXRDY))
  		;
  	c = inb(iobase + com_data);
--- 3272,3286 ----
  	Port_t	iobase;
  	int	s;
  	struct siocnstate	sp;
+ 	struct com_s		*com;
  
  	if (minor(dev) == siogdbunit)
  		iobase = siogdbiobase;
  	else
  		iobase = siocniobase;
+ 	com = com_addr(MINOR_TO_UNIT(minor(dev)));
  	s = spltty();
! 	siocnopen(&sp, iobase, comdefaultrate, com->clock);
  	while (!(inb(iobase + com_lsr) & LSR_RXRDY))
  		;
  	c = inb(iobase + com_data);
***************
*** 3232,3245 ****
  {
  	int	s;
  	struct siocnstate	sp;
  	Port_t	iobase;
  
  	if (minor(dev) == siogdbunit)
  		iobase = siogdbiobase;
  	else
  		iobase = siocniobase;
  	s = spltty();
! 	siocnopen(&sp, iobase, comdefaultrate);
  	siocntxwait(iobase);
  	outb(iobase + com_data, c);
  	siocnclose(&sp, iobase);
--- 3296,3311 ----
  {
  	int	s;
  	struct siocnstate	sp;
+ 	struct com_s		*com;
  	Port_t	iobase;
  
  	if (minor(dev) == siogdbunit)
  		iobase = siogdbiobase;
  	else
  		iobase = siocniobase;
+ 	com = com_addr(MINOR_TO_UNIT(minor(dev)));
  	s = spltty();
! 	siocnopen(&sp, iobase, comdefaultrate, com->clock);
  	siocntxwait(iobase);
  	outb(iobase + com_data, c);
  	siocnclose(&sp, iobase);
***************
*** 3254,3263 ****
  	Port_t	iobase;
  	int	s;
  	struct siocnstate	sp;
  
  	iobase = siogdbiobase;
  	s = spltty();
! 	siocnopen(&sp, iobase, gdbdefaultrate);
  	while (!(inb(iobase + com_lsr) & LSR_RXRDY))
  		;
  	c = inb(iobase + com_data);
--- 3320,3331 ----
  	Port_t	iobase;
  	int	s;
  	struct siocnstate	sp;
+ 	struct com_s		*com;
  
  	iobase = siogdbiobase;
+ 	com = com_addr(MINOR_TO_UNIT(minor(dev)));
  	s = spltty();
! 	siocnopen(&sp, iobase, gdbdefaultrate, com->clock);
  	while (!(inb(iobase + com_lsr) & LSR_RXRDY))
  		;
  	c = inb(iobase + com_data);
***************
*** 3272,3280 ****
  {
  	int	s;
  	struct siocnstate	sp;
  
  	s = spltty();
! 	siocnopen(&sp, siogdbiobase, gdbdefaultrate);
  	siocntxwait(siogdbiobase);
  	outb(siogdbiobase + com_data, c);
  	siocnclose(&sp, siogdbiobase);
--- 3340,3350 ----
  {
  	int	s;
  	struct siocnstate	sp;
+ 	struct com_s		*com;
  
+ 	com = com_addr(MINOR_TO_UNIT(minor(dev)));
  	s = spltty();
! 	siocnopen(&sp, siogdbiobase, gdbdefaultrate, com->clock);
  	siocntxwait(siogdbiobase);
  	outb(siogdbiobase + com_data, c);
  	siocnclose(&sp, siogdbiobase);
*** /usr/src/sys/isa/sioreg.h.orig	Sun Feb 27 19:09:02 2000
--- /usr/src/sys/isa/sioreg.h	Fri Aug  4 19:49:55 2000
***************
*** 40,45 ****
--- 40,47 ----
  #ifdef PC98
  #define	COMBRD_RSA(x)	(14745600 / (16*(x)))
  #endif
+ #define BPSDIV(f,x)	(f / (16*(x)))
+ #define BPSDIVMOD(f,x)	(f % (16*(x)))
  
  /* interrupt enable register */
  #define	IER_ERXRDY	0x1
***************
*** 62,67 ****
--- 64,70 ----
  #define	FIFO_RCV_RST	0x02
  #define	FIFO_XMT_RST	0x04
  #define	FIFO_DMA_MODE	0x08
+ #define	FIFO_BIG	0x20
  #define	FIFO_RX_LOW	0x00
  #define	FIFO_RX_MEDL	0x40
  #define	FIFO_RX_MEDH	0x80
***************
*** 82,87 ****
--- 85,92 ----
  #define	CFCR_5BITS	0x00
  
  /* modem control register */
+ #define	MCR_HS		0x40
+ #define	MCR_AFE		0x20
  #define	MCR_LOOPBACK	0x10
  #define	MCR_IENABLE	0x08
  #define	MCR_DRS		0x04
***************
*** 126,128 ****
--- 131,139 ----
  #ifndef CONSPEED
  #define CONSPEED 9600
  #endif
+ 
+ /* st16650a internal multiplier */
+ #define	ST16650AMULT	4
+ 
+ /* standard sio clock */
+ #define	STDSIOCLOCK	1843200
*** /usr/src/sys/sys/termios.h.orig	Sun Feb 27 23:48:45 2000
--- /usr/src/sys/sys/termios.h	Fri Aug  4 21:27:21 2000
***************
*** 225,231 ****
--- 225,236 ----
  #define B57600	57600
  #define B76800	76800
  #define B115200	115200
+ #define B153600	153600
+ #define B184320	184320
  #define B230400	230400
+ #define B307200	307200
+ #define B460800	460800
+ #define B921600	921600
  #define EXTA	19200
  #define EXTB	38400
  #endif  /* !_POSIX_SOURCE */


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000804225144.0334446167>