diff --git a/ChangeLog b/ChangeLog index 280e7bb4a79c89b806181d134e7f612b3a2755c6..d3a5f291cb0f2f3912433ce58acc97e8c0b43bb3 100755 --- a/ChangeLog +++ b/ChangeLog @@ -11140,8 +11140,3 @@ of the block driver (2015-11-21). * libc/stdio/lib_freopen.c and include/stdio.h: Add support for freopen() (2015-11-22). - * drivers/mtd/smart.c: Add option to specify logical sector size - during low level format plus adds some run-time geometry tests. From - Ken Petit (2015-11-22). - * fs/smartfs: Remove the 'mksmartfs()' code from the kernel 'fs' - directory and build. From Ken Petit (2015-11-22). diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c index 08bae53c0d697507725c83f0ae749873286e1566..a07bd220971b85d8d8c04549202925b91dcadfa6 100644 --- a/drivers/mtd/smart.c +++ b/drivers/mtd/smart.c @@ -994,10 +994,6 @@ static int smart_setsectorsize(FAR struct smart_struct_s *dev, uint16_t size) { dev->availSectPerBlk = 255; } - else if (dev->sectorsPerBlk == 0) - { - return -EINVAL; - } else { dev->availSectPerBlk = dev->sectorsPerBlk; @@ -1446,7 +1442,7 @@ static uint16_t smart_cache_lookup(FAR struct smart_struct_s *dev, uint16_t logi /* Calculate the read address for this sector */ readaddress = block * dev->erasesize + - sector * dev->sectorsize; + sector * CONFIG_MTD_SMART_SECTOR_SIZE; /* Read the header for this sector */ @@ -1822,10 +1818,6 @@ static int smart_scan(FAR struct smart_struct_s *dev) offset >>= 1; if (offset < 256 && sectorsize == 0xFFFF) { - /* No valid sectors found on device. Default the - * sector size to the CONFIG value - */ - sectorsize = CONFIG_MTD_SMART_SECTOR_SIZE; } } @@ -2301,17 +2293,6 @@ static int smart_scan(FAR struct smart_struct_s *dev) fdbg(" Erase count: %10d\n", dev->neraseblocks); fdbg(" Sect/block: %10d\n", dev->sectorsPerBlk); fdbg(" MTD Blk/Sect: %10d\n", dev->mtdBlksPerSector); - - /* Validate the geometry */ - - if (dev->mtdBlksPerSector == 0 || dev->sectorsPerBlk == 0 || - dev->sectorsPerBlk == 0 || dev->sectorsize == 0) - { - fdbg("Invalid Geometry!\n"); - ret = -EINVAL; - goto err_out; - } - #ifdef CONFIG_MTD_SMART_ALLOC_DEBUG fdbg(" Allocations:\n"); for (sector = 0; sector < SMART_MAX_ALLOCS; sector++) @@ -2800,11 +2781,6 @@ static crc_t smart_calc_sector_crc(FAR struct smart_struct_s *dev) * involves erasing the device and writing a valid sector * zero (logical) with proper format signature. * - * Input Parameters: - * - * arg: Upper 16 bits contains the sector size - * Lower 16 bits contains the number of root dir entries - * ****************************************************************************/ #ifdef CONFIG_FS_WRITABLE @@ -2815,29 +2791,18 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a int x; int ret; uint8_t sectsize, prerelease; - uint16_t sectorsize; fvdbg("Entry\n"); - /* Get the sector size from the provided arg */ - - sectorsize = arg >> 16; - if (sectorsize == 0) - { - sectorsize = CONFIG_MTD_SMART_SECTOR_SIZE; - } - - /* Set the sector size for the device */ - - smart_setsectorsize(dev, sectorsize); + smart_setsectorsize(dev, CONFIG_MTD_SMART_SECTOR_SIZE); /* Check for invalid format */ - if (dev->erasesize == 0 || dev->sectorsPerBlk == 0) + if (dev->erasesize == 0) { dev->erasesize = dev->geo.erasesize; - dbg("ERROR: Invalid geometery ... Sectors per erase block must be 1-256\n"); + dbg("ERROR: Invalid geometery ... Sectors per erase block must be 256 or less\n"); dbg(" Erase block size = %d\n", dev->erasesize); dbg(" Sector size = %d\n", dev->sectorsize); dbg(" Sectors/erase block = %d\n", dev->erasesize / dev->sectorsize); @@ -2863,22 +2828,18 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a /* CRC enabled. Using an 8-bit sequence number */ sectorheader->seq = 0; - #else /* CRC not enabled. Using a 16-bit sequence number */ *((FAR uint16_t *) §orheader->seq) = 0; - #endif #else /* SMART_STATUS_VERSION == 1 */ - sectorheader->seq = 0; - #endif /* SMART_STATUS_VERSION == 1 */ /* Set the sector size of this sector */ - sectsize = (sectorsize >> 9) << 2; + sectsize = (CONFIG_MTD_SMART_SECTOR_SIZE >> 9) << 2; /* Set the sector logical sector to zero and setup the header status */ @@ -2912,7 +2873,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a /* Record the number of root directory entries we have */ - dev->rwbuffer[SMART_FMT_ROOTDIRS_POS] = (uint8_t) (arg & 0xFF); + dev->rwbuffer[SMART_FMT_ROOTDIRS_POS] = (uint8_t) arg; #ifdef CONFIG_SMART_CRC_8 sectorheader->crc8 = smart_calc_sector_crc(dev); @@ -2939,7 +2900,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a /* Now initialize our internal control variables */ - ret = smart_setsectorsize(dev, sectorsize); + ret = smart_setsectorsize(dev, CONFIG_MTD_SMART_SECTOR_SIZE); if (ret != OK) { return ret; diff --git a/fs/smartfs/Make.defs b/fs/smartfs/Make.defs index 3be1487cde4a9f4b8665d431910822398b91557b..97bf50fbb910737bfba1f4e80898ecf4cc30ebbc 100644 --- a/fs/smartfs/Make.defs +++ b/fs/smartfs/Make.defs @@ -40,6 +40,11 @@ ifeq ($(CONFIG_FS_SMARTFS),y) ASRCS += CSRCS += smartfs_smart.c smartfs_utils.c smartfs_procfs.c +# Files required for mksmartfs utility function + +ASRCS += +CSRCS += smartfs_mksmartfs.c + # Include SMART build support DEPPATH += --dep-path smartfs diff --git a/fs/smartfs/smartfs.h b/fs/smartfs/smartfs.h index 189d521d72edbfbb8250e95ebbe7cdba64d88cac..36ed65b41b872602825ac6feca15a550193af287 100644 --- a/fs/smartfs/smartfs.h +++ b/fs/smartfs/smartfs.h @@ -188,6 +188,15 @@ #define FS_BOPS(f) (f)->fs_blkdriver->u.i_bops #define FS_IOCTL(f,c,a) (FS_BOPS(f)->ioctl ? FS_BOPS(f)->ioctl((f)->fs_blkdriver,c,a) : (-ENOSYS)) +/* The logical sector number of the root directory. */ + +#define SMARTFS_ROOT_DIR_SECTOR 3 + +/* Defines the sector types */ + +#define SMARTFS_SECTOR_TYPE_DIR 1 +#define SMARTFS_SECTOR_TYPE_FILE 2 + #ifndef CONFIG_SMARTFS_DIRDEPTH # define CONFIG_SMARTFS_DIRDEPTH 8 #endif diff --git a/fs/smartfs/smartfs_mksmartfs.c b/fs/smartfs/smartfs_mksmartfs.c new file mode 100644 index 0000000000000000000000000000000000000000..076915e169c0792d96961a54ceeb5aaa66eeaaee --- /dev/null +++ b/fs/smartfs/smartfs_mksmartfs.c @@ -0,0 +1,191 @@ +/**************************************************************************** + * fs/smartfs/smartfs_mksmartfs.c + * + * Copyright (C) 2013 Ken Pettit. All rights reserved. + * Author: Ken Pettit <pettitkd@gmail.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <debug.h> +#include <errno.h> + +#include <nuttx/kmalloc.h> +#include <nuttx/fs/fs.h> +#include <nuttx/fs/mksmartfs.h> +#include <nuttx/fs/ioctl.h> +#include <nuttx/fs/smart.h> + +#include "smartfs.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mksmartfs + * + * Description: + * Make a SMART Flash file system image on the specified block device + * + * Inputs: + * pathname - the full path to a registered block driver + * nrootdirs - Number of root directory entries to create. + * + * Return: + * Zero (OK) on success; -1 (ERROR) on failure with errno set appropriately: + * + * EINVAL - NULL block driver string, bad number of FATS in 'fmt', bad FAT + * size in 'fmt', bad cluster size in 'fmt' + * ENOENT - 'pathname' does not refer to anything in the filesystem. + * ENOTBLK - 'pathname' does not refer to a block driver + * EACCES - block driver does not support wrie or geometry methods + * + * Assumptions: + * - The caller must assure that the block driver is not mounted and not in + * use when this function is called. The result of formatting a mounted + * device is indeterminate (but likely not good). + * + ****************************************************************************/ + +#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS +int mksmartfs(FAR const char *pathname, uint8_t nrootdirs) +#else +int mksmartfs(FAR const char *pathname) +#endif +{ + FAR struct inode *inode; + struct smart_format_s fmt; + int ret; + int x; + uint8_t type; + struct smart_read_write_s request; + + /* Find the inode of the block driver indentified by 'source' */ + + ret = open_blockdriver(pathname, 0, &inode); + if (ret < 0) + { + fdbg("Failed to open %s\n", pathname); + goto errout; + } + + /* Make sure that the inode supports the write and geometry methods at a minimum */ + + if (!inode->u.i_bops->write || !inode->u.i_bops->geometry) + { + fdbg("%s does not support write or geometry methods\n", pathname); + ret = -EACCES; + goto errout_with_driver; + } + + /* Validate the block device is a SMART device */ + + /* Perform a low-level SMART format */ + +#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS + ret = inode->u.i_bops->ioctl(inode, BIOC_LLFORMAT, nrootdirs); +#else + ret = inode->u.i_bops->ioctl(inode, BIOC_LLFORMAT, 0); +#endif + if (ret != OK) + { + fdbg("Error creating low-level format: %d\n", ret); + goto errout_with_driver; + } + + /* Get the format information so we know how big the sectors are */ + + ret = inode->u.i_bops->ioctl(inode, BIOC_GETFORMAT, (unsigned long) &fmt); + + /* Now Write the filesystem to media. Loop for each root dir entry and + * allocate the reserved Root Dir Enty, then write a blank root dir for it. + */ + + type = SMARTFS_SECTOR_TYPE_DIR; + request.offset = 0; + request.count = 1; + request.buffer = &type; + x = 0; +#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS + for (; x < nrootdirs; x++) +#endif + { + ret = inode->u.i_bops->ioctl(inode, BIOC_ALLOCSECT, SMARTFS_ROOT_DIR_SECTOR + x); + if (ret != SMARTFS_ROOT_DIR_SECTOR + x) + { + ret = -EIO; + goto errout_with_driver; + } + + /* Mark this block as a directory entry */ + + request.logsector = SMARTFS_ROOT_DIR_SECTOR + x; + + /* Issue a write to the sector, single byte */ + + ret = inode->u.i_bops->ioctl(inode, BIOC_WRITESECT, (unsigned long) &request); + if (ret != 0) + { + ret = -EIO; + goto errout_with_driver; + } + } + +errout_with_driver: + /* Close the driver */ + + (void)close_blockdriver(inode); + +errout: + /* Release all allocated memory */ + + /* Return any reported errors */ + + if (ret < 0) + { + set_errno(-ret); + return ERROR; + } + + return OK; +} diff --git a/include/nuttx/fs/mksmartfs.h b/include/nuttx/fs/mksmartfs.h new file mode 100644 index 0000000000000000000000000000000000000000..f907ba305abfd1ba7b7ffbe91ff168335b44f02a --- /dev/null +++ b/include/nuttx/fs/mksmartfs.h @@ -0,0 +1,110 @@ +/**************************************************************************** + * include/nuttx/fs/mksmartfs.h + * + * Copyright (C) 2013, 2015 Ken Pettit. All rights reserved. + * Author: Ken Pettit <pettitkd@gmail.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SMART_MKSMARTFS_H +#define __INCLUDE_NUTTX_SMART_MKSMARTFS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <stdint.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: mksmartfs + * + * Description: + * Make a SMART (Sector Mapped Allocation for Really Tiny) Flash file + * system image on the specified block device (must be a SMART device). + * + * Inputs: + * pathname - the full path to a registered block driver + * nrootdirs - the number of Root Directory entries to support + * on this device (supports multiple mount points). + * + * Return: + * Zero (OK) on success; -1 (ERROR) on failure with errno set appropriately: + * + * EINVAL - NULL block driver string + * ENOENT - 'pathname' does not refer to anything in the filesystem. + * ENOTBLK - 'pathname' does not refer to a block driver + * EACCESS - block driver does not support write or geometry methods or + * is not a SMART device + * + * Assumptions: + * - The caller must assure that the block driver is not mounted and not in + * use when this function is called. The result of formatting a mounted + * device is indeterminate (but likely not good). + * + ****************************************************************************/ + +#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS +int mksmartfs(FAR const char *pathname, uint8_t nrootdirs); +#else +int mksmartfs(FAR const char *pathname); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_NUTTX_SMART_MKSMARTFS_H */ diff --git a/include/nuttx/fs/smart.h b/include/nuttx/fs/smart.h index f3bff10cb679663cba39ef49e62ce46498bf888e..2621dd77f626d79d077668ff59961aa42a72ad2a 100644 --- a/include/nuttx/fs/smart.h +++ b/include/nuttx/fs/smart.h @@ -55,15 +55,6 @@ #define SMART_FMT_ISFORMATTED 0x01 #define SMART_FMT_HASBYTEWRITE 0x02 -/* The logical sector number of the root directory. */ - -#define SMARTFS_ROOT_DIR_SECTOR 3 - -/* Defines the sector types */ - -#define SMARTFS_SECTOR_TYPE_DIR 1 -#define SMARTFS_SECTOR_TYPE_FILE 2 - /**************************************************************************** * Public Types ****************************************************************************/