Chinaunix首页 | 论坛 | 博客
  • 博客访问: 569267
  • 博文数量: 137
  • 博客积分: 4040
  • 博客等级: 上校
  • 技术积分: 1584
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-08 13:05
文章分类

全部博文(137)

文章存档

2011年(10)

2010年(23)

2009年(104)

分类: LINUX

2009-08-19 11:10:52

/*
 * linux/fs/char_dev.c
 *
 * (C) 1991 Linus Torvalds
 */


#include <errno.h>
#include <sys/types.h>

#include <linux/sched.h>
#include <linux/kernel.h>

#include <asm/segment.h>
#include <asm/io.h>

extern int tty_read(unsigned minor,char * buf,int count);// 终端读

extern int tty_write(unsigned minor,char * buf,int count);// 终端写


typedef (*crw_ptr)(int rw,unsigned minor,char * buf,int count,off_t * pos);// 定义字符设备读写函数指针类型


static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos)// 串口终端读写操作函数

{//参数:rw - 读写命令;minor - 终端子设备号;buf - 缓冲区;cout - 读写字节数 pos - 读写操作当前指针,对于终端操作,该指针无用

    return ((rw==READ)?tty_read(minor,buf,count):
        tty_write(minor,buf,count));
}

static int rw_tty(int rw,unsigned minor,char * buf,int count, off_t * pos)// 终端读写操作函数

{// 同上rw_ttyx(),只是增加了对进程是否有控制终端的检测

    if (current->tty<0)
        return -EPERM;
    return rw_ttyx(rw,current->tty,buf,count,pos);
}

static int rw_ram(int rw,char * buf, int count, off_t *pos)// 内存数据读写

{
    return -EIO;
}

static int rw_mem(int rw,char * buf, int count, off_t * pos)// 内存数据读写操作函数

{
    return -EIO;
}

static int rw_kmem(int rw,char * buf, int count, off_t * pos)// 内核数据区读写函数

{
    return -EIO;
}

static int rw_port(int rw,char * buf, int count, off_t * pos)// 端口读写操作函数

{// 参数:rw - 读写命令;buf - 缓冲区;cout - 读写字节数;pos - 端口地址

    int i=*pos;//端口地址


    while (count-->0 && i<65536) {// 对于所要求读写的字节数,并且端口地址小于64k 时,循环执行"单个字节"的读写操作

        if (rw==READ)// 若是读命令,则从端口i 中读取一字节内容并放到用户缓冲区中

            put_fs_byte(inb(i),buf++);
        else// 若是写命令,则从用户数据缓冲区中取一字节输出到端口i

            outb(get_fs_byte(buf++),i);
        i++;// 前移一个端口

    }
    i -= *pos;// 计算读/写的字节数,

    *pos += i;//并相应调整读写指针

    return i;// 返回读/写的字节数。

}

static int rw_memory(int rw, unsigned minor, char * buf, int count, off_t * pos)// 内存读写操作函数

{// 根据内存设备子设备号,分别调用不同的内存读写函数

    switch(minor) {
        case 0:
            return rw_ram(rw,buf,count,pos);
        case 1:
            return rw_mem(rw,buf,count,pos);
        case 2:
            return rw_kmem(rw,buf,count,pos);
        case 3:
            return (rw==READ)?0:count;    /* rw_null */
        case 4:
            return rw_port(rw,buf,count,pos);
        default:
            return -EIO;
    }
}
// 定义系统中设备种数。

#define NRDEVS ((sizeof (crw_table))/(sizeof (crw_ptr)))
// 字符设备读写函数指针表。

static crw_ptr crw_table[]={
    NULL,        /* nodev */
    rw_memory,    /* /dev/mem etc */
    NULL,        /* /dev/fd */
    NULL,        /* /dev/hd */
    rw_ttyx,    /* /dev/ttyx */
    rw_tty,        /* /dev/tty */
    NULL,        /* /dev/lp */
    NULL};        /* unnamed pipes */

int rw_char(int rw,int dev, char * buf, int count, off_t * pos)// 字符设备读写操作函数

{// 参数:rw - 读写命令;dev - 设备号;buf - 缓冲区;count - 读写字节数;pos -读写指针

    crw_ptr call_addr;

    if (MAJOR(dev)>=NRDEVS)// 取主设备号

        return -ENODEV;
    if (!(call_addr=crw_table[MAJOR(dev)]))// 取该设备对应的读写函数

        return -ENODEV;
    return call_addr(rw,MINOR(dev),buf,count,pos);//调用对应设备的读写操作函数

}

阅读(830) | 评论(0) | 转发(0) |
0

上一篇:pipe.c

下一篇:read_write.c

给主人留下些什么吧!~~