/* * Copyright (C) 2010-2011 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) #include #else #include #endif #include #include #include #include #include #include #include #include /* bmem_region_info */ #include "b_bare_os.h" #include "nexus_generic_driver.h" #include "nexus_driver_firmware.h" #ifdef MODULE int init_module(void); void cleanup_module(void); #else #error "Not supported" #endif static int nexus_driver_open(struct inode *inode, struct file *file); static int nexus_driver_close(struct inode *inode, struct file * file); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) static int nexus_driver_ioctl(struct inode *inode, struct file * file, unsigned int cmd, unsigned long arg); #else static int nexus_driver_ioctl(struct file * file, unsigned int cmd, unsigned long arg); #endif static int nexus_driver_mmap(struct file *file, struct vm_area_struct *vma); static struct file_operations nexus_driver_fops = { owner: THIS_MODULE, read: NULL, write: NULL, #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) ioctl: nexus_driver_ioctl, #else unlocked_ioctl: nexus_driver_ioctl, #endif mmap: nexus_driver_mmap, open: nexus_driver_open, release: nexus_driver_close }; static char b_env[256]=""; module_param_string(config, b_env, sizeof(b_env), 0); static void b_parse_env(char *env) { char *s; const char *name; const char *value; /* traverse string, and split it to name/value pairs */ for(s=env, name=env, value=NULL;;s++) { switch(*s) { case '\0': goto done; case '=': *s = '\0'; value = s+1; break; case ' ': case ':': case ';': *s = '\0'; if (value==NULL) { value=s; } pb_bare_os->setenv(name, value); name = s+1; value = NULL; break; default: break; } } done: if(*name) { if (value==NULL) { value=s; } pb_bare_os->setenv(name, value); } return; } static int nexus_driver_open(struct inode *inode, struct file *file) { int rc; unsigned minor = MINOR(inode->i_rdev); rc = nexus_generic_driver_open(minor, &file->private_data, current->pid, current_euid() == 0); if (rc) return -ENODEV; return 0; } static int nexus_driver_close(struct inode *inode, struct file *file) { unsigned minor = MINOR(inode->i_rdev); nexus_generic_driver_close(minor, file->private_data, signal_pending(current)); return 0; } static int nexus_driver_mmap(struct file *file, struct vm_area_struct *vma) { int rc; unsigned offset = vma->vm_pgoff << PAGE_SHIFT; rc = nexus_generic_driver_validate_mmap(0 /* unused */, file->private_data, offset, vma->vm_end - vma->vm_start); if (rc) return -EINVAL; rc = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); if (rc) { return -EAGAIN; } return rc; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) static int nexus_driver_ioctl(struct inode *inode, struct file * file, unsigned int cmd, unsigned long arg) #else static int nexus_driver_ioctl(struct file * file, unsigned int cmd, unsigned long arg) #endif { int rc; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) unsigned minor = MINOR(inode->i_rdev); #else unsigned minor = MINOR(file->f_path.dentry->d_inode->i_rdev); #endif rc = nexus_generic_driver_ioctl(minor, file->private_data, cmd, arg); if (rc) return -EFAULT; return 0; } MODULE_LICENSE("GPL"); #ifdef MODULE int init_module(void) { int rc; unsigned i; struct nexus_generic_driver_init_settings settings; struct brcm_cache_info info; rc = nexus_driver_firmware_init(); if (rc) goto error; rc = b_bare_os_init(); if (rc) goto error; memset(&settings, 0, sizeof(settings)); for (i=0;i