15b81b6b3SRodney W. Grimes /*- 25b81b6b3SRodney W. Grimes * Copyright (c) 1988 University of Utah. 35b81b6b3SRodney W. Grimes * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 45b81b6b3SRodney W. Grimes * All rights reserved. 55b81b6b3SRodney W. Grimes * 65b81b6b3SRodney W. Grimes * This code is derived from software contributed to Berkeley by 75b81b6b3SRodney W. Grimes * the Systems Programming Group of the University of Utah Computer 85b81b6b3SRodney W. Grimes * Science Department, and code derived from software contributed to 95b81b6b3SRodney W. Grimes * Berkeley by William Jolitz. 105b81b6b3SRodney W. Grimes * 115b81b6b3SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 125b81b6b3SRodney W. Grimes * modification, are permitted provided that the following conditions 135b81b6b3SRodney W. Grimes * are met: 145b81b6b3SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 155b81b6b3SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 165b81b6b3SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 175b81b6b3SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 185b81b6b3SRodney W. Grimes * documentation and/or other materials provided with the distribution. 195b81b6b3SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 205b81b6b3SRodney W. Grimes * must display the following acknowledgement: 215b81b6b3SRodney W. Grimes * This product includes software developed by the University of 225b81b6b3SRodney W. Grimes * California, Berkeley and its contributors. 235b81b6b3SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 245b81b6b3SRodney W. Grimes * may be used to endorse or promote products derived from this software 255b81b6b3SRodney W. Grimes * without specific prior written permission. 265b81b6b3SRodney W. Grimes * 275b81b6b3SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 285b81b6b3SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 295b81b6b3SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 305b81b6b3SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 315b81b6b3SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 325b81b6b3SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 335b81b6b3SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 345b81b6b3SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 355b81b6b3SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 365b81b6b3SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 375b81b6b3SRodney W. Grimes * SUCH DAMAGE. 385b81b6b3SRodney W. Grimes * 395b81b6b3SRodney W. Grimes * from: Utah $Hdr: mem.c 1.13 89/10/08$ 4047cacd38SRodney W. Grimes * from: @(#)mem.c 7.2 (Berkeley) 5/9/91 41efeaf95aSDavid Greenman * $Id: mem.c,v 1.21 1995/11/29 14:39:26 julian Exp $ 425b81b6b3SRodney W. Grimes */ 435b81b6b3SRodney W. Grimes 445b81b6b3SRodney W. Grimes /* 455b81b6b3SRodney W. Grimes * Memory special file 465b81b6b3SRodney W. Grimes */ 475b81b6b3SRodney W. Grimes 4826f9a767SRodney W. Grimes #include <sys/param.h> 4926f9a767SRodney W. Grimes #include <sys/conf.h> 5026f9a767SRodney W. Grimes #include <sys/buf.h> 5126f9a767SRodney W. Grimes #include <sys/systm.h> 5226f9a767SRodney W. Grimes #include <sys/uio.h> 5326f9a767SRodney W. Grimes #include <sys/malloc.h> 5426f9a767SRodney W. Grimes #include <sys/proc.h> 555b81b6b3SRodney W. Grimes 5626f9a767SRodney W. Grimes #include <machine/cpu.h> 5700f7f6beSBruce Evans #include <machine/random.h> 5826f9a767SRodney W. Grimes #include <machine/psl.h> 595b81b6b3SRodney W. Grimes 60c87801feSDavid Greenman #include <vm/vm.h> 6126f9a767SRodney W. Grimes #include <vm/vm_param.h> 6226f9a767SRodney W. Grimes #include <vm/lock.h> 6326f9a767SRodney W. Grimes #include <vm/vm_prot.h> 6426f9a767SRodney W. Grimes #include <vm/pmap.h> 65efeaf95aSDavid Greenman #include <vm/vm_extern.h> 665b81b6b3SRodney W. Grimes 6753ac6efbSJulian Elischer #ifdef JREMOD 6853ac6efbSJulian Elischer #include <sys/kernel.h> 6953ac6efbSJulian Elischer #define CDEV_MAJOR 2 7053ac6efbSJulian Elischer #endif /*JREMOD*/ 7153ac6efbSJulian Elischer 728af5d536SJulian Elischer #ifdef DEVFS 738af5d536SJulian Elischer #include <sys/devfsext.h> 7433f538b9SBruce Evans 7533f538b9SBruce Evans static void 7653ac6efbSJulian Elischer memdevfs_init(dev_t dev) 778af5d536SJulian Elischer { 788af5d536SJulian Elischer void * x; 7953ac6efbSJulian Elischer int maj = major(dev); 8053ac6efbSJulian Elischer /* path name major minor type uid gid perm*/ 8153ac6efbSJulian Elischer x=devfs_add_devsw("/misc", "mem", maj, 0, DV_CHR, 0, 2, 0640); 8253ac6efbSJulian Elischer x=devfs_add_devsw("/misc", "kmem", maj, 1, DV_CHR, 0, 2, 0640); 8353ac6efbSJulian Elischer x=devfs_add_devsw("/misc", "null", maj, 2, DV_CHR, 0, 0, 0666); 8453ac6efbSJulian Elischer x=devfs_add_devsw("/misc", "random", maj, 3, DV_CHR, 0, 0, 0666); 8553ac6efbSJulian Elischer x=devfs_add_devsw("/misc", "urandom", maj, 4, DV_CHR, 0, 0, 0666); 8653ac6efbSJulian Elischer x=devfs_add_devsw("/misc", "zero", maj, 12, DV_CHR, 0, 0, 0666); 8753ac6efbSJulian Elischer x=devfs_add_devsw("/misc", "io", maj, 14, DV_CHR, 0, 2, 0640); 888af5d536SJulian Elischer } 898af5d536SJulian Elischer #endif /* DEVFS */ 908af5d536SJulian Elischer 9126f9a767SRodney W. Grimes extern char *ptvmmap; /* poor name! */ 9233f538b9SBruce Evans 93381fe1aaSGarrett Wollman int 9460039670SBruce Evans mmclose(dev, flags, fmt, p) 9578d172caSRodney W. Grimes dev_t dev; 9678d172caSRodney W. Grimes int flags; 9760039670SBruce Evans int fmt; 9860039670SBruce Evans struct proc *p; 9978d172caSRodney W. Grimes { 100c8a13ecdSDavid Greenman struct trapframe *fp; 10178d172caSRodney W. Grimes 10278d172caSRodney W. Grimes switch (minor(dev)) { 10378d172caSRodney W. Grimes case 14: 10426f9a767SRodney W. Grimes fp = (struct trapframe *)curproc->p_md.md_regs; 105c8a13ecdSDavid Greenman fp->tf_eflags &= ~PSL_IOPL; 10678d172caSRodney W. Grimes break; 10778d172caSRodney W. Grimes default: 10878d172caSRodney W. Grimes break; 10978d172caSRodney W. Grimes } 11078d172caSRodney W. Grimes return(0); 11178d172caSRodney W. Grimes } 11233f538b9SBruce Evans 113381fe1aaSGarrett Wollman int 11460039670SBruce Evans mmopen(dev, flags, fmt, p) 11578d172caSRodney W. Grimes dev_t dev; 11678d172caSRodney W. Grimes int flags; 11760039670SBruce Evans int fmt; 11860039670SBruce Evans struct proc *p; 11978d172caSRodney W. Grimes { 120c8a13ecdSDavid Greenman struct trapframe *fp; 12178d172caSRodney W. Grimes 12278d172caSRodney W. Grimes switch (minor(dev)) { 12378d172caSRodney W. Grimes case 14: 12426f9a767SRodney W. Grimes fp = (struct trapframe *)curproc->p_md.md_regs; 125c8a13ecdSDavid Greenman fp->tf_eflags |= PSL_IOPL; 12678d172caSRodney W. Grimes break; 12778d172caSRodney W. Grimes default: 12878d172caSRodney W. Grimes break; 12978d172caSRodney W. Grimes } 13078d172caSRodney W. Grimes return(0); 13178d172caSRodney W. Grimes } 13233f538b9SBruce Evans 133381fe1aaSGarrett Wollman int 1345b81b6b3SRodney W. Grimes mmrw(dev, uio, flags) 1355b81b6b3SRodney W. Grimes dev_t dev; 1365b81b6b3SRodney W. Grimes struct uio *uio; 1375b81b6b3SRodney W. Grimes int flags; 1385b81b6b3SRodney W. Grimes { 1395b81b6b3SRodney W. Grimes register int o; 1405b81b6b3SRodney W. Grimes register u_int c, v; 1411bb2d314SMark Murray u_int poolsize; 1425b81b6b3SRodney W. Grimes register struct iovec *iov; 1435b81b6b3SRodney W. Grimes int error = 0; 1441bb2d314SMark Murray caddr_t buf = NULL; 1455b81b6b3SRodney W. Grimes 1465b81b6b3SRodney W. Grimes while (uio->uio_resid > 0 && error == 0) { 1475b81b6b3SRodney W. Grimes iov = uio->uio_iov; 1485b81b6b3SRodney W. Grimes if (iov->iov_len == 0) { 1495b81b6b3SRodney W. Grimes uio->uio_iov++; 1505b81b6b3SRodney W. Grimes uio->uio_iovcnt--; 1515b81b6b3SRodney W. Grimes if (uio->uio_iovcnt < 0) 1525b81b6b3SRodney W. Grimes panic("mmrw"); 1535b81b6b3SRodney W. Grimes continue; 1545b81b6b3SRodney W. Grimes } 1555b81b6b3SRodney W. Grimes switch (minor(dev)) { 1565b81b6b3SRodney W. Grimes 1575b81b6b3SRodney W. Grimes /* minor device 0 is physical memory */ 1585b81b6b3SRodney W. Grimes case 0: 1595b81b6b3SRodney W. Grimes v = uio->uio_offset; 16026f9a767SRodney W. Grimes pmap_enter(kernel_pmap, (vm_offset_t)ptvmmap, v, 1615b81b6b3SRodney W. Grimes uio->uio_rw == UIO_READ ? VM_PROT_READ : VM_PROT_WRITE, 1625b81b6b3SRodney W. Grimes TRUE); 1635b81b6b3SRodney W. Grimes o = (int)uio->uio_offset & PGOFSET; 1645b81b6b3SRodney W. Grimes c = (u_int)(NBPG - ((int)iov->iov_base & PGOFSET)); 16526f9a767SRodney W. Grimes c = min(c, (u_int)(NBPG - o)); 16626f9a767SRodney W. Grimes c = min(c, (u_int)iov->iov_len); 16726f9a767SRodney W. Grimes error = uiomove((caddr_t)&ptvmmap[o], (int)c, uio); 16826f9a767SRodney W. Grimes pmap_remove(kernel_pmap, (vm_offset_t)ptvmmap, 16926f9a767SRodney W. Grimes (vm_offset_t)&ptvmmap[NBPG]); 1705b81b6b3SRodney W. Grimes continue; 1715b81b6b3SRodney W. Grimes 1725b81b6b3SRodney W. Grimes /* minor device 1 is kernel memory */ 17397e11262SDavid Greenman case 1: { 17497e11262SDavid Greenman vm_offset_t addr, eaddr; 1755b81b6b3SRodney W. Grimes c = iov->iov_len; 17697e11262SDavid Greenman 17797e11262SDavid Greenman /* 17897e11262SDavid Greenman * Make sure that all of the pages are currently resident so 17997e11262SDavid Greenman * that we don't create any zero-fill pages. 18097e11262SDavid Greenman */ 18197e11262SDavid Greenman addr = trunc_page(uio->uio_offset); 1820704324aSDavid Greenman eaddr = round_page(uio->uio_offset + c); 18397e11262SDavid Greenman for (; addr < eaddr; addr += PAGE_SIZE) 18497e11262SDavid Greenman if (pmap_extract(kernel_pmap, addr) == 0) 18597e11262SDavid Greenman return EFAULT; 18697e11262SDavid Greenman 18726f9a767SRodney W. Grimes if (!kernacc((caddr_t)(int)uio->uio_offset, c, 1885b81b6b3SRodney W. Grimes uio->uio_rw == UIO_READ ? B_READ : B_WRITE)) 1895b81b6b3SRodney W. Grimes return(EFAULT); 19026f9a767SRodney W. Grimes error = uiomove((caddr_t)(int)uio->uio_offset, (int)c, uio); 1915b81b6b3SRodney W. Grimes continue; 19297e11262SDavid Greenman } 1935b81b6b3SRodney W. Grimes 1945b81b6b3SRodney W. Grimes /* minor device 2 is EOF/RATHOLE */ 1955b81b6b3SRodney W. Grimes case 2: 1965b81b6b3SRodney W. Grimes if (uio->uio_rw == UIO_READ) 1975b81b6b3SRodney W. Grimes return (0); 1985b81b6b3SRodney W. Grimes c = iov->iov_len; 1995b81b6b3SRodney W. Grimes break; 2005b81b6b3SRodney W. Grimes 2011bb2d314SMark Murray /* minor device 3 (/dev/random) is source of filth on read, rathole on write */ 2021bb2d314SMark Murray case 3: 2031bb2d314SMark Murray if (uio->uio_rw == UIO_WRITE) { 2041bb2d314SMark Murray c = iov->iov_len; 2051bb2d314SMark Murray break; 2061bb2d314SMark Murray } 2071bb2d314SMark Murray if (buf == NULL) 2081bb2d314SMark Murray buf = (caddr_t) 2091bb2d314SMark Murray malloc(CLBYTES, M_TEMP, M_WAITOK); 2101bb2d314SMark Murray c = min(iov->iov_len, CLBYTES); 2111bb2d314SMark Murray poolsize = read_random(buf, c); 2121bb2d314SMark Murray if (poolsize == 0) { 2131bb2d314SMark Murray if (buf) 2141bb2d314SMark Murray free(buf, M_TEMP); 2151bb2d314SMark Murray return (0); 2161bb2d314SMark Murray } 2171bb2d314SMark Murray c = min(c, poolsize); 2181bb2d314SMark Murray error = uiomove(buf, (int)c, uio); 2191bb2d314SMark Murray continue; 2201bb2d314SMark Murray 2211bb2d314SMark Murray /* minor device 4 (/dev/urandom) is source of muck on read, rathole on write */ 2221bb2d314SMark Murray case 4: 2231bb2d314SMark Murray if (uio->uio_rw == UIO_WRITE) { 2241bb2d314SMark Murray c = iov->iov_len; 2251bb2d314SMark Murray break; 2261bb2d314SMark Murray } 2271bb2d314SMark Murray if (buf == NULL) 2281bb2d314SMark Murray buf = (caddr_t) 2291bb2d314SMark Murray malloc(CLBYTES, M_TEMP, M_WAITOK); 2301bb2d314SMark Murray c = min(iov->iov_len, CLBYTES); 2311bb2d314SMark Murray poolsize = read_random_unlimited(buf, c); 2321bb2d314SMark Murray c = min(c, poolsize); 2331bb2d314SMark Murray error = uiomove(buf, (int)c, uio); 2341bb2d314SMark Murray continue; 2351bb2d314SMark Murray 2365b81b6b3SRodney W. Grimes /* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */ 2375b81b6b3SRodney W. Grimes case 12: 2385b81b6b3SRodney W. Grimes if (uio->uio_rw == UIO_WRITE) { 2395b81b6b3SRodney W. Grimes c = iov->iov_len; 2405b81b6b3SRodney W. Grimes break; 2415b81b6b3SRodney W. Grimes } 2421bb2d314SMark Murray if (buf == NULL) { 2431bb2d314SMark Murray buf = (caddr_t) 2445b81b6b3SRodney W. Grimes malloc(CLBYTES, M_TEMP, M_WAITOK); 2451bb2d314SMark Murray bzero(buf, CLBYTES); 2465b81b6b3SRodney W. Grimes } 24726f9a767SRodney W. Grimes c = min(iov->iov_len, CLBYTES); 2481bb2d314SMark Murray error = uiomove(buf, (int)c, uio); 2495b81b6b3SRodney W. Grimes continue; 2505b81b6b3SRodney W. Grimes 2515b81b6b3SRodney W. Grimes #ifdef notyet 2525b81b6b3SRodney W. Grimes /* 386 I/O address space (/dev/ioport[bwl]) is a read/write access to seperate 2535b81b6b3SRodney W. Grimes i/o device address bus, different than memory bus. Semantics here are 2545b81b6b3SRodney W. Grimes very different than ordinary read/write, as if iov_len is a multiple 2555b81b6b3SRodney W. Grimes an implied string move from a single port will be done. Note that lseek 2565b81b6b3SRodney W. Grimes must be used to set the port number reliably. */ 2575b81b6b3SRodney W. Grimes case 14: 2585b81b6b3SRodney W. Grimes if (iov->iov_len == 1) { 2595b81b6b3SRodney W. Grimes u_char tmp; 2605b81b6b3SRodney W. Grimes tmp = inb(uio->uio_offset); 2615b81b6b3SRodney W. Grimes error = uiomove (&tmp, iov->iov_len, uio); 2625b81b6b3SRodney W. Grimes } else { 2635b81b6b3SRodney W. Grimes if (!useracc((caddr_t)iov->iov_base, 2645b81b6b3SRodney W. Grimes iov->iov_len, uio->uio_rw)) 2655b81b6b3SRodney W. Grimes return (EFAULT); 2665b81b6b3SRodney W. Grimes insb(uio->uio_offset, iov->iov_base, 2675b81b6b3SRodney W. Grimes iov->iov_len); 2685b81b6b3SRodney W. Grimes } 2695b81b6b3SRodney W. Grimes break; 2705b81b6b3SRodney W. Grimes case 15: 2715b81b6b3SRodney W. Grimes if (iov->iov_len == sizeof (short)) { 2725b81b6b3SRodney W. Grimes u_short tmp; 2735b81b6b3SRodney W. Grimes tmp = inw(uio->uio_offset); 2745b81b6b3SRodney W. Grimes error = uiomove (&tmp, iov->iov_len, uio); 2755b81b6b3SRodney W. Grimes } else { 2765b81b6b3SRodney W. Grimes if (!useracc((caddr_t)iov->iov_base, 2775b81b6b3SRodney W. Grimes iov->iov_len, uio->uio_rw)) 2785b81b6b3SRodney W. Grimes return (EFAULT); 2795b81b6b3SRodney W. Grimes insw(uio->uio_offset, iov->iov_base, 2805b81b6b3SRodney W. Grimes iov->iov_len/ sizeof (short)); 2815b81b6b3SRodney W. Grimes } 2825b81b6b3SRodney W. Grimes break; 2835b81b6b3SRodney W. Grimes case 16: 2845b81b6b3SRodney W. Grimes if (iov->iov_len == sizeof (long)) { 2855b81b6b3SRodney W. Grimes u_long tmp; 2865b81b6b3SRodney W. Grimes tmp = inl(uio->uio_offset); 2875b81b6b3SRodney W. Grimes error = uiomove (&tmp, iov->iov_len, uio); 2885b81b6b3SRodney W. Grimes } else { 2895b81b6b3SRodney W. Grimes if (!useracc((caddr_t)iov->iov_base, 2905b81b6b3SRodney W. Grimes iov->iov_len, uio->uio_rw)) 2915b81b6b3SRodney W. Grimes return (EFAULT); 2925b81b6b3SRodney W. Grimes insl(uio->uio_offset, iov->iov_base, 2935b81b6b3SRodney W. Grimes iov->iov_len/ sizeof (long)); 2945b81b6b3SRodney W. Grimes } 2955b81b6b3SRodney W. Grimes break; 2965b81b6b3SRodney W. Grimes #endif 2975b81b6b3SRodney W. Grimes 2985b81b6b3SRodney W. Grimes default: 2995b81b6b3SRodney W. Grimes return (ENXIO); 3005b81b6b3SRodney W. Grimes } 3015b81b6b3SRodney W. Grimes if (error) 3025b81b6b3SRodney W. Grimes break; 3035b81b6b3SRodney W. Grimes iov->iov_base += c; 3045b81b6b3SRodney W. Grimes iov->iov_len -= c; 3055b81b6b3SRodney W. Grimes uio->uio_offset += c; 3065b81b6b3SRodney W. Grimes uio->uio_resid -= c; 3075b81b6b3SRodney W. Grimes } 3081bb2d314SMark Murray if (buf) 3091bb2d314SMark Murray free(buf, M_TEMP); 3105b81b6b3SRodney W. Grimes return (error); 3115b81b6b3SRodney W. Grimes } 312b513c262SDavid Greenman 313b513c262SDavid Greenman 314b513c262SDavid Greenman 315b513c262SDavid Greenman 316b513c262SDavid Greenman /*******************************************************\ 317b513c262SDavid Greenman * allow user processes to MMAP some memory sections * 318b513c262SDavid Greenman * instead of going through read/write * 319b513c262SDavid Greenman \*******************************************************/ 320b513c262SDavid Greenman int memmmap(dev_t dev, int offset, int nprot) 321b513c262SDavid Greenman { 322b513c262SDavid Greenman switch (minor(dev)) 323b513c262SDavid Greenman { 324b513c262SDavid Greenman 325b513c262SDavid Greenman /* minor device 0 is physical memory */ 326b513c262SDavid Greenman case 0: 327b513c262SDavid Greenman return i386_btop(offset); 328b513c262SDavid Greenman 329b513c262SDavid Greenman /* minor device 1 is kernel memory */ 330b513c262SDavid Greenman case 1: 331b513c262SDavid Greenman return i386_btop(vtophys(offset)); 332b513c262SDavid Greenman 333b513c262SDavid Greenman default: 334b513c262SDavid Greenman return -1; 335b513c262SDavid Greenman } 336b513c262SDavid Greenman } 337b513c262SDavid Greenman 3381bb2d314SMark Murray /* 3391bb2d314SMark Murray * Allow userland to select which interrupts will be used in the muck 3401bb2d314SMark Murray * gathering business. 3411bb2d314SMark Murray */ 3421bb2d314SMark Murray int 34300f7f6beSBruce Evans mmioctl(dev, cmd, cmdarg, flags, p) 34400f7f6beSBruce Evans dev_t dev; 34500f7f6beSBruce Evans int cmd; 34600f7f6beSBruce Evans caddr_t cmdarg; 34700f7f6beSBruce Evans int flags; 34800f7f6beSBruce Evans struct proc *p; 3491bb2d314SMark Murray { 350a0135d7eSMark Murray int error; 351a0135d7eSMark Murray 3521bb2d314SMark Murray if (minor(dev) != 3 && minor(dev) != 4) 3531bb2d314SMark Murray return (ENODEV); 3541bb2d314SMark Murray 3551bb2d314SMark Murray if (*(u_int16_t *)cmdarg >= 16) 3561bb2d314SMark Murray return (EINVAL); 3571bb2d314SMark Murray 358a0135d7eSMark Murray /* Only root can do this */ 359a0135d7eSMark Murray error = suser(p->p_ucred, &p->p_acflag); 360a0135d7eSMark Murray if (error != 0) { 361a0135d7eSMark Murray return (error); 362a0135d7eSMark Murray } 363a0135d7eSMark Murray 3641bb2d314SMark Murray switch (cmd){ 3651bb2d314SMark Murray 3661bb2d314SMark Murray case MEM_SETIRQ: 3671bb2d314SMark Murray interrupt_allowed |= 1 << *(u_int16_t *)cmdarg; 3681bb2d314SMark Murray break; 3691bb2d314SMark Murray 3701bb2d314SMark Murray case MEM_CLEARIRQ: 3711bb2d314SMark Murray interrupt_allowed &= ~(1 << *(u_int16_t *)cmdarg); 3721bb2d314SMark Murray break; 3731bb2d314SMark Murray 3741bb2d314SMark Murray case MEM_RETURNIRQ: 3751bb2d314SMark Murray *(u_int16_t *)cmdarg = interrupt_allowed; 3761bb2d314SMark Murray break; 3771bb2d314SMark Murray 3781bb2d314SMark Murray default: 3791bb2d314SMark Murray return (ENOTTY); 3801bb2d314SMark Murray } 3811bb2d314SMark Murray return (0); 38200f7f6beSBruce Evans } 38353ac6efbSJulian Elischer 38453ac6efbSJulian Elischer 38553ac6efbSJulian Elischer 38653ac6efbSJulian Elischer #ifdef JREMOD 38753ac6efbSJulian Elischer struct cdevsw mem_cdevsw = 38853ac6efbSJulian Elischer { mmopen, mmclose, mmrw, mmrw, /*2*/ 38953ac6efbSJulian Elischer mmioctl, nullstop, nullreset, nodevtotty,/* memory */ 39053ac6efbSJulian Elischer seltrue, memmmap, NULL }; 39153ac6efbSJulian Elischer 39253ac6efbSJulian Elischer static mem_devsw_installed = 0; 39353ac6efbSJulian Elischer 39453ac6efbSJulian Elischer static void mem_drvinit(void *unused) 39553ac6efbSJulian Elischer { 39653ac6efbSJulian Elischer dev_t dev; 39753ac6efbSJulian Elischer 39853ac6efbSJulian Elischer if( ! mem_devsw_installed ) { 39953ac6efbSJulian Elischer dev = makedev(CDEV_MAJOR,0); 40053ac6efbSJulian Elischer cdevsw_add(&dev,&mem_cdevsw,NULL); 40153ac6efbSJulian Elischer mem_devsw_installed = 1; 40253ac6efbSJulian Elischer #ifdef DEVFS 40353ac6efbSJulian Elischer memdevfs_init(dev); 40453ac6efbSJulian Elischer #endif 40553ac6efbSJulian Elischer } 4067198bf47SJulian Elischer } 40753ac6efbSJulian Elischer 40853ac6efbSJulian Elischer SYSINIT(memdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,mem_drvinit,NULL) 40953ac6efbSJulian Elischer 41053ac6efbSJulian Elischer #endif /* JREMOD */ 41153ac6efbSJulian Elischer 412