From e51bd967cda1989d606b5b6178ed6d2c8d151707 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 28 Feb 2002 20:39:54 +0000 Subject: 2002-02-28 Joel Sherrill * Submitted by Victor V. Vengerov and merged into the RTEMS source. * ChangeLog, Makefile.am, README, configure.ac, include/Makefile.am, include/rtems/bdbuf.h, include/rtems/blkdev.h, include/rtems/diskdevs.h, include/rtems/ramdisk.h, include/rtems/.cvsignore, include/.cvsignore, src/Makefile.am, src/bdbuf.c, src/blkdev.c, src/diskdevs.c, src/ramdisk.c, src/.cvsignore, .cvsignore: New files. --- c/src/exec/libblock/src/ramdisk.c | 224 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 c/src/exec/libblock/src/ramdisk.c (limited to 'c/src/exec/libblock/src/ramdisk.c') diff --git a/c/src/exec/libblock/src/ramdisk.c b/c/src/exec/libblock/src/ramdisk.c new file mode 100644 index 0000000000..08f42846e0 --- /dev/null +++ b/c/src/exec/libblock/src/ramdisk.c @@ -0,0 +1,224 @@ +/* ramdisk.c -- RAM disk block device implementation + * + * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov + * + * @(#) $Id$ + */ + +#include +#include +#include +#include +#include + +#include "rtems/blkdev.h" +#include "rtems/diskdevs.h" +#include "rtems/ramdisk.h" + +#define RAMDISK_DEVICE_BASE_NAME "/dev/ramdisk" + +/* Internal RAM disk descriptor */ +struct ramdisk { + int block_size; /* RAM disk block size */ + int block_num; /* Number of blocks on this RAM disk */ + void *area; /* RAM disk memory area */ + rtems_boolean initialized;/* RAM disk is initialized */ + rtems_boolean malloced; /* != 0, if memory allocated by malloc for this + RAM disk */ +}; + +static struct ramdisk *ramdisk; +static int nramdisks; + +/* ramdisk_read -- + * RAM disk READ request handler. This primitive copies data from RAM + * disk to supplied buffer and invoke the callout function to inform + * upper layer that reading is completed. + * + * PARAMETERS: + * req - pointer to the READ block device request info + * + * RETURNS: + * ioctl return value + */ +static int +ramdisk_read(struct ramdisk *rd, blkdev_request *req) +{ + char *from; + rtems_unsigned32 i; + blkdev_sg_buffer *sg; + rtems_unsigned32 remains; + + from = (char *)rd->area + (req->start * rd->block_size); + remains = rd->block_size * req->count; + sg = req->bufs; + for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++) + { + int count = sg->length; + if (count > remains) + count = remains; + memcpy(sg->buffer, from, count); + remains -= count; + } + req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0); + return 0; +} + +/* ramdisk_write -- + * RAM disk WRITE request handler. This primitive copies data from + * supplied buffer to RAM disk and invoke the callout function to inform + * upper layer that writing is completed. + * + * PARAMETERS: + * req - pointer to the WRITE block device request info + * + * RETURNS: + * ioctl return value + */ +static int +ramdisk_write(struct ramdisk *rd, blkdev_request *req) +{ + char *to; + rtems_unsigned32 i; + blkdev_sg_buffer *sg; + rtems_unsigned32 remains; + + to = (char *)rd->area + (req->start * rd->block_size); + remains = rd->block_size * req->count; + sg = req->bufs; + for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++) + { + int count = sg->length; + if (count > remains) + count = remains; + memcpy(to, sg->buffer, count); + remains -= count; + } + req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0); + return 0; +} + +/* ramdisk_ioctl -- + * IOCTL handler for RAM disk device. + * + * PARAMETERS: + * dev - device number (major, minor number) + * req - IOCTL request code + * argp - IOCTL argument + * + * RETURNS: + * IOCTL return value + */ +static int +ramdisk_ioctl(dev_t dev, int req, void *argp) +{ + switch (req) + { + case BLKIO_REQUEST: + { + rtems_device_minor_number minor; + blkdev_request *r = argp; + struct ramdisk *rd; + + minor = rtems_filesystem_dev_minor_t(dev); + if ((minor >= nramdisks) || !ramdisk[minor].initialized) + { + errno = ENODEV; + return -1; + } + + rd = ramdisk + minor; + + switch (r->req) + { + case BLKDEV_REQ_READ: + return ramdisk_read(rd, r); + + case BLKDEV_REQ_WRITE: + return ramdisk_write(rd, r); + + default: + errno = EBADRQC; + return -1; + } + break; + } + + default: + errno = EBADRQC; + return -1; + } +} + +/* ramdisk_initialize -- + * RAM disk device driver initialization. Run through RAM disk + * configuration information and configure appropriate RAM disks. + * + * PARAMETERS: + * major - RAM disk major device number + * minor - minor device number, not applicable + * arg - initialization argument, not applicable + * + * RETURNS: + * none + */ +rtems_device_driver +ramdisk_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_device_minor_number i; + rtems_ramdisk_config *c = rtems_ramdisk_configuration; + struct ramdisk *r; + rtems_status_code rc; + + rc = rtems_disk_io_initialize(); + if (rc != RTEMS_SUCCESSFUL) + return rc; + + r = ramdisk = calloc(rtems_ramdisk_configuration_size, + sizeof(struct ramdisk)); + + for (i = 0; i < rtems_ramdisk_configuration_size; i++, c++, r++) + { + dev_t dev = rtems_filesystem_make_dev_t(major, i); + char name[sizeof(RAMDISK_DEVICE_BASE_NAME "0123456789")]; + snprintf(name, sizeof(name), RAMDISK_DEVICE_BASE_NAME "%d", i); + r->block_size = c->block_size; + r->block_num = c->block_num; + if (c->location == NULL) + { + r->malloced = TRUE; + r->area = malloc(r->block_size * r->block_num); + if (r->area == NULL) /* No enough memory for this disk */ + { + r->initialized = FALSE; + continue; + } + else + { + r->initialized = TRUE; + } + } + else + { + r->malloced = FALSE; + r->initialized = TRUE; + r->area = c->location; + } + rc = rtems_disk_create_phys(dev, c->block_size, c->block_num, + ramdisk_ioctl, name); + if (rc != RTEMS_SUCCESSFUL) + { + if (r->malloced) + { + free(r->area); + } + r->initialized = FALSE; + } + } + nramdisks = rtems_ramdisk_configuration_size; + return RTEMS_SUCCESSFUL; +} -- cgit v1.2.3