[PATCH] Add a driver for the Technisat Skystar2 DVB card
[linux-2.6/history.git] / fs / char_dev.c
blob4ed6926d4fc009d2b82ac824662290a86f7765ff
1 /*
2 * linux/fs/char_dev.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 #include <linux/config.h>
8 #include <linux/init.h>
9 #include <linux/fs.h>
10 #include <linux/slab.h>
11 #include <linux/string.h>
13 #include <linux/major.h>
14 #include <linux/string.h>
15 #include <linux/errno.h>
16 #include <linux/module.h>
17 #include <linux/smp_lock.h>
18 #include <linux/devfs_fs_kernel.h>
20 #include <linux/kobject.h>
21 #include <linux/kobj_map.h>
22 #include <linux/cdev.h>
24 #ifdef CONFIG_KMOD
25 #include <linux/kmod.h>
26 #endif
28 static struct kobj_map *cdev_map;
30 #define MAX_PROBE_HASH 255 /* random */
32 static rwlock_t chrdevs_lock = RW_LOCK_UNLOCKED;
34 static struct char_device_struct {
35 struct char_device_struct *next;
36 unsigned int major;
37 unsigned int baseminor;
38 int minorct;
39 const char *name;
40 struct file_operations *fops;
41 struct cdev *cdev; /* will die */
42 } *chrdevs[MAX_PROBE_HASH];
44 /* index in the above */
45 static inline int major_to_index(int major)
47 return major % MAX_PROBE_HASH;
50 /* get char device names in somewhat random order */
51 int get_chrdev_list(char *page)
53 struct char_device_struct *cd;
54 int i, len;
56 len = sprintf(page, "Character devices:\n");
58 read_lock(&chrdevs_lock);
59 for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
60 for (cd = chrdevs[i]; cd; cd = cd->next)
61 len += sprintf(page+len, "%3d %s\n",
62 cd->major, cd->name);
64 read_unlock(&chrdevs_lock);
66 return len;
70 * Register a single major with a specified minor range.
72 * If major == 0 this functions will dynamically allocate a major and return
73 * its number.
75 * If major > 0 this function will attempt to reserve the passed range of
76 * minors and will return zero on success.
78 * Returns a -ve errno on failure.
80 static struct char_device_struct *
81 __register_chrdev_region(unsigned int major, unsigned int baseminor,
82 int minorct, const char *name)
84 struct char_device_struct *cd, **cp;
85 int ret = 0;
86 int i;
88 cd = kmalloc(sizeof(struct char_device_struct), GFP_KERNEL);
89 if (cd == NULL)
90 return ERR_PTR(-ENOMEM);
92 memset(cd, 0, sizeof(struct char_device_struct));
94 write_lock_irq(&chrdevs_lock);
96 /* temporary */
97 if (major == 0) {
98 for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) {
99 if (chrdevs[i] == NULL)
100 break;
103 if (i == 0) {
104 ret = -EBUSY;
105 goto out;
107 major = i;
108 ret = major;
111 cd->major = major;
112 cd->baseminor = baseminor;
113 cd->minorct = minorct;
114 cd->name = name;
116 i = major_to_index(major);
118 for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
119 if ((*cp)->major > major ||
120 ((*cp)->major == major && (*cp)->baseminor >= baseminor))
121 break;
122 if (*cp && (*cp)->major == major &&
123 (*cp)->baseminor < baseminor + minorct) {
124 ret = -EBUSY;
125 goto out;
127 cd->next = *cp;
128 *cp = cd;
129 write_unlock_irq(&chrdevs_lock);
130 return cd;
131 out:
132 write_unlock_irq(&chrdevs_lock);
133 kfree(cd);
134 return ERR_PTR(ret);
137 static struct char_device_struct *
138 __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
140 struct char_device_struct *cd = NULL, **cp;
141 int i = major_to_index(major);
143 write_lock_irq(&chrdevs_lock);
144 for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
145 if ((*cp)->major == major &&
146 (*cp)->baseminor == baseminor &&
147 (*cp)->minorct == minorct)
148 break;
149 if (*cp) {
150 cd = *cp;
151 *cp = cd->next;
153 write_unlock_irq(&chrdevs_lock);
154 return cd;
157 int register_chrdev_region(dev_t from, unsigned count, char *name)
159 struct char_device_struct *cd;
160 dev_t to = from + count;
161 dev_t n, next;
163 for (n = from; n < to; n = next) {
164 next = MKDEV(MAJOR(n)+1, 0);
165 if (next > to)
166 next = to;
167 cd = __register_chrdev_region(MAJOR(n), MINOR(n),
168 next - n, name);
169 if (IS_ERR(cd))
170 goto fail;
172 return 0;
173 fail:
174 to = n;
175 for (n = from; n < to; n = next) {
176 next = MKDEV(MAJOR(n)+1, 0);
177 kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
179 return PTR_ERR(cd);
182 int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, char *name)
184 struct char_device_struct *cd;
185 cd = __register_chrdev_region(0, baseminor, count, name);
186 if (IS_ERR(cd))
187 return PTR_ERR(cd);
188 *dev = MKDEV(cd->major, cd->baseminor);
189 return 0;
192 int register_chrdev(unsigned int major, const char *name,
193 struct file_operations *fops)
195 struct char_device_struct *cd;
196 struct cdev *cdev;
197 char *s;
198 int err = -ENOMEM;
200 cd = __register_chrdev_region(major, 0, 256, name);
201 if (IS_ERR(cd))
202 return PTR_ERR(cd);
204 cdev = cdev_alloc();
205 if (!cdev)
206 goto out2;
208 cdev->owner = fops->owner;
209 cdev->ops = fops;
210 strcpy(cdev->kobj.name, name);
211 for (s = strchr(cdev->kobj.name, '/'); s; s = strchr(s, '/'))
212 *s = '!';
214 err = cdev_add(cdev, MKDEV(cd->major, 0), 256);
215 if (err)
216 goto out;
218 cd->cdev = cdev;
220 return major ? 0 : cd->major;
221 out:
222 kobject_put(&cdev->kobj);
223 out2:
224 kfree(__unregister_chrdev_region(cd->major, 0, 256));
225 return err;
228 void unregister_chrdev_region(dev_t from, unsigned count)
230 dev_t to = from + count;
231 dev_t n, next;
233 for (n = from; n < to; n = next) {
234 next = MKDEV(MAJOR(n)+1, 0);
235 if (next > to)
236 next = to;
237 kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
241 int unregister_chrdev(unsigned int major, const char *name)
243 struct char_device_struct *cd;
244 cdev_unmap(MKDEV(major, 0), 256);
245 cd = __unregister_chrdev_region(major, 0, 256);
246 if (cd && cd->cdev)
247 cdev_del(cd->cdev);
248 kfree(cd);
249 return 0;
252 static spinlock_t cdev_lock = SPIN_LOCK_UNLOCKED;
254 * Called every time a character special file is opened
256 int chrdev_open(struct inode * inode, struct file * filp)
258 struct cdev *p;
259 struct cdev *new = NULL;
260 int ret = 0;
262 spin_lock(&cdev_lock);
263 p = inode->i_cdev;
264 if (!p) {
265 struct kobject *kobj;
266 int idx;
267 spin_unlock(&cdev_lock);
268 kobj = kobj_lookup(cdev_map, kdev_t_to_nr(inode->i_rdev), &idx);
269 if (!kobj)
270 return -ENODEV;
271 new = container_of(kobj, struct cdev, kobj);
272 spin_lock(&cdev_lock);
273 p = inode->i_cdev;
274 if (!p) {
275 inode->i_cdev = p = new;
276 inode->i_cindex = idx;
277 list_add(&inode->i_devices, &p->list);
278 new = NULL;
279 } else if (!cdev_get(p))
280 ret = -ENODEV;
281 } else if (!cdev_get(p))
282 ret = -ENODEV;
283 spin_unlock(&cdev_lock);
284 cdev_put(new);
285 if (ret)
286 return ret;
287 filp->f_op = fops_get(p->ops);
288 if (!filp->f_op) {
289 cdev_put(p);
290 return -ENODEV;
292 if (filp->f_op->open) {
293 lock_kernel();
294 ret = filp->f_op->open(inode,filp);
295 unlock_kernel();
297 if (ret)
298 cdev_put(p);
299 return ret;
302 void cd_forget(struct inode *inode)
304 spin_lock(&cdev_lock);
305 list_del_init(&inode->i_devices);
306 inode->i_cdev = NULL;
307 spin_unlock(&cdev_lock);
310 void cdev_purge(struct cdev *cdev)
312 spin_lock(&cdev_lock);
313 while (!list_empty(&cdev->list)) {
314 struct inode *inode;
315 inode = container_of(cdev->list.next, struct inode, i_devices);
316 list_del_init(&inode->i_devices);
317 inode->i_cdev = NULL;
319 spin_unlock(&cdev_lock);
323 * Dummy default file-operations: the only thing this does
324 * is contain the open that then fills in the correct operations
325 * depending on the special file...
327 struct file_operations def_chr_fops = {
328 .open = chrdev_open,
331 const char *cdevname(kdev_t dev)
333 static char buffer[40];
334 const char *name = "unknown-char";
335 unsigned int major = major(dev);
336 unsigned int minor = minor(dev);
337 int i = major_to_index(major);
338 struct char_device_struct *cd;
340 read_lock(&chrdevs_lock);
341 for (cd = chrdevs[i]; cd; cd = cd->next)
342 if (cd->major == major)
343 break;
344 if (cd)
345 name = cd->name;
346 sprintf(buffer, "%s(%d,%d)", name, major, minor);
347 read_unlock(&chrdevs_lock);
349 return buffer;
352 static struct kobject *exact_match(dev_t dev, int *part, void *data)
354 struct cdev *p = data;
355 return &p->kobj;
358 static int exact_lock(dev_t dev, void *data)
360 struct cdev *p = data;
361 return cdev_get(p) ? 0 : -1;
364 int cdev_add(struct cdev *p, dev_t dev, unsigned count)
366 int err = kobject_add(&p->kobj);
367 if (err)
368 return err;
369 err = kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
370 if (err)
371 kobject_del(&p->kobj);
372 return err;
375 void cdev_unmap(dev_t dev, unsigned count)
377 kobj_unmap(cdev_map, dev, count);
380 void cdev_del(struct cdev *p)
382 kobject_del(&p->kobj);
383 kobject_put(&p->kobj);
386 struct kobject *cdev_get(struct cdev *p)
388 struct module *owner = p->owner;
389 struct kobject *kobj;
391 if (owner && !try_module_get(owner))
392 return NULL;
393 kobj = kobject_get(&p->kobj);
394 if (!kobj)
395 module_put(owner);
396 return kobj;
399 void cdev_put(struct cdev *p)
401 if (p) {
402 kobject_put(&p->kobj);
403 module_put(p->owner);
407 static decl_subsys(cdev, NULL, NULL);
409 static void cdev_default_release(struct kobject *kobj)
411 struct cdev *p = container_of(kobj, struct cdev, kobj);
412 cdev_purge(p);
415 static void cdev_dynamic_release(struct kobject *kobj)
417 struct cdev *p = container_of(kobj, struct cdev, kobj);
418 cdev_purge(p);
419 kfree(p);
422 static struct kobj_type ktype_cdev_default = {
423 .release = cdev_default_release,
426 static struct kobj_type ktype_cdev_dynamic = {
427 .release = cdev_dynamic_release,
430 static struct kset kset_dynamic = {
431 .subsys = &cdev_subsys,
432 .kobj = {.name = "major",},
433 .ktype = &ktype_cdev_dynamic,
436 struct cdev *cdev_alloc(void)
438 struct cdev *p = kmalloc(sizeof(struct cdev), GFP_KERNEL);
439 if (p) {
440 memset(p, 0, sizeof(struct cdev));
441 p->kobj.kset = &kset_dynamic;
442 INIT_LIST_HEAD(&p->list);
443 kobject_init(&p->kobj);
445 return p;
448 void cdev_init(struct cdev *cdev, struct file_operations *fops)
450 INIT_LIST_HEAD(&cdev->list);
451 kobj_set_kset_s(cdev, cdev_subsys);
452 cdev->kobj.ktype = &ktype_cdev_default;
453 kobject_init(&cdev->kobj);
454 cdev->ops = fops;
457 static struct kobject *base_probe(dev_t dev, int *part, void *data)
459 char name[30];
460 sprintf(name, "char-major-%d", MAJOR(dev));
461 request_module(name);
462 return NULL;
465 void __init chrdev_init(void)
467 subsystem_register(&cdev_subsys);
468 kset_register(&kset_dynamic);
469 cdev_map = kobj_map_init(base_probe, &cdev_subsys);