New version of the z8530 driver that should permit the mac68k port
to use this instead of its own. Also fix warnings, etc.
This commit is contained in:
parent
6a4e12cde0
commit
494730c376
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: z8530sc.c,v 1.4 1996/05/17 19:30:34 gwr Exp $ */
|
||||
/* $NetBSD: z8530sc.c,v 1.5 1996/12/17 20:42:40 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Gordon W. Ross
|
||||
|
@ -67,7 +67,7 @@
|
|||
#include <dev/ic/z8530reg.h>
|
||||
#include <machine/z8530var.h>
|
||||
|
||||
int
|
||||
void
|
||||
zs_break(cs, set)
|
||||
struct zs_chanstate *cs;
|
||||
int set;
|
||||
|
@ -87,20 +87,6 @@ zs_break(cs, set)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compute the current baud rate given a ZSCC channel.
|
||||
*/
|
||||
int
|
||||
zs_getspeed(cs)
|
||||
struct zs_chanstate *cs;
|
||||
{
|
||||
int tconst;
|
||||
|
||||
tconst = zs_read_reg(cs, 12);
|
||||
tconst |= zs_read_reg(cs, 13) << 8;
|
||||
return (TCONST_TO_BPS(cs->cs_brg_clk, tconst));
|
||||
}
|
||||
|
||||
/*
|
||||
* drain on-chip fifo
|
||||
*/
|
||||
|
@ -142,7 +128,6 @@ zs_loadchannelregs(cs)
|
|||
struct zs_chanstate *cs;
|
||||
{
|
||||
u_char *reg;
|
||||
int i;
|
||||
|
||||
/* Copy "pending" regs to "current" */
|
||||
bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16);
|
||||
|
@ -158,6 +143,9 @@ zs_loadchannelregs(cs)
|
|||
zs_iflush(cs); /* XXX */
|
||||
#endif
|
||||
|
||||
/* disable interrupts */
|
||||
zs_write_reg(cs, 1, reg[1] & ~ZSWR1_IMASK);
|
||||
|
||||
/* baud clock divisor, stop bits, parity */
|
||||
zs_write_reg(cs, 4, reg[4]);
|
||||
|
||||
|
@ -168,8 +156,9 @@ zs_loadchannelregs(cs)
|
|||
zs_write_reg(cs, 3, reg[3] & ~ZSWR3_RX_ENABLE);
|
||||
zs_write_reg(cs, 5, reg[5] & ~ZSWR5_TX_ENABLE);
|
||||
|
||||
/* interrupt enables: TX, TX, STATUS */
|
||||
zs_write_reg(cs, 1, reg[1]);
|
||||
/* synchronous mode stuff */
|
||||
zs_write_reg(cs, 6, reg[6]);
|
||||
zs_write_reg(cs, 7, reg[7]);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
|
@ -185,6 +174,14 @@ zs_loadchannelregs(cs)
|
|||
zs_write_reg(cs, 9, reg[9]);
|
||||
#endif
|
||||
|
||||
/* Shut down the BRG */
|
||||
zs_write_reg(cs, 14, reg[14] & ~ZSWR14_BAUD_ENA);
|
||||
|
||||
#ifdef ZS_MD_SETCLK
|
||||
/* Let the MD code setup any external clock. */
|
||||
ZS_MD_SETCLK(cs);
|
||||
#endif /* ZS_MD_SETCLK */
|
||||
|
||||
/* clock mode control */
|
||||
zs_write_reg(cs, 11, reg[11]);
|
||||
|
||||
|
@ -198,9 +195,21 @@ zs_loadchannelregs(cs)
|
|||
/* which lines cause status interrupts */
|
||||
zs_write_reg(cs, 15, reg[15]);
|
||||
|
||||
/*
|
||||
* Zilog docs recommend resetting external status twice at this
|
||||
* point. Mainly as the status bits are latched, and the first
|
||||
* interrupt clear might unlatch them to new values, generating
|
||||
* a second interrupt request.
|
||||
*/
|
||||
zs_write_csr(cs, ZSM_RESET_STINT);
|
||||
zs_write_csr(cs, ZSM_RESET_STINT);
|
||||
|
||||
/* char size, enable (RX/TX)*/
|
||||
zs_write_reg(cs, 3, reg[3]);
|
||||
zs_write_reg(cs, 5, reg[5]);
|
||||
|
||||
/* interrupt enables: RX, TX, STATUS */
|
||||
zs_write_reg(cs, 1, reg[1]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,48 +232,49 @@ zsc_intr_hard(arg)
|
|||
register struct zs_chanstate *cs_a;
|
||||
register struct zs_chanstate *cs_b;
|
||||
register int rval;
|
||||
register u_char rr3;
|
||||
register u_char rr3, rr3a;
|
||||
|
||||
cs_a = &zsc->zsc_cs[0];
|
||||
cs_b = &zsc->zsc_cs[1];
|
||||
cs_a = zsc->zsc_cs[0];
|
||||
cs_b = zsc->zsc_cs[1];
|
||||
rval = 0;
|
||||
rr3a = 0;
|
||||
|
||||
/* Note: only channel A has an RR3 */
|
||||
rr3 = zs_read_reg(cs_a, 3);
|
||||
while ((rr3 = zs_read_reg(cs_a, 3)) != 0) {
|
||||
|
||||
/* Handle receive interrupts first. */
|
||||
if (rr3 & ZSRR3_IP_A_RX)
|
||||
(*cs_a->cs_ops->zsop_rxint)(cs_a);
|
||||
if (rr3 & ZSRR3_IP_B_RX)
|
||||
(*cs_b->cs_ops->zsop_rxint)(cs_b);
|
||||
/* Handle receive interrupts first. */
|
||||
if (rr3 & ZSRR3_IP_A_RX)
|
||||
(*cs_a->cs_ops->zsop_rxint)(cs_a);
|
||||
if (rr3 & ZSRR3_IP_B_RX)
|
||||
(*cs_b->cs_ops->zsop_rxint)(cs_b);
|
||||
|
||||
/* Handle status interrupts (i.e. flow control). */
|
||||
if (rr3 & ZSRR3_IP_A_STAT)
|
||||
(*cs_a->cs_ops->zsop_stint)(cs_a);
|
||||
if (rr3 & ZSRR3_IP_B_STAT)
|
||||
(*cs_b->cs_ops->zsop_stint)(cs_b);
|
||||
/* Handle status interrupts (i.e. flow control). */
|
||||
if (rr3 & ZSRR3_IP_A_STAT)
|
||||
(*cs_a->cs_ops->zsop_stint)(cs_a);
|
||||
if (rr3 & ZSRR3_IP_B_STAT)
|
||||
(*cs_b->cs_ops->zsop_stint)(cs_b);
|
||||
|
||||
/* Handle transmit done interrupts. */
|
||||
if (rr3 & ZSRR3_IP_A_TX)
|
||||
(*cs_a->cs_ops->zsop_txint)(cs_a);
|
||||
if (rr3 & ZSRR3_IP_B_TX)
|
||||
(*cs_b->cs_ops->zsop_txint)(cs_b);
|
||||
/* Handle transmit done interrupts. */
|
||||
if (rr3 & ZSRR3_IP_A_TX)
|
||||
(*cs_a->cs_ops->zsop_txint)(cs_a);
|
||||
if (rr3 & ZSRR3_IP_B_TX)
|
||||
(*cs_b->cs_ops->zsop_txint)(cs_b);
|
||||
|
||||
/* Accumulate so we know what needs to be cleared. */
|
||||
rr3a |= rr3;
|
||||
}
|
||||
|
||||
/* Clear interrupt. */
|
||||
if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
|
||||
if (rr3a & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
|
||||
zs_write_csr(cs_a, ZSWR0_CLR_INTR);
|
||||
rval |= 1;
|
||||
}
|
||||
if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
|
||||
if (rr3a & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
|
||||
zs_write_csr(cs_b, ZSWR0_CLR_INTR);
|
||||
rval |= 2;
|
||||
}
|
||||
|
||||
if ((cs_a->cs_softreq) || (cs_b->cs_softreq)) {
|
||||
/* This is a machine-dependent function (or macro). */
|
||||
zsc_req_softint(zsc);
|
||||
}
|
||||
|
||||
/* Note: caller will check cs_x->cs_softreq and DTRT. */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
|
@ -278,11 +288,11 @@ zsc_intr_soft(arg)
|
|||
{
|
||||
register struct zsc_softc *zsc = arg;
|
||||
register struct zs_chanstate *cs;
|
||||
register int rval, unit;
|
||||
register int rval, chan;
|
||||
|
||||
rval = 0;
|
||||
for (unit = 0; unit < 2; unit++) {
|
||||
cs = &zsc->zsc_cs[unit];
|
||||
for (chan = 0; chan < 2; chan++) {
|
||||
cs = zsc->zsc_cs[chan];
|
||||
|
||||
/*
|
||||
* The softint flag can be safely cleared once
|
||||
|
@ -292,25 +302,33 @@ zsc_intr_soft(arg)
|
|||
if (cs->cs_softreq) {
|
||||
cs->cs_softreq = 0;
|
||||
(*cs->cs_ops->zsop_softint)(cs);
|
||||
rval = 1;
|
||||
rval++;
|
||||
}
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide a null zs "ops" vector.
|
||||
*/
|
||||
|
||||
static void zsnull_intr __P((struct zs_chanstate *));
|
||||
static void zsnull_softint __P((struct zs_chanstate *));
|
||||
|
||||
static void
|
||||
zsnull_intr(cs)
|
||||
struct zs_chanstate *cs;
|
||||
{
|
||||
zs_write_reg(cs, 1, 0);
|
||||
zs_write_reg(cs, 15, 0);
|
||||
/* Ask for softint() call. */
|
||||
cs->cs_softreq = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
zsnull_softint(cs)
|
||||
struct zs_chanstate *cs;
|
||||
{
|
||||
zs_write_reg(cs, 1, 0);
|
||||
zs_write_reg(cs, 15, 0);
|
||||
}
|
||||
|
||||
struct zsops zsops_null = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: z8530sc.h,v 1.4 1996/10/16 20:34:54 gwr Exp $ */
|
||||
/* $NetBSD: z8530sc.h,v 1.5 1996/12/17 20:42:42 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Gordon W. Ross
|
||||
|
@ -49,11 +49,13 @@
|
|||
/*
|
||||
* Function vector - per channel
|
||||
*/
|
||||
struct zs_chanstate;
|
||||
typedef void (*zsop_t) __P((struct zs_chanstate *));
|
||||
struct zsops {
|
||||
void (*zsop_rxint)(); /* receive char available */
|
||||
void (*zsop_stint)(); /* external/status */
|
||||
void (*zsop_txint)(); /* xmit buffer empty */
|
||||
void (*zsop_softint)(); /* process software interrupt */
|
||||
zsop_t zsop_rxint; /* receive char available */
|
||||
zsop_t zsop_stint; /* external/status */
|
||||
zsop_t zsop_txint; /* xmit buffer empty */
|
||||
zsop_t zsop_softint; /* process software interrupt */
|
||||
};
|
||||
|
||||
extern struct zsops zsops_null;
|
||||
|
@ -74,7 +76,8 @@ struct zs_chanstate {
|
|||
|
||||
int cs_brg_clk; /* BAUD Rate Generator clock
|
||||
* (usually PCLK / 16) */
|
||||
int cs_defspeed; /* default baud rate (from PROM) */
|
||||
int cs_defspeed; /* default baud rate */
|
||||
int cs_defcflag; /* default cflag */
|
||||
|
||||
/*
|
||||
* We must keep a copy of the write registers as they are
|
||||
|
@ -91,22 +94,41 @@ struct zs_chanstate {
|
|||
*/
|
||||
u_char cs_creg[16]; /* current values */
|
||||
u_char cs_preg[16]; /* pending values */
|
||||
int cs_heldchange; /* change pending (creg != preg) */
|
||||
|
||||
u_char cs_heldchange; /* change pending (creg != preg) */
|
||||
u_char cs_rr0; /* last rr0 processed */
|
||||
u_char cs_rr0_delta; /* rr0 changes at status intr. */
|
||||
u_char cs_rr0_dcd; /* which bit to read as DCD */
|
||||
u_char cs_rr0_cts; /* which bit to read as CTS */
|
||||
/* the above is set only while CRTSCTS is enabled. */
|
||||
|
||||
u_char cs_wr5_dtr; /* which bit to write as DTR */
|
||||
u_char cs_wr5_rts; /* which bit to write as RTS */
|
||||
/* the above is set only while CRTSCTS is enabled. */
|
||||
|
||||
char cs_softreq; /* need soft interrupt call */
|
||||
};
|
||||
|
||||
struct zsc_softc {
|
||||
struct device zsc_dev; /* required first: base device */
|
||||
struct zs_chanstate zsc_cs[2]; /* channel A and B soft state */
|
||||
char cs_pad[1];
|
||||
/* MD code might define a larger variant of this. */
|
||||
};
|
||||
|
||||
struct zsc_attach_args {
|
||||
int channel; /* two serial channels per zsc */
|
||||
int hwflags;
|
||||
};
|
||||
#define ZS_HWFLAG_CONSOLE 1
|
||||
#define ZS_HWFLAG_CONSOLE 1
|
||||
#define ZS_HWFLAG_NO_DCD 2 /* Ignore the DCD bit */
|
||||
#define ZS_HWFLAG_NO_CTS 4 /* Ignore the CTS bit */
|
||||
#define ZS_HWFLAG_RAW 8 /* advise raw mode */
|
||||
|
||||
int zsc_intr_soft __P((void *));
|
||||
int zsc_intr_hard __P((void *));
|
||||
|
||||
void zs_abort __P((struct zs_chanstate *));
|
||||
void zs_break __P((struct zs_chanstate *, int));
|
||||
void zs_iflush __P((struct zs_chanstate *));
|
||||
void zs_loadchannelregs __P((struct zs_chanstate *));
|
||||
int zs_set_speed __P((struct zs_chanstate *, int));
|
||||
int zs_set_modes __P((struct zs_chanstate *, int));
|
||||
|
||||
extern int zs_major;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: z8530tty.c,v 1.13 1996/10/16 20:42:14 gwr Exp $ */
|
||||
/* $NetBSD: z8530tty.c,v 1.14 1996/12/17 20:42:43 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Gordon W. Ross
|
||||
|
@ -85,14 +85,6 @@
|
|||
extern int zs_check_kgdb();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allow the MD var.h to override the default CFLAG so that
|
||||
* console messages during boot come out with correct parity.
|
||||
*/
|
||||
#ifndef ZSTTY_DEF_CFLAG
|
||||
#define ZSTTY_DEF_CFLAG TTYDEF_CFLAG
|
||||
#endif
|
||||
|
||||
/*
|
||||
* How many input characters we can buffer.
|
||||
* The port-specific var.h may override this.
|
||||
|
@ -158,7 +150,11 @@ struct zstty_softc {
|
|||
|
||||
|
||||
/* Definition of the driver for autoconfig. */
|
||||
#ifdef __BROKEN_INDIRECT_CONFIG
|
||||
static int zstty_match(struct device *, void *, void *);
|
||||
#else
|
||||
static int zstty_match(struct device *, struct cfdata *, void *);
|
||||
#endif
|
||||
static void zstty_attach(struct device *, struct device *, void *);
|
||||
|
||||
struct cfattach zstty_ca = {
|
||||
|
@ -174,21 +170,22 @@ struct zsops zsops_tty;
|
|||
/* Routines called from other code. */
|
||||
cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */
|
||||
|
||||
static void zsstart(struct tty *);
|
||||
static int zsparam(struct tty *, struct termios *);
|
||||
static void zs_modem(struct zstty_softc *zst, int onoff);
|
||||
static int zshwiflow(struct tty *, int);
|
||||
static void zs_hwiflow(struct zstty_softc *, int);
|
||||
static void zsstart __P((struct tty *));
|
||||
static int zsparam __P((struct tty *, struct termios *));
|
||||
static void zs_modem __P((struct zstty_softc *zst, int onoff));
|
||||
static int zshwiflow __P((struct tty *, int));
|
||||
static void zs_hwiflow __P((struct zstty_softc *, int));
|
||||
|
||||
/*
|
||||
* zstty_match: how is this zs channel configured?
|
||||
*/
|
||||
#ifdef __BROKEN_INDIRECT_CONFIG
|
||||
int
|
||||
zstty_match(parent, match, aux)
|
||||
zstty_match(parent, vcf, aux)
|
||||
struct device *parent;
|
||||
void *match, *aux;
|
||||
void *vcf, *aux;
|
||||
{
|
||||
struct cfdata *cf = match;
|
||||
struct cfdata *cf = vcf;
|
||||
struct zsc_attach_args *args = aux;
|
||||
|
||||
/* Exact match is better than wildcard. */
|
||||
|
@ -201,6 +198,26 @@ zstty_match(parent, match, aux)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#else /* __BROKEN_INDIRECT_CONFIG */
|
||||
int
|
||||
zstty_match(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
{
|
||||
struct zsc_attach_args *args = aux;
|
||||
|
||||
/* Exact match is better than wildcard. */
|
||||
if (cf->cf_loc[0] == args->channel)
|
||||
return 2;
|
||||
|
||||
/* This driver accepts wildcard. */
|
||||
if (cf->cf_loc[0] == -1)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* __BROKEN_INDIRECT_CONFIG */
|
||||
|
||||
void
|
||||
zstty_attach(parent, self, aux)
|
||||
|
@ -210,24 +227,23 @@ zstty_attach(parent, self, aux)
|
|||
{
|
||||
struct zsc_softc *zsc = (void *) parent;
|
||||
struct zstty_softc *zst = (void *) self;
|
||||
struct cfdata *cf = self->dv_cfdata;
|
||||
struct zsc_attach_args *args = aux;
|
||||
struct zs_chanstate *cs;
|
||||
struct cfdata *cf;
|
||||
struct tty *tp;
|
||||
int channel, tty_unit;
|
||||
dev_t dev;
|
||||
|
||||
cf = zst->zst_dev.dv_cfdata;
|
||||
tty_unit = zst->zst_dev.dv_unit;
|
||||
channel = args->channel;
|
||||
cs = &zsc->zsc_cs[channel];
|
||||
cs = zsc->zsc_cs[channel];
|
||||
cs->cs_private = zst;
|
||||
cs->cs_ops = &zsops_tty;
|
||||
|
||||
zst->zst_cs = cs;
|
||||
zst->zst_swflags = cf->cf_flags; /* softcar, etc. */
|
||||
zst->zst_hwflags = args->hwflags;
|
||||
dev = makedev(ZSTTY_MAJOR, tty_unit);
|
||||
dev = makedev(zs_major, tty_unit);
|
||||
|
||||
if (zst->zst_swflags)
|
||||
printf(" flags 0x%x", zst->zst_swflags);
|
||||
|
@ -266,18 +282,26 @@ zstty_attach(parent, self, aux)
|
|||
zst->zst_rbuf = malloc(zstty_rbuf_size * sizeof(zst->zst_rbuf[0]),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
|
||||
/* XXX - Do we need an MD hook here? */
|
||||
|
||||
/*
|
||||
* Hardware init
|
||||
*/
|
||||
if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE) {
|
||||
/* This unit is the console. */
|
||||
/* Call zsparam similar to open. */
|
||||
struct termios t;
|
||||
|
||||
/* Make console output work while closed. */
|
||||
zst->zst_swflags |= TIOCFLAG_SOFTCAR;
|
||||
/* Call _param so interrupts get enabled. */
|
||||
cs->cs_defspeed = zs_getspeed(cs);
|
||||
tp->t_ispeed = cs->cs_defspeed;
|
||||
tp->t_ospeed = cs->cs_defspeed;
|
||||
tp->t_cflag = ZSTTY_DEF_CFLAG;
|
||||
(void) zsparam(tp, &tp->t_termios);
|
||||
/* Setup the "new" parameters in t. */
|
||||
bzero((void*)&t, sizeof(t));
|
||||
t.c_cflag = cs->cs_defcflag;
|
||||
t.c_ospeed = cs->cs_defspeed;
|
||||
/* Enable interrupts. */
|
||||
cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE;
|
||||
/* Make sure zsparam will see changes. */
|
||||
tp->t_ospeed = 0;
|
||||
(void) zsparam(tp, &t);
|
||||
} else {
|
||||
/* Not the console; may need reset. */
|
||||
int reset, s;
|
||||
|
@ -357,48 +381,77 @@ zsopen(dev, flags, mode, p)
|
|||
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
/* First open. */
|
||||
ttychars(tp);
|
||||
tp->t_iflag = TTYDEF_IFLAG;
|
||||
tp->t_oflag = TTYDEF_OFLAG;
|
||||
tp->t_cflag = ZSTTY_DEF_CFLAG;
|
||||
struct termios t;
|
||||
|
||||
/*
|
||||
* Setup the "new" parameters in t.
|
||||
* Can not use tp->t because zsparam
|
||||
* deals only with what has changed.
|
||||
*/
|
||||
bzero((void*)&t, sizeof(t));
|
||||
t.c_cflag = cs->cs_defcflag;
|
||||
if (zst->zst_swflags & TIOCFLAG_CLOCAL)
|
||||
tp->t_cflag |= CLOCAL;
|
||||
t.c_cflag |= CLOCAL;
|
||||
if (zst->zst_swflags & TIOCFLAG_CRTSCTS)
|
||||
tp->t_cflag |= CRTSCTS;
|
||||
t.c_cflag |= CRTSCTS;
|
||||
if (zst->zst_swflags & TIOCFLAG_MDMBUF)
|
||||
tp->t_cflag |= MDMBUF;
|
||||
tp->t_lflag = TTYDEF_LFLAG;
|
||||
tp->t_ispeed = tp->t_ospeed = cs->cs_defspeed;
|
||||
(void) zsparam(tp, &tp->t_termios);
|
||||
t.c_cflag |= MDMBUF;
|
||||
t.c_ospeed = cs->cs_defspeed;
|
||||
/* Enable interrupts. */
|
||||
cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE;
|
||||
/* Make sure zsparam will see changes. */
|
||||
tp->t_ospeed = 0;
|
||||
(void) zsparam(tp, &t);
|
||||
/*
|
||||
* Note: zsparam has done: cflag, ispeed, ospeed
|
||||
* so we just need to do: iflag, oflag, lflag, cc
|
||||
* For "raw" mode, just leave all zeros.
|
||||
*/
|
||||
if ((zst->zst_hwflags & ZS_HWFLAG_RAW) == 0) {
|
||||
tp->t_iflag = TTYDEF_IFLAG;
|
||||
tp->t_oflag = TTYDEF_OFLAG;
|
||||
tp->t_lflag = TTYDEF_LFLAG;
|
||||
ttychars(tp);
|
||||
}
|
||||
ttsetwater(tp);
|
||||
/* Flush any pending input. */
|
||||
zst->zst_rbget = zst->zst_rbput;
|
||||
zs_iflush(cs); /* XXX */
|
||||
/* Turn on DTR */
|
||||
zs_modem(zst, 1);
|
||||
/* DTR was turned on by zsparam. */
|
||||
if (zst->zst_swflags & TIOCFLAG_SOFTCAR) {
|
||||
tp->t_state |= TS_CARR_ON;
|
||||
}
|
||||
/* XXX - The MD code could just force CLOCAL instead. */
|
||||
if (zst->zst_hwflags & ZS_HWFLAG_NO_DCD) {
|
||||
tp->t_state |= TS_CARR_ON;
|
||||
}
|
||||
}
|
||||
error = 0;
|
||||
|
||||
/* Wait for carrier. */
|
||||
for (;;) {
|
||||
/* In this section, we may touch the chip. */
|
||||
(void)splzs();
|
||||
|
||||
/* Might never get status intr if carrier already on. */
|
||||
cs->cs_rr0 = zs_read_csr(cs);
|
||||
if (cs->cs_rr0 & ZSRR0_DCD) {
|
||||
/*
|
||||
* Get initial value of RR0. This is done after we
|
||||
* raise DTR in case the cable loops DTR back to CTS.
|
||||
*/
|
||||
cs->cs_rr0 = zs_read_csr(cs);
|
||||
|
||||
/*
|
||||
* Wait for DCD (if necessary). Note that we might
|
||||
* never get status interrupt if DCD is already on.
|
||||
*/
|
||||
for (;;) {
|
||||
/* Check the DCD bit (if we have one). */
|
||||
if (cs->cs_rr0 & cs->cs_rr0_dcd)
|
||||
tp->t_state |= TS_CARR_ON;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((tp->t_state & TS_CARR_ON) ||
|
||||
(tp->t_cflag & CLOCAL) ||
|
||||
(flags & O_NONBLOCK) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sleep waiting for a status interrupt. */
|
||||
tp->t_state |= TS_WOPEN;
|
||||
error = ttysleep(tp, (caddr_t)&tp->t_rawq,
|
||||
TTIPRI | PCATCH, ttopen, 0);
|
||||
|
@ -411,13 +464,12 @@ zsopen(dev, flags, mode, p)
|
|||
}
|
||||
break;
|
||||
}
|
||||
/* The status interrupt changed cs->cs_rr0 */
|
||||
}
|
||||
|
||||
splx(s);
|
||||
|
||||
if (error == 0)
|
||||
error = linesw[tp->t_line].l_open(dev, tp);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -434,7 +486,6 @@ zsclose(dev, flags, mode, p)
|
|||
struct zstty_softc *zst;
|
||||
register struct zs_chanstate *cs;
|
||||
register struct tty *tp;
|
||||
struct zsinfo *zi;
|
||||
int hup, s;
|
||||
|
||||
zst = zstty_cd.cd_devs[minor(dev)];
|
||||
|
@ -446,6 +497,14 @@ zsclose(dev, flags, mode, p)
|
|||
return 0;
|
||||
|
||||
(*linesw[tp->t_line].l_close)(tp, flags);
|
||||
|
||||
/* Disable interrupts. */
|
||||
s = splzs();
|
||||
cs->cs_creg[1] = cs->cs_preg[1] = 0;
|
||||
zs_write_reg(cs, 1, cs->cs_creg[1]);
|
||||
splx(s);
|
||||
|
||||
/* Maybe do "hangup" (drop DTR). */
|
||||
hup = tp->t_cflag & HUPCL;
|
||||
if (zst->zst_swflags & TIOCFLAG_SOFTCAR)
|
||||
hup = 0;
|
||||
|
@ -457,7 +516,6 @@ zsclose(dev, flags, mode, p)
|
|||
if (cs->cs_creg[5] & ZSWR5_BREAK) {
|
||||
zs_break(cs, 0);
|
||||
}
|
||||
/* XXX - turn off interrupts? */
|
||||
|
||||
ttyclose(tp);
|
||||
return (0);
|
||||
|
@ -517,10 +575,17 @@ zsioctl(dev, cmd, data, flag, p)
|
|||
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return (error);
|
||||
|
||||
error = ttioctl(tp, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return (error);
|
||||
|
||||
#ifdef ZS_MD_IOCTL
|
||||
error = ZS_MD_IOCTL;
|
||||
if (error >= 0)
|
||||
return (error);
|
||||
#endif /* ZS_MD_IOCTL */
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case TIOCSBRK:
|
||||
|
@ -592,10 +657,10 @@ zsstart(tp)
|
|||
|
||||
/*
|
||||
* If under CRTSCTS hfc and halted, do nothing
|
||||
* This flag can only be set with CRTSCTS.
|
||||
*/
|
||||
if (tp->t_cflag & CRTSCTS)
|
||||
if (zst->zst_tx_stopped)
|
||||
goto out;
|
||||
if (zst->zst_tx_stopped)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If there are sleepers, and output has drained below low
|
||||
|
@ -671,101 +736,116 @@ zsstop(tp, flag)
|
|||
* Set ZS tty parameters from termios.
|
||||
* XXX - Should just copy the whole termios after
|
||||
* making sure all the changes could be done.
|
||||
* XXX - Only whack the UART when params change...
|
||||
*/
|
||||
static int
|
||||
zsparam(tp, t)
|
||||
register struct tty *tp;
|
||||
register struct termios *t;
|
||||
{
|
||||
register struct zstty_softc *zst;
|
||||
register struct zs_chanstate *cs;
|
||||
register int s, bps, cflag, tconst;
|
||||
u_char tmp3, tmp4, tmp5, reset;
|
||||
struct zstty_softc *zst;
|
||||
struct zs_chanstate *cs;
|
||||
int s, bps, cflag, error;
|
||||
u_char tmp3, tmp4, tmp5;
|
||||
|
||||
zst = zstty_cd.cd_devs[minor(tp->t_dev)];
|
||||
cs = zst->zst_cs;
|
||||
|
||||
/* XXX: Need to use an MD function for this. */
|
||||
bps = t->c_ospeed;
|
||||
cflag = t->c_cflag;
|
||||
|
||||
if (bps < 0 || (t->c_ispeed && t->c_ispeed != bps))
|
||||
return (EINVAL);
|
||||
if (bps == 0) {
|
||||
/* stty 0 => drop DTR and RTS */
|
||||
zs_modem(zst, 0);
|
||||
|
||||
/*
|
||||
* Only whack the UART when params change.
|
||||
* Some callers need to clear tp->t_ospeed
|
||||
* to make sure initialization gets done.
|
||||
*/
|
||||
if ((tp->t_ospeed == bps) &&
|
||||
(tp->t_cflag == cflag) )
|
||||
return (0);
|
||||
}
|
||||
tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps);
|
||||
if (tconst < 0)
|
||||
return (EINVAL);
|
||||
|
||||
/* Convert back to make sure we can do it. */
|
||||
bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst);
|
||||
if (bps != t->c_ospeed)
|
||||
return (EINVAL);
|
||||
tp->t_ispeed = tp->t_ospeed = bps;
|
||||
/*
|
||||
* Call MD functions to deal with changed
|
||||
* clock modes or H/W flow control modes.
|
||||
* The BRG divisor is set now. (reg 12,13)
|
||||
*/
|
||||
error = zs_set_speed(cs, bps);
|
||||
if (error)
|
||||
return (error);
|
||||
error = zs_set_modes(cs, cflag);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
cflag = t->c_cflag;
|
||||
/* OK, we are now committed to do it. */
|
||||
tp->t_cflag = cflag;
|
||||
tp->t_ospeed = bps;
|
||||
tp->t_ispeed = bps;
|
||||
|
||||
/*
|
||||
* Block interrupts so that state will not
|
||||
* be altered until we are done setting it up.
|
||||
*/
|
||||
s = splzs();
|
||||
|
||||
/*
|
||||
*
|
||||
* Initial values in cs_preg are set before
|
||||
* our attach routine is called. The master
|
||||
* interrupt enable is handled by zsc.c
|
||||
*
|
||||
*/
|
||||
s = splzs();
|
||||
|
||||
cs->cs_preg[12] = tconst;
|
||||
cs->cs_preg[13] = tconst >> 8;
|
||||
|
||||
/* Recompute character size bits. */
|
||||
tmp3 = cs->cs_preg[3] & ~ZSWR3_RXSIZE;
|
||||
tmp5 = cs->cs_preg[5] & ~ZSWR5_TXSIZE;
|
||||
switch (cflag & CSIZE) {
|
||||
case CS5:
|
||||
tmp3 = ZSWR3_RX_5;
|
||||
tmp5 = ZSWR5_TX_5;
|
||||
/* These are |= 0 but let the optimizer deal with it. */
|
||||
tmp3 |= ZSWR3_RX_5;
|
||||
tmp5 |= ZSWR5_TX_5;
|
||||
break;
|
||||
case CS6:
|
||||
tmp3 = ZSWR3_RX_6;
|
||||
tmp5 = ZSWR5_TX_6;
|
||||
tmp3 |= ZSWR3_RX_6;
|
||||
tmp5 |= ZSWR5_TX_6;
|
||||
break;
|
||||
case CS7:
|
||||
tmp3 = ZSWR3_RX_7;
|
||||
tmp5 = ZSWR5_TX_7;
|
||||
tmp3 |= ZSWR3_RX_7;
|
||||
tmp5 |= ZSWR5_TX_7;
|
||||
break;
|
||||
case CS8:
|
||||
default:
|
||||
tmp3 = ZSWR3_RX_8;
|
||||
tmp5 = ZSWR5_TX_8;
|
||||
tmp3 |= ZSWR3_RX_8;
|
||||
tmp5 |= ZSWR5_TX_8;
|
||||
break;
|
||||
}
|
||||
/* Raise or lower DTR and RTS as appropriate. */
|
||||
if (bps) {
|
||||
/* Raise DTR and RTS */
|
||||
tmp5 |= cs->cs_wr5_dtr;
|
||||
} else {
|
||||
/* Drop DTR and RTS */
|
||||
/* XXX: Should SOFTCAR prevent this? */
|
||||
tmp5 &= ~(cs->cs_wr5_dtr);
|
||||
}
|
||||
cs->cs_preg[3] = tmp3;
|
||||
cs->cs_preg[5] = tmp5;
|
||||
|
||||
cs->cs_preg[3] = tmp3 | ZSWR3_RX_ENABLE;
|
||||
cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
|
||||
|
||||
tmp4 = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB);
|
||||
/*
|
||||
* Recompute the stop bits and parity bits. Note that
|
||||
* zs_set_speed() may have set clock selection bits etc.
|
||||
* in wr4, so those must preserved.
|
||||
*/
|
||||
tmp4 = cs->cs_preg[4];
|
||||
/* Recompute stop bits. */
|
||||
tmp4 &= ~ZSWR4_SBMASK;
|
||||
tmp4 |= (cflag & CSTOPB) ?
|
||||
ZSWR4_TWOSB : ZSWR4_ONESB;
|
||||
/* Recompute parity bits. */
|
||||
tmp4 &= ~ZSWR4_PARMASK;
|
||||
if ((cflag & PARODD) == 0)
|
||||
tmp4 |= ZSWR4_EVENP;
|
||||
if (cflag & PARENB)
|
||||
tmp4 |= ZSWR4_PARENB;
|
||||
cs->cs_preg[4] = tmp4;
|
||||
|
||||
/*
|
||||
* Output hardware flow control on the chip is horrendous:
|
||||
* if carrier detect drops, the receiver is disabled.
|
||||
* Therefore, NEVER set the HFC bit, and instead use
|
||||
* the status interrupts to detect CTS changes.
|
||||
*/
|
||||
if (cflag & CRTSCTS) {
|
||||
zst->zst_rbhiwat = zstty_rbuf_hiwat;
|
||||
cs->cs_preg[15] |= ZSWR15_CTS_IE;
|
||||
} else {
|
||||
zst->zst_rbhiwat = zstty_rbuf_size; /* impossible value */
|
||||
cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
|
||||
}
|
||||
/* The MD function zs_set_modes handled CRTSCTS, etc. */
|
||||
|
||||
/*
|
||||
* If nothing is being transmitted, set up new current values,
|
||||
|
@ -775,12 +855,27 @@ zsparam(tp, t)
|
|||
if (zst->zst_tx_busy) {
|
||||
zst->zst_heldtbc = zst->zst_tbc;
|
||||
zst->zst_tbc = 0;
|
||||
cs->cs_heldchange = 0xFF; /* XXX */
|
||||
cs->cs_heldchange = 0xFFFF;
|
||||
} else {
|
||||
zs_loadchannelregs(cs);
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
|
||||
/* If we can throttle input, enable "high water" detection. */
|
||||
if (cflag & CHWFLOW) {
|
||||
zst->zst_rbhiwat = zstty_rbuf_hiwat;
|
||||
} else {
|
||||
/* This impossible value prevents a "high water" trigger. */
|
||||
zst->zst_rbhiwat = zstty_rbuf_size;
|
||||
/* XXX: Lost hwi ability, so unblock and restart. */
|
||||
zst->zst_rx_blocked = 0;
|
||||
if (zst->zst_tx_stopped) {
|
||||
zst->zst_tx_stopped = 0;
|
||||
zsstart(tp);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -794,21 +889,23 @@ zs_modem(zst, onoff)
|
|||
int onoff;
|
||||
{
|
||||
struct zs_chanstate *cs;
|
||||
struct tty *tp;
|
||||
int s, bis, and;
|
||||
int s, clr, set;
|
||||
|
||||
cs = zst->zst_cs;
|
||||
tp = zst->zst_tty;
|
||||
if (cs->cs_wr5_dtr == 0)
|
||||
return;
|
||||
|
||||
if (onoff) {
|
||||
bis = ZSWR5_DTR | ZSWR5_RTS;
|
||||
and = ~0;
|
||||
clr = 0;
|
||||
set = cs->cs_wr5_dtr;
|
||||
} else {
|
||||
bis = 0;
|
||||
and = ~(ZSWR5_DTR | ZSWR5_RTS);
|
||||
clr = cs->cs_wr5_dtr;
|
||||
set = 0;
|
||||
}
|
||||
|
||||
s = splzs();
|
||||
cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and;
|
||||
cs->cs_preg[5] &= ~clr;
|
||||
cs->cs_preg[5] |= set;
|
||||
if (cs->cs_heldchange == 0) {
|
||||
if (zst->zst_tx_busy) {
|
||||
zst->zst_heldtbc = zst->zst_tbc;
|
||||
|
@ -834,9 +931,15 @@ zshwiflow(tp, stop)
|
|||
int stop;
|
||||
{
|
||||
register struct zstty_softc *zst;
|
||||
register struct zs_chanstate *cs;
|
||||
int s;
|
||||
|
||||
zst = zstty_cd.cd_devs[minor(tp->t_dev)];
|
||||
cs = zst->zst_cs;
|
||||
|
||||
/* Can not do this without some bit assigned as RTS. */
|
||||
if (cs->cs_wr5_rts == 0)
|
||||
return (0);
|
||||
|
||||
s = splzs();
|
||||
if (stop) {
|
||||
|
@ -870,23 +973,25 @@ zs_hwiflow(zst, stop)
|
|||
int stop;
|
||||
{
|
||||
register struct zs_chanstate *cs;
|
||||
register struct tty *tp;
|
||||
register int bis, and;
|
||||
register int clr, set;
|
||||
|
||||
cs = zst->zst_cs;
|
||||
tp = zst->zst_tty;
|
||||
|
||||
if (cs->cs_wr5_rts == 0)
|
||||
return;
|
||||
|
||||
if (stop) {
|
||||
/* Block input (Lower RTS) */
|
||||
bis = 0;
|
||||
and = ~ZSWR5_RTS;
|
||||
clr = cs->cs_wr5_rts;
|
||||
set = 0;
|
||||
} else {
|
||||
/* Unblock input (Raise RTS) */
|
||||
bis = ZSWR5_RTS;
|
||||
and = ~0;
|
||||
clr = 0;
|
||||
set = cs->cs_wr5_rts;
|
||||
}
|
||||
|
||||
cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and;
|
||||
cs->cs_preg[5] &= ~clr;
|
||||
cs->cs_preg[5] |= set;
|
||||
if (cs->cs_heldchange == 0) {
|
||||
if (zst->zst_tx_busy) {
|
||||
zst->zst_heldtbc = zst->zst_tbc;
|
||||
|
@ -904,6 +1009,12 @@ zs_hwiflow(zst, stop)
|
|||
* Interface to the lower layer (zscc)
|
||||
****************************************************************/
|
||||
|
||||
static void zstty_rxint __P((struct zs_chanstate *));
|
||||
static void zstty_txint __P((struct zs_chanstate *));
|
||||
static void zstty_stint __P((struct zs_chanstate *));
|
||||
static void zstty_softint __P((struct zs_chanstate *));
|
||||
|
||||
static void zsoverrun __P((struct zstty_softc *, long *, char *));
|
||||
|
||||
/*
|
||||
* receiver ready interrupt.
|
||||
|
@ -1033,11 +1144,9 @@ zstty_stint(cs)
|
|||
register struct zs_chanstate *cs;
|
||||
{
|
||||
register struct zstty_softc *zst;
|
||||
register struct tty *tp;
|
||||
register u_char rr0;
|
||||
register u_char rr0, delta;
|
||||
|
||||
zst = cs->cs_private;
|
||||
tp = zst->zst_tty;
|
||||
|
||||
rr0 = zs_read_csr(cs);
|
||||
zs_write_csr(cs, ZSWR0_RESET_STATUS);
|
||||
|
@ -1049,23 +1158,10 @@ zstty_stint(cs)
|
|||
if ((rr0 & ZSRR0_BREAK) &&
|
||||
(zst->zst_hwflags & ZS_HWFLAG_CONSOLE))
|
||||
{
|
||||
zs_abort();
|
||||
zs_abort(cs);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to handle CTS output flow control here.
|
||||
* Output remains stopped as long as either the
|
||||
* zst_tx_stopped or TS_TTSTOP flag is set.
|
||||
* Never restart here; the softint routine will
|
||||
* do that after things are ready to move.
|
||||
*/
|
||||
if (((rr0 & ZSRR0_CTS) == 0) && (tp->t_cflag & CRTSCTS)) {
|
||||
zst->zst_tbc = 0;
|
||||
zst->zst_heldtbc = 0;
|
||||
zst->zst_tx_stopped = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to accumulate status line changes here.
|
||||
* Otherwise, if we get multiple status interrupts
|
||||
|
@ -1073,8 +1169,24 @@ zstty_stint(cs)
|
|||
* some status line changes in the softint routine.
|
||||
* Fix from Bill Studenmund, October 1996.
|
||||
*/
|
||||
cs->cs_rr0_delta |= (cs->cs_rr0 ^ rr0);
|
||||
delta = (cs->cs_rr0 ^ rr0);
|
||||
cs->cs_rr0_delta |= delta;
|
||||
cs->cs_rr0 = rr0;
|
||||
|
||||
/*
|
||||
* Need to handle CTS output flow control here.
|
||||
* Output remains stopped as long as either the
|
||||
* zst_tx_stopped or TS_TTSTOP flag is set.
|
||||
* Never restart here; the softint routine will
|
||||
* do that after things are ready to move.
|
||||
*/
|
||||
if ((delta & cs->cs_rr0_cts) &&
|
||||
((rr0 & cs->cs_rr0_cts) == 0))
|
||||
{
|
||||
zst->zst_tbc = 0;
|
||||
zst->zst_heldtbc = 0;
|
||||
zst->zst_tx_stopped = 1;
|
||||
}
|
||||
zst->zst_st_check = 1;
|
||||
|
||||
/* Ask for softint() call. */
|
||||
|
@ -1120,7 +1232,7 @@ zstty_softint(cs)
|
|||
register int get, c, s;
|
||||
int ringmask, overrun;
|
||||
register u_short ring_data;
|
||||
register u_char rr0, rr1, delta;
|
||||
register u_char rr0, delta;
|
||||
|
||||
zst = cs->cs_private;
|
||||
tp = zst->zst_tty;
|
||||
|
@ -1189,22 +1301,28 @@ zstty_softint(cs)
|
|||
if (zst->zst_st_check) {
|
||||
zst->zst_st_check = 0;
|
||||
|
||||
(void) splzs();
|
||||
rr0 = cs->cs_rr0;
|
||||
delta = cs->cs_rr0_delta;
|
||||
cs->cs_rr0_delta = 0;
|
||||
if (delta & ZSRR0_DCD) {
|
||||
c = ((rr0 & ZSRR0_DCD) != 0);
|
||||
(void) spltty();
|
||||
|
||||
/* Note, the MD code may use DCD for something else. */
|
||||
if (delta & cs->cs_rr0_dcd) {
|
||||
c = ((rr0 & cs->cs_rr0_dcd) != 0);
|
||||
if (line->l_modem(tp, c) == 0)
|
||||
zs_modem(zst, c);
|
||||
}
|
||||
if ((delta & ZSRR0_CTS) && (tp->t_cflag & CRTSCTS)) {
|
||||
|
||||
/* Note, cs_rr0_cts is set only with H/W flow control. */
|
||||
if (delta & cs->cs_rr0_cts) {
|
||||
/*
|
||||
* Only do restart here. Stop is handled
|
||||
* at the h/w interrupt level.
|
||||
*/
|
||||
if (rr0 & ZSRR0_CTS) {
|
||||
if (rr0 & cs->cs_rr0_cts) {
|
||||
zst->zst_tx_stopped = 0;
|
||||
tp->t_state &= ~TS_TTSTOP;
|
||||
/* tp->t_state &= ~TS_TTSTOP; */
|
||||
(*line->l_start)(tp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
/* $NetBSD: z8530var.h,v 1.5 1996/10/23 00:38:05 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Gordon W. Ross
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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 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.
|
||||
*
|
||||
* @(#)zsvar.h 8.1 (Berkeley) 6/11/93
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Function vector - per channel
|
||||
*/
|
||||
struct zs_chanstate;
|
||||
typedef void (*zsop_t) __P((struct zs_chanstate *));
|
||||
struct zsops {
|
||||
zsop_t zsop_rxint; /* receive char available */
|
||||
zsop_t zsop_stint; /* external/status */
|
||||
zsop_t zsop_txint; /* xmit buffer empty */
|
||||
zsop_t zsop_softint; /* process software interrupt */
|
||||
};
|
||||
|
||||
extern struct zsops zsops_null;
|
||||
|
||||
|
||||
/*
|
||||
* Software state, per zs channel.
|
||||
*/
|
||||
struct zs_chanstate {
|
||||
|
||||
/* Pointers to the device registers. */
|
||||
volatile u_char *cs_reg_csr; /* ctrl, status, and reg. number. */
|
||||
volatile u_char *cs_reg_data; /* data or numbered register */
|
||||
|
||||
int cs_channel; /* sub-unit number */
|
||||
void *cs_private; /* sub-driver data pointer */
|
||||
struct zsops *cs_ops;
|
||||
|
||||
int cs_brg_clk; /* BAUD Rate Generator clock
|
||||
* (usually PCLK / 16) */
|
||||
int cs_defspeed; /* default baud rate */
|
||||
int cs_defcflag; /* default cflag */
|
||||
|
||||
/*
|
||||
* We must keep a copy of the write registers as they are
|
||||
* mostly write-only and we sometimes need to set and clear
|
||||
* individual bits (e.g., in WR3). Not all of these are
|
||||
* needed but 16 bytes is cheap and this makes the addressing
|
||||
* simpler. Unfortunately, we can only write to some registers
|
||||
* when the chip is not actually transmitting, so whenever
|
||||
* we are expecting a `transmit done' interrupt the preg array
|
||||
* is allowed to `get ahead' of the current values. In a
|
||||
* few places we must change the current value of a register,
|
||||
* rather than (or in addition to) the pending value; for these
|
||||
* cs_creg[] contains the current value.
|
||||
*/
|
||||
u_char cs_creg[16]; /* current values */
|
||||
u_char cs_preg[16]; /* pending values */
|
||||
int cs_heldchange; /* change pending (creg != preg) */
|
||||
|
||||
u_char cs_rr0; /* last rr0 processed */
|
||||
u_char cs_rr0_delta; /* rr0 changes at status intr. */
|
||||
u_char cs_rr0_dcd; /* which bit to read as DCD */
|
||||
u_char cs_rr0_cts; /* which bit to read as CTS */
|
||||
/* the above is set only while CRTSCTS is enabled. */
|
||||
|
||||
u_char cs_wr5_dtr; /* which bit to write as DTR */
|
||||
u_char cs_wr5_rts; /* which bit to write as RTS */
|
||||
/* the above is set only while CRTSCTS is enabled. */
|
||||
|
||||
char cs_softreq; /* need soft interrupt call */
|
||||
char cs_pad[1];
|
||||
/* MD code might define a larger variant of this. */
|
||||
};
|
||||
|
||||
struct zsc_softc {
|
||||
struct device zsc_dev; /* required first: base device */
|
||||
struct zs_chanstate *zsc_cs[2]; /* channel A and B soft state */
|
||||
/* MD code might define a larger variant of this. */
|
||||
};
|
||||
|
||||
struct zsc_attach_args {
|
||||
int channel; /* two serial channels per zsc */
|
||||
int hwflags;
|
||||
};
|
||||
#define ZS_HWFLAG_CONSOLE 1
|
||||
#define ZS_HWFLAG_NO_DCD 2 /* Ignore the DCD bit */
|
||||
#define ZS_HWFLAG_NO_CTS 4 /* Ignore the CTS bit */
|
||||
#define ZS_HWFLAG_RAW 8 /* advise raw mode */
|
||||
|
||||
int zsc_intr_soft __P((void *));
|
||||
int zsc_intr_hard __P((void *));
|
||||
|
||||
void zs_abort __P((struct zs_chanstate *));
|
||||
void zs_break __P((struct zs_chanstate *, int));
|
||||
void zs_iflush __P((struct zs_chanstate *));
|
||||
void zs_loadchannelregs __P((struct zs_chanstate *));
|
||||
int zs_set_speed __P((struct zs_chanstate *, int));
|
||||
int zs_set_modes __P((struct zs_chanstate *, int));
|
||||
|
||||
u_char zs_read_reg __P((struct zs_chanstate *, u_char));
|
||||
void zs_write_reg __P((struct zs_chanstate *, u_char, u_char));
|
||||
|
||||
u_char zs_read_csr __P((struct zs_chanstate *));
|
||||
void zs_write_csr __P((struct zs_chanstate *, u_char));
|
||||
|
||||
u_char zs_read_data __P((struct zs_chanstate *));
|
||||
void zs_write_data __P((struct zs_chanstate *, u_char));
|
||||
|
||||
extern int zs_major;
|
||||
|
Loading…
Reference in New Issue