ドライバと上位APとのインターフェース


ここでは、当該ドライバがサポートしているシステムコールについて「のみ」解説します。

  1. file_operations 構造体

    ドライバ内部の 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(再有効化) */
    };

  2. open()

    当該デバイスをアプリケーションが 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 */
    };

  3. release()

    当該デバイスを open(2) している「すべての」アプリケーションが close(2) するかまたは終了する時、wd33c_release() に制御が移ります。この関数は、以下の引数を取ります。

      static void wd33c_release(
        struct inode * inode, /* inode情報*/
        struct file * filp); /* file 情報*/
    当該ドライバの場合は、オープン中フラグを落としているくらいで、特に何も行っていません。

  4. ioctl()

    当該デバイスを open(2) しているアプリケーションが ioctl(2) を発行すると、wd33c_ioctl() に制御が移ります。この関数は、以下の引数を取ります。

      static int wd33c_ioctl(
        struct inode * inode, /* inode情報*/
        struct file * filp, /* file 情報*/
        unsigned int iocmd, /* ユーザ定義コマンド */
        unsigned long ioarg); /* コマンドへの引数 */