OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [ioctl.c] - Blame information for rev 79

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  linux/fs/ioctl.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 */
6
 
7
#include <linux/syscalls.h>
8
#include <linux/mm.h>
9
#include <linux/smp_lock.h>
10
#include <linux/capability.h>
11
#include <linux/file.h>
12
#include <linux/fs.h>
13
#include <linux/security.h>
14
#include <linux/module.h>
15
 
16
#include <asm/uaccess.h>
17
#include <asm/ioctls.h>
18
 
19
static long do_ioctl(struct file *filp, unsigned int cmd,
20
                unsigned long arg)
21
{
22
        int error = -ENOTTY;
23
 
24
        if (!filp->f_op)
25
                goto out;
26
 
27
        if (filp->f_op->unlocked_ioctl) {
28
                error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
29
                if (error == -ENOIOCTLCMD)
30
                        error = -EINVAL;
31
                goto out;
32
        } else if (filp->f_op->ioctl) {
33
                lock_kernel();
34
                error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
35
                                          filp, cmd, arg);
36
                unlock_kernel();
37
        }
38
 
39
 out:
40
        return error;
41
}
42
 
43
static int file_ioctl(struct file *filp, unsigned int cmd,
44
                unsigned long arg)
45
{
46
        int error;
47
        int block;
48
        struct inode * inode = filp->f_path.dentry->d_inode;
49
        int __user *p = (int __user *)arg;
50
 
51
        switch (cmd) {
52
                case FIBMAP:
53
                {
54
                        struct address_space *mapping = filp->f_mapping;
55
                        int res;
56
                        /* do we support this mess? */
57
                        if (!mapping->a_ops->bmap)
58
                                return -EINVAL;
59
                        if (!capable(CAP_SYS_RAWIO))
60
                                return -EPERM;
61
                        if ((error = get_user(block, p)) != 0)
62
                                return error;
63
 
64
                        lock_kernel();
65
                        res = mapping->a_ops->bmap(mapping, block);
66
                        unlock_kernel();
67
                        return put_user(res, p);
68
                }
69
                case FIGETBSZ:
70
                        return put_user(inode->i_sb->s_blocksize, p);
71
                case FIONREAD:
72
                        return put_user(i_size_read(inode) - filp->f_pos, p);
73
        }
74
 
75
        return do_ioctl(filp, cmd, arg);
76
}
77
 
78
/*
79
 * When you add any new common ioctls to the switches above and below
80
 * please update compat_sys_ioctl() too.
81
 *
82
 * vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
83
 * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
84
 */
85
int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg)
86
{
87
        unsigned int flag;
88
        int on, error = 0;
89
 
90
        switch (cmd) {
91
                case FIOCLEX:
92
                        set_close_on_exec(fd, 1);
93
                        break;
94
 
95
                case FIONCLEX:
96
                        set_close_on_exec(fd, 0);
97
                        break;
98
 
99
                case FIONBIO:
100
                        if ((error = get_user(on, (int __user *)arg)) != 0)
101
                                break;
102
                        flag = O_NONBLOCK;
103
#ifdef __sparc__
104
                        /* SunOS compatibility item. */
105
                        if(O_NONBLOCK != O_NDELAY)
106
                                flag |= O_NDELAY;
107
#endif
108
                        if (on)
109
                                filp->f_flags |= flag;
110
                        else
111
                                filp->f_flags &= ~flag;
112
                        break;
113
 
114
                case FIOASYNC:
115
                        if ((error = get_user(on, (int __user *)arg)) != 0)
116
                                break;
117
                        flag = on ? FASYNC : 0;
118
 
119
                        /* Did FASYNC state change ? */
120
                        if ((flag ^ filp->f_flags) & FASYNC) {
121
                                if (filp->f_op && filp->f_op->fasync) {
122
                                        lock_kernel();
123
                                        error = filp->f_op->fasync(fd, filp, on);
124
                                        unlock_kernel();
125
                                }
126
                                else error = -ENOTTY;
127
                        }
128
                        if (error != 0)
129
                                break;
130
 
131
                        if (on)
132
                                filp->f_flags |= FASYNC;
133
                        else
134
                                filp->f_flags &= ~FASYNC;
135
                        break;
136
 
137
                case FIOQSIZE:
138
                        if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) ||
139
                            S_ISREG(filp->f_path.dentry->d_inode->i_mode) ||
140
                            S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) {
141
                                loff_t res = inode_get_bytes(filp->f_path.dentry->d_inode);
142
                                error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0;
143
                        }
144
                        else
145
                                error = -ENOTTY;
146
                        break;
147
                default:
148
                        if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
149
                                error = file_ioctl(filp, cmd, arg);
150
                        else
151
                                error = do_ioctl(filp, cmd, arg);
152
                        break;
153
        }
154
        return error;
155
}
156
 
157
asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
158
{
159
        struct file * filp;
160
        int error = -EBADF;
161
        int fput_needed;
162
 
163
        filp = fget_light(fd, &fput_needed);
164
        if (!filp)
165
                goto out;
166
 
167
        error = security_file_ioctl(filp, cmd, arg);
168
        if (error)
169
                goto out_fput;
170
 
171
        error = vfs_ioctl(filp, fd, cmd, arg);
172
 out_fput:
173
        fput_light(filp, fput_needed);
174
 out:
175
        return error;
176
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.