*BSD News Article 28602


Return to BSD News archive

Xref: sserve comp.os.386bsd.questions:9378 comp.os.386bsd.misc:2083
Newsgroups: comp.os.386bsd.questions,comp.os.386bsd.misc,relcom.fido.ru.unix
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!pacbell.com!ihnp4.ucsd.edu!agate!howland.reston.ans.net!pipex!sunic!EU.net!news.eunet.fi!KremlSun!kiae!relcom!elvisti!fbsd
From: fbsd@elvisti.ua
Subject: [FAQ] FreeBSD beginner's guide to 'sio' and modem stuff
Organization: Elektronni Visti
Date: Fri, 18 Mar 1994 02:32:44 GMT
Message-ID: <1994Mar18.023244.512@elvisti.ua>
X-Newsreader: TIN [version 1.2 PL1]
Lines: 645

Hi all!

The history of this tutorial looks like this. A few month ago some
people who made attempts to set up FreeBSD 1.0 OS, were stucked with
some strange problems - 'sio' and multiport stuff didn't work.
One of them was Terry Dwyer (Australia), who summarized the experience
of successfull bringing up FreeBSD 'sio' devices in the form of
some 'beginner's guide' (maybe this will be in a FAQ list?)
Great thanks to him for his efforts!

In any case, seeing the questions about FreeBSD and (sio, multiport cards,
modems) again and again, I'm posting this to all. Please, read and enjoy!
Additions/comments/fixes are welcome!

			Yours -- Andrew Stesin, Kiev.

Note: with FreeBSD 1.1 some changes in 'sio' staff will take place -
      for example, code is added for support multiple multiport cards.
      Today I have only FreeBSD 1.0.2, so - excuse me! When the new
      things will come to us, this text, of course, will be updated.
      But this edition is also applicable :)

--------------------------------------------------------------------------

From: Terry Dwyer <tdwyer@netbsd08.dn.itg.telecom.com.au>

						/usr/tdwyer/comm-tut

Setting up comm ports for FreeBSD-1.0.2

Thanks to "Andrew V. Stesin" <stesin@elvisti.kiev.ua> for explaining
the `flags=0xNNN' in the system config, it's workings in the serial 
port driver and for constructive criticism of this document.

To Piero Serini <piero@strider.st.dsi.unimi.it> who pooled some 
knowledge with me and pestered some of those people who seem to know
how to configure the AST card but have _never_ documented this in detail.

Thanks to Guenter Jung <gjung@gjbsd.franken.de>  
and Wilko Bulte <wilko@idca.tds.philips.nl> For help with the kernel
config options for the AST 4 port card.

Thanks to Jim Haldane <haldanej@netbsd08> for reading the AST card manual
and picking up the switch setting that I and an (obviously) large number
of others missed.

I will be pretty basic with the explanation of how to set up your
serial ports.  I don't want to assume that anyone knows all about this 
sio stuff, I just want to explain this so anyone can use it.

----------------------------------------------------------------------
STANDARD comm ports
----------------------------------------------------------------------

First the device names:

I use tty00 for the mouse and tty01 for the dialin modem port.

crw-r--r--    1 uucp     wheel     28,   0 Jan 16 12:11 /dev/tty00
crw-r--r--    1 uucp     wheel     28,   1 Jan 16 09:36 /dev/tty01

These are the companion dialout ports.

crw-------    1 uucp     wheel     28, 128 Dec 25 15:37 /dev/ttyd00
crw-------    1 uucp     wheel     28, 129 Jan 16 17:41 /dev/ttyd01

Note the correspondence between port pairs.  the major numbers (28) 
are the same, the minors are different.  For dialout, they have 128
added to them.

These port pairs go together.  tty01/ttyd01 are a pair.  tty01 is used for 
the getty, (dialin port), ttyd01 is used to make an outgoing call.

A lot of people call the dialout ports cua[0-n].  I call my dialout 
ports ttyd01 (etc.) so I can do a `ps -td01' and see what's going on.


----------------------------------------------------------------------
OWNERSHIP and PERMISSIONS
----------------------------------------------------------------------

Please note:

The ownership of these devices is important.  cu, which I use in
preference to tip, requires that ownership be set as above for proper
operation.

suid bit must be set for cu.   as root:	chmod 4555 /usr/bin/cu
it should look like this after you chmod it:

-r-sr-xr-x    1 uucp     bin        188416 Oct 28 13:05 /usr/bin/cu

[ Note that this is how I got _my_ comm stuff to work - not how it  ]
[ would be set up by more knowledgeable people.                     ]


----------------------------------------------------------------------
MAKEDEV to setup the device files
----------------------------------------------------------------------

To make the comm port pairs with the names _I_ liked, I modified the 
script that makes the devices; /dev/MAKEDEV
If you like you can copy this over the similar section of the script and 
make life easier for yourself.

sio*|tty*)
        unit=`expr $i : '...\(.*\)'`
        rm -f tty0$unit
        mknod tty0$unit c 28 $unit
        chown uucp.wheel tty0$unit
        # makes dialout devices
        dunit=`expr $unit + 128`
        rm -f ttyd0$unit
        mknod ttyd0$unit c 28 $dunit
        chown uucp.wheel ttyd0$unit
        ;;


To make the devices, cd to /dev, then,  as root `sh MAKEDEV sio0' for
each device you want to make changing the number of the device for each
iteration: sio0 sio1...

This will make a pair of devices for each invocation:
/dev/tty00  +  /dev/ttyd00
...


----------------------------------------------------------------------
GETTY for calling in
----------------------------------------------------------------------

Now /etc/ttys

To allow calling in to your machine, the port you connect the modem to
must be set up correctly.

The appropriate lines in /etc/ttys are below:

# Standard COM1 and COM2
# tty00 "/usr/libexec/getty D9600"      mouse off             secure
tty01 "/usr/libexec/getty D9600"      unknown on              secure
^^^^

Remember tty01 is the dialin side of the pair of devices.
This is what we will be setting up here.



----------------------------------------------------------------------
GETTYTAB to set the dialin line characteristics
----------------------------------------------------------------------

You should modify /etc/gettytab for no parity (:np:), this is not
documented in the GETTYTAB(5) man page.

#
#Modem with fixed-baud interface (19200)
#
D19200:\
        :np:to#30:hc:tc=19200-baud:

#
#Modem with fixed-baud interface (9600)
#
D9600:\
        :np:to#30:hc:tc=9600-baud:

The section of the line above `:tc=9600-baud:' extends this (incomplete)
definition to include the other `9600-baud' entry in /etc/gettytab.
The entry `9600-baud' would be a normal terminal connected to the same
serial port.  It would not then need the D9600 as well.

This should be easy enough to work out for your machine.  Just remember,
in /etc/ttys, where you specify the getty, you must nominate one that 
has been set up for a modem.  Examples of these are the Dnnnn entries.


----------------------------------------------------------------------
/ETC/RC sets up the modem control and bidirectional ports
----------------------------------------------------------------------

The final touch is to set your modem port up so you can dial out _while_ 
there is a getty on the other half of the pair of ports...

edit your /etc/rc _BEFORE_ the line that runs inetd

echo -n 'setting comm ports...'
echo -n 'port 1 ' ; stty -f /dev/tty01 -clocal crtscts ; comcontrol 
/dev/tty01 bidir

[ NOTE: the line above is one line - it has been wrapped by the text 
editor ]

	tty01 is the second comm port, the first, in my example, is
	used by the mouse.

The device you are setting is the _DIALIN_ side of the comm port pair.
You don't have to do this for the _DIALOUT_ side of the pair.

To test with your modem attached to the second (standard) comm port:

	cu -l /dev/ttyd01 -s 9600 dir
                             ^^^^
You must set the baud rate of your modem here.



----------------------------------------------------------------------
KERNEL configuration
----------------------------------------------------------------------

----------------------------------------------------------------------
BIDIRECTIONAL kernel option
----------------------------------------------------------------------
Now your system's config (/sys/i386/conf/MACHINENAME)

#Standard comm ports
device          sio0    at isa? port "IO_COM1" tty irq 4 vector siointr
device          sio1    at isa? port "IO_COM2" tty irq 3 vector siointr


To include support for bidirectional capability in your kernel.
Add the line below to your /sys/i386/conf/MACHINENAME

options		"COM_BIDIR"

By the way, sio0 is the name the kernel uses to refer to the 
dialin/dialout pair of ports /dev/tty00 and /dev/ttyd00


----------------------------------------------------------------------
MULTIPORT kernel option
----------------------------------------------------------------------

If you have a multiport card, and want to configure it in, there are a 
few things you must change:

Add the line below to your /sys/i386/conf/MACHINENAME

options		"COM_MULTIPORT"

You must then configure the multiport `sio' devices into the kernel.  A 
likely place for these entries would be just below the entries for the 
standard com ports.  Insert these lines:

# AST 4 Port configuration
device          sio2    at isa? port 0x2a0 tty irq 5 flags 0x501 vector siointr
device          sio3    at isa? port 0x2a8 tty flags 0x501 vector siointr
device          sio4    at isa? port 0x2b0 tty flags 0x501 vector siointr
device          sio5    at isa? port 0x2b8 tty flags 0x501 vector siointr


The explanation as to how the `flags 0xn01' is arrived at, courtesy of
Andrew Stesin:

[
#       a) non-zero in hi-byte of flags indicates master port;
#          this is used by 'sio.c' code to find master.
#          Today I assume the 1-st port - sio2 to be master;
#	   in 'sio.c' of the version I have, this is enough - ports
#	   are scanned by interrupt handler startin from sio2.
#	   For a newer release of 'sio' see Terry's explanation,
#	   mine is slightly out of date.
#       b) every chip in the card must have the low bit switched on in
#          it's corresponding flags; 'sio.c' uses this bit to determine,
#          that the port is a part of muliport device;
]


My understanding of how this works as follows:

Part of this came from Wilko Bulte's new sio man page but was modified by me.

   For multiport cards the flags keyword in the kernel configuration file
   is determine by the minor device number to which it is assigned, and 
   whether the port is part of a multiport card. The master device is the
   port which has the register through which all interrupts of the card are
   funneled.  All ports of a multiport card report pending interrupts using
   this single register.

   In this example, flags 0x0501 means that the master device is 
   configured in the kernel as sio5, Minor device Number 5, (the 
   MSB of the flags), and that the ports (01) are part of a multiport
   card, (the LSB of the flags).  Actually only the LS bit is used to 
   indicate this.  This config infers that the multiport range for 
   this (AST type) card would start at sio2 and end at sio5.  Which port
   is the master device depends on the card type. Consult the hardware 
   documentation for your card to obtain this info.  Because of the 
   numbering used for this example, it may be inferred that there are two
   other (standard) comm ports occupying sio0 and sio1, sio2 to sio5 being
   used for the AST card.

end paraphrase.


The flags 0x501 can be in _any_ of the `sio' config lines for the card.
The reason for this is that when an interrupt is generated by the card,
the interrupt service routine reads from a defined address 02BFH for 
address settings 02A0H-02A7H upwards and 01BFH for address settings 
1A0H-01A7H upwards  these are determined by the setting of SW3-2

Don't bother looking in the FAQ for this.  It isn't there.  
Some of this info _should_ also go in sio.c 


----------------------------------------------------------------------------
AST 4 PORT CARD problems
----------------------------------------------------------------------------

Note the symptoms below.  If you had this problem, please let me
know.  I suspect there is a load of people who have had seen the 
effect described below.

The problem I always had was this "delayed echo' effect.  I would connect 
to the modem:

	cu -l /dev/ttyd02 -s 9600 dir		# all OK so far!
	connected				# nice of it to tell me
	I send   I see
        ------   -----
	a	<<<<<not a bloody thing>>>>>
	t	a
	i	t
	7	i
	<CR>	7
	<CR>	lots of RX data, but _nothing_ on the screen.
		The modem sends a page of output for 6 or 7 <CR>'s.
		I would expect this, ati7 is a method to get my modem
		to dump everything it knows about itself to the
		terminal that is connected to it.
	<CR>...


This was my own dumb fault, but see below...


----------------------------------------------------------------------------
AST 4 PORT CARD switch settings
----------------------------------------------------------------------------

On my genuine AST 4 port card the switch layout is like this:
SW1 and SW2 are double width dip switches. SW3 is normal size.

 "O" indicates position of switch (on or off)

	        SW1                 SW2                  SW3

	   1     2     3         1     2     3       1   2   3   4
    ON  -------------------   -------------------  -----------------
     ^  |  O  |     |     |   |     |     |     |  | O | O | O |   |
     |  |     |  O  |  O  |   |  O  |  O  |  O  |  |   |   |   | O |
    OFF -------------------   -------------------  -----------------

------------------Bottom of card---------------------------------------|
                                                                       |
These are the DEFAULT settings                                         |
                                                        Edge Connector |_____
                                                                        

                SW1                 SW2                  SW3
           
           1     2     3         1     2     3       1   2   3   4  
    ON  -------------------   -------------------  -----------------
     ^  |     |     |     |   |  O  |     |     |  |   | O | O |   |
     |  |  O  |  O  |  O  |   |     |  O  |  O  |  | O |   |   | O |
    OFF -------------------   -------------------  -----------------

------------------Bottom of card---------------------------------------|
                                                                       |
These are MY working settings                                          |
                                                        Edge Connector |_____
	   ^     ^     ^         ^     ^     ^       ^   ^   ^   ^
	   |     |     |         |     |     |       |   |   |   |
If ON     IRQ2  IRQ3  IRQ4      IRQ5  IRQ6  IRQ7     |   |   |   |
                                                     |   |   |   |
                    Compatible mode turned off! <----+   |   |   |
          I/O addresses selected by this switch <--------+   |   |
          on = 02A0H , off = 01A0H (port 1 base addr)        |   |
        Interrupt Sharing Disabled - MUST be on <------------+   |
                         Reserved - Must be off <----------------+


The only REALLY important switch here is SW3-3 this is what 
confused me up for so long.  *** IT MUST BE ON ***  

I _had_ looked at the manual, and the section on this switch is really 
badly written.  There is no mention of what will happen of you use it 
without having a _SECOND_ AST card in the _SAME_ machine using the _SAME_ 
interrupt line.  That is what this switch is for.  The way I read this in 
the manual was:   "disable shared interrupt", S*&t no, I _NEED_ shared 
interrupts, after all this card _shares_ the same IRQ among 4 UARTS 
doesn't it?   WRONG interpretation.

Please let me know if it works for you.



----------------------------------------------------------------------------
ONE FINAL NOTE
----------------------------------------------------------------------------

One more thing.  This _really_ caused me problems for a while.  Before you 
compile your kernel, which you should do after reading this, be sure you 
cd to /sys/compile and _REMOVE_ the directory the with same name as your 
/sys/i386/conf/MACHINENAME config file.  I've seen a few comments about 
how doing this has fixed unexplained problems.  I tried it at some stage 
during the setup of my standard comm ports, and all of a sudden, the 
ports started working.  They should have before, but never did.

Make sure what you remove is: /sys/compile/MACHINENAME
NOT THE CONFIG FILE in /sys/i386/isa !!!!

If you don't want to do this, OK, but I found it to be effective.


Good luck.

Terry

email: tdwyer@netbsd08.dn.itg.telecom.com.au

--------------------MODEM-TUT------------------------------------------

Set your modem up like this:

Once connected direct to the modem I use the command at*o to see how my
modem is set up.  Your modem will probably be different. 

If you've never used `cu' before, try the following command line to
connect to it, using the appropriate device name and baud rate.
Remember to connect to the -=dial-out=- device, not the dial-in device.


	+----------------------------------------------------+
	|                                                    |
	|$ cu -l /dev/ttyd01 -s 19200 dir                    |
	|Connected.                                          |
	|                                                    |
	|at*o                                                |
	|MODEL:SPIRIT II                                     |
	|DTE:  19200  N81                                    |
	|DCE:  IDLE                                          |
	|                                                    |
	|E1  K1  M1  Q2  V1  X4 TONE                         |
	|&B0 &C1 &D3 &M0 &R0 &T5                             |
	|*E9 *F3 *G0 *M2 *N6 *P0 *Q1 *S1 *T1                 |
	|                                                    |
	|S00=005  S04=010  S08=002  S15=255                  |
	|S01=000  S05=008  S09=000  S18=000                  |	
	|S02=043  S06=002  S10=003  S25=000                  |
	|S03=013  S07=045  S12=050  S26=000                  |
	|OK                                                  |
	|                                                    |
	+----------------------------------------------------+


My modem is a QuickComm Spirit II.  The settings above are the ones
that I use.

For those unfamiliar with modems:

Although the command set shows all uppercase characters, case is not
important.  You can send commands to the modem using uppercase or
lowercase, to the modem, it's all the same.

To tell the modem to do something, you must first gain it's ATtention.
this is done with the AT prefix.  You must prefix all commands with `AT'
Most modems will accept spaces between the AT and the command you send
to it.

To set the various modem parameters for a Hayes style command set, you
will usually only have to do something like this:

ate1	set echo on. You can now see everything typed to the modem

atq0	Quiet mode off.  All modem responses will be displayed.
	If your modem supports it use q2.  The modem will then
	only display results on out-going calls.   No result 
	codes will be sent to getty on an incoming call.

	If you are unable to set q2, you will need to set q0
	after you have set all the other parameters you will
	use during the setup procedure for your modem.  This
	will prevent the modem sending useless garbage to
	the getty running on the serial port the modem is
	connected to.  

atv1	Verbal responses to commands on.  The other mode is numeric 
	if v0 is set.  This command relates to atq0, above.

You should set these three parameters before anything else.  They should be
common to all modems with hayes compatible command sets.

If your modem does not use Hayes style command syntax, sorry, read the manual
and interpret the commands from the descriptions associated with each command.
Be consoled,  Most owners of hayes compatible modems will have to do a lot of 
the same.

Now, an explanation of the modem settings in the box above:

at*o	Display Parameter settings.
	All modems in use today will have this command,
	yours may use something other than the string `*o'

The commands `e1', `q2' and `v1' have been described above

k1	This allows a break to be sent to the remote modem.
	It is a default and need not be changed unless you
	have an application that doesn't like break being
	sent.

m1	The modem's speaker is set on while in command mode,
	during the call connect phase and while the modems
	negotiate the baud rate and error correction they will
	use.  The speaker will be disconnected when Carrier is
	detected.  Using this setting allows you to hear the
	modems handshake, and can assist in diagnosing problems
	with call progress tones and handshake problems.

x4	The set of responses the modem will display and the
	conditions it will detect on the line such as no 
	dialtone, busy and ring tone.  This command is 
	associated with the `v1'and `q2/q0' commands above.

&b0	DSR, (Data Set Ready) is always on.  If you try to set DSR
	to follow DTR, be prepared to hook your modem up to a DOS
	box to reset this parameter.  By default DSR will probably
	be set on permanently for most modems.

&c1	CD (Carrier Detect) follows the true state of the connection.
	This is the way it should be set.  Alternatives are &c0 and 
	&c2 which both force CD on artificially.

&d3	DTR (Data Terminal Ready).  With this setting the modem will
	do a full reset when DTR drops after the call disconnects.
	Other settings work OK, &d1 merely returns to command mode,
	(the normal state), when DTR drops.  This is an alternative
	if your modem is not capable of &d3.


&r0	CTS (Clear To Send) is set to follow RTS (Request To Send).
	Register S26 can have a delay time, (usually in increments
	of 10 milliseconds), to allow some time to elapse between 
	the request and the data being sent.  I set this value to 0
	which implies no delay.  The same effect can be achieved
	by using &r1 which turns CTS on immediately an RTS signal
	is sent to the modem from the serial port.

&t5	Deny remote modem request for Remote Digital Loopback.
	Prevents a dial-in user from setting your modem into a
	state where others will not be able to use it.

*e9	Error control settings.  This is the default setting for
	14400 modems generally.  There is good reason not to use
	a higher number (*e10), as negotiation with a non error-
	correcting modem _will_ fail to connect.  *e9 is defined
	on my modem as "Auto Reliable V.42bis with Phase Detection"
	The key word here is Auto.  This allows the modem to negotiate
	a connection with modems with inferior or no error correction
	at all.  The call, in this case will be sucessful where it 
	would fail with *e10, defined as "Reliable V.42bis with
	phase detection".   Straight from my modem manual:

	"*e5 through *e9 activates V.42bis and V.42 detection. A
	V.42 data connection uses LAPM first, then tries MNP.  If
	the remote modem doesn't negotiate either LAPM or MNP,
	the modem then reverts to a normal modem connection
	without error control."

*f3	Turn on RTS/CTS flow control.  This is _required_ by
	FreeBSD.  If your modem offers a combination of RTS/CTS
	and XON/XOFF, (software flow control), do _not_ use it.
	XON/XOFF flow control is not desirable.

*g0	Adaptive handshake disabled.  I don't know what this means.
	My manual does not describe this feature, except to say
	how to turn it of an on.  I have it turned off.

*m2	Sends (to your terminal) error correction responses and
	the type of error correction being used.  For example,
	"CONNECT 9600EC/MNP5".  *m1 would produce "CONNECT 9600EC".

*n6	Force DCE Speed.  For my modem which is capable of 14,400 
	Bits Per Second, this attemps to force a connect at 14,400 
	to the remote modem (DCE side of the connection).  Your 
	modem may or may not have this capability.

*p0	Enable user abort.  Allows manual intervention during the
	connection handshake.

*q1	Signal Quality.  *q0 turns off signal quality monitoring
	*q1 forces the modem to attempt a retrain when the error rate
	rises above a set level.  This is _very_ effective.
	*q2 allows fallback to lower speed and retrain if the initial
	train is unsucsessful.  *q3 will disconnect the call if the
	error rate rises above a preset value.

*s1	Allow the modem to do internal speed conversion.  If on, 
	allows DTE rate to be set as high as either the serial
	port or the modem will permit.  This should be on, as
	a DTE rate higher than the DCE (line) permits the CPU
	to push data to the modem faster than the line will allow,
	preventing the modem from waiting on the CPU and
	saturating the line.

*t1	Turns on Trellis coding.  A data compression method used
	to achieve high line throughput.  This will only be used
	if the remote modem is capable of it.


Set up your comm ports ( the incoming side - these are the ones with the 
lower minor numbers ) like this:

echo -n 'setting com ports...'
echo -n 'port 1 ' ; stty -f /dev/tty01 -parity -clocal crtscts ; comcontrol /dev
/tty01 bidir

This code fragment goes in your /etc/rc -=BEFORE=- the section of code that
runs sendmail and inetd.  You will find this right near the end of /etc/rc.

Repeat this line for every comm port you want to set up, changing the 
dev/tty0x for each dial-in port 

Explanation of what this command line does

Parameters passed to stty:

-f /dev/tty01	The device to set up 
-parity		Set to no parity
-clocal		This is -=NOT=- a local device - use modem control
crtscts		Use RTS/CTS flow control

Parameters passed to comcontrol:

/dev/tty01The device to set
bidirSet the dial-in device so the dial-out half of the
pair can be used for out-going calls.

--------------------------------END---------------------------------

   _-_|\    Terry Dwyer 	  E-Mail: tdwyer@netbsd08.dn.itg.telecom.com.au
  /     \   System Administrator  Phone: +61 9 491 5161     Fax: +61 9 221 2631
  *_.^\_/   Telecom Australia     Telstra Corporation       MIME capable mailer
       v    Perth  WA                 ( I do not speak for Telstra or Telecom )