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."