summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sparc64/dev/sab.c162
1 files changed, 160 insertions, 2 deletions
diff --git a/sys/arch/sparc64/dev/sab.c b/sys/arch/sparc64/dev/sab.c
index bee1220a567..c53e666d750 100644
--- a/sys/arch/sparc64/dev/sab.c
+++ b/sys/arch/sparc64/dev/sab.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sab.c,v 1.1 2001/10/28 02:19:16 jason Exp $ */
+/* $OpenBSD: sab.c,v 1.2 2002/01/17 05:39:16 jason Exp $ */
/*
* Copyright (c) 2001 Jason L. Wright (jason@thought.net)
@@ -77,6 +77,7 @@ struct sab_softc {
struct sabtty_softc * sc_child[SAB_NCHAN];
u_int sc_nchild;
void * sc_softintr;
+ int sc_node;
};
struct sabtty_attach_args {
@@ -100,10 +101,15 @@ struct sabtty_softc {
#define SABTTYF_DONE 0x02
#define SABTTYF_RINGOVERFLOW 0x04
#define SABTTYF_CDCHG 0x08
+#define SABTTYF_CONS_IN 0x10
+#define SABTTYF_CONS_OUT 0x20
u_int8_t sc_rbuf[SABTTY_RBUF_SIZE];
u_int8_t *sc_rend, *sc_rput, *sc_rget;
};
+struct sabtty_softc *sabtty_cons_input;
+struct sabtty_softc *sabtty_cons_output;
+
#define SAB_READ(sc,r) \
bus_space_read_1((sc)->sc_bt, (sc)->sc_bh, (r))
#define SAB_WRITE(sc,r,v) \
@@ -114,6 +120,10 @@ void sab_attach __P((struct device *, struct device *, void *));
int sab_print __P((void *, const char *));
int sab_intr __P((void *));
void sab_softintr __P((void *));
+struct sabtty_softc *sab_findsabtty __P((dev_t));
+void sab_cnputc __P((dev_t, int));
+int sab_cngetc __P((dev_t));
+void sab_cnpollc __P((dev_t, int));
int sabtty_match __P((struct device *, void *, void *));
void sabtty_attach __P((struct device *, struct device *, void *));
@@ -127,6 +137,7 @@ void sabtty_tec_wait __P((struct sabtty_softc *));
void sabtty_reset __P((struct sabtty_softc *));
void sabtty_flush __P((struct sabtty_softc *));
int sabtty_speed __P((int));
+void sabtty_console_flags __P((struct sabtty_softc *));
int sabttyopen __P((dev_t, int, int, struct proc *));
int sabttyclose __P((dev_t, int, int, struct proc *));
@@ -135,6 +146,8 @@ int sabttywrite __P((dev_t, struct uio *, int));
int sabttyioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
int sabttystop __P((struct tty *, int));
struct tty *sabttytty __P((dev_t));
+void sabtty_cnputc __P((struct sabtty_softc *, int));
+int sabtty_cngetc __P((struct sabtty_softc *));
struct cfattach sab_ca = {
sizeof(struct sab_softc), sab_match, sab_attach
@@ -208,6 +221,7 @@ sab_attach(parent, self, aux)
u_int i;
sc->sc_bt = ea->ea_bustag;
+ sc->sc_node = ea->ea_node;
/* Use prom mapping, if available. */
if (ea->ea_nvaddrs)
@@ -377,7 +391,45 @@ sabtty_attach(parent, self, aux)
return;
}
- sabtty_reset(sc);
+ sabtty_console_flags(sc);
+
+ if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
+ char *acc;
+
+ switch (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
+ case SABTTYF_CONS_IN:
+ acc = "input";
+ break;
+ case SABTTYF_CONS_OUT:
+ acc = "output";
+ break;
+ case SABTTYF_CONS_IN|SABTTYF_CONS_OUT:
+ default:
+ acc = "i/o";
+ break;
+ }
+
+ /* Let current output drain */
+ DELAY(100000);
+
+ if (sc->sc_flags & SABTTYF_CONS_IN) {
+ sabtty_cons_input = sc;
+ cn_tab->cn_pollc = sab_cnpollc;
+ cn_tab->cn_getc = sab_cngetc;
+ cn_tab->cn_dev = makedev(77/*XXX*/, self->dv_unit);
+ }
+
+ if (sc->sc_flags & SABTTYF_CONS_OUT) {
+ sabtty_cons_output = sc;
+ cn_tab->cn_putc = sab_cnputc;
+ cn_tab->cn_dev = makedev(77/*XXX*/, self->dv_unit);
+ }
+ printf(": console %s", acc);
+ } else {
+ /* Not a console... */
+ sabtty_reset(sc);
+ }
+
printf("\n");
}
@@ -1034,3 +1086,109 @@ sabtty_speed(rate)
}
return (-1);
}
+
+void
+sabtty_cnputc(sc, c)
+ struct sabtty_softc *sc;
+ int c;
+{
+ sabtty_tec_wait(sc);
+ SAB_WRITE(sc, SAB_TIC, c);
+}
+
+int
+sabtty_cngetc(sc)
+ struct sabtty_softc *sc;
+{
+ return (-1);
+}
+
+struct sabtty_softc *
+sab_findsabtty(dev)
+ dev_t dev;
+{
+ struct sab_softc *bc;
+ int card = SAB_CARD(dev), port = SAB_PORT(dev);
+
+ if (card >= sab_cd.cd_ndevs || (bc = sab_cd.cd_devs[card]) == NULL)
+ return (NULL);
+ if (port >= bc->sc_nchild)
+ return (NULL);
+ return (bc->sc_child[port]);
+}
+
+void
+sab_cnputc(dev, c)
+ dev_t dev;
+ int c;
+{
+ struct sabtty_softc *sc = sabtty_cons_output;
+
+ if (sc == NULL) {
+ printf("sab_cnputc: invalid device\n");
+ return;
+ }
+ sabtty_cnputc(sc, c);
+}
+
+void
+sab_cnpollc(dev, on)
+ dev_t dev;
+ int on;
+{
+}
+
+int
+sab_cngetc(dev)
+ dev_t dev;
+{
+ struct sabtty_softc *sc = sabtty_cons_input;
+
+ if (sc == NULL) {
+ printf("sab_cngetc: invalid device\n");
+ return (-1);
+ }
+ return (sabtty_cngetc(sc));
+}
+
+void
+sabtty_console_flags(sc)
+ struct sabtty_softc *sc;
+{
+ int node, channel, cookie;
+ u_int chosen;
+ char buf[255];
+
+ node = sc->sc_parent->sc_node;
+ channel = sc->sc_portno;
+
+ chosen = OF_finddevice("/chosen");
+
+ /* Default to channel 0 if there are no explicit prom args */
+ cookie = 0;
+
+ if (node == OF_instance_to_package(OF_stdin())) {
+ if (OF_getprop(chosen, "input-device", buf,
+ sizeof(buf)) != -1) {
+ if (strcmp("ttyb", buf) == 0)
+ cookie = 1;
+ }
+
+ if (channel == cookie)
+ sc->sc_flags |= SABTTYF_CONS_IN;
+ }
+
+ /* Default to same channel if there are no explicit prom args */
+
+ if (node == OF_instance_to_package(OF_stdout())) {
+ if (OF_getprop(chosen, "output-device", buf,
+ sizeof(buf)) != -1) {
+ printf("Found output device: %s\n", buf);
+ if (strcmp("ttyb", buf) == 0)
+ cookie = 1;
+ }
+
+ if (channel == cookie)
+ sc->sc_flags |= SABTTYF_CONS_OUT;
+ }
+}