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