/*1* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#include <types.h>30#include <kern/errno.h>31#include <kern/fcntl.h>32#include <lib.h>33#include <uio.h>34#include <vfs.h>35#include <generic/random.h>36#include "autoconf.h"3738/*39* Machine-independent generic randomness device.40*41* Remembers something that's a random source, and provides random()42* and randmax() to the rest of the kernel.43*44* The kernel config mechanism can be used to explicitly choose which45* of the available random sources to use, if more than one is46* available.47*/4849static struct random_softc *the_random = NULL;5051/*52* VFS device functions.53* open: allow reading only.54*/55static56int57randopen(struct device *dev, int openflags)58{59(void)dev;6061if (openflags != O_RDONLY) {62return EIO;63}6465return 0;66}6768/*69* VFS close function.70*/71static72int73randclose(struct device *dev)74{75(void)dev;76return 0;77}7879/*80* VFS I/O function. Hand off to implementation.81*/82static83int84randio(struct device *dev, struct uio *uio)85{86struct random_softc *rs = dev->d_data;8788if (uio->uio_rw != UIO_READ) {89return EIO;90}9192return rs->rs_read(rs->rs_devdata, uio);93}9495/*96* VFS ioctl function.97*/98static99int100randioctl(struct device *dev, int op, userptr_t data)101{102/*103* We don't support any ioctls.104*/105(void)dev;106(void)op;107(void)data;108return EIOCTL;109}110111/*112* Config function.113*/114int115config_random(struct random_softc *rs, int unit)116{117int result;118119/* We use only the first random device. */120if (unit!=0) {121return ENODEV;122}123124KASSERT(the_random==NULL);125the_random = rs;126127rs->rs_dev.d_open = randopen;128rs->rs_dev.d_close = randclose;129rs->rs_dev.d_io = randio;130rs->rs_dev.d_ioctl = randioctl;131rs->rs_dev.d_blocks = 0;132rs->rs_dev.d_blocksize = 1;133rs->rs_dev.d_data = rs;134135/* Add the VFS device structure to the VFS device list. */136result = vfs_adddev("random", &rs->rs_dev, 0);137if (result) {138return result;139}140141return 0;142}143144145/*146* Random number functions exported to the rest of the kernel.147*/148149uint32_t150random(void)151{152if (the_random==NULL) {153panic("No random device\n");154}155return the_random->rs_random(the_random->rs_devdata);156}157158uint32_t159randmax(void)160{161if (the_random==NULL) {162panic("No random device\n");163}164return the_random->rs_randmax(the_random->rs_devdata);165}166167168