diff --git a/sbin/comcontrol/comcontrol.8 b/sbin/comcontrol/comcontrol.8 index ec12dee1e4df..84309a04960f 100644 --- a/sbin/comcontrol/comcontrol.8 +++ b/sbin/comcontrol/comcontrol.8 @@ -54,7 +54,6 @@ dialout devices .El .Sh SEE ALSO .Xr stty 1 , -.Xr sio 4 .Sh HISTORY Originally part of cgd's com package patches, version 0.2.1, to .Bx 386 0.1 . diff --git a/sbin/conscontrol/conscontrol.8 b/sbin/conscontrol/conscontrol.8 index bbb40630704d..eb9b4dfdbc0f 100644 --- a/sbin/conscontrol/conscontrol.8 +++ b/sbin/conscontrol/conscontrol.8 @@ -101,7 +101,6 @@ This is an interface to the tty ioctl .Dv TIOCCONS . .El .Sh SEE ALSO -.Xr sio 4 , .Xr syscons 4 , .Xr tty 4 , .Xr vt 4 , diff --git a/sbin/reboot/boot_i386.8 b/sbin/reboot/boot_i386.8 index 087aaeb55e48..2974efd473e1 100644 --- a/sbin/reboot/boot_i386.8 +++ b/sbin/reboot/boot_i386.8 @@ -36,7 +36,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 30, 2019 +.Dd November 19, 2019 .Dt BOOT 8 i386 .Os .Sh NAME @@ -223,15 +223,6 @@ you can use the .Fl h option to force the kernel to use the serial port as its console device. -The serial port driver -.Xr sio 4 -(but not -.Xr uart 4 ) -has a flag (0x20) to override this option. -If that flag is set, the serial port will always be used as the console, -regardless of the -.Fl h -option described here. .It Fl m mute the console to suppress all kernel console input and output during the boot. diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 6b41c030a722..b0dccc1ff7a2 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -461,7 +461,6 @@ MAN= aac.4 \ siftr.4 \ siis.4 \ simplebus.4 \ - sio.4 \ sis.4 \ sk.4 \ ${_smartpqi.4} \ diff --git a/share/man/man4/rc.4 b/share/man/man4/rc.4 index c2ab34a8bc0a..95bcae6c3981 100644 --- a/share/man/man4/rc.4 +++ b/share/man/man4/rc.4 @@ -91,7 +91,6 @@ file can be consulted for more information. .Sh SEE ALSO .Xr tty 1 , .Xr ttyname 3 , -.Xr sio 4 , .Xr tty 4 , .Xr device.hints 5 , .Xr comcontrol 8 , diff --git a/share/man/man4/sio.4 b/share/man/man4/sio.4 deleted file mode 100644 index 9987eee6ea0d..000000000000 --- a/share/man/man4/sio.4 +++ /dev/null @@ -1,410 +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 -.\" $FreeBSD$ -.\" -.Dd August 30, 2006 -.Dt SIO 4 -.Os -.Sh NAME -.Nm sio -.Nd "fast interrupt driven asynchronous serial communications interface" -.Sh SYNOPSIS -For standard ISA ports: -.Bd -ragged -offset indent -compact -.Cd "device sio" -.Pp -In -.Pa /boot/device.hints : -.Cd hint.sio.0.at="isa" -.Cd hint.sio.0.port="0x3f8" -.Cd hint.sio.0.flags="0x10" -.Cd hint.sio.0.irq="4" -.Cd hint.sio.1.at="isa" -.Cd hint.sio.1.port="0x2f8" -.Cd hint.sio.1.flags="0x0" -.Cd hint.sio.1.irq="3" -.Ed -.Pp -For AST compatible multiport cards with 4 ports: -.Bd -ragged -offset indent -compact -.Cd "options COM_MULTIPORT" -.Cd "device sio" -.Pp -In -.Pa /boot/device.hints : -.Cd hint.sio.4.at="isa" -.Cd hint.sio.4.port="0x2a0" -.Cd hint.sio.4.flags="0x701" -.Cd hint.sio.5.at="isa" -.Cd hint.sio.5.port="0x2a8" -.Cd hint.sio.5.flags="0x701" -.Cd hint.sio.6.at="isa" -.Cd hint.sio.6.port="0x2b0" -.Cd hint.sio.6.flags="0x701" -.Cd hint.sio.7.at="isa" -.Cd hint.sio.7.port="0x2b8" -.Cd hint.sio.7.flags="0x701" -.Cd hint.sio.7.irq="12" -.Ed -.Pp -For Boca Board compatible multiport cards with 8 ports: -.Bd -ragged -offset indent -compact -.Cd "options COM_MULTIPORT" -.Cd "device sio" -.Pp -In -.Pa /boot/device.hints : -.Cd hint.sio.4.at="isa" -.Cd hint.sio.4.port="0x100" -.Cd hint.sio.4.flags="0xb05" -.Cd "..." -.Cd hint.sio.11.at="isa" -.Cd hint.sio.11.port="0x138" -.Cd hint.sio.11.flags="0xb05" -.Cd hint.sio.11.irq="12" -.Ed -.Pp -For Netmos Nm9845 multiport cards with 6 ports: -.Bd -ragged -offset indent -compact -.Cd "options COM_MULTIPORT" -.Cd "device sio" -.Pp -In -.Pa /boot/device.hints : -.Cd hint.sio.4.at="isa" -.Cd hint.sio.4.port="0xb000" -.Cd hint.sio.4.flags="0x901" -.Cd hint.sio.5.at="isa" -.Cd hint.sio.5.port="0xb400" -.Cd hint.sio.5.flags="0x901" -.Cd hint.sio.6.at="isa" -.Cd hint.sio.6.port="0xb800" -.Cd hint.sio.6.flags="0x901" -.Cd hint.sio.7.at="isa" -.Cd hint.sio.7.port="0xbc00" -.Cd hint.sio.7.flags="0x901" -.Cd hint.sio.8.at="isa" -.Cd hint.sio.8.port="0xc000" -.Cd hint.sio.8.flags="0x901" -.Cd hint.sio.9.at="isa" -.Cd hint.sio.9.port="0xac00" -.Cd hint.sio.9.flags="0x901" -.Cd hint.sio.9.irq="12" -.Ed -.Pp -For Hayes ESP cards: -.Bd -ragged -offset indent -compact -.Cd "options COM_ESP" -.Cd "device sio" -.Cd "..." -.Ed -.Pp -For single port PCI and PCCARD cards: -.Bd -ragged -offset indent -compact -.Cd "device sio" -.Pp -No lines are required in -.Pa /boot/device.hints -for these cards. -.Ed -.Pp -For dual port PCI cards that share an interrupt: -.Bd -ragged -offset indent -compact -.Cd "device sio" -.Cd "options COM_MULTIPORT" -.Pp -In -.Pa /boot/device.hints : -.Cd hint.sio.2.flags="0x201" -.Cd hint.sio.3.flags="0x201" -.Ed -.Pp -Meaning of -.Ar flags : -.Bl -tag -offset indent -compact -width 0x000000 -.It 0x00001 -shared IRQs -.It 0x00002 -disable FIFO -.It 0x00004 -no AST/4 compatible IRQ control register -.It 0x00008 -recover sooner from lost output interrupts -.It 0x00010 -device is potential system console -.It 0x00020 -device is forced to become system console -.It 0x00040 -device is reserved for low-level IO (e.g.\& for remote kernel debugging) -.It 0x00080 -use this port for remote kernel debugging -.It 0x0 Ns Em ?? Ns 00 -minor number of master port -.It 0x10000 -PPS timestamping on CTS instead of DCD -.It 0x20000 -device is assumed to use a 16650A-type (extended FIFO) chip -.El -.Sh DESCRIPTION -The -.Nm -driver provides support for NS8250-, NS16450-, NS16550 and NS16550A-based -.Tn EIA -.Tn RS-232C -.Pf ( Tn CCITT -.Tn V.24 ) -communications interfaces. -The NS8250 and NS16450 have single character -buffers, the NS16550A has 16 character FIFO input and output buffers. -.Pp -Input and output for each line may set to one of following baud rates; -50, 75, 110, 134.5, 150, 300, 600, 1200, 1800, 2400, 4800, 9600, -19200, 28800, 38400, 57600, or 115200. -Your hardware may limit your baud rate choices. -.Pp -The driver supports `multiport' cards. -Multiport cards are those that have one or more groups of ports -that share an Interrupt Request (IRQ) line per group. -Shared IRQs on different cards are not supported. -Frequently 4 ports share 1 IRQ; some 8 port cards have 2 groups of 4 ports, -thus using 2 IRQs. -Some cards allow the first 2 serial ports to have separate IRQs per port -(as per DOS PC standard). -.Pp -Some cards have an IRQ control register for each group. -Some cards require special initialization related to such registers. -Only AST/4 compatible IRQ control registers are supported. -Some cards have an IRQ status register for each group. -The driver does not require or use such registers yet. -To work, the control and status registers for a group, if any, -must be mapped to the scratch register (register 7) -of a port in the group. -Such a port is called a -.Em master -port. -.Pp -The driver supports controller based PCI modems. -The 3Com FaxModem PCI and the Advantec 56k Voice Messaging PCI -FaxModem are the only cards supported. -WinModems, softmodems, hfc modems and any other modems that are not -controller based are not supported. -.Pp -The -.Em flags -keyword may be used on each -.Em device sio -line in the kernel configuration file -to disable the FIFO on 16550A UARTs -(see the synopsis). -Disabling the FIFO should rarely be necessary. -.Pp -The -.Em flags -keyword -.Em must -be used for all ports that are part of an IRQ sharing group. -One bit specifies IRQ sharing; another bit specifies whether the port does -.Em not -require AST/4 compatible initialization. -The minor number of the device corresponding a master port -for the group is encoded as a bitfield in the high byte. -The same master port must be specified for all ports in a group. -.Pp -The -.Em irq -specification must be given for master ports -and for ports that are not part of an IRQ sharing group, -and not for other ports. -.Pp -In the synopsis, -.Em flags 0x701 -means that the 8th port (sio7) is the master -port, and that the port is on a multiport card with shared IRQs -and an AST/4 compatible IRQ control register. -.Pp -.Em flags 0xb05 -means that the 12th port (sio11) is the master -port, and that the port is on a multiport card with shared IRQs -and no special IRQ control register. -.Pp -Which port is the master port depends on the card type. -Consult the hardware documentation of your card. -Since IRQ status registers are never used, -and IRQ control registers are only used for AST/4 compatible cards, -and some cards map the control/status registers to all ports in a group, -any port in a group will sometimes do for the master port. -Choose a port containing an IRQ status register for forwards compatibility, -and the highest possible port for consistency. -.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 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. -E.g., to lock a speed to 115200, use -.Dq Li stty 115200 -on the initial-state device and -.Dq Li stty 1 -on the lock-state device. -.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. -.Sh FILES -.Bl -tag -width /dev/ttyd?.init -compact -.It Pa /dev/ttyd? -for callin ports -.It Pa /dev/ttyd?.init -.It Pa /dev/ttyd?.lock -corresponding callin initial-state and lock-state devices -.Pp -.It Pa /dev/cuad? -for callout ports -.It Pa /dev/cuad?.init -.It Pa /dev/cuad?.lock -corresponding callout initial-state and lock-state devices -.El -.Pp -.Bl -tag -width /etc/rc.d/serial -compact -.It Pa /etc/rc.d/serial -examples of setting the initial-state and lock-state devices -.El -.Pp -The device numbers are made from the set [0-9a-v] so that more than -10 ports can be supported. -.Sh DIAGNOSTICS -.Bl -diag -.It sio%d: silo overflow. -Problem in the interrupt handler. -.El -.Bl -diag -.It sio%d: interrupt-level buffer overflow. -Problem in the bottom half of the driver. -.El -.Bl -diag -.It sio%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 -.Sh HISTORY -The -.Nm -driver is derived from the -.Tn HP9000/300 -.Xr dca 4 -driver and is -.Ud -.Sh BUGS -Data loss may occur at very high baud rates on slow systems, -or with too many ports on any system, -or on heavily loaded systems when crtscts cannot be used. -The use of NS16550A's reduces system load and helps to avoid data loss. -.Pp -Stay away from plain NS16550's. -These are early implementations of the chip with non-functional FIFO hardware. -.Pp -The constants which define the locations -of the various serial ports are holdovers from -.Tn DOS . -As shown, hex addresses can be and for clarity probably should be used instead. -.Pp -Note that on the AST/4 the card's dipswitches should -.Em not -be set to use interrupt sharing. -AST/4-like interrupt sharing is only used when -.Em multiple -AST/4 cards are installed in the same system. -The -.Nm -driver does not support more than 1 AST/4 on one IRQ. -.Pp -The examples in the synopsis are too vendor-specific. diff --git a/share/man/man4/snp.4 b/share/man/man4/snp.4 index 36816bd943ec..ce0ef66c5721 100644 --- a/share/man/man4/snp.4 +++ b/share/man/man4/snp.4 @@ -69,7 +69,6 @@ and detached. .El .Sh SEE ALSO .Xr pty 4 , -.Xr sio 4 , .Xr kldload 8 , .Xr watch 8 .Sh HISTORY diff --git a/share/man/man5/device.hints.5 b/share/man/man5/device.hints.5 index 4f33e3518aeb..ecaed2ed8085 100644 --- a/share/man/man5/device.hints.5 +++ b/share/man/man5/device.hints.5 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 23, 2015 +.Dd November 19, 2019 .Dt DEVICE.HINTS 5 .Os .Sh NAME @@ -138,13 +138,13 @@ Notes on the kernel configuration file and device resource hints. .El .Sh EXAMPLES The following example sets up resources for the -.Xr sio 4 +.Xr uart 4 driver on the ISA bus: .Bd -literal -offset indent -hint.sio.0.at="isa" -hint.sio.0.port="0x3F8" -hint.sio.0.flags="0x10" -hint.sio.0.irq="4" +hint.uart.0.at="isa" +hint.uart.0.port="0x3F8" +hint.uart.0.flags="0x10" +hint.uart.0.irq="4" .Ed .Pp The following example disables the ACPI driver: diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 294b8878df5a..4942333ab587 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -300,11 +300,6 @@ dev/sfxge/sfxge_nvram.c optional sfxge pci dev/sfxge/sfxge_port.c optional sfxge pci dev/sfxge/sfxge_rx.c optional sfxge pci dev/sfxge/sfxge_tx.c optional sfxge pci -dev/sio/sio.c optional sio -dev/sio/sio_isa.c optional sio isa -dev/sio/sio_pccard.c optional sio pccard -dev/sio/sio_pci.c optional sio pci -dev/sio/sio_puc.c optional sio puc dev/smartpqi/smartpqi_cam.c optional smartpqi dev/smartpqi/smartpqi_cmd.c optional smartpqi dev/smartpqi/smartpqi_discovery.c optional smartpqi diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 33d2f953857a..8562346712b9 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -136,11 +136,6 @@ dev/random/nehemiah.c optional padlock_rng !random_loadable dev/sbni/if_sbni.c optional sbni dev/sbni/if_sbni_isa.c optional sbni isa dev/sbni/if_sbni_pci.c optional sbni pci -dev/sio/sio.c optional sio -dev/sio/sio_isa.c optional sio isa -dev/sio/sio_pccard.c optional sio pccard -dev/sio/sio_pci.c optional sio pci -dev/sio/sio_puc.c optional sio puc dev/speaker/spkr.c optional speaker dev/superio/superio.c optional superio isa dev/syscons/apm/apm_saver.c optional apm_saver apm diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c deleted file mode 100644 index d5d56fb97ed1..000000000000 --- a/sys/dev/sio/sio.c +++ /dev/null @@ -1,2643 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1991 The Regents of the University of California. - * 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 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: @(#)com.c 7.5 (Berkeley) 5/16/91 - * from: i386/isa sio.c,v 1.234 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_gdb.h" -#include "opt_kdb.h" -#include "opt_sio.h" - -/* - * Serial driver, based on 386BSD-0.1 com driver. - * Mostly rewritten to use pseudo-DMA. - * Works for National Semiconductor NS8250-NS16550AF UARTs. - * COM driver, based on HP dca driver. - * - * Changes for PC Card integration: - * - Added PC Card driver table and handlers - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#ifdef COM_ESP -#include -#endif -#include - -#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ - -#ifdef COM_MULTIPORT -/* checks in flags for multiport and which is multiport "master chip" - * for a given card - */ -#define COM_ISMULTIPORT(flags) ((flags) & 0x01) -#define COM_MPMASTER(flags) (((flags) >> 8) & 0x0ff) -#define COM_NOTAST4(flags) ((flags) & 0x04) -#else -#define COM_ISMULTIPORT(flags) (0) -#endif /* COM_MULTIPORT */ - -#define COM_C_IIR_TXRDYBUG 0x80000 -#define COM_CONSOLE(flags) ((flags) & 0x10) -#define COM_DEBUGGER(flags) ((flags) & 0x80) -#define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24) -#define COM_FORCECONSOLE(flags) ((flags) & 0x20) -#define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG) -#define COM_LLCONSOLE(flags) ((flags) & 0x40) -#define COM_LOSESOUTINTS(flags) ((flags) & 0x08) -#define COM_NOFIFO(flags) ((flags) & 0x02) -#define COM_NOPROBE(flags) ((flags) & 0x40000) -#define COM_NOSCR(flags) ((flags) & 0x100000) -#define COM_PPSCTS(flags) ((flags) & 0x10000) -#define COM_ST16650A(flags) ((flags) & 0x20000) -#define COM_TI16754(flags) ((flags) & 0x200000) - -#define sio_getreg(com, off) \ - (bus_space_read_1((com)->bst, (com)->bsh, (off))) -#define sio_setreg(com, off, value) \ - (bus_space_write_1((com)->bst, (com)->bsh, (off), (value))) - -/* - * 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 comstart(), siopoll() and - * comstop()) - * CS_TTGO = ~TS_TTSTOP (maintained by comparam() and comstart()) - * CS_CTS_OFLOW = CCTS_OFLOW (maintained by comparam()) - * CS_RTS_IFLOW = CRTS_IFLOW (maintained by comparam()) - * 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_BUSYCHECK 1 /* siobusycheck() scheduled */ - -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]) - -/* types. XXX - should be elsewhere */ -typedef u_int Port_t; /* hardware port */ -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 cfcr_image; /* copy of value written to CFCR */ -#ifdef COM_ESP - bool_t esp; /* is this unit a hayes esp board? */ -#endif - u_char extra_state; /* more flag bits, separate for order trick */ - u_char fifo_image; /* copy of value written to FIFO */ - bool_t hasfifo; /* nonzero for 16550 UARTs */ - bool_t loses_outints; /* nonzero if device loses output interrupts */ - u_char mcr_image; /* copy of value written to MCR */ -#ifdef COM_MULTIPORT - bool_t multiport; /* is this unit part of a multiport device? */ -#endif /* COM_MULTIPORT */ - bool_t no_irq; /* nonzero if irq is not attached */ - bool_t gone; /* hardware disappeared */ - bool_t poll; /* nonzero if polling is required */ - bool_t poll_output; /* nonzero if polling for output is required */ - bool_t st16650a; /* nonzero if Startech 16650A compatible */ - int unit; /* unit number */ - u_int flags; /* copy of device flags */ - u_int tx_fifo_size; - - /* - * 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 */ - - bus_space_tag_t bst; - bus_space_handle_t bsh; - - Port_t data_port; /* i/o ports */ -#ifdef COM_ESP - Port_t esp_port; -#endif - Port_t int_ctl_port; - Port_t int_id_port; - Port_t modem_ctl_port; - Port_t line_status_port; - Port_t modem_status_port; - - struct tty *tp; /* cross reference */ - - struct pps_state pps; - int pps_bit; -#ifdef KDB - int alt_brk_state; -#endif - - u_long bytes_in; /* statistics */ - u_long bytes_out; - u_int delta_error_counts[CE_NTYPES]; - u_long error_counts[CE_NTYPES]; - - u_long rclk; - - struct resource *irqres; - struct resource *ioportres; - int ioportrid; - void *cookie; - - /* - * Data area for output buffers. Someday we should build the output - * buffer queue without copying data. - */ - u_char obuf1[256]; - u_char obuf2[256]; -}; - -#ifdef COM_ESP -static int espattach(struct com_s *com, Port_t esp_port); -#endif - -static void combreak(struct tty *tp, int sig); -static timeout_t siobusycheck; -static u_int siodivisor(u_long rclk, speed_t speed); -static void comclose(struct tty *tp); -static int comopen(struct tty *tp, struct cdev *dev); -static void sioinput(struct com_s *com); -static void siointr1(struct com_s *com); -static int siointr(void *arg); -static int commodem(struct tty *tp, int sigon, int sigoff); -static int comparam(struct tty *tp, struct termios *t); -static void siopoll(void *); -static void siosettimeout(void); -static int siosetwater(struct com_s *com, speed_t speed); -static void comstart(struct tty *tp); -static void comstop(struct tty *tp, int rw); -static timeout_t comwakeup; - -char sio_driver_name[] = "sio"; -static struct mtx sio_lock; -static int sio_inited; - -/* table and macro for fast conversion from a unit number to its com struct */ -devclass_t sio_devclass; -/* - * XXX Assmues that devclass_get_device, devclass_get_softc and - * device_get_softc are fast interrupt safe. The current implementation - * of these functions are. - */ -#define com_addr(unit) ((struct com_s *) \ - devclass_get_softc(sio_devclass, unit)) /* XXX */ - -int comconsole = -1; -static volatile speed_t comdefaultrate = CONSPEED; -static u_long comdefaultrclk = DEFAULT_RCLK; -SYSCTL_ULONG(_machdep, OID_AUTO, conrclk, CTLFLAG_RW, &comdefaultrclk, 0, ""); -static speed_t gdbdefaultrate = GDBSPEED; -SYSCTL_UINT(_machdep, OID_AUTO, gdbspeed, CTLFLAG_RW, - &gdbdefaultrate, GDBSPEED, ""); -static u_int com_events; /* input chars + weighted output completions */ -static Port_t siocniobase; -static int siocnunit = -1; -static void *sio_slow_ih; -static void *sio_fast_ih; -static int sio_timeout; -static int sio_timeouts_until_log; -static struct callout_handle sio_timeout_handle - = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle); -static int sio_numunits; - -#ifdef GDB -static Port_t siogdbiobase = 0; -#endif - -#ifdef COM_ESP -/* XXX configure this properly. */ -/* XXX quite broken for new-bus. */ -static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, }; -static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 }; -#endif - -/* - * handle sysctl read/write requests for console speed - * - * In addition to setting comdefaultrate for I/O through /dev/console, - * also set the initial and lock values for the /dev/ttyXX device - * if there is one associated with the console. Finally, if the /dev/tty - * device has already been open, change the speed on the open running port - * itself. - */ - -static int -sysctl_machdep_comdefaultrate(SYSCTL_HANDLER_ARGS) -{ - int error, s; - speed_t newspeed; - struct com_s *com; - struct tty *tp; - - newspeed = comdefaultrate; - - error = sysctl_handle_opaque(oidp, &newspeed, sizeof newspeed, req); - if (error || !req->newptr) - return (error); - - comdefaultrate = newspeed; - - if (comconsole < 0) /* serial console not selected? */ - return (0); - - com = com_addr(comconsole); - if (com == NULL) - return (ENXIO); - - tp = com->tp; - if (tp == NULL) - return (ENXIO); - - /* - * set the initial and lock rates for /dev/ttydXX and /dev/cuaXX - * (note, the lock rates really are boolean -- if non-zero, disallow - * speed changes) - */ - tp->t_init_in.c_ispeed = tp->t_init_in.c_ospeed = - tp->t_lock_in.c_ispeed = tp->t_lock_in.c_ospeed = - tp->t_init_out.c_ispeed = tp->t_init_out.c_ospeed = - tp->t_lock_out.c_ispeed = tp->t_lock_out.c_ospeed = comdefaultrate; - - if (tp->t_state & TS_ISOPEN) { - tp->t_termios.c_ispeed = - tp->t_termios.c_ospeed = comdefaultrate; - s = spltty(); - error = comparam(tp, &tp->t_termios); - splx(s); - } - return error; -} - -SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NOFETCH, - 0, 0, sysctl_machdep_comdefaultrate, "I", ""); -TUNABLE_INT("machdep.conspeed", __DEVOLATILE(int *, &comdefaultrate)); - -#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit)) -#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit)) - -/* - * Unload the driver and clear the table. - * XXX this is mostly wrong. - * XXX TODO: - * This is usually called when the card is ejected, but - * can be caused by a kldunload of a controller driver. - * The idea is to reset the driver's view of the device - * and ensure that any driver entry points such as - * read and write do not hang. - */ -int -siodetach(device_t dev) -{ - struct com_s *com; - - com = (struct com_s *) device_get_softc(dev); - if (com == NULL) { - device_printf(dev, "NULL com in siounload\n"); - return (0); - } - com->gone = TRUE; - if (com->tp) - ttyfree(com->tp); - if (com->irqres) { - bus_teardown_intr(dev, com->irqres, com->cookie); - bus_release_resource(dev, SYS_RES_IRQ, 0, com->irqres); - } - if (com->ioportres) - bus_release_resource(dev, SYS_RES_IOPORT, com->ioportrid, - com->ioportres); - if (com->ibuf != NULL) - free(com->ibuf, M_DEVBUF); - - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - return (0); -} - -int -sioprobe(dev, xrid, rclk, noprobe) - device_t dev; - int xrid; - u_long rclk; - int noprobe; -{ -#if 0 - static bool_t already_init; - device_t xdev; -#endif - struct com_s *com; - u_int divisor; - bool_t failures[10]; - int fn; - device_t idev; - Port_t iobase; - intrmask_t irqmap[4]; - intrmask_t irqs; - u_char mcr_image; - int result; - u_long xirq; - u_int flags = device_get_flags(dev); - int rid; - struct resource *port; - - rid = xrid; - port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - IO_COMSIZE, RF_ACTIVE); - if (!port) - return (ENXIO); - - com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO); - if (com == NULL) { - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return (ENOMEM); - } - device_set_softc(dev, com); - com->bst = rman_get_bustag(port); - com->bsh = rman_get_bushandle(port); - if (rclk == 0) - rclk = DEFAULT_RCLK; - com->rclk = rclk; - - while (sio_inited != 2) - if (atomic_cmpset_int(&sio_inited, 0, 1)) { - mtx_init(&sio_lock, sio_driver_name, NULL, - (comconsole != -1) ? - MTX_SPIN | MTX_QUIET : MTX_SPIN); - atomic_store_rel_int(&sio_inited, 2); - } - -#if 0 - /* - * XXX this is broken - when we are first called, there are no - * previously configured IO ports. We could hard code - * 0x3f8, 0x2f8, 0x3e8, 0x2e8 etc but that's probably worse. - * This code has been doing nothing since the conversion since - * "count" is zero the first time around. - */ - if (!already_init) { - /* - * Turn off MCR_IENABLE for all likely serial ports. An unused - * port with its MCR_IENABLE gate open will inhibit interrupts - * from any used port that shares the interrupt vector. - * XXX the gate enable is elsewhere for some multiports. - */ - device_t *devs; - int count, i, xioport; - - devclass_get_devices(sio_devclass, &devs, &count); - for (i = 0; i < count; i++) { - xdev = devs[i]; - if (device_is_enabled(xdev) && - bus_get_resource(xdev, SYS_RES_IOPORT, 0, &xioport, - NULL) == 0) - outb(xioport + com_mcr, 0); - } - free(devs, M_TEMP); - already_init = TRUE; - } -#endif - - if (COM_LLCONSOLE(flags)) { - printf("sio%d: reserved for low-level i/o\n", - device_get_unit(dev)); - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - return (ENXIO); - } - - /* - * If the device is on a multiport card and has an AST/4 - * compatible interrupt control register, initialize this - * register and prepare to leave MCR_IENABLE clear in the mcr. - * Otherwise, prepare to set MCR_IENABLE in the mcr. - * Point idev to the device struct giving the correct id_irq. - * This is the struct for the master device if there is one. - */ - idev = dev; - mcr_image = MCR_IENABLE; -#ifdef COM_MULTIPORT - if (COM_ISMULTIPORT(flags)) { - Port_t xiobase; - u_long io; - - idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags)); - if (idev == NULL) { - printf("sio%d: master device %d not configured\n", - device_get_unit(dev), COM_MPMASTER(flags)); - idev = dev; - } - if (!COM_NOTAST4(flags)) { - if (bus_get_resource(idev, SYS_RES_IOPORT, 0, &io, - NULL) == 0) { - xiobase = io; - if (bus_get_resource(idev, SYS_RES_IRQ, 0, - NULL, NULL) == 0) - outb(xiobase + com_scr, 0x80); - else - outb(xiobase + com_scr, 0); - } - mcr_image = 0; - } - } -#endif /* COM_MULTIPORT */ - if (bus_get_resource(idev, SYS_RES_IRQ, 0, NULL, NULL) != 0) - mcr_image = 0; - - bzero(failures, sizeof failures); - iobase = rman_get_start(port); - - /* - * We don't want to get actual interrupts, just masked ones. - * Interrupts from this line should already be masked in the ICU, - * but mask them in the processor as well in case there are some - * (misconfigured) shared interrupts. - */ - mtx_lock_spin(&sio_lock); -/* EXTRA DELAY? */ - - /* - * For the TI16754 chips, set prescaler to 1 (4 is often the - * default after-reset value) as otherwise it's impossible to - * get highest baudrates. - */ - if (COM_TI16754(flags)) { - u_char cfcr, efr; - - cfcr = sio_getreg(com, com_cfcr); - sio_setreg(com, com_cfcr, CFCR_EFR_ENABLE); - efr = sio_getreg(com, com_efr); - /* Unlock extended features to turn off prescaler. */ - sio_setreg(com, com_efr, efr | EFR_EFE); - /* Disable EFR. */ - sio_setreg(com, com_cfcr, (cfcr != CFCR_EFR_ENABLE) ? cfcr : 0); - /* Turn off prescaler. */ - sio_setreg(com, com_mcr, - sio_getreg(com, com_mcr) & ~MCR_PRESCALE); - sio_setreg(com, com_cfcr, CFCR_EFR_ENABLE); - sio_setreg(com, com_efr, efr); - sio_setreg(com, com_cfcr, cfcr); - } - - /* - * Initialize the speed and the word size and wait long enough to - * drain the maximum of 16 bytes of junk in device output queues. - * The speed is undefined after a master reset and must be set - * before relying on anything related to output. There may be - * junk after a (very fast) soft reboot and (apparently) after - * master reset. - * XXX what about the UART bug avoided by waiting in comparam()? - * We don't want to wait long enough to drain at 2 bps. - */ - if (iobase == siocniobase) - DELAY((16 + 1) * 1000000 / (comdefaultrate / 10)); - else { - sio_setreg(com, com_cfcr, CFCR_DLAB | CFCR_8BITS); - divisor = siodivisor(rclk, SIO_TEST_SPEED); - sio_setreg(com, com_dlbl, divisor & 0xff); - sio_setreg(com, com_dlbh, divisor >> 8); - sio_setreg(com, com_cfcr, CFCR_8BITS); - DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10)); - } - - /* - * Enable the interrupt gate and disable device interrupts. This - * should leave the device driving the interrupt line low and - * guarantee an edge trigger if an interrupt can be generated. - */ -/* EXTRA DELAY? */ - sio_setreg(com, com_mcr, mcr_image); - sio_setreg(com, com_ier, 0); - DELAY(1000); /* XXX */ - irqmap[0] = isa_irq_pending(); - - /* - * Attempt to set loopback mode so that we can send a null byte - * without annoying any external device. - */ -/* EXTRA DELAY? */ - sio_setreg(com, com_mcr, mcr_image | MCR_LOOPBACK); - - /* - * Attempt to generate an output interrupt. On 8250's, setting - * IER_ETXRDY generates an interrupt independent of the current - * setting and independent of whether the THR is empty. On 16450's, - * setting IER_ETXRDY generates an interrupt independent of the - * current setting. On 16550A's, setting IER_ETXRDY only - * generates an interrupt when IER_ETXRDY is not already set. - */ - sio_setreg(com, com_ier, IER_ETXRDY); - - /* - * On some 16x50 incompatibles, setting IER_ETXRDY doesn't generate - * an interrupt. They'd better generate one for actually doing - * output. Loopback may be broken on the same incompatibles but - * it's unlikely to do more than allow the null byte out. - */ - sio_setreg(com, com_data, 0); - if (iobase == siocniobase) - DELAY((1 + 2) * 1000000 / (comdefaultrate / 10)); - else - DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10)); - - /* - * Turn off loopback mode so that the interrupt gate works again - * (MCR_IENABLE was hidden). This should leave the device driving - * an interrupt line high. It doesn't matter if the interrupt - * line oscillates while we are not looking at it, since interrupts - * are disabled. - */ -/* EXTRA DELAY? */ - sio_setreg(com, com_mcr, mcr_image); - - /* - * It seems my Xircom CBEM56G Cardbus modem wants to be reset - * to 8 bits *again*, or else probe test 0 will fail. - * gwk@sgi.com, 4/19/2001 - */ - sio_setreg(com, com_cfcr, CFCR_8BITS); - - /* - * Some PCMCIA cards (Palido 321s, DC-1S, ...) have the "TXRDY bug", - * so we probe for a buggy IIR_TXRDY implementation even in the - * noprobe case. We don't probe for it in the !noprobe case because - * noprobe is always set for PCMCIA cards and the problem is not - * known to affect any other cards. - */ - if (noprobe) { - /* Read IIR a few times. */ - for (fn = 0; fn < 2; fn ++) { - DELAY(10000); - failures[6] = sio_getreg(com, com_iir); - } - - /* IIR_TXRDY should be clear. Is it? */ - result = 0; - if (failures[6] & IIR_TXRDY) { - /* - * No. We seem to have the bug. Does our fix for - * it work? - */ - sio_setreg(com, com_ier, 0); - if (sio_getreg(com, com_iir) & IIR_NOPEND) { - /* Yes. We discovered the TXRDY bug! */ - SET_FLAG(dev, COM_C_IIR_TXRDYBUG); - } else { - /* No. Just fail. XXX */ - result = ENXIO; - sio_setreg(com, com_mcr, 0); - } - } else { - /* Yes. No bug. */ - CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); - } - sio_setreg(com, com_ier, 0); - sio_setreg(com, com_cfcr, CFCR_8BITS); - mtx_unlock_spin(&sio_lock); - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - if (iobase == siocniobase) - result = 0; - /* - * XXX: Since we don't return 0, we shouldn't be relying on - * the softc that we set to persist to the call to attach - * since other probe routines may be called, and the malloc - * here causes subr_bus to not allocate anything for the - * other probes. Instead, this softc is preserved and other - * probe routines can corrupt it. - */ - if (result != 0) { - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - } - return (result == 0 ? BUS_PROBE_DEFAULT + 1 : result); - } - - /* - * Check that - * o the CFCR, IER and MCR in UART hold the values written to them - * (the values happen to be all distinct - this is good for - * avoiding false positive tests from bus echoes). - * o an output interrupt is generated and its vector is correct. - * o the interrupt goes away when the IIR in the UART is read. - */ -/* EXTRA DELAY? */ - failures[0] = sio_getreg(com, com_cfcr) - CFCR_8BITS; - failures[1] = sio_getreg(com, com_ier) - IER_ETXRDY; - failures[2] = sio_getreg(com, com_mcr) - mcr_image; - DELAY(10000); /* Some internal modems need this time */ - irqmap[1] = isa_irq_pending(); - failures[4] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_TXRDY; - DELAY(1000); /* XXX */ - irqmap[2] = isa_irq_pending(); - failures[6] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND; - - /* - * Turn off all device interrupts and check that they go off properly. - * Leave MCR_IENABLE alone. For ports without a master port, it gates - * the OUT2 output of the UART to - * the ICU input. Closing the gate would give a floating ICU input - * (unless there is another device driving it) and spurious interrupts. - * (On the system that this was first tested on, the input floats high - * and gives a (masked) interrupt as soon as the gate is closed.) - */ - sio_setreg(com, com_ier, 0); - sio_setreg(com, com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */ - failures[7] = sio_getreg(com, com_ier); - DELAY(1000); /* XXX */ - irqmap[3] = isa_irq_pending(); - failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND; - - mtx_unlock_spin(&sio_lock); - - irqs = irqmap[1] & ~irqmap[0]; - if (bus_get_resource(idev, SYS_RES_IRQ, 0, &xirq, NULL) == 0 && - ((1 << xirq) & irqs) == 0) { - printf( - "sio%d: configured irq %ld not in bitmap of probed irqs %#x\n", - device_get_unit(dev), xirq, irqs); - printf( - "sio%d: port may not be enabled\n", - device_get_unit(dev)); - } - if (bootverbose) - printf("sio%d: irq maps: %#x %#x %#x %#x\n", - device_get_unit(dev), - irqmap[0], irqmap[1], irqmap[2], irqmap[3]); - - result = 0; - for (fn = 0; fn < sizeof failures; ++fn) - if (failures[fn]) { - sio_setreg(com, com_mcr, 0); - result = ENXIO; - if (bootverbose) { - printf("sio%d: probe failed test(s):", - device_get_unit(dev)); - for (fn = 0; fn < sizeof failures; ++fn) - if (failures[fn]) - printf(" %d", fn); - printf("\n"); - } - break; - } - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - if (iobase == siocniobase) - result = 0; - /* - * XXX: Since we don't return 0, we shouldn't be relying on the softc - * that we set to persist to the call to attach since other probe - * routines may be called, and the malloc here causes subr_bus to not - * allocate anything for the other probes. Instead, this softc is - * preserved and other probe routines can corrupt it. - */ - if (result != 0) { - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - } - return (result == 0 ? BUS_PROBE_DEFAULT + 1 : result); -} - -#ifdef COM_ESP -static int -espattach(com, esp_port) - struct com_s *com; - Port_t esp_port; -{ - u_char dips; - u_char val; - - /* - * Check the ESP-specific I/O port to see if we're an ESP - * card. If not, return failure immediately. - */ - if ((inb(esp_port) & 0xf3) == 0) { - printf(" port 0x%x is not an ESP board?\n", esp_port); - return (0); - } - - /* - * We've got something that claims to be a Hayes ESP card. - * Let's hope so. - */ - - /* Get the dip-switch configuration */ - outb(esp_port + ESP_CMD1, ESP_GETDIPS); - dips = inb(esp_port + ESP_STATUS1); - - /* - * Bits 0,1 of dips say which COM port we are. - */ - if (rman_get_start(com->ioportres) == likely_com_ports[dips & 0x03]) - printf(" : ESP"); - else { - printf(" esp_port has com %d\n", dips & 0x03); - return (0); - } - - /* - * Check for ESP version 2.0 or later: bits 4,5,6 = 010. - */ - outb(esp_port + ESP_CMD1, ESP_GETTEST); - val = inb(esp_port + ESP_STATUS1); /* clear reg 1 */ - val = inb(esp_port + ESP_STATUS2); - if ((val & 0x70) < 0x20) { - printf("-old (%o)", val & 0x70); - return (0); - } - - /* - * Check for ability to emulate 16550: bit 7 == 1 - */ - if ((dips & 0x80) == 0) { - printf(" slave"); - return (0); - } - - /* - * Okay, we seem to be a Hayes ESP card. Whee. - */ - com->esp = TRUE; - com->esp_port = esp_port; - return (1); -} -#endif /* COM_ESP */ - -int -sioattach(dev, xrid, rclk) - device_t dev; - int xrid; - u_long rclk; -{ - struct com_s *com; -#ifdef COM_ESP - Port_t *espp; -#endif - Port_t iobase; - int unit; - u_int flags; - int rid; - struct resource *port; - int ret; - int error; - struct tty *tp; - - rid = xrid; - port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - IO_COMSIZE, RF_ACTIVE); - if (!port) - return (ENXIO); - - iobase = rman_get_start(port); - unit = device_get_unit(dev); - com = device_get_softc(dev); - flags = device_get_flags(dev); - - if (unit >= sio_numunits) - sio_numunits = unit + 1; - /* - * sioprobe() has initialized the device registers as follows: - * o cfcr = CFCR_8BITS. - * It is most important that CFCR_DLAB is off, so that the - * data port is not hidden when we enable interrupts. - * o ier = 0. - * Interrupts are only enabled when the line is open. - * o mcr = MCR_IENABLE, or 0 if the port has AST/4 compatible - * interrupt control register or the config specifies no irq. - * Keeping MCR_DTR and MCR_RTS off might stop the external - * device from sending before we are ready. - */ - bzero(com, sizeof *com); - com->unit = unit; - com->ioportres = port; - com->ioportrid = rid; - com->bst = rman_get_bustag(port); - com->bsh = rman_get_bushandle(port); - com->cfcr_image = CFCR_8BITS; - com->loses_outints = COM_LOSESOUTINTS(flags) != 0; - com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0; - com->tx_fifo_size = 1; - com->obufs[0].l_head = com->obuf1; - com->obufs[1].l_head = com->obuf2; - - com->data_port = iobase + com_data; - com->int_ctl_port = iobase + com_ier; - com->int_id_port = iobase + com_iir; - com->modem_ctl_port = iobase + com_mcr; - com->mcr_image = inb(com->modem_ctl_port); - com->line_status_port = iobase + com_lsr; - com->modem_status_port = iobase + com_msr; - - tp = com->tp = ttyalloc(); - tp->t_oproc = comstart; - tp->t_param = comparam; - tp->t_stop = comstop; - tp->t_modem = commodem; - tp->t_break = combreak; - tp->t_close = comclose; - tp->t_open = comopen; - tp->t_sc = com; - - if (rclk == 0) - rclk = DEFAULT_RCLK; - com->rclk = rclk; - - if (unit == comconsole) - ttyconsolemode(tp, comdefaultrate); - error = siosetwater(com, tp->t_init_in.c_ispeed); - mtx_unlock_spin(&sio_lock); - if (error) { - /* - * Leave i/o resources allocated if this is a `cn'-level - * console, so that other devices can't snarf them. - */ - if (iobase != siocniobase) - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return (ENOMEM); - } - - /* attempt to determine UART type */ - printf("sio%d: type", unit); - - if (!COM_ISMULTIPORT(flags) && - !COM_IIR_TXRDYBUG(flags) && !COM_NOSCR(flags)) { - u_char scr; - u_char scr1; - u_char scr2; - - scr = sio_getreg(com, com_scr); - sio_setreg(com, com_scr, 0xa5); - scr1 = sio_getreg(com, com_scr); - sio_setreg(com, com_scr, 0x5a); - scr2 = sio_getreg(com, com_scr); - sio_setreg(com, com_scr, scr); - if (scr1 != 0xa5 || scr2 != 0x5a) { - printf(" 8250 or not responding"); - goto determined_type; - } - } - sio_setreg(com, com_fifo, FIFO_ENABLE | FIFO_RX_HIGH); - DELAY(100); - switch (inb(com->int_id_port) & IIR_FIFO_MASK) { - case FIFO_RX_LOW: - printf(" 16450"); - break; - case FIFO_RX_MEDL: - printf(" 16450?"); - break; - case FIFO_RX_MEDH: - printf(" 16550?"); - break; - case FIFO_RX_HIGH: - if (COM_NOFIFO(flags)) { - printf(" 16550A fifo disabled"); - break; - } - com->hasfifo = TRUE; - if (COM_ST16650A(flags)) { - printf(" ST16650A"); - com->st16650a = TRUE; - com->tx_fifo_size = 32; - break; - } - if (COM_TI16754(flags)) { - printf(" TI16754"); - com->tx_fifo_size = 64; - break; - } - printf(" 16550A"); -#ifdef COM_ESP - for (espp = likely_esp_ports; *espp != 0; espp++) - if (espattach(com, *espp)) { - com->tx_fifo_size = 1024; - break; - } - if (com->esp) - break; -#endif - com->tx_fifo_size = COM_FIFOSIZE(flags); - if (com->tx_fifo_size == 0) - com->tx_fifo_size = 16; - else - printf(" lookalike with %u bytes FIFO", - com->tx_fifo_size); - break; - } -#ifdef COM_ESP - if (com->esp) { - /* - * Set 16550 compatibility mode. - * We don't use the ESP_MODE_SCALE bit to increase the - * fifo trigger levels because we can't handle large - * bursts of input. - * XXX flow control should be set in comparam(), not here. - */ - outb(com->esp_port + ESP_CMD1, ESP_SETMODE); - outb(com->esp_port + ESP_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO); - - /* Set RTS/CTS flow control. */ - outb(com->esp_port + ESP_CMD1, ESP_SETFLOWTYPE); - outb(com->esp_port + ESP_CMD2, ESP_FLOW_RTS); - outb(com->esp_port + ESP_CMD2, ESP_FLOW_CTS); - - /* Set flow-control levels. */ - outb(com->esp_port + ESP_CMD1, ESP_SETRXFLOW); - outb(com->esp_port + ESP_CMD2, HIBYTE(768)); - outb(com->esp_port + ESP_CMD2, LOBYTE(768)); - outb(com->esp_port + ESP_CMD2, HIBYTE(512)); - outb(com->esp_port + ESP_CMD2, LOBYTE(512)); - } -#endif /* COM_ESP */ - sio_setreg(com, com_fifo, 0); -determined_type: ; - -#ifdef COM_MULTIPORT - if (COM_ISMULTIPORT(flags)) { - device_t masterdev; - - com->multiport = TRUE; - printf(" (multiport"); - if (unit == COM_MPMASTER(flags)) - printf(" master"); - printf(")"); - masterdev = devclass_get_device(sio_devclass, - COM_MPMASTER(flags)); - com->no_irq = (masterdev == NULL || bus_get_resource(masterdev, - SYS_RES_IRQ, 0, NULL, NULL) != 0); - } -#endif /* COM_MULTIPORT */ - if (unit == comconsole) - printf(", console"); - if (COM_IIR_TXRDYBUG(flags)) - printf(" with a buggy IIR_TXRDY implementation"); - printf("\n"); - - if (sio_fast_ih == NULL) { - swi_add(&tty_intr_event, "sio", siopoll, NULL, SWI_TTY, 0, - &sio_fast_ih); - swi_add(&clk_intr_event, "sio", siopoll, NULL, SWI_CLOCK, 0, - &sio_slow_ih); - } - - com->flags = flags; - com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; - tp->t_pps = &com->pps; - - if (COM_PPSCTS(flags)) - com->pps_bit = MSR_CTS; - else - com->pps_bit = MSR_DCD; - pps_init(&com->pps); - - rid = 0; - com->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (com->irqres) { - ret = bus_setup_intr(dev, com->irqres, - INTR_TYPE_TTY, - siointr, NULL, com, - &com->cookie); - if (ret) { - ret = bus_setup_intr(dev, - com->irqres, INTR_TYPE_TTY, - NULL, (driver_intr_t *)siointr, com, &com->cookie); - if (ret == 0) - device_printf(dev, "unable to activate interrupt in fast mode - using normal mode\n"); - } - if (ret) - device_printf(dev, "could not activate interrupt\n"); -#if defined(KDB) - /* - * Enable interrupts for early break-to-debugger support - * on the console. - */ - if (ret == 0 && unit == comconsole) - outb(siocniobase + com_ier, IER_ERXRDY | IER_ERLS | - IER_EMSC); -#endif - } - - /* We're ready, open the doors... */ - ttycreate(tp, TS_CALLOUT, "d%r", unit); - - return (0); -} - -static int -comopen(struct tty *tp, struct cdev *dev) -{ - struct com_s *com; - int i; - - com = tp->t_sc; - com->poll = com->no_irq; - com->poll_output = com->loses_outints; - if (com->hasfifo) { - /* - * (Re)enable and drain fifos. - * - * Certain SMC chips cause problems if the fifos - * are enabled while input is ready. Turn off the - * fifo if necessary to clear the input. We test - * the input ready bit after enabling the fifos - * since we've already enabled them in comparam() - * and to handle races between enabling and fresh - * input. - */ - for (i = 0; i < 500; i++) { - sio_setreg(com, com_fifo, - FIFO_RCV_RST | FIFO_XMT_RST - | com->fifo_image); - /* - * XXX the delays are for superstitious - * historical reasons. It must be less than - * the character time at the maximum - * supported speed (87 usec at 115200 bps - * 8N1). Otherwise we might loop endlessly - * if data is streaming in. We used to use - * delays of 100. That usually worked - * because DELAY(100) used to usually delay - * for about 85 usec instead of 100. - */ - DELAY(50); - if (!(inb(com->line_status_port) & LSR_RXRDY)) - break; - sio_setreg(com, com_fifo, 0); - DELAY(50); - (void) inb(com->data_port); - } - if (i == 500) - return (EIO); - } - - mtx_lock_spin(&sio_lock); - (void) inb(com->line_status_port); - (void) inb(com->data_port); - com->prev_modem_status = com->last_modem_status - = inb(com->modem_status_port); - outb(com->int_ctl_port, - IER_ERXRDY | IER_ERLS | IER_EMSC - | (COM_IIR_TXRDYBUG(com->flags) ? 0 : IER_ETXRDY)); - mtx_unlock_spin(&sio_lock); - siosettimeout(); - /* XXX: should be generic ? */ - if (com->prev_modem_status & MSR_DCD || ISCALLOUT(dev)) - ttyld_modem(tp, 1); - return (0); -} - -static void -comclose(tp) - struct tty *tp; -{ - int s; - struct com_s *com; - - s = spltty(); - com = tp->t_sc; - com->poll = FALSE; - com->poll_output = FALSE; - sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); - -#if defined(KDB) - /* - * Leave interrupts enabled and don't clear DTR if this is the - * console. This allows us to detect break-to-debugger events - * while the console device is closed. - */ - if (com->unit != comconsole) -#endif - { - sio_setreg(com, com_ier, 0); - 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 & MSR_DCD) - && !(tp->t_init_in.c_cflag & CLOCAL)) - || !(tp->t_state & TS_ISOPEN)) { - (void)commodem(tp, 0, SER_DTR); - ttydtrwaitstart(tp); - } - } - if (com->hasfifo) { - /* - * Disable fifos so that they are off after controlled - * reboots. Some BIOSes fail to detect 16550s when the - * fifos are enabled. - */ - sio_setreg(com, com_fifo, 0); - } - tp->t_actout = FALSE; - wakeup(&tp->t_actout); - wakeup(TSA_CARR_ON(tp)); /* restart any wopeners */ - siosettimeout(); - splx(s); -} - -static void -siobusycheck(chan) - void *chan; -{ - struct com_s *com; - int s; - - com = (struct com_s *)chan; - - /* - * Clear TS_BUSY if low-level output is complete. - * spl locking is sufficient because siointr1() does not set CS_BUSY. - * If siointr1() clears CS_BUSY after we look at it, then we'll get - * called again. Reading the line status port outside of siointr1() - * is safe because CS_BUSY is clear so there are no output interrupts - * to lose. - */ - s = spltty(); - if (com->state & CS_BUSY) - com->extra_state &= ~CSE_BUSYCHECK; /* False alarm. */ - else if ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY)) - == (LSR_TSRE | LSR_TXRDY)) { - com->tp->t_state &= ~TS_BUSY; - ttwwakeup(com->tp); - com->extra_state &= ~CSE_BUSYCHECK; - } else - timeout(siobusycheck, com, hz / 100); - splx(s); -} - -static u_int -siodivisor(rclk, speed) - u_long rclk; - speed_t speed; -{ - long actual_speed; - u_int divisor; - int error; - - if (speed == 0) - return (0); -#if UINT_MAX > (ULONG_MAX - 1) / 8 - if (speed > (ULONG_MAX - 1) / 8) - return (0); -#endif - divisor = (rclk / (8UL * speed) + 1) / 2; - if (divisor == 0 || divisor >= 65536) - return (0); - actual_speed = rclk / (16UL * divisor); - - /* 10 times error in percent: */ - error = ((actual_speed - (long)speed) * 2000 / (long)speed + 1) / 2; - - /* 3.0% maximum error tolerance: */ - if (error < -30 || error > 30) - return (0); - - return (divisor); -} - -/* - * Call this function with the sio_lock mutex held. It will return with the - * lock still held. - */ -static void -sioinput(com) - 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) || !(tp->t_cflag & CREAD)) { - com_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. - */ - mtx_unlock_spin(&sio_lock); - 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; - comstart(tp); - } - mtx_lock_spin(&sio_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. - */ - mtx_unlock_spin(&sio_lock); - line_status = buf[com->ierroff]; - recv_data = *buf++; - if (line_status - & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) { - if (line_status & LSR_BI) - recv_data |= TTY_BI; - if (line_status & LSR_FE) - recv_data |= TTY_FE; - if (line_status & LSR_OE) - recv_data |= TTY_OE; - if (line_status & LSR_PE) - recv_data |= TTY_PE; - } - ttyld_rint(tp, recv_data); - mtx_lock_spin(&sio_lock); - } while (buf < com->iptr); - } - com_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 & MCR_RTS) && - !(tp->t_state & TS_TBLOCK)) - outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); -} - -static int -siointr(arg) - void *arg; -{ - struct com_s *com; - -#ifndef COM_MULTIPORT - com = (struct com_s *)arg; - - mtx_lock_spin(&sio_lock); - siointr1(com); - mtx_unlock_spin(&sio_lock); -#else /* COM_MULTIPORT */ - bool_t possibly_more_intrs; - int unit; - - /* - * Loop until there is no activity on any port. This is necessary - * to get an interrupt edge more than to avoid another interrupt. - * If the IRQ signal is just an OR of the IRQ signals from several - * devices, then the edge from one may be lost because another is - * on. - */ - mtx_lock_spin(&sio_lock); - do { - possibly_more_intrs = FALSE; - for (unit = 0; unit < sio_numunits; ++unit) { - com = com_addr(unit); - /* - * XXX COM_LOCK(); - * would it work here, or be counter-productive? - */ - if (com != NULL - && !com->gone - && (inb(com->int_id_port) & IIR_IMASK) - != IIR_NOPEND) { - siointr1(com); - possibly_more_intrs = TRUE; - } - /* XXX COM_UNLOCK(); */ - } - } while (possibly_more_intrs); - mtx_unlock_spin(&sio_lock); -#endif /* COM_MULTIPORT */ - return(FILTER_HANDLED); -} - -static struct timespec siots[8]; -static int siotso; -static int volatile siotsunit = -1; - -static int -sysctl_siots(SYSCTL_HANDLER_ARGS) -{ - char buf[128]; - long long delta; - size_t len; - int error, i, tso; - - for (i = 1, tso = siotso; i < tso; i++) { - delta = (long long)(siots[i].tv_sec - siots[i - 1].tv_sec) * - 1000000000 + - (siots[i].tv_nsec - siots[i - 1].tv_nsec); - len = sprintf(buf, "%lld\n", delta); - if (delta >= 110000) - len += sprintf(buf + len - 1, ": *** %ld.%09ld\n", - (long)siots[i].tv_sec, siots[i].tv_nsec) - 1; - if (i == tso - 1) - buf[len - 1] = '\0'; - error = SYSCTL_OUT(req, buf, len); - if (error != 0) - return (error); - } - return (0); -} - -SYSCTL_PROC(_machdep, OID_AUTO, siots, CTLTYPE_STRING | CTLFLAG_RD, - 0, 0, sysctl_siots, "A", "sio timestamps"); - -static void -siointr1(com) - struct com_s *com; -{ - u_char int_ctl; - u_char int_ctl_new; - u_char line_status; - u_char modem_status; - u_char *ioptr; - u_char recv_data; - -#ifdef KDB -again: -#endif - - if (COM_IIR_TXRDYBUG(com->flags)) { - int_ctl = inb(com->int_ctl_port); - int_ctl_new = int_ctl; - } else { - int_ctl = 0; - int_ctl_new = 0; - } - - while (!com->gone) { - if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) { - modem_status = inb(com->modem_status_port); - if ((modem_status ^ com->last_modem_status) & - com->pps_bit) { - pps_capture(&com->pps); - pps_event(&com->pps, - (modem_status & com->pps_bit) ? - PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); - } - } - line_status = inb(com->line_status_port); - - /* input event? (check first to help avoid overruns) */ - while (line_status & LSR_RCV_MASK) { - /* break/unnattached error bits or real input? */ - if (!(line_status & LSR_RXRDY)) - recv_data = 0; - else - recv_data = inb(com->data_port); -#ifdef KDB - if (com->unit == comconsole && - kdb_alt_break(recv_data, &com->alt_brk_state) != 0) - goto again; -#endif /* KDB */ - if (line_status & (LSR_BI | LSR_FE | LSR_PE)) { - /* - * Don't store BI if IGNBRK or FE/PE if IGNPAR. - * Otherwise, push the work to a higher level - * (to handle PARMRK) if we're bypassing. - * Otherwise, convert BI/FE and PE+INPCK to 0. - * - * This makes bypassing work right in the - * usual "raw" case (IGNBRK set, and IGNPAR - * and INPCK clear). - * - * Note: BI together with FE/PE means just BI. - */ - if (line_status & LSR_BI) { -#if defined(KDB) - if (com->unit == comconsole) { - kdb_break(); - goto cont; - } -#endif - if (com->tp == NULL - || com->tp->t_iflag & IGNBRK) - goto cont; - } else { - if (com->tp == NULL - || com->tp->t_iflag & IGNPAR) - goto cont; - } - if (com->tp->t_state & TS_CAN_BYPASS_L_RINT - && (line_status & (LSR_BI | LSR_FE) - || com->tp->t_iflag & INPCK)) - recv_data = 0; - } - ++com->bytes_in; - if (com->tp != NULL && - com->tp->t_hotchar != 0 && recv_data == com->tp->t_hotchar) - swi_sched(sio_fast_ih, 0); - 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); - ++com_events; - swi_sched(sio_slow_ih, SWI_DELAY); -#if 0 /* for testing input latency vs efficiency */ -if (com->iptr - com->ibuf == 8) - swi_sched(sio_fast_ih, 0); -#endif - ioptr[0] = recv_data; - ioptr[com->ierroff] = line_status; - com->iptr = ++ioptr; - if (ioptr == com->ihighwater - && com->state & CS_RTS_IFLOW) - outb(com->modem_ctl_port, - com->mcr_image &= ~MCR_RTS); - if (line_status & LSR_OE) - CE_RECORD(com, CE_OVERRUN); - } -cont: - if (line_status & LSR_TXRDY - && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) - goto txrdy; - - /* - * "& 0x7F" is to avoid the gcc-1.40 generating a slow - * jump from the top of the loop to here - */ - line_status = inb(com->line_status_port) & 0x7F; - } - - /* modem status change? (always check before doing output) */ - modem_status = inb(com->modem_status_port); - 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)) { - com_events += LOTS_OF_EVENTS; - com->state |= CS_CHECKMSR; - swi_sched(sio_fast_ih, 0); - } - - /* handle CTS change immediately for crisp flow ctl */ - if (com->state & CS_CTS_OFLOW) { - if (modem_status & MSR_CTS) - com->state |= CS_ODEVREADY; - else - com->state &= ~CS_ODEVREADY; - } - } - -txrdy: - /* output queued and everything ready? */ - if (line_status & LSR_TXRDY - && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) { - ioptr = com->obufq.l_head; - if (com->tx_fifo_size > 1 && com->unit != siotsunit) { - u_int ocount; - - ocount = com->obufq.l_tail - ioptr; - if (ocount > com->tx_fifo_size) - ocount = com->tx_fifo_size; - com->bytes_out += ocount; - do - outb(com->data_port, *ioptr++); - while (--ocount != 0); - } else { - outb(com->data_port, *ioptr++); - ++com->bytes_out; - if (com->unit == siotsunit - && siotso < nitems(siots)) - nanouptime(&siots[siotso++]); - } - com->obufq.l_head = ioptr; - if (COM_IIR_TXRDYBUG(com->flags)) - int_ctl_new = int_ctl | IER_ETXRDY; - 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 */ - if (COM_IIR_TXRDYBUG(com->flags)) - int_ctl_new = int_ctl - & ~IER_ETXRDY; - com->state &= ~CS_BUSY; - } - if (!(com->state & CS_ODONE)) { - com_events += LOTS_OF_EVENTS; - com->state |= CS_ODONE; - /* handle at high level ASAP */ - swi_sched(sio_fast_ih, 0); - } - } - if (COM_IIR_TXRDYBUG(com->flags) - && int_ctl != int_ctl_new) - outb(com->int_ctl_port, int_ctl_new); - } - - /* finished? */ -#ifndef COM_MULTIPORT - if ((inb(com->int_id_port) & IIR_IMASK) == IIR_NOPEND) -#endif /* COM_MULTIPORT */ - return; - } -} - -/* software interrupt handler for SWI_TTY */ -static void -siopoll(void *dummy) -{ - int unit; - - if (com_events == 0) - return; -repeat: - for (unit = 0; unit < sio_numunits; ++unit) { - struct com_s *com; - int incc; - struct tty *tp; - - com = com_addr(unit); - if (com == NULL) - continue; - tp = com->tp; - if (tp == NULL || com->gone) { - /* - * Discard any events related to never-opened or - * going-away devices. - */ - mtx_lock_spin(&sio_lock); - incc = com->iptr - com->ibuf; - com->iptr = com->ibuf; - if (com->state & CS_CHECKMSR) { - incc += LOTS_OF_EVENTS; - com->state &= ~CS_CHECKMSR; - } - com_events -= incc; - mtx_unlock_spin(&sio_lock); - continue; - } - if (com->iptr != com->ibuf) { - mtx_lock_spin(&sio_lock); - sioinput(com); - mtx_unlock_spin(&sio_lock); - } - if (com->state & CS_CHECKMSR) { - u_char delta_modem_status; - - mtx_lock_spin(&sio_lock); - delta_modem_status = com->last_modem_status - ^ com->prev_modem_status; - com->prev_modem_status = com->last_modem_status; - com_events -= LOTS_OF_EVENTS; - com->state &= ~CS_CHECKMSR; - mtx_unlock_spin(&sio_lock); - if (delta_modem_status & MSR_DCD) - ttyld_modem(tp, - com->prev_modem_status & MSR_DCD); - } - if (com->state & CS_ODONE) { - mtx_lock_spin(&sio_lock); - com_events -= LOTS_OF_EVENTS; - com->state &= ~CS_ODONE; - mtx_unlock_spin(&sio_lock); - if (!(com->state & CS_BUSY) - && !(com->extra_state & CSE_BUSYCHECK)) { - timeout(siobusycheck, com, hz / 100); - com->extra_state |= CSE_BUSYCHECK; - } - ttyld_start(tp); - } - if (com_events == 0) - break; - } - if (com_events >= LOTS_OF_EVENTS) - goto repeat; -} - -static void -combreak(tp, sig) - struct tty *tp; - int sig; -{ - struct com_s *com; - - com = tp->t_sc; - - if (sig) - sio_setreg(com, com_cfcr, com->cfcr_image |= CFCR_SBREAK); - else - sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); -} - -static int -comparam(tp, t) - struct tty *tp; - struct termios *t; -{ - u_int cfcr; - int cflag; - struct com_s *com; - u_int divisor; - u_char dlbh; - u_char dlbl; - u_char efr_flowbits; - int s; - - com = tp->t_sc; - if (com == NULL) - return (ENODEV); - - /* check requested parameters */ - if (t->c_ispeed != (t->c_ospeed != 0 ? t->c_ospeed : tp->t_ospeed)) - return (EINVAL); - divisor = siodivisor(com->rclk, t->c_ispeed); - if (divisor == 0) - return (EINVAL); - - /* parameters are OK, convert them to the com struct and the device */ - s = spltty(); - if (t->c_ospeed == 0) - (void)commodem(tp, 0, SER_DTR); /* hang up line */ - else - (void)commodem(tp, SER_DTR, 0); - cflag = t->c_cflag; - switch (cflag & CSIZE) { - case CS5: - cfcr = CFCR_5BITS; - break; - case CS6: - cfcr = CFCR_6BITS; - break; - case CS7: - cfcr = CFCR_7BITS; - break; - default: - cfcr = CFCR_8BITS; - break; - } - if (cflag & PARENB) { - cfcr |= CFCR_PENAB; - if (!(cflag & PARODD)) - cfcr |= CFCR_PEVEN; - } - if (cflag & CSTOPB) - cfcr |= CFCR_STOPB; - - if (com->hasfifo) { - /* - * Use a fifo trigger level low enough so that the input - * latency from the fifo is less than about 16 msec and - * the total latency is less than about 30 msec. These - * latencies are reasonable for humans. Serial comms - * protocols shouldn't expect anything better since modem - * latencies are larger. - * - * The fifo trigger level cannot be set at RX_HIGH for high - * speed connections without further work on reducing - * interrupt disablement times in other parts of the system, - * without producing silo overflow errors. - */ - com->fifo_image = com->unit == siotsunit ? 0 - : t->c_ispeed <= 4800 - ? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_MEDH; -#ifdef COM_ESP - /* - * The Hayes ESP card needs the fifo DMA mode bit set - * in compatibility mode. If not, it will interrupt - * for each character received. - */ - if (com->esp) - com->fifo_image |= FIFO_DMA_MODE; -#endif - sio_setreg(com, com_fifo, com->fifo_image); - } - - /* - * This returns with interrupts disabled so that we can complete - * the speed change atomically. Keeping interrupts disabled is - * especially important while com_data is hidden. - */ - (void) siosetwater(com, t->c_ispeed); - - sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB); - /* - * Only set the divisor registers if they would change, since on - * some 16550 incompatibles (UMC8669F), setting them while input - * is arriving loses sync until data stops arriving. - */ - dlbl = divisor & 0xFF; - if (sio_getreg(com, com_dlbl) != dlbl) - sio_setreg(com, com_dlbl, dlbl); - dlbh = divisor >> 8; - if (sio_getreg(com, com_dlbh) != dlbh) - sio_setreg(com, com_dlbh, dlbh); - - efr_flowbits = 0; - - if (cflag & CRTS_IFLOW) { - com->state |= CS_RTS_IFLOW; - efr_flowbits |= EFR_AUTORTS; - /* - * If CS_RTS_IFLOW just changed from off to on, the change - * needs to be propagated to MCR_RTS. This isn't urgent, - * so do it later by calling comstart() instead of repeating - * a lot of code from comstart() here. - */ - } else if (com->state & CS_RTS_IFLOW) { - com->state &= ~CS_RTS_IFLOW; - /* - * CS_RTS_IFLOW just changed from on to off. Force MCR_RTS - * on here, since comstart() won't do it later. - */ - outb(com->modem_ctl_port, com->mcr_image |= 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; - com->state &= ~CS_CTS_OFLOW; - if (cflag & CCTS_OFLOW) { - com->state |= CS_CTS_OFLOW; - efr_flowbits |= EFR_AUTOCTS; - if (!(com->last_modem_status & MSR_CTS)) - com->state &= ~CS_ODEVREADY; - } - - if (com->st16650a) { - sio_setreg(com, com_lcr, LCR_EFR_ENABLE); - sio_setreg(com, com_efr, - (sio_getreg(com, com_efr) - & ~(EFR_AUTOCTS | EFR_AUTORTS)) | efr_flowbits); - } - sio_setreg(com, com_cfcr, com->cfcr_image = cfcr); - - /* XXX shouldn't call functions while intrs are disabled. */ - ttyldoptim(tp); - - mtx_unlock_spin(&sio_lock); - splx(s); - comstart(tp); - if (com->ibufold != NULL) { - free(com->ibufold, M_DEVBUF); - com->ibufold = NULL; - } - return (0); -} - -/* - * This function must be called with the sio_lock mutex released and will - * return with it obtained. - */ -static int -siosetwater(com, speed) - 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) { - mtx_lock_spin(&sio_lock); - 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) { - mtx_lock_spin(&sio_lock); - 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. - */ - mtx_lock_spin(&sio_lock); - if (com->iptr != com->ibuf) - sioinput(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; - return (0); -} - -static void -comstart(tp) - struct tty *tp; -{ - struct com_s *com; - int s; - - com = tp->t_sc; - if (com == NULL) - return; - s = spltty(); - mtx_lock_spin(&sio_lock); - if (tp->t_state & TS_TTSTOP) - com->state &= ~CS_TTGO; - else - com->state |= CS_TTGO; - if (tp->t_state & TS_TBLOCK) { - if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW) - outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); - } else { - if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater - && com->state & CS_RTS_IFLOW) - outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); - } - mtx_unlock_spin(&sio_lock); - 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) { - 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; - mtx_lock_spin(&sio_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; - } - mtx_unlock_spin(&sio_lock); - } - if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { - 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; - mtx_lock_spin(&sio_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; - } - mtx_unlock_spin(&sio_lock); - } - tp->t_state |= TS_BUSY; - } - mtx_lock_spin(&sio_lock); - if (com->state >= (CS_BUSY | CS_TTGO)) - siointr1(com); /* fake interrupt to start output */ - mtx_unlock_spin(&sio_lock); - ttwwakeup(tp); - splx(s); -} - -static void -comstop(tp, rw) - struct tty *tp; - int rw; -{ - struct com_s *com; - - com = tp->t_sc; - if (com == NULL || com->gone) - return; - mtx_lock_spin(&sio_lock); - if (rw & FWRITE) { - if (com->hasfifo) -#ifdef COM_ESP - /* XXX avoid h/w bug. */ - if (!com->esp) -#endif - sio_setreg(com, com_fifo, - FIFO_XMT_RST | com->fifo_image); - com->obufs[0].l_queued = FALSE; - com->obufs[1].l_queued = FALSE; - if (com->state & CS_ODONE) - com_events -= LOTS_OF_EVENTS; - com->state &= ~(CS_ODONE | CS_BUSY); - com->tp->t_state &= ~TS_BUSY; - } - if (rw & FREAD) { - if (com->hasfifo) -#ifdef COM_ESP - /* XXX avoid h/w bug. */ - if (!com->esp) -#endif - sio_setreg(com, com_fifo, - FIFO_RCV_RST | com->fifo_image); - com_events -= (com->iptr - com->ibuf); - com->iptr = com->ibuf; - } - mtx_unlock_spin(&sio_lock); - comstart(tp); -} - -static int -commodem(struct tty *tp, int sigon, int sigoff) -{ - struct com_s *com; - int bitand, bitor, msr; - - com = tp->t_sc; - if (com->gone) - return(0); - if (sigon != 0 || sigoff != 0) { - bitand = bitor = 0; - if (sigoff & SER_DTR) - bitand |= MCR_DTR; - if (sigoff & SER_RTS) - bitand |= MCR_RTS; - if (sigon & SER_DTR) - bitor |= MCR_DTR; - if (sigon & SER_RTS) - bitor |= MCR_RTS; - bitand = ~bitand; - mtx_lock_spin(&sio_lock); - com->mcr_image &= bitand; - com->mcr_image |= bitor; - outb(com->modem_ctl_port, com->mcr_image); - mtx_unlock_spin(&sio_lock); - return (0); - } else { - bitor = 0; - if (com->mcr_image & MCR_DTR) - bitor |= SER_DTR; - if (com->mcr_image & MCR_RTS) - bitor |= SER_RTS; - msr = com->prev_modem_status; - if (msr & MSR_CTS) - bitor |= SER_CTS; - if (msr & MSR_DCD) - bitor |= SER_DCD; - if (msr & MSR_DSR) - bitor |= SER_DSR; - if (msr & MSR_DSR) - bitor |= SER_DSR; - if (msr & (MSR_RI | MSR_TERI)) - bitor |= SER_RI; - return (bitor); - } -} - -static void -siosettimeout() -{ - 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(comwakeup, (void *)NULL, sio_timeout_handle); - sio_timeout = hz; - someopen = FALSE; - for (unit = 0; unit < sio_numunits; ++unit) { - com = com_addr(unit); - if (com != NULL && com->tp != NULL - && com->tp->t_state & TS_ISOPEN && !com->gone) { - someopen = TRUE; - if (com->poll || com->poll_output) { - sio_timeout = hz > 200 ? hz / 200 : 1; - break; - } - } - } - if (someopen) { - sio_timeouts_until_log = hz / sio_timeout; - sio_timeout_handle = timeout(comwakeup, (void *)NULL, - sio_timeout); - } else { - /* Flush error messages, if any. */ - sio_timeouts_until_log = 1; - comwakeup((void *)NULL); - untimeout(comwakeup, (void *)NULL, sio_timeout_handle); - } -} - -static void -comwakeup(chan) - void *chan; -{ - struct com_s *com; - int unit; - - sio_timeout_handle = timeout(comwakeup, (void *)NULL, sio_timeout); - - /* - * Recover from lost output interrupts. - * Poll any lines that don't use interrupts. - */ - for (unit = 0; unit < sio_numunits; ++unit) { - com = com_addr(unit); - if (com != NULL && !com->gone - && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { - mtx_lock_spin(&sio_lock); - siointr1(com); - mtx_unlock_spin(&sio_lock); - } - } - - /* - * Check for and log errors, but not too often. - */ - if (--sio_timeouts_until_log > 0) - return; - sio_timeouts_until_log = hz / sio_timeout; - for (unit = 0; unit < sio_numunits; ++unit) { - int errnum; - - com = com_addr(unit); - if (com == NULL) - continue; - if (com->gone) - continue; - for (errnum = 0; errnum < CE_NTYPES; ++errnum) { - u_int delta; - u_long total; - - mtx_lock_spin(&sio_lock); - delta = com->delta_error_counts[errnum]; - com->delta_error_counts[errnum] = 0; - mtx_unlock_spin(&sio_lock); - if (delta == 0) - continue; - total = com->error_counts[errnum] += delta; - log(LOG_ERR, "sio%d: %u more %s%s (total %lu)\n", - unit, delta, error_desc[errnum], - delta == 1 ? "" : "s", total); - } - } -} - -/* - * Following are all routines needed for SIO to act as console - */ -struct siocnstate { - u_char dlbl; - u_char dlbh; - u_char ier; - u_char cfcr; - u_char mcr; -}; - -/* - * This is a function in order to not replicate "ttyd%d" more - * places than absolutely necessary. - */ -static void -siocnset(struct consdev *cd, int unit) -{ - - cd->cn_unit = unit; - sprintf(cd->cn_name, "ttyd%d", unit); -} - -static speed_t siocngetspeed(Port_t, u_long rclk); -static void siocnclose(struct siocnstate *sp, Port_t iobase); -static void siocnopen(struct siocnstate *sp, Port_t iobase, int speed); -static void siocntxwait(Port_t iobase); - -static cn_probe_t sio_cnprobe; -static cn_init_t sio_cninit; -static cn_term_t sio_cnterm; -static cn_getc_t sio_cngetc; -static cn_putc_t sio_cnputc; -static cn_grab_t sio_cngrab; -static cn_ungrab_t sio_cnungrab; - -CONSOLE_DRIVER(sio); - -static void -siocntxwait(iobase) - Port_t iobase; -{ - int timo; - - /* - * Wait for any pending transmission to finish. Required to avoid - * the UART lockup bug when the speed is changed, and for normal - * transmits. - */ - timo = 100000; - while ((inb(iobase + com_lsr) & (LSR_TSRE | LSR_TXRDY)) - != (LSR_TSRE | LSR_TXRDY) && --timo != 0) - ; -} - -/* - * Read the serial port specified and try to figure out what speed - * it's currently running at. We're assuming the serial port has - * been initialized and is basically idle. This routine is only intended - * to be run at system startup. - * - * If the value read from the serial port doesn't make sense, return 0. - */ - -static speed_t -siocngetspeed(iobase, rclk) - Port_t iobase; - u_long rclk; -{ - u_int divisor; - u_char dlbh; - u_char dlbl; - u_char cfcr; - - cfcr = inb(iobase + com_cfcr); - outb(iobase + com_cfcr, CFCR_DLAB | cfcr); - - dlbl = inb(iobase + com_dlbl); - dlbh = inb(iobase + com_dlbh); - - outb(iobase + com_cfcr, cfcr); - - divisor = dlbh << 8 | dlbl; - - /* XXX there should be more sanity checking. */ - if (divisor == 0) - return (CONSPEED); - return (rclk / (16UL * divisor)); -} - -static void -siocnopen(sp, iobase, speed) - struct siocnstate *sp; - Port_t iobase; - int speed; -{ - u_int divisor; - u_char dlbh; - u_char dlbl; - - /* - * Save all the device control registers except the fifo register - * and set our default ones (cs8 -parenb speed=comdefaultrate). - * We can't save the fifo register since it is read-only. - */ - sp->ier = inb(iobase + com_ier); - outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */ - siocntxwait(iobase); - sp->cfcr = inb(iobase + com_cfcr); - outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS); - sp->dlbl = inb(iobase + com_dlbl); - sp->dlbh = inb(iobase + com_dlbh); - /* - * Only set the divisor registers if they would change, since on - * some 16550 incompatibles (Startech), setting them clears the - * data input register. This also reduces the effects of the - * UMC8669F bug. - */ - divisor = siodivisor(comdefaultrclk, speed); - dlbl = divisor & 0xFF; - if (sp->dlbl != dlbl) - outb(iobase + com_dlbl, dlbl); - dlbh = divisor >> 8; - if (sp->dlbh != dlbh) - outb(iobase + com_dlbh, dlbh); - outb(iobase + com_cfcr, CFCR_8BITS); - sp->mcr = inb(iobase + com_mcr); - /* - * We don't want interrupts, but must be careful not to "disable" - * them by clearing the MCR_IENABLE bit, since that might cause - * an interrupt by floating the IRQ line. - */ - outb(iobase + com_mcr, (sp->mcr & MCR_IENABLE) | MCR_DTR | MCR_RTS); -} - -static void -siocnclose(sp, iobase) - struct siocnstate *sp; - Port_t iobase; -{ - /* - * Restore the device control registers. - */ - siocntxwait(iobase); - outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS); - if (sp->dlbl != inb(iobase + com_dlbl)) - outb(iobase + com_dlbl, sp->dlbl); - if (sp->dlbh != inb(iobase + com_dlbh)) - outb(iobase + com_dlbh, sp->dlbh); - outb(iobase + com_cfcr, sp->cfcr); - /* - * XXX damp oscillations of MCR_DTR and MCR_RTS by not restoring them. - */ - outb(iobase + com_mcr, sp->mcr | MCR_DTR | MCR_RTS); - outb(iobase + com_ier, sp->ier); -} - -static void -sio_cnprobe(cp) - struct consdev *cp; -{ - speed_t boot_speed; - u_char cfcr; - u_int divisor; - int s, unit; - struct siocnstate sp; - - /* - * Find our first enabled console, if any. If it is a high-level - * console device, then initialize it and return successfully. - * If it is a low-level console device, then initialize it and - * return unsuccessfully. It must be initialized in both cases - * for early use by console drivers and debuggers. Initializing - * the hardware is not necessary in all cases, since the i/o - * routines initialize it on the fly, but it is necessary if - * input might arrive while the hardware is switched back to an - * uninitialized state. We can't handle multiple console devices - * yet because our low-level routines don't take a device arg. - * We trust the user to set the console flags properly so that we - * don't need to probe. - */ - cp->cn_pri = CN_DEAD; - - for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */ - int flags; - - if (resource_disabled("sio", unit)) - continue; - if (resource_int_value("sio", unit, "flags", &flags)) - continue; - if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) { - int port; - Port_t iobase; - - if (resource_int_value("sio", unit, "port", &port)) - continue; - iobase = port; - s = spltty(); - if ((boothowto & RB_SERIAL) && COM_CONSOLE(flags)) { - boot_speed = - siocngetspeed(iobase, comdefaultrclk); - if (boot_speed) - comdefaultrate = boot_speed; - } - - /* - * Initialize the divisor latch. We can't rely on - * siocnopen() to do this the first time, since it - * avoids writing to the latch if the latch appears - * to have the correct value. Also, if we didn't - * just read the speed from the hardware, then we - * need to set the speed in hardware so that - * switching it later is null. - */ - cfcr = inb(iobase + com_cfcr); - outb(iobase + com_cfcr, CFCR_DLAB | cfcr); - divisor = siodivisor(comdefaultrclk, comdefaultrate); - outb(iobase + com_dlbl, divisor & 0xff); - outb(iobase + com_dlbh, divisor >> 8); - outb(iobase + com_cfcr, cfcr); - - siocnopen(&sp, iobase, comdefaultrate); - - splx(s); - if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) { - siocnset(cp, unit); - cp->cn_pri = COM_FORCECONSOLE(flags) - || boothowto & RB_SERIAL - ? CN_REMOTE : CN_NORMAL; - siocniobase = iobase; - siocnunit = unit; - } -#ifdef GDB - if (COM_DEBUGGER(flags)) - siogdbiobase = iobase; -#endif - } - } -} - -static void -sio_cninit(cp) - struct consdev *cp; -{ - comconsole = cp->cn_unit; -} - -static void -sio_cnterm(cp) - struct consdev *cp; -{ - comconsole = -1; -} - -static void -sio_cngrab(struct consdev *cp) -{ -} - -static void -sio_cnungrab(struct consdev *cp) -{ -} - -static int -sio_cngetc(struct consdev *cd) -{ - int c; - Port_t iobase; - int s; - struct siocnstate sp; - speed_t speed; - - if (cd != NULL && cd->cn_unit == siocnunit) { - iobase = siocniobase; - speed = comdefaultrate; - } else { -#ifdef GDB - iobase = siogdbiobase; - speed = gdbdefaultrate; -#else - return (-1); -#endif - } - s = spltty(); - siocnopen(&sp, iobase, speed); - if (inb(iobase + com_lsr) & LSR_RXRDY) - c = inb(iobase + com_data); - else - c = -1; - siocnclose(&sp, iobase); - splx(s); - return (c); -} - -static void -sio_cnputc(struct consdev *cd, int c) -{ - int need_unlock; - int s; - struct siocnstate sp; - Port_t iobase; - speed_t speed; - - if (cd != NULL && cd->cn_unit == siocnunit) { - iobase = siocniobase; - speed = comdefaultrate; - } else { -#ifdef GDB - iobase = siogdbiobase; - speed = gdbdefaultrate; -#else - return; -#endif - } - s = spltty(); - need_unlock = 0; - if (!kdb_active && sio_inited == 2 && !mtx_owned(&sio_lock)) { - mtx_lock_spin(&sio_lock); - need_unlock = 1; - } - siocnopen(&sp, iobase, speed); - siocntxwait(iobase); - outb(iobase + com_data, c); - siocnclose(&sp, iobase); - if (need_unlock) - mtx_unlock_spin(&sio_lock); - splx(s); -} - -/* - * Remote gdb(1) support. - */ - -#if defined(GDB) - -#include - -static gdb_probe_f siogdbprobe; -static gdb_init_f siogdbinit; -static gdb_term_f siogdbterm; -static gdb_getc_f siogdbgetc; -static gdb_putc_f siogdbputc; - -GDB_DBGPORT(sio, siogdbprobe, siogdbinit, siogdbterm, siogdbgetc, siogdbputc); - -static int -siogdbprobe(void) -{ - return ((siogdbiobase != 0) ? 0 : -1); -} - -static void -siogdbinit(void) -{ -} - -static void -siogdbterm(void) -{ -} - -static void -siogdbputc(int c) -{ - sio_cnputc(NULL, c); -} - -static int -siogdbgetc(void) -{ - return (sio_cngetc(NULL)); -} - -#endif diff --git a/sys/dev/sio/sio_isa.c b/sys/dev/sio/sio_isa.c deleted file mode 100644 index 04fe5b4a6e48..000000000000 --- a/sys/dev/sio/sio_isa.c +++ /dev/null @@ -1,178 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2001 M. Warner Losh. - * - * 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 ``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 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 -__FBSDID("$FreeBSD$"); - -#include "opt_sio.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -static int sio_isa_attach(device_t dev); -static int sio_isa_probe(device_t dev); - -static device_method_t sio_isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_isa_probe), - DEVMETHOD(device_attach, sio_isa_attach), - DEVMETHOD(device_detach, siodetach), - - { 0, 0 } -}; - -static driver_t sio_isa_driver = { - sio_driver_name, - sio_isa_methods, - 0, -}; - -static struct isa_pnp_id sio_ids[] = { - {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ - {0x0105d041, "16550A-compatible COM port"}, /* PNP0501 */ - {0x0205d041, "Multiport serial device (non-intelligent 16550)"}, /* PNP0502 */ - {0x1005d041, "Generic IRDA-compatible device"}, /* PNP0510 */ - {0x1105d041, "Generic IRDA-compatible device"}, /* PNP0511 */ - /* Devices that do not have a compatid */ - {0x12206804, NULL}, /* ACH2012 - 5634BTS 56K Video Ready Modem */ - {0x7602a904, NULL}, /* AEI0276 - 56K v.90 Fax Modem (LKT) */ - {0x00007905, NULL}, /* AKY0000 - 56K Plug&Play Modem */ - {0x21107905, NULL}, /* AKY1021 - 56K Plug&Play Modem */ - {0x01405407, NULL}, /* AZT4001 - AZT3000 PnP SOUND DEVICE, MODEM */ - {0x56039008, NULL}, /* BDP0356 - Best Data 56x2 */ - {0x56159008, NULL}, /* BDP1556 - B.D. Smart One 56SPS,Voice Modem*/ - {0x36339008, NULL}, /* BDP3336 - Best Data Prods. 336F */ - {0x0014490a, NULL}, /* BRI1400 - Boca 33.6 PnP */ - {0x0015490a, NULL}, /* BRI1500 - Internal Fax Data */ - {0x0034490a, NULL}, /* BRI3400 - Internal ACF Modem */ - {0x0094490a, NULL}, /* BRI9400 - Boca K56Flex PnP */ - {0x00b4490a, NULL}, /* BRIB400 - Boca 56k PnP */ - {0x0010320d, NULL}, /* CIR1000 - Cirrus Logic V34 */ - {0x0030320d, NULL}, /* CIR3000 - Cirrus Logic V43 */ - {0x0100440e, NULL}, /* CRD0001 - Cardinal MVP288IV ? */ - {0x01308c0e, NULL}, /* CTL3001 - Creative Labs Phoneblaster */ - {0x36033610, NULL}, /* DAV0336 - DAVICOM 336PNP MODEM */ - {0x01009416, NULL}, /* ETT0001 - E-Tech Bullet 33k6 PnP */ - {0x0000aa1a, NULL}, /* FUJ0000 - FUJITSU Modem 33600 PNP/I2 */ - {0x1200c31e, NULL}, /* GVC0012 - VF1128HV-R9 (win modem?) */ - {0x0303c31e, NULL}, /* GVC0303 - MaxTech 33.6 PnP D/F/V */ - {0x0505c31e, NULL}, /* GVC0505 - GVC 56k Faxmodem */ - {0x0116c31e, NULL}, /* GVC1601 - Rockwell V.34 Plug & Play Modem */ - {0x0050c31e, NULL}, /* GVC5000 - some GVC modem */ - {0x3800f91e, NULL}, /* GWY0038 - Telepath with v.90 */ - {0x9062f91e, NULL}, /* GWY6290 - Telepath with x2 Technology */ - {0x8100e425, NULL}, /* IOD0081 - I-O DATA DEVICE,INC. IFML-560 */ - {0x71004d24, NULL}, /* IBM0071 - IBM ThinkPad 240 IrDA controller*/ - {0x21002534, NULL}, /* MAE0021 - Jetstream Int V.90 56k Voice Series 2*/ - {0x0000f435, NULL}, /* MOT0000 - Motorola ModemSURFR 33.6 Intern */ - {0x5015f435, NULL}, /* MOT1550 - Motorola ModemSURFR 56K Modem */ - {0xf015f435, NULL}, /* MOT15F0 - Motorola VoiceSURFR 56K Modem */ - {0x6045f435, NULL}, /* MOT4560 - Motorola ? */ - {0x61e7a338, NULL}, /* NECE761 - 33.6Modem */ - {0x0160633a, NULL}, /* NSC6001 - National Semi's IrDA Controller*/ - {0x08804f3f, NULL}, /* OZO8008 - Zoom (33.6k Modem) */ - {0x0f804f3f, NULL}, /* OZO800f - Zoom 2812 (56k Modem) */ - {0x39804f3f, NULL}, /* OZO8039 - Zoom 56k flex */ - {0x00914f3f, NULL}, /* OZO9100 - Zoom 2919 (K56 Faxmodem) */ - {0x3024a341, NULL}, /* PMC2430 - Pace 56 Voice Internal Modem */ - {0x1000eb49, NULL}, /* ROK0010 - Rockwell ? */ - {0x1200b23d, NULL}, /* RSS0012 - OMRON ME5614ISA */ - {0x5002734a, NULL}, /* RSS0250 - 5614Jx3(G) Internal Modem */ - {0x6202734a, NULL}, /* RSS0262 - 5614Jx3[G] V90+K56Flex Modem */ - {0x1010104d, NULL}, /* SHP1010 - Rockwell 33600bps Modem */ - {0x10f0a34d, NULL}, /* SMCF010 - SMC IrCC*/ - {0xc100ad4d, NULL}, /* SMM00C1 - Leopard 56k PnP */ - {0x9012b04e, NULL}, /* SUP1290 - Supra ? */ - {0x1013b04e, NULL}, /* SUP1310 - SupraExpress 336i PnP */ - {0x8013b04e, NULL}, /* SUP1380 - SupraExpress 288i PnP Voice */ - {0x8113b04e, NULL}, /* SUP1381 - SupraExpress 336i PnP Voice */ - {0x5016b04e, NULL}, /* SUP1650 - Supra 336i Sp Intl */ - {0x7016b04e, NULL}, /* SUP1670 - Supra 336i V+ Intl */ - {0x7420b04e, NULL}, /* SUP2070 - Supra ? */ - {0x8020b04e, NULL}, /* SUP2080 - Supra ? */ - {0x8420b04e, NULL}, /* SUP2084 - SupraExpress 56i PnP */ - {0x7121b04e, NULL}, /* SUP2171 - SupraExpress 56i Sp? */ - {0x8024b04e, NULL}, /* SUP2480 - Supra ? */ - {0x01007256, NULL}, /* USR0001 - U.S. Robotics Inc., Sportster W */ - {0x02007256, NULL}, /* USR0002 - U.S. Robotics Inc. Sportster 33. */ - {0x04007256, NULL}, /* USR0004 - USR Sportster 14.4k */ - {0x06007256, NULL}, /* USR0006 - USR Sportster 33.6k */ - {0x11007256, NULL}, /* USR0011 - USR ? */ - {0x01017256, NULL}, /* USR0101 - USR ? */ - {0x30207256, NULL}, /* USR2030 - U.S.Robotics Inc. Sportster 560 */ - {0x50207256, NULL}, /* USR2050 - U.S.Robotics Inc. Sportster 33. */ - {0x70207256, NULL}, /* USR2070 - U.S.Robotics Inc. Sportster 560 */ - {0x30307256, NULL}, /* USR3030 - U.S. Robotics 56K FAX INT */ - {0x31307256, NULL}, /* USR3031 - U.S. Robotics 56K FAX INT */ - {0x50307256, NULL}, /* USR3050 - U.S. Robotics 56K FAX INT */ - {0x70307256, NULL}, /* USR3070 - U.S. Robotics 56K Voice INT */ - {0x90307256, NULL}, /* USR3090 - USR ? */ - {0x70917256, NULL}, /* USR9170 - U.S. Robotics 56K FAX INT */ - {0x90917256, NULL}, /* USR9190 - USR 56k Voice INT */ - {0x04f0235c, NULL}, /* WACF004 - Wacom Tablet PC Screen*/ - {0x0300695c, NULL}, /* WCI0003 - Fax/Voice/Modem/Speakphone/Asvd */ - {0x01a0896a, NULL}, /* ZTIA001 - Zoom Internal V90 Faxmodem */ - {0x61f7896a, NULL}, /* ZTIF761 - Zoom ComStar 33.6 */ - {0} -}; - -static int -sio_isa_probe(dev) - device_t dev; -{ - /* Check isapnp ids */ - if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) - return (ENXIO); - return (sioprobe(dev, 0, 0UL, 0)); -} - -static int -sio_isa_attach(dev) - device_t dev; -{ - return (sioattach(dev, 0, 0UL)); -} - -DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0); -#ifndef COM_NO_ACPI -DRIVER_MODULE(sio, acpi, sio_isa_driver, sio_devclass, 0, 0); -#endif -ISA_PNP_INFO(sio_ids); diff --git a/sys/dev/sio/sio_pccard.c b/sys/dev/sio/sio_pccard.c deleted file mode 100644 index dbf4443e4be7..000000000000 --- a/sys/dev/sio/sio_pccard.c +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2001 M. Warner Losh. - * - * 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 ``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 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -static int sio_pccard_attach(device_t dev); -static int sio_pccard_probe(device_t dev); - -static device_method_t sio_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_pccard_probe), - DEVMETHOD(device_attach, sio_pccard_attach), - DEVMETHOD(device_detach, siodetach), - - { 0, 0 } -}; - -static driver_t sio_pccard_driver = { - sio_driver_name, - sio_pccard_methods, - 0, -}; - -static int -sio_pccard_probe(device_t dev) -{ - int error = 0; - u_int32_t fcn = PCCARD_FUNCTION_UNSPEC; - - error = pccard_get_function(dev, &fcn); - if (error != 0) - return (error); - - /* - * If a serial card, we are likely the right driver. However, - * some serial cards are better servered by other drivers, so - * allow other drivers to claim it, if they want. - */ - if (fcn == PCCARD_FUNCTION_SERIAL) - return (-100); - return (ENXIO); -} - -static int -sio_pccard_attach(device_t dev) -{ - int err; - - /* Do not probe IRQ - pccard doesn't turn on the interrupt line */ - /* until bus_setup_intr */ - if ((err = sioprobe(dev, 0, 0UL, 1)) > 0) - return (err); - return (sioattach(dev, 0, 0UL)); -} - -DRIVER_MODULE(sio, pccard, sio_pccard_driver, sio_devclass, 0, 0); diff --git a/sys/dev/sio/sio_pci.c b/sys/dev/sio/sio_pci.c deleted file mode 100644 index cd2e03e28966..000000000000 --- a/sys/dev/sio/sio_pci.c +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2001 M. Warner Losh. - * - * 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 ``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 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static int sio_pci_attach(device_t dev); -static int sio_pci_probe(device_t dev); - -static device_method_t sio_pci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_pci_probe), - DEVMETHOD(device_attach, sio_pci_attach), - DEVMETHOD(device_detach, siodetach), - - { 0, 0 } -}; - -static driver_t sio_pci_driver = { - sio_driver_name, - sio_pci_methods, - 0, -}; - -struct pci_ids { - u_int32_t type; - const char *desc; - int rid; -}; - -static struct pci_ids pci_ids[] = { - { 0x100812b9, "3COM PCI FaxModem", 0x10 }, - { 0x2000131f, "CyberSerial (1-port) 16550", 0x10 }, - { 0x01101407, "Koutech IOFLEX-2S PCI Dual Port Serial", 0x10 }, - { 0x01111407, "Koutech IOFLEX-2S PCI Dual Port Serial", 0x10 }, - { 0x048011c1, "Lucent kermit based PCI Modem", 0x14 }, - { 0x95211415, "Oxford Semiconductor PCI Dual Port Serial", 0x10 }, - { 0x7101135e, "SeaLevel Ultra 530.PCI Single Port Serial", 0x18 }, - { 0x0000151f, "SmartLink 5634PCV SurfRider", 0x10 }, - { 0x0103115d, "Xircom Cardbus modem", 0x10 }, - { 0x432214e4, "Broadcom 802.11b/GPRS CardBus (Serial)", 0x10 }, - { 0x434414e4, "Broadcom 802.11bg/EDGE/GPRS CardBus (Serial)", 0x10 }, - { 0x01c0135c, "Quatech SSCLP-200/300", 0x18 - /* - * NB: You must mount the "SPAD" jumper to correctly detect - * the FIFO on the UART. Set the options on the jumpers, - * we do not support the extra registers on the Quatech. - */ - }, - { 0x00000000, NULL, 0 } -}; - -static int -sio_pci_attach(dev) - device_t dev; -{ - u_int32_t type; - struct pci_ids *id; - - type = pci_get_devid(dev); - id = pci_ids; - while (id->type && id->type != type) - id++; - if (id->desc == NULL) - return (ENXIO); - return (sioattach(dev, id->rid, 0UL)); -} - -static int -sio_pci_probe(dev) - device_t dev; -{ - u_int32_t type; - struct pci_ids *id; - - type = pci_get_devid(dev); - id = pci_ids; - while (id->type && id->type != type) - id++; - if (id->desc == NULL) - return (ENXIO); - device_set_desc(dev, id->desc); - - return (sioprobe(dev, id->rid, 0UL, 0)); -} - -DRIVER_MODULE(sio, pci, sio_pci_driver, sio_devclass, 0, 0); diff --git a/sys/dev/sio/sio_puc.c b/sys/dev/sio/sio_puc.c deleted file mode 100644 index ee6bb59b5591..000000000000 --- a/sys/dev/sio/sio_puc.c +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2002 JF Hay. All rights reserved. - * Copyright (c) 2001 M. Warner Losh. - * - * 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 ``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 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -static int sio_puc_attach(device_t dev); -static int sio_puc_probe(device_t dev); - -static device_method_t sio_puc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_puc_probe), - DEVMETHOD(device_attach, sio_puc_attach), - DEVMETHOD(device_detach, siodetach), - - { 0, 0 } -}; - -static driver_t sio_puc_driver = { - sio_driver_name, - sio_puc_methods, - 0, -}; - -static int -sio_puc_attach(device_t dev) -{ - uintptr_t rclk; - - if (BUS_READ_IVAR(device_get_parent(dev), dev, PUC_IVAR_CLOCK, - &rclk) != 0) - rclk = DEFAULT_RCLK; - return (sioattach(dev, 0, rclk)); -} - -static int -sio_puc_probe(device_t dev) -{ - device_t parent; - uintptr_t rclk, type; - int error; - - parent = device_get_parent(dev); - - if (BUS_READ_IVAR(parent, dev, PUC_IVAR_TYPE, &type)) - return (ENXIO); - if (type != PUC_TYPE_SERIAL) - return (ENXIO); - - if (BUS_READ_IVAR(parent, dev, PUC_IVAR_CLOCK, &rclk)) - rclk = DEFAULT_RCLK; - - error = sioprobe(dev, 0, rclk, 1); - return ((error > 0) ? error : BUS_PROBE_LOW_PRIORITY); -} - -DRIVER_MODULE(sio, puc, sio_puc_driver, sio_devclass, 0, 0); diff --git a/sys/dev/sio/sioreg.h b/sys/dev/sio/sioreg.h deleted file mode 100644 index 64ba19e757bf..000000000000 --- a/sys/dev/sio/sioreg.h +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1991 The Regents of the University of California. - * 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 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: @(#)comreg.h 7.2 (Berkeley) 5/9/91 - * $FreeBSD$ - */ - -/* Receiver clock frequency for "standard" pc serial ports. */ -#define DEFAULT_RCLK 1843200 - -/* speed to initialize to during chip tests */ -#define SIO_TEST_SPEED 9600 - -/* default serial console speed if not set with sysctl or probed from boot */ -#ifndef CONSPEED -#define CONSPEED 9600 -#endif - -/* default serial gdb speed if not set with sysctl or probed from boot */ -#ifndef GDBSPEED -#define GDBSPEED CONSPEED -#endif - -#define IO_COMSIZE 8 /* 8250, 16x50 com controllers */ diff --git a/sys/dev/sio/siovar.h b/sys/dev/sio/siovar.h deleted file mode 100644 index 91a907de102c..000000000000 --- a/sys/dev/sio/siovar.h +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1991 The Regents of the University of California. - * 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 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. - * - * $FreeBSD$ - */ - -int sioattach(device_t dev, int xrid, u_long rclk); -int siodetach(device_t dev); -int sioprobe(device_t dev, int xrid, u_long rclk, int noprobe); - -extern devclass_t sio_devclass; -extern char sio_driver_name[]; diff --git a/sys/modules/sio/Makefile b/sys/modules/sio/Makefile deleted file mode 100644 index 48fdfc88ebec..000000000000 --- a/sys/modules/sio/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/sio - -KMOD= sio -SRCS= bus_if.h card_if.h device_if.h isa_if.h pci_if.h serdev_if.h \ - opt_gdb.h opt_kdb.h opt_sio.h \ - sio.c sio_isa.c sio_pccard.c sio_pci.c sio_puc.c pccarddevs.h - -.include diff --git a/usr.sbin/watch/watch.8 b/usr.sbin/watch/watch.8 index 052c95d49b87..9a5485fcf61f 100644 --- a/usr.sbin/watch/watch.8 +++ b/usr.sbin/watch/watch.8 @@ -105,7 +105,6 @@ control-X is passed to the terminal as with other control characters. .El .Sh SEE ALSO .Xr pty 4 , -.Xr sio 4 , .Xr snp 4 , .Xr kldload 8 .Sh HISTORY