summaryrefslogtreecommitdiff
path: root/sys/arch/hppa/dev/pdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/hppa/dev/pdc.c')
-rw-r--r--sys/arch/hppa/dev/pdc.c199
1 files changed, 124 insertions, 75 deletions
diff --git a/sys/arch/hppa/dev/pdc.c b/sys/arch/hppa/dev/pdc.c
index 7f4053c469e..e266930356a 100644
--- a/sys/arch/hppa/dev/pdc.c
+++ b/sys/arch/hppa/dev/pdc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pdc.c,v 1.9 1999/09/07 03:25:13 mickey Exp $ */
+/* $OpenBSD: pdc.c,v 1.10 1999/11/26 16:48:28 mickey Exp $ */
/*
* Copyright (c) 1998,1999 Michael Shalayeff
@@ -23,8 +23,8 @@
* 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
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF MIND,
+ * 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.
@@ -58,6 +58,7 @@ char pdc_consbuf[IODC_MINIOSIZ] PDC_ALIGNMENT;
iodcio_t pdc_cniodc, pdc_kbdiodc;
pz_device_t *pz_kbd, *pz_cons;
struct tty *pdc_tty[1];
+int CONADDR;
int pdcmatch __P((struct device *, void *, void*));
void pdcattach __P((struct device *, struct device *, void *));
@@ -70,6 +71,11 @@ struct cfdriver pdc_cd = {
NULL, "pdc", DV_DULL
};
+void pdcstart __P((struct tty *tp));
+void pdctimeout __P((void *v));
+int pdcparam __P((struct tty *tp, struct termios *));
+int pdccnlookc __P((dev_t dev, char *cp));
+
void
pdc_init()
{
@@ -99,6 +105,7 @@ pdc_init()
/* XXX make pdc current console */
cn_tab = &constab[0];
+ /* TODO: detect that we are on cereal, and set CONADDR */
}
int
@@ -135,7 +142,48 @@ pdcopen(dev, flag, mode, p)
int flag, mode;
struct proc *p;
{
- return ENXIO;
+ int unit = minor(dev);
+ struct tty *tp;
+ int s;
+ int error = 0, setuptimeout;
+
+ if (unit >= 1)
+ return ENXIO;
+
+ s = spltty();
+
+ if (!pdc_tty[unit]) {
+ tp = pdc_tty[unit] = ttymalloc();
+ tty_attach(tp);
+ } else
+ tp = pdc_tty[unit];
+
+ tp->t_oproc = pdcstart;
+ tp->t_param = pdcparam;
+ tp->t_dev = dev;
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_WOPEN|TS_CARR_ON;
+ ttychars(tp);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = 9600;
+ ttsetwater(tp);
+
+ setuptimeout = 1;
+ } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return EBUSY;
+ }
+
+ splx(s);
+
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+ if (error == 0 && setuptimeout)
+ timeout(pdctimeout, tp, 1);
+
+ return error;
}
int
@@ -144,7 +192,13 @@ pdcclose(dev, flag, mode, p)
int flag, mode;
struct proc *p;
{
- return ENXIO;
+ int unit = minor(dev);
+ struct tty *tp = pdc_tty[unit];
+
+ untimeout(pdctimeout, tp);
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+ return 0;
}
int
@@ -204,16 +258,25 @@ void
pdcstart(tp)
struct tty *tp;
{
-}
-
-struct tty *
-pdctty(dev)
- dev_t dev;
-{
- if (minor(dev) != 0)
- panic("pdctty: bogus");
+ int s;
- return pdc_tty[0];
+ s = spltty();
+ if (tp->t_state & (TS_TTSTOP | TS_BUSY)) {
+ splx(s);
+ return;
+ }
+ if (tp->t_outq.c_cc <= tp->t_lowat) {
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t)&tp->t_outq);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+ tp->t_state |= TS_BUSY;
+ while (tp->t_outq.c_cc != 0)
+ pdccnputc(tp->t_dev, getc(&tp->t_outq));
+ tp->t_state &= ~TS_BUSY;
+ splx(s);
}
int
@@ -232,10 +295,34 @@ pdcstop(tp, flag)
}
void
+pdctimeout(v)
+ void *v;
+{
+ struct tty *tp = v;
+ u_char c;
+
+ while (pdccnlookc(tp->t_dev, &c)) {
+ if (tp->t_state & TS_ISOPEN)
+ (*linesw[tp->t_line].l_rint)(c, tp);
+ }
+ timeout(pdctimeout, tp, 1);
+}
+
+struct tty *
+pdctty(dev)
+ dev_t dev;
+{
+ if (minor(dev) != 0)
+ panic("pdctty: bogus");
+
+ return pdc_tty[0];
+}
+
+void
pdccnprobe(cn)
struct consdev *cn;
{
- cn->cn_dev = makedev(28,0);
+ cn->cn_dev = makedev(22,0);
cn->cn_pri = CN_NORMAL;
}
@@ -249,43 +336,37 @@ pdccninit(cn)
}
int
-pdccngetc(dev)
+pdccnlookc(dev, cp)
dev_t dev;
+ char *cp;
{
- static int stash = 0;
- register int err, c, l;
+ int err, l;
- if (!pdc)
- return 0;
+ err = pdc_call(pdc_kbdiodc, 0, pz_kbd->pz_hpa, IODC_IO_CONSIN,
+ pz_kbd->pz_spa, pz_kbd->pz_layers, pdcret, 0,
+ pdc_consbuf, 1, 0);
- if (stash) {
- c = stash;
- if (!(dev & 0x80))
- stash = 0;
- return c;
- }
-
- do {
- err = pdc_call(pdc_kbdiodc, 0, pz_kbd->pz_hpa,
- IODC_IO_CONSIN, pz_kbd->pz_spa,
- pz_kbd->pz_layers, pdcret,
- 0, pdc_consbuf, 1, 0);
-
- l = pdcret[0];
- c = pdc_consbuf[0];
+ l = pdcret[0];
+ *cp = pdc_consbuf[0];
#ifdef DEBUG
- if (err < 0)
- printf("pdccngetc: input error: %d\n", err);
+ if (err < 0)
+ printf("pdccnlookc: input error: %d\n", err);
#endif
- /* if we are doing ischar() report immidiatelly */
- if (dev & 0x80 && l == 0)
- return (0);
+ return l;
+}
- } while(!l);
+int
+pdccngetc(dev)
+ dev_t dev;
+{
+ char c;
- if (dev & 0x80)
- stash = c;
+ if (!pdc)
+ return 0;
+
+ while(!pdccnlookc(dev, &c))
+ ;
return (c);
}
@@ -315,35 +396,3 @@ pdccnpollc(dev, on)
{
}
-
-int
-pdc_call(func, pdc_flag)
- iodcio_t func;
- int pdc_flag;
-{
- register register_t ret, opsw;
- va_list va;
- int args[10], i, s;
-
- va_start(va, pdc_flag);
- for (i = 0; i < sizeof(args)/sizeof(args[0]); i++)
- args[i] = va_arg(va, int);
- va_end(va);
-
- if (kernelmapped) {
- s = splhigh();
- opsw = set_psw(PSW_Q |
- ((!pdc_flag && args[0] == PDC_PIM)? PSW_M:0));
- }
-
- ret = (func)((void *)args[0], args[1], args[2], args[3], args[4],
- args[5], args[6], args[7], args[8], args[9]);
-
- if (kernelmapped) {
- set_psw(opsw);
- splx(s);
- }
-
- return ret;
-}
-