version 1.1, 1993/03/21 09:45:37 |
version 1.2, 1993/03/21 18:04:42 |
|
|
* SUCH DAMAGE. |
* SUCH DAMAGE. |
* |
* |
* @(#)com.c 7.5 (Berkeley) 5/16/91 |
* @(#)com.c 7.5 (Berkeley) 5/16/91 |
|
* |
|
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE |
|
* -------------------- ----- ---------------------- |
|
* CURRENT PATCH LEVEL: 4 00079 |
|
* -------------------- ----- ---------------------- |
|
* |
|
* 23 Sep 92 Rodney W. Grimes Fix SILO overflow on 16550 UARTS |
|
* 30 Aug 92 Poul-Henning Kamp Stabilize SLIP on lossy lines/UARTS |
|
* 09 Aug 92 Christoph Robitschko Correct minor number on com ports |
|
* 10 Feb 93 Jordan K. Hubbard Added select code |
*/ |
*/ |
static char rcsid[] = "$Header$"; |
static char rcsid[] = "$Header$"; |
|
|
Line 108 extern int kgdb_rate; |
|
Line 118 extern int kgdb_rate; |
|
extern int kgdb_debug_init; |
extern int kgdb_debug_init; |
#endif |
#endif |
|
|
#define UNIT(x) (minor(x)-1) |
#define UNIT(x) (minor(x)) |
|
|
comprobe(dev) |
comprobe(dev) |
struct isa_device *dev; |
struct isa_device *dev; |
Line 131 struct isa_device *isdp; |
|
Line 141 struct isa_device *isdp; |
|
u_char unit; |
u_char unit; |
int port = isdp->id_iobase; |
int port = isdp->id_iobase; |
|
|
unit = isdp->id_unit - 1; |
unit = isdp->id_unit; |
if (unit == comconsole) |
if (unit == comconsole) |
DELAY(1000); |
DELAY(1000); |
com_addr[unit] = port; |
com_addr[unit] = port; |
Line 139 struct isa_device *isdp; |
|
Line 149 struct isa_device *isdp; |
|
comsoftCAR |= 1 << unit; /* XXX */ |
comsoftCAR |= 1 << unit; /* XXX */ |
|
|
/* look for a NS 16550AF UART with FIFOs */ |
/* look for a NS 16550AF UART with FIFOs */ |
outb(port+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14); |
outb(port+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4); |
DELAY(100); |
DELAY(100); |
if ((inb(port+com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK) { |
if ((inb(port+com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK) { |
com_hasfifo |= 1 << unit; |
com_hasfifo |= 1 << unit; |
Line 149 struct isa_device *isdp; |
|
Line 159 struct isa_device *isdp; |
|
outb(port+com_ier, 0); |
outb(port+com_ier, 0); |
outb(port+com_mcr, 0 | MCR_IENABLE); |
outb(port+com_mcr, 0 | MCR_IENABLE); |
#ifdef KGDB |
#ifdef KGDB |
if (kgdb_dev == makedev(commajor, unit+1)) { |
if (kgdb_dev == makedev(commajor, unit)) { |
if (comconsole == unit) |
if (comconsole == unit) |
kgdb_dev = -1; /* can't debug over console port */ |
kgdb_dev = -1; /* can't debug over console port */ |
else { |
else { |
Line 239 comclose(dev, flag, mode, p) |
|
Line 249 comclose(dev, flag, mode, p) |
|
outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK); |
outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK); |
#ifdef KGDB |
#ifdef KGDB |
/* do not disable interrupts if debugging */ |
/* do not disable interrupts if debugging */ |
if (kgdb_dev != makedev(commajor, unit+1)) |
if (kgdb_dev != makedev(commajor, unit)) |
#endif |
#endif |
outb(com+com_ier, 0); |
outb(com+com_ier, 0); |
if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || |
if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || |
|
|
register u_char code; |
register u_char code; |
register struct tty *tp; |
register struct tty *tp; |
|
|
unit--; |
unit; |
com = com_addr[unit]; |
com = com_addr[unit]; |
while (1) { |
while (1) { |
code = inb(com+com_iir); |
code = inb(com+com_iir); |
|
|
#define RCVBYTE() \ |
#define RCVBYTE() \ |
code = inb(com+com_data); \ |
code = inb(com+com_data); \ |
if ((tp->t_state & TS_ISOPEN) == 0) { \ |
if ((tp->t_state & TS_ISOPEN) == 0) { \ |
if (kgdb_dev == makedev(commajor, unit+1) && \ |
if (kgdb_dev == makedev(commajor, unit) && \ |
code == FRAME_END) \ |
code == FRAME_END) \ |
kgdb_connect(0); /* trap into kgdb */ \ |
kgdb_connect(0); /* trap into kgdb */ \ |
} else \ |
} else \ |
Line 359 comeint(unit, stat, com) |
|
Line 369 comeint(unit, stat, com) |
|
#ifdef KGDB |
#ifdef KGDB |
/* we don't care about parity errors */ |
/* we don't care about parity errors */ |
if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) && |
if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) && |
kgdb_dev == makedev(commajor, unit+1) && c == FRAME_END) |
kgdb_dev == makedev(commajor, unit) && c == FRAME_END) |
kgdb_connect(0); /* trap into kgdb */ |
kgdb_connect(0); /* trap into kgdb */ |
#endif |
#endif |
return; |
return; |
Line 368 comeint(unit, stat, com) |
|
Line 378 comeint(unit, stat, com) |
|
c |= TTY_FE; |
c |= TTY_FE; |
else if (stat & LSR_PE) |
else if (stat & LSR_PE) |
c |= TTY_PE; |
c |= TTY_PE; |
else if (stat & LSR_OE) |
else if (stat & LSR_OE) { /* 30 Aug 92*/ |
|
c |= TTY_PE; /* Ought to have it's own define... */ |
log(LOG_WARNING, "com%d: silo overflow\n", unit); |
log(LOG_WARNING, "com%d: silo overflow\n", unit); |
|
} |
(*linesw[tp->t_line].l_rint)(c, tp); |
(*linesw[tp->t_line].l_rint)(c, tp); |
} |
} |
|
|
|
|
outb(com+com_cfcr, cfcr); |
outb(com+com_cfcr, cfcr); |
|
|
if (com_hasfifo & (1 << unit)) |
if (com_hasfifo & (1 << unit)) |
outb(com+com_fifo, FIFO_ENABLE | FIFO_TRIGGER_14); |
outb(com+com_fifo, FIFO_ENABLE | FIFO_TRIGGER_4); |
|
|
return(0); |
return(0); |
} |
} |
|
|
/* make sure hardware exists? XXX */ |
/* make sure hardware exists? XXX */ |
|
|
/* initialize required fields */ |
/* initialize required fields */ |
cp->cn_dev = makedev(commajor, unit+1); |
cp->cn_dev = makedev(commajor, unit); |
cp->cn_tp = &com_tty[unit]; |
cp->cn_tp = &com_tty[unit]; |
#ifdef COMCONSOLE |
#ifdef COMCONSOLE |
cp->cn_pri = CN_REMOTE; /* Force a serial port console */ |
cp->cn_pri = CN_REMOTE; /* Force a serial port console */ |
Line 653 cominit(unit, rate) |
|
Line 665 cominit(unit, rate) |
|
outb(com+com_ier, rate >> 8); |
outb(com+com_ier, rate >> 8); |
outb(com+com_cfcr, CFCR_8BITS); |
outb(com+com_cfcr, CFCR_8BITS); |
outb(com+com_ier, IER_ERXRDY | IER_ETXRDY); |
outb(com+com_ier, IER_ERXRDY | IER_ETXRDY); |
outb(com+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14); |
outb(com+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4); |
stat = inb(com+com_iir); |
stat = inb(com+com_iir); |
splx(s); |
splx(s); |
} |
} |
Line 712 comcnputc(dev, c) |
|
Line 724 comcnputc(dev, c) |
|
splx(s); |
splx(s); |
} |
} |
#endif |
#endif |
|
|
|
int |
|
comselect(dev, rw, p) |
|
dev_t dev; |
|
int rw; |
|
struct proc *p; |
|
{ |
|
register struct tty *tp = &com_tty[UNIT(dev)]; |
|
int nread; |
|
int s = spltty(); |
|
struct proc *selp; |
|
|
|
switch (rw) { |
|
|
|
case FREAD: |
|
nread = ttnread(tp); |
|
if (nread > 0 || |
|
((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0)) |
|
goto win; |
|
if (tp->t_rsel && (selp = pfind(tp->t_rsel)) && selp->p_wchan == (caddr_t)&selwait) |
|
tp->t_state |= TS_RCOLL; |
|
else |
|
tp->t_rsel = p->p_pid; |
|
break; |
|
|
|
case FWRITE: |
|
if (RB_LEN(&tp->t_out) <= tp->t_lowat) |
|
goto win; |
|
if (tp->t_wsel && (selp = pfind(tp->t_wsel)) && selp->p_wchan == (caddr_t)&selwait) |
|
tp->t_state |= TS_WCOLL; |
|
else |
|
tp->t_wsel = p->p_pid; |
|
break; |
|
} |
|
splx(s); |
|
return (0); |
|
win: |
|
splx(s); |
|
return (1); |
|
} |