static inline void lpc31_initsrc(void)
{
  FAR struct spi_dev_s *spi;
#ifdef CONFIG_DEBUG
  uint32_t capacity;
  int ret;
#endif

  /* Are we already initialized? */

 if (!g_pgsrc.initialized)
   {
      /* No... the initialize now */

      pgllvdbg("Initializing\n");

      /* First get an instance of the SPI device interface */

      spi = up_spiinitialize(CONFIG_EA3131_PAGING_SPIPORT);
      DEBUGASSERT(spi != NULL);

      /* Then bind the SPI interface to the MTD driver */

#ifdef CONFIG_PAGING_M25PX
      g_pgsrc.mtd = m25p_initialize(spi);
#else
      g_pgsrc.mtd = at45db_initialize(spi);
#endif
      DEBUGASSERT(g_pgsrc.mtd != NULL);

      /* Verify that we can use the device */

#ifdef CONFIG_DEBUG
      /* Get the device geometry. (casting to uintptr_t first eliminates
       * complaints on some architectures where the sizeof long is different
       * from the size of a pointer).
       */

      ret = MTD_IOCTL(g_pgsrc.mtd, MTDIOC_GEOMETRY, (unsigned long)&g_pgsrc.geo);
      DEBUGASSERT(ret >= 0);
      capacity = g_pgsrc.geo.erasesize*g_pgsrc.geo.neraseblocks;
      pgllvdbg("capacity: %d\n", capacity);
      DEBUGASSERT(capacity >= (CONFIG_EA3131_PAGING_BINOFFSET + PG_TEXT_VSIZE));
#endif

      /* We are now initialized */

      g_pgsrc.initialized = true;
    }
}
Exemplo n.º 2
0
Arquivo: ftl.c Projeto: a1ien/nuttx
static int ftl_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
{
  struct ftl_struct_s *dev ;
  int ret;

  finfo("Entry\n");
  DEBUGASSERT(inode && inode->i_private);

  /* Only one block driver ioctl command is supported by this driver (and
   * that command is just passed on to the MTD driver in a slightly
   * different form).
   */

  if (cmd == BIOC_XIPBASE)
    {
      /* The argument accompanying the BIOC_XIPBASE should be non-NULL.  If
       * DEBUG is enabled, we will catch it here instead of in the MTD
       * driver.
       */

#ifdef CONFIG_DEBUG_FEATURES
      if (arg == 0)
        {
          ferr("ERROR: BIOC_XIPBASE argument is NULL\n");
          return -EINVAL;
        }
#endif

      /* Just change the BIOC_XIPBASE command to the MTDIOC_XIPBASE command. */

      cmd = MTDIOC_XIPBASE;
    }

  /* No other block driver ioctl commmands are not recognized by this
   * driver.  Other possible MTD driver ioctl commands are passed through
   * to the MTD driver (unchanged).
   */

  dev = (struct ftl_struct_s *)inode->i_private;
  ret = MTD_IOCTL(dev->mtd, cmd, arg);
  if (ret < 0)
    {
      ferr("ERROR: MTD ioctl(%04x) failed: %d\n", cmd, ret);
    }

  return ret;
}
Exemplo n.º 3
0
int mtdconfig_register(FAR struct mtd_dev_s *mtd)
{
  int ret = OK;
  struct mtdconfig_struct_s *dev;
  struct mtd_geometry_s geo;      /* Device geometry */

  dev = (struct mtdconfig_struct_s *)kmm_malloc(sizeof(struct mtdconfig_struct_s));
  if (dev)
    {
      /* Initialize the mtdconfig device structure */

      dev->mtd = mtd;
      sem_init(&dev->exclsem, 0, 1);

      /* Get the device geometry. (casting to uintptr_t first eliminates
       * complaints on some architectures where the sizeof long is different
       * from the size of a pointer).
       */

      ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo));
      if (ret < 0)
        {
          fdbg("MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", ret);
          kmm_free(dev);
          goto errout;
        }

      dev->blocksize = geo.blocksize;
      dev->neraseblocks = geo.neraseblocks;
      dev->erasesize = geo.erasesize;
      dev->nblocks = geo.neraseblocks * geo.erasesize / geo.blocksize;

      (void)register_driver("/dev/config", &mtdconfig_fops, 0666, dev);
    }

errout:
  return ret;
}
int smart_main(int argc, char *argv[])
{
  FAR struct mtd_dev_s *mtd;
  unsigned int i;
  int ret;

  /* Seed the random number generated */

  srand(0x93846);

  /* Create and initialize a RAM MTD device instance */

#ifdef CONFIG_EXAMPLES_SMART_ARCHINIT
  mtd = smart_archinitialize();
#else
  mtd = rammtd_initialize(g_simflash, EXAMPLES_SMART_BUFSIZE);
#endif
  if (!mtd)
    {
      message("ERROR: Failed to create RAM MTD instance\n");
      msgflush();
      exit(1);
    }

  /* Initialize to provide SMART on an MTD interface */

  MTD_IOCTL(mtd, MTDIOC_BULKERASE, 0);
  ret = smart_initialize(1, mtd);
  if (ret < 0)
    {
      message("ERROR: SMART initialization failed: %d\n", -ret);
      msgflush();
      exit(2);
    }

  /* Creaet a SMARTFS filesystem */

  ret = mksmartfs("/dev/smart1");

  /* Mount the file system */

  ret = mount("/dev/smart1", CONFIG_EXAMPLES_SMART_MOUNTPT, "smartfs", 0, NULL);
  if (ret < 0)
    {
      message("ERROR: Failed to mount the SMART volume: %d\n", errno);
      msgflush();
      exit(3);
    }

  /* Set up memory monitoring */

#ifdef CONFIG_CAN_PASS_STRUCTS
  g_mmbefore = mallinfo();
  g_mmprevious = g_mmbefore;
#else
  (void)mallinfo(&g_mmbefore);
  memcpy(&g_mmprevious, &g_mmbefore, sizeof(struct mallinfo));
#endif

  /* Loop a few times ... file the file system with some random, files,
   * delete some files randomly, fill the file system with more random file,
   * delete, etc.  This beats the FLASH very hard!
   */

#if CONFIG_EXAMPLES_SMART_NLOOPS == 0
  for (i = 0; ; i++)
#else
  for (i = 1; i <= CONFIG_EXAMPLES_SMART_NLOOPS; i++)
#endif
    {
      /* Write a files to the SMART file system until either (1) all of the
       * open file structures are utilized or until (2) SMART reports an error
       * (hopefully that the file system is full)
       */

      message("\n=== FILLING %d =============================\n", i);
      ret = smart_fillfs();
      message("Filled file system\n");
      message("  Number of files: %d\n", g_nfiles);
      message("  Number deleted:  %d\n", g_ndeleted);

      /* Directory listing */

      smart_directory();

      /* Verify all files written to FLASH */

      ret = smart_verifyfs();
      if (ret < 0)
        {
          message("ERROR: Failed to verify files\n");
          message("  Number of files: %d\n", g_nfiles);
          message("  Number deleted:  %d\n", g_ndeleted);
        }
      else
        {
#if CONFIG_EXAMPLES_SMART_VERBOSE != 0
          message("Verified!\n");
          message("  Number of files: %d\n", g_nfiles);
          message("  Number deleted:  %d\n", g_ndeleted);
#endif
        }

      /* Delete some files */

      message("\n=== DELETING %d ============================\n", i);
      ret = smart_delfiles();
      if (ret < 0)
        {
          message("ERROR: Failed to delete files\n");
          message("  Number of files: %d\n", g_nfiles);
          message("  Number deleted:  %d\n", g_ndeleted);
        }
      else
        {
          message("Deleted some files\n");
          message("  Number of files: %d\n", g_nfiles);
          message("  Number deleted:  %d\n", g_ndeleted);
        }

      /* Directory listing */

      smart_directory();

      /* Verify all files written to FLASH */

      ret = smart_verifyfs();
      if (ret < 0)
        {
          message("ERROR: Failed to verify files\n");
          message("  Number of files: %d\n", g_nfiles);
          message("  Number deleted:  %d\n", g_ndeleted);
        }
      else
        {
#if CONFIG_EXAMPLES_SMART_VERBOSE != 0
          message("Verified!\n");
          message("  Number of files: %d\n", g_nfiles);
          message("  Number deleted:  %d\n", g_ndeleted);
#endif
        }

      /* Show memory usage */

      smart_loopmemusage();
      msgflush();
    }

  /* Delete all files then show memory usage again */

  smart_delallfiles();
  smart_endmemusage();
  msgflush();
  return 0;
}
Exemplo n.º 5
0
int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose)
{
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_FS)
  struct nxffs_blkinfo_s blkinfo;
  int ret;

  /* Get the volume geometry. (casting to uintptr_t first eliminates
   * complaints on some architectures where the sizeof long is different
   * from the size of a pointer).
   */

  memset(&blkinfo, 0, sizeof(struct nxffs_blkinfo_s));
  ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&blkinfo.geo));
  if (ret < 0)
    {
      fdbg("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret);
      goto errout;
    }

  /* Save the verbose output indication */

  blkinfo.verbose = verbose;

  /* Allocate a buffer to hold one block */

  blkinfo.buffer = (FAR uint8_t *)kmalloc(blkinfo.geo.blocksize);
  if (!blkinfo.buffer)
    {
      fdbg("ERROR: Failed to allocate block cache\n");
      ret = -ENOMEM;
      goto errout;
    }

  /* Now read every block on the device */

  fdbg("NXFFS Dump:\n");
  fdbg(g_hdrformat);

  blkinfo.nblocks = blkinfo.geo.erasesize * blkinfo.geo.neraseblocks / blkinfo.geo.blocksize;
  for (blkinfo.block = 0, blkinfo.offset = 0;
       blkinfo.block < blkinfo.nblocks;
       blkinfo.block++, blkinfo.offset += blkinfo.geo.blocksize)
    {
      /* Read the next block */

      ret = MTD_BREAD(mtd, blkinfo.block, 1, blkinfo.buffer);
      if (ret < 0)
        {
          fdbg("ERROR: Failed to read block %d\n", blkinfo.block);
          goto errout_with_block;
        }

      /* Analyze the block */

      nxffs_analyze(&blkinfo);
    }
  fdbg("%d blocks analyzed\n", blkinfo.nblocks);

errout_with_block:
  kfree(blkinfo.buffer);
errout:
  return ret;

#else
  return -ENOSYS;
#endif
}
Exemplo n.º 6
0
int nxffs_initialize(FAR struct mtd_dev_s *mtd)
{
  FAR struct nxffs_volume_s *volume;
  struct nxffs_blkstats_s stats;
  off_t threshold;
  int ret;

  /* If CONFIG_NXFFS_PREALLOCATED is defined, then this is the single, pre-
   * allocated NXFFS volume instance.
   */

#ifdef CONFIG_NXFFS_PREALLOCATED

  volume = &g_volume;
  memset(volume, 0, sizeof(struct nxffs_volume_s));

#else

  /* Allocate a NXFFS volume structure */

  volume = (FAR struct nxffs_volume_s *)kzalloc(sizeof(struct nxffs_volume_s));
  if (!volume)
    {
      ret = -ENOMEM;
      goto errout;
    }
#endif

  /* Initialize the NXFFS volume structure */

  volume->mtd    = mtd;
  volume->cblock = (off_t)-1;
  sem_init(&volume->exclsem, 0, 1);
  sem_init(&volume->wrsem, 0, 1);

  /* Get the volume geometry. (casting to uintptr_t first eliminates
   * complaints on some architectures where the sizeof long is different
   * from the size of a pointer).
   */

  ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&volume->geo));
  if (ret < 0)
    {
      fdbg("MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret);
      goto errout_with_volume;
    }

  /* Allocate one I/O block buffer to general files system access */

  volume->cache = (FAR uint8_t *)kmalloc(volume->geo.blocksize);
  if (!volume->cache)
    {
      fdbg("Failed to allocate an erase block buffer\n");
      ret = -ENOMEM;
      goto errout_with_volume;
    }

  /* Pre-allocate one, full, in-memory erase block.  This is needed for filesystem
   * packing (but is useful in other places as well). This buffer is not needed
   * often, but is best to have pre-allocated and in-place.
   */

  volume->pack = (FAR uint8_t *)kmalloc(volume->geo.erasesize);
  if (!volume->pack)
    {
      fdbg("Failed to allocate an I/O block buffer\n");
      ret = -ENOMEM;
      goto errout_with_cache;
    }

  /* Get the number of R/W blocks per erase block and the total number o
   * R/W blocks
   */

  volume->blkper  = volume->geo.erasesize / volume->geo.blocksize;
  volume->nblocks = volume->geo.neraseblocks * volume->blkper;
  DEBUGASSERT((off_t)volume->blkper * volume->geo.blocksize == volume->geo.erasesize);

  /* Check if there is a valid NXFFS file system on the flash */

  ret = nxffs_blockstats(volume, &stats);
  if (ret < 0)
    {
      fdbg("Failed to collect block statistics: %d\n", -ret);
      goto errout_with_buffer;
    }

  /* If the proportion of good blocks is low or the proportion of unformatted
   * blocks is high, then reformat the FLASH.
   */

  threshold = stats.nblocks / 5;
  if (stats.ngood < threshold || stats.nunformat > threshold)
    {
      /* Reformat the volume */

      ret = nxffs_reformat(volume);
      if (ret < 0)
        {
          fdbg("Failed to reformat the volume: %d\n", -ret);
          goto errout_with_buffer;
        }

      /* Get statistics on the re-formatted volume */

#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_FS)
      ret = nxffs_blockstats(volume, &stats);
      if (ret < 0)
        {
          fdbg("Failed to collect block statistics: %d\n", -ret);
          goto errout_with_buffer;
        }
#endif
    }

  /* Get the file system limits */

  ret = nxffs_limits(volume);
  if (ret == OK)
    {
      return OK;
    }
  fdbg("Failed to calculate file system limits: %d\n", -ret);

errout_with_buffer:
  kfree(volume->pack);
errout_with_cache:
  kfree(volume->cache);
errout_with_volume:
#ifndef CONFIG_NXFFS_PREALLOCATED
  kfree(volume);
#endif
  return ret;
}
Exemplo n.º 7
0
int board_app_initialize(uintptr_t arg)
{
#ifdef HAVE_RTC_DRIVER
  FAR struct rtc_lowerhalf_s *rtclower;
#endif
#if defined(HAVE_N25QXXX)
FAR struct mtd_dev_s *mtd_temp;
#endif
#if defined(HAVE_N25QXXX_CHARDEV)
  char blockdev[18];
  char chardev[12];
#endif
  int ret;

  (void)ret;

#ifdef HAVE_PROC
  /* mount the proc filesystem */

  syslog(LOG_INFO, "Mounting procfs to /proc\n");

  ret = mount(NULL, CONFIG_NSH_PROC_MOUNTPOINT, "procfs", 0, NULL);
  if (ret < 0)
    {
      syslog(LOG_ERR,
             "ERROR: Failed to mount the PROC filesystem: %d (%d)\n",
             ret, errno);
      return ret;
    }
#endif

#ifdef HAVE_RTC_DRIVER
  /* Instantiate the STM32 lower-half RTC driver */

  rtclower = stm32l4_rtc_lowerhalf();
  if (!rtclower)
    {
      serr("ERROR: Failed to instantiate the RTC lower-half driver\n");
      return -ENOMEM;
    }
  else
    {
      /* Bind the lower half driver and register the combined RTC driver
       * as /dev/rtc0
       */

      ret = rtc_initialize(0, rtclower);
      if (ret < 0)
        {
          serr("ERROR: Failed to bind/register the RTC driver: %d\n", ret);
          return ret;
        }
    }
#endif

#ifdef HAVE_N25QXXX
  /* Create an instance of the STM32L4 QSPI device driver */

  g_qspi = stm32l4_qspi_initialize(0);
  if (!g_qspi)
    {
      _err("ERROR: stm32l4_qspi_initialize failed\n");
      return ret;
    }
  else
    {
      /* Use the QSPI device instance to initialize the
       * N25QXXX device.
       */

      mtd_temp = n25qxxx_initialize(g_qspi, true);
      if (!mtd_temp)
        {
          _err("ERROR: n25qxxx_initialize failed\n");
          return ret;
        }
      g_mtd_fs = mtd_temp;

#ifdef CONFIG_MTD_PARTITION
      {
        FAR struct mtd_geometry_s geo;
        off_t nblocks;

        /* Setup a partition of 256KiB for our file system. */

        ret = MTD_IOCTL(g_mtd_fs, MTDIOC_GEOMETRY, (unsigned long)(uintptr_t)&geo);
        if (ret < 0)
          {
            _err("ERROR: MTDIOC_GEOMETRY failed\n");
            return ret;
          }

        nblocks = (256*1024) / geo.blocksize;

        mtd_temp = mtd_partition(g_mtd_fs, 0, nblocks);
        if (!mtd_temp)
          {
            _err("ERROR: mtd_partition failed\n");
            return ret;
          }

        g_mtd_fs = mtd_temp;
      }
#endif

#ifdef HAVE_N25QXXX_SMARTFS
      /* Configure the device with no partition support */

      ret = smart_initialize(N25QXXX_SMART_MINOR, g_mtd_fs, NULL);
      if (ret != OK)
        {
          _err("ERROR: Failed to initialize SmartFS: %d\n", ret);
        }

#elif defined(HAVE_N25QXXX_NXFFS)
      /* Initialize to provide NXFFS on the N25QXXX MTD interface */

      ret = nxffs_initialize(g_mtd_fs);
      if (ret < 0)
        {
         _err("ERROR: NXFFS initialization failed: %d\n", ret);
        }

      /* Mount the file system at /mnt/nxffs */

      ret = mount(NULL, "/mnt/nxffs", "nxffs", 0, NULL);
      if (ret < 0)
        {
          _err("ERROR: Failed to mount the NXFFS volume: %d\n", errno);
          return ret;
        }

#else /* if  defined(HAVE_N25QXXX_CHARDEV) */
      /* Use the FTL layer to wrap the MTD driver as a block driver */

      ret = ftl_initialize(N25QXXX_MTD_MINOR, g_mtd_fs);
      if (ret < 0)
        {
          _err("ERROR: Failed to initialize the FTL layer: %d\n", ret);
          return ret;
        }

      /* Use the minor number to create device paths */

      snprintf(blockdev, 18, "/dev/mtdblock%d", N25QXXX_MTD_MINOR);
      snprintf(chardev, 12, "/dev/mtd%d", N25QXXX_MTD_MINOR);

      /* Now create a character device on the block device */

      /* NOTE:  for this to work, you will need to make sure that
       * CONFIG_FS_WRITABLE is set in the config.  It's not a user-
       * visible setting, but you can make it set by selecting an
       * arbitrary writable file system (you don't have to actually
       * use it, just select it so that the block device created via
       * ftl_initialize() will be writable).
       */

      ret = bchdev_register(blockdev, chardev, false);
      if (ret < 0)
        {
          _err("ERROR: bchdev_register %s failed: %d\n", chardev, ret);
          return ret;
        }
#endif
    }
#endif

#ifdef HAVE_USBHOST
  /* Initialize USB host operation.  stm32l4_usbhost_initialize() starts a thread
   * will monitor for USB connection and disconnection events.
   */

  ret = stm32l4_usbhost_initialize();
  if (ret != OK)
    {
      udbg("ERROR: Failed to initialize USB host: %d\n", ret);
      return ret;
    }
#endif

#ifdef HAVE_USBMONITOR
  /* Start the USB Monitor */

  ret = usbmonitor_start(0, NULL);
  if (ret != OK)
    {
      udbg("ERROR: Failed to start USB monitor: %d\n", ret);
      return ret;
    }
#endif

  return OK;
}
Exemplo n.º 8
0
static int mtdconfig_setconfig(FAR struct mtdconfig_struct_s *dev,
                               FAR struct config_data_s *pdata)
{
  uint8_t   sig[CONFIGDATA_BLOCK_HDR_SIZE];       /* Format signature bytes ("CD") */
  char      retrycount = 0;
  int       ret = -ENOSYS;
  off_t     offset, bytes_left_in_block, bytes;
  uint16_t  block;
  struct mtdconfig_header_s hdr;
  uint8_t   ram_consolidate;

  /* Allocate a temp block buffer */

  dev->buffer = (FAR uint8_t *) kmm_malloc(dev->blocksize);

  /* Read and vaidate the signature bytes */

retry:
  offset = mtdconfig_findfirstentry(dev, &hdr);
  if (offset == 0)
    {
      /* Config Data partition not formatted. */

      if (retrycount)
        {
          ret = -ENOSYS;
          goto errout;
        }

      /* Try to format the config partition */

      ret = MTD_IOCTL(dev->mtd, MTDIOC_BULKERASE, 0);
      if (ret < 0)
        {
          goto errout;
        }

      /* Write a format signature */

      sig[0] = 'C';
      sig[1] = 'D';
      sig[2] = CONFIGDATA_FORMAT_VERSION;
      mtdconfig_writebytes(dev, 0, sig, sizeof(sig));

      /* Now go try to read the signature again (as verification) */

      retrycount++;
      goto retry;
    }

  /* Okay, the Config Data partition is formatted.  Check if the
   * config item being written is already in the database.  If it
   * is, we must mark it as obsolete before creating a new entry.
   */

  offset = mtdconfig_findentry(dev, offset, pdata, &hdr);

  /* Test if the header was found. */

  if (offset > 0 && pdata->id == hdr.id && pdata->instance ==
      hdr.instance)
    {
      /* Mark this entry as released */

      hdr.flags = (uint8_t)~MTD_ERASED_FLAGS;
      mtdconfig_writebytes(dev, offset, &hdr.flags, sizeof(hdr.flags));
    }

  /* Test if the new length is zero.  If it is, then we are
   * deleting the entry.
   */

  if (pdata->len == 0)
    {
      ret = OK;
      goto errout;
    }

  /* Now find a new entry for this config data */

  retrycount = 0;
retry_find:
  offset = mtdconfig_findfirstentry(dev, &hdr);
  if (offset > 0 && hdr.id == MTD_ERASED_ID)
    {
      block = offset / dev->erasesize;
      bytes_left_in_block = (block + 1) * dev->erasesize - offset;
      if (bytes_left_in_block < sizeof(hdr) + pdata->len)
        {
          /* Simulate an active block to search for the next one
           * in the code below.
           */

          hdr.id = 1;
        }
    }

  if (hdr.id != MTD_ERASED_ID)
    {
      /* Read the next entry */

      offset = mtdconfig_findnextentry(dev, offset, &hdr, pdata->len);
      if (offset == 0)
        {
          /* No free entries left on device! */

#ifdef CONFIG_MTD_CONFIG_RAM_CONSOLIDATE
          ram_consolidate = 1;
#else
          ram_consolidate = dev->neraseblocks == 1;
#endif
          if (ram_consolidate)
            {
              /* If we only have 1 erase block, then we must do a RAM
               * assisted consolidation of released entries.
               */

              if (retrycount)
                {
                  /* Out of space! */

                  ret = -ENOMEM;
                  goto errout;
                }

              mtdconfig_ramconsolidate(dev);
              retrycount++;
              goto retry_find;
            }
#ifndef CONFIG_MTD_CONFIG_RAM_CONSOLIDATE
          else
            {
              if (retrycount)
                {
                  /* Out of space! */

                  ret = -ENOMEM;
                  goto errout;
                }

              mtdconfig_consolidate(dev);
              retrycount++;
              goto retry_find;
            }
#endif
        }
    }

  /* Test if a new entry was found */

  if (offset > 0)
    {
      /* Save the data at this entry */

      hdr.id = pdata->id;
      hdr.instance = pdata->instance;
      hdr.len = pdata->len;
      hdr.flags = MTD_ERASED_FLAGS;
      //printf("SAV HDR: ID=%04X,%02X  Len=%4d  Off=%5d\n",
      //    hdr.id, hdr.instance, hdr.len, offset);
      mtdconfig_writebytes(dev, offset, (uint8_t *)&hdr, sizeof(hdr));
      bytes = mtdconfig_writebytes(dev, offset + sizeof(hdr), pdata->configdata,
                                   pdata->len);
      if (bytes != pdata->len)
        {
          /* Error writing data! */

          hdr.flags = MTD_ERASED_FLAGS;
          mtdconfig_writebytes(dev, offset, (uint8_t *)&hdr, sizeof(hdr.flags));
          ret = -EIO;
          goto errout;
        }

      ret = OK;
    }

errout:

  /* Free the buffer */

  kmm_free(dev->buffer);
  return ret;
}
Exemplo n.º 9
0
Arquivo: ftl.c Projeto: a1ien/nuttx
int ftl_initialize(int minor, FAR struct mtd_dev_s *mtd)
{
  struct ftl_struct_s *dev;
  char devname[16];
  int ret = -ENOMEM;

  /* Sanity check */

#ifdef CONFIG_DEBUG_FEATURES
  if (minor < 0 || minor > 255 || !mtd)
    {
      return -EINVAL;
    }
#endif

  /* Allocate a FTL device structure */

  dev = (struct ftl_struct_s *)kmm_malloc(sizeof(struct ftl_struct_s));
  if (dev)
    {
      /* Initialize the FTL device structure */

      dev->mtd = mtd;

      /* Get the device geometry. (casting to uintptr_t first eliminates
       * complaints on some architectures where the sizeof long is different
       * from the size of a pointer).
       */

      ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&dev->geo));
      if (ret < 0)
        {
          ferr("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", ret);
          kmm_free(dev);
          return ret;
        }

      /* Allocate one, in-memory erase block buffer */

#ifdef CONFIG_FS_WRITABLE
      dev->eblock  = (FAR uint8_t *)kmm_malloc(dev->geo.erasesize);
      if (!dev->eblock)
        {
          ferr("ERROR: Failed to allocate an erase block buffer\n");
          kmm_free(dev);
          return -ENOMEM;
        }
#endif

      /* Get the number of R/W blocks per erase block */

      dev->blkper = dev->geo.erasesize / dev->geo.blocksize;
      DEBUGASSERT(dev->blkper * dev->geo.blocksize == dev->geo.erasesize);

      /* Configure read-ahead/write buffering */

#ifdef FTL_HAVE_RWBUFFER
      dev->rwb.blocksize   = dev->geo.blocksize;
      dev->rwb.nblocks     = dev->geo.neraseblocks * dev->blkper;
      dev->rwb.dev         = (FAR void *)dev;

#if defined(CONFIG_FS_WRITABLE) && defined(CONFIG_FTL_WRITEBUFFER)
      dev->rwb.wrmaxblocks = dev->blkper;
      dev->rwb.wrflush     = ftl_flush;
#endif

#ifdef CONFIG_FTL_READAHEAD
      dev->rwb.rhmaxblocks = dev->blkper;
      dev->rwb.rhreload    = ftl_reload;
#endif

      ret = rwb_initialize(&dev->rwb);
      if (ret < 0)
        {
          ferr("ERROR: rwb_initialize failed: %d\n", ret);
          kmm_free(dev);
          return ret;
        }
#endif

      /* Create a MTD block device name */

      snprintf(devname, 16, "/dev/mtdblock%d", minor);

      /* Inode private data is a reference to the FTL device structure */

      ret = register_blockdriver(devname, &g_bops, 0, dev);
      if (ret < 0)
        {
          ferr("ERROR: register_blockdriver failed: %d\n", -ret);
          kmm_free(dev);
        }
    }

  return ret;
}
int configdata_main(int argc, char *argv[])
{
  unsigned int i;
  int ret;
  FAR struct mtd_dev_s *mtd;

  /* Seed the random number generated */

  srand(0x93846);

  /* Create and initialize a RAM MTD device instance */

#ifdef CONFIG_EXAMPLES_CONFIGDATA_ARCHINIT
  mtd = configdata_archinitialize();
#else
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
  message("Creating %d byte RAM drive\n", EXAMPLES_CONFIGDATA_BUFSIZE);
#endif
  mtd = rammtd_initialize(g_simflash, EXAMPLES_CONFIGDATA_BUFSIZE);
#endif
  if (!mtd)
    {
      message("ERROR: Failed to create RAM MTD instance\n");
      msgflush();
      exit(1);
    }

  /* Initialize to provide CONFIGDATA on an MTD interface */

#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
  message("Registering /dev/config device\n");
#endif
  MTD_IOCTL(mtd, MTDIOC_BULKERASE, 0);
  ret = mtdconfig_register(mtd);
  if (ret < 0)
    {
      message("ERROR: /dev/config registration failed: %d\n", -ret);
      msgflush();
      exit(2);
    }

  /* Zero out our entry array */

  memset(g_entries, 0, sizeof(g_entries));

  /* Open the /dev/config device */

  g_fd = open("/dev/config", O_RDOK);
  if (g_fd == -1)
    {
      message("ERROR: Failed to open /dev/config %d\n", -errno);
      msgflush();
      exit(2);
    }

  /* Initialize the before memory values */

#ifdef CONFIG_CAN_PASS_STRUCTS
  g_mmbefore = mallinfo();
#else
  (void)mallinfo(&g_mmbefore);
#endif

  /* Loop seveal times ... create some config data items, delete them
   * randomly, verify them randomly, add new config items.
   */

  g_ntests = g_nverified = 0;
  g_ntotaldelete = g_ntotalalloc = 0;

#if CONFIG_EXAMPLES_CONFIGDATA_NLOOPS == 0
  for (i = 0; ; i++)
#else
  for (i = 1; i <= CONFIG_EXAMPLES_CONFIGDATA_NLOOPS; i++)
#endif
    {
      /* Write config data to the /dev/config device until either (1) all of the
       * open file structures are utilized or until (2) CONFIGDATA reports an error
       * (hopefully that the /dev/config device is full)
       */

#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
      message("\n=== FILLING %d =============================\n", i);
#endif
      ret = configdata_fillconfig();
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
      message("Filled /dev/config\n");
      message("  Number of entries: %d\n", g_nentries);
#endif

      /* Verify all files entries to FLASH */

      ret = configdata_verifyconfig();
      if (ret < 0)
        {
          message("ERROR: Failed to verify partition\n");
          message("  Number of entries: %d\n", g_nentries);
        }
      else
        {
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
          message("Verified!\n");
          message("  Number of entries: %d\n", g_nentries);
#endif
#endif
        }

      /* Delete some entries */

#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
      message("\n=== DELETING %d ============================\n", i);
#endif
      ret = configdata_delentries();
      if (ret < 0)
        {
          message("ERROR: Failed to delete enries\n");
          message("  Number of entries: %d\n", g_nentries);
          message("  Number deleted:    %d\n", g_ndeleted);
        }
      else
        {
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
          message("Deleted some enries\n");
          message("  Number of entries: %d\n", g_nentries);
          message("  Number deleted:    %d\n", g_ndeleted);
#endif
        }

      /* Verify all files written to FLASH */

      ret = configdata_verifyconfig();
      if (ret < 0)
        {
          message("ERROR: Failed to verify partition\n");
          message("  Number of entries: %d\n", g_nentries);
          message("  Number deleted:    %d\n", g_ndeleted);
        }
      else
        {
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
          message("Verified!\n");
          message("  Number of entries: %d\n", g_nentries);
          message("  Number deleted:    %d\n", g_ndeleted);
#endif
#endif
        }

      /* Clear deleted entries */

      configdata_cleardeleted();

      /* Show memory usage */

#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
      configdata_loopmemusage();
      msgflush();
#else
      if ((i % EXAMPLES_CONFIGDATA_REPORT) == 0)
        {
          message("%d\n", i);
          msgflush();
        }
#endif
    }

  /* Delete all files then show memory usage again */

  //configdata_delallfiles();
  configdata_endmemusage();
  msgflush();
  return 0;
}
Exemplo n.º 11
0
int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose)
{
#if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_FS)
  struct nxffs_blkinfo_s blkinfo;
  int ret;

  /* Get the volume geometry. (casting to uintptr_t first eliminates
   * complaints on some architectures where the sizeof long is different
   * from the size of a pointer).
   */

  memset(&blkinfo, 0, sizeof(struct nxffs_blkinfo_s));
  ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&blkinfo.geo));
  if (ret < 0)
    {
      ferr("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret);
      return ret;
    }

  /* Save the verbose output indication */

  blkinfo.verbose = verbose;

  /* Allocate a buffer to hold one block */

  blkinfo.buffer = (FAR uint8_t *)kmm_malloc(blkinfo.geo.blocksize);
  if (!blkinfo.buffer)
    {
      ferr("ERROR: Failed to allocate block cache\n");
      return -ENOMEM;
    }

  /* Now read every block on the device */

  syslog(LOG_NOTICE, "NXFFS Dump:\n");
  syslog(LOG_NOTICE, g_hdrformat);

  blkinfo.nblocks = blkinfo.geo.erasesize * blkinfo.geo.neraseblocks / blkinfo.geo.blocksize;
  for (blkinfo.block = 0, blkinfo.offset = 0;
       blkinfo.block < blkinfo.nblocks;
       blkinfo.block++, blkinfo.offset += blkinfo.geo.blocksize)
    {
      /* Read the next block */

      ret = MTD_BREAD(mtd, blkinfo.block, 1, blkinfo.buffer);
      if (ret < 0)
        {
#ifndef CONFIG_NXFFS_NAND
          /* Read errors are fatal */

          ferr("ERROR: Failed to read block %d\n", blkinfo.block);
          kmm_free(blkinfo.buffer);
          return ret;
#else
          /* A read error is probably fatal on all media but NAND.
           * On NAND, the read error probably just signifies a block
           * with an uncorrectable ECC failure.  So, to handle NAND,
           * just report the read error and continue.
           */

          syslog(LOG_NOTICE, g_format, blkinfo.block, 0, "BLOCK", "RD FAIL",
               blkinfo.geo.blocksize);
#endif
        }
      else
        {
          /* Analyze the block that we just read */

          nxffs_analyze(&blkinfo);
        }
    }

  syslog(LOG_NOTICE, "%d blocks analyzed\n", blkinfo.nblocks);

  kmm_free(blkinfo.buffer);
  return OK;

#else
  return -ENOSYS;
#endif
}