Subject: Re: should cngetc block?
To: Bill Studenmund <wrstuden@netbsd.org>
From: Kin Cho <kin@neoscale.com>
List: tech-kern
Date: 02/11/2002 08:54:27
Bill Studenmund <wrstuden@netbsd.org> writes:

> On 8 Feb 2002, Kin Cho wrote:
> 
> > Bill Studenmund <wrstuden@netbsd.org> writes:
> >
> > > 	cnopen(<console dev for your port>, FREAD | FWRITE | <other opts>
> > > 		0, curproc);
> >
> > What can I use for <console dev for your port>?  I tried using
> > cn_tab->cn_dev but that's forbidden in cnopen because cn_dev is
> > alrady set to our "com0" device in com_attach_subr in
> > com.c:
> >
> > 		cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
> 
> ls -l /dev/console
> 
> For i386, it's major 0, minor 0. So "0" is the right value.

0 does work.  Strangely though, looking at the code, as long as
dev isn't cn_tab->cn_dev, cnopen ignores the parameter and uses
cn_tab->cn_dev anyway.

> 
> > > /*
> > >  * Set up a uio to do a read, then call cnread()
> > >  */
> >
> > I have no experience with uio.  Searching around, here's what I
> > come up with:
> >
> >             struct iovec aiov;
> >             struct uio auio;
> >             int buf[2];			// code and lsr as stored in comintr?
> >             aiov.iov_base = buf;
> >             aiov.iov_len = sizeof(buf);
> >             auio.uio_iov = &aiov;
> >             auio.uio_iovcnt = 1;
> >             auio.uio_offset = 0;
> >             auio.uio_resid = 0;
> >             auio.uio_segflg = UIO_SYSSPACE;
> >             auio.uio_rw = UIO_READ;
> >             auio.uio_procp = curproc;
> > 	    ret = cnread(<dev>, &auio, 0);
> >
> > I doubt that iov_len, uio_offset, and uio_resid are right.
> > Any suggestion what they should be?
> 
> man read tells some.
> 
> uio_offset is fine, as you're reading a device that can't seek. uio_resid
> is how much is left to do, 0 is a good initial value.

uio_resid==0 doesn't seem to work, but 1 does.

For my purpose, the tty needs to put in "raw" mode, so I
copied some code from tip.c:

		cnioctl(dev, TIOCGETA, (caddr_t)&term, 0, curproc);
		term.c_lflag &= ~(ICANON|IEXTEN|ECHO);
		term.c_iflag &= ~(INPCK|ICRNL);
		term.c_oflag &= ~OPOST;
		term.c_cc[VINTR] = term.c_cc[VQUIT] = term.c_cc[VSUSP] =
			term.c_cc[VDSUSP] = term.c_cc[VDISCARD] = 
			term.c_cc[VLNEXT] = _POSIX_VDISABLE;
		cnioctl(dev, TIOCSETA, (caddr_t)&term, 0, curproc);

I also had to put the tty back into "cooked" mode before
calling cngetsn.

Now polling for character works.

Thanks a lot for your help!

-kin