summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-30 13:40:34 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-31 11:05:48 +0200
commit73c09b3b8efc52831e80295e010fd7bfbd8c4b0c (patch)
treef4232b1f6ba94d5b0666177c8a00a2ff5c87a0f5
parentlibblock: Remove explicit bds_per_group parameter (diff)
downloadrtems-73c09b3b8efc52831e80295e010fd7bfbd8c4b0c.tar.bz2
libblock: Simplify disk management
Add block_count and media_blocks_per_block to rtems_disk_device. Add and use rtems_disk_init_phys() and rtems_disk_init_log().
-rw-r--r--cpukit/libblock/Makefile.am1
-rw-r--r--cpukit/libblock/include/rtems/bdbuf.h11
-rw-r--r--cpukit/libblock/include/rtems/diskdevs.h54
-rw-r--r--cpukit/libblock/src/bdbuf.c27
-rw-r--r--cpukit/libblock/src/blkdev-imfs.c83
-rw-r--r--cpukit/libblock/src/diskdevs-init.c88
-rw-r--r--cpukit/libblock/src/diskdevs.c83
-rw-r--r--testsuites/libtests/block01/init.c2
8 files changed, 230 insertions, 119 deletions
diff --git a/cpukit/libblock/Makefile.am b/cpukit/libblock/Makefile.am
index 242c44e1f6..6ddc52418d 100644
--- a/cpukit/libblock/Makefile.am
+++ b/cpukit/libblock/Makefile.am
@@ -8,6 +8,7 @@ libblock_a_SOURCES = src/bdbuf.c \
src/blkdev-ioctl.c \
src/blkdev-ops.c \
src/diskdevs.c \
+ src/diskdevs-init.c \
src/flashdisk.c \
src/ramdisk-driver.c \
src/ramdisk-init.c \
diff --git a/cpukit/libblock/include/rtems/bdbuf.h b/cpukit/libblock/include/rtems/bdbuf.h
index c065f4ec55..43a95dfe99 100644
--- a/cpukit/libblock/include/rtems/bdbuf.h
+++ b/cpukit/libblock/include/rtems/bdbuf.h
@@ -141,7 +141,7 @@ extern "C" {
* A block being accessed is given to the file system layer and not accessible
* to another requester until released back to the cache. The same goes to a
* buffer in the transfer state. The transfer state means being read or
- * written. If the file system has modifed the block and releases it as
+ * written. If the file system has modified the block and releases it as
* modified it placed on the cache's modified list and a hold timer
* initialised. The buffer is held for the hold time before being written to
* disk. Buffers are held for a configurable period of time on the modified
@@ -462,7 +462,7 @@ rtems_bdbuf_init (void);
/**
* Get block buffer for data to be written into. The buffers is set to the
- * access or modifed access state. If the buffer is in the cache and modified
+ * access or modified access state. If the buffer is in the cache and modified
* the state is access modified else the state is access. This buffer contents
* are not initialised if the buffer is not already in the cache. If the block
* is already resident in memory it is returned how-ever if not in memory the
@@ -498,7 +498,7 @@ rtems_bdbuf_get (
/**
* Get the block buffer and if not already in the cache read from the disk. If
* specified block already cached return. The buffer is set to the access or
- * modifed access state. If the buffer is in the cache and modified the state
+ * modified access state. If the buffer is in the cache and modified the state
* is access modified else the state is access. If block is already being read
* from disk for being written to disk this call blocks. If the buffer is
* waiting to be written it is removed from modified queue and returned to the
@@ -601,7 +601,7 @@ rtems_bdbuf_sync (rtems_bdbuf_buffer* bd);
/**
* Synchronize all modified buffers for this device with the disk and wait
* until the transfers have completed. The sync mutex for the cache is locked
- * stopping the addition of any further modifed buffers. It is only the
+ * stopping the addition of any further modified buffers. It is only the
* currently modified buffers that are written.
*
* @note Nesting calls to sync multiple devices will be handled sequentially. A
@@ -635,8 +635,7 @@ rtems_bdbuf_purge_dev (rtems_disk_device *dd);
/**
* @brief Sets the block size of a disk device.
*
- * This will also change the block_to_media_block_shift and bds_per_group
- * fields of the disk device.
+ * This will set the block size derived fields of the disk device.
*
* Before you can use this function, the rtems_bdbuf_init() routine must be
* called at least once to initialize the cache, otherwise a fatal error will
diff --git a/cpukit/libblock/include/rtems/diskdevs.h b/cpukit/libblock/include/rtems/diskdevs.h
index 2e3f7533f3..fe931f8a94 100644
--- a/cpukit/libblock/include/rtems/diskdevs.h
+++ b/cpukit/libblock/include/rtems/diskdevs.h
@@ -92,33 +92,48 @@ struct rtems_disk_device {
unsigned uses;
/**
- * @brief Start block number.
+ * @brief Start media block number.
*
- * Equals zero for physical devices. It is a block offset to the related
- * physical device for logical device.
+ * Equals zero for physical devices. It is a media block offset to the
+ * related physical device for logical device.
*/
rtems_blkdev_bnum start;
/**
- * @brief Size of the physical or logical disk in blocks.
+ * @brief Size of the physical or logical disk in media blocks.
*/
rtems_blkdev_bnum size;
/**
- * @brief Device block size in bytes.
+ * @brief Media block size in bytes.
*
- * This is the minimum transfer unit. It must be positive.
+ * This is the media transfer unit the hardware defaults to.
+ */
+ uint32_t media_block_size;
+
+ /**
+ * @brief Block size in bytes.
+ *
+ * This is the minimum transfer unit. It may be a multiple of the media
+ * block size. It must be positive.
*
* @see rtems_bdbuf_set_block_size().
*/
uint32_t block_size;
/**
- * @brief Device media block size in bytes.
+ * @brief Block count.
*
- * This is the media transfer unit the hardware defaults to.
+ * @see rtems_bdbuf_set_block_size().
*/
- uint32_t media_block_size;
+ rtems_blkdev_bnum block_count;
+
+ /**
+ * @brief Media blocks per device blocks.
+ *
+ * @see rtems_bdbuf_set_block_size().
+ */
+ uint32_t media_blocks_per_block;
/**
* @brief Block to media block shift.
@@ -259,7 +274,7 @@ rtems_status_code rtems_disk_create_phys(
*
* A logical disk manages a subset of consecutive blocks contained in the
* physical disk with identifier @a phys. The start block index of the logical
- * disk device is @a begin_block. The block count of the logcal disk will be
+ * disk device is @a block_begin. The block count of the logcal disk will be
* @a block_count. The blocks must be within the range of blocks managed by
* the associated physical disk device. A device node will be registered in
* the file system with absolute path @a name, if @a name is not @c NULL. The
@@ -278,7 +293,7 @@ rtems_status_code rtems_disk_create_phys(
rtems_status_code rtems_disk_create_log(
dev_t dev,
dev_t phys,
- rtems_blkdev_bnum begin_block,
+ rtems_blkdev_bnum block_begin,
rtems_blkdev_bnum block_count,
const char *name
);
@@ -373,6 +388,23 @@ rtems_status_code rtems_disk_io_done(void);
*/
rtems_disk_device *rtems_disk_next(dev_t dev);
+/* Internal function, do not use */
+rtems_status_code rtems_disk_init_phys(
+ rtems_disk_device *dd,
+ uint32_t block_size,
+ rtems_blkdev_bnum block_count,
+ rtems_block_device_ioctl handler,
+ void *driver_data
+);
+
+/* Internal function, do not use */
+rtems_status_code rtems_disk_init_log(
+ rtems_disk_device *dd,
+ rtems_disk_device *phys_dd,
+ rtems_blkdev_bnum block_begin,
+ rtems_blkdev_bnum block_count
+);
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index 4985dc1e16..c0744c6db2 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ b/cpukit/libblock/src/bdbuf.c
@@ -1754,20 +1754,23 @@ rtems_bdbuf_get_media_block (const rtems_disk_device *dd,
rtems_blkdev_bnum block,
rtems_blkdev_bnum *media_block_ptr)
{
- /*
- * Compute the media block number. Drivers work with media block number not
- * the block number a BD may have as this depends on the block size set by
- * the user.
- */
- rtems_blkdev_bnum mb = rtems_bdbuf_media_block (dd, block);
- if (mb >= dd->size)
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ if (block < dd->block_count)
+ {
+ /*
+ * Compute the media block number. Drivers work with media block number not
+ * the block number a BD may have as this depends on the block size set by
+ * the user.
+ */
+ *media_block_ptr = rtems_bdbuf_media_block (dd, block) + dd->start;
+ }
+ else
{
- return RTEMS_INVALID_ID;
+ sc = RTEMS_INVALID_ID;
}
- *media_block_ptr = mb + dd->start;
-
- return RTEMS_SUCCESSFUL;
+ return sc;
}
rtems_status_code
@@ -2909,6 +2912,8 @@ rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size)
block_to_media_block_shift = -1;
dd->block_size = block_size;
+ dd->block_count = dd->size / media_blocks_per_block;
+ dd->media_blocks_per_block = media_blocks_per_block;
dd->block_to_media_block_shift = block_to_media_block_shift;
dd->bds_per_group = bds_per_group;
}
diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c
index c159ca3abe..e3c76a1d2f 100644
--- a/cpukit/libblock/src/blkdev-imfs.c
+++ b/cpukit/libblock/src/blkdev-imfs.c
@@ -269,46 +269,36 @@ rtems_status_code rtems_blkdev_create(
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_blkdev_imfs_context *ctx = malloc(sizeof(*ctx));
- if (block_count > 0) {
- rtems_blkdev_imfs_context *ctx = calloc(1, sizeof(*ctx));
+ if (ctx != NULL) {
+ sc = rtems_disk_init_phys(
+ &ctx->dd,
+ block_size,
+ block_count,
+ handler,
+ driver_data
+ );
- if (ctx != NULL) {
- rtems_disk_device *dd = &ctx->dd;
+ ctx->fd = -1;
- ctx->fd = -1;
-
- dd->phys_dev = dd;
- dd->size = block_count;
- dd->media_block_size = block_size;
- dd->ioctl = handler;
- dd->driver_data = driver_data;
-
- if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) != 0) {
- dd->capabilities = 0;
- }
-
- sc = rtems_bdbuf_set_block_size(dd, block_size);
- if (sc == RTEMS_SUCCESSFUL) {
- int rv = IMFS_make_generic_node(
- device,
- S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,
- &rtems_blkdev_imfs_control,
- ctx
- );
-
- if (rv != 0) {
- free(ctx);
- sc = RTEMS_UNSATISFIED;
- }
- } else {
+ if (sc == RTEMS_SUCCESSFUL) {
+ int rv = IMFS_make_generic_node(
+ device,
+ S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,
+ &rtems_blkdev_imfs_control,
+ ctx
+ );
+
+ if (rv != 0) {
free(ctx);
+ sc = RTEMS_UNSATISFIED;
}
} else {
- sc = RTEMS_NO_MEMORY;
+ free(ctx);
}
} else {
- sc = RTEMS_INVALID_NUMBER;
+ sc = RTEMS_NO_MEMORY;
}
return sc;
@@ -330,24 +320,21 @@ rtems_status_code rtems_blkdev_create_partition(
rv = fstat(fd, &st);
if (rv == 0 && S_ISBLK(st.st_mode)) {
- rtems_disk_device *dd;
+ rtems_disk_device *phys_dd;
- rv = rtems_disk_fd_get_disk_device(fd, &dd);
+ rv = rtems_disk_fd_get_disk_device(fd, &phys_dd);
if (rv == 0) {
- rtems_blkdev_bnum device_block_count = rtems_disk_get_block_count(dd);
-
- if (
- block_begin < device_block_count
- && block_count > 0
- && block_count <= device_block_count - block_begin
- ) {
- rtems_blkdev_imfs_context *ctx = malloc(sizeof(*ctx));
+ rtems_blkdev_imfs_context *ctx = malloc(sizeof(*ctx));
- if (ctx != NULL) {
- memcpy(&ctx->dd, dd, sizeof(ctx->dd));
+ if (ctx != NULL) {
+ sc = rtems_disk_init_log(
+ &ctx->dd,
+ phys_dd,
+ block_begin,
+ block_count
+ );
- ctx->dd.start = block_begin;
- ctx->dd.size = block_count;
+ if (sc == RTEMS_SUCCESSFUL) {
ctx->fd = fd;
rv = IMFS_make_generic_node(
@@ -362,10 +349,10 @@ rtems_status_code rtems_blkdev_create_partition(
sc = RTEMS_UNSATISFIED;
}
} else {
- sc = RTEMS_NO_MEMORY;
+ free(ctx);
}
} else {
- sc = RTEMS_INVALID_NUMBER;
+ sc = RTEMS_NO_MEMORY;
}
} else {
sc = RTEMS_NOT_IMPLEMENTED;
diff --git a/cpukit/libblock/src/diskdevs-init.c b/cpukit/libblock/src/diskdevs-init.c
new file mode 100644
index 0000000000..ccf954a49a
--- /dev/null
+++ b/cpukit/libblock/src/diskdevs-init.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/blkdev.h>
+#include <rtems/bdbuf.h>
+
+rtems_status_code rtems_disk_init_phys(
+ rtems_disk_device *dd,
+ uint32_t block_size,
+ rtems_blkdev_bnum block_count,
+ rtems_block_device_ioctl handler,
+ void *driver_data
+)
+{
+ rtems_status_code sc;
+
+ dd = memset(dd, 0, sizeof(*dd));
+
+ dd->phys_dev = dd;
+ dd->size = block_count;
+ dd->media_block_size = block_size;
+ dd->ioctl = handler;
+ dd->driver_data = driver_data;
+
+ if (block_count > 0) {
+ if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) != 0) {
+ dd->capabilities = 0;
+ }
+
+ sc = rtems_bdbuf_set_block_size(dd, block_size);
+ } else {
+ sc = RTEMS_INVALID_NUMBER;
+ }
+
+ return sc;
+}
+
+rtems_status_code rtems_disk_init_log(
+ rtems_disk_device *dd,
+ rtems_disk_device *phys_dd,
+ rtems_blkdev_bnum block_begin,
+ rtems_blkdev_bnum block_count
+)
+{
+ rtems_status_code sc;
+
+ dd = memset(dd, 0, sizeof(*dd));
+
+ dd->phys_dev = phys_dd;
+ dd->start = block_begin;
+ dd->size = block_count;
+ dd->media_block_size = phys_dd->media_block_size;
+ dd->ioctl = phys_dd->ioctl;
+ dd->driver_data = phys_dd->driver_data;
+
+ if (phys_dd->phys_dev == phys_dd) {
+ rtems_blkdev_bnum phys_block_count = phys_dd->size;
+
+ if (
+ block_begin < phys_block_count
+ && block_count > 0
+ && block_count <= phys_block_count - block_begin
+ ) {
+ sc = rtems_bdbuf_set_block_size(dd, phys_dd->media_block_size);
+ } else {
+ sc = RTEMS_INVALID_NUMBER;
+ }
+ } else {
+ sc = RTEMS_INVALID_ID;
+ }
+
+ return sc;
+}
diff --git a/cpukit/libblock/src/diskdevs.c b/cpukit/libblock/src/diskdevs.c
index 285bc05efb..96bcf88f52 100644
--- a/cpukit/libblock/src/diskdevs.c
+++ b/cpukit/libblock/src/diskdevs.c
@@ -10,7 +10,7 @@
* Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
* Author: Victor V. Vengerov <vvv@oktet.ru>
*
- * Copyright (c) 2009 embedded brains GmbH.
+ * Copyright (c) 2009-2012 embedded brains GmbH.
*/
#if HAVE_CONFIG_H
@@ -170,7 +170,12 @@ create_disk_table_entry(dev_t dev)
}
static rtems_status_code
-create_disk(dev_t dev, const char *name, rtems_disk_device **dd_ptr)
+create_disk(
+ dev_t dev,
+ const char *name,
+ rtems_disk_device **dd_ptr,
+ char **alloc_name_ptr
+)
{
rtems_disk_device **dd_entry = create_disk_table_entry(dev);
rtems_disk_device *dd = NULL;
@@ -207,13 +212,9 @@ create_disk(dev_t dev, const char *name, rtems_disk_device **dd_ptr)
}
}
- dd->dev = dev;
- dd->name = alloc_name;
- dd->uses = 0;
- dd->deleted = false;
-
*dd_entry = dd;
*dd_ptr = dd;
+ *alloc_name_ptr = alloc_name;
return RTEMS_SUCCESSFUL;
}
@@ -238,6 +239,7 @@ rtems_status_code rtems_disk_create_phys(
{
rtems_disk_device *dd = NULL;
rtems_status_code sc = RTEMS_SUCCESSFUL;
+ char *alloc_name = NULL;
if (handler == NULL) {
return RTEMS_INVALID_ADDRESS;
@@ -248,25 +250,24 @@ rtems_status_code rtems_disk_create_phys(
return sc;
}
- sc = create_disk(dev, name, &dd);
+ sc = create_disk(dev, name, &dd, &alloc_name);
if (sc != RTEMS_SUCCESSFUL) {
disk_unlock();
return sc;
}
- dd->phys_dev = dd;
- dd->start = 0;
- dd->size = block_count;
- dd->media_block_size = block_size;
- dd->ioctl = handler;
- dd->driver_data = driver_data;
+ sc = rtems_disk_init_phys(
+ dd,
+ block_size,
+ block_count,
+ handler,
+ driver_data
+ );
- if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) < 0) {
- dd->capabilities = 0;
- }
+ dd->dev = dev;
+ dd->name = alloc_name;
- sc = rtems_bdbuf_set_block_size(dd, block_size);
if (sc != RTEMS_SUCCESSFUL) {
dd->ioctl = null_handler;
rtems_disk_delete(dev);
@@ -289,57 +290,55 @@ is_physical_disk(const rtems_disk_device *dd)
rtems_status_code rtems_disk_create_log(
dev_t dev,
dev_t phys,
- rtems_blkdev_bnum begin_block,
+ rtems_blkdev_bnum block_begin,
rtems_blkdev_bnum block_count,
const char *name
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_disk_device *physical_disk = NULL;
+ rtems_disk_device *phys_dd = NULL;
rtems_disk_device *dd = NULL;
- rtems_blkdev_bnum end_block = begin_block + block_count;
+ char *alloc_name = NULL;
sc = disk_lock();
if (sc != RTEMS_SUCCESSFUL) {
return sc;
}
- physical_disk = get_disk_entry(phys, true);
- if (physical_disk == NULL || !is_physical_disk(physical_disk)) {
+ phys_dd = get_disk_entry(phys, true);
+ if (phys_dd == NULL) {
disk_unlock();
return RTEMS_INVALID_ID;
}
- if (
- begin_block >= physical_disk->size
- || end_block <= begin_block
- || end_block > physical_disk->size
- ) {
+ sc = create_disk(dev, name, &dd, &alloc_name);
+ if (sc != RTEMS_SUCCESSFUL) {
disk_unlock();
- return RTEMS_INVALID_NUMBER;
+ return sc;
}
- sc = create_disk(dev, name, &dd);
+ sc = rtems_disk_init_log(
+ dd,
+ phys_dd,
+ block_begin,
+ block_count
+ );
+
+ dd->dev = dev;
+ dd->name = alloc_name;
+
+ ++phys_dd->uses;
+
if (sc != RTEMS_SUCCESSFUL) {
+ dd->ioctl = null_handler;
+ rtems_disk_delete(dev);
disk_unlock();
return sc;
}
- dd->phys_dev = physical_disk;
- dd->start = begin_block;
- dd->size = block_count;
- dd->block_size = physical_disk->block_size;
- dd->media_block_size = physical_disk->media_block_size;
- dd->block_to_media_block_shift = physical_disk->block_to_media_block_shift;
- dd->bds_per_group = physical_disk->bds_per_group;
- dd->ioctl = physical_disk->ioctl;
- dd->driver_data = physical_disk->driver_data;
-
- ++physical_disk->uses;
-
disk_unlock();
return RTEMS_SUCCESSFUL;
diff --git a/testsuites/libtests/block01/init.c b/testsuites/libtests/block01/init.c
index 03ff097b62..c26f18adbd 100644
--- a/testsuites/libtests/block01/init.c
+++ b/testsuites/libtests/block01/init.c
@@ -183,7 +183,7 @@ static void test_diskdevs(void)
sc = rtems_disk_create_log(logical_dev, physical_dev, 0, 1, "/dev/rda1");
ASSERT_SC_EQ(sc, RTEMS_RESOURCE_IN_USE);
- sc = rtems_disk_create_log(logical_2_dev, logical_dev, 0, 1, "/dev/rda1");
+ sc = rtems_disk_create_log(logical_2_dev, logical_dev, 0, 1, "/dev/rda2");
ASSERT_SC_EQ(sc, RTEMS_INVALID_ID);
sc = rtems_disk_delete(logical_dev);