|
|
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.1.4 ! root 16: extern int tty_read(unsigned minor,char * buf,int count,unsigned short flags);
1.1 root 17: extern int tty_write(unsigned minor,char * buf,int count);
18:
1.1.1.4 ! root 19: typedef (*crw_ptr)(int,unsigned,char *,int,off_t *,unsigned short);
1.1.1.2 root 20:
1.1.1.4 ! root 21: static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos, unsigned short flags)
1.1.1.2 root 22: {
1.1.1.4 ! root 23: return ((rw==READ)?tty_read(minor,buf,count,flags):
1.1.1.2 root 24: tty_write(minor,buf,count));
25: }
26:
1.1.1.4 ! root 27: static int rw_tty(int rw,unsigned minor,char * buf,int count, off_t * pos, unsigned short flags)
1.1.1.2 root 28: {
29: if (current->tty<0)
30: return -EPERM;
1.1.1.4 ! root 31: return rw_ttyx(rw,current->tty,buf,count,pos,flags);
1.1.1.2 root 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: {
1.1.1.4 ! root 46: /* kmem by Damiano */
! 47: int i = *pos; /* Current position where to read */
! 48:
! 49: /* i can go from 0 to LOW_MEM (See include/linux/mm.h */
! 50: /* I am not shure about it but it doesn't mem fault :-) */
! 51: while ( (count-- > 0) && (i <LOW_MEM) ) {
! 52: if (rw==READ)
! 53: put_fs_byte( *(char *)i ,buf++);
! 54: else
! 55: return (-EIO);
! 56: i++;
! 57: }
! 58: i -= *pos; /* Count how many read or write */
! 59: *pos += i; /* Update position */
! 60: return (i); /* Return number read */
1.1.1.2 root 61: }
62:
63: static int rw_port(int rw,char * buf, int count, off_t * pos)
64: {
65: int i=*pos;
66:
67: while (count-->0 && i<65536) {
68: if (rw==READ)
69: put_fs_byte(inb(i),buf++);
70: else
71: outb(get_fs_byte(buf++),i);
72: i++;
73: }
74: i -= *pos;
75: *pos += i;
76: return i;
77: }
78:
1.1.1.4 ! root 79: static int rw_memory(int rw, unsigned minor, char * buf, int count,
! 80: off_t * pos, unsigned short flags)
1.1.1.2 root 81: {
82: switch(minor) {
83: case 0:
84: return rw_ram(rw,buf,count,pos);
85: case 1:
86: return rw_mem(rw,buf,count,pos);
87: case 2:
88: return rw_kmem(rw,buf,count,pos);
89: case 3:
90: return (rw==READ)?0:count; /* rw_null */
91: case 4:
92: return rw_port(rw,buf,count,pos);
93: default:
94: return -EIO;
95: }
96: }
1.1 root 97:
98: #define NRDEVS ((sizeof (crw_table))/(sizeof (crw_ptr)))
99:
100: static crw_ptr crw_table[]={
101: NULL, /* nodev */
1.1.1.2 root 102: rw_memory, /* /dev/mem etc */
1.1 root 103: NULL, /* /dev/fd */
104: NULL, /* /dev/hd */
105: rw_ttyx, /* /dev/ttyx */
106: rw_tty, /* /dev/tty */
107: NULL, /* /dev/lp */
108: NULL}; /* unnamed pipes */
109:
1.1.1.4 ! root 110: int char_read(struct inode * inode, struct file * filp, char * buf, int count)
! 111: {
! 112: unsigned int major,minor;
! 113: crw_ptr call_addr;
! 114:
! 115: major = MAJOR(inode->i_rdev);
! 116: minor = MINOR(inode->i_rdev);
! 117: if (major >= NRDEVS)
! 118: return -ENODEV;
! 119: if (!(call_addr = crw_table[major]))
! 120: return -ENODEV;
! 121: return call_addr(READ,minor,buf,count,&filp->f_pos,filp->f_flags);
! 122: }
! 123:
! 124: int char_write(struct inode * inode, struct file * filp, char * buf, int count)
1.1 root 125: {
1.1.1.4 ! root 126: unsigned int major,minor;
1.1 root 127: crw_ptr call_addr;
128:
1.1.1.4 ! root 129: major = MAJOR(inode->i_rdev);
! 130: minor = MINOR(inode->i_rdev);
! 131: if (major >= NRDEVS)
1.1.1.3 root 132: return -ENODEV;
1.1.1.4 ! root 133: if (!(call_addr=crw_table[major]))
1.1.1.3 root 134: return -ENODEV;
1.1.1.4 ! root 135: return call_addr(WRITE,minor,buf,count,&filp->f_pos,filp->f_flags);
1.1 root 136: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.