From: ache@astral.msk.su (Andrew A. Chernov, Black Mage)
Newsgroups: comp.unix.bsd
Subject: [386bsd] patch for cgd's multiport com driver, select() bug fix
Date: 23 Dec 92 08:01:49 GMT
Reply-To: ache@astral.msk.su
Organization: Ha-oh-lahm Yetzirah

I just found this bug, maybe, it present in standard com driver too...
I don't use it and can't check.

BUG DESCRIPTION:
select() call don't work at all.

WHY:
ttselect() kernel routine used for coms too, its code say:
	register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
but for cgd's multiport com driver it must be:
	register struct tty *tp = &com_tty[UNIT(dev)];

FIX:
Simple, duplicate ttselect() code into comselect() code
with replacing above. Modify conf.c ttselect()-->comselect()


*** /sys/i386/isa/com.c.cgd.was       Thu Dec 10 01:07:29 1992
--- /sys/i386/isa/com.c       Wed Dec 23 10:11:01 1992
***************
*** 932,934 ****
--- 932,973 ----
  	return 0;
  }
  #endif
+ 
+ int
+ comselect(dev, rw, p)
+ 	dev_t dev;
+ 	int rw;
+ 	struct proc *p;
+ {
+ 	register struct tty *tp = &com_tty[UNIT(dev)];
+ 	int nread;
+ 	int s = spltty();
+ 
+ 	switch (rw) {
+ 
+ 	case FREAD:
+ 		nread = ttnread(tp);
+ 		if (nread > 0 || 
+ 		   ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0))
+ 			goto win;
+ 		if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
+ 			tp->t_state |= TS_RCOLL;
+ 		else
+ 			tp->t_rsel = p;
+ 		break;
+ 
+ 	case FWRITE:
+ 		if (RB_LEN(&tp->t_out) <= tp->t_lowat)
+ 			goto win;
+ 		if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
+ 			tp->t_state |= TS_WCOLL;
+ 		else
+ 			tp->t_wsel = p;
+ 		break;
+ 	}
+ 	splx(s);
+ 	return (0);
+ win:
+ 	splx(s);
+ 	return (1);
+ }
*** /sys/i386/i386/conf.c.cgd.was      Mon Nov 23 08:00:07 1992
--- /sys/i386/i386/conf.c      Wed Dec 23 10:13:12 1992
***************
*** 152,158 ****
  
  #include "com.h"
  #if NCOM > 0
! int	comopen(),comclose(),comread(),comwrite(),comioctl();
  #define comreset	enxio
  extern	struct tty com_tty[];
  #else
--- 152,158 ----
  
  #include "com.h"
  #if NCOM > 0
! int     comopen(),comclose(),comread(),comwrite(),comioctl(),comselect();
  #define comreset	enxio
  extern	struct tty com_tty[];
  #else
***************
*** 162,167 ****
--- 162,168 ----
  #define comwrite	enxio
  #define comioctl	enxio
  #define comreset	enxio
+ #define comselect       enxio
  #define	com_tty		NULL
  #endif
  
***************
*** 220,226 ****
  	  logselect,	enodev,		NULL },
  	{ comopen,	comclose,	comread,	comwrite,	/*8*/
  	  comioctl,	enodev,		comreset,	com_tty,
! 	  ttselect,	enodev,		NULL },
  	{ Fdopen,	fdclose,	rawread,	rawwrite,	/*9*/
  	  fdioctl,	enodev,		nullop,		NULL,
  	  seltrue,	enodev,		fdstrategy },
--- 221,227 ----
  	  logselect,	enodev,		NULL },
  	{ comopen,	comclose,	comread,	comwrite,	/*8*/
  	  comioctl,	enodev,		comreset,	com_tty,
! 	  comselect,    enodev,         NULL },
  	{ Fdopen,	fdclose,	rawread,	rawwrite,	/*9*/
  	  fdioctl,	enodev,		nullop,		NULL,
  	  seltrue,	enodev,		fdstrategy },
-- 
In-This-Life:  Andrew A. Chernov    |  "Hay mas dicha, mas contento
Internet:      ache@astral.msk.su   |  "Que adorar una hermosura
Organization:  The RELCOM Corp.,    |  "Brujuleada entre los lejos
               Moscow, Russia       |  "De lo imposible?!"  (Calderon)
Newsgroups: comp.unix.bsd