Subject: dhu.c should support the DHQ11 with 8 lines in DHU11 mode (#493) Index: src/sys/conf/{config,GENERIC}, src/sys/pdpuba/{dhu.c,dhv.c,dh.c,dz.c}, src/libexec/getty/gettytab.h src/libexec/telnetd/telnetd.c Description: Several serial drivers don't understand what ANYP means and enable parity even though they shouldn't. Minor errors in gettytab.h, telnetd really should turn on PASS8 when the BINARY option is used 1. The dhu driver assumes it controls 16 lines, which is correct for a real DHU11. The DHQ11 can be configured to behave exactly like either a DHV11 or a DHU11, but it only has 8 lines. It would be useful to be able to configure the dhu driver to only support 8 lines for use with the DHQ11. 2. ANYP is defined as (EVENP|ODDP) in sys/ioctl.h, and it means "accept any parity, send none". With the notable exception of dhv.c (and cons.c, where this is hardwired in the controller), all our serial drivers just check for EVENP or ODDP and set a flag in the line parameter register accordingly. 3. While trying to get 8bit I/O with a VT320 connected to a DHQ11 to work, I spotted two minor errors in gettytab.h. 4. When telnetd is using the BINARY option, it only sets the RAW flag, but it really should also set PASS8. Repeat-By: 1. Configure a system with a 8-line DHQ11 set to DHU11 mode. The driver allocates 16 lines, even though the hardware has only 8. 2. Connect a VT220 or any other terminal supporting 8bit characters to a DHQ11 or DZ11. Configure the terminal for 8N1 and 8bit characters, and set up a gettytab entry that sets the "np" flag to enable PASS8. Observe that when you log in, getty(8) drives the line in 8N1, but the login prompt looks odd: Páóóworä: When login(1) starts and isn't configured to do otherwise by a special "login" gettytab entry, before it prints the password prompt it clears PASS8 but keeps ANYP from the default gettytab entry. On a DHQ11 in DHU11 mode, the line is configured as 7E1 because PASS8 is no longer set and ANYP is actually EVENP|ODDP, and only EVENP is checked by the dhu driver. (The dz and dh drivers enable odd parity as that's what the corresponding bit in LPAR does on these controllers. Oddly enough, the dhv driver has been fixed some time before to understand that ANYP means no parity on output.) After a successful login, login(1) restores the original tty flags, restoring PASS8 again and everything looks good again. 3. Code inspection: The definitions for APset, EPset, and OPset are all the same, but it doesn't look like they should be. 4. Telnet into a 2.11BSD system enabling binary mode: $ telnet -8 x.x.x.x Run stty to check the tty flags, pass8 isn't set. NOTE: login is NOT recompiled. While gettytab.h is used the OPset and APset flags are only used in getty/main.c and not by gettytab.c or login.c Fix: Update submitted by Hans Rosenfeld Minor changes/Editing/Formatting by bugs@2bsd.com ;) Cut where indicated and save to a file (/tmp/493.patch). Then: cd / patch -p0 < /tmp/493.patch cd /usr/src/libexec/getty make install make clean cd /usr/src/libexec/telnetd make install make clean ------------The remainder is to be done manually-------------- cd /sys/conf ed YOURKERNEL <> dhu.h For a DHQ11 configured to run as a DHU echo "#define NHDUL 8" >> dhu.h If you have configured the kernel with: DHQ11, DHU11, DHV11, DZ11, or DH11 you want to rebuild your kernel to get the drivers' 8bit updates. cd /sys/YOURKERNEL make install -m 644 -o root -g wheel unix / install -m 644 -o root -g wheel netnix / This and previous updates to 2.11BSD are available at the following locations: ftp://ftp.dfupdate.se/pub/pdp11/2.11BSD https://www.tuhs.org/Archive/Distributions/UCB/2.11BSD/Patches/ ftp://ftp.2bsd.com/2.11BSD http://www.2bsd.com/2.11BSD/ ---------------------------cut here-------------------- *** ./usr/src/sys/pdpuba/dhv.c.old Sat May 31 18:15:26 1997 --- ./usr/src/sys/pdpuba/dhv.c Tue Aug 12 18:38:33 2025 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dhv.c 2.4 (2.11BSD 2.11BSD) 1997/5/31 */ /* --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dhv.c 2.5 (2.11BSD) 2025/8/11 */ /* *************** *** 471,491 **** goto out; } lpar = (dhv_speeds[tp->t_ospeed]<<12) | (dhv_speeds[tp->t_ispeed]<<8); if (tp->t_ispeed == B134) ! lpar |= DHV_LP_BITS6|DHV_LP_PENABLE; ! else if (tp->t_flags & (RAW|LITOUT|PASS8)) lpar |= DHV_LP_BITS8; else ! lpar |= DHV_LP_BITS7|DHV_LP_PENABLE; ! if (tp->t_flags&EVENP) ! lpar |= DHV_LP_EPAR; ! if ((tp->t_flags & EVENP) && (tp->t_flags & ODDP)) ! { ! /* hack alert. assume "allow both" means don't care */ ! /* trying to make xon/xoff work with evenp+oddp */ ! lpar |= DHV_LP_BITS8; ! lpar &= ~DHV_LP_PENABLE; ! } if ((tp->t_ospeed) == B110) lpar |= DHV_LP_TWOSB; addr->dhvcsr = DHV_SELECT(unit) | DHV_IE; --- 471,486 ---- goto out; } lpar = (dhv_speeds[tp->t_ospeed]<<12) | (dhv_speeds[tp->t_ispeed]<<8); + if ((tp->t_flags & (EVENP|ODDP)) == EVENP) + lpar |= DHV_LP_PENABLE|DHV_LP_EPAR; + else if ((tp->t_flags & (EVENP|ODDP)) == ODDP) + lpar |= DHV_LP_PENABLE; if (tp->t_ispeed == B134) ! lpar |= DHV_LP_BITS6; ! else if ((tp->t_flags & (RAW|LITOUT|PASS8)) || !(lpar & DHV_LP_PENABLE)) lpar |= DHV_LP_BITS8; else ! lpar |= DHV_LP_BITS7; if ((tp->t_ospeed) == B110) lpar |= DHV_LP_TWOSB; addr->dhvcsr = DHV_SELECT(unit) | DHV_IE; *** ./usr/src/sys/pdpuba/dh.c.old Thu Jun 12 23:37:55 1997 --- ./usr/src/sys/pdpuba/dh.c Tue Aug 12 18:38:57 2025 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dh.c 1.5 (2.11BSD GTE) 1997/6/12 */ /* --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dh.c 1.6 (2.11BSD) 2025/8/11 */ /* *************** *** 413,426 **** goto out; } lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6); if ((tp->t_ispeed) == B134) lpar |= BITS6|PENABLE|HDUPLX; ! else if (tp->t_flags & (RAW|LITOUT|PASS8)) lpar |= BITS8; else ! lpar |= BITS7|PENABLE; ! if ((tp->t_flags&EVENP) == 0) ! lpar |= OPAR; if ((tp->t_ospeed) == B110) lpar |= TWOSB; addr->dhlpr = lpar; --- 413,428 ---- goto out; } lpar = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6); + if ((tp->t_flags & (EVENP|ODDP)) == ODDP) + lpar |= PENABLE|OPAR; + else if ((tp->t_flags & (EVENP|ODDP)) == EVENP) + lpar |= PENABLE; if ((tp->t_ispeed) == B134) lpar |= BITS6|PENABLE|HDUPLX; ! else if ((tp->t_flags & (RAW|LITOUT|PASS8)) || !(lpar & PENABLE)) lpar |= BITS8; else ! lpar |= BITS7; if ((tp->t_ospeed) == B110) lpar |= TWOSB; addr->dhlpr = lpar; *** ./usr/src/sys/pdpuba/dhu.c.old Sat May 31 18:13:24 1997 --- ./usr/src/sys/pdpuba/dhu.c Tue Aug 12 18:38:00 2025 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dhu.c 2.3 (2.11BSD GTE) 1997/5/9 */ /* --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dhu.c 2.4 (2.11BSD) 2025/8/112025/8/11 */ /* *************** *** 39,45 **** struct uba_device dhuinfo[NDHU]; ! #define NDHULINE (NDHU*16) #define UNIT(x) (minor(x) & 077) #define SOFTCAR 0x80 --- 39,48 ---- struct uba_device dhuinfo[NDHU]; ! #ifndef NDHUL ! #define NDHUL 16 ! #endif ! #define NDHULINE (NDHU*NDHUL) #define UNIT(x) (minor(x) & 077) #define SOFTCAR 0x80 *************** *** 451,464 **** goto out; } lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8); if ((tp->t_ispeed) == B134) ! lpar |= DHU_LP_BITS6|DHU_LP_PENABLE; ! else if (tp->t_flags & (RAW|LITOUT|PASS8)) lpar |= DHU_LP_BITS8; else ! lpar |= DHU_LP_BITS7|DHU_LP_PENABLE; ! if (tp->t_flags&EVENP) ! lpar |= DHU_LP_EPAR; if ((tp->t_ospeed) == B110) lpar |= DHU_LP_TWOSB; addr->dhucsr = DHU_SELECT(unit) | DHU_IE; --- 454,469 ---- goto out; } lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8); + if ((tp->t_flags & (EVENP|ODDP)) == EVENP) + lpar |= DHU_LP_PENABLE|DHU_LP_EPAR; + else if ((tp->t_flags & (EVENP|ODDP)) == ODDP) + lpar |= DHU_LP_PENABLE; if ((tp->t_ispeed) == B134) ! lpar |= DHU_LP_BITS6; ! else if ((tp->t_flags & (RAW|LITOUT|PASS8)) || !(lpar & DHU_LP_PENABLE)) lpar |= DHU_LP_BITS8; else ! lpar |= DHU_LP_BITS7; if ((tp->t_ospeed) == B110) lpar |= DHU_LP_TWOSB; addr->dhucsr = DHU_SELECT(unit) | DHU_IE; *** ./usr/src/sys/pdpuba/dz.c.old Thu Apr 13 06:23:01 2023 --- ./usr/src/sys/pdpuba/dz.c Tue Aug 12 18:39:14 2025 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dz.c 1.5 (2.11BSD) 2023/4/13 */ /* --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dz.c 1.6 (2.11BSD) 2025/8/11 */ /* *************** *** 373,384 **** return; } lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); ! if (tp->t_flags & (RAW|LITOUT|PASS8)) lpr |= BITS8; else ! lpr |= (BITS7|PENABLE); ! if ((tp->t_flags & EVENP) == 0) ! lpr |= OPAR; if (tp->t_ispeed == B110) lpr |= TWOSB; dzaddr->dzlpr = lpr; --- 373,386 ---- return; } lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); ! if ((tp->t_flags & (EVENP|ODDP) == ODDP) ! lpr |= PENABLE|OPAR; ! else if ((tp->t_flags & (EVENP|ODDP) == EVENP) ! lpr |= PENABLE; ! if ((tp->t_flags & (RAW|LITOUT|PASS8)) || !(lpr & PENABLE)) lpr |= BITS8; else ! lpr |= BITS7; if (tp->t_ispeed == B110) lpr |= TWOSB; dzaddr->dzlpr = lpr; *** ./usr/src/sys/conf/config.old Fri Oct 18 13:43:15 2019 --- ./usr/src/sys/conf/config Tue Aug 12 18:43:28 2025 *************** *** 1,6 **** --- 1,7 ---- #! /bin/sh # 2.11BSD script to set up a new kernel configuration directory. # + # 2025/08/11 - add NDHUL to specify no. of lines per DHU # 2019/10/18 - the kernel runs on GMT. The kernel timezone structure # is obsolete, will be initialized to 0 now and only # present for historical reference. *************** *** 175,180 **** --- 176,182 ---- echo "#define NDM $NDM" >> ../$MACHINE/dh.h echo "#define NDN $NDN" > ../$MACHINE/dn.h echo "#define NDHU $NDHU" > ../$MACHINE/dhu.h + echo "#define NDHUL $NDHUL" >> ../$MACHINE/dhu.h echo "#define NDHV $NDHV" > ../$MACHINE/dhv.h echo "#define NDMC $NDMC" > ../$MACHINE/dmc.h echo "#define NDR $NDR" > ../$MACHINE/dr.h *** ./usr/src/sys/conf/GENERIC.old Fri Oct 18 13:45:18 2019 --- ./usr/src/sys/conf/GENERIC Tue Aug 12 18:44:07 2025 *************** *** 1,3 **** --- 1,4 ---- + # 2025/08/11 - add NDHUL # 2019/10/18 - TIMEZONE set to GMT # 1997/1/21 - RK added to GENERIC kernel (for use with Bob Supnik's emulator) # 1995/12/14 - RX added to GENERIC kernel. *************** *** 188,193 **** --- 189,195 ---- # boards on a 22bit Qbus. NDM 0 # DM11; NDM is in units of boards (16 each) NDHU 0 # DHU11 + NDHUL 16 # No. of lines per DHU11 NDHV 0 # DHV11 NDZ 0 # DZ11; NDZ is in units of boards (8 each) *** ./usr/src/libexec/telnetd/telnetd.c.old Sat Mar 29 07:23:36 2025 --- ./usr/src/libexec/telnetd/telnetd.c Tue Aug 12 18:44:54 2025 *************** *** 9,15 **** "@(#) Copyright (c) 1983 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)telnetd.c 5.22 (2.11BSD) 2025/3/29"; #endif /* --- 9,15 ---- "@(#) Copyright (c) 1983 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)telnetd.c 5.23 (2.11BSD) 2025/8/11"; #endif /* *************** *** 865,870 **** --- 865,871 ---- case TELOPT_BINARY: mode(RAW, 0); + lmode(PASS8, 0); fmt = doopt; break; *************** *** 927,932 **** --- 928,934 ---- case TELOPT_BINARY: mode(0, RAW); + lmode(0, PASS8); break; case TELOPT_TTYPE: *************** *** 958,963 **** --- 960,966 ---- case TELOPT_BINARY: mode(RAW, 0); + lmode(PASS8, 0); fmt = will; break; *************** *** 1068,1073 **** --- 1071,1089 ---- b.sg_flags |= on; b.sg_flags &= ~off; ioctl(pty, TIOCSETP, &b); + } + + lmode(on, off) + long on, off; + { + int some_on = on >> 16; + int some_off = off >> 16; + int old = 0; + + ioctl(pty, TIOCLGET, &old); + old |= some_on; + old &= ~some_off; + ioctl(pty, TIOCLSET, &old); } /* *** ./usr/src/libexec/getty/gettytab.h.old Fri Mar 21 18:53:03 2025 --- ./usr/src/libexec/getty/gettytab.h Tue Aug 12 18:45:15 2025 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)gettytab.h 5.3 (2.11BSD) 2023/4/13 */ /* --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)gettytab.h 5.4 (2.11BSD) 2025/8/11 */ /* *************** *** 81,89 **** #define EP gettyflags[2].value #define EPset gettyflags[2].set #define OP gettyflags[3].value ! #define OPset gettyflags[2].set #define AP gettyflags[4].value ! #define APset gettyflags[2].set /* EC is defined and used also for telnet, with a different meaning. * However, in telnetd, we don't care about the getty EC anyway, so * we just protect ourself from a double definition error this way. --- 81,89 ---- #define EP gettyflags[2].value #define EPset gettyflags[2].set #define OP gettyflags[3].value ! #define OPset gettyflags[3].set #define AP gettyflags[4].value ! #define APset gettyflags[4].set /* EC is defined and used also for telnet, with a different meaning. * However, in telnetd, we don't care about the getty EC anyway, so * we just protect ourself from a double definition error this way.