Page MenuHomeFreeBSD

D25874.id75107.diff
No OneTemporary

D25874.id75107.diff

Index: share/man/man4/Makefile
===================================================================
--- share/man/man4/Makefile
+++ share/man/man4/Makefile
@@ -121,7 +121,6 @@
cxgb.4 \
cxgbe.4 \
cxgbev.4 \
- cy.4 \
cyapa.4 \
da.4 \
dc.4 \
@@ -434,7 +433,6 @@
${_qlnxe.4} \
ral.4 \
random.4 \
- rc.4 \
rctl.4 \
re.4 \
rgephy.4 \
@@ -442,7 +440,6 @@
rl.4 \
rndtest.4 \
route.4 \
- rp.4 \
rtwn.4 \
rtwnfw.4 \
rtwn_pci.4 \
Index: share/man/man4/cy.4
===================================================================
--- share/man/man4/cy.4
+++ /dev/null
@@ -1,257 +0,0 @@
-.\" Copyright (c) 1990, 1991 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" This code is derived from software contributed to Berkeley by
-.\" the Systems Programming Group of the University of Utah Computer
-.\" Science Department.
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" from: @(#)dca.4 5.2 (Berkeley) 3/27/91
-.\" from: com.4,v 1.1 1993/08/06 11:19:07 cgd Exp
-.\" from: sio.4,v 1.16 1995/06/26 06:05:30 bde Exp $
-.\" $FreeBSD$
-.\"
-.Dd May 24, 2004
-.Dt CY 4
-.Os
-.Sh NAME
-.Nm cy
-.Nd Cyclades Cyclom-Y serial driver
-.Sh SYNOPSIS
-For one ISA card:
-.Bd -ragged -offset indent -compact
-.Cd "device cy"
-.Pp
-In
-.Pa /boot/device.hints :
-.Cd hint.cy.0.at="isa"
-.Cd hint.cy.0.irq="10"
-.Cd hint.cy.0.maddr="0xd4000"
-.Cd hint.cy.0.msize="0x2000"
-.Ed
-.Pp
-For two ISA cards:
-.Bd -ragged -offset indent -compact
-.Cd "device cy"
-.Pp
-In
-.Pa /boot/device.hints :
-.Cd hint.cy.0.at="isa"
-.Cd hint.cy.0.irq="10"
-.Cd hint.cy.0.maddr="0xd4000"
-.Cd hint.cy.0.msize="0x2000"
-.Cd hint.cy.1.at="isa"
-.Cd hint.cy.1.irq="11"
-.Cd hint.cy.1.maddr="0xd6000"
-.Cd hint.cy.1.msize="0x2000"
-.Ed
-.Pp
-For PCI cards:
-.Bd -ragged -offset indent -compact
-.Cd "device cy"
-.Cd "options CY_PCI_FASTINTR"
-.Pp
-No lines are required in
-.Pa /boot/device.hints
-for PCI cards.
-.Ed
-.Pp
-Minor numbering:
-.Bd -literal -offset indent -compact
-0b\fIMMMMMMMMMMMMMMMMxxxxxxxxOLIMMMMM\fR
- call\fBO\fRut
- \fBL\fRock
- \fBI\fRnitial
- \fBMMMMMMMMMMMMMMMM MMMMMM\fRinor
-.Ed
-.Sh DESCRIPTION
-The
-.Nm
-driver provides support for Cirrus Logic CD1400-based
-.Tn EIA
-.Tn RS-232C
-.Pf ( Tn CCITT
-.Tn V.24 )
-communications interfaces (ports) on Cyclades Cyclom-Y boards.
-Each CD1400 provides 4 ports.
-Cyclom-Y boards with various numbers of CD1400's are available.
-This driver supports up to 8 CD1400's (32 ports) per board.
-.Pp
-Input and output for each line may set independently
-to the following speeds:
-50, 75, 110, 134.5, 150, 300, 600, 1200, 1800, 2400, 4800, 9600,
-19200, 38400, 57600, or 115200 bps.
-Other speeds of up to 150000 are supported by the termios interface
-but not by the sgttyb compatibility interface.
-The CD1400 is not fast enough to handle speeds above 115200 bps
-effectively.
-It can transmit on a single line at slightly more than 115200 bps,
-but when 4 lines are active in both directions its limit is about
-90000 bps on each line.
-.\" XXX the following should be true for all serial drivers and
-.\" should not be repeated in the man pages for all serial drivers.
-.\" It was copied from sio.4. The only change was s/sio/cy/g.
-.Pp
-Serial ports controlled by the
-.Nm
-driver can be used for both `callin' and `callout'.
-For each port there is a callin device and a callout device.
-The minor number of the callout device is 128 higher
-than that of the corresponding callin port.
-The callin device is general purpose.
-Processes opening it normally wait for carrier
-and for the callout device to become inactive.
-The callout device is used to steal the port from
-processes waiting for carrier on the callin device.
-Processes opening it do not wait for carrier
-and put any processes waiting for carrier on the callin device into
-a deeper sleep so that they do not conflict with the callout session.
-The callout device is abused for handling programs that are supposed
-to work on general ports and need to open the port without waiting
-but are too stupid to do so.
-.Pp
-The
-.Nm
-driver also supports an initial-state and a lock-state control
-device for each of the callin and the callout "data" devices.
-The minor number of the initial-state device is 32 higher
-than that of the corresponding data device.
-The minor number of the lock-state device is 64 higher
-than that of the corresponding data device.
-The termios settings of a data device are copied
-from those of the corresponding initial-state device
-on first opens and are not inherited from previous opens.
-Use
-.Xr stty 1
-in the normal way on the initial-state devices to program
-initial termios states suitable for your setup.
-.Pp
-The lock termios state acts as flags to disable changing
-the termios state.
-E.g., to lock a flag variable such as
-CRTSCTS, use
-.Em "stty crtscts"
-on the lock-state device.
-Speeds and special characters
-may be locked by setting the corresponding value in the lock-state
-device to any nonzero value.
-.Pp
-Correct programs talking to correctly wired external devices
-work with almost arbitrary initial states and almost no locking,
-but other setups may benefit from changing some of the default
-initial state and locking the state.
-In particular, the initial states for non (POSIX) standard flags
-should be set to suit the devices attached and may need to be
-locked to prevent buggy programs from changing them.
-E.g., CRTSCTS should be locked on for devices that support
-RTS/CTS handshaking at all times and off for devices that do not
-support it at all.
-CLOCAL should be locked on for devices
-that do not support carrier.
-HUPCL may be locked off if you do not
-want to hang up for some reason.
-In general, very bad things happen
-if something is locked to the wrong state, and things should not
-be locked for devices that support more than one setting.
-The
-CLOCAL flag on callin ports should be locked off for logins
-to avoid certain security holes, but this needs to be done by
-getty if the callin port is used for anything else.
-.Ss Kernel Configuration Options
-The
-.Em CY_PCI_FASTINTR
-option should be used to avoid suboptimal interrupt handling for
-PCI Cyclades boards.
-The PCI BIOS must be configured with the
-.Nm
-interrupt not shared with any other active device
-for this option to work.
-This option is not the default because it is currently harmful in
-certain cases where it does not work.
-.Sh FILES
-.\" XXX more cloning: s/d/c/g and add a ? for the card number.
-.Bl -tag -width /dev/ttyic?? -compact
-.It Pa /dev/ttyc??
-for callin ports
-.It Pa /dev/ttyic??
-.It Pa /dev/ttylc??
-corresponding callin initial-state and lock-state devices
-.Pp
-.\" XXX more cloning: s/a/c/g. No consistency :-(.
-.It Pa /dev/cuac??
-for callout ports
-.It Pa /dev/cuaic??
-.It Pa /dev/cualc??
-corresponding callout initial-state and lock-state devices
-.El
-.Pp
-.Bl -tag -width /etc/rc.serial -compact
-.It Pa /etc/rc.serial
-examples of setting the initial-state and lock-state devices
-.El
-.Pp
-The first question mark in these device names is short for the
-card number
-(a decimal number between 0 and 65535 inclusive).
-The second question mark is short for the port number
-(a letter in the range [0-9a-v]).
-.Sh DIAGNOSTICS
-.Bl -diag
-.\" XXX back to s/sio/cy/g.
-.It cy%d: silo overflow.
-Problem in the interrupt handler.
-.El
-.Bl -diag
-.It cy%d: interrupt-level buffer overflow.
-Problem in the bottom half of the driver.
-.El
-.Bl -diag
-.It cy%d: tty-level buffer overflow.
-Problem in the application.
-Input has arrived faster than the given module could process it
-and some has been lost.
-.El
-.\" .Bl -diag
-.\" .It sio%d: reduced fifo trigger level to %d.
-.\" Attempting to avoid further silo overflows.
-.\" .El
-.Sh SEE ALSO
-.Xr stty 1 ,
-.Xr termios 4 ,
-.Xr tty 4 ,
-.Xr comcontrol 8 ,
-.Xr pstat 8
-.Sh HISTORY
-The
-.Nm
-driver is derived from the
-.Nm sio
-driver and the
-.Nx
-.Nm
-driver and is
-.Ud
-.Sh BUGS
-Serial consoles are not implemented.
Index: share/man/man4/rc.4
===================================================================
--- share/man/man4/rc.4
+++ /dev/null
@@ -1,124 +0,0 @@
-.\"
-.\" Copyright (c) 2004 Tom Rhodes
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd March 18, 2005
-.Dt RC 4
-.Os
-.Sh NAME
-.Nm rc
-.Nd RISCom/8 multiport card
-.Sh SYNOPSIS
-.Cd device isa
-.Cd device rc
-.Sh DESCRIPTION
-The
-.Tn RISCom/8
-is an eight port
-.Tn ISA
-.Tn RS-232C
-communications multiplexer with a built in
-.Tn RISC
-processor.
-It uses a block of sixteen
-.Tn I/O
-ports in the range 0x200 to 0x3f0 selectable by on-board
-switches or jumpers.
-The block must be aligned on a sixteen port boundary.
-The jumper-selectable hardware interrupt level may be set to
-be detected during system
-initialization using settings found in the
-.Pa /boot/device.hints
-file.
-.Pp
-This driver is mostly based on the Cirrus Logic CL-CD180 driver.
-.Sh HARDWARE
-The
-.Nm
-driver provides support for the
-.Tn SDL
-Communications
-.Tn RISCom/8
-boards.
-.Sh DIAGNOSTICS
-The following driver specific error messages
-may be reported:
-.Bl -diag
-.It "rc%d channel%d: interrupt-level buffer overflow"
-An internal buffer overflow error has occurred on
-the listed channel.
-The
-.Nm
-driver will need to be reloaded to correct this.
-.It "rc%d: Bad char chan %d"
-The channel has obtained a bad set of characters.
-.It "rc%d: Got extra chars chan %d"
-The
-.Nm
-driver got more characters than expected on the channel shown.
-.It "rc%d: data mismatch chan %d ptr %d (%d != %d)"
-Data sent from channel
-.Ar %d
-to the rx buffer was different then expected.
-.It "rc%d: channel %d command timeout, rc.c line: %d"
-A command timeout has occurred on the channel, the
-.Pa src/sys/dev/rc/rc.c
-file can be consulted for more information.
-.El
-.Sh SEE ALSO
-.Xr tty 1 ,
-.Xr ttyname 3 ,
-.Xr tty 4 ,
-.Xr device.hints 5 ,
-.Xr comcontrol 8 ,
-.Xr getty 8 ,
-.Xr mutex 9 ,
-.Xr splx 9
-.Pp
-.Pa http://www.sdlcomm.com
-.Sh HISTORY
-The
-.Nm
-driver first appeared in
-.Fx 2.0.5 .
-This manual page first appeared in
-.Fx 5.3 .
-.Sh AUTHORS
-This manual page was written by
-.An Tom Rhodes Aq Mt trhodes@FreeBSD.org .
-.Sh BUGS
-The
-.Nm
-driver code still uses the
-.Xr spl 9
-functions.
-These should be replaced by
-.Xr mutex 9
-functions.
-.Pp
-The various
-.Fn ttyld_*
-functions should be documented.
Index: share/man/man4/rp.4
===================================================================
--- share/man/man4/rp.4
+++ /dev/null
@@ -1,195 +0,0 @@
-.\" Copyright (c) 1995 Comtrol, Inc.
-.\" All rights reserved.
-.\"
-.\" $FreeBSD$
-.Dd November 15, 1995
-.Dt RP 4
-.Os
-.Sh NAME
-.Nm rp
-.Nd "driver for Comtrol RocketPort Intelligent Serial Port Cards"
-.Sh SYNOPSIS
-.Cd "device rp"
-.Pp
-For ISA cards, you must specify the port address in
-.Pa /boot/device.hints :
-.Cd hint.rp.0.at="isa"
-.Cd hint.rp.0.port="0x100"
-.Sh DESCRIPTION
-This driver provides a kernel device driver for the
-.Tn RocketPort
-and
-.Tn RocketPort RA
-serial boards.
-These boards provide 8, 16, or 32 high-speed serial ports
-while requiring only 68 bytes of I/O space for all 8, 16,
-or 32 ports, and do not require an interrupt channel.
-This driver supports up to four
-.Tn RocketPort
-or
-.Tn RocketPort RA
-boards in one machine simultaneously.
-If you are using four 32 port
-.Tn RocketPort
-boards, you can put as many as 128 intelligent serial ports
-on your system.
-.Pp
-The
-.Nm
-driver supports the following speeds: 50, 75, 110, 134, 150,
-200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 7200,
-14400, 57600, 76800, 115200, and 230400.
-(You must use
-.Xr termios 4 ,
-rather than the old style ioctl interface to use non-traditional
-speeds.)
-.Pp
-An open on the
-.Nm
-driver will block until carrier is present, unless
-.Dv O_NONBLOCK
-or
-.Dv CLOCAL
-is set.
-.Sh HARDWARE CONFIGURATION
-The first
-.Tn RocketPort
-or
-.Tn RocketPort RA
-card requires a 68-byte contiguous block of I/O addresses,
-starting at one of the following:
-0x100h, 0x140h, 0x180h, 0x200h, 0x240h, 0x280h, 0x300h, 0x340h,
-0x380h.
-The second, third, and fourth
-.Tn RocketPort
-cards require only a
-64-byte contiguous block of I/O addresses, starting at one of the
-above address ranges.
-The I/O address range used by any of the
-.Tn RocketPort
-cards must not conflict with any other cards in the system,
-including other
-.Tn RocketPort
-cards.
-The starting range of the I/O ports used by each card
-must match with the I/O address specified in
-.Pa /boot/device.hints .
-.Pp
-Since the first
-.Tn RocketPort
-uses 68 I/O addresses, if the first card is
-set to use an I/O block starting at 0x100,
-it will occupy the I/O ports between 0x100 and 0x143.
-This means that the second, third, or fourth
-.Tn RocketPort
-board may not use the block of addresses starting at 0x140,
-since the first three I/O addresses of that range
-are used by the first board.
-This is an important point to keep in mind.
-.Pp
-If you have two ISA cards, one installed at 0x100 and the
-second installed at 0x180, then you should add the following to
-.Pa /boot/device.hints :
-.Pp
-.Dl hint.rp.0.at="isa"
-.Dl hint.rp.0.port="0x100"
-.Dl hint.rp.1.at="isa"
-.Dl hint.rp.1.port="0x180"
-.Pp
-The configuration of the
-.Tn RocketPort
-cards is done via the set of 8 DIP switches,
-labeled SW1 on the
-.Tn RocketPort
-card:
-.Bd -literal -offset indent
-+-------------------------------+
-| 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
-+-------+-------+---------------+
-| Unused| Card | I/O Port Block|
-+-------------------------------+
-.Ed
-.Pp
-DIP switches 7 and 8 are unused, and must be left on.
-.Pp
-DIP switches 6 and 5 identify the card number of each
-.Tn RocketPort
-card.
-The first card installed in the system must have its DIP switches set
-as card number one; the second card installed in the system must have
-its DIP switches set as card number two; and so on.
-As shipped from
-the factory, DIP switches 6 and 5 are both on by default, indicating
-that this is the first card installed on the system:
-.Bd -literal -offset indent
-DIP Switches
-6 5
-===================
-On On First Card
-On Off Second Card
-Off On Third Card
-Off Off Fourth Card
-.Ed
-.Pp
-DIP switches 4, 3, 2, and 1 indicate the I/O address range used by the
-first
-.Tn RocketPort
-card.
-If there are more than one
-.Tn RocketPort
-cards installed in a system,
-the second, third and fourth
-.Tn RocketPort
-cards must
-also be set to the I/O address range used by the first
-.Tn RocketPort
-card;
-all cards must have these DIP switches set identically
-for proper operation.
-As shipped from the factory, DIP switch 4 is on,
-and switches 3, 2, and 1 are off by default,
-indicating an I/O address range used by the first
-card which starts at 0x180 and extends to 0x1C3.
-.Bd -literal -offset indent
-DIP Switches I/O Address Range
-4 3 2 1 Used by the First Card
-=====================================
-On Off On Off 100-143
-On Off Off On 140-183
-On Off Off Off 180-1C3
-Off On On Off 200-243
-Off On Off On 240-283
-Off On Off Off 280-2C3
-Off Off On Off 300-343
-Off Off Off On 340-383
-Off Off Off Off 380-3C3
-.Ed
-.Sh FILES
-.Bl -tag -width ".Pa /dev/ttyR[0-4][0-9a-f]"
-.It Pa /dev/ttyR[0-4][0-9a-f]
-.El
-.Sh AUTHORS
-.An Theodore Ts'o Aq Mt tytso@mit.edu
-.Pp
-This driver was written under contract for Comtrol Corporation.
-For dealer, distributor and other information regarding Comtrol
-.Tn RocketPort ,
-contact Comtrol Corporation at (800) 926-6876 or send email to
-.Aq Mt info@comtrol.com .
-To report bugs for this driver, please send email to
-.Aq Mt bug-bsdi-rocketport@comtrol.com .
-.Sh BUGS
-If incoming software flow control is enabled on a 486 or Pentium
-machine, and the flow control is very heavily exercised, on rare occasions
-a character will get dropped.
-This problem does not occur on a 386, and
-it is not currently known whether the bug is in the
-.Nm
-driver
-or in the
-.Bsx
-tty layer.
-.\" (Although my bet is that it's in the higher-level tty layer;
-.\" given the bugs I found while writing this driver, it's clear
-.\" the BSD software flow control code has not been tested very much
-.\" at all! -- TYT)
Index: sys/dev/cy/cy.c
===================================================================
--- sys/dev/cy/cy.c
+++ sys/dev/cy/cy.c
@@ -1,2242 +0,0 @@
-/*-
- * cyclades cyclom-y serial driver
- * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1993 Andrew Herbert.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name Andrew Herbert may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * TODO:
- * Atomic COR change.
- * Consoles.
- */
-
-/*
- * Temporary compile-time configuration options.
- */
-#define RxFifoThreshold (CD1400_RX_FIFO_SIZE / 2)
- /* Number of chars in the receiver FIFO before an
- * an interrupt is generated. Should depend on
- * line speed. Needs to be about 6 on a 486DX33
- * for 4 active ports at 115200 bps. Why doesn't
- * 10 work?
- */
-#define PollMode /* Use polling-based irq service routine, not the
- * hardware svcack lines. Must be defined for
- * Cyclom-16Y boards. Less efficient for Cyclom-8Ys,
- * and stops 4 * 115200 bps from working.
- */
-#undef Smarts /* Enable slightly more CD1400 intelligence. Mainly
- * the output CR/LF processing, plus we can avoid a
- * few checks usually done in ttyinput().
- *
- * XXX not fully implemented, and not particularly
- * worthwhile.
- */
-#undef CyDebug /* Include debugging code (not very expensive). */
-
-/* These will go away. */
-#undef SOFT_CTS_OFLOW
-#define SOFT_HOTCHAR
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/interrupt.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/serial.h>
-#include <sys/syslog.h>
-#include <sys/tty.h>
-
-#include <machine/psl.h>
-
-#include <dev/ic/cd1400.h>
-
-#include <dev/cy/cyreg.h>
-#include <dev/cy/cyvar.h>
-
-#define NCY 10 /* KLUDGE */
-
-#define NPORTS (NCY * CY_MAX_PORTS)
-
-#define CY_MAX_PORTS (CD1400_NO_OF_CHANNELS * CY_MAX_CD1400s)
-
-/* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */
-#define CD1400_xIVR_CHAN_SHIFT 3
-#define CD1400_xIVR_CHAN 0x1F
-
-/*
- * ETC states. com->etc may also contain a hardware ETC command value,
- * meaning that execution of that command is pending.
- */
-#define ETC_NONE 0 /* we depend on bzero() setting this */
-#define ETC_BREAK_STARTING 1
-#define ETC_BREAK_STARTED 2
-#define ETC_BREAK_ENDING 3
-#define ETC_BREAK_ENDED 4
-
-#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
-
-/*
- * com state bits.
- * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher
- * than the other bits so that they can be tested as a group without masking
- * off the low bits.
- *
- * The following com and tty flags correspond closely:
- * CS_BUSY = TS_BUSY (maintained by cystart(), cypoll() and
- * comstop())
- * CS_TTGO = ~TS_TTSTOP (maintained by cyparam() and cystart())
- * CS_CTS_OFLOW = CCTS_OFLOW (maintained by cyparam())
- * CS_RTS_IFLOW = CRTS_IFLOW (maintained by cyparam())
- * TS_FLUSH is not used.
- * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON.
- * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state).
- */
-#define CS_BUSY 0x80 /* output in progress */
-#define CS_TTGO 0x40 /* output not stopped by XOFF */
-#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
-#define CS_CHECKMSR 1 /* check of MSR scheduled */
-#define CS_CTS_OFLOW 2 /* use CTS output flow control */
-#define CS_ODONE 4 /* output completed */
-#define CS_RTS_IFLOW 8 /* use RTS input flow control */
-#define CSE_ODONE 1 /* output transmitted */
-
-static char const * const error_desc[] = {
-#define CE_OVERRUN 0
- "silo overflow",
-#define CE_INTERRUPT_BUF_OVERFLOW 1
- "interrupt-level buffer overflow",
-#define CE_TTY_BUF_OVERFLOW 2
- "tty-level buffer overflow",
-};
-
-#define CE_NTYPES 3
-#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
-
-#ifdef SMP
-#define COM_LOCK() mtx_lock_spin(&cy_lock)
-#define COM_UNLOCK() mtx_unlock_spin(&cy_lock)
-#else
-#define COM_LOCK()
-#define COM_UNLOCK()
-#endif
-
-/* types. XXX - should be elsewhere */
-typedef u_char bool_t; /* boolean */
-
-/* queue of linear buffers */
-struct lbq {
- u_char *l_head; /* next char to process */
- u_char *l_tail; /* one past the last char to process */
- struct lbq *l_next; /* next in queue */
- bool_t l_queued; /* nonzero if queued */
-};
-
-/* com device structure */
-struct com_s {
- u_char state; /* miscellaneous flag bits */
- u_char etc; /* pending Embedded Transmit Command */
- u_char extra_state; /* more flag bits, separate for order trick */
- u_char gfrcr_image; /* copy of value read from GFRCR */
- u_char mcr_dtr; /* MCR bit that is wired to DTR */
- u_char mcr_image; /* copy of value written to MCR */
- u_char mcr_rts; /* MCR bit that is wired to RTS */
- int unit; /* unit number */
-
- /*
- * The high level of the driver never reads status registers directly
- * because there would be too many side effects to handle conveniently.
- * Instead, it reads copies of the registers stored here by the
- * interrupt handler.
- */
- u_char last_modem_status; /* last MSR read by intr handler */
- u_char prev_modem_status; /* last MSR handled by high level */
-
- u_char *ibuf; /* start of input buffer */
- u_char *ibufend; /* end of input buffer */
- u_char *ibufold; /* old input buffer, to be freed */
- u_char *ihighwater; /* threshold in input buffer */
- u_char *iptr; /* next free spot in input buffer */
- int ibufsize; /* size of ibuf (not include error bytes) */
- int ierroff; /* offset of error bytes in ibuf */
-
- struct lbq obufq; /* head of queue of output buffers */
- struct lbq obufs[2]; /* output buffers */
-
- int cy_align; /* index for register alignment */
- cy_addr cy_iobase; /* base address of this port's cyclom */
- cy_addr iobase; /* base address of this port's cd1400 */
- int mcr_rts_reg; /* cd1400 reg number of reg holding mcr_rts */
-
- struct tty *tp; /* cross reference */
-
- u_long bytes_in; /* statistics */
- u_long bytes_out;
- u_int delta_error_counts[CE_NTYPES];
- u_long error_counts[CE_NTYPES];
-
- u_int recv_exception; /* exception chars received */
- u_int mdm; /* modem signal changes */
-#ifdef CyDebug
- u_int start_count; /* no. of calls to cystart() */
- u_int start_real; /* no. of calls that did something */
-#endif
- u_char car; /* CD1400 CAR shadow (if first unit in cd) */
- u_char channel_control;/* CD1400 CCR control command shadow */
- u_char cor[3]; /* CD1400 COR1-3 shadows */
- u_char intr_enable; /* CD1400 SRER shadow */
-
- /*
- * Data area for output buffers. Someday we should build the output
- * buffer queue without copying data.
- */
- u_char obuf1[256];
- u_char obuf2[256];
-};
-
-devclass_t cy_devclass;
-char cy_driver_name[] = "cy";
-
-static void cd1400_channel_cmd(struct com_s *com, int cmd);
-static void cd1400_channel_cmd_wait(struct com_s *com);
-static void cd_etc(struct com_s *com, int etc);
-static int cd_getreg(struct com_s *com, int reg);
-static void cd_setreg(struct com_s *com, int reg, int val);
-static void cyinput(struct com_s *com);
-static int cyparam(struct tty *tp, struct termios *t);
-static void cypoll(void *arg);
-static void cysettimeout(void);
-static int cysetwater(struct com_s *com, speed_t speed);
-static int cyspeed(speed_t speed, u_long cy_clock, int *prescaler_io);
-static void cystart(struct tty *tp);
-static void comstop(struct tty *tp, int rw);
-static timeout_t cywakeup;
-static void disc_optim(struct tty *tp, struct termios *t,
- struct com_s *com);
-
-static t_break_t cybreak;
-static t_modem_t cymodem;
-static t_open_t cyopen;
-static t_close_t cyclose;
-
-#ifdef CyDebug
-void cystatus(int unit);
-#endif
-
-static struct mtx cy_lock;
-static int cy_inited;
-
-/* table and macro for fast conversion from a unit number to its com struct */
-static struct com_s *p_cy_addr[NPORTS];
-#define cy_addr(unit) (p_cy_addr[unit])
-
-static u_int cy_events; /* input chars + weighted output completions */
-static void *cy_fast_ih;
-static void *cy_slow_ih;
-static int cy_timeout;
-static int cy_timeouts_until_log;
-static struct callout_handle cy_timeout_handle
- = CALLOUT_HANDLE_INITIALIZER(&cy_timeout_handle);
-
-#ifdef CyDebug
-static u_int cd_inbs;
-static u_int cy_inbs;
-static u_int cd_outbs;
-static u_int cy_outbs;
-static u_int cy_svrr_probes;
-static u_int cy_timeouts;
-#endif
-
-static int cy_chip_offset[] = {
- 0x0000, 0x0400, 0x0800, 0x0c00, 0x0200, 0x0600, 0x0a00, 0x0e00,
-};
-static int cy_nr_cd1400s[NCY];
-static int cy_total_devices;
-#undef RxFifoThreshold
-static int volatile RxFifoThreshold = (CD1400_RX_FIFO_SIZE / 2);
-
-int
-cy_units(cy_addr cy_iobase, int cy_align)
-{
- int cyu;
- u_char firmware_version;
- int i;
- cy_addr iobase;
-
- for (cyu = 0; cyu < CY_MAX_CD1400s; ++cyu) {
- iobase = cy_iobase + (cy_chip_offset[cyu] << cy_align);
-
- /* wait for chip to become ready for new command */
- for (i = 0; i < 10; i++) {
- DELAY(50);
- if (!cd_inb(iobase, CD1400_CCR, cy_align))
- break;
- }
-
- /* clear the GFRCR register */
- cd_outb(iobase, CD1400_GFRCR, cy_align, 0);
-
- /* issue a reset command */
- cd_outb(iobase, CD1400_CCR, cy_align,
- CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
-
- /* XXX bogus initialization to avoid a gcc bug/warning. */
- firmware_version = 0;
-
- /* wait for the CD1400 to initialize itself */
- for (i = 0; i < 200; i++) {
- DELAY(50);
-
- /* retrieve firmware version */
- firmware_version = cd_inb(iobase, CD1400_GFRCR,
- cy_align);
- if ((firmware_version & 0xf0) == 0x40)
- break;
- }
-
- /*
- * Anything in the 0x40-0x4F range is fine.
- * If one CD1400 is bad then we don't support higher
- * numbered good ones on this board.
- */
- if ((firmware_version & 0xf0) != 0x40)
- break;
- }
- return (cyu);
-}
-
-void *
-cyattach_common(cy_addr cy_iobase, int cy_align)
-{
- int adapter;
- int cyu;
- u_char firmware_version;
- cy_addr iobase;
- int ncyu;
- int unit;
- struct tty *tp;
-
- while (cy_inited != 2)
- if (atomic_cmpset_int(&cy_inited, 0, 1)) {
- mtx_init(&cy_lock, cy_driver_name, NULL, MTX_SPIN);
- atomic_store_rel_int(&cy_inited, 2);
- }
-
- adapter = cy_total_devices;
- if ((u_int)adapter >= NCY) {
- printf(
- "cy%d: can't attach adapter: insufficient cy devices configured\n",
- adapter);
- return (NULL);
- }
- ncyu = cy_units(cy_iobase, cy_align);
- if (ncyu == 0)
- return (NULL);
- cy_nr_cd1400s[adapter] = ncyu;
- cy_total_devices++;
-
- unit = adapter * CY_MAX_PORTS;
- for (cyu = 0; cyu < ncyu; ++cyu) {
- int cdu;
-
- iobase = (cy_addr) (cy_iobase
- + (cy_chip_offset[cyu] << cy_align));
- firmware_version = cd_inb(iobase, CD1400_GFRCR, cy_align);
-
- /* Set up a receive timeout period of than 1+ ms. */
- cd_outb(iobase, CD1400_PPR, cy_align,
- howmany(CY_CLOCK(firmware_version)
- / CD1400_PPR_PRESCALER, 1000));
-
- for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) {
- struct com_s *com;
- int s;
-
- com = malloc(sizeof *com, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (com == NULL)
- break;
- com->unit = unit;
- com->gfrcr_image = firmware_version;
- if (CY_RTS_DTR_SWAPPED(firmware_version)) {
- com->mcr_dtr = CD1400_MSVR1_RTS;
- com->mcr_rts = CD1400_MSVR2_DTR;
- com->mcr_rts_reg = CD1400_MSVR2;
- } else {
- com->mcr_dtr = CD1400_MSVR2_DTR;
- com->mcr_rts = CD1400_MSVR1_RTS;
- com->mcr_rts_reg = CD1400_MSVR1;
- }
- com->obufs[0].l_head = com->obuf1;
- com->obufs[1].l_head = com->obuf2;
-
- com->cy_align = cy_align;
- com->cy_iobase = cy_iobase;
- com->iobase = iobase;
- com->car = ~CD1400_CAR_CHAN;
-
- tp = com->tp = ttyalloc();
- tp->t_open = cyopen;
- tp->t_close = cyclose;
- tp->t_oproc = cystart;
- tp->t_stop = comstop;
- tp->t_param = cyparam;
- tp->t_break = cybreak;
- tp->t_modem = cymodem;
- tp->t_sc = com;
-
- if (cysetwater(com, tp->t_init_in.c_ispeed) != 0) {
- free(com, M_DEVBUF);
- return (NULL);
- }
-
- s = spltty();
- cy_addr(unit) = com;
- splx(s);
-
- if (cy_fast_ih == NULL) {
- swi_add(&tty_intr_event, "cy", cypoll, NULL, SWI_TTY, 0,
- &cy_fast_ih);
- swi_add(&clk_intr_event, "cy", cypoll, NULL, SWI_CLOCK, 0,
- &cy_slow_ih);
- }
- ttycreate(tp, TS_CALLOUT, "c%r%r",
- adapter, unit % CY_MAX_PORTS);
- }
- }
-
- /* ensure an edge for the next interrupt */
- cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
-
- return (cy_addr(adapter * CY_MAX_PORTS));
-}
-
-static int
-cyopen(struct tty *tp, struct cdev *dev)
-{
- struct com_s *com;
- int s;
-
- com = tp->t_sc;
- s = spltty();
- /*
- * We jump to this label after all non-interrupted sleeps to pick
- * up any changes of the device state.
- */
-
- /* Encode per-board unit in LIVR for access in intr routines. */
- cd_setreg(com, CD1400_LIVR,
- (com->unit & CD1400_xIVR_CHAN) << CD1400_xIVR_CHAN_SHIFT);
-
- /*
- * Flush fifos. This requires a full channel reset which
- * also disables the transmitter and receiver. Recover
- * from this.
- */
- cd1400_channel_cmd(com,
- CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET);
- cd1400_channel_cmd(com, com->channel_control);
-
- critical_enter();
- COM_LOCK();
- com->prev_modem_status = com->last_modem_status
- = cd_getreg(com, CD1400_MSVR2);
- cd_setreg(com, CD1400_SRER,
- com->intr_enable
- = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
- COM_UNLOCK();
- critical_exit();
- cysettimeout();
- return (0);
-}
-
-
-static void
-cyclose(struct tty *tp)
-{
- cy_addr iobase;
- struct com_s *com;
- int s;
- int unit;
-
- com = tp->t_sc;
- unit = com->unit;
- iobase = com->iobase;
- s = spltty();
- /* XXX */
- critical_enter();
- COM_LOCK();
- com->etc = ETC_NONE;
- cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC);
- COM_UNLOCK();
- critical_exit();
- cd_etc(com, CD1400_ETC_STOPBREAK);
- cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
-
- {
- critical_enter();
- COM_LOCK();
- cd_setreg(com, CD1400_SRER, com->intr_enable = 0);
- COM_UNLOCK();
- critical_exit();
- tp = com->tp;
- if ((tp->t_cflag & HUPCL)
- /*
- * XXX we will miss any carrier drop between here and the
- * next open. Perhaps we should watch DCD even when the
- * port is closed; it is not sufficient to check it at
- * the next open because it might go up and down while
- * we're not watching.
- */
- || (!tp->t_actout
- && !(com->prev_modem_status & CD1400_MSVR2_CD)
- && !(tp->t_init_in.c_cflag & CLOCAL))
- || !(tp->t_state & TS_ISOPEN)) {
- (void)cymodem(tp, 0, SER_DTR);
-
- /* Disable receiver (leave transmitter enabled). */
- com->channel_control = CD1400_CCR_CMDCHANCTL
- | CD1400_CCR_XMTEN
- | CD1400_CCR_RCVDIS;
- cd1400_channel_cmd(com, com->channel_control);
-
- ttydtrwaitstart(tp);
- }
- }
- tp->t_actout = FALSE;
- wakeup(&tp->t_actout);
- wakeup(TSA_CARR_ON(tp)); /* restart any wopeners */
- splx(s);
-}
-
-/*
- * This function:
- * a) needs to be called with COM_LOCK() held, and
- * b) needs to return with COM_LOCK() held.
- */
-static void
-cyinput(struct com_s *com)
-{
- u_char *buf;
- int incc;
- u_char line_status;
- int recv_data;
- struct tty *tp;
-
- buf = com->ibuf;
- tp = com->tp;
- if (!(tp->t_state & TS_ISOPEN)) {
- cy_events -= (com->iptr - com->ibuf);
- com->iptr = com->ibuf;
- return;
- }
- if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
- /*
- * Avoid the grotesquely inefficient lineswitch routine
- * (ttyinput) in "raw" mode. It usually takes about 450
- * instructions (that's without canonical processing or echo!).
- * slinput is reasonably fast (usually 40 instructions plus
- * call overhead).
- */
-
- do {
- /*
- * This may look odd, but it is using save-and-enable
- * semantics instead of the save-and-disable semantics
- * that are used everywhere else.
- */
- COM_UNLOCK();
- critical_exit();
- incc = com->iptr - buf;
- if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
- && (com->state & CS_RTS_IFLOW
- || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK))
- ttyblock(tp);
- com->delta_error_counts[CE_TTY_BUF_OVERFLOW]
- += b_to_q((char *)buf, incc, &tp->t_rawq);
- buf += incc;
- tk_nin += incc;
- tk_rawcc += incc;
- tp->t_rawcc += incc;
- ttwakeup(tp);
- if (tp->t_state & TS_TTSTOP
- && (tp->t_iflag & IXANY
- || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
- tp->t_state &= ~TS_TTSTOP;
- tp->t_lflag &= ~FLUSHO;
- cystart(tp);
- }
- critical_enter();
- COM_LOCK();
- } while (buf < com->iptr);
- } else {
- do {
- /*
- * This may look odd, but it is using save-and-enable
- * semantics instead of the save-and-disable semantics
- * that are used everywhere else.
- */
- COM_UNLOCK();
- critical_exit();
- line_status = buf[com->ierroff];
- recv_data = *buf++;
- if (line_status
- & (CD1400_RDSR_BREAK | CD1400_RDSR_FE | CD1400_RDSR_OE | CD1400_RDSR_PE)) {
- if (line_status & CD1400_RDSR_BREAK)
- recv_data |= TTY_BI;
- if (line_status & CD1400_RDSR_FE)
- recv_data |= TTY_FE;
- if (line_status & CD1400_RDSR_OE)
- recv_data |= TTY_OE;
- if (line_status & CD1400_RDSR_PE)
- recv_data |= TTY_PE;
- }
- ttyld_rint(tp, recv_data);
- critical_enter();
- COM_LOCK();
- } while (buf < com->iptr);
- }
- cy_events -= (com->iptr - com->ibuf);
- com->iptr = com->ibuf;
-
- /*
- * There is now room for another low-level buffer full of input,
- * so enable RTS if it is now disabled and there is room in the
- * high-level buffer.
- */
- if ((com->state & CS_RTS_IFLOW) && !(com->mcr_image & com->mcr_rts) &&
- !(tp->t_state & TS_TBLOCK))
- cd_setreg(com, com->mcr_rts_reg,
- com->mcr_image |= com->mcr_rts);
-}
-
-int
-cyintr(void *vcom)
-{
- struct com_s *basecom;
- int baseu;
- int cy_align;
- cy_addr cy_iobase;
- int cyu;
- cy_addr iobase;
- u_char status;
- int unit;
-
- COM_LOCK(); /* XXX could this be placed down lower in the loop? */
-
- basecom = (struct com_s *)vcom;
- baseu = basecom->unit;
- cy_align = basecom->cy_align;
- cy_iobase = basecom->cy_iobase;
- unit = baseu / CY_MAX_PORTS;
-
- /* check each CD1400 in turn */
- for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
- iobase = (cy_addr) (cy_iobase
- + (cy_chip_offset[cyu] << cy_align));
- /* poll to see if it has any work */
- status = cd_inb(iobase, CD1400_SVRR, cy_align);
- if (status == 0)
- continue; // XXX - FILTER_STRAY?
-#ifdef CyDebug
- ++cy_svrr_probes;
-#endif
- /* service requests as appropriate, giving priority to RX */
- if (status & CD1400_SVRR_RXRDY) {
- struct com_s *com;
- u_int count;
- u_char *ioptr;
- u_char line_status;
- u_char recv_data;
- u_char serv_type;
-#ifdef PollMode
- u_char save_rir;
-#endif
-
-#ifdef PollMode
- save_rir = cd_inb(iobase, CD1400_RIR, cy_align);
-
- /* enter rx service */
- cd_outb(iobase, CD1400_CAR, cy_align, save_rir);
- cy_addr(baseu + cyu * CD1400_NO_OF_CHANNELS)->car
- = save_rir & CD1400_CAR_CHAN;
-
- serv_type = cd_inb(iobase, CD1400_RIVR, cy_align);
- com = cy_addr(baseu
- + ((serv_type >> CD1400_xIVR_CHAN_SHIFT)
- & CD1400_xIVR_CHAN));
-#else
- /* ack receive service */
- serv_type = cy_inb(iobase, CY8_SVCACKR, cy_align);
-
- com = cy_addr(baseu +
- + ((serv_type >> CD1400_xIVR_CHAN_SHIFT)
- & CD1400_xIVR_CHAN));
-#endif
-
- if (serv_type & CD1400_RIVR_EXCEPTION) {
- ++com->recv_exception;
- line_status = cd_inb(iobase, CD1400_RDSR, cy_align);
- /* break/unnattached error bits or real input? */
- recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
-#ifndef SOFT_HOTCHAR
- if (line_status & CD1400_RDSR_SPECIAL
- && com->tp->t_hotchar != 0)
- swi_sched(cy_fast_ih, 0);
-
-#endif
-#if 1 /* XXX "intelligent" PFO error handling would break O error handling */
- if (line_status & (CD1400_RDSR_PE|CD1400_RDSR_FE|CD1400_RDSR_BREAK)) {
- /*
- Don't store PE if IGNPAR and BI if IGNBRK,
- this hack allows "raw" tty optimization
- works even if IGN* is set.
- */
- if ( com->tp == NULL
- || !(com->tp->t_state & TS_ISOPEN)
- || ((line_status & (CD1400_RDSR_PE|CD1400_RDSR_FE))
- && (com->tp->t_iflag & IGNPAR))
- || ((line_status & CD1400_RDSR_BREAK)
- && (com->tp->t_iflag & IGNBRK)))
- goto cont;
- if ( (line_status & (CD1400_RDSR_PE|CD1400_RDSR_FE))
- && (com->tp->t_state & TS_CAN_BYPASS_L_RINT)
- && ((line_status & CD1400_RDSR_FE)
- || ((line_status & CD1400_RDSR_PE)
- && (com->tp->t_iflag & INPCK))))
- recv_data = 0;
- }
-#endif /* 1 */
- ++com->bytes_in;
-#ifdef SOFT_HOTCHAR
- if (com->tp->t_hotchar != 0 && recv_data == com->tp->t_hotchar)
- swi_sched(cy_fast_ih, 0);
-#endif
- ioptr = com->iptr;
- if (ioptr >= com->ibufend)
- CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
- else {
- if (com->tp != NULL && com->tp->t_do_timestamp)
- microtime(&com->tp->t_timestamp);
- ++cy_events;
- ioptr[0] = recv_data;
- ioptr[com->ierroff] = line_status;
- com->iptr = ++ioptr;
- if (ioptr == com->ihighwater
- && com->state & CS_RTS_IFLOW)
- cd_outb(iobase, com->mcr_rts_reg,
- cy_align,
- com->mcr_image &=
- ~com->mcr_rts);
- if (line_status & CD1400_RDSR_OE)
- CE_RECORD(com, CE_OVERRUN);
- }
- goto cont;
- } else {
- int ifree;
-
- count = cd_inb(iobase, CD1400_RDCR, cy_align);
- if (!count)
- goto cont;
- com->bytes_in += count;
- ioptr = com->iptr;
- ifree = com->ibufend - ioptr;
- if (count > ifree) {
- count -= ifree;
- cy_events += ifree;
- if (ifree != 0) {
- if (com->tp != NULL && com->tp->t_do_timestamp)
- microtime(&com->tp->t_timestamp);
- do {
- recv_data = cd_inb(iobase,
- CD1400_RDSR,
- cy_align);
-#ifdef SOFT_HOTCHAR
- if (com->tp->t_hotchar != 0
- && recv_data
- == com->tp->t_hotchar)
- swi_sched(cy_fast_ih,
- 0);
-#endif
- ioptr[0] = recv_data;
- ioptr[com->ierroff] = 0;
- ++ioptr;
- } while (--ifree != 0);
- }
- com->delta_error_counts
- [CE_INTERRUPT_BUF_OVERFLOW] += count;
- do {
- recv_data = cd_inb(iobase, CD1400_RDSR,
- cy_align);
-#ifdef SOFT_HOTCHAR
- if (com->tp->t_hotchar != 0
- && recv_data == com->tp->t_hotchar)
- swi_sched(cy_fast_ih, 0);
-#endif
- } while (--count != 0);
- } else {
- if (com->tp != NULL && com->tp->t_do_timestamp)
- microtime(&com->tp->t_timestamp);
- if (ioptr <= com->ihighwater
- && ioptr + count > com->ihighwater
- && com->state & CS_RTS_IFLOW)
- cd_outb(iobase, com->mcr_rts_reg,
- cy_align,
- com->mcr_image
- &= ~com->mcr_rts);
- cy_events += count;
- do {
- recv_data = cd_inb(iobase, CD1400_RDSR,
- cy_align);
-#ifdef SOFT_HOTCHAR
- if (com->tp->t_hotchar != 0
- && recv_data == com->tp->t_hotchar)
- swi_sched(cy_fast_ih, 0);
-#endif
- ioptr[0] = recv_data;
- ioptr[com->ierroff] = 0;
- ++ioptr;
- } while (--count != 0);
- }
- com->iptr = ioptr;
- }
-cont:
-
- /* terminate service context */
-#ifdef PollMode
- cd_outb(iobase, CD1400_RIR, cy_align,
- save_rir
- & ~(CD1400_RIR_RDIREQ | CD1400_RIR_RBUSY));
-#else
- cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
-#endif
- }
- if (status & CD1400_SVRR_MDMCH) {
- struct com_s *com;
- u_char modem_status;
-#ifdef PollMode
- u_char save_mir;
-#else
- u_char vector;
-#endif
-
-#ifdef PollMode
- save_mir = cd_inb(iobase, CD1400_MIR, cy_align);
-
- /* enter modem service */
- cd_outb(iobase, CD1400_CAR, cy_align, save_mir);
- cy_addr(baseu + cyu * CD1400_NO_OF_CHANNELS)->car
- = save_mir & CD1400_CAR_CHAN;
-
- com = cy_addr(baseu + cyu * CD1400_NO_OF_CHANNELS
- + (save_mir & CD1400_MIR_CHAN));
-#else
- /* ack modem service */
- vector = cy_inb(iobase, CY8_SVCACKM, cy_align);
-
- com = cy_addr(baseu
- + ((vector >> CD1400_xIVR_CHAN_SHIFT)
- & CD1400_xIVR_CHAN));
-#endif
- ++com->mdm;
- modem_status = cd_inb(iobase, CD1400_MSVR2, cy_align);
- if (modem_status != com->last_modem_status) {
- /*
- * Schedule high level to handle DCD changes. Note
- * that we don't use the delta bits anywhere. Some
- * UARTs mess them up, and it's easy to remember the
- * previous bits and calculate the delta.
- */
- com->last_modem_status = modem_status;
- if (!(com->state & CS_CHECKMSR)) {
- cy_events += LOTS_OF_EVENTS;
- com->state |= CS_CHECKMSR;
- swi_sched(cy_fast_ih, 0);
- }
-
-#ifdef SOFT_CTS_OFLOW
- /* handle CTS change immediately for crisp flow ctl */
- if (com->state & CS_CTS_OFLOW) {
- if (modem_status & CD1400_MSVR2_CTS) {
- com->state |= CS_ODEVREADY;
- if (com->state >= (CS_BUSY | CS_TTGO
- | CS_ODEVREADY)
- && !(com->intr_enable
- & CD1400_SRER_TXRDY))
- cd_outb(iobase, CD1400_SRER,
- cy_align,
- com->intr_enable
- = com->intr_enable
- & ~CD1400_SRER_TXMPTY
- | CD1400_SRER_TXRDY);
- } else {
- com->state &= ~CS_ODEVREADY;
- if (com->intr_enable
- & CD1400_SRER_TXRDY)
- cd_outb(iobase, CD1400_SRER,
- cy_align,
- com->intr_enable
- = com->intr_enable
- & ~CD1400_SRER_TXRDY
- | CD1400_SRER_TXMPTY);
- }
- }
-#endif
- }
-
- /* terminate service context */
-#ifdef PollMode
- cd_outb(iobase, CD1400_MIR, cy_align,
- save_mir
- & ~(CD1400_MIR_RDIREQ | CD1400_MIR_RBUSY));
-#else
- cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
-#endif
- }
- if (status & CD1400_SVRR_TXRDY) {
- struct com_s *com;
-#ifdef PollMode
- u_char save_tir;
-#else
- u_char vector;
-#endif
-
-#ifdef PollMode
- save_tir = cd_inb(iobase, CD1400_TIR, cy_align);
-
- /* enter tx service */
- cd_outb(iobase, CD1400_CAR, cy_align, save_tir);
- cy_addr(baseu + cyu * CD1400_NO_OF_CHANNELS)->car
- = save_tir & CD1400_CAR_CHAN;
-
- com = cy_addr(baseu
- + cyu * CD1400_NO_OF_CHANNELS
- + (save_tir & CD1400_TIR_CHAN));
-#else
- /* ack transmit service */
- vector = cy_inb(iobase, CY8_SVCACKT, cy_align);
-
- com = cy_addr(baseu
- + ((vector >> CD1400_xIVR_CHAN_SHIFT)
- & CD1400_xIVR_CHAN));
-#endif
-
- if (com->etc != ETC_NONE) {
- if (com->intr_enable & CD1400_SRER_TXRDY) {
- /*
- * Here due to sloppy SRER_TXRDY
- * enabling. Ignore. Come back when
- * tx is empty.
- */
- cd_outb(iobase, CD1400_SRER, cy_align,
- com->intr_enable
- = (com->intr_enable
- & ~CD1400_SRER_TXRDY)
- | CD1400_SRER_TXMPTY);
- goto terminate_tx_service;
- }
- switch (com->etc) {
- case CD1400_ETC_SENDBREAK:
- case CD1400_ETC_STOPBREAK:
- /*
- * Start the command. Come back on
- * next tx empty interrupt, hopefully
- * after command has been executed.
- */
- cd_outb(iobase, CD1400_COR2, cy_align,
- com->cor[1] |= CD1400_COR2_ETC);
- cd_outb(iobase, CD1400_TDR, cy_align,
- CD1400_ETC_CMD);
- cd_outb(iobase, CD1400_TDR, cy_align,
- com->etc);
- if (com->etc == CD1400_ETC_SENDBREAK)
- com->etc = ETC_BREAK_STARTING;
- else
- com->etc = ETC_BREAK_ENDING;
- goto terminate_tx_service;
- case ETC_BREAK_STARTING:
- /*
- * BREAK is now on. Continue with
- * SRER_TXMPTY processing, hopefully
- * don't come back.
- */
- com->etc = ETC_BREAK_STARTED;
- break;
- case ETC_BREAK_STARTED:
- /*
- * Came back due to sloppy SRER_TXMPTY
- * enabling. Hope again.
- */
- break;
- case ETC_BREAK_ENDING:
- /*
- * BREAK is now off. Continue with
- * SRER_TXMPTY processing and don't
- * come back. The SWI handler will
- * restart tx interrupts if necessary.
- */
- cd_outb(iobase, CD1400_COR2, cy_align,
- com->cor[1]
- &= ~CD1400_COR2_ETC);
- com->etc = ETC_BREAK_ENDED;
- if (!(com->state & CS_ODONE)) {
- cy_events += LOTS_OF_EVENTS;
- com->state |= CS_ODONE;
- swi_sched(cy_fast_ih, 0);
- }
- break;
- case ETC_BREAK_ENDED:
- /*
- * Shouldn't get here. Hope again.
- */
- break;
- }
- }
- if (com->intr_enable & CD1400_SRER_TXMPTY) {
- if (!(com->extra_state & CSE_ODONE)) {
- cy_events += LOTS_OF_EVENTS;
- com->extra_state |= CSE_ODONE;
- swi_sched(cy_fast_ih, 0);
- }
- cd_outb(iobase, CD1400_SRER, cy_align,
- com->intr_enable
- &= ~CD1400_SRER_TXMPTY);
- goto terminate_tx_service;
- }
- if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
- u_char *ioptr;
- u_int ocount;
-
- ioptr = com->obufq.l_head;
- ocount = com->obufq.l_tail - ioptr;
- if (ocount > CD1400_TX_FIFO_SIZE)
- ocount = CD1400_TX_FIFO_SIZE;
- com->bytes_out += ocount;
- do
- cd_outb(iobase, CD1400_TDR, cy_align,
- *ioptr++);
- while (--ocount != 0);
- com->obufq.l_head = ioptr;
- if (ioptr >= com->obufq.l_tail) {
- struct lbq *qp;
-
- qp = com->obufq.l_next;
- qp->l_queued = FALSE;
- qp = qp->l_next;
- if (qp != NULL) {
- com->obufq.l_head = qp->l_head;
- com->obufq.l_tail = qp->l_tail;
- com->obufq.l_next = qp;
- } else {
- /* output just completed */
- com->state &= ~CS_BUSY;
-
- /*
- * The setting of CSE_ODONE may be
- * stale here. We currently only
- * use it when CS_BUSY is set, and
- * fixing it when we clear CS_BUSY
- * is easiest.
- */
- if (com->extra_state & CSE_ODONE) {
- cy_events -= LOTS_OF_EVENTS;
- com->extra_state &= ~CSE_ODONE;
- }
-
- cd_outb(iobase, CD1400_SRER, cy_align,
- com->intr_enable
- = (com->intr_enable
- & ~CD1400_SRER_TXRDY)
- | CD1400_SRER_TXMPTY);
- }
- if (!(com->state & CS_ODONE)) {
- cy_events += LOTS_OF_EVENTS;
- com->state |= CS_ODONE;
-
- /* handle at high level ASAP */
- swi_sched(cy_fast_ih, 0);
- }
- }
- }
-
- /* terminate service context */
-terminate_tx_service:
-#ifdef PollMode
- cd_outb(iobase, CD1400_TIR, cy_align,
- save_tir
- & ~(CD1400_TIR_RDIREQ | CD1400_TIR_RBUSY));
-#else
- cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
-#endif
- }
- }
-
- /* ensure an edge for the next interrupt */
- cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
-
- swi_sched(cy_slow_ih, SWI_DELAY);
-
- COM_UNLOCK();
- return (FILTER_HANDLED);
-}
-
-static void
-cybreak(struct tty *tp, int sig)
-{
- struct com_s *com;
-
- com = tp->t_sc;
- if (sig)
- cd_etc(com, CD1400_ETC_SENDBREAK);
- else
- cd_etc(com, CD1400_ETC_STOPBREAK);
-}
-
-static void
-cypoll(void *arg)
-{
- int unit;
-
-#ifdef CyDebug
- ++cy_timeouts;
-#endif
- if (cy_events == 0)
- return;
-repeat:
- for (unit = 0; unit < NPORTS; ++unit) {
- struct com_s *com;
- int incc;
- struct tty *tp;
-
- com = cy_addr(unit);
- if (com == NULL)
- continue;
- tp = com->tp;
- if (tp == NULL) {
- /*
- * XXX forget any events related to closed devices
- * (actually never opened devices) so that we don't
- * loop.
- */
- critical_enter();
- COM_LOCK();
- incc = com->iptr - com->ibuf;
- com->iptr = com->ibuf;
- if (com->state & CS_CHECKMSR) {
- incc += LOTS_OF_EVENTS;
- com->state &= ~CS_CHECKMSR;
- }
- cy_events -= incc;
- COM_UNLOCK();
- critical_exit();
- if (incc != 0)
- log(LOG_DEBUG,
- "cy%d: %d events for device with no tp\n",
- unit, incc);
- continue;
- }
- if (com->iptr != com->ibuf) {
- critical_enter();
- COM_LOCK();
- cyinput(com);
- COM_UNLOCK();
- critical_exit();
- }
- if (com->state & CS_CHECKMSR) {
- u_char delta_modem_status;
-
- critical_enter();
- COM_LOCK();
- cyinput(com);
- delta_modem_status = com->last_modem_status
- ^ com->prev_modem_status;
- com->prev_modem_status = com->last_modem_status;
- cy_events -= LOTS_OF_EVENTS;
- com->state &= ~CS_CHECKMSR;
- COM_UNLOCK();
- critical_exit();
- if (delta_modem_status & CD1400_MSVR2_CD)
- ttyld_modem(tp,
- com->prev_modem_status & CD1400_MSVR2_CD);
- }
- if (com->extra_state & CSE_ODONE) {
- critical_enter();
- COM_LOCK();
- cy_events -= LOTS_OF_EVENTS;
- com->extra_state &= ~CSE_ODONE;
- COM_UNLOCK();
- critical_exit();
- if (!(com->state & CS_BUSY)) {
- tp->t_state &= ~TS_BUSY;
- ttwwakeup(com->tp);
- }
- if (com->etc != ETC_NONE) {
- if (com->etc == ETC_BREAK_ENDED)
- com->etc = ETC_NONE;
- wakeup(&com->etc);
- }
- }
- if (com->state & CS_ODONE) {
- critical_enter();
- COM_LOCK();
- cy_events -= LOTS_OF_EVENTS;
- com->state &= ~CS_ODONE;
- COM_UNLOCK();
- critical_exit();
- ttyld_start(tp);
- }
- if (cy_events == 0)
- break;
- }
- if (cy_events >= LOTS_OF_EVENTS)
- goto repeat;
-}
-
-static int
-cyparam(struct tty *tp, struct termios *t)
-{
- int bits;
- int cflag;
- struct com_s *com;
- u_char cor_change;
- u_long cy_clock;
- int idivisor;
- int iflag;
- int iprescaler;
- int itimeout;
- int odivisor;
- int oprescaler;
- u_char opt;
- int s;
-
- com = tp->t_sc;
-
- /* check requested parameters */
- cy_clock = CY_CLOCK(com->gfrcr_image);
- idivisor = cyspeed(t->c_ispeed, cy_clock, &iprescaler);
- if (idivisor <= 0)
- return (EINVAL);
- odivisor = cyspeed(t->c_ospeed != 0 ? t->c_ospeed : tp->t_ospeed,
- cy_clock, &oprescaler);
- if (odivisor <= 0)
- return (EINVAL);
-
- /* parameters are OK, convert them to the com struct and the device */
- s = spltty();
- if (t->c_ospeed == 0)
- (void)cymodem(tp, 0, SER_DTR);
- else
- (void)cymodem(tp, SER_DTR, 0);
-
- (void) cysetwater(com, t->c_ispeed);
-
- /* XXX we don't actually change the speed atomically. */
-
- cd_setreg(com, CD1400_RBPR, idivisor);
- cd_setreg(com, CD1400_RCOR, iprescaler);
- cd_setreg(com, CD1400_TBPR, odivisor);
- cd_setreg(com, CD1400_TCOR, oprescaler);
-
- /*
- * channel control
- * receiver enable
- * transmitter enable (always set)
- */
- cflag = t->c_cflag;
- opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN
- | (cflag & CREAD ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
- if (opt != com->channel_control) {
- com->channel_control = opt;
- cd1400_channel_cmd(com, opt);
- }
-
-#ifdef Smarts
- /* set special chars */
- /* XXX if one is _POSIX_VDISABLE, can't use some others */
- if (t->c_cc[VSTOP] != _POSIX_VDISABLE)
- cd_setreg(com, CD1400_SCHR1, t->c_cc[VSTOP]);
- if (t->c_cc[VSTART] != _POSIX_VDISABLE)
- cd_setreg(com, CD1400_SCHR2, t->c_cc[VSTART]);
- if (t->c_cc[VINTR] != _POSIX_VDISABLE)
- cd_setreg(com, CD1400_SCHR3, t->c_cc[VINTR]);
- if (t->c_cc[VSUSP] != _POSIX_VDISABLE)
- cd_setreg(com, CD1400_SCHR4, t->c_cc[VSUSP]);
-#endif
-
- /*
- * set channel option register 1 -
- * parity mode
- * stop bits
- * char length
- */
- opt = 0;
- /* parity */
- if (cflag & PARENB) {
- if (cflag & PARODD)
- opt |= CD1400_COR1_PARODD;
- opt |= CD1400_COR1_PARNORMAL;
- }
- iflag = t->c_iflag;
- if (!(iflag & INPCK))
- opt |= CD1400_COR1_NOINPCK;
- bits = 1 + 1;
- /* stop bits */
- if (cflag & CSTOPB) {
- ++bits;
- opt |= CD1400_COR1_STOP2;
- }
- /* char length */
- switch (cflag & CSIZE) {
- case CS5:
- bits += 5;
- opt |= CD1400_COR1_CS5;
- break;
- case CS6:
- bits += 6;
- opt |= CD1400_COR1_CS6;
- break;
- case CS7:
- bits += 7;
- opt |= CD1400_COR1_CS7;
- break;
- default:
- bits += 8;
- opt |= CD1400_COR1_CS8;
- break;
- }
- cor_change = 0;
- if (opt != com->cor[0]) {
- cor_change |= CD1400_CCR_COR1;
- cd_setreg(com, CD1400_COR1, com->cor[0] = opt);
- }
-
- /*
- * Set receive time-out period, normally to max(one char time, 5 ms).
- */
- itimeout = howmany(1000 * bits, t->c_ispeed);
-#ifdef SOFT_HOTCHAR
-#define MIN_RTP 1
-#else
-#define MIN_RTP 5
-#endif
- if (itimeout < MIN_RTP)
- itimeout = MIN_RTP;
- if (!(t->c_lflag & ICANON) && t->c_cc[VMIN] != 0 && t->c_cc[VTIME] != 0
- && t->c_cc[VTIME] * 10 > itimeout)
- itimeout = t->c_cc[VTIME] * 10;
- if (itimeout > 255)
- itimeout = 255;
- cd_setreg(com, CD1400_RTPR, itimeout);
-
- /*
- * set channel option register 2 -
- * flow control
- */
- opt = 0;
-#ifdef Smarts
- if (iflag & IXANY)
- opt |= CD1400_COR2_IXANY;
- if (iflag & IXOFF)
- opt |= CD1400_COR2_IXOFF;
-#endif
-#ifndef SOFT_CTS_OFLOW
- if (cflag & CCTS_OFLOW)
- opt |= CD1400_COR2_CCTS_OFLOW;
-#endif
- critical_enter();
- COM_LOCK();
- if (opt != com->cor[1]) {
- cor_change |= CD1400_CCR_COR2;
- cd_setreg(com, CD1400_COR2, com->cor[1] = opt);
- }
- COM_UNLOCK();
- critical_exit();
-
- /*
- * set channel option register 3 -
- * receiver FIFO interrupt threshold
- * flow control
- */
- opt = RxFifoThreshold;
-#ifdef Smarts
- if (t->c_lflag & ICANON)
- opt |= CD1400_COR3_SCD34; /* detect INTR & SUSP chars */
- if (iflag & IXOFF)
- /* detect and transparently handle START and STOP chars */
- opt |= CD1400_COR3_FCT | CD1400_COR3_SCD12;
-#endif
- if (opt != com->cor[2]) {
- cor_change |= CD1400_CCR_COR3;
- cd_setreg(com, CD1400_COR3, com->cor[2] = opt);
- }
-
- /* notify the CD1400 if COR1-3 have changed */
- if (cor_change)
- cd1400_channel_cmd(com, CD1400_CCR_CMDCORCHG | cor_change);
-
- /*
- * set channel option register 4 -
- * CR/NL processing
- * break processing
- * received exception processing
- */
- opt = 0;
- if (iflag & IGNCR)
- opt |= CD1400_COR4_IGNCR;
-#ifdef Smarts
- /*
- * we need a new ttyinput() for this, as we don't want to
- * have ICRNL && INLCR being done in both layers, or to have
- * synchronisation problems
- */
- if (iflag & ICRNL)
- opt |= CD1400_COR4_ICRNL;
- if (iflag & INLCR)
- opt |= CD1400_COR4_INLCR;
-#endif
- if (iflag & IGNBRK)
- opt |= CD1400_COR4_IGNBRK | CD1400_COR4_NOBRKINT;
- /*
- * The `-ignbrk -brkint parmrk' case is not handled by the hardware,
- * so only tell the hardware about -brkint if -parmrk.
- */
- if (!(iflag & (BRKINT | PARMRK)))
- opt |= CD1400_COR4_NOBRKINT;
-#if 0
- /* XXX using this "intelligence" breaks reporting of overruns. */
- if (iflag & IGNPAR)
- opt |= CD1400_COR4_PFO_DISCARD;
- else {
- if (iflag & PARMRK)
- opt |= CD1400_COR4_PFO_ESC;
- else
- opt |= CD1400_COR4_PFO_NUL;
- }
-#else
- opt |= CD1400_COR4_PFO_EXCEPTION;
-#endif
- cd_setreg(com, CD1400_COR4, opt);
-
- /*
- * set channel option register 5 -
- */
- opt = 0;
- if (iflag & ISTRIP)
- opt |= CD1400_COR5_ISTRIP;
- if (t->c_iflag & IEXTEN)
- /* enable LNEXT (e.g. ctrl-v quoting) handling */
- opt |= CD1400_COR5_LNEXT;
-#ifdef Smarts
- if (t->c_oflag & ONLCR)
- opt |= CD1400_COR5_ONLCR;
- if (t->c_oflag & OCRNL)
- opt |= CD1400_COR5_OCRNL;
-#endif
- cd_setreg(com, CD1400_COR5, opt);
-
- /*
- * We always generate modem status change interrupts for CD changes.
- * Among other things, this is necessary to track TS_CARR_ON for
- * pstat to print even when the driver doesn't care. CD changes
- * should be rare so interrupts for them are not worth extra code to
- * avoid. We avoid interrupts for other modem status changes (except
- * for CTS changes when SOFT_CTS_OFLOW is configured) since this is
- * simplest and best.
- */
-
- /*
- * set modem change option register 1
- * generate modem interrupts on which 1 -> 0 input transitions
- * also controls auto-DTR output flow-control, which we don't use
- */
- opt = CD1400_MCOR1_CDzd;
-#ifdef SOFT_CTS_OFLOW
- if (cflag & CCTS_OFLOW)
- opt |= CD1400_MCOR1_CTSzd;
-#endif
- cd_setreg(com, CD1400_MCOR1, opt);
-
- /*
- * set modem change option register 2
- * generate modem interrupts on specific 0 -> 1 input transitions
- */
- opt = CD1400_MCOR2_CDod;
-#ifdef SOFT_CTS_OFLOW
- if (cflag & CCTS_OFLOW)
- opt |= CD1400_MCOR2_CTSod;
-#endif
- cd_setreg(com, CD1400_MCOR2, opt);
-
- /*
- * XXX should have done this long ago, but there is too much state
- * to change all atomically.
- */
- critical_enter();
- COM_LOCK();
-
- com->state &= ~CS_TTGO;
- if (!(tp->t_state & TS_TTSTOP))
- com->state |= CS_TTGO;
- if (cflag & CRTS_IFLOW) {
- com->state |= CS_RTS_IFLOW;
- /*
- * If CS_RTS_IFLOW just changed from off to on, the change
- * needs to be propagated to CD1400_MSVR1_RTS. This isn't urgent,
- * so do it later by calling cystart() instead of repeating
- * a lot of code from cystart() here.
- */
- } else if (com->state & CS_RTS_IFLOW) {
- com->state &= ~CS_RTS_IFLOW;
- /*
- * CS_RTS_IFLOW just changed from on to off. Force CD1400_MSVR1_RTS
- * on here, since cystart() won't do it later.
- */
- cd_setreg(com, com->mcr_rts_reg,
- com->mcr_image |= com->mcr_rts);
- }
-
- /*
- * Set up state to handle output flow control.
- * XXX - worth handling MDMBUF (DCD) flow control at the lowest level?
- * Now has 10+ msec latency, while CTS flow has 50- usec latency.
- */
- com->state |= CS_ODEVREADY;
-#ifdef SOFT_CTS_OFLOW
- com->state &= ~CS_CTS_OFLOW;
- if (cflag & CCTS_OFLOW) {
- com->state |= CS_CTS_OFLOW;
- if (!(com->last_modem_status & CD1400_MSVR2_CTS))
- com->state &= ~CS_ODEVREADY;
- }
-#endif
- /* XXX shouldn't call functions while intrs are disabled. */
- disc_optim(tp, t, com);
-#if 0
- /*
- * Recover from fiddling with CS_TTGO. We used to call cyintr1()
- * unconditionally, but that defeated the careful discarding of
- * stale input in cyopen().
- */
- if (com->state >= (CS_BUSY | CS_TTGO))
- cyintr1(com);
-#endif
- if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
- if (!(com->intr_enable & CD1400_SRER_TXRDY))
- cd_setreg(com, CD1400_SRER,
- com->intr_enable
- = (com->intr_enable & ~CD1400_SRER_TXMPTY)
- | CD1400_SRER_TXRDY);
- } else {
- if (com->intr_enable & CD1400_SRER_TXRDY)
- cd_setreg(com, CD1400_SRER,
- com->intr_enable
- = (com->intr_enable & ~CD1400_SRER_TXRDY)
- | CD1400_SRER_TXMPTY);
- }
-
- COM_UNLOCK();
- critical_exit();
- splx(s);
- cystart(tp);
- if (com->ibufold != NULL) {
- free(com->ibufold, M_DEVBUF);
- com->ibufold = NULL;
- }
- return (0);
-}
-
-static int
-cysetwater(struct com_s *com, speed_t speed)
-{
- int cp4ticks;
- u_char *ibuf;
- int ibufsize;
- struct tty *tp;
-
- /*
- * Make the buffer size large enough to handle a softtty interrupt
- * latency of about 2 ticks without loss of throughput or data
- * (about 3 ticks if input flow control is not used or not honoured,
- * but a bit less for CS5-CS7 modes).
- */
- cp4ticks = speed / 10 / hz * 4;
- for (ibufsize = 128; ibufsize < cp4ticks;)
- ibufsize <<= 1;
- if (ibufsize == com->ibufsize) {
- return (0);
- }
-
- /*
- * Allocate input buffer. The extra factor of 2 in the size is
- * to allow for an error byte for each input byte.
- */
- ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
- if (ibuf == NULL) {
- return (ENOMEM);
- }
-
- /* Initialize non-critical variables. */
- com->ibufold = com->ibuf;
- com->ibufsize = ibufsize;
- tp = com->tp;
- if (tp != NULL) {
- tp->t_ififosize = 2 * ibufsize;
- tp->t_ispeedwat = (speed_t)-1;
- tp->t_ospeedwat = (speed_t)-1;
- }
-
- /*
- * Read current input buffer, if any. Continue with interrupts
- * disabled.
- */
- critical_enter();
- COM_LOCK();
- if (com->iptr != com->ibuf)
- cyinput(com);
-
- /*-
- * Initialize critical variables, including input buffer watermarks.
- * The external device is asked to stop sending when the buffer
- * exactly reaches high water, or when the high level requests it.
- * The high level is notified immediately (rather than at a later
- * clock tick) when this watermark is reached.
- * The buffer size is chosen so the watermark should almost never
- * be reached.
- * The low watermark is invisibly 0 since the buffer is always
- * emptied all at once.
- */
- com->iptr = com->ibuf = ibuf;
- com->ibufend = ibuf + ibufsize;
- com->ierroff = ibufsize;
- com->ihighwater = ibuf + 3 * ibufsize / 4;
-
- COM_UNLOCK();
- critical_exit();
- return (0);
-}
-
-static void
-cystart(struct tty *tp)
-{
- struct com_s *com;
- int s;
-#ifdef CyDebug
- bool_t started;
-#endif
-
- com = tp->t_sc;
- s = spltty();
-
-#ifdef CyDebug
- ++com->start_count;
- started = FALSE;
-#endif
-
- critical_enter();
- COM_LOCK();
- if (tp->t_state & TS_TTSTOP) {
- com->state &= ~CS_TTGO;
- if (com->intr_enable & CD1400_SRER_TXRDY)
- cd_setreg(com, CD1400_SRER,
- com->intr_enable
- = (com->intr_enable & ~CD1400_SRER_TXRDY)
- | CD1400_SRER_TXMPTY);
- } else {
- com->state |= CS_TTGO;
- if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)
- && !(com->intr_enable & CD1400_SRER_TXRDY))
- cd_setreg(com, CD1400_SRER,
- com->intr_enable
- = (com->intr_enable & ~CD1400_SRER_TXMPTY)
- | CD1400_SRER_TXRDY);
- }
- if (tp->t_state & TS_TBLOCK) {
- if (com->mcr_image & com->mcr_rts && com->state & CS_RTS_IFLOW)
-#if 0
- outb(com->modem_ctl_port, com->mcr_image &= ~CD1400_MSVR1_RTS);
-#else
- cd_setreg(com, com->mcr_rts_reg,
- com->mcr_image &= ~com->mcr_rts);
-#endif
- } else {
- if (!(com->mcr_image & com->mcr_rts)
- && com->iptr < com->ihighwater
- && com->state & CS_RTS_IFLOW)
-#if 0
- outb(com->modem_ctl_port, com->mcr_image |= CD1400_MSVR1_RTS);
-#else
- cd_setreg(com, com->mcr_rts_reg,
- com->mcr_image |= com->mcr_rts);
-#endif
- }
- COM_UNLOCK();
- critical_exit();
- if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
- ttwwakeup(tp);
- splx(s);
- return;
- }
- if (tp->t_outq.c_cc != 0) {
- struct lbq *qp;
- struct lbq *next;
-
- if (!com->obufs[0].l_queued) {
-#ifdef CyDebug
- started = TRUE;
-#endif
- com->obufs[0].l_tail
- = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
- sizeof com->obuf1);
- com->obufs[0].l_next = NULL;
- com->obufs[0].l_queued = TRUE;
- critical_enter();
- COM_LOCK();
- if (com->state & CS_BUSY) {
- qp = com->obufq.l_next;
- while ((next = qp->l_next) != NULL)
- qp = next;
- qp->l_next = &com->obufs[0];
- } else {
- com->obufq.l_head = com->obufs[0].l_head;
- com->obufq.l_tail = com->obufs[0].l_tail;
- com->obufq.l_next = &com->obufs[0];
- com->state |= CS_BUSY;
- if (com->state >= (CS_BUSY | CS_TTGO
- | CS_ODEVREADY))
- cd_setreg(com, CD1400_SRER,
- com->intr_enable
- = (com->intr_enable
- & ~CD1400_SRER_TXMPTY)
- | CD1400_SRER_TXRDY);
- }
- COM_UNLOCK();
- critical_exit();
- }
- if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
-#ifdef CyDebug
- started = TRUE;
-#endif
- com->obufs[1].l_tail
- = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
- sizeof com->obuf2);
- com->obufs[1].l_next = NULL;
- com->obufs[1].l_queued = TRUE;
- critical_enter();
- COM_LOCK();
- if (com->state & CS_BUSY) {
- qp = com->obufq.l_next;
- while ((next = qp->l_next) != NULL)
- qp = next;
- qp->l_next = &com->obufs[1];
- } else {
- com->obufq.l_head = com->obufs[1].l_head;
- com->obufq.l_tail = com->obufs[1].l_tail;
- com->obufq.l_next = &com->obufs[1];
- com->state |= CS_BUSY;
- if (com->state >= (CS_BUSY | CS_TTGO
- | CS_ODEVREADY))
- cd_setreg(com, CD1400_SRER,
- com->intr_enable
- = (com->intr_enable
- & ~CD1400_SRER_TXMPTY)
- | CD1400_SRER_TXRDY);
- }
- COM_UNLOCK();
- critical_exit();
- }
- tp->t_state |= TS_BUSY;
- }
-#ifdef CyDebug
- if (started)
- ++com->start_real;
-#endif
-#if 0
- critical_enter();
- COM_LOCK();
- if (com->state >= (CS_BUSY | CS_TTGO))
- cyintr1(com); /* fake interrupt to start output */
- COM_UNLOCK();
- critical_exit();
-#endif
- ttwwakeup(tp);
- splx(s);
-}
-
-static void
-comstop(struct tty *tp, int rw)
-{
- struct com_s *com;
- bool_t wakeup_etc;
-
- com = tp->t_sc;
- wakeup_etc = FALSE;
- critical_enter();
- COM_LOCK();
- if (rw & FWRITE) {
- com->obufs[0].l_queued = FALSE;
- com->obufs[1].l_queued = FALSE;
- if (com->extra_state & CSE_ODONE) {
- cy_events -= LOTS_OF_EVENTS;
- com->extra_state &= ~CSE_ODONE;
- if (com->etc != ETC_NONE) {
- if (com->etc == ETC_BREAK_ENDED)
- com->etc = ETC_NONE;
- wakeup_etc = TRUE;
- }
- }
- com->tp->t_state &= ~TS_BUSY;
- if (com->state & CS_ODONE)
- cy_events -= LOTS_OF_EVENTS;
- com->state &= ~(CS_ODONE | CS_BUSY);
- }
- if (rw & FREAD) {
- /* XXX no way to reset only input fifo. */
- cy_events -= (com->iptr - com->ibuf);
- com->iptr = com->ibuf;
- }
- COM_UNLOCK();
- critical_exit();
- if (wakeup_etc)
- wakeup(&com->etc);
- if (rw & FWRITE && com->etc == ETC_NONE)
- cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
- cystart(tp);
-}
-
-static int
-cymodem(struct tty *tp, int sigon, int sigoff)
-{
- struct com_s *com;
- int mcr;
- int msr;
-
- com = tp->t_sc;
- if (sigon == 0 && sigoff == 0) {
- sigon = 0;
- mcr = com->mcr_image;
- if (mcr & com->mcr_dtr)
- sigon |= SER_DTR;
- if (mcr & com->mcr_rts)
- /* XXX wired on for Cyclom-8Ys */
- sigon |= SER_RTS;
-
- /*
- * We must read the modem status from the hardware because
- * we don't generate modem status change interrupts for all
- * changes, so com->prev_modem_status is not guaranteed to
- * be up to date. This is safe, unlike for sio, because
- * reading the status register doesn't clear pending modem
- * status change interrupts.
- */
- msr = cd_getreg(com, CD1400_MSVR2);
-
- if (msr & CD1400_MSVR2_CTS)
- sigon |= SER_CTS;
- if (msr & CD1400_MSVR2_CD)
- sigon |= SER_DCD;
- if (msr & CD1400_MSVR2_DSR)
- sigon |= SER_DSR;
- if (msr & CD1400_MSVR2_RI)
- /* XXX not connected except for Cyclom-16Y? */
- sigon |= SER_RI;
- return (sigon);
- }
- mcr = com->mcr_image;
- if (sigon & SER_DTR)
- mcr |= com->mcr_dtr;
- if (sigoff & SER_DTR)
- mcr &= ~com->mcr_dtr;
- if (sigon & SER_RTS)
- mcr |= com->mcr_rts;
- if (sigoff & SER_RTS)
- mcr &= ~com->mcr_rts;
- critical_enter();
- COM_LOCK();
- com->mcr_image = mcr;
- cd_setreg(com, CD1400_MSVR1, mcr);
- cd_setreg(com, CD1400_MSVR2, mcr);
- COM_UNLOCK();
- critical_exit();
- return (0);
-}
-
-static void
-cysettimeout()
-{
- struct com_s *com;
- bool_t someopen;
- int unit;
-
- /*
- * Set our timeout period to 1 second if no polled devices are open.
- * Otherwise set it to max(1/200, 1/hz).
- * Enable timeouts iff some device is open.
- */
- untimeout(cywakeup, (void *)NULL, cy_timeout_handle);
- cy_timeout = hz;
- someopen = FALSE;
- for (unit = 0; unit < NPORTS; ++unit) {
- com = cy_addr(unit);
- if (com != NULL && com->tp != NULL
- && com->tp->t_state & TS_ISOPEN) {
- someopen = TRUE;
- }
- }
- if (someopen) {
- cy_timeouts_until_log = hz / cy_timeout;
- cy_timeout_handle = timeout(cywakeup, (void *)NULL,
- cy_timeout);
- } else {
- /* Flush error messages, if any. */
- cy_timeouts_until_log = 1;
- cywakeup((void *)NULL);
- untimeout(cywakeup, (void *)NULL, cy_timeout_handle);
- }
-}
-
-static void
-cywakeup(void *chan)
-{
- struct com_s *com;
- int unit;
-
- cy_timeout_handle = timeout(cywakeup, (void *)NULL, cy_timeout);
-
- /*
- * Check for and log errors, but not too often.
- */
- if (--cy_timeouts_until_log > 0)
- return;
- cy_timeouts_until_log = hz / cy_timeout;
- for (unit = 0; unit < NPORTS; ++unit) {
- int errnum;
-
- com = cy_addr(unit);
- if (com == NULL)
- continue;
- for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
- u_int delta;
- u_long total;
-
- critical_enter();
- COM_LOCK();
- delta = com->delta_error_counts[errnum];
- com->delta_error_counts[errnum] = 0;
- COM_UNLOCK();
- critical_exit();
- if (delta == 0)
- continue;
- total = com->error_counts[errnum] += delta;
- log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n",
- unit, delta, error_desc[errnum],
- delta == 1 ? "" : "s", total);
- }
- }
-}
-
-static void
-disc_optim(struct tty *tp, struct termios *t, struct com_s *com)
-{
-#ifndef SOFT_HOTCHAR
- u_char opt;
-#endif
-
- ttyldoptim(tp);
-#ifndef SOFT_HOTCHAR
- opt = com->cor[2] & ~CD1400_COR3_SCD34;
- if (com->tp->t_hotchar != 0) {
- cd_setreg(com, CD1400_SCHR3, com->tp->t_hotchar);
- cd_setreg(com, CD1400_SCHR4, com->tp->t_hotchar);
- opt |= CD1400_COR3_SCD34;
- }
- if (opt != com->cor[2]) {
- cd_setreg(com, CD1400_COR3, com->cor[2] = opt);
- cd1400_channel_cmd(com, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3);
- }
-#endif
-}
-
-#ifdef Smarts
-/* standard line discipline input routine */
-int
-cyinput(int c, struct tty *tp)
-{
- /* XXX duplicate ttyinput(), but without the IXOFF/IXON/ISTRIP/IPARMRK
- * bits, as they are done by the CD1400. Hardly worth the effort,
- * given that high-throughput session are raw anyhow.
- */
-}
-#endif /* Smarts */
-
-static int
-cyspeed(speed_t speed, u_long cy_clock, int *prescaler_io)
-{
- int actual;
- int error;
- int divider;
- int prescaler;
- int prescaler_unit;
-
- if (speed == 0)
- return (0);
- if (speed < 0 || speed > 150000)
- return (-1);
-
- /* determine which prescaler to use */
- for (prescaler_unit = 4, prescaler = 2048; prescaler_unit;
- prescaler_unit--, prescaler >>= 2) {
- if (cy_clock / prescaler / speed > 63)
- break;
- }
-
- divider = (cy_clock / prescaler * 2 / speed + 1) / 2; /* round off */
- if (divider > 255)
- divider = 255;
- actual = cy_clock/prescaler/divider;
-
- /* 10 times error in percent: */
- error = ((actual - (long)speed) * 2000 / (long)speed + 1) / 2;
-
- /* 3.0% max error tolerance */
- if (error < -30 || error > 30)
- return (-1);
-
- *prescaler_io = prescaler_unit;
- return (divider);
-}
-
-static void
-cd1400_channel_cmd(struct com_s *com, int cmd)
-{
- cd1400_channel_cmd_wait(com);
- cd_setreg(com, CD1400_CCR, cmd);
- cd1400_channel_cmd_wait(com);
-}
-
-static void
-cd1400_channel_cmd_wait(struct com_s *com)
-{
- struct timeval start;
- struct timeval tv;
- long usec;
-
- if (cd_getreg(com, CD1400_CCR) == 0)
- return;
- microtime(&start);
- for (;;) {
- if (cd_getreg(com, CD1400_CCR) == 0)
- return;
- microtime(&tv);
- usec = 1000000 * (tv.tv_sec - start.tv_sec) +
- tv.tv_usec - start.tv_usec;
- if (usec >= 5000) {
- log(LOG_ERR,
- "cy%d: channel command timeout (%ld usec)\n",
- com->unit, usec);
- return;
- }
- }
-}
-
-static void
-cd_etc(struct com_s *com, int etc)
-{
-
- /*
- * We can't change the hardware's ETC state while there are any
- * characters in the tx fifo, since those characters would be
- * interpreted as commands! Unputting characters from the fifo
- * is difficult, so we wait up to 12 character times for the fifo
- * to drain. The command will be delayed for up to 2 character
- * times for the tx to become empty. Unputting characters from
- * the tx holding and shift registers is impossible, so we wait
- * for the tx to become empty so that the command is sure to be
- * executed soon after we issue it.
- */
- critical_enter();
- COM_LOCK();
- if (com->etc == etc)
- goto wait;
- if ((etc == CD1400_ETC_SENDBREAK
- && (com->etc == ETC_BREAK_STARTING
- || com->etc == ETC_BREAK_STARTED))
- || (etc == CD1400_ETC_STOPBREAK
- && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED
- || com->etc == ETC_NONE))) {
- COM_UNLOCK();
- critical_exit();
- return;
- }
- com->etc = etc;
- cd_setreg(com, CD1400_SRER,
- com->intr_enable
- = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY);
-wait:
- COM_UNLOCK();
- critical_exit();
- while (com->etc == etc
- && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0)
- continue;
-}
-
-static int
-cd_getreg(struct com_s *com, int reg)
-{
- struct com_s *basecom;
- u_char car;
- int cy_align;
- cy_addr iobase;
-#ifdef SMP
- int need_unlock;
-#endif
- int val;
-
- basecom = cy_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
- car = com->unit & CD1400_CAR_CHAN;
- cy_align = com->cy_align;
- iobase = com->iobase;
- critical_enter();
-#ifdef SMP
- need_unlock = 0;
- if (!mtx_owned(&cy_lock)) {
- COM_LOCK();
- need_unlock = 1;
- }
-#endif
- if (basecom->car != car)
- cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
- val = cd_inb(iobase, reg, cy_align);
-#ifdef SMP
- if (need_unlock)
- COM_UNLOCK();
-#endif
- critical_exit();
- return (val);
-}
-
-static void
-cd_setreg(struct com_s *com, int reg, int val)
-{
- struct com_s *basecom;
- u_char car;
- int cy_align;
- cy_addr iobase;
-#ifdef SMP
- int need_unlock;
-#endif
-
- basecom = cy_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
- car = com->unit & CD1400_CAR_CHAN;
- cy_align = com->cy_align;
- iobase = com->iobase;
- critical_enter();
-#ifdef SMP
- need_unlock = 0;
- if (!mtx_owned(&cy_lock)) {
- COM_LOCK();
- need_unlock = 1;
- }
-#endif
- if (basecom->car != car)
- cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
- cd_outb(iobase, reg, cy_align, val);
-#ifdef SMP
- if (need_unlock)
- COM_UNLOCK();
-#endif
- critical_exit();
-}
-
-#ifdef CyDebug
-/* useful in ddb */
-void
-cystatus(int unit)
-{
- struct com_s *com;
- cy_addr iobase;
- u_int ocount;
- struct tty *tp;
-
- com = cy_addr(unit);
- printf("info for channel %d\n", unit);
- printf("------------------\n");
- printf("total cyclom service probes:\t%d\n", cy_svrr_probes);
- printf("calls to upper layer:\t\t%d\n", cy_timeouts);
- if (com == NULL)
- return;
- iobase = com->iobase;
- printf("\n");
- printf("cd1400 base address:\\tt%p\n", iobase);
- printf("saved channel_control:\t\t0x%02x\n", com->channel_control);
- printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n",
- com->cor[0], com->cor[1], com->cor[2]);
- printf("service request enable reg:\t0x%02x (0x%02x cached)\n",
- cd_getreg(com, CD1400_SRER), com->intr_enable);
- printf("service request register:\t0x%02x\n",
- cd_inb(iobase, CD1400_SVRR, com->cy_align));
- printf("modem status:\t\t\t0x%02x (0x%02x cached)\n",
- cd_getreg(com, CD1400_MSVR2), com->prev_modem_status);
- printf("rx/tx/mdm interrupt registers:\t0x%02x 0x%02x 0x%02x\n",
- cd_inb(iobase, CD1400_RIR, com->cy_align),
- cd_inb(iobase, CD1400_TIR, com->cy_align),
- cd_inb(iobase, CD1400_MIR, com->cy_align));
- printf("\n");
- printf("com state:\t\t\t0x%02x\n", com->state);
- printf("calls to cystart():\t\t%d (%d useful)\n",
- com->start_count, com->start_real);
- printf("rx buffer chars free:\t\t%d\n", com->iptr - com->ibuf);
- ocount = 0;
- if (com->obufs[0].l_queued)
- ocount += com->obufs[0].l_tail - com->obufs[0].l_head;
- if (com->obufs[1].l_queued)
- ocount += com->obufs[1].l_tail - com->obufs[1].l_head;
- printf("tx buffer chars:\t\t%u\n", ocount);
- printf("received chars:\t\t\t%d\n", com->bytes_in);
- printf("received exceptions:\t\t%d\n", com->recv_exception);
- printf("modem signal deltas:\t\t%d\n", com->mdm);
- printf("transmitted chars:\t\t%d\n", com->bytes_out);
- printf("\n");
- tp = com->tp;
- if (tp != NULL) {
- printf("tty state:\t\t\t0x%08x\n", tp->t_state);
- printf(
- "upper layer queue lengths:\t%d raw, %d canon, %d output\n",
- tp->t_rawq.c_cc, tp->t_canq.c_cc, tp->t_outq.c_cc);
- } else
- printf("tty state:\t\t\tclosed\n");
-}
-#endif /* CyDebug */
Index: sys/dev/cy/cy_isa.c
===================================================================
--- sys/dev/cy/cy_isa.c
+++ sys/dev/cy/cy_isa.c
@@ -1,152 +0,0 @@
-/*-
- * cyclades cyclom-y serial driver
- * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1993 Andrew Herbert.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name Andrew Herbert may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Cyclades Y ISA serial interface driver
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <machine/resource.h>
-
-#include <isa/isavar.h>
-
-#include <dev/cy/cyreg.h>
-#include <dev/cy/cyvar.h>
-
-static int cy_isa_attach(device_t dev);
-static int cy_isa_probe(device_t dev);
-
-static device_method_t cy_isa_methods[] = {
- /* Device interface. */
- DEVMETHOD(device_probe, cy_isa_probe),
- DEVMETHOD(device_attach, cy_isa_attach),
-
- { 0, 0 }
-};
-
-static driver_t cy_isa_driver = {
- cy_driver_name,
- cy_isa_methods,
- 0,
-};
-
-DRIVER_MODULE(cy, isa, cy_isa_driver, cy_devclass, 0, 0);
-
-static int
-cy_isa_probe(device_t dev)
-{
- struct resource *mem_res;
- cy_addr iobase;
- int error, mem_rid;
-
- if (isa_get_logicalid(dev) != 0) /* skip PnP probes */
- return (ENXIO);
-
- mem_rid = 0;
- mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &mem_rid,
- RF_ACTIVE);
- if (mem_res == NULL) {
- device_printf(dev, "ioport resource allocation failed\n");
- return (ENXIO);
- }
- iobase = rman_get_virtual(mem_res);
-
- /* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
- cy_inb(iobase, CY16_RESET, 0); /* XXX? */
- DELAY(500); /* wait for the board to get its act together */
-
- /* this is needed to get the board out of reset */
- cy_outb(iobase, CY_CLEAR_INTR, 0, 0);
- DELAY(500);
-
- error = (cy_units(iobase, 0) == 0 ? ENXIO : 0);
- bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res);
- return (error);
-}
-
-static int
-cy_isa_attach(device_t dev)
-{
- struct resource *irq_res, *mem_res;
- void *irq_cookie, *vaddr, *vsc;
- int irq_rid, mem_rid;
-
- irq_res = NULL;
- mem_res = NULL;
-
- mem_rid = 0;
- mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &mem_rid,
- RF_ACTIVE);
- if (mem_res == NULL) {
- device_printf(dev, "memory resource allocation failed\n");
- goto fail;
- }
- vaddr = rman_get_virtual(mem_res);
-
- vsc = cyattach_common(vaddr, 0);
- if (vsc == NULL) {
- device_printf(dev, "no ports found!\n");
- goto fail;
- }
-
- irq_rid = 0;
- irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irq_rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (irq_res == NULL) {
- device_printf(dev, "interrupt resource allocation failed\n");
- goto fail;
- }
- if (bus_setup_intr(dev, irq_res, INTR_TYPE_TTY,
- cyintr, NULL, vsc, &irq_cookie) != 0) {
- device_printf(dev, "interrupt setup failed\n");
- goto fail;
- }
-
- return (0);
-
-fail:
- if (irq_res != NULL)
- bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
- if (mem_res != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res);
- return (ENXIO);
-}
Index: sys/dev/cy/cy_pci.c
===================================================================
--- sys/dev/cy/cy_pci.c
+++ sys/dev/cy/cy_pci.c
@@ -1,194 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 1996, David Greenman
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice unmodified, this list of conditions, and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Cyclades Y PCI serial interface driver
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_cy_pci_fastintr.h"
-
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <machine/resource.h>
-
-#include <dev/pci/pcivar.h>
-
-#include <dev/cy/cyvar.h>
-
-#define CY_PCI_BASE_ADDR0 0x10
-#define CY_PCI_BASE_ADDR1 0x14
-#define CY_PCI_BASE_ADDR2 0x18
-
-#define CY_PLX_9050_ICS 0x4c
-#define CY_PLX_9060_ICS 0x68
-#define CY_PLX_9050_ICS_IENABLE 0x040
-#define CY_PLX_9050_ICS_LOCAL_IENABLE 0x001
-#define CY_PLX_9050_ICS_LOCAL_IPOLARITY 0x002
-#define CY_PLX_9060_ICS_IENABLE 0x100
-#define CY_PLX_9060_ICS_LOCAL_IENABLE 0x800
-
-/* Cyclom-Y Custom Register for PLX ID. */
-#define PLX_VER 0x3400
-#define PLX_9050 0x0b
-#define PLX_9060 0x0c
-#define PLX_9080 0x0d
-
-static int cy_pci_attach(device_t dev);
-static int cy_pci_probe(device_t dev);
-
-static device_method_t cy_pci_methods[] = {
- /* Device interface. */
- DEVMETHOD(device_probe, cy_pci_probe),
- DEVMETHOD(device_attach, cy_pci_attach),
-
- { 0, 0 }
-};
-
-static driver_t cy_pci_driver = {
- cy_driver_name,
- cy_pci_methods,
- 0,
-};
-
-DRIVER_MODULE(cy, pci, cy_pci_driver, cy_devclass, 0, 0);
-MODULE_DEPEND(cy, pci, 1, 1, 1);
-
-static int
-cy_pci_probe(dev)
- device_t dev;
-{
- u_int32_t device_id;
-
- device_id = pci_get_devid(dev);
- device_id &= ~0x00060000;
- if (device_id != 0x0100120e && device_id != 0x0101120e)
- return (ENXIO);
- device_set_desc(dev, "Cyclades Cyclom-Y Serial Adapter");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-cy_pci_attach(dev)
- device_t dev;
-{
- struct resource *ioport_res, *irq_res, *mem_res;
- void *irq_cookie, *vaddr, *vsc;
- u_int32_t ioport;
- int irq_setup, ioport_rid, irq_rid, mem_rid;
- u_char plx_ver;
-
- ioport_res = NULL;
- irq_res = NULL;
- mem_res = NULL;
-
- ioport_rid = CY_PCI_BASE_ADDR1;
- ioport_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &ioport_rid,
- RF_ACTIVE);
- if (ioport_res == NULL) {
- device_printf(dev, "ioport resource allocation failed\n");
- goto fail;
- }
- ioport = rman_get_start(ioport_res);
-
- mem_rid = CY_PCI_BASE_ADDR2;
- mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &mem_rid,
- RF_ACTIVE);
- if (mem_res == NULL) {
- device_printf(dev, "memory resource allocation failed\n");
- goto fail;
- }
- vaddr = rman_get_virtual(mem_res);
-
- vsc = cyattach_common(vaddr, 1);
- if (vsc == NULL) {
- device_printf(dev, "no ports found!\n");
- goto fail;
- }
-
- irq_rid = 0;
- irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irq_rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (irq_res == NULL) {
- device_printf(dev, "interrupt resource allocation failed\n");
- goto fail;
- }
-#ifdef CY_PCI_FASTINTR
- irq_setup = bus_setup_intr(dev, irq_res, INTR_TYPE_TTY,
- cyintr, NULL, vsc, &irq_cookie);
-#else
- irq_setup = ENXIO;
-#endif
- if (irq_setup != 0)
- irq_setup = bus_setup_intr(dev, irq_res, INTR_TYPE_TTY,
- NULL, (driver_intr_t *)cyintr, vsc, &irq_cookie);
- if (irq_setup != 0) {
- device_printf(dev, "interrupt setup failed\n");
- goto fail;
- }
-
- /*
- * Enable the "local" interrupt input to generate a
- * PCI interrupt.
- */
- plx_ver = *((u_char *)vaddr + PLX_VER) & 0x0f;
- switch (plx_ver) {
- case PLX_9050:
- outw(ioport + CY_PLX_9050_ICS,
- CY_PLX_9050_ICS_IENABLE | CY_PLX_9050_ICS_LOCAL_IENABLE |
- CY_PLX_9050_ICS_LOCAL_IPOLARITY);
- break;
- case PLX_9060:
- case PLX_9080:
- default: /* Old board, use PLX_9060 values. */
- outw(ioport + CY_PLX_9060_ICS,
- inw(ioport + CY_PLX_9060_ICS) | CY_PLX_9060_ICS_IENABLE |
- CY_PLX_9060_ICS_LOCAL_IENABLE);
- break;
- }
-
- return (0);
-
-fail:
- if (ioport_res != NULL)
- bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid,
- ioport_res);
- if (irq_res != NULL)
- bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
- if (mem_res != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res);
- return (ENXIO);
-}
Index: sys/dev/cy/cyreg.h
===================================================================
--- sys/dev/cy/cyreg.h
+++ sys/dev/cy/cyreg.h
@@ -1,77 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1995 Bruce Evans.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Definitions for Cyclades Cyclom-Y serial boards.
- */
-
-/*
- * Cyclades register offsets. These are physical offsets for ISA boards
- * and physical offsets divided by 2 for PCI boards.
- */
-#define CY8_SVCACKR 0x100 /* (r) */
-#define CY8_SVCACKT 0x200 /* (r) */
-#define CY8_SVCACKM 0x300 /* (r) */
-#define CY16_RESET 0x1400 /* (r) */
-#define CY_CLEAR_INTR 0x1800 /* intr ack address (w) */
-
-#define CY_MAX_CD1400s 8 /* for Cyclom-32Y */
-
-#define CY_CLOCK(version) ((version) >= 0x48 ? 60000000 : 25000000)
-#define CY_RTS_DTR_SWAPPED(version) ((version) >= 0x48)
-
-/*
- * The `cd' macros are for access to cd1400 registers. The `cy' macros
- * are for access to Cyclades registers. Both sets of macros scale the
- * register number to get an offset, but the scales are different for
- * mostly historical reasons.
- */
-#ifdef CyDebug
-#define cd_inb(iobase, reg, cy_align) \
- (++cd_inbs, *((iobase) + (2 * (reg) << (cy_align))))
-#define cy_inb(iobase, reg, cy_align) \
- (++cy_inbs, *((iobase) + ((reg) << (cy_align))))
-#define cd_outb(iobase, reg, cy_align, val) \
- (++cd_outbs, (void)(*((iobase) + (2 * (reg) << (cy_align))) = (val)))
-#define cy_outb(iobase, reg, cy_align, val) \
- (++cy_outbs, (void)(*((iobase) + ((reg) << (cy_align))) = (val)))
-#else
-#define cd_inb(iobase, reg, cy_align) \
- (*((iobase) + (2 * (reg) << (cy_align))))
-#define cy_inb(iobase, reg, cy_align) \
- (*((iobase) + ((reg) << (cy_align))))
-#define cd_outb(iobase, reg, cy_align, val) \
- ((void)(*((iobase) + (2 * (reg) << (cy_align))) = (val)))
-#define cy_outb(iobase, reg, cy_align, val) \
- ((void)(*((iobase) + ((reg) << (cy_align))) = (val)))
-#endif
Index: sys/dev/cy/cyvar.h
===================================================================
--- sys/dev/cy/cyvar.h
+++ sys/dev/cy/cyvar.h
@@ -1,38 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2004 Bruce D. Evans
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-typedef u_char volatile *cy_addr;
-
-extern devclass_t cy_devclass;
-extern char cy_driver_name[];
-
-void *cyattach_common(cy_addr cy_iobase, int cy_align);
-driver_filter_t cyintr;
-int cy_units(cy_addr cy_iobase, int cy_align);
Index: sys/dev/rc/rc.c
===================================================================
--- sys/dev/rc/rc.c
+++ sys/dev/rc/rc.c
@@ -1,1314 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 1995 by Pavel Antonov, Moscow, Russia.
- * Copyright (C) 1995 by Andrey A. Chernov, Moscow, Russia.
- * All rights reserved.
- * Copyright (C) 2002 by John Baldwin <jhb@FreeBSD.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * SDL Communications Riscom/8 (based on Cirrus Logic CL-CD180) driver
- *
- */
-
-/*#define RCDEBUG*/
-
-#include "opt_tty.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/interrupt.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <dev/ic/cd180.h>
-#include <dev/rc/rcreg.h>
-#include <isa/isavar.h>
-
-#define IOBASE_ADDRS 14
-
-#define rcin(sc, port) RC_IN(sc, port)
-#define rcout(sc, port, v) RC_OUT(sc, port, v)
-
-#define WAITFORCCR(sc, chan) rc_wait0((sc), (chan), __LINE__)
-
-#define CCRCMD(sc, chan, cmd) do { \
- WAITFORCCR((sc), (chan)); \
- rcout((sc), CD180_CCR, (cmd)); \
-} while (0)
-
-#define RC_IBUFSIZE 256
-#define RB_I_HIGH_WATER (TTYHOG - 2 * RC_IBUFSIZE)
-#define RC_OBUFSIZE 512
-#define RC_IHIGHWATER (3 * RC_IBUFSIZE / 4)
-#define INPUT_FLAGS_SHIFT (2 * RC_IBUFSIZE)
-#define LOTS_OF_EVENTS 64
-
-#define RC_FAKEID 0x10
-
-/* Per-channel structure */
-struct rc_chans {
- struct rc_softc *rc_rcb; /* back ptr */
- u_short rc_flags; /* Misc. flags */
- int rc_chan; /* Channel # */
- u_char rc_ier; /* intr. enable reg */
- u_char rc_msvr; /* modem sig. status */
- u_char rc_cor2; /* options reg */
- u_char rc_pendcmd; /* special cmd pending */
- u_int rc_dcdwaits; /* how many waits DCD in open */
- struct tty *rc_tp; /* tty struct */
- u_char *rc_iptr; /* Chars input buffer */
- u_char *rc_hiwat; /* hi-water mark */
- u_char *rc_bufend; /* end of buffer */
- u_char *rc_optr; /* ptr in output buf */
- u_char *rc_obufend; /* end of output buf */
- u_char rc_ibuf[4 * RC_IBUFSIZE]; /* input buffer */
- u_char rc_obuf[RC_OBUFSIZE]; /* output buffer */
- struct callout rc_dtrcallout;
-};
-
-/* Per-board structure */
-struct rc_softc {
- device_t sc_dev;
- struct resource *sc_irq;
- struct resource *sc_port[IOBASE_ADDRS];
- int sc_irqrid;
- void *sc_hwicookie;
- bus_space_tag_t sc_bt;
- bus_space_handle_t sc_bh;
- u_int sc_unit; /* unit # */
- u_char sc_dtr; /* DTR status */
- int sc_scheduled_event;
- void *sc_swicookie;
- struct rc_chans sc_channels[CD180_NCHAN]; /* channels */
-};
-
-/* Static prototypes */
-static t_close_t rc_close;
-static void rc_break(struct tty *, int);
-static void rc_release_resources(device_t dev);
-static void rc_intr(void *);
-static void rc_hwreset(struct rc_softc *, unsigned int);
-static int rc_test(struct rc_softc *);
-static void rc_discard_output(struct rc_chans *);
-static int rc_modem(struct tty *, int, int);
-static void rc_start(struct tty *);
-static void rc_stop(struct tty *, int rw);
-static int rc_param(struct tty *, struct termios *);
-static void rc_pollcard(void *);
-static void rc_reinit(struct rc_softc *);
-#ifdef RCDEBUG
-static void printrcflags();
-#endif
-static void rc_wait0(struct rc_softc *sc, int chan, int line);
-
-static devclass_t rc_devclass;
-
-/* Flags */
-#define RC_DTR_OFF 0x0001 /* DTR wait, for close/open */
-#define RC_ACTOUT 0x0002 /* Dial-out port active */
-#define RC_RTSFLOW 0x0004 /* RTS flow ctl enabled */
-#define RC_CTSFLOW 0x0008 /* CTS flow ctl enabled */
-#define RC_DORXFER 0x0010 /* RXFER event planned */
-#define RC_DOXXFER 0x0020 /* XXFER event planned */
-#define RC_MODCHG 0x0040 /* Modem status changed */
-#define RC_OSUSP 0x0080 /* Output suspended */
-#define RC_OSBUSY 0x0100 /* start() routine in progress */
-#define RC_WAS_BUFOVFL 0x0200 /* low-level buffer ovferflow */
-#define RC_WAS_SILOVFL 0x0400 /* silo buffer overflow */
-#define RC_SEND_RDY 0x0800 /* ready to send */
-
-/* Table for translation of RCSR status bits to internal form */
-static int rc_rcsrt[16] = {
- 0, TTY_OE, TTY_FE,
- TTY_FE|TTY_OE, TTY_PE, TTY_PE|TTY_OE,
- TTY_PE|TTY_FE, TTY_PE|TTY_FE|TTY_OE, TTY_BI,
- TTY_BI|TTY_OE, TTY_BI|TTY_FE, TTY_BI|TTY_FE|TTY_OE,
- TTY_BI|TTY_PE, TTY_BI|TTY_PE|TTY_OE, TTY_BI|TTY_PE|TTY_FE,
- TTY_BI|TTY_PE|TTY_FE|TTY_OE
-};
-
-static int rc_ports[] =
- { 0x220, 0x240, 0x250, 0x260, 0x2a0, 0x2b0, 0x300, 0x320 };
-static int iobase_addrs[IOBASE_ADDRS] =
- { 0, 0x400, 0x800, 0xc00, 0x1400, 0x1800, 0x1c00, 0x2000,
- 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x8000 };
-
-/**********************************************/
-
-static int
-rc_probe(device_t dev)
-{
- u_int port;
- int i, found;
-
- /*
- * We don't know of any PnP ID's for these cards.
- */
- if (isa_get_logicalid(dev) != 0)
- return (ENXIO);
-
- /*
- * We have to have an IO port hint that is valid.
- */
- port = isa_get_port(dev);
- if (port == -1)
- return (ENXIO);
- found = 0;
- for (i = 0; i < nitems(rc_ports); i++)
- if (rc_ports[i] == port) {
- found = 1;
- break;
- }
- if (!found)
- return (ENXIO);
-
- /*
- * We have to have an IRQ hint.
- */
- if (isa_get_irq(dev) == -1)
- return (ENXIO);
-
- device_set_desc(dev, "SDL Riscom/8");
- return (0);
-}
-
-static int
-rc_attach(device_t dev)
-{
- struct rc_chans *rc;
- struct tty *tp;
- struct rc_softc *sc;
- u_int port;
- int base, chan, error, i, x;
-
- sc = device_get_softc(dev);
- sc->sc_dev = dev;
-
- /*
- * We need to have IO ports. Lots of them. We need
- * the following ranges relative to the base port:
- * 0x0 - 0x10
- * 0x400 - 0x410
- * 0x800 - 0x810
- * 0xc00 - 0xc10
- * 0x1400 - 0x1410
- * 0x1800 - 0x1810
- * 0x1c00 - 0x1c10
- * 0x2000 - 0x2010
- * 0x3000 - 0x3010
- * 0x3400 - 0x3410
- * 0x3800 - 0x3810
- * 0x3c00 - 0x3c10
- * 0x4000 - 0x4010
- * 0x8000 - 0x8010
- */
- port = isa_get_port(dev);
- for (i = 0; i < IOBASE_ADDRS; i++)
- if (bus_set_resource(dev, SYS_RES_IOPORT, i,
- port + iobase_addrs[i], 0x10) != 0)
- return (ENXIO);
- error = ENOMEM;
- for (i = 0; i < IOBASE_ADDRS; i++) {
- x = i;
- sc->sc_port[i] = bus_alloc_resource_anywhere(dev,
- SYS_RES_IOPORT, &x, 0x10, RF_ACTIVE);
- if (x != i) {
- device_printf(dev, "ioport %d was rid %d\n", i, x);
- goto fail;
- }
- if (sc->sc_port[i] == NULL) {
- device_printf(dev, "failed to alloc ioports %x-%x\n",
- port + iobase_addrs[i],
- port + iobase_addrs[i] + 0x10);
- goto fail;
- }
- }
- sc->sc_bt = rman_get_bustag(sc->sc_port[0]);
- sc->sc_bh = rman_get_bushandle(sc->sc_port[0]);
-
- sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqrid,
- RF_ACTIVE);
- if (sc->sc_irq == NULL) {
- device_printf(dev, "failed to alloc IRQ\n");
- goto fail;
- }
-
- /*
- * Now do some actual tests to make sure it works.
- */
- error = ENXIO;
- rcout(sc, CD180_PPRL, 0x22); /* Random values to Prescale reg. */
- rcout(sc, CD180_PPRH, 0x11);
- if (rcin(sc, CD180_PPRL) != 0x22 || rcin(sc, CD180_PPRH) != 0x11)
- goto fail;
- if (rc_test(sc))
- goto fail;
-
- /*
- * Ok, start actually hooking things up.
- */
- sc->sc_unit = device_get_unit(dev);
- /*sc->sc_chipid = 0x10 + device_get_unit(dev);*/
- device_printf(dev, "%d chans, firmware rev. %c\n",
- CD180_NCHAN, (rcin(sc, CD180_GFRCR) & 0xF) + 'A');
- rc = sc->sc_channels;
- base = CD180_NCHAN * sc->sc_unit;
- for (chan = 0; chan < CD180_NCHAN; chan++, rc++) {
- rc->rc_rcb = sc;
- rc->rc_chan = chan;
- rc->rc_iptr = rc->rc_ibuf;
- rc->rc_bufend = &rc->rc_ibuf[RC_IBUFSIZE];
- rc->rc_hiwat = &rc->rc_ibuf[RC_IHIGHWATER];
- rc->rc_optr = rc->rc_obufend = rc->rc_obuf;
- callout_init(&rc->rc_dtrcallout, 0);
- tp = rc->rc_tp = ttyalloc();
- tp->t_sc = rc;
- tp->t_oproc = rc_start;
- tp->t_param = rc_param;
- tp->t_modem = rc_modem;
- tp->t_break = rc_break;
- tp->t_close = rc_close;
- tp->t_stop = rc_stop;
- ttycreate(tp, TS_CALLOUT, "m%d", chan + base);
- }
-
- error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_TTY, NULL, rc_intr,
- sc, &sc->sc_hwicookie);
- if (error) {
- device_printf(dev, "failed to register interrupt handler\n");
- goto fail;
- }
-
- swi_add(&tty_intr_event, "rc", rc_pollcard, sc, SWI_TTY, 0,
- &sc->sc_swicookie);
- return (0);
-
-fail:
- rc_release_resources(dev);
- return (error);
-}
-
-static int
-rc_detach(device_t dev)
-{
- struct rc_softc *sc;
- struct rc_chans *rc;
- int error, i;
-
- sc = device_get_softc(dev);
-
- rc = sc->sc_channels;
- for (i = 0; i < CD180_NCHAN; i++, rc++)
- ttyfree(rc->rc_tp);
-
- error = bus_teardown_intr(dev, sc->sc_irq, sc->sc_hwicookie);
- if (error)
- device_printf(dev, "failed to deregister interrupt handler\n");
- swi_remove(sc->sc_swicookie);
- rc_release_resources(dev);
-
- return (0);
-}
-
-static void
-rc_release_resources(device_t dev)
-{
- struct rc_softc *sc;
- int i;
-
- sc = device_get_softc(dev);
- if (sc->sc_irq != NULL) {
- bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqrid,
- sc->sc_irq);
- sc->sc_irq = NULL;
- }
- for (i = 0; i < IOBASE_ADDRS; i++) {
- if (sc->sc_port[i] == NULL)
- break;
- bus_release_resource(dev, SYS_RES_IOPORT, i, sc->sc_port[i]);
- sc->sc_port[i] = NULL;
- }
-}
-
-/* RC interrupt handling */
-static void
-rc_intr(void *arg)
-{
- struct rc_softc *sc;
- struct rc_chans *rc;
- int resid, chan;
- u_char val, iack, bsr, ucnt, *optr;
- int good_data, t_state;
-
- sc = (struct rc_softc *)arg;
- bsr = ~(rcin(sc, RC_BSR));
- if (!(bsr & (RC_BSR_TOUT|RC_BSR_RXINT|RC_BSR_TXINT|RC_BSR_MOINT))) {
- device_printf(sc->sc_dev, "extra interrupt\n");
- rcout(sc, CD180_EOIR, 0);
- return;
- }
-
- while (bsr & (RC_BSR_TOUT|RC_BSR_RXINT|RC_BSR_TXINT|RC_BSR_MOINT)) {
-#ifdef RCDEBUG_DETAILED
- device_printf(sc->sc_dev, "intr (%p) %s%s%s%s\n", arg, bsr,
- (bsr & RC_BSR_TOUT)?"TOUT ":"",
- (bsr & RC_BSR_RXINT)?"RXINT ":"",
- (bsr & RC_BSR_TXINT)?"TXINT ":"",
- (bsr & RC_BSR_MOINT)?"MOINT":"");
-#endif
- if (bsr & RC_BSR_TOUT) {
- device_printf(sc->sc_dev,
- "hardware failure, reset board\n");
- rcout(sc, RC_CTOUT, 0);
- rc_reinit(sc);
- return;
- }
- if (bsr & RC_BSR_RXINT) {
- iack = rcin(sc, RC_PILR_RX);
- good_data = (iack == (GIVR_IT_RGDI | RC_FAKEID));
- if (!good_data && iack != (GIVR_IT_REI | RC_FAKEID)) {
- device_printf(sc->sc_dev,
- "fake rxint: %02x\n", iack);
- goto more_intrs;
- }
- chan = ((rcin(sc, CD180_GICR) & GICR_CHAN) >> GICR_LSH);
- rc = &sc->sc_channels[chan];
- t_state = rc->rc_tp->t_state;
- /* Do RTS flow control stuff */
- if ( (rc->rc_flags & RC_RTSFLOW)
- || !(t_state & TS_ISOPEN)
- ) {
- if ( ( !(t_state & TS_ISOPEN)
- || (t_state & TS_TBLOCK)
- )
- && (rc->rc_msvr & MSVR_RTS)
- )
- rcout(sc, CD180_MSVR,
- rc->rc_msvr &= ~MSVR_RTS);
- else if (!(rc->rc_msvr & MSVR_RTS))
- rcout(sc, CD180_MSVR,
- rc->rc_msvr |= MSVR_RTS);
- }
- ucnt = rcin(sc, CD180_RDCR) & 0xF;
- resid = 0;
-
- if (t_state & TS_ISOPEN) {
- /* check for input buffer overflow */
- if ((rc->rc_iptr + ucnt) >= rc->rc_bufend) {
- resid = ucnt;
- ucnt = rc->rc_bufend - rc->rc_iptr;
- resid -= ucnt;
- if (!(rc->rc_flags & RC_WAS_BUFOVFL)) {
- rc->rc_flags |= RC_WAS_BUFOVFL;
- sc->sc_scheduled_event++;
- }
- }
- optr = rc->rc_iptr;
- /* check foor good data */
- if (good_data) {
- while (ucnt-- > 0) {
- val = rcin(sc, CD180_RDR);
- optr[0] = val;
- optr[INPUT_FLAGS_SHIFT] = 0;
- optr++;
- sc->sc_scheduled_event++;
- if (val != 0 && val == rc->rc_tp->t_hotchar)
- swi_sched(sc->sc_swicookie, 0);
- }
- } else {
- /* Store also status data */
- while (ucnt-- > 0) {
- iack = rcin(sc, CD180_RCSR);
- if (iack & RCSR_Timeout)
- break;
- if ( (iack & RCSR_OE)
- && !(rc->rc_flags & RC_WAS_SILOVFL)) {
- rc->rc_flags |= RC_WAS_SILOVFL;
- sc->sc_scheduled_event++;
- }
- val = rcin(sc, CD180_RDR);
- /*
- Don't store PE if IGNPAR and BREAK if IGNBRK,
- this hack allows "raw" tty optimization
- works even if IGN* is set.
- */
- if ( !(iack & (RCSR_PE|RCSR_FE|RCSR_Break))
- || ((!(iack & (RCSR_PE|RCSR_FE))
- || !(rc->rc_tp->t_iflag & IGNPAR))
- && (!(iack & RCSR_Break)
- || !(rc->rc_tp->t_iflag & IGNBRK)))) {
- if ( (iack & (RCSR_PE|RCSR_FE))
- && (t_state & TS_CAN_BYPASS_L_RINT)
- && ((iack & RCSR_FE)
- || ((iack & RCSR_PE)
- && (rc->rc_tp->t_iflag & INPCK))))
- val = 0;
- else if (val != 0 && val == rc->rc_tp->t_hotchar)
- swi_sched(sc->sc_swicookie, 0);
- optr[0] = val;
- optr[INPUT_FLAGS_SHIFT] = iack;
- optr++;
- sc->sc_scheduled_event++;
- }
- }
- }
- rc->rc_iptr = optr;
- rc->rc_flags |= RC_DORXFER;
- } else
- resid = ucnt;
- /* Clear FIFO if necessary */
- while (resid-- > 0) {
- if (!good_data)
- iack = rcin(sc, CD180_RCSR);
- else
- iack = 0;
- if (iack & RCSR_Timeout)
- break;
- (void) rcin(sc, CD180_RDR);
- }
- goto more_intrs;
- }
- if (bsr & RC_BSR_MOINT) {
- iack = rcin(sc, RC_PILR_MODEM);
- if (iack != (GIVR_IT_MSCI | RC_FAKEID)) {
- device_printf(sc->sc_dev, "fake moint: %02x\n",
- iack);
- goto more_intrs;
- }
- chan = ((rcin(sc, CD180_GICR) & GICR_CHAN) >> GICR_LSH);
- rc = &sc->sc_channels[chan];
- iack = rcin(sc, CD180_MCR);
- rc->rc_msvr = rcin(sc, CD180_MSVR);
- rcout(sc, CD180_MCR, 0);
-#ifdef RCDEBUG
- printrcflags(rc, "moint");
-#endif
- if (rc->rc_flags & RC_CTSFLOW) {
- if (rc->rc_msvr & MSVR_CTS)
- rc->rc_flags |= RC_SEND_RDY;
- else
- rc->rc_flags &= ~RC_SEND_RDY;
- } else
- rc->rc_flags |= RC_SEND_RDY;
- if ((iack & MCR_CDchg) && !(rc->rc_flags & RC_MODCHG)) {
- sc->sc_scheduled_event += LOTS_OF_EVENTS;
- rc->rc_flags |= RC_MODCHG;
- swi_sched(sc->sc_swicookie, 0);
- }
- goto more_intrs;
- }
- if (bsr & RC_BSR_TXINT) {
- iack = rcin(sc, RC_PILR_TX);
- if (iack != (GIVR_IT_TDI | RC_FAKEID)) {
- device_printf(sc->sc_dev, "fake txint: %02x\n",
- iack);
- goto more_intrs;
- }
- chan = ((rcin(sc, CD180_GICR) & GICR_CHAN) >> GICR_LSH);
- rc = &sc->sc_channels[chan];
- if ( (rc->rc_flags & RC_OSUSP)
- || !(rc->rc_flags & RC_SEND_RDY)
- )
- goto more_intrs;
- /* Handle breaks and other stuff */
- if (rc->rc_pendcmd) {
- rcout(sc, CD180_COR2, rc->rc_cor2 |= COR2_ETC);
- rcout(sc, CD180_TDR, CD180_C_ESC);
- rcout(sc, CD180_TDR, rc->rc_pendcmd);
- rcout(sc, CD180_COR2, rc->rc_cor2 &= ~COR2_ETC);
- rc->rc_pendcmd = 0;
- goto more_intrs;
- }
- optr = rc->rc_optr;
- resid = rc->rc_obufend - optr;
- if (resid > CD180_NFIFO)
- resid = CD180_NFIFO;
- while (resid-- > 0)
- rcout(sc, CD180_TDR, *optr++);
- rc->rc_optr = optr;
-
- /* output completed? */
- if (optr >= rc->rc_obufend) {
- rcout(sc, CD180_IER, rc->rc_ier &= ~IER_TxRdy);
-#ifdef RCDEBUG
- device_printf(sc->sc_dev,
- "channel %d: output completed\n",
- rc->rc_chan);
-#endif
- if (!(rc->rc_flags & RC_DOXXFER)) {
- sc->sc_scheduled_event += LOTS_OF_EVENTS;
- rc->rc_flags |= RC_DOXXFER;
- swi_sched(sc->sc_swicookie, 0);
- }
- }
- }
- more_intrs:
- rcout(sc, CD180_EOIR, 0); /* end of interrupt */
- rcout(sc, RC_CTOUT, 0);
- bsr = ~(rcin(sc, RC_BSR));
- }
-}
-
-/* Feed characters to output buffer */
-static void
-rc_start(struct tty *tp)
-{
- struct rc_softc *sc;
- struct rc_chans *rc;
- int s;
-
- rc = tp->t_sc;
- if (rc->rc_flags & RC_OSBUSY)
- return;
- sc = rc->rc_rcb;
- s = spltty();
- rc->rc_flags |= RC_OSBUSY;
- critical_enter();
- if (tp->t_state & TS_TTSTOP)
- rc->rc_flags |= RC_OSUSP;
- else
- rc->rc_flags &= ~RC_OSUSP;
- /* Do RTS flow control stuff */
- if ( (rc->rc_flags & RC_RTSFLOW)
- && (tp->t_state & TS_TBLOCK)
- && (rc->rc_msvr & MSVR_RTS)
- ) {
- rcout(sc, CD180_CAR, rc->rc_chan);
- rcout(sc, CD180_MSVR, rc->rc_msvr &= ~MSVR_RTS);
- } else if (!(rc->rc_msvr & MSVR_RTS)) {
- rcout(sc, CD180_CAR, rc->rc_chan);
- rcout(sc, CD180_MSVR, rc->rc_msvr |= MSVR_RTS);
- }
- critical_exit();
- if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
- goto out;
-#ifdef RCDEBUG
- printrcflags(rc, "rcstart");
-#endif
- ttwwakeup(tp);
-#ifdef RCDEBUG
- printf("rcstart: outq = %d obuf = %d\n",
- tp->t_outq.c_cc, rc->rc_obufend - rc->rc_optr);
-#endif
- if (tp->t_state & TS_BUSY)
- goto out; /* output still in progress ... */
-
- if (tp->t_outq.c_cc > 0) {
- u_int ocnt;
-
- tp->t_state |= TS_BUSY;
- ocnt = q_to_b(&tp->t_outq, rc->rc_obuf, sizeof rc->rc_obuf);
- critical_enter();
- rc->rc_optr = rc->rc_obuf;
- rc->rc_obufend = rc->rc_optr + ocnt;
- critical_exit();
- if (!(rc->rc_ier & IER_TxRdy)) {
-#ifdef RCDEBUG
- device_printf(sc->sc_dev,
- "channel %d: rcstart enable txint\n", rc->rc_chan);
-#endif
- rcout(sc, CD180_CAR, rc->rc_chan);
- rcout(sc, CD180_IER, rc->rc_ier |= IER_TxRdy);
- }
- }
-out:
- rc->rc_flags &= ~RC_OSBUSY;
- (void) splx(s);
-}
-
-/* Handle delayed events. */
-void
-rc_pollcard(void *arg)
-{
- struct rc_softc *sc;
- struct rc_chans *rc;
- struct tty *tp;
- u_char *tptr, *eptr;
- int chan, icnt;
-
- sc = (struct rc_softc *)arg;
- if (sc->sc_scheduled_event == 0)
- return;
- do {
- rc = sc->sc_channels;
- for (chan = 0; chan < CD180_NCHAN; rc++, chan++) {
- tp = rc->rc_tp;
-#ifdef RCDEBUG
- if (rc->rc_flags & (RC_DORXFER|RC_DOXXFER|RC_MODCHG|
- RC_WAS_BUFOVFL|RC_WAS_SILOVFL))
- printrcflags(rc, "rcevent");
-#endif
- if (rc->rc_flags & RC_WAS_BUFOVFL) {
- critical_enter();
- rc->rc_flags &= ~RC_WAS_BUFOVFL;
- sc->sc_scheduled_event--;
- critical_exit();
- device_printf(sc->sc_dev,
- "channel %d: interrupt-level buffer overflow\n",
- chan);
- }
- if (rc->rc_flags & RC_WAS_SILOVFL) {
- critical_enter();
- rc->rc_flags &= ~RC_WAS_SILOVFL;
- sc->sc_scheduled_event--;
- critical_exit();
- device_printf(sc->sc_dev,
- "channel %d: silo overflow\n", chan);
- }
- if (rc->rc_flags & RC_MODCHG) {
- critical_enter();
- rc->rc_flags &= ~RC_MODCHG;
- sc->sc_scheduled_event -= LOTS_OF_EVENTS;
- critical_exit();
- ttyld_modem(tp, !!(rc->rc_msvr & MSVR_CD));
- }
- if (rc->rc_flags & RC_DORXFER) {
- critical_enter();
- rc->rc_flags &= ~RC_DORXFER;
- eptr = rc->rc_iptr;
- if (rc->rc_bufend == &rc->rc_ibuf[2 * RC_IBUFSIZE])
- tptr = &rc->rc_ibuf[RC_IBUFSIZE];
- else
- tptr = rc->rc_ibuf;
- icnt = eptr - tptr;
- if (icnt > 0) {
- if (rc->rc_bufend == &rc->rc_ibuf[2 * RC_IBUFSIZE]) {
- rc->rc_iptr = rc->rc_ibuf;
- rc->rc_bufend = &rc->rc_ibuf[RC_IBUFSIZE];
- rc->rc_hiwat = &rc->rc_ibuf[RC_IHIGHWATER];
- } else {
- rc->rc_iptr = &rc->rc_ibuf[RC_IBUFSIZE];
- rc->rc_bufend = &rc->rc_ibuf[2 * RC_IBUFSIZE];
- rc->rc_hiwat =
- &rc->rc_ibuf[RC_IBUFSIZE + RC_IHIGHWATER];
- }
- if ( (rc->rc_flags & RC_RTSFLOW)
- && (tp->t_state & TS_ISOPEN)
- && !(tp->t_state & TS_TBLOCK)
- && !(rc->rc_msvr & MSVR_RTS)
- ) {
- rcout(sc, CD180_CAR, chan);
- rcout(sc, CD180_MSVR,
- rc->rc_msvr |= MSVR_RTS);
- }
- sc->sc_scheduled_event -= icnt;
- }
- critical_exit();
-
- if (icnt <= 0 || !(tp->t_state & TS_ISOPEN))
- goto done1;
-
- if ( (tp->t_state & TS_CAN_BYPASS_L_RINT)
- && !(tp->t_state & TS_LOCAL)) {
- if ((tp->t_rawq.c_cc + icnt) >= RB_I_HIGH_WATER
- && ((rc->rc_flags & RC_RTSFLOW) || (tp->t_iflag & IXOFF))
- && !(tp->t_state & TS_TBLOCK))
- ttyblock(tp);
- tk_nin += icnt;
- tk_rawcc += icnt;
- tp->t_rawcc += icnt;
- if (b_to_q(tptr, icnt, &tp->t_rawq))
- device_printf(sc->sc_dev,
- "channel %d: tty-level buffer overflow\n",
- chan);
- ttwakeup(tp);
- if ((tp->t_state & TS_TTSTOP) && ((tp->t_iflag & IXANY)
- || (tp->t_cc[VSTART] == tp->t_cc[VSTOP]))) {
- tp->t_state &= ~TS_TTSTOP;
- tp->t_lflag &= ~FLUSHO;
- rc_start(tp);
- }
- } else {
- for (; tptr < eptr; tptr++)
- ttyld_rint(tp,
- (tptr[0] |
- rc_rcsrt[tptr[INPUT_FLAGS_SHIFT] & 0xF]));
- }
-done1: ;
- }
- if (rc->rc_flags & RC_DOXXFER) {
- critical_enter();
- sc->sc_scheduled_event -= LOTS_OF_EVENTS;
- rc->rc_flags &= ~RC_DOXXFER;
- rc->rc_tp->t_state &= ~TS_BUSY;
- critical_exit();
- ttyld_start(tp);
- }
- if (sc->sc_scheduled_event == 0)
- break;
- }
- } while (sc->sc_scheduled_event >= LOTS_OF_EVENTS);
-}
-
-static void
-rc_stop(struct tty *tp, int rw)
-{
- struct rc_softc *sc;
- struct rc_chans *rc;
- u_char *tptr, *eptr;
-
- rc = tp->t_sc;
- sc = rc->rc_rcb;
-#ifdef RCDEBUG
- device_printf(sc->sc_dev, "channel %d: rc_stop %s%s\n",
- rc->rc_chan, (rw & FWRITE)?"FWRITE ":"", (rw & FREAD)?"FREAD":"");
-#endif
- if (rw & FWRITE)
- rc_discard_output(rc);
- critical_enter();
- if (rw & FREAD) {
- rc->rc_flags &= ~RC_DORXFER;
- eptr = rc->rc_iptr;
- if (rc->rc_bufend == &rc->rc_ibuf[2 * RC_IBUFSIZE]) {
- tptr = &rc->rc_ibuf[RC_IBUFSIZE];
- rc->rc_iptr = &rc->rc_ibuf[RC_IBUFSIZE];
- } else {
- tptr = rc->rc_ibuf;
- rc->rc_iptr = rc->rc_ibuf;
- }
- sc->sc_scheduled_event -= eptr - tptr;
- }
- if (tp->t_state & TS_TTSTOP)
- rc->rc_flags |= RC_OSUSP;
- else
- rc->rc_flags &= ~RC_OSUSP;
- critical_exit();
-}
-
-static void
-rc_close(struct tty *tp)
-{
- struct rc_chans *rc;
- struct rc_softc *sc;
- int s;
-
- rc = tp->t_sc;
- sc = rc->rc_rcb;
- s = spltty();
- rcout(sc, CD180_CAR, rc->rc_chan);
-
- /* Disable rx/tx intrs */
- rcout(sc, CD180_IER, rc->rc_ier = 0);
- if ( (tp->t_cflag & HUPCL)
- || (!(rc->rc_flags & RC_ACTOUT)
- && !(rc->rc_msvr & MSVR_CD)
- && !(tp->t_cflag & CLOCAL))
- || !(tp->t_state & TS_ISOPEN)
- ) {
- CCRCMD(sc, rc->rc_chan, CCR_ResetChan);
- WAITFORCCR(sc, rc->rc_chan);
- (void) rc_modem(tp, SER_RTS, 0);
- ttydtrwaitstart(tp);
- }
- rc->rc_flags &= ~RC_ACTOUT;
- wakeup( &rc->rc_rcb); /* wake bi */
- wakeup(TSA_CARR_ON(tp));
- (void) splx(s);
-}
-
-/* Reset the bastard */
-static void
-rc_hwreset(struct rc_softc *sc, u_int chipid)
-{
- CCRCMD(sc, -1, CCR_HWRESET); /* Hardware reset */
- DELAY(20000);
- WAITFORCCR(sc, -1);
-
- rcout(sc, RC_CTOUT, 0); /* Clear timeout */
- rcout(sc, CD180_GIVR, chipid);
- rcout(sc, CD180_GICR, 0);
-
- /* Set Prescaler Registers (1 msec) */
- rcout(sc, CD180_PPRL, ((RC_OSCFREQ + 999) / 1000) & 0xFF);
- rcout(sc, CD180_PPRH, ((RC_OSCFREQ + 999) / 1000) >> 8);
-
- /* Initialize Priority Interrupt Level Registers */
- rcout(sc, CD180_PILR1, RC_PILR_MODEM);
- rcout(sc, CD180_PILR2, RC_PILR_TX);
- rcout(sc, CD180_PILR3, RC_PILR_RX);
-
- /* Reset DTR */
- rcout(sc, RC_DTREG, ~0);
-}
-
-/* Set channel parameters */
-static int
-rc_param(struct tty *tp, struct termios *ts)
-{
- struct rc_softc *sc;
- struct rc_chans *rc;
- int idivs, odivs, s, val, cflag, iflag, lflag, inpflow;
-
- if ( ts->c_ospeed < 0 || ts->c_ospeed > 76800
- || ts->c_ispeed < 0 || ts->c_ispeed > 76800
- )
- return (EINVAL);
- if (ts->c_ispeed == 0)
- ts->c_ispeed = ts->c_ospeed;
- odivs = RC_BRD(ts->c_ospeed);
- idivs = RC_BRD(ts->c_ispeed);
-
- rc = tp->t_sc;
- sc = rc->rc_rcb;
- s = spltty();
-
- /* Select channel */
- rcout(sc, CD180_CAR, rc->rc_chan);
-
- /* If speed == 0, hangup line */
- if (ts->c_ospeed == 0) {
- CCRCMD(sc, rc->rc_chan, CCR_ResetChan);
- WAITFORCCR(sc, rc->rc_chan);
- (void) rc_modem(tp, 0, SER_DTR);
- }
-
- tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
- cflag = ts->c_cflag;
- iflag = ts->c_iflag;
- lflag = ts->c_lflag;
-
- if (idivs > 0) {
- rcout(sc, CD180_RBPRL, idivs & 0xFF);
- rcout(sc, CD180_RBPRH, idivs >> 8);
- }
- if (odivs > 0) {
- rcout(sc, CD180_TBPRL, odivs & 0xFF);
- rcout(sc, CD180_TBPRH, odivs >> 8);
- }
-
- /* set timeout value */
- if (ts->c_ispeed > 0) {
- int itm = ts->c_ispeed > 2400 ? 5 : 10000 / ts->c_ispeed + 1;
-
- if ( !(lflag & ICANON)
- && ts->c_cc[VMIN] != 0 && ts->c_cc[VTIME] != 0
- && ts->c_cc[VTIME] * 10 > itm)
- itm = ts->c_cc[VTIME] * 10;
-
- rcout(sc, CD180_RTPR, itm <= 255 ? itm : 255);
- }
-
- switch (cflag & CSIZE) {
- case CS5: val = COR1_5BITS; break;
- case CS6: val = COR1_6BITS; break;
- case CS7: val = COR1_7BITS; break;
- default:
- case CS8: val = COR1_8BITS; break;
- }
- if (cflag & PARENB) {
- val |= COR1_NORMPAR;
- if (cflag & PARODD)
- val |= COR1_ODDP;
- if (!(cflag & INPCK))
- val |= COR1_Ignore;
- } else
- val |= COR1_Ignore;
- if (cflag & CSTOPB)
- val |= COR1_2SB;
- rcout(sc, CD180_COR1, val);
-
- /* Set FIFO threshold */
- val = ts->c_ospeed <= 4800 ? 1 : CD180_NFIFO / 2;
- inpflow = 0;
- if ( (iflag & IXOFF)
- && ( ts->c_cc[VSTOP] != _POSIX_VDISABLE
- && ( ts->c_cc[VSTART] != _POSIX_VDISABLE
- || (iflag & IXANY)
- )
- )
- ) {
- inpflow = 1;
- val |= COR3_SCDE|COR3_FCT;
- }
- rcout(sc, CD180_COR3, val);
-
- /* Initialize on-chip automatic flow control */
- val = 0;
- rc->rc_flags &= ~(RC_CTSFLOW|RC_SEND_RDY);
- if (cflag & CCTS_OFLOW) {
- rc->rc_flags |= RC_CTSFLOW;
- val |= COR2_CtsAE;
- } else
- rc->rc_flags |= RC_SEND_RDY;
- if (tp->t_state & TS_TTSTOP)
- rc->rc_flags |= RC_OSUSP;
- else
- rc->rc_flags &= ~RC_OSUSP;
- if (cflag & CRTS_IFLOW)
- rc->rc_flags |= RC_RTSFLOW;
- else
- rc->rc_flags &= ~RC_RTSFLOW;
-
- if (inpflow) {
- if (ts->c_cc[VSTART] != _POSIX_VDISABLE)
- rcout(sc, CD180_SCHR1, ts->c_cc[VSTART]);
- rcout(sc, CD180_SCHR2, ts->c_cc[VSTOP]);
- val |= COR2_TxIBE;
- if (iflag & IXANY)
- val |= COR2_IXM;
- }
-
- rcout(sc, CD180_COR2, rc->rc_cor2 = val);
-
- CCRCMD(sc, rc->rc_chan, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
-
- ttyldoptim(tp);
-
- /* modem ctl */
- val = cflag & CLOCAL ? 0 : MCOR1_CDzd;
- if (cflag & CCTS_OFLOW)
- val |= MCOR1_CTSzd;
- rcout(sc, CD180_MCOR1, val);
-
- val = cflag & CLOCAL ? 0 : MCOR2_CDod;
- if (cflag & CCTS_OFLOW)
- val |= MCOR2_CTSod;
- rcout(sc, CD180_MCOR2, val);
-
- /* enable i/o and interrupts */
- CCRCMD(sc, rc->rc_chan,
- CCR_XMTREN | ((cflag & CREAD) ? CCR_RCVREN : CCR_RCVRDIS));
- WAITFORCCR(sc, rc->rc_chan);
-
- rc->rc_ier = cflag & CLOCAL ? 0 : IER_CD;
- if (cflag & CCTS_OFLOW)
- rc->rc_ier |= IER_CTS;
- if (cflag & CREAD)
- rc->rc_ier |= IER_RxData;
- if (tp->t_state & TS_BUSY)
- rc->rc_ier |= IER_TxRdy;
- if (ts->c_ospeed != 0)
- rc_modem(tp, SER_DTR, 0);
- if ((cflag & CCTS_OFLOW) && (rc->rc_msvr & MSVR_CTS))
- rc->rc_flags |= RC_SEND_RDY;
- rcout(sc, CD180_IER, rc->rc_ier);
- (void) splx(s);
- return 0;
-}
-
-/* Re-initialize board after bogus interrupts */
-static void
-rc_reinit(struct rc_softc *sc)
-{
- struct rc_chans *rc;
- int i;
-
- rc_hwreset(sc, RC_FAKEID);
- rc = sc->sc_channels;
- for (i = 0; i < CD180_NCHAN; i++, rc++)
- (void) rc_param(rc->rc_tp, &rc->rc_tp->t_termios);
-}
-
-/* Modem control routines */
-
-static int
-rc_modem(struct tty *tp, int biton, int bitoff)
-{
- struct rc_chans *rc;
- struct rc_softc *sc;
- u_char *dtr;
- u_char msvr;
-
- rc = tp->t_sc;
- sc = rc->rc_rcb;
- dtr = &sc->sc_dtr;
- rcout(sc, CD180_CAR, rc->rc_chan);
-
- if (biton == 0 && bitoff == 0) {
- msvr = rc->rc_msvr = rcin(sc, CD180_MSVR);
-
- if (msvr & MSVR_RTS)
- biton |= SER_RTS;
- if (msvr & MSVR_CTS)
- biton |= SER_CTS;
- if (msvr & MSVR_DSR)
- biton |= SER_DSR;
- if (msvr & MSVR_DTR)
- biton |= SER_DTR;
- if (msvr & MSVR_CD)
- biton |= SER_DCD;
- if (~rcin(sc, RC_RIREG) & (1 << rc->rc_chan))
- biton |= SER_RI;
- return biton;
- }
- if (biton & SER_DTR)
- rcout(sc, RC_DTREG, ~(*dtr |= 1 << rc->rc_chan));
- if (bitoff & SER_DTR)
- rcout(sc, RC_DTREG, ~(*dtr &= ~(1 << rc->rc_chan)));
- msvr = rcin(sc, CD180_MSVR);
- if (biton & SER_DTR)
- msvr |= MSVR_DTR;
- if (bitoff & SER_DTR)
- msvr &= ~MSVR_DTR;
- if (biton & SER_RTS)
- msvr |= MSVR_RTS;
- if (bitoff & SER_RTS)
- msvr &= ~MSVR_RTS;
- rcout(sc, CD180_MSVR, msvr);
- return 0;
-}
-
-static void
-rc_break(struct tty *tp, int brk)
-{
- struct rc_chans *rc;
-
- rc = tp->t_sc;
-
- if (brk)
- rc->rc_pendcmd = CD180_C_SBRK;
- else
- rc->rc_pendcmd = CD180_C_EBRK;
-}
-
-#define ERR(s) do { \
- device_printf(sc->sc_dev, "%s", ""); \
- printf s ; \
- printf("\n"); \
- (void) splx(old_level); \
- return 1; \
-} while (0)
-
-/* Test the board. */
-int
-rc_test(struct rc_softc *sc)
-{
- int chan = 0;
- int i = 0, rcnt, old_level;
- unsigned int iack, chipid;
- unsigned short divs;
- static u_char ctest[] = "\377\125\252\045\244\0\377";
-#define CTLEN 8
-
- struct rtest {
- u_char txbuf[CD180_NFIFO]; /* TX buffer */
- u_char rxbuf[CD180_NFIFO]; /* RX buffer */
- int rxptr; /* RX pointer */
- int txptr; /* TX pointer */
- } tchans[CD180_NCHAN];
-
- old_level = spltty();
-
- chipid = RC_FAKEID;
-
- /* First, reset board to initial state */
- rc_hwreset(sc, chipid);
-
- divs = RC_BRD(19200);
-
- /* Initialize channels */
- for (chan = 0; chan < CD180_NCHAN; chan++) {
-
- /* Select and reset channel */
- rcout(sc, CD180_CAR, chan);
- CCRCMD(sc, chan, CCR_ResetChan);
- WAITFORCCR(sc, chan);
-
- /* Set speed */
- rcout(sc, CD180_RBPRL, divs & 0xFF);
- rcout(sc, CD180_RBPRH, divs >> 8);
- rcout(sc, CD180_TBPRL, divs & 0xFF);
- rcout(sc, CD180_TBPRH, divs >> 8);
-
- /* set timeout value */
- rcout(sc, CD180_RTPR, 0);
-
- /* Establish local loopback */
- rcout(sc, CD180_COR1, COR1_NOPAR | COR1_8BITS | COR1_1SB);
- rcout(sc, CD180_COR2, COR2_LLM);
- rcout(sc, CD180_COR3, CD180_NFIFO);
- CCRCMD(sc, chan, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
- CCRCMD(sc, chan, CCR_RCVREN | CCR_XMTREN);
- WAITFORCCR(sc, chan);
- rcout(sc, CD180_MSVR, MSVR_RTS);
-
- /* Fill TXBUF with test data */
- for (i = 0; i < CD180_NFIFO; i++) {
- tchans[chan].txbuf[i] = ctest[i];
- tchans[chan].rxbuf[i] = 0;
- }
- tchans[chan].txptr = tchans[chan].rxptr = 0;
-
- /* Now, start transmit */
- rcout(sc, CD180_IER, IER_TxMpty|IER_RxData);
- }
- /* Pseudo-interrupt poll stuff */
- for (rcnt = 10000; rcnt-- > 0; rcnt--) {
- i = ~(rcin(sc, RC_BSR));
- if (i & RC_BSR_TOUT)
- ERR(("BSR timeout bit set\n"));
- else if (i & RC_BSR_TXINT) {
- iack = rcin(sc, RC_PILR_TX);
- if (iack != (GIVR_IT_TDI | chipid))
- ERR(("Bad TX intr ack (%02x != %02x)\n",
- iack, GIVR_IT_TDI | chipid));
- chan = (rcin(sc, CD180_GICR) & GICR_CHAN) >> GICR_LSH;
- /* If no more data to transmit, disable TX intr */
- if (tchans[chan].txptr >= CD180_NFIFO) {
- iack = rcin(sc, CD180_IER);
- rcout(sc, CD180_IER, iack & ~IER_TxMpty);
- } else {
- for (iack = tchans[chan].txptr;
- iack < CD180_NFIFO; iack++)
- rcout(sc, CD180_TDR,
- tchans[chan].txbuf[iack]);
- tchans[chan].txptr = iack;
- }
- rcout(sc, CD180_EOIR, 0);
- } else if (i & RC_BSR_RXINT) {
- u_char ucnt;
-
- iack = rcin(sc, RC_PILR_RX);
- if (iack != (GIVR_IT_RGDI | chipid) &&
- iack != (GIVR_IT_REI | chipid))
- ERR(("Bad RX intr ack (%02x != %02x)\n",
- iack, GIVR_IT_RGDI | chipid));
- chan = (rcin(sc, CD180_GICR) & GICR_CHAN) >> GICR_LSH;
- ucnt = rcin(sc, CD180_RDCR) & 0xF;
- while (ucnt-- > 0) {
- iack = rcin(sc, CD180_RCSR);
- if (iack & RCSR_Timeout)
- break;
- if (iack & 0xF)
- ERR(("Bad char chan %d (RCSR = %02X)\n",
- chan, iack));
- if (tchans[chan].rxptr > CD180_NFIFO)
- ERR(("Got extra chars chan %d\n",
- chan));
- tchans[chan].rxbuf[tchans[chan].rxptr++] =
- rcin(sc, CD180_RDR);
- }
- rcout(sc, CD180_EOIR, 0);
- }
- rcout(sc, RC_CTOUT, 0);
- for (iack = chan = 0; chan < CD180_NCHAN; chan++)
- if (tchans[chan].rxptr >= CD180_NFIFO)
- iack++;
- if (iack == CD180_NCHAN)
- break;
- }
- for (chan = 0; chan < CD180_NCHAN; chan++) {
- /* Select and reset channel */
- rcout(sc, CD180_CAR, chan);
- CCRCMD(sc, chan, CCR_ResetChan);
- }
-
- if (!rcnt)
- ERR(("looses characters during local loopback\n"));
- /* Now, check data */
- for (chan = 0; chan < CD180_NCHAN; chan++)
- for (i = 0; i < CD180_NFIFO; i++)
- if (ctest[i] != tchans[chan].rxbuf[i])
- ERR(("data mismatch chan %d ptr %d (%d != %d)\n",
- chan, i, ctest[i], tchans[chan].rxbuf[i]));
- (void) splx(old_level);
- return 0;
-}
-
-#ifdef RCDEBUG
-static void
-printrcflags(struct rc_chans *rc, char *comment)
-{
- struct rc_softc *sc;
- u_short f = rc->rc_flags;
-
- sc = rc->rc_rcb;
- printf("rc%d/%d: %s flags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
- rc->rc_rcb->rcb_unit, rc->rc_chan, comment,
- (f & RC_DTR_OFF)?"DTR_OFF " :"",
- (f & RC_ACTOUT) ?"ACTOUT " :"",
- (f & RC_RTSFLOW)?"RTSFLOW " :"",
- (f & RC_CTSFLOW)?"CTSFLOW " :"",
- (f & RC_DORXFER)?"DORXFER " :"",
- (f & RC_DOXXFER)?"DOXXFER " :"",
- (f & RC_MODCHG) ?"MODCHG " :"",
- (f & RC_OSUSP) ?"OSUSP " :"",
- (f & RC_OSBUSY) ?"OSBUSY " :"",
- (f & RC_WAS_BUFOVFL) ?"BUFOVFL " :"",
- (f & RC_WAS_SILOVFL) ?"SILOVFL " :"",
- (f & RC_SEND_RDY) ?"SEND_RDY":"");
-
- rcout(sc, CD180_CAR, rc->rc_chan);
-
- printf("rc%d/%d: msvr %02x ier %02x ccsr %02x\n",
- rc->rc_rcb->rcb_unit, rc->rc_chan,
- rcin(sc, CD180_MSVR),
- rcin(sc, CD180_IER),
- rcin(sc, CD180_CCSR));
-}
-#endif /* RCDEBUG */
-
-static void
-rc_discard_output(struct rc_chans *rc)
-{
- critical_enter();
- if (rc->rc_flags & RC_DOXXFER) {
- rc->rc_rcb->sc_scheduled_event -= LOTS_OF_EVENTS;
- rc->rc_flags &= ~RC_DOXXFER;
- }
- rc->rc_optr = rc->rc_obufend;
- rc->rc_tp->t_state &= ~TS_BUSY;
- critical_exit();
- ttwwakeup(rc->rc_tp);
-}
-
-static void
-rc_wait0(struct rc_softc *sc, int chan, int line)
-{
- int rcnt;
-
- for (rcnt = 50; rcnt && rcin(sc, CD180_CCR); rcnt--)
- DELAY(30);
- if (rcnt == 0)
- device_printf(sc->sc_dev,
- "channel %d command timeout, rc.c line: %d\n", chan, line);
-}
-
-static device_method_t rc_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, rc_probe),
- DEVMETHOD(device_attach, rc_attach),
- DEVMETHOD(device_detach, rc_detach),
- { 0, 0 }
-};
-
-static driver_t rc_driver = {
- "rc",
- rc_methods, sizeof(struct rc_softc),
-};
-
-DRIVER_MODULE(rc, isa, rc_driver, rc_devclass, 0, 0);
Index: sys/dev/rc/rcreg.h
===================================================================
--- sys/dev/rc/rcreg.h
+++ sys/dev/rc/rcreg.h
@@ -1,72 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 1995 by Pavel Antonov, Moscow, Russia.
- * Copyright (C) 1995 by Andrey A. Chernov, Moscow, Russia.
- * All rights reserved.
- * Copyright (C) 2002 by John Baldwin <jhb@FreeBSD.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Cirrus Logic CD180 -based RISCom/8 board definitions
- */
-
-/* Oscillator frequency - 19660.08Mhz / 2 */
-#define RC_OSCFREQ 9830400
-
-#define RC_BRD(s) ((s) == 0 ? 0 : \
- (((RC_OSCFREQ + (s) / 2) / (s)) + CD180_CTICKS/2) / CD180_CTICKS)
-
-/* Riscom/8 board ISA I/O mapping */
-#define RC_IOMAP(r) ((((r) & 07) << 1) | (((r) & ~07) << 7))
-
-/* I/O commands */
-#define RC_OUT(sc, addr, value) \
- bus_space_write_1((sc)->sc_bt, (sc)->sc_bh, RC_IOMAP(addr), (value))
-#define RC_IN(sc, addr) \
- bus_space_read_1((sc)->sc_bt, (sc)->sc_bh, RC_IOMAP(addr))
-
-/* Riscom on-board registers (mapping assumed) */
-#define RC_RIREG 0x100 /* Ring Indicator Register (read-only) */
-#define RC_DTREG 0x100 /* DTR Register (write-only) */
-#define RC_BSR 0x101 /* Board Status Register (read-only) */
-#define RC_CTOUT 0x101 /* Clear Timeout (write-only) */
-
-/* Board Status Register */
-#define RC_BSR_TOUT 0x08 /* Timeout */
-#define RC_BSR_RXINT 0x04 /* Receiver Interrupt */
-#define RC_BSR_TXINT 0x02 /* Transmitter Interrupt */
-#define RC_BSR_MOINT 0x01 /* Modem Control Interrupt */
-
-/* Interrupt groups */
-#define RC_MODEMGRP 0x01 /* Modem interrupt group */
-#define RC_RXGRP 0x02 /* Receiver interrupt group */
-#define RC_TXGRP 0x04 /* Transmitter interrupt group */
-
-/* Priority Interrupt Level definitions */
-#define RC_PILR_MODEM (0x80 | RC_MODEMGRP)
-#define RC_PILR_RX (0x80 | RC_RXGRP )
-#define RC_PILR_TX (0x80 | RC_TXGRP )
Index: sys/dev/rp/rp.c
===================================================================
--- sys/dev/rp/rp.c
+++ sys/dev/rp/rp.c
@@ -1,1113 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) Comtrol Corporation <support@comtrol.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted prodived that the follwoing conditions
- * are met.
- * 1. Redistributions of source code must retain the above copyright
- * notive, this list of conditions and the following disclainer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials prodided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Comtrol Corporation.
- * 4. The name of Comtrol Corporation may not be used to endorse or
- * promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * rp.c - for RocketPort FreeBSD
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/endian.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <sys/bus.h>
-#include <sys/rman.h>
-
-#define ROCKET_C
-#include <dev/rp/rpreg.h>
-#include <dev/rp/rpvar.h>
-
-static const char RocketPortVersion[] = "3.02";
-
-static Byte_t RData[RDATASIZE] =
-{
- 0x00, 0x09, 0xf6, 0x82,
- 0x02, 0x09, 0x86, 0xfb,
- 0x04, 0x09, 0x00, 0x0a,
- 0x06, 0x09, 0x01, 0x0a,
- 0x08, 0x09, 0x8a, 0x13,
- 0x0a, 0x09, 0xc5, 0x11,
- 0x0c, 0x09, 0x86, 0x85,
- 0x0e, 0x09, 0x20, 0x0a,
- 0x10, 0x09, 0x21, 0x0a,
- 0x12, 0x09, 0x41, 0xff,
- 0x14, 0x09, 0x82, 0x00,
- 0x16, 0x09, 0x82, 0x7b,
- 0x18, 0x09, 0x8a, 0x7d,
- 0x1a, 0x09, 0x88, 0x81,
- 0x1c, 0x09, 0x86, 0x7a,
- 0x1e, 0x09, 0x84, 0x81,
- 0x20, 0x09, 0x82, 0x7c,
- 0x22, 0x09, 0x0a, 0x0a
-};
-
-static Byte_t RRegData[RREGDATASIZE]=
-{
- 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
- 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
- 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
- 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
- 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
- 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
- 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
- 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
- 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
- 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
- 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
- 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
- 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
-};
-
-#if 0
-/* IRQ number to MUDBAC register 2 mapping */
-Byte_t sIRQMap[16] =
-{
- 0,0,0,0x10,0x20,0x30,0,0,0,0x40,0x50,0x60,0x70,0,0,0x80
-};
-#endif
-
-Byte_t rp_sBitMapClrTbl[8] =
-{
- 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f
-};
-
-Byte_t rp_sBitMapSetTbl[8] =
-{
- 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
-};
-
-static void rpfree(void *);
-
-/***************************************************************************
-Function: sReadAiopID
-Purpose: Read the AIOP idenfication number directly from an AIOP.
-Call: sReadAiopID(CtlP, aiop)
- CONTROLLER_T *CtlP; Ptr to controller structure
- int aiop: AIOP index
-Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X
- is replace by an identifying number.
- Flag AIOPID_NULL if no valid AIOP is found
-Warnings: No context switches are allowed while executing this function.
-
-*/
-int sReadAiopID(CONTROLLER_T *CtlP, int aiop)
-{
- Byte_t AiopID; /* ID byte from AIOP */
-
- rp_writeaiop1(CtlP, aiop, _CMD_REG, RESET_ALL); /* reset AIOP */
- rp_writeaiop1(CtlP, aiop, _CMD_REG, 0x0);
- AiopID = rp_readaiop1(CtlP, aiop, _CHN_STAT0) & 0x07;
- if(AiopID == 0x06)
- return(1);
- else /* AIOP does not exist */
- return(-1);
-}
-
-/***************************************************************************
-Function: sReadAiopNumChan
-Purpose: Read the number of channels available in an AIOP directly from
- an AIOP.
-Call: sReadAiopNumChan(CtlP, aiop)
- CONTROLLER_T *CtlP; Ptr to controller structure
- int aiop: AIOP index
-Return: int: The number of channels available
-Comments: The number of channels is determined by write/reads from identical
- offsets within the SRAM address spaces for channels 0 and 4.
- If the channel 4 space is mirrored to channel 0 it is a 4 channel
- AIOP, otherwise it is an 8 channel.
-Warnings: No context switches are allowed while executing this function.
-*/
-int sReadAiopNumChan(CONTROLLER_T *CtlP, int aiop)
-{
- Word_t x, y;
-
- rp_writeaiop4(CtlP, aiop, _INDX_ADDR,0x12340000L); /* write to chan 0 SRAM */
- rp_writeaiop2(CtlP, aiop, _INDX_ADDR,0); /* read from SRAM, chan 0 */
- x = rp_readaiop2(CtlP, aiop, _INDX_DATA);
- rp_writeaiop2(CtlP, aiop, _INDX_ADDR,0x4000); /* read from SRAM, chan 4 */
- y = rp_readaiop2(CtlP, aiop, _INDX_DATA);
- if(x != y) /* if different must be 8 chan */
- return(8);
- else
- return(4);
-}
-
-/***************************************************************************
-Function: sInitChan
-Purpose: Initialization of a channel and channel structure
-Call: sInitChan(CtlP,ChP,AiopNum,ChanNum)
- CONTROLLER_T *CtlP; Ptr to controller structure
- CHANNEL_T *ChP; Ptr to channel structure
- int AiopNum; AIOP number within controller
- int ChanNum; Channel number within AIOP
-Return: int: TRUE if initialization succeeded, FALSE if it fails because channel
- number exceeds number of channels available in AIOP.
-Comments: This function must be called before a channel can be used.
-Warnings: No range checking on any of the parameters is done.
-
- No context switches are allowed while executing this function.
-*/
-int sInitChan( CONTROLLER_T *CtlP,
- CHANNEL_T *ChP,
- int AiopNum,
- int ChanNum)
-{
- int i, ChOff;
- Byte_t *ChR;
- static Byte_t R[4];
-
- if(ChanNum >= CtlP->AiopNumChan[AiopNum])
- return(FALSE); /* exceeds num chans in AIOP */
-
- /* Channel, AIOP, and controller identifiers */
- ChP->CtlP = CtlP;
- ChP->ChanID = CtlP->AiopID[AiopNum];
- ChP->AiopNum = AiopNum;
- ChP->ChanNum = ChanNum;
-
- /* Initialize the channel from the RData array */
- for(i=0; i < RDATASIZE; i+=4)
- {
- R[0] = RData[i];
- R[1] = RData[i+1] + 0x10 * ChanNum;
- R[2] = RData[i+2];
- R[3] = RData[i+3];
- rp_writech4(ChP,_INDX_ADDR,le32dec(R));
- }
-
- ChR = ChP->R;
- for(i=0; i < RREGDATASIZE; i+=4)
- {
- ChR[i] = RRegData[i];
- ChR[i+1] = RRegData[i+1] + 0x10 * ChanNum;
- ChR[i+2] = RRegData[i+2];
- ChR[i+3] = RRegData[i+3];
- }
-
- /* Indexed registers */
- ChOff = (Word_t)ChanNum * 0x1000;
-
- ChP->BaudDiv[0] = (Byte_t)(ChOff + _BAUD);
- ChP->BaudDiv[1] = (Byte_t)((ChOff + _BAUD) >> 8);
- ChP->BaudDiv[2] = (Byte_t)BRD9600;
- ChP->BaudDiv[3] = (Byte_t)(BRD9600 >> 8);
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->BaudDiv));
-
- ChP->TxControl[0] = (Byte_t)(ChOff + _TX_CTRL);
- ChP->TxControl[1] = (Byte_t)((ChOff + _TX_CTRL) >> 8);
- ChP->TxControl[2] = 0;
- ChP->TxControl[3] = 0;
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxControl));
-
- ChP->RxControl[0] = (Byte_t)(ChOff + _RX_CTRL);
- ChP->RxControl[1] = (Byte_t)((ChOff + _RX_CTRL) >> 8);
- ChP->RxControl[2] = 0;
- ChP->RxControl[3] = 0;
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->RxControl));
-
- ChP->TxEnables[0] = (Byte_t)(ChOff + _TX_ENBLS);
- ChP->TxEnables[1] = (Byte_t)((ChOff + _TX_ENBLS) >> 8);
- ChP->TxEnables[2] = 0;
- ChP->TxEnables[3] = 0;
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxEnables));
-
- ChP->TxCompare[0] = (Byte_t)(ChOff + _TXCMP1);
- ChP->TxCompare[1] = (Byte_t)((ChOff + _TXCMP1) >> 8);
- ChP->TxCompare[2] = 0;
- ChP->TxCompare[3] = 0;
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxCompare));
-
- ChP->TxReplace1[0] = (Byte_t)(ChOff + _TXREP1B1);
- ChP->TxReplace1[1] = (Byte_t)((ChOff + _TXREP1B1) >> 8);
- ChP->TxReplace1[2] = 0;
- ChP->TxReplace1[3] = 0;
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxReplace1));
-
- ChP->TxReplace2[0] = (Byte_t)(ChOff + _TXREP2);
- ChP->TxReplace2[1] = (Byte_t)((ChOff + _TXREP2) >> 8);
- ChP->TxReplace2[2] = 0;
- ChP->TxReplace2[3] = 0;
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxReplace2));
-
- ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
- ChP->TxFIFO = ChOff + _TX_FIFO;
-
- rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */
- rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum); /* remove reset Tx FIFO count */
- rp_writech2(ChP,_INDX_ADDR,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
- rp_writech2(ChP,_INDX_DATA,0);
- ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
- ChP->RxFIFO = ChOff + _RX_FIFO;
-
- rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */
- rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum); /* remove reset Rx FIFO count */
- rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs); /* clear Rx out ptr */
- rp_writech2(ChP,_INDX_DATA,0);
- rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
- rp_writech2(ChP,_INDX_DATA,0);
- ChP->TxPrioCnt = ChOff + _TXP_CNT;
- rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioCnt);
- rp_writech1(ChP,_INDX_DATA,0);
- ChP->TxPrioPtr = ChOff + _TXP_PNTR;
- rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioPtr);
- rp_writech1(ChP,_INDX_DATA,0);
- ChP->TxPrioBuf = ChOff + _TXP_BUF;
- sEnRxProcessor(ChP); /* start the Rx processor */
-
- return(TRUE);
-}
-
-/***************************************************************************
-Function: sStopRxProcessor
-Purpose: Stop the receive processor from processing a channel.
-Call: sStopRxProcessor(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-
-Comments: The receive processor can be started again with sStartRxProcessor().
- This function causes the receive processor to skip over the
- stopped channel. It does not stop it from processing other channels.
-
-Warnings: No context switches are allowed while executing this function.
-
- Do not leave the receive processor stopped for more than one
- character time.
-
- After calling this function a delay of 4 uS is required to ensure
- that the receive processor is no longer processing this channel.
-*/
-void sStopRxProcessor(CHANNEL_T *ChP)
-{
- Byte_t R[4];
-
- R[0] = ChP->R[0];
- R[1] = ChP->R[1];
- R[2] = 0x0a;
- R[3] = ChP->R[3];
- rp_writech4(ChP,_INDX_ADDR,le32dec(R));
-}
-
-/***************************************************************************
-Function: sFlushRxFIFO
-Purpose: Flush the Rx FIFO
-Call: sFlushRxFIFO(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: void
-Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
- while it is being flushed the receive processor is stopped
- and the transmitter is disabled. After these operations a
- 4 uS delay is done before clearing the pointers to allow
- the receive processor to stop. These items are handled inside
- this function.
-Warnings: No context switches are allowed while executing this function.
-*/
-void sFlushRxFIFO(CHANNEL_T *ChP)
-{
- int i;
- Byte_t Ch; /* channel number within AIOP */
- int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */
-
- if(sGetRxCnt(ChP) == 0) /* Rx FIFO empty */
- return; /* don't need to flush */
-
- RxFIFOEnabled = FALSE;
- if(ChP->R[0x32] == 0x08) /* Rx FIFO is enabled */
- {
- RxFIFOEnabled = TRUE;
- sDisRxFIFO(ChP); /* disable it */
- for(i=0; i < 2000/200; i++) /* delay 2 uS to allow proc to disable FIFO*/
- rp_readch1(ChP,_INT_CHAN); /* depends on bus i/o timing */
- }
- sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */
- Ch = (Byte_t)sGetChanNum(ChP);
- rp_writech1(ChP,_CMD_REG,Ch | RESRXFCNT); /* apply reset Rx FIFO count */
- rp_writech1(ChP,_CMD_REG,Ch); /* remove reset Rx FIFO count */
- rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs); /* clear Rx out ptr */
- rp_writech2(ChP,_INDX_DATA,0);
- rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
- rp_writech2(ChP,_INDX_DATA,0);
- if(RxFIFOEnabled)
- sEnRxFIFO(ChP); /* enable Rx FIFO */
-}
-
-/***************************************************************************
-Function: sFlushTxFIFO
-Purpose: Flush the Tx FIFO
-Call: sFlushTxFIFO(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: void
-Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
- while it is being flushed the receive processor is stopped
- and the transmitter is disabled. After these operations a
- 4 uS delay is done before clearing the pointers to allow
- the receive processor to stop. These items are handled inside
- this function.
-Warnings: No context switches are allowed while executing this function.
-*/
-void sFlushTxFIFO(CHANNEL_T *ChP)
-{
- int i;
- Byte_t Ch; /* channel number within AIOP */
- int TxEnabled; /* TRUE if transmitter enabled */
-
- if(sGetTxCnt(ChP) == 0) /* Tx FIFO empty */
- return; /* don't need to flush */
-
- TxEnabled = FALSE;
- if(ChP->TxControl[3] & TX_ENABLE)
- {
- TxEnabled = TRUE;
- sDisTransmit(ChP); /* disable transmitter */
- }
- sStopRxProcessor(ChP); /* stop Rx processor */
- for(i = 0; i < 4000/200; i++) /* delay 4 uS to allow proc to stop */
- rp_readch1(ChP,_INT_CHAN); /* depends on bus i/o timing */
- Ch = (Byte_t)sGetChanNum(ChP);
- rp_writech1(ChP,_CMD_REG,Ch | RESTXFCNT); /* apply reset Tx FIFO count */
- rp_writech1(ChP,_CMD_REG,Ch); /* remove reset Tx FIFO count */
- rp_writech2(ChP,_INDX_ADDR,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
- rp_writech2(ChP,_INDX_DATA,0);
- if(TxEnabled)
- sEnTransmit(ChP); /* enable transmitter */
- sStartRxProcessor(ChP); /* restart Rx processor */
-}
-
-/***************************************************************************
-Function: sWriteTxPrioByte
-Purpose: Write a byte of priority transmit data to a channel
-Call: sWriteTxPrioByte(ChP,Data)
- CHANNEL_T *ChP; Ptr to channel structure
- Byte_t Data; The transmit data byte
-
-Return: int: 1 if the bytes is successfully written, otherwise 0.
-
-Comments: The priority byte is transmitted before any data in the Tx FIFO.
-
-Warnings: No context switches are allowed while executing this function.
-*/
-int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data)
-{
- Byte_t DWBuf[4]; /* buffer for double word writes */
-
- if(sGetTxCnt(ChP) > 1) /* write it to Tx priority buffer */
- {
- rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioCnt); /* get priority buffer status */
- if(rp_readch1(ChP,_INDX_DATA) & PRI_PEND) /* priority buffer busy */
- return(0); /* nothing sent */
-
- le16enc(DWBuf,ChP->TxPrioBuf); /* data byte address */
-
- DWBuf[2] = Data; /* data byte value */
- DWBuf[3] = 0; /* priority buffer pointer */
- rp_writech4(ChP,_INDX_ADDR,le32dec(DWBuf)); /* write it out */
-
- le16enc(DWBuf,ChP->TxPrioCnt); /* Tx priority count address */
-
- DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */
- DWBuf[3] = 0; /* priority buffer pointer */
- rp_writech4(ChP,_INDX_ADDR,le32dec(DWBuf)); /* write it out */
- }
- else /* write it to Tx FIFO */
- {
- sWriteTxByte(ChP,sGetTxRxDataIO(ChP),Data);
- }
- return(1); /* 1 byte sent */
-}
-
-/***************************************************************************
-Function: sEnInterrupts
-Purpose: Enable one or more interrupts for a channel
-Call: sEnInterrupts(ChP,Flags)
- CHANNEL_T *ChP; Ptr to channel structure
- Word_t Flags: Interrupt enable flags, can be any combination
- of the following flags:
- TXINT_EN: Interrupt on Tx FIFO empty
- RXINT_EN: Interrupt on Rx FIFO at trigger level (see
- sSetRxTrigger())
- SRCINT_EN: Interrupt on SRC (Special Rx Condition)
- MCINT_EN: Interrupt on modem input change
- CHANINT_EN: Allow channel interrupt signal to the AIOP's
- Interrupt Channel Register.
-Return: void
-Comments: If an interrupt enable flag is set in Flags, that interrupt will be
- enabled. If an interrupt enable flag is not set in Flags, that
- interrupt will not be changed. Interrupts can be disabled with
- function sDisInterrupts().
-
- This function sets the appropriate bit for the channel in the AIOP's
- Interrupt Mask Register if the CHANINT_EN flag is set. This allows
- this channel's bit to be set in the AIOP's Interrupt Channel Register.
-
- Interrupts must also be globally enabled before channel interrupts
- will be passed on to the host. This is done with function
- sEnGlobalInt().
-
- In some cases it may be desirable to disable interrupts globally but
- enable channel interrupts. This would allow the global interrupt
- status register to be used to determine which AIOPs need service.
-*/
-void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags)
-{
- Byte_t Mask; /* Interrupt Mask Register */
-
- ChP->RxControl[2] |=
- ((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
-
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->RxControl));
-
- ChP->TxControl[2] |= ((Byte_t)Flags & TXINT_EN);
-
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxControl));
-
- if(Flags & CHANINT_EN)
- {
- Mask = rp_readch1(ChP,_INT_MASK) | rp_sBitMapSetTbl[ChP->ChanNum];
- rp_writech1(ChP,_INT_MASK,Mask);
- }
-}
-
-/***************************************************************************
-Function: sDisInterrupts
-Purpose: Disable one or more interrupts for a channel
-Call: sDisInterrupts(ChP,Flags)
- CHANNEL_T *ChP; Ptr to channel structure
- Word_t Flags: Interrupt flags, can be any combination
- of the following flags:
- TXINT_EN: Interrupt on Tx FIFO empty
- RXINT_EN: Interrupt on Rx FIFO at trigger level (see
- sSetRxTrigger())
- SRCINT_EN: Interrupt on SRC (Special Rx Condition)
- MCINT_EN: Interrupt on modem input change
- CHANINT_EN: Disable channel interrupt signal to the
- AIOP's Interrupt Channel Register.
-Return: void
-Comments: If an interrupt flag is set in Flags, that interrupt will be
- disabled. If an interrupt flag is not set in Flags, that
- interrupt will not be changed. Interrupts can be enabled with
- function sEnInterrupts().
-
- This function clears the appropriate bit for the channel in the AIOP's
- Interrupt Mask Register if the CHANINT_EN flag is set. This blocks
- this channel's bit from being set in the AIOP's Interrupt Channel
- Register.
-*/
-void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags)
-{
- Byte_t Mask; /* Interrupt Mask Register */
-
- ChP->RxControl[2] &=
- ~((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->RxControl));
- ChP->TxControl[2] &= ~((Byte_t)Flags & TXINT_EN);
- rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxControl));
-
- if(Flags & CHANINT_EN)
- {
- Mask = rp_readch1(ChP,_INT_MASK) & rp_sBitMapClrTbl[ChP->ChanNum];
- rp_writech1(ChP,_INT_MASK,Mask);
- }
-}
-
-/*********************************************************************
- Begin FreeBsd-specific driver code
-**********************************************************************/
-
-#define POLL_INTERVAL (hz / 100)
-
-#define RP_ISMULTIPORT(dev) ((dev)->id_flags & 0x1)
-#define RP_MPMASTER(dev) (((dev)->id_flags >> 8) & 0xff)
-#define RP_NOTAST4(dev) ((dev)->id_flags & 0x04)
-
-/*
- * The top-level routines begin here
- */
-
-static void rpclose(struct tty *tp);
-static void rphardclose(struct tty *tp);
-static int rpmodem(struct tty *, int, int);
-static int rpparam(struct tty *, struct termios *);
-static void rpstart(struct tty *);
-static int rpioctl(struct tty *, u_long, caddr_t, struct thread *);
-static int rpopen(struct tty *);
-
-static void rp_do_receive(struct rp_port *rp, struct tty *tp,
- CHANNEL_t *cp, unsigned int ChanStatus)
-{
- unsigned int CharNStat;
- int ToRecv, ch, err = 0;
-
- ToRecv = sGetRxCnt(cp);
- if(ToRecv == 0)
- return;
-
-/* If status indicates there are errored characters in the
- FIFO, then enter status mode (a word in FIFO holds
- characters and status)
-*/
-
- if(ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
- if(!(ChanStatus & STATMODE)) {
- ChanStatus |= STATMODE;
- sEnRxStatusMode(cp);
- }
- }
-/*
- if we previously entered status mode then read down the
- FIFO one word at a time, pulling apart the character and
- the status. Update error counters depending on status.
-*/
- tty_lock(tp);
- if(ChanStatus & STATMODE) {
- while(ToRecv) {
- CharNStat = rp_readch2(cp,sGetTxRxDataIO(cp));
- ch = CharNStat & 0xff;
-
- if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH))
- err |= TRE_FRAMING;
- else if (CharNStat & STMPARITYH)
- err |= TRE_PARITY;
- else if (CharNStat & STMRCVROVRH) {
- rp->rp_overflows++;
- err |= TRE_OVERRUN;
- }
-
- ttydisc_rint(tp, ch, err);
- ToRecv--;
- }
-/*
- After emtying FIFO in status mode, turn off status mode
-*/
-
- if(sGetRxCnt(cp) == 0) {
- sDisRxStatusMode(cp);
- }
- } else {
- ToRecv = sGetRxCnt(cp);
- while (ToRecv) {
- ch = rp_readch1(cp,sGetTxRxDataIO(cp));
- ttydisc_rint(tp, ch & 0xff, err);
- ToRecv--;
- }
- }
- ttydisc_rint_done(tp);
- tty_unlock(tp);
-}
-
-static void rp_handle_port(struct rp_port *rp)
-{
- CHANNEL_t *cp;
- struct tty *tp;
- unsigned int IntMask, ChanStatus;
-
- if(!rp)
- return;
-
- cp = &rp->rp_channel;
- tp = rp->rp_tty;
- IntMask = sGetChanIntID(cp);
- IntMask = IntMask & rp->rp_intmask;
- ChanStatus = sGetChanStatus(cp);
- if(IntMask & RXF_TRIG)
- rp_do_receive(rp, tp, cp, ChanStatus);
- if(IntMask & DELTA_CD) {
- if(ChanStatus & CD_ACT) {
- (void)ttydisc_modem(tp, 1);
- } else {
- (void)ttydisc_modem(tp, 0);
- }
- }
-/* oldcts = rp->rp_cts;
- rp->rp_cts = ((ChanStatus & CTS_ACT) != 0);
- if(oldcts != rp->rp_cts) {
- printf("CTS change (now %s)... on port %d\n", rp->rp_cts ? "on" : "off", rp->rp_port);
- }
-*/
-}
-
-static void rp_do_poll(void *arg)
-{
- CONTROLLER_t *ctl;
- struct rp_port *rp;
- struct tty *tp;
- int count;
- unsigned char CtlMask, AiopMask;
-
- rp = arg;
- tp = rp->rp_tty;
- tty_assert_locked(tp);
- ctl = rp->rp_ctlp;
- CtlMask = ctl->ctlmask(ctl);
- if (CtlMask & (1 << rp->rp_aiop)) {
- AiopMask = sGetAiopIntStatus(ctl, rp->rp_aiop);
- if (AiopMask & (1 << rp->rp_chan)) {
- rp_handle_port(rp);
- }
- }
-
- count = sGetTxCnt(&rp->rp_channel);
- if (count >= 0 && (count <= rp->rp_restart)) {
- rpstart(tp);
- }
- callout_schedule(&rp->rp_timer, POLL_INTERVAL);
-}
-
-static struct ttydevsw rp_tty_class = {
- .tsw_flags = TF_INITLOCK|TF_CALLOUT,
- .tsw_open = rpopen,
- .tsw_close = rpclose,
- .tsw_outwakeup = rpstart,
- .tsw_ioctl = rpioctl,
- .tsw_param = rpparam,
- .tsw_modem = rpmodem,
- .tsw_free = rpfree,
-};
-
-
-static void
-rpfree(void *softc)
-{
- struct rp_port *rp = softc;
- CONTROLLER_t *ctlp = rp->rp_ctlp;
-
- atomic_subtract_32(&ctlp->free, 1);
-}
-
-int
-rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports)
-{
- int unit;
- int num_chan;
- int aiop, chan, port;
- int ChanStatus;
- int retval;
- struct rp_port *rp;
- struct tty *tp;
-
- unit = device_get_unit(ctlp->dev);
-
- printf("RocketPort%d (Version %s) %d ports.\n", unit,
- RocketPortVersion, num_ports);
-
- ctlp->num_ports = num_ports;
- ctlp->rp = rp = (struct rp_port *)
- malloc(sizeof(struct rp_port) * num_ports, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (rp == NULL) {
- device_printf(ctlp->dev, "rp_attachcommon: Could not malloc rp_ports structures.\n");
- retval = ENOMEM;
- goto nogo;
- }
-
- port = 0;
- for(aiop=0; aiop < num_aiops; aiop++) {
- num_chan = sGetAiopNumChan(ctlp, aiop);
- for(chan=0; chan < num_chan; chan++, port++, rp++) {
- rp->rp_tty = tp = tty_alloc(&rp_tty_class, rp);
- callout_init_mtx(&rp->rp_timer, tty_getlock(tp), 0);
- rp->rp_port = port;
- rp->rp_ctlp = ctlp;
- rp->rp_unit = unit;
- rp->rp_chan = chan;
- rp->rp_aiop = aiop;
-
- rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT |
- DELTA_CD | DELTA_CTS | DELTA_DSR;
-#ifdef notdef
- ChanStatus = sGetChanStatus(&rp->rp_channel);
-#endif /* notdef */
- if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) {
- device_printf(ctlp->dev, "RocketPort sInitChan(%d, %d, %d) failed.\n",
- unit, aiop, chan);
- retval = ENXIO;
- goto nogo;
- }
- ChanStatus = sGetChanStatus(&rp->rp_channel);
- rp->rp_cts = (ChanStatus & CTS_ACT) != 0;
- tty_makedev(tp, NULL, "R%r%r", unit, port);
- }
- }
-
- mtx_init(&ctlp->hwmtx, "rp_hwmtx", NULL, MTX_DEF);
- ctlp->hwmtx_init = 1;
- return (0);
-
-nogo:
- rp_releaseresource(ctlp);
-
- return (retval);
-}
-
-void
-rp_releaseresource(CONTROLLER_t *ctlp)
-{
- struct rp_port *rp;
- int i;
-
- if (ctlp->rp != NULL) {
- for (i = 0; i < ctlp->num_ports; i++) {
- rp = ctlp->rp + i;
- atomic_add_32(&ctlp->free, 1);
- tty_lock(rp->rp_tty);
- tty_rel_gone(rp->rp_tty);
- }
- free(ctlp->rp, M_DEVBUF);
- ctlp->rp = NULL;
- }
-
- while (ctlp->free != 0) {
- pause("rpwt", hz / 10);
- }
-
- if (ctlp->hwmtx_init)
- mtx_destroy(&ctlp->hwmtx);
-}
-
-static int
-rpopen(struct tty *tp)
-{
- struct rp_port *rp;
- int flags;
- unsigned int IntMask, ChanStatus;
-
- rp = tty_softc(tp);
-
- flags = 0;
- flags |= SET_RTS;
- flags |= SET_DTR;
- rp->rp_channel.TxControl[3] =
- ((rp->rp_channel.TxControl[3]
- & ~(SET_RTS | SET_DTR)) | flags);
- rp_writech4(&rp->rp_channel,_INDX_ADDR,
- le32dec(rp->rp_channel.TxControl));
- sSetRxTrigger(&rp->rp_channel, TRIG_1);
- sDisRxStatusMode(&rp->rp_channel);
- sFlushRxFIFO(&rp->rp_channel);
- sFlushTxFIFO(&rp->rp_channel);
-
- sEnInterrupts(&rp->rp_channel,
- (TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN));
- sSetRxTrigger(&rp->rp_channel, TRIG_1);
-
- sDisRxStatusMode(&rp->rp_channel);
- sClrTxXOFF(&rp->rp_channel);
-
-/* sDisRTSFlowCtl(&rp->rp_channel);
- sDisCTSFlowCtl(&rp->rp_channel);
-*/
- sDisTxSoftFlowCtl(&rp->rp_channel);
-
- sStartRxProcessor(&rp->rp_channel);
-
- sEnRxFIFO(&rp->rp_channel);
- sEnTransmit(&rp->rp_channel);
-
-/* sSetDTR(&rp->rp_channel);
- sSetRTS(&rp->rp_channel);
-*/
-
- IntMask = sGetChanIntID(&rp->rp_channel);
- IntMask = IntMask & rp->rp_intmask;
- ChanStatus = sGetChanStatus(&rp->rp_channel);
-
- callout_reset(&rp->rp_timer, POLL_INTERVAL, rp_do_poll, rp);
-
- device_busy(rp->rp_ctlp->dev);
- return(0);
-}
-
-static void
-rpclose(struct tty *tp)
-{
- struct rp_port *rp;
-
- rp = tty_softc(tp);
- callout_stop(&rp->rp_timer);
- rphardclose(tp);
- device_unbusy(rp->rp_ctlp->dev);
-}
-
-static void
-rphardclose(struct tty *tp)
-{
- struct rp_port *rp;
- CHANNEL_t *cp;
-
- rp = tty_softc(tp);
- cp = &rp->rp_channel;
-
- sFlushRxFIFO(cp);
- sFlushTxFIFO(cp);
- sDisTransmit(cp);
- sDisInterrupts(cp, TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN);
- sDisRTSFlowCtl(cp);
- sDisCTSFlowCtl(cp);
- sDisTxSoftFlowCtl(cp);
- sClrTxXOFF(cp);
-
-#ifdef DJA
- if(tp->t_cflag&HUPCL || !(tp->t_state&TS_ISOPEN) || !tp->t_actout) {
- sClrDTR(cp);
- }
- if(ISCALLOUT(tp->t_dev)) {
- sClrDTR(cp);
- }
- tp->t_actout = FALSE;
- wakeup(&tp->t_actout);
- wakeup(TSA_CARR_ON(tp));
-#endif /* DJA */
-}
-
-static int
-rpioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
-{
- struct rp_port *rp;
-
- rp = tty_softc(tp);
- switch (cmd) {
- case TIOCSBRK:
- sSendBreak(&rp->rp_channel);
- return (0);
- case TIOCCBRK:
- sClrBreak(&rp->rp_channel);
- return (0);
- default:
- return ENOIOCTL;
- }
-}
-
-static int
-rpmodem(struct tty *tp, int sigon, int sigoff)
-{
- struct rp_port *rp;
- int i, j, k;
-
- rp = tty_softc(tp);
- if (sigon != 0 || sigoff != 0) {
- i = j = 0;
- if (sigon & SER_DTR)
- i = SET_DTR;
- if (sigoff & SER_DTR)
- j = SET_DTR;
- if (sigon & SER_RTS)
- i = SET_RTS;
- if (sigoff & SER_RTS)
- j = SET_RTS;
- rp->rp_channel.TxControl[3] &= ~i;
- rp->rp_channel.TxControl[3] |= j;
- rp_writech4(&rp->rp_channel,_INDX_ADDR,
- le32dec(rp->rp_channel.TxControl));
- } else {
- i = sGetChanStatusLo(&rp->rp_channel);
- j = rp->rp_channel.TxControl[3];
- k = 0;
- if (j & SET_DTR)
- k |= SER_DTR;
- if (j & SET_RTS)
- k |= SER_RTS;
- if (i & CD_ACT)
- k |= SER_DCD;
- if (i & DSR_ACT)
- k |= SER_DSR;
- if (i & CTS_ACT)
- k |= SER_CTS;
- return(k);
- }
- return (0);
-}
-
-static struct
-{
- int baud;
- int conversion;
-} baud_table[] = {
- {B0, 0}, {B50, BRD50}, {B75, BRD75},
- {B110, BRD110}, {B134, BRD134}, {B150, BRD150},
- {B200, BRD200}, {B300, BRD300}, {B600, BRD600},
- {B1200, BRD1200}, {B1800, BRD1800}, {B2400, BRD2400},
- {B4800, BRD4800}, {B9600, BRD9600}, {B19200, BRD19200},
- {B38400, BRD38400}, {B7200, BRD7200}, {B14400, BRD14400},
- {B57600, BRD57600}, {B76800, BRD76800},
- {B115200, BRD115200}, {B230400, BRD230400},
- {-1, -1}
-};
-
-static int rp_convert_baud(int baud) {
- int i;
-
- for (i = 0; baud_table[i].baud >= 0; i++) {
- if (baud_table[i].baud == baud)
- break;
- }
-
- return baud_table[i].conversion;
-}
-
-static int
-rpparam(tp, t)
- struct tty *tp;
- struct termios *t;
-{
- struct rp_port *rp;
- CHANNEL_t *cp;
- int cflag, iflag, oflag, lflag;
- int ospeed;
-#ifdef RPCLOCAL
- int devshift;
-#endif
-
- rp = tty_softc(tp);
- cp = &rp->rp_channel;
-
- cflag = t->c_cflag;
-#ifdef RPCLOCAL
- devshift = umynor / 32;
- devshift = 1 << devshift;
- if ( devshift & RPCLOCAL ) {
- cflag |= CLOCAL;
- }
-#endif
- iflag = t->c_iflag;
- oflag = t->c_oflag;
- lflag = t->c_lflag;
-
- ospeed = rp_convert_baud(t->c_ispeed);
- if(ospeed < 0 || t->c_ispeed != t->c_ospeed)
- return(EINVAL);
-
- if(t->c_ospeed == 0) {
- sClrDTR(cp);
- return(0);
- }
- rp->rp_fifo_lw = ((t->c_ospeed*2) / 1000) +1;
-
- /* Set baud rate ----- we only pay attention to ispeed */
- sSetDTR(cp);
- sSetRTS(cp);
- sSetBaud(cp, ospeed);
-
- if(cflag & CSTOPB) {
- sSetStop2(cp);
- } else {
- sSetStop1(cp);
- }
-
- if(cflag & PARENB) {
- sEnParity(cp);
- if(cflag & PARODD) {
- sSetOddParity(cp);
- } else {
- sSetEvenParity(cp);
- }
- }
- else {
- sDisParity(cp);
- }
- if((cflag & CSIZE) == CS8) {
- sSetData8(cp);
- rp->rp_imask = 0xFF;
- } else {
- sSetData7(cp);
- rp->rp_imask = 0x7F;
- }
-
- if(iflag & ISTRIP) {
- rp->rp_imask &= 0x7F;
- }
-
- if(cflag & CLOCAL) {
- rp->rp_intmask &= ~DELTA_CD;
- } else {
- rp->rp_intmask |= DELTA_CD;
- }
-
- /* Put flow control stuff here */
-
- if(cflag & CCTS_OFLOW) {
- sEnCTSFlowCtl(cp);
- } else {
- sDisCTSFlowCtl(cp);
- }
-
- if(cflag & CRTS_IFLOW) {
- rp->rp_rts_iflow = 1;
- } else {
- rp->rp_rts_iflow = 0;
- }
-
- if(cflag & CRTS_IFLOW) {
- sEnRTSFlowCtl(cp);
- } else {
- sDisRTSFlowCtl(cp);
- }
-
- return(0);
-}
-
-static void
-rpstart(struct tty *tp)
-{
- struct rp_port *rp;
- CHANNEL_t *cp;
- char flags;
- int xmit_fifo_room;
- int i, count, wcount;
-
- rp = tty_softc(tp);
- cp = &rp->rp_channel;
- flags = rp->rp_channel.TxControl[3];
-
- if(rp->rp_xmit_stopped) {
- sEnTransmit(cp);
- rp->rp_xmit_stopped = 0;
- }
-
- xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
- count = ttydisc_getc(tp, &rp->TxBuf, xmit_fifo_room);
- if(xmit_fifo_room > 0) {
- for( i = 0, wcount = count >> 1; wcount > 0; i += 2, wcount-- ) {
- rp_writech2(cp, sGetTxRxDataIO(cp), le16dec(&rp->TxBuf[i]));
- }
- if ( count & 1 ) {
- rp_writech1(cp, sGetTxRxDataIO(cp), rp->TxBuf[(count-1)]);
- }
- }
-}
Index: sys/dev/rp/rp_isa.c
===================================================================
--- sys/dev/rp/rp_isa.c
+++ sys/dev/rp/rp_isa.c
@@ -1,508 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) Comtrol Corporation <support@comtrol.com>
- * All rights reserved.
- *
- * ISA-specific part separated from:
- * sys/i386/isa/rp.c,v 1.33 1999/09/28 11:45:27 phk Exp
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted prodived that the follwoing conditions
- * are met.
- * 1. Redistributions of source code must retain the above copyright
- * notive, this list of conditions and the following disclainer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials prodided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Comtrol Corporation.
- * 4. The name of Comtrol Corporation may not be used to endorse or
- * promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/mutex.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <sys/bus.h>
-#include <sys/rman.h>
-
-#define ROCKET_C
-#include <dev/rp/rpreg.h>
-#include <dev/rp/rpvar.h>
-
-#include <isa/isavar.h>
-
-/* ISA-specific part of CONTROLLER_t */
-struct ISACONTROLLER_T {
- int MBaseIO; /* rid of the Mudbac controller for this controller */
- int MReg0IO; /* offset0 of the Mudbac controller for this controller */
- int MReg1IO; /* offset1 of the Mudbac controller for this controller */
- int MReg2IO; /* offset2 of the Mudbac controller for this controller */
- int MReg3IO; /* offset3 of the Mudbac controller for this controller */
- Byte_t MReg2;
- Byte_t MReg3;
-};
-typedef struct ISACONTROLLER_T ISACONTROLLER_t;
-
-#define ISACTL(ctlp) ((ISACONTROLLER_t *)((ctlp)->bus_ctlp))
-
-/***************************************************************************
-Function: sControllerEOI
-Purpose: Strobe the MUDBAC's End Of Interrupt bit.
-Call: sControllerEOI(MudbacCtlP,CtlP)
- CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
- CONTROLLER_T *CtlP; Ptr to controller structure
-*/
-#define sControllerEOI(MudbacCtlP,CtlP) \
- rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2 | INT_STROB)
-
-/***************************************************************************
-Function: sDisAiop
-Purpose: Disable I/O access to an AIOP
-Call: sDisAiop(MudbacCtlP,CtlP)
- CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
- CONTROLLER_T *CtlP; Ptr to controller structure
- int AiopNum; Number of AIOP on controller
-*/
-#define sDisAiop(MudbacCtlP,CtlP,AIOPNUM) \
-{ \
- ISACTL(CtlP)->MReg3 &= rp_sBitMapClrTbl[AIOPNUM]; \
- rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); \
-}
-
-/***************************************************************************
-Function: sEnAiop
-Purpose: Enable I/O access to an AIOP
-Call: sEnAiop(MudbacCtlP,CtlP)
- CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
- CONTROLLER_T *CtlP; Ptr to controller structure
- int AiopNum; Number of AIOP on controller
-*/
-#define sEnAiop(MudbacCtlP,CtlP,AIOPNUM) \
-{ \
- ISACTL(CtlP)->MReg3 |= rp_sBitMapSetTbl[AIOPNUM]; \
- rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); \
-}
-
-/***************************************************************************
-Function: sGetControllerIntStatus
-Purpose: Get the controller interrupt status
-Call: sGetControllerIntStatus(MudbacCtlP,CtlP)
- CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
- CONTROLLER_T *CtlP; Ptr to controller structure
-Return: Byte_t: The controller interrupt status in the lower 4
- bits. Bits 0 through 3 represent AIOP's 0
- through 3 respectively. If a bit is set that
- AIOP is interrupting. Bits 4 through 7 will
- always be cleared.
-*/
-#define sGetControllerIntStatus(MudbacCtlP,CtlP) \
- (rp_readio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg1IO) & 0x0f)
-
-static devclass_t rp_devclass;
-static CONTROLLER_t *rp_controller;
-static int rp_nisadevs;
-
-static int rp_probe(device_t dev);
-static int rp_attach(device_t dev);
-static void rp_isareleaseresource(CONTROLLER_t *ctlp);
-static int sInitController(CONTROLLER_T *CtlP,
- CONTROLLER_T *MudbacCtlP,
- int AiopNum,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly);
-static rp_aiop2rid_t rp_isa_aiop2rid;
-static rp_aiop2off_t rp_isa_aiop2off;
-static rp_ctlmask_t rp_isa_ctlmask;
-
-static int
-rp_probe(device_t dev)
-{
- int unit;
- CONTROLLER_t *controller;
- int num_aiops;
- CONTROLLER_t *ctlp;
- int retval;
-
- /*
- * We have no PnP RocketPort cards.
- * (At least according to LINT)
- */
- if (isa_get_logicalid(dev) != 0)
- return (ENXIO);
-
- /* We need IO port resource to configure an ISA device. */
- if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 0)
- return (ENXIO);
-
- unit = device_get_unit(dev);
- if (unit >= 4) {
- device_printf(dev, "rpprobe: unit number %d invalid.\n", unit);
- return (ENXIO);
- }
- device_printf(dev, "probing for RocketPort(ISA) unit %d.\n", unit);
-
- ctlp = device_get_softc(dev);
- bzero(ctlp, sizeof(*ctlp));
- ctlp->dev = dev;
- ctlp->aiop2rid = rp_isa_aiop2rid;
- ctlp->aiop2off = rp_isa_aiop2off;
- ctlp->ctlmask = rp_isa_ctlmask;
-
- /* The IO ports of AIOPs for an ISA controller are discrete. */
- ctlp->io_num = 1;
- ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO);
- ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (ctlp->io_rid == NULL || ctlp->io == NULL) {
- device_printf(dev, "rp_attach: Out of memory.\n");
- retval = ENOMEM;
- goto nogo;
- }
-
- ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (ctlp->bus_ctlp == NULL) {
- device_printf(dev, "rp_attach: Out of memory.\n");
- retval = ENOMEM;
- goto nogo;
- }
-
- ctlp->io_rid[0] = 0;
- if (rp_controller != NULL) {
- controller = rp_controller;
- ctlp->io[0] = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0x40, RF_ACTIVE);
- } else {
- controller = rp_controller = ctlp;
- ctlp->io[0] = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0x44, RF_ACTIVE);
- }
- if (ctlp->io[0] == NULL) {
- device_printf(dev, "rp_attach: Resource not available.\n");
- retval = ENXIO;
- goto nogo;
- }
-
- num_aiops = sInitController(ctlp,
- controller,
- MAX_AIOPS_PER_BOARD, 0,
- FREQ_DIS, 0);
- if (num_aiops <= 0) {
- device_printf(dev, "board%d init failed.\n", unit);
- retval = ENXIO;
- goto nogo;
- }
-
- if (rp_controller == NULL)
- rp_controller = controller;
- rp_nisadevs++;
-
- device_set_desc(dev, "RocketPort ISA");
-
- return (0);
-
-nogo:
- rp_isareleaseresource(ctlp);
-
- return (retval);
-}
-
-static int
-rp_attach(device_t dev)
-{
- int unit;
- int num_ports, num_aiops;
- int aiop;
- CONTROLLER_t *ctlp;
- int retval;
-
- unit = device_get_unit(dev);
-
- ctlp = device_get_softc(dev);
-
-#ifdef notdef
- num_aiops = sInitController(ctlp,
- rp_controller,
- MAX_AIOPS_PER_BOARD, 0,
- FREQ_DIS, 0);
-#else
- num_aiops = ctlp->NumAiop;
-#endif /* notdef */
-
- num_ports = 0;
- for(aiop=0; aiop < num_aiops; aiop++) {
- sResetAiopByNum(ctlp, aiop);
- sEnAiop(rp_controller, ctlp, aiop);
- num_ports += sGetAiopNumChan(ctlp, aiop);
- }
-
- retval = rp_attachcommon(ctlp, num_aiops, num_ports);
- if (retval != 0)
- goto nogo;
-
- return (0);
-
-nogo:
- rp_isareleaseresource(ctlp);
-
- return (retval);
-}
-
-static void
-rp_isareleaseresource(CONTROLLER_t *ctlp)
-{
- int i;
-
- rp_releaseresource(ctlp);
-
- if (ctlp == rp_controller)
- rp_controller = NULL;
- if (ctlp->io != NULL) {
- for (i = 0 ; i < MAX_AIOPS_PER_BOARD ; i++)
- if (ctlp->io[i] != NULL)
- bus_release_resource(ctlp->dev, SYS_RES_IOPORT, ctlp->io_rid[i], ctlp->io[i]);
- free(ctlp->io, M_DEVBUF);
- }
- if (ctlp->io_rid != NULL)
- free(ctlp->io_rid, M_DEVBUF);
- if (rp_controller != NULL && rp_controller->io[ISACTL(ctlp)->MBaseIO] != NULL) {
- bus_release_resource(rp_controller->dev, SYS_RES_IOPORT, rp_controller->io_rid[ISACTL(ctlp)->MBaseIO], rp_controller->io[ISACTL(ctlp)->MBaseIO]);
- rp_controller->io[ISACTL(ctlp)->MBaseIO] = NULL;
- rp_controller->io_rid[ISACTL(ctlp)->MBaseIO] = 0;
- }
- if (ctlp->bus_ctlp != NULL)
- free(ctlp->bus_ctlp, M_DEVBUF);
-}
-
-/***************************************************************************
-Function: sInitController
-Purpose: Initialization of controller global registers and controller
- structure.
-Call: sInitController(CtlP,MudbacCtlP,AiopNum,
- IRQNum,Frequency,PeriodicOnly)
- CONTROLLER_T *CtlP; Ptr to controller structure
- CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
- int AiopNum; Number of Aiops
- int IRQNum; Interrupt Request number. Can be any of the following:
- 0: Disable global interrupts
- 3: IRQ 3
- 4: IRQ 4
- 5: IRQ 5
- 9: IRQ 9
- 10: IRQ 10
- 11: IRQ 11
- 12: IRQ 12
- 15: IRQ 15
- Byte_t Frequency: A flag identifying the frequency
- of the periodic interrupt, can be any one of the following:
- FREQ_DIS - periodic interrupt disabled
- FREQ_137HZ - 137 Hertz
- FREQ_69HZ - 69 Hertz
- FREQ_34HZ - 34 Hertz
- FREQ_17HZ - 17 Hertz
- FREQ_9HZ - 9 Hertz
- FREQ_4HZ - 4 Hertz
- If IRQNum is set to 0 the Frequency parameter is
- overidden, it is forced to a value of FREQ_DIS.
- int PeriodicOnly: TRUE if all interrupts except the periodic
- interrupt are to be blocked.
- FALSE is both the periodic interrupt and
- other channel interrupts are allowed.
- If IRQNum is set to 0 the PeriodicOnly parameter is
- overidden, it is forced to a value of FALSE.
-Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
- initialization failed.
-
-Comments:
- If periodic interrupts are to be disabled but AIOP interrupts
- are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
-
- If interrupts are to be completely disabled set IRQNum to 0.
-
- Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
- invalid combination.
-
- This function performs initialization of global interrupt modes,
- but it does not actually enable global interrupts. To enable
- and disable global interrupts use functions sEnGlobalInt() and
- sDisGlobalInt(). Enabling of global interrupts is normally not
- done until all other initializations are complete.
-
- Even if interrupts are globally enabled, they must also be
- individually enabled for each channel that is to generate
- interrupts.
-
-Warnings: No range checking on any of the parameters is done.
-
- No context switches are allowed while executing this function.
-
- After this function all AIOPs on the controller are disabled,
- they can be enabled with sEnAiop().
-*/
-static int
-sInitController( CONTROLLER_T *CtlP,
- CONTROLLER_T *MudbacCtlP,
- int AiopNum,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly)
-{
- int i;
- int ctl_base, aiop_base, aiop_size;
-
- CtlP->CtlID = CTLID_0001; /* controller release 1 */
-
- ISACTL(CtlP)->MBaseIO = rp_nisadevs;
- if (MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] != NULL) {
- ISACTL(CtlP)->MReg0IO = 0x40 + 0;
- ISACTL(CtlP)->MReg1IO = 0x40 + 1;
- ISACTL(CtlP)->MReg2IO = 0x40 + 2;
- ISACTL(CtlP)->MReg3IO = 0x40 + 3;
- } else {
- MudbacCtlP->io_rid[ISACTL(CtlP)->MBaseIO] = ISACTL(CtlP)->MBaseIO;
- ctl_base = rman_get_start(MudbacCtlP->io[0]) + 0x40 + 0x400 * rp_nisadevs;
- MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] = bus_alloc_resource(MudbacCtlP->dev, SYS_RES_IOPORT, &CtlP->io_rid[ISACTL(CtlP)->MBaseIO], ctl_base, ctl_base + 3, 4, RF_ACTIVE);
- ISACTL(CtlP)->MReg0IO = 0;
- ISACTL(CtlP)->MReg1IO = 1;
- ISACTL(CtlP)->MReg2IO = 2;
- ISACTL(CtlP)->MReg3IO = 3;
- }
-#if 1
- ISACTL(CtlP)->MReg2 = 0; /* interrupt disable */
- ISACTL(CtlP)->MReg3 = 0; /* no periodic interrupts */
-#else
- if(sIRQMap[IRQNum] == 0) /* interrupts globally disabled */
- {
- ISACTL(CtlP)->MReg2 = 0; /* interrupt disable */
- ISACTL(CtlP)->MReg3 = 0; /* no periodic interrupts */
- }
- else
- {
- ISACTL(CtlP)->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */
- ISACTL(CtlP)->MReg3 = Frequency; /* set frequency */
- if(PeriodicOnly) /* periodic interrupt only */
- {
- ISACTL(CtlP)->MReg3 |= PERIODIC_ONLY;
- }
- }
-#endif
- rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2);
- rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3);
- sControllerEOI(MudbacCtlP,CtlP); /* clear EOI if warm init */
-
- /* Init AIOPs */
- CtlP->NumAiop = 0;
- for(i=0; i < AiopNum; i++)
- {
- if (CtlP->io[i] == NULL) {
- CtlP->io_rid[i] = i;
- aiop_base = rman_get_start(CtlP->io[0]) + 0x400 * i;
- if (rp_nisadevs == 0)
- aiop_size = 0x44;
- else
- aiop_size = 0x40;
- CtlP->io[i] = bus_alloc_resource(CtlP->dev, SYS_RES_IOPORT, &CtlP->io_rid[i], aiop_base, aiop_base + aiop_size - 1, aiop_size, RF_ACTIVE);
- } else
- aiop_base = rman_get_start(CtlP->io[i]);
- rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,
- ISACTL(CtlP)->MReg2IO,
- ISACTL(CtlP)->MReg2 | (i & 0x03)); /* AIOP index */
- rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,
- ISACTL(CtlP)->MReg0IO,
- (Byte_t)(aiop_base >> 6)); /* set up AIOP I/O in MUDBAC */
- sEnAiop(MudbacCtlP,CtlP,i); /* enable the AIOP */
-
- CtlP->AiopID[i] = sReadAiopID(CtlP, i); /* read AIOP ID */
- if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
- {
- sDisAiop(MudbacCtlP,CtlP,i); /* disable AIOP */
- bus_release_resource(CtlP->dev, SYS_RES_IOPORT, CtlP->io_rid[i], CtlP->io[i]);
- CtlP->io[i] = NULL;
- break; /* done looking for AIOPs */
- }
-
- CtlP->AiopNumChan[i] = sReadAiopNumChan(CtlP, i); /* num channels in AIOP */
- rp_writeaiop2(CtlP,i,_INDX_ADDR,_CLK_PRE); /* clock prescaler */
- rp_writeaiop1(CtlP,i,_INDX_DATA,CLOCK_PRESC);
- CtlP->NumAiop++; /* bump count of AIOPs */
- sDisAiop(MudbacCtlP,CtlP,i); /* disable AIOP */
- }
-
- if(CtlP->NumAiop == 0)
- return(-1);
- else
- return(CtlP->NumAiop);
-}
-
-/*
- * ARGSUSED
- * Maps (aiop, offset) to rid.
- */
-static int
-rp_isa_aiop2rid(int aiop, int offset)
-{
- /* rid equals to aiop for an ISA controller. */
- return aiop;
-}
-
-/*
- * ARGSUSED
- * Maps (aiop, offset) to the offset of resource.
- */
-static int
-rp_isa_aiop2off(int aiop, int offset)
-{
- /* Each aiop has its own resource. */
- return offset;
-}
-
-/* Read the int status for an ISA controller. */
-static unsigned char
-rp_isa_ctlmask(CONTROLLER_t *ctlp)
-{
- return sGetControllerIntStatus(rp_controller,ctlp);
-}
-
-static device_method_t rp_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, rp_probe),
- DEVMETHOD(device_attach, rp_attach),
-
- { 0, 0 }
-};
-
-static driver_t rp_driver = {
- "rp",
- rp_methods,
- sizeof(CONTROLLER_t),
-};
-
-/*
- * rp can be attached to an isa bus.
- */
-DRIVER_MODULE(rp, isa, rp_driver, rp_devclass, 0, 0);
Index: sys/dev/rp/rp_pci.c
===================================================================
--- sys/dev/rp/rp_pci.c
+++ sys/dev/rp/rp_pci.c
@@ -1,368 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) Comtrol Corporation <support@comtrol.com>
- * All rights reserved.
- *
- * PCI-specific part separated from:
- * sys/i386/isa/rp.c,v 1.33 1999/09/28 11:45:27 phk Exp
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted prodived that the follwoing conditions
- * are met.
- * 1. Redistributions of source code must retain the above copyright
- * notive, this list of conditions and the following disclainer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials prodided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Comtrol Corporation.
- * 4. The name of Comtrol Corporation may not be used to endorse or
- * promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/mutex.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <sys/bus.h>
-#include <sys/rman.h>
-
-#define ROCKET_C
-#include <dev/rp/rpreg.h>
-#include <dev/rp/rpvar.h>
-
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-
-/* PCI IDs */
-#define RP_VENDOR_ID 0x11FE
-#define RP_DEVICE_ID_32I 0x0001
-#define RP_DEVICE_ID_8I 0x0002
-#define RP_DEVICE_ID_16I 0x0003
-#define RP_DEVICE_ID_4Q 0x0004
-#define RP_DEVICE_ID_8O 0x0005
-#define RP_DEVICE_ID_8J 0x0006
-#define RP_DEVICE_ID_4J 0x0007
-#define RP_DEVICE_ID_6M 0x000C
-#define RP_DEVICE_ID_4M 0x000D
-#define RP_DEVICE_ID_UPCI_32 0x0801
-#define RP_DEVICE_ID_UPCI_16 0x0803
-#define RP_DEVICE_ID_UPCI_8O 0x0805
-
-/**************************************************************************
- MUDBAC remapped for PCI
-**************************************************************************/
-
-#define _CFG_INT_PCI 0x40
-#define _PCI_INT_FUNC 0x3A
-
-#define PCI_STROB 0x2000
-#define INTR_EN_PCI 0x0010
-
-/***************************************************************************
-Function: sPCIControllerEOI
-Purpose: Strobe the MUDBAC's End Of Interrupt bit.
-Call: sPCIControllerEOI(CtlP)
- CONTROLLER_T *CtlP; Ptr to controller structure
-*/
-#define sPCIControllerEOI(CtlP) rp_writeio2(CtlP, 0, _PCI_INT_FUNC, PCI_STROB)
-
-/***************************************************************************
-Function: sPCIGetControllerIntStatus
-Purpose: Get the controller interrupt status
-Call: sPCIGetControllerIntStatus(CtlP)
- CONTROLLER_T *CtlP; Ptr to controller structure
-Return: Byte_t: The controller interrupt status in the lower 4
- bits. Bits 0 through 3 represent AIOP's 0
- through 3 respectively. If a bit is set that
- AIOP is interrupting. Bits 4 through 7 will
- always be cleared.
-*/
-#define sPCIGetControllerIntStatus(CTLP) ((rp_readio2(CTLP, 0, _PCI_INT_FUNC) >> 8) & 0x1f)
-
-static devclass_t rp_devclass;
-
-static int rp_pciprobe(device_t dev);
-static int rp_pciattach(device_t dev);
-#ifdef notdef
-static int rp_pcidetach(device_t dev);
-static int rp_pcishutdown(device_t dev);
-#endif /* notdef */
-static void rp_pcireleaseresource(CONTROLLER_t *ctlp);
-static int sPCIInitController( CONTROLLER_t *CtlP,
- int AiopNum,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly,
- int VendorDevice);
-static rp_aiop2rid_t rp_pci_aiop2rid;
-static rp_aiop2off_t rp_pci_aiop2off;
-static rp_ctlmask_t rp_pci_ctlmask;
-
-/*
- * The following functions are the pci-specific part
- * of rp driver.
- */
-
-static int
-rp_pciprobe(device_t dev)
-{
- char *s;
-
- s = NULL;
- if (pci_get_vendor(dev) == RP_VENDOR_ID)
- s = "RocketPort PCI";
-
- if (s != NULL) {
- device_set_desc(dev, s);
- return (BUS_PROBE_DEFAULT);
- }
-
- return (ENXIO);
-}
-
-static int
-rp_pciattach(device_t dev)
-{
- int num_ports, num_aiops;
- int aiop;
- CONTROLLER_t *ctlp;
- int unit;
- int retval;
-
- ctlp = device_get_softc(dev);
- bzero(ctlp, sizeof(*ctlp));
- ctlp->dev = dev;
- unit = device_get_unit(dev);
- ctlp->aiop2rid = rp_pci_aiop2rid;
- ctlp->aiop2off = rp_pci_aiop2off;
- ctlp->ctlmask = rp_pci_ctlmask;
-
- /* The IO ports of AIOPs for a PCI controller are continuous. */
- ctlp->io_num = 1;
- ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * ctlp->io_num, M_DEVBUF, M_NOWAIT | M_ZERO);
- ctlp->io = malloc(sizeof(*(ctlp->io)) * ctlp->io_num, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (ctlp->io_rid == NULL || ctlp->io == NULL) {
- device_printf(dev, "rp_pciattach: Out of memory.\n");
- retval = ENOMEM;
- goto nogo;
- }
-
- ctlp->bus_ctlp = NULL;
-
- switch (pci_get_device(dev)) {
- case RP_DEVICE_ID_UPCI_16:
- case RP_DEVICE_ID_UPCI_32:
- case RP_DEVICE_ID_UPCI_8O:
- ctlp->io_rid[0] = PCIR_BAR(2);
- break;
- default:
- ctlp->io_rid[0] = PCIR_BAR(0);
- break;
- }
- ctlp->io[0] = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
- &ctlp->io_rid[0], RF_ACTIVE);
- if(ctlp->io[0] == NULL) {
- device_printf(dev, "ioaddr mapping failed for RocketPort(PCI).\n");
- retval = ENXIO;
- goto nogo;
- }
-
- num_aiops = sPCIInitController(ctlp,
- MAX_AIOPS_PER_BOARD, 0,
- FREQ_DIS, 0, pci_get_device(dev));
-
- num_ports = 0;
- for(aiop=0; aiop < num_aiops; aiop++) {
- sResetAiopByNum(ctlp, aiop);
- num_ports += sGetAiopNumChan(ctlp, aiop);
- }
-
- retval = rp_attachcommon(ctlp, num_aiops, num_ports);
- if (retval != 0)
- goto nogo;
-
- return (0);
-
-nogo:
- rp_pcireleaseresource(ctlp);
-
- return (retval);
-}
-
-static int
-rp_pcidetach(device_t dev)
-{
- CONTROLLER_t *ctlp;
-
- ctlp = device_get_softc(dev);
- rp_pcireleaseresource(ctlp);
-
- return (0);
-}
-
-static int
-rp_pcishutdown(device_t dev)
-{
- CONTROLLER_t *ctlp;
-
- ctlp = device_get_softc(dev);
- rp_pcireleaseresource(ctlp);
-
- return (0);
-}
-
-static void
-rp_pcireleaseresource(CONTROLLER_t *ctlp)
-{
- rp_releaseresource(ctlp);
- if (ctlp->io != NULL) {
- if (ctlp->io[0] != NULL)
- bus_release_resource(ctlp->dev, SYS_RES_IOPORT, ctlp->io_rid[0], ctlp->io[0]);
- free(ctlp->io, M_DEVBUF);
- ctlp->io = NULL;
- }
- if (ctlp->io_rid != NULL) {
- free(ctlp->io_rid, M_DEVBUF);
- ctlp->io = NULL;
- }
-}
-
-static int
-sPCIInitController( CONTROLLER_t *CtlP,
- int AiopNum,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly,
- int VendorDevice)
-{
- int i;
-
- CtlP->CtlID = CTLID_0001; /* controller release 1 */
-
- sPCIControllerEOI(CtlP);
-
- /* Init AIOPs */
- CtlP->NumAiop = 0;
- for(i=0; i < AiopNum; i++)
- {
- /*device_printf(CtlP->dev, "aiop %d.\n", i);*/
- CtlP->AiopID[i] = sReadAiopID(CtlP, i); /* read AIOP ID */
- /*device_printf(CtlP->dev, "ID = %d.\n", CtlP->AiopID[i]);*/
- if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
- {
- break; /* done looking for AIOPs */
- }
-
- switch( VendorDevice ) {
- case RP_DEVICE_ID_4Q:
- case RP_DEVICE_ID_4J:
- case RP_DEVICE_ID_4M:
- CtlP->AiopNumChan[i] = 4;
- break;
- case RP_DEVICE_ID_6M:
- CtlP->AiopNumChan[i] = 6;
- break;
- case RP_DEVICE_ID_8O:
- case RP_DEVICE_ID_8J:
- case RP_DEVICE_ID_8I:
- case RP_DEVICE_ID_16I:
- case RP_DEVICE_ID_32I:
- CtlP->AiopNumChan[i] = 8;
- break;
- default:
-#ifdef notdef
- CtlP->AiopNumChan[i] = 8;
-#else
- CtlP->AiopNumChan[i] = sReadAiopNumChan(CtlP, i);
-#endif /* notdef */
- break;
- }
- /*device_printf(CtlP->dev, "%d channels.\n", CtlP->AiopNumChan[i]);*/
- rp_writeaiop2(CtlP, i, _INDX_ADDR,_CLK_PRE); /* clock prescaler */
- /*device_printf(CtlP->dev, "configuring clock prescaler.\n");*/
- rp_writeaiop1(CtlP, i, _INDX_DATA,CLOCK_PRESC);
- /*device_printf(CtlP->dev, "configured clock prescaler.\n");*/
- CtlP->NumAiop++; /* bump count of AIOPs */
- }
-
- if(CtlP->NumAiop == 0)
- return(-1);
- else
- return(CtlP->NumAiop);
-}
-
-/*
- * ARGSUSED
- * Maps (aiop, offset) to rid.
- */
-static int
-rp_pci_aiop2rid(int aiop, int offset)
-{
- /* Always return zero for a PCI controller. */
- return 0;
-}
-
-/*
- * ARGSUSED
- * Maps (aiop, offset) to the offset of resource.
- */
-static int
-rp_pci_aiop2off(int aiop, int offset)
-{
- /* Each AIOP reserves 0x40 bytes. */
- return aiop * 0x40 + offset;
-}
-
-/* Read the int status for a PCI controller. */
-static unsigned char
-rp_pci_ctlmask(CONTROLLER_t *ctlp)
-{
- return sPCIGetControllerIntStatus(ctlp);
-}
-
-static device_method_t rp_pcimethods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, rp_pciprobe),
- DEVMETHOD(device_attach, rp_pciattach),
- DEVMETHOD(device_detach, rp_pcidetach),
- DEVMETHOD(device_shutdown, rp_pcishutdown),
-
- { 0, 0 }
-};
-
-static driver_t rp_pcidriver = {
- "rp",
- rp_pcimethods,
- sizeof(CONTROLLER_t),
-};
-
-/*
- * rp can be attached to a pci bus.
- */
-DRIVER_MODULE(rp, pci, rp_pcidriver, rp_devclass, 0, 0);
Index: sys/dev/rp/rpreg.h
===================================================================
--- sys/dev/rp/rpreg.h
+++ sys/dev/rp/rpreg.h
@@ -1,1033 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) Comtrol Corporation <support@comtrol.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted prodived that the follwoing conditions
- * are met.
- * 1. Redistributions of source code must retain the above copyright
- * notive, this list of conditions and the following disclainer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials prodided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Comtrol Corporation.
- * 4. The name of Comtrol Corporation may not be used to endorse or
- * promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Begin OS-specific defines - rpreg.h - for RocketPort FreeBSD
- */
-
-typedef uint8_t Byte_t;
-typedef uint8_t ByteIO_t;
-
-typedef uint16_t Word_t;
-typedef uint16_t WordIO_t;
-
-typedef uint32_t DWord_t;
-typedef uint32_t DWordIO_t;
-
-#define rp_readio(size, ctlp, rid, offset) \
- (bus_read_##size(ctlp->io[rid], offset))
-#define rp_readmultiio(size, ctlp, rid, offset, addr, count) \
- (bus_read_multi_##size(ctlp->io[rid], offset, addr, count))
-#define rp_writeio(size, ctlp, rid, offset, data) \
- (bus_write_##size(ctlp->io[rid], offset, data))
-#define rp_writemultiio(size, ctlp, rid, offset, addr, count) \
- (bus_write_multi_##size(ctlp->io[rid], offset, addr, count))
-
-#define rp_readio1(ctlp, rid, offset) rp_readio(1, ctlp, rid, offset)
-#define rp_readio2(ctlp, rid, offset) rp_readio(2, ctlp, rid, offset)
-#define rp_readio4(ctlp, rid, offset) rp_readio(4, ctlp, rid, offset)
-#define rp_writeio1(ctlp, rid, offset, data) rp_writeio(1, ctlp, rid, offset, data)
-#define rp_writeio2(ctlp, rid, offset, data) rp_writeio(2, ctlp, rid, offset, data)
-#define rp_writeio4(ctlp, rid, offset, data) rp_writeio(4, ctlp, rid, offset, data)
-#define rp_readmultiio1(ctlp, rid, offset, addr, count) rp_readmultiio(1, ctlp, rid, offset, addr, count)
-#define rp_readmultiio2(ctlp, rid, offset, addr, count) rp_readmultiio(2, ctlp, rid, offset, addr, count)
-#define rp_readmultiio4(ctlp, rid, offset, addr, count) rp_readmultiio(4, ctlp, rid, offset, addr, count)
-#define rp_writemultiio1(ctlp, rid, offset, addr, count) rp_writemultiio(1, ctlp, rid, offset, addr, count)
-#define rp_writemultiio2(ctlp, rid, offset, addr, count) rp_writemultiio(2, ctlp, rid, offset, addr, count)
-#define rp_writemultiio4(ctlp, rid, offset, addr, count) rp_writemultiio(4, ctlp, rid, offset, addr, count)
-
-#define rp_readaiop1(ctlp, aiop, offset) \
- (rp_readio1((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset)))
-#define rp_readaiop2(ctlp, aiop, offset) \
- (rp_readio2((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset)))
-#define rp_readaiop4(ctlp, aiop, offset) \
- (rp_readio4((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset)))
-#define rp_readmultiaiop1(ctlp, aiop, offset, addr, count) \
- (rp_readmultiio1((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
-#define rp_readmultiaiop2(ctlp, aiop, offset, addr, count) \
- (rp_readmultiio2((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
-#define rp_readmultiaiop4(ctlp, aiop, offset, addr, count) \
- (rp_readmultiio4((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
-#define rp_writeaiop1(ctlp, aiop, offset, data) \
- (rp_writeio1((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), data))
-#define rp_writeaiop2(ctlp, aiop, offset, data) \
- (rp_writeio2((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), data))
-#define rp_writeaiop4(ctlp, aiop, offset, data) \
- (rp_writeio4((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), data))
-#define rp_writemultiaiop1(ctlp, aiop, offset, addr, count) \
- (rp_writemultiio1((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
-#define rp_writemultiaiop2(ctlp, aiop, offset, addr, count) \
- (rp_writemultiio2((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
-#define rp_writemultiaiop4(ctlp, aiop, offset, addr, count) \
- (rp_writemultiio4((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
-
-#define rp_readch1(chp, offset) \
- (rp_readaiop1((chp)->CtlP, (chp)->AiopNum, offset))
-#define rp_readch2(chp, offset) \
- (rp_readaiop2((chp)->CtlP, (chp)->AiopNum, offset))
-#define rp_readch4(chp, offset) \
- (rp_readaiop4((chp)->CtlP, (chp)->AiopNum, offset))
-#define rp_readmultich1(chp, offset, addr, count) \
- (rp_readmultiaiop1((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
-#define rp_readmultich2(chp, offset, addr, count) \
- (rp_readmultiaiop2((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
-#define rp_readmultich4(chp, offset, addr, count) \
- (rp_readmultiaiop4((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
-#define rp_writech1(chp, offset, data) \
- (rp_writeaiop1((chp)->CtlP, (chp)->AiopNum, offset, data))
-#define rp_writech2(chp, offset, data) \
- (rp_writeaiop2((chp)->CtlP, (chp)->AiopNum, offset, data))
-#define rp_writech4(chp, offset, data) \
- (rp_writeaiop4((chp)->CtlP, (chp)->AiopNum, offset, data))
-#define rp_writemultich1(chp, offset, addr, count) \
- (rp_writemultiaiop1((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
-#define rp_writemultich2(chp, offset, addr, count) \
- (rp_writemultiaiop2((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
-#define rp_writemultich4(chp, offset, addr, count) \
- (rp_writemultiaiop4((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
-
-/*
- * End of OS-specific defines
- */
-
-#define ROCKET_H
-
-#define CTL_SIZE 4
-#define AIOP_CTL_SIZE 4
-#define CHAN_AIOP_SIZE 8
-#define MAX_PORTS_PER_AIOP 8
-#define MAX_AIOPS_PER_BOARD 4
-#define MAX_PORTS_PER_BOARD 32
-
-/* Controller ID numbers */
-#define CTLID_NULL -1 /* no controller exists */
-#define CTLID_0001 0x0001 /* controller release 1 */
-
-/* AIOP ID numbers, identifies AIOP type implementing channel */
-#define AIOPID_NULL -1 /* no AIOP or channel exists */
-#define AIOPID_0001 0x0001 /* AIOP release 1 */
-
-#define NULLDEV -1 /* identifies non-existant device */
-#define NULLCTL -1 /* identifies non-existant controller */
-#define NULLCTLPTR (CONTROLLER_T *)0 /* identifies non-existant controller */
-#define NULLAIOP -1 /* identifies non-existant AIOP */
-#define NULLCHAN -1 /* identifies non-existant channel */
-
-/************************************************************************
- Global Register Offsets - Direct Access - Fixed values
-************************************************************************/
-
-#define _CMD_REG 0x38 /* Command Register 8 Write */
-#define _INT_CHAN 0x39 /* Interrupt Channel Register 8 Read */
-#define _INT_MASK 0x3A /* Interrupt Mask Register 8 Read / Write */
-#define _UNUSED 0x3B /* Unused 8 */
-#define _INDX_ADDR 0x3C /* Index Register Address 16 Write */
-#define _INDX_DATA 0x3E /* Index Register Data 8/16 Read / Write */
-
-/************************************************************************
- Channel Register Offsets for 1st channel in AIOP - Direct Access
-************************************************************************/
-#define _TD0 0x00 /* Transmit Data 16 Write */
-#define _RD0 0x00 /* Receive Data 16 Read */
-#define _CHN_STAT0 0x20 /* Channel Status 8/16 Read / Write */
-#define _FIFO_CNT0 0x10 /* Transmit/Receive FIFO Count 16 Read */
-#define _INT_ID0 0x30 /* Interrupt Identification 8 Read */
-
-/************************************************************************
- Tx Control Register Offsets - Indexed - External - Fixed
-************************************************************************/
-#define _TX_ENBLS 0x980 /* Tx Processor Enables Register 8 Read / Write */
-#define _TXCMP1 0x988 /* Transmit Compare Value #1 8 Read / Write */
-#define _TXCMP2 0x989 /* Transmit Compare Value #2 8 Read / Write */
-#define _TXREP1B1 0x98A /* Tx Replace Value #1 - Byte 1 8 Read / Write */
-#define _TXREP1B2 0x98B /* Tx Replace Value #1 - Byte 2 8 Read / Write */
-#define _TXREP2 0x98C /* Transmit Replace Value #2 8 Read / Write */
-
-/************************************************************************
- Receive FIFO
-************************************************************************/
-#define RXFIFO_DATA 0x5f
-#define RXFIFO_OUT 0x5c
-#define RXFIFO_EN 0x08
-#define RXFIFO_DIS 0xa7
-
-/************************************************************************
-Memory Controller Register Offsets - Indexed - External - Fixed
-************************************************************************/
-#define _RX_FIFO 0x000 /* Rx FIFO */
-#define _TX_FIFO 0x800 /* Tx FIFO */
-#define _RXF_OUTP 0x990 /* Rx FIFO OUT pointer 16 Read / Write */
-#define _RXF_INP 0x992 /* Rx FIFO IN pointer 16 Read / Write */
-#define _TXF_OUTP 0x994 /* Tx FIFO OUT pointer 8 Read / Write */
-#define _TXF_INP 0x995 /* Tx FIFO IN pointer 8 Read / Write */
-#define _TXP_CNT 0x996 /* Tx Priority Count 8 Read / Write */
-#define _TXP_PNTR 0x997 /* Tx Priority Pointer 8 Read / Write */
-
-#define PRI_PEND 0x80 /* Priority data pending (bit7, Tx pri cnt) */
-#define TXFIFO_SIZE 255 /* size of Tx FIFO */
-#define RXFIFO_SIZE 1023 /* size of Rx FIFO */
-
-/************************************************************************
-Tx Priority Buffer - Indexed - External - Fixed
-************************************************************************/
-#define _TXP_BUF 0x9C0 /* Tx Priority Buffer 32 Bytes Read / Write */
-#define TXP_SIZE 0x20 /* 32 bytes */
-
-/************************************************************************
-Channel Register Offsets - Indexed - Internal - Fixed
-************************************************************************/
-
-#define _TX_CTRL 0xFF0 /* Transmit Control 16 Write */
-#define _RX_CTRL 0xFF2 /* Receive Control 8 Write */
-#define _BAUD 0xFF4 /* Baud Rate 16 Write */
-#define _CLK_PRE 0xFF6 /* Clock Prescaler 8 Write */
-
-#define CLOCK_PRESC 0x19 /* mod 9 (divide by 10) prescale */
-
-#define BRD50 4607
-#define BRD75 3071
-#define BRD110 2094
-#define BRD134 1712
-#define BRD150 1535
-#define BRD200 1151
-#define BRD300 767
-#define BRD600 383
-#define BRD1200 191
-#define BRD1800 127
-#define BRD2000 114
-#define BRD2400 95
-#define BRD3600 64
-#define BRD4800 47
-#define BRD7200 31
-#define BRD9600 23
-#define BRD14400 15
-#define BRD19200 11
-#define BRD38400 5
-#define BRD57600 3
-#define BRD76800 2
-#define BRD115200 1
-#define BRD230400 0
-
-#define STMBREAK 0x08 /* BREAK */
-#define STMFRAME 0x04 /* framing error */
-#define STMRCVROVR 0x02 /* receiver over run error */
-#define STMPARITY 0x01 /* parity error */
-#define STMERROR (STMBREAK | STMFRAME | STMPARITY)
-#define STMBREAKH 0x800 /* BREAK */
-#define STMFRAMEH 0x400 /* framing error */
-#define STMRCVROVRH 0x200 /* receiver over run error */
-#define STMPARITYH 0x100 /* parity error */
-#define STMERRORH (STMBREAKH | STMFRAMEH | STMPARITYH)
-
-#define CTS_ACT 0x20 /* CTS input asserted */
-#define DSR_ACT 0x10 /* DSR input asserted */
-#define CD_ACT 0x08 /* CD input asserted */
-#define TXFIFOMT 0x04 /* Tx FIFO is empty */
-#define TXSHRMT 0x02 /* Tx shift register is empty */
-#define RDA 0x01 /* Rx data available */
-#define DRAINED (TXFIFOMT | TXSHRMT) /* indicates Tx is drained */
-
-#define STATMODE 0x8000 /* status mode enable bit */
-#define RXFOVERFL 0x2000 /* receive FIFO overflow */
-#define RX2MATCH 0x1000 /* receive compare byte 2 match */
-#define RX1MATCH 0x0800 /* receive compare byte 1 match */
-#define RXBREAK 0x0400 /* received BREAK */
-#define RXFRAME 0x0200 /* received framing error */
-#define RXPARITY 0x0100 /* received parity error */
-#define STATERROR (RXBREAK | RXFRAME | RXPARITY)
-
-#define CTSFC_EN 0x80 /* CTS flow control enable bit */
-#define RTSTOG_EN 0x40 /* RTS toggle enable bit */
-#define TXINT_EN 0x10 /* transmit interrupt enable */
-#define STOP2 0x08 /* enable 2 stop bits (0 = 1 stop) */
-#define PARITY_EN 0x04 /* enable parity (0 = no parity) */
-#define EVEN_PAR 0x02 /* even parity (0 = odd parity) */
-#define DATA8BIT 0x01 /* 8 bit data (0 = 7 bit data) */
-
-#define SETBREAK 0x10 /* send break condition (must clear) */
-#define LOCALLOOP 0x08 /* local loopback set for test */
-#define SET_DTR 0x04 /* assert DTR */
-#define SET_RTS 0x02 /* assert RTS */
-#define TX_ENABLE 0x01 /* enable transmitter */
-
-#define RTSFC_EN 0x40 /* RTS flow control enable */
-#define RXPROC_EN 0x20 /* receive processor enable */
-#define TRIG_NO 0x00 /* Rx FIFO trigger level 0 (no trigger) */
-#define TRIG_1 0x08 /* trigger level 1 char */
-#define TRIG_1_2 0x10 /* trigger level 1/2 */
-#define TRIG_7_8 0x18 /* trigger level 7/8 */
-#define TRIG_MASK 0x18 /* trigger level mask */
-#define SRCINT_EN 0x04 /* special Rx condition interrupt enable */
-#define RXINT_EN 0x02 /* Rx interrupt enable */
-#define MCINT_EN 0x01 /* modem change interrupt enable */
-
-#define RXF_TRIG 0x20 /* Rx FIFO trigger level interrupt */
-#define TXFIFO_MT 0x10 /* Tx FIFO empty interrupt */
-#define SRC_INT 0x08 /* special receive condition interrupt */
-#define DELTA_CD 0x04 /* CD change interrupt */
-#define DELTA_CTS 0x02 /* CTS change interrupt */
-#define DELTA_DSR 0x01 /* DSR change interrupt */
-
-#define REP1W2_EN 0x10 /* replace byte 1 with 2 bytes enable */
-#define IGN2_EN 0x08 /* ignore byte 2 enable */
-#define IGN1_EN 0x04 /* ignore byte 1 enable */
-#define COMP2_EN 0x02 /* compare byte 2 enable */
-#define COMP1_EN 0x01 /* compare byte 1 enable */
-
-#define RESET_ALL 0x80 /* reset AIOP (all channels) */
-#define TXOVERIDE 0x40 /* Transmit software off override */
-#define RESETUART 0x20 /* reset channel's UART */
-#define RESTXFCNT 0x10 /* reset channel's Tx FIFO count register */
-#define RESRXFCNT 0x08 /* reset channel's Rx FIFO count register */
-
-#define INTSTAT0 0x01 /* AIOP 0 interrupt status */
-#define INTSTAT1 0x02 /* AIOP 1 interrupt status */
-#define INTSTAT2 0x04 /* AIOP 2 interrupt status */
-#define INTSTAT3 0x08 /* AIOP 3 interrupt status */
-
-#define INTR_EN 0x08 /* allow interrupts to host */
-#define INT_STROB 0x04 /* strobe and clear interrupt line (EOI) */
-
-#define CHAN3_EN 0x08 /* enable AIOP 3 */
-#define CHAN2_EN 0x04 /* enable AIOP 2 */
-#define CHAN1_EN 0x02 /* enable AIOP 1 */
-#define CHAN0_EN 0x01 /* enable AIOP 0 */
-#define FREQ_DIS 0x00
-#define FREQ_274HZ 0x60
-#define FREQ_137HZ 0x50
-#define FREQ_69HZ 0x40
-#define FREQ_34HZ 0x30
-#define FREQ_17HZ 0x20
-#define FREQ_9HZ 0x10
-#define PERIODIC_ONLY 0x80 /* only PERIODIC interrupt */
-
-#define CHANINT_EN 0x0100 /* flags to enable/disable channel ints */
-
-#define RDATASIZE 72
-#define RREGDATASIZE 52
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-struct CONTROLLER_str;
-struct CHANNEL_str;
-
-/* The types of bus-specific methods */
-typedef int rp_aiop2rid_t(int, int);
-typedef int rp_aiop2off_t(int, int);
-typedef unsigned char rp_ctlmask_t(struct CONTROLLER_str *);
-
-/* Controller level information structure */
-struct CONTROLLER_str
-{
- int CtlID;
- int NumAiop;
- int AiopID[AIOP_CTL_SIZE];
- int AiopNumChan[AIOP_CTL_SIZE];
-
- struct mtx hwmtx; /* Spinlock protecting hardware. */
- int hwmtx_init;
- int free;
- int num_ports;
-
- /* Device and resource management */
- device_t dev; /* device */
- int io_num; /* Number of IO resources */
- int *io_rid; /* IO resource IDs */
- struct resource **io; /* IO resources */
-
- struct rp_port *rp; /* port */
-
- /* Device nodes */
- struct cdev **dev_nodes;
-
- /* Bus-specific properties */
- void *bus_ctlp;
-
- /* Bus-specific methods */
- rp_aiop2rid_t *aiop2rid; /* (aiop, offset) -> rid */
- rp_aiop2off_t *aiop2off; /* (aiop, offset) -> off */
- rp_ctlmask_t *ctlmask; /* Int status */
-};
-typedef struct CONTROLLER_str CONTROLLER_T;
-typedef CONTROLLER_T CONTROLLER_t;
-
-/* Channel level information structure */
-struct CHANNEL_str
-{
- CONTROLLER_t *CtlP;
- int AiopNum;
- int ChanID;
- int ChanNum;
-
- Word_t TxFIFO;
- Word_t TxFIFOPtrs;
- Word_t RxFIFO;
- Word_t RxFIFOPtrs;
- Word_t TxPrioCnt;
- Word_t TxPrioPtr;
- Word_t TxPrioBuf;
-
- Byte_t R[RREGDATASIZE];
-
- Byte_t BaudDiv[4];
- Byte_t TxControl[4];
- Byte_t RxControl[4];
- Byte_t TxEnables[4];
- Byte_t TxCompare[4];
- Byte_t TxReplace1[4];
- Byte_t TxReplace2[4];
-};
-
-typedef struct CHANNEL_str CHANNEL_T;
-typedef CHANNEL_T CHANNEL_t;
-typedef CHANNEL_T * CHANPTR_T;
-
-#define CHNOFF_TXRXDATA(chp) ((chp)->ChanNum * 2 + _TD0)
-#define CHNOFF_CHANSTAT(chp) ((chp)->ChanNum * 2 + _CHN_STAT0)
-#define CHNOFF_TXRXCOUNT(chp) ((chp)->ChanNum * 2 + _FIFO_CNT0)
-#define CHNOFF_INTID(chp) ((chp)->ChanNum + _INT_ID0)
-
-/***************************************************************************
-Function: sClrBreak
-Purpose: Stop sending a transmit BREAK signal
-Call: sClrBreak(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sClrBreak(ChP) \
-{ \
- (ChP)->TxControl[3] &= ~SETBREAK; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sClrDTR
-Purpose: Clr the DTR output
-Call: sClrDTR(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sClrDTR(ChP) \
-{ \
- (ChP)->TxControl[3] &= ~SET_DTR; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sClrRTS
-Purpose: Clr the RTS output
-Call: sClrRTS(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sClrRTS(ChP) \
-{ \
- (ChP)->TxControl[3] &= ~SET_RTS; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sClrTxXOFF
-Purpose: Clear any existing transmit software flow control off condition
-Call: sClrTxXOFF(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sClrTxXOFF(ChP) \
-{ \
- rp_writech1(ChP,_CMD_REG,TXOVERIDE | (Byte_t)(ChP)->ChanNum); \
- rp_writech1(ChP,_CMD_REG,(Byte_t)(ChP)->ChanNum); \
-}
-
-/***************************************************************************
-Function: sDisCTSFlowCtl
-Purpose: Disable output flow control using CTS
-Call: sDisCTSFlowCtl(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sDisCTSFlowCtl(ChP) \
-{ \
- (ChP)->TxControl[2] &= ~CTSFC_EN; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: DisParity
-Purpose: Disable parity
-Call: sDisParity(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Comments: Function sSetParity() can be used in place of functions sEnParity(),
- sDisParity(), sSetOddParity(), and sSetEvenParity().
-*/
-#define sDisParity(ChP) \
-{ \
- (ChP)->TxControl[2] &= ~PARITY_EN; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sDisRxFIFO
-Purpose: Disable Rx FIFO
-Call: sDisRxFIFO(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sDisRxFIFO(ChP) \
-{ \
- (ChP)->R[0x32] = 0x0a; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->R + 0x30)); \
-}
-
-/***************************************************************************
-Function: sDisRxStatusMode
-Purpose: Disable the Rx status mode
-Call: sDisRxStatusMode(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Comments: This takes the channel out of the receive status mode. All
- subsequent reads of receive data using sReadRxWord() will return
- two data bytes.
-*/
-#define sDisRxStatusMode(ChP) rp_writech2(ChP,CHNOFF_CHANSTAT(ChP),0)
-
-/***************************************************************************
-Function: sDisTransmit
-Purpose: Disable transmit
-Call: sDisTransmit(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
- This disables movement of Tx data from the Tx FIFO into the 1 byte
- Tx buffer. Therefore there could be up to a 2 byte latency
- between the time sDisTransmit() is called and the transmit buffer
- and transmit shift register going completely empty.
-*/
-#define sDisTransmit(ChP) \
-{ \
- (ChP)->TxControl[3] &= ~TX_ENABLE; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sDisTxSoftFlowCtl
-Purpose: Disable Tx Software Flow Control
-Call: sDisTxSoftFlowCtl(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sDisTxSoftFlowCtl(ChP) \
-{ \
- (ChP)->R[0x06] = 0x8a; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->R + 0x04)); \
-}
-
-/***************************************************************************
-Function: sEnCTSFlowCtl
-Purpose: Enable output flow control using CTS
-Call: sEnCTSFlowCtl(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sEnCTSFlowCtl(ChP) \
-{ \
- (ChP)->TxControl[2] |= CTSFC_EN; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: EnParity
-Purpose: Enable parity
-Call: sEnParity(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Comments: Function sSetParity() can be used in place of functions sEnParity(),
- sDisParity(), sSetOddParity(), and sSetEvenParity().
-
-Warnings: Before enabling parity odd or even parity should be chosen using
- functions sSetOddParity() or sSetEvenParity().
-*/
-#define sEnParity(ChP) \
-{ \
- (ChP)->TxControl[2] |= PARITY_EN; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sEnRTSFlowCtl
-Return: void
-*/
-#define sEnRTSFlowCtl(ChP) \
-{ \
- (ChP)->TxControl[2] &= ~RTSTOG_EN; \
- (ChP)->TxControl[3] &= ~SET_RTS; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
- (ChP)->RxControl[2] |= RTSFC_EN; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->RxControl)); \
-}
-
-/***************************************************************************
-Function: sDisRTSFlowCtl
-Return: void
-*/
-#define sDisRTSFlowCtl(ChP) \
-{ \
- (ChP)->RxControl[2] &= ~RTSFC_EN; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->RxControl)); \
-}
-
-/***************************************************************************
-Function: sEnRxFIFO
-Purpose: Enable Rx FIFO
-Call: sEnRxFIFO(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sEnRxFIFO(ChP) \
-{ \
- (ChP)->R[0x32] = 0x08; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->R + 0x30)); \
-}
-
-/***************************************************************************
-Function: sEnRxProcessor
-Purpose: Enable the receive processor
-Call: sEnRxProcessor(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Comments: This function is used to start the receive processor. When
- the channel is in the reset state the receive processor is not
- running. This is done to prevent the receive processor from
- executing invalid microcode instructions prior to the
- downloading of the microcode.
-
-Warnings: This function must be called after valid microcode has been
- downloaded to the AIOP, and it must not be called before the
- microcode has been downloaded.
-*/
-#define sEnRxProcessor(ChP) \
-{ \
- (ChP)->RxControl[2] |= RXPROC_EN; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->RxControl)); \
-}
-
-/***************************************************************************
-Function: sEnRxStatusMode
-Purpose: Enable the Rx status mode
-Call: sEnRxStatusMode(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Comments: This places the channel in the receive status mode. All subsequent
- reads of receive data using sReadRxWord() will return a data byte
- in the low word and a status byte in the high word.
-
-*/
-#define sEnRxStatusMode(ChP) rp_writech2(ChP,CHNOFF_CHANSTAT(ChP),STATMODE)
-
-/***************************************************************************
-Function: sEnTransmit
-Purpose: Enable transmit
-Call: sEnTransmit(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sEnTransmit(ChP) \
-{ \
- (ChP)->TxControl[3] |= TX_ENABLE; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sGetAiopIntStatus
-Purpose: Get the AIOP interrupt status
-Call: sGetAiopIntStatus(CtlP,AiopNum)
- CONTROLLER_T *CtlP; Ptr to controller structure
- int AiopNum; AIOP number
-Return: Byte_t: The AIOP interrupt status. Bits 0 through 7
- represent channels 0 through 7 respectively. If a
- bit is set that channel is interrupting.
-*/
-#define sGetAiopIntStatus(CtlP,AIOPNUM) rp_readaiop1(CtlP,AIOPNUM,_INT_CHAN)
-
-/***************************************************************************
-Function: sGetAiopNumChan
-Purpose: Get the number of channels supported by an AIOP
-Call: sGetAiopNumChan(CtlP,AiopNum)
- CONTROLLER_T *CtlP; Ptr to controller structure
- int AiopNum; AIOP number
-Return: int: The number of channels supported by the AIOP
-*/
-#define sGetAiopNumChan(CtlP,AIOPNUM) CtlP->AiopNumChan[AIOPNUM]
-
-/***************************************************************************
-Function: sGetChanIntID
-Purpose: Get a channel's interrupt identification byte
-Call: sGetChanIntID(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: Byte_t: The channel interrupt ID. Can be any
- combination of the following flags:
- RXF_TRIG: Rx FIFO trigger level interrupt
- TXFIFO_MT: Tx FIFO empty interrupt
- SRC_INT: Special receive condition interrupt
- DELTA_CD: CD change interrupt
- DELTA_CTS: CTS change interrupt
- DELTA_DSR: DSR change interrupt
-*/
-#define sGetChanIntID(ChP) (rp_readch1(ChP,(ChP)->ChanNum+_INT_ID0) & (RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR))
-
-/***************************************************************************
-Function: sGetChanNum
-Purpose: Get the number of a channel within an AIOP
-Call: sGetChanNum(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: int: Channel number within AIOP, or NULLCHAN if channel does
- not exist.
-*/
-#define sGetChanNum(ChP) (ChP)->ChanNum
-
-/***************************************************************************
-Function: sGetChanStatus
-Purpose: Get the channel status
-Call: sGetChanStatus(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: Word_t: The channel status. Can be any combination of
- the following flags:
- LOW BYTE FLAGS
- CTS_ACT: CTS input asserted
- DSR_ACT: DSR input asserted
- CD_ACT: CD input asserted
- TXFIFOMT: Tx FIFO is empty
- TXSHRMT: Tx shift register is empty
- RDA: Rx data available
-
- HIGH BYTE FLAGS
- STATMODE: status mode enable bit
- RXFOVERFL: receive FIFO overflow
- RX2MATCH: receive compare byte 2 match
- RX1MATCH: receive compare byte 1 match
- RXBREAK: received BREAK
- RXFRAME: received framing error
- RXPARITY: received parity error
-Warnings: This function will clear the high byte flags in the Channel
- Status Register.
-*/
-#define sGetChanStatus(ChP) rp_readch2(ChP,CHNOFF_CHANSTAT(ChP))
-
-/***************************************************************************
-Function: sGetChanStatusLo
-Purpose: Get the low byte only of the channel status
-Call: sGetChanStatusLo(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: Byte_t: The channel status low byte. Can be any combination
- of the following flags:
- CTS_ACT: CTS input asserted
- DSR_ACT: DSR input asserted
- CD_ACT: CD input asserted
- TXFIFOMT: Tx FIFO is empty
- TXSHRMT: Tx shift register is empty
- RDA: Rx data available
-*/
-#define sGetChanStatusLo(ChP) rp_readch1(ChP,CHNOFF_CHANSTAT(ChP))
-
-/***************************************************************************
-Function: sGetRxCnt
-Purpose: Get the number of data bytes in the Rx FIFO
-Call: sGetRxCnt(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: int: The number of data bytes in the Rx FIFO.
-Comments: Byte read of count register is required to obtain Rx count.
-
-*/
-#define sGetRxCnt(ChP) rp_readch2(ChP,CHNOFF_TXRXCOUNT(ChP))
-
-/***************************************************************************
-Function: sGetTxCnt
-Purpose: Get the number of data bytes in the Tx FIFO
-Call: sGetTxCnt(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: Byte_t: The number of data bytes in the Tx FIFO.
-Comments: Byte read of count register is required to obtain Tx count.
-
-*/
-#define sGetTxCnt(ChP) rp_readch1(ChP,CHNOFF_TXRXCOUNT(ChP))
-
-/*****************************************************************************
-Function: sGetTxRxDataIO
-Purpose: Get the offset of a channel's TxRx Data register
-Call: sGetTxRxDataIO(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Return: WordIO_t: offset of a channel's TxRx Data register
-*/
-#define sGetTxRxDataIO(ChP) CHNOFF_TXRXDATA(ChP)
-
-/***************************************************************************
-Function: sInitChanDefaults
-Purpose: Initialize a channel structure to its default state.
-Call: sInitChanDefaults(ChP)
- CHANNEL_T *ChP; Ptr to the channel structure
-Comments: This function must be called once for every channel structure
- that exists before any other SSCI calls can be made.
-
-*/
-#define sInitChanDefaults(ChP) \
-{ \
- (ChP)->CtlP = NULLCTLPTR; \
- (ChP)->AiopNum = NULLAIOP; \
- (ChP)->ChanID = AIOPID_NULL; \
- (ChP)->ChanNum = NULLCHAN; \
-}
-
-/***************************************************************************
-Function: sResetAiopByNum
-Purpose: Reset the AIOP by number
-Call: sResetAiopByNum(CTLP,AIOPNUM)
- CONTROLLER_T CTLP; Ptr to controller structure
- AIOPNUM; AIOP index
-*/
-#define sResetAiopByNum(CTLP,AIOPNUM) \
-{ \
- rp_writeaiop1(CTLP,AIOPNUM,_CMD_REG,RESET_ALL); \
- rp_writeaiop1(CTLP,AIOPNUM,_CMD_REG,0x0); \
-}
-
-/***************************************************************************
-Function: sSendBreak
-Purpose: Send a transmit BREAK signal
-Call: sSendBreak(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sSendBreak(ChP) \
-{ \
- (ChP)->TxControl[3] |= SETBREAK; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sSetBaud
-Purpose: Set baud rate
-Call: sSetBaud(ChP,Divisor)
- CHANNEL_T *ChP; Ptr to channel structure
- Word_t Divisor; 16 bit baud rate divisor for channel
-*/
-#define sSetBaud(ChP,DIVISOR) \
-{ \
- (ChP)->BaudDiv[2] = (Byte_t)(DIVISOR); \
- (ChP)->BaudDiv[3] = (Byte_t)((DIVISOR) >> 8); \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->BaudDiv)); \
-}
-
-/***************************************************************************
-Function: sSetData7
-Purpose: Set data bits to 7
-Call: sSetData7(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sSetData7(ChP) \
-{ \
- (ChP)->TxControl[2] &= ~DATA8BIT; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sSetData8
-Purpose: Set data bits to 8
-Call: sSetData8(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sSetData8(ChP) \
-{ \
- (ChP)->TxControl[2] |= DATA8BIT; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sSetDTR
-Purpose: Set the DTR output
-Call: sSetDTR(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sSetDTR(ChP) \
-{ \
- (ChP)->TxControl[3] |= SET_DTR; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sSetEvenParity
-Purpose: Set even parity
-Call: sSetEvenParity(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Comments: Function sSetParity() can be used in place of functions sEnParity(),
- sDisParity(), sSetOddParity(), and sSetEvenParity().
-
-Warnings: This function has no effect unless parity is enabled with function
- sEnParity().
-*/
-#define sSetEvenParity(ChP) \
-{ \
- (ChP)->TxControl[2] |= EVEN_PAR; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sSetOddParity
-Purpose: Set odd parity
-Call: sSetOddParity(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Comments: Function sSetParity() can be used in place of functions sEnParity(),
- sDisParity(), sSetOddParity(), and sSetEvenParity().
-
-Warnings: This function has no effect unless parity is enabled with function
- sEnParity().
-*/
-#define sSetOddParity(ChP) \
-{ \
- (ChP)->TxControl[2] &= ~EVEN_PAR; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sSetRTS
-Purpose: Set the RTS output
-Call: sSetRTS(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sSetRTS(ChP) \
-{ \
- (ChP)->TxControl[3] |= SET_RTS; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sSetRxTrigger
-Purpose: Set the Rx FIFO trigger level
-Call: sSetRxProcessor(ChP,Level)
- CHANNEL_T *ChP; Ptr to channel structure
- Byte_t Level; Number of characters in Rx FIFO at which the
- interrupt will be generated. Can be any of the following flags:
-
- TRIG_NO: no trigger
- TRIG_1: 1 character in FIFO
- TRIG_1_2: FIFO 1/2 full
- TRIG_7_8: FIFO 7/8 full
-Comments: An interrupt will be generated when the trigger level is reached
- only if function sEnInterrupt() has been called with flag
- RXINT_EN set. The RXF_TRIG flag in the Interrupt Idenfification
- register will be set whenever the trigger level is reached
- regardless of the setting of RXINT_EN.
-
-*/
-#define sSetRxTrigger(ChP,LEVEL) \
-{ \
- (ChP)->RxControl[2] &= ~TRIG_MASK; \
- (ChP)->RxControl[2] |= LEVEL; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->RxControl)); \
-}
-
-/***************************************************************************
-Function: sSetStop1
-Purpose: Set stop bits to 1
-Call: sSetStop1(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sSetStop1(ChP) \
-{ \
- (ChP)->TxControl[2] &= ~STOP2; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sSetStop2
-Purpose: Set stop bits to 2
-Call: sSetStop2(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-*/
-#define sSetStop2(ChP) \
-{ \
- (ChP)->TxControl[2] |= STOP2; \
- rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->TxControl)); \
-}
-
-/***************************************************************************
-Function: sStartRxProcessor
-Purpose: Start a channel's receive processor
-Call: sStartRxProcessor(ChP)
- CHANNEL_T *ChP; Ptr to channel structure
-Comments: This function is used to start a Rx processor after it was
- stopped with sStopRxProcessor() or sStopSWInFlowCtl(). It
- will restart both the Rx processor and software input flow control.
-
-*/
-#define sStartRxProcessor(ChP) rp_writech4(ChP,_INDX_ADDR,le32dec((ChP)->R))
-
-/***************************************************************************
-Function: sWriteTxByte
-Purpose: Write a transmit data byte to a channel.
- CHANNEL_T *ChP; Ptr to channel structure
- ByteIO_t io: Channel transmit register I/O address. This can
- be obtained with sGetTxRxDataIO().
- Byte_t Data; The transmit data byte.
-Warnings: This function writes the data byte without checking to see if
- sMaxTxSize is exceeded in the Tx FIFO.
-*/
-#define sWriteTxByte(ChP,IO,DATA) rp_writech1(ChP,IO,DATA)
-
-int sReadAiopID(CONTROLLER_T *CtlP, int aiop);
-int sReadAiopNumChan(CONTROLLER_T *CtlP, int aiop);
-int sInitChan( CONTROLLER_T *CtlP,
- CHANNEL_T *ChP,
- int AiopNum,
- int ChanNum);
-Byte_t sGetRxErrStatus(CHANNEL_T *ChP);
-void sStopRxProcessor(CHANNEL_T *ChP);
-void sStopSWInFlowCtl(CHANNEL_T *ChP);
-void sFlushRxFIFO(CHANNEL_T *ChP);
-void sFlushTxFIFO(CHANNEL_T *ChP);
-int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data);
-void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags);
-void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags);
-int rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports);
-void rp_releaseresource(CONTROLLER_t *ctlp);
-static __inline void
-rp_lock(CONTROLLER_T *CtlP)
-{
- if (CtlP->hwmtx_init != 0)
- mtx_lock(&CtlP->hwmtx);
-}
-static __inline void
-rp_unlock(CONTROLLER_T *CtlP)
-{
- if (CtlP->hwmtx_init != 0)
- mtx_unlock(&CtlP->hwmtx);
-}
-
-#ifndef ROCKET_C
-extern Byte_t R[RDATASIZE];
-extern CONTROLLER_T sController[CTL_SIZE];
-extern Byte_t sIRQMap[16];
-#endif
-extern Byte_t rp_sBitMapClrTbl[8];
-extern Byte_t rp_sBitMapSetTbl[8];
Index: sys/dev/rp/rpvar.h
===================================================================
--- sys/dev/rp/rpvar.h
+++ sys/dev/rp/rpvar.h
@@ -1,76 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * Copyright (c) Comtrol Corporation <support@comtrol.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted prodived that the follwoing conditions
- * are met.
- * 1. Redistributions of source code must retain the above copyright
- * notive, this list of conditions and the following disclainer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials prodided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Comtrol Corporation.
- * 4. The name of Comtrol Corporation may not be used to endorse or
- * promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * rpvar.h --- RocketPort data structure includes for FreeBSD
- */
-
-#define RP_UNIT(x) dv_unit(x)
-#define RP_PORT(x) (dev2unit(x) & 0x3f)
-#define MAX_RP_PORTS 128
-
-
-struct rp_port {
- struct tty * rp_tty; /* cross reference */
- struct callout rp_timer;
-
- unsigned char state; /* state of dtr */
-
- int rp_port;
- int rp_flags;
- int rp_unit:2;
- int rp_aiop:2;
- int rp_chan:3;
- int rp_intmask;
- int rp_imask; /* Input mask */
- int rp_fifo_lw;
- int rp_restart;
- int rp_overflows;
- int rp_rts_iflow:1;
- int rp_disable_writes:1;
- int rp_cts:1;
- int rp_waiting:1;
- int rp_xmit_stopped:1;
- CONTROLLER_t * rp_ctlp;
- CHANNEL_t rp_channel;
- unsigned char TxBuf[TXFIFO_SIZE];
- unsigned char RxBuf[RXFIFO_SIZE];
-};
-
-/* Actually not used */
-#ifdef notdef
-extern struct termios deftermios;
-#endif /* notdef */
Index: sys/modules/rc/Makefile
===================================================================
--- sys/modules/rc/Makefile
+++ sys/modules/rc/Makefile
@@ -1,8 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${SRCTOP}/sys/dev/rc
-
-KMOD= rc
-SRCS= rc.c device_if.h bus_if.h isa_if.h
-
-.include <bsd.kmod.mk>

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 25, 1:37 AM (13 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30288210
Default Alt Text
D25874.id75107.diff (232 KB)

Event Timeline