source: svn/trunk/newcon3bcm2_21bu/nexus/build/nfe_driver/nexus_driver.c

Last change on this file was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 6.1 KB
Line 
1/*
2 * Copyright (C) 2010-2011 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17#include <linux/version.h>
18#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
19#include <linux/autoconf.h>
20#else
21#include <generated/autoconf.h>
22#endif
23#include <linux/module.h>
24#include <linux/fs.h>
25#include <linux/ioctl.h>
26#include <linux/sched.h>
27#include <linux/mm.h>
28#include <linux/signal.h>
29#include <linux/kernel.h>
30#include <asm/brcmstb/brcmapi.h> /* bmem_region_info */
31#include "b_bare_os.h"
32#include "nexus_generic_driver.h"
33#include "nexus_driver_firmware.h"
34
35#ifdef MODULE
36int     init_module(void);
37void    cleanup_module(void);
38#else
39#error "Not supported"
40#endif
41
42static int      nexus_driver_open(struct inode *inode, struct file *file);
43static int      nexus_driver_close(struct inode *inode, struct file * file);
44#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
45static int      nexus_driver_ioctl(struct inode *inode, struct file * file, unsigned int cmd, unsigned long arg);
46#else
47static int      nexus_driver_ioctl(struct file * file, unsigned int cmd, unsigned long arg);
48#endif
49static int      nexus_driver_mmap(struct file *file, struct vm_area_struct *vma);
50
51static struct file_operations
52nexus_driver_fops = {
53    owner:      THIS_MODULE,
54    read:       NULL,
55    write:      NULL,
56#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
57    ioctl:          nexus_driver_ioctl,
58#else
59    unlocked_ioctl: nexus_driver_ioctl,
60#endif
61    mmap:       nexus_driver_mmap,
62    open:       nexus_driver_open,
63    release:    nexus_driver_close
64};
65
66static char b_env[256]="";
67module_param_string(config, b_env, sizeof(b_env), 0);
68
69static void
70b_parse_env(char *env)
71{
72    char *s;
73    const char *name;
74    const char *value;
75    /* traverse  string, and split it to name/value pairs */
76    for(s=env, name=env, value=NULL;;s++) {
77        switch(*s) {
78        case '\0':
79            goto done;
80        case '=':
81            *s = '\0';
82            value = s+1;
83            break;
84        case ' ':
85        case ':':
86        case ';':
87            *s = '\0';
88            if (value==NULL) {
89                value=s;
90            }
91            pb_bare_os->setenv(name, value);
92            name = s+1;
93            value = NULL;
94            break;
95        default:
96            break;
97        }
98    }
99done:
100    if(*name) {
101        if (value==NULL) {
102            value=s;
103        }
104        pb_bare_os->setenv(name, value);
105    }
106    return;
107}
108
109static int
110nexus_driver_open(struct inode *inode, struct file *file)
111{
112    int rc;
113    unsigned minor = MINOR(inode->i_rdev);
114    rc = nexus_generic_driver_open(minor, &file->private_data, current->pid, current_euid() == 0);
115    if (rc) return -ENODEV;
116    return 0;
117}
118
119static int
120nexus_driver_close(struct inode *inode, struct file *file)
121{
122    unsigned minor = MINOR(inode->i_rdev);
123    nexus_generic_driver_close(minor, file->private_data, signal_pending(current));
124    return 0;
125}
126
127static int nexus_driver_mmap(struct file *file, struct vm_area_struct *vma) {
128    int rc;
129    unsigned offset = vma->vm_pgoff << PAGE_SHIFT;
130
131    rc = nexus_generic_driver_validate_mmap(0 /* unused */, file->private_data, offset, vma->vm_end - vma->vm_start);
132    if (rc) return -EINVAL;
133   
134    rc = remap_pfn_range(vma,
135        vma->vm_start,
136        vma->vm_pgoff,
137        vma->vm_end - vma->vm_start,
138        vma->vm_page_prot);
139    if (rc) {
140        return -EAGAIN;
141    }
142
143    return rc;
144}
145
146#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
147static int
148nexus_driver_ioctl(struct inode *inode, struct file * file,
149                      unsigned int cmd, unsigned long arg)
150#else
151static int
152nexus_driver_ioctl(struct file * file,
153                     unsigned int cmd, unsigned long arg)
154#endif
155{
156    int rc;
157#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
158    unsigned minor = MINOR(inode->i_rdev);
159#else
160    unsigned minor = MINOR(file->f_path.dentry->d_inode->i_rdev);
161#endif
162    rc = nexus_generic_driver_ioctl(minor, file->private_data, cmd, arg);
163    if (rc) return -EFAULT;
164    return 0;
165}
166
167MODULE_LICENSE("GPL");
168
169#ifdef MODULE
170int
171init_module(void)
172{
173    int rc;
174    unsigned i;
175    struct nexus_generic_driver_init_settings settings;
176    struct brcm_cache_info info;
177   
178    rc = nexus_driver_firmware_init();
179    if (rc) goto error;
180
181    rc = b_bare_os_init();
182    if (rc) goto error;
183   
184    memset(&settings, 0, sizeof(settings));
185    for (i=0;i<sizeof(settings.region)/sizeof(settings.region[0]);i++) {
186        unsigned long offset, size;
187        rc = bmem_region_info(i, &offset, &size);
188        if (rc) break;
189        settings.region[i].offset = offset;
190        settings.region[i].size = size;
191    }
192   
193    /* If MEM's alignment is not set to the MIPS L1 and (if present) L2 cache line size,
194    we will have cache coherency problems (which lead to major system failures).
195    This code verifies that Nexus's MEM configuration is compatible with the MIPS cache line size.
196    If this code fails, please check to make sure the Linux kernel is configured right, then modify nexus_core_features.h to match. */
197    brcm_get_cache_info(&info);
198    settings.max_dcache_line_size = info.max_writeback;
199   
200    b_parse_env(b_env);
201   
202    rc = nexus_generic_driver_init(&settings);
203    if (rc) goto error;
204   
205    register_chrdev(NEXUS_DRIVER_MAJOR, "nexus", &nexus_driver_fops);
206
207    printk("nexus driver initialized\n");
208    return 0;
209
210error:
211    return rc;
212}
213
214void
215cleanup_module(void)
216{
217    unregister_chrdev(NEXUS_DRIVER_MAJOR, "nexus");
218    nexus_generic_driver_uninit();
219    b_bare_os_uninit();
220    nexus_driver_firmware_uninit();
221
222    printk("nexus driver uninitialized\n");
223    return;
224}
225#else
226#error "Not supported"
227#endif
Note: See TracBrowser for help on using the repository browser.