Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Feb 1997 11:40:59 +1030 (CST)
From:      Michael Smith <msmith@atrad.adelaide.edu.au>
To:        mcgovern@spoon.beta.com (Brian J. McGovern)
Cc:        hackers@freebsd.org
Subject:   Re: Device driver help needed...
Message-ID:  <199702020111.LAA15091@genesis.atrad.adelaide.edu.au>
In-Reply-To: <199702012336.SAA12533@spoon.beta.com> from "Brian J. McGovern" at "Feb 1, 97 06:36:59 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
Brian J. McGovern stands accused of saying:
> Ok. I'm sure that now I've terribly bastardized the uio structure, but at
> least the damn thing compiles :) Let see if I can get some comment
> on my interpretation of the uio stucture:

"correct" usage of the uio structure means ignoring its contents, with
the exception of the uio_resid member, which gives you a count of
bytes outstanding.  On a read, this is how much of the user buffer is
left, on a write this is how much more the user process wants to
write.

You drag stuff around with uiomove() :

	u_char	mybuf[128];
	int	hmuch;
	int	result;
	...
	hmuch = min(uio->uio_resid, sizeof(mybuf));
	if ((result = uiomove(mybuf, hmuch, uio)))
		return(result);
	...

In a read() style routine, this will copy data from mybuf out to the
user, in a write() style routine, the data goes the other way.  This
is handled invisibly by the contents of the uio strcture.

> With that in mind, I've bent my device driver to look like this:

I'm assuming that this is meant to be a pseudo-device, correct?

> static struct cdevsw foo_cdevsw =
>   {
>     nxopen, nxclose, fooread, nxwrite,
>     nxioctl, nxstop, nxreset, nxdevtotty,
>     nxselect, nxmmap, NULL, "foo", NULL, -1
>   };

You probably want nullopen and nullclose there, so that the device can
be opened and closed.

> fooinit()
>   {
>   }

If this is a pseudo-device, you're going to want some code here to
install you cdevsw and any devfs nodes you plan on advertising.  I
_strongly_ suggest looking at the logic in vn_drvinit, which does just
that (as well as installing a shutdown hook).

> static int fooread(dev,myuio, flag)
>   dev_t dev;
>   struct uio *myuio;
>   int flag;
>   {
>     unsigned char *buffer_pointer;
>     int toread;
>     if ((myuio->uio_iovcnt != 1) || (MINOR(dev) != 0))
>       return ENODEV;
>     while(myuio->uio_resid)
>       {
>         buffer_pointer = (message + (myuio->uio_offset % sizeof(message)));
>         toread = ((long unsigned int)(message + sizeof(message)) - (long unsigned int)buffer_pointer);
>         uiomove(buffer_pointer, toread, myuio);
> 	myuio->uio_offset + toread;
> 	myuio->uio_resid = myuio->uio_resid - toread;
>       }
>   }
> #define CDEV_MAJOR 20

Ouch.  Leave the innards of the uio structure alone; uiomove takes
care of all that for you.  If what you want the read function to do is
to return as much of the message string as will fit in the requeted
read buffer, try :

static int
fooread(dev_t dev, struct uio *uio, int flag)
{
	int	toread;

	if (MINOR(dev) != 1)
		return(ENODEV);
	toread = (min(uio->uio_resid, sizeof(message));
	return(uiomove(message, toread, uio));
}

> as a pseudo-device driver. The file above is located in
> /usr/src/sys/i386/addons/foo.c. Anyone care to give me a set of steps (and
> code changes) to get it in the kernel? Thanks.
> 	-Brian

Move it to /sys/dev/foo/foo.c, bracket the whole file in #if NFOO > 0
/ #endif, add a line to /sys/conf/files that reads '/dev/foo/foo.c
optional foo' and stick a line in your kernel config that reads
'pseudo-device foo 1'.

Add a SYSINIT macro to your file that looks like :

SYSINIT(foodev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,foo_init,NULL);

and rework your init function along the lines of the 'vn' one
mentioned above.

When you're testing your kernels, _don't_ use 'make install' to
install them, as it's fairly likely you'll end up with two dead ones
in a row 8)

--
]] Mike Smith, Software Engineer        msmith@gsoft.com.au             [[
]] Genesis Software                     genesis@gsoft.com.au            [[
]] High-speed data acquisition and      (GSM mobile)     0411-222-496   [[
]] realtime instrument control.         (ph)          +61-8-8267-3493   [[
]] Unix hardware collector.             "Where are your PEZ?" The Tick  [[



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702020111.LAA15091>