Cronyx/Sigma sync/async serial driver with PPP support
from Serge Vakulenko
This commit is contained in:
parent
114a506d1a
commit
6014635361
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/cronyx/; revision=4910
4
sbin/cxconfig/Makefile
Normal file
4
sbin/cxconfig/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
PROG = cxconfig
|
||||
MAN8 = cxconfig.8
|
||||
|
||||
.include <bsd.prog.mk>
|
297
sbin/cxconfig/cxconfig.8
Normal file
297
sbin/cxconfig/cxconfig.8
Normal file
@ -0,0 +1,297 @@
|
||||
.TH Cronyx-Sigma 1
|
||||
.rm ES
|
||||
.rm EE
|
||||
.de ES
|
||||
.PP
|
||||
.nf
|
||||
.in +0.5i
|
||||
..
|
||||
.de EE
|
||||
.in -0.5i
|
||||
.fi
|
||||
..
|
||||
.na
|
||||
.SH NAME
|
||||
.B cxconfig
|
||||
\- channel options management utility for Cronyx-Sigma adapter
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fBcxconfig\fP utility is used for configuring the channel options of
|
||||
the Cronyx-Sigma adapter.
|
||||
.PP
|
||||
To change cha options the channel should be free: the corresponding
|
||||
network interface in ``down'' state, the asynchronous terminal device /dev/tty*
|
||||
closed.
|
||||
Generally, the channel options are set up during the operating
|
||||
system startup, for example from the \fI/etc/rc\fP file.
|
||||
.PP
|
||||
Note, that not all options have a sense for every particular
|
||||
case, and an attempt to set some of them can hang up the channel or
|
||||
the whole adapter.
|
||||
.SH "Usage"
|
||||
.IP "cxconfig"
|
||||
The brief information about all channels.
|
||||
.IP "cxconfig -a"
|
||||
The full information about all channels.
|
||||
.IP "cxconfig <channel>"
|
||||
The brief information about the channel.
|
||||
.IP "cxconfig -a <channel>"
|
||||
The full information about the channel.
|
||||
.IP "cxconfig <channel> <option>..."
|
||||
Setting the channel options.
|
||||
.SH "Channel options"
|
||||
.IP ispeed=#
|
||||
Set the receiver baud rate to the number given.
|
||||
The maximal value is 256000 bits/sec.
|
||||
In the synchronous mode the receiver baud rate is significant
|
||||
only when DPLL mode is used.
|
||||
.IP ospeed=#
|
||||
Set the transmitter baud rate to the number given.
|
||||
The maximal value is 256000 bits/sec.
|
||||
In the synchronous mode the transmitter baud rate is significant
|
||||
only in the case of the internal clock source.
|
||||
If receiver and transmitter have equal data rate, then it could
|
||||
be set by specifying only the numerical argument.
|
||||
.IP async
|
||||
Set the asynchronous channel mode.
|
||||
.IP "hdlc, bisync, bsc, x.21, x21
|
||||
Set the synchronous channel mode: HDLC, Bisync (BSC) or X.21.
|
||||
.IP ppp
|
||||
Set the link-level protocol: PPP/HDLC. The built-in simplified synchronous PPP
|
||||
implementation is used (see RFC-1548, RFC-1549).
|
||||
.IP cisco
|
||||
Set the link-level protocol: Cisco/HDLC (see RFC-1547).
|
||||
This protocol is intended for compatibility with old models of Cisco routers,
|
||||
and with early versions of BSD/386 drivers.
|
||||
The extensive usage of this protocol is not recommended.
|
||||
.IP ext
|
||||
Use the external link-level protocol suite (for BSD/386 only).
|
||||
.IP "+keepalive, -keepalive"
|
||||
Enable the automatic line state control sub-protocol.
|
||||
This setting is not significant when the external link-level protocol is used.
|
||||
.IP "+autorts, -autorts"
|
||||
Enable the automatic RTS signal control.
|
||||
When enabled, the RTS signal goes up only when both halves of
|
||||
the receiver ring buffer are free and ready for receive,
|
||||
and goes down when one or both buffers are busy.
|
||||
.IP "port=rs232, port=rs449, port=v35
|
||||
Set the zero channel hardware interface type.
|
||||
.SH "Common options"
|
||||
.IP "nrz, nrzi, manchester
|
||||
Set the data line signal encoding.
|
||||
In the case of \fINRZ\fP encoding the zero bit is transmitted by the zero signal
|
||||
level, the one bit - by the positive signal level.
|
||||
In the case of \fINRZI\fP encoding the zero bit is transmitted by the change of
|
||||
the signal level, the one bit - by the constant signal level.
|
||||
In the case of \fIManchester\fP encoding the zero bit is encoded as 01 value,
|
||||
the one bit - as 10 value.
|
||||
.IP "+dpll, -dpll"
|
||||
Enable the digital phase locked loop mode (DPLL).
|
||||
When enabled, the receiver timing clock signal
|
||||
is derived from the received data.
|
||||
.IP "+lloop, -lloop"
|
||||
Set the local loopback mode.
|
||||
.IP "+extclock, -extclock"
|
||||
Set the timing clock source of synchronous channels. There are
|
||||
two possible variants: \fIexternal clock\fP source or \fIinternal clock\fP
|
||||
generation.
|
||||
.br
|
||||
\fIExternal clock\fP mode is the most common method for connecting
|
||||
external modem hardware. In this mode the external timing
|
||||
signal is received on TXCIN pin of the connector, and it is
|
||||
used as a synchronization clock for transmitting data (TXD).
|
||||
.br
|
||||
In the case of \fIinternal clock\fP mode the transmitted data (TXD)
|
||||
are synchronized using the internal on-board timing generator,
|
||||
the internally generated timing signal is driven on the TXCOUT
|
||||
pin, and the signal on the TXCIN pin is ignored. This mode
|
||||
is used for direct terminal-to-terminal communication,
|
||||
e.g. for connecting two computers together in a synchronous mode
|
||||
via relatively short cable. This method should also be used
|
||||
for testing channels with an external loopback connector.
|
||||
.IP fifo=#
|
||||
FIFO threshold level setup for receiver and transmitter.
|
||||
.IP rfifo=#
|
||||
Hardware RTS/CTS flow control FIFO threshold setup.
|
||||
.IP "+ctsup, -ctsup"
|
||||
Enable/disable interrupts on CTS (Clear To Send) signal setup (0 to 1 transition).
|
||||
.IP "+ctsdown, -ctsdown"
|
||||
Enable/disable interrupts on CTS (Clear To Send) signal clear (1 to 0 transition).
|
||||
.IP "+cdup, -cdup"
|
||||
Enable/disable interrupts on CD (Carrier Detect) signal setup (0 to 1 transition).
|
||||
.IP "+cddown, -cddown"
|
||||
Enable/disable interrupts on CD (Carrier Detect) signal clear (1 to 0 transition).
|
||||
.IP "+dsrup, -dsrup"
|
||||
Enable/disable interrupts on DSR (Data Set Ready) signal setup (0 to 1 transition).
|
||||
.IP "+dsrdown, -dsrdown"
|
||||
Enable/disable interrupts on DSR (Data Set Ready) signal clear (1 to 0 transition).
|
||||
.SH "Asynchronous mode options"
|
||||
.IP cs#
|
||||
Select character size: 5, 6, 7 or 8 bits.
|
||||
.IP "parodd, pareven
|
||||
Parity mode: odd or even.
|
||||
.IP "+ignpar, -ignpar
|
||||
Disable/enable parity detection.
|
||||
.IP nopar
|
||||
Disable parity bit generation.
|
||||
.IP forcepar
|
||||
Force parity: even - 0, odd - 1.
|
||||
.IP "stopb1, stopb1.5, stopb2
|
||||
Use 1 or 1.5 or 2 stop bits per character.
|
||||
.IP "+dsr, -dsr"
|
||||
Use the DSR input signal as receiver enable/disable.
|
||||
.IP "+cts, -cts"
|
||||
Use the CTS input signal as transmitter enable/disable.
|
||||
.IP "+rts, -rts"
|
||||
Drive the RTS output signal as transmitter ready.
|
||||
.IP "+rloop, -rloop"
|
||||
Set the remote loopback mode.
|
||||
.IP "+etc, -etc"
|
||||
Enable the embedded transmit commands mode.
|
||||
.IP "+ixon, -ixon"
|
||||
Enable the hardware XON/XOFF flow control support.
|
||||
.IP "+ixany, -ixany"
|
||||
Use the hardware IXANY mode support.
|
||||
.IP "+sdt, -sdt"
|
||||
Detect the spec. characters SCHR1 and SCHR2 in the receive data.
|
||||
.IP "+flowct, -flowct"
|
||||
Receive the flow control spec. characters as data.
|
||||
.IP "+rdt, -rdt"
|
||||
Detect the spec. characters in range SCRL..SCRH in the receive data.
|
||||
.IP "+exdt, -exdt"
|
||||
Detect the spec. characters SCHR3 and SCHR4 in the receive data.
|
||||
.IP "parintr, parnull, parign, pardisc, parffnull
|
||||
Action on parity errors:
|
||||
.ES
|
||||
Mode Action
|
||||
-----------------------------------------------------
|
||||
parintr Generate the receiver error interrupt
|
||||
parnull Input the NULL character
|
||||
parign Ignore the error, receive as good data
|
||||
pardisc Ignore the character
|
||||
parffnull Input the sequence <0xFF, NULL, character>
|
||||
.EE
|
||||
.IP "brkintr, brknull, brkdisc
|
||||
Line break state action:
|
||||
.ES
|
||||
Mode Action
|
||||
---------------------------------------------------
|
||||
brkintr Generate the receiver error interrupt
|
||||
brknull Input the NULL character
|
||||
brkdisc Ignore the line break state
|
||||
.EE
|
||||
.IP "+inlcr, -inlcr"
|
||||
Translate received NL characters to CR.
|
||||
.IP "+icrnl, -icrnl"
|
||||
Translate received CR characters to NL.
|
||||
.IP "+igncr, -igncr"
|
||||
Ignore received CR characters.
|
||||
.IP "+ocrnl, -ocrnl"
|
||||
Translate transmitted CR characters to NL.
|
||||
.IP "+onlcr, -onlcr"
|
||||
Translate transmitted NL characters to CR.
|
||||
.IP "+fcerr, -fcerr"
|
||||
Process (don't process) the characters, received with errors,
|
||||
for special character/flow control matching.
|
||||
.IP "+lnext, -lnext"
|
||||
Enable the LNEXT character option: the character following
|
||||
the LNEXT character is not processed for special character/flow
|
||||
control matching.
|
||||
.IP "+istrip, -istrip"
|
||||
Strip input characters to seven bits.
|
||||
.IP schr1=#
|
||||
The XON flow control character value.
|
||||
.IP schr2=#
|
||||
The XOFF flow control character value.
|
||||
.IP schr3=#
|
||||
The SCHR3 spec. character value.
|
||||
.IP schr4=#
|
||||
The SCHR4 spec. character value.
|
||||
.IP "scrl=#, scrh=#
|
||||
The spec. character range (inclusive).
|
||||
.IP lnext=#
|
||||
The LNEXT spec. character value.
|
||||
.SH "HDLC mode options"
|
||||
.IP if#
|
||||
The minimum number of flags transmitted before a frame is started.
|
||||
.IP noaddr
|
||||
No frame address recognition.
|
||||
.IP "addrlen1, addrlen2"
|
||||
Address field length: 1 or 2 bytes.
|
||||
.IP "addr1, addr2"
|
||||
Addressing mode: 4x1 bytes or 2x2 bytes.
|
||||
Registers RFAR1..RFAR4 should contain the address to be matched.
|
||||
.IP "+clrdet, -clrdet"
|
||||
Enable/disable clear detect for X.21 protocol support.
|
||||
.IP "+dsr, -dsr"
|
||||
Use the DSR input signal as receiver enable/disable.
|
||||
.IP "+cts, -cts"
|
||||
Use the CTS input signal as transmitter enable/disable.
|
||||
.IP "+rts, -rts"
|
||||
Drive the RTS output signal as transmitter ready.
|
||||
.IP "+fcs, -fcs"
|
||||
Enable/disable the frame checksum generation and checking.
|
||||
.IP "crc-16, crc-v.41
|
||||
Select the CRC polynomial: CRC-16 (x^16+x^15+x^2+1)
|
||||
or CRC V.41 (x^16+x^12+x^5+1).
|
||||
.IP "fcs-crc-16, fcs-v.41
|
||||
Frame checksum preset: all zeros (CRC-16) or all ones (CRC V.41).
|
||||
.IP "+crcinv, -crcinv"
|
||||
Invert (ie. CRC V.41) or don't invert (ie. CRC-16) the transmitted frame checksum.
|
||||
.IP "+fcsapd, -fcsapd"
|
||||
Pass the received CRC to the host at the end of receiver data buffer.
|
||||
.IP "idlemark, idleflag
|
||||
Idle mode: idle in mark (transmit all ones) or idle in flag (transmit flag).
|
||||
.IP "+syn, -syn"
|
||||
Enable/disable sending pad characters before sending flag when coming out
|
||||
of the idle mode.
|
||||
.IP pad#
|
||||
The number of synchronous characters sent (0..4).
|
||||
.IP "syn=0xaa, syn=0x00
|
||||
Send sync pattern.
|
||||
.IP "rfar1=#, rfar2=#, rfar3=#, rfar4=#
|
||||
Frame address registers for address recognition.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
Set up the channel 7 of the adapter Sigma-400 under FreeBSD.
|
||||
Physical 4-wire leased line with Zelax+ M115 short-range modems.
|
||||
Synchronous mode, 128000 bits/sec, interface RS-232,
|
||||
protocol PPP/HDLC without keepalive support, NRZI encoding,
|
||||
DPLL mode, no flow control:
|
||||
.ES
|
||||
cxconfig cx7 128000 hdlc ppp -keepalive nrzi -cts +dpll -extclock
|
||||
ifconfig cx7 158.250.244.2 158.250.244.1 up
|
||||
.EE
|
||||
.PP
|
||||
Set up the channel 0 of the adapter Sigma-100 under FreeBSD.
|
||||
Attachment to the near computer by short cable, internal clock source.
|
||||
Synchronous mode, 256000 bits/sec, interface RS-232,
|
||||
protocol Cisco/HDLC with keepalive support:
|
||||
.ES
|
||||
cxconfig cx0 hdlc 256000 cisco +keepalive -extclock
|
||||
ifconfig cx0 200.1.1.1 200.1.1.2 up
|
||||
.EE
|
||||
.PP
|
||||
Set up the channel 1 of the adapter Sigma-840 under BSD/386.
|
||||
Synchronous 64 kbit/sec leased line, external clock source.
|
||||
Synchronous mode, interface V.35, external protocol suite:
|
||||
.ES
|
||||
cxconfig cx1 hdlc ext
|
||||
ifconfig cx1 193.124.254.50 193.124.254.49 multicast up
|
||||
.EE
|
||||
.PP
|
||||
Set up the channel 0 of the adapter Sigma-840 under FreeBSD.
|
||||
Attachment to the Cisco-4000 router by null-modem cable, internal clock source.
|
||||
Synchronous mode, 64000 bits/sec, interface RS-232,
|
||||
protocol PPP/HDLC with keepalive support and flow control,
|
||||
LCP and IPCP protocols (see RFC-1548 and RFC-1332) debug tracing enabled:
|
||||
.ES
|
||||
cxconfig cx0 hdlc 64000 port=rs232 ppp +keepalive -extclock +cts
|
||||
ifconfig cx0 100.0.0.2 100.0.0.1 debug up
|
||||
.EE
|
||||
.SH FILES
|
||||
.IP /dev/cronyx
|
||||
The special device file for adapter options management.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
cx(4)
|
704
sbin/cxconfig/cxconfig.c
Normal file
704
sbin/cxconfig/cxconfig.c
Normal file
@ -0,0 +1,704 @@
|
||||
/*
|
||||
* Cronyx-Sigma adapter configuration utility for Unix.
|
||||
*
|
||||
* Copyright (C) 1994 Cronyx Ltd.
|
||||
* Author: Serge Vakulenko, <vak@zebub.msk.su>
|
||||
*
|
||||
* This software is distributed with NO WARRANTIES, not even the implied
|
||||
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Authors grant any other persons or organisations permission to use
|
||||
* or modify this software as long as this message is kept with the software,
|
||||
* all derivative works or modified versions.
|
||||
*
|
||||
* Version 1.1, Wed Oct 26 16:08:09 MSK 1994
|
||||
*
|
||||
* Usage:
|
||||
* cxconfig [-a]
|
||||
* -- print status of all channels
|
||||
* cxconfig [-a] <channel>
|
||||
* -- print status of the channel
|
||||
* cxconfig <channel> <option>...
|
||||
* -- set channel options
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/cronyx.h>
|
||||
#include <net/if.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define CXDEV "/dev/cronyx"
|
||||
#define atoi(a) strtol((a), (char**)0, 0)
|
||||
|
||||
cx_options_t o;
|
||||
int aflag;
|
||||
|
||||
char *symbol (unsigned char sym)
|
||||
{
|
||||
static char buf[40];
|
||||
|
||||
if (sym < ' ')
|
||||
sprintf (buf, "^%c", sym+0100);
|
||||
else if (sym == '\\')
|
||||
strcat (buf, "\\\\");
|
||||
else if (sym < 127)
|
||||
sprintf (buf, "%c", sym);
|
||||
else
|
||||
sprintf (buf, "\\%03o", sym);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
unsigned char atosym (char *s)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
if (*s == '^')
|
||||
return (*++s & 037);
|
||||
if (*s == '\\')
|
||||
return (strtol (++s, 0, 8));
|
||||
return (*s);
|
||||
}
|
||||
|
||||
void usage ()
|
||||
{
|
||||
printf ("Cronyx-Sigma Adapter Configuration Utility, Version 1.0\n");
|
||||
printf ("Copyright (C) 1994 Cronyx Ltd.\n");
|
||||
printf ("Usage:\n");
|
||||
printf ("\tcxconfig [-a]\n");
|
||||
printf ("\t\t-- print status of all channels\n");
|
||||
printf ("\tcxconfig [-a] <channel>\n");
|
||||
printf ("\t\t-- print status of the channel\n");
|
||||
printf ("\tcxconfig <channel> [async | hdlc | bisync | x.21] [ispeed #] [ospeed #]\n");
|
||||
printf ("\t\t[+cts | -cts]\n");
|
||||
printf ("\t\t-- set channel options\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
char *chantype (int type)
|
||||
{
|
||||
switch (type) {
|
||||
case T_NONE: return ("none");
|
||||
case T_ASYNC: return ("RS-232");
|
||||
case T_UNIV_RS232: return ("RS-232");
|
||||
case T_UNIV_RS449: return ("RS-232/RS-449");
|
||||
case T_UNIV_V35: return ("RS-232/V.35");
|
||||
case T_SYNC_RS232: return ("RS-232");
|
||||
case T_SYNC_V35: return ("V.35");
|
||||
case T_SYNC_RS449: return ("RS-449");
|
||||
}
|
||||
}
|
||||
|
||||
char *chanmode (int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case M_ASYNC: return ("Async");
|
||||
case M_HDLC: return ("HDLC");
|
||||
case M_BISYNC: return ("Bisync");
|
||||
case M_X21: return ("X.21");
|
||||
default: return ("???");
|
||||
}
|
||||
}
|
||||
|
||||
void getchan (int channel)
|
||||
{
|
||||
int s = open (CXDEV, 0);
|
||||
if (s < 0) {
|
||||
perror (CXDEV);
|
||||
exit (1);
|
||||
}
|
||||
o.board = channel/NCHAN;
|
||||
o.channel = channel%NCHAN;
|
||||
if (ioctl (s, CXIOCGETMODE, (caddr_t)&o) < 0) {
|
||||
perror ("cxconfig: CXIOCGETMODE");
|
||||
exit (1);
|
||||
}
|
||||
close (s);
|
||||
if (o.type == T_NONE) {
|
||||
fprintf (stderr, "cx%d: channel %d not configured\n", o.board,
|
||||
o.channel);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
void setchan (int channel)
|
||||
{
|
||||
int s = open (CXDEV, 0);
|
||||
if (s < 0) {
|
||||
perror (CXDEV);
|
||||
exit (1);
|
||||
}
|
||||
o.board = channel/NCHAN;
|
||||
o.channel = channel%NCHAN;
|
||||
if (ioctl (s, CXIOCSETMODE, (caddr_t)&o) < 0) {
|
||||
perror ("cxconfig: CXIOCSETMODE");
|
||||
exit (1);
|
||||
}
|
||||
close (s);
|
||||
}
|
||||
|
||||
void printopt ()
|
||||
{
|
||||
/* Common channel options */
|
||||
/* channel option register 4 */
|
||||
printf ("\t");
|
||||
printf ("fifo=%d ", o.opt.cor4.thr); /* FIFO threshold */
|
||||
printf ("%cctsdown ", o.opt.cor4.cts_zd ? '+' : '-'); /* detect 1 to 0 transition on the CTS */
|
||||
printf ("%ccddown ", o.opt.cor4.cd_zd ? '+' : '-'); /* detect 1 to 0 transition on the CD */
|
||||
printf ("%cdsrdown ", o.opt.cor4.dsr_zd ? '+' : '-'); /* detect 1 to 0 transition on the DSR */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 5 */
|
||||
printf ("\t");
|
||||
printf ("rfifo=%d ", o.opt.cor5.rx_thr); /* receive flow control FIFO threshold */
|
||||
printf ("%cctsup ", o.opt.cor5.cts_od ? '+' : '-'); /* detect 0 to 1 transition on the CTS */
|
||||
printf ("%ccdup ", o.opt.cor5.cd_od ? '+' : '-'); /* detect 0 to 1 transition on the CD */
|
||||
printf ("%cdsrup ", o.opt.cor5.dsr_od ? '+' : '-'); /* detect 0 to 1 transition on the DSR */
|
||||
printf ("\n");
|
||||
|
||||
/* receive clock option register */
|
||||
printf ("\t");
|
||||
printf ("%s ", o.opt.rcor.encod == ENCOD_NRZ ? "nrz" : /* signal encoding */
|
||||
o.opt.rcor.encod == ENCOD_NRZI ? "nrzi" :
|
||||
o.opt.rcor.encod == ENCOD_MANCHESTER ? "manchester" : "???");
|
||||
printf ("%cdpll ", o.opt.rcor.dpll ? '+' : '-'); /* DPLL enable */
|
||||
|
||||
/* transmit clock option register */
|
||||
printf ("%clloop ", o.opt.tcor.llm ? '+' : '-'); /* local loopback mode */
|
||||
printf ("%cextclock ", o.opt.tcor.ext1x ? '+' : '-'); /* external 1x clock mode */
|
||||
printf ("\n");
|
||||
|
||||
switch (o.mode) {
|
||||
case M_ASYNC: /* async mode options */
|
||||
/* channel option register 1 */
|
||||
printf ("\t");
|
||||
printf ("cs%d ", o.aopt.cor1.charlen+1); /* character length, 5..8 */
|
||||
printf ("par%s ", o.aopt.cor1.parity ? "odd" : "even"); /* parity */
|
||||
printf ("%cignpar ", o.aopt.cor1.ignpar ? '+' : '-'); /* ignore parity */
|
||||
if (o.aopt.cor1.parmode != PARM_NORMAL) /* parity mode */
|
||||
printf ("%s ", o.aopt.cor1.parmode == PARM_NOPAR ? "nopar" :
|
||||
o.aopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 2 */
|
||||
printf ("\t");
|
||||
printf ("%cdsr ", o.aopt.cor2.dsrae ? '+' : '-'); /* DSR automatic enable */
|
||||
printf ("%ccts ", o.aopt.cor2.ctsae ? '+' : '-'); /* CTS automatic enable */
|
||||
printf ("%crts ", o.aopt.cor2.rtsao ? '+' : '-'); /* RTS automatic output enable */
|
||||
printf ("%crloop ", o.aopt.cor2.rlm ? '+' : '-'); /* remote loopback mode enable */
|
||||
printf ("%cetc ", o.aopt.cor2.etc ? '+' : '-'); /* embedded transmitter cmd enable */
|
||||
printf ("%cxon ", o.aopt.cor2.ixon ? '+' : '-'); /* in-band XON/XOFF enable */
|
||||
printf ("%cxany ", o.aopt.cor2.ixany ? '+' : '-'); /* XON on any character */
|
||||
printf ("\n");
|
||||
|
||||
/* option register 3 */
|
||||
printf ("\t");
|
||||
printf ("%s ", o.aopt.cor3.stopb == STOPB_1 ? "stopb1" : /* stop bit length */
|
||||
o.aopt.cor3.stopb == STOPB_15 ? "stopb1.5" :
|
||||
o.aopt.cor3.stopb == STOPB_2 ? "stopb2" : "???");
|
||||
printf ("%csdt ", o.aopt.cor3.scde ? '+' : '-'); /* special char detection enable */
|
||||
printf ("%cflowct ", o.aopt.cor3.flowct ? '+' : '-'); /* flow control transparency mode */
|
||||
printf ("%crdt ", o.aopt.cor3.rngde ? '+' : '-'); /* range detect enable */
|
||||
printf ("%cexdt ", o.aopt.cor3.escde ? '+' : '-'); /* extended spec. char detect enable */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 6 */
|
||||
printf ("\t");
|
||||
printf ("%s ", o.aopt.cor6.parerr == PERR_INTR ? "parintr" : /* parity/framing error actions */
|
||||
o.aopt.cor6.parerr == PERR_NULL ? "parnull" :
|
||||
o.aopt.cor6.parerr == PERR_IGNORE ? "parign" :
|
||||
o.aopt.cor6.parerr == PERR_DISCARD ? "pardisc" :
|
||||
o.aopt.cor6.parerr == PERR_FFNULL ? "parffnull" : "???");
|
||||
printf ("%s ", o.aopt.cor6.brk == BRK_INTR ? "brkintr" : /* action on break condition */
|
||||
o.aopt.cor6.brk == BRK_NULL ? "brknull" :
|
||||
o.aopt.cor6.brk == BRK_DISCARD ? "brkdisc" : "???");
|
||||
printf ("%cinlcr ", o.aopt.cor6.inlcr ? '+' : '-'); /* translate NL to CR on input */
|
||||
printf ("%cicrnl ", o.aopt.cor6.icrnl ? '+' : '-'); /* translate CR to NL on input */
|
||||
printf ("%cigncr ", o.aopt.cor6.igncr ? '+' : '-'); /* discard CR on input */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 7 */
|
||||
printf ("\t");
|
||||
printf ("%cocrnl ", o.aopt.cor7.ocrnl ? '+' : '-'); /* translate CR to NL on output */
|
||||
printf ("%conlcr ", o.aopt.cor7.onlcr ? '+' : '-'); /* translate NL to CR on output */
|
||||
printf ("%cfcerr ", o.aopt.cor7.fcerr ? '+' : '-'); /* process flow ctl err chars enable */
|
||||
printf ("%clnext ", o.aopt.cor7.lnext ? '+' : '-'); /* LNext option enable */
|
||||
printf ("%cistrip ", o.aopt.cor7.istrip ? '+' : '-'); /* strip 8-bit on input */
|
||||
printf ("\n");
|
||||
|
||||
printf ("\t");
|
||||
printf ("schr1=%s ", symbol (o.aopt.schr1)); /* special character register 1 (XON) */
|
||||
printf ("schr2=%s ", symbol (o.aopt.schr2)); /* special character register 2 (XOFF) */
|
||||
printf ("schr3=%s ", symbol (o.aopt.schr3)); /* special character register 3 */
|
||||
printf ("schr4=%s ", symbol (o.aopt.schr4)); /* special character register 4 */
|
||||
printf ("scrl=%s ", symbol (o.aopt.scrl)); /* special character range low */
|
||||
printf ("scrh=%s ", symbol (o.aopt.scrh)); /* special character range high */
|
||||
printf ("lnext=%s ", symbol (o.aopt.lnxt)); /* LNext character */
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case M_HDLC: /* hdlc mode options */
|
||||
/* hdlc channel option register 1 */
|
||||
printf ("\t");
|
||||
printf ("if%d ", o.hopt.cor1.ifflags); /* number of inter-frame flags sent */
|
||||
printf ("%s ", o.hopt.cor1.admode == ADMODE_NOADDR ? "noaddr" : /* addressing mode */
|
||||
o.hopt.cor1.admode == ADMODE_4_1 ? "addr1" :
|
||||
o.hopt.cor1.admode == ADMODE_2_2 ? "addr2" : "???");
|
||||
printf ("%cclrdet ", o.hopt.cor1.clrdet ? '+' : '-'); /* clear detect for X.21 data transfer phase */
|
||||
printf ("addrlen%d ", o.hopt.cor1.aflo + 1); /* address field length option */
|
||||
printf ("\n");
|
||||
|
||||
/* hdlc channel option register 2 */
|
||||
printf ("\t");
|
||||
printf ("%cdsr ", o.hopt.cor2.dsrae ? '+' : '-'); /* DSR automatic enable */
|
||||
printf ("%ccts ", o.hopt.cor2.ctsae ? '+' : '-'); /* CTS automatic enable */
|
||||
printf ("%crts ", o.hopt.cor2.rtsao ? '+' : '-'); /* RTS automatic output enable */
|
||||
printf ("%ccrcinv ", o.hopt.cor2.crcninv ? '-' : '+'); /* CRC invertion option */
|
||||
printf ("%cfcsapd ", o.hopt.cor2.fcsapd ? '+' : '-'); /* FCS append */
|
||||
printf ("\n");
|
||||
|
||||
/* hdlc channel option register 3 */
|
||||
printf ("\t");
|
||||
printf ("pad%d ", o.hopt.cor3.padcnt); /* pad character count */
|
||||
printf ("idle%s ", o.hopt.cor3.idle ? "mark" : "flag"); /* idle mode */
|
||||
printf ("%cfcs ", o.hopt.cor3.nofcs ? '-' : '+'); /* FCS disable */
|
||||
printf ("fcs-%s ", o.hopt.cor3.fcspre ? "crc-16" : "v.41"); /* FCS preset */
|
||||
printf ("syn=%s ", o.hopt.cor3.syncpat ? "0xAA" : "0x00"); /* send sync pattern */
|
||||
printf ("%csyn ", o.hopt.cor3.sndpad ? '+' : '-'); /* send pad characters before flag enable */
|
||||
printf ("\n");
|
||||
|
||||
printf ("\t");
|
||||
printf ("rfar1=0x%02x ", o.hopt.rfar1); /* receive frame address register 1 */
|
||||
printf ("rfar2=0x%02x ", o.hopt.rfar2); /* receive frame address register 2 */
|
||||
printf ("rfar3=0x%02x ", o.hopt.rfar3); /* receive frame address register 3 */
|
||||
printf ("rfar4=0x%02x ", o.hopt.rfar4); /* receive frame address register 4 */
|
||||
printf ("crc-%s ", o.hopt.cpsr ? "16" : "v.41"); /* CRC polynomial select */
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case M_BISYNC: /* bisync mode options */
|
||||
/* channel option register 1 */
|
||||
printf ("\t");
|
||||
printf ("cs%d ", o.bopt.cor1.charlen+1); /* character length, 5..8 */
|
||||
printf ("par%s ", o.bopt.cor1.parity ? "odd" : "even"); /* parity */
|
||||
printf ("%cignpar ", o.bopt.cor1.ignpar ? '+' : '-'); /* ignore parity */
|
||||
if (o.bopt.cor1.parmode != PARM_NORMAL) /* parity mode */
|
||||
printf ("%s ", o.bopt.cor1.parmode == PARM_NOPAR ? "nopar" :
|
||||
o.bopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 2 */
|
||||
printf ("\t");
|
||||
printf ("syn%d ", o.bopt.cor2.syns+2); /* number of extra SYN chars before a frame */
|
||||
printf ("%ccrcinv ", o.bopt.cor2.crcninv ? '-' : '+'); /* CRC invertion option */
|
||||
printf ("%s ", o.bopt.cor2.ebcdic ? "ebcdic" : "ascii"); /* use EBCDIC as char set (instead of ASCII) */
|
||||
printf ("%cbccapd ", o.bopt.cor2.bcc ? '+' : '-'); /* BCC append enable */
|
||||
printf ("%s ", o.bopt.cor2.lrc ? "lrc" : "crc-16"); /* longitudinal redundancy check */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 3 */
|
||||
printf ("\t");
|
||||
printf ("pad%d ", o.bopt.cor3.padcnt); /* pad character count */
|
||||
printf ("idle%s ", o.bopt.cor3.idle ? "mark" : "syn"); /* idle mode */
|
||||
printf ("%cfcs ", o.bopt.cor3.nofcs ? '-' : '+'); /* FCS disable */
|
||||
printf ("fcs-%s ", o.bopt.cor3.fcspre ? "crc-16" : "v.41"); /* FCS preset */
|
||||
printf ("syn=%s ", o.bopt.cor3.padpat ? "0x55" : "0xAA"); /* send sync pattern */
|
||||
printf ("%csyn ", o.bopt.cor3.sndpad ? '+' : '-'); /* send pad characters before flag enable */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 6 */
|
||||
printf ("\t");
|
||||
printf ("specterm=%s ", symbol (o.bopt.cor6.specterm)); /* special termination character */
|
||||
|
||||
printf ("crc-%s ", o.bopt.cpsr ? "16" : "v.41"); /* CRC polynomial select */
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case M_X21: /* x.21 mode options */
|
||||
/* channel option register 1 */
|
||||
printf ("\t");
|
||||
printf ("cs%d ", o.xopt.cor1.charlen+1); /* character length, 5..8 */
|
||||
printf ("par%s ", o.xopt.cor1.parity ? "odd" : "even"); /* parity */
|
||||
printf ("%cignpar ", o.xopt.cor1.ignpar ? '+' : '-'); /* ignore parity */
|
||||
if (o.xopt.cor1.parmode != PARM_NORMAL) /* parity mode */
|
||||
printf ("%s ", o.xopt.cor1.parmode == PARM_NOPAR ? "nopar" :
|
||||
o.xopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 2 */
|
||||
printf ("\t");
|
||||
printf ("%cetc ", o.xopt.cor2.etc ? '+' : '-'); /* embedded transmitter cmd enable */
|
||||
|
||||
/* channel option register 3 */
|
||||
printf ("%csdt ", o.xopt.cor3.scde ? '+' : '-'); /* special char detection enable */
|
||||
printf ("%cstripsyn ", o.xopt.cor3.stripsyn ? '+' : '-'); /* treat SYN chars as special condition */
|
||||
printf ("%cssdt ", o.xopt.cor3.ssde ? '+' : '-'); /* steady state detect enable */
|
||||
printf ("syn%c ", o.xopt.cor3.syn ? '1' : '2'); /* the number of SYN chars on receive */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 6 */
|
||||
printf ("\t");
|
||||
printf ("syn=%s ", symbol (o.xopt.cor6.synchar)); /* syn character */
|
||||
|
||||
printf ("schr1=%s ", symbol (o.xopt.schr1)); /* special character register 1 */
|
||||
printf ("schr2=%s ", symbol (o.xopt.schr2)); /* special character register 2 */
|
||||
printf ("schr3=%s ", symbol (o.xopt.schr3)); /* special character register 3 */
|
||||
printf ("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void printchan (int channel)
|
||||
{
|
||||
printf ("cx%d (%s) %s", channel, chantype (o.type), chanmode (o.mode));
|
||||
if (o.txbaud == o.rxbaud)
|
||||
printf (" %d", o.rxbaud);
|
||||
else
|
||||
printf (" ospeed=%d ispeed=%d", o.txbaud, o.rxbaud);
|
||||
if ((o.channel == 0 || o.channel == 8) &&
|
||||
(o.type == T_UNIV_V35 || o.type == T_UNIV_RS449))
|
||||
printf (" port=%s", o.iftype ? (o.type == T_UNIV_V35 ?
|
||||
"v35" : "rs449") : "rs232");
|
||||
printf (o.sopt.ext ? " ext" : o.sopt.cisco ? " cisco" : " ppp");
|
||||
printf (" %ckeepalive", o.sopt.keepalive ? '+' : '-');
|
||||
printf (" %cautorts", o.sopt.norts ? '-' : '+');
|
||||
printf ("\n");
|
||||
if (aflag)
|
||||
printopt ();
|
||||
}
|
||||
|
||||
void printall ()
|
||||
{
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifr;
|
||||
char buf[BUFSIZ], *cp;
|
||||
int s, c;
|
||||
|
||||
s = socket (AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
perror ("cxconfig: socket");
|
||||
exit (1);
|
||||
}
|
||||
ifc.ifc_len = sizeof (buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if (ioctl (s, SIOCGIFCONF, (caddr_t)&ifc) < 0) {
|
||||
perror ("cxconfig: SIOCGIFCONF");
|
||||
exit (1);
|
||||
}
|
||||
close (s);
|
||||
s = open (CXDEV, 0);
|
||||
if (s < 0) {
|
||||
perror (CXDEV);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
ifr = ifc.ifc_req;
|
||||
#define max(a,b) ((a)>(b) ? (a) : (b))
|
||||
#define size(p) max((p).sa_len, sizeof(p))
|
||||
for (cp=buf; cp<buf+ifc.ifc_len; cp+=sizeof(ifr->ifr_name)+size(ifr->ifr_addr)) {
|
||||
ifr = (struct ifreq*) cp;
|
||||
if (ifr->ifr_addr.sa_family != AF_LINK)
|
||||
continue;
|
||||
if (strncmp (ifr->ifr_name, "cx", 2) != 0)
|
||||
continue;
|
||||
c = atoi (ifr->ifr_name + 2);
|
||||
o.board = c/NCHAN;
|
||||
o.channel = c%NCHAN;
|
||||
if (ioctl (s, CXIOCGETMODE, (caddr_t)&o) < 0) {
|
||||
perror ("cxconfig: CXIOCGETMODE");
|
||||
exit (1);
|
||||
}
|
||||
printchan (c);
|
||||
}
|
||||
close (s);
|
||||
}
|
||||
|
||||
void set_interface_type (char *type)
|
||||
{
|
||||
if (o.channel != 0 && o.channel != 8) {
|
||||
printf ("interface option is applicable only for channels 0 and 8\n");
|
||||
exit (1);
|
||||
}
|
||||
if (o.type != T_UNIV_V35 && o.type != T_UNIV_RS449) {
|
||||
printf ("interface option is applicable only for universal channels\n");
|
||||
exit (1);
|
||||
}
|
||||
if (! strcasecmp (type, "port=rs232"))
|
||||
o.iftype = 0;
|
||||
else
|
||||
o.iftype = 1;
|
||||
}
|
||||
|
||||
void set_async_opt (char *opt)
|
||||
{
|
||||
/* channel option register 1 */
|
||||
if (! strncasecmp (opt, "cs", 2)) o.aopt.cor1.charlen = atoi (opt + 2) - 1;
|
||||
else if (! strcasecmp (opt, "parodd")) o.aopt.cor1.parity = 1;
|
||||
else if (! strcasecmp (opt, "pareven")) o.aopt.cor1.parity = 0;
|
||||
else if (! strcasecmp (opt, "-ignpar")) o.aopt.cor1.ignpar = 0;
|
||||
else if (! strcasecmp (opt, "+ignpar")) o.aopt.cor1.ignpar = 1;
|
||||
else if (! strcasecmp (opt, "nopar")) o.aopt.cor1.parmode = PARM_NOPAR;
|
||||
else if (! strcasecmp (opt, "forcepar")) o.aopt.cor1.parmode = PARM_FORCE;
|
||||
|
||||
/* channel option register 2 */
|
||||
else if (! strcasecmp (opt, "-dsr")) o.aopt.cor2.dsrae = 0;
|
||||
else if (! strcasecmp (opt, "+dsr")) o.aopt.cor2.dsrae = 1;
|
||||
else if (! strcasecmp (opt, "-cts")) o.aopt.cor2.ctsae = 0;
|
||||
else if (! strcasecmp (opt, "+cts")) o.aopt.cor2.ctsae = 1;
|
||||
else if (! strcasecmp (opt, "-rts")) o.aopt.cor2.rtsao = 0;
|
||||
else if (! strcasecmp (opt, "+rts")) o.aopt.cor2.rtsao = 1;
|
||||
else if (! strcasecmp (opt, "-rloop")) o.aopt.cor2.rlm = 0;
|
||||
else if (! strcasecmp (opt, "+rloop")) o.aopt.cor2.rlm = 1;
|
||||
else if (! strcasecmp (opt, "-etc")) o.aopt.cor2.etc = 0;
|
||||
else if (! strcasecmp (opt, "+etc")) o.aopt.cor2.etc = 1;
|
||||
else if (! strcasecmp (opt, "-ixon")) o.aopt.cor2.ixon = 0;
|
||||
else if (! strcasecmp (opt, "+ixon")) o.aopt.cor2.ixon = 1;
|
||||
else if (! strcasecmp (opt, "-ixany")) o.aopt.cor2.ixany = 0;
|
||||
else if (! strcasecmp (opt, "+ixany")) o.aopt.cor2.ixany = 1;
|
||||
|
||||
/* option register 3 */
|
||||
else if (! strcasecmp (opt, "stopb1")) o.aopt.cor3.stopb = STOPB_1;
|
||||
else if (! strcasecmp (opt, "stopb1.5")) o.aopt.cor3.stopb = STOPB_15;
|
||||
else if (! strcasecmp (opt, "stopb2")) o.aopt.cor3.stopb = STOPB_2;
|
||||
else if (! strcasecmp (opt, "-sdt")) o.aopt.cor3.scde = 0;
|
||||
else if (! strcasecmp (opt, "+sdt")) o.aopt.cor3.scde = 1;
|
||||
else if (! strcasecmp (opt, "-flowct")) o.aopt.cor3.flowct = 0;
|
||||
else if (! strcasecmp (opt, "+flowct")) o.aopt.cor3.flowct = 1;
|
||||
else if (! strcasecmp (opt, "-rdt")) o.aopt.cor3.rngde = 0;
|
||||
else if (! strcasecmp (opt, "+rdt")) o.aopt.cor3.rngde = 1;
|
||||
else if (! strcasecmp (opt, "-exdt")) o.aopt.cor3.escde = 0;
|
||||
else if (! strcasecmp (opt, "+exdt")) o.aopt.cor3.escde = 1;
|
||||
|
||||
/* channel option register 6 */
|
||||
else if (! strcasecmp (opt, "parintr")) o.aopt.cor6.parerr = PERR_INTR;
|
||||
else if (! strcasecmp (opt, "parnull")) o.aopt.cor6.parerr = PERR_NULL;
|
||||
else if (! strcasecmp (opt, "parign")) o.aopt.cor6.parerr = PERR_IGNORE;
|
||||
else if (! strcasecmp (opt, "pardisc")) o.aopt.cor6.parerr = PERR_DISCARD;
|
||||
else if (! strcasecmp (opt, "parffnull")) o.aopt.cor6.parerr = PERR_FFNULL;
|
||||
else if (! strcasecmp (opt, "brkintr")) o.aopt.cor6.brk = BRK_INTR;
|
||||
else if (! strcasecmp (opt, "brknull")) o.aopt.cor6.brk = BRK_NULL;
|
||||
else if (! strcasecmp (opt, "brkdisc")) o.aopt.cor6.brk = BRK_DISCARD;
|
||||
else if (! strcasecmp (opt, "-inlcr")) o.aopt.cor6.inlcr = 0;
|
||||
else if (! strcasecmp (opt, "+inlcr")) o.aopt.cor6.inlcr = 1;
|
||||
else if (! strcasecmp (opt, "-icrnl")) o.aopt.cor6.icrnl = 0;
|
||||
else if (! strcasecmp (opt, "+icrnl")) o.aopt.cor6.icrnl = 1;
|
||||
else if (! strcasecmp (opt, "-igncr")) o.aopt.cor6.igncr = 0;
|
||||
else if (! strcasecmp (opt, "+igncr")) o.aopt.cor6.igncr = 1;
|
||||
|
||||
/* channel option register 7 */
|
||||
else if (! strcasecmp (opt, "-ocrnl")) o.aopt.cor7.ocrnl = 0;
|
||||
else if (! strcasecmp (opt, "+ocrnl")) o.aopt.cor7.ocrnl = 1;
|
||||
else if (! strcasecmp (opt, "-onlcr")) o.aopt.cor7.onlcr = 0;
|
||||
else if (! strcasecmp (opt, "+onlcr")) o.aopt.cor7.onlcr = 1;
|
||||
else if (! strcasecmp (opt, "-fcerr")) o.aopt.cor7.fcerr = 0;
|
||||
else if (! strcasecmp (opt, "+fcerr")) o.aopt.cor7.fcerr = 1;
|
||||
else if (! strcasecmp (opt, "-lnext")) o.aopt.cor7.lnext = 0;
|
||||
else if (! strcasecmp (opt, "+lnext")) o.aopt.cor7.lnext = 1;
|
||||
else if (! strcasecmp (opt, "-istrip")) o.aopt.cor7.istrip = 0;
|
||||
else if (! strcasecmp (opt, "+istrip")) o.aopt.cor7.istrip = 1;
|
||||
|
||||
else if (! strncasecmp (opt, "schr1=", 6)) o.aopt.schr1 = atosym (opt+6);
|
||||
else if (! strncasecmp (opt, "schr2=", 6)) o.aopt.schr2 = atosym (opt+6);
|
||||
else if (! strncasecmp (opt, "schr3=", 6)) o.aopt.schr3 = atosym (opt+6);
|
||||
else if (! strncasecmp (opt, "schr4=", 6)) o.aopt.schr4 = atosym (opt+6);
|
||||
else if (! strncasecmp (opt, "scrl=", 5)) o.aopt.scrl = atosym (opt+5);
|
||||
else if (! strncasecmp (opt, "scrh=", 5)) o.aopt.scrh = atosym (opt+5);
|
||||
else if (! strncasecmp (opt, "lnext=", 6)) o.aopt.lnxt = atosym (opt+6);
|
||||
else
|
||||
usage ();
|
||||
}
|
||||
|
||||
void set_hdlc_opt (char *opt)
|
||||
{
|
||||
/* hdlc channel option register 1 */
|
||||
if (! strncasecmp (opt, "if", 2)) o.hopt.cor1.ifflags = atoi (opt + 2);
|
||||
else if (! strcasecmp (opt, "noaddr")) o.hopt.cor1.admode = ADMODE_NOADDR;
|
||||
else if (! strcasecmp (opt, "addr1")) o.hopt.cor1.admode = ADMODE_4_1;
|
||||
else if (! strcasecmp (opt, "addr2")) o.hopt.cor1.admode = ADMODE_2_2;
|
||||
else if (! strcasecmp (opt, "-clrdet")) o.hopt.cor1.clrdet = 0;
|
||||
else if (! strcasecmp (opt, "+clrdet")) o.hopt.cor1.clrdet = 1;
|
||||
else if (! strcasecmp (opt, "addrlen1")) o.hopt.cor1.aflo = 0;
|
||||
else if (! strcasecmp (opt, "addrlen2")) o.hopt.cor1.aflo = 1;
|
||||
|
||||
/* hdlc channel option register 2 */
|
||||
else if (! strcasecmp (opt, "-dsr")) o.hopt.cor2.dsrae = 0;
|
||||
else if (! strcasecmp (opt, "+dsr")) o.hopt.cor2.dsrae = 1;
|
||||
else if (! strcasecmp (opt, "-cts")) o.hopt.cor2.ctsae = 0;
|
||||
else if (! strcasecmp (opt, "+cts")) o.hopt.cor2.ctsae = 1;
|
||||
else if (! strcasecmp (opt, "-rts")) o.hopt.cor2.rtsao = 0;
|
||||
else if (! strcasecmp (opt, "+rts")) o.hopt.cor2.rtsao = 1;
|
||||
else if (! strcasecmp (opt, "-fcsapd")) o.hopt.cor2.fcsapd = 0;
|
||||
else if (! strcasecmp (opt, "+fcsapd")) o.hopt.cor2.fcsapd = 1;
|
||||
else if (! strcasecmp (opt, "-crcinv")) o.hopt.cor2.crcninv = 1;
|
||||
else if (! strcasecmp (opt, "+crcinv")) o.hopt.cor2.crcninv = 0;
|
||||
|
||||
/* hdlc channel option register 3 */
|
||||
else if (! strncasecmp (opt, "pad", 3)) o.hopt.cor3.padcnt = atoi (opt + 3);
|
||||
else if (! strcasecmp (opt, "idlemark")) o.hopt.cor3.idle = 1;
|
||||
else if (! strcasecmp (opt, "idleflag")) o.hopt.cor3.idle = 0;
|
||||
else if (! strcasecmp (opt, "-fcs")) o.hopt.cor3.nofcs = 1;
|
||||
else if (! strcasecmp (opt, "+fcs")) o.hopt.cor3.nofcs = 0;
|
||||
else if (! strcasecmp (opt, "fcs-crc-16")) o.hopt.cor3.fcspre = 1;
|
||||
else if (! strcasecmp (opt, "fcs-v.41")) o.hopt.cor3.fcspre = 0;
|
||||
else if (! strcasecmp (opt, "syn=0xaa")) o.hopt.cor3.syncpat = 1;
|
||||
else if (! strcasecmp (opt, "syn=0x00")) o.hopt.cor3.syncpat = 0;
|
||||
else if (! strcasecmp (opt, "-syn")) o.hopt.cor3.sndpad = 0;
|
||||
else if (! strcasecmp (opt, "+syn")) o.hopt.cor3.sndpad = 1;
|
||||
|
||||
else if (! strncasecmp (opt, "rfar1=", 6)) o.hopt.rfar1 = atoi (opt + 6);
|
||||
else if (! strncasecmp (opt, "rfar2=", 6)) o.hopt.rfar2 = atoi (opt + 6);
|
||||
else if (! strncasecmp (opt, "rfar3=", 6)) o.hopt.rfar3 = atoi (opt + 6);
|
||||
else if (! strncasecmp (opt, "rfar4=", 6)) o.hopt.rfar4 = atoi (opt + 6);
|
||||
else if (! strcasecmp (opt, "crc-16")) o.hopt.cpsr = 1;
|
||||
else if (! strcasecmp (opt, "crc-v.41")) o.hopt.cpsr = 0;
|
||||
else usage ();
|
||||
}
|
||||
|
||||
void set_bisync_opt (char *opt)
|
||||
{
|
||||
usage ();
|
||||
}
|
||||
|
||||
void set_x21_opt (char *opt)
|
||||
{
|
||||
usage ();
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int channel;
|
||||
|
||||
for (--argc, ++argv; argc>0 && **argv=='-'; --argc, ++argv)
|
||||
if (! strcasecmp (*argv, "-a"))
|
||||
++aflag;
|
||||
else
|
||||
usage ();
|
||||
|
||||
if (argc <= 0) {
|
||||
printall ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (argv[0][0]=='c' && argv[0][1]=='x')
|
||||
*argv += 2;
|
||||
if (**argv<'0' || **argv>'9')
|
||||
usage ();
|
||||
channel = atoi (*argv);
|
||||
--argc, ++argv;
|
||||
getchan (channel);
|
||||
|
||||
if (argc <= 0) {
|
||||
printchan (channel);
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (; argc>0; --argc, ++argv)
|
||||
if (**argv == '(')
|
||||
continue;
|
||||
else if (! strncasecmp (*argv, "ispeed=", 7))
|
||||
o.rxbaud = atoi (*argv+7);
|
||||
else if (! strncasecmp (*argv, "ospeed=", 7))
|
||||
o.txbaud = atoi (*argv+7);
|
||||
else if (! strcasecmp (*argv, "async"))
|
||||
o.mode = M_ASYNC;
|
||||
else if (! strcasecmp (*argv, "hdlc"))
|
||||
o.mode = M_HDLC;
|
||||
else if (! strcasecmp (*argv, "bisync") ||
|
||||
! strcasecmp (*argv, "bsc"))
|
||||
o.mode = M_BISYNC;
|
||||
else if (! strcasecmp (*argv, "x.21") ||
|
||||
! strcasecmp (*argv, "x21"))
|
||||
o.mode = M_X21;
|
||||
else if (**argv>='0' && **argv<='9')
|
||||
o.txbaud = o.rxbaud = atoi (*argv);
|
||||
else if (! strcasecmp (*argv, "cisco")) {
|
||||
o.sopt.cisco = 1;
|
||||
o.sopt.ext = 0;
|
||||
} else if (! strcasecmp (*argv, "ppp")) {
|
||||
o.sopt.cisco = 0;
|
||||
o.sopt.ext = 0;
|
||||
} else if (! strcasecmp (*argv, "ext"))
|
||||
o.sopt.ext = 1;
|
||||
else if (! strcasecmp (*argv, "+keepalive"))
|
||||
o.sopt.keepalive = 1;
|
||||
else if (! strcasecmp (*argv, "-keepalive"))
|
||||
o.sopt.keepalive = 0;
|
||||
else if (! strcasecmp (*argv, "+autorts"))
|
||||
o.sopt.norts = 0;
|
||||
else if (! strcasecmp (*argv, "-autorts"))
|
||||
o.sopt.norts = 1;
|
||||
else if (! strcasecmp (*argv, "port=rs232") ||
|
||||
! strcasecmp (*argv, "port=rs449") ||
|
||||
! strcasecmp (*argv, "port=v35"))
|
||||
set_interface_type (*argv);
|
||||
|
||||
/*
|
||||
* Common channel options
|
||||
*/
|
||||
/* channel option register 4 */
|
||||
else if (! strcasecmp (*argv, "-ctsdown"))
|
||||
o.opt.cor4.cts_zd = 0;
|
||||
else if (! strcasecmp (*argv, "+ctsdown"))
|
||||
o.opt.cor4.cts_zd = 1;
|
||||
else if (! strcasecmp (*argv, "-cddown"))
|
||||
o.opt.cor4.cd_zd = 0;
|
||||
else if (! strcasecmp (*argv, "+cddown"))
|
||||
o.opt.cor4.cd_zd = 1;
|
||||
else if (! strcasecmp (*argv, "-dsrdown"))
|
||||
o.opt.cor4.dsr_zd = 0;
|
||||
else if (! strcasecmp (*argv, "+dsrdown"))
|
||||
o.opt.cor4.dsr_zd = 1;
|
||||
else if (! strncasecmp (*argv, "fifo=", 5))
|
||||
o.opt.cor4.thr = atoi (*argv + 5);
|
||||
|
||||
/* channel option register 5 */
|
||||
else if (! strcasecmp (*argv, "-ctsup"))
|
||||
o.opt.cor5.cts_od = 0;
|
||||
else if (! strcasecmp (*argv, "+ctsup"))
|
||||
o.opt.cor5.cts_od = 1;
|
||||
else if (! strcasecmp (*argv, "-cdup"))
|
||||
o.opt.cor5.cd_od = 0;
|
||||
else if (! strcasecmp (*argv, "+cdup"))
|
||||
o.opt.cor5.cd_od = 1;
|
||||
else if (! strcasecmp (*argv, "-dsrup"))
|
||||
o.opt.cor5.dsr_od = 0;
|
||||
else if (! strcasecmp (*argv, "+dsrup"))
|
||||
o.opt.cor5.dsr_od = 1;
|
||||
else if (! strncasecmp (*argv, "rfifo=", 6))
|
||||
o.opt.cor5.rx_thr = atoi (*argv + 6);
|
||||
|
||||
/* receive clock option register */
|
||||
else if (! strcasecmp (*argv, "nrz"))
|
||||
o.opt.rcor.encod = ENCOD_NRZ;
|
||||
else if (! strcasecmp (*argv, "nrzi"))
|
||||
o.opt.rcor.encod = ENCOD_NRZI;
|
||||
else if (! strcasecmp (*argv, "manchester"))
|
||||
o.opt.rcor.encod = ENCOD_MANCHESTER;
|
||||
else if (! strcasecmp (*argv, "-dpll"))
|
||||
o.opt.rcor.dpll = 0;
|
||||
else if (! strcasecmp (*argv, "+dpll"))
|
||||
o.opt.rcor.dpll = 1;
|
||||
|
||||
/* transmit clock option register */
|
||||
else if (! strcasecmp (*argv, "-lloop"))
|
||||
o.opt.tcor.llm = 0;
|
||||
else if (! strcasecmp (*argv, "+lloop"))
|
||||
o.opt.tcor.llm = 1;
|
||||
else if (! strcasecmp (*argv, "-extclock"))
|
||||
o.opt.tcor.ext1x = 0;
|
||||
else if (! strcasecmp (*argv, "+extclock"))
|
||||
o.opt.tcor.ext1x = 1;
|
||||
|
||||
/*
|
||||
* Mode dependent channel options
|
||||
*/
|
||||
else switch (o.mode) {
|
||||
case M_ASYNC: set_async_opt (*argv); break;
|
||||
case M_HDLC: set_hdlc_opt (*argv); break;
|
||||
case M_BISYNC: set_bisync_opt (*argv); break;
|
||||
case M_X21: set_x21_opt (*argv); break;
|
||||
}
|
||||
|
||||
setchan (channel);
|
||||
return (0);
|
||||
}
|
5
sbin/i386/Makefile
Normal file
5
sbin/i386/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $Id$
|
||||
|
||||
SUBDIR= cxconfig
|
||||
|
||||
.include <bsd.subdir.mk>
|
4
sbin/i386/cxconfig/Makefile
Normal file
4
sbin/i386/cxconfig/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
PROG = cxconfig
|
||||
MAN8 = cxconfig.8
|
||||
|
||||
.include <bsd.prog.mk>
|
297
sbin/i386/cxconfig/cxconfig.8
Normal file
297
sbin/i386/cxconfig/cxconfig.8
Normal file
@ -0,0 +1,297 @@
|
||||
.TH Cronyx-Sigma 1
|
||||
.rm ES
|
||||
.rm EE
|
||||
.de ES
|
||||
.PP
|
||||
.nf
|
||||
.in +0.5i
|
||||
..
|
||||
.de EE
|
||||
.in -0.5i
|
||||
.fi
|
||||
..
|
||||
.na
|
||||
.SH NAME
|
||||
.B cxconfig
|
||||
\- channel options management utility for Cronyx-Sigma adapter
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fBcxconfig\fP utility is used for configuring the channel options of
|
||||
the Cronyx-Sigma adapter.
|
||||
.PP
|
||||
To change cha options the channel should be free: the corresponding
|
||||
network interface in ``down'' state, the asynchronous terminal device /dev/tty*
|
||||
closed.
|
||||
Generally, the channel options are set up during the operating
|
||||
system startup, for example from the \fI/etc/rc\fP file.
|
||||
.PP
|
||||
Note, that not all options have a sense for every particular
|
||||
case, and an attempt to set some of them can hang up the channel or
|
||||
the whole adapter.
|
||||
.SH "Usage"
|
||||
.IP "cxconfig"
|
||||
The brief information about all channels.
|
||||
.IP "cxconfig -a"
|
||||
The full information about all channels.
|
||||
.IP "cxconfig <channel>"
|
||||
The brief information about the channel.
|
||||
.IP "cxconfig -a <channel>"
|
||||
The full information about the channel.
|
||||
.IP "cxconfig <channel> <option>..."
|
||||
Setting the channel options.
|
||||
.SH "Channel options"
|
||||
.IP ispeed=#
|
||||
Set the receiver baud rate to the number given.
|
||||
The maximal value is 256000 bits/sec.
|
||||
In the synchronous mode the receiver baud rate is significant
|
||||
only when DPLL mode is used.
|
||||
.IP ospeed=#
|
||||
Set the transmitter baud rate to the number given.
|
||||
The maximal value is 256000 bits/sec.
|
||||
In the synchronous mode the transmitter baud rate is significant
|
||||
only in the case of the internal clock source.
|
||||
If receiver and transmitter have equal data rate, then it could
|
||||
be set by specifying only the numerical argument.
|
||||
.IP async
|
||||
Set the asynchronous channel mode.
|
||||
.IP "hdlc, bisync, bsc, x.21, x21
|
||||
Set the synchronous channel mode: HDLC, Bisync (BSC) or X.21.
|
||||
.IP ppp
|
||||
Set the link-level protocol: PPP/HDLC. The built-in simplified synchronous PPP
|
||||
implementation is used (see RFC-1548, RFC-1549).
|
||||
.IP cisco
|
||||
Set the link-level protocol: Cisco/HDLC (see RFC-1547).
|
||||
This protocol is intended for compatibility with old models of Cisco routers,
|
||||
and with early versions of BSD/386 drivers.
|
||||
The extensive usage of this protocol is not recommended.
|
||||
.IP ext
|
||||
Use the external link-level protocol suite (for BSD/386 only).
|
||||
.IP "+keepalive, -keepalive"
|
||||
Enable the automatic line state control sub-protocol.
|
||||
This setting is not significant when the external link-level protocol is used.
|
||||
.IP "+autorts, -autorts"
|
||||
Enable the automatic RTS signal control.
|
||||
When enabled, the RTS signal goes up only when both halves of
|
||||
the receiver ring buffer are free and ready for receive,
|
||||
and goes down when one or both buffers are busy.
|
||||
.IP "port=rs232, port=rs449, port=v35
|
||||
Set the zero channel hardware interface type.
|
||||
.SH "Common options"
|
||||
.IP "nrz, nrzi, manchester
|
||||
Set the data line signal encoding.
|
||||
In the case of \fINRZ\fP encoding the zero bit is transmitted by the zero signal
|
||||
level, the one bit - by the positive signal level.
|
||||
In the case of \fINRZI\fP encoding the zero bit is transmitted by the change of
|
||||
the signal level, the one bit - by the constant signal level.
|
||||
In the case of \fIManchester\fP encoding the zero bit is encoded as 01 value,
|
||||
the one bit - as 10 value.
|
||||
.IP "+dpll, -dpll"
|
||||
Enable the digital phase locked loop mode (DPLL).
|
||||
When enabled, the receiver timing clock signal
|
||||
is derived from the received data.
|
||||
.IP "+lloop, -lloop"
|
||||
Set the local loopback mode.
|
||||
.IP "+extclock, -extclock"
|
||||
Set the timing clock source of synchronous channels. There are
|
||||
two possible variants: \fIexternal clock\fP source or \fIinternal clock\fP
|
||||
generation.
|
||||
.br
|
||||
\fIExternal clock\fP mode is the most common method for connecting
|
||||
external modem hardware. In this mode the external timing
|
||||
signal is received on TXCIN pin of the connector, and it is
|
||||
used as a synchronization clock for transmitting data (TXD).
|
||||
.br
|
||||
In the case of \fIinternal clock\fP mode the transmitted data (TXD)
|
||||
are synchronized using the internal on-board timing generator,
|
||||
the internally generated timing signal is driven on the TXCOUT
|
||||
pin, and the signal on the TXCIN pin is ignored. This mode
|
||||
is used for direct terminal-to-terminal communication,
|
||||
e.g. for connecting two computers together in a synchronous mode
|
||||
via relatively short cable. This method should also be used
|
||||
for testing channels with an external loopback connector.
|
||||
.IP fifo=#
|
||||
FIFO threshold level setup for receiver and transmitter.
|
||||
.IP rfifo=#
|
||||
Hardware RTS/CTS flow control FIFO threshold setup.
|
||||
.IP "+ctsup, -ctsup"
|
||||
Enable/disable interrupts on CTS (Clear To Send) signal setup (0 to 1 transition).
|
||||
.IP "+ctsdown, -ctsdown"
|
||||
Enable/disable interrupts on CTS (Clear To Send) signal clear (1 to 0 transition).
|
||||
.IP "+cdup, -cdup"
|
||||
Enable/disable interrupts on CD (Carrier Detect) signal setup (0 to 1 transition).
|
||||
.IP "+cddown, -cddown"
|
||||
Enable/disable interrupts on CD (Carrier Detect) signal clear (1 to 0 transition).
|
||||
.IP "+dsrup, -dsrup"
|
||||
Enable/disable interrupts on DSR (Data Set Ready) signal setup (0 to 1 transition).
|
||||
.IP "+dsrdown, -dsrdown"
|
||||
Enable/disable interrupts on DSR (Data Set Ready) signal clear (1 to 0 transition).
|
||||
.SH "Asynchronous mode options"
|
||||
.IP cs#
|
||||
Select character size: 5, 6, 7 or 8 bits.
|
||||
.IP "parodd, pareven
|
||||
Parity mode: odd or even.
|
||||
.IP "+ignpar, -ignpar
|
||||
Disable/enable parity detection.
|
||||
.IP nopar
|
||||
Disable parity bit generation.
|
||||
.IP forcepar
|
||||
Force parity: even - 0, odd - 1.
|
||||
.IP "stopb1, stopb1.5, stopb2
|
||||
Use 1 or 1.5 or 2 stop bits per character.
|
||||
.IP "+dsr, -dsr"
|
||||
Use the DSR input signal as receiver enable/disable.
|
||||
.IP "+cts, -cts"
|
||||
Use the CTS input signal as transmitter enable/disable.
|
||||
.IP "+rts, -rts"
|
||||
Drive the RTS output signal as transmitter ready.
|
||||
.IP "+rloop, -rloop"
|
||||
Set the remote loopback mode.
|
||||
.IP "+etc, -etc"
|
||||
Enable the embedded transmit commands mode.
|
||||
.IP "+ixon, -ixon"
|
||||
Enable the hardware XON/XOFF flow control support.
|
||||
.IP "+ixany, -ixany"
|
||||
Use the hardware IXANY mode support.
|
||||
.IP "+sdt, -sdt"
|
||||
Detect the spec. characters SCHR1 and SCHR2 in the receive data.
|
||||
.IP "+flowct, -flowct"
|
||||
Receive the flow control spec. characters as data.
|
||||
.IP "+rdt, -rdt"
|
||||
Detect the spec. characters in range SCRL..SCRH in the receive data.
|
||||
.IP "+exdt, -exdt"
|
||||
Detect the spec. characters SCHR3 and SCHR4 in the receive data.
|
||||
.IP "parintr, parnull, parign, pardisc, parffnull
|
||||
Action on parity errors:
|
||||
.ES
|
||||
Mode Action
|
||||
-----------------------------------------------------
|
||||
parintr Generate the receiver error interrupt
|
||||
parnull Input the NULL character
|
||||
parign Ignore the error, receive as good data
|
||||
pardisc Ignore the character
|
||||
parffnull Input the sequence <0xFF, NULL, character>
|
||||
.EE
|
||||
.IP "brkintr, brknull, brkdisc
|
||||
Line break state action:
|
||||
.ES
|
||||
Mode Action
|
||||
---------------------------------------------------
|
||||
brkintr Generate the receiver error interrupt
|
||||
brknull Input the NULL character
|
||||
brkdisc Ignore the line break state
|
||||
.EE
|
||||
.IP "+inlcr, -inlcr"
|
||||
Translate received NL characters to CR.
|
||||
.IP "+icrnl, -icrnl"
|
||||
Translate received CR characters to NL.
|
||||
.IP "+igncr, -igncr"
|
||||
Ignore received CR characters.
|
||||
.IP "+ocrnl, -ocrnl"
|
||||
Translate transmitted CR characters to NL.
|
||||
.IP "+onlcr, -onlcr"
|
||||
Translate transmitted NL characters to CR.
|
||||
.IP "+fcerr, -fcerr"
|
||||
Process (don't process) the characters, received with errors,
|
||||
for special character/flow control matching.
|
||||
.IP "+lnext, -lnext"
|
||||
Enable the LNEXT character option: the character following
|
||||
the LNEXT character is not processed for special character/flow
|
||||
control matching.
|
||||
.IP "+istrip, -istrip"
|
||||
Strip input characters to seven bits.
|
||||
.IP schr1=#
|
||||
The XON flow control character value.
|
||||
.IP schr2=#
|
||||
The XOFF flow control character value.
|
||||
.IP schr3=#
|
||||
The SCHR3 spec. character value.
|
||||
.IP schr4=#
|
||||
The SCHR4 spec. character value.
|
||||
.IP "scrl=#, scrh=#
|
||||
The spec. character range (inclusive).
|
||||
.IP lnext=#
|
||||
The LNEXT spec. character value.
|
||||
.SH "HDLC mode options"
|
||||
.IP if#
|
||||
The minimum number of flags transmitted before a frame is started.
|
||||
.IP noaddr
|
||||
No frame address recognition.
|
||||
.IP "addrlen1, addrlen2"
|
||||
Address field length: 1 or 2 bytes.
|
||||
.IP "addr1, addr2"
|
||||
Addressing mode: 4x1 bytes or 2x2 bytes.
|
||||
Registers RFAR1..RFAR4 should contain the address to be matched.
|
||||
.IP "+clrdet, -clrdet"
|
||||
Enable/disable clear detect for X.21 protocol support.
|
||||
.IP "+dsr, -dsr"
|
||||
Use the DSR input signal as receiver enable/disable.
|
||||
.IP "+cts, -cts"
|
||||
Use the CTS input signal as transmitter enable/disable.
|
||||
.IP "+rts, -rts"
|
||||
Drive the RTS output signal as transmitter ready.
|
||||
.IP "+fcs, -fcs"
|
||||
Enable/disable the frame checksum generation and checking.
|
||||
.IP "crc-16, crc-v.41
|
||||
Select the CRC polynomial: CRC-16 (x^16+x^15+x^2+1)
|
||||
or CRC V.41 (x^16+x^12+x^5+1).
|
||||
.IP "fcs-crc-16, fcs-v.41
|
||||
Frame checksum preset: all zeros (CRC-16) or all ones (CRC V.41).
|
||||
.IP "+crcinv, -crcinv"
|
||||
Invert (ie. CRC V.41) or don't invert (ie. CRC-16) the transmitted frame checksum.
|
||||
.IP "+fcsapd, -fcsapd"
|
||||
Pass the received CRC to the host at the end of receiver data buffer.
|
||||
.IP "idlemark, idleflag
|
||||
Idle mode: idle in mark (transmit all ones) or idle in flag (transmit flag).
|
||||
.IP "+syn, -syn"
|
||||
Enable/disable sending pad characters before sending flag when coming out
|
||||
of the idle mode.
|
||||
.IP pad#
|
||||
The number of synchronous characters sent (0..4).
|
||||
.IP "syn=0xaa, syn=0x00
|
||||
Send sync pattern.
|
||||
.IP "rfar1=#, rfar2=#, rfar3=#, rfar4=#
|
||||
Frame address registers for address recognition.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
Set up the channel 7 of the adapter Sigma-400 under FreeBSD.
|
||||
Physical 4-wire leased line with Zelax+ M115 short-range modems.
|
||||
Synchronous mode, 128000 bits/sec, interface RS-232,
|
||||
protocol PPP/HDLC without keepalive support, NRZI encoding,
|
||||
DPLL mode, no flow control:
|
||||
.ES
|
||||
cxconfig cx7 128000 hdlc ppp -keepalive nrzi -cts +dpll -extclock
|
||||
ifconfig cx7 158.250.244.2 158.250.244.1 up
|
||||
.EE
|
||||
.PP
|
||||
Set up the channel 0 of the adapter Sigma-100 under FreeBSD.
|
||||
Attachment to the near computer by short cable, internal clock source.
|
||||
Synchronous mode, 256000 bits/sec, interface RS-232,
|
||||
protocol Cisco/HDLC with keepalive support:
|
||||
.ES
|
||||
cxconfig cx0 hdlc 256000 cisco +keepalive -extclock
|
||||
ifconfig cx0 200.1.1.1 200.1.1.2 up
|
||||
.EE
|
||||
.PP
|
||||
Set up the channel 1 of the adapter Sigma-840 under BSD/386.
|
||||
Synchronous 64 kbit/sec leased line, external clock source.
|
||||
Synchronous mode, interface V.35, external protocol suite:
|
||||
.ES
|
||||
cxconfig cx1 hdlc ext
|
||||
ifconfig cx1 193.124.254.50 193.124.254.49 multicast up
|
||||
.EE
|
||||
.PP
|
||||
Set up the channel 0 of the adapter Sigma-840 under FreeBSD.
|
||||
Attachment to the Cisco-4000 router by null-modem cable, internal clock source.
|
||||
Synchronous mode, 64000 bits/sec, interface RS-232,
|
||||
protocol PPP/HDLC with keepalive support and flow control,
|
||||
LCP and IPCP protocols (see RFC-1548 and RFC-1332) debug tracing enabled:
|
||||
.ES
|
||||
cxconfig cx0 hdlc 64000 port=rs232 ppp +keepalive -extclock +cts
|
||||
ifconfig cx0 100.0.0.2 100.0.0.1 debug up
|
||||
.EE
|
||||
.SH FILES
|
||||
.IP /dev/cronyx
|
||||
The special device file for adapter options management.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
cx(4)
|
704
sbin/i386/cxconfig/cxconfig.c
Normal file
704
sbin/i386/cxconfig/cxconfig.c
Normal file
@ -0,0 +1,704 @@
|
||||
/*
|
||||
* Cronyx-Sigma adapter configuration utility for Unix.
|
||||
*
|
||||
* Copyright (C) 1994 Cronyx Ltd.
|
||||
* Author: Serge Vakulenko, <vak@zebub.msk.su>
|
||||
*
|
||||
* This software is distributed with NO WARRANTIES, not even the implied
|
||||
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Authors grant any other persons or organisations permission to use
|
||||
* or modify this software as long as this message is kept with the software,
|
||||
* all derivative works or modified versions.
|
||||
*
|
||||
* Version 1.1, Wed Oct 26 16:08:09 MSK 1994
|
||||
*
|
||||
* Usage:
|
||||
* cxconfig [-a]
|
||||
* -- print status of all channels
|
||||
* cxconfig [-a] <channel>
|
||||
* -- print status of the channel
|
||||
* cxconfig <channel> <option>...
|
||||
* -- set channel options
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/cronyx.h>
|
||||
#include <net/if.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define CXDEV "/dev/cronyx"
|
||||
#define atoi(a) strtol((a), (char**)0, 0)
|
||||
|
||||
cx_options_t o;
|
||||
int aflag;
|
||||
|
||||
char *symbol (unsigned char sym)
|
||||
{
|
||||
static char buf[40];
|
||||
|
||||
if (sym < ' ')
|
||||
sprintf (buf, "^%c", sym+0100);
|
||||
else if (sym == '\\')
|
||||
strcat (buf, "\\\\");
|
||||
else if (sym < 127)
|
||||
sprintf (buf, "%c", sym);
|
||||
else
|
||||
sprintf (buf, "\\%03o", sym);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
unsigned char atosym (char *s)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
if (*s == '^')
|
||||
return (*++s & 037);
|
||||
if (*s == '\\')
|
||||
return (strtol (++s, 0, 8));
|
||||
return (*s);
|
||||
}
|
||||
|
||||
void usage ()
|
||||
{
|
||||
printf ("Cronyx-Sigma Adapter Configuration Utility, Version 1.0\n");
|
||||
printf ("Copyright (C) 1994 Cronyx Ltd.\n");
|
||||
printf ("Usage:\n");
|
||||
printf ("\tcxconfig [-a]\n");
|
||||
printf ("\t\t-- print status of all channels\n");
|
||||
printf ("\tcxconfig [-a] <channel>\n");
|
||||
printf ("\t\t-- print status of the channel\n");
|
||||
printf ("\tcxconfig <channel> [async | hdlc | bisync | x.21] [ispeed #] [ospeed #]\n");
|
||||
printf ("\t\t[+cts | -cts]\n");
|
||||
printf ("\t\t-- set channel options\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
char *chantype (int type)
|
||||
{
|
||||
switch (type) {
|
||||
case T_NONE: return ("none");
|
||||
case T_ASYNC: return ("RS-232");
|
||||
case T_UNIV_RS232: return ("RS-232");
|
||||
case T_UNIV_RS449: return ("RS-232/RS-449");
|
||||
case T_UNIV_V35: return ("RS-232/V.35");
|
||||
case T_SYNC_RS232: return ("RS-232");
|
||||
case T_SYNC_V35: return ("V.35");
|
||||
case T_SYNC_RS449: return ("RS-449");
|
||||
}
|
||||
}
|
||||
|
||||
char *chanmode (int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case M_ASYNC: return ("Async");
|
||||
case M_HDLC: return ("HDLC");
|
||||
case M_BISYNC: return ("Bisync");
|
||||
case M_X21: return ("X.21");
|
||||
default: return ("???");
|
||||
}
|
||||
}
|
||||
|
||||
void getchan (int channel)
|
||||
{
|
||||
int s = open (CXDEV, 0);
|
||||
if (s < 0) {
|
||||
perror (CXDEV);
|
||||
exit (1);
|
||||
}
|
||||
o.board = channel/NCHAN;
|
||||
o.channel = channel%NCHAN;
|
||||
if (ioctl (s, CXIOCGETMODE, (caddr_t)&o) < 0) {
|
||||
perror ("cxconfig: CXIOCGETMODE");
|
||||
exit (1);
|
||||
}
|
||||
close (s);
|
||||
if (o.type == T_NONE) {
|
||||
fprintf (stderr, "cx%d: channel %d not configured\n", o.board,
|
||||
o.channel);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
void setchan (int channel)
|
||||
{
|
||||
int s = open (CXDEV, 0);
|
||||
if (s < 0) {
|
||||
perror (CXDEV);
|
||||
exit (1);
|
||||
}
|
||||
o.board = channel/NCHAN;
|
||||
o.channel = channel%NCHAN;
|
||||
if (ioctl (s, CXIOCSETMODE, (caddr_t)&o) < 0) {
|
||||
perror ("cxconfig: CXIOCSETMODE");
|
||||
exit (1);
|
||||
}
|
||||
close (s);
|
||||
}
|
||||
|
||||
void printopt ()
|
||||
{
|
||||
/* Common channel options */
|
||||
/* channel option register 4 */
|
||||
printf ("\t");
|
||||
printf ("fifo=%d ", o.opt.cor4.thr); /* FIFO threshold */
|
||||
printf ("%cctsdown ", o.opt.cor4.cts_zd ? '+' : '-'); /* detect 1 to 0 transition on the CTS */
|
||||
printf ("%ccddown ", o.opt.cor4.cd_zd ? '+' : '-'); /* detect 1 to 0 transition on the CD */
|
||||
printf ("%cdsrdown ", o.opt.cor4.dsr_zd ? '+' : '-'); /* detect 1 to 0 transition on the DSR */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 5 */
|
||||
printf ("\t");
|
||||
printf ("rfifo=%d ", o.opt.cor5.rx_thr); /* receive flow control FIFO threshold */
|
||||
printf ("%cctsup ", o.opt.cor5.cts_od ? '+' : '-'); /* detect 0 to 1 transition on the CTS */
|
||||
printf ("%ccdup ", o.opt.cor5.cd_od ? '+' : '-'); /* detect 0 to 1 transition on the CD */
|
||||
printf ("%cdsrup ", o.opt.cor5.dsr_od ? '+' : '-'); /* detect 0 to 1 transition on the DSR */
|
||||
printf ("\n");
|
||||
|
||||
/* receive clock option register */
|
||||
printf ("\t");
|
||||
printf ("%s ", o.opt.rcor.encod == ENCOD_NRZ ? "nrz" : /* signal encoding */
|
||||
o.opt.rcor.encod == ENCOD_NRZI ? "nrzi" :
|
||||
o.opt.rcor.encod == ENCOD_MANCHESTER ? "manchester" : "???");
|
||||
printf ("%cdpll ", o.opt.rcor.dpll ? '+' : '-'); /* DPLL enable */
|
||||
|
||||
/* transmit clock option register */
|
||||
printf ("%clloop ", o.opt.tcor.llm ? '+' : '-'); /* local loopback mode */
|
||||
printf ("%cextclock ", o.opt.tcor.ext1x ? '+' : '-'); /* external 1x clock mode */
|
||||
printf ("\n");
|
||||
|
||||
switch (o.mode) {
|
||||
case M_ASYNC: /* async mode options */
|
||||
/* channel option register 1 */
|
||||
printf ("\t");
|
||||
printf ("cs%d ", o.aopt.cor1.charlen+1); /* character length, 5..8 */
|
||||
printf ("par%s ", o.aopt.cor1.parity ? "odd" : "even"); /* parity */
|
||||
printf ("%cignpar ", o.aopt.cor1.ignpar ? '+' : '-'); /* ignore parity */
|
||||
if (o.aopt.cor1.parmode != PARM_NORMAL) /* parity mode */
|
||||
printf ("%s ", o.aopt.cor1.parmode == PARM_NOPAR ? "nopar" :
|
||||
o.aopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 2 */
|
||||
printf ("\t");
|
||||
printf ("%cdsr ", o.aopt.cor2.dsrae ? '+' : '-'); /* DSR automatic enable */
|
||||
printf ("%ccts ", o.aopt.cor2.ctsae ? '+' : '-'); /* CTS automatic enable */
|
||||
printf ("%crts ", o.aopt.cor2.rtsao ? '+' : '-'); /* RTS automatic output enable */
|
||||
printf ("%crloop ", o.aopt.cor2.rlm ? '+' : '-'); /* remote loopback mode enable */
|
||||
printf ("%cetc ", o.aopt.cor2.etc ? '+' : '-'); /* embedded transmitter cmd enable */
|
||||
printf ("%cxon ", o.aopt.cor2.ixon ? '+' : '-'); /* in-band XON/XOFF enable */
|
||||
printf ("%cxany ", o.aopt.cor2.ixany ? '+' : '-'); /* XON on any character */
|
||||
printf ("\n");
|
||||
|
||||
/* option register 3 */
|
||||
printf ("\t");
|
||||
printf ("%s ", o.aopt.cor3.stopb == STOPB_1 ? "stopb1" : /* stop bit length */
|
||||
o.aopt.cor3.stopb == STOPB_15 ? "stopb1.5" :
|
||||
o.aopt.cor3.stopb == STOPB_2 ? "stopb2" : "???");
|
||||
printf ("%csdt ", o.aopt.cor3.scde ? '+' : '-'); /* special char detection enable */
|
||||
printf ("%cflowct ", o.aopt.cor3.flowct ? '+' : '-'); /* flow control transparency mode */
|
||||
printf ("%crdt ", o.aopt.cor3.rngde ? '+' : '-'); /* range detect enable */
|
||||
printf ("%cexdt ", o.aopt.cor3.escde ? '+' : '-'); /* extended spec. char detect enable */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 6 */
|
||||
printf ("\t");
|
||||
printf ("%s ", o.aopt.cor6.parerr == PERR_INTR ? "parintr" : /* parity/framing error actions */
|
||||
o.aopt.cor6.parerr == PERR_NULL ? "parnull" :
|
||||
o.aopt.cor6.parerr == PERR_IGNORE ? "parign" :
|
||||
o.aopt.cor6.parerr == PERR_DISCARD ? "pardisc" :
|
||||
o.aopt.cor6.parerr == PERR_FFNULL ? "parffnull" : "???");
|
||||
printf ("%s ", o.aopt.cor6.brk == BRK_INTR ? "brkintr" : /* action on break condition */
|
||||
o.aopt.cor6.brk == BRK_NULL ? "brknull" :
|
||||
o.aopt.cor6.brk == BRK_DISCARD ? "brkdisc" : "???");
|
||||
printf ("%cinlcr ", o.aopt.cor6.inlcr ? '+' : '-'); /* translate NL to CR on input */
|
||||
printf ("%cicrnl ", o.aopt.cor6.icrnl ? '+' : '-'); /* translate CR to NL on input */
|
||||
printf ("%cigncr ", o.aopt.cor6.igncr ? '+' : '-'); /* discard CR on input */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 7 */
|
||||
printf ("\t");
|
||||
printf ("%cocrnl ", o.aopt.cor7.ocrnl ? '+' : '-'); /* translate CR to NL on output */
|
||||
printf ("%conlcr ", o.aopt.cor7.onlcr ? '+' : '-'); /* translate NL to CR on output */
|
||||
printf ("%cfcerr ", o.aopt.cor7.fcerr ? '+' : '-'); /* process flow ctl err chars enable */
|
||||
printf ("%clnext ", o.aopt.cor7.lnext ? '+' : '-'); /* LNext option enable */
|
||||
printf ("%cistrip ", o.aopt.cor7.istrip ? '+' : '-'); /* strip 8-bit on input */
|
||||
printf ("\n");
|
||||
|
||||
printf ("\t");
|
||||
printf ("schr1=%s ", symbol (o.aopt.schr1)); /* special character register 1 (XON) */
|
||||
printf ("schr2=%s ", symbol (o.aopt.schr2)); /* special character register 2 (XOFF) */
|
||||
printf ("schr3=%s ", symbol (o.aopt.schr3)); /* special character register 3 */
|
||||
printf ("schr4=%s ", symbol (o.aopt.schr4)); /* special character register 4 */
|
||||
printf ("scrl=%s ", symbol (o.aopt.scrl)); /* special character range low */
|
||||
printf ("scrh=%s ", symbol (o.aopt.scrh)); /* special character range high */
|
||||
printf ("lnext=%s ", symbol (o.aopt.lnxt)); /* LNext character */
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case M_HDLC: /* hdlc mode options */
|
||||
/* hdlc channel option register 1 */
|
||||
printf ("\t");
|
||||
printf ("if%d ", o.hopt.cor1.ifflags); /* number of inter-frame flags sent */
|
||||
printf ("%s ", o.hopt.cor1.admode == ADMODE_NOADDR ? "noaddr" : /* addressing mode */
|
||||
o.hopt.cor1.admode == ADMODE_4_1 ? "addr1" :
|
||||
o.hopt.cor1.admode == ADMODE_2_2 ? "addr2" : "???");
|
||||
printf ("%cclrdet ", o.hopt.cor1.clrdet ? '+' : '-'); /* clear detect for X.21 data transfer phase */
|
||||
printf ("addrlen%d ", o.hopt.cor1.aflo + 1); /* address field length option */
|
||||
printf ("\n");
|
||||
|
||||
/* hdlc channel option register 2 */
|
||||
printf ("\t");
|
||||
printf ("%cdsr ", o.hopt.cor2.dsrae ? '+' : '-'); /* DSR automatic enable */
|
||||
printf ("%ccts ", o.hopt.cor2.ctsae ? '+' : '-'); /* CTS automatic enable */
|
||||
printf ("%crts ", o.hopt.cor2.rtsao ? '+' : '-'); /* RTS automatic output enable */
|
||||
printf ("%ccrcinv ", o.hopt.cor2.crcninv ? '-' : '+'); /* CRC invertion option */
|
||||
printf ("%cfcsapd ", o.hopt.cor2.fcsapd ? '+' : '-'); /* FCS append */
|
||||
printf ("\n");
|
||||
|
||||
/* hdlc channel option register 3 */
|
||||
printf ("\t");
|
||||
printf ("pad%d ", o.hopt.cor3.padcnt); /* pad character count */
|
||||
printf ("idle%s ", o.hopt.cor3.idle ? "mark" : "flag"); /* idle mode */
|
||||
printf ("%cfcs ", o.hopt.cor3.nofcs ? '-' : '+'); /* FCS disable */
|
||||
printf ("fcs-%s ", o.hopt.cor3.fcspre ? "crc-16" : "v.41"); /* FCS preset */
|
||||
printf ("syn=%s ", o.hopt.cor3.syncpat ? "0xAA" : "0x00"); /* send sync pattern */
|
||||
printf ("%csyn ", o.hopt.cor3.sndpad ? '+' : '-'); /* send pad characters before flag enable */
|
||||
printf ("\n");
|
||||
|
||||
printf ("\t");
|
||||
printf ("rfar1=0x%02x ", o.hopt.rfar1); /* receive frame address register 1 */
|
||||
printf ("rfar2=0x%02x ", o.hopt.rfar2); /* receive frame address register 2 */
|
||||
printf ("rfar3=0x%02x ", o.hopt.rfar3); /* receive frame address register 3 */
|
||||
printf ("rfar4=0x%02x ", o.hopt.rfar4); /* receive frame address register 4 */
|
||||
printf ("crc-%s ", o.hopt.cpsr ? "16" : "v.41"); /* CRC polynomial select */
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case M_BISYNC: /* bisync mode options */
|
||||
/* channel option register 1 */
|
||||
printf ("\t");
|
||||
printf ("cs%d ", o.bopt.cor1.charlen+1); /* character length, 5..8 */
|
||||
printf ("par%s ", o.bopt.cor1.parity ? "odd" : "even"); /* parity */
|
||||
printf ("%cignpar ", o.bopt.cor1.ignpar ? '+' : '-'); /* ignore parity */
|
||||
if (o.bopt.cor1.parmode != PARM_NORMAL) /* parity mode */
|
||||
printf ("%s ", o.bopt.cor1.parmode == PARM_NOPAR ? "nopar" :
|
||||
o.bopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 2 */
|
||||
printf ("\t");
|
||||
printf ("syn%d ", o.bopt.cor2.syns+2); /* number of extra SYN chars before a frame */
|
||||
printf ("%ccrcinv ", o.bopt.cor2.crcninv ? '-' : '+'); /* CRC invertion option */
|
||||
printf ("%s ", o.bopt.cor2.ebcdic ? "ebcdic" : "ascii"); /* use EBCDIC as char set (instead of ASCII) */
|
||||
printf ("%cbccapd ", o.bopt.cor2.bcc ? '+' : '-'); /* BCC append enable */
|
||||
printf ("%s ", o.bopt.cor2.lrc ? "lrc" : "crc-16"); /* longitudinal redundancy check */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 3 */
|
||||
printf ("\t");
|
||||
printf ("pad%d ", o.bopt.cor3.padcnt); /* pad character count */
|
||||
printf ("idle%s ", o.bopt.cor3.idle ? "mark" : "syn"); /* idle mode */
|
||||
printf ("%cfcs ", o.bopt.cor3.nofcs ? '-' : '+'); /* FCS disable */
|
||||
printf ("fcs-%s ", o.bopt.cor3.fcspre ? "crc-16" : "v.41"); /* FCS preset */
|
||||
printf ("syn=%s ", o.bopt.cor3.padpat ? "0x55" : "0xAA"); /* send sync pattern */
|
||||
printf ("%csyn ", o.bopt.cor3.sndpad ? '+' : '-'); /* send pad characters before flag enable */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 6 */
|
||||
printf ("\t");
|
||||
printf ("specterm=%s ", symbol (o.bopt.cor6.specterm)); /* special termination character */
|
||||
|
||||
printf ("crc-%s ", o.bopt.cpsr ? "16" : "v.41"); /* CRC polynomial select */
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case M_X21: /* x.21 mode options */
|
||||
/* channel option register 1 */
|
||||
printf ("\t");
|
||||
printf ("cs%d ", o.xopt.cor1.charlen+1); /* character length, 5..8 */
|
||||
printf ("par%s ", o.xopt.cor1.parity ? "odd" : "even"); /* parity */
|
||||
printf ("%cignpar ", o.xopt.cor1.ignpar ? '+' : '-'); /* ignore parity */
|
||||
if (o.xopt.cor1.parmode != PARM_NORMAL) /* parity mode */
|
||||
printf ("%s ", o.xopt.cor1.parmode == PARM_NOPAR ? "nopar" :
|
||||
o.xopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 2 */
|
||||
printf ("\t");
|
||||
printf ("%cetc ", o.xopt.cor2.etc ? '+' : '-'); /* embedded transmitter cmd enable */
|
||||
|
||||
/* channel option register 3 */
|
||||
printf ("%csdt ", o.xopt.cor3.scde ? '+' : '-'); /* special char detection enable */
|
||||
printf ("%cstripsyn ", o.xopt.cor3.stripsyn ? '+' : '-'); /* treat SYN chars as special condition */
|
||||
printf ("%cssdt ", o.xopt.cor3.ssde ? '+' : '-'); /* steady state detect enable */
|
||||
printf ("syn%c ", o.xopt.cor3.syn ? '1' : '2'); /* the number of SYN chars on receive */
|
||||
printf ("\n");
|
||||
|
||||
/* channel option register 6 */
|
||||
printf ("\t");
|
||||
printf ("syn=%s ", symbol (o.xopt.cor6.synchar)); /* syn character */
|
||||
|
||||
printf ("schr1=%s ", symbol (o.xopt.schr1)); /* special character register 1 */
|
||||
printf ("schr2=%s ", symbol (o.xopt.schr2)); /* special character register 2 */
|
||||
printf ("schr3=%s ", symbol (o.xopt.schr3)); /* special character register 3 */
|
||||
printf ("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void printchan (int channel)
|
||||
{
|
||||
printf ("cx%d (%s) %s", channel, chantype (o.type), chanmode (o.mode));
|
||||
if (o.txbaud == o.rxbaud)
|
||||
printf (" %d", o.rxbaud);
|
||||
else
|
||||
printf (" ospeed=%d ispeed=%d", o.txbaud, o.rxbaud);
|
||||
if ((o.channel == 0 || o.channel == 8) &&
|
||||
(o.type == T_UNIV_V35 || o.type == T_UNIV_RS449))
|
||||
printf (" port=%s", o.iftype ? (o.type == T_UNIV_V35 ?
|
||||
"v35" : "rs449") : "rs232");
|
||||
printf (o.sopt.ext ? " ext" : o.sopt.cisco ? " cisco" : " ppp");
|
||||
printf (" %ckeepalive", o.sopt.keepalive ? '+' : '-');
|
||||
printf (" %cautorts", o.sopt.norts ? '-' : '+');
|
||||
printf ("\n");
|
||||
if (aflag)
|
||||
printopt ();
|
||||
}
|
||||
|
||||
void printall ()
|
||||
{
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifr;
|
||||
char buf[BUFSIZ], *cp;
|
||||
int s, c;
|
||||
|
||||
s = socket (AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
perror ("cxconfig: socket");
|
||||
exit (1);
|
||||
}
|
||||
ifc.ifc_len = sizeof (buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if (ioctl (s, SIOCGIFCONF, (caddr_t)&ifc) < 0) {
|
||||
perror ("cxconfig: SIOCGIFCONF");
|
||||
exit (1);
|
||||
}
|
||||
close (s);
|
||||
s = open (CXDEV, 0);
|
||||
if (s < 0) {
|
||||
perror (CXDEV);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
ifr = ifc.ifc_req;
|
||||
#define max(a,b) ((a)>(b) ? (a) : (b))
|
||||
#define size(p) max((p).sa_len, sizeof(p))
|
||||
for (cp=buf; cp<buf+ifc.ifc_len; cp+=sizeof(ifr->ifr_name)+size(ifr->ifr_addr)) {
|
||||
ifr = (struct ifreq*) cp;
|
||||
if (ifr->ifr_addr.sa_family != AF_LINK)
|
||||
continue;
|
||||
if (strncmp (ifr->ifr_name, "cx", 2) != 0)
|
||||
continue;
|
||||
c = atoi (ifr->ifr_name + 2);
|
||||
o.board = c/NCHAN;
|
||||
o.channel = c%NCHAN;
|
||||
if (ioctl (s, CXIOCGETMODE, (caddr_t)&o) < 0) {
|
||||
perror ("cxconfig: CXIOCGETMODE");
|
||||
exit (1);
|
||||
}
|
||||
printchan (c);
|
||||
}
|
||||
close (s);
|
||||
}
|
||||
|
||||
void set_interface_type (char *type)
|
||||
{
|
||||
if (o.channel != 0 && o.channel != 8) {
|
||||
printf ("interface option is applicable only for channels 0 and 8\n");
|
||||
exit (1);
|
||||
}
|
||||
if (o.type != T_UNIV_V35 && o.type != T_UNIV_RS449) {
|
||||
printf ("interface option is applicable only for universal channels\n");
|
||||
exit (1);
|
||||
}
|
||||
if (! strcasecmp (type, "port=rs232"))
|
||||
o.iftype = 0;
|
||||
else
|
||||
o.iftype = 1;
|
||||
}
|
||||
|
||||
void set_async_opt (char *opt)
|
||||
{
|
||||
/* channel option register 1 */
|
||||
if (! strncasecmp (opt, "cs", 2)) o.aopt.cor1.charlen = atoi (opt + 2) - 1;
|
||||
else if (! strcasecmp (opt, "parodd")) o.aopt.cor1.parity = 1;
|
||||
else if (! strcasecmp (opt, "pareven")) o.aopt.cor1.parity = 0;
|
||||
else if (! strcasecmp (opt, "-ignpar")) o.aopt.cor1.ignpar = 0;
|
||||
else if (! strcasecmp (opt, "+ignpar")) o.aopt.cor1.ignpar = 1;
|
||||
else if (! strcasecmp (opt, "nopar")) o.aopt.cor1.parmode = PARM_NOPAR;
|
||||
else if (! strcasecmp (opt, "forcepar")) o.aopt.cor1.parmode = PARM_FORCE;
|
||||
|
||||
/* channel option register 2 */
|
||||
else if (! strcasecmp (opt, "-dsr")) o.aopt.cor2.dsrae = 0;
|
||||
else if (! strcasecmp (opt, "+dsr")) o.aopt.cor2.dsrae = 1;
|
||||
else if (! strcasecmp (opt, "-cts")) o.aopt.cor2.ctsae = 0;
|
||||
else if (! strcasecmp (opt, "+cts")) o.aopt.cor2.ctsae = 1;
|
||||
else if (! strcasecmp (opt, "-rts")) o.aopt.cor2.rtsao = 0;
|
||||
else if (! strcasecmp (opt, "+rts")) o.aopt.cor2.rtsao = 1;
|
||||
else if (! strcasecmp (opt, "-rloop")) o.aopt.cor2.rlm = 0;
|
||||
else if (! strcasecmp (opt, "+rloop")) o.aopt.cor2.rlm = 1;
|
||||
else if (! strcasecmp (opt, "-etc")) o.aopt.cor2.etc = 0;
|
||||
else if (! strcasecmp (opt, "+etc")) o.aopt.cor2.etc = 1;
|
||||
else if (! strcasecmp (opt, "-ixon")) o.aopt.cor2.ixon = 0;
|
||||
else if (! strcasecmp (opt, "+ixon")) o.aopt.cor2.ixon = 1;
|
||||
else if (! strcasecmp (opt, "-ixany")) o.aopt.cor2.ixany = 0;
|
||||
else if (! strcasecmp (opt, "+ixany")) o.aopt.cor2.ixany = 1;
|
||||
|
||||
/* option register 3 */
|
||||
else if (! strcasecmp (opt, "stopb1")) o.aopt.cor3.stopb = STOPB_1;
|
||||
else if (! strcasecmp (opt, "stopb1.5")) o.aopt.cor3.stopb = STOPB_15;
|
||||
else if (! strcasecmp (opt, "stopb2")) o.aopt.cor3.stopb = STOPB_2;
|
||||
else if (! strcasecmp (opt, "-sdt")) o.aopt.cor3.scde = 0;
|
||||
else if (! strcasecmp (opt, "+sdt")) o.aopt.cor3.scde = 1;
|
||||
else if (! strcasecmp (opt, "-flowct")) o.aopt.cor3.flowct = 0;
|
||||
else if (! strcasecmp (opt, "+flowct")) o.aopt.cor3.flowct = 1;
|
||||
else if (! strcasecmp (opt, "-rdt")) o.aopt.cor3.rngde = 0;
|
||||
else if (! strcasecmp (opt, "+rdt")) o.aopt.cor3.rngde = 1;
|
||||
else if (! strcasecmp (opt, "-exdt")) o.aopt.cor3.escde = 0;
|
||||
else if (! strcasecmp (opt, "+exdt")) o.aopt.cor3.escde = 1;
|
||||
|
||||
/* channel option register 6 */
|
||||
else if (! strcasecmp (opt, "parintr")) o.aopt.cor6.parerr = PERR_INTR;
|
||||
else if (! strcasecmp (opt, "parnull")) o.aopt.cor6.parerr = PERR_NULL;
|
||||
else if (! strcasecmp (opt, "parign")) o.aopt.cor6.parerr = PERR_IGNORE;
|
||||
else if (! strcasecmp (opt, "pardisc")) o.aopt.cor6.parerr = PERR_DISCARD;
|
||||
else if (! strcasecmp (opt, "parffnull")) o.aopt.cor6.parerr = PERR_FFNULL;
|
||||
else if (! strcasecmp (opt, "brkintr")) o.aopt.cor6.brk = BRK_INTR;
|
||||
else if (! strcasecmp (opt, "brknull")) o.aopt.cor6.brk = BRK_NULL;
|
||||
else if (! strcasecmp (opt, "brkdisc")) o.aopt.cor6.brk = BRK_DISCARD;
|
||||
else if (! strcasecmp (opt, "-inlcr")) o.aopt.cor6.inlcr = 0;
|
||||
else if (! strcasecmp (opt, "+inlcr")) o.aopt.cor6.inlcr = 1;
|
||||
else if (! strcasecmp (opt, "-icrnl")) o.aopt.cor6.icrnl = 0;
|
||||
else if (! strcasecmp (opt, "+icrnl")) o.aopt.cor6.icrnl = 1;
|
||||
else if (! strcasecmp (opt, "-igncr")) o.aopt.cor6.igncr = 0;
|
||||
else if (! strcasecmp (opt, "+igncr")) o.aopt.cor6.igncr = 1;
|
||||
|
||||
/* channel option register 7 */
|
||||
else if (! strcasecmp (opt, "-ocrnl")) o.aopt.cor7.ocrnl = 0;
|
||||
else if (! strcasecmp (opt, "+ocrnl")) o.aopt.cor7.ocrnl = 1;
|
||||
else if (! strcasecmp (opt, "-onlcr")) o.aopt.cor7.onlcr = 0;
|
||||
else if (! strcasecmp (opt, "+onlcr")) o.aopt.cor7.onlcr = 1;
|
||||
else if (! strcasecmp (opt, "-fcerr")) o.aopt.cor7.fcerr = 0;
|
||||
else if (! strcasecmp (opt, "+fcerr")) o.aopt.cor7.fcerr = 1;
|
||||
else if (! strcasecmp (opt, "-lnext")) o.aopt.cor7.lnext = 0;
|
||||
else if (! strcasecmp (opt, "+lnext")) o.aopt.cor7.lnext = 1;
|
||||
else if (! strcasecmp (opt, "-istrip")) o.aopt.cor7.istrip = 0;
|
||||
else if (! strcasecmp (opt, "+istrip")) o.aopt.cor7.istrip = 1;
|
||||
|
||||
else if (! strncasecmp (opt, "schr1=", 6)) o.aopt.schr1 = atosym (opt+6);
|
||||
else if (! strncasecmp (opt, "schr2=", 6)) o.aopt.schr2 = atosym (opt+6);
|
||||
else if (! strncasecmp (opt, "schr3=", 6)) o.aopt.schr3 = atosym (opt+6);
|
||||
else if (! strncasecmp (opt, "schr4=", 6)) o.aopt.schr4 = atosym (opt+6);
|
||||
else if (! strncasecmp (opt, "scrl=", 5)) o.aopt.scrl = atosym (opt+5);
|
||||
else if (! strncasecmp (opt, "scrh=", 5)) o.aopt.scrh = atosym (opt+5);
|
||||
else if (! strncasecmp (opt, "lnext=", 6)) o.aopt.lnxt = atosym (opt+6);
|
||||
else
|
||||
usage ();
|
||||
}
|
||||
|
||||
void set_hdlc_opt (char *opt)
|
||||
{
|
||||
/* hdlc channel option register 1 */
|
||||
if (! strncasecmp (opt, "if", 2)) o.hopt.cor1.ifflags = atoi (opt + 2);
|
||||
else if (! strcasecmp (opt, "noaddr")) o.hopt.cor1.admode = ADMODE_NOADDR;
|
||||
else if (! strcasecmp (opt, "addr1")) o.hopt.cor1.admode = ADMODE_4_1;
|
||||
else if (! strcasecmp (opt, "addr2")) o.hopt.cor1.admode = ADMODE_2_2;
|
||||
else if (! strcasecmp (opt, "-clrdet")) o.hopt.cor1.clrdet = 0;
|
||||
else if (! strcasecmp (opt, "+clrdet")) o.hopt.cor1.clrdet = 1;
|
||||
else if (! strcasecmp (opt, "addrlen1")) o.hopt.cor1.aflo = 0;
|
||||
else if (! strcasecmp (opt, "addrlen2")) o.hopt.cor1.aflo = 1;
|
||||
|
||||
/* hdlc channel option register 2 */
|
||||
else if (! strcasecmp (opt, "-dsr")) o.hopt.cor2.dsrae = 0;
|
||||
else if (! strcasecmp (opt, "+dsr")) o.hopt.cor2.dsrae = 1;
|
||||
else if (! strcasecmp (opt, "-cts")) o.hopt.cor2.ctsae = 0;
|
||||
else if (! strcasecmp (opt, "+cts")) o.hopt.cor2.ctsae = 1;
|
||||
else if (! strcasecmp (opt, "-rts")) o.hopt.cor2.rtsao = 0;
|
||||
else if (! strcasecmp (opt, "+rts")) o.hopt.cor2.rtsao = 1;
|
||||
else if (! strcasecmp (opt, "-fcsapd")) o.hopt.cor2.fcsapd = 0;
|
||||
else if (! strcasecmp (opt, "+fcsapd")) o.hopt.cor2.fcsapd = 1;
|
||||
else if (! strcasecmp (opt, "-crcinv")) o.hopt.cor2.crcninv = 1;
|
||||
else if (! strcasecmp (opt, "+crcinv")) o.hopt.cor2.crcninv = 0;
|
||||
|
||||
/* hdlc channel option register 3 */
|
||||
else if (! strncasecmp (opt, "pad", 3)) o.hopt.cor3.padcnt = atoi (opt + 3);
|
||||
else if (! strcasecmp (opt, "idlemark")) o.hopt.cor3.idle = 1;
|
||||
else if (! strcasecmp (opt, "idleflag")) o.hopt.cor3.idle = 0;
|
||||
else if (! strcasecmp (opt, "-fcs")) o.hopt.cor3.nofcs = 1;
|
||||
else if (! strcasecmp (opt, "+fcs")) o.hopt.cor3.nofcs = 0;
|
||||
else if (! strcasecmp (opt, "fcs-crc-16")) o.hopt.cor3.fcspre = 1;
|
||||
else if (! strcasecmp (opt, "fcs-v.41")) o.hopt.cor3.fcspre = 0;
|
||||
else if (! strcasecmp (opt, "syn=0xaa")) o.hopt.cor3.syncpat = 1;
|
||||
else if (! strcasecmp (opt, "syn=0x00")) o.hopt.cor3.syncpat = 0;
|
||||
else if (! strcasecmp (opt, "-syn")) o.hopt.cor3.sndpad = 0;
|
||||
else if (! strcasecmp (opt, "+syn")) o.hopt.cor3.sndpad = 1;
|
||||
|
||||
else if (! strncasecmp (opt, "rfar1=", 6)) o.hopt.rfar1 = atoi (opt + 6);
|
||||
else if (! strncasecmp (opt, "rfar2=", 6)) o.hopt.rfar2 = atoi (opt + 6);
|
||||
else if (! strncasecmp (opt, "rfar3=", 6)) o.hopt.rfar3 = atoi (opt + 6);
|
||||
else if (! strncasecmp (opt, "rfar4=", 6)) o.hopt.rfar4 = atoi (opt + 6);
|
||||
else if (! strcasecmp (opt, "crc-16")) o.hopt.cpsr = 1;
|
||||
else if (! strcasecmp (opt, "crc-v.41")) o.hopt.cpsr = 0;
|
||||
else usage ();
|
||||
}
|
||||
|
||||
void set_bisync_opt (char *opt)
|
||||
{
|
||||
usage ();
|
||||
}
|
||||
|
||||
void set_x21_opt (char *opt)
|
||||
{
|
||||
usage ();
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int channel;
|
||||
|
||||
for (--argc, ++argv; argc>0 && **argv=='-'; --argc, ++argv)
|
||||
if (! strcasecmp (*argv, "-a"))
|
||||
++aflag;
|
||||
else
|
||||
usage ();
|
||||
|
||||
if (argc <= 0) {
|
||||
printall ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (argv[0][0]=='c' && argv[0][1]=='x')
|
||||
*argv += 2;
|
||||
if (**argv<'0' || **argv>'9')
|
||||
usage ();
|
||||
channel = atoi (*argv);
|
||||
--argc, ++argv;
|
||||
getchan (channel);
|
||||
|
||||
if (argc <= 0) {
|
||||
printchan (channel);
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (; argc>0; --argc, ++argv)
|
||||
if (**argv == '(')
|
||||
continue;
|
||||
else if (! strncasecmp (*argv, "ispeed=", 7))
|
||||
o.rxbaud = atoi (*argv+7);
|
||||
else if (! strncasecmp (*argv, "ospeed=", 7))
|
||||
o.txbaud = atoi (*argv+7);
|
||||
else if (! strcasecmp (*argv, "async"))
|
||||
o.mode = M_ASYNC;
|
||||
else if (! strcasecmp (*argv, "hdlc"))
|
||||
o.mode = M_HDLC;
|
||||
else if (! strcasecmp (*argv, "bisync") ||
|
||||
! strcasecmp (*argv, "bsc"))
|
||||
o.mode = M_BISYNC;
|
||||
else if (! strcasecmp (*argv, "x.21") ||
|
||||
! strcasecmp (*argv, "x21"))
|
||||
o.mode = M_X21;
|
||||
else if (**argv>='0' && **argv<='9')
|
||||
o.txbaud = o.rxbaud = atoi (*argv);
|
||||
else if (! strcasecmp (*argv, "cisco")) {
|
||||
o.sopt.cisco = 1;
|
||||
o.sopt.ext = 0;
|
||||
} else if (! strcasecmp (*argv, "ppp")) {
|
||||
o.sopt.cisco = 0;
|
||||
o.sopt.ext = 0;
|
||||
} else if (! strcasecmp (*argv, "ext"))
|
||||
o.sopt.ext = 1;
|
||||
else if (! strcasecmp (*argv, "+keepalive"))
|
||||
o.sopt.keepalive = 1;
|
||||
else if (! strcasecmp (*argv, "-keepalive"))
|
||||
o.sopt.keepalive = 0;
|
||||
else if (! strcasecmp (*argv, "+autorts"))
|
||||
o.sopt.norts = 0;
|
||||
else if (! strcasecmp (*argv, "-autorts"))
|
||||
o.sopt.norts = 1;
|
||||
else if (! strcasecmp (*argv, "port=rs232") ||
|
||||
! strcasecmp (*argv, "port=rs449") ||
|
||||
! strcasecmp (*argv, "port=v35"))
|
||||
set_interface_type (*argv);
|
||||
|
||||
/*
|
||||
* Common channel options
|
||||
*/
|
||||
/* channel option register 4 */
|
||||
else if (! strcasecmp (*argv, "-ctsdown"))
|
||||
o.opt.cor4.cts_zd = 0;
|
||||
else if (! strcasecmp (*argv, "+ctsdown"))
|
||||
o.opt.cor4.cts_zd = 1;
|
||||
else if (! strcasecmp (*argv, "-cddown"))
|
||||
o.opt.cor4.cd_zd = 0;
|
||||
else if (! strcasecmp (*argv, "+cddown"))
|
||||
o.opt.cor4.cd_zd = 1;
|
||||
else if (! strcasecmp (*argv, "-dsrdown"))
|
||||
o.opt.cor4.dsr_zd = 0;
|
||||
else if (! strcasecmp (*argv, "+dsrdown"))
|
||||
o.opt.cor4.dsr_zd = 1;
|
||||
else if (! strncasecmp (*argv, "fifo=", 5))
|
||||
o.opt.cor4.thr = atoi (*argv + 5);
|
||||
|
||||
/* channel option register 5 */
|
||||
else if (! strcasecmp (*argv, "-ctsup"))
|
||||
o.opt.cor5.cts_od = 0;
|
||||
else if (! strcasecmp (*argv, "+ctsup"))
|
||||
o.opt.cor5.cts_od = 1;
|
||||
else if (! strcasecmp (*argv, "-cdup"))
|
||||
o.opt.cor5.cd_od = 0;
|
||||
else if (! strcasecmp (*argv, "+cdup"))
|
||||
o.opt.cor5.cd_od = 1;
|
||||
else if (! strcasecmp (*argv, "-dsrup"))
|
||||
o.opt.cor5.dsr_od = 0;
|
||||
else if (! strcasecmp (*argv, "+dsrup"))
|
||||
o.opt.cor5.dsr_od = 1;
|
||||
else if (! strncasecmp (*argv, "rfifo=", 6))
|
||||
o.opt.cor5.rx_thr = atoi (*argv + 6);
|
||||
|
||||
/* receive clock option register */
|
||||
else if (! strcasecmp (*argv, "nrz"))
|
||||
o.opt.rcor.encod = ENCOD_NRZ;
|
||||
else if (! strcasecmp (*argv, "nrzi"))
|
||||
o.opt.rcor.encod = ENCOD_NRZI;
|
||||
else if (! strcasecmp (*argv, "manchester"))
|
||||
o.opt.rcor.encod = ENCOD_MANCHESTER;
|
||||
else if (! strcasecmp (*argv, "-dpll"))
|
||||
o.opt.rcor.dpll = 0;
|
||||
else if (! strcasecmp (*argv, "+dpll"))
|
||||
o.opt.rcor.dpll = 1;
|
||||
|
||||
/* transmit clock option register */
|
||||
else if (! strcasecmp (*argv, "-lloop"))
|
||||
o.opt.tcor.llm = 0;
|
||||
else if (! strcasecmp (*argv, "+lloop"))
|
||||
o.opt.tcor.llm = 1;
|
||||
else if (! strcasecmp (*argv, "-extclock"))
|
||||
o.opt.tcor.ext1x = 0;
|
||||
else if (! strcasecmp (*argv, "+extclock"))
|
||||
o.opt.tcor.ext1x = 1;
|
||||
|
||||
/*
|
||||
* Mode dependent channel options
|
||||
*/
|
||||
else switch (o.mode) {
|
||||
case M_ASYNC: set_async_opt (*argv); break;
|
||||
case M_HDLC: set_hdlc_opt (*argv); break;
|
||||
case M_BISYNC: set_bisync_opt (*argv); break;
|
||||
case M_X21: set_x21_opt (*argv); break;
|
||||
}
|
||||
|
||||
setchan (channel);
|
||||
return (0);
|
||||
}
|
239
share/man/man4/man4.i386/cx.4
Normal file
239
share/man/man4/man4.i386/cx.4
Normal file
@ -0,0 +1,239 @@
|
||||
.TH Cronyx-Sigma 1
|
||||
.rm ES
|
||||
.rm EE
|
||||
.de ES
|
||||
.PP
|
||||
.nf
|
||||
.in +0.5i
|
||||
..
|
||||
.de EE
|
||||
.in -0.5i
|
||||
.fi
|
||||
..
|
||||
.na
|
||||
.SH NAME
|
||||
.B cx
|
||||
\- asynchronous Cronyx-Sigma adapter driver
|
||||
.br
|
||||
.B if_cx
|
||||
\- synchronous Cronyx-Sigma adapter driver
|
||||
.SH CONFIGURATION
|
||||
.B
|
||||
device cx0 at isa? port 0x240 irq 15 drq 7
|
||||
.br
|
||||
.B
|
||||
device cx1 at isa? port 0x260 irq 12 drq 6
|
||||
.br
|
||||
.B
|
||||
pseudo-device sppp
|
||||
.P
|
||||
The base i/o port address should be set by jumpers on the board.
|
||||
The DMA i/o channel and interrupt request numbers are configured
|
||||
by software at adapter initialization. Legal values are:
|
||||
.IP Port
|
||||
0x240, 0x260, 0x280, 0x300, 0x320, 0x380
|
||||
.IP IRQ
|
||||
3, 5, 7, 10, 11, 12, 15
|
||||
.IP DMA
|
||||
5, 6, 7
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The Cronyx-Sigma driver supports the adapters of models 100,
|
||||
400, 500, 401, 404, 410, 440, 703, 801, 810, 840. Different models have
|
||||
different set of channels:
|
||||
.ES
|
||||
Model Channels
|
||||
----------------------------------------------
|
||||
Cronyx-Sigma-100 0
|
||||
Cronyx-Sigma-400 4, 5, 6, 7
|
||||
Cronyx-Sigma-500 0, 4, 5, 6, 7
|
||||
Cronyx-Sigma-401 0, 1, 2, 3
|
||||
Cronyx-Sigma-404 0, 1, 2, 3
|
||||
Cronyx-Sigma-410 0, 1, 2, 3
|
||||
Cronyx-Sigma-440 0, 1, 2, 3
|
||||
Cronyx-Sigma-703 0, 1, 2, 4, 5, 6, 7
|
||||
Cronyx-Sigma-801 0, 1, 2, 3, 4, 5, 6, 7
|
||||
Cronyx-Sigma-810 0, 1, 2, 3, 4, 5, 6, 7
|
||||
Cronyx-Sigma-840 0, 1, 2, 3, 4, 5, 6, 7
|
||||
.EE
|
||||
.PP
|
||||
A pair of two adapters can be united together by the special
|
||||
short inter-board cable. Two united adapters use the same
|
||||
IRQ and DMA channels and from the point of driver works
|
||||
as the single 16-channel multiplexer. One of the united
|
||||
boards is ``master'' and the other is ``slave''.
|
||||
.PP
|
||||
The channels of the slave united board are numbered by the driver
|
||||
beginning with 8, for example, the united adapter of the model 100/500
|
||||
has channels 0, 8, 12, 13, 14, 15.
|
||||
.PP
|
||||
The channels which have the RS-232 interface can be used
|
||||
both in synchronous and asynchronous modes (software selectable
|
||||
by cxconfig utility) and hence are called ``universal'' channels.
|
||||
.PP
|
||||
The special device files (/dev/*) for the adapter Cronyx-Sigma
|
||||
are created by the command file ``/dev/MAKEDEV.cx''.
|
||||
An example:
|
||||
.ES
|
||||
cd /dev
|
||||
sh MAKEDEV.cx cronyx ttyx0 ttyx1 ttyy0
|
||||
.EE
|
||||
.SH "Asynchronous driver"
|
||||
.PP
|
||||
The asynchronous channel device files have the names:
|
||||
/dev/ttyx# - for adapter cx0, /dev/ttyy# - for adapter cx1,
|
||||
/dev/ttyz# - for cx2.
|
||||
Here\ # is the channel number in hexadecimal form, 0-9-a-f.
|
||||
.PP
|
||||
The driver fulfills the following standard ioctl requests (see ioctl(2)):
|
||||
.IP TIOCSBRK
|
||||
Start sending BREAK.
|
||||
.IP TIOCCBRK
|
||||
Stop sending BREAK.
|
||||
.IP TIOCSDTR
|
||||
Set DTR signal (DTR := 1). The DTR signal is always set
|
||||
on the first open(2) and could be changed by
|
||||
TIOCCDTR, TIOCSDTR, TIOCMSET, TIOCMBIS, TIOCMBIC ioctl calls.
|
||||
.IP TIOCCDTR
|
||||
Clear DTR signal (DTR := 0).
|
||||
.IP TIOCMSET
|
||||
Set the given values of DTR and RTS signals (<DTR:RTS> := data).
|
||||
The signals DTR and RTS are controlled by TIOCM_DTR and TIOCM_RTS
|
||||
bits of the data argument of the ioctl system call.
|
||||
.IP TIOCMBIS
|
||||
Set DTR and RTS signals (<DTR:RTS> |= data).
|
||||
The signals DTR and RTS are controlled by TIOCM_DTR and TIOCM_RTS
|
||||
bits of the data argument of the ioctl system call.
|
||||
.IP TIOCMBIC
|
||||
Clear DTR and RTS signals (<DTR:RTS> &= ~data).
|
||||
The signals DTR and RTS are controlled by TIOCM_DTR and TIOCM_RTS
|
||||
bits of the data argument of the ioctl system call.
|
||||
.IP TIOCMGET
|
||||
Determine the state of the modem signals of the line.
|
||||
After the call the data argument contains the following bits:
|
||||
.ES
|
||||
TIOCM_LE - always set (Line Enabled)
|
||||
TIOCM_DSR - Data Set Ready signal received
|
||||
TIOCM_CTS - Clear To Send signal received
|
||||
TIOCM_CD - Data Carrier Detect signal received
|
||||
TIOCM_DTR - Data Terminal Ready signal transmitted
|
||||
TIOCM_RTS - Request To Send signal transmitted
|
||||
.EE
|
||||
.SH "Synchronous driver"
|
||||
.PP
|
||||
The synchronous channels and universal channels, turned to the synchronous
|
||||
mode by the cxconfig(8) utility, are accessible as network
|
||||
interfaces named ``cx#'' where\ # is the channel number, 0..47.
|
||||
All standard network interface parameters could be set by ifconfig(8) utility.
|
||||
The cxconfig(8) command is used to change some extended channel
|
||||
options, and also for setting the high-level software protocol
|
||||
(e.g. PPP or Cisco HDLC).
|
||||
.PP
|
||||
The universal channels could be used both in asynchronous and synchronous modes.
|
||||
By default the asynchronous mode is set.
|
||||
The mode could be changed by cxconfig(8) utility.
|
||||
The mode is blocked while the channel is busy (an asynchronous channel
|
||||
in open state or the network interface is up).
|
||||
.SH "Synchronous Point-to-Point protocol"
|
||||
.PP
|
||||
The Cronyx-Sigma driver uses the built-in implementation of the synchronous
|
||||
Point-to-Point protocol (sppp). It includes the support for such
|
||||
protocols as PPP/HDLC and Cisco/HDLC, and also the automatic
|
||||
connection loss test (via keepalive packets).
|
||||
The sppp protocol set is implemented as an independent module
|
||||
and could be used by other drivers of synchronous serial channels.
|
||||
The version of the driver for BSD/386 (BSDI) operating system
|
||||
also supports the usage of the general set of synchronous
|
||||
protocols, implemented inside the OS.
|
||||
The external protocol set could be selected by ``cxconfig ext'' command
|
||||
(see cxconfig(8)).
|
||||
.SH "Channel Options Management"
|
||||
.PP
|
||||
The cxconfig(8) utility is used for setting the channels options.
|
||||
The channel options are generally set at the start of the operating
|
||||
system (for example, from the file /etc/rc).
|
||||
Note, that not all options have a sense for every particular
|
||||
case, and an attempt to set some of them can hang up the channel or
|
||||
the whole adapter.
|
||||
.PP
|
||||
The actual channel options control functions are implemented via
|
||||
the ioctl-s on the special device file /dev/cronyx.
|
||||
There are the following ioctl-s available:
|
||||
.IP CXIOCGETMODE
|
||||
Get the channel option values.
|
||||
.IP CXIOCSETMODE
|
||||
Set the channel option values.
|
||||
.PP
|
||||
The data argument of the ioctl call has an address of the options structure:
|
||||
.ES
|
||||
typedef struct {
|
||||
unsigned char board; /* adapter number, 0..2 */
|
||||
unsigned char channel; /* channel number, 0..15 */
|
||||
unsigned char type; /* channel type (read only) */
|
||||
unsigned char iftype; /* chan0 interface */
|
||||
unsigned long rxbaud; /* receiver speed */
|
||||
unsigned long txbaud; /* transmitter speed */
|
||||
cx_chan_mode_t mode; /* channel mode */
|
||||
cx_chan_opt_t opt; /* common channel options */
|
||||
cx_opt_async_t aopt; /* async mode options */
|
||||
cx_opt_hdlc_t hopt; /* hdlc mode options */
|
||||
cx_opt_bisync_t bopt; /* bisync mode options */
|
||||
cx_opt_x21_t xopt; /* x.21 mode options */
|
||||
cx_soft_opt_t sopt; /* software options and state flags */
|
||||
} cx_options_t; /* user settable options */
|
||||
.EE
|
||||
.IP board
|
||||
The adapter number, 0..2.
|
||||
.IP channel
|
||||
The channel number, 0..15.
|
||||
.IP type
|
||||
The type of the channel (read-only argument).
|
||||
.IP iftype
|
||||
The interface type of the zero (and also the eight) channel: 0 - RS-232,
|
||||
1 - RS-449/V.35.
|
||||
.IP rxbaud
|
||||
The receiver data baud rate.
|
||||
.IP txbaud
|
||||
The transmitter data baud rate.
|
||||
.IP mode
|
||||
The channel mode: asynchronous/HDLC/Bisync/X.21.
|
||||
.IP opt
|
||||
The general channel options.
|
||||
.IP aopt
|
||||
The asynchronous mode options.
|
||||
.IP hopt
|
||||
The HDLC mode options.
|
||||
.IP bopt
|
||||
The Bisync mode options.
|
||||
.IP xopt
|
||||
The X.21 mode options.
|
||||
.IP sopt
|
||||
The software protocol options.
|
||||
.SH FILES
|
||||
.PP
|
||||
/dev/cx??
|
||||
.IP
|
||||
Asynchronous channels.
|
||||
.PP
|
||||
/dev/cronyx
|
||||
.IP
|
||||
The special device file for the channel options management.
|
||||
.PP
|
||||
/sys/i386/isa/cronyx.c
|
||||
.br
|
||||
/sys/i386/isa/cx.c
|
||||
.br
|
||||
/sys/i386/isa/if_cx.c
|
||||
.br
|
||||
/sys/i386/isa/cronyx.h
|
||||
.br
|
||||
/sys/i386/isa/cxreg.h
|
||||
.br
|
||||
/sys/net/if_spppsubr.c
|
||||
.br
|
||||
/sys/net/if_sppp.h
|
||||
.IP
|
||||
The sources of the driver.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
cxconfig(8)
|
475
sys/i386/include/cronyx.h
Normal file
475
sys/i386/include/cronyx.h
Normal file
@ -0,0 +1,475 @@
|
||||
/*
|
||||
* Defines for Cronyx-Sigma adapter driver.
|
||||
*
|
||||
* Copyright (C) 1994 Cronyx Ltd.
|
||||
* Author: Serge Vakulenko, <vak@zebub.msk.su>
|
||||
*
|
||||
* This software is distributed with NO WARRANTIES, not even the implied
|
||||
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Authors grant any other persons or organisations permission to use
|
||||
* or modify this software as long as this message is kept with the software,
|
||||
* all derivative works or modified versions.
|
||||
*
|
||||
* Version 1.1, Wed Oct 26 16:09:46 MSK 1994
|
||||
*/
|
||||
/*
|
||||
* Asynchronous channel mode -------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Parity */
|
||||
#define PAR_EVEN 0 /* even parity */
|
||||
#define PAR_ODD 1 /* odd parity */
|
||||
|
||||
/* Parity mode */
|
||||
#define PARM_NOPAR 0 /* no parity */
|
||||
#define PARM_FORCE 1 /* force parity (odd = force 1, even = 0) */
|
||||
#define PARM_NORMAL 2 /* normal parity */
|
||||
|
||||
/* Flow control transparency mode */
|
||||
#define FLOWCC_PASS 0 /* pass flow ctl chars as exceptions */
|
||||
#define FLOWCC_NOTPASS 1 /* don't pass flow ctl chars to the host */
|
||||
|
||||
/* Stop bit length */
|
||||
#define STOPB_1 2 /* 1 stop bit */
|
||||
#define STOPB_15 3 /* 1.5 stop bits */
|
||||
#define STOPB_2 4 /* 2 stop bits */
|
||||
|
||||
/* Action on break condition */
|
||||
#define BRK_INTR 0 /* generate an exception interrupt */
|
||||
#define BRK_NULL 1 /* translate to a NULL character */
|
||||
#define BRK_RESERVED 2 /* reserved */
|
||||
#define BRK_DISCARD 3 /* discard character */
|
||||
|
||||
/* Parity/framing error actions */
|
||||
#define PERR_INTR 0 /* generate an exception interrupt */
|
||||
#define PERR_NULL 1 /* translate to a NULL character */
|
||||
#define PERR_IGNORE 2 /* ignore error; char passed as good data */
|
||||
#define PERR_DISCARD 3 /* discard error character */
|
||||
#define PERR_FFNULL 5 /* translate to FF NULL char */
|
||||
|
||||
typedef struct { /* async channel option register 1 */
|
||||
unsigned charlen : 4; /* character length, 5..8 */
|
||||
unsigned ignpar : 1; /* ignore parity */
|
||||
unsigned parmode : 2; /* parity mode */
|
||||
unsigned parity : 1; /* parity */
|
||||
} cx_cor1_async_t;
|
||||
|
||||
typedef struct { /* async channel option register 2 */
|
||||
unsigned dsrae : 1; /* DSR automatic enable */
|
||||
unsigned ctsae : 1; /* CTS automatic enable */
|
||||
unsigned rtsao : 1; /* RTS automatic output enable */
|
||||
unsigned rlm : 1; /* remote loopback mode enable */
|
||||
unsigned zero : 1;
|
||||
unsigned etc : 1; /* embedded transmitter cmd enable */
|
||||
unsigned ixon : 1; /* in-band XON/XOFF enable */
|
||||
unsigned ixany : 1; /* XON on any character */
|
||||
} cx_cor2_async_t;
|
||||
|
||||
typedef struct { /* async channel option register 3 */
|
||||
unsigned stopb : 3; /* stop bit length */
|
||||
unsigned zero : 1;
|
||||
unsigned scde : 1; /* special char detection enable */
|
||||
unsigned flowct : 1; /* flow control transparency mode */
|
||||
unsigned rngde : 1; /* range detect enable */
|
||||
unsigned escde : 1; /* extended spec. char detect enable */
|
||||
} cx_cor3_async_t;
|
||||
|
||||
typedef struct { /* async channel option register 6 */
|
||||
unsigned parerr : 3; /* parity/framing error actions */
|
||||
unsigned brk : 2; /* action on break condition */
|
||||
unsigned inlcr : 1; /* translate NL to CR on input */
|
||||
unsigned icrnl : 1; /* translate CR to NL on input */
|
||||
unsigned igncr : 1; /* discard CR on input */
|
||||
} cx_cor6_async_t;
|
||||
|
||||
typedef struct { /* async channel option register 7 */
|
||||
unsigned ocrnl : 1; /* translate CR to NL on output */
|
||||
unsigned onlcr : 1; /* translate NL to CR on output */
|
||||
unsigned zero : 3;
|
||||
unsigned fcerr : 1; /* process flow ctl err chars enable */
|
||||
unsigned lnext : 1; /* LNext option enable */
|
||||
unsigned istrip : 1; /* strip 8-bit on input */
|
||||
} cx_cor7_async_t;
|
||||
|
||||
typedef struct { /* async channel options */
|
||||
cx_cor1_async_t cor1; /* channel option register 1 */
|
||||
cx_cor2_async_t cor2; /* channel option register 2 */
|
||||
cx_cor3_async_t cor3; /* option register 3 */
|
||||
cx_cor6_async_t cor6; /* channel option register 6 */
|
||||
cx_cor7_async_t cor7; /* channel option register 7 */
|
||||
unsigned char schr1; /* special character register 1 (XON) */
|
||||
unsigned char schr2; /* special character register 2 (XOFF) */
|
||||
unsigned char schr3; /* special character register 3 */
|
||||
unsigned char schr4; /* special character register 4 */
|
||||
unsigned char scrl; /* special character range low */
|
||||
unsigned char scrh; /* special character range high */
|
||||
unsigned char lnxt; /* LNext character */
|
||||
} cx_opt_async_t;
|
||||
|
||||
/*
|
||||
* HDLC channel mode ---------------------------------------------------------
|
||||
*/
|
||||
/* Address field length option */
|
||||
#define AFLO_1OCT 0 /* address field is 1 octet in length */
|
||||
#define AFLO_2OCT 1 /* address field is 2 octet in length */
|
||||
|
||||
/* Clear detect for X.21 data transfer phase */
|
||||
#define CLRDET_DISABLE 0 /* clear detect disabled */
|
||||
#define CLRDET_ENABLE 1 /* clear detect enabled */
|
||||
|
||||
/* Addressing mode */
|
||||
#define ADMODE_NOADDR 0 /* no address */
|
||||
#define ADMODE_4_1 1 /* 4 * 1 byte */
|
||||
#define ADMODE_2_2 2 /* 2 * 2 byte */
|
||||
|
||||
/* FCS append */
|
||||
#define FCS_NOTPASS 0 /* receive CRC is not passed to the host */
|
||||
#define FCS_PASS 1 /* receive CRC is passed to the host */
|
||||
|
||||
/* CRC modes */
|
||||
#define CRC_INVERT 0 /* CRC is transmitted inverted (CRC V.41) */
|
||||
#define CRC_DONT_INVERT 1 /* CRC is not transmitted inverted (CRC-16) */
|
||||
|
||||
/* Send sync pattern */
|
||||
#define SYNC_00 0 /* send 00h as pad char (NRZI encoding) */
|
||||
#define SYNC_AA 1 /* send AAh (Manchester/NRZ encoding) */
|
||||
|
||||
/* FCS preset */
|
||||
#define FCSP_ONES 0 /* FCS is preset to all ones (CRC V.41) */
|
||||
#define FCSP_ZEROS 1 /* FCS is preset to all zeros (CRC-16) */
|
||||
|
||||
/* idle mode */
|
||||
#define IDLE_FLAG 0 /* idle in flag */
|
||||
#define IDLE_MARK 1 /* idle in mark */
|
||||
|
||||
/* CRC polynomial select */
|
||||
#define POLY_V41 0 /* x^16+x^12+x^5+1 (HDLC, preset to 1) */
|
||||
#define POLY_16 1 /* x^16+x^15+x^2+1 (bisync, preset to 0) */
|
||||
|
||||
typedef struct { /* hdlc channel option register 1 */
|
||||
unsigned ifflags : 4; /* number of inter-frame flags sent */
|
||||
unsigned admode : 2; /* addressing mode */
|
||||
unsigned clrdet : 1; /* clear detect for X.21 data transfer phase */
|
||||
unsigned aflo : 1; /* address field length option */
|
||||
} cx_cor1_hdlc_t;
|
||||
|
||||
typedef struct { /* hdlc channel option register 2 */
|
||||
unsigned dsrae : 1; /* DSR automatic enable */
|
||||
unsigned ctsae : 1; /* CTS automatic enable */
|
||||
unsigned rtsao : 1; /* RTS automatic output enable */
|
||||
unsigned zero1 : 1;
|
||||
unsigned crcninv : 1; /* CRC invertion option */
|
||||
unsigned zero2 : 1;
|
||||
unsigned fcsapd : 1; /* FCS append */
|
||||
unsigned zero3 : 1;
|
||||
} cx_cor2_hdlc_t;
|
||||
|
||||
typedef struct { /* hdlc channel option register 3 */
|
||||
unsigned padcnt : 3; /* pad character count */
|
||||
unsigned idle : 1; /* idle mode */
|
||||
unsigned nofcs : 1; /* FCS disable */
|
||||
unsigned fcspre : 1; /* FCS preset */
|
||||
unsigned syncpat : 1; /* send sync pattern */
|
||||
unsigned sndpad : 1; /* send pad characters before flag enable */
|
||||
} cx_cor3_hdlc_t;
|
||||
|
||||
typedef struct { /* hdlc channel options */
|
||||
cx_cor1_hdlc_t cor1; /* hdlc channel option register 1 */
|
||||
cx_cor2_hdlc_t cor2; /* hdlc channel option register 2 */
|
||||
cx_cor3_hdlc_t cor3; /* hdlc channel option register 3 */
|
||||
unsigned char rfar1; /* receive frame address register 1 */
|
||||
unsigned char rfar2; /* receive frame address register 2 */
|
||||
unsigned char rfar3; /* receive frame address register 3 */
|
||||
unsigned char rfar4; /* receive frame address register 4 */
|
||||
unsigned char cpsr; /* CRC polynomial select */
|
||||
} cx_opt_hdlc_t;
|
||||
|
||||
/*
|
||||
* BISYNC channel mode -------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Longitudinal redundancy check */
|
||||
#define BCC_CRC16 0 /* CRC16 is used for BCC */
|
||||
#define BCC_LRC 1 /* LRC is used for BCC */
|
||||
|
||||
/* Send pad pattern */
|
||||
#define PAD_AA 0 /* send AAh as pad character */
|
||||
#define PAD_55 1 /* send 55h as pad character */
|
||||
|
||||
typedef struct { /* channel option register 1 */
|
||||
unsigned charlen : 4; /* character length, 5..8 */
|
||||
unsigned ignpar : 1; /* ignore parity */
|
||||
unsigned parmode : 2; /* parity mode */
|
||||
unsigned parity : 1; /* parity */
|
||||
} cx_cor1_bisync_t;
|
||||
|
||||
typedef struct { /* channel option register 2 */
|
||||
unsigned syns : 4; /* number of extra SYN chars before a frame */
|
||||
unsigned crcninv : 1; /* CRC invertion option */
|
||||
unsigned ebcdic : 1; /* use EBCDIC as char set (instead of ASCII) */
|
||||
unsigned bcc : 1; /* BCC append enable */
|
||||
unsigned lrc : 1; /* longitudinal redundancy check */
|
||||
} cx_cor2_bisync_t;
|
||||
|
||||
typedef struct { /* channel option register 3 */
|
||||
unsigned padcnt : 3; /* pad character count */
|
||||
unsigned idle : 1; /* idle mode */
|
||||
unsigned nofcs : 1; /* FCS disable */
|
||||
unsigned fcspre : 1; /* FCS preset */
|
||||
unsigned padpat : 1; /* send pad pattern */
|
||||
unsigned sndpad : 1; /* send pad characters before SYN enable */
|
||||
} cx_cor3_bisync_t;
|
||||
|
||||
typedef struct { /* channel option register 6 */
|
||||
unsigned char specterm; /* special termination character */
|
||||
} cx_cor6_bisync_t;
|
||||
|
||||
typedef struct { /* bisync channel options */
|
||||
cx_cor1_bisync_t cor1; /* channel option register 1 */
|
||||
cx_cor2_bisync_t cor2; /* channel option register 2 */
|
||||
cx_cor3_bisync_t cor3; /* channel option register 3 */
|
||||
cx_cor6_bisync_t cor6; /* channel option register 6 */
|
||||
unsigned char cpsr; /* CRC polynomial select */
|
||||
} cx_opt_bisync_t;
|
||||
|
||||
/*
|
||||
* X.21 channel mode ---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* The number of SYN chars on receive */
|
||||
#define X21SYN_2 0 /* two SYN characters are required */
|
||||
#define X21SYN_1 1 /* one SYN character is required */
|
||||
|
||||
typedef struct { /* channel option register 1 */
|
||||
unsigned charlen : 4; /* character length, 5..8 */
|
||||
unsigned ignpar : 1; /* ignore parity */
|
||||
unsigned parmode : 2; /* parity mode */
|
||||
unsigned parity : 1; /* parity */
|
||||
} cx_cor1_x21_t;
|
||||
|
||||
typedef struct { /* channel option register 2 */
|
||||
unsigned zero1 : 5;
|
||||
unsigned etc : 1; /* embedded transmitter command enable */
|
||||
unsigned zero2 : 2;
|
||||
} cx_cor2_x21_t;
|
||||
|
||||
typedef struct { /* channel option register 3 */
|
||||
unsigned zero : 4;
|
||||
unsigned scde : 1; /* special character detect enable */
|
||||
unsigned stripsyn : 1; /* treat SYN chars as special condition */
|
||||
unsigned ssde : 1; /* steady state detect enable */
|
||||
unsigned syn : 1; /* the number of SYN chars on receive */
|
||||
} cx_cor3_x21_t;
|
||||
|
||||
typedef struct { /* channel option register 6 */
|
||||
unsigned char synchar; /* syn character */
|
||||
} cx_cor6_x21_t;
|
||||
|
||||
typedef struct { /* x21 channel options */
|
||||
cx_cor1_x21_t cor1; /* channel option register 1 */
|
||||
cx_cor2_x21_t cor2; /* channel option register 2 */
|
||||
cx_cor3_x21_t cor3; /* channel option register 3 */
|
||||
cx_cor6_x21_t cor6; /* channel option register 6 */
|
||||
unsigned char schr1; /* special character register 1 */
|
||||
unsigned char schr2; /* special character register 2 */
|
||||
unsigned char schr3; /* special character register 3 */
|
||||
} cx_opt_x21_t;
|
||||
|
||||
/*
|
||||
* CD2400 channel state structure --------------------------------------------
|
||||
*/
|
||||
|
||||
/* Signal encoding */
|
||||
#define ENCOD_NRZ 0 /* NRZ mode */
|
||||
#define ENCOD_NRZI 1 /* NRZI mode */
|
||||
#define ENCOD_MANCHESTER 2 /* Manchester mode */
|
||||
|
||||
/* Clock source */
|
||||
#define CLK_0 0 /* clock 0 */
|
||||
#define CLK_1 1 /* clock 1 */
|
||||
#define CLK_2 2 /* clock 2 */
|
||||
#define CLK_3 3 /* clock 3 */
|
||||
#define CLK_4 4 /* clock 4 */
|
||||
#define CLK_EXT 6 /* external clock */
|
||||
#define CLK_RCV 7 /* receive clock */
|
||||
|
||||
/* Channel type */
|
||||
#define T_NONE 0 /* no channel */
|
||||
#define T_ASYNC 1 /* pure asynchronous RS-232 channel */
|
||||
#define T_SYNC_RS232 2 /* pure synchronous RS-232 channel */
|
||||
#define T_SYNC_V35 3 /* pure synchronous V.35 channel */
|
||||
#define T_SYNC_RS449 4 /* pure synchronous RS-449 channel */
|
||||
#define T_UNIV_RS232 5 /* sync/async RS-232 channel */
|
||||
#define T_UNIV_RS449 6 /* sync/async RS-232/RS-449 channel */
|
||||
#define T_UNIV_V35 7 /* sync/async RS-232/V.35 channel */
|
||||
|
||||
typedef enum { /* channel mode */
|
||||
M_ASYNC, /* asynchronous mode */
|
||||
M_HDLC, /* HDLC mode */
|
||||
M_BISYNC, /* BISYNC mode */
|
||||
M_X21, /* X.21 mode */
|
||||
} cx_chan_mode_t;
|
||||
|
||||
typedef struct { /* channel option register 4 */
|
||||
unsigned thr : 4; /* FIFO threshold */
|
||||
unsigned zero : 1;
|
||||
unsigned cts_zd : 1; /* detect 1 to 0 transition on the CTS */
|
||||
unsigned cd_zd : 1; /* detect 1 to 0 transition on the CD */
|
||||
unsigned dsr_zd : 1; /* detect 1 to 0 transition on the DSR */
|
||||
} cx_cor4_t;
|
||||
|
||||
typedef struct { /* channel option register 5 */
|
||||
unsigned rx_thr : 4; /* receive flow control FIFO threshold */
|
||||
unsigned zero : 1;
|
||||
unsigned cts_od : 1; /* detect 0 to 1 transition on the CTS */
|
||||
unsigned cd_od : 1; /* detect 0 to 1 transition on the CD */
|
||||
unsigned dsr_od : 1; /* detect 0 to 1 transition on the DSR */
|
||||
} cx_cor5_t;
|
||||
|
||||
typedef struct { /* receive clock option register */
|
||||
unsigned clk : 3; /* receive clock source */
|
||||
unsigned encod : 2; /* signal encoding NRZ/NRZI/Manchester */
|
||||
unsigned dpll : 1; /* DPLL enable */
|
||||
unsigned zero : 1;
|
||||
unsigned tlval : 1; /* transmit line value */
|
||||
} cx_rcor_t;
|
||||
|
||||
typedef struct { /* transmit clock option register */
|
||||
unsigned zero1 : 1;
|
||||
unsigned llm : 1; /* local loopback mode */
|
||||
unsigned zero2 : 1;
|
||||
unsigned ext1x : 1; /* external 1x clock mode */
|
||||
unsigned zero3 : 1;
|
||||
unsigned clk : 3; /* transmit clock source */
|
||||
} cx_tcor_t;
|
||||
|
||||
typedef struct {
|
||||
cx_cor4_t cor4; /* channel option register 4 */
|
||||
cx_cor5_t cor5; /* channel option register 5 */
|
||||
cx_rcor_t rcor; /* receive clock option register */
|
||||
cx_tcor_t tcor; /* transmit clock option register */
|
||||
} cx_chan_opt_t;
|
||||
|
||||
typedef enum { /* line break mode */
|
||||
BRK_IDLE, /* normal line mode */
|
||||
BRK_SEND, /* start sending break */
|
||||
BRK_STOP, /* stop sending break */
|
||||
} cx_break_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned cisco : 1; /* cisco mode */
|
||||
unsigned keepalive : 1; /* keepalive enable */
|
||||
unsigned ext : 1; /* use external ppp implementation */
|
||||
unsigned lock : 1; /* channel locked for use by driver */
|
||||
unsigned norts : 1; /* disable automatic RTS control */
|
||||
} cx_soft_opt_t;
|
||||
|
||||
#define NCHIP 4 /* the number of controllers per board */
|
||||
#define NCHAN 16 /* the number of channels on the board */
|
||||
|
||||
typedef struct {
|
||||
unsigned char board; /* adapter number, 0..2 */
|
||||
unsigned char channel; /* channel number, 0..15 */
|
||||
unsigned char type; /* channel type (read only) */
|
||||
unsigned char iftype; /* chan0 interface RS-232/RS-449/V.35 */
|
||||
unsigned long rxbaud; /* receiver speed */
|
||||
unsigned long txbaud; /* transmitter speed */
|
||||
cx_chan_mode_t mode; /* channel mode */
|
||||
cx_chan_opt_t opt; /* common channel options */
|
||||
cx_opt_async_t aopt; /* async mode options */
|
||||
cx_opt_hdlc_t hopt; /* hdlc mode options */
|
||||
cx_opt_bisync_t bopt; /* bisync mode options */
|
||||
cx_opt_x21_t xopt; /* x.21 mode options */
|
||||
cx_soft_opt_t sopt; /* software options and state flags */
|
||||
} cx_options_t; /* user settable options */
|
||||
|
||||
typedef struct _chan_t {
|
||||
unsigned char type; /* channel type */
|
||||
unsigned char num; /* channel number, 0..15 */
|
||||
struct _board_t *board; /* board pointer */
|
||||
struct _chip_t *chip; /* controller pointer */
|
||||
unsigned long rxbaud; /* receiver speed */
|
||||
unsigned long txbaud; /* transmitter speed */
|
||||
cx_chan_mode_t mode; /* channel mode */
|
||||
cx_chan_opt_t opt; /* common channel options */
|
||||
cx_opt_async_t aopt; /* async mode options */
|
||||
cx_opt_hdlc_t hopt; /* hdlc mode options */
|
||||
cx_opt_bisync_t bopt; /* bisync mode options */
|
||||
cx_opt_x21_t xopt; /* x.21 mode options */
|
||||
unsigned char *arbuf; /* receiver A dma buffer */
|
||||
unsigned char *brbuf; /* receiver B dma buffer */
|
||||
unsigned char *atbuf; /* transmitter A dma buffer */
|
||||
unsigned char *btbuf; /* transmitter B dma buffer */
|
||||
unsigned long arphys; /* receiver A phys address */
|
||||
unsigned long brphys; /* receiver B phys address */
|
||||
unsigned long atphys; /* transmitter A phys address */
|
||||
unsigned long btphys; /* transmitter B phys address */
|
||||
unsigned char dtr; /* DTR signal value */
|
||||
unsigned char rts; /* RTS signal value */
|
||||
#ifdef KERNEL
|
||||
struct tty *ttyp; /* tty structure pointer */
|
||||
struct ifnet *ifp; /* network interface data */
|
||||
caddr_t bpf; /* packet filter data */
|
||||
cx_soft_opt_t sopt; /* software options and state flags */
|
||||
cx_break_t brk; /* line break mode */
|
||||
#ifdef __bsdi__
|
||||
struct ttydevice_tmp *ttydev; /* tty statistics structure */
|
||||
#endif
|
||||
#endif
|
||||
} cx_chan_t;
|
||||
|
||||
typedef struct _chip_t {
|
||||
unsigned short port; /* base port address, or 0 if no chip */
|
||||
unsigned char num; /* controller number, 0..3 */
|
||||
struct _board_t *board; /* board pointer */
|
||||
unsigned long oscfreq; /* oscillator frequency in Hz */
|
||||
} cx_chip_t;
|
||||
|
||||
typedef struct _board_t {
|
||||
unsigned short port; /* base board port, 0..3f0 */
|
||||
unsigned short num; /* board number, 0..2 */
|
||||
unsigned char irq; /* intterupt request {3 5 7 10 11 12 15} */
|
||||
unsigned char dma; /* DMA request {5 6 7} */
|
||||
unsigned char if0type; /* chan0 interface RS-232/RS-449/V.35 */
|
||||
unsigned char if8type; /* chan8 interface RS-232/RS-449/V.35 */
|
||||
unsigned short bcr0; /* BCR0 image */
|
||||
unsigned short bcr0b; /* BCR0b image */
|
||||
unsigned short bcr1; /* BCR1 image */
|
||||
unsigned short bcr1b; /* BCR1b image */
|
||||
cx_chip_t chip[NCHIP]; /* controller structures */
|
||||
cx_chan_t chan[NCHAN]; /* channel structures */
|
||||
char name[16]; /* board version name */
|
||||
unsigned char nuniv; /* number of universal channels */
|
||||
unsigned char nsync; /* number of sync. channels */
|
||||
unsigned char nasync; /* number of async. channels */
|
||||
} cx_board_t;
|
||||
|
||||
#define CX_SPEED_DFLT 9600
|
||||
|
||||
extern long cx_rxbaud, cx_txbaud;
|
||||
extern int cx_univ_mode, cx_sync_mode, cx_iftype;
|
||||
|
||||
extern cx_chan_opt_t chan_opt_dflt; /* default mode-independent options */
|
||||
extern cx_opt_async_t opt_async_dflt; /* default async options */
|
||||
extern cx_opt_hdlc_t opt_hdlc_dflt; /* default hdlc options */
|
||||
extern cx_opt_bisync_t opt_bisync_dflt; /* default bisync options */
|
||||
extern cx_opt_x21_t opt_x21_dflt; /* default x21 options */
|
||||
|
||||
int cx_probe_board (int port);
|
||||
void cx_init (cx_board_t *b, int num, int port, int irq, int dma);
|
||||
void cx_init_board (cx_board_t *b, int num, int port, int irq, int dma,
|
||||
int chain, int rev, int osc, int rev2, int osc2);
|
||||
void cx_setup_board (cx_board_t *b);
|
||||
void cx_setup_chan (cx_chan_t *c);
|
||||
void cx_chan_dtr (cx_chan_t *c, int on);
|
||||
void cx_chan_rts (cx_chan_t *c, int on);
|
||||
void cx_cmd (int base, int cmd);
|
||||
void cx_disable_dma (cx_board_t *b);
|
||||
void cx_reinit_board (cx_board_t *b);
|
||||
int cx_chan_dsr (cx_chan_t *c);
|
||||
int cx_chan_cd (cx_chan_t *c);
|
||||
void cx_clock (long hz, long ba, int *clk, int *div);
|
||||
|
||||
#define CXIOCGETMODE _IOWR('x', 1, cx_options_t) /* get channel options */
|
||||
#define CXIOCSETMODE _IOW('x', 2, cx_options_t) /* set channel options */
|
1041
sys/i386/isa/cronyx.c
Normal file
1041
sys/i386/isa/cronyx.c
Normal file
File diff suppressed because it is too large
Load Diff
898
sys/i386/isa/cx.c
Normal file
898
sys/i386/isa/cx.c
Normal file
@ -0,0 +1,898 @@
|
||||
/*
|
||||
* Cronyx-Sigma adapter driver for FreeBSD.
|
||||
* Supports PPP/HDLC protocol in synchronous mode,
|
||||
* and asyncronous channels with full modem control.
|
||||
*
|
||||
* Copyright (C) 1994 Cronyx Ltd.
|
||||
* Author: Serge Vakulenko, <vak@zebub.msk.su>
|
||||
*
|
||||
* This software is distributed with NO WARRANTIES, not even the implied
|
||||
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Authors grant any other persons or organisations permission to use
|
||||
* or modify this software as long as this message is kept with the software,
|
||||
* all derivative works or modified versions.
|
||||
*
|
||||
* Version 1.2, Tue Nov 22 18:57:27 MSK 1994
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include "cx.h"
|
||||
#if NCX > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <systm.h>
|
||||
#include <kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# if __FreeBSD__ < 2
|
||||
# include <i386/include/pio.h>
|
||||
# define RB_GETC(q) getc(q)
|
||||
# else /* BSD 4.4 Lite */
|
||||
# include <i386/include/cpufunc.h>
|
||||
# include <sys/devconf.h>
|
||||
# endif
|
||||
# define oproc_func_t void(*)(struct tty*)
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
# include <sys/ttystats.h>
|
||||
# include <i386/include/inline.h>
|
||||
# define tsleep(tp,pri,msg,x) ((tp)->t_state |= TS_WOPEN,\
|
||||
ttysleep (tp, (caddr_t)&tp->t_rawq, pri, msg, x))
|
||||
# define oproc_func_t int(*)()
|
||||
# define timeout_func_t void(*)()
|
||||
#endif
|
||||
#if !defined (__FreeBSD__) || __FreeBSD__ >= 2
|
||||
# define t_out t_outq
|
||||
# define RB_LEN(q) ((q).c_cc)
|
||||
# define RB_GETC(q) getc(&q)
|
||||
# define TSA_CARR_ON(tp) tp
|
||||
# define TSA_OLOWAT(q) ((caddr_t)&(q)->t_out)
|
||||
#endif
|
||||
|
||||
#include <sys/cronyx.h>
|
||||
#include <i386/isa/cxreg.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
# define print(s) printf s
|
||||
#else
|
||||
# define print(s) /*void*/
|
||||
#endif
|
||||
|
||||
#define DMABUFSZ (6*256) /* buffer size */
|
||||
#define BYTE *(unsigned char*)&
|
||||
#define UNIT(u) ((u) & 077)
|
||||
#define UNIT_CTL 077
|
||||
|
||||
extern cx_board_t cxboard [NCX]; /* adapter state structures */
|
||||
extern cx_chan_t *cxchan [NCX*NCHAN]; /* unit to channel struct pointer */
|
||||
#if __FreeBSD__ >= 2
|
||||
extern struct kern_devconf kdc_cx [NCX];
|
||||
struct tty cx_tty [NCX*NCHAN]; /* tty data */
|
||||
#else
|
||||
struct tty *cx_tty [NCX*NCHAN]; /* tty data */
|
||||
#endif
|
||||
|
||||
void cxoproc (struct tty *tp);
|
||||
int cxparam (struct tty *tp, struct termios *t);
|
||||
void cxswitch (cx_chan_t *c, cx_soft_opt_t new);
|
||||
|
||||
int cxopen (dev_t dev, int flag, int mode, struct proc *p)
|
||||
{
|
||||
int unit = UNIT (dev);
|
||||
cx_chan_t *c = cxchan[unit];
|
||||
unsigned short port;
|
||||
struct tty *tp;
|
||||
int error = 0;
|
||||
|
||||
if (unit == UNIT_CTL) {
|
||||
print (("cx: cxopen /dev/cronyx\n"));
|
||||
return (0);
|
||||
}
|
||||
if (unit >= NCX*NCHAN || !c || c->type==T_NONE)
|
||||
return (ENXIO);
|
||||
port = c->chip->port;
|
||||
print (("cx%d.%d: cxopen unit=%d\n", c->board->num, c->num, unit));
|
||||
if (c->mode != M_ASYNC)
|
||||
return (EBUSY);
|
||||
if (! c->ttyp) {
|
||||
#if __FreeBSD__ >= 2
|
||||
c->ttyp = &cx_tty[unit];
|
||||
#else
|
||||
MALLOC (cx_tty[unit], struct tty*, sizeof (struct tty), M_DEVBUF, M_WAITOK);
|
||||
bzero (cx_tty[unit], sizeof (*cx_tty[unit]));
|
||||
c->ttyp = cx_tty[unit];
|
||||
#endif
|
||||
c->ttyp->t_oproc = (oproc_func_t) cxoproc;
|
||||
c->ttyp->t_param = cxparam;
|
||||
}
|
||||
#ifdef __bsdi__
|
||||
if (! c->ttydev) {
|
||||
MALLOC (c->ttydev, struct ttydevice_tmp*,
|
||||
sizeof (struct ttydevice_tmp), M_DEVBUF, M_WAITOK);
|
||||
bzero (c->ttydev, sizeof (*c->ttydev));
|
||||
strcpy (c->ttydev->tty_name, "cx");
|
||||
c->ttydev->tty_unit = unit;
|
||||
c->ttydev->tty_base = unit;
|
||||
c->ttydev->tty_count = 1;
|
||||
c->ttydev->tty_ttys = c->ttyp;
|
||||
tty_attach (c->ttydev);
|
||||
}
|
||||
#endif
|
||||
tp = c->ttyp;
|
||||
tp->t_dev = dev;
|
||||
if ((tp->t_state & TS_ISOPEN) && (tp->t_state & TS_XCLUDE) &&
|
||||
p->p_ucred->cr_uid != 0)
|
||||
return (EBUSY);
|
||||
if (! (tp->t_state & TS_ISOPEN)) {
|
||||
ttychars (tp);
|
||||
if (tp->t_ispeed == 0) {
|
||||
#ifdef __bsdi__
|
||||
tp->t_termios = deftermios;
|
||||
#else
|
||||
tp->t_iflag = 0;
|
||||
tp->t_oflag = 0;
|
||||
tp->t_lflag = 0;
|
||||
tp->t_cflag = CREAD | CS8 | HUPCL;
|
||||
tp->t_ispeed = c->rxbaud;
|
||||
tp->t_ospeed = c->txbaud;
|
||||
#endif
|
||||
}
|
||||
cxparam (tp, &tp->t_termios);
|
||||
ttsetwater (tp);
|
||||
}
|
||||
|
||||
spltty ();
|
||||
if (! (tp->t_state & TS_ISOPEN)) {
|
||||
/*
|
||||
* Compute optimal receiver buffer length.
|
||||
* The best choice is rxbaud/400.
|
||||
* Make it even, to avoid byte-wide DMA transfers.
|
||||
* --------------------------
|
||||
* Baud rate Buffer length
|
||||
* --------------------------
|
||||
* 300 4
|
||||
* 1200 4
|
||||
* 9600 24
|
||||
* 19200 48
|
||||
* 38400 96
|
||||
* 57600 192
|
||||
* 115200 288
|
||||
* --------------------------
|
||||
*/
|
||||
int rbsz = (c->rxbaud + 800 - 1) / 800 * 2;
|
||||
if (rbsz < 4)
|
||||
rbsz = 4;
|
||||
else if (rbsz > DMABUFSZ)
|
||||
rbsz = DMABUFSZ;
|
||||
|
||||
/* Initialize channel, enable receiver. */
|
||||
cx_cmd (port, CCR_INITCH | CCR_ENRX);
|
||||
cx_cmd (port, CCR_INITCH | CCR_ENRX);
|
||||
|
||||
/* Start receiver. */
|
||||
outw (ARBCNT(port), rbsz);
|
||||
outw (BRBCNT(port), rbsz);
|
||||
outw (ARBSTS(port), BSTS_OWN24);
|
||||
outw (BRBSTS(port), BSTS_OWN24);
|
||||
|
||||
/* Enable interrupts. */
|
||||
outb (IER(port), IER_RXD | IER_RET | IER_TXD | IER_MDM);
|
||||
|
||||
cx_chan_dtr (c, 1);
|
||||
cx_chan_rts (c, 1);
|
||||
}
|
||||
if (cx_chan_cd (c))
|
||||
tp->t_state |= TS_CARR_ON;
|
||||
if (! (flag & O_NONBLOCK)) {
|
||||
/* Lock the channel against cxconfig while we are
|
||||
* waiting for carrier. */
|
||||
c->sopt.lock = 1;
|
||||
while (!(tp->t_cflag & CLOCAL) && !(tp->t_state & TS_CARR_ON))
|
||||
if ((error = tsleep (TSA_CARR_ON(tp), TTIPRI | PCATCH,
|
||||
"cxdcd", 0)))
|
||||
break;
|
||||
c->sopt.lock = 0; /* Unlock the channel. */
|
||||
}
|
||||
print (("cx%d.%d: cxopen done csr=%b\n", c->board->num, c->num,
|
||||
inb(CSR(c->chip->port)), CSRA_BITS));
|
||||
spl0 ();
|
||||
if (error)
|
||||
return (error);
|
||||
#if __FreeBSD__ >= 2
|
||||
error = (*linesw[tp->t_line].l_open) (dev, tp);
|
||||
if (tp->t_state & TS_ISOPEN)
|
||||
/* Mark the board busy on the first startup.
|
||||
* Never goes idle. */
|
||||
kdc_cx[c->board->num].kdc_state = DC_BUSY;
|
||||
#else
|
||||
error = (*linesw[tp->t_line].l_open) (dev, tp, 0);
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
int cxclose (dev_t dev, int flag, int mode, struct proc *p)
|
||||
{
|
||||
int unit = UNIT (dev);
|
||||
cx_chan_t *c = cxchan[unit];
|
||||
struct tty *tp;
|
||||
int s;
|
||||
|
||||
if (unit == UNIT_CTL)
|
||||
return (0);
|
||||
tp = c->ttyp;
|
||||
(*linesw[tp->t_line].l_close) (tp, flag);
|
||||
|
||||
/* Disable receiver.
|
||||
* Transmitter continues sending the queued data. */
|
||||
s = spltty ();
|
||||
outb (CAR(c->chip->port), c->num & 3);
|
||||
outb (IER(c->chip->port), IER_TXD | IER_MDM);
|
||||
cx_cmd (c->chip->port, CCR_DISRX);
|
||||
|
||||
/* Clear DTR and RTS. */
|
||||
if ((tp->t_cflag & HUPCL) || ! (tp->t_state & TS_ISOPEN)) {
|
||||
cx_chan_dtr (c, 0);
|
||||
cx_chan_rts (c, 0);
|
||||
}
|
||||
|
||||
/* Stop sending break. */
|
||||
if (c->brk == BRK_SEND) {
|
||||
c->brk = BRK_STOP;
|
||||
if (! (tp->t_state & TS_BUSY))
|
||||
cxoproc (tp);
|
||||
}
|
||||
splx (s);
|
||||
ttyclose (tp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int cxread (dev_t dev, struct uio *uio, int flag)
|
||||
{
|
||||
int unit = UNIT (dev);
|
||||
struct tty *tp;
|
||||
|
||||
if (unit == UNIT_CTL)
|
||||
return (EIO);
|
||||
tp = cxchan[unit]->ttyp;
|
||||
return ((*linesw[tp->t_line].l_read) (tp, uio, flag));
|
||||
}
|
||||
|
||||
int cxwrite (dev_t dev, struct uio *uio, int flag)
|
||||
{
|
||||
int unit = UNIT (dev);
|
||||
struct tty *tp;
|
||||
|
||||
if (unit == UNIT_CTL)
|
||||
return (EIO);
|
||||
tp = cxchan[unit]->ttyp;
|
||||
return ((*linesw[tp->t_line].l_write) (tp, uio, flag));
|
||||
}
|
||||
|
||||
int cxioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
{
|
||||
int unit = UNIT (dev);
|
||||
cx_chan_t *c;
|
||||
struct tty *tp;
|
||||
int error, s;
|
||||
unsigned char msv;
|
||||
|
||||
if (unit == UNIT_CTL) {
|
||||
/* Process an ioctl request on /dev/cronyx */
|
||||
cx_options_t *o = (cx_options_t*) data;
|
||||
|
||||
if (o->board >= NCX || o->channel >= NCHAN)
|
||||
return (EINVAL);
|
||||
c = &cxboard[o->board].chan[o->channel];
|
||||
if (c->type == T_NONE)
|
||||
return (ENXIO);
|
||||
switch (cmd) {
|
||||
default:
|
||||
return (EINVAL);
|
||||
|
||||
case CXIOCSETMODE:
|
||||
print (("cx%d.%d: CXIOCSETMODE\n", o->board, o->channel));
|
||||
if (c->type == T_NONE)
|
||||
return (EINVAL);
|
||||
if (c->type == T_ASYNC && o->mode != M_ASYNC)
|
||||
return (EINVAL);
|
||||
if (o->mode == M_ASYNC)
|
||||
switch (c->type) {
|
||||
case T_SYNC_RS232:
|
||||
case T_SYNC_V35:
|
||||
case T_SYNC_RS449:
|
||||
return (EINVAL);
|
||||
}
|
||||
/* Somebody is waiting for carrier? */
|
||||
if (c->sopt.lock)
|
||||
return (EBUSY);
|
||||
/* /dev/ttyXX is already opened by someone? */
|
||||
if (c->mode == M_ASYNC && c->ttyp &&
|
||||
(c->ttyp->t_state & TS_ISOPEN))
|
||||
return (EBUSY);
|
||||
/* Network interface is up? */
|
||||
if (c->mode != M_ASYNC && (c->ifp->if_flags & IFF_UP))
|
||||
return (EBUSY);
|
||||
c->mode = o->mode;
|
||||
c->rxbaud = o->rxbaud;
|
||||
c->txbaud = o->txbaud;
|
||||
c->opt = o->opt;
|
||||
c->aopt = o->aopt;
|
||||
c->hopt = o->hopt;
|
||||
c->bopt = o->bopt;
|
||||
c->xopt = o->xopt;
|
||||
switch (c->num) {
|
||||
case 0: c->board->if0type = o->iftype; break;
|
||||
case 8: c->board->if8type = o->iftype; break;
|
||||
}
|
||||
cxswitch (c, o->sopt);
|
||||
s = spltty ();
|
||||
cx_setup_chan (c);
|
||||
outb (IER(c->chip->port), 0);
|
||||
splx (s);
|
||||
break;
|
||||
|
||||
case CXIOCGETMODE:
|
||||
print (("cx%d.%d: CXIOCGETMODE\n", o->board, o->channel));
|
||||
o->type = c->type;
|
||||
o->mode = c->mode;
|
||||
o->rxbaud = c->rxbaud;
|
||||
o->txbaud = c->txbaud;
|
||||
o->opt = c->opt;
|
||||
o->aopt = c->aopt;
|
||||
o->hopt = c->hopt;
|
||||
o->bopt = c->bopt;
|
||||
o->xopt = c->xopt;
|
||||
o->sopt = c->sopt;
|
||||
switch (c->num) {
|
||||
case 0: o->iftype = c->board->if0type; break;
|
||||
case 8: o->iftype = c->board->if8type; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
c = cxchan[unit];
|
||||
tp = c->ttyp;
|
||||
if (! tp)
|
||||
return (EINVAL);
|
||||
#if __FreeBSD__ >= 2
|
||||
error = (*linesw[tp->t_line].l_ioctl) (tp, cmd, data, flag, p);
|
||||
#else
|
||||
error = (*linesw[tp->t_line].l_ioctl) (tp, cmd, data, flag);
|
||||
#endif
|
||||
if (error >= 0)
|
||||
return (error);
|
||||
error = ttioctl (tp, cmd, data, flag);
|
||||
if (error >= 0)
|
||||
return (error);
|
||||
|
||||
s = spltty ();
|
||||
switch (cmd) {
|
||||
default:
|
||||
splx (s);
|
||||
return (ENOTTY);
|
||||
case TIOCSBRK: /* Start sending line break */
|
||||
c->brk = BRK_SEND;
|
||||
if (! (tp->t_state & TS_BUSY))
|
||||
cxoproc (tp);
|
||||
break;
|
||||
case TIOCCBRK: /* Stop sending line break */
|
||||
c->brk = BRK_STOP;
|
||||
if (! (tp->t_state & TS_BUSY))
|
||||
cxoproc (tp);
|
||||
break;
|
||||
case TIOCSDTR: /* Set DTR */
|
||||
cx_chan_dtr (c, 1);
|
||||
break;
|
||||
case TIOCCDTR: /* Clear DTR */
|
||||
cx_chan_dtr (c, 0);
|
||||
break;
|
||||
case TIOCMSET: /* Set DTR/RTS */
|
||||
cx_chan_dtr (c, (*(int*)data & TIOCM_DTR) ? 1 : 0);
|
||||
cx_chan_rts (c, (*(int*)data & TIOCM_RTS) ? 1 : 0);
|
||||
break;
|
||||
case TIOCMBIS: /* Add DTR/RTS */
|
||||
if (*(int*)data & TIOCM_DTR) cx_chan_dtr (c, 1);
|
||||
if (*(int*)data & TIOCM_RTS) cx_chan_rts (c, 1);
|
||||
break;
|
||||
case TIOCMBIC: /* Clear DTR/RTS */
|
||||
if (*(int*)data & TIOCM_DTR) cx_chan_dtr (c, 0);
|
||||
if (*(int*)data & TIOCM_RTS) cx_chan_rts (c, 0);
|
||||
break;
|
||||
case TIOCMGET: /* Get modem status */
|
||||
msv = inb (MSVR(c->chip->port));
|
||||
*(int*)data = TIOCM_LE; /* always enabled while open */
|
||||
if (msv & MSV_DSR) *(int*)data |= TIOCM_DSR;
|
||||
if (msv & MSV_CTS) *(int*)data |= TIOCM_CTS;
|
||||
if (msv & MSV_CD) *(int*)data |= TIOCM_CD;
|
||||
if (c->dtr) *(int*)data |= TIOCM_DTR;
|
||||
if (c->rts) *(int*)data |= TIOCM_RTS;
|
||||
break;
|
||||
}
|
||||
splx (s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill transmitter buffer with data.
|
||||
*/
|
||||
void cxout (cx_chan_t *c, char b)
|
||||
{
|
||||
unsigned char *buf, *p, sym;
|
||||
unsigned short port = c->chip->port, len = 0, cnt_port, sts_port;
|
||||
struct tty *tp = c->ttyp;
|
||||
int i;
|
||||
|
||||
if (! tp)
|
||||
return;
|
||||
|
||||
/* Choose the buffer. */
|
||||
if (b == 'A') {
|
||||
buf = c->atbuf;
|
||||
cnt_port = ATBCNT(port);
|
||||
sts_port = ATBSTS(port);
|
||||
} else {
|
||||
buf = c->btbuf;
|
||||
cnt_port = BTBCNT(port);
|
||||
sts_port = BTBSTS(port);
|
||||
}
|
||||
|
||||
/* Is it busy? */
|
||||
if (inb (sts_port) & BSTS_OWN24) {
|
||||
tp->t_state |= TS_BUSY;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (c->brk) {
|
||||
case BRK_SEND:
|
||||
*buf++ = 0; /* extended transmit command */
|
||||
*buf++ = 0x81; /* send break */
|
||||
*buf++ = 0; /* extended transmit command */
|
||||
*buf++ = 0x82; /* insert delay */
|
||||
*buf++ = 250; /* 1/4 of second */
|
||||
*buf++ = 0; /* extended transmit command */
|
||||
*buf++ = 0x82; /* insert delay */
|
||||
*buf++ = 250; /* + 1/4 of second */
|
||||
len = 8;
|
||||
c->brk = BRK_IDLE;
|
||||
break;
|
||||
case BRK_STOP:
|
||||
*buf++ = 0; /* extended transmit command */
|
||||
*buf++ = 0x83; /* stop break */
|
||||
len = 2;
|
||||
c->brk = BRK_IDLE;
|
||||
break;
|
||||
case BRK_IDLE:
|
||||
len = RB_LEN (tp->t_out);
|
||||
if (tp->t_iflag & IXOFF)
|
||||
for (i=0, p=buf; i<len && p<buf+DMABUFSZ-1; ++i) {
|
||||
sym = RB_GETC (tp->t_out);
|
||||
/* Send XON/XOFF out of band. */
|
||||
if (sym == tp->t_cc[VSTOP]) {
|
||||
outb (STCR(port), STC_SNDSPC|STC_SSPC_2);
|
||||
continue;
|
||||
}
|
||||
if (sym == tp->t_cc[VSTART]) {
|
||||
outb (STCR(port), STC_SNDSPC|STC_SSPC_1);
|
||||
continue;
|
||||
}
|
||||
/* Duplicate NULLs in ETC mode. */
|
||||
if (! sym)
|
||||
*p++ = 0;
|
||||
*p++ = sym;
|
||||
}
|
||||
else
|
||||
for (i=0, p=buf; i<len && p<buf+DMABUFSZ-1; ++i) {
|
||||
sym = RB_GETC (tp->t_out);
|
||||
/* Duplicate NULLs in ETC mode. */
|
||||
if (! sym)
|
||||
*p++ = 0;
|
||||
*p++ = sym;
|
||||
}
|
||||
len = p - buf;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Start transmitter. */
|
||||
if (len) {
|
||||
outw (cnt_port, len);
|
||||
outb (sts_port, BSTS_INTR | BSTS_OWN24);
|
||||
tp->t_state |= TS_BUSY;
|
||||
print (("cx%d.%d: out %d bytes to %c\n",
|
||||
c->board->num, c->num, len, b));
|
||||
}
|
||||
}
|
||||
|
||||
void cxoproc (struct tty *tp)
|
||||
{
|
||||
int unit = UNIT (tp->t_dev);
|
||||
cx_chan_t *c = cxchan[unit];
|
||||
unsigned short port = c->chip->port;
|
||||
int s = spltty ();
|
||||
|
||||
/* Set current channel number */
|
||||
outb (CAR(port), c->num & 3);
|
||||
|
||||
if (! (tp->t_state & (TS_TIMEOUT | TS_TTSTOP))) {
|
||||
/* Start transmitter. */
|
||||
if (! (inb (CSR(port)) & CSRA_TXEN))
|
||||
cx_cmd (port, CCR_ENTX);
|
||||
|
||||
/* Determine the buffer order. */
|
||||
if (inb (DMABSTS(port)) & DMABSTS_NTBUF) {
|
||||
cxout (c, 'B');
|
||||
cxout (c, 'A');
|
||||
} else {
|
||||
cxout (c, 'A');
|
||||
cxout (c, 'B');
|
||||
}
|
||||
}
|
||||
#if defined (__FreeBSD__) && __FreeBSD__ < 2
|
||||
if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel)
|
||||
ttwwakeup (tp);
|
||||
#else /* FreeBSD 2.x and BSDI */
|
||||
if (RB_LEN (tp->t_out) <= tp->t_lowat) {
|
||||
if (tp->t_state & TS_ASLEEP) {
|
||||
tp->t_state &= ~TS_ASLEEP;
|
||||
wakeup(TSA_OLOWAT(tp));
|
||||
}
|
||||
selwakeup(&tp->t_wsel);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Enable TXMPTY interrupt,
|
||||
* to catch the case when the second buffer is empty.
|
||||
*/
|
||||
if ((inb (ATBSTS(port)) & BSTS_OWN24) &&
|
||||
(inb (BTBSTS(port)) & BSTS_OWN24)) {
|
||||
outb (IER(port), IER_RXD|IER_RET|IER_TXD|IER_TXMPTY|IER_MDM);
|
||||
} else
|
||||
outb (IER(port), IER_RXD|IER_RET|IER_TXD|IER_MDM);
|
||||
splx (s);
|
||||
}
|
||||
|
||||
int cxparam (struct tty *tp, struct termios *t)
|
||||
{
|
||||
int unit = UNIT (tp->t_dev);
|
||||
cx_chan_t *c = cxchan[unit];
|
||||
unsigned short port = c->chip->port;
|
||||
int clock, period, s;
|
||||
cx_cor1_async_t cor1;
|
||||
|
||||
if (t->c_ospeed == 0) {
|
||||
/* Clear DTR and RTS. */
|
||||
s = spltty ();
|
||||
cx_chan_dtr (c, 0);
|
||||
cx_chan_rts (c, 0);
|
||||
splx (s);
|
||||
print (("cx%d.%d: cxparam (hangup)\n", c->board->num, c->num));
|
||||
return (0);
|
||||
}
|
||||
print (("cx%d.%d: cxparam\n", c->board->num, c->num));
|
||||
|
||||
/* Check requested parameters. */
|
||||
if (t->c_ospeed < 300 || t->c_ospeed > 256*1024)
|
||||
return(EINVAL);
|
||||
if (t->c_ispeed && (t->c_ispeed < 300 || t->c_ispeed > 256*1024))
|
||||
return(EINVAL);
|
||||
|
||||
#ifdef __bsdi__
|
||||
/* CLOCAL flag set -- wakeup everybody who waits for CD. */
|
||||
/* FreeBSD does this themselves. */
|
||||
if (! (tp->t_cflag & CLOCAL) && (t->c_cflag & CLOCAL))
|
||||
wakeup ((caddr_t) &tp->t_rawq);
|
||||
#endif
|
||||
/* And copy them to tty and channel structures. */
|
||||
c->rxbaud = tp->t_ispeed = t->c_ispeed;
|
||||
c->txbaud = tp->t_ospeed = t->c_ospeed;
|
||||
tp->t_cflag = t->c_cflag;
|
||||
|
||||
/* Set character length and parity mode. */
|
||||
BYTE cor1 = 0;
|
||||
switch (t->c_cflag & CSIZE) {
|
||||
default:
|
||||
case CS8: cor1.charlen = 7; break;
|
||||
case CS7: cor1.charlen = 6; break;
|
||||
case CS6: cor1.charlen = 5; break;
|
||||
case CS5: cor1.charlen = 4; break;
|
||||
}
|
||||
if (t->c_cflag & PARENB) {
|
||||
cor1.parmode = PARM_NORMAL;
|
||||
cor1.ignpar = 0;
|
||||
cor1.parity = (t->c_cflag & PARODD) ? PAR_ODD : PAR_EVEN;
|
||||
} else {
|
||||
cor1.parmode = PARM_NOPAR;
|
||||
cor1.ignpar = 1;
|
||||
}
|
||||
|
||||
/* Enable/disable hardware CTS. */
|
||||
c->aopt.cor2.ctsae = (t->c_cflag & CRTSCTS) ? 1 : 0;
|
||||
/* Handle DSR as CTS. */
|
||||
c->aopt.cor2.dsrae = (t->c_cflag & CRTSCTS) ? 1 : 0;
|
||||
/* Enable extended transmit command mode.
|
||||
* Unfortunately, there is no other method for sending break. */
|
||||
c->aopt.cor2.etc = 1;
|
||||
/* Enable/disable hardware XON/XOFF. */
|
||||
c->aopt.cor2.ixon = (t->c_iflag & IXON) ? 1 : 0;
|
||||
c->aopt.cor2.ixany = (t->c_iflag & IXANY) ? 1 : 0;
|
||||
|
||||
/* Set the number of stop bits. */
|
||||
if (t->c_cflag & CSTOPB)
|
||||
c->aopt.cor3.stopb = STOPB_2;
|
||||
else
|
||||
c->aopt.cor3.stopb = STOPB_1;
|
||||
/* Disable/enable passing XON/XOFF chars to the host. */
|
||||
c->aopt.cor3.scde = (t->c_iflag & IXON) ? 1 : 0;
|
||||
c->aopt.cor3.flowct = (t->c_iflag & IXON) ? FLOWCC_NOTPASS : FLOWCC_PASS;
|
||||
|
||||
c->aopt.schr1 = t->c_cc[VSTART]; /* XON */
|
||||
c->aopt.schr2 = t->c_cc[VSTOP]; /* XOFF */
|
||||
|
||||
/* Set current channel number. */
|
||||
s = spltty ();
|
||||
outb (CAR(port), c->num & 3);
|
||||
|
||||
/* Set up receiver clock values. */
|
||||
cx_clock (c->chip->oscfreq, c->rxbaud, &clock, &period);
|
||||
c->opt.rcor.clk = clock;
|
||||
outb (RCOR(port), BYTE c->opt.rcor);
|
||||
outb (RBPR(port), period);
|
||||
|
||||
/* Set up transmitter clock values. */
|
||||
cx_clock (c->chip->oscfreq, c->txbaud, &clock, &period);
|
||||
c->opt.tcor.clk = clock;
|
||||
c->opt.tcor.ext1x = 0;
|
||||
outb (TCOR(port), BYTE c->opt.tcor);
|
||||
outb (TBPR(port), period);
|
||||
|
||||
outb (COR2(port), BYTE c->aopt.cor2);
|
||||
outb (COR3(port), BYTE c->aopt.cor3);
|
||||
outb (SCHR1(port), c->aopt.schr1);
|
||||
outb (SCHR2(port), c->aopt.schr2);
|
||||
|
||||
if (BYTE c->aopt.cor1 != BYTE cor1) {
|
||||
BYTE c->aopt.cor1 = BYTE cor1;
|
||||
outb (COR1(port), BYTE c->aopt.cor1);
|
||||
/* Any change to COR1 require reinitialization. */
|
||||
/* Unfortunately, it may cause transmitter glitches... */
|
||||
cx_cmd (port, CCR_INITCH);
|
||||
}
|
||||
splx (s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int cxselect (dev_t dev, int flag, struct proc *p)
|
||||
{
|
||||
int unit = UNIT (dev);
|
||||
|
||||
if (unit == UNIT_CTL)
|
||||
return (0);
|
||||
#ifdef __FreeBSD__
|
||||
return (ttselect (dev, flag, p));
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
return (ttyselect (cxchan[unit]->ttyp, flag, p));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop output on a line
|
||||
*/
|
||||
void cxstop (struct tty *tp, int flag)
|
||||
{
|
||||
cx_chan_t *c = cxchan[UNIT(tp->t_dev)];
|
||||
unsigned short port = c->chip->port;
|
||||
int s = spltty ();
|
||||
|
||||
if (tp->t_state & TS_BUSY) {
|
||||
print (("cx%d.%d: cxstop\n", c->board->num, c->num));
|
||||
|
||||
/* Set current channel number */
|
||||
outb (CAR(port), c->num & 3);
|
||||
|
||||
/* Stop transmitter */
|
||||
cx_cmd (port, CCR_DISTX);
|
||||
}
|
||||
splx (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle receive interrupts, including receive errors and
|
||||
* receive timeout interrupt.
|
||||
*/
|
||||
int cxrinta (cx_chan_t *c)
|
||||
{
|
||||
unsigned short port = c->chip->port;
|
||||
unsigned short len = 0, risr = inw (RISR(port)), reoir = 0;
|
||||
struct tty *tp = c->ttyp;
|
||||
|
||||
/* Compute optimal receiver buffer length. */
|
||||
int rbsz = (c->rxbaud + 800 - 1) / 800 * 2;
|
||||
if (rbsz < 4)
|
||||
rbsz = 4;
|
||||
else if (rbsz > DMABUFSZ)
|
||||
rbsz = DMABUFSZ;
|
||||
|
||||
if (risr & RISA_TIMEOUT) {
|
||||
unsigned long rcbadr = (unsigned short) inw (RCBADRL(port)) |
|
||||
(long) inw (RCBADRU(port)) << 16;
|
||||
unsigned char *buf = 0;
|
||||
unsigned short cnt_port = 0, sts_port = 0;
|
||||
if (rcbadr >= c->brphys && rcbadr < c->brphys+DMABUFSZ) {
|
||||
buf = c->brbuf;
|
||||
len = rcbadr - c->brphys;
|
||||
cnt_port = BRBCNT(port);
|
||||
sts_port = BRBSTS(port);
|
||||
} else if (rcbadr >= c->arphys && rcbadr < c->arphys+DMABUFSZ) {
|
||||
buf = c->arbuf;
|
||||
len = rcbadr - c->arphys;
|
||||
cnt_port = ARBCNT(port);
|
||||
sts_port = ARBSTS(port);
|
||||
} else
|
||||
printf ("cx%d.%d: timeout: invalid buffer address\n",
|
||||
c->board->num, c->num);
|
||||
|
||||
if (len) {
|
||||
print (("cx%d.%d: async receive timeout (%d bytes), risr=%b, arbsts=%b, brbsts=%b\n",
|
||||
c->board->num, c->num, len, risr, RISA_BITS,
|
||||
inb (ARBSTS(port)), BSTS_BITS, inb (BRBSTS(port)), BSTS_BITS));
|
||||
if (tp && (tp->t_state & TS_ISOPEN)) {
|
||||
int i;
|
||||
void (*rint)() = (void(*)())
|
||||
linesw[tp->t_line].l_rint;
|
||||
|
||||
for (i=0; i<len; ++i)
|
||||
(*rint) (buf[i], tp);
|
||||
}
|
||||
|
||||
/* Restart receiver. */
|
||||
outw (cnt_port, rbsz);
|
||||
outb (sts_port, BSTS_OWN24);
|
||||
}
|
||||
return (REOI_TERMBUFF);
|
||||
}
|
||||
|
||||
print (("cx%d.%d: async receive interrupt, risr=%b, arbsts=%b, brbsts=%b\n",
|
||||
c->board->num, c->num, risr, RISA_BITS,
|
||||
inb (ARBSTS(port)), BSTS_BITS, inb (BRBSTS(port)), BSTS_BITS));
|
||||
|
||||
if (risr & RIS_BUSERR)
|
||||
printf ("cx%d.%d: receive bus error\n", c->board->num, c->num);
|
||||
|
||||
if (risr & (RIS_OVERRUN | RISA_PARERR | RISA_FRERR)) {
|
||||
print (("cx%d.%d: receive error\n", c->board->num, c->num));
|
||||
if (tp && (tp->t_state & TS_ISOPEN))
|
||||
(*linesw[tp->t_line].l_rint) (' ' |
|
||||
(risr & RISA_FRERR) ? TTY_FE : TTY_PE, tp);
|
||||
}
|
||||
|
||||
/* Handle line break condition. */
|
||||
if ((risr & RISA_BREAK) && tp && (tp->t_state & TS_ISOPEN))
|
||||
(*linesw[tp->t_line].l_rint) (TTY_FE, tp);
|
||||
|
||||
/* Discard exception characters. */
|
||||
if ((risr & RISA_SCMASK) && (tp->t_iflag & IXON))
|
||||
reoir |= REOI_DISCEXC;
|
||||
|
||||
/* Handle received data. */
|
||||
if ((risr & RIS_EOBUF) && tp && (tp->t_state & TS_ISOPEN)) {
|
||||
void (*rint)() = (void(*)()) linesw[tp->t_line].l_rint;
|
||||
unsigned char *buf;
|
||||
int i;
|
||||
|
||||
len = (risr & RIS_BB) ? inw(BRBCNT(port)) : inw(ARBCNT(port));
|
||||
|
||||
print (("cx%d.%d: async: %d bytes received\n",
|
||||
c->board->num, c->num, len));
|
||||
|
||||
buf = (risr & RIS_BB) ? c->brbuf : c->arbuf;
|
||||
for (i=0; i<len; ++i)
|
||||
(*rint) (buf[i], tp);
|
||||
}
|
||||
|
||||
/* Restart receiver. */
|
||||
if (! (inb (ARBSTS(port)) & BSTS_OWN24)) {
|
||||
outw (ARBCNT(port), rbsz);
|
||||
outb (ARBSTS(port), BSTS_OWN24);
|
||||
}
|
||||
if (! (inb (BRBSTS(port)) & BSTS_OWN24)) {
|
||||
outw (BRBCNT(port), rbsz);
|
||||
outb (BRBSTS(port), BSTS_OWN24);
|
||||
}
|
||||
return (reoir);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle transmit interrupt.
|
||||
*/
|
||||
void cxtinta (cx_chan_t *c)
|
||||
{
|
||||
struct tty *tp = c->ttyp;
|
||||
unsigned short port = c->chip->port;
|
||||
unsigned char tisr = inb (TISR(port));
|
||||
|
||||
print (("cx%d.%d: async transmit interrupt, tisr=%b, atbsts=%b, btbsts=%b\n",
|
||||
c->board->num, c->num, tisr, TIS_BITS,
|
||||
inb (ATBSTS(port)), BSTS_BITS, inb (BTBSTS(port)), BSTS_BITS));
|
||||
|
||||
if (tisr & TIS_BUSERR)
|
||||
printf ("cx%d.%d: transmit bus error\n",
|
||||
c->board->num, c->num);
|
||||
else if (tisr & TIS_UNDERRUN)
|
||||
printf ("cx%d.%d: transmit underrun error\n",
|
||||
c->board->num, c->num);
|
||||
|
||||
if (tp) {
|
||||
tp->t_state &= ~(TS_BUSY | TS_FLUSH);
|
||||
if (tp->t_line)
|
||||
(*linesw[tp->t_line].l_start) (tp);
|
||||
else
|
||||
cxoproc (tp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle modem interrupt.
|
||||
*/
|
||||
void cxmint (cx_chan_t *c)
|
||||
{
|
||||
unsigned short port = c->chip->port;
|
||||
unsigned char misr = inb (MISR(port));
|
||||
unsigned char msvr = inb (MSVR(port));
|
||||
struct tty *tp = c->ttyp;
|
||||
|
||||
if (c->mode != M_ASYNC) {
|
||||
printf ("cx%d.%d: unexpected modem interrupt, misr=%b, msvr=%b\n",
|
||||
c->board->num, c->num, misr, MIS_BITS, msvr, MSV_BITS);
|
||||
return;
|
||||
}
|
||||
print (("cx%d.%d: modem interrupt, misr=%b, msvr=%b\n",
|
||||
c->board->num, c->num, misr, MIS_BITS, msvr, MSV_BITS));
|
||||
|
||||
/* Ignore DSR events. */
|
||||
/* Ignore RTC/CTS events, handled by hardware. */
|
||||
/* Handle carrier detect/loss. */
|
||||
if (tp && (misr & MIS_CCD))
|
||||
(*linesw[tp->t_line].l_modem) (tp, (msvr & MSV_CD) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Recover after lost transmit interrupts.
|
||||
*/
|
||||
void cxtimeout (caddr_t a)
|
||||
{
|
||||
cx_board_t *b;
|
||||
cx_chan_t *c;
|
||||
struct tty *tp;
|
||||
int s;
|
||||
|
||||
for (b=cxboard; b<cxboard+NCX; ++b)
|
||||
for (c=b->chan; c<b->chan+NCHAN; ++c) {
|
||||
tp = c->ttyp;
|
||||
if (c->type==T_NONE || c->mode!=M_ASYNC || !tp)
|
||||
continue;
|
||||
s = spltty ();
|
||||
if (tp->t_state & TS_BUSY) {
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
if (tp->t_line)
|
||||
(*linesw[tp->t_line].l_start) (tp);
|
||||
else
|
||||
cxoproc (tp);
|
||||
}
|
||||
splx (s);
|
||||
}
|
||||
timeout ((timeout_func_t) cxtimeout, 0, hz*5);
|
||||
}
|
||||
#endif /* NCX */
|
429
sys/i386/isa/cxreg.h
Normal file
429
sys/i386/isa/cxreg.h
Normal file
@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Defines for Cronyx-Sigma adapter, based on Cirrus Logic multiprotocol
|
||||
* controller RISC processor CL-CD2400/2401.
|
||||
*
|
||||
* Copyright (C) 1994 Cronyx Ltd.
|
||||
* Author: Serge Vakulenko, <vak@zebub.msk.su>
|
||||
*
|
||||
* This software is distributed with NO WARRANTIES, not even the implied
|
||||
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Authors grant any other persons or organisations permission to use
|
||||
* or modify this software as long as this message is kept with the software,
|
||||
* all derivative works or modified versions.
|
||||
*
|
||||
* Version 1.0, Fri Oct 7 19:34:06 MSD 1994
|
||||
*/
|
||||
#define NBRD 3 /* the maximum number of installed boards */
|
||||
#define NPORT 16 /* the number of i/o ports per board */
|
||||
|
||||
#define REVCL_MIN 7 /* CD2400 min. revision number G */
|
||||
#define REVCL_MAX 11 /* CD2400 max. revision number K */
|
||||
|
||||
#define BRD_INTR_LEVEL 0x5a /* interrupt level (arbitrary PILR value) */
|
||||
|
||||
#define CS0(p) ((p) | 0x8000) /* chip select 0 */
|
||||
#define CS1(p) ((p) | 0xc000) /* chip select 1 */
|
||||
#define BSR(p) (p) /* board status register, read only */
|
||||
#define BCR0(p) (p) /* board command register 0, write only */
|
||||
#define BCR1(p) ((p) | 0x2000) /* board command register 1, write only */
|
||||
|
||||
/*
|
||||
* Chip register address, B is chip base port, R is chip register number.
|
||||
*/
|
||||
#define R(b,r) ((b) | (((r)<<6 & 0x3c00) | ((r) & 0xf)))
|
||||
|
||||
/*
|
||||
* Interrupt acknowledge register, P is board port, L is interrupt level,
|
||||
* as prodrammed in PILR.
|
||||
*/
|
||||
#define IACK(p,l) (R(p,l) | 0x4000)
|
||||
|
||||
/*
|
||||
* Global registers.
|
||||
*/
|
||||
#define GFRCR(b) R(b,0x82) /* global firmware revision code register */
|
||||
#define CAR(b) R(b,0xec) /* channel access register */
|
||||
|
||||
/*
|
||||
* Option registers.
|
||||
*/
|
||||
#define CMR(b) R(b,0x18) /* channel mode register */
|
||||
#define COR1(b) R(b,0x13) /* channel option register 1 */
|
||||
#define COR2(b) R(b,0x14) /* channel option register 2 */
|
||||
#define COR3(b) R(b,0x15) /* channel option register 3 */
|
||||
#define COR4(b) R(b,0x16) /* channel option register 4 */
|
||||
#define COR5(b) R(b,0x17) /* channel option register 5 */
|
||||
#define COR6(b) R(b,0x1b) /* channel option register 6 */
|
||||
#define COR7(b) R(b,0x04) /* channel option register 7 */
|
||||
#define SCHR1(b) R(b,0x1c) /* special character register 1 */
|
||||
#define SCHR2(b) R(b,0x1d) /* special character register 2 */
|
||||
#define SCHR3(b) R(b,0x1e) /* special character register 3 */
|
||||
#define SCHR4(b) R(b,0x1f) /* special character register 4 */
|
||||
#define SCRL(b) R(b,0x20) /* special character range low */
|
||||
#define SCRH(b) R(b,0x21) /* special character range high */
|
||||
#define LNXT(b) R(b,0x2d) /* LNext character */
|
||||
#define RFAR1(b) R(b,0x1c) /* receive frame address register 1 */
|
||||
#define RFAR2(b) R(b,0x1d) /* receive frame address register 2 */
|
||||
#define RFAR3(b) R(b,0x1e) /* receive frame address register 3 */
|
||||
#define RFAR4(b) R(b,0x1f) /* receive frame address register 4 */
|
||||
#define CPSR(b) R(b,0xd4) /* CRC polynomial select register */
|
||||
|
||||
/*
|
||||
* Bit rate and clock option registers.
|
||||
*/
|
||||
#define RBPR(b) R(b,0xc9) /* receive baud rate period register */
|
||||
#define RCOR(b) R(b,0xca) /* receive clock option register */
|
||||
#define TBPR(b) R(b,0xc1) /* transmit baud rate period register */
|
||||
#define TCOR(b) R(b,0xc2) /* receive clock option register */
|
||||
|
||||
/*
|
||||
* Channel command and status registers.
|
||||
*/
|
||||
#define CCR(b) R(b,0x10) /* channel command register */
|
||||
#define STCR(b) R(b,0x11) /* special transmit command register */
|
||||
#define CSR(b) R(b,0x19) /* channel status register */
|
||||
#define MSVR(b) R(b,0xdc) /* modem signal value register */
|
||||
#define MSVR_RTS(b) R(b,0xdc) /* modem RTS setup register */
|
||||
#define MSVR_DTR(b) R(b,0xdd) /* modem DTR setup register */
|
||||
|
||||
/*
|
||||
* Interrupt registers.
|
||||
*/
|
||||
#define LIVR(b) R(b,0x0a) /* local interrupt vector register */
|
||||
#define IER(b) R(b,0x12) /* interrupt enable register */
|
||||
#define LICR(b) R(b,0x25) /* local interrupting channel register */
|
||||
#define STK(b) R(b,0xe0) /* stack register */
|
||||
|
||||
/*
|
||||
* Receive interrupt registers.
|
||||
*/
|
||||
#define RPILR(b) R(b,0xe3) /* receive priority interrupt level register */
|
||||
#define RIR(b) R(b,0xef) /* receive interrupt register */
|
||||
#define RISR(b) R(b,0x8a) /* receive interrupt status register */
|
||||
#define RISRL(b) R(b,0x8a) /* receive interrupt status register low */
|
||||
#define RISRH(b) R(b,0x8b) /* receive interrupt status register high */
|
||||
#define RFOC(b) R(b,0x33) /* receive FIFO output count */
|
||||
#define RDR(b) R(b,0xf8) /* receive data register */
|
||||
#define REOIR(b) R(b,0x87) /* receive end of interrupt register */
|
||||
|
||||
/*
|
||||
* Transmit interrupt registers.
|
||||
*/
|
||||
#define TPILR(b) R(b,0xe2) /* transmit priority interrupt level reg */
|
||||
#define TIR(b) R(b,0xee) /* transmit interrupt register */
|
||||
#define TISR(b) R(b,0x89) /* transmit interrupt status register */
|
||||
#define TFTC(b) R(b,0x83) /* transmit FIFO transfer count */
|
||||
#define TDR(b) R(b,0xf8) /* transmit data register */
|
||||
#define TEOIR(b) R(b,0x86) /* transmit end of interrupt register */
|
||||
|
||||
/*
|
||||
* Modem interrupt registers.
|
||||
*/
|
||||
#define MPILR(b) R(b,0xe1) /* modem priority interrupt level register */
|
||||
#define MIR(b) R(b,0xed) /* modem interrupt register */
|
||||
#define MISR(b) R(b,0x88) /* modem/timer interrupt status register */
|
||||
#define MEOIR(b) R(b,0x85) /* modem end of interrupt register */
|
||||
|
||||
/*
|
||||
* DMA registers.
|
||||
*/
|
||||
#define DMR(b) R(b,0xf4) /* DMA mode register */
|
||||
#define BERCNT(b) R(b,0x8d) /* bus error retry count */
|
||||
#define DMABSTS(b) R(b,0x1a) /* DMA buffer status */
|
||||
|
||||
/*
|
||||
* DMA receive registers.
|
||||
*/
|
||||
#define ARBADRL(b) R(b,0x40) /* A receive buffer address lower */
|
||||
#define ARBADRU(b) R(b,0x42) /* A receive buffer address upper */
|
||||
#define BRBADRL(b) R(b,0x44) /* B receive buffer address lower */
|
||||
#define BRBADRU(b) R(b,0x46) /* B receive buffer address upper */
|
||||
#define ARBCNT(b) R(b,0x48) /* A receive buffer byte count */
|
||||
#define BRBCNT(b) R(b,0x4a) /* B receive buffer byte count */
|
||||
#define ARBSTS(b) R(b,0x4c) /* A receive buffer status */
|
||||
#define BRBSTS(b) R(b,0x4d) /* B receive buffer status */
|
||||
#define RCBADRL(b) R(b,0x3c) /* receive current buffer address lower */
|
||||
#define RCBADRU(b) R(b,0x3e) /* receive current buffer address upper */
|
||||
|
||||
/*
|
||||
* DMA transmit registers.
|
||||
*/
|
||||
#define ATBADRL(b) R(b,0x50) /* A transmit buffer address lower */
|
||||
#define ATBADRU(b) R(b,0x52) /* A transmit buffer address upper */
|
||||
#define BTBADRL(b) R(b,0x54) /* B transmit buffer address lower */
|
||||
#define BTBADRU(b) R(b,0x56) /* B transmit buffer address upper */
|
||||
#define ATBCNT(b) R(b,0x58) /* A transmit buffer byte count */
|
||||
#define BTBCNT(b) R(b,0x5a) /* B transmit buffer byte count */
|
||||
#define ATBSTS(b) R(b,0x5c) /* A transmit buffer status */
|
||||
#define BTBSTS(b) R(b,0x5d) /* B transmit buffer status */
|
||||
#define TCBADRL(b) R(b,0x38) /* transmit current buffer address lower */
|
||||
#define TCBADRU(b) R(b,0x3a) /* transmit current buffer address upper */
|
||||
|
||||
/*
|
||||
* Timer registers.
|
||||
*/
|
||||
#define TPR(b) R(b,0xd8) /* timer period register */
|
||||
#define RTPR(b) R(b,0x26) /* receive timeout period register */
|
||||
#define RTPRL(b) R(b,0x26) /* receive timeout period register low */
|
||||
#define RTPTH(b) R(b,0x27) /* receive timeout period register high */
|
||||
#define GT1(b) R(b,0x28) /* general timer 1 */
|
||||
#define GT1L(b) R(b,0x28) /* general timer 1 low */
|
||||
#define GT1H(b) R(b,0x29) /* general timer 1 high */
|
||||
#define GT2(b) R(b,0x2a) /* general timer 2 */
|
||||
#define TTR(b) R(b,0x2a) /* transmit timer register */
|
||||
|
||||
/*
|
||||
* Board status register bits.
|
||||
*/
|
||||
#define BSR_NOINTR 0x01 /* no interrupt pending flag */
|
||||
|
||||
#define BSR_VAR_MASK 0x66 /* adapter variant mask */
|
||||
|
||||
#define BSR_OSC_MASK 0x18 /* oscillator frequency mask */
|
||||
#define BSR_OSC_20 0x18 /* 20 MHz */
|
||||
#define BSR_OSC_18432 0x10 /* 18.432 MHz */
|
||||
|
||||
#define BSR_NOCHAIN 0x80 /* no daisy chained board */
|
||||
|
||||
#define BSR_NODSR(n) (0x100 << (n)) /* DSR from channels 0-3, inverted */
|
||||
#define BSR_NOCD(n) (0x1000 << (n)) /* CD from channels 0-3, inverted */
|
||||
|
||||
/*
|
||||
* Board revision mask.
|
||||
*/
|
||||
#define BSR_REV_MASK (BSR_OSC_MASK|BSR_VAR_MASK|BSR_NOCHAIN)
|
||||
|
||||
/*
|
||||
* Board control register 0 bits.
|
||||
*/
|
||||
#define BCR0_IRQ_DIS 0x00 /* no interrupt generated */
|
||||
#define BCR0_IRQ_3 0x01 /* select IRQ number 3 */
|
||||
#define BCR0_IRQ_5 0x02 /* select IRQ number 5 */
|
||||
#define BCR0_IRQ_7 0x03 /* select IRQ number 7 */
|
||||
#define BCR0_IRQ_10 0x04 /* select IRQ number 10 */
|
||||
#define BCR0_IRQ_11 0x05 /* select IRQ number 11 */
|
||||
#define BCR0_IRQ_12 0x06 /* select IRQ number 12 */
|
||||
#define BCR0_IRQ_15 0x07 /* select IRQ number 15 */
|
||||
|
||||
#define BCR0_NORESET 0x08 /* CD2400 reset flag (inverted) */
|
||||
|
||||
#define BCR0_DMA_DIS 0x00 /* no interrupt generated */
|
||||
#define BCR0_DMA_5 0x10 /* select DMA channel 5 */
|
||||
#define BCR0_DMA_6 0x20 /* select DMA channel 6 */
|
||||
#define BCR0_DMA_7 0x30 /* select DMA channel 7 */
|
||||
|
||||
#define BCR0_UM_ASYNC 0x00 /* channel 0 mode - async */
|
||||
#define BCR0_UM_SYNC 0x80 /* channel 0 mode - sync */
|
||||
#define BCR0_UI_RS232 0x00 /* channel 0 interface - RS-232 */
|
||||
#define BCR0_UI_RS449 0x40 /* channel 0 interface - RS-449/V.35 */
|
||||
#define BCR0_UMASK 0xc0 /* channel 0 interface mask */
|
||||
|
||||
/*
|
||||
* Board control register 1 bits.
|
||||
*/
|
||||
#define BCR1_DTR(n) (0x100 << (n)) /* DTR for channels 0-3 sync */
|
||||
|
||||
/*
|
||||
* Cronyx board variants.
|
||||
*/
|
||||
#define CRONYX_100 0x64
|
||||
#define CRONYX_400 0x62
|
||||
#define CRONYX_500 0x60
|
||||
#define CRONYX_410 0x24
|
||||
#define CRONYX_810 0x20
|
||||
#define CRONYX_410s 0x04
|
||||
#define CRONYX_810s 0x00
|
||||
#define CRONYX_440 0x44
|
||||
#define CRONYX_840 0x40
|
||||
#define CRONYX_401 0x26
|
||||
#define CRONYX_801 0x22
|
||||
#define CRONYX_401s 0x06
|
||||
#define CRONYX_801s 0x02
|
||||
#define CRONYX_404 0x46
|
||||
#define CRONYX_703 0x42
|
||||
|
||||
/*
|
||||
* Channel commands (CCR).
|
||||
*/
|
||||
#define CCR_CLRCH 0x40 /* clear channel */
|
||||
#define CCR_INITCH 0x20 /* initialize channel */
|
||||
#define CCR_RSTALL 0x10 /* reset all channels */
|
||||
#define CCR_ENTX 0x08 /* enable transmitter */
|
||||
#define CCR_DISTX 0x04 /* disable transmitter */
|
||||
#define CCR_ENRX 0x02 /* enable receiver */
|
||||
#define CCR_DISRX 0x01 /* disable receiver */
|
||||
#define CCR_CLRT1 0xc0 /* clear timer 1 */
|
||||
#define CCR_CLRT2 0xa0 /* clear timer 2 */
|
||||
#define CCR_CLRRCV 0x90 /* clear receiver */
|
||||
|
||||
/*
|
||||
* Interrupt enable register (IER) bits.
|
||||
*/
|
||||
#define IER_MDM 0x80 /* modem status changed */
|
||||
#define IER_RET 0x20 /* receive exception timeout */
|
||||
#define IER_RXD 0x08 /* data received */
|
||||
#define IER_TIMER 0x04 /* timer expired */
|
||||
#define IER_TXMPTY 0x02 /* transmitter empty */
|
||||
#define IER_TXD 0x01 /* data transmitted */
|
||||
|
||||
/*
|
||||
* Modem signal values register bits (MSVR).
|
||||
*/
|
||||
#define MSV_DSR 0x80 /* state of Data Set Ready input */
|
||||
#define MSV_CD 0x40 /* state of Carrier Detect input */
|
||||
#define MSV_CTS 0x20 /* state of Clear to Send input */
|
||||
#define MSV_TXCOUT 0x10 /* TXCout/DTR pin output flag */
|
||||
#define MSV_PORTID 0x04 /* device is CL-CD2401 (not 2400) */
|
||||
#define MSV_DTR 0x02 /* state of Data Terminal Ready output */
|
||||
#define MSV_RTS 0x01 /* state of Request to Send output */
|
||||
#define MSV_BITS "\20\1rts\2dtr\3cd2400\5txcout\6cts\7cd\10dsr"
|
||||
|
||||
/*
|
||||
* DMA buffer status register bits (DMABSTS).
|
||||
*/
|
||||
#define DMABSTS_TDALIGN 0x80 /* internal data alignment in transmit FIFO */
|
||||
#define DMABSTS_RSTAPD 0x40 /* reset append mode */
|
||||
#define DMABSTS_CRTTBUF 0x20 /* internal current transmit buffer in use */
|
||||
#define DMABSTS_APPEND 0x10 /* append buffer is in use */
|
||||
#define DMABSTS_NTBUF 0x08 /* next transmit buffer is B (not A) */
|
||||
#define DMABSTS_TBUSY 0x04 /* current transmit buffer is in use */
|
||||
#define DMABSTS_NRBUF 0x02 /* next receive buffer is B (not A) */
|
||||
#define DMABSTS_RBUSY 0x01 /* current receive buffer is in use */
|
||||
|
||||
/*
|
||||
* Buffer status register bits ([AB][RT]BSTS).
|
||||
*/
|
||||
#define BSTS_BUSERR 0x80 /* bus error */
|
||||
#define BSTS_EOFR 0x40 /* end of frame */
|
||||
#define BSTS_EOBUF 0x20 /* end of buffer */
|
||||
#define BSTS_APPEND 0x08 /* append mode */
|
||||
#define BSTS_INTR 0x02 /* interrupt required */
|
||||
#define BSTS_OWN24 0x01 /* buffer is (free to be) used by CD2400 */
|
||||
#define BSTS_BITS "\20\1own24\2intr\4append\6eobuf\7eofr\10buserr"
|
||||
|
||||
/*
|
||||
* Receive interrupt status register (RISR) bits.
|
||||
*/
|
||||
#define RIS_OVERRUN 0x0008 /* overrun error */
|
||||
#define RIS_BB 0x0800 /* buffer B status (not A) */
|
||||
#define RIS_EOBUF 0x2000 /* end of buffer reached */
|
||||
#define RIS_EOFR 0x4000 /* frame reception complete */
|
||||
#define RIS_BUSERR 0x8000 /* bus error */
|
||||
|
||||
#define RISH_CLRDCT 0x0001 /* X.21 clear detect */
|
||||
#define RISH_RESIND 0x0004 /* residual indication */
|
||||
#define RISH_CRCERR 0x0010 /* CRC error */
|
||||
#define RISH_RXABORT 0x0020 /* abort sequence received */
|
||||
#define RISH_EOFR 0x0040 /* complete frame received */
|
||||
#define RISH_BITS "\20\1clrdct\3resind\4overrun\5crcerr\6rxabort\7eofr\14bb\16eobuf\17eofr\20buserr"
|
||||
|
||||
#define RISA_BREAK 0x0001 /* break signal detected */
|
||||
#define RISA_FRERR 0x0002 /* frame error (bad stop bits) */
|
||||
#define RISA_PARERR 0x0004 /* parity error */
|
||||
#define RISA_SCMASK 0x0070 /* special character detect mask */
|
||||
#define RISA_SCHR1 0x0010 /* special character 1 detected */
|
||||
#define RISA_SCHR2 0x0020 /* special character 2 detected */
|
||||
#define RISA_SCHR3 0x0030 /* special character 3 detected */
|
||||
#define RISA_SCHR4 0x0040 /* special character 4 detected */
|
||||
#define RISA_SCRANGE 0x0070 /* special character in range detected */
|
||||
#define RISA_TIMEOUT 0x0080 /* receive timeout, no data */
|
||||
#define RISA_BITS "\20\1break\2frerr\3parerr\4overrun\5schr1\6schr2\7schr4\10timeout\14bb\16eobuf\17eofr\20buserr"
|
||||
|
||||
#define RISB_CRCERR 0x0010 /* CRC error */
|
||||
#define RISB_RXABORT 0x0020 /* abort sequence received */
|
||||
#define RISB_EOFR 0x0040 /* complete frame received */
|
||||
|
||||
#define RISX_LEADCHG 0x0001 /* CTS lead change */
|
||||
#define RISX_PARERR 0x0004 /* parity error */
|
||||
#define RISX_SCMASK 0x0070 /* special character detect mask */
|
||||
#define RISX_SCHR1 0x0010 /* special character 1 detected */
|
||||
#define RISX_SCHR2 0x0020 /* special character 2 detected */
|
||||
#define RISX_SCHR3 0x0030 /* special character 3 detected */
|
||||
#define RISX_ALLZERO 0x0040 /* all 0 condition detected */
|
||||
#define RISX_ALLONE 0x0050 /* all 1 condition detected */
|
||||
#define RISX_ALTOZ 0x0060 /* alternating 1 0 condition detected */
|
||||
#define RISX_SYN 0x0070 /* SYN detected */
|
||||
#define RISX_LEAD 0x0080 /* leading value */
|
||||
|
||||
/*
|
||||
* Channel mode register (CMR) bits.
|
||||
*/
|
||||
#define CMR_RXDMA 0x80 /* DMA receive transfer mode */
|
||||
#define CMR_TXDMA 0x40 /* DMA transmit transfer mode */
|
||||
#define CMR_HDLC 0x00 /* HDLC protocol mode */
|
||||
#define CMR_BISYNC 0x01 /* BISYNC protocol mode */
|
||||
#define CMR_ASYNC 0x02 /* ASYNC protocol mode */
|
||||
#define CMR_X21 0x03 /* X.21 protocol mode */
|
||||
|
||||
/*
|
||||
* Modem interrupt status register (MISR) bits.
|
||||
*/
|
||||
#define MIS_CDSR 0x80 /* DSR changed */
|
||||
#define MIS_CCD 0x40 /* CD changed */
|
||||
#define MIS_CCTS 0x20 /* CTS changed */
|
||||
#define MIS_CGT2 0x02 /* GT2 timer expired */
|
||||
#define MIS_CGT1 0x01 /* GT1 timer expired */
|
||||
#define MIS_BITS "\20\1gt1\2gt2\6ccts\7ccd\10cdsr"
|
||||
|
||||
/*
|
||||
* Transmit interrupt status register (TISR) bits.
|
||||
*/
|
||||
#define TIS_BUSERR 0x80 /* Bus error */
|
||||
#define TIS_EOFR 0x40 /* End of frame */
|
||||
#define TIS_EOBUF 0x20 /* end of transmit buffer reached */
|
||||
#define TIS_UNDERRUN 0x10 /* transmit underrun */
|
||||
#define TIS_BB 0x08 /* buffer B status (not A) */
|
||||
#define TIS_TXEMPTY 0x02 /* transmitter empty */
|
||||
#define TIS_TXDATA 0x01 /* transmit data below threshold */
|
||||
#define TIS_BITS "\20\1txdata\2txempty\4bb\5underrun\6eobuf\7eofr\10buserr"
|
||||
|
||||
/*
|
||||
* Local interrupt vector register (LIVR) bits.
|
||||
*/
|
||||
#define LIV_EXCEP 0
|
||||
#define LIV_MODEM 1
|
||||
#define LIV_TXDATA 2
|
||||
#define LIV_RXDATA 3
|
||||
|
||||
/*
|
||||
* Transmit end of interrupt registers (TEOIR) bits.
|
||||
*/
|
||||
#define TEOI_TERMBUFF 0x80 /* force current buffer to be discarded */
|
||||
#define TEOI_EOFR 0x40 /* end of frame in interrupt mode */
|
||||
#define TEOI_SETTM2 0x20 /* set general timer 2 in sync mode */
|
||||
#define TEOI_SETTM1 0x10 /* set general timer 1 in sync mode */
|
||||
#define TEOI_NOTRANSF 0x08 /* no transfer of data on this interrupt */
|
||||
|
||||
/*
|
||||
* Receive end of interrupt registers (REOIR) bits.
|
||||
*/
|
||||
#define REOI_TERMBUFF 0x80 /* force current buffer to be terminated */
|
||||
#define REOI_DISCEXC 0x40 /* discard exception character */
|
||||
#define REOI_SETTM2 0x20 /* set general timer 2 */
|
||||
#define REOI_SETTM1 0x10 /* set general timer 1 */
|
||||
#define REOI_NOTRANSF 0x08 /* no transfer of data */
|
||||
#define REOI_GAP_MASK 0x07 /* optional gap size to leave in buffer */
|
||||
|
||||
/*
|
||||
* Special transmit command register (STCR) bits.
|
||||
*/
|
||||
#define STC_ABORTTX 0x40 /* abort transmission (HDLC mode) */
|
||||
#define STC_APPDCMP 0x20 /* append complete (async DMA mode) */
|
||||
#define STC_SNDSPC 0x08 /* send special characters (async mode) */
|
||||
#define STC_SSPC_MASK 0x07 /* special character select */
|
||||
#define STC_SSPC_1 0x01 /* send special character #1 */
|
||||
#define STC_SSPC_2 0x02 /* send special character #2 */
|
||||
#define STC_SSPC_3 0x03 /* send special character #3 */
|
||||
#define STC_SSPC_4 0x04 /* send special character #4 */
|
||||
|
||||
/*
|
||||
* Channel status register (CSR) bits, asynchronous mode.
|
||||
*/
|
||||
#define CSRA_RXEN 0x80 /* receiver enable */
|
||||
#define CSRA_RXFLOFF 0x40 /* receiver flow off */
|
||||
#define CSRA_RXFLON 0x20 /* receiver flow on */
|
||||
#define CSRA_TXEN 0x08 /* transmitter enable */
|
||||
#define CSRA_TXFLOFF 0x04 /* transmitter flow off */
|
||||
#define CSRA_TXFLON 0x02 /* transmitter flow on */
|
||||
#define CSRA_BITS "\20\2txflon\3txfloff\4txen\6rxflon\7rxfloff\10rxen"
|
818
sys/i386/isa/if_cx.c
Normal file
818
sys/i386/isa/if_cx.c
Normal file
@ -0,0 +1,818 @@
|
||||
/*
|
||||
* Cronyx-Sigma adapter driver for FreeBSD.
|
||||
* Supports PPP/HDLC and Cisco/HDLC protocol in synchronous mode,
|
||||
* and asyncronous channels with full modem control.
|
||||
* Keepalive protocol implemented in both Cisco and PPP modes.
|
||||
*
|
||||
* Copyright (C) 1994 Cronyx Ltd.
|
||||
* Author: Serge Vakulenko, <vak@zebub.msk.su>
|
||||
*
|
||||
* This software is distributed with NO WARRANTIES, not even the implied
|
||||
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Authors grant any other persons or organisations permission to use
|
||||
* or modify this software as long as this message is kept with the software,
|
||||
* all derivative works or modified versions.
|
||||
*
|
||||
* Version 1.2, Tue Nov 22 18:57:27 MSK 1994
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include "cx.h"
|
||||
#if NCX > 0
|
||||
#include <bpfilter.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <systm.h>
|
||||
#include <kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#if NBPFILTER > 0
|
||||
#include <net/bpf.h>
|
||||
#include <net/bpfdesc.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# include <i386/isa/isa_device.h>
|
||||
# if __FreeBSD__ < 2
|
||||
# include <i386/include/pio.h>
|
||||
# else
|
||||
# include <i386/include/cpufunc.h>
|
||||
# include <sys/devconf.h>
|
||||
# endif
|
||||
# define init_func_t void(*)(int)
|
||||
# define watchdog_func_t void(*)(int)
|
||||
# define start_func_t void(*)(struct ifnet*)
|
||||
#endif
|
||||
|
||||
#ifdef __bsdi__
|
||||
# if INET
|
||||
# include <netinet/in.h>
|
||||
# include <netinet/in_systm.h>
|
||||
# include <netinet/ip.h>
|
||||
# endif
|
||||
# include <sys/device.h>
|
||||
# include <i386/isa/isavar.h>
|
||||
# include <i386/isa/icu.h>
|
||||
# include <i386/include/inline.h>
|
||||
# include <net/if_slvar.h>
|
||||
# include <net/if_p2p.h>
|
||||
# define timeout_func_t void(*)()
|
||||
# define init_func_t int(*)()
|
||||
# define watchdog_func_t int(*)()
|
||||
# define start_func_t int(*)()
|
||||
struct cxsoftc {
|
||||
struct device dev; /* base device */
|
||||
struct isadev isadev; /* ISA device */
|
||||
struct intrhand intr; /* interrupt vectoring */
|
||||
};
|
||||
#endif
|
||||
|
||||
#include <net/if_sppp.h>
|
||||
#include <sys/cronyx.h>
|
||||
#include <i386/isa/cxreg.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
# define print(s) printf s
|
||||
#else
|
||||
# define print(s) /*void*/
|
||||
#endif
|
||||
|
||||
#define TXTIMEOUT 2 /* transmit timeout in seconds */
|
||||
#define DMABUFSZ (6*256) /* buffer size */
|
||||
#define PPP_HEADER_LEN 4 /* size of PPP header */
|
||||
|
||||
/*
|
||||
* Under BSDI it's possible to use general p2p protocol scheme,
|
||||
* as well as our own one. Switching is done via IFF_ALTPHYS flag.
|
||||
* Our ifnet pointer holds the buffer large enough to contain
|
||||
* any of sppp and p2p structures.
|
||||
*/
|
||||
#ifdef __bsdi__
|
||||
# define SPPPSZ (sizeof (struct sppp))
|
||||
# define P2PSZ (sizeof (struct p2pcom))
|
||||
# define IFSTRUCTSZ (SPPPSZ>P2PSZ ? SPPPSZ : P2PSZ)
|
||||
#else
|
||||
# define IFSTRUCTSZ (sizeof (struct sppp))
|
||||
#endif
|
||||
#define IFNETSZ (sizeof (struct ifnet))
|
||||
|
||||
int cxoutput (struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt);
|
||||
int cxsioctl (struct ifnet *ifp, int cmd, caddr_t data);
|
||||
void cxinit (int unit);
|
||||
void cxstart (struct ifnet *ifp);
|
||||
void cxwatchdog (int unit);
|
||||
void cxinput (cx_chan_t *c, void *buf, unsigned len);
|
||||
int cxrinta (cx_chan_t *c);
|
||||
void cxtinta (cx_chan_t *c);
|
||||
void cxmint (cx_chan_t *c);
|
||||
void cxtimeout (caddr_t a);
|
||||
|
||||
cx_board_t cxboard [NCX]; /* adapter state structures */
|
||||
cx_chan_t *cxchan [NCX*NCHAN]; /* unit to channel struct pointer */
|
||||
|
||||
static unsigned short irq_valid_values [] = { 3, 5, 7, 10, 11, 12, 15, 0 };
|
||||
static unsigned short drq_valid_values [] = { 5, 6, 7, 0 };
|
||||
static unsigned short port_valid_values [] = {
|
||||
0x240, 0x260, 0x280, 0x300, 0x320, 0x380, 0x3a0, 0,
|
||||
};
|
||||
|
||||
#if __FreeBSD__ >= 2
|
||||
static char cxdescription [80];
|
||||
struct kern_devconf kdc_cx [NCX] = { {
|
||||
0, 0, 0, "cx", 0, { MDDT_ISA, 0, "net" },
|
||||
isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, &kdc_isa0, 0,
|
||||
DC_IDLE, cxdescription,
|
||||
} };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check that the value is contained in the list of correct values.
|
||||
*/
|
||||
static int valid (unsigned short value, unsigned short *list)
|
||||
{
|
||||
while (*list)
|
||||
if (value == *list++)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the mbuf chain, for debug purposes only.
|
||||
*/
|
||||
static void printmbuf (struct mbuf *m)
|
||||
{
|
||||
printf ("mbuf:");
|
||||
for (; m; m=m->m_next) {
|
||||
if (m->m_flags & M_PKTHDR)
|
||||
printf (" HDR %d:", m->m_pkthdr.len);
|
||||
if (m->m_flags & M_EXT)
|
||||
printf (" EXT:");
|
||||
printf (" %d", m->m_len);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Make an mbuf from data.
|
||||
*/
|
||||
static struct mbuf *makembuf (void *buf, unsigned len)
|
||||
{
|
||||
struct mbuf *m, *o, *p;
|
||||
|
||||
MGETHDR (m, M_DONTWAIT, MT_DATA);
|
||||
if (! m)
|
||||
return (0);
|
||||
if (len >= MINCLSIZE)
|
||||
MCLGET (m, M_DONTWAIT);
|
||||
m->m_pkthdr.len = len;
|
||||
m->m_len = 0;
|
||||
|
||||
p = m;
|
||||
while (len) {
|
||||
unsigned n = M_TRAILINGSPACE (p);
|
||||
if (n > len)
|
||||
n = len;
|
||||
|
||||
if (! n) {
|
||||
/* Allocate new mbuf. */
|
||||
o = p;
|
||||
MGET (p, M_DONTWAIT, MT_DATA);
|
||||
if (! p) {
|
||||
m_freem (m);
|
||||
return (0);
|
||||
}
|
||||
if (len >= MINCLSIZE)
|
||||
MCLGET (p, M_DONTWAIT);
|
||||
p->m_len = 0;
|
||||
o->m_next = p;
|
||||
|
||||
n = M_TRAILINGSPACE (p);
|
||||
if (n > len)
|
||||
n = len;
|
||||
}
|
||||
|
||||
bcopy (buf, mtod (p, caddr_t) + p->m_len, n);
|
||||
|
||||
p->m_len += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
return (m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the presence of the adapter on the given i/o port.
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
int cxprobe (struct isa_device *id)
|
||||
{
|
||||
int unit = id->id_unit;
|
||||
int iobase = id->id_iobase;
|
||||
int irq = id->id_irq;
|
||||
int drq = id->id_drq;
|
||||
int irqnum;
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
int cxprobe (struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
int unit = cf->cf_unit;
|
||||
int iobase = ((struct isa_attach_args*)aux)->ia_iobase;
|
||||
int irq = ((struct isa_attach_args*)aux)->ia_irq;
|
||||
int drq = ((struct isa_attach_args*)aux)->ia_drq;
|
||||
int irqnum, i;
|
||||
|
||||
for (i=0; i<NCX; ++i)
|
||||
if (i != unit && cxboard[i].port == iobase)
|
||||
return (0);
|
||||
if (irq == IRQUNK) {
|
||||
irq = isa_irqalloc (IRQ3|IRQ5|IRQ7|IRQ10|IRQ11|IRQ12|IRQ15);
|
||||
if (! irq)
|
||||
return (0);
|
||||
((struct isa_attach_args*)aux)->ia_irq = irq;
|
||||
}
|
||||
#endif
|
||||
irqnum = ffs (irq) - 1;
|
||||
|
||||
print (("cx%d: probe iobase=0x%x irq=%d drq=%d\n",
|
||||
unit, iobase, irqnum, drq));
|
||||
if (! valid (irqnum, irq_valid_values)) {
|
||||
printf ("cx%d: Incorrect IRQ: %d\n", unit, irqnum);
|
||||
return (0);
|
||||
}
|
||||
if (! valid (iobase, port_valid_values)) {
|
||||
printf ("cx%d: Incorrect port address: 0x%x\n", unit, iobase);
|
||||
return (0);
|
||||
}
|
||||
if (! valid (drq, drq_valid_values)) {
|
||||
printf ("cx%d: Incorrect DMA channel: %d\n", unit, drq);
|
||||
return (0);
|
||||
}
|
||||
if (! cx_probe_board (iobase))
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* The adapter is present, initialize the driver structures.
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
int cxattach (struct isa_device *id)
|
||||
{
|
||||
int unit = id->id_unit;
|
||||
int iobase = id->id_iobase;
|
||||
int irq = id->id_irq;
|
||||
int drq = id->id_drq;
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
void cxattach (struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
int unit = self->dv_unit;
|
||||
int iobase = ((struct isa_attach_args*)aux)->ia_iobase;
|
||||
int irq = ((struct isa_attach_args*)aux)->ia_irq;
|
||||
int drq = ((struct isa_attach_args*)aux)->ia_drq;
|
||||
struct cxsoftc *sc = (struct cxsoftc*) self;
|
||||
void cxintr (cx_board_t *b);
|
||||
#endif
|
||||
cx_board_t *b = cxboard + unit;
|
||||
int i;
|
||||
|
||||
/* Initialize the board structure. */
|
||||
cx_init (b, unit, iobase, ffs(irq)-1, drq);
|
||||
|
||||
for (i=0; i<NCHAN; ++i) {
|
||||
cx_chan_t *c = b->chan + i;
|
||||
int u = b->num*NCHAN + i;
|
||||
cxchan[u] = c;
|
||||
|
||||
if (c->type == T_NONE)
|
||||
continue;
|
||||
|
||||
/* Allocate the buffer memory. */
|
||||
c->arbuf = malloc (DMABUFSZ, M_DEVBUF, M_NOWAIT);
|
||||
c->brbuf = malloc (DMABUFSZ, M_DEVBUF, M_NOWAIT);
|
||||
c->atbuf = malloc (DMABUFSZ, M_DEVBUF, M_NOWAIT);
|
||||
c->btbuf = malloc (DMABUFSZ, M_DEVBUF, M_NOWAIT);
|
||||
|
||||
/* All buffers should be located in lower 16M of memory! */
|
||||
if (!c->arbuf || !c->brbuf || !c->atbuf || !c->btbuf) {
|
||||
printf ("cx%d.%d: No memory for channel buffers\n",
|
||||
c->board->num, c->num);
|
||||
c->type = T_NONE;
|
||||
}
|
||||
|
||||
switch (c->type) {
|
||||
case T_SYNC_RS232:
|
||||
case T_SYNC_V35:
|
||||
case T_SYNC_RS449:
|
||||
case T_UNIV_RS232:
|
||||
case T_UNIV_RS449:
|
||||
case T_UNIV_V35:
|
||||
c->ifp = malloc (IFSTRUCTSZ, M_DEVBUF, M_NOWAIT);
|
||||
if (! c->ifp) {
|
||||
printf ("cx%d.%d: No memory for ifnet buffer\n",
|
||||
c->board->num, c->num);
|
||||
c->type = T_NONE;
|
||||
continue;
|
||||
}
|
||||
c->ifp->if_unit = u;
|
||||
c->ifp->if_name = "cx";
|
||||
c->ifp->if_mtu = PP_MTU;
|
||||
c->ifp->if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
|
||||
c->ifp->if_ioctl = cxsioctl;
|
||||
c->ifp->if_start = (start_func_t) cxstart;
|
||||
c->ifp->if_watchdog = (watchdog_func_t) cxwatchdog;
|
||||
/* Init routine is never called by upper level? */
|
||||
c->ifp->if_init = (init_func_t) cxinit;
|
||||
sppp_attach (c->ifp);
|
||||
if_attach (c->ifp);
|
||||
#if NBPFILTER > 0
|
||||
/* If BPF is in the kernel, call the attach for it. */
|
||||
bpfattach (&c->bpf, c->ifp, DLT_PPP, PPP_HEADER_LEN);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the adapter. */
|
||||
cx_setup_board (b);
|
||||
|
||||
/* Activate the timeout routine. */
|
||||
if (unit == 0)
|
||||
timeout ((timeout_func_t) cxtimeout, 0, hz*5);
|
||||
|
||||
#if __FreeBSD__ >= 2
|
||||
if (unit != 0)
|
||||
kdc_cx[unit] = kdc_cx[0];
|
||||
kdc_cx[unit].kdc_unit = unit;
|
||||
kdc_cx[unit].kdc_isa = id;
|
||||
sprintf (cxdescription, "Cronyx-Sigma-%s sync/async serial adapter",
|
||||
b->name);
|
||||
dev_attach (&kdc_cx[unit]);
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
printf ("cx%d: <Cronyx-%s>\n", unit, b->name);
|
||||
return (1);
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
printf (": <Cronyx-%s>\n", b->name);
|
||||
isa_establish (&sc->isadev, &sc->dev);
|
||||
sc->intr.ih_fun = (int(*)()) cxintr;
|
||||
sc->intr.ih_arg = (void*) b;
|
||||
intr_establish (irq, &sc->intr, DV_NET);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
struct isa_driver cxdriver = { cxprobe, cxattach, "cx" };
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
struct cfdriver cxcd = { 0, "cx", cxprobe, cxattach, sizeof (struct cxsoftc) };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Process an ioctl request.
|
||||
*/
|
||||
int cxsioctl (struct ifnet *ifp, int cmd, caddr_t data)
|
||||
{
|
||||
cx_chan_t *c = cxchan[ifp->if_unit];
|
||||
int error, s;
|
||||
|
||||
if (c->type==T_NONE || c->mode==M_ASYNC)
|
||||
return (EINVAL);
|
||||
#ifdef __bsdi__
|
||||
if (c->sopt.ext) {
|
||||
/* Save RUNNING flag. */
|
||||
int running = (ifp->if_flags & IFF_RUNNING);
|
||||
error = p2p_ioctl (ifp, cmd, data);
|
||||
ifp->if_flags &= ~IFF_RUNNING;
|
||||
ifp->if_flags |= running;
|
||||
} else
|
||||
#endif
|
||||
error = sppp_ioctl (ifp, cmd, data);
|
||||
if (error)
|
||||
return (error);
|
||||
if (cmd != SIOCSIFFLAGS)
|
||||
return (0);
|
||||
|
||||
s = splimp ();
|
||||
if (! (ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
|
||||
/* Interface is down and running -- stop it. */
|
||||
cxinit (ifp->if_unit);
|
||||
else if ((ifp->if_flags & IFF_UP) && ! (ifp->if_flags & IFF_RUNNING))
|
||||
/* Interface is up and not running -- start it. */
|
||||
cxinit (ifp->if_unit);
|
||||
splx (s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization of interface.
|
||||
*/
|
||||
void cxinit (int unit)
|
||||
{
|
||||
cx_chan_t *c = cxchan[unit];
|
||||
unsigned short port = c->chip->port;
|
||||
int s;
|
||||
|
||||
print (("cx%d.%d: cxinit\n", c->board->num, c->num));
|
||||
|
||||
/* Disable interrupts */
|
||||
s = splimp();
|
||||
|
||||
/* Reset the channel (for sync modes only) */
|
||||
if (c->ifp->if_flags & IFF_OACTIVE) {
|
||||
outb (CAR(port), c->num & 3);
|
||||
outb (STCR(port), STC_ABORTTX | STC_SNDSPC);
|
||||
}
|
||||
cx_setup_chan (c);
|
||||
c->ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
|
||||
|
||||
if (c->ifp->if_flags & IFF_UP) {
|
||||
/* The interface is up, start it */
|
||||
c->ifp->if_flags |= IFF_RUNNING;
|
||||
|
||||
#if __FreeBSD__ >= 2
|
||||
/* Mark the board busy on the first startup.
|
||||
* Never goes idle. */
|
||||
kdc_cx[c->board->num].kdc_state = DC_BUSY;
|
||||
#endif
|
||||
/* Initialize channel, enable receiver and transmitter */
|
||||
cx_cmd (port, CCR_INITCH | CCR_ENRX | CCR_ENTX);
|
||||
/* Repeat the command, to avoid the rev.H bug */
|
||||
cx_cmd (port, CCR_INITCH | CCR_ENRX | CCR_ENTX);
|
||||
|
||||
/* Start receiver */
|
||||
outw (ARBCNT(port), DMABUFSZ);
|
||||
outb (ARBSTS(port), BSTS_OWN24);
|
||||
outw (BRBCNT(port), DMABUFSZ);
|
||||
outb (BRBSTS(port), BSTS_OWN24);
|
||||
|
||||
/* Raise DTR and RTS */
|
||||
cx_chan_dtr (c, 1);
|
||||
cx_chan_rts (c, 1);
|
||||
|
||||
/* Enable interrupts */
|
||||
outb (IER(port), IER_RXD | IER_TXD);
|
||||
|
||||
cxstart (c->ifp);
|
||||
|
||||
} else if (! c->sopt.ext)
|
||||
/* Flush the interface output queue, if it is down */
|
||||
sppp_flush (c->ifp);
|
||||
|
||||
splx (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill transmitter buffer with data.
|
||||
*/
|
||||
void cxput (cx_chan_t *c, char b)
|
||||
{
|
||||
struct mbuf *m;
|
||||
unsigned char *buf;
|
||||
unsigned short port = c->chip->port, len, cnt_port, sts_port;
|
||||
|
||||
/* Choose the buffer. */
|
||||
if (b == 'A') {
|
||||
buf = c->atbuf;
|
||||
cnt_port = ATBCNT(port);
|
||||
sts_port = ATBSTS(port);
|
||||
} else {
|
||||
buf = c->btbuf;
|
||||
cnt_port = BTBCNT(port);
|
||||
sts_port = BTBSTS(port);
|
||||
}
|
||||
|
||||
/* Is it busy? */
|
||||
if (inb (sts_port) & BSTS_OWN24) {
|
||||
c->ifp->if_flags |= IFF_OACTIVE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the packet to send. */
|
||||
#ifdef __bsdi__
|
||||
if (c->sopt.ext) {
|
||||
struct p2pcom *p = (struct p2pcom*) c->ifp;
|
||||
int s = splimp ();
|
||||
|
||||
IF_DEQUEUE (&p->p2p_isnd, m)
|
||||
if (! m)
|
||||
IF_DEQUEUE (&c->ifp->if_snd, m)
|
||||
splx (s);
|
||||
} else
|
||||
#endif
|
||||
m = sppp_dequeue (c->ifp);
|
||||
if (! m)
|
||||
return;
|
||||
len = m->m_pkthdr.len;
|
||||
if (len >= DMABUFSZ) {
|
||||
printf ("cx%d.%d: too long packet: %d bytes\n",
|
||||
c->board->num, c->num, len);
|
||||
printmbuf (m);
|
||||
m_freem (m);
|
||||
return;
|
||||
}
|
||||
m_copydata (m, 0, len, buf);
|
||||
#if NBPFILTER > 0
|
||||
if (c->bpf)
|
||||
bpf_mtap (c->bpf, m);
|
||||
#endif
|
||||
m_freem (m);
|
||||
|
||||
/* Start transmitter. */
|
||||
outw (cnt_port, len);
|
||||
outb (sts_port, BSTS_EOFR | BSTS_INTR | BSTS_OWN24);
|
||||
#ifdef DEBUG
|
||||
if (c->ifp->if_flags & IFF_DEBUG)
|
||||
printf ("cx%d.%d: enqueue %d bytes to %c\n",
|
||||
c->board->num, c->num, len, buf==c->atbuf ? 'A' : 'B');
|
||||
#endif
|
||||
c->ifp->if_flags |= IFF_OACTIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start output on interface. Get another datagram to send
|
||||
* off of the interface queue, and copy it to the interface
|
||||
* before starting the output.
|
||||
*/
|
||||
void cxstart (struct ifnet *ifp)
|
||||
{
|
||||
cx_chan_t *c = cxchan[ifp->if_unit];
|
||||
unsigned short port = c->chip->port;
|
||||
|
||||
/* No output if the interface is down. */
|
||||
if (! (ifp->if_flags & IFF_RUNNING))
|
||||
return;
|
||||
|
||||
/* Set the current channel number. */
|
||||
outb (CAR(port), c->num & 3);
|
||||
|
||||
/* Determine the buffer order. */
|
||||
if (inb (DMABSTS(port)) & DMABSTS_NTBUF) {
|
||||
cxput (c, 'B');
|
||||
cxput (c, 'A');
|
||||
} else {
|
||||
cxput (c, 'A');
|
||||
cxput (c, 'B');
|
||||
}
|
||||
|
||||
/* Set up transmit timeout. */
|
||||
if (c->ifp->if_flags & IFF_OACTIVE)
|
||||
c->ifp->if_timer = TXTIMEOUT;
|
||||
|
||||
/*
|
||||
* Enable TXMPTY interrupt,
|
||||
* to catch the case when the second buffer is empty.
|
||||
*/
|
||||
if ((inb (ATBSTS(port)) & BSTS_OWN24) &&
|
||||
(inb (BTBSTS(port)) & BSTS_OWN24)) {
|
||||
outb (IER(port), IER_RXD | IER_TXD | IER_TXMPTY);
|
||||
} else
|
||||
outb (IER(port), IER_RXD | IER_TXD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle transmit timeouts.
|
||||
* Recover after lost transmit interrupts.
|
||||
*/
|
||||
void cxwatchdog (int unit)
|
||||
{
|
||||
cx_chan_t *c = cxchan[unit];
|
||||
|
||||
if (c->ifp->if_flags & IFF_OACTIVE) {
|
||||
c->ifp->if_flags &= ~IFF_OACTIVE;
|
||||
cxstart (c->ifp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle receive interrupts, including receive errors and
|
||||
* receive timeout interrupt.
|
||||
*/
|
||||
void cxrinth (cx_chan_t *c)
|
||||
{
|
||||
unsigned short port = c->chip->port;
|
||||
unsigned short len, risr = inw (RISR(port));
|
||||
|
||||
print (("cx%d.%d: hdlc receive interrupt, risr=%b, arbsts=%b, brbsts=%b\n",
|
||||
c->board->num, c->num, risr, RISH_BITS,
|
||||
inb (ARBSTS(port)), BSTS_BITS, inb (BRBSTS(port)), BSTS_BITS));
|
||||
|
||||
/* Receive errors. */
|
||||
if (risr & (RIS_BUSERR | RIS_OVERRUN | RISH_CRCERR | RISH_RXABORT)) {
|
||||
if (c->ifp->if_flags & IFF_DEBUG)
|
||||
printf ("cx%d.%d: receive error, risr=%b\n",
|
||||
c->board->num, c->num, risr, RISH_BITS);
|
||||
++c->ifp->if_ierrors;
|
||||
if (risr & RIS_OVERRUN)
|
||||
++c->ifp->if_collisions;
|
||||
} else if (risr & RIS_EOBUF) {
|
||||
/* Handle received data. */
|
||||
len = (risr & RIS_BB) ? inw(BRBCNT(port)) : inw(ARBCNT(port));
|
||||
if (len > DMABUFSZ) {
|
||||
/* Fatal error: actual DMA transfer size
|
||||
* exceeds our buffer size. It could be caused
|
||||
* by incorrectly programmed DMA register or
|
||||
* hardware fault. Possibly, should panic here. */
|
||||
printf ("cx%d.%d: panic! DMA buffer overflow: %d bytes\n",
|
||||
c->board->num, c->num, len);
|
||||
++c->ifp->if_ierrors;
|
||||
} else if (! (risr & RIS_EOFR)) {
|
||||
/* The received frame does not fit in the DMA buffer.
|
||||
* It could be caused by serial lie noise,
|
||||
* or if the peer has too big MTU. */
|
||||
if (c->ifp->if_flags & IFF_DEBUG)
|
||||
printf ("cx%d.%d: received frame length exceeds MTU, risr=%b\n",
|
||||
c->board->num, c->num, risr, RISH_BITS);
|
||||
++c->ifp->if_ierrors;
|
||||
} else {
|
||||
/* Valid frame received. */
|
||||
print (("cx%d.%d: HDLC: %d bytes received\n",
|
||||
c->board->num, c->num, len));
|
||||
cxinput (c, (risr & RIS_BB) ? c->brbuf : c->arbuf, len);
|
||||
++c->ifp->if_ipackets;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart receiver. */
|
||||
if (! (inb (ARBSTS(port)) & BSTS_OWN24)) {
|
||||
outw (ARBCNT(port), DMABUFSZ);
|
||||
outb (ARBSTS(port), BSTS_OWN24);
|
||||
}
|
||||
if (! (inb (BRBSTS(port)) & BSTS_OWN24)) {
|
||||
outw (BRBCNT(port), DMABUFSZ);
|
||||
outb (BRBSTS(port), BSTS_OWN24);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle transmit interrupt.
|
||||
*/
|
||||
int cxtinth (cx_chan_t *c)
|
||||
{
|
||||
unsigned short port = c->chip->port;
|
||||
unsigned char tisr = inb (TISR(port));
|
||||
unsigned char teoir = 0;
|
||||
|
||||
print (("cx%d.%d: hdlc transmit interrupt, tisr=%b, atbsts=%b, btbsts=%b\n",
|
||||
c->board->num, c->num, tisr, TIS_BITS,
|
||||
inb (ATBSTS(port)), BSTS_BITS, inb (BTBSTS(port)), BSTS_BITS));
|
||||
|
||||
if (tisr & (TIS_BUSERR | TIS_UNDERRUN)) {
|
||||
if (c->ifp->if_flags & IFF_DEBUG)
|
||||
printf ("cx%d.%d: transmit error, tisr=%b\n",
|
||||
c->board->num, c->num, tisr, TIS_BITS);
|
||||
++c->ifp->if_oerrors;
|
||||
/* Terminate the failed buffer. */
|
||||
teoir |= TEOI_TERMBUFF;
|
||||
} else if (tisr & (TIS_EOFR))
|
||||
++c->ifp->if_opackets;
|
||||
|
||||
c->ifp->if_flags &= ~IFF_OACTIVE;
|
||||
cxstart (c->ifp);
|
||||
return (teoir);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
void cxintr (int bnum)
|
||||
{
|
||||
cx_board_t *b = cxboard + bnum;
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
void cxintr (cx_board_t *b)
|
||||
{
|
||||
#endif
|
||||
while (! (inw (BSR(b->port)) & BSR_NOINTR)) {
|
||||
/* Acknowledge the interrupt to enter the interrupt context. */
|
||||
/* Read the local interrupt vector register. */
|
||||
unsigned char livr = inb (IACK(b->port, BRD_INTR_LEVEL));
|
||||
cx_chan_t *c = b->chan + (livr>>2 & 0xf);
|
||||
unsigned short port = c->chip->port;
|
||||
unsigned short eoiport = REOIR(port);
|
||||
unsigned char eoi = 0;
|
||||
|
||||
if (c->type == T_NONE) {
|
||||
printf ("cx%d.%d: unexpected interrupt, livr=0x%x\n",
|
||||
c->board->num, c->num, livr);
|
||||
continue; /* incorrect channel number? */
|
||||
}
|
||||
/* print (("cx%d.%d: interrupt, livr=0x%x\n",
|
||||
c->board->num, c->num, livr)); */
|
||||
|
||||
/* Clear RTS to stop receiver data flow while we are busy
|
||||
* processing the interrupt, thus avoiding underruns. */
|
||||
if (! c->sopt.norts) {
|
||||
outb (MSVR_RTS(port), 0);
|
||||
c->rts = 0;
|
||||
}
|
||||
|
||||
switch (livr & 3) {
|
||||
case LIV_EXCEP: /* receive exception */
|
||||
case LIV_RXDATA: /* receive interrupt */
|
||||
switch (c->mode) {
|
||||
case M_ASYNC: eoi = cxrinta (c); break;
|
||||
case M_HDLC: cxrinth (c); break;
|
||||
default:; /* No bisync and X.21 yet */
|
||||
}
|
||||
break;
|
||||
case LIV_TXDATA: /* transmit interrupt */
|
||||
eoiport = TEOIR(port);
|
||||
switch (c->mode) {
|
||||
case M_ASYNC: cxtinta (c); break;
|
||||
case M_HDLC: eoi = cxtinth (c); break;
|
||||
default:; /* No bisync and X.21 yet */
|
||||
}
|
||||
break;
|
||||
case LIV_MODEM: /* modem/timer interrupt */
|
||||
eoiport = MEOIR(port);
|
||||
cxmint (c);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Raise RTS for this channel if and only if
|
||||
* both receive buffers are empty. */
|
||||
if (! c->sopt.norts && (inb (CSR(port)) & CSRA_RXEN) &&
|
||||
(inb (ARBSTS(port)) & BSTS_OWN24) &&
|
||||
(inb (BRBSTS(port)) & BSTS_OWN24)) {
|
||||
outb (MSVR_RTS(port), MSV_RTS);
|
||||
c->rts = 1;
|
||||
}
|
||||
|
||||
/* Exit from interrupt context. */
|
||||
outb (eoiport, eoi);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the received packet.
|
||||
*/
|
||||
void cxinput (cx_chan_t *c, void *buf, unsigned len)
|
||||
{
|
||||
/* Make an mbuf. */
|
||||
struct mbuf *m = makembuf (buf, len);
|
||||
if (! m) {
|
||||
if (c->ifp->if_flags & IFF_DEBUG)
|
||||
printf ("cx%d.%d: no memory for packet\n",
|
||||
c->board->num, c->num);
|
||||
++c->ifp->if_iqdrops;
|
||||
return;
|
||||
}
|
||||
m->m_pkthdr.rcvif = c->ifp;
|
||||
#ifdef DEBUG
|
||||
printmbuf (m);
|
||||
#endif
|
||||
|
||||
#if NBPFILTER > 0
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface.
|
||||
* If so, hand off the raw packet to bpf.
|
||||
*/
|
||||
if (c->bpf)
|
||||
bpf_tap (c->bpf, buf, len);
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
if (c->sopt.ext) {
|
||||
struct p2pcom *p = (struct p2pcom*) c->ifp;
|
||||
(*p->p2p_input) (p, m);
|
||||
} else
|
||||
#endif
|
||||
sppp_input (c->ifp, m);
|
||||
}
|
||||
|
||||
void cxswitch (cx_chan_t *c, cx_soft_opt_t new)
|
||||
{
|
||||
#ifdef __bsdi__
|
||||
if (new.ext && ! c->sopt.ext) {
|
||||
/* Switch to external ppp implementation (BSDI) */
|
||||
sppp_detach (c->ifp);
|
||||
bzero ((void*) c->ifp + IFNETSZ, IFSTRUCTSZ-IFNETSZ);
|
||||
} else if (! new.ext && c->sopt.ext) {
|
||||
/* Switch to built-in ppp implementation */
|
||||
bzero ((void*) c->ifp + IFNETSZ, IFSTRUCTSZ-IFNETSZ);
|
||||
sppp_attach (c->ifp);
|
||||
}
|
||||
#else
|
||||
new.ext = 0;
|
||||
#endif
|
||||
if (! new.ext) {
|
||||
struct sppp *sp = (struct sppp*) c->ifp;
|
||||
|
||||
if (new.cisco)
|
||||
sp->pp_flags |= PP_CISCO;
|
||||
else
|
||||
sp->pp_flags &= ~PP_CISCO;
|
||||
if (new.keepalive)
|
||||
sp->pp_flags |= PP_KEEPALIVE;
|
||||
else
|
||||
sp->pp_flags &= ~PP_KEEPALIVE;
|
||||
}
|
||||
c->sopt = new;
|
||||
}
|
||||
#endif /* NCX */
|
70
sys/net/if_sppp.h
Normal file
70
sys/net/if_sppp.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Defines for synchronous PPP/Cisco link level subroutines.
|
||||
*
|
||||
* Copyright (C) 1994 Cronyx Ltd.
|
||||
* Author: Serge Vakulenko, <vak@zebub.msk.su>
|
||||
*
|
||||
* This software is distributed with NO WARRANTIES, not even the implied
|
||||
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Authors grant any other persons or organisations permission to use
|
||||
* or modify this software as long as this message is kept with the software,
|
||||
* all derivative works or modified versions.
|
||||
*
|
||||
* Version 1.1, Thu Oct 27 21:15:02 MSK 1994
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_HDLC_H_
|
||||
#define _NET_IF_HDLC_H_ 1
|
||||
|
||||
struct slcp {
|
||||
u_short state; /* state machine */
|
||||
u_long magic; /* local magic number */
|
||||
u_long rmagic; /* remote magic number */
|
||||
u_char lastid; /* id of last keepalive echo request */
|
||||
};
|
||||
|
||||
struct sipcp {
|
||||
u_short state; /* state machine */
|
||||
};
|
||||
|
||||
struct sppp {
|
||||
struct ifnet pp_if; /* network interface data */
|
||||
struct ifqueue pp_fastq; /* fast output queue */
|
||||
struct sppp *pp_next; /* next interface in keepalive list */
|
||||
u_int pp_flags; /* use Cisco protocol instead of PPP */
|
||||
u_short pp_alivecnt; /* keepalive packets counter */
|
||||
u_short pp_loopcnt; /* loopback detection counter */
|
||||
u_long pp_seq; /* local sequence number */
|
||||
u_long pp_rseq; /* remote sequence number */
|
||||
struct slcp lcp; /* LCP params */
|
||||
struct sipcp ipcp; /* IPCP params */
|
||||
};
|
||||
|
||||
#define PP_KEEPALIVE 0x01 /* use keepalive protocol */
|
||||
#define PP_CISCO 0x02 /* use Cisco protocol instead of PPP */
|
||||
|
||||
#define PP_MTU 1500 /* max. transmit unit */
|
||||
|
||||
#define LCP_STATE_CLOSED 0 /* LCP state: closed (conf-req sent) */
|
||||
#define LCP_STATE_ACK_RCVD 1 /* LCP state: conf-ack received */
|
||||
#define LCP_STATE_ACK_SENT 2 /* LCP state: conf-ack sent */
|
||||
#define LCP_STATE_OPENED 3 /* LCP state: opened */
|
||||
|
||||
#define IPCP_STATE_CLOSED 0 /* IPCP state: closed (conf-req sent) */
|
||||
#define IPCP_STATE_ACK_RCVD 1 /* IPCP state: conf-ack received */
|
||||
#define IPCP_STATE_ACK_SENT 2 /* IPCP state: conf-ack sent */
|
||||
#define IPCP_STATE_OPENED 3 /* IPCP state: opened */
|
||||
|
||||
#ifdef KERNEL
|
||||
void sppp_attach (struct ifnet *ifp);
|
||||
void sppp_detach (struct ifnet *ifp);
|
||||
void sppp_input (struct ifnet *ifp, struct mbuf *m);
|
||||
int sppp_output (struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
struct rtentry *rt);
|
||||
int sppp_ioctl (struct ifnet *ifp, int cmd, caddr_t data);
|
||||
struct mbuf *sppp_dequeue (struct ifnet *ifp);
|
||||
void sppp_flush (struct ifnet *ifp);
|
||||
#endif
|
||||
|
||||
#endif /* _NET_IF_HDLC_H_ */
|
1219
sys/net/if_spppsubr.c
Normal file
1219
sys/net/if_spppsubr.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user