1997-02-02 11:41:07 +00:00
|
|
|
.\"
|
|
|
|
.\" Copyright (c) 1997 Joerg Wunsch
|
|
|
|
.\"
|
|
|
|
.\" All rights reserved.
|
|
|
|
.\"
|
|
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
|
|
.\" modification, are permitted provided that the following conditions
|
|
|
|
.\" are met:
|
|
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
|
|
.\"
|
|
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
.\"
|
1999-08-28 00:22:10 +00:00
|
|
|
.\" $FreeBSD$
|
2001-11-21 12:02:28 +00:00
|
|
|
.\"
|
2007-10-30 16:04:23 +00:00
|
|
|
.Dd October 30, 2007
|
1997-02-02 11:41:07 +00:00
|
|
|
.Os
|
|
|
|
.Dt UIO 9
|
|
|
|
.Sh NAME
|
|
|
|
.Nm uio ,
|
|
|
|
.Nm uiomove
|
2001-11-21 12:02:28 +00:00
|
|
|
.Nd device driver I/O routines
|
1997-02-02 11:41:07 +00:00
|
|
|
.Sh SYNOPSIS
|
2001-10-01 16:09:29 +00:00
|
|
|
.In sys/types.h
|
|
|
|
.In sys/uio.h
|
1997-02-02 11:41:07 +00:00
|
|
|
.Pp
|
|
|
|
.Bd -literal
|
|
|
|
struct uio {
|
2006-11-29 19:10:53 +00:00
|
|
|
struct iovec *uio_iov; /* scatter/gather list */
|
|
|
|
int uio_iovcnt; /* length of scatter/gather list */
|
|
|
|
off_t uio_offset; /* offset in target object */
|
|
|
|
int uio_resid; /* remaining bytes to copy */
|
|
|
|
enum uio_seg uio_segflg; /* address space */
|
|
|
|
enum uio_rw uio_rw; /* operation */
|
|
|
|
struct thread *uio_td; /* owner */
|
1997-02-02 11:41:07 +00:00
|
|
|
};
|
|
|
|
.Ed
|
|
|
|
.Ft int
|
2003-03-03 10:49:37 +00:00
|
|
|
.Fn uiomove "void *buf" "int howmuch" "struct uio *uiop"
|
1997-02-02 11:41:07 +00:00
|
|
|
.Sh DESCRIPTION
|
|
|
|
The function
|
|
|
|
.Fn uiomove
|
2001-11-21 12:02:28 +00:00
|
|
|
is used to handle transfer of data between buffers and I/O vectors
|
1997-02-02 11:41:07 +00:00
|
|
|
that might possibly also cross the user/kernel space boundary.
|
|
|
|
.Pp
|
|
|
|
As a result of any
|
|
|
|
.Xr read 2 ,
|
|
|
|
.Xr write 2 ,
|
|
|
|
.Xr readv 2 ,
|
|
|
|
or
|
|
|
|
.Xr writev 2
|
|
|
|
system call that is being passed to a character-device driver, the
|
|
|
|
appropriate driver
|
2001-11-21 12:02:28 +00:00
|
|
|
.Va d_read
|
1997-02-02 11:41:07 +00:00
|
|
|
or
|
2001-11-21 12:02:28 +00:00
|
|
|
.Va d_write
|
1997-02-02 11:41:07 +00:00
|
|
|
entry will be called with a pointer to a
|
2001-11-21 12:02:28 +00:00
|
|
|
.Vt "struct uio"
|
|
|
|
being passed.
|
|
|
|
The transfer request is encoded in this structure.
|
1997-02-02 11:41:07 +00:00
|
|
|
The driver itself should use
|
|
|
|
.Fn uiomove
|
|
|
|
to get at the data in this structure.
|
|
|
|
.Pp
|
2001-11-21 12:02:28 +00:00
|
|
|
The fields in the
|
|
|
|
.Vt uio
|
|
|
|
structure are:
|
|
|
|
.Bl -tag -width ".Va uio_iovcnt"
|
|
|
|
.It Va uio_iov
|
|
|
|
The array of I/O vectors to be processed.
|
|
|
|
In the case of scatter/gather
|
|
|
|
I/O, this will be more than one vector.
|
|
|
|
.It Va uio_iovcnt
|
|
|
|
The number of I/O vectors present.
|
|
|
|
.It Va uio_offset
|
1997-02-02 11:41:07 +00:00
|
|
|
The offset into the device.
|
2001-11-21 12:02:28 +00:00
|
|
|
.It Va uio_resid
|
2006-11-29 19:10:53 +00:00
|
|
|
The remaining number of bytes to process, updated after transfer.
|
2001-11-21 12:02:28 +00:00
|
|
|
.It Va uio_segflg
|
1997-02-02 11:41:07 +00:00
|
|
|
One of the following flags:
|
2002-06-20 07:09:24 +00:00
|
|
|
.Bl -tag -width ".Dv UIO_USERSPACE"
|
1997-02-02 11:41:07 +00:00
|
|
|
.It Dv UIO_USERSPACE
|
2001-11-21 12:02:28 +00:00
|
|
|
The I/O vector points into a process's address space.
|
1997-02-02 11:41:07 +00:00
|
|
|
.It Dv UIO_SYSSPACE
|
2001-11-21 12:02:28 +00:00
|
|
|
The I/O vector points into the kernel address space.
|
1997-02-02 11:41:07 +00:00
|
|
|
.It Dv UIO_NOCOPY
|
2005-02-13 22:25:33 +00:00
|
|
|
Do not copy, already in object.
|
1997-02-02 11:41:07 +00:00
|
|
|
.El
|
2001-11-21 12:02:28 +00:00
|
|
|
.It Va uio_rw
|
1997-02-02 11:41:07 +00:00
|
|
|
The direction of the desired transfer, either
|
|
|
|
.Dv UIO_READ ,
|
|
|
|
or
|
|
|
|
.Dv UIO_WRITE .
|
2001-11-21 12:02:28 +00:00
|
|
|
.It Va uio_td
|
1997-02-02 11:41:07 +00:00
|
|
|
The pointer to a
|
2001-11-21 12:02:28 +00:00
|
|
|
.Vt "struct thread"
|
2001-11-05 00:41:39 +00:00
|
|
|
for the associated thread; used if
|
2001-11-21 12:02:28 +00:00
|
|
|
.Va uio_segflg
|
1997-02-02 11:41:07 +00:00
|
|
|
indicates that the transfer is to be made from/to a process's address
|
|
|
|
space.
|
|
|
|
.El
|
2005-01-21 08:36:40 +00:00
|
|
|
.Sh RETURN VALUES
|
2006-11-29 19:10:53 +00:00
|
|
|
On success
|
2005-01-21 08:36:40 +00:00
|
|
|
.Fn uiomove
|
2006-11-29 19:10:53 +00:00
|
|
|
will return 0, on error it will return an appropriate errno.
|
|
|
|
.Sh ERRORS
|
|
|
|
.Fn uiomove
|
|
|
|
will fail and return the following error code if:
|
|
|
|
.Bl -tag -width Er
|
|
|
|
.It Bq Er EFAULT
|
|
|
|
The invoked
|
2005-01-21 08:36:40 +00:00
|
|
|
.Xr copyin 9
|
|
|
|
or
|
|
|
|
.Xr copyout 9
|
2006-11-29 19:10:53 +00:00
|
|
|
returned
|
|
|
|
.Er EFAULT
|
2007-10-30 16:04:23 +00:00
|
|
|
.El
|
1997-02-02 11:41:07 +00:00
|
|
|
.Sh EXAMPLES
|
|
|
|
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
|
2001-11-21 12:02:28 +00:00
|
|
|
buffer.
|
|
|
|
Note that the buffer handling below is very simplified and
|
2005-02-13 22:25:33 +00:00
|
|
|
will not work (the buffer pointer is not being advanced in case of a
|
2005-02-13 23:45:54 +00:00
|
|
|
partial read), it is just here to demonstrate the
|
2001-11-21 12:02:28 +00:00
|
|
|
.Nm
|
|
|
|
handling.
|
1997-02-02 11:41:07 +00:00
|
|
|
.Bd -literal
|
|
|
|
/* 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;
|
|
|
|
|
2004-04-15 07:24:10 +00:00
|
|
|
rv = 0;
|
1997-02-02 11:41:07 +00:00
|
|
|
while (uio->uio_resid > 0) {
|
|
|
|
if (data_available > 0) {
|
1997-02-02 21:38:10 +00:00
|
|
|
amnt = MIN(uio->uio_resid, data_available);
|
2004-04-15 07:24:10 +00:00
|
|
|
rv = uiomove(buffer, amnt, uio);
|
|
|
|
if (rv != 0)
|
|
|
|
break;
|
1997-02-02 11:41:07 +00:00
|
|
|
data_available -= amnt;
|
2004-04-15 07:24:10 +00:00
|
|
|
} else
|
1997-02-02 11:41:07 +00:00
|
|
|
tsleep(...); /* wait for a better time */
|
|
|
|
}
|
2004-04-15 07:24:10 +00:00
|
|
|
if (rv != 0) {
|
|
|
|
/* do error cleanup here */
|
|
|
|
}
|
|
|
|
return (rv);
|
1997-02-02 11:41:07 +00:00
|
|
|
}
|
|
|
|
.Ed
|
|
|
|
.Sh SEE ALSO
|
|
|
|
.Xr read 2 ,
|
|
|
|
.Xr readv 2 ,
|
|
|
|
.Xr write 2 ,
|
|
|
|
.Xr writev 2 ,
|
|
|
|
.Xr copyin 9 ,
|
|
|
|
.Xr copyout 9 ,
|
|
|
|
.Xr sleep 9
|
|
|
|
.Sh HISTORY
|
2001-11-21 12:02:28 +00:00
|
|
|
The
|
|
|
|
.Nm
|
|
|
|
mechanism appeared in some early version of
|
1997-02-02 11:41:07 +00:00
|
|
|
.Ux .
|
|
|
|
.Sh AUTHORS
|
2005-06-28 20:15:19 +00:00
|
|
|
This manual page was written by
|
2000-11-10 17:46:15 +00:00
|
|
|
.An J\(:org Wunsch .
|