Annotation of linux/kernel/chr_drv/mem.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  *  linux/kernel/chr_drv/mem.c
                      3:  *
1.1.1.4 ! root        4:  *  Copyright (C) 1991, 1992  Linus Torvalds
1.1       root        5:  */
                      6: 
1.1.1.4 ! root        7: #include <linux/types.h>
        !             8: #include <linux/errno.h>
1.1       root        9: #include <linux/sched.h>
                     10: #include <linux/kernel.h>
                     11: #include <linux/tty.h>
1.1.1.4 ! root       12: #include <linux/mouse.h>
1.1       root       13: 
                     14: #include <asm/segment.h>
                     15: #include <asm/io.h>
                     16: 
                     17: static int read_ram(struct inode * inode, struct file * file,char * buf, int count)
                     18: {
                     19:        return -EIO;
                     20: }
                     21: 
                     22: static int write_ram(struct inode * inode, struct file * file,char * buf, int count)
                     23: {
                     24:        return -EIO;
                     25: }
                     26: 
                     27: static int read_mem(struct inode * inode, struct file * file,char * buf, int count)
                     28: {
                     29:        unsigned long addr;
                     30:        char *tmp;
                     31:        unsigned long pde, pte, page;
                     32:        int i;
                     33: 
                     34:        if (count < 0)
                     35:                return -EINVAL;
                     36:        addr = file->f_pos;
                     37:        tmp = buf;
                     38:        while (count > 0) {
1.1.1.4 ! root       39:                if (current->signal & ~current->blocked)
        !            40:                        break;
1.1       root       41:                pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
1.1.1.4 ! root       42:                pte = *(unsigned long *) pde;
        !            43:                if (!(pte & PAGE_PRESENT))
1.1       root       44:                        break;
                     45:                pte &= 0xfffff000;
                     46:                pte += (addr >> 10) & 0xffc;
1.1.1.4 ! root       47:                page = *(unsigned long *) pte;
        !            48:                if (!(page & 1))
1.1       root       49:                        break;
                     50:                page &= 0xfffff000;
                     51:                page += addr & 0xfff;
                     52:                i = 4096-(addr & 0xfff);
                     53:                if (i > count)
                     54:                        i = count;
                     55:                memcpy_tofs(tmp,(void *) page,i);
                     56:                addr += i;
                     57:                tmp += i;
                     58:                count -= i;
                     59:        }
                     60:        file->f_pos = addr;
                     61:        return tmp-buf;
                     62: }
                     63: 
                     64: static int write_mem(struct inode * inode, struct file * file,char * buf, int count)
                     65: {
                     66:        unsigned long addr;
                     67:        char *tmp;
                     68:        unsigned long pde, pte, page;
                     69:        int i;
                     70: 
                     71:        if (count < 0)
                     72:                return -EINVAL;
                     73:        addr = file->f_pos;
                     74:        tmp = buf;
                     75:        while (count > 0) {
1.1.1.4 ! root       76:                if (current->signal & ~current->blocked)
        !            77:                        break;
1.1       root       78:                pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
1.1.1.4 ! root       79:                pte = *(unsigned long *) pde;
        !            80:                if (!(pte & PAGE_PRESENT))
1.1       root       81:                        break;
                     82:                pte &= 0xfffff000;
                     83:                pte += (addr >> 10) & 0xffc;
1.1.1.4 ! root       84:                page = *(unsigned long *) pte;
        !            85:                if (!(page & PAGE_PRESENT))
1.1       root       86:                        break;
1.1.1.4 ! root       87:                if (!(page & 2)) {
        !            88:                        do_wp_page(0,addr,current,0);
        !            89:                        continue;
        !            90:                }
1.1       root       91:                page &= 0xfffff000;
                     92:                page += addr & 0xfff;
                     93:                i = 4096-(addr & 0xfff);
                     94:                if (i > count)
                     95:                        i = count;
                     96:                memcpy_fromfs((void *) page,tmp,i);
                     97:                addr += i;
                     98:                tmp += i;
                     99:                count -= i;
                    100:        }
                    101:        file->f_pos = addr;
1.1.1.4 ! root      102:        if (tmp != buf)
        !           103:                return tmp-buf;
        !           104:        if (current->signal & ~current->blocked)
        !           105:                return -ERESTARTSYS;
        !           106:        return 0;
1.1       root      107: }
                    108: 
                    109: static int read_kmem(struct inode * inode, struct file * file,char * buf, int count)
                    110: {
                    111:        unsigned long p = file->f_pos;
                    112: 
                    113:        if (count < 0)
                    114:                return -EINVAL;
1.1.1.4 ! root      115:        if (p >= high_memory)
1.1       root      116:                return 0;
1.1.1.4 ! root      117:        if (count > high_memory - p)
        !           118:                count = high_memory - p;
1.1       root      119:        memcpy_tofs(buf,(void *) p,count);
                    120:        file->f_pos += count;
                    121:        return count;
                    122: }
                    123: 
                    124: static int write_kmem(struct inode * inode, struct file * file,char * buf, int count)
                    125: {
                    126:        unsigned long p = file->f_pos;
                    127: 
                    128:        if (count < 0)
                    129:                return -EINVAL;
1.1.1.4 ! root      130:        if (p >= high_memory)
1.1       root      131:                return 0;
1.1.1.4 ! root      132:        if (count > high_memory - p)
        !           133:                count = high_memory - p;
1.1       root      134:        memcpy_fromfs((void *) p,buf,count);
                    135:        file->f_pos += count;
                    136:        return count;
                    137: }
                    138: 
                    139: static int read_port(struct inode * inode,struct file * file,char * buf, int count)
                    140: {
                    141:        unsigned int i = file->f_pos;
                    142:        char * tmp = buf;
                    143: 
                    144:        while (count-- > 0 && i < 65536) {
                    145:                put_fs_byte(inb(i),tmp);
                    146:                i++;
                    147:                tmp++;
                    148:        }
                    149:        file->f_pos = i;
                    150:        return tmp-buf;
                    151: }
                    152: 
                    153: static int write_port(struct inode * inode,struct file * file,char * buf, int count)
                    154: {
                    155:        unsigned int i = file->f_pos;
                    156:        char * tmp = buf;
                    157: 
                    158:        while (count-- > 0 && i < 65536) {
                    159:                outb(get_fs_byte(tmp),i);
                    160:                i++;
                    161:                tmp++;
                    162:        }
                    163:        file->f_pos = i;
                    164:        return tmp-buf;
                    165: }
                    166: 
1.1.1.2   root      167: static int read_zero(struct inode *node,struct file *file,char *buf,int count)
                    168: {
                    169:        int left;
                    170: 
                    171:        for (left = count; left > 0; left--) {
                    172:                put_fs_byte(0,buf);
                    173:                buf++;
                    174:        }
                    175:        return count;
                    176: }
                    177: 
1.1       root      178: /*
                    179:  * The memory devices use the full 32 bits of the offset, and so we cannot
                    180:  * check against negative addresses: they are ok. The return value is weird,
                    181:  * though, in that case (0).
                    182:  *
                    183:  * also note that seeking relative to the "end of file" isn't supported:
                    184:  * it has no meaning, so it returns -EINVAL.
                    185:  */
                    186: static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
                    187: {
                    188:        switch (orig) {
                    189:                case 0:
                    190:                        file->f_pos = offset;
                    191:                        return file->f_pos;
                    192:                case 1:
                    193:                        file->f_pos += offset;
                    194:                        return file->f_pos;
                    195:                default:
                    196:                        return -EINVAL;
                    197:        }
                    198:        if (file->f_pos < 0)
                    199:                return 0;
                    200:        return file->f_pos;
                    201: }
                    202: 
                    203: static int mem_read(struct inode * inode, struct file * file, char * buf, int count)
                    204: {
                    205:        switch (MINOR(inode->i_rdev)) {
                    206:                case 0:
                    207:                        return read_ram(inode,file,buf,count);
                    208:                case 1:
                    209:                        return read_mem(inode,file,buf,count);
                    210:                case 2:
                    211:                        return read_kmem(inode,file,buf,count);
                    212:                case 3:
                    213:                        return 0;       /* /dev/null */
                    214:                case 4:
                    215:                        return read_port(inode,file,buf,count);
1.1.1.2   root      216:                case 5:
                    217:                        return read_zero(inode,file,buf,count);
1.1       root      218:                default:
                    219:                        return -ENODEV;
                    220:        }
                    221: }
                    222: 
                    223: static int mem_write(struct inode * inode, struct file * file, char * buf, int count)
                    224: {
                    225:        switch (MINOR(inode->i_rdev)) {
                    226:                case 0:
                    227:                        return write_ram(inode,file,buf,count);
                    228:                case 1:
                    229:                        return write_mem(inode,file,buf,count);
                    230:                case 2:
                    231:                        return write_kmem(inode,file,buf,count);
                    232:                case 3:
                    233:                        return count;   /* /dev/null */
                    234:                case 4:
                    235:                        return write_port(inode,file,buf,count);
1.1.1.2   root      236:                case 5:
                    237:                        return count; /* /dev/zero */
1.1       root      238:                default:
                    239:                        return -ENODEV;
                    240:        }
                    241: }
                    242: 
                    243: static struct file_operations mem_fops = {
                    244:        mem_lseek,
                    245:        mem_read,
                    246:        mem_write,
                    247:        NULL,           /* mem_readdir */
                    248:        NULL,           /* mem_select */
                    249:        NULL,           /* mem_ioctl */
                    250:        NULL,           /* no special open code */
                    251:        NULL            /* no special release code */
                    252: };
                    253: 
1.1.1.3   root      254: long chr_dev_init(long mem_start, long mem_end)
1.1       root      255: {
                    256:        chrdev_fops[1] = &mem_fops;
1.1.1.3   root      257:        mem_start = tty_init(mem_start);
                    258:        mem_start = lp_init(mem_start);
1.1.1.4 ! root      259:        mem_start = mouse_init(mem_start);
1.1.1.3   root      260:        return mem_start;
1.1       root      261: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.