Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
UIO(9)		       FreeBSD Kernel Developer's Manual		UIO(9)

     uio, uiomove -- device driver IO routines

     #include <sys/types.h>
     #include <sys/cdefs.h>
     #include <sys/uio.h>

     struct uio	{
	     struct  iovec *uio_iov;
	     int     uio_iovcnt;
	     off_t   uio_offset;
	     int     uio_resid;
	     enum    uio_seg uio_segflg;
	     enum    uio_rw uio_rw;
	     struct  proc *uio_procp;

     uiomove(caddr_t buf, int howmuch, struct uio *uiop);

     The function uiomove() is used to handle transfer of data between buffers
     and IO vectors that might possibly	also cross the user/kernel space

     As	a result of any	read(2), write(2), readv(2), or	writev(2) system call
     that is being passed to a character-device	driver,	the appropriate	driver
     read or write entry will be called	with a pointer to a struct uio being
     passed.  The transfer request is encoded in this structure.  The driver
     itself should use uiomove() to get	at the data in this structure.

     The fields	in the uio structure are:
     uio_iov	     The array of IO vectors to	be processed.  In the case of
		     scatter/gather IO,	this will be more than one vector.
     uio_iovcnt	     The number	of IO vectors present.
     uio_offset	     The offset	into the device.
     uio_resid	     The number	of bytes to process.
     uio_segflg	     One of the	following flags:
		     UIO_USERSPACE    The IO vector points into	a process's
				      address space.
		     UIO_SYSSPACE     The IO vector points into	the kernel
				      address space.
		     UIO_USERISPACE   The IO vector points into	the instruc-
				      tion area	of a process's address space.
		     UIO_NOCOPY	      Don't copy, already in object.
     uio_rw uio_rw   The direction of the desired transfer, either UIO_READ,
		     or	UIO_WRITE.
     uio_procp	     The pointer to a struct proc for the associated process;
		     used if uio_segflg	indicates that the transfer is to be
		     made from/to a process's address space.

     The idea is that the driver maintains a private buffer for	its data, and
     processes the request in chunks of	maximal	the size of this buffer.  Note
     that the buffer handling below is very simplified and won't work (the
     buffer pointer is not being advanced in case of a partial read), it's
     just here to demonstrate the uio handling.

     /*	MIN() can be found there: */
     #include <sys/param.h>

     #define BUFSIZE 512
     static char buffer[BUFSIZE];

     static int	data_available;	     /*	amount of data that can	be read	*/

     static int
     fooread(dev_t dev,	struct uio *uio, int flag)
	     int rv, amnt;

	     while (uio->uio_resid > 0)	{
		     if	(data_available	> 0) {
			     amnt = MIN(uio->uio_resid,	data_available);
			     if	((rv = uiomove((caddr_t)buffer,	amnt, uio))
				 != 0)
				     goto error;
			     data_available -= amnt;
		     } else {
			     tsleep(...);    /*	wait for a better time */
	     return 0;
	     /*	do error cleanup here */
	     return rv;

     uiomove() can return EFAULT from the invoked copyin(9) or copyout(9) in
     case the transfer was to/from a process's address space.

     read(2), readv(2),	write(2), writev(2), copyin(9),	copyout(9), sleep(9)

     The uio mechanism appeared	in some	early version of UNIX.

     This man page has been written by Joerg Wunsch.

FreeBSD	2.2.1		       February	2, 1997			 FreeBSD 2.2.1


Want to link to this manual page? Use this URL:

home | help