linux/fs/char_dev.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/char_dev.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 */
   6
   7#include <linux/init.h>
   8#include <linux/fs.h>
   9#include <linux/kdev_t.h>
  10#include <linux/slab.h>
  11#include <linux/string.h>
  12
  13#include <linux/major.h>
  14#include <linux/errno.h>
  15#include <linux/module.h>
  16#include <linux/smp_lock.h>
  17#include <linux/seq_file.h>
  18
  19#include <linux/kobject.h>
  20#include <linux/kobj_map.h>
  21#include <linux/cdev.h>
  22#include <linux/mutex.h>
  23#include <linux/backing-dev.h>
  24
  25#ifdef CONFIG_KMOD
  26#include <linux/kmod.h>
  27#endif
  28#include "internal.h"
  29
  30/*
  31 * capabilities for /dev/mem, /dev/kmem and similar directly mappable character
  32 * devices
  33 * - permits shared-mmap for read, write and/or exec
  34 * - does not permit private mmap in NOMMU mode (can't do COW)
  35 * - no readahead or I/O queue unplugging required
  36 */
  37struct backing_dev_info directly_mappable_cdev_bdi = {
  38        .capabilities   = (
  39#ifdef CONFIG_MMU
  40                /* permit private copies of the data to be taken */
  41                BDI_CAP_MAP_COPY |
  42#endif
  43                /* permit direct mmap, for read, write or exec */
  44                BDI_CAP_MAP_DIRECT |
  45                BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP),
  46};
  47
  48static struct kobj_map *cdev_map;
  49
  50static DEFINE_MUTEX(chrdevs_lock);
  51
  52static struct char_device_struct {
  53        struct char_device_struct *next;
  54        unsigned int major;
  55        unsigned int baseminor;
  56        int minorct;
  57        char name[64];
  58        struct file_operations *fops;
  59        struct cdev *cdev;              /* will die */
  60} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
  61
  62/* index in the above */
  63static inline int major_to_index(int major)
  64{
  65        return major % CHRDEV_MAJOR_HASH_SIZE;
  66}
  67
  68#ifdef CONFIG_PROC_FS
  69
  70void chrdev_show(struct seq_file *f, off_t offset)
  71{
  72        struct char_device_struct *cd;
  73
  74        if (offset < CHRDEV_MAJOR_HASH_SIZE) {
  75                mutex_lock(&chrdevs_lock);
  76                for (cd = chrdevs[offset]; cd; cd = cd->next)
  77                        seq_printf(f, "%3d %s\n", cd->major, cd->name);
  78                mutex_unlock(&chrdevs_lock);
  79        }
  80}
  81
  82#endif /* CONFIG_PROC_FS */
  83
  84/*
  85 * Register a single major with a specified minor range.
  86 *
  87 * If major == 0 this functions will dynamically allocate a major and return
  88 * its number.
  89 *
  90 * If major > 0 this function will attempt to reserve the passed range of
  91 * minors and will return zero on success.
  92 *
  93 * Returns a -ve errno on failure.
  94 */
  95static struct char_device_struct *
  96__register_chrdev_region(unsigned int major, unsigned int baseminor,
  97                           int minorct, const char *name)
  98{
  99        struct char_device_struct *cd, **cp;
 100        int ret = 0;
 101        int i;
 102
 103        cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);
 104        if (cd == NULL)
 105                return ERR_PTR(-ENOMEM);
 106
 107        mutex_lock(&chrdevs_lock);
 108
 109        /* temporary */
 110        if (major == 0) {
 111                for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) {
 112                        if (chrdevs[i] == NULL)
 113                                break;
 114                }
 115
 116                if (i == 0) {
 117                        ret = -EBUSY;
 118                        goto out;
 119                }
 120                major = i;
 121                ret = major;
 122        }
 123
 124        cd->major = major;
 125        cd->baseminor = baseminor;
 126        cd->minorct = minorct;
 127        strncpy(cd->name,name, 64);
 128
 129        i = major_to_index(major);
 130
 131        for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
 132                if ((*cp)->major > major ||
 133                    ((*cp)->major == major &&
 134                     (((*cp)->baseminor >= baseminor) ||
 135                      ((*cp)->baseminor + (*cp)->minorct > baseminor))))
 136                        break;
 137
 138        /* Check for overlapping minor ranges.  */
 139        if (*cp && (*cp)->major == major) {
 140                int old_min = (*cp)->baseminor;
 141                int old_max = (*cp)->baseminor + (*cp)->minorct - 1;
 142                int new_min = baseminor;
 143                int new_max = baseminor + minorct - 1;
 144
 145                /* New driver overlaps from the left.  */
 146                if (new_max >= old_min && new_max <= old_max) {
 147                        ret = -EBUSY;
 148                        goto out;
 149                }
 150
 151                /* New driver overlaps from the right.  */
 152                if (new_min <= old_max && new_min >= old_min) {
 153                        ret = -EBUSY;
 154                        goto out;
 155                }
 156        }
 157
 158        cd->next = *cp;
 159        *cp = cd;
 160        mutex_unlock(&chrdevs_lock);
 161        return cd;
 162out:
 163        mutex_unlock(&chrdevs_lock);
 164        kfree(cd);
 165        return ERR_PTR(ret);
 166}
 167
 168static struct char_device_struct *
 169__unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
 170{
 171        struct char_device_struct *cd = NULL, **cp;
 172        int i = major_to_index(major);
 173
 174        mutex_lock(&chrdevs_lock);
 175        for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
 176                if ((*cp)->major == major &&
 177                    (*cp)->baseminor == baseminor &&
 178                    (*cp)->minorct == minorct)
 179                        break;
 180        if (*cp) {
 181                cd = *cp;
 182                *cp = cd->next;
 183        }
 184        mutex_unlock(&chrdevs_lock);
 185        return cd;
 186}
 187
 188/**
 189 * register_chrdev_region() - register a range of device numbers
 190 * @from: the first in the desired range of device numbers; must include
 191 *        the major number.
 192 * @count: the number of consecutive device numbers required
 193 * @name: the name of the device or driver.
 194 *
 195 * Return value is zero on success, a negative error code on failure.
 196 */
 197int register_chrdev_region(dev_t from, unsigned count, const char *name)
 198{
 199        struct char_device_struct *cd;
 200        dev_t to = from + count;
 201        dev_t n, next;
 202
 203        for (n = from; n < to; n = next) {
 204                next = MKDEV(MAJOR(n)+1, 0);
 205                if (next > to)
 206                        next = to;
 207                cd = __register_chrdev_region(MAJOR(n), MINOR(n),
 208                               next - n, name);
 209                if (IS_ERR(cd))
 210                        goto fail;
 211        }
 212        return 0;
 213fail:
 214        to = n;
 215        for (n = from; n < to; n = next) {
 216                next = MKDEV(MAJOR(n)+1, 0);
 217                kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
 218        }
 219        return PTR_ERR(cd);
 220}
 221
 222/**
 223 * alloc_chrdev_region() - register a range of char device numbers
 224 * @dev: output parameter for first assigned number
 225 * @baseminor: first of the requested range of minor numbers
 226 * @count: the number of minor numbers required
 227 * @name: the name of the associated device or driver
 228 *
 229 * Allocates a range of char device numbers.  The major number will be
 230 * chosen dynamically, and returned (along with the first minor number)
 231 * in @dev.  Returns zero or a negative error code.
 232 */
 233int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
 234                        const char *name)
 235{
 236        struct char_device_struct *cd;
 237        cd = __register_chrdev_region(0, baseminor, count, name);
 238        if (IS_ERR(cd))
 239                return PTR_ERR(cd);
 240        *dev = MKDEV(cd->major, cd->baseminor);
 241        return 0;
 242}
 243
 244/**
 245 * register_chrdev() - Register a major number for character devices.
 246 * @major: major device number or 0 for dynamic allocation
 247 * @name: name of this range of devices
 248 * @fops: file operations associated with this devices
 249 *
 250 * If @major == 0 this functions will dynamically allocate a major and return
 251 * its number.
 252 *
 253 * If @major > 0 this function will attempt to reserve a device with the given
 254 * major number and will return zero on success.
 255 *
 256 * Returns a -ve errno on failure.
 257 *
 258 * The name of this device has nothing to do with the name of the device in
 259 * /dev. It only helps to keep track of the different owners of devices. If
 260 * your module name has only one type of devices it's ok to use e.g. the name
 261 * of the module here.
 262 *
 263 * This function registers a range of 256 minor numbers. The first minor number
 264 * is 0.
 265 */
 266int register_chrdev(unsigned int major, const char *name,
 267                    const struct file_operations *fops)
 268{
 269        struct char_device_struct *cd;
 270        struct cdev *cdev;
 271        char *s;
 272        int err = -ENOMEM;
 273
 274        cd = __register_chrdev_region(major, 0, 256, name);
 275        if (IS_ERR(cd))
 276                return PTR_ERR(cd);
 277        
 278        cdev = cdev_alloc();
 279        if (!cdev)
 280                goto out2;
 281
 282        cdev->owner = fops->owner;
 283        cdev->ops = fops;
 284        kobject_set_name(&cdev->kobj, "%s", name);
 285        for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/'))
 286                *s = '!';
 287                
 288        err = cdev_add(cdev, MKDEV(cd->major, 0), 256);
 289        if (err)
 290                goto out;
 291
 292        cd->cdev = cdev;
 293
 294        return major ? 0 : cd->major;
 295out:
 296        kobject_put(&cdev->kobj);
 297out2:
 298        kfree(__unregister_chrdev_region(cd->major, 0, 256));
 299        return err;
 300}
 301
 302/**
 303 * unregister_chrdev_region() - return a range of device numbers
 304 * @from: the first in the range of numbers to unregister
 305 * @count: the number of device numbers to unregister
 306 *
 307 * This function will unregister a range of @count device numbers,
 308 * starting with @from.  The caller should normally be the one who
 309 * allocated those numbers in the first place...
 310 */
 311void unregister_chrdev_region(dev_t from, unsigned count)
 312{
 313        dev_t to = from + count;
 314        dev_t n, next;
 315
 316        for (n = from; n < to; n = next) {
 317                next = MKDEV(MAJOR(n)+1, 0);
 318                if (next > to)
 319                        next = to;
 320                kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
 321        }
 322}
 323
 324void unregister_chrdev(unsigned int major, const char *name)
 325{
 326        struct char_device_struct *cd;
 327        cd = __unregister_chrdev_region(major, 0, 256);
 328        if (cd && cd->cdev)
 329                cdev_del(cd->cdev);
 330        kfree(cd);
 331}
 332
 333static DEFINE_SPINLOCK(cdev_lock);
 334
 335static struct kobject *cdev_get(struct cdev *p)
 336{
 337        struct module *owner = p->owner;
 338        struct kobject *kobj;
 339
 340        if (owner && !try_module_get(owner))
 341                return NULL;
 342        kobj = kobject_get(&p->kobj);
 343        if (!kobj)
 344                module_put(owner);
 345        return kobj;
 346}
 347
 348void cdev_put(struct cdev *p)
 349{
 350        if (p) {
 351                struct module *owner = p->owner;
 352                kobject_put(&p->kobj);
 353                module_put(owner);
 354        }
 355}
 356
 357/*
 358 * Called every time a character special file is opened
 359 */
 360int chrdev_open(struct inode * inode, struct file * filp)
 361{
 362        struct cdev *p;
 363        struct cdev *new = NULL;
 364        int ret = 0;
 365
 366        spin_lock(&cdev_lock);
 367        p = inode->i_cdev;
 368        if (!p) {
 369                struct kobject *kobj;
 370                int idx;
 371                spin_unlock(&cdev_lock);
 372                kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
 373                if (!kobj)
 374                        return -ENXIO;
 375                new = container_of(kobj, struct cdev, kobj);
 376                spin_lock(&cdev_lock);
 377                p = inode->i_cdev;
 378                if (!p) {
 379                        inode->i_cdev = p = new;
 380                        inode->i_cindex = idx;
 381                        list_add(&inode->i_devices, &p->list);
 382                        new = NULL;
 383                } else if (!cdev_get(p))
 384                        ret = -ENXIO;
 385        } else if (!cdev_get(p))
 386                ret = -ENXIO;
 387        spin_unlock(&cdev_lock);
 388        cdev_put(new);
 389        if (ret)
 390                return ret;
 391        filp->f_op = fops_get(p->ops);
 392        if (!filp->f_op) {
 393                cdev_put(p);
 394                return -ENXIO;
 395        }
 396        if (filp->f_op->open) {
 397                lock_kernel();
 398                ret = filp->f_op->open(inode,filp);
 399                unlock_kernel();
 400        }
 401        if (ret)
 402                cdev_put(p);
 403        return ret;
 404}
 405
 406void cd_forget(struct inode *inode)
 407{
 408        spin_lock(&cdev_lock);
 409        list_del_init(&inode->i_devices);
 410        inode->i_cdev = NULL;
 411        spin_unlock(&cdev_lock);
 412}
 413
 414static void cdev_purge(struct cdev *cdev)
 415{
 416        spin_lock(&cdev_lock);
 417        while (!list_empty(&cdev->list)) {
 418                struct inode *inode;
 419                inode = container_of(cdev->list.next, struct inode, i_devices);
 420                list_del_init(&inode->i_devices);
 421                inode->i_cdev = NULL;
 422        }
 423        spin_unlock(&cdev_lock);
 424}
 425
 426/*
 427 * Dummy default file-operations: the only thing this does
 428 * is contain the open that then fills in the correct operations
 429 * depending on the special file...
 430 */
 431const struct file_operations def_chr_fops = {
 432        .open = chrdev_open,
 433};
 434
 435static struct kobject *exact_match(dev_t dev, int *part, void *data)
 436{
 437        struct cdev *p = data;
 438        return &p->kobj;
 439}
 440
 441static int exact_lock(dev_t dev, void *data)
 442{
 443        struct cdev *p = data;
 444        return cdev_get(p) ? 0 : -1;
 445}
 446
 447/**
 448 * cdev_add() - add a char device to the system
 449 * @p: the cdev structure for the device
 450 * @dev: the first device number for which this device is responsible
 451 * @count: the number of consecutive minor numbers corresponding to this
 452 *         device
 453 *
 454 * cdev_add() adds the device represented by @p to the system, making it
 455 * live immediately.  A negative error code is returned on failure.
 456 */
 457int cdev_add(struct cdev *p, dev_t dev, unsigned count)
 458{
 459        p->dev = dev;
 460        p->count = count;
 461        return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
 462}
 463
 464static void cdev_unmap(dev_t dev, unsigned count)
 465{
 466        kobj_unmap(cdev_map, dev, count);
 467}
 468
 469/**
 470 * cdev_del() - remove a cdev from the system
 471 * @p: the cdev structure to be removed
 472 *
 473 * cdev_del() removes @p from the system, possibly freeing the structure
 474 * itself.
 475 */
 476void cdev_del(struct cdev *p)
 477{
 478        cdev_unmap(p->dev, p->count);
 479        kobject_put(&p->kobj);
 480}
 481
 482
 483static void cdev_default_release(struct kobject *kobj)
 484{
 485        struct cdev *p = container_of(kobj, struct cdev, kobj);
 486        cdev_purge(p);
 487}
 488
 489static void cdev_dynamic_release(struct kobject *kobj)
 490{
 491        struct cdev *p = container_of(kobj, struct cdev, kobj);
 492        cdev_purge(p);
 493        kfree(p);
 494}
 495
 496static struct kobj_type ktype_cdev_default = {
 497        .release        = cdev_default_release,
 498};
 499
 500static struct kobj_type ktype_cdev_dynamic = {
 501        .release        = cdev_dynamic_release,
 502};
 503
 504/**
 505 * cdev_alloc() - allocate a cdev structure
 506 *
 507 * Allocates and returns a cdev structure, or NULL on failure.
 508 */
 509struct cdev *cdev_alloc(void)
 510{
 511        struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
 512        if (p) {
 513                p->kobj.ktype = &ktype_cdev_dynamic;
 514                INIT_LIST_HEAD(&p->list);
 515                kobject_init(&p->kobj);
 516        }
 517        return p;
 518}
 519
 520/**
 521 * cdev_init() - initialize a cdev structure
 522 * @cdev: the structure to initialize
 523 * @fops: the file_operations for this device
 524 *
 525 * Initializes @cdev, remembering @fops, making it ready to add to the
 526 * system with cdev_add().
 527 */
 528void cdev_init(struct cdev *cdev, const struct file_operations *fops)
 529{
 530        memset(cdev, 0, sizeof *cdev);
 531        INIT_LIST_HEAD(&cdev->list);
 532        cdev->kobj.ktype = &ktype_cdev_default;
 533        kobject_init(&cdev->kobj);
 534        cdev->ops = fops;
 535}
 536
 537static struct kobject *base_probe(dev_t dev, int *part, void *data)
 538{
 539        if (request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0)
 540                /* Make old-style 2.4 aliases work */
 541                request_module("char-major-%d", MAJOR(dev));
 542        return NULL;
 543}
 544
 545void __init chrdev_init(void)
 546{
 547        cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
 548        bdi_init(&directly_mappable_cdev_bdi);
 549}
 550
 551
 552/* Let modules do char dev stuff */
 553EXPORT_SYMBOL(register_chrdev_region);
 554EXPORT_SYMBOL(unregister_chrdev_region);
 555EXPORT_SYMBOL(alloc_chrdev_region);
 556EXPORT_SYMBOL(cdev_init);
 557EXPORT_SYMBOL(cdev_alloc);
 558EXPORT_SYMBOL(cdev_del);
 559EXPORT_SYMBOL(cdev_add);
 560EXPORT_SYMBOL(register_chrdev);
 561EXPORT_SYMBOL(unregister_chrdev);
 562EXPORT_SYMBOL(directly_mappable_cdev_bdi);
 563