Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 May 1995 12:55:12 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        hackers@FreeBSD.org, peter@haywire.DIALix.COM
Subject:   Re: aargh! How to handle 128 ttys on a system?
Message-ID:  <199505290255.MAA24888@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>I have a Specialix SI and XIO driver running on a FreeBSD-current box 
>here.  There's only one problem..    It supports up to 128 ports per host 
>- how the !@#^&% does one use meaningful names for them all without 
>colliding with some other driver?

Find all programs that depend on ttys being named tty?? and fix them.

>Also, the probe/attach only leaves the card in a quiescent state. I'm
>using a user mode program the uploads the firmware for the host controller
>and booting it in /etc/rc*.  This step also configures the port array. 
>Was there a decision made on the best place to put these during the boot 
>sequence?

No, but if serial lines are used for networking, then they must be
initialized very early, before /etc/netstart is run.

>I still have an unresolved problem though.. I'm getting an obscure panic 
>after a line is hung while being flow control blocked..  Something like: 
>"putc to a clist with no reserved cblocks" or something like that.  My first 
>browse over the code doesn't pick up anything obvious yet.  It appears to 
>be happening after DCD goes up after getty has done a blocking open in 
>carrier wait.  I'm wondering if it's some peculiar variation between the 
>different clist implementations of different OS's.

The clist reservation stuff is nonstandard.  Drivers shouldn't be affected
by it unless they do something wrong.  In your case the driver apparently
calls l_rint() after DCD goes up but before it calls l_open().  The clists
aren't fully allocated until l_open() is called (and logically go away when
l_close() is called).  TS_ISOPEN tells you if the first l_open() has been
called; running at spltty() throughout TIOCSETD and close() should prevent
l_rint() being called after l_close() has been called.

>One more thing.. I really dont want to statically allocate 256 tty 
>structures (attached printer support..) at compile, when in fact there 
>may be as little as 4 ports present at boot.  I had a look at the other 
>drivers, and there seems to be some sort of taboo on dynamically 
>allocating the tty structure..  Things like:
>#if __FreeBSD__ >= 2
>/* cant dynamically allocate ttys yet */
>#else /* bsdi || FreeBSD 1.x || netbsd */
>... code to allocate the tty structures ....
>#endif
>and so on.  What gives?

ttselect() used to require an array of tty structs.  It no longer does,
but the drivers haven't been changed.  More annoyingly, parts of the
tty struct need to live across closes, so you can never deallocate a
tty struct.  Dynamic allocation isn't free, and it would be silly to
have lots of physical ports without ever using them, so static allocation
works better in most cases.  It only loses when there might be a huge
number of ports (128) and you want to allocate the maximum number
statically, but most target systems don't have that many ports.

>OBTW: How many minor numbers can I have?  I snooped in /dev and found 

Minor numbers are 23 bits (there are various bugs if the high bit is
used, starting with mknod(8) using atoi() to convert its args.  atoi()
provides no error checking and is based on strtol(), which truncates
all numbers >= 0x80000000 to 0x7fffffff).

>some unit numbers up in the high millions...  This would be really nice 
>if I dont have to try and resort to multiple major's.  Currently, there 
>is a maximum of 128 ports.  It currenty uses a single minor per port, 
>which is configured to optionally hotwire DCD for terminals. There are no 
>cua ports.  and there is a control minor.  To fit that in, the driver 
>currently only allows 31 of the ports on the 4'th host card to be used.  
>There's no room to spare if there's 256 minors supported.  (the minor() 
>macro in <sys/types.h> is certainly.. umm.. "interesting.." ).  it might 
>make sense to use the lower 8 bits as a port number, and bits 16 upwards 
>as a "type"..  0 = modem, 1 = terminal (DCD ignored), 2 = transparent 
>print, 3 = (maybe) cua and so on.  Does that sound reasonable?

I'd say to use type bits from the top down except for other problems
with large minor numbers: tar only supports 18 bit minor numbers and
silently truncates bits 18-31; cpio for the default format only
supports 8 bit minor numbers and silently truncates bits 8-31 (cpio
works right for some non-default formats); pax loses the same as the
worst cpio format.  The tar limit would not be so much of a problem
if minor numbers were contiguous.

I hope all FreeBSD tty drivers will support the same control interface:

	1 bit in minor number: cua select
	2 bits in minor number: control select
				00 = normal port
				01 = initial state port
				02 = lock state port
				03 = spare (status port?)

Special behaviours modem/terminal/transparent print/cua can be programmed
into internal state bits in the initial and lock state ports.  This is
more flexible.  You can still encode the behaviour in other minor bits by
programming the initial and lock state ports, except possibly cua behaviour
which requires special handling of sleeping opens on the non-cua port.
(Aliased ports requires special handling too - what do you do if there is
an open sleeping waiting for DCD on the modem port when something attempts
to open the ignore-DCD port?  The cua handling of putting the sleeping
open into a deeper sleep seems best.)

>IMHO: CUA ports are a crude hack which suck pretty badly.  I really dont 

Some users like them.  You have a special application.

Bruce



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