|
|
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)
1.1.1.3 ! root 100: return -ENODEV;
! 101: if (!(call_addr=crw_table[MAJOR(dev)]))
! 102: return -ENODEV;
1.1.1.2 root 103: return call_addr(rw,MINOR(dev),buf,count,pos);
1.1 root 104: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.