summaryrefslogtreecommitdiff
path: root/sys/arch/i386/isa/pccom.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386/isa/pccom.c')
-rw-r--r--sys/arch/i386/isa/pccom.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/sys/arch/i386/isa/pccom.c b/sys/arch/i386/isa/pccom.c
index c66dce26ab4..d235d46cbb9 100644
--- a/sys/arch/i386/isa/pccom.c
+++ b/sys/arch/i386/isa/pccom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pccom.c,v 1.2 1996/07/28 05:07:06 downsj Exp $ */
+/* $OpenBSD: pccom.c,v 1.3 1996/08/29 12:58:32 deraadt Exp $ */
/* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
/*-
@@ -107,6 +107,8 @@ struct com_softc {
u_char sc_msr, sc_mcr, sc_lcr, sc_ier;
u_char sc_dtr;
+ u_char sc_cua;
+
#define RBUFSIZE 512
#define RBUFMASK 511
u_int sc_rxget;
@@ -193,7 +195,8 @@ extern int kgdb_rate;
extern int kgdb_debug_init;
#endif
-#define PCCOMUNIT(x) (minor(x))
+#define DEVUNIT(x) (minor(x) & 0x7f)
+#define DEVCUA(x) (minor(x) & 0x80)
/* Macros to clear/set/test flags. */
#define SET(t, f) (t) |= (f)
@@ -748,7 +751,7 @@ comopen(dev, flag, mode, p)
int flag, mode;
struct proc *p;
{
- int unit = PCCOMUNIT(dev);
+ int unit = DEVUNIT(dev);
struct com_softc *sc;
bus_chipset_tag_t bc;
bus_io_handle_t ioh;
@@ -762,11 +765,13 @@ comopen(dev, flag, mode, p)
if (!sc || ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING))
return ENXIO;
+ s = spltty();
if (!sc->sc_tty) {
tp = sc->sc_tty = ttymalloc();
tty_attach(tp);
} else
tp = sc->sc_tty;
+ splx(s);
tp->t_oproc = comstart;
tp->t_param = comparam;
@@ -870,7 +875,7 @@ comopen(dev, flag, mode, p)
bus_io_write_1(bc, ioh, com_ier, sc->sc_ier);
sc->sc_msr = bus_io_read_1(bc, ioh, com_msr);
- if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) ||
+ if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || DEVCUA(dev) ||
ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
SET(tp->t_state, TS_CARR_ON);
else
@@ -880,9 +885,25 @@ comopen(dev, flag, mode, p)
else
s = spltty();
+ if (DEVCUA(dev)) {
+ if (ISSET(tp->t_state, TS_ISOPEN)) {
+ /* Ah, but someone already is dialed in... */
+ splx(s);
+ return EBUSY;
+ }
+ sc->sc_cua = 1; /* We go into CUA mode */
+ }
+
/* wait for carrier if necessary */
- if (!ISSET(flag, O_NONBLOCK))
- while (!ISSET(tp->t_cflag, CLOCAL) &&
+ if (ISSET(flag, O_NONBLOCK)) {
+ if (!DEVCUA(dev) && sc->sc_cua) {
+ /* Opening TTY non-blocking... but the CUA is busy */
+ splx(s);
+ return EBUSY;
+ }
+ } else {
+ while (!(DEVCUA(dev) && sc->sc_cua) &&
+ !ISSET(tp->t_cflag, CLOCAL) &&
!ISSET(tp->t_state, TS_CARR_ON)) {
SET(tp->t_state, TS_WOPEN);
error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
@@ -890,10 +911,13 @@ comopen(dev, flag, mode, p)
if (error) {
/* XXX should turn off chip if we're the
only waiter */
+ if (DEVCUA(dev))
+ sc->sc_cua = 0;
splx(s);
return error;
}
}
+ }
splx(s);
return (*linesw[tp->t_line].l_open)(dev, tp);
@@ -905,7 +929,7 @@ comclose(dev, flag, mode, p)
int flag, mode;
struct proc *p;
{
- int unit = PCCOMUNIT(dev);
+ int unit = DEVUNIT(dev);
struct com_softc *sc = pccom_cd.cd_devs[unit];
struct tty *tp = sc->sc_tty;
bus_chipset_tag_t bc = sc->sc_bc;
@@ -934,6 +958,7 @@ comclose(dev, flag, mode, p)
* FIFO off
*/
bus_io_write_1(bc, ioh, com_fifo, 0);
+ sc->sc_cua = 0;
splx(s);
ttyclose(tp);
#ifdef PCCOM_DEBUG
@@ -959,7 +984,7 @@ comread(dev, uio, flag)
struct uio *uio;
int flag;
{
- struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(dev)];
+ struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
struct tty *tp = sc->sc_tty;
if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
@@ -978,7 +1003,7 @@ comwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
- struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(dev)];
+ struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
struct tty *tp = sc->sc_tty;
if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
@@ -995,7 +1020,7 @@ struct tty *
comtty(dev)
dev_t dev;
{
- struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(dev)];
+ struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
struct tty *tp = sc->sc_tty;
return (tp);
@@ -1022,7 +1047,7 @@ comioctl(dev, cmd, data, flag, p)
int flag;
struct proc *p;
{
- int unit = PCCOMUNIT(dev);
+ int unit = DEVUNIT(dev);
struct com_softc *sc = pccom_cd.cd_devs[unit];
struct tty *tp = sc->sc_tty;
bus_chipset_tag_t bc = sc->sc_bc;
@@ -1142,7 +1167,7 @@ comparam(tp, t)
struct tty *tp;
struct termios *t;
{
- struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(tp->t_dev)];
+ struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
bus_chipset_tag_t bc = sc->sc_bc;
bus_io_handle_t ioh = sc->sc_ioh;
int ospeed = comspeed(t->c_ospeed);
@@ -1304,7 +1329,7 @@ comhwiflow(tp, block)
struct tty *tp;
int block;
{
- struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(tp->t_dev)];
+ struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
bus_chipset_tag_t bc = sc->sc_bc;
bus_io_handle_t ioh = sc->sc_ioh;
int s;
@@ -1345,7 +1370,7 @@ void
comstart(tp)
struct tty *tp;
{
- struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(tp->t_dev)];
+ struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
bus_chipset_tag_t bc = sc->sc_bc;
bus_io_handle_t ioh = sc->sc_ioh;
int s, count;
@@ -1414,7 +1439,7 @@ comstop(tp, flag)
int flag;
{
int s;
- struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(tp->t_dev)];
+ struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
s = splhigh();
if (ISSET(tp->t_state, TS_BUSY)) {