Return to BSD News archive
Newsgroups: comp.unix.bsd Path: sserve!manuel!munnari.oz.au!mips!mips!sdd.hp.com!wupost!uunet!email!news.univie.ac.at!news.tu-graz.ac.at!fstgds01!chmr From: chmr@fstgds01.tu-graz.ac.at (Christoph Robitschko) Subject: com woes Message-ID: <1992Aug9.085755.6237@news.tu-graz.ac.at> Summary: select() now working on com ports Sender: news@news.tu-graz.ac.at (USENET News System) Nntp-Posting-Host: fstgds01 Organization: Technical University of Graz, Austria Date: Sun, 9 Aug 92 08:57:55 GMT Lines: 175 I had the problem with select() not working on com ports. I got no response from a post regarding this one, so I started to look into it myself. I found out that the com driver calculates unit = minor(dev) -1; This has the following implications: /dev/com1 corresponds to COM0, /dev/com2 to COM1 (very confusing in kernel messages) It is incompatible with the config file entries com1 at..., com2 at... Unpredictible results will occur if someone puts a com0 at.. in his config file. It is incompatible with the DOS usage of COM1, COM2 (But who cares 8-) ttselect() calculates unit = minor(dev), and uses this as an index in com_tty. Because this index is different from that used in the com driver, select() on /dev/com1 looks at /dev/com2 and select() on /dev/com2 looks at an undefined entry in com_tty and returns always true. I include a patch to the stock 0.1 com driver. It simply corrects "unit = minor(dev) - 1" to "unit = minor(dev)" If you are running cgd's driver and you need select working (I don't think this applies to many people, since I got NO response to my request), there is a *ugly* workaround: In the initialisation of cdevsw in /sys/i386/i386/conf.c, replace com_tty with (com_tty -1). To Chris Demetriou: Please fix your driver. I could not do it because I currently have no ftp connection to agate. Here is the patch to the *stock 0.1* com driver (diff -p com.c.ori com.c) --- CUT HERE --- *** /sys/i386/isa/com.c.ori Wed Jul 29 11:02:48 1992 --- /sys/i386/isa/com.c Sat Aug 8 21:49:48 1992 *************** extern int kgdb_rate; *** 108,114 **** extern int kgdb_debug_init; #endif ! #define UNIT(x) (minor(x)-1) comprobe(dev) struct isa_device *dev; --- 108,114 ---- extern int kgdb_debug_init; #endif ! #define UNIT(x) (minor(x)) comprobe(dev) struct isa_device *dev; *************** struct isa_device *isdp; *** 131,137 **** u_char unit; int port = isdp->id_iobase; ! unit = isdp->id_unit - 1; if (unit == comconsole) DELAY(1000); com_addr[unit] = port; --- 131,137 ---- u_char unit; int port = isdp->id_iobase; ! unit = isdp->id_unit; if (unit == comconsole) DELAY(1000); com_addr[unit] = port; *************** struct isa_device *isdp; *** 149,155 **** outb(port+com_ier, 0); outb(port+com_mcr, 0 | MCR_IENABLE); #ifdef KGDB ! if (kgdb_dev == makedev(commajor, unit+1)) { if (comconsole == unit) kgdb_dev = -1; /* can't debug over console port */ else { --- 149,155 ---- outb(port+com_ier, 0); outb(port+com_mcr, 0 | MCR_IENABLE); #ifdef KGDB ! if (kgdb_dev == makedev(commajor, unit)) { if (comconsole == unit) kgdb_dev = -1; /* can't debug over console port */ else { *************** comclose(dev, flag, mode, p) *** 239,245 **** outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK); #ifdef KGDB /* do not disable interrupts if debugging */ ! if (kgdb_dev != makedev(commajor, unit+1)) #endif outb(com+com_ier, 0); if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || --- 239,245 ---- outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK); #ifdef KGDB /* do not disable interrupts if debugging */ ! if (kgdb_dev != makedev(commajor, unit)) #endif outb(com+com_ier, 0); if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || *************** comintr(unit) *** 283,289 **** register u_char code; register struct tty *tp; ! unit--; com = com_addr[unit]; while (1) { code = inb(com+com_iir); --- 283,289 ---- register u_char code; register struct tty *tp; ! unit; com = com_addr[unit]; while (1) { code = inb(com+com_iir); *************** comintr(unit) *** 300,306 **** #define RCVBYTE() \ code = inb(com+com_data); \ if ((tp->t_state & TS_ISOPEN) == 0) { \ ! if (kgdb_dev == makedev(commajor, unit+1) && \ code == FRAME_END) \ kgdb_connect(0); /* trap into kgdb */ \ } else \ --- 300,306 ---- #define RCVBYTE() \ code = inb(com+com_data); \ if ((tp->t_state & TS_ISOPEN) == 0) { \ ! if (kgdb_dev == makedev(commajor, unit) && \ code == FRAME_END) \ kgdb_connect(0); /* trap into kgdb */ \ } else \ *************** comeint(unit, stat, com) *** 359,365 **** #ifdef KGDB /* we don't care about parity errors */ if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) && ! kgdb_dev == makedev(commajor, unit+1) && c == FRAME_END) kgdb_connect(0); /* trap into kgdb */ #endif return; --- 359,365 ---- #ifdef KGDB /* we don't care about parity errors */ if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) && ! kgdb_dev == makedev(commajor, unit) && c == FRAME_END) kgdb_connect(0); /* trap into kgdb */ #endif return; *************** comcnprobe(cp) *** 616,622 **** /* make sure hardware exists? XXX */ /* initialize required fields */ ! cp->cn_dev = makedev(commajor, unit+1); cp->cn_tp = &com_tty[unit]; #ifdef COMCONSOLE cp->cn_pri = CN_REMOTE; /* Force a serial port console */ --- 616,622 ---- /* make sure hardware exists? XXX */ /* initialize required fields */ ! cp->cn_dev = makedev(commajor, unit); cp->cn_tp = &com_tty[unit]; #ifdef COMCONSOLE cp->cn_pri = CN_REMOTE; /* Force a serial port console */ --- CUT HERE --- As usual, use at your own risk. Christoph -- ------------------------------------------------------------------------ Christoph M. Robitschko | "the only man who got his work done by Friday chmr@edvz.tu-graz.ac.at | was Robinson Crusoe."