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 March 11, 2017 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, either 111.Dv UIO_READ 112or 113.Dv UIO_WRITE . 114.It Va uio_td 115The pointer to a 116.Vt "struct thread" 117for the associated thread; used if 118.Va uio_segflg 119indicates that the transfer is to be made from/to a process's address 120space. 121.El 122.Pp 123The function 124.Fn uiomove_nofault 125requires that the buffer and I/O vectors be accessible without 126incurring a page fault. 127The source and destination addresses must be physically mapped for 128read and write access, respectively, and neither the source nor 129destination addresses may be pageable. 130Thus, the function 131.Fn uiomove_nofault 132can be called from contexts where acquiring virtual memory system 133locks or sleeping are prohibited. 134.Pp 135The 136.Fn uiomove_frombuf 137function is a convenience wrapper around 138.Fn uiomove 139for drivers that serve data which is wholly contained within an 140existing buffer in memory. 141It validates the 142.Va uio_offset 143and 144.Va uio_resid 145values against the size of the existing buffer, handling short 146transfers when the request partially overlaps the buffer. 147When 148.Va uio_offset 149is greater than or equal to the buffer size, the result is success 150with no bytes transferred, effectively signaling EOF. 151.Sh RETURN VALUES 152On success 153.Fn uiomove , 154.Fn uiomove_frombuf , 155and 156.Fn uiomove_nofault 157will return 0; on error they will return an appropriate error code. 158.Sh EXAMPLES 159The idea is that the driver maintains a private buffer for its data, 160and processes the request in chunks of maximal the size of this 161buffer. 162Note that the buffer handling below is very simplified and 163will not work (the buffer pointer is not being advanced in case of a 164partial read), it is just here to demonstrate the 165.Nm 166handling. 167.Bd -literal 168/* MIN() can be found there: */ 169#include <sys/param.h> 170 171#define BUFSIZE 512 172static char buffer[BUFSIZE]; 173 174static int data_available; /* amount of data that can be read */ 175 176static int 177fooread(struct cdev *dev, struct uio *uio, int flag) 178{ 179 int rv, amnt; 180 181 rv = 0; 182 while (uio->uio_resid > 0) { 183 if (data_available > 0) { 184 amnt = MIN(uio->uio_resid, data_available); 185 rv = uiomove(buffer, amnt, uio); 186 if (rv != 0) 187 break; 188 data_available -= amnt; 189 } else 190 tsleep(...); /* wait for a better time */ 191 } 192 if (rv != 0) { 193 /* do error cleanup here */ 194 } 195 return (rv); 196} 197.Ed 198.Sh ERRORS 199.Fn uiomove 200and 201.Fn uiomove_nofault 202will fail and return the following error code if: 203.Bl -tag -width Er 204.It Bq Er EFAULT 205The invoked 206.Xr copyin 9 207or 208.Xr copyout 9 209returned 210.Er EFAULT 211.El 212.Pp 213In addition, 214.Fn uiomove_nofault 215will fail and return the following error code if: 216.Bl -tag -width Er 217.It Bq Er EFAULT 218A page fault occurs. 219.El 220.Sh SEE ALSO 221.Xr read 2 , 222.Xr readv 2 , 223.Xr write 2 , 224.Xr writev 2 , 225.Xr copyin 9 , 226.Xr copyout 9 , 227.Xr sleep 9 228.Sh HISTORY 229The 230.Nm 231mechanism appeared in some early version of 232.Ux . 233.Sh AUTHORS 234This manual page was written by 235.An J\(:org Wunsch . 236