bcm2835_vcio.c revision 290382
1290382Sgonzo/*- 2290382Sgonzo * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org> 3290382Sgonzo * 4290382Sgonzo * Redistribution and use in source and binary forms, with or without 5290382Sgonzo * modification, are permitted provided that the following conditions 6290382Sgonzo * are met: 7290382Sgonzo * 1. Redistributions of source code must retain the above copyright 8290382Sgonzo * notice, this list of conditions and the following disclaimer. 9290382Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 10290382Sgonzo * notice, this list of conditions and the following disclaimer in the 11290382Sgonzo * documentation and/or other materials provided with the distribution. 12290382Sgonzo * 13290382Sgonzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14290382Sgonzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15290382Sgonzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16290382Sgonzo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17290382Sgonzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18290382Sgonzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19290382Sgonzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20290382Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21290382Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22290382Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23290382Sgonzo * SUCH DAMAGE. 24290382Sgonzo */ 25290382Sgonzo#include <sys/cdefs.h> 26290382Sgonzo__FBSDID("$FreeBSD: head/sys/arm/broadcom/bcm2835/bcm2835_vcio.c 290382 2015-11-05 04:16:03Z gonzo $"); 27290382Sgonzo 28290382Sgonzo#include <sys/param.h> 29290382Sgonzo#include <sys/systm.h> 30290382Sgonzo#include <sys/kernel.h> 31290382Sgonzo#include <sys/malloc.h> 32290382Sgonzo#include <sys/module.h> 33290382Sgonzo#include <sys/ioccom.h> 34290382Sgonzo#include <sys/conf.h> 35290382Sgonzo#include <sys/proc.h> 36290382Sgonzo 37290382Sgonzo#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h> 38290382Sgonzo 39290382SgonzoMALLOC_DECLARE(M_VCIO); 40290382SgonzoMALLOC_DEFINE(M_VCIO, "vcio", "VCIO temporary buffers"); 41290382Sgonzo 42290382Sgonzostatic struct cdev *sdev; 43290382Sgonzostatic d_ioctl_t vcio_ioctl; 44290382Sgonzo 45290382Sgonzostatic struct cdevsw vcio_devsw = { 46290382Sgonzo /* version */ .d_version = D_VERSION, 47290382Sgonzo /* ioctl */ .d_ioctl = vcio_ioctl, 48290382Sgonzo}; 49290382Sgonzo 50290382Sgonzo#define VCIO_IOC_MAGIC 100 51290382Sgonzo#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) 52290382Sgonzo 53290382Sgonzoint 54290382Sgonzovcio_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, 55290382Sgonzo struct thread *td) 56290382Sgonzo{ 57290382Sgonzo int error; 58290382Sgonzo void *ptr; 59290382Sgonzo uint32_t size; 60290382Sgonzo uint8_t *property; 61290382Sgonzo 62290382Sgonzo error = 0; 63290382Sgonzo switch(cmd) { 64290382Sgonzo case IOCTL_MBOX_PROPERTY: 65290382Sgonzo memcpy (&ptr, arg, sizeof(ptr)); 66290382Sgonzo error = copyin(ptr, &size, sizeof(size)); 67290382Sgonzo 68290382Sgonzo if (error != 0) 69290382Sgonzo break; 70290382Sgonzo property = malloc(size, M_VCIO, M_WAITOK); 71290382Sgonzo if (property == NULL) { 72290382Sgonzo error = ENOMEM; 73290382Sgonzo break; 74290382Sgonzo } 75290382Sgonzo 76290382Sgonzo error = copyin(ptr, property, size); 77290382Sgonzo if (error) { 78290382Sgonzo free(property, M_VCIO); 79290382Sgonzo break; 80290382Sgonzo } 81290382Sgonzo 82290382Sgonzo error = bcm2835_mbox_property(property, size); 83290382Sgonzo if (error) { 84290382Sgonzo free(property, M_VCIO); 85290382Sgonzo break; 86290382Sgonzo } 87290382Sgonzo 88290382Sgonzo error = copyout(property, ptr, size); 89290382Sgonzo free(property, M_VCIO); 90290382Sgonzo 91290382Sgonzo break; 92290382Sgonzo default: 93290382Sgonzo error = EINVAL; 94290382Sgonzo break; 95290382Sgonzo } 96290382Sgonzo return (error); 97290382Sgonzo} 98290382Sgonzo 99290382Sgonzostatic int 100290382Sgonzovcio_load(module_t mod, int cmd, void *arg) 101290382Sgonzo{ 102290382Sgonzo int err = 0; 103290382Sgonzo 104290382Sgonzo switch (cmd) { 105290382Sgonzo case MOD_LOAD: 106290382Sgonzo sdev = make_dev(&vcio_devsw, 0, UID_ROOT, GID_WHEEL, 0600, "vcio"); 107290382Sgonzo break; 108290382Sgonzo 109290382Sgonzo case MOD_UNLOAD: 110290382Sgonzo destroy_dev(sdev); 111290382Sgonzo break; 112290382Sgonzo 113290382Sgonzo default: 114290382Sgonzo err = EOPNOTSUPP; 115290382Sgonzo break; 116290382Sgonzo } 117290382Sgonzo 118290382Sgonzo return(err); 119290382Sgonzo} 120290382Sgonzo 121290382SgonzoDEV_MODULE(vcio, vcio_load, NULL); 122290382SgonzoMODULE_DEPEND(vcio, mbox, 1, 1, 1); 123