xref: /freebsd/share/man/man9/uio.9 (revision 6829dae12bb055451fa467da4589c43bd03b1e64)
1.\"
2.\" Copyright (c) 1997 Joerg Wunsch
3.\"
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\"    notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\"    notice, this list of conditions and the following disclaimer in the
13.\"    documentation and/or other materials provided with the distribution.
14.\"
15.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
16.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
19.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25.\"
26.\" $FreeBSD$
27.\"
28.Dd March 11, 2017
29.Dt UIO 9
30.Os
31.Sh NAME
32.Nm uio ,
33.Nm uiomove ,
34.Nm uiomove_frombuf ,
35.Nm uiomove_nofault
36.Nd device driver I/O routines
37.Sh SYNOPSIS
38.In sys/types.h
39.In sys/uio.h
40.Bd -literal
41struct uio {
42	struct	iovec *uio_iov;		/* scatter/gather list */
43	int	uio_iovcnt;		/* length of scatter/gather list */
44	off_t	uio_offset;		/* offset in target object */
45	ssize_t	uio_resid;		/* remaining bytes to copy */
46	enum	uio_seg uio_segflg;	/* address space */
47	enum	uio_rw uio_rw;		/* operation */
48	struct	thread *uio_td;		/* owner */
49};
50.Ed
51.Ft int
52.Fn uiomove "void *buf" "int howmuch" "struct uio *uiop"
53.Ft int
54.Fn uiomove_frombuf "void *buf" "int howmuch" "struct uio *uiop"
55.Ft int
56.Fn uiomove_nofault "void *buf" "int howmuch" "struct uio *uiop"
57.Sh DESCRIPTION
58The functions
59.Fn uiomove ,
60.Fn uiomove_frombuf ,
61and
62.Fn uiomove_nofault
63are used to transfer data between buffers and I/O vectors that might
64possibly cross the user/kernel space boundary.
65.Pp
66As a result of any
67.Xr read 2 ,
68.Xr write 2 ,
69.Xr readv 2 ,
70or
71.Xr writev 2
72system call that is being passed to a character-device driver, the
73appropriate driver
74.Va d_read
75or
76.Va d_write
77entry will be called with a pointer to a
78.Vt "struct uio"
79being passed.
80The transfer request is encoded in this structure.
81The driver itself should use
82.Fn uiomove
83or
84.Fn uiomove_nofault
85to get at the data in this structure.
86.Pp
87The fields in the
88.Vt uio
89structure are:
90.Bl -tag -width ".Va uio_iovcnt"
91.It Va uio_iov
92The array of I/O vectors to be processed.
93In the case of scatter/gather
94I/O, this will be more than one vector.
95.It Va uio_iovcnt
96The number of I/O vectors present.
97.It Va uio_offset
98The offset into the device.
99.It Va uio_resid
100The remaining number of bytes to process, updated after transfer.
101.It Va uio_segflg
102One of the following flags:
103.Bl -tag -width ".Dv UIO_USERSPACE"
104.It Dv UIO_USERSPACE
105The I/O vector points into a process's address space.
106.It Dv UIO_SYSSPACE
107The I/O vector points into the kernel address space.
108.It Dv UIO_NOCOPY
109Do not copy, already in object.
110.El
111.It Va uio_rw
112The direction of the desired transfer, either
113.Dv UIO_READ
114or
115.Dv UIO_WRITE .
116.It Va uio_td
117The pointer to a
118.Vt "struct thread"
119for the associated thread; used if
120.Va uio_segflg
121indicates that the transfer is to be made from/to a process's address
122space.
123.El
124.Pp
125The function
126.Fn uiomove_nofault
127requires that the buffer and I/O vectors be accessible without
128incurring a page fault.
129The source and destination addresses must be physically mapped for
130read and write access, respectively, and neither the source nor
131destination addresses may be pageable.
132Thus, the function
133.Fn uiomove_nofault
134can be called from contexts where acquiring virtual memory system
135locks or sleeping are prohibited.
136.Pp
137The
138.Fn uiomove_frombuf
139function is a convenience wrapper around
140.Fn uiomove
141for drivers that serve data which is wholly contained within an
142existing buffer in memory.
143It validates the
144.Va uio_offset
145and
146.Va uio_resid
147values against the size of the existing buffer, handling short
148transfers when the request partially overlaps the buffer.
149When
150.Va uio_offset
151is greater than or equal to the buffer size, the result is success
152with no bytes transferred, effectively signaling EOF.
153.Sh RETURN VALUES
154On success
155.Fn uiomove ,
156.Fn uiomove_frombuf ,
157and
158.Fn uiomove_nofault
159will return 0; on error they will return an appropriate error code.
160.Sh EXAMPLES
161The idea is that the driver maintains a private buffer for its data,
162and processes the request in chunks of maximal the size of this
163buffer.
164Note that the buffer handling below is very simplified and
165will not work (the buffer pointer is not being advanced in case of a
166partial read), it is just here to demonstrate the
167.Nm
168handling.
169.Bd -literal
170/* MIN() can be found there: */
171#include <sys/param.h>
172
173#define BUFSIZE 512
174static char buffer[BUFSIZE];
175
176static int data_available;	/* amount of data that can be read */
177
178static int
179fooread(struct cdev *dev, struct uio *uio, int flag)
180{
181	int rv, amnt;
182
183	rv = 0;
184	while (uio->uio_resid > 0) {
185		if (data_available > 0) {
186			amnt = MIN(uio->uio_resid, data_available);
187			rv = uiomove(buffer, amnt, uio);
188			if (rv != 0)
189				break;
190			data_available -= amnt;
191		} else
192			tsleep(...);	/* wait for a better time */
193	}
194	if (rv != 0) {
195		/* do error cleanup here */
196	}
197	return (rv);
198}
199.Ed
200.Sh ERRORS
201.Fn uiomove
202and
203.Fn uiomove_nofault
204will fail and return the following error code if:
205.Bl -tag -width Er
206.It Bq Er EFAULT
207The invoked
208.Xr copyin 9
209or
210.Xr copyout 9
211returned
212.Er EFAULT
213.El
214.Pp
215In addition,
216.Fn uiomove_nofault
217will fail and return the following error code if:
218.Bl -tag -width Er
219.It Bq Er EFAULT
220A page fault occurs.
221.El
222.Sh SEE ALSO
223.Xr read 2 ,
224.Xr readv 2 ,
225.Xr write 2 ,
226.Xr writev 2 ,
227.Xr copyin 9 ,
228.Xr copyout 9 ,
229.Xr sleep 9
230.Sh HISTORY
231The
232.Nm
233mechanism appeared in some early version of
234.Ux .
235.Sh AUTHORS
236This manual page was written by
237.An J\(:org Wunsch .
238