root/fs/devices.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_device_list
  2. get_blkfops
  3. get_chrfops
  4. register_chrdev
  5. register_blkdev
  6. unregister_chrdev
  7. unregister_blkdev
  8. blkdev_open
  9. chrdev_open

   1 /*
   2  *  linux/fs/devices.c
   3  *
   4  * (C) 1993 Matthias Urlichs -- collected common code and tables.
   5  * 
   6  *  Copyright (C) 1991, 1992  Linus Torvalds
   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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  * Called every time a block special file is opened
 115  */
 116 int blkdev_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  * Dummy default file-operations: the only thing this does
 131  * is contain the open that then fills in the correct operations
 132  * depending on the special file...
 133  */
 134 struct file_operations def_blk_fops = {
 135         NULL,           /* lseek */
 136         NULL,           /* read */
 137         NULL,           /* write */
 138         NULL,           /* readdir */
 139         NULL,           /* select */
 140         NULL,           /* ioctl */
 141         NULL,           /* mmap */
 142         blkdev_open,    /* open */
 143         NULL,           /* release */
 144 };
 145 
 146 struct inode_operations blkdev_inode_operations = {
 147         &def_blk_fops,          /* default file operations */
 148         NULL,                   /* create */
 149         NULL,                   /* lookup */
 150         NULL,                   /* link */
 151         NULL,                   /* unlink */
 152         NULL,                   /* symlink */
 153         NULL,                   /* mkdir */
 154         NULL,                   /* rmdir */
 155         NULL,                   /* mknod */
 156         NULL,                   /* rename */
 157         NULL,                   /* readlink */
 158         NULL,                   /* follow_link */
 159         NULL,                   /* bmap */
 160         NULL,                   /* truncate */
 161         NULL                    /* permission */
 162 };
 163 
 164 /*
 165  * Called every time a character special file is opened
 166  */
 167 int chrdev_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  * Dummy default file-operations: the only thing this does
 182  * is contain the open that then fills in the correct operations
 183  * depending on the special file...
 184  */
 185 struct file_operations def_chr_fops = {
 186         NULL,           /* lseek */
 187         NULL,           /* read */
 188         NULL,           /* write */
 189         NULL,           /* readdir */
 190         NULL,           /* select */
 191         NULL,           /* ioctl */
 192         NULL,           /* mmap */
 193         chrdev_open,    /* open */
 194         NULL,           /* release */
 195 };
 196 
 197 struct inode_operations chrdev_inode_operations = {
 198         &def_chr_fops,          /* default file operations */
 199         NULL,                   /* create */
 200         NULL,                   /* lookup */
 201         NULL,                   /* link */
 202         NULL,                   /* unlink */
 203         NULL,                   /* symlink */
 204         NULL,                   /* mkdir */
 205         NULL,                   /* rmdir */
 206         NULL,                   /* mknod */
 207         NULL,                   /* rename */
 208         NULL,                   /* readlink */
 209         NULL,                   /* follow_link */
 210         NULL,                   /* bmap */
 211         NULL,                   /* truncate */
 212         NULL                    /* permission */
 213 };

/* [previous][next][first][last][top][bottom][index][help] */