Prex Home / Browse Source - Prex Version: 0.9.0

root/bsp/drv/dev/block/ramdisk.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ramdisk_read
  2. ramdisk_write
  3. ramdisk_probe
  4. ramdisk_init

   1 /*-
   2  * Copyright (c) 2006, Kohsuke Ohtani
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the author nor the names of any co-contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 /*
  31  * ramdisk.c - RAM disk driver
  32  */
  33 
  34 #include <driver.h>
  35 
  36 /* #define DEBUG_RAMDISK 1 */
  37 
  38 #ifdef DEBUG_RAMDISK
  39 #define DPRINTF(a)      printf a
  40 #else
  41 #define DPRINTF(a)
  42 #endif
  43 
  44 /* Block size */
  45 #define BSIZE           512
  46 
  47 struct ramdisk_softc {
  48         device_t        dev;            /* device object */
  49         char            *addr;          /* base address of image */
  50         size_t          size;           /* image size */
  51 };
  52 
  53 static int ramdisk_read(device_t, char *, size_t *, int);
  54 static int ramdisk_write(device_t, char *, size_t *, int);
  55 static int ramdisk_probe(struct driver *);
  56 static int ramdisk_init(struct driver *);
  57 
  58 static struct devops ramdisk_devops = {
  59         /* open */      no_open,
  60         /* close */     no_close,
  61         /* read */      ramdisk_read,
  62         /* write */     ramdisk_write,
  63         /* ioctl */     no_ioctl,
  64         /* devctl */    no_devctl,
  65 };
  66 
  67 struct driver ramdisk_driver = {
  68         /* name */      "ramdisk",
  69         /* devops */    &ramdisk_devops,
  70         /* devsz */     sizeof(struct ramdisk_softc),
  71         /* flags */     0,
  72         /* probe */     ramdisk_probe,
  73         /* init */      ramdisk_init,
  74         /* shutdown */  NULL,
  75 };
  76 
  77 static int
  78 ramdisk_read(device_t dev, char *buf, size_t *nbyte, int blkno)
  79 {
  80         struct ramdisk_softc *sc = device_private(dev);
  81         int offset = blkno * BSIZE;
  82         void *kbuf;
  83         size_t nr_read;
  84 
  85         DPRINTF(("ramdisk_read: buf=%x nbyte=%d blkno=%x\n",
  86                  buf, *nbyte, blkno));
  87 
  88         /* Check overrun */
  89         if (offset > (int)sc->size) {
  90                 DPRINTF(("ramdisk_read: overrun!\n"));
  91                 return EIO;
  92         }
  93         nr_read = *nbyte;
  94         if (offset + nr_read > (int)sc->size)
  95                 nr_read = sc->size - offset;
  96 
  97         /* Translate buffer address to kernel address */
  98         if ((kbuf = kmem_map(buf, nr_read)) == NULL) {
  99                 return EFAULT;
 100         }
 101 
 102         /* Copy data */
 103         memcpy(kbuf, sc->addr + offset, nr_read);
 104         *nbyte = nr_read;
 105         return 0;
 106 }
 107 
 108 static int
 109 ramdisk_write(device_t dev, char *buf, size_t *nbyte, int blkno)
 110 {
 111         struct ramdisk_softc *sc = device_private(dev);
 112         int offset = blkno * BSIZE;
 113         void *kbuf;
 114         size_t nr_write;
 115 
 116         DPRINTF(("ramdisk_write: buf=%x nbyte=%d blkno=%x\n",
 117                  buf, *nbyte, blkno));
 118 
 119         /* Check overrun */
 120         if (offset > (int)sc->size)
 121                 return EIO;
 122         nr_write = *nbyte;
 123         if (offset + nr_write > (int)sc->size)
 124                 nr_write = sc->size - offset;
 125 
 126         /* Translate buffer address to kernel address */
 127         if ((kbuf = kmem_map(buf, nr_write)) == NULL)
 128                 return EFAULT;
 129 
 130         /* Copy data */
 131         memcpy(sc->addr + offset, kbuf, nr_write);
 132         *nbyte = nr_write;
 133         return 0;
 134 }
 135 
 136 static int
 137 ramdisk_probe(struct driver *self)
 138 {
 139         struct bootinfo *bi;
 140         struct physmem *phys;
 141 
 142         machine_bootinfo(&bi);
 143         phys = &bi->bootdisk;
 144         if (phys->size == 0) {
 145 #ifdef DEBUG
 146                 printf("ramdisk: no bootdisk found...\n");
 147 #endif
 148                 return ENXIO;
 149         }
 150         return 0;
 151 }
 152 
 153 static int
 154 ramdisk_init(struct driver *self)
 155 {
 156         struct ramdisk_softc *sc;
 157         struct bootinfo *bi;
 158         struct physmem *phys;
 159         device_t dev;
 160 
 161         machine_bootinfo(&bi);
 162         phys = &bi->bootdisk;
 163 
 164         dev = device_create(self, "ram0", D_BLK|D_PROT);
 165 
 166         sc = device_private(dev);
 167         sc->dev = dev;
 168         sc->addr = (char *)ptokv(phys->base);
 169         sc->size = (size_t)phys->size;
 170 
 171 #ifdef DEBUG
 172         printf("RAM disk at 0x%08x (%dK bytes)\n",
 173                (u_int)sc->addr, sc->size/1024);
 174 #endif
 175         return 0;
 176 }

/* [<][>][^][v][top][bottom][index][help] */