struct device_struct {
const char * name;
struct file_operations * fops;
};
static struct device_struct chrdevs[MAX_CHRDEV];
register_chrdev(major, name, fops)
int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)
{
if (major == 0) {
for (major = MAX_CHRDEV-1; major > 0; major--) {
if (chrdevs[major].fops == NULL) {
chrdevs[major].name = name;
chrdevs[major].fops = fops;
return major;
}
}
}
...
chrdevs[major].name = name;
chrdevs[major].fops = fops;
...
return 0;
}
struct file_operations {
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*lock) (struct file *, int, struct file_lock *);
...
}
int chrdev_open(struct inode * inode, struct file * filp)
{
...
filp->f_op = chrdevs[MAJOR(inode->i_rdev)].fops;
...
ret = filp->f_op->open(inode,filp);
...
}
static struct {
const char *name;
struct block_device_operations *bdops;
} blkdevs[MAX_BLKDEV];
struct block_device_operations {
int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *);
int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
int (*check_media_change) (kdev_t);
int (*revalidate) (kdev_t);
};
int register_chrdev(unsigned int major, const char * name, struct file_operations *fops) int register_blkdev(unsigned int major, const char * name, struct block_device_operations *bdops)
int unregister_chrdev(unsigned int major, const char * name) int unregister_blkdev(unsigned int major, const char * name)
devfs_handle_t devfs_register (
devfs_handle_t dir,
const char *name,
unsigned int flags,
unsigned int major, unsigned int minor,
umode_t mode,
void *ops,
void *info);
extern void devfs_unregister (devfs_handle_t de);