162052Smarkm/*- 262052Smarkm * Copyright (c) 2000 Mark R. V. Murray & Jeroen C. van Gelderen 3130788Smarkm * Copyright (c) 2001-2004 Mark R. V. Murray 462052Smarkm * All rights reserved. 562052Smarkm * 662052Smarkm * Redistribution and use in source and binary forms, with or without 762052Smarkm * modification, are permitted provided that the following conditions 862052Smarkm * are met: 962052Smarkm * 1. Redistributions of source code must retain the above copyright 1062052Smarkm * notice, this list of conditions and the following disclaimer 1162052Smarkm * in this position and unchanged. 1262052Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1362052Smarkm * notice, this list of conditions and the following disclaimer in the 1462052Smarkm * documentation and/or other materials provided with the distribution. 1562052Smarkm * 1662052Smarkm * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 1762052Smarkm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1862052Smarkm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1962052Smarkm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2062052Smarkm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2162052Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2262052Smarkm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2362052Smarkm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2462052Smarkm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2562052Smarkm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2662052Smarkm * 2762052Smarkm */ 2862052Smarkm 29119418Sobrien#include <sys/cdefs.h> 30119418Sobrien__FBSDID("$FreeBSD$"); 31119418Sobrien 3262052Smarkm#include <sys/param.h> 3362052Smarkm#include <sys/systm.h> 3462052Smarkm#include <sys/conf.h> 3562052Smarkm#include <sys/uio.h> 3662052Smarkm#include <sys/kernel.h> 3762052Smarkm#include <sys/malloc.h> 3862052Smarkm#include <sys/module.h> 39164033Srwatson#include <sys/priv.h> 4094182Sphk#include <sys/disk.h> 4162052Smarkm#include <sys/bus.h> 42229965Sgnn#include <sys/filio.h> 43221855Smdf 4462052Smarkm#include <machine/bus.h> 45221855Smdf#include <machine/vmparam.h> 4662052Smarkm 4762052Smarkm/* For use with destroy_dev(9). */ 48130585Sphkstatic struct cdev *null_dev; 49130585Sphkstatic struct cdev *zero_dev; 5062052Smarkm 5162843Smarkmstatic d_write_t null_write; 5293496Sphkstatic d_ioctl_t null_ioctl; 53229965Sgnnstatic d_ioctl_t zero_ioctl; 5462843Smarkmstatic d_read_t zero_read; 5562052Smarkm 5662052Smarkmstatic struct cdevsw null_cdevsw = { 57126080Sphk .d_version = D_VERSION, 58121856Smarkm .d_read = (d_read_t *)nullop, 59111815Sphk .d_write = null_write, 60111815Sphk .d_ioctl = null_ioctl, 61111815Sphk .d_name = "null", 6262052Smarkm}; 6362052Smarkm 6462052Smarkmstatic struct cdevsw zero_cdevsw = { 65126080Sphk .d_version = D_VERSION, 66111815Sphk .d_read = zero_read, 67111815Sphk .d_write = null_write, 68229965Sgnn .d_ioctl = zero_ioctl, 69111815Sphk .d_name = "zero", 70126080Sphk .d_flags = D_MMAP_ANON, 7162052Smarkm}; 7262052Smarkm 73121189Smarkm/* ARGSUSED */ 74111758Sphkstatic int 75130585Sphknull_write(struct cdev *dev __unused, struct uio *uio, int flags __unused) 7662052Smarkm{ 7762052Smarkm uio->uio_resid = 0; 78130788Smarkm 79130788Smarkm return (0); 8062052Smarkm} 8162052Smarkm 82121189Smarkm/* ARGSUSED */ 8362052Smarkmstatic int 84130585Sphknull_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused, 85121189Smarkm int flags __unused, struct thread *td) 8693496Sphk{ 8793496Sphk int error; 88229965Sgnn error = 0; 8993496Sphk 90229965Sgnn switch (cmd) { 91229965Sgnn case DIOCSKERNELDUMP: 92229965Sgnn error = priv_check(td, PRIV_SETDUMPER); 93229965Sgnn if (error == 0) 94242439Salfred error = set_dumper(NULL, NULL); 95229965Sgnn break; 96229965Sgnn case FIONBIO: 97229965Sgnn break; 98229965Sgnn case FIOASYNC: 99229965Sgnn if (*(int *)data != 0) 100229965Sgnn error = EINVAL; 101229965Sgnn break; 102229965Sgnn default: 103229965Sgnn error = ENOIOCTL; 104229965Sgnn } 105229965Sgnn return (error); 10693496Sphk} 10793496Sphk 108111630Smarkm/* ARGSUSED */ 10993496Sphkstatic int 110229965Sgnnzero_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused, 111229965Sgnn int flags __unused, struct thread *td) 112229965Sgnn{ 113229965Sgnn int error; 114229965Sgnn error = 0; 115229965Sgnn 116229965Sgnn switch (cmd) { 117229965Sgnn case FIONBIO: 118229965Sgnn break; 119229965Sgnn case FIOASYNC: 120229965Sgnn if (*(int *)data != 0) 121229965Sgnn error = EINVAL; 122229965Sgnn break; 123229965Sgnn default: 124229965Sgnn error = ENOIOCTL; 125229965Sgnn } 126229965Sgnn return (error); 127229965Sgnn} 128229965Sgnn 129229965Sgnn 130229965Sgnn/* ARGSUSED */ 131229965Sgnnstatic int 132130585Sphkzero_read(struct cdev *dev __unused, struct uio *uio, int flags __unused) 13362052Smarkm{ 134221853Smdf void *zbuf; 135221853Smdf ssize_t len; 13662052Smarkm int error = 0; 13762052Smarkm 138221853Smdf KASSERT(uio->uio_rw == UIO_READ, 139221853Smdf ("Can't be in %s for write", __func__)); 140221853Smdf zbuf = __DECONST(void *, zero_region); 141221853Smdf while (uio->uio_resid > 0 && error == 0) { 142221853Smdf len = uio->uio_resid; 143221853Smdf if (len > ZERO_REGION_SIZE) 144221853Smdf len = ZERO_REGION_SIZE; 145221853Smdf error = uiomove(zbuf, len, uio); 146221853Smdf } 147130788Smarkm 148130788Smarkm return (error); 14962052Smarkm} 15062052Smarkm 151111630Smarkm/* ARGSUSED */ 15262052Smarkmstatic int 153111630Smarkmnull_modevent(module_t mod __unused, int type, void *data __unused) 15462052Smarkm{ 15562052Smarkm switch(type) { 15662052Smarkm case MOD_LOAD: 15762052Smarkm if (bootverbose) 15866709Sjhb printf("null: <null device, zero device>\n"); 159210926Skib null_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &null_cdevsw, 0, 160210926Skib NULL, UID_ROOT, GID_WHEEL, 0666, "null"); 161210926Skib zero_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &zero_cdevsw, 0, 162210926Skib NULL, UID_ROOT, GID_WHEEL, 0666, "zero"); 163130788Smarkm break; 16462052Smarkm 16562052Smarkm case MOD_UNLOAD: 16662052Smarkm destroy_dev(null_dev); 16762052Smarkm destroy_dev(zero_dev); 168130788Smarkm break; 16962052Smarkm 17062052Smarkm case MOD_SHUTDOWN: 171130788Smarkm break; 17262052Smarkm 173132199Sphk default: 174132199Sphk return (EOPNOTSUPP); 17562052Smarkm } 176130788Smarkm 177130788Smarkm return (0); 17862052Smarkm} 17962052Smarkm 18066560SjhbDEV_MODULE(null, null_modevent, NULL); 181133033SmarkmMODULE_VERSION(null, 1); 182