|
|
1.1.1.2 ! root 1: /* ! 2: * linux/fs/char_dev.c ! 3: * ! 4: * (C) 1991 Linus Torvalds ! 5: */ ! 6: 1.1 root 7: #include <errno.h> 1.1.1.2 ! root 8: #include <sys/types.h> 1.1 root 9: 10: #include <linux/sched.h> 11: #include <linux/kernel.h> 12: 1.1.1.2 ! root 13: #include <asm/segment.h> ! 14: #include <asm/io.h> ! 15: 1.1 root 16: extern int tty_read(unsigned minor,char * buf,int count); 17: extern int tty_write(unsigned minor,char * buf,int count); 18: 1.1.1.2 ! root 19: typedef (*crw_ptr)(int rw,unsigned minor,char * buf,int count,off_t * pos); ! 20: ! 21: static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos) ! 22: { ! 23: return ((rw==READ)?tty_read(minor,buf,count): ! 24: tty_write(minor,buf,count)); ! 25: } ! 26: ! 27: static int rw_tty(int rw,unsigned minor,char * buf,int count, off_t * pos) ! 28: { ! 29: if (current->tty<0) ! 30: return -EPERM; ! 31: return rw_ttyx(rw,current->tty,buf,count,pos); ! 32: } ! 33: ! 34: static int rw_ram(int rw,char * buf, int count, off_t *pos) ! 35: { ! 36: return -EIO; ! 37: } ! 38: ! 39: static int rw_mem(int rw,char * buf, int count, off_t * pos) ! 40: { ! 41: return -EIO; ! 42: } 1.1 root 43: 1.1.1.2 ! root 44: static int rw_kmem(int rw,char * buf, int count, off_t * pos) ! 45: { ! 46: return -EIO; ! 47: } ! 48: ! 49: static int rw_port(int rw,char * buf, int count, off_t * pos) ! 50: { ! 51: int i=*pos; ! 52: ! 53: while (count-->0 && i<65536) { ! 54: if (rw==READ) ! 55: put_fs_byte(inb(i),buf++); ! 56: else ! 57: outb(get_fs_byte(buf++),i); ! 58: i++; ! 59: } ! 60: i -= *pos; ! 61: *pos += i; ! 62: return i; ! 63: } ! 64: ! 65: static int rw_memory(int rw, unsigned minor, char * buf, int count, off_t * pos) ! 66: { ! 67: switch(minor) { ! 68: case 0: ! 69: return rw_ram(rw,buf,count,pos); ! 70: case 1: ! 71: return rw_mem(rw,buf,count,pos); ! 72: case 2: ! 73: return rw_kmem(rw,buf,count,pos); ! 74: case 3: ! 75: return (rw==READ)?0:count; /* rw_null */ ! 76: case 4: ! 77: return rw_port(rw,buf,count,pos); ! 78: default: ! 79: return -EIO; ! 80: } ! 81: } 1.1 root 82: 83: #define NRDEVS ((sizeof (crw_table))/(sizeof (crw_ptr))) 84: 85: static crw_ptr crw_table[]={ 86: NULL, /* nodev */ 1.1.1.2 ! root 87: rw_memory, /* /dev/mem etc */ 1.1 root 88: NULL, /* /dev/fd */ 89: NULL, /* /dev/hd */ 90: rw_ttyx, /* /dev/ttyx */ 91: rw_tty, /* /dev/tty */ 92: NULL, /* /dev/lp */ 93: NULL}; /* unnamed pipes */ 94: 1.1.1.2 ! root 95: int rw_char(int rw,int dev, char * buf, int count, off_t * pos) 1.1 root 96: { 97: crw_ptr call_addr; 98: 99: if (MAJOR(dev)>=NRDEVS) 100: panic("rw_char: dev>NRDEV"); 101: if (!(call_addr=crw_table[MAJOR(dev)])) { 102: printk("dev: %04x\n",dev); 103: panic("Trying to r/w from/to nonexistent character device"); 104: } 1.1.1.2 ! root 105: return call_addr(rw,MINOR(dev),buf,count,pos); 1.1 root 106: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.