Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!agate!howland.reston.ans.net!xlink.net!zib-berlin.de!news.th-darmstadt.de!hotb.RoBIN.de!flinx.RoBIN.de!not-for-mail From: hannes@flinx.RoBIN.de (Hannes Deeken) Newsgroups: comp.os.386bsd.questions Subject: Re: Question about serial driver design in NetBSD Date: 10 Jan 1994 20:11:50 +0100 Organization: Nosimals & Co. Lines: 898 Message-ID: <2gs9a4INNb29@flinx.RoBIN.de> References: <2gne5h$1hq@nwfocus.wa.com> NNTP-Posting-Host: flinx.robin.de Keywords: CLOCAL, calling units, carrier detect sandy@halcyon.com (Jeremy Scofield) writes: >I'm looking for some info from the *BSD developers, or anyone who >understands the design of the serial-port driver in NetBSD. Since this >may not be the best place to ask, I also solicit suggestions on where I >might find an answer. You could try the NetBSD mailing lists (send a 'help' to majordomo@sun-lamp.cs.berkeley.edu). >I've been trying to get a modem attached to my NetBSD 0.9 system, to >use for dialing in and out. Unfortunately, the serial-port driver >isn't making this easy. The man page termios(4) says that an ordinary >open() of the device will block until carrier is detected (provided >that CLOCAL is off). The driver isn't working that way -- getty gets >the device open immediately and writes the prompt, causing a hard echo >loop between the port and the modem. (I know that I can can fix this >particular problem by telling the modem not to echo while in command >mode, but that doesn't solve the other related problems with the >driver.) >Reading through the driver code (com.c), I found what appears to be the >reason -- the line > comsoftCAR |= 1 << unit; /* XXX */ >in the comattach() routine. This makes the driver act as if CD >(carrier detect) is always on. That's the first half of the problem. The second half is in comparam(): > outb(com+com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS /*| IER_EMSC*/); The modem status interrupt never gets enabled. That causes the DCD and CTS(!) lines to be ignored, preventing carrier detection and hardware flowcontrol from working. >I have three questions. > 1. What is that line doing there? The XXX suggests that maybe it > was added as a temporary fix. Is there a problem supporting real > CD on PC serial ports? > 2. I don't see any code in com.c to support Berkeley ``calling > units'' (e.g. cu00 corresponding to tty00), that make it > possible to dial *out* on a port while getty is blocked waiting > for CD. According to an old comp.unix.bsd article by Terry > Lambert, the ``calling unit'' approach is simpler *and* more > robust than the uugetty/O_NDELAY/CLOCAL jazz. So if this is a > Berkeleyism, and it was available in some versions of 386BSD, > and it's technically superior, why isn't it in the NetBSD code? I can't speak for the NetBSD developers, but the serial driver for i386 machines is (modulo some changes due to dynamic tty allocation) the same as in 386BSD 0.1 (as far as I can see). > 3. What are the NetBSD developers planning to do about serial > ports? Will CD be supported, at least on those serial cards > that can do it? Will there be ``calling units'', or are they > moving away from that idea for some reason? (I may do some > whacking on the driver, but I'd like to avoid going off in a > completely different direction.) I don't know what the NetBSD developers plan, but I did "some whacking on the driver" :) and got carrier detection, hardware flowcontrol and calling units working (at least it looks as if :). Thanks to Chris Demetriou, whose "serial driver hacks" [his words :)] for 386BSD enabled me to create the following patches. ------------------------------ snip ------------------------------ #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: README com.c-diff termios.h-diff ttydefaults.h-diff # Wrapped by hannes@flinx.RoBIN.de on Mon Jan 10 20:11:23 1994 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(5325 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XWhat is this? X------------- X XThese patches for the serial driver in NetBSD 0.9 enable carrier detection, Xhardware flowcontrol (at least a bit :), and separate devices for dialing Xin and out ("calling units"). X X XWarranty X-------- XNone. Use at your own risk. If this software causes you headache, peptic Xulcer, loss of money, health or life, don't blame me. XIt works for me. That doesn't mean that it works for you. But you have Xa good chance (IMHO). XThe code may be a hack, ugly and buggy as hell, but in my eyes it is Xat least more functional than the original serial driver in NetBSD 0.9. X X XHow do I use it? X---------------- X XSave the files X /sys/arch/i386/isa/com.c X /sys/sys/termios.h X /sys/sys/ttydefaults.h Xso you can later restore these files in case the patches don't work for you. X(If you want your system to keep 7 databits and even parity as Xdefault mode on your ttys, don't use the patch for ttydefaults.h) X XThen run the patches through 'patch -p0'. If you didn't change the files Xmentioned above before, there should be no rejects. X XNext, go to /usr/src/include and do a 'make install'. This either copies Xthe files from /sys/sys to /usr/include/sys or creates the necessary symlinks. XEither way, the patched header files are accessible in /usr/include/sys Xafterwards. X XIf you want to enable the added features, go to /sys/arch/i386/conf Xand edit the config file for your system. XTo enable the calling unit code, add 'option COM_BIDIR' at the Xbeginning of the file. XFeatures are enabled via the 'flags' field on the 'device' line for Xthe serial ports. The possible values are: X X 0x1 -- set CRTSCTS on this port as default (hardware flowcontrol) X 0x2 -- set CLOCAL on this port as default (open succeeds without carrier) X 0x4 -- this port is used for dial-in and -out. Enable calling unit. X XIf you want several features on one port, add these values. For example, Xthe configuration for my modem port: X X>device com3 at isa? port 0x3e0 tty irq 5 flags 0x5 vector comintr X ^^^^^^^^^ XHere we have hardware flowcontrol [= 0x1] and enabled calling unit [= 0x5]. X X XAfter changing your config file, do a 'config <YOUR-CONFIG>', rebuild Xyour kernel, save your old kernel, install the new one and reboot. X XIf you enabled calling units, you need to create the devices for them. XThe major device number is the same as for the regular tty devices (8 on Xmy system), and the minor number is the minor number for the associated Xtty plus 128. X XExample: X If you enabled the calling unit for com3, you need to create X /dev/cua03 in addition to your already existing /dev/tty03. X Let's take a look at tty03's major and minor number: X X crw------- 1 root 8, 3 Jan 9 18:46 /dev/tty03 X X Ok, the major number is 8, and the minor number is 3. X So the minor number for /dev/cua03 is 131 (3 + 128). X Now you do a 'mknod /dev/cua03 c 8 131' and you're done. X X XNow you can put a getty on /dev/tty03 for dialing in, and dial out Xvia /dev/cua03, without interferring with getty. X XIf you want a 8-bit clean data path into your system, recompile and Xre-install getty (so it uses the new definitions in ttydefaults.h). X X XWhat are these patches adding/changing? X--------------------------------------- X XThe patch to com.c adds separate devices for dial-in and -out, a setable Xdelay in comclose() to ensure that DTR is low long enough to make a modem X(at least mine :) hang up the phone and a way to set CRTSCTS and/or CLOCAL Xon a port permanently (surviving the last close :). XIt changes the existing code to set DTR and RTS when the port speed is Xchanged away from 0 (so you can drop DTR by setting the speed to 0 and get Xit back up when you restore the speed setting) and makes the XTIOCM{GET,SET,BIS,BIC) ioctls use the proper values (TIOCM_{DTR,RTS,CTS,RI,LE}) Xfor getting and setting the port state (as a side effect enabling the RTS Xflowcontrol). X XThe patch to termios.h changes the definition of CRTSCTS to include _both_ Xdirections of flowcontrol (CCTS_OFLOW | CRTS_IFLOW), so the upper layer of Xthe tty system knows when to do RTS handling. X XThe patch to ttydefaults.h changes the default settings for the system X(BEWARE: this affects _all_ tty devices, not only serial ports!) from X7 databits, even parity to 8 databits, no parity. To get a 8-bit clean Xpath into your system, you have to make a new getty binary (so the new Xttydefaults.h gets used). X X XKnown bugs X---------- XI'm not sure whether CTS flowcontrol works right. XSometimes, when using the 'partial open hack' (open port with O_NONBLOCK, Xset CLOCAL, open port without O_NONBLOCK, close first filedescriptor) on Xthe port my modem is on, characters sent by the modem get echoed back and Xforth between the modem and the computer. I was not able to track this down. X X XCredits X------- X XThanks go to Chris Demetriou, whose patches to the com driver in 386BSD Xwere my starting point, and who initially wrote most of the code you find Xin these patches. Without his work, these patches wouldn't exist. X X XContact X------- X XIf you have questions, criticism, bug reports or fixes, or enhancements, Xsend me mail. X XHave fun, XHannes X-- XHans-Christoph Deeken | hannes@flinx.{RoBIN.de,hotb.sub.org} (home) XJungfernstrasse 34 | deeken@iti.informatik.th-darmstadt.de (university) X64291 Darmstadt | IRC: Glenlivet END_OF_FILE if test 5325 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'com.c-diff' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'com.c-diff'\" else echo shar: Extracting \"'com.c-diff'\" \(15191 characters\) sed "s/^X//" >'com.c-diff' <<'END_OF_FILE' X*** /sys/arch/i386/isa/com.c-dist Thu Aug 26 22:46:23 1993 X--- /sys/arch/i386/isa/com.c Mon Jan 10 18:42:48 1994 X*************** X*** 65,73 **** X--- 65,92 ---- X comprobe, comattach, "com" X }; X X+ /* how long to hold DTR down on close (* 1/HZ) */ X+ #ifndef COM_DTRWAIT X+ #define COM_DTRWAIT 50 X+ #endif /* COM_DTRWAIT */ X+ X+ #ifdef COM_BIDIR X+ struct com_bidir_info { X+ int bidir; /* is this unit bidirectional? */ X+ int active; /* is the port active _at all_? */ X+ int active_in; /* is the incoming port in use? */ X+ int active_out; /* is the outgoing port in use? */ X+ int fake_dcd; /* should we fake DCD for now? */ X+ }; X+ X+ struct com_bidir_info com_bdi[NCOM]; X+ #endif /* COM_BIDIR */ X+ X int comsoftCAR; X int com_active; X int com_hasfifo; X+ int com_setlocal; X+ int com_sethwflow; X int ncom = NCOM; X #ifdef COMCONSOLE X int comconsole = COMCONSOLE; X*************** X*** 79,84 **** X--- 98,104 ---- X int commajor; X short com_addr[NCOM]; X struct tty *com_tty[NCOM]; X+ short com_use[NCOM]; X X struct speedtab comspeedtab[] = { X 0, 0, X*************** X*** 110,116 **** X--- 130,144 ---- X extern int kgdb_debug_init; X #endif X X+ #ifdef COM_BIDIR X+ #define COM_UNITMASK 0x7f X+ #define COM_CALLOUTMASK 0x80 X+ X+ #define UNIT(x) (minor(x) & COM_UNITMASK) X+ #define CALLOUT(x) (minor(x) & COM_CALLOUTMASK) X+ #else X #define UNIT(x) (minor(x)) X+ #endif /* COM_BIDIR */ X X comprobe(dev) X struct isa_device *dev; X*************** X*** 132,144 **** X struct tty *tp; X u_char unit; X int port = isdp->id_iobase; X X! unit = isdp->id_unit; X if (unit == comconsole) X DELAY(1000); X com_addr[unit] = port; X com_active |= 1 << unit; X! comsoftCAR |= 1 << unit; /* XXX */ X X /* look for a NS 16550AF UART with FIFOs */ X outb(port+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4); X--- 160,178 ---- X struct tty *tp; X u_char unit; X int port = isdp->id_iobase; X+ int is_bidir = 0; X X! unit = UNIT(isdp->id_unit); X if (unit == comconsole) X DELAY(1000); X com_addr[unit] = port; X com_active |= 1 << unit; X! if (isdp->id_flags & 0x1) /* 0x1 -> CRTSCTS as default */ X! com_sethwflow |= 1 << unit; X! if (isdp->id_flags & 0x2) /* 0x2 -> CLOCAL as default */ X! com_setlocal |= 1 << unit; X! if (isdp->id_flags & 0x4) /* 0x4 -> separate tty/cua devices */ X! is_bidir = 1; X X /* look for a NS 16550AF UART with FIFOs */ X outb(port+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4); X*************** X*** 149,154 **** X--- 183,190 ---- X } X X outb(port+com_ier, 0); X+ inb(port+com_msr); /* Clear delta bits in MSR */ X+ inb(port+com_lsr); /* Clear error bits in LSR */ X outb(port+com_mcr, 0 | MCR_IENABLE); X #ifdef KGDB X if (kgdb_dev == makedev(commajor, unit)) { X*************** X*** 176,181 **** X--- 212,233 ---- X comconsinit = 0; X comsoftCAR |= (1 << unit); X } X+ X+ /* X+ * Reset usage counter X+ */ X+ com_use[unit] = 0; X+ X+ #ifdef COM_BIDIR X+ /* X+ * if bidirectional ports possible, initialize the bidir port info; X+ */ X+ com_bdi[unit].bidir = is_bidir; X+ com_bdi[unit].active = 0; X+ com_bdi[unit].active_in = com_bdi[unit].active_out = 0; X+ com_bdi[unit].fake_dcd = 0; X+ #endif /* COM_BIDIR */ X+ X return (1); X } X X*************** X*** 183,198 **** X comopen(dev_t dev, int flag, int mode, struct proc *p) X { X register struct tty *tp; X! register int unit; X int error = 0; X X- unit = UNIT(dev); X if (unit >= NCOM || (com_active & (1 << unit)) == 0) X return (ENXIO); X if(!com_tty[unit]) { X tp = com_tty[unit] = ttymalloc(); X } else X tp = com_tty[unit]; X tp->t_oproc = comstart; X tp->t_param = comparam; X tp->t_dev = dev; X--- 235,344 ---- X comopen(dev_t dev, int flag, int mode, struct proc *p) X { X register struct tty *tp; X! register int unit = UNIT(dev); X! #ifdef COM_BIDIR X! register int callout = CALLOUT(dev); X! register int com = com_addr[unit]; X! #endif /* COM_BIDIR */ X int error = 0; X X if (unit >= NCOM || (com_active & (1 << unit)) == 0) X return (ENXIO); X+ X+ #ifdef COM_BIDIR X+ /* if it's a callout device, and bidir not possible on that dev, die */ X+ if (callout && !(com_bdi[unit].bidir)) X+ return (ENXIO); X+ #endif /* COM_BIDIR */ X+ X if(!com_tty[unit]) { X tp = com_tty[unit] = ttymalloc(); X } else X tp = com_tty[unit]; X+ X+ /* increment usage counter */ X+ (void) spltty(); X+ com_use[unit] ++; X+ X+ #ifdef COM_BIDIR X+ X+ bidir_open_top: X+ X+ /* if it's bidirectional, we've gotta deal with it... */ X+ if (com_bdi[unit].bidir) { X+ if (callout) { X+ if (com_bdi[unit].active_in) { X+ /* it's busy. die */ X+ (void) spl0(); X+ return (EBUSY); X+ } else { X+ /* it's ours. lock it down, and set it up */ X+ com_bdi[unit].active_out = 1; X+ com_bdi[unit].fake_dcd = 1; X+ } X+ } else { X+ if (com_bdi[unit].active_out) { X+ /* it's busy, outgoing. wait, if possible */ X+ if (flag & O_NONBLOCK) { X+ /* can't wait; bail */ X+ (void) spl0(); X+ return (EBUSY); X+ } else { X+ /* wait for it... */ X+ error = tsleep((caddr_t)&com_bdi[unit].active_out, X+ TTIPRI|PCATCH, X+ "comoth", X+ 0); X+ /* if there was an error, take off. */ X+ if (error != 0) { X+ (void) spl0(); X+ return (error); X+ } X+ /* else take it from the top */ X+ goto bidir_open_top; X+ } X+ } else if (commctl(dev, 0, DMGET) & MSR_DCD) { X+ /* there's a carrier on the line; we win */ X+ com_bdi[unit].active_in = 1; X+ com_bdi[unit].fake_dcd = 0; X+ } else { X+ /* there is no carrier on the line */ X+ if (flag & O_NONBLOCK) { X+ /* can't wait; let it open */ X+ com_bdi[unit].active_in = 1; X+ com_bdi[unit].fake_dcd = 0; X+ } else { X+ /* put DTR & RTS up */ X+ commctl(dev, MCR_DTR | MCR_RTS, DMBIS); X+ outb(com+com_ier, X+ inb(com+com_ier) | IER_EMSC); X+ X+ /* wait for it... */ X+ error = tsleep((caddr_t)&com_bdi[unit].active_in, X+ TTIPRI|PCATCH, X+ "comdcd", X+ 0); X+ X+ /* if not active, turn DTR & RTS off */ X+ if (!com_bdi[unit].active) X+ commctl(dev, MCR_DTR | MCR_RTS, DMBIC); X+ X+ /* if there was an error, take off. */ X+ if (error != 0) { X+ (void) spl0(); X+ return (error); X+ } X+ /* else take it from the top */ X+ goto bidir_open_top; X+ } X+ } X+ } X+ } X+ X+ com_bdi[unit].active = 1; X+ #endif /* COM_BIDIR */ X+ (void) spl0(); X+ X tp->t_oproc = comstart; X tp->t_param = comparam; X tp->t_dev = dev; X*************** X*** 202,208 **** X if (tp->t_ispeed == 0) { X tp->t_iflag = TTYDEF_IFLAG; X tp->t_oflag = TTYDEF_OFLAG; X! tp->t_cflag = TTYDEF_CFLAG; X tp->t_lflag = TTYDEF_LFLAG; X tp->t_ispeed = tp->t_ospeed = comdefaultrate; X } X--- 348,356 ---- X if (tp->t_ispeed == 0) { X tp->t_iflag = TTYDEF_IFLAG; X tp->t_oflag = TTYDEF_OFLAG; X! tp->t_cflag = TTYDEF_CFLAG X! | (com_sethwflow & (1 << unit) ? CRTSCTS : 0) X! | (com_setlocal & (1 << unit) ? CLOCAL : 0); X tp->t_lflag = TTYDEF_LFLAG; X tp->t_ispeed = tp->t_ospeed = comdefaultrate; X } X*************** X*** 212,232 **** X return (EBUSY); X (void) spltty(); X (void) commctl(dev, MCR_DTR | MCR_RTS, DMSET); X if ((comsoftCAR & (1 << unit)) || (commctl(dev, 0, DMGET) & MSR_DCD)) X tp->t_state |= TS_CARR_ON; X! while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && X! (tp->t_state & TS_CARR_ON) == 0) { X! tp->t_state |= TS_WOPEN; X! if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, X! ttopen, 0)) X! break; X! } X (void) spl0(); X if (error == 0) X error = (*linesw[tp->t_line].l_open)(dev, tp); X return (error); X } X X /*ARGSUSED*/ X comclose(dev, flag, mode, p) X dev_t dev; X--- 360,405 ---- X return (EBUSY); X (void) spltty(); X (void) commctl(dev, MCR_DTR | MCR_RTS, DMSET); X+ #ifdef COM_BIDIR X+ if ((comsoftCAR & (1 << unit)) X+ || com_bdi[unit].fake_dcd X+ || (commctl(dev, 0, DMGET) & MSR_DCD)) X+ #else /* COM_BIDIR */ X if ((comsoftCAR & (1 << unit)) || (commctl(dev, 0, DMGET) & MSR_DCD)) X+ #endif /* COM_BIDIR */ X tp->t_state |= TS_CARR_ON; X! else X! tp->t_state &=~ TS_CARR_ON; X! #ifdef COM_BIDIR X! if (!com_bdi[unit].bidir && !(flag & O_NONBLOCK)) X! #else /* COM_BIDIR */ X! if (!(flag & O_NONBLOCK)) X! #endif /* COM_BIDIR */ X! while ((tp->t_cflag&CLOCAL) == 0 && X! (tp->t_state & TS_CARR_ON) == 0) { X! tp->t_state |= TS_WOPEN; X! if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, X! TTIPRI | PCATCH, ttopen, 0)) X! break; X! } X (void) spl0(); X+ X+ #ifdef COM_BIDIR X+ /* wakeup sleepers */ X+ wakeup((caddr_t) &com_bdi[unit].active_in); X+ #endif /* COM_BIDIR */ X+ X if (error == 0) X error = (*linesw[tp->t_line].l_open)(dev, tp); X return (error); X } X X+ void comclose_wakeup(arg) X+ caddr_t arg; X+ { X+ wakeup(arg); X+ } X+ X /*ARGSUSED*/ X comclose(dev, flag, mode, p) X dev_t dev; X*************** X*** 236,241 **** X--- 409,415 ---- X register struct tty *tp; X register com; X register int unit; X+ int s, error; X X unit = UNIT(dev); X com = com_addr[unit]; X*************** X*** 249,258 **** X outb(com+com_ier, 0); X if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || X (tp->t_state&TS_ISOPEN) == 0) X! (void) commctl(dev, 0, DMSET); X ttyclose(tp); X! ttyfree(tp); X! com_tty[unit] = (struct tty *)NULL; X return(0); X } X X--- 423,459 ---- X outb(com+com_ier, 0); X if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || X (tp->t_state&TS_ISOPEN) == 0) X! (void) commctl(dev, MCR_DTR | MCR_RTS, DMBIC); X ttyclose(tp); X! X! do { X! timeout(comclose_wakeup, (caddr_t)&com_bdi[unit].active, X! COM_DTRWAIT); X! error = tsleep((caddr_t)&com_bdi[unit].active, TTIPRI|PCATCH, X! "comclose", 0); X! } while (error == ERESTART); X! X! /* up spl */ X! s = spltty(); X! #ifdef COM_BIDIR X! /* clear in, out, fake_dcd, lower spl */ X! com_bdi[unit].active = com_bdi[unit].active_in = X! com_bdi[unit].active_out = 0; X! com_bdi[unit].fake_dcd = 0; X! X! /* wakeup sleepers who are waiting for out to finish */ X! wakeup((caddr_t) &com_bdi[unit].active_out); X! #endif /* COM_BIDIR */ X! X! /* decrement usage counter, free tty if possible */ X! if(--com_use[unit] == 0) { X! #ifdef broken /* session holds a ref to the tty; can't deallocate */ X! ttyfree(tp); X! com_tty[unit] = (struct tty *)NULL; X! #endif X! } X! (void) splx(s); X! X return(0); X } X X*************** X*** 392,404 **** X tp = com_tty[unit]; X stat = inb(com+com_msr); X if ((stat & MSR_DDCD) && (comsoftCAR & (1 << unit)) == 0) { X! if (stat & MSR_DCD) X (void)(*linesw[tp->t_line].l_modem)(tp, 1); X! else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0) X outb(com+com_mcr, X inb(com+com_mcr) & ~(MCR_DTR | MCR_RTS) | MCR_IENABLE); X! } else if ((stat & MSR_DCTS) && (tp->t_state & TS_ISOPEN) && X! (tp->t_flags & CRTSCTS)) { X /* the line is up and we want to do rts/cts flow control */ X if (stat & MSR_CTS) { X tp->t_state &=~ TS_TTSTOP; X--- 593,616 ---- X tp = com_tty[unit]; X stat = inb(com+com_msr); X if ((stat & MSR_DDCD) && (comsoftCAR & (1 << unit)) == 0) { X! if (stat & MSR_DCD) { X! #ifdef COM_BIDIR X! if ((*linesw[tp->t_line].l_modem)(tp, 1)) X! /* tty layer has ack'd carrier up, so stop faking */ X! com_bdi[unit].fake_dcd = 0; X! X! /* wakeup sleepers on active_in, who X! * are waiting for DCD X! */ X! wakeup((caddr_t) &com_bdi[unit].active_in); X! #else X (void)(*linesw[tp->t_line].l_modem)(tp, 1); X! #endif /* COM_BIDIR */ X! } else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0) X outb(com+com_mcr, X inb(com+com_mcr) & ~(MCR_DTR | MCR_RTS) | MCR_IENABLE); X! } else if ((stat & MSR_DCTS) && (tp != NULL) X! && (tp->t_state & TS_ISOPEN) && (tp->t_flags & CRTSCTS)) { X /* the line is up and we want to do rts/cts flow control */ X if (stat & MSR_CTS) { X tp->t_state &=~ TS_TTSTOP; X*************** X*** 408,413 **** X--- 620,635 ---- X } X } X X+ static X+ int tiocm_xxx2mcr(data) X+ register data; X+ { X+ register m = 0; X+ if (data & TIOCM_DTR) m |= MCR_DTR; X+ if (data & TIOCM_RTS) m |= MCR_RTS; X+ return m; X+ } X+ X comioctl(dev, cmd, data, flag) X dev_t dev; X caddr_t data; X*************** X*** 445,464 **** X break; X X case TIOCMSET: X! (void) commctl(dev, *(int *)data, DMSET); X break; X X case TIOCMBIS: X! (void) commctl(dev, *(int *)data, DMBIS); X break; X X case TIOCMBIC: X! (void) commctl(dev, *(int *)data, DMBIC); X break; X X case TIOCMGET: X! *(int *)data = commctl(dev, 0, DMGET); X! break; X X default: X return (ENOTTY); X--- 667,705 ---- X break; X X case TIOCMSET: X! case TIOCMODS: X! (void) commctl(dev, tiocm_xxx2mcr(*(int *)data), DMSET); X break; X X case TIOCMBIS: X! (void) commctl(dev, tiocm_xxx2mcr(*(int *)data), DMBIS); X break; X X case TIOCMBIC: X! (void) commctl(dev, tiocm_xxx2mcr(*(int *)data), DMBIC); X break; X X case TIOCMGET: X! case TIOCMODG: X! { X! register m = commctl(dev, 0, DMGET), bits = 0; X! X! if (m & MCR_DTR) bits |= TIOCM_DTR; X! if (m & MCR_RTS) bits |= TIOCM_RTS; X! X! if ((m & MSR_DCD) X! #ifdef COM_BIDIR X! || com_bdi[unit].fake_dcd X! #endif /* COM_BIDIR */ X! ) bits |= TIOCM_CD; X! X! if (m & MSR_CTS) bits |= TIOCM_CTS; X! if (m & MSR_DSR) bits |= TIOCM_DSR; X! if (m & (MSR_RI|MSR_TERI)) bits |= TIOCM_RI; X! if (inb(com+com_ier)) bits |= TIOCM_LE; X! *(int *)data = bits; X! break; X! } X X default: X return (ENOTTY); X*************** X*** 476,494 **** X int ospeed = ttspeedtab(t->c_ospeed, comspeedtab); X X /* check requested parameters */ X! if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed)) X return(EINVAL); X /* and copy to tty */ X- tp->t_ispeed = t->c_ispeed; X tp->t_ospeed = t->c_ospeed; X tp->t_cflag = cflag; X X com = com_addr[unit]; X! outb(com+com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS /*| IER_EMSC*/); X if (ospeed == 0) { X! (void) commctl(unit, 0, DMSET); /* hang up line */ X return(0); X! } X outb(com+com_cfcr, inb(com+com_cfcr) | CFCR_DLAB); X outb(com+com_data, ospeed & 0xFF); X outb(com+com_ier, ospeed >> 8); X--- 717,740 ---- X int ospeed = ttspeedtab(t->c_ospeed, comspeedtab); X X /* check requested parameters */ X! if (ospeed < 0 || (t->c_ospeed && t->c_ispeed X! && t->c_ispeed != t->c_ospeed)) X return(EINVAL); X /* and copy to tty */ X tp->t_ospeed = t->c_ospeed; X+ tp->t_ispeed = t->c_ispeed; X tp->t_cflag = cflag; X X com = com_addr[unit]; X! outb(com+com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC); X if (ospeed == 0) { X! /* hang up line */ X! (void) commctl(unit, MCR_DTR | MCR_RTS, DMBIC); X return(0); X! } else X! /* assert DTR and RTS */ X! (void) commctl(unit, MCR_DTR | MCR_RTS, DMBIS); X! X outb(com+com_cfcr, inb(com+com_cfcr) | CFCR_DLAB); X outb(com+com_data, ospeed & 0xFF); X outb(com+com_ier, ospeed >> 8); END_OF_FILE if test 15191 -ne `wc -c <'com.c-diff'`; then echo shar: \"'com.c-diff'\" unpacked with wrong size! fi # end of 'com.c-diff' fi if test -f 'termios.h-diff' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'termios.h-diff'\" else echo shar: Extracting \"'termios.h-diff'\" \(832 characters\) sed "s/^X//" >'termios.h-diff' <<'END_OF_FILE' X*** /sys/sys/termios.h-dist Sun Jun 6 00:40:26 1993 X--- /sys/sys/termios.h Thu Aug 26 20:13:19 1993 X*************** X*** 136,143 **** X #define CLOCAL 0x00008000 /* ignore modem status lines */ X #ifndef _POSIX_SOURCE X #define CCTS_OFLOW 0x00010000 /* CTS flow control of output */ X- #define CRTSCTS CCTS_OFLOW /* ??? */ X #define CRTS_IFLOW 0x00020000 /* RTS flow control of input */ X #define MDMBUF 0x00100000 /* flow control output via Carrier */ X #endif X X--- 136,143 ---- X #define CLOCAL 0x00008000 /* ignore modem status lines */ X #ifndef _POSIX_SOURCE X #define CCTS_OFLOW 0x00010000 /* CTS flow control of output */ X #define CRTS_IFLOW 0x00020000 /* RTS flow control of input */ X+ #define CRTSCTS (CCTS_OFLOW | CRTS_IFLOW) /* ??? */ X #define MDMBUF 0x00100000 /* flow control output via Carrier */ X #endif X END_OF_FILE if test 832 -ne `wc -c <'termios.h-diff'`; then echo shar: \"'termios.h-diff'\" unpacked with wrong size! fi # end of 'termios.h-diff' fi if test -f 'ttydefaults.h-diff' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ttydefaults.h-diff'\" else echo shar: Extracting \"'ttydefaults.h-diff'\" \(807 characters\) sed "s/^X//" >'ttydefaults.h-diff' <<'END_OF_FILE' X*** /sys/sys/ttydefaults.h-dist Thu May 20 18:23:18 1993 X--- /sys/sys/ttydefaults.h Thu Jan 6 16:41:58 1994 X*************** X*** 44,53 **** X /* X * Defaults on "first" open. X */ X! #define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY) X #define TTYDEF_OFLAG (OPOST | ONLCR | OXTABS) X #define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL) X! #define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL) X #define TTYDEF_SPEED (B9600) X X /* X--- 44,53 ---- X /* X * Defaults on "first" open. X */ X! #define TTYDEF_IFLAG (BRKINT | ICRNL | IMAXBEL | IXON | IXANY) X #define TTYDEF_OFLAG (OPOST | ONLCR | OXTABS) X #define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL) X! #define TTYDEF_CFLAG (CREAD | CS8 | HUPCL) X #define TTYDEF_SPEED (B9600) X X /* END_OF_FILE if test 807 -ne `wc -c <'ttydefaults.h-diff'`; then echo shar: \"'ttydefaults.h-diff'\" unpacked with wrong size! fi # end of 'ttydefaults.h-diff' fi echo shar: End of shell archive. exit 0 ------------------------------ snap ------------------------------ Have fun, Hannes -- Hans-Christoph Deeken | hannes@flinx.{RoBIN.de,hotb.sub.org} (home) Jungfernstrasse 34 | deeken@iti.informatik.th-darmstadt.de (university) 64291 Darmstadt | IRC: Glenlivet