From 2b3e9d9b244e279ef5693a7cf5dacc7903164af5 Mon Sep 17 00:00:00 2001 From: Ralf Corsepius Date: Mon, 22 Jul 2002 09:46:48 +0000 Subject: Remove, moved to cpukit. --- c/src/exec/libblock/src/.cvsignore | 2 - c/src/exec/libblock/src/Makefile.am | 27 - c/src/exec/libblock/src/bdbuf.c | 1648 ----------------------------------- c/src/exec/libblock/src/blkdev.c | 245 ------ c/src/exec/libblock/src/diskdevs.c | 631 -------------- c/src/exec/libblock/src/ramdisk.c | 225 ----- 6 files changed, 2778 deletions(-) delete mode 100644 c/src/exec/libblock/src/.cvsignore delete mode 100644 c/src/exec/libblock/src/Makefile.am delete mode 100644 c/src/exec/libblock/src/bdbuf.c delete mode 100644 c/src/exec/libblock/src/blkdev.c delete mode 100644 c/src/exec/libblock/src/diskdevs.c delete mode 100644 c/src/exec/libblock/src/ramdisk.c (limited to 'c/src/exec/libblock/src') diff --git a/c/src/exec/libblock/src/.cvsignore b/c/src/exec/libblock/src/.cvsignore deleted file mode 100644 index 282522db03..0000000000 --- a/c/src/exec/libblock/src/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/c/src/exec/libblock/src/Makefile.am b/c/src/exec/libblock/src/Makefile.am deleted file mode 100644 index 96d611491c..0000000000 --- a/c/src/exec/libblock/src/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -## -## $Id$ -## - - -LIBNAME = libblock -LIB = ${ARCH}/${LIBNAME}.a - -C_FILES = bdbuf.c blkdev.c diskdevs.c ramdisk.c - -C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o) - -SRCS = $(C_FILES) -OBJS = $(C_O_FILES) - -include $(top_srcdir)/../automake/multilib.am -include $(top_srcdir)/../automake/compile.am -include $(top_srcdir)/../automake/lib.am - -AM_CFLAGS += $(LIBC_DEFINES) - -$(LIB): ${OBJS} - $(make-library) - -all-local: ${ARCH} $(LIB) - -include $(top_srcdir)/../automake/local.am diff --git a/c/src/exec/libblock/src/bdbuf.c b/c/src/exec/libblock/src/bdbuf.c deleted file mode 100644 index 0960ac4c3a..0000000000 --- a/c/src/exec/libblock/src/bdbuf.c +++ /dev/null @@ -1,1648 +0,0 @@ -/* - * Disk I/O buffering - * Buffer managment - * - * Copyright (C) 2001 OKTET Ltd., St.-Peterburg, Russia - * Author: Andrey G. Ivanov - * Victor V. Vengerov - * Alexander Kukuta - * - * @(#) $Id$ - */ - -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ -#include -#include -#include -#include - -#include "rtems/bdbuf.h" - -/* Fatal errors: */ -#define BLKDEV_FATAL_ERROR(n) (('B' << 24) | ((n) & 0x00FFFFFF)) -#define BLKDEV_FATAL_BDBUF_CONSISTENCY BLKDEV_FATAL_ERROR(1) -#define BLKDEV_FATAL_BDBUF_SWAPOUT BLKDEV_FATAL_ERROR(2) - - -#define SWAPOUT_PRIORITY 15 -#define SWAPOUT_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2) - -static rtems_task bdbuf_swapout_task(rtems_task_argument unused); - -/* - * The groups of the blocks with the same size are collected in the - * bd_pool. Note that a several of the buffer's groups with the - * same size can exists. - */ -typedef struct bdbuf_pool -{ - bdbuf_buffer *tree; /* Buffer descriptor lookup AVL tree root */ - - Chain_Control free; /* Free buffers list */ - Chain_Control lru; /* Last recently used list */ - - int blksize; /* The size of the blocks (in bytes) */ - int nblks; /* Number of blocks in this pool */ - rtems_id bufget_sema; /* Buffer obtain counting semaphore */ - void *mallocd_bufs; /* Pointer to the malloc'd buffer memory, - or NULL, if buffer memory provided in - buffer configuration */ - bdbuf_buffer *bdbufs; /* Pointer to table of buffer descriptors - allocated for this buffer pool. */ -} bdbuf_pool; - -/* Buffering layer context definition */ -struct bdbuf_context { - bdbuf_pool *pool; /* Table of buffer pools */ - int npools; /* Number of entries in pool table */ - - Chain_Control mod; /* Modified buffers list */ - rtems_id flush_sema; /* Buffer flush semaphore; counting - semaphore; incremented when buffer - flushed to the disk; decremented when - buffer modified */ - rtems_id swapout_task; /* Swapout task ID */ -}; - -/* Block device request with a single buffer provided */ -typedef struct blkdev_request1 { - blkdev_request req; - blkdev_sg_buffer sg[1]; -} blkdev_request1; - -/* The static context of buffering layer */ -static struct bdbuf_context bd_ctx; - -#define SAFE -#ifdef SAFE -typedef rtems_mode preemption_key; - -#define DISABLE_PREEMPTION(key) \ - do { \ - rtems_task_mode(RTEMS_PREEMPT_MASK, RTEMS_NO_PREEMPT, &(key)); \ - } while (0) - -#define ENABLE_PREEMPTION(key) \ - do { \ - rtems_mode temp; \ - rtems_task_mode(RTEMS_PREEMPT_MASK, (key), &temp); \ - } while (0) - -#else - -typedef boolean preemption_key; - -#define DISABLE_PREEMPTION(key) \ - do { \ - (key) = _Thread_Executing->is_preemptible; \ - _Thread_Executing->is_preemptible = 0; \ - } while (0) - -#define ENABLE_PREEMPTION(key) \ - do { \ - _Thread_Executing->is_preemptible = (key); \ - if (_Thread_Evaluate_mode()) \ - _Thread_Dispatch(); \ - } while (0) - -#endif - - -/* The default maximum height of 32 allows for AVL trees having - between 5,704,880 and 4,294,967,295 nodes, depending on order of - insertion. You may change this compile-time constant as you - wish. */ -#ifndef AVL_MAX_HEIGHT -#define AVL_MAX_HEIGHT 32 -#endif - -/* - * avl_search -- - * Searches for the node with specified dev/block. - * - * PARAMETERS: - * root - pointer to the root node of the AVL-Tree. - * dev, block - search key - * - * RETURNS: - * NULL if node with specified dev/block not found - * non-NULL - pointer to the node with specified dev/block - */ -static bdbuf_buffer * -avl_search(bdbuf_buffer **root, dev_t dev, blkdev_bnum block) -{ - bdbuf_buffer *p = *root; - - while ((p != NULL) && ((p->dev != dev) || (p->block != block))) - { - if ((p->dev < dev) || ((p->dev == dev) && (p->block < block))) - { - p = p->avl.right; - } - else - { - p = p->avl.left; - } - } - - return p; -} - - -/* avl_search_for_sync -- - * Search in AVL tree for first modified buffer belongs to specified - * disk device. - * - * PARAMETERS: - * root - pointer to tree root - * dd - disk device descriptor - * - * RETURNS: - * Block buffer, or NULL if no modified blocks on specified device - * exists. - */ -static bdbuf_buffer * -avl_search_for_sync(bdbuf_buffer **root, disk_device *dd) -{ - dev_t dev = dd->phys_dev->dev; - blkdev_bnum block_start = dd->start; - blkdev_bnum block_end = dd->start + dd->size - 1; - - bdbuf_buffer *buf_stack[AVL_MAX_HEIGHT]; - bdbuf_buffer **buf_prev = buf_stack; - bdbuf_buffer *p = *root; - - while (p != NULL) - { - if ((p->dev < dev) || ((p->dev == dev) && (p->block < block_start))) - { - p = p->avl.right; - } - else if ((p->dev > dev) || ((p->dev == dev) && (p->block > block_end))) - { - p = p->avl.left; - } - else if (p->modified) - { - return p; - } - else - { - if (p->avl.right != NULL) - { - *buf_prev++ = p->avl.right; - } - p = p->avl.left; - } - - if ((p == NULL) && (buf_prev > buf_stack)) - { - p = *--buf_prev; - } - } - - return p; -} - - -/* - * avl_insert -- - * Inserts the specified node to the AVl-Tree. - * - * PARAMETERS: - * root - Pointer to pointer to the root node - * node - Pointer to the node to add. - * - * RETURNS: - * 0 - The node added successfully - * -1 - An error occured - */ -static int -avl_insert(bdbuf_buffer **root, bdbuf_buffer *node) -{ - dev_t dev = node->dev; - blkdev_bnum block = node->block; - - bdbuf_buffer *p = *root; - bdbuf_buffer *q, *p1, *p2; - bdbuf_buffer *buf_stack[AVL_MAX_HEIGHT]; - bdbuf_buffer **buf_prev = buf_stack; - - boolean modified = FALSE; - - if (p == NULL) - { - *root = node; - node->avl.left = NULL; - node->avl.right = NULL; - node->avl.bal = 0; - return 0; - } - - while (p != NULL) - { - *buf_prev++ = p; - - if ((p->dev < dev) || ((p->dev == dev) && (p->block < block))) - { - p->avl.cache = 1; - q = p->avl.right; - if (q == NULL) - { - q = node; - p->avl.right = q = node; - break; - } - } - else if ((p->dev != dev) || (p->block != block)) - { - p->avl.cache = -1; - q = p->avl.left; - if (q == NULL) - { - q = node; - p->avl.left = q; - break; - } - } - else - { - return -1; - } - - p = q; - } - - q->avl.left = q->avl.right = NULL; - q->avl.bal = 0; - modified = TRUE; - buf_prev--; - - while (modified) - { - if (p->avl.cache == -1) - { - switch (p->avl.bal) - { - case 1: - p->avl.bal = 0; - modified = FALSE; - break; - - case 0: - p->avl.bal = -1; - break; - - case -1: - p1 = p->avl.left; - if (p1->avl.bal == -1) /* simple LL-turn */ - { - p->avl.left = p1->avl.right; - p1->avl.right = p; - p->avl.bal = 0; - p = p1; - } - else /* double LR-turn */ - { - p2 = p1->avl.right; - p1->avl.right = p2->avl.left; - p2->avl.left = p1; - p->avl.left = p2->avl.right; - p2->avl.right = p; - if (p2->avl.bal == -1) p->avl.bal = +1; else p->avl.bal = 0; - if (p2->avl.bal == +1) p1->avl.bal = -1; else p1->avl.bal = 0; - p = p2; - } - p->avl.bal = 0; - modified = FALSE; - break; - - default: - break; - } - } - else - { - switch (p->avl.bal) - { - case -1: - p->avl.bal = 0; - modified = FALSE; - break; - - case 0: - p->avl.bal = 1; - break; - - case 1: - p1 = p->avl.right; - if (p1->avl.bal == 1) /* simple RR-turn */ - { - p->avl.right = p1->avl.left; - p1->avl.left = p; - p->avl.bal = 0; - p = p1; - } - else /* double RL-turn */ - { - p2 = p1->avl.left; - p1->avl.left = p2->avl.right; - p2->avl.right = p1; - p->avl.right = p2->avl.left; - p2->avl.left = p; - if (p2->avl.bal == +1) p->avl.bal = -1; else p->avl.bal = 0; - if (p2->avl.bal == -1) p1->avl.bal = +1; else p1->avl.bal = 0; - p = p2; - } - p->avl.bal = 0; - modified = FALSE; - break; - - default: - break; - } - } - q = p; - if (buf_prev > buf_stack) - { - p = *--buf_prev; - - if (p->avl.cache == -1) - { - p->avl.left = q; - } - else - { - p->avl.right = q; - } - } - else - { - *root = p; - break; - } - }; - - return 0; -} - - -/* avl_remove -- - * removes the node from the tree. - * - * PARAMETERS: - * root_addr - Pointer to pointer to the root node - * node - Pointer to the node to remove - * - * RETURNS: - * 0 - Item removed - * -1 - No such item found - */ -static int -avl_remove(bdbuf_buffer **root, const bdbuf_buffer *node) -{ - dev_t dev = node->dev; - blkdev_bnum block = node->block; - - bdbuf_buffer *p = *root; - bdbuf_buffer *q, *r, *s, *p1, *p2; - bdbuf_buffer *buf_stack[AVL_MAX_HEIGHT]; - bdbuf_buffer **buf_prev = buf_stack; - - boolean modified = FALSE; - - memset(buf_stack, 0, sizeof(buf_stack)); - - while (p != NULL) - { - *buf_prev++ = p; - - if ((p->dev < dev) || ((p->dev == dev) && (p->block < block))) - { - p->avl.cache = 1; - p = p->avl.right; - } - else if ((p->dev != dev) || (p->block != block)) - { - p->avl.cache = -1; - p = p->avl.left; - } - else - { - /* node found */ - break; - } - } - - if (p == NULL) - { - /* there is no such node */ - return -1; - } - - q = p; - - buf_prev--; - if (buf_prev > buf_stack) - { - p = *(buf_prev - 1); - } - else - { - p = NULL; - } - - /* at this moment q - is a node to delete, p is q's parent */ - if (q->avl.right == NULL) - { - r = q->avl.left; - if (r != NULL) - { - r->avl.bal = 0; - } - q = r; - } - else - { - bdbuf_buffer **t; - - r = q->avl.right; - - if (r->avl.left == NULL) - { - r->avl.left = q->avl.left; - r->avl.bal = q->avl.bal; - r->avl.cache = 1; - *buf_prev++ = q = r; - } - else - { - t = buf_prev++; - s = r; - - while (s->avl.left != NULL) - { - *buf_prev++ = r = s; - s = r->avl.left; - r->avl.cache = -1; - } - - s->avl.left = q->avl.left; - r->avl.left = s->avl.right; - s->avl.right = q->avl.right; - s->avl.bal = q->avl.bal; - s->avl.cache = 1; - - *t = q = s; - } - } - - if (p != NULL) - { - if (p->avl.cache == -1) - { - p->avl.left = q; - } - else - { - p->avl.right = q; - } - } - else - { - *root = q; - } - - modified = TRUE; - - while (modified) - { - if (buf_prev > buf_stack) - { - p = *--buf_prev; - } - else - { - break; - } - - if (p->avl.cache == -1) - { - /* rebalance left branch */ - switch (p->avl.bal) - { - case -1: - p->avl.bal = 0; - break; - case 0: - p->avl.bal = 1; - modified = FALSE; - break; - - case +1: - p1 = p->avl.right; - - if (p1->avl.bal >= 0) /* simple RR-turn */ - { - p->avl.right = p1->avl.left; - p1->avl.left = p; - - if (p1->avl.bal == 0) - { - p1->avl.bal = -1; - modified = FALSE; - } - else - { - p->avl.bal = 0; - p1->avl.bal = 0; - } - p = p1; - } - else /* double RL-turn */ - { - p2 = p1->avl.left; - - p1->avl.left = p2->avl.right; - p2->avl.right = p1; - p->avl.right = p2->avl.left; - p2->avl.left = p; - - if (p2->avl.bal == +1) p->avl.bal = -1; else p->avl.bal = 0; - if (p2->avl.bal == -1) p1->avl.bal = 1; else p1->avl.bal = 0; - - p = p2; - p2->avl.bal = 0; - } - break; - - default: - break; - } - } - else - { - /* rebalance right branch */ - switch (p->avl.bal) - { - case +1: - p->avl.bal = 0; - break; - - case 0: - p->avl.bal = -1; - modified = FALSE; - break; - - case -1: - p1 = p->avl.left; - - if (p1->avl.bal <= 0) /* simple LL-turn */ - { - p->avl.left = p1->avl.right; - p1->avl.right = p; - if (p1->avl.bal == 0) - { - p1->avl.bal = 1; - modified = FALSE; - } - else - { - p->avl.bal = 0; - p1->avl.bal = 0; - } - p = p1; - } - else /* double LR-turn */ - { - p2 = p1->avl.right; - - p1->avl.right = p2->avl.left; - p2->avl.left = p1; - p->avl.left = p2->avl.right; - p2->avl.right = p; - - if (p2->avl.bal == -1) p->avl.bal = 1; else p->avl.bal = 0; - if (p2->avl.bal == +1) p1->avl.bal = -1; else p1->avl.bal = 0; - - p = p2; - p2->avl.bal = 0; - } - break; - - default: - break; - } - } - - if (buf_prev > buf_stack) - { - q = *(buf_prev - 1); - - if (q->avl.cache == -1) - { - q->avl.left = p; - } - else - { - q->avl.right = p; - } - } - else - { - *root = p; - break; - } - - } - - return 0; -} - -/* bdbuf_initialize_pool -- - * Initialize single buffer pool. - * - * PARAMETERS: - * config - buffer pool configuration - * pool - pool number - * - * RETURNS: - * RTEMS_SUCCESSFUL, if buffer pool initialized successfully, or error - * code if error occured. - */ -static rtems_status_code -bdbuf_initialize_pool(rtems_bdbuf_config *config, int pool) -{ - bdbuf_pool *p = bd_ctx.pool + pool; - unsigned char *bufs; - bdbuf_buffer *b; - rtems_status_code rc; - int i; - - p->blksize = config->size; - p->nblks = config->num; - p->tree = NULL; - - Chain_Initialize_empty(&p->free); - Chain_Initialize_empty(&p->lru); - - /* Allocate memory for buffer descriptors */ - p->bdbufs = calloc(config->num, sizeof(bdbuf_buffer)); - if (p->bdbufs == NULL) - { - return RTEMS_NO_MEMORY; - } - - /* Allocate memory for buffers if required */ - if (config->mem_area == NULL) - { - bufs = p->mallocd_bufs = malloc(config->num * config->size); - if (bufs == NULL) - { - free(p->bdbufs); - return RTEMS_NO_MEMORY; - } - } - else - { - bufs = config->mem_area; - p->mallocd_bufs = NULL; - } - - for (i = 0, b = p->bdbufs; i < p->nblks; i++, b++, bufs += p->blksize) - { - b->dev = -1; b->block = 0; - b->buffer = bufs; - b->actual = b->modified = b->in_progress = FALSE; - b->use_count = 0; - b->pool = pool; - _Chain_Append(&p->free, &b->link); - } - - rc = rtems_semaphore_create( - rtems_build_name('B', 'U', 'F', 'G'), - p->nblks, - RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | - RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, - 0, - &p->bufget_sema); - - if (rc != RTEMS_SUCCESSFUL) - { - free(p->bdbufs); - free(p->mallocd_bufs); - return rc; - } - - return RTEMS_SUCCESSFUL; -} - -/* bdbuf_release_pool -- - * Free resources allocated for buffer pool with specified number. - * - * PARAMETERS: - * pool - buffer pool number - * - * RETURNS: - * RTEMS_SUCCESSFUL - */ -static rtems_status_code -bdbuf_release_pool(rtems_bdpool_id pool) -{ - bdbuf_pool *p = bd_ctx.pool + pool; - rtems_semaphore_delete(p->bufget_sema); - free(p->bdbufs); - free(p->mallocd_bufs); - return RTEMS_SUCCESSFUL; -} - -/* rtems_bdbuf_init -- - * Prepare buffering layer to work - initialize buffer descritors - * and (if it is neccessary)buffers. Buffers will be allocated accoriding - * to the configuration table, each entry describes kind of block and - * amount requested. After initialization all blocks is placed into - * free elements lists. - * - * PARAMETERS: - * conf_table - pointer to the buffers configuration table - * size - number of entries in configuration table - * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - */ -rtems_status_code -rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size) -{ - rtems_bdpool_id i; - rtems_status_code rc; - - if (size <= 0) - return RTEMS_INVALID_SIZE; - - bd_ctx.npools = size; - - /* - * Allocate memory for buffer pool descriptors - */ - bd_ctx.pool = calloc(size, sizeof(bdbuf_pool)); - if (bd_ctx.pool == NULL) - { - return RTEMS_NO_MEMORY; - } - - Chain_Initialize_empty(&bd_ctx.mod); - - /* Initialize buffer pools and roll out if something failed */ - for (i = 0; i < size; i++) - { - rc = bdbuf_initialize_pool(conf_table + i, i); - if (rc != RTEMS_SUCCESSFUL) - { - rtems_bdpool_id j; - for (j = 0; j < i - 1; j++) - { - bdbuf_release_pool(j); - } - return rc; - } - } - - /* Create buffer flush semaphore */ - rc = rtems_semaphore_create( - rtems_build_name('B', 'F', 'L', 'U'), 0, - RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | - RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, 0, - &bd_ctx.flush_sema); - if (rc != RTEMS_SUCCESSFUL) - { - for (i = 0; i < size; i++) - bdbuf_release_pool(i); - free(bd_ctx.pool); - return rc; - } - - /* Create and start swapout task */ - rc = rtems_task_create( - rtems_build_name('B', 'S', 'W', 'P'), - SWAPOUT_PRIORITY, - SWAPOUT_STACK_SIZE, - RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT, - RTEMS_DEFAULT_ATTRIBUTES, - &bd_ctx.swapout_task); - if (rc != RTEMS_SUCCESSFUL) - { - rtems_semaphore_delete(bd_ctx.flush_sema); - for (i = 0; i < size; i++) - bdbuf_release_pool(i); - free(bd_ctx.pool); - return rc; - } - - rc = rtems_task_start(bd_ctx.swapout_task, bdbuf_swapout_task, 0); - if (rc != RTEMS_SUCCESSFUL) - { - rtems_task_delete(bd_ctx.swapout_task); - rtems_semaphore_delete(bd_ctx.flush_sema); - for (i = 0; i < size; i++) - bdbuf_release_pool(i); - free(bd_ctx.pool); - return rc; - } - - return RTEMS_SUCCESSFUL; -} - -/* find_or_assign_buffer -- - * Looks for buffer already assigned for this dev/block. If one is found - * obtain block buffer. If specified block already cached (i.e. there's - * block in the _modified_, or _recently_used_), return address - * of appropriate buffer descriptor and increment reference counter to 1. - * If block is not cached, allocate new buffer and return it. Data - * shouldn't be read to the buffer from media; buffer contains arbitrary - * data. This primitive may be blocked if there are no free buffer - * descriptors available and there are no unused non-modified (or - * synchronized with media) buffers available. - * - * PARAMETERS: - * device - device number (constructed of major and minor device number - * block - linear media block number - * ret_buf - address of the variable to store address of found descriptor - * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - * - * SIDE EFFEECTS: - * bufget_sema may be obtained by this primitive - * - * NOTE: - * It is assumed that primitive invoked when thread preemption is disabled. - */ -static rtems_status_code -find_or_assign_buffer(disk_device *dd, - blkdev_bnum block, - bdbuf_buffer **ret_buf) -{ - bdbuf_buffer *bd_buf; - bdbuf_pool *bd_pool; - rtems_status_code rc; - dev_t device; - ISR_Level level; - - int blksize; - - device = dd->dev; - bd_pool = bd_ctx.pool + dd->pool; - blksize = dd->block_size; - -again: - /* Looking for buffer descriptor used for this dev/block. */ - bd_buf = avl_search(&bd_pool->tree, device, block); - - if (bd_buf == NULL) - { - /* Try to obtain semaphore without waiting first. It is the most - frequent case when reasonable number of buffers configured. If - it is failed, obtain semaphore blocking on it. In this case - it should be checked that appropriate buffer hasn't been loaded - by another thread, because this thread is preempted */ - rc = rtems_semaphore_obtain(bd_pool->bufget_sema, RTEMS_NO_WAIT, 0); - if (rc == RTEMS_UNSATISFIED) - { - rc = rtems_semaphore_obtain(bd_pool->bufget_sema, - RTEMS_WAIT, RTEMS_NO_TIMEOUT); - bd_buf = avl_search(&bd_pool->tree, device, block); - if (bd_buf != NULL) - rtems_semaphore_release(bd_pool->bufget_sema); - } - } - - if (bd_buf == NULL) - { - /* Assign new buffer descriptor */ - if (_Chain_Is_empty(&bd_pool->free)) - { - bd_buf = (bdbuf_buffer *)Chain_Get(&bd_pool->lru); - if (bd_buf != NULL) - { - int avl_result; - avl_result = avl_remove(&bd_pool->tree, bd_buf); - if (avl_result != 0) - { - rtems_fatal_error_occurred(BLKDEV_FATAL_BDBUF_CONSISTENCY); - return RTEMS_INTERNAL_ERROR; - } - } - } - else - { - bd_buf = (bdbuf_buffer *)Chain_Get(&(bd_pool->free)); - } - - if (bd_buf == NULL) - { - goto again; - } - else - { - bd_buf->dev = device; - bd_buf->block = block; -#ifdef AVL_GPL - bd_buf->avl.link[0] = NULL; - bd_buf->avl.link[1] = NULL; -#else - bd_buf->avl.left = NULL; - bd_buf->avl.right = NULL; -#endif - bd_buf->use_count = 1; - bd_buf->modified = bd_buf->actual = bd_buf->in_progress = FALSE; - bd_buf->status = RTEMS_SUCCESSFUL; - - if (avl_insert(&bd_pool->tree, bd_buf) != 0) - { - rtems_fatal_error_occurred(BLKDEV_FATAL_BDBUF_CONSISTENCY); - return RTEMS_INTERNAL_ERROR; - } - - *ret_buf = bd_buf; - - return RTEMS_SUCCESSFUL; - } - } - else - { - /* Buffer descriptor already assigned for this dev/block */ - if (bd_buf->use_count == 0) - { - /* If we are removing from lru list, obtain the bufget_sema - * first. If we are removing from mod list, obtain flush sema. - * It should be obtained without blocking because we know - * that our buffer descriptor is in the list. */ - if (bd_buf->modified) - { - rc = rtems_semaphore_obtain(bd_ctx.flush_sema, - RTEMS_NO_WAIT, 0); - } - else - { - rc = rtems_semaphore_obtain(bd_pool->bufget_sema, - RTEMS_NO_WAIT, 0); - } - /* It is possible that we couldn't obtain flush or bufget sema - * although buffer in the appropriate chain is available: - * semaphore may be released to swapout task, but this task - * actually did not start to process it. */ - if (rc == RTEMS_UNSATISFIED) - rc = RTEMS_SUCCESSFUL; - if (rc != RTEMS_SUCCESSFUL) - { - rtems_fatal_error_occurred(BLKDEV_FATAL_BDBUF_CONSISTENCY); - return RTEMS_INTERNAL_ERROR; - } - - /* Buffer descriptor is linked to the lru or mod chain. Remove - it from there. */ - Chain_Extract(&bd_buf->link); - } - bd_buf->use_count++; - while (bd_buf->in_progress != 0) - { - rtems_interrupt_disable(level); - _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE, - WATCHDOG_NO_TIMEOUT, level); - } - - *ret_buf = bd_buf; - return RTEMS_SUCCESSFUL; - } -} - -/* rtems_bdbuf_get -- - * Obtain block buffer. If specified block already cached (i.e. there's - * block in the _modified_, or _recently_used_), return address - * of appropriate buffer descriptor and increment reference counter to 1. - * If block is not cached, allocate new buffer and return it. Data - * shouldn't be read to the buffer from media; buffer may contains - * arbitrary data. This primitive may be blocked if there are no free - * buffer descriptors available and there are no unused non-modified - * (or synchronized with media) buffers available. - * - * PARAMETERS: - * device - device number (constructed of major and minor device number) - * block - linear media block number - * bd - address of variable to store pointer to the buffer descriptor - * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - * - * SIDE EFFECTS: - * bufget_sema semaphore obtained by this primitive. - */ -rtems_status_code -rtems_bdbuf_get(dev_t device, blkdev_bnum block, bdbuf_buffer **bd) -{ - rtems_status_code rc; - disk_device *dd; - disk_device *pdd; - preemption_key key; - - /* - * Convert logical dev/block to physical one - */ - dd = rtems_disk_lookup(device); - if (dd == NULL) - return RTEMS_INVALID_ID; - - if (block >= dd->size) - { - rtems_disk_release(dd); - return RTEMS_INVALID_NUMBER; - } - - pdd = dd->phys_dev; - block += dd->start; - rtems_disk_release(dd); - - DISABLE_PREEMPTION(key); - rc = find_or_assign_buffer(pdd, block, bd); - ENABLE_PREEMPTION(key); - - if (rc != RTEMS_SUCCESSFUL) - return rc; - - return RTEMS_SUCCESSFUL; -} - -/* bdbuf_initialize_transfer_sema -- - * Initialize transfer_sema mutex semaphore associated with buffer - * descriptor. - */ -static inline void -bdbuf_initialize_transfer_sema(bdbuf_buffer *bd_buf) -{ - CORE_mutex_Attributes mutex_attr; - mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_BLOCKS; - mutex_attr.only_owner_release = FALSE; - mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_FIFO; - mutex_attr.priority_ceiling = 0; - - _CORE_mutex_Initialize(&bd_buf->transfer_sema, - &mutex_attr, CORE_MUTEX_LOCKED); -} - -/* bdbuf_write_transfer_done -- - * Callout function. Invoked by block device driver when data transfer - * to device (write) is completed. This function may be invoked from - * interrupt handler. - * - * PARAMETERS: - * arg - arbitrary argument specified in block device request - * structure (in this case - pointer to the appropriate - * bdbuf_buffer buffer descriptor structure). - * status - I/O completion status - * error - errno error code if status != RTEMS_SUCCESSFUL - * - * RETURNS: - * none - */ -static void -bdbuf_write_transfer_done(void *arg, rtems_status_code status, int error) -{ - bdbuf_buffer *bd_buf = arg; - bd_buf->status = status; - bd_buf->error = error; - bd_buf->in_progress = bd_buf->modified = FALSE; - _CORE_mutex_Surrender(&bd_buf->transfer_sema, 0, NULL); - _CORE_mutex_Flush(&bd_buf->transfer_sema, NULL, - CORE_MUTEX_STATUS_SUCCESSFUL); -} - -/* bdbuf_read_transfer_done -- - * Callout function. Invoked by block device driver when data transfer - * from device (read) is completed. This function may be invoked from - * interrupt handler. - * - * PARAMETERS: - * arg - arbitrary argument specified in block device request - * structure (in this case - pointer to the appropriate - * bdbuf_buffer buffer descriptor structure). - * status - I/O completion status - * error - errno error code if status != RTEMS_SUCCESSFUL - * - * RETURNS: - * none - */ -static void -bdbuf_read_transfer_done(void *arg, rtems_status_code status, int error) -{ - bdbuf_buffer *bd_buf = arg; - bd_buf->status = status; - bd_buf->error = error; - _CORE_mutex_Surrender(&bd_buf->transfer_sema, 0, NULL); - _CORE_mutex_Flush(&bd_buf->transfer_sema, NULL, - CORE_MUTEX_STATUS_SUCCESSFUL); -} - -/* rtems_bdbuf_read -- - * (Similar to the rtems_bdbuf_get, except reading data from media) - * Obtain block buffer. If specified block already cached, return address - * of appropriate buffer and increment reference counter to 1. If block is - * not cached, allocate new buffer and read data to it from the media. - * This primitive may be blocked on waiting until data to be read from - * media, if there are no free buffer descriptors available and there are - * no unused non-modified (or synchronized with media) buffers available. - * - * PARAMETERS: - * device - device number (consists of major and minor device number) - * block - linear media block number - * bd - address of variable to store pointer to the buffer descriptor - * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - * - * SIDE EFFECTS: - * bufget_sema and transfer_sema semaphores obtained by this primitive. - */ -rtems_status_code -rtems_bdbuf_read(dev_t device, - blkdev_bnum block, - bdbuf_buffer **bd) -{ - preemption_key key; - ISR_Level level; - - bdbuf_buffer *bd_buf; - rtems_status_code rc; - int result; - disk_device *dd; - disk_device *pdd; - blkdev_request1 req; - - dd = rtems_disk_lookup(device); - if (dd == NULL) - return RTEMS_INVALID_ID; - - if (block >= dd->size) - { - rtems_disk_release(dd); - return RTEMS_INVALID_NUMBER; - } - - pdd = dd->phys_dev; - block += dd->start; - - DISABLE_PREEMPTION(key); - rc = find_or_assign_buffer(pdd, block, &bd_buf); - - if (rc != RTEMS_SUCCESSFUL) - { - ENABLE_PREEMPTION(key); - rtems_disk_release(dd); - return rc; - } - - if (!bd_buf->actual) - { - bd_buf->in_progress = 1; - - req.req.req = BLKDEV_REQ_READ; - req.req.req_done = bdbuf_read_transfer_done; - req.req.done_arg = bd_buf; - req.req.start = block; - req.req.count = 1; - req.req.bufnum = 1; - req.req.bufs[0].length = dd->block_size; - req.req.bufs[0].buffer = bd_buf->buffer; - - bdbuf_initialize_transfer_sema(bd_buf); - result = dd->ioctl(device, BLKIO_REQUEST, &req); - if (result == -1) - { - bd_buf->status = RTEMS_IO_ERROR; - bd_buf->error = errno; - bd_buf->actual = FALSE; - } - else - { - rtems_interrupt_disable(level); - _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE, - WATCHDOG_NO_TIMEOUT, level); - bd_buf->actual = TRUE; - } - bd_buf->in_progress = FALSE; - } - rtems_disk_release(dd); - - ENABLE_PREEMPTION(key); - - *bd = bd_buf; - - return RTEMS_SUCCESSFUL; -} - - -/* bdbuf_release -- - * Release buffer. Decrease buffer usage counter. If it is zero, further - * processing depends on modified attribute. If buffer was modified, it - * is inserted into mod chain and swapout task waken up. If buffer was - * not modified, it is returned to the end of lru chain making it available - * for further use. - * - * PARAMETERS: - * bd_buf - pointer to the released buffer descriptor. - * - * RETURNS: - * RTEMS_SUCCESSFUL if buffer released successfully, or error code if - * error occured. - * - * NOTE: - * This is internal function. It is assumed that task made non-preemptive - * before its invocation. - */ -static rtems_status_code -bdbuf_release(bdbuf_buffer *bd_buf) -{ - bdbuf_pool *bd_pool; - rtems_status_code rc = RTEMS_SUCCESSFUL; - - if (bd_buf->use_count <= 0) - return RTEMS_INTERNAL_ERROR; - - bd_pool = bd_ctx.pool + bd_buf->pool; - - bd_buf->use_count--; - - if (bd_buf->use_count == 0) - { - if (bd_buf->modified) - { - - /* Buffer was modified. Insert buffer to the modified buffers - * list and initiate flushing. */ - Chain_Append(&bd_ctx.mod, &bd_buf->link); - - /* Release the flush_sema */ - rc = rtems_semaphore_release(bd_ctx.flush_sema); - } - else - { - /* Buffer was not modified. Add this descriptor to the - * end of lru chain and make it available for reuse. */ - Chain_Append(&bd_pool->lru, &bd_buf->link); - rc = rtems_semaphore_release(bd_pool->bufget_sema); - } - } - return rc; -} - - -/* rtems_bdbuf_release -- - * Release buffer allocated before. This primitive decrease the - * usage counter. If it is zero, further destiny of buffer depends on - * 'modified' status. If buffer was modified, it is placed to the end of - * mod list and flush task waken up. If buffer was not modified, - * it is placed to the end of lru list, and bufget_sema released, allowing - * to reuse this buffer. - * - * PARAMETERS: - * bd_buf - pointer to the bdbuf_buffer structure previously obtained using - * get/read primitive. - * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - * - * SIDE EFFECTS: - * flush_sema and bufget_sema semaphores may be released by this primitive. - */ -rtems_status_code -rtems_bdbuf_release(bdbuf_buffer *bd_buf) -{ - preemption_key key; - rtems_status_code rc = RTEMS_SUCCESSFUL; - - if (bd_buf == NULL) - return RTEMS_INVALID_ADDRESS; - - DISABLE_PREEMPTION(key); - - rc = bdbuf_release(bd_buf); - - ENABLE_PREEMPTION(key); - - return rc; -} - -/* rtems_bdbuf_release_modified -- - * Release buffer allocated before, assuming that it is _modified_ by - * it's owner. This primitive decrease usage counter for buffer, mark - * buffer descriptor as modified. If usage counter is 0, insert it at - * end of mod chain and release flush_sema semaphore to activate the - * flush task. - * - * PARAMETERS: - * bd_buf - pointer to the bdbuf_buffer structure previously obtained using - * get/read primitive. - * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - * - * SIDE EFFECTS: - * flush_sema semaphore may be released by this primitive. - */ -rtems_status_code -rtems_bdbuf_release_modified(bdbuf_buffer *bd_buf) -{ - preemption_key key; - rtems_status_code rc = RTEMS_SUCCESSFUL; - - if (bd_buf == NULL) - return RTEMS_INVALID_ADDRESS; - - DISABLE_PREEMPTION(key); - - if (!bd_buf->modified) - { - bdbuf_initialize_transfer_sema(bd_buf); - } - bd_buf->modified = TRUE; - bd_buf->actual = TRUE; - rc = bdbuf_release(bd_buf); - - ENABLE_PREEMPTION(key); - - return rc; -} - -/* rtems_bdbuf_sync -- - * Wait until specified buffer synchronized with disk. Invoked on exchanges - * critical for data consistency on the media. This primitive mark owned - * block as modified, decrease usage counter. If usage counter is 0, - * block inserted to the mod chain and flush_sema semaphore released. - * Finally, primitives blocked on transfer_sema semaphore. - * - * PARAMETERS: - * bd_buf - pointer to the bdbuf_buffer structure previously obtained using - * get/read primitive. - * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - * - * SIDE EFFECTS: - * Primitive may be blocked on transfer_sema semaphore. - */ -rtems_status_code -rtems_bdbuf_sync(bdbuf_buffer *bd_buf) -{ - preemption_key key; - ISR_Level level; - rtems_status_code rc = RTEMS_SUCCESSFUL; - - if (bd_buf == NULL) - return RTEMS_INVALID_ADDRESS; - - DISABLE_PREEMPTION(key); - - if (!bd_buf->modified) - { - bdbuf_initialize_transfer_sema(bd_buf); - } - bd_buf->modified = TRUE; - bd_buf->actual = TRUE; - - rc = bdbuf_release(bd_buf); - - if (rc == RTEMS_SUCCESSFUL) - { - rtems_interrupt_disable(level); - _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE, - WATCHDOG_NO_TIMEOUT, level); - } - - ENABLE_PREEMPTION(key); - - return rc; -} - -/* rtems_bdbuf_syncdev -- - * Synchronize with disk all buffers containing the blocks belonging to - * specified device. - * - * PARAMETERS: - * dev - block device number - * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - */ -rtems_status_code -rtems_bdbuf_syncdev(dev_t dev) -{ - preemption_key key; - ISR_Level level; - - bdbuf_buffer *bd_buf; - disk_device *dd; - bdbuf_pool *pool; - - dd = rtems_disk_lookup(dev); - if (dd == NULL) - return RTEMS_INVALID_ID; - - pool = bd_ctx.pool + dd->pool; - - DISABLE_PREEMPTION(key); - do { - bd_buf = avl_search_for_sync(&pool->tree, dd); - if (bd_buf != NULL /* && bd_buf->modified */) - { - rtems_interrupt_disable(level); - _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE, - WATCHDOG_NO_TIMEOUT, level); - } - } while (bd_buf != NULL); - ENABLE_PREEMPTION(key); - return rtems_disk_release(dd); -} - -/* bdbuf_swapout_task -- - * Body of task which take care on flushing modified buffers to the - * disk. - */ -static rtems_task -bdbuf_swapout_task(rtems_task_argument unused) -{ - rtems_status_code rc; - int result; - ISR_Level level; - bdbuf_buffer *bd_buf; - bdbuf_pool *bd_pool; - disk_device *dd; - blkdev_request1 req; - - while (1) - { - rc = rtems_semaphore_obtain(bd_ctx.flush_sema, RTEMS_WAIT, 0); - if (rc != RTEMS_SUCCESSFUL) - { - rtems_fatal_error_occurred(BLKDEV_FATAL_BDBUF_SWAPOUT); - } - - bd_buf = (bdbuf_buffer *)Chain_Get(&bd_ctx.mod); - if (bd_buf == NULL) - { - /* It is possible that flush_sema semaphore will be released, but - * buffer to be removed from mod chain before swapout task start - * its processing. */ - continue; - } - - bd_buf->in_progress = TRUE; - bd_buf->use_count++; - bd_pool = bd_ctx.pool + bd_buf->pool; - dd = rtems_disk_lookup(bd_buf->dev); - - req.req.req = BLKDEV_REQ_WRITE; - req.req.req_done = bdbuf_write_transfer_done; - req.req.done_arg = bd_buf; - req.req.start = bd_buf->block + dd->start; - req.req.count = 1; - req.req.bufnum = 1; - req.req.bufs[0].length = dd->block_size; - req.req.bufs[0].buffer = bd_buf->buffer; - - /* transfer_sema initialized when bd_buf inserted in the mod chain - first time */ - result = dd->ioctl(dd->phys_dev->dev, BLKIO_REQUEST, &req); - - rtems_disk_release(dd); - - if (result == -1) - { - bd_buf->status = RTEMS_IO_ERROR; - bd_buf->error = errno; - /* Release tasks waiting on syncing this buffer */ - _CORE_mutex_Flush(&bd_buf->transfer_sema, NULL, - CORE_MUTEX_STATUS_SUCCESSFUL); - } - else - { - if (bd_buf->in_progress) - { - rtems_interrupt_disable(level); - _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE, 0, level); - } - } - bd_buf->use_count--; - - /* Another task have chance to use this buffer, or even - * modify it. If buffer is not in use, insert it in appropriate chain - * and release semaphore */ - if (bd_buf->use_count == 0) - { - if (bd_buf->modified) - { - Chain_Append(&bd_ctx.mod, &bd_buf->link); - rc = rtems_semaphore_release(bd_ctx.flush_sema); - } - else - { - Chain_Append(&bd_pool->lru, &bd_buf->link); - rc = rtems_semaphore_release(bd_pool->bufget_sema); - } - } - } -} - -/* rtems_bdbuf_find_pool -- - * Find first appropriate buffer pool. This primitive returns the index - * of first buffer pool which block size is greater than or equal to - * specified size. - * - * PARAMETERS: - * block_size - requested block size - * pool - placeholder for result - * - * RETURNS: - * RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully, - * RTEMS_INVALID_SIZE if specified block size is invalid (not a power - * of 2), RTEMS_NOT_DEFINED if buffer pool for this or greater block size - * is not configured. - */ -rtems_status_code -rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool) -{ - rtems_bdpool_id i; - bdbuf_pool *p; - int cursize = INT_MAX; - rtems_bdpool_id curid = -1; - rtems_boolean found = FALSE; - int j; - - for (j = block_size; (j != 0) && ((j & 1) == 0); j >>= 1); - if (j != 1) - return RTEMS_INVALID_SIZE; - - for (i = 0, p = bd_ctx.pool; i < bd_ctx.npools; i++, p++) - { - if ((p->blksize >= block_size) && - (p->blksize < cursize)) - { - curid = i; - cursize = p->blksize; - found = TRUE; - } - } - - if (found) - { - if (pool != NULL) - *pool = curid; - return RTEMS_SUCCESSFUL; - } - else - { - return RTEMS_NOT_DEFINED; - } -} - -/* rtems_bdbuf_get_pool_info -- - * Obtain characteristics of buffer pool with specified number. - * - * PARAMETERS: - * pool - buffer pool number - * block_size - block size for which buffer pool is configured returned - * there - * blocks - number of buffers in buffer pool returned there - * - * RETURNS: - * RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully, - * RTEMS_INVALID_NUMBER if appropriate buffer pool is not configured. - * - * NOTE: - * Buffer pools enumerated contiguously starting from 0. - */ -rtems_status_code -rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size, - int *blocks) -{ - if (pool >= bd_ctx.npools) - return RTEMS_INVALID_NUMBER; - - if (block_size != NULL) - { - *block_size = bd_ctx.pool[pool].blksize; - } - - if (blocks != NULL) - { - *blocks = bd_ctx.pool[pool].nblks; - } - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/exec/libblock/src/blkdev.c b/c/src/exec/libblock/src/blkdev.c deleted file mode 100644 index d769dc45ca..0000000000 --- a/c/src/exec/libblock/src/blkdev.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * blkdev.h - block device driver generic support - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Victor V. Vengerov - * - * @(#) $Id$ - */ - -#include - -#include -#include -#include - -#include "rtems/diskdevs.h" -#include "rtems/bdbuf.h" - -/* rtems_blkdev_generic_read -- - * Generic block device read primitive. Implemented using block device - * buffer management primitives. - */ -rtems_device_driver -rtems_blkdev_generic_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_libio_rw_args_t *args = arg; - int block_size_log2; - int block_size; - char *buf; - unsigned int count; - unsigned int block; - unsigned int blkofs; - dev_t dev; - disk_device *dd; - - dev = rtems_filesystem_make_dev_t(major, minor); - dd = rtems_disk_lookup(dev); - if (dd == NULL) - return RTEMS_INVALID_NUMBER; - - block_size_log2 = dd->block_size_log2; - block_size = dd->block_size; - - buf = args->buffer; - count = args->count; - args->bytes_moved = 0; - - block = args->offset >> block_size_log2; - blkofs = args->offset & (block_size - 1); - - while (count > 0) - { - bdbuf_buffer *diskbuf; - int copy; - rtems_status_code rc; - - rc = rtems_bdbuf_read(dev, block, &diskbuf); - if (rc != RTEMS_SUCCESSFUL) - return rc; - copy = block_size - blkofs; - if (copy > count) - copy = count; - memcpy(buf, (char *)diskbuf->buffer + blkofs, copy); - rc = rtems_bdbuf_release(diskbuf); - args->bytes_moved += copy; - if (rc != RTEMS_SUCCESSFUL) - return rc; - count -= copy; - buf += copy; - blkofs = 0; - block++; - } - return RTEMS_SUCCESSFUL; -} - -/* rtems_blkdev_generic_write -- - * Generic block device write primitive. Implemented using block device - * buffer management primitives. - */ -rtems_device_driver -rtems_blkdev_generic_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_libio_rw_args_t *args = arg; - int block_size_log2; - int block_size; - char *buf; - unsigned int count; - unsigned int block; - unsigned int blkofs; - dev_t dev; - rtems_status_code rc; - disk_device *dd; - - dev = rtems_filesystem_make_dev_t(major, minor); - dd = rtems_disk_lookup(dev); - if (dd == NULL) - return RTEMS_INVALID_NUMBER; - - block_size_log2 = dd->block_size_log2; - block_size = dd->block_size; - - buf = args->buffer; - count = args->count; - args->bytes_moved = 0; - - block = args->offset >> block_size_log2; - blkofs = args->offset & (block_size - 1); - - while (count > 0) - { - bdbuf_buffer *diskbuf; - int copy; - - if ((blkofs == 0) && (count > block_size)) - rc = rtems_bdbuf_get(dev, block, &diskbuf); - else - rc = rtems_bdbuf_read(dev, block, &diskbuf); - if (rc != RTEMS_SUCCESSFUL) - return rc; - - copy = block_size - blkofs; - if (copy > count) - copy = count; - memcpy((char *)diskbuf->buffer + blkofs, buf, copy); - args->bytes_moved += copy; - - rc = rtems_bdbuf_release_modified(diskbuf); - if (rc != RTEMS_SUCCESSFUL) - return rc; - - count -= copy; - buf += copy; - blkofs = 0; - block++; - } - return RTEMS_SUCCESSFUL; -} - -/* blkdev_generic_open -- - * Generic block device open primitive. - */ -rtems_device_driver -rtems_blkdev_generic_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - dev_t dev; - disk_device *dd; - - dev = rtems_filesystem_make_dev_t(major, minor); - dd = rtems_disk_lookup(dev); - if (dd == NULL) - return RTEMS_INVALID_NUMBER; - - dd->uses++; - - rtems_disk_release(dd); - - return RTEMS_SUCCESSFUL; -} - - -/* blkdev_generic_close -- - * Generic block device close primitive. - */ -rtems_device_driver -rtems_blkdev_generic_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - dev_t dev; - disk_device *dd; - - dev = rtems_filesystem_make_dev_t(major, minor); - dd = rtems_disk_lookup(dev); - if (dd == NULL) - return RTEMS_INVALID_NUMBER; - - dd->uses--; - - rtems_disk_release(dd); - - return RTEMS_SUCCESSFUL; -} - -/* blkdev_generic_ioctl -- - * Generic block device ioctl primitive. - */ -rtems_device_driver -rtems_blkdev_generic_ioctl( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_libio_ioctl_args_t *args = arg; - dev_t dev; - disk_device *dd; - int rc; - - dev = rtems_filesystem_make_dev_t(major, minor); - dd = rtems_disk_lookup(dev); - if (dd == NULL) - return RTEMS_INVALID_NUMBER; - - switch (args->command) - { - case BLKIO_GETBLKSIZE: - args->ioctl_return = dd->block_size; - break; - - case BLKIO_GETSIZE: - args->ioctl_return = dd->size; - break; - - case BLKIO_SYNCDEV: - rc = rtems_bdbuf_syncdev(dd->dev); - args->ioctl_return = (rc == RTEMS_SUCCESSFUL ? 0 : -1); - break; - - case BLKIO_REQUEST: - { - blkdev_request *req = args->buffer; - req->start += dd->start; - args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command, - req); - break; - } - - default: - args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command, - args->buffer); - break; - } - rtems_disk_release(dd); - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/exec/libblock/src/diskdevs.c b/c/src/exec/libblock/src/diskdevs.c deleted file mode 100644 index a9d6035e8b..0000000000 --- a/c/src/exec/libblock/src/diskdevs.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * diskdevs.c - Physical and logical block devices (disks) support - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Victor V. Vengerov - * - * @(#) $Id$ - */ - - -#include -#include -#include -#include - -#include "rtems/diskdevs.h" -#include "rtems/bdbuf.h" - -#define DISKTAB_INITIAL_SIZE 32 - -/* Table of disk devices having the same major number */ -struct disk_device_table { - disk_device **minor; /* minor-indexed disk device table */ - int size; /* Number of entries in the table */ -}; - -/* Pointer to [major].minor[minor] indexed array of disk devices */ -static struct disk_device_table *disktab; - -/* Number of allocated entries in disktab table */ -static int disktab_size; - -/* Mutual exclusion semaphore for disk devices table */ -static rtems_id diskdevs_mutex; - -/* Flag meaning that disk I/O, buffering etc. already has been initialized. */ -static boolean disk_io_initialized = FALSE; - -/* diskdevs data structures protection flag. - * Normally, only table lookup operations performed. It is quite fast, so - * it is possible to done lookups when interrupts are disabled, avoiding - * obtaining the semaphore. This flags sets immediately after entering in - * mutex-protected section and cleared before leaving this section in - * "big" primitives like add/delete new device etc. Lookup function first - * disable interrupts and check this flag. If it is set, lookup function - * will be blocked on semaphore and lookup operation will be performed in - * semaphore-protected code. If it is not set (very-very frequent case), - * we can do lookup safely, enable interrupts and return result. - */ -static volatile rtems_boolean diskdevs_protected; - -/* create_disk_entry -- - * Return pointer to the disk_entry structure for the specified device, or - * create one if it is not exists. - * - * PARAMETERS: - * dev - device id (major, minor) - * - * RETURNS: - * pointer to the disk device descirptor entry, or NULL if no memory - * available for its creation. - */ -static disk_device * -create_disk_entry(dev_t dev) -{ - rtems_device_major_number major; - rtems_device_minor_number minor; - struct disk_device **d; - - rtems_filesystem_split_dev_t (dev, major, minor); - - if (major >= disktab_size) - { - struct disk_device_table *p; - int newsize; - int i; - newsize = disktab_size * 2; - if (major >= newsize) - newsize = major + 1; - p = realloc(disktab, sizeof(struct disk_device_table) * newsize); - if (p == NULL) - return NULL; - p += disktab_size; - for (i = disktab_size; i < newsize; i++, p++) - { - p->minor = NULL; - p->size = 0; - } - disktab_size = newsize; - } - - if ((disktab[major].minor == NULL) || - (minor >= disktab[major].size)) - { - int newsize; - disk_device **p; - int i; - int s = disktab[major].size; - - if (s == 0) - newsize = DISKTAB_INITIAL_SIZE; - else - newsize = s * 2; - if (minor >= newsize) - newsize = minor + 1; - - p = realloc(disktab[major].minor, sizeof(disk_device *) * newsize); - if (p == NULL) - return NULL; - disktab[major].minor = p; - p += s; - for (i = s; i < newsize; i++, p++) - *p = NULL; - disktab[major].size = newsize; - } - - d = disktab[major].minor + minor; - if (*d == NULL) - { - *d = calloc(1, sizeof(disk_device)); - } - return *d; -} - -/* get_disk_entry -- - * Get disk device descriptor by device number. - * - * PARAMETERS: - * dev - block device number - * - * RETURNS: - * Pointer to the disk device descriptor corresponding to the specified - * device number, or NULL if disk device with such number not exists. - */ -static inline disk_device * -get_disk_entry(dev_t dev) -{ - rtems_device_major_number major; - rtems_device_minor_number minor; - struct disk_device_table *dtab; - - rtems_filesystem_split_dev_t (dev, major, minor); - - if ((major >= disktab_size) || (disktab == NULL)) - return NULL; - - dtab = disktab + major; - - if ((minor >= dtab->size) || (dtab->minor == NULL)) - return NULL; - - return dtab->minor[minor]; -} - -/* create_disk -- - * Check that disk entry for specified device number is not defined - * and create it. - * - * PARAMETERS: - * dev - device identifier (major, minor numbers) - * name - character name of device (e.g. /dev/hda) - * disdev - placeholder for pointer to created disk descriptor - * - * RETURNS: - * RTEMS_SUCCESSFUL if disk entry successfully created, or - * error code if error occured (device already registered, - * no memory available). - */ -static rtems_status_code -create_disk(dev_t dev, char *name, disk_device **diskdev) -{ - disk_device *dd; - char *n; - - dd = get_disk_entry(dev); - if (dd != NULL) - { - return RTEMS_RESOURCE_IN_USE; - } - - if (name == NULL) - { - n = NULL; - } - else - { - int nlen = strlen(name) + 1; - n = malloc(nlen); - if (n == NULL) - return RTEMS_NO_MEMORY; - strncpy(n, name, nlen); - } - - dd = create_disk_entry(dev); - if (dd == NULL) - { - free(n); - return RTEMS_NO_MEMORY; - } - - dd->dev = dev; - dd->name = n; - - *diskdev = dd; - - return RTEMS_SUCCESSFUL; -} - -/* rtems_disk_create_phys -- - * Create physical disk entry. This function usually invoked from - * block device driver initialization code when physical device - * detected in the system. Device driver should provide ioctl handler - * to allow block device access operations. This primitive will register - * device in rtems (invoke rtems_io_register_name). - * - * PARAMETERS: - * dev - device identifier (major, minor numbers) - * block_size - size of disk block (minimum data transfer unit); must be - * power of 2 - * disk_size - number of blocks on device - * handler - IOCTL handler (function providing basic block input/output - * request handling BIOREQUEST and other device management - * operations) - * name - character name of device (e.g. /dev/hda) - * - * RETURNS: - * RTEMS_SUCCESSFUL if information about new physical disk added, or - * error code if error occured (device already registered, wrong block - * size value, no memory available). - */ -rtems_status_code -rtems_disk_create_phys(dev_t dev, int block_size, int disk_size, - block_device_ioctl handler, - char *name) -{ - int bs_log2; - int i; - disk_device *dd; - rtems_status_code rc; - rtems_bdpool_id pool; - rtems_device_major_number major; - rtems_device_minor_number minor; - - rtems_filesystem_split_dev_t (dev, major, minor); - - - for (bs_log2 = 0, i = block_size; (i & 1) == 0; i >>= 1, bs_log2++); - if ((bs_log2 < 9) || (i != 1)) /* block size < 512 or not power of 2 */ - return RTEMS_INVALID_NUMBER; - - rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (rc != RTEMS_SUCCESSFUL) - return rc; - diskdevs_protected = TRUE; - - rc = rtems_bdbuf_find_pool(block_size, &pool); - if (rc != RTEMS_SUCCESSFUL) - { - diskdevs_protected = FALSE; - rtems_semaphore_release(diskdevs_mutex); - return rc; - } - - rc = create_disk(dev, name, &dd); - if (rc != RTEMS_SUCCESSFUL) - { - diskdevs_protected = FALSE; - rtems_semaphore_release(diskdevs_mutex); - return rc; - } - - dd->phys_dev = dd; - dd->uses = 0; - dd->start = 0; - dd->size = disk_size; - dd->block_size = block_size; - dd->block_size_log2 = bs_log2; - dd->ioctl = handler; - dd->pool = pool; - - rc = rtems_io_register_name(name, major, minor); - - diskdevs_protected = FALSE; - rtems_semaphore_release(diskdevs_mutex); - - return rc; -} - -/* rtems_disk_create_log -- - * Create logical disk entry. Logical disk is contiguous area on physical - * disk. Disk may be splitted to several logical disks in several ways: - * manually or using information stored in blocks on physical disk - * (DOS-like partition table, BSD disk label, etc). This function usually - * invoked from application when application-specific splitting are in use, - * or from generic code which handle different logical disk organizations. - * This primitive will register device in rtems (invoke - * rtems_io_register_name). - * - * PARAMETERS: - * dev - logical device identifier (major, minor numbers) - * phys - physical device (block device which holds this logical disk) - * identifier - * start - starting block number on the physical device - * size - logical disk size in blocks - * name - logical disk name - * - * RETURNS: - * RTEMS_SUCCESSFUL if logical device successfully added, or error code - * if error occured (device already registered, no physical device - * exists, logical disk is out of physical disk boundaries, no memory - * available). - */ -rtems_status_code -rtems_disk_create_log(dev_t dev, dev_t phys, int start, int size, char *name) -{ - disk_device *dd; - disk_device *pdd; - rtems_status_code rc; - rtems_device_major_number major; - rtems_device_minor_number minor; - - rtems_filesystem_split_dev_t (dev, major, minor); - - rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (rc != RTEMS_SUCCESSFUL) - return rc; - diskdevs_protected = TRUE; - - pdd = get_disk_entry(phys); - if (pdd == NULL) - { - diskdevs_protected = FALSE; - rtems_semaphore_release(diskdevs_mutex); - return RTEMS_INVALID_NUMBER; - } - - rc = create_disk(dev, name, &dd); - if (rc != RTEMS_SUCCESSFUL) - { - diskdevs_protected = FALSE; - rtems_semaphore_release(diskdevs_mutex); - return rc; - } - - dd->phys_dev = pdd; - dd->uses = 0; - dd->start = start; - dd->size = size; - dd->block_size = pdd->block_size; - dd->block_size_log2 = pdd->block_size_log2; - dd->ioctl = pdd->ioctl; - - rc = rtems_io_register_name(name, major, minor); - - diskdevs_protected = FALSE; - rc = rtems_semaphore_release(diskdevs_mutex); - - return rc; -} - -/* rtems_disk_delete -- - * Delete physical or logical disk device. Device may be deleted if its - * use counter (and use counters of all logical devices - if it is - * physical device) equal to 0. When physical device deleted, - * all logical devices deleted inherently. Appropriate devices removed - * from "/dev" filesystem. - * - * PARAMETERS: - * dev - device identifier (major, minor numbers) - * - * RETURNS: - * RTEMS_SUCCESSFUL if block device successfully deleted, or error code - * if error occured (device is not defined, device is in use). - */ -rtems_status_code -rtems_disk_delete(dev_t dev) -{ - rtems_status_code rc; - int used; - rtems_device_major_number maj; - rtems_device_minor_number min; - - rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (rc != RTEMS_SUCCESSFUL) - return rc; - diskdevs_protected = TRUE; - - /* Check if this device is in use -- calculate usage counter */ - used = 0; - for (maj = 0; maj < disktab_size; maj++) - { - struct disk_device_table *dtab = disktab + maj; - if (dtab != NULL) - { - for (min = 0; min < dtab->size; min++) - { - disk_device *dd = dtab->minor[min]; - if ((dd != NULL) && (dd->phys_dev->dev == dev)) - used += dd->uses; - } - } - } - - if (used != 0) - { - diskdevs_protected = FALSE; - rtems_semaphore_release(diskdevs_mutex); - return RTEMS_RESOURCE_IN_USE; - } - - /* Delete this device and all of its logical devices */ - for (maj = 0; maj < disktab_size; maj++) - { - struct disk_device_table *dtab = disktab +maj; - if (dtab != NULL) - { - for (min = 0; min < dtab->size; min++) - { - disk_device *dd = dtab->minor[min]; - if ((dd != NULL) && (dd->phys_dev->dev == dev)) - { - unlink(dd->name); - free(dd->name); - free(dd); - dtab->minor[min] = NULL; - } - } - } - } - - diskdevs_protected = FALSE; - rc = rtems_semaphore_release(diskdevs_mutex); - return rc; -} - -/* rtems_disk_lookup -- - * Find block device descriptor by its device identifier. - * - * PARAMETERS: - * dev - device identifier (major, minor numbers) - * - * RETURNS: - * pointer to the block device descriptor, or NULL if no such device - * exists. - */ -disk_device * -rtems_disk_lookup(dev_t dev) -{ - rtems_interrupt_level level; - disk_device *dd; - rtems_status_code rc; - - rtems_interrupt_disable(level); - if (diskdevs_protected) - { - rtems_interrupt_enable(level); - rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, - RTEMS_NO_TIMEOUT); - if (rc != RTEMS_SUCCESSFUL) - return NULL; - diskdevs_protected = TRUE; - dd = get_disk_entry(dev); - dd->uses++; - diskdevs_protected = FALSE; - rtems_semaphore_release(diskdevs_mutex); - return dd; - } - else - { - /* Frequent and quickest case */ - dd = get_disk_entry(dev); - dd->uses++; - rtems_interrupt_enable(level); - return dd; - } -} - -/* rtems_disk_release -- - * Release disk_device structure (decrement usage counter to 1). - * - * PARAMETERS: - * dd - pointer to disk device structure - * - * RETURNS: - * RTEMS_SUCCESSFUL - */ -rtems_status_code -rtems_disk_release(disk_device *dd) -{ - rtems_interrupt_level level; - rtems_interrupt_disable(level); - dd->uses--; - rtems_interrupt_enable(level); - return RTEMS_SUCCESSFUL; -} - -/* rtems_disk_next -- - * Disk device enumerator. Looking for device having device number larger - * than dev and return disk device descriptor for it. If there are no - * such device, NULL value returned. - * - * PARAMETERS: - * dev - device number (use -1 to start search) - * - * RETURNS: - * Pointer to the disk descriptor for next disk device, or NULL if all - * devices enumerated. - */ -disk_device * -rtems_disk_next(dev_t dev) -{ - rtems_device_major_number major; - rtems_device_minor_number minor; - struct disk_device_table *dtab; - - dev++; - rtems_filesystem_split_dev_t (dev, major, minor); - - if (major >= disktab_size) - return NULL; - - dtab = disktab + major; - while (TRUE) - { - if ((dtab == NULL) || (minor > dtab->size)) - { - major++; minor = 0; - if (major >= disktab_size) - return NULL; - dtab = disktab + major; - } - else if (dtab->minor[minor] == NULL) - { - minor++; - } - else - return dtab->minor[minor]; - } -} - -/* rtems_disk_initialize -- - * Initialization of disk device library (initialize all data structures, - * etc.) - * - * PARAMETERS: - * none - * - * RETURNS: - * RTEMS_SUCCESSFUL if library initialized, or error code if error - * occured. - */ -rtems_status_code -rtems_disk_io_initialize(void) -{ - rtems_status_code rc; - - if (disk_io_initialized) - return RTEMS_SUCCESSFUL; - - disktab_size = DISKTAB_INITIAL_SIZE; - disktab = calloc(disktab_size, sizeof(struct disk_device_table)); - if (disktab == NULL) - return RTEMS_NO_MEMORY; - - diskdevs_protected = FALSE; - rc = rtems_semaphore_create( - rtems_build_name('D', 'D', 'E', 'V'), 1, - RTEMS_FIFO | RTEMS_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | - RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, 0, &diskdevs_mutex); - - if (rc != RTEMS_SUCCESSFUL) - { - free(disktab); - return rc; - } - - rc = rtems_bdbuf_init(rtems_bdbuf_configuration, - rtems_bdbuf_configuration_size); - - if (rc != RTEMS_SUCCESSFUL) - { - rtems_semaphore_delete(diskdevs_mutex); - free(disktab); - return rc; - } - - disk_io_initialized = 1; - return RTEMS_SUCCESSFUL; -} - -/* rtems_disk_io_done -- - * Release all resources allocated for disk device interface. - * - * PARAMETERS: - * none - * - * RETURNS: - * RTEMS_SUCCESSFUL if all resources released, or error code if error - * occured. - */ -rtems_status_code -rtems_disk_io_done(void) -{ - rtems_device_major_number maj; - rtems_device_minor_number min; - rtems_status_code rc; - - /* Free data structures */ - for (maj = 0; maj < disktab_size; maj++) - { - struct disk_device_table *dtab = disktab + maj; - if (dtab != NULL) - { - for (min = 0; min < dtab->size; min++) - { - disk_device *dd = dtab->minor[min]; - unlink(dd->name); - free(dd->name); - free(dd); - } - free(dtab); - } - } - free(disktab); - - rc = rtems_semaphore_release(diskdevs_mutex); - - /* XXX bdbuf should be released too! */ - disk_io_initialized = 0; - return rc; -} diff --git a/c/src/exec/libblock/src/ramdisk.c b/c/src/exec/libblock/src/ramdisk.c deleted file mode 100644 index 7be2eabcc8..0000000000 --- a/c/src/exec/libblock/src/ramdisk.c +++ /dev/null @@ -1,225 +0,0 @@ -/* 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 - -#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