root/kernel/chr_drv/mem.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. read_ram
  2. write_ram
  3. read_mem
  4. write_mem
  5. read_port
  6. write_port
  7. read_zero
  8. mem_lseek
  9. mem_read
  10. mem_write
  11. chr_dev_init

   1 /*
   2  *  linux/kernel/chr_drv/mem.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 #include <linux/types.h>
   8 #include <linux/errno.h>
   9 #include <linux/sched.h>
  10 #include <linux/kernel.h>
  11 #include <linux/tty.h>
  12 #include <linux/mouse.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)
     /* [previous][next][first][last][top][bottom][index][help] */
  18 {
  19         return -EIO;
  20 }
  21 
  22 static int write_ram(struct inode * inode, struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  23 {
  24         return -EIO;
  25 }
  26 
  27 static int read_mem(struct inode * inode, struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  28 {
  29         unsigned long p = file->f_pos;
  30 
  31         if (count < 0)
  32                 return -EINVAL;
  33         if (p >= high_memory)
  34                 return 0;
  35         if (count > high_memory - p)
  36                 count = high_memory - p;
  37         memcpy_tofs(buf,(void *) p,count);
  38         file->f_pos += count;
  39         return count;
  40 }
  41 
  42 static int write_mem(struct inode * inode, struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  43 {
  44         unsigned long p = file->f_pos;
  45 
  46         if (count < 0)
  47                 return -EINVAL;
  48         if (p >= high_memory)
  49                 return 0;
  50         if (count > high_memory - p)
  51                 count = high_memory - p;
  52         memcpy_fromfs((void *) p,buf,count);
  53         file->f_pos += count;
  54         return count;
  55 }
  56 
  57 static int read_port(struct inode * inode,struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59         unsigned int i = file->f_pos;
  60         char * tmp = buf;
  61 
  62         while (count-- > 0 && i < 65536) {
  63                 put_fs_byte(inb(i),tmp);
  64                 i++;
  65                 tmp++;
  66         }
  67         file->f_pos = i;
  68         return tmp-buf;
  69 }
  70 
  71 static int write_port(struct inode * inode,struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73         unsigned int i = file->f_pos;
  74         char * tmp = buf;
  75 
  76         while (count-- > 0 && i < 65536) {
  77                 outb(get_fs_byte(tmp),i);
  78                 i++;
  79                 tmp++;
  80         }
  81         file->f_pos = i;
  82         return tmp-buf;
  83 }
  84 
  85 static int read_zero(struct inode *node,struct file *file,char *buf,int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87         int left;
  88 
  89         for (left = count; left > 0; left--) {
  90                 put_fs_byte(0,buf);
  91                 buf++;
  92         }
  93         return count;
  94 }
  95 
  96 /*
  97  * The memory devices use the full 32 bits of the offset, and so we cannot
  98  * check against negative addresses: they are ok. The return value is weird,
  99  * though, in that case (0).
 100  *
 101  * also note that seeking relative to the "end of file" isn't supported:
 102  * it has no meaning, so it returns -EINVAL.
 103  */
 104 static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 105 {
 106         switch (orig) {
 107                 case 0:
 108                         file->f_pos = offset;
 109                         return file->f_pos;
 110                 case 1:
 111                         file->f_pos += offset;
 112                         return file->f_pos;
 113                 default:
 114                         return -EINVAL;
 115         }
 116         if (file->f_pos < 0)
 117                 return 0;
 118         return file->f_pos;
 119 }
 120 
 121 #define read_kmem read_mem
 122 #define write_kmem write_mem
 123 
 124 static int mem_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126         switch (MINOR(inode->i_rdev)) {
 127                 case 0:
 128                         return read_ram(inode,file,buf,count);
 129                 case 1:
 130                         return read_mem(inode,file,buf,count);
 131                 case 2:
 132                         return read_kmem(inode,file,buf,count);
 133                 case 3:
 134                         return 0;       /* /dev/null */
 135                 case 4:
 136                         return read_port(inode,file,buf,count);
 137                 case 5:
 138                         return read_zero(inode,file,buf,count);
 139                 default:
 140                         return -ENODEV;
 141         }
 142 }
 143 
 144 static int mem_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146         switch (MINOR(inode->i_rdev)) {
 147                 case 0:
 148                         return write_ram(inode,file,buf,count);
 149                 case 1:
 150                         return write_mem(inode,file,buf,count);
 151                 case 2:
 152                         return write_kmem(inode,file,buf,count);
 153                 case 3:
 154                         return count;   /* /dev/null */
 155                 case 4:
 156                         return write_port(inode,file,buf,count);
 157                 case 5:
 158                         return count; /* /dev/zero */
 159                 default:
 160                         return -ENODEV;
 161         }
 162 }
 163 
 164 static struct file_operations mem_fops = {
 165         mem_lseek,
 166         mem_read,
 167         mem_write,
 168         NULL,           /* mem_readdir */
 169         NULL,           /* mem_select */
 170         NULL,           /* mem_ioctl */
 171         NULL,           /* no special open code */
 172         NULL            /* no special release code */
 173 };
 174 
 175 long chr_dev_init(long mem_start, long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177         chrdev_fops[1] = &mem_fops;
 178         mem_start = tty_init(mem_start);
 179         mem_start = lp_init(mem_start);
 180         mem_start = mouse_init(mem_start);
 181         return mem_start;
 182 }

/* [previous][next][first][last][top][bottom][index][help] */