Beispiel #1
0
int romdisk_register(int minor, FAR const uint8_t *buffer, uint32_t nsectors,
                     uint16_t sectsize)
#endif
{
  struct rd_struct_s *dev;
  char devname[16];
  int ret = -ENOMEM;

  finfo("buffer: %p nsectors: %d sectsize: %d\n", buffer, nsectors, sectsize);

  /* Sanity check */

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

  /* Allocate a ramdisk device structure */

  dev = (struct rd_struct_s *)kmm_zalloc(sizeof(struct rd_struct_s));
  if (dev)
    {
      /* Initialize the ramdisk device structure */

      dev->rd_nsectors     = nsectors;     /* Number of sectors on device */
      dev->rd_sectsize     = sectsize;     /* The size of one sector */
      dev->rd_buffer       = buffer;       /* RAM disk backup memory */

#ifdef CONFIG_FS_WRITABLE
      dev->rd_flags        = rdflags & RDFLAG_USER;
#endif

      /* Create a ramdisk device name */

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

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

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

  return ret;
}
Beispiel #2
0
int losetup(FAR const char *devname, FAR const char *filename, uint16_t sectsize, off_t offset, bool readonly)
{
	FAR struct loop_struct_s *dev;
	struct stat sb;
	int ret;

	/* Sanity check */

#ifdef CONFIG_DEBUG
	if (!devname || !filename || !sectsize) {
		return -EINVAL;
	}
#endif

	/* Get the size of the file */

	ret = stat(filename, &sb);
	if (ret < 0) {
		dbg("Failed to stat %s: %d\n", filename, get_errno());
		return -get_errno();
	}

	/* Check if the file system is big enough for one block */

	if (sb.st_size - offset < sectsize) {
		dbg("File is too small for blocksize\n");
		return -ERANGE;
	}

	/* Allocate a loop device structure */

	dev = (FAR struct loop_struct_s *)kmm_zalloc(sizeof(struct loop_struct_s));
	if (!dev) {
		return -ENOMEM;
	}

	/* Initialize the loop device structure. */

	sem_init(&dev->sem, 0, 1);
	dev->nsectors = (sb.st_size - offset) / sectsize;
	dev->sectsize = sectsize;
	dev->offset = offset;

	/* Open the file. */

#ifdef CONFIG_FS_WRITABLE
	dev->writeenabled = false;	/* Assume failure */
	dev->fd = -1;

	/* First try to open the device R/W access (unless we are asked
	 * to open it readonly).
	 */

	if (!readonly) {
		dev->fd = open(filename, O_RDWR);
	}

	if (dev->fd >= 0) {
		dev->writeenabled = true;	/* Success */
	} else
#endif
	{
		/* If that fails, then try to open the device read-only */

		dev->fd = open(filename, O_RDWR);
		if (dev->fd < 0) {
			dbg("Failed to open %s: %d\n", filename, get_errno());
			ret = -get_errno();
			goto errout_with_dev;
		}
	}

	/* Inode private data will be reference to the loop device structure */

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

	return OK;

errout_with_fd:
	close(dev->fd);
errout_with_dev:
	kmm_free(dev);
	return ret;
}
Beispiel #3
0
Datei: ftl.c Projekt: 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;
}