summaryrefslogtreecommitdiffstats
path: root/sys/dev/sab
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2003-01-05 04:07:31 +0000
committerjake <jake@FreeBSD.org>2003-01-05 04:07:31 +0000
commita0f93710bd82f19e930a50ac7ff37c52107566e6 (patch)
tree73d4160461925a7450721ef2c2b6eebca6480f0b /sys/dev/sab
parente9f9befcb11e6af9c7f61fc80b72721915b6ff78 (diff)
downloadFreeBSD-src-a0f93710bd82f19e930a50ac7ff37c52107566e6.zip
FreeBSD-src-a0f93710bd82f19e930a50ac7ff37c52107566e6.tar.gz
Sync with zs.
- Fix some bogosity with mixing unit numbers and channels, which would only work for one instance of the device. - Use a simpler scheme for input and output queueing. - Use db_alt_break.
Diffstat (limited to 'sys/dev/sab')
-rw-r--r--sys/dev/sab/sab.c418
1 files changed, 179 insertions, 239 deletions
diff --git a/sys/dev/sab/sab.c b/sys/dev/sab/sab.c
index 59ff400..88e13d6 100644
--- a/sys/dev/sab/sab.c
+++ b/sys/dev/sab/sab.c
@@ -61,18 +61,15 @@
#include <sys/syslog.h>
#include <sys/tty.h>
+#include <ddb/ddb.h>
+
#include <ofw/openfirm.h>
#include <sparc64/ebus/ebusvar.h>
#include <dev/sab/sab82532reg.h>
-#define KTR_SAB KTR_CT3
-
#define CDEV_MAJOR 168
-#define SABTTY_RBUF_SIZE 1024
-#define SABTTY_XBUF_SIZE 1024
-
#define SAB_READ(sc, r) \
bus_space_read_1((sc)->sc_bt, (sc)->sc_bh, (r))
#define SAB_WRITE(sc, r, v) \
@@ -88,27 +85,22 @@ struct sabtty_softc {
bus_space_handle_t sc_bh;
dev_t sc_si;
struct tty *sc_tty;
- uint8_t *sc_rend;
- uint8_t *sc_rput;
- uint8_t *sc_rget;
- uint8_t *sc_xend;
- uint8_t *sc_xput;
- uint8_t *sc_xget;
- int sc_xc;
- int sc_openflags;
- int sc_flags;
-#define SABTTYF_STOP 0x01
-#define SABTTYF_DONE 0x02
-#define SABTTYF_RBUF_OVERFLOW 0x04
-#define SABTTYF_CDCHG 0x08
-#define SABTTYF_CONS 0x10
+ int sc_channel;
+ int sc_icnt;
+ uint8_t *sc_iput;
+ uint8_t *sc_iget;
+ int sc_ocnt;
+ uint8_t *sc_oget;
+ int sc_alt_break_state;
+ struct mtx sc_mtx;
+ uint8_t sc_console;
+ uint8_t sc_tx_done;
uint8_t sc_pvr_dtr;
uint8_t sc_pvr_dsr;
uint8_t sc_imr0;
uint8_t sc_imr1;
- struct mtx sc_mtx;
- uint8_t sc_rbuf[SABTTY_RBUF_SIZE];
- uint8_t sc_xbuf[SABTTY_XBUF_SIZE];
+ uint8_t sc_ibuf[CBLOCK];
+ uint8_t sc_obuf[CBLOCK];
};
struct sab_softc {
@@ -380,9 +372,9 @@ sab_detach(device_t dev)
}
static void
-sab_intr(void *vsc)
+sab_intr(void *v)
{
- struct sab_softc *sc = vsc;
+ struct sab_softc *sc = v;
int needsoft = 0;
uint8_t gis;
@@ -401,18 +393,18 @@ sab_intr(void *vsc)
}
static void
-sab_softintr(void *vsc)
+sab_softintr(void *v)
{
- struct sab_softc *sc = vsc;
+ struct sab_softc *sc = v;
sabtty_softintr(sc->sc_child[0]);
sabtty_softintr(sc->sc_child[1]);
}
static void
-sab_shutdown(void *vsc)
+sab_shutdown(void *v)
{
- struct sab_softc *sc = vsc;
+ struct sab_softc *sc = v;
SAB_WRITE(sc, SAB_IPC, SAB_IPC_ICPL | SAB_IPC_VIS);
SAB_WRITE(sc, SAB_RFC, SAB_READ(sc, SAB_RFC) & ~SAB_RFC_RFDF);
@@ -422,22 +414,10 @@ static int
sabtty_probe(device_t dev)
{
- switch (device_get_unit(dev)) {
- case 0:
- if (sabtty_console(dev, NULL, 0))
- device_set_desc(dev, "Channel A, console");
- else
- device_set_desc(dev, "Channel A");
- break;
- case 1:
- if (sabtty_console(dev, NULL, 0))
- device_set_desc(dev, "Channel B, console");
- else
- device_set_desc(dev, "Channel B");
- break;
- default:
- return (ENXIO);
- }
+ if ((device_get_unit(dev) & 1) == 0)
+ device_set_desc(dev, "ttya");
+ else
+ device_set_desc(dev, "ttyb");
return (0);
}
@@ -458,12 +438,11 @@ sabtty_attach(device_t dev)
sc->sc_dev = dev;
sc->sc_parent = device_get_softc(device_get_parent(dev));
sc->sc_bt = sc->sc_parent->sc_bt;
- sc->sc_rput = sc->sc_rget = sc->sc_rbuf;
- sc->sc_rend = sc->sc_rbuf + SABTTY_RBUF_SIZE;
- sc->sc_xput = sc->sc_xget = sc->sc_xbuf;
- sc->sc_xend = sc->sc_xbuf + SABTTY_XBUF_SIZE;
+ sc->sc_channel = device_get_unit(dev) & 1;
+ sc->sc_iput = sc->sc_iget = sc->sc_ibuf;
+ sc->sc_oget = sc->sc_obuf;
- switch (device_get_unit(dev)) {
+ switch (sc->sc_channel) {
case 0: /* port A */
sc->sc_pvr_dtr = SAB_PVR_DTR_A;
sc->sc_pvr_dsr = SAB_PVR_DSR_A;
@@ -480,7 +459,7 @@ sabtty_attach(device_t dev)
tp = ttymalloc(NULL);
sc->sc_si = make_dev(&sabtty_cdevsw, device_get_unit(dev),
- UID_ROOT, GID_WHEEL, 0600, "tty%c", 'a' + device_get_unit(dev));
+ UID_ROOT, GID_WHEEL, 0600, "%s", device_get_desc(dev));
sc->sc_si->si_drv1 = sc;
sc->sc_si->si_tty = tp;
tp->t_dev = sc->sc_si;
@@ -528,7 +507,8 @@ sabtty_attach(device_t dev)
if (stop == 2)
tp->t_cflag |= CSTOPB;
}
- sc->sc_flags |= SABTTYF_CONS;
+ device_printf(dev, "console %s\n", mode);
+ sc->sc_console = 1;
sabtty_cons = sc;
}
@@ -539,19 +519,25 @@ static int
sabtty_detach(device_t dev)
{
- return (0);
+ return (bus_generic_detach(dev));
}
static int
sabtty_intr(struct sabtty_softc *sc)
{
- uint8_t isr0, isr1;
- int i, len = 0, needsoft = 0, clearfifo = 0;
-#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
- int brk = 0;
-#endif
- uint8_t data;
- uint8_t *ptr;
+ int clearfifo;
+ int needsoft;
+ uint8_t isr0;
+ uint8_t isr1;
+ uint8_t c;
+ int brk;
+ int len;
+ int i;
+
+ brk = 0;
+ len = 0;
+ clearfifo = 0;
+ needsoft = 0;
SABTTY_LOCK(sc);
@@ -570,58 +556,19 @@ sabtty_intr(struct sabtty_softc *sc)
sabtty_cec_wait(sc);
SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RFRD);
}
- if (isr0 & SAB_ISR0_RFO) {
- sc->sc_flags |= SABTTYF_RBUF_OVERFLOW;
+ if (isr0 & SAB_ISR0_RFO)
clearfifo = 1;
- }
if (len != 0) {
- ptr = sc->sc_rput;
for (i = 0; i < len; i++) {
- data = SAB_READ(sc, SAB_RFIFO);
+ c = SAB_READ(sc, SAB_RFIFO);
#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
- /*
- * Solaris implements a new BREAK which is initiated
- * by a character sequence CR ~ ^b which is similar
- * to a familiar pattern used on Sun servers by the
- * Remote Console.
- */
-#define KEY_CR 13 /* CR '\r' */
-#define KEY_TILDE 126 /* ~ */
-#define KEY_CRTLB 2 /* ^B */
-
- if ((sc->sc_flags & SABTTYF_CONS) != 0 &&
- (i & 1) == 0) {
- static int state;
- switch (data) {
- case KEY_CR:
- state = KEY_TILDE;
- break;
- case KEY_TILDE:
- if (state == KEY_TILDE)
- state = KEY_CRTLB;
- else
- state = 0;
- break;
- case KEY_CRTLB:
- if (state == KEY_CRTLB)
- brk = 1;
- default:
- state = 0;
- break;
- }
- }
+ if (sc->sc_console != 0 && (i & 1) == 0)
+ brk = db_alt_break(c, &sc->sc_alt_break_state);
#endif
- *ptr++ = data;
- if (ptr == sc->sc_rend)
- ptr = sc->sc_rbuf;
- if (ptr == sc->sc_rget) {
- if (ptr == sc->sc_rbuf)
- ptr = sc->sc_rend;
- ptr--;
- sc->sc_flags |= SABTTYF_RBUF_OVERFLOW;
- }
+ *sc->sc_iput++ = c;
+ if (sc->sc_iput == sc->sc_ibuf + sizeof(sc->sc_ibuf))
+ sc->sc_iput = sc->sc_ibuf;
}
- sc->sc_rput = ptr;
needsoft = 1;
}
@@ -630,33 +577,23 @@ sabtty_intr(struct sabtty_softc *sc)
SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RMC);
}
- if (isr0 & SAB_ISR0_CDSC) {
- sc->sc_flags |= SABTTYF_CDCHG;
- needsoft = 1;
- }
-
if (isr1 & SAB_ISR1_ALLS) {
- sc->sc_flags |= SABTTYF_DONE;
+ sc->sc_tx_done = 1;
sc->sc_imr1 |= SAB_IMR1_ALLS;
SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
needsoft = 1;
}
if (isr1 & SAB_ISR1_XPR) {
- ptr = sc->sc_xget;
- len = min(sc->sc_xc, 32);
- for (i = 0; i < len; i++) {
- SAB_WRITE(sc, SAB_XFIFO + i, *ptr++);
- if (ptr == sc->sc_xend)
- ptr = sc->sc_xbuf;
- }
- if (i != 0) {
+ if (sc->sc_ocnt > 0) {
+ len = min(sc->sc_ocnt, 32);
+ for (i = 0; i < len; i++)
+ SAB_WRITE(sc, SAB_XFIFO + i, *sc->sc_oget++);
+ sc->sc_ocnt -= len;
sabtty_cec_wait(sc);
SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XF);
}
- sc->sc_xget = ptr;
- sc->sc_xc -= len;
- if (sc->sc_xc == 0) {
+ if (sc->sc_ocnt == 0) {
sc->sc_imr1 |= SAB_IMR1_XPR;
sc->sc_imr1 &= ~SAB_IMR1_ALLS;
SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
@@ -665,10 +602,8 @@ sabtty_intr(struct sabtty_softc *sc)
SABTTY_UNLOCK(sc);
-#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
- if (brk)
+ if (brk != 0)
breakpoint();
-#endif
return (needsoft);
}
@@ -677,48 +612,27 @@ static void
sabtty_softintr(struct sabtty_softc *sc)
{
struct tty *tp = sc->sc_tty;
- int s, flags;
- uint8_t r;
+ int data;
+ int stat;
if ((tp->t_state & TS_ISOPEN) == 0)
return;
- while (sc->sc_rget != sc->sc_rput) {
- int data;
- u_int8_t stat;
-
- data = sc->sc_rget[0];
- stat = sc->sc_rget[1];
- sc->sc_rget += 2;
+ while (sc->sc_iget != sc->sc_iput) {
+ data = *sc->sc_iget++;
+ stat = *sc->sc_iget++;
if (stat & SAB_RSTAT_PE)
data |= TTY_PE;
if (stat & SAB_RSTAT_FE)
data |= TTY_FE;
- if (sc->sc_rget == sc->sc_rend)
- sc->sc_rget = sc->sc_rbuf;
+ if (sc->sc_iget == sc->sc_ibuf + sizeof(sc->sc_ibuf))
+ sc->sc_iget = sc->sc_ibuf;
(*linesw[tp->t_line].l_rint)(data, tp);
}
- SABTTY_LOCK(sc);
- flags = sc->sc_flags;
- sc->sc_flags &= ~(SABTTYF_DONE | SABTTYF_CDCHG |
- SABTTYF_RBUF_OVERFLOW);
- SABTTY_UNLOCK(sc);
-
- if (flags & SABTTYF_CDCHG) {
- s = spltty();
- r = SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD;
- splx(s);
-
- (*linesw[tp->t_line].l_modem)(tp, r);
- }
-
- if (flags & SABTTYF_RBUF_OVERFLOW)
- log(LOG_WARNING, "%s: rbuf overflow\n",
- device_get_name(sc->sc_dev));
-
- if (flags & SABTTYF_DONE) {
+ if (sc->sc_tx_done != 0) {
+ sc->sc_tx_done = 0;
tp->t_state &= ~TS_BUSY;
(*linesw[tp->t_line].l_start)(tp);
}
@@ -730,26 +644,39 @@ sabttyopen(dev_t dev, int flags, int mode, struct thread *td)
struct sabtty_softc *sc;
struct tty *tp;
int error;
- int s;
sc = dev->si_drv1;
tp = dev->si_tty;
+ if ((tp->t_state & TS_ISOPEN) != 0 &&
+ (tp->t_state & TS_XCLUDE) != 0 &&
+ !suser(td))
+ return (EBUSY);
+
if ((tp->t_state & TS_ISOPEN) == 0) {
+ struct termios t;
+
+ sc->sc_iput = sc->sc_iget = sc->sc_ibuf;
+
+ /*
+ * Initialize the termios status to the defaults. Add in the
+ * sticky bits from TIOCSFLAGS.
+ */
+ t.c_ispeed = 0;
+ t.c_ospeed = TTYDEF_SPEED;
+ t.c_cflag = TTYDEF_CFLAG;
+ /* Make sure zstty_param() will do something. */
+ tp->t_ospeed = 0;
+ (void)sabtty_param(sc, tp, &t);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
ttychars(tp);
-
- sc->sc_rput = sc->sc_rget = sc->sc_rbuf;
- sc->sc_xput = sc->sc_xget = sc->sc_xbuf;
- sc->sc_xc = 0;
-
- s = spltty();
-
ttsetwater(tp);
SABTTY_LOCK(sc);
sabtty_reset(sc);
- sabtty_param(sc, tp, &tp->t_termios);
sc->sc_parent->sc_ipc = SAB_IPC_ICPL;
SAB_WRITE(sc->sc_parent, SAB_IPC, sc->sc_parent->sc_ipc);
sc->sc_imr0 = SAB_IMR0_PERR | SAB_IMR0_FERR | SAB_IMR0_PLLA;
@@ -768,54 +695,33 @@ sabttyopen(dev_t dev, int flags, int mode, struct thread *td)
SABTTY_UNLOCK(sc);
- if (SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD)
- tp->t_state |= TS_CARR_ON;
- else
- tp->t_state &= ~TS_CARR_ON;
- } else {
- if ((tp->t_state & TS_XCLUDE) && (!suser(td)))
- return (EBUSY);
- }
+ /* XXX turn on DTR */
- s = spltty();
- if ((flags & O_NONBLOCK) == 0) {
- while ((tp->t_cflag & CLOCAL) == 0 &&
- (tp->t_state & TS_CARR_ON) == 0) {
- int error;
-
- error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
- "sabttycd", 0);
- if (error != 0) {
- splx(s);
- return (error);
- }
- }
+ /* XXX handle initial DCD */
}
- splx(s);
- error = (*linesw[tp->t_line].l_open)(dev, tp);
- if (error != 0 && (tp->t_state & TS_ISOPEN) != 0)
+ error = ttyopen(dev, tp);
+ if (error != 0)
return (error);
- if (tp->t_cflag & HUPCL) {
- sabtty_mdmctrl(sc, 0, DMSET);
- (void)tsleep(sc, TTIPRI, "ttclos", hz);
- }
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+ if (error != 0)
+ return (error);
- return (error);
+ return (0);
}
static int
sabttyclose(dev_t dev, int flags, int mode, struct thread *td)
{
- struct sabtty_softc *sc;
struct tty *tp;
- sc = dev->si_drv1;
tp = dev->si_tty;
+ if ((tp->t_state & TS_ISOPEN) == 0)
+ return (0);
+
(*linesw[tp->t_line].l_close)(tp, flags);
- sabttystop(tp, FREAD | FWRITE);
ttyclose(tp);
return (0);
@@ -831,7 +737,6 @@ sabttyioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
sc = dev->si_drv1;
tp = dev->si_tty;
-
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, td);
if (error != ENOIOCTL)
return (error);
@@ -841,7 +746,6 @@ sabttyioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
return (error);
error = 0;
-
switch (cmd) {
case TIOCSBRK:
SAB_WRITE(sc, SAB_DAFO,
@@ -881,50 +785,66 @@ static void
sabttystart(struct tty *tp)
{
struct sabtty_softc *sc;
- int len;
- int nb;
- int s;
sc = tp->t_dev->si_drv1;
- s = spltty();
- if ((tp->t_state & (TS_TTSTOP | TS_TIMEOUT)) == 0) {
- if (tp->t_outq.c_cc) {
- SABTTY_LOCK(sc);
- while (tp->t_outq.c_cc != 0 &&
- sc->sc_xc < sizeof(sc->sc_xbuf)) {
- len = sc->sc_xget <= sc->sc_xput ?
- sc->sc_xend - sc->sc_xput :
- sc->sc_xget - sc->sc_xput;
- nb = q_to_b(&tp->t_outq, sc->sc_xput, len);
- sc->sc_xput += nb;
- sc->sc_xc += nb;
- if (sc->sc_xput == sc->sc_xend)
- sc->sc_xput = sc->sc_xbuf;
+ if ((tp->t_state & TS_TBLOCK) != 0)
+ /* XXX clear RTS */;
+ else
+ /* XXX set RTS */;
+
+ if ((tp->t_state & (TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) != 0) {
+ ttwwakeup(tp);
+ return;
+ }
+
+ if (tp->t_outq.c_cc <= tp->t_olowat) {
+ if ((tp->t_state & TS_SO_OLOWAT) != 0) {
+ tp->t_state &= ~TS_SO_OLOWAT;
+ wakeup(TSA_OLOWAT(tp));
+ }
+ selwakeup(&tp->t_wsel);
+ if (tp->t_outq.c_cc == 0) {
+ if ((tp->t_state & (TS_BUSY | TS_SO_OCOMPLETE)) ==
+ TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
+ tp->t_state &= ~TS_SO_OCOMPLETE;
+ wakeup(TSA_OCOMPLETE(tp));
}
- tp->t_state |= TS_BUSY;
- sc->sc_imr1 &= ~SAB_IMR1_XPR;
- SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
- SABTTY_UNLOCK(sc);
+ return;
}
}
+
+ sc->sc_ocnt = q_to_b(&tp->t_outq, sc->sc_obuf, sizeof(sc->sc_obuf));
+ if (sc->sc_ocnt == 0)
+ return;
+ sc->sc_oget = sc->sc_obuf;
+
+ tp->t_state |= TS_BUSY;
+
+ sc->sc_imr1 &= ~SAB_IMR1_XPR;
+ SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
+
ttwwakeup(tp);
- splx(s);
}
static void
-sabttystop(struct tty *tp, int rw)
+sabttystop(struct tty *tp, int flag)
{
struct sabtty_softc *sc;
sc = tp->t_dev->si_drv1;
- tp->t_state &= ~TS_BUSY;
- sc->sc_rput = sc->sc_rget = sc->sc_rbuf;
- sc->sc_xput = sc->sc_xget = sc->sc_xbuf;
- sc->sc_imr1 |= SAB_IMR1_ALLS | SAB_IMR1_XPR;
- SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
- sabttystart(tp);
+ if ((flag & FREAD) != 0) {
+ /* XXX stop reading, anything to do? */;
+ }
+
+ if ((flag & FWRITE) != 0) {
+ if ((tp->t_state & TS_BUSY) != 0) {
+ /* XXX do what? */
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ }
+ }
}
static int
@@ -940,9 +860,7 @@ int
sabtty_mdmctrl(struct sabtty_softc *sc, int bits, int how)
{
u_int8_t r;
- int s;
- s = spltty();
switch (how) {
case DMGET:
bits = 0;
@@ -1003,14 +921,13 @@ sabtty_mdmctrl(struct sabtty_softc *sc, int bits, int how)
}
break;
}
- splx(s);
return (bits);
}
int
sabtty_param(struct sabtty_softc *sc, struct tty *tp, struct termios *t)
{
- int s, ospeed;
+ int ospeed;
tcflag_t cflag;
u_int8_t dafo, r;
@@ -1018,7 +935,14 @@ sabtty_param(struct sabtty_softc *sc, struct tty *tp, struct termios *t)
if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
return (EINVAL);
- s = spltty();
+ /*
+ * If there were no changes, don't do anything. This avoids dropping
+ * input and improves performance when all we did was frob things like
+ * VMIN and VTIME.
+ */
+ if (tp->t_ospeed == t->c_ospeed &&
+ tp->t_cflag == t->c_cflag)
+ return (0);
/* hang up line if ospeed is zero, otherwise raise dtr */
sabtty_mdmctrl(sc, TIOCM_DTR,
@@ -1028,7 +952,7 @@ sabtty_param(struct sabtty_softc *sc, struct tty *tp, struct termios *t)
cflag = t->c_cflag;
- if ((sc->sc_flags & SABTTYF_CONS) != 0) {
+ if (sc->sc_console != 0) {
cflag |= CLOCAL;
cflag &= ~HUPCL;
}
@@ -1063,6 +987,14 @@ sabtty_param(struct sabtty_softc *sc, struct tty *tp, struct termios *t)
} else
dafo |= SAB_DAFO_PAR_NONE;
+ tp->t_ispeed = 0;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = cflag;
+
+ ttsetwater(tp);
+
+ SABTTY_LOCK(sc);
+
if (ospeed != 0) {
SAB_WRITE(sc, SAB_BGR, ospeed & 0xff);
r = SAB_READ(sc, SAB_CCR2);
@@ -1085,9 +1017,8 @@ sabtty_param(struct sabtty_softc *sc, struct tty *tp, struct termios *t)
SAB_WRITE(sc, SAB_MODE, r);
SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
- tp->t_cflag = cflag;
+ SABTTY_UNLOCK(sc);
- splx(s);
return (0);
}
@@ -1318,18 +1249,27 @@ sabtty_cnputc(struct sabtty_softc *sc, int c)
static int
sabtty_console(device_t dev, char *mode, int len)
{
+ device_t parent;
+ phandle_t chosen;
phandle_t options;
+ ihandle_t stdin;
+ ihandle_t stdout;
char output[32];
char input[32];
char name[32];
- sprintf(name, "tty%c", 'a' + device_get_unit(dev));
+ parent = device_get_parent(dev);
+ chosen = OF_finddevice("/chosen");
options = OF_finddevice("/options");
- if (OF_getprop(options, "input-device", input, sizeof(input)) == -1 ||
+ if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1 ||
+ OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1 ||
+ OF_getprop(options, "input-device", input, sizeof(input)) == -1 ||
OF_getprop(options, "output-device", output, sizeof(output)) == -1)
return (0);
- if (strcmp(input, output) == 0 &&
- strcmp(input, name) == 0) {
+ if (ebus_get_node(parent) == OF_instance_to_package(stdin) &&
+ ebus_get_node(parent) == OF_instance_to_package(stdout) &&
+ strcmp(input, device_get_desc(dev)) == 0 &&
+ strcmp(output, device_get_desc(dev)) == 0) {
if (mode != NULL) {
sprintf(name, "%s-mode", input);
return (OF_getprop(options, name, mode, len) != -1);
OpenPOWER on IntegriCloud