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

1.1       root        1: /*
                      2:  *  linux/kernel/chr_drv/mem.c
                      3:  *
                      4:  *  (C) 1991  Linus Torvalds
                      5:  */
                      6: 
                      7: #include <errno.h>
                      8: #include <sys/types.h>
                      9: 
                     10: #include <linux/sched.h>
                     11: #include <linux/kernel.h>
                     12: #include <linux/tty.h>
                     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) {
                     39:                pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
                     40:                if (!((pte = *((unsigned long *) pde)) & 1))
                     41:                        break;
                     42:                pte &= 0xfffff000;
                     43:                pte += (addr >> 10) & 0xffc;
                     44:                if (((page = *((unsigned long *) pte)) & 1) == 0)
                     45:                        break;
                     46: /*
                     47:                if ((page & 2) == 0)
                     48:                        un_wp_page((unsigned long *) pte);
                     49: */
                     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) {
                     76:                pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
                     77:                if (!((pte = *((unsigned long *) pde)) & 1))
                     78:                        break;
                     79:                pte &= 0xfffff000;
                     80:                pte += (addr >> 10) & 0xffc;
                     81:                if (((page = *((unsigned long *) pte)) & 1) == 0)
                     82:                        break;
                     83:                if ((page & 2) == 0)
                     84:                        un_wp_page((unsigned long *) pte);
                     85:                page &= 0xfffff000;
                     86:                page += addr & 0xfff;
                     87:                i = 4096-(addr & 0xfff);
                     88:                if (i > count)
                     89:                        i = count;
                     90:                memcpy_fromfs((void *) page,tmp,i);
                     91:                addr += i;
                     92:                tmp += i;
                     93:                count -= i;
                     94:        }
                     95:        file->f_pos = addr;
                     96:        return tmp-buf;
                     97: }
                     98: 
                     99: static int read_kmem(struct inode * inode, struct file * file,char * buf, int count)
                    100: {
                    101:        unsigned long p = file->f_pos;
                    102: 
                    103:        if (count < 0)
                    104:                return -EINVAL;
                    105:        if (p >= HIGH_MEMORY)
                    106:                return 0;
                    107:        if (count > HIGH_MEMORY - p)
                    108:                count = HIGH_MEMORY - p;
                    109:        memcpy_tofs(buf,(void *) p,count);
                    110:        file->f_pos += count;
                    111:        return count;
                    112: }
                    113: 
                    114: static int write_kmem(struct inode * inode, struct file * file,char * buf, int count)
                    115: {
                    116:        unsigned long p = file->f_pos;
                    117: 
                    118:        if (count < 0)
                    119:                return -EINVAL;
                    120:        if (p >= HIGH_MEMORY)
                    121:                return 0;
                    122:        if (count > HIGH_MEMORY - p)
                    123:                count = HIGH_MEMORY - p;
                    124:        memcpy_fromfs((void *) p,buf,count);
                    125:        file->f_pos += count;
                    126:        return count;
                    127: }
                    128: 
                    129: static int read_port(struct inode * inode,struct file * file,char * buf, int count)
                    130: {
                    131:        unsigned int i = file->f_pos;
                    132:        char * tmp = buf;
                    133: 
                    134:        while (count-- > 0 && i < 65536) {
                    135:                put_fs_byte(inb(i),tmp);
                    136:                i++;
                    137:                tmp++;
                    138:        }
                    139:        file->f_pos = i;
                    140:        return tmp-buf;
                    141: }
                    142: 
                    143: static int write_port(struct inode * inode,struct file * file,char * buf, int count)
                    144: {
                    145:        unsigned int i = file->f_pos;
                    146:        char * tmp = buf;
                    147: 
                    148:        while (count-- > 0 && i < 65536) {
                    149:                outb(get_fs_byte(tmp),i);
                    150:                i++;
                    151:                tmp++;
                    152:        }
                    153:        file->f_pos = i;
                    154:        return tmp-buf;
                    155: }
                    156: 
1.1.1.2 ! root      157: static int read_zero(struct inode *node,struct file *file,char *buf,int count)
        !           158: {
        !           159:        int left;
        !           160: 
        !           161:        for (left = count; left > 0; left--) {
        !           162:                put_fs_byte(0,buf);
        !           163:                buf++;
        !           164:        }
        !           165:        return count;
        !           166: }
        !           167: 
1.1       root      168: /*
                    169:  * The memory devices use the full 32 bits of the offset, and so we cannot
                    170:  * check against negative addresses: they are ok. The return value is weird,
                    171:  * though, in that case (0).
                    172:  *
                    173:  * also note that seeking relative to the "end of file" isn't supported:
                    174:  * it has no meaning, so it returns -EINVAL.
                    175:  */
                    176: static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
                    177: {
                    178:        switch (orig) {
                    179:                case 0:
                    180:                        file->f_pos = offset;
                    181:                        return file->f_pos;
                    182:                case 1:
                    183:                        file->f_pos += offset;
                    184:                        return file->f_pos;
                    185:                default:
                    186:                        return -EINVAL;
                    187:        }
                    188:        if (file->f_pos < 0)
                    189:                return 0;
                    190:        return file->f_pos;
                    191: }
                    192: 
                    193: static int mem_read(struct inode * inode, struct file * file, char * buf, int count)
                    194: {
                    195:        switch (MINOR(inode->i_rdev)) {
                    196:                case 0:
                    197:                        return read_ram(inode,file,buf,count);
                    198:                case 1:
                    199:                        return read_mem(inode,file,buf,count);
                    200:                case 2:
                    201:                        return read_kmem(inode,file,buf,count);
                    202:                case 3:
                    203:                        return 0;       /* /dev/null */
                    204:                case 4:
                    205:                        return read_port(inode,file,buf,count);
1.1.1.2 ! root      206:                case 5:
        !           207:                        return read_zero(inode,file,buf,count);
1.1       root      208:                default:
                    209:                        return -ENODEV;
                    210:        }
                    211: }
                    212: 
                    213: static int mem_write(struct inode * inode, struct file * file, char * buf, int count)
                    214: {
                    215:        switch (MINOR(inode->i_rdev)) {
                    216:                case 0:
                    217:                        return write_ram(inode,file,buf,count);
                    218:                case 1:
                    219:                        return write_mem(inode,file,buf,count);
                    220:                case 2:
                    221:                        return write_kmem(inode,file,buf,count);
                    222:                case 3:
                    223:                        return count;   /* /dev/null */
                    224:                case 4:
                    225:                        return write_port(inode,file,buf,count);
1.1.1.2 ! root      226:                case 5:
        !           227:                        return count; /* /dev/zero */
1.1       root      228:                default:
                    229:                        return -ENODEV;
                    230:        }
                    231: }
                    232: 
                    233: static struct file_operations mem_fops = {
                    234:        mem_lseek,
                    235:        mem_read,
                    236:        mem_write,
                    237:        NULL,           /* mem_readdir */
                    238:        NULL,           /* mem_select */
                    239:        NULL,           /* mem_ioctl */
                    240:        NULL,           /* no special open code */
                    241:        NULL            /* no special release code */
                    242: };
                    243: 
1.1.1.2 ! root      244: long chr_dev_init(long kmem_start)
1.1       root      245: {
                    246:        chrdev_fops[1] = &mem_fops;
1.1.1.2 ! root      247:        kmem_start = tty_init(kmem_start);
        !           248:        kmem_start = lp_init(kmem_start);
        !           249:        return kmem_start;
1.1       root      250: }

unix.superglobalmegacorp.com

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