1f6011da8SMark Murray /*- 2f6011da8SMark Murray * Copyright (c) 2000 Mark R. V. Murray & Jeroen C. van Gelderen 344562634SMark Murray * Copyright (c) 2001-2004 Mark R. V. Murray 4a345aa59SEitan Adler * Copyright (c) 2014 Eitan Adler 5f6011da8SMark Murray * All rights reserved. 6f6011da8SMark Murray * 7f6011da8SMark Murray * Redistribution and use in source and binary forms, with or without 8f6011da8SMark Murray * modification, are permitted provided that the following conditions 9f6011da8SMark Murray * are met: 10f6011da8SMark Murray * 1. Redistributions of source code must retain the above copyright 11f6011da8SMark Murray * notice, this list of conditions and the following disclaimer 12f6011da8SMark Murray * in this position and unchanged. 13f6011da8SMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14f6011da8SMark Murray * notice, this list of conditions and the following disclaimer in the 15f6011da8SMark Murray * documentation and/or other materials provided with the distribution. 16f6011da8SMark Murray * 17f6011da8SMark Murray * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 18f6011da8SMark Murray * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19f6011da8SMark Murray * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20f6011da8SMark Murray * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21f6011da8SMark Murray * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22f6011da8SMark Murray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23f6011da8SMark Murray * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24f6011da8SMark Murray * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25f6011da8SMark Murray * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26f6011da8SMark Murray * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27f6011da8SMark Murray * 28f6011da8SMark Murray */ 29f6011da8SMark Murray 30aad970f1SDavid E. O'Brien #include <sys/cdefs.h> 31aad970f1SDavid E. O'Brien __FBSDID("$FreeBSD$"); 32aad970f1SDavid E. O'Brien 33f6011da8SMark Murray #include <sys/param.h> 34f6011da8SMark Murray #include <sys/systm.h> 35f6011da8SMark Murray #include <sys/conf.h> 36f6011da8SMark Murray #include <sys/uio.h> 37f6011da8SMark Murray #include <sys/kernel.h> 38f6011da8SMark Murray #include <sys/malloc.h> 39f6011da8SMark Murray #include <sys/module.h> 40acd3428bSRobert Watson #include <sys/priv.h> 412dd527b3SPoul-Henning Kamp #include <sys/disk.h> 42f6011da8SMark Murray #include <sys/bus.h> 43844d43d9SGeorge V. Neville-Neil #include <sys/filio.h> 44cfb00e5aSMatthew D Fleming 45f6011da8SMark Murray #include <machine/bus.h> 46cfb00e5aSMatthew D Fleming #include <machine/vmparam.h> 47f6011da8SMark Murray 48f6011da8SMark Murray /* For use with destroy_dev(9). */ 497a07ae0aSEitan Adler static struct cdev *full_dev; 5089c9c53dSPoul-Henning Kamp static struct cdev *null_dev; 5189c9c53dSPoul-Henning Kamp static struct cdev *zero_dev; 52f6011da8SMark Murray 53a345aa59SEitan Adler static d_write_t full_write; 5411197ed1SMark Murray static d_write_t null_write; 5581661c94SPoul-Henning Kamp static d_ioctl_t null_ioctl; 56844d43d9SGeorge V. Neville-Neil static d_ioctl_t zero_ioctl; 5711197ed1SMark Murray static d_read_t zero_read; 58f6011da8SMark Murray 597a07ae0aSEitan Adler static struct cdevsw full_cdevsw = { 607a07ae0aSEitan Adler .d_version = D_VERSION, 617a07ae0aSEitan Adler .d_read = zero_read, 627a07ae0aSEitan Adler .d_write = full_write, 637a07ae0aSEitan Adler .d_ioctl = zero_ioctl, 647a07ae0aSEitan Adler .d_name = "full", 657a07ae0aSEitan Adler }; 667a07ae0aSEitan Adler 67f6011da8SMark Murray static struct cdevsw null_cdevsw = { 68dc08ffecSPoul-Henning Kamp .d_version = D_VERSION, 694e0a104fSMark Murray .d_read = (d_read_t *)nullop, 707ac40f5fSPoul-Henning Kamp .d_write = null_write, 717ac40f5fSPoul-Henning Kamp .d_ioctl = null_ioctl, 727ac40f5fSPoul-Henning Kamp .d_name = "null", 73f6011da8SMark Murray }; 74f6011da8SMark Murray 75f6011da8SMark Murray static struct cdevsw zero_cdevsw = { 76dc08ffecSPoul-Henning Kamp .d_version = D_VERSION, 777ac40f5fSPoul-Henning Kamp .d_read = zero_read, 787ac40f5fSPoul-Henning Kamp .d_write = null_write, 79844d43d9SGeorge V. Neville-Neil .d_ioctl = zero_ioctl, 807ac40f5fSPoul-Henning Kamp .d_name = "zero", 81dc08ffecSPoul-Henning Kamp .d_flags = D_MMAP_ANON, 82f6011da8SMark Murray }; 83f6011da8SMark Murray 84a345aa59SEitan Adler 85a345aa59SEitan Adler 86a345aa59SEitan Adler /* ARGSUSED */ 87a345aa59SEitan Adler static int 88*9ca1db65SEitan Adler full_write(struct cdev *dev __unused, struct uio *uio __unused, int flags __unused) 89a345aa59SEitan Adler { 90a345aa59SEitan Adler 91a345aa59SEitan Adler return (ENOSPC); 92a345aa59SEitan Adler } 93a345aa59SEitan Adler 948f559ca0SMark Murray /* ARGSUSED */ 95a36ef7f3SPoul-Henning Kamp static int 9689c9c53dSPoul-Henning Kamp null_write(struct cdev *dev __unused, struct uio *uio, int flags __unused) 97f6011da8SMark Murray { 98f6011da8SMark Murray uio->uio_resid = 0; 9944562634SMark Murray 10044562634SMark Murray return (0); 101f6011da8SMark Murray } 102f6011da8SMark Murray 1038f559ca0SMark Murray /* ARGSUSED */ 104f6011da8SMark Murray static int 10589c9c53dSPoul-Henning Kamp null_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused, 1068f559ca0SMark Murray int flags __unused, struct thread *td) 10781661c94SPoul-Henning Kamp { 10881661c94SPoul-Henning Kamp int error; 109844d43d9SGeorge V. Neville-Neil error = 0; 11081661c94SPoul-Henning Kamp 111844d43d9SGeorge V. Neville-Neil switch (cmd) { 112844d43d9SGeorge V. Neville-Neil case DIOCSKERNELDUMP: 113acd3428bSRobert Watson error = priv_check(td, PRIV_SETDUMPER); 114844d43d9SGeorge V. Neville-Neil if (error == 0) 115bad7e7f3SAlfred Perlstein error = set_dumper(NULL, NULL); 116844d43d9SGeorge V. Neville-Neil break; 117844d43d9SGeorge V. Neville-Neil case FIONBIO: 118844d43d9SGeorge V. Neville-Neil break; 119844d43d9SGeorge V. Neville-Neil case FIOASYNC: 120844d43d9SGeorge V. Neville-Neil if (*(int *)data != 0) 121844d43d9SGeorge V. Neville-Neil error = EINVAL; 122844d43d9SGeorge V. Neville-Neil break; 123844d43d9SGeorge V. Neville-Neil default: 124844d43d9SGeorge V. Neville-Neil error = ENOIOCTL; 12581661c94SPoul-Henning Kamp } 126844d43d9SGeorge V. Neville-Neil return (error); 127844d43d9SGeorge V. Neville-Neil } 128844d43d9SGeorge V. Neville-Neil 129844d43d9SGeorge V. Neville-Neil /* ARGSUSED */ 130844d43d9SGeorge V. Neville-Neil static int 131844d43d9SGeorge V. Neville-Neil zero_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused, 132844d43d9SGeorge V. Neville-Neil int flags __unused, struct thread *td) 133844d43d9SGeorge V. Neville-Neil { 134844d43d9SGeorge V. Neville-Neil int error; 135844d43d9SGeorge V. Neville-Neil error = 0; 136844d43d9SGeorge V. Neville-Neil 137844d43d9SGeorge V. Neville-Neil switch (cmd) { 138844d43d9SGeorge V. Neville-Neil case FIONBIO: 139844d43d9SGeorge V. Neville-Neil break; 140844d43d9SGeorge V. Neville-Neil case FIOASYNC: 141844d43d9SGeorge V. Neville-Neil if (*(int *)data != 0) 142844d43d9SGeorge V. Neville-Neil error = EINVAL; 143844d43d9SGeorge V. Neville-Neil break; 144844d43d9SGeorge V. Neville-Neil default: 145844d43d9SGeorge V. Neville-Neil error = ENOIOCTL; 146844d43d9SGeorge V. Neville-Neil } 147844d43d9SGeorge V. Neville-Neil return (error); 148844d43d9SGeorge V. Neville-Neil } 149844d43d9SGeorge V. Neville-Neil 15081661c94SPoul-Henning Kamp 151ef8b020cSMark Murray /* ARGSUSED */ 15281661c94SPoul-Henning Kamp static int 15389c9c53dSPoul-Henning Kamp zero_read(struct cdev *dev __unused, struct uio *uio, int flags __unused) 154f6011da8SMark Murray { 15589cb2a19SMatthew D Fleming void *zbuf; 15689cb2a19SMatthew D Fleming ssize_t len; 157f6011da8SMark Murray int error = 0; 158f6011da8SMark Murray 15989cb2a19SMatthew D Fleming KASSERT(uio->uio_rw == UIO_READ, 16089cb2a19SMatthew D Fleming ("Can't be in %s for write", __func__)); 16189cb2a19SMatthew D Fleming zbuf = __DECONST(void *, zero_region); 16289cb2a19SMatthew D Fleming while (uio->uio_resid > 0 && error == 0) { 16389cb2a19SMatthew D Fleming len = uio->uio_resid; 16489cb2a19SMatthew D Fleming if (len > ZERO_REGION_SIZE) 16589cb2a19SMatthew D Fleming len = ZERO_REGION_SIZE; 16689cb2a19SMatthew D Fleming error = uiomove(zbuf, len, uio); 16789cb2a19SMatthew D Fleming } 16844562634SMark Murray 16944562634SMark Murray return (error); 170f6011da8SMark Murray } 171f6011da8SMark Murray 172ef8b020cSMark Murray /* ARGSUSED */ 173f6011da8SMark Murray static int 174ef8b020cSMark Murray null_modevent(module_t mod __unused, int type, void *data __unused) 175f6011da8SMark Murray { 176f6011da8SMark Murray switch(type) { 177f6011da8SMark Murray case MOD_LOAD: 178f6011da8SMark Murray if (bootverbose) 179a345aa59SEitan Adler printf("null: <full device, null device, zero device>\n"); 180a345aa59SEitan Adler full_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &full_cdevsw, 0, 181a345aa59SEitan Adler NULL, UID_ROOT, GID_WHEEL, 0666, "full"); 182f53444bcSKonstantin Belousov null_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &null_cdevsw, 0, 183f53444bcSKonstantin Belousov NULL, UID_ROOT, GID_WHEEL, 0666, "null"); 184f53444bcSKonstantin Belousov zero_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &zero_cdevsw, 0, 185f53444bcSKonstantin Belousov NULL, UID_ROOT, GID_WHEEL, 0666, "zero"); 18644562634SMark Murray break; 187f6011da8SMark Murray 188f6011da8SMark Murray case MOD_UNLOAD: 189a345aa59SEitan Adler destroy_dev(full_dev); 190f6011da8SMark Murray destroy_dev(null_dev); 191f6011da8SMark Murray destroy_dev(zero_dev); 19244562634SMark Murray break; 193f6011da8SMark Murray 194f6011da8SMark Murray case MOD_SHUTDOWN: 19544562634SMark Murray break; 196f6011da8SMark Murray 1973e019deaSPoul-Henning Kamp default: 1983e019deaSPoul-Henning Kamp return (EOPNOTSUPP); 199f6011da8SMark Murray } 20044562634SMark Murray 20144562634SMark Murray return (0); 202f6011da8SMark Murray } 203f6011da8SMark Murray 204005b841fSJohn Baldwin DEV_MODULE(null, null_modevent, NULL); 2054ec450ceSMark Murray MODULE_VERSION(null, 1); 206