Return to BSD News archive
Path: euryale.cc.adfa.oz.au!newshost.carno.net.au!harbinger.cc.monash.edu.au!nntp.coast.net!howland.erols.net!surfnet.nl!news.tue.nl!news.IAEhv.nl!adv.IAEhv.nl!adv.IAEhv.nl!not-for-mail From: devet@adv.IAEhv.nl (Arjan de Vet) Newsgroups: comp.unix.bsd.freebsd.misc,alt.comp.periphs.mainboard.asus Subject: Re: Problem with com ports on ASUS P55T2P4 (solution) Date: 30 Oct 1996 21:56:57 +0100 Organization: Internet Access Eindhoven, the Netherlands Lines: 113 Message-ID: <558fep$18l@adv.IAEhv.nl> References: <5513ro$2i8@bpeters.uucp> NNTP-Posting-Host: adv.iaehv.nl Xref: euryale.cc.adfa.oz.au comp.unix.bsd.freebsd.misc:30248 alt.comp.periphs.mainboard.asus:27021 In article <5513ro$2i8@bpeters.uucp>, Bruce Peterson <peterson@mail.cyberoptics.com> wrote: >I just purchased an ASUS P55T2P4 motherboard (P120) for use with FreeBSD >2.1.5. I connected my modem (28.8kbps, 38400 dte) to a com port on the >motherboard, but uucp gave up about 100k into each call, with an error >message saying "Too many protocol 'i' errors." The received packets arrive >continuously, and the acks are transmitted regularly, as observed from modem >LED activity. The second com port on the motherboard exhibited the same >problem. I put an old ISA i/o board (with a 16550 UART) into the system, >and uucp went for an hour and a half with no errors. The only other boards >in the system are an ISA Tseng ET4000 VGA board and an Adaptec 1542 SCSI >adapter. > >Is there a known problem with the UART design on this motherboard, or >could this be a defective unit? Yes, I had exactly the same. The following kernel patch for sys/i386/isa/sio.c fixes it. Arjan --- sio.c.2.1.5 Sat Apr 13 17:01:25 1996 +++ sio.c Tue Oct 15 21:38:27 1996 @@ -443,7 +443,7 @@ * 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); @@ -1601,6 +1601,8 @@ int cflag; struct com_s *com; int divisor; + u_char dlbh; + u_char dlbl; int error; Port_t iobase; int s; @@ -1712,8 +1714,18 @@ 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); if (!(tp->t_state & TS_TTSTOP)) @@ -2115,6 +2127,8 @@ struct siocnstate *sp; { int divisor; + u_char dlbh; + u_char dlbl; Port_t iobase; /* @@ -2127,12 +2141,22 @@ 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); /* @@ -2154,9 +2178,11 @@ */ 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.