diff options
-rw-r--r-- | cpukit/libblock/Makefile.am | 1 | ||||
-rw-r--r-- | cpukit/libblock/include/rtems/blkdev.h | 50 | ||||
-rw-r--r-- | cpukit/libblock/src/blkdev-imfs.c | 380 | ||||
-rw-r--r-- | testsuites/libtests/Makefile.am | 2 | ||||
-rw-r--r-- | testsuites/libtests/block11/Makefile.am | 25 | ||||
-rw-r--r-- | testsuites/libtests/block11/block11.doc | 12 | ||||
-rw-r--r-- | testsuites/libtests/block11/block11.scn | 2 | ||||
-rw-r--r-- | testsuites/libtests/block11/init.c | 402 | ||||
-rw-r--r-- | testsuites/libtests/configure.ac | 1 |
9 files changed, 874 insertions, 1 deletions
diff --git a/cpukit/libblock/Makefile.am b/cpukit/libblock/Makefile.am index 0311319888..5cf143dae3 100644 --- a/cpukit/libblock/Makefile.am +++ b/cpukit/libblock/Makefile.am @@ -8,6 +8,7 @@ include $(top_srcdir)/automake/compile.am noinst_LIBRARIES = libblock.a libblock_a_SOURCES = src/bdbuf.c \ src/blkdev.c \ + src/blkdev-imfs.c \ src/blkdev-ioctl.c \ src/blkdev-ops.c \ src/diskdevs.c \ diff --git a/cpukit/libblock/include/rtems/blkdev.h b/cpukit/libblock/include/rtems/blkdev.h index 70259d6c43..c51238084b 100644 --- a/cpukit/libblock/include/rtems/blkdev.h +++ b/cpukit/libblock/include/rtems/blkdev.h @@ -307,6 +307,56 @@ rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp); */ extern const rtems_driver_address_table rtems_blkdev_generic_ops; +/** + * @brief Creates a block device. + * + * @param[in] device The path for the new block device. + * @param[in] block_size The block size. Must be positive. + * @param[in] block_count The block count. Must be positive. + * @param[in] handler The block device IO control handler. Must not be @c NULL. + * @param[in] driver_data The block device driver data. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_NUMBER Block size or block count is not positive. + * @retval RTEMS_NO_MEMORY Not enough memory. + * @retval RTEMS_UNSATISFIED Cannot create generic device node. + */ +rtems_status_code rtems_blkdev_create( + const char *device, + uint32_t block_size, + rtems_blkdev_bnum block_count, + rtems_block_device_ioctl handler, + void *driver_data +); + +/** + * @brief Creates a partition within a block device. + * + * A partition manages a subset of consecutive blocks contained in a block + * device. The blocks must be within the range of blocks managed by the + * associated block device. The media block size, block size, and IO control + * handler are inherited by the block device. + * + * @param[in] partition The path for the new partition device. + * @param[in] device The block device path. + * @param[in] block_begin The block begin of the partition. + * @param[in] block_count The block count of the partition. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Block device node does not exist. + * @retval RTEMS_INVALID_NODE File system node is not a block device. + * @retval RTEMS_NOT_IMPLEMENTED Block device implementation is incomplete. + * @retval RTEMS_INVALID_NUMBER Block begin or block count is invalid. + * @retval RTEMS_NO_MEMORY Not enough memory. + * @retval RTEMS_UNSATISFIED Cannot create generic device node. + */ +rtems_status_code rtems_blkdev_create_partition( + const char *partition, + const char *device, + rtems_blkdev_bnum block_begin, + rtems_blkdev_bnum block_count +); + /** @} */ #ifdef __cplusplus diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c new file mode 100644 index 0000000000..080ca2155e --- /dev/null +++ b/cpukit/libblock/src/blkdev-imfs.c @@ -0,0 +1,380 @@ +/* + * 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 <sys/stat.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> + +#include <rtems/blkdev.h> +#include <rtems/bdbuf.h> +#include <rtems/imfs.h> + +typedef struct { + rtems_disk_device dd; + int fd; +} rtems_blkdev_imfs_context; + +static ssize_t rtems_blkdev_imfs_read( + rtems_libio_t *iop, + void *buffer, + size_t count +) +{ + int rv; + const rtems_blkdev_imfs_context *ctx = IMFS_generic_get_context_by_iop(iop); + const rtems_disk_device *dd = &ctx->dd; + ssize_t remaining = (ssize_t) count; + off_t offset = iop->offset; + ssize_t block_size = (ssize_t) rtems_disk_get_block_size(dd); + rtems_blkdev_bnum block = (rtems_blkdev_bnum) (offset / block_size); + ssize_t block_offset = (ssize_t) (offset % block_size); + char *dst = buffer; + + while (remaining > 0) { + rtems_bdbuf_buffer *bd; + rtems_status_code sc = rtems_bdbuf_read(dd, block, &bd); + + if (sc == RTEMS_SUCCESSFUL) { + ssize_t copy = block_size - block_offset; + + if (copy > remaining) { + copy = remaining; + } + + memcpy(dst, (char *) bd->buffer + block_offset, (size_t) copy); + + sc = rtems_bdbuf_release(bd); + if (sc == RTEMS_SUCCESSFUL) { + block_offset = 0; + remaining -= copy; + dst += copy; + ++block; + } else { + remaining = -1; + } + } else { + remaining = -1; + } + } + + if (remaining >= 0) { + rv = (ssize_t) count; + } else { + errno = EIO; + rv = -1; + } + + return rv; +} + +static ssize_t rtems_blkdev_imfs_write( + rtems_libio_t *iop, + const void *buffer, + size_t count +) +{ + int rv; + const rtems_blkdev_imfs_context *ctx = IMFS_generic_get_context_by_iop(iop); + const rtems_disk_device *dd = &ctx->dd; + ssize_t remaining = (ssize_t) count; + off_t offset = iop->offset; + ssize_t block_size = (ssize_t) rtems_disk_get_block_size(dd); + rtems_blkdev_bnum block = (rtems_blkdev_bnum) (offset / block_size); + ssize_t block_offset = (ssize_t) (offset % block_size); + const char *src = buffer; + + while (remaining > 0) { + rtems_status_code sc; + rtems_bdbuf_buffer *bd; + + if (block_offset == 0 && remaining >= block_size) { + sc = rtems_bdbuf_get(dd, block, &bd); + } else { + sc = rtems_bdbuf_read(dd, block, &bd); + } + + if (sc == RTEMS_SUCCESSFUL) { + ssize_t copy = block_size - block_offset; + + if (copy > remaining) { + copy = remaining; + } + + memcpy((char *) bd->buffer + block_offset, src, (size_t) copy); + + sc = rtems_bdbuf_release_modified(bd); + if (sc == RTEMS_SUCCESSFUL) { + block_offset = 0; + remaining -= copy; + src += copy; + ++block; + } else { + remaining = -1; + } + } else { + remaining = -1; + } + } + + if (remaining >= 0) { + rv = (ssize_t) count; + } else { + errno = EIO; + rv = -1; + } + + return rv; +} + +static int rtems_blkdev_imfs_ioctl( + rtems_libio_t *iop, + uint32_t request, + void *buffer +) +{ + int rv = 0; + + if (request != RTEMS_BLKIO_REQUEST) { + rtems_blkdev_imfs_context *ctx = IMFS_generic_get_context_by_iop(iop); + rtems_disk_device *dd = &ctx->dd; + + rv = (*dd->ioctl)(dd, request, buffer); + } else { + /* + * It is not allowed to directly access the driver circumventing the cache. + */ + errno = EINVAL; + rv = -1; + } + + return rv; +} + +static int rtems_blkdev_imfs_fstat( + const rtems_filesystem_location_info_t *loc, + struct stat *buf +) +{ + const rtems_blkdev_imfs_context *ctx = + IMFS_generic_get_context_by_location(loc); + const rtems_disk_device *dd = &ctx->dd; + + buf->st_rdev = rtems_disk_get_device_identifier(dd); + buf->st_blksize = rtems_disk_get_block_size(dd); + buf->st_blocks = rtems_disk_get_block_count(dd); + + return IMFS_stat(loc, buf); +} + +static int rtems_blkdev_imfs_fsync_or_fdatasync( + rtems_libio_t *iop +) +{ + int rv = 0; + const rtems_blkdev_imfs_context *ctx = IMFS_generic_get_context_by_iop(iop); + const rtems_disk_device *dd = &ctx->dd; + rtems_status_code sc = rtems_bdbuf_syncdev(dd); + + if (sc != RTEMS_SUCCESSFUL) { + errno = EIO; + rv = -1; + } + + return rv; +} + +static const rtems_filesystem_file_handlers_r rtems_blkdev_imfs_node = { + .open_h = rtems_filesystem_default_open, + .close_h = rtems_filesystem_default_close, + .read_h = rtems_blkdev_imfs_read, + .write_h = rtems_blkdev_imfs_write, + .ioctl_h = rtems_blkdev_imfs_ioctl, + .lseek_h = rtems_filesystem_default_lseek_success, + .fstat_h = rtems_blkdev_imfs_fstat, + .ftruncate_h = rtems_filesystem_default_ftruncate, + .fsync_h = rtems_blkdev_imfs_fsync_or_fdatasync, + .fdatasync_h = rtems_blkdev_imfs_fsync_or_fdatasync, + .fcntl_h = rtems_filesystem_default_fcntl +}; + +static IMFS_jnode_t *rtems_blkdev_imfs_initialize( + IMFS_jnode_t *node, + const IMFS_types_union *info +) +{ + rtems_blkdev_imfs_context *ctx; + rtems_disk_device *dd; + + node = IMFS_node_initialize_generic(node, info); + + ctx = IMFS_generic_get_context_by_node(node); + dd = &ctx->dd; + dd->dev = IMFS_generic_get_device_identifier_by_node(node); + + return node; +} + +static IMFS_jnode_t *rtems_blkdev_imfs_destroy(IMFS_jnode_t *node) +{ + rtems_blkdev_imfs_context *ctx = IMFS_generic_get_context_by_node(node); + rtems_disk_device *dd = &ctx->dd; + + rtems_bdbuf_syncdev(dd); + rtems_bdbuf_purge_dev(dd); + + if (ctx->fd >= 0) { + close(ctx->fd); + } else { + (*dd->ioctl)(dd, RTEMS_BLKIO_DELETED, NULL); + } + + free(ctx); + + return node; +} + +static const IMFS_node_control rtems_blkdev_imfs_control = { + .imfs_type = IMFS_GENERIC, + .handlers = &rtems_blkdev_imfs_node, + .node_initialize = rtems_blkdev_imfs_initialize, + .node_remove = IMFS_node_remove_default, + .node_destroy = rtems_blkdev_imfs_destroy +}; + +rtems_status_code rtems_blkdev_create( + const char *device, + uint32_t block_size, + rtems_blkdev_bnum block_count, + rtems_block_device_ioctl handler, + void *driver_data +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + if (block_size > 0 && block_count > 0) { + rtems_blkdev_imfs_context *ctx = calloc(1, sizeof(*ctx)); + + if (ctx != NULL) { + rtems_disk_device *dd = &ctx->dd; + int rv; + + ctx->fd = -1; + + dd->phys_dev = dd; + dd->size = block_count; + dd->media_block_size = block_size; + dd->block_size = block_size; + dd->ioctl = handler; + dd->driver_data = driver_data; + + if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) != 0) { + dd->capabilities = 0; + } + + 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; + } + } else { + sc = RTEMS_INVALID_NUMBER; + } + + return sc; +} + +rtems_status_code rtems_blkdev_create_partition( + const char *partition, + const char *device, + rtems_blkdev_bnum block_begin, + rtems_blkdev_bnum block_count +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + int fd = open(device, O_RDWR); + + if (fd >= 0) { + int rv; + struct stat st; + + rv = fstat(fd, &st); + if (rv == 0 && S_ISBLK(st.st_mode)) { + rtems_disk_device *dd; + + rv = ioctl(fd, RTEMS_BLKIO_GETDISKDEV, &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)); + + if (ctx != NULL) { + memcpy(&ctx->dd, dd, sizeof(ctx->dd)); + + ctx->dd.start = block_begin; + ctx->dd.size = block_count; + ctx->fd = fd; + + rv = IMFS_make_generic_node( + partition, + 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; + } + } else { + sc = RTEMS_INVALID_NUMBER; + } + } else { + sc = RTEMS_NOT_IMPLEMENTED; + } + } else { + sc = RTEMS_INVALID_NODE; + } + + if (sc != RTEMS_SUCCESSFUL) { + close(fd); + } + } else { + sc = RTEMS_INVALID_ID; + } + + return sc; +} diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am index a3990325ec..0e30a51032 100644 --- a/testsuites/libtests/Makefile.am +++ b/testsuites/libtests/Makefile.am @@ -13,7 +13,7 @@ SUBDIRS += bspcmdline01 cpuuse devfs01 devfs02 devfs03 devfs04 \ termios termios01 termios02 termios03 termios04 termios05 \ termios06 termios07 termios08 \ rtems++ tztest block01 block02 block03 block04 block05 block06 block07 \ - block08 block09 block10 stringto01 \ + block08 block09 block10 block11 stringto01 \ tar01 tar02 tar03 \ math mathf mathl complex \ mouse01 diff --git a/testsuites/libtests/block11/Makefile.am b/testsuites/libtests/block11/Makefile.am new file mode 100644 index 0000000000..dee51b6584 --- /dev/null +++ b/testsuites/libtests/block11/Makefile.am @@ -0,0 +1,25 @@ +## +## $Id$ +## + + +rtems_tests_PROGRAMS = block11 +block11_SOURCES = init.c + +dist_rtems_tests_DATA = block11.scn block11.doc + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../automake/compile.am +include $(top_srcdir)/../automake/leaf.am + + +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(block11_OBJECTS) +LINK_LIBS = $(block11_LDLIBS) + +block11$(EXEEXT): $(block11_OBJECTS) $(block11_DEPENDENCIES) + @rm -f block11$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/libtests/block11/block11.doc b/testsuites/libtests/block11/block11.doc new file mode 100644 index 0000000000..e52b2440a1 --- /dev/null +++ b/testsuites/libtests/block11/block11.doc @@ -0,0 +1,12 @@ +This file describes the directives and concepts tested by this test set. + +test set name: block11 + +directives: + + rtems_blkdev_create + rtems_blkdev_create_partition + +concepts: + + TBD diff --git a/testsuites/libtests/block11/block11.scn b/testsuites/libtests/block11/block11.scn new file mode 100644 index 0000000000..fff48c0d56 --- /dev/null +++ b/testsuites/libtests/block11/block11.scn @@ -0,0 +1,2 @@ +*** TEST BLOCK 11 *** +*** END OF TEST BLOCK 11 *** diff --git a/testsuites/libtests/block11/init.c b/testsuites/libtests/block11/init.c new file mode 100644 index 0000000000..31273313b5 --- /dev/null +++ b/testsuites/libtests/block11/init.c @@ -0,0 +1,402 @@ +/** + * @file + * + * @ingroup tests + * + * @brief Block device tests. + */ + +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include "tmacros.h" + +#include <sys/stat.h> +#include <stdio.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +#include <rtems.h> +#include <rtems/ramdisk.h> +#include <rtems/diskdevs.h> +#include <rtems/malloc.h> + +#define ASSERT_SC(sc) rtems_test_assert((sc) == RTEMS_SUCCESSFUL) + +#define CHUNK_MAX 32U + +#define AREA_SIZE ((CHUNK_MAX * (CHUNK_MAX + 1U)) / 2U) + +#define BLOCK_SIZE 4U + +#define BLOCK_COUNT (AREA_SIZE / BLOCK_SIZE) + +static const char rda [] = "/dev/rda"; + +static const char rda1 [] = "/dev/rda1"; + +static const char not_exist [] = "not_exist"; + +static const char not_blkdev [] = "not_blkdev"; + +static const char invalid_blkdev [] = "invalid_blkdev"; + +static long area_a [AREA_SIZE / sizeof(long)]; + +static long area_b [AREA_SIZE / sizeof(long)]; + +static void area_init(long *area) +{ + size_t i; + size_t n = AREA_SIZE / sizeof(long); + + for (i = 0; i < n; ++i) { + area [i] = mrand48(); + } +} + +static void area_read(int fd, long *area) +{ + size_t i; + size_t n = CHUNK_MAX; + char *dst = (char *) area; + + for (i = 0; i <= n; ++i) { + ssize_t m = read(fd, dst, i); + rtems_test_assert(m == (ssize_t) i); + dst += i; + } +} + +static void area_write(int fd, const long *area) +{ + size_t i; + size_t n = CHUNK_MAX; + const char *src = (const char *) area; + + for (i = 0; i <= n; ++i) { + ssize_t m = write(fd, src, i); + rtems_test_assert(m == (ssize_t) i); + src += i; + } +} + +static void area_compare(const long *area_a, const long *area_b, bool equal) +{ + bool actual_equal = memcmp(area_a, area_b, AREA_SIZE) == 0; + rtems_test_assert(actual_equal == equal); +} + +static void test_blkdev_imfs_read_and_write(void) +{ + rtems_status_code sc; + int rv; + ramdisk *rd; + int fd; + off_t off; + + rd = ramdisk_allocate(area_a, BLOCK_SIZE, BLOCK_COUNT, false); + rtems_test_assert(rd != NULL); + + ramdisk_enable_free_at_delete_request(rd); + + sc = rtems_blkdev_create( + rda, + BLOCK_SIZE, + BLOCK_COUNT, + ramdisk_ioctl, + rd + ); + ASSERT_SC(sc); + + fd = open(rda, O_RDWR); + rtems_test_assert(fd >= 0); + + area_init(area_a); + area_read(fd, area_b); + area_compare(area_a, area_b, true); + + off = lseek(fd, 0, SEEK_SET); + rtems_test_assert(off == 0); + + area_init(area_b); + area_write(fd, area_b); + area_compare(area_a, area_b, false); + + rv = close(fd); + rtems_test_assert(rv == 0); + + rv = unlink(rda); + rtems_test_assert(rv == 0); + + area_compare(area_a, area_b, true); +} + +static void test_blkdev_imfs_parameters(void) +{ + rtems_status_code sc; + int rv; + ramdisk *rd; + int fd; + const rtems_disk_device *dd; + struct stat st; + + rd = ramdisk_allocate(NULL, BLOCK_SIZE, BLOCK_COUNT, false); + rtems_test_assert(rd != NULL); + + ramdisk_enable_free_at_delete_request(rd); + + sc = rtems_blkdev_create( + rda, + BLOCK_SIZE, + BLOCK_COUNT, + ramdisk_ioctl, + rd + ); + ASSERT_SC(sc); + + sc = rtems_blkdev_create_partition( + rda1, + rda, + 1, + BLOCK_COUNT - 1 + ); + ASSERT_SC(sc); + + fd = open(rda, O_RDWR); + rtems_test_assert(fd >= 0); + + rv = fstat(fd, &st); + rtems_test_assert(rv == 0); + + rv = rtems_disk_fd_get_disk_device(fd, &dd); + rtems_test_assert(rv == 0); + + rtems_test_assert(rtems_disk_get_driver_data(dd) == rd); + rtems_test_assert(rtems_disk_get_device_identifier(dd) == st.st_rdev); + rtems_test_assert(rtems_disk_get_media_block_size(dd) == BLOCK_SIZE); + rtems_test_assert(rtems_disk_get_block_size(dd) == BLOCK_SIZE); + rtems_test_assert(rtems_disk_get_block_begin(dd) == 0); + rtems_test_assert(rtems_disk_get_block_count(dd) == BLOCK_COUNT); + + rv = close(fd); + rtems_test_assert(rv == 0); + + fd = open(rda1, O_RDWR); + rtems_test_assert(fd >= 0); + + rv = fstat(fd, &st); + rtems_test_assert(rv == 0); + + rv = rtems_disk_fd_get_disk_device(fd, &dd); + rtems_test_assert(rv == 0); + + rtems_test_assert(rtems_disk_get_driver_data(dd) == rd); + rtems_test_assert(rtems_disk_get_device_identifier(dd) == st.st_rdev); + rtems_test_assert(rtems_disk_get_media_block_size(dd) == BLOCK_SIZE); + rtems_test_assert(rtems_disk_get_block_size(dd) == BLOCK_SIZE); + rtems_test_assert(rtems_disk_get_block_begin(dd) == 1); + rtems_test_assert(rtems_disk_get_block_count(dd) == BLOCK_COUNT - 1); + + rv = close(fd); + rtems_test_assert(rv == 0); + + rv = unlink(rda1); + rtems_test_assert(rv == 0); + + rv = unlink(rda); + rtems_test_assert(rv == 0); +} + +static void test_blkdev_imfs_errors(void) +{ + rtems_status_code sc; + int rv; + ramdisk *rd; + void *opaque; + + rd = ramdisk_allocate(NULL, BLOCK_SIZE, BLOCK_COUNT, false); + rtems_test_assert(rd != NULL); + + ramdisk_enable_free_at_delete_request(rd); + + sc = rtems_blkdev_create( + rda, + 0, + BLOCK_COUNT, + ramdisk_ioctl, + rd + ); + rtems_test_assert(sc == RTEMS_INVALID_NUMBER); + + sc = rtems_blkdev_create( + rda, + BLOCK_SIZE, + 0, + ramdisk_ioctl, + rd + ); + rtems_test_assert(sc == RTEMS_INVALID_NUMBER); + + opaque = rtems_heap_greedy_allocate(0); + sc = rtems_blkdev_create( + rda, + BLOCK_SIZE, + BLOCK_COUNT, + ramdisk_ioctl, + rd + ); + rtems_test_assert(sc == RTEMS_NO_MEMORY); + rtems_heap_greedy_free(opaque); + + opaque = rtems_heap_greedy_allocate(sizeof(rtems_disk_device) + sizeof(int)); + sc = rtems_blkdev_create( + rda, + BLOCK_SIZE, + BLOCK_COUNT, + ramdisk_ioctl, + rd + ); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + rtems_heap_greedy_free(opaque); + + sc = rtems_blkdev_create( + rda, + BLOCK_SIZE, + BLOCK_COUNT, + ramdisk_ioctl, + rd + ); + ASSERT_SC(sc); + + sc = rtems_blkdev_create_partition( + rda1, + not_exist, + 0, + BLOCK_COUNT + ); + rtems_test_assert(sc == RTEMS_INVALID_ID); + + rv = mknod(not_blkdev, S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO, 0); + rtems_test_assert(rv == 0); + + sc = rtems_blkdev_create_partition( + rda1, + not_blkdev, + 0, + BLOCK_COUNT + ); + rtems_test_assert(sc == RTEMS_INVALID_NODE); + + rv = mknod(invalid_blkdev, S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO, 0); + rtems_test_assert(rv == 0); + + sc = rtems_blkdev_create_partition( + rda1, + invalid_blkdev, + 0, + BLOCK_COUNT + ); + rtems_test_assert(sc == RTEMS_NOT_IMPLEMENTED); + + sc = rtems_blkdev_create_partition( + rda1, + rda, + 0, + 0 + ); + rtems_test_assert(sc == RTEMS_INVALID_NUMBER); + + sc = rtems_blkdev_create_partition( + rda1, + rda, + BLOCK_COUNT, + BLOCK_COUNT + ); + rtems_test_assert(sc == RTEMS_INVALID_NUMBER); + + sc = rtems_blkdev_create_partition( + rda1, + rda, + 0, + BLOCK_COUNT + 1 + ); + rtems_test_assert(sc == RTEMS_INVALID_NUMBER); + + opaque = rtems_heap_greedy_allocate(0); + sc = rtems_blkdev_create_partition( + rda1, + rda, + 0, + BLOCK_COUNT + ); + rtems_test_assert(sc == RTEMS_NO_MEMORY); + rtems_heap_greedy_free(opaque); + + opaque = rtems_heap_greedy_allocate(sizeof(rtems_disk_device) + sizeof(int)); + sc = rtems_blkdev_create_partition( + rda1, + rda, + 0, + BLOCK_COUNT + ); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + rtems_heap_greedy_free(opaque); + + rv = unlink(rda); + rtems_test_assert(rv == 0); +} + +static rtems_task Init(rtems_task_argument argument) +{ + rtems_status_code sc; + + puts("\n\n*** TEST BLOCK 11 ***"); + + sc = rtems_disk_io_initialize(); + ASSERT_SC(sc); + + test_blkdev_imfs_read_and_write(); + test_blkdev_imfs_parameters(); + test_blkdev_imfs_errors(); + + sc = rtems_disk_io_done(); + ASSERT_SC(sc); + + puts("*** END OF TEST BLOCK 11 ***"); + + exit(0); +} + +#define CONFIGURE_INIT + +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK + +#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM +#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 5 + +#define CONFIGURE_MAXIMUM_TASKS 2 +#define CONFIGURE_MAXIMUM_DRIVERS 2 +#define CONFIGURE_EXTRA_TASK_STACKS (8 * 1024) + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#include <rtems/confdefs.h> diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac index 675f3430b1..b634ff8246 100644 --- a/testsuites/libtests/configure.ac +++ b/testsuites/libtests/configure.ac @@ -53,6 +53,7 @@ block07/Makefile block08/Makefile block09/Makefile block10/Makefile +block11/Makefile bspcmdline01/Makefile cpuuse/Makefile devfs01/Makefile |