summaryrefslogtreecommitdiff
path: root/sys/arch/hp300/dev/dcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/hp300/dev/dcm.c')
-rw-r--r--sys/arch/hp300/dev/dcm.c296
1 files changed, 219 insertions, 77 deletions
diff --git a/sys/arch/hp300/dev/dcm.c b/sys/arch/hp300/dev/dcm.c
index a124effeb8f..5f211ba768b 100644
--- a/sys/arch/hp300/dev/dcm.c
+++ b/sys/arch/hp300/dev/dcm.c
@@ -1,4 +1,5 @@
-/* $NetBSD: dcm.c,v 1.27.4.1 1996/06/06 15:39:11 thorpej Exp $ */
+/* $OpenBSD: dcm.c,v 1.6 1997/01/12 15:12:22 downsj Exp $ */
+/* $NetBSD: dcm.c,v 1.34 1996/12/17 08:41:01 thorpej Exp $ */
/*
* Copyright (c) 1995, 1996 Jason R. Thorpe. All rights reserved.
@@ -49,8 +50,6 @@
* Test console support.
*/
-#include "dcm.h"
-#if NDCM > 0
/*
* 98642/MUX
*/
@@ -65,13 +64,20 @@
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <sys/time.h>
+#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <dev/cons.h>
+#ifndef NEWCONFIG
#include <hp300/dev/device.h>
+#endif
+
+#include <hp300/dev/dioreg.h>
+#include <hp300/dev/diovar.h>
+#include <hp300/dev/diodevs.h>
#include <hp300/dev/dcmreg.h>
#include <hp300/hp300/isr.h>
@@ -79,12 +85,6 @@
#define DEFAULT_BAUD_RATE 9600
#endif
-int dcmmatch(), dcmparam();
-void dcmattach(), dcmstart();
-struct driver dcmdriver = {
- dcmmatch, dcmattach, "dcm",
-};
-
struct speedtab dcmspeedtab[] = {
0, BR_0,
50, BR_50,
@@ -223,7 +223,10 @@ static char iconv[16] = {
#define NDCMPORT 4
struct dcm_softc {
+ struct device sc_dev; /* generic device glue */
+#ifndef NEWCONFIG
struct hp_device *sc_hd; /* device info */
+#endif
struct dcmdevice *sc_dcm; /* pointer to hardware */
struct tty *sc_tty[NDCMPORT]; /* our tty instances */
struct modemreg *sc_modem[NDCMPORT]; /* modem control */
@@ -249,71 +252,98 @@ struct dcm_softc {
#ifdef DCMSTATS
struct dcmstats sc_stats; /* metrics gathering */
#endif
-} dcm_softc[NDCM];
+};
+
+#ifdef NEWCONFIG
+int dcmmatch __P((struct device *, struct cfdata *, void *));
+void dcmattach __P((struct device *, struct device *, void *));
+
+struct cfattach dcm_ca = {
+ sizeof(struct dcm_softc), dcmmatch, dcmattach
+};
+
+struct cfdriver dcm_cd = {
+ NULL, "dcm", DV_TTY
+};
+#else /* ! NEWCONFIG */
+int dcmmatch();
+void dcmattach();
+
+struct driver dcmdriver = {
+ dcmmatch, dcmattach, "dcm",
+};
+
+#include "dcm.h"
+struct dcm_softc dcm_softc[NDCM];
+#endif /* NEWCONFIG */
+
+int dcmparam();
+void dcmstart();
void dcminit __P((struct dcmdevice *, int, int));
int dcmintr __P((void *));
+int dcmselftest __P((struct dcm_softc *));
+
+#ifdef NEWCONFIG
+int
+dcmmatch(parent, match, aux)
+ struct device *parent;
+ struct cfdata *match;
+ void *aux;
+{
+ struct dio_attach_args *da = aux;
+
+ switch (da->da_id) {
+ case DIO_DEVICE_ID_DCM:
+ case DIO_DEVICE_ID_DCMREM:
+ return (1);
+ }
+
+ return (0);
+}
+#else /* ! NEWCONFIG */
int
dcmmatch(hd)
register struct hp_device *hd;
{
struct dcm_softc *sc = &dcm_softc[hd->hp_unit];
- struct dcmdevice *dcm;
- int i, timo = 0;
- int s, brd, mbits;
+ struct dcmdevice *dcm = (struct dcmdevice *)hd->hp_addr;
- dcm = (struct dcmdevice *)hd->hp_addr;
if ((dcm->dcm_rsid & 0x1f) != DCMID)
return (0);
- brd = hd->hp_unit;
-
sc->sc_hd = hd;
hd->hp_ipl = DCMIPL(dcm->dcm_ic);
-
- /*
- * Empirically derived self-test magic
- */
- s = spltty();
- dcm->dcm_rsid = DCMRS;
- DELAY(50000); /* 5000 is not long enough */
- dcm->dcm_rsid = 0;
- dcm->dcm_ic = IC_IE;
- dcm->dcm_cr = CR_SELFT;
- while ((dcm->dcm_ic & IC_IR) == 0)
- if (++timo == 20000)
- return (0);
- DELAY(50000); /* XXX why is this needed ???? */
- while ((dcm->dcm_iir & IIR_SELFT) == 0)
- if (++timo == 400000)
- return (0);
- DELAY(50000); /* XXX why is this needed ???? */
- if (dcm->dcm_stcon != ST_OK) {
- if (hd->hp_args->hw_sc != conscode)
- printf("dcm%d: self test failed: %x\n",
- brd, dcm->dcm_stcon);
- return (0);
- }
- dcm->dcm_ic = IC_ID;
- splx(s);
-
- return (1);
}
+#endif /* NEWCONFIG */
+#ifdef NEWCONFIG
+void
+dcmattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct dcm_softc *sc = (struct dcm_softc *)self;
+ struct dio_attach_args *da = aux;
+ struct dcmdevice *dcm;
+ int brd = self->dv_unit;
+ int scode = da->da_scode;
+ int i, mbits, ipl;
+#else /* ! NEWCONFIG */
void
dcmattach(hd)
register struct hp_device *hd;
{
struct dcm_softc *sc = &dcm_softc[hd->hp_unit];
- struct dcmdevice *dcm;
- int i, timo = 0;
- int s, brd, mbits;
-
- dcm = sc->sc_dcm = (struct dcmdevice *)hd->hp_addr;
-
- brd = hd->hp_unit;
- if (hd->hp_args->hw_sc == conscode) {
+ struct dcmdevice *dcm = (struct dcmdevice *)hd->hp_addr;
+ int brd = hd->hp_unit;
+ int scode = hd->hp_args->hw_sc;
+ int i, mbits, ipl = hd->hp_ipl;
+#endif /* NEWCONFIG */
+
+ if (scode == conscode) {
+ dcm = (struct dcmdevice *)conaddr;
sc->sc_flags |= DCM_ISCONSOLE;
/*
@@ -322,17 +352,48 @@ dcmattach(hd)
* Note that we always assume port 1 on the board.
*/
cn_tab->cn_dev = makedev(dcmmajor, (brd << 2) | DCMCONSPORT);
+ } else {
+#ifdef NEWCONFIG
+ dcm = (struct dcmdevice *)iomap(dio_scodetopa(da->da_scode),
+ da->da_size);
+ if (dcm == NULL) {
+ printf("\n%s: can't map registers\n",
+ sc->sc_dev.dv_xname);
+ return;
+ }
+#endif
+ }
+
+ sc->sc_dcm = dcm;
+
+#ifdef NEWCONFIG
+ ipl = DIO_IPL(dcm);
+ printf(" ipl %d", ipl);
+#else /* ! NEWCONFIG */
+ /* XXX Set the device class. */
+ hd->hp_dev.dv_class = DV_TTY;
+ bcopy(&hd->hp_dev, &sc->sc_dev, sizeof(struct device));
+#endif /* NEWCONFIG */
+
+ if (dcmselftest(sc)) {
+ printf("\n%s: self-test failed\n", sc->sc_dev.dv_xname);
+ return;
}
/* Extract configuration info from flags. */
+#ifdef NEWCONFIG
+ sc->sc_softCAR = self->dv_cfdata->cf_flags & DCM_SOFTCAR;
+ sc->sc_flags = self->dv_cfdata->cf_flags & DCM_FLAGMASK;
+#else
sc->sc_softCAR = (hd->hp_flags & DCM_SOFTCAR);
sc->sc_flags = (hd->hp_flags & DCM_FLAGMASK);
+#endif /* NEWCONFIG */
/* Mark our unit as configured. */
sc->sc_flags |= DCM_ACTIVE;
/* Establish the interrupt handler. */
- isrlink(dcmintr, sc, hd->hp_ipl, ISRPRI_TTY);
+ (void) isrlink(dcmintr, sc, ipl, ISRPRI_TTY);
if (dcmistype == DIS_TIMER)
dcmsetischeme(brd, DIS_RESET|DIS_TIMER);
@@ -381,18 +442,18 @@ dcmattach(hd)
dcminit(dcm, DCMPORT(DCMUNIT(kgdb_dev)),
kgdb_rate);
if (kgdb_debug_init) {
- printf("%s port %d: ", sc->sc_hd->hp_xname,
+ printf("%s port %d: ", sc->sc_dev.dv_xname,
DCMPORT(DCMUNIT(kgdb_dev)));
kgdb_connect(1);
} else
printf("%s port %d: kgdb enabled\n",
- sc->sc_hd->hp_xname,
+ sc->sc_dev.dv_xname,
DCMPORT(DCMUNIT(kgdb_dev)));
}
/* end could be replaced */
-#endif
+#endif /* KGDB_CHEAT */
}
-#endif
+#endif /* KGDB */
}
/* ARGSUSED */
@@ -411,10 +472,16 @@ dcmopen(dev, flag, mode, p)
brd = DCMBOARD(unit);
port = DCMPORT(unit);
+#ifdef NEWCONFIG
+ if (brd >= dcm_cd.cd_ndevs || port >= NDCMPORT ||
+ (sc = dcm_cd.cd_devs[brd]) == NULL)
+ return (ENXIO);
+#else /* ! NEWCONFIG */
if ((brd >= NDCM) || (port >= NDCMPORT))
return (ENXIO);
-
sc = &dcm_softc[brd];
+#endif /* NEWCONFIG */
+
if ((sc->sc_flags & DCM_ACTIVE) == 0)
return (ENXIO);
@@ -468,7 +535,7 @@ dcmopen(dev, flag, mode, p)
#ifdef DEBUG
if (dcmdebug & DDB_MODEM)
printf("%s: dcmopen port %d softcarr %c\n",
- sc->sc_hd->hp_xname, port,
+ sc->sc_dev.dv_xname, port,
(tp->t_state & TS_CARR_ON) ? '1' : '0');
#endif
@@ -490,7 +557,7 @@ dcmopen(dev, flag, mode, p)
#ifdef DEBUG
if (dcmdebug & DDB_OPENCLOSE)
printf("%s port %d: dcmopen: st %x fl %x\n",
- sc->sc_hd->hp_xname, port, tp->t_state, tp->t_flags);
+ sc->sc_dev.dv_xname, port, tp->t_state, tp->t_flags);
#endif
if (error == 0)
error = (*linesw[tp->t_line].l_open)(dev, tp);
@@ -513,7 +580,11 @@ dcmclose(dev, flag, mode, p)
board = DCMBOARD(unit);
port = DCMPORT(unit);
+#ifdef NEWCONFIG
+ sc = dcm_cd.cd_devs[board];
+#else
sc = &dcm_softc[board];
+#endif
tp = sc->sc_tty[port];
(*linesw[tp->t_line].l_close)(tp, flag);
@@ -526,7 +597,7 @@ dcmclose(dev, flag, mode, p)
#ifdef DEBUG
if (dcmdebug & DDB_OPENCLOSE)
printf("%s port %d: dcmclose: st %x fl %x\n",
- sc->sc_hd->hp_xname, port, tp->t_state, tp->t_flags);
+ sc->sc_dev.dv_xname, port, tp->t_state, tp->t_flags);
#endif
splx(s);
ttyclose(tp);
@@ -552,7 +623,11 @@ dcmread(dev, uio, flag)
board = DCMBOARD(unit);
port = DCMPORT(unit);
+#ifdef NEWCONFIG
+ sc = dcm_cd.cd_devs[board];
+#else
sc = &dcm_softc[board];
+#endif
tp = sc->sc_tty[port];
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
@@ -572,7 +647,11 @@ dcmwrite(dev, uio, flag)
board = DCMBOARD(unit);
port = DCMPORT(unit);
+#ifdef NEWCONFIG
+ sc = dcm_cd.cd_devs[board];
+#else
sc = &dcm_softc[board];
+#endif
tp = sc->sc_tty[port];
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
@@ -589,7 +668,11 @@ dcmtty(dev)
board = DCMBOARD(unit);
port = DCMPORT(unit);
+#ifdef NEWCONFIG
+ sc = dcm_cd.cd_devs[board];
+#else
sc = &dcm_softc[board];
+#endif
return (sc->sc_tty[port]);
}
@@ -601,7 +684,7 @@ dcmintr(arg)
struct dcm_softc *sc = arg;
struct dcmdevice *dcm = sc->sc_dcm;
struct dcmischeme *dis = &sc->sc_scheme;
- int brd = sc->sc_hd->hp_unit;
+ int brd = sc->sc_dev.dv_unit;
int code, i;
int pcnd[4], mcode, mcnd[4];
@@ -631,7 +714,7 @@ dcmintr(arg)
#ifdef DEBUG
if (dcmdebug & DDB_INTR) {
printf("%s: dcmintr: iir %x pc %x/%x/%x/%x ",
- sc->sc_hd->hp_xname, code, pcnd[0], pcnd[1],
+ sc->sc_dev.dv_xname, code, pcnd[0], pcnd[1],
pcnd[2], pcnd[3]);
printf("miir %x mc %x/%x/%x/%x\n",
mcode, mcnd[0], mcnd[1], mcnd[2], mcnd[3]);
@@ -773,7 +856,7 @@ dcmreadbuf(sc, port)
#ifdef DEBUG
if (dcmdebug & DDB_INPUT)
printf("%s port %d: dcmreadbuf: c%x('%c') s%x f%x h%x t%x\n",
- sc->sc_hd->hp_xname, port,
+ sc->sc_dev.dv_xname, port,
c&0xFF, c, stat&0xFF,
tp->t_flags, head, pp->r_tail);
#endif
@@ -784,7 +867,7 @@ dcmreadbuf(sc, port)
#ifdef DEBUG
if (dcmdebug & (DDB_INPUT|DDB_SIOERR))
printf("%s port %d: dcmreadbuf: err: c%x('%c') s%x\n",
- sc->sc_hd->hp_xname, port,
+ sc->sc_dev.dv_xname, port,
stat, c&0xFF, c);
#endif
if (stat & (RD_BD | RD_FE))
@@ -794,11 +877,11 @@ dcmreadbuf(sc, port)
else if (stat & RD_OVF)
log(LOG_WARNING,
"%s port %d: silo overflow\n",
- sc->sc_hd->hp_xname, port);
+ sc->sc_dev.dv_xname, port);
else if (stat & RD_OE)
log(LOG_WARNING,
"%s port %d: uart overflow\n",
- sc->sc_hd->hp_xname, port);
+ sc->sc_dev.dv_xname, port);
}
(*linesw[tp->t_line].l_rint)(c, tp);
}
@@ -838,7 +921,7 @@ dcmmint(sc, port, mcnd)
#ifdef DEBUG
if (dcmdebug & DDB_MODEM)
printf("%s port %d: dcmmint: mcnd %x mcndlast %x\n",
- sc->sc_hd->hp_xname, port, mcnd, sc->sc_mcndlast[port]);
+ sc->sc_dev.dv_xname, port, mcnd, sc->sc_mcndlast[port]);
#endif
delta = mcnd ^ sc->sc_mcndlast[port];
sc->sc_mcndlast[port] = mcnd;
@@ -882,14 +965,18 @@ dcmioctl(dev, cmd, data, flag, p)
port = DCMPORT(unit);
board = DCMBOARD(unit);
+#ifdef NEWCONFIG
+ sc = dcm_cd.cd_devs[board];
+#else
sc = &dcm_softc[board];
+#endif
dcm = sc->sc_dcm;
tp = sc->sc_tty[port];
#ifdef DEBUG
if (dcmdebug & DDB_IOCTL)
printf("%s port %d: dcmioctl: cmd %x data %x flag %x\n",
- sc->sc_hd->hp_xname, port, cmd, *data, flag);
+ sc->sc_dev.dv_xname, port, cmd, *data, flag);
#endif
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
if (error >= 0)
@@ -997,7 +1084,11 @@ dcmparam(tp, t)
board = DCMBOARD(unit);
port = DCMPORT(unit);
+#ifdef NEWCONFIG
+ sc = dcm_cd.cd_devs[board];
+#else
sc = &dcm_softc[board];
+#endif
dcm = sc->sc_dcm;
/* check requested parameters */
@@ -1036,7 +1127,7 @@ dcmparam(tp, t)
#ifdef DEBUG
if (dcmdebug & DDB_PARAM)
printf("%s port %d: dcmparam: cflag %x mode %x speed %d uperch %d\n",
- sc->sc_hd->hp_xname, port, cflag, mode, tp->t_ospeed,
+ sc->sc_dev.dv_xname, port, cflag, mode, tp->t_ospeed,
DCM_USPERCH(tp->t_ospeed));
#endif
@@ -1084,7 +1175,11 @@ dcmstart(tp)
board = DCMBOARD(unit);
port = DCMPORT(unit);
+#ifdef NEWCONFIG
+ sc = dcm_cd.cd_devs[board];
+#else
sc = &dcm_softc[board];
+#endif
dcm = sc->sc_dcm;
s = spltty();
@@ -1094,7 +1189,7 @@ dcmstart(tp)
#ifdef DEBUG
if (dcmdebug & DDB_OUTPUT)
printf("%s port %d: dcmstart: state %x flags %x outcc %d\n",
- sc->sc_hd->hp_xname, port, tp->t_state, tp->t_flags,
+ sc->sc_dev.dv_xname, port, tp->t_state, tp->t_flags,
tp->t_outq.c_cc);
#endif
if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
@@ -1176,7 +1271,7 @@ again:
#ifdef DEBUG
if (dcmdebug & DDB_INTR)
printf("%s port %d: dcmstart(%d): head %x tail %x outqcc %d\n",
- sc->sc_hd->hp_xname, port, head, tail, tp->t_outq.c_cc);
+ sc->sc_dev.dv_xname, port, head, tail, tp->t_outq.c_cc);
#endif
out:
#ifdef DCMSTATS
@@ -1192,7 +1287,7 @@ out:
/*
* Stop output on a line.
*/
-int
+void
dcmstop(tp, flag)
register struct tty *tp;
int flag;
@@ -1222,13 +1317,18 @@ dcmmctl(dev, bits, how)
unit = DCMUNIT(dev);
brd = DCMBOARD(unit);
port = DCMPORT(unit);
+
+#ifdef NEWCONFIG
+ sc = dcm_cd.cd_devs[brd];
+#else
sc = &dcm_softc[brd];
+#endif
dcm = sc->sc_dcm;
#ifdef DEBUG
if (dcmdebug & DDB_MODEM)
printf("%s port %d: dcmmctl: bits 0x%x how %x\n",
- sc->sc_hd->hp_xname, port, bits, how);
+ sc->sc_dev.dv_xname, port, bits, how);
#endif
s = spltty();
@@ -1272,7 +1372,11 @@ dcmmctl(dev, bits, how)
dcmsetischeme(brd, flags)
int brd, flags;
{
+#ifdef NEWCONFIG
+ struct dcm_softc *sc = dcm_cd.cd_devs[brd];
+#else
struct dcm_softc *sc = &dcm_softc[brd];
+#endif
struct dcmdevice *dcm = sc->sc_dcm;
struct dcmischeme *dis = &sc->sc_scheme;
int i;
@@ -1282,11 +1386,11 @@ dcmsetischeme(brd, flags)
#ifdef DEBUG
if (dcmdebug & DDB_INTSCHM)
printf("%s: dcmsetischeme(%d): cur %d, ints %d, chars %d\n",
- sc->sc_hd->hp_xname, perchar, dis->dis_perchar,
+ sc->sc_dev.dv_xname, perchar, dis->dis_perchar,
dis->dis_intr, dis->dis_char);
if ((flags & DIS_RESET) == 0 && perchar == dis->dis_perchar) {
printf("%s: dcmsetischeme: redundent request %d\n",
- sc->sc_hd->hp_xname, perchar);
+ sc->sc_dev.dv_xname, perchar);
return;
}
#endif
@@ -1369,6 +1473,45 @@ dcminit(dcm, port, rate)
}
/*
+ * Empirically derived self-test magic
+ */
+int
+dcmselftest(sc)
+ struct dcm_softc *sc;
+{
+ struct dcmdevice *dcm = sc->sc_dcm;
+ int i, timo = 0;
+ int s, brd, mbits;
+
+ s = spltty();
+ dcm->dcm_rsid = DCMRS;
+ DELAY(50000); /* 5000 is not long enough */
+ dcm->dcm_rsid = 0;
+ dcm->dcm_ic = IC_IE;
+ dcm->dcm_cr = CR_SELFT;
+ while ((dcm->dcm_ic & IC_IR) == 0)
+ if (++timo == 20000)
+ return (1);
+ DELAY(50000); /* XXX why is this needed ???? */
+ while ((dcm->dcm_iir & IIR_SELFT) == 0)
+ if (++timo == 400000)
+ return (1);
+ DELAY(50000); /* XXX why is this needed ???? */
+ if (dcm->dcm_stcon != ST_OK) {
+#if 0
+ if (hd->hp_args->hw_sc != conscode)
+ printf("dcm%d: self test failed: %x\n",
+ brd, dcm->dcm_stcon);
+#endif
+ return (1);
+ }
+ dcm->dcm_ic = IC_ID;
+ splx(s);
+
+ return (0);
+}
+
+/*
* Following are all routines needed for DCM to act as console
*/
@@ -1558,4 +1701,3 @@ dcmcnputc(dev, c)
}
splx(s);
}
-#endif /* NDCM > 0 */