ドライバ内部の file_operations 構造体(register_chrdev() 参照)は以下のように定義されています。この例を使って説明していきます。筆者が使っていない引数などは、当然解説不能です(^_^);
static struct file_operations Wd33c93a_fops =
{
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
wd33c_ioctl, /* ioctl */
NULL, /* mmap */
wd33c_open, /* open */
wd33c_release, /* release */
NULL, /* fsync */
NULL, /* fasync */
NULL, /* check_media_change */
NULL /* revalidate(再有効化) */
};
当該デバイスをアプリケーションが open(2) すると、wd33c_open() に制御が移ります。この関数は、以下の引数を取ります。
static int wd33c_open(
struct inode * inode, /* inode情報*/
struct file * filp, /* file 情報*/
各構造体の定義は、/usr/include/linux/fs.h にあります。ちょっと長いですが、引用します。
struct inode {
kdev_t i_dev;
unsigned long i_ino;
umode_t i_mode;
nlink_t i_nlink;
uid_t i_uid;
gid_t i_gid;
kdev_t i_rdev;
off_t i_size;
time_t i_atime;
time_t i_mtime;
time_t i_ctime;
unsigned long i_blksize;
unsigned long i_blocks;
unsigned long i_version;
unsigned long i_nrpages;
struct semaphore i_sem;
struct inode_operations *i_op;
struct super_block *i_sb;
struct wait_queue *i_wait;
struct file_lock *i_flock;
struct vm_area_struct *i_mmap;
struct page *i_pages;
struct dquot *i_dquot[MAXQUOTAS];
struct inode *i_next, *i_prev;
struct inode *i_hash_next, *i_hash_prev;
struct inode *i_bound_to, *i_bound_by;
struct inode *i_mount;
unsigned short i_count;
unsigned short i_flags;
unsigned char i_lock;
unsigned char i_dirt;
unsigned char i_pipe;
unsigned char i_sock;
unsigned char i_seek;
unsigned char i_update;
unsigned short i_writecount;
union {
struct pipe_inode_info pipe_i;
struct minix_inode_info minix_i;
struct ext_inode_info ext_i;
struct ext2_inode_info ext2_i;
struct hpfs_inode_info hpfs_i;
struct msdos_inode_info msdos_i;
struct umsdos_inode_info umsdos_i;
struct iso_inode_info isofs_i;
struct nfs_inode_info nfs_i;
struct xiafs_inode_info xiafs_i;
struct sysv_inode_info sysv_i;
struct affs_inode_info affs_i;
struct ufs_inode_info ufs_i;
struct socket socket_i;
void * generic_ip;
} u;
};
なんかごちゃごちゃと並んでいますが、私は全く使っていないのでよくわかりません。ブロック・デバイスのドライバを書く場合には必須になると思います。
struct file {
mode_t f_mode; /* O_READ|O_WRITEなど?*/
loff_t f_pos;
unsigned short f_flags; /* O_BINARYなど?*/
unsigned short f_count; /* 同時にオープンしているプロセス数? */
unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;
struct file *f_next, *f_prev;
int f_owner; /* pid or -pgrp where SIGIO should be sent */
struct inode * f_inode;
struct file_operations * f_op;
unsigned long f_version;
void *private_data; /* needed for tty driver, and maybe others */
};
当該デバイスを open(2) している「すべての」アプリケーションが close(2) するかまたは終了する時、wd33c_release() に制御が移ります。この関数は、以下の引数を取ります。
static void wd33c_release(当該ドライバの場合は、オープン中フラグを落としているくらいで、特に何も行っていません。
struct inode * inode, /* inode情報*/
struct file * filp); /* file 情報*/
当該デバイスを open(2) しているアプリケーションが ioctl(2) を発行すると、wd33c_ioctl() に制御が移ります。この関数は、以下の引数を取ります。
static int wd33c_ioctl(
struct inode * inode, /* inode情報*/
struct file * filp, /* file 情報*/
unsigned int iocmd, /* ユーザ定義コマンド */
unsigned long ioarg); /* コマンドへの引数 */