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.Dd October 22, 2025 27.Dt UIO 9 28.Os 29.Sh NAME 30.Nm uio , 31.Nm uiomove , 32.Nm uiomove_frombuf , 33.Nm uiomove_nofault 34.Nd device driver I/O routines 35.Sh SYNOPSIS 36.In sys/types.h 37.In sys/uio.h 38.Bd -literal 39struct uio { 40 struct iovec *uio_iov; /* scatter/gather list */ 41 int uio_iovcnt; /* length of scatter/gather list */ 42 off_t uio_offset; /* offset in target object */ 43 ssize_t uio_resid; /* remaining bytes to copy */ 44 enum uio_seg uio_segflg; /* address space */ 45 enum uio_rw uio_rw; /* operation */ 46 struct thread *uio_td; /* owner */ 47}; 48.Ed 49.Ft int 50.Fn uiomove "void *buf" "int howmuch" "struct uio *uiop" 51.Ft int 52.Fn uiomove_frombuf "void *buf" "int howmuch" "struct uio *uiop" 53.Ft int 54.Fn uiomove_nofault "void *buf" "int howmuch" "struct uio *uiop" 55.Sh DESCRIPTION 56The functions 57.Fn uiomove , 58.Fn uiomove_frombuf , 59and 60.Fn uiomove_nofault 61are used to transfer data between buffers and I/O vectors that might 62possibly cross the user/kernel space boundary. 63.Pp 64As a result of any 65.Xr read 2 , 66.Xr write 2 , 67.Xr readv 2 , 68or 69.Xr writev 2 70system call that is being passed to a character-device driver, the 71appropriate driver 72.Va d_read 73or 74.Va d_write 75entry will be called with a pointer to a 76.Vt "struct uio" 77being passed. 78The transfer request is encoded in this structure. 79The driver itself should use 80.Fn uiomove 81or 82.Fn uiomove_nofault 83to get at the data in this structure. 84.Pp 85The fields in the 86.Vt uio 87structure are: 88.Bl -tag -width ".Va uio_iovcnt" 89.It Va uio_iov 90The array of I/O vectors to be processed. 91In the case of scatter/gather 92I/O, this will be more than one vector. 93.It Va uio_iovcnt 94The number of I/O vectors present. 95.It Va uio_offset 96The offset into the device. 97.It Va uio_resid 98The remaining number of bytes to process, updated after transfer. 99.It Va uio_segflg 100One of the following flags: 101.Bl -tag -width ".Dv UIO_USERSPACE" 102.It Dv UIO_USERSPACE 103The I/O vector points into a process's address space. 104.It Dv UIO_SYSSPACE 105The I/O vector points into the kernel address space. 106.It Dv UIO_NOCOPY 107Do not copy, already in object. 108.El 109.It Va uio_rw 110The direction of the desired transfer. 111The supported flags are: 112.Bl -tag -width "UIO_WRITE" 113.It Dv UIO_READ 114Transfer data from the buffers into the I/O vectors. 115.It Dv UIO_WRITE 116Transfer data from the I/O vectors into the buffers. 117.El 118.It Va uio_td 119The pointer to a 120.Vt "struct thread" 121for the associated thread; used if 122.Va uio_segflg 123indicates that the transfer is to be made from/to a process's address 124space. 125.El 126.Pp 127The function 128.Fn uiomove_nofault 129requires that the buffer and I/O vectors be accessible without 130incurring a page fault. 131The source and destination addresses must be physically mapped for 132read and write access, respectively, and neither the source nor 133destination addresses may be pageable. 134Thus, the function 135.Fn uiomove_nofault 136can be called from contexts where acquiring virtual memory system 137locks or sleeping are prohibited. 138.Pp 139The 140.Fn uiomove_frombuf 141function is a convenience wrapper around 142.Fn uiomove 143for drivers that serve data which is wholly contained within an 144existing buffer in memory. 145It validates the 146.Va uio_offset 147and 148.Va uio_resid 149values against the size of the existing buffer, handling short 150transfers when the request partially overlaps the buffer. 151When 152.Va uio_offset 153is greater than or equal to the buffer size, the result is success 154with no bytes transferred, effectively signaling EOF. 155.Sh RETURN VALUES 156On success 157.Fn uiomove , 158.Fn uiomove_frombuf , 159and 160.Fn uiomove_nofault 161will return 0; on error they will return an appropriate error code. 162.Sh EXAMPLES 163The idea is that the driver maintains a private buffer for its data, 164and processes the request in chunks of maximal the size of this 165buffer. 166Note that the buffer handling below is very simplified and 167will not work (the buffer pointer is not being advanced in case of a 168partial read), it is just here to demonstrate the 169.Nm 170handling. 171.Bd -literal 172/* MIN() can be found there: */ 173#include <sys/param.h> 174 175#define BUFSIZE 512 176static char buffer[BUFSIZE]; 177 178static int data_available; /* amount of data that can be read */ 179 180static int 181fooread(struct cdev *dev, struct uio *uio, int flag) 182{ 183 int rv, amnt; 184 185 rv = 0; 186 while (uio->uio_resid > 0) { 187 if (data_available > 0) { 188 amnt = MIN(uio->uio_resid, data_available); 189 rv = uiomove(buffer, amnt, uio); 190 if (rv != 0) 191 break; 192 data_available -= amnt; 193 } else 194 tsleep(...); /* wait for a better time */ 195 } 196 if (rv != 0) { 197 /* do error cleanup here */ 198 } 199 return (rv); 200} 201.Ed 202.Sh ERRORS 203.Fn uiomove 204and 205.Fn uiomove_nofault 206will fail and return the following error code if: 207.Bl -tag -width Er 208.It Bq Er EFAULT 209The invoked 210.Xr copyin 9 211or 212.Xr copyout 9 213returned 214.Er EFAULT 215.El 216.Pp 217In addition, 218.Fn uiomove_nofault 219will fail and return the following error code if: 220.Bl -tag -width Er 221.It Bq Er EFAULT 222A page fault occurs. 223.El 224.Sh SEE ALSO 225.Xr read 2 , 226.Xr readv 2 , 227.Xr write 2 , 228.Xr writev 2 , 229.Xr copyin 9 , 230.Xr copyout 9 , 231.Xr sleep 9 232.Sh HISTORY 233The 234.Nm 235mechanism appeared in some early version of 236.Ux . 237.Sh AUTHORS 238This manual page was written by 239.An J\(:org Wunsch . 240