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

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