Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149376252
D25874.id75107.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
232 KB
Referenced Files
None
Subscribers
None
D25874.id75107.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D25874: remove some serial drivers (rc, rp, cy)
Attached
Detach File
Event Timeline
Log In to Comment