Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!mit-eddie!uw-beaver!tektronix!teklds!copper!stevesu From: stevesu@copper.UUCP Newsgroups: comp.unix.wizards,comp.bugs.4bsd Subject: Re: lack of modem control on MVAX-II with DHV running 4.3bsd Message-ID: <1075@copper.TEK.COM> Date: Fri, 29-May-87 00:54:20 EDT Article-I.D.: copper.1075 Posted: Fri May 29 00:54:20 1987 Date-Received: Sat, 30-May-87 08:03:08 EDT References: <312@asic001.UUCP> Organization: Tektronix Inc., Beaverton, Or. Lines: 227 Xref: utgpu comp.unix.wizards:2283 comp.bugs.4bsd:350 Summary: three ways... In article <312@asic001.UUCP>, ron@asic001.UUCP (Ron Werther) writes: > Guy Middleton, University of Waterloo MFCF/ICR, gamiddleton@watmath writes: > >We have a Microvax-II with a DHV11. > >However, when the system is running, the DHV completely ignores modem > >controls (DTR, CTS, RTS and DCD). > > this situation is very inconvinient because you never can detect > if a printer or plotter is switched off. > Because the systems thinks there is a working device on > that tty-line, your output get lost. > > I think someting that could cause this is the initiation of the > flags from the DHV and DZQ devices in the configuration file. > > A second question: is it possible to fix this without rebuilding a new > kernel ? I've done some work with MicroVAX II's and Ultrix 1.2, and I know of three (possibly interrelated) conditions affecting modem control on tty lines, specifically on DHV's. Unfortunately, I don't have root access to any of the Ultrix MicroVAXes around here at the moment, so I can't try any of this out for you. Modem state can be controlled by: 1. the flags word in the config file 2. /etc/ttys 3. new ioctl's that DEC has defined in Ultrix Although the dhu(4) man page (which also applies to the dhv) states that the "flags can be specified for a DHU-11 to say that a line is not properly connected, and that the line should be treated as hard-wired with carrier always present," implying that somebody understood that "real" carrier is a Good Thing, MicroVAXes (both Ultrix and VMS) seem to be shipped "broken," with soft carrier enabled on all lines. That is, the standard Ultrix MicroVAX configuration file (the one that says "Seahorse and Mayflower" at the top) includes the lines device dhu0 at uba0 csr 0160440 flags 0xff vector dhurint dhuxint device dhu1 at uba0 csr 0160460 flags 0xff vector dhurint dhuxint with the "flags 0xff" conspiring to turn off true carrier detection on all lines. Even when I rebuilt the kernel for this machine, after changing the lines to device dhu0 at uba0 csr 0160440 vector dhurint dhuxint device dhu1 at uba0 csr 0160460 vector dhurint dhuxint modem controls still didn't work (disconnected terminals stayed logged in, for instance). It appears that the modem/nomodem specification in /etc/ttys can override the compiled-in kernel flags. (Actually, this is nice, since it may mean you don't have to recompile to change the settings in either direction.) The /etc/ttys distributed with Ultrix contains lines like ttyh0 "/etc/getty std.9600" vt100 on nomodem After rebuilding the kernel, I had to change these lines to ttyh0 "/etc/getty std.9600" vt100 on modem before modem controls were properly interpreted. After all of this, I notice that the people using the system have changed the lines in /etc/ttys back to "nomodem". Apparently they had some cabling problems. From my own experience, then, I can fill in three of the slots in the following decision matrix: | configuration file /etc/ttys | flags 0xff no flags --------------------------------------------- nomodem | no modem no modem modem | ??? correct modem What I don't know is whether you can turn modem controls on, without recompiling, simply by setting "modem" in /etc/ttys. I suspect that you can, and that /etc/ttys completely overrides the kernel configuration, but I haven't tried it or inspected source code, so I can't be sure. The final wrinkle is the new Ultrix tty ioctl's (these are from 1.2; I don't know if they were in earlier versions). This is from : #define TIOCNMODEM _IOW(t, 99, int) /* ignore modem status */ #define TIOCMODEM _IOW(t, 98, int) /* look at modem status */ #define TIOCWONLINE _IO(t, 97) /* wait for device to come * on line */ #define TIOCNCAR _IO(t, 96) /* ignore soft carrier */ #define TIOCCAR _IO(t, 95) /* dont ignore soft carrier */ I suspect that the modem/nomodem code in init plays with these ioctls, and that they override the kernel flags. This information may not help you (to enable modem control without rebuilding a kernel) if 1. the line is turned off in /etc/ttys, since the modem/nomodem distinction may not be dealt with in that case. (This would be a problem for a printer or plotter connected to a nonlogin line.) It might be possible to manually turn modem control back on, by writing a little program (hypothetical program attached) to do the ioctl's. However, this might not work if 2. you're not using Ultrix 1.2 or above, since I don't know if these ioctl's (or similar ones) have been implemented elsewhere. Of course (as Chris Torek will tell you if I don't) you can always use adb on the kernel to patch the flags without rebuilding. Flame on: Why do all of these systems have soft carrier as the default? A MicroVAX is a _r_e_a_l _c_o_m_p_u_t_e_r, not some brain-damaged toy PC, and it's got male (DTE) connectors on the back, as it should (even though that makes it a bit tougher to connect terminals directly) so why do you have to jump through hoops and batter it over the head several ways to convince it to listen for carrier? It's obviously not an accident, but a deliberate plot on somebody's part: the problem exists in 4.3bsd, Ultrix, _a_n_d MicroVMS. (This is net.unix.wizards, so I won't belabor the point, but I've got to say SET TERM/PERM/MODEM on all of my DHV ports on a VMS MicroVAX. I suppose I could go into SYSGEN and change TTY_DEFCHAR. Cripes.) It's really not hard to wire terminals so that carrier works, whether you're using modems or not, and there are significant advantages. When you turn your terminal off (and many people do this, forgetting to log out) you get logged out, and your account isn't left waiting for somebody else to turn the terminal back on and snoop around. You have the option of yanking the RS232 line to kill runaway programs when ^C and ^\ aren't working. (No :-), I do this all the time.) Steve Summit stevesu@copper.tek.com Appendix A: How to wire terminals so that silly soft carrier games don't have to be played in the terminal driver software: computer Null modem cable terminal (DTE) (DCE TO DCE) (DTE) 2 > >------------------------------------< < 3 3 > >------------------------------------< < 2 4 > >-+ +-< < 4 5 > >-+ +-< < 5 6 > >-+----------------------------------< < 20 8 > >-+ +-< < 6 20 > >----------------------------------+-< < 8 7 > >------------------------------------< < 7 If that crude ASCII representation is unclear (and it is), the null modem cable is supposed to: swap pins 2 and 3 short together pins 4 and 5 at each end send pin 20 to both pins 6 and 8 at the other end, in both directions send pin 7 straight through Most people understand the "swap pins 2 and 3" part, since you've got to get that right in order to talk at all. If the computer port has modem control enabled (and I claim it should), it is listening for a signal on pin 6 (DSR, Data Set Ready) or pin 8 (DCD, Data Carrier Detect) before it will talk. The terminal is emitting DTR (Data Terminal Ready) on pin 20, so that gets sent to both inputs. The same thing is done in the other direction, because the computer raises DTR on its end when it's okay to log in, and some terminals (notably NEC spinwriters) won't talk unless they hear DSR and/or DCD. Appendix B: sample program for manually turning on modem control (this might be what init does when /etc/ttys specifies "modem"): #include #include main(argc, argv) int argc; char *argv[]; { int fd; int err = 0; if(argc != 2) { fprintf(stderr, "usage: modem /dev/device\n"); exit(1); } if((fd = open(argv[1], 2)) < 0) { fprintf(stderr, "modem: can't open %s: ", argv[1]); perror(""); exit(1); } if(ioctl(fd, TIOCMODEM, (struct sgttyb *)NULL) < 0) { fprintf(stderr, "modem: can't set TIOCMODEM: "); perror(""); err = 1; } if(ioctl(fd, TIOCNCAR, (struct sgttyb *)NULL) < 0) { fprintf(stderr, "modem: can't set TIOCNCAR: "); perror(""); err = 1; } exit(err); } I think this program will have to be run as root. I haven't tested it, so please don't flame me if it doesn't work. I'm presenting it as an example.