Subject: port-amiga/1475: Amiga internal allows wrong and forbids right baud settings
To: None <gnats-bugs@gnats.netbsd.org>
From: Ignatios Souvatzis <is@beverly.rhein.de>
List: netbsd-bugs
Date: 09/19/1995 09:37:34
>Number:         1475
>Category:       port-amiga
>Synopsis:       Amiga internal allows wrong and forbids right baud settings
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 19 04:05:02 1995
>Last-Modified:
>Originator:     Ignatios Souvatzis
>Organization:
	private
>Release:        950913
>Environment:
System: NetBSD beverly 1.0A NetBSD 1.0A (BEVERLY) #171: Tue Sep 19 08:47:25 MET DST 1995 is@beverly:/usr/src/sys/arch/amiga/compile/BEVERLY amiga


>Description:
	The Amiga builtin serial hardware can be set from about 110 bps 
to (theoretically) 3500000 bps, by adjusting a timer's divisor. The driver, however,
a) restricts the baud rates to the values in a table
b) allows 50bps and 75bps, giving wrong divisors for them.

E.g., setting the MIDI baud rate of 31250 (?) is impossible.

>How-To-Repeat:
	stty 50 < /dev/tty00; stty < /dev/tty00 outputs 50 (should give invalid parameter)
	stty 31250 < /dev/tty00; stty < /dev/tty00 outputs invalid parameter (should give 
		31250)

>Fix:

Apply this fix:

===================================================================
RCS file: RCS/ser.c,v
retrieving revision 1.1
diff -c -r1.1 ser.c
*** ser.c	1995/09/19 06:44:19	1.1
--- ser.c	1995/09/19 07:16:25
***************
*** 35,41 ****
   *	@(#)ser.c	7.12 (Berkeley) 6/27/91
   */
  /*
!  * XXX This file needs major cleanup it will never ervice more than one
   * XXX unit.
   */
  
--- 35,41 ----
   *	@(#)ser.c	7.12 (Berkeley) 6/27/91
   */
  /*
!  * XXX This file needs major cleanup it will never service more than one
   * XXX unit.
   */
  
***************
*** 99,128 ****
  struct	tty ser_cons;
  struct	tty *ser_tty[NSER];
  
- struct speedtab serspeedtab[] = {
- 	0,	0,
- 	50,	SERBRD(50),
- 	75,	SERBRD(75),
- 	110,	SERBRD(110),
- 	134,	SERBRD(134),
- 	150,	SERBRD(150),
- 	200,	SERBRD(200),
- 	300,	SERBRD(300),
- 	600,	SERBRD(600),
- 	1200,	SERBRD(1200),
- 	1800,	SERBRD(1800),
- 	2400,	SERBRD(2400),
- 	4800,	SERBRD(4800),
- 	9600,	SERBRD(9600),
- 	19200,	SERBRD(19200),
- 	38400,	SERBRD(38400),
- 	57600,	SERBRD(57600),
- 	76800,	SERBRD(76800),
- 	115200,	SERBRD(115200),
- 	-1,	-1
- };
- 
- 
  /* 
   * Since this UART is not particularly bright (to put it nicely), we'll
   * have to do parity stuff on our own.	This table contains the 8th bit
--- 99,104 ----
***************
*** 694,702 ****
  	
  	cflag = t->c_cflag;
  	unit = SERUNIT(tp->t_dev);
- 	ospeed = ttspeedtab(t->c_ospeed, serspeedtab);
  
! 	if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
  		return(EINVAL);
  
  	/* 
--- 670,683 ----
  	
  	cflag = t->c_cflag;
  	unit = SERUNIT(tp->t_dev);
  
! 	if (t->c_ospeed > 0) {
! 		if (t->c_ospeed < 110)
! 			return(EINVAL);
! 		ospeed = SERBRD(t->c_ospeed);
! 	}
! 
! 	if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
  		return(EINVAL);
  
  	/* 
***************
*** 712,718 ****
  	custom.intena = INTF_SETCLR | INTF_RBF | INTF_TBE;
  	last_ciab_pra = ciab.pra;
  
! 	if (ospeed == 0)
  		(void)sermctl(tp->t_dev, 0, DMSET);	/* hang up line */
  	else {
  		/* 
--- 693,699 ----
  	custom.intena = INTF_SETCLR | INTF_RBF | INTF_TBE;
  	last_ciab_pra = ciab.pra;
  
! 	if (t->c_ospeed == 0)
  		(void)sermctl(tp->t_dev, 0, DMSET);	/* hang up line */
  	else {
  		/* 
***************
*** 1014,1020 ****
  	/*
  	 * might want to fiddle with the CIA later ???
  	 */
! 	custom.serper = ttspeedtab(rate, serspeedtab);
  	splx(s);
  }
  
--- 995,1001 ----
  	/*
  	 * might want to fiddle with the CIA later ???
  	 */
! 	custom.serper = (rate>=110 ? SERBRD(rate) : 0);
  	splx(s);
  }
  
>Audit-Trail:
>Unformatted:
Ignatios Souvatzis