diff options
Diffstat (limited to 'cpukit/libblock/src/ramdisk-driver.c')
-rw-r--r-- | cpukit/libblock/src/ramdisk-driver.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/cpukit/libblock/src/ramdisk-driver.c b/cpukit/libblock/src/ramdisk-driver.c new file mode 100644 index 0000000000..2bc8d27962 --- /dev/null +++ b/cpukit/libblock/src/ramdisk-driver.c @@ -0,0 +1,134 @@ +/** + * @file + * + * @ingroup rtems_ramdisk + * + * @brief RAM disk block device implementation. + */ + +/* + * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * @(#) $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* FIXME: How to set this define? */ +#if !defined(RTEMS_RAMDISK_TRACE) + #define RTEMS_RAMDISK_TRACE 0 +#endif + +#include <stdlib.h> +#include <errno.h> +#include <string.h> + +#if RTEMS_RAMDISK_TRACE + #include <stdio.h> +#endif + +#include <rtems.h> +#include <rtems/ramdisk.h> + +#if RTEMS_RAMDISK_TRACE + static void + rtems_ramdisk_printf (const ramdisk *rd, const char *format, ...) + { + if (rd->trace) + { + va_list args; + va_start (args, format); + printf ("ramdisk:"); + vprintf (format, args); + printf ("\n"); + } + } +#endif + +static int +ramdisk_read(struct ramdisk *rd, rtems_blkdev_request *req) +{ + uint8_t *from = rd->area; + uint32_t i; + rtems_blkdev_sg_buffer *sg; + +#if RTEMS_RAMDISK_TRACE + rtems_ramdisk_printf (rd, "ramdisk read: start=%d, blocks=%d", + req->bufs[0].block, req->bufnum); +#endif + + for (i = 0, sg = req->bufs; i < req->bufnum; i++, sg++) + { +#if RTEMS_RAMDISK_TRACE + rtems_ramdisk_printf (rd, "ramdisk read: buf=%d block=%d length=%d off=%d addr=%p", + i, sg->block, sg->length, sg->block * rd->block_size, + from + (sg->block * rd->block_size)); +#endif + memcpy(sg->buffer, from + (sg->block * rd->block_size), sg->length); + } + req->status = RTEMS_SUCCESSFUL; + req->req_done(req->done_arg, RTEMS_SUCCESSFUL); + return 0; +} + +static int +ramdisk_write(struct ramdisk *rd, rtems_blkdev_request *req) +{ + uint8_t *to = rd->area; + uint32_t i; + rtems_blkdev_sg_buffer *sg; + +#if RTEMS_RAMDISK_TRACE + rtems_ramdisk_printf (rd, "ramdisk write: start=%d, blocks=%d", + req->bufs[0].block, req->bufnum); +#endif + for (i = 0, sg = req->bufs; i < req->bufnum; i++, sg++) + { +#if RTEMS_RAMDISK_TRACE + rtems_ramdisk_printf (rd, "ramdisk write: buf=%d block=%d length=%d off=%d addr=%p", + i, sg->block, sg->length, sg->block * rd->block_size, + to + (sg->block * rd->block_size)); +#endif + memcpy(to + (sg->block * rd->block_size), sg->buffer, sg->length); + } + req->status = RTEMS_SUCCESSFUL; + req->req_done(req->done_arg, RTEMS_SUCCESSFUL); + return 0; +} + +int +ramdisk_ioctl(rtems_disk_device *dd, uint32_t req, void *argp) +{ + switch (req) + { + case RTEMS_BLKIO_REQUEST: + { + rtems_blkdev_request *r = argp; + struct ramdisk *rd = rtems_disk_get_driver_data(dd); + + switch (r->req) + { + case RTEMS_BLKDEV_REQ_READ: + return ramdisk_read(rd, r); + + case RTEMS_BLKDEV_REQ_WRITE: + return ramdisk_write(rd, r); + + default: + errno = EINVAL; + return -1; + } + break; + } + + default: + return rtems_blkdev_ioctl (dd, req, argp); + break; + } + + errno = EINVAL; + return -1; +} |