1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*        All Rights Reserved   */
  28 
  29 /*
  30  * University Copyright- Copyright (c) 1982, 1986, 1988
  31  * The Regents of the University of California
  32  * All Rights Reserved
  33  *
  34  * University Acknowledgment- Portions of this document are derived from
  35  * software developed by the University of California, Berkeley, and its
  36  * contributors.
  37  */
  38 
  39 #ifndef _SYS_UIO_H
  40 #define _SYS_UIO_H
  41 
  42 #include <sys/feature_tests.h>
  43 
  44 #ifdef  __cplusplus
  45 extern "C" {
  46 #endif
  47 
  48 #include <sys/types.h>
  49 
  50 /*
  51  * I/O parameter information.  A uio structure describes the I/O which
  52  * is to be performed by an operation.  Typically the data movement will
  53  * be performed by a routine such as uiomove(), which updates the uio
  54  * structure to reflect what was done.
  55  */
  56 
  57 #if     defined(_XPG4_2)
  58 typedef struct iovec {
  59         void    *iov_base;
  60         size_t  iov_len;
  61 } iovec_t;
  62 #else
  63 typedef struct iovec {
  64         caddr_t iov_base;
  65 #if defined(_LP64)
  66         size_t  iov_len;
  67 #else
  68         long    iov_len;
  69 #endif
  70 } iovec_t;
  71 #endif  /* defined(_XPG4_2) */
  72 
  73 #if defined(_SYSCALL32)
  74 
  75 /* Kernel's view of user ILP32 iovec struct */
  76 
  77 typedef struct iovec32 {
  78         caddr32_t       iov_base;
  79         int32_t         iov_len;
  80 } iovec32_t;
  81 
  82 #endif  /* _SYSCALL32 */
  83 
  84 #if     !defined(_XPG4_2) || defined(__EXTENSIONS__)
  85 /*
  86  * Segment flag values.
  87  */
  88 typedef enum uio_seg { UIO_USERSPACE, UIO_SYSSPACE, UIO_USERISPACE } uio_seg_t;
  89 
  90 typedef struct uio {
  91         iovec_t         *uio_iov;       /* pointer to array of iovecs */
  92         int             uio_iovcnt;     /* number of iovecs */
  93         lloff_t         _uio_offset;    /* file offset */
  94         uio_seg_t       uio_segflg;     /* address space (kernel or user) */
  95         uint16_t        uio_fmode;      /* file mode flags */
  96         uint16_t        uio_extflg;     /* extended flags */
  97         lloff_t         _uio_limit;     /* u-limit (maximum byte offset) */
  98         ssize_t         uio_resid;      /* residual count */
  99 } uio_t;
 100 
 101 /*
 102  * Extended uio_t uioa_t used for asynchronous uio.
 103  *
 104  * Note: UIOA_IOV_MAX is defined and used as it is in "fs/vncalls.c"
 105  *       as there isn't a formal definition of IOV_MAX for the kernel.
 106  */
 107 #define UIOA_IOV_MAX    16
 108 
 109 typedef struct uioa_page_s {            /* locked uio_iov state */
 110         int     uioa_pfncnt;            /* count of pfn_t(s) in *uioa_ppp */
 111         void    **uioa_ppp;             /* page_t or pfn_t arrary */
 112         caddr_t uioa_base;              /* address base */
 113         size_t  uioa_len;               /* span length */
 114 } uioa_page_t;
 115 
 116 typedef struct uioa_s {
 117         iovec_t         *uio_iov;       /* pointer to array of iovecs */
 118         int             uio_iovcnt;     /* number of iovecs */
 119         lloff_t         _uio_offset;    /* file offset */
 120         uio_seg_t       uio_segflg;     /* address space (kernel or user) */
 121         uint16_t        uio_fmode;      /* file mode flags */
 122         uint16_t        uio_extflg;     /* extended flags */
 123         lloff_t         _uio_limit;     /* u-limit (maximum byte offset) */
 124         ssize_t         uio_resid;      /* residual count */
 125         /*
 126          * uioa extended members.
 127          */
 128         uint32_t        uioa_state;     /* state of asynch i/o */
 129         ssize_t         uioa_mbytes;    /* bytes that have been uioamove()ed */
 130         uioa_page_t     *uioa_lcur;     /* pointer into uioa_locked[] */
 131         void            **uioa_lppp;    /* pointer into lcur->uioa_ppp[] */
 132         void            *uioa_hwst[4];  /* opaque hardware state */
 133         uioa_page_t     uioa_locked[UIOA_IOV_MAX]; /* Per iov locked pages */
 134 } uioa_t;
 135 
 136 /*
 137  * uio extensions
 138  *
 139  * PSARC 2009/478: Copy Reduction Interfaces
 140  */
 141 typedef enum xuio_type {
 142         UIOTYPE_ASYNCIO,
 143         UIOTYPE_ZEROCOPY
 144 } xuio_type_t;
 145 
 146 typedef struct xuio {
 147         uio_t xu_uio;           /* Embedded UIO structure */
 148 
 149         /* Extended uio fields */
 150         enum xuio_type xu_type; /* What kind of uio structure? */
 151         union {
 152                 /* Async I/O Support, intend to replace uioa_t. */
 153                 struct {
 154                         uint32_t xu_a_state;    /* state of async i/o */
 155                         /* bytes that have been uioamove()ed */
 156                         ssize_t xu_a_mbytes;
 157                         uioa_page_t *xu_a_lcur; /* pointer into uioa_locked[] */
 158                         /* pointer into lcur->uioa_ppp[] */
 159                         void **xu_a_lppp;
 160                         void *xu_a_hwst[4];     /* opaque hardware state */
 161                         /* Per iov locked pages */
 162                         uioa_page_t xu_a_locked[UIOA_IOV_MAX];
 163                 } xu_aio;
 164 
 165                 /*
 166                  * Copy Reduction Support -- facilate loaning / returning of
 167                  * filesystem cache buffers.
 168                  */
 169                 struct {
 170                         int xu_zc_rw;   /* read or write buffer */
 171                         void *xu_zc_priv;       /* fs specific */
 172                 } xu_zc;
 173         } xu_ext;
 174 } xuio_t;
 175 
 176 #define XUIO_XUZC_PRIV(xuio)    xuio->xu_ext.xu_zc.xu_zc_priv
 177 #define XUIO_XUZC_RW(xuio)      xuio->xu_ext.xu_zc.xu_zc_rw
 178 
 179 #define UIOA_ALLOC      0x0001          /* allocated but not yet initialized */
 180 #define UIOA_INIT       0x0002          /* initialized but not yet enabled */
 181 #define UIOA_ENABLED    0x0004          /* enabled, asynch i/o active */
 182 #define UIOA_FINI       0x0008          /* finished waiting for uioafini() */
 183 
 184 #define UIOA_CLR        (~0x000F)       /* clear mutually exclusive bits */
 185 
 186 #define UIOA_POLL       0x0010          /* need dcopy_poll() */
 187 
 188 #define uio_loffset     _uio_offset._f
 189 #if !defined(_LP64)
 190 #define uio_offset      _uio_offset._p._l
 191 #else
 192 #define uio_offset      uio_loffset
 193 #endif
 194 
 195 #define uio_llimit      _uio_limit._f
 196 #if !defined(_LP64)
 197 #define uio_limit       _uio_limit._p._l
 198 #else
 199 #define uio_limit       uio_llimit
 200 #endif
 201 
 202 /*
 203  * I/O direction.
 204  */
 205 typedef enum uio_rw { UIO_READ, UIO_WRITE } uio_rw_t;
 206 
 207 /*
 208  * uio_extflg: extended flags
 209  *
 210  * NOTE: This flag will be used in uiomove to determine if non-temporal
 211  * access, ie, access bypassing caches, should be used.  Filesystems that
 212  * don't initialize this field could experience suboptimal performance due to
 213  * the random data the field contains.
 214  *
 215  * NOTE: This flag is also used by uioasync callers to pass an extended
 216  * uio_t (uioa_t), to uioasync enabled consumers. Unlike above all
 217  * consumers of a uioa_t require the uio_extflg to be initialized.
 218  */
 219 #define UIO_COPY_DEFAULT        0x0000  /* no special options to copy */
 220 #define UIO_COPY_CACHED         0x0001  /* copy should not bypass caches */
 221 
 222 #define UIO_ASYNC               0x0002  /* uio_t is really a uioa_t */
 223 #define UIO_XUIO                0x0004  /* Structure is xuio_t */
 224 
 225 /*
 226  * Global uioasync capability shadow state.
 227  */
 228 typedef struct uioasync_s {
 229         boolean_t       enabled;        /* Is uioasync enabled? */
 230         size_t          mincnt;         /* Minimum byte count for use of */
 231 } uioasync_t;
 232 
 233 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
 234 
 235 #if     defined(_KERNEL)
 236 
 237 int     uiomove(void *, size_t, enum uio_rw, uio_t *);
 238 void    uio_prefaultpages(ssize_t, uio_t *);
 239 int     uiocopy(void *, size_t, enum uio_rw, uio_t *, size_t *);
 240 int     ureadc(int, uio_t *);   /* should be errno_t in future */
 241 int     uwritec(struct uio *);
 242 void    uioskip(uio_t *, size_t);
 243 int     uiodup(uio_t *, uio_t *, iovec_t *, int);
 244 
 245 int     uioamove(void *, size_t, enum uio_rw, uioa_t *);
 246 int     uioainit(uio_t *, uioa_t *);
 247 int     uioafini(uio_t *, uioa_t *);
 248 extern  uioasync_t uioasync;
 249 
 250 #else   /* defined(_KERNEL) */
 251 
 252 #if     defined(__STDC__)
 253 
 254 extern ssize_t readv(int, const struct iovec *, int);
 255 extern ssize_t writev(int, const struct iovec *, int);
 256 
 257 #else   /* defined(__STDC__) */
 258 
 259 extern ssize_t readv();
 260 extern ssize_t writev();
 261 
 262 #endif  /* defined(__STDC__) */
 263 
 264 #endif  /* defined(_KERNEL) */
 265 
 266 #ifdef  __cplusplus
 267 }
 268 #endif
 269 
 270 #endif  /* _SYS_UIO_H */