Fork me on GitHub

root/drivers/block/ramdisk.c

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

DEFINITIONS

This source file includes following definitions.
  1. get_ramdisk
  2. ramdisk_open
  3. ramdisk_close
  4. ramdisk_read
  5. ramdisk_write
  6. ramdisk_ioctl
  7. ramdisk_lseek
  8. ramdisk_init

   1 /*
   2  * fiwix/drivers/block/ramdisk.c
   3  *
   4  * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/kernel.h>
   9 #include <fiwix/ramdisk.h>
  10 #include <fiwix/ioctl.h>
  11 #include <fiwix/devices.h>
  12 #include <fiwix/part.h>
  13 #include <fiwix/fs.h>
  14 #include <fiwix/errno.h>
  15 #include <fiwix/mm.h>
  16 #include <fiwix/stdio.h>
  17 #include <fiwix/string.h>
  18 
  19 struct ramdisk ramdisk_table[RAMDISK_MINORS];
  20 static unsigned int rd_sizes[256];
  21 
  22 static struct fs_operations ramdisk_driver_fsop = {
  23         0,
  24         0,
  25 
  26         ramdisk_open,
  27         ramdisk_close,
  28         NULL,                   /* read */
  29         NULL,                   /* write */
  30         ramdisk_ioctl,
  31         ramdisk_lseek,
  32         NULL,                   /* readdir */
  33         NULL,                   /* mmap */
  34         NULL,                   /* select */
  35 
  36         NULL,                   /* readlink */
  37         NULL,                   /* followlink */
  38         NULL,                   /* bmap */
  39         NULL,                   /* lockup */
  40         NULL,                   /* rmdir */
  41         NULL,                   /* link */
  42         NULL,                   /* unlink */
  43         NULL,                   /* symlink */
  44         NULL,                   /* mkdir */
  45         NULL,                   /* mknod */
  46         NULL,                   /* truncate */
  47         NULL,                   /* create */
  48         NULL,                   /* rename */
  49 
  50         ramdisk_read,
  51         ramdisk_write,
  52 
  53         NULL,                   /* read_inode */
  54         NULL,                   /* write_inode */
  55         NULL,                   /* ialloc */
  56         NULL,                   /* ifree */
  57         NULL,                   /* statfs */
  58         NULL,                   /* read_superblock */
  59         NULL,                   /* remount_fs */
  60         NULL,                   /* write_superblock */
  61         NULL                    /* release_superblock */
  62 };
  63 
  64 static struct device ramdisk_device = {
  65         "ramdisk",
  66         RAMDISK_MAJOR,
  67         { 0, 0, 0, 0, 0, 0, 0, 0 },
  68         BLKSIZE_1K,
  69         &rd_sizes,
  70         &ramdisk_driver_fsop,
  71         NULL
  72 };
  73 
  74 static struct ramdisk * get_ramdisk(int minor)
  75 {
  76         if(TEST_MINOR(ramdisk_device.minors, minor)) {
  77                 return &ramdisk_table[minor];
  78         }
  79         return NULL;
  80 }
  81 
  82 int ramdisk_open(struct inode *i, struct fd *fd_table)
  83 {
  84         if(!get_ramdisk(MINOR(i->rdev))) {
  85                 return -ENXIO;
  86         }
  87         return 0;
  88 }
  89 
  90 int ramdisk_close(struct inode *i, struct fd *fd_table)
  91 {
  92         if(!get_ramdisk(MINOR(i->rdev))) {
  93                 return -ENXIO;
  94         }
  95         return 0;
  96 }
  97 
  98 int ramdisk_read(__dev_t dev, __blk_t block, char *buffer, int blksize)
  99 {
 100         int size;
 101         __off_t offset;
 102         struct ramdisk *ramdisk;
 103 
 104         if(!(ramdisk = get_ramdisk(MINOR(dev)))) {
 105                 return -ENXIO;
 106         }
 107 
 108         size = rd_sizes[MINOR(dev)] * 1024;
 109         offset = block * blksize;
 110         if(offset > size) {
 111                 printk("%s(): block %d is beyond the size of the ramdisk.\n", __FUNCTION__, block);
 112                 return -EIO;
 113         }
 114         blksize = MIN(blksize, size - offset);
 115         memcpy_b((void *)buffer, ramdisk->addr + offset, blksize);
 116         return blksize;
 117 }
 118 
 119 int ramdisk_write(__dev_t dev, __blk_t block, char *buffer, int blksize)
 120 {
 121         int size;
 122         __off_t offset;
 123         struct ramdisk *ramdisk;
 124 
 125         if(!(ramdisk = get_ramdisk(MINOR(dev)))) {
 126                 return -ENXIO;
 127         }
 128 
 129         size = rd_sizes[MINOR(dev)] * 1024;
 130         offset = block * blksize;
 131         if(offset > size) {
 132                 printk("%s(): block %d is beyond the size of the ramdisk.\n", __FUNCTION__, block);
 133                 return -EIO;
 134         }
 135         blksize = MIN(blksize, size - offset);
 136         memcpy_b(ramdisk->addr + offset, buffer, blksize);
 137         return blksize;
 138 }
 139 
 140 int ramdisk_ioctl(struct inode *i, int cmd, unsigned long int arg)
 141 {
 142         struct hd_geometry *geom;
 143         int errno;
 144 
 145         if(!get_ramdisk(MINOR(i->rdev))) {
 146                 return -ENXIO;
 147         }
 148 
 149         switch(cmd) {
 150                 case HDIO_GETGEO:
 151                         if((errno = check_user_area(VERIFY_WRITE, (void *)arg, sizeof(struct hd_geometry)))) {
 152                                 return errno;
 153                         }
 154                         geom = (struct hd_geometry *)arg;
 155                         geom->heads = 63;
 156                         geom->sectors = 16;
 157                         geom->cylinders = rd_sizes[MINOR(i->rdev)] * 1024 / BPS;
 158                         geom->cylinders /= (geom->heads * geom->sectors);
 159                         geom->start = 0;
 160                         break;
 161                 case BLKRRPART:
 162                         break;
 163                 case BLKGETSIZE:
 164                         if((errno = check_user_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned int)))) {
 165                                 return errno;
 166                         }
 167                         *(int *)arg = rd_sizes[MINOR(i->rdev)] * 2;
 168                         break;
 169                 default:
 170                         return -EINVAL;
 171         }
 172         return 0;
 173 }
 174 
 175 int ramdisk_lseek(struct inode *i, __off_t offset)
 176 {
 177         return offset;
 178 }
 179 
 180 void ramdisk_init(void)
 181 {
 182         int n;
 183         struct ramdisk *ramdisk;
 184 
 185         if(!_noramdisk) {
 186                 for(n = 0; n < RAMDISK_MINORS; n++) {
 187                         SET_MINOR(ramdisk_device.minors, n);
 188                         rd_sizes[n] = _ramdisksize;
 189                         ramdisk = get_ramdisk(n);
 190                         printk("ram%d      0x%08X-0x%08X %d RAMdisk(s) of %dKB size, %dKB blocksize\n", n, ramdisk->addr, ramdisk->addr + (_ramdisksize * 1024), RAMDISK_MINORS, _ramdisksize, BLKSIZE_1K / 1024);
 191                 }
 192                 register_device(BLK_DEV, &ramdisk_device);
 193         }
 194 }

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