This source file includes following definitions.
- get_device_list
- get_blkfops
- get_chrfops
- register_chrdev
- register_blkdev
- unregister_chrdev
- unregister_blkdev
- blkdev_open
- chrdev_open
1
2
3
4
5
6
7
8
9 #include <linux/fs.h>
10 #include <linux/major.h>
11 #include <linux/string.h>
12 #include <linux/sched.h>
13 #include <linux/ext_fs.h>
14 #include <linux/stat.h>
15 #include <linux/fcntl.h>
16 #include <linux/errno.h>
17
18 struct device_struct {
19 const char * name;
20 struct file_operations * fops;
21 };
22
23 static struct device_struct chrdevs[MAX_CHRDEV] = {
24 { NULL, NULL },
25 };
26
27 static struct device_struct blkdevs[MAX_BLKDEV] = {
28 { NULL, NULL },
29 };
30
31 int get_device_list(char * page)
32 {
33 int i;
34 int len;
35
36 len = sprintf(page, "Character devices:\n");
37 for (i = 0; i < MAX_CHRDEV ; i++) {
38 if (chrdevs[i].fops) {
39 len += sprintf(page+len, "%2d %s\n", i, chrdevs[i].name);
40 }
41 }
42 len += sprintf(page+len, "\nBlock devices:\n");
43 for (i = 0; i < MAX_BLKDEV ; i++) {
44 if (blkdevs[i].fops) {
45 len += sprintf(page+len, "%2d %s\n", i, blkdevs[i].name);
46 }
47 }
48 return len;
49 }
50
51 struct file_operations * get_blkfops(unsigned int major)
52 {
53 if (major >= MAX_BLKDEV)
54 return NULL;
55 return blkdevs[major].fops;
56 }
57
58 struct file_operations * get_chrfops(unsigned int major)
59 {
60 if (major >= MAX_CHRDEV)
61 return NULL;
62 return chrdevs[major].fops;
63 }
64
65 int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)
66 {
67 if (major >= MAX_CHRDEV)
68 return -EINVAL;
69 if (chrdevs[major].fops)
70 return -EBUSY;
71 chrdevs[major].name = name;
72 chrdevs[major].fops = fops;
73 return 0;
74 }
75
76 int register_blkdev(unsigned int major, const char * name, struct file_operations *fops)
77 {
78 if (major >= MAX_BLKDEV)
79 return -EINVAL;
80 if (blkdevs[major].fops)
81 return -EBUSY;
82 blkdevs[major].name = name;
83 blkdevs[major].fops = fops;
84 return 0;
85 }
86
87 int unregister_chrdev(unsigned int major, const char * name)
88 {
89 if (major >= MAX_CHRDEV)
90 return -EINVAL;
91 if (!chrdevs[major].fops)
92 return -EINVAL;
93 if (strcmp(chrdevs[major].name, name))
94 return -EINVAL;
95 chrdevs[major].name = NULL;
96 chrdevs[major].fops = NULL;
97 return 0;
98 }
99
100 int unregister_blkdev(unsigned int major, const char * name)
101 {
102 if (major >= MAX_BLKDEV)
103 return -EINVAL;
104 if (!blkdevs[major].fops)
105 return -EINVAL;
106 if (strcmp(blkdevs[major].name, name))
107 return -EINVAL;
108 blkdevs[major].name = NULL;
109 blkdevs[major].fops = NULL;
110 return 0;
111 }
112
113
114
115
116 int blkdev_open(struct inode * inode, struct file * filp)
117 {
118 int i;
119
120 i = MAJOR(inode->i_rdev);
121 if (i >= MAX_BLKDEV || !blkdevs[i].fops)
122 return -ENODEV;
123 filp->f_op = blkdevs[i].fops;
124 if (filp->f_op->open)
125 return filp->f_op->open(inode,filp);
126 return 0;
127 }
128
129
130
131
132
133
134 struct file_operations def_blk_fops = {
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 NULL,
140 NULL,
141 NULL,
142 blkdev_open,
143 NULL,
144 };
145
146 struct inode_operations blkdev_inode_operations = {
147 &def_blk_fops,
148 NULL,
149 NULL,
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155 NULL,
156 NULL,
157 NULL,
158 NULL,
159 NULL,
160 NULL,
161 NULL
162 };
163
164
165
166
167 int chrdev_open(struct inode * inode, struct file * filp)
168 {
169 int i;
170
171 i = MAJOR(inode->i_rdev);
172 if (i >= MAX_CHRDEV || !chrdevs[i].fops)
173 return -ENODEV;
174 filp->f_op = chrdevs[i].fops;
175 if (filp->f_op->open)
176 return filp->f_op->open(inode,filp);
177 return 0;
178 }
179
180
181
182
183
184
185 struct file_operations def_chr_fops = {
186 NULL,
187 NULL,
188 NULL,
189 NULL,
190 NULL,
191 NULL,
192 NULL,
193 chrdev_open,
194 NULL,
195 };
196
197 struct inode_operations chrdev_inode_operations = {
198 &def_chr_fops,
199 NULL,
200 NULL,
201 NULL,
202 NULL,
203 NULL,
204 NULL,
205 NULL,
206 NULL,
207 NULL,
208 NULL,
209 NULL,
210 NULL,
211 NULL,
212 NULL
213 };