summaryrefslogtreecommitdiffstats
path: root/sys/pc98/cbus/sio.c
diff options
context:
space:
mode:
authorasami <asami@FreeBSD.org>1996-10-09 21:47:16 +0000
committerasami <asami@FreeBSD.org>1996-10-09 21:47:16 +0000
commit8c4b57c465eeb8efd16bd3b8416454f8ab6c5185 (patch)
tree89e1d8c7c7558e413954ce87041b0b6005ce6673 /sys/pc98/cbus/sio.c
parent130a49f9b81084ee94f9cf5c2122e5b4a7d1bde9 (diff)
downloadFreeBSD-src-8c4b57c465eeb8efd16bd3b8416454f8ab6c5185.zip
FreeBSD-src-8c4b57c465eeb8efd16bd3b8416454f8ab6c5185.tar.gz
Another round of updates. Highlights:
(1) Merged i386/i386/sb.h, deleted pc98/pc98/sb.h. (2) pc98/conf/GENERIC8 looks more like i386/conf/GENERIC now. (3) Fixed display bug in pc98/boot/biosboot/io.c. (4) Prepare to merge memory allocation routines: pc98/i386/locore.s pc98/i386/machdep.c pc98/pc98/pc98_machdep.c pc98/pc98/pc98_machdep.h (5) Support new board "C-NET(98)": pc98/pc98/if_ed98.h pc98/pc98/if_ed.c (6) Make sure FPU is recognized for non-Intel CPUs: pc98/pc98/npx.c (7) Do not expect bss to be zero-allocated: pc98/pc98/pc98.c Submitted by: The FreeBSD(98) Development Team
Diffstat (limited to 'sys/pc98/cbus/sio.c')
-rw-r--r--sys/pc98/cbus/sio.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c
index aacf54c..bcd8f13 100644
--- a/sys/pc98/cbus/sio.c
+++ b/sys/pc98/cbus/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.6 1996/09/10 09:38:34 asami Exp $
+ * $Id: sio.c,v 1.7 1996/09/12 11:09:56 asami Exp $
*/
#include "opt_comconsole.h"
@@ -875,7 +875,7 @@ sioprobe(dev)
* XXX what about the UART bug avoided by waiting in comparam()?
* We don't want to to wait long enough to drain at 2 bps.
*/
- outb(iobase + com_cfcr, CFCR_DLAB);
+ outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
outb(iobase + com_dlbl, COMBRD(9600) & 0xff);
outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8);
outb(iobase + com_cfcr, CFCR_8BITS);
@@ -1299,7 +1299,6 @@ determined_type: ;
dev = makedev(CDEV_MAJOR, 0);
cdevsw_add(&dev, &sio_cdevsw, NULL);
#ifdef DEVFS
- /* devsw, minor, type, uid, gid, perm, fmt, ... */
com->devfs_token_ttyd = devfs_add_devswf(&sio_cdevsw,
unit, DV_CHR,
UID_ROOT, GID_WHEEL, 0600, "ttyd%n", unit);
@@ -2401,6 +2400,8 @@ comparam(tp, t)
int cflag;
struct com_s *com;
int divisor;
+ u_char dlbh;
+ u_char dlbl;
int error;
Port_t iobase;
int s;
@@ -2562,8 +2563,18 @@ retry:
#endif
if (divisor != 0) {
outb(iobase + com_cfcr, cfcr | CFCR_DLAB);
- outb(iobase + com_dlbl, divisor & 0xFF);
- outb(iobase + com_dlbh, (u_int) divisor >> 8);
+ /*
+ * Only set the divisor registers if they would change,
+ * since on some 16550 incompatibles (UMC8669F), setting
+ * them while input is arriving them loses sync until
+ * data stops arriving.
+ */
+ dlbl = divisor & 0xFF;
+ if (inb(iobase + com_dlbl) != dlbl)
+ outb(iobase + com_dlbl, dlbl);
+ dlbh = (u_int) divisor >> 8;
+ if (inb(iobase + com_dlbh) != dlbh)
+ outb(iobase + com_dlbh, dlbh);
}
outb(iobase + com_cfcr, com->cfcr_image = cfcr);
#ifdef PC98
@@ -3035,6 +3046,8 @@ siocnopen(sp)
struct siocnstate *sp;
{
int divisor;
+ u_char dlbh;
+ u_char dlbl;
Port_t iobase;
/*
@@ -3047,12 +3060,22 @@ siocnopen(sp)
outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */
siocntxwait();
sp->cfcr = inb(iobase + com_cfcr);
- outb(iobase + com_cfcr, CFCR_DLAB);
+ outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
sp->dlbl = inb(iobase + com_dlbl);
sp->dlbh = inb(iobase + com_dlbh);
+ /*
+ * Only set the divisor registers if they would change, since on
+ * some 16550 incompatibles (Startech), setting them clears the
+ * data input register. This also reduces the effects of the
+ * UMC8669F bug.
+ */
divisor = ttspeedtab(comdefaultrate, comspeedtab);
- outb(iobase + com_dlbl, divisor & 0xFF);
- outb(iobase + com_dlbh, (u_int) divisor >> 8);
+ dlbl = divisor & 0xFF;
+ if (sp->dlbl != dlbl)
+ outb(iobase + com_dlbl, dlbl);
+ dlbh = (u_int) divisor >> 8;
+ if (sp->dlbh != dlbh)
+ outb(iobase + com_dlbh, dlbh);
outb(iobase + com_cfcr, CFCR_8BITS);
sp->mcr = inb(iobase + com_mcr);
/*
@@ -3074,9 +3097,11 @@ siocnclose(sp)
*/
siocntxwait();
iobase = siocniobase;
- outb(iobase + com_cfcr, CFCR_DLAB);
- outb(iobase + com_dlbl, sp->dlbl);
- outb(iobase + com_dlbh, sp->dlbh);
+ outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
+ if (sp->dlbl != inb(iobase + com_dlbl))
+ outb(iobase + com_dlbl, sp->dlbl);
+ if (sp->dlbh != inb(iobase + com_dlbh))
+ outb(iobase + com_dlbh, sp->dlbh);
outb(iobase + com_cfcr, sp->cfcr);
/*
* XXX damp oscillations of MCR_DTR and MCR_RTS by not restoring them.
@@ -3128,7 +3153,7 @@ siocncheckc(dev)
if (inb(iobase + com_lsr) & LSR_RXRDY)
c = inb(iobase + com_data);
else
- c = 0;
+ c = -1;
siocnclose(&sp);
splx(s);
return (c);
OpenPOWER on IntegriCloud