This source file includes following definitions.
- get_device_list
- get_blkfops
- get_chrfops
- register_chrdev
- register_blkdev
- unregister_chrdev
- unregister_blkdev
- check_disk_change
- 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 #include <linux/config.h>
19
20
21
22
23
24 #ifdef CONFIG_MCD
25 extern int check_mcd_media_change(int, int);
26 #endif
27 #ifdef CONFIG_SBPCD
28 extern int check_sbpcd_media_change(int, int);
29 #endif
30
31 struct device_struct {
32 const char * name;
33 struct file_operations * fops;
34 };
35
36 static struct device_struct chrdevs[MAX_CHRDEV] = {
37 { NULL, NULL },
38 };
39
40 static struct device_struct blkdevs[MAX_BLKDEV] = {
41 { NULL, NULL },
42 };
43
44 int get_device_list(char * page)
45 {
46 int i;
47 int len;
48
49 len = sprintf(page, "Character devices:\n");
50 for (i = 0; i < MAX_CHRDEV ; i++) {
51 if (chrdevs[i].fops) {
52 len += sprintf(page+len, "%2d %s\n", i, chrdevs[i].name);
53 }
54 }
55 len += sprintf(page+len, "\nBlock devices:\n");
56 for (i = 0; i < MAX_BLKDEV ; i++) {
57 if (blkdevs[i].fops) {
58 len += sprintf(page+len, "%2d %s\n", i, blkdevs[i].name);
59 }
60 }
61 return len;
62 }
63
64 struct file_operations * get_blkfops(unsigned int major)
65 {
66 if (major >= MAX_BLKDEV)
67 return NULL;
68 return blkdevs[major].fops;
69 }
70
71 struct file_operations * get_chrfops(unsigned int major)
72 {
73 if (major >= MAX_CHRDEV)
74 return NULL;
75 return chrdevs[major].fops;
76 }
77
78 int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)
79 {
80 if (major >= MAX_CHRDEV)
81 return -EINVAL;
82 if (chrdevs[major].fops)
83 return -EBUSY;
84 chrdevs[major].name = name;
85 chrdevs[major].fops = fops;
86 return 0;
87 }
88
89 int register_blkdev(unsigned int major, const char * name, struct file_operations *fops)
90 {
91 if (major >= MAX_BLKDEV)
92 return -EINVAL;
93 if (blkdevs[major].fops)
94 return -EBUSY;
95 blkdevs[major].name = name;
96 blkdevs[major].fops = fops;
97 return 0;
98 }
99
100 int unregister_chrdev(unsigned int major, const char * name)
101 {
102 if (major >= MAX_CHRDEV)
103 return -EINVAL;
104 if (!chrdevs[major].fops)
105 return -EINVAL;
106 if (strcmp(chrdevs[major].name, name))
107 return -EINVAL;
108 chrdevs[major].name = NULL;
109 chrdevs[major].fops = NULL;
110 return 0;
111 }
112
113 int unregister_blkdev(unsigned int major, const char * name)
114 {
115 if (major >= MAX_BLKDEV)
116 return -EINVAL;
117 if (!blkdevs[major].fops)
118 return -EINVAL;
119 if (strcmp(blkdevs[major].name, name))
120 return -EINVAL;
121 blkdevs[major].name = NULL;
122 blkdevs[major].fops = NULL;
123 return 0;
124 }
125
126
127
128
129
130
131
132
133
134
135 int check_disk_change(dev_t dev)
136 {
137 int i;
138 struct file_operations * fops;
139
140 i = MAJOR(dev);
141 if (i >= MAX_BLKDEV || (fops = blkdevs[i].fops) == NULL)
142 return 0;
143 if (fops->check_media_change != NULL) {
144 if (!fops->check_media_change(dev))
145 return 0;
146 }
147 #if 1
148 else switch(MAJOR(dev)){
149
150 #if defined(CONFIG_MCD)
151 case MITSUMI_CDROM_MAJOR:
152 if (!check_mcd_media_change(dev, 0))
153 return 0;
154 break;
155 #endif
156
157 #if defined(CONFIG_SBPCD)
158 case MATSUSHITA_CDROM_MAJOR:
159 if (!check_sbpcd_media_change(dev, 0))
160 return 0;
161 break;
162 #endif
163
164 default:
165 return 0;
166 }
167 #endif
168
169 printk("VFS: Disk change detected on device %d/%d\n",
170 MAJOR(dev), MINOR(dev));
171 for (i=0 ; i<NR_SUPER ; i++)
172 if (super_blocks[i].s_dev == dev)
173 put_super(super_blocks[i].s_dev);
174 invalidate_inodes(dev);
175 invalidate_buffers(dev);
176
177 if (fops->revalidate)
178 fops->revalidate(dev);
179 return 1;
180 }
181
182
183
184
185 int blkdev_open(struct inode * inode, struct file * filp)
186 {
187 int i;
188
189 i = MAJOR(inode->i_rdev);
190 if (i >= MAX_BLKDEV || !blkdevs[i].fops)
191 return -ENODEV;
192 filp->f_op = blkdevs[i].fops;
193 if (filp->f_op->open)
194 return filp->f_op->open(inode,filp);
195 return 0;
196 }
197
198
199
200
201
202
203 struct file_operations def_blk_fops = {
204 NULL,
205 NULL,
206 NULL,
207 NULL,
208 NULL,
209 NULL,
210 NULL,
211 blkdev_open,
212 NULL,
213 };
214
215 struct inode_operations blkdev_inode_operations = {
216 &def_blk_fops,
217 NULL,
218 NULL,
219 NULL,
220 NULL,
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 NULL,
226 NULL,
227 NULL,
228 NULL,
229 NULL,
230 NULL
231 };
232
233
234
235
236 int chrdev_open(struct inode * inode, struct file * filp)
237 {
238 int i;
239
240 i = MAJOR(inode->i_rdev);
241 if (i >= MAX_CHRDEV || !chrdevs[i].fops)
242 return -ENODEV;
243 filp->f_op = chrdevs[i].fops;
244 if (filp->f_op->open)
245 return filp->f_op->open(inode,filp);
246 return 0;
247 }
248
249
250
251
252
253
254 struct file_operations def_chr_fops = {
255 NULL,
256 NULL,
257 NULL,
258 NULL,
259 NULL,
260 NULL,
261 NULL,
262 chrdev_open,
263 NULL,
264 };
265
266 struct inode_operations chrdev_inode_operations = {
267 &def_chr_fops,
268 NULL,
269 NULL,
270 NULL,
271 NULL,
272 NULL,
273 NULL,
274 NULL,
275 NULL,
276 NULL,
277 NULL,
278 NULL,
279 NULL,
280 NULL,
281 NULL
282 };