1 /** @file 2 The EFI kernel's interpretation of a "file". 3 4 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials are licensed and made available 6 under the terms and conditions of the BSD License which accompanies this 7 distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php. 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 * Copyright (c) 1982, 1986, 1989, 1993 14 * The Regents of the University of California. All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * file.h 8.3 (Berkeley) 1/9/95 41 NetBSD: file.h,v 1.56 2006/05/14 21:38:18 elad Exp 42 **/ 43 #ifndef _PIF_KFILE_H_ 44 #define _PIF_KFILE_H_ 45 46 #include <Uefi.h> 47 #include <Protocol/SimpleTextOut.h> 48 #include <Protocol/SimpleFileSystem.h> 49 50 #include <wchar.h> 51 #include <stdarg.h> 52 #include <sys/fcntl.h> 53 #include <sys/unistd.h> 54 55 struct stat; 56 struct fileops; 57 struct _Device_Node; 58 59 /* The number of "special" character stream devices. 60 These include: 61 stdin, stdout, stderr 62 */ 63 #define NUM_SPECIAL 3 64 65 /* Organization of the f_iflags member of the __filedes structure. */ 66 #define DTYPE_MASK 0x00000007 ///< Device Type 67 #define DTYPE_VNODE 1 /* file */ 68 #define DTYPE_SOCKET 2 /* communications endpoint */ 69 #define DTYPE_PIPE 3 /* pipe */ 70 #define DTYPE_KQUEUE 4 /* event queue */ 71 #define DTYPE_MISC 5 /* misc file descriptor type */ 72 #define DTYPE_CRYPTO 6 /* crypto */ 73 #define DTYPE_NAMES "0", "file", "socket", "pipe", "kqueue", "misc", "crypto" 74 75 #define FIF_WANTCLOSE 0x10000000 /* a close is waiting for usecount */ 76 #define FIF_DELCLOSE 0x20000000 /* Delete on close. */ 77 #define FIF_LARVAL 0x80000000 /* not fully constructed; don't use */ 78 79 /* 80 This structure must be a multiple of 8 bytes in length. 81 */ 82 struct __filedes { 83 off_t f_offset; /* current position in file */ 84 const struct fileops *f_ops; 85 86 /* The devdata member has different meanings depending upon whether 87 a block oriented or character oriented device is being accessed. 88 For block devices, devdata holds an EFI handle to the open file or directory. 89 For character devices, devdata points to the device's IIO structure, 90 if it has one. It may be NULL indicating a non-interactive character 91 device. 92 */ 93 void *devdata; /* Device-specific data */ 94 int Oflags; // From the open call, see fcntl.h 95 int Omode; // From the open call 96 int RefCount; // Reference count of opens 97 UINT32 f_flag; /* see fcntl.h */ 98 UINT32 f_iflags; // In use if non-zero 99 UINT16 MyFD; // Which FD this is. 100 UINT16 Reserved_1; // Force this structure to be a multiple of 8-bytes in length 101 }; 102 103 struct fileops { 104 /* These functions must always be implemented. */ 105 106 /** Perform device specific operations for closing the device. 107 It is the responsibility of this function to flush or discard 108 buffer contents. 109 **/ 110 int (EFIAPI *fo_close) (struct __filedes *filp); 111 112 ssize_t (EFIAPI *fo_read) (struct __filedes *filp, off_t *Offset, size_t Len, void *Buf); 113 ssize_t (EFIAPI *fo_write) (struct __filedes *filp, off_t *Offset, size_t Len, const void *Buf); 114 115 /* Call the fnullop_* version of these functions if not implemented by the device. */ 116 int (EFIAPI *fo_fcntl) (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4); 117 short (EFIAPI *fo_poll) (struct __filedes *filp, short Events); 118 int (EFIAPI *fo_flush) (struct __filedes *filp); 119 120 /* Call the fbadop_* version of these functions if not implemented by the device. */ 121 int (EFIAPI *fo_stat) (struct __filedes *filp, struct stat *StatBuf, void *Buf); 122 int (EFIAPI *fo_ioctl) (struct __filedes *filp, ULONGN Cmd, va_list argp); 123 int (EFIAPI *fo_delete) (struct __filedes *filp); 124 int (EFIAPI *fo_rmdir) (struct __filedes *filp); 125 int (EFIAPI *fo_mkdir) (const char *path, __mode_t perms); 126 int (EFIAPI *fo_rename) (const char *from, const char *to); 127 128 /* Use a NULL if this function has not been implemented by the device. */ 129 off_t (EFIAPI *fo_lseek) (struct __filedes *filp, off_t, int); 130 }; 131 132 /* A generic instance structure which is valid 133 for all device instance structures. 134 135 All device instance structures MUST be a multiple of 8-bytes in length. 136 */ 137 typedef struct { 138 UINT32 Cookie; ///< Special value identifying this as a valid Instance 139 UINT32 InstanceNum; ///< Which instance is this? Zero-based. 140 EFI_HANDLE Dev; ///< Pointer to either Input or Output Protocol. 141 struct _Device_Node *Parent; ///< Points to the parent Device Node. 142 struct fileops Abstraction; ///< Pointers to functions implementing this device's abstraction. 143 UINTN Reserved_1; // Force this to always be a multiple of 8-bytes in length 144 } GenericInstance; 145 146 /* Type of all Device-specific handler's open routines. */ 147 typedef 148 int (EFIAPI *FO_OPEN) (struct _Device_Node *This, struct __filedes *FD, 149 int Instance, wchar_t *Path, wchar_t *MPath); 150 151 #define FILE_IS_USABLE(fp) (((fp)->f_iflags & \ 152 (FIF_WANTCLOSE|FIF_LARVAL)) == 0) 153 154 #define FILE_SET_MATURE(fp) \ 155 do { \ 156 (fp)->f_iflags &= ~FIF_LARVAL; \ 157 } while (/*CONSTCOND*/0) 158 159 /* 160 * Flags for fo_read and fo_write. 161 */ 162 #define FOF_UPDATE_OFFSET 0x01 /* update the file offset */ 163 164 __BEGIN_DECLS 165 166 int fdcreate (CHAR16 *, UINT32, UINT32, BOOLEAN, VOID *, const struct fileops *); 167 168 /* Commonly used fileops 169 fnullop_* Does nothing and returns success. 170 fbadop_* Does nothing and returns EPERM 171 */ 172 int EFIAPI fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4); 173 short EFIAPI fnullop_poll (struct __filedes *filp, short Events); 174 int EFIAPI fnullop_flush (struct __filedes *filp); 175 176 int EFIAPI fbadop_stat (struct __filedes *filp, struct stat *StatBuf, void *Buf); 177 int EFIAPI fbadop_ioctl (struct __filedes *filp, ULONGN Cmd, va_list argp); 178 int EFIAPI fbadop_delete (struct __filedes *filp); 179 int EFIAPI fbadop_rmdir (struct __filedes *filp); 180 int EFIAPI fbadop_mkdir (const char *path, __mode_t perms); 181 int EFIAPI fbadop_rename (const char *from, const char *to); 182 183 __END_DECLS 184 185 /* From the original file... */ 186 #if 0 187 188 //struct proc; 189 //struct lwp; 190 //struct uio; 191 //struct iovec; 192 //struct knote; 193 194 //LIST_HEAD(filelist, file); 195 //extern struct filelist filehead; /* head of list of open files */ 196 //extern int maxfiles; /* kernel limit on # of open files */ 197 //extern int nfiles; /* actual number of open files */ 198 199 //extern const struct fileops vnops; /* vnode operations for files */ 200 201 struct fileops { 202 int (*fo_read) (struct file *, off_t *, struct uio *, kauth_cred_t, int); 203 int (*fo_write) (struct file *, off_t *, struct uio *, kauth_cred_t, int); 204 int (*fo_ioctl) (struct file *, u_long, void *, struct lwp *); 205 int (*fo_fcntl) (struct file *, u_int, void *, struct lwp *); 206 int (*fo_poll) (struct file *, int, struct lwp *); 207 int (*fo_stat) (struct file *, struct stat *, struct lwp *); 208 int (*fo_close) (struct file *, struct lwp *); 209 }; 210 211 /* 212 * Kernel descriptor table. 213 * One entry for each open kernel vnode and socket. 214 */ 215 struct file { 216 LIST_ENTRY(file) f_list; /* list of active files */ 217 void *f_data; /* descriptor data, e.g. vnode/socket */ 218 const struct fileops *f_ops; 219 void *f_DevDesc; /* Device Descriptor pointer */ 220 EFI_FILE_HANDLE FileHandle; 221 EFI_HANDLE Handle; 222 off_t f_offset; /* current position in file */ 223 int f_flag; /* see fcntl.h */ 224 UINT32 f_iflags; /* internal flags; FIF_* */ 225 int f_advice; /* access pattern hint; UVM_ADV_* */ 226 int f_type; /* descriptor type */ 227 int f_usecount; /* number active users */ 228 u_int f_count; /* reference count */ 229 u_int f_msgcount; /* references from message queue */ 230 // kauth_cred_t f_cred; /* creds associated with descriptor */ 231 struct simplelock f_slock; 232 UINT16 MyFD; /* Which FD this is. */ 233 }; 234 235 #ifdef DIAGNOSTIC 236 #define FILE_USE_CHECK(fp, str) \ 237 do { \ 238 if ((fp)->f_usecount < 0) \ 239 panic(str); \ 240 } while (/* CONSTCOND */ 0) 241 #else 242 #define FILE_USE_CHECK(fp, str) /* nothing */ 243 #endif 244 245 /* 246 * FILE_USE() must be called with the file lock held. 247 * (Typical usage is: `fp = fd_getfile(..); FILE_USE(fp);' 248 * and fd_getfile() returns the file locked) 249 * 250 * fp is a pointer to a __filedes structure. 251 */ 252 #define FILE_USE(fp) \ 253 do { \ 254 (fp)->f_usecount++; \ 255 FILE_USE_CHECK((fp), "f_usecount overflow"); \ 256 simple_unlock(&(fp)->f_slock); \ 257 } while (/* CONSTCOND */ 0) 258 259 #define FILE_UNUSE_WLOCK(fp, l, havelock) \ 260 do { \ 261 if (!(havelock)) \ 262 simple_lock(&(fp)->f_slock); \ 263 if ((fp)->f_iflags & FIF_WANTCLOSE) { \ 264 simple_unlock(&(fp)->f_slock); \ 265 /* Will drop usecount */ \ 266 (void) closef((fp), (l)); \ 267 break; \ 268 } else { \ 269 (fp)->f_usecount--; \ 270 FILE_USE_CHECK((fp), "f_usecount underflow"); \ 271 } \ 272 simple_unlock(&(fp)->f_slock); \ 273 } while (/* CONSTCOND */ 0) 274 275 #define FILE_UNUSE(fp, l) FILE_UNUSE_WLOCK(fp, l, 0) 276 #define FILE_UNUSE_HAVELOCK(fp, l) FILE_UNUSE_WLOCK(fp, l, 1) 277 278 __BEGIN_DECLS 279 //int dofileread (struct lwp *, int, struct file *, void *, size_t, off_t *, int, register_t *); 280 //int dofilewrite (struct lwp *, int, struct file *, const void *, size_t, off_t *, int, register_t *); 281 282 //int dofilereadv (struct lwp *, int, struct file *, const struct iovec *, int, off_t *, int, register_t *); 283 //int dofilewritev(struct lwp *, int, struct file *, const struct iovec *, int, off_t *, int, register_t *); 284 285 //int fsetown (struct proc *, pid_t *, int, const void *); 286 //int fgetown (struct proc *, pid_t, int, void *); 287 //void fownsignal (pid_t, int, int, int, void *); 288 289 //int fdclone (struct lwp *, struct file *, int, int, const struct fileops *, void *); 290 291 /* Commonly used fileops 292 fnullop_* Does nothing and returns success. 293 fbadop_* Does nothing and returns EPERM 294 */ 295 //int fnullop_fcntl (struct file *, u_int, void *, struct lwp *); 296 //int fnullop_poll (struct file *, int, struct lwp *); 297 //int fnullop_kqfilter(struct file *, struct knote *); 298 //int fbadop_stat (struct file *, struct stat *, struct lwp *); 299 //int fbadop_ioctl (struct file *, u_long, void *, struct lwp *); 300 __END_DECLS 301 302 #endif 303 304 #endif /* _PIF_KFILE_H_ */ 305