Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / char_dev.c
blob7357a9127df1551066f4b07554e2ccddd598633e
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/errno.h>
15 #include <linux/module.h>
16 #include <linux/smp_lock.h>
17 #include <linux/devfs_fs_kernel.h>
19 #include <linux/kobject.h>
20 #include <linux/kobj_map.h>
21 #include <linux/cdev.h>
23 #ifdef CONFIG_KMOD
24 #include <linux/kmod.h>
25 #endif
27 static struct kobj_map *cdev_map;
29 /* degrade to linked list for small systems */
30 #define MAX_PROBE_HASH (CONFIG_BASE_SMALL ? 1 : 255)
32 static DECLARE_MUTEX(chrdevs_lock);
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 down(&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 up(&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 down(&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 up(&chrdevs_lock);
130 return cd;
131 out:
132 up(&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 up(&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 up(&chrdevs_lock);
154 return cd;
157 int register_chrdev_region(dev_t from, unsigned count, const 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,
183 const char *name)
185 struct char_device_struct *cd;
186 cd = __register_chrdev_region(0, baseminor, count, name);
187 if (IS_ERR(cd))
188 return PTR_ERR(cd);
189 *dev = MKDEV(cd->major, cd->baseminor);
190 return 0;
193 int register_chrdev(unsigned int major, const char *name,
194 struct file_operations *fops)
196 struct char_device_struct *cd;
197 struct cdev *cdev;
198 char *s;
199 int err = -ENOMEM;
201 cd = __register_chrdev_region(major, 0, 256, name);
202 if (IS_ERR(cd))
203 return PTR_ERR(cd);
205 cdev = cdev_alloc();
206 if (!cdev)
207 goto out2;
209 cdev->owner = fops->owner;
210 cdev->ops = fops;
211 kobject_set_name(&cdev->kobj, "%s", name);
212 for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/'))
213 *s = '!';
215 err = cdev_add(cdev, MKDEV(cd->major, 0), 256);
216 if (err)
217 goto out;
219 cd->cdev = cdev;
221 return major ? 0 : cd->major;
222 out:
223 kobject_put(&cdev->kobj);
224 out2:
225 kfree(__unregister_chrdev_region(cd->major, 0, 256));
226 return err;
229 void unregister_chrdev_region(dev_t from, unsigned count)
231 dev_t to = from + count;
232 dev_t n, next;
234 for (n = from; n < to; n = next) {
235 next = MKDEV(MAJOR(n)+1, 0);
236 if (next > to)
237 next = to;
238 kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
242 int unregister_chrdev(unsigned int major, const char *name)
244 struct char_device_struct *cd;
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 DEFINE_SPINLOCK(cdev_lock);
254 static struct kobject *cdev_get(struct cdev *p)
256 struct module *owner = p->owner;
257 struct kobject *kobj;
259 if (owner && !try_module_get(owner))
260 return NULL;
261 kobj = kobject_get(&p->kobj);
262 if (!kobj)
263 module_put(owner);
264 return kobj;
267 void cdev_put(struct cdev *p)
269 if (p) {
270 kobject_put(&p->kobj);
271 module_put(p->owner);
276 * Called every time a character special file is opened
278 int chrdev_open(struct inode * inode, struct file * filp)
280 struct cdev *p;
281 struct cdev *new = NULL;
282 int ret = 0;
284 spin_lock(&cdev_lock);
285 p = inode->i_cdev;
286 if (!p) {
287 struct kobject *kobj;
288 int idx;
289 spin_unlock(&cdev_lock);
290 kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
291 if (!kobj)
292 return -ENXIO;
293 new = container_of(kobj, struct cdev, kobj);
294 spin_lock(&cdev_lock);
295 p = inode->i_cdev;
296 if (!p) {
297 inode->i_cdev = p = new;
298 inode->i_cindex = idx;
299 list_add(&inode->i_devices, &p->list);
300 new = NULL;
301 } else if (!cdev_get(p))
302 ret = -ENXIO;
303 } else if (!cdev_get(p))
304 ret = -ENXIO;
305 spin_unlock(&cdev_lock);
306 cdev_put(new);
307 if (ret)
308 return ret;
309 filp->f_op = fops_get(p->ops);
310 if (!filp->f_op) {
311 cdev_put(p);
312 return -ENXIO;
314 if (filp->f_op->open) {
315 lock_kernel();
316 ret = filp->f_op->open(inode,filp);
317 unlock_kernel();
319 if (ret)
320 cdev_put(p);
321 return ret;
324 void cd_forget(struct inode *inode)
326 spin_lock(&cdev_lock);
327 list_del_init(&inode->i_devices);
328 inode->i_cdev = NULL;
329 spin_unlock(&cdev_lock);
332 void cdev_purge(struct cdev *cdev)
334 spin_lock(&cdev_lock);
335 while (!list_empty(&cdev->list)) {
336 struct inode *inode;
337 inode = container_of(cdev->list.next, struct inode, i_devices);
338 list_del_init(&inode->i_devices);
339 inode->i_cdev = NULL;
341 spin_unlock(&cdev_lock);
345 * Dummy default file-operations: the only thing this does
346 * is contain the open that then fills in the correct operations
347 * depending on the special file...
349 struct file_operations def_chr_fops = {
350 .open = chrdev_open,
353 static struct kobject *exact_match(dev_t dev, int *part, void *data)
355 struct cdev *p = data;
356 return &p->kobj;
359 static int exact_lock(dev_t dev, void *data)
361 struct cdev *p = data;
362 return cdev_get(p) ? 0 : -1;
365 int cdev_add(struct cdev *p, dev_t dev, unsigned count)
367 p->dev = dev;
368 p->count = count;
369 return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
372 static void cdev_unmap(dev_t dev, unsigned count)
374 kobj_unmap(cdev_map, dev, count);
377 void cdev_del(struct cdev *p)
379 cdev_unmap(p->dev, p->count);
380 kobject_put(&p->kobj);
384 static void cdev_default_release(struct kobject *kobj)
386 struct cdev *p = container_of(kobj, struct cdev, kobj);
387 cdev_purge(p);
390 static void cdev_dynamic_release(struct kobject *kobj)
392 struct cdev *p = container_of(kobj, struct cdev, kobj);
393 cdev_purge(p);
394 kfree(p);
397 static struct kobj_type ktype_cdev_default = {
398 .release = cdev_default_release,
401 static struct kobj_type ktype_cdev_dynamic = {
402 .release = cdev_dynamic_release,
405 struct cdev *cdev_alloc(void)
407 struct cdev *p = kmalloc(sizeof(struct cdev), GFP_KERNEL);
408 if (p) {
409 memset(p, 0, sizeof(struct cdev));
410 p->kobj.ktype = &ktype_cdev_dynamic;
411 INIT_LIST_HEAD(&p->list);
412 kobject_init(&p->kobj);
414 return p;
417 void cdev_init(struct cdev *cdev, struct file_operations *fops)
419 memset(cdev, 0, sizeof *cdev);
420 INIT_LIST_HEAD(&cdev->list);
421 cdev->kobj.ktype = &ktype_cdev_default;
422 kobject_init(&cdev->kobj);
423 cdev->ops = fops;
426 static struct kobject *base_probe(dev_t dev, int *part, void *data)
428 if (request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0)
429 /* Make old-style 2.4 aliases work */
430 request_module("char-major-%d", MAJOR(dev));
431 return NULL;
434 void __init chrdev_init(void)
436 cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
440 /* Let modules do char dev stuff */
441 EXPORT_SYMBOL(register_chrdev_region);
442 EXPORT_SYMBOL(unregister_chrdev_region);
443 EXPORT_SYMBOL(alloc_chrdev_region);
444 EXPORT_SYMBOL(cdev_init);
445 EXPORT_SYMBOL(cdev_alloc);
446 EXPORT_SYMBOL(cdev_del);
447 EXPORT_SYMBOL(cdev_add);
448 EXPORT_SYMBOL(register_chrdev);
449 EXPORT_SYMBOL(unregister_chrdev);