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_core
  4. read_mem
  5. write_mem
  6. read_port
  7. write_port
  8. read_null
  9. write_null
  10. read_zero
  11. write_zero
  12. memory_lseek
  13. memory_open
  14. 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 #include <linux/soundcard.h>
  14 
  15 #include <linux/user.h>
  16 #include <linux/a.out.h>
  17 #include <linux/string.h>
  18 
  19 #include <asm/segment.h>
  20 #include <asm/io.h>
  21 
  22 static int read_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 write_ram(struct inode * inode, struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  28 {
  29         return -EIO;
  30 }
  31 
  32 static int read_core(struct inode * inode, struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  33 {
  34         unsigned long p = file->f_pos;
  35         int read;
  36         int count1;
  37         char * pnt;
  38         struct user dump;
  39 
  40         memset(&dump, 0, sizeof(struct user));
  41         dump.magic = CMAGIC;
  42         dump.u_dsize = high_memory >> 12;
  43 
  44         if (count < 0)
  45                 return -EINVAL;
  46         if (p >= high_memory)
  47                 return 0;
  48         if (count > high_memory - p)
  49                 count = high_memory - p;
  50         read = 0;
  51 
  52         if (p < sizeof(struct user) && count > 0) {
  53                 count1 = count;
  54                 if (p + count1 > sizeof(struct user))
  55                         count1 = sizeof(struct user)-p;
  56                 pnt = (char *) &dump + p;
  57                 memcpy_tofs(buf,(void *) pnt, count1);
  58                 buf += count1;
  59                 p += count1;
  60                 count -= count1;
  61                 read += count1;
  62         }
  63 
  64         while (p < (4096 + 4096) && count > 0) {
  65                 put_fs_byte(0,buf);
  66                 buf++;
  67                 p++;
  68                 count--;
  69                 read++;
  70         }
  71         memcpy_tofs(buf,(void *) (p - 4096),count);
  72         read += count;
  73         file->f_pos += read;
  74         return read;
  75 }
  76 
  77 static int read_mem(struct inode * inode, struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79         unsigned long p = file->f_pos;
  80         int read;
  81 
  82         if (count < 0)
  83                 return -EINVAL;
  84         if (p >= high_memory)
  85                 return 0;
  86         if (count > high_memory - p)
  87                 count = high_memory - p;
  88         read = 0;
  89         while (p < 4096 && count > 0) {
  90                 put_fs_byte(0,buf);
  91                 buf++;
  92                 p++;
  93                 count--;
  94                 read++;
  95         }
  96         memcpy_tofs(buf,(void *) p,count);
  97         read += count;
  98         file->f_pos += read;
  99         return read;
 100 }
 101 
 102 static int write_mem(struct inode * inode, struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104         unsigned long p = file->f_pos;
 105         int written;
 106 
 107         if (count < 0)
 108                 return -EINVAL;
 109         if (p >= high_memory)
 110                 return 0;
 111         if (count > high_memory - p)
 112                 count = high_memory - p;
 113         written = 0;
 114         while (p < 4096 && count > 0) {
 115                 /* Hmm. Do something? */
 116                 buf++;
 117                 p++;
 118                 count--;
 119                 written++;
 120         }
 121         memcpy_fromfs((void *) p,buf,count);
 122         written += count;
 123         file->f_pos += written;
 124         return count;
 125 }
 126 
 127 static int read_port(struct inode * inode,struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         unsigned int i = file->f_pos;
 130         char * tmp = buf;
 131 
 132         while (count-- > 0 && i < 65536) {
 133                 put_fs_byte(inb(i),tmp);
 134                 i++;
 135                 tmp++;
 136         }
 137         file->f_pos = i;
 138         return tmp-buf;
 139 }
 140 
 141 static int write_port(struct inode * inode,struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 142 {
 143         unsigned int i = file->f_pos;
 144         char * tmp = buf;
 145 
 146         while (count-- > 0 && i < 65536) {
 147                 outb(get_fs_byte(tmp),i);
 148                 i++;
 149                 tmp++;
 150         }
 151         file->f_pos = i;
 152         return tmp-buf;
 153 }
 154 
 155 static int read_null(struct inode * node,struct file * file,char * buf,int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157         return 0;
 158 }
 159 
 160 static int write_null(struct inode * inode,struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162         return count;
 163 }
 164 
 165 static int read_zero(struct inode * node,struct file * file,char * buf,int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167         int left;
 168 
 169         for (left = count; left > 0; left--) {
 170                 put_fs_byte(0,buf);
 171                 buf++;
 172         }
 173         return count;
 174 }
 175 
 176 static int write_zero(struct inode * inode,struct file * file,char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178         return count;
 179 }
 180 
 181 /*
 182  * The memory devices use the full 32 bits of the offset, and so we cannot
 183  * check against negative addresses: they are ok. The return value is weird,
 184  * though, in that case (0).
 185  *
 186  * also note that seeking relative to the "end of file" isn't supported:
 187  * it has no meaning, so it returns -EINVAL.
 188  */
 189 static int memory_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 190 {
 191         switch (orig) {
 192                 case 0:
 193                         file->f_pos = offset;
 194                         return file->f_pos;
 195                 case 1:
 196                         file->f_pos += offset;
 197                         return file->f_pos;
 198                 default:
 199                         return -EINVAL;
 200         }
 201         if (file->f_pos < 0)
 202                 return 0;
 203         return file->f_pos;
 204 }
 205 
 206 #define read_kmem read_mem
 207 #define write_kmem write_mem
 208 
 209 static struct file_operations ram_fops = {
 210         memory_lseek,
 211         read_ram,
 212         write_ram,
 213         NULL,           /* ram_readdir */
 214         NULL,           /* ram_select */
 215         NULL,           /* ram_ioctl */
 216         NULL,           /* ram_mmap */
 217         NULL,           /* no special open code */
 218         NULL            /* no special release code */
 219 };
 220 
 221 static struct file_operations mem_fops = {
 222         memory_lseek,
 223         read_mem,
 224         write_mem,
 225         NULL,           /* mem_readdir */
 226         NULL,           /* mem_select */
 227         NULL,           /* mem_ioctl */
 228         NULL,           /* mem_mmap */
 229         NULL,           /* no special open code */
 230         NULL            /* no special release code */
 231 };
 232 
 233 static struct file_operations kmem_fops = {
 234         memory_lseek,
 235         read_kmem,
 236         write_kmem,
 237         NULL,           /* kmem_readdir */
 238         NULL,           /* kmem_select */
 239         NULL,           /* kmem_ioctl */
 240         NULL,           /* kmem_mmap */
 241         NULL,           /* no special open code */
 242         NULL            /* no special release code */
 243 };
 244 
 245 static struct file_operations null_fops = {
 246         memory_lseek,
 247         read_null,
 248         write_null,
 249         NULL,           /* null_readdir */
 250         NULL,           /* null_select */
 251         NULL,           /* null_ioctl */
 252         NULL,           /* null_mmap */
 253         NULL,           /* no special open code */
 254         NULL            /* no special release code */
 255 };
 256 
 257 static struct file_operations port_fops = {
 258         memory_lseek,
 259         read_port,
 260         write_port,
 261         NULL,           /* port_readdir */
 262         NULL,           /* port_select */
 263         NULL,           /* port_ioctl */
 264         NULL,           /* port_mmap */
 265         NULL,           /* no special open code */
 266         NULL            /* no special release code */
 267 };
 268 
 269 static struct file_operations zero_fops = {
 270         memory_lseek,
 271         read_zero,
 272         write_zero,
 273         NULL,           /* zero_readdir */
 274         NULL,           /* zero_select */
 275         NULL,           /* zero_ioctl */
 276         NULL,           /* zero_mmap */
 277         NULL,           /* no special open code */
 278         NULL            /* no special release code */
 279 };
 280 
 281 static struct file_operations core_fops = {
 282         memory_lseek,
 283         read_core,
 284         NULL,
 285         NULL,           /* zero_readdir */
 286         NULL,           /* zero_select */
 287         NULL,           /* zero_ioctl */
 288         NULL,           /* zero_mmap */
 289         NULL,           /* no special open code */
 290         NULL            /* no special release code */
 291 };
 292 
 293 static int memory_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295         switch (MINOR(inode->i_rdev)) {
 296                 case 0:
 297                         filp->f_op = &ram_fops;
 298                         break;
 299                 case 1:
 300                         filp->f_op = &mem_fops;
 301                         break;
 302                 case 2:
 303                         filp->f_op = &kmem_fops;
 304                         break;
 305                 case 3:
 306                         filp->f_op = &null_fops;
 307                         break;
 308                 case 4:
 309                         filp->f_op = &port_fops;
 310                         break;
 311                 case 5:
 312                         filp->f_op = &zero_fops;
 313                         break;
 314                 case 6:
 315                         filp->f_op = &core_fops;
 316                         break;
 317                 default:
 318                         return -ENODEV;
 319         }
 320         if (filp->f_op && filp->f_op->open)
 321                 return filp->f_op->open(inode,filp);
 322         return 0;
 323 }
 324 
 325 static struct file_operations memory_fops = {
 326         NULL,           /* lseek */
 327         NULL,           /* read */
 328         NULL,           /* write */
 329         NULL,           /* readdir */
 330         NULL,           /* select */
 331         NULL,           /* ioctl */
 332         NULL,           /* mmap */
 333         memory_open,    /* just a selector for the real open */
 334         NULL            /* release */
 335 };
 336 
 337 long chr_dev_init(long mem_start, long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 338 {
 339         chrdev_fops[1] = &memory_fops;
 340         mem_start = tty_init(mem_start);
 341         mem_start = lp_init(mem_start);
 342         mem_start = mouse_init(mem_start);
 343         mem_start = soundcard_init(mem_start);
 344         return mem_start;
 345 }

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