You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/12/04 14:49:39 UTC

[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #4937: drivers/mtd: add MTD null driver support

xiaoxiang781216 commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762433514



##########
File path: drivers/mtd/nullmtd.c
##########
@@ -0,0 +1,395 @@
+/****************************************************************************
+ * drivers/mtd/nullmtd.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/mtd/mtd.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_NULLMTD_BLOCKSIZE
+#  define CONFIG_NULLMTD_BLOCKSIZE 512
+#endif
+
+#ifndef CONFIG_NULLMTD_ERASESIZE
+#  define CONFIG_NULLMTD_ERASESIZE 4096
+#endif
+
+#ifndef CONFIG_NULLMTD_ERASESTATE
+#  define CONFIG_NULLMTD_ERASESTATE 0xff
+#endif
+
+#if CONFIG_NULLMTD_ERASESTATE != 0xff && CONFIG_NULLMTD_ERASESTATE != 0x00
+#  error "Unsupported value for CONFIG_NULLMTD_ERASESTATE"
+#endif
+
+#if CONFIG_NULLMTD_BLOCKSIZE > CONFIG_NULLMTD_ERASESIZE
+#  error "Must have CONFIG_NULLMTD_BLOCKSIZE <= CONFIG_NULLMTD_ERASESIZE"
+#endif
+
+#undef  NULLMTD_BLKPER
+#define NULLMTD_BLKPER (CONFIG_NULLMTD_ERASESIZE/CONFIG_NULLMTD_BLOCKSIZE)
+
+#if NULLMTD_BLKPER*CONFIG_NULLMTD_BLOCKSIZE != CONFIG_NULLMTD_ERASESIZE
+#  error "CONFIG_NULLMTD_ERASESIZE must be an even multiple of CONFIG_NULLMTD_BLOCKSIZE"
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This type represents the state of the MTD device.  The struct mtd_dev_s
+ * must appear at the beginning of the definition so that you can freely
+ * cast between pointers to struct mtd_dev_s and struct null_dev_s.
+ */
+
+struct null_dev_s
+{
+  struct mtd_dev_s mtd;        /* MTD device */
+  size_t           nblocks;    /* Number of erase blocks */
+  size_t           erasesize;  /* Offset from start of file */
+  size_t           blocksize;  /* Offset from start of file */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#define nullmtd_read(dest, len) memset(dest, CONFIG_NULLMTD_ERASESTATE, len)
+
+/* MTD driver methods */
+
+static int     nullmtd_erase(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks);
+static ssize_t nullmtd_bread(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks, FAR uint8_t *buf);
+static ssize_t nullmtd_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
+                              size_t nblocks, FAR const uint8_t *buf);
+static ssize_t nullmtd_byteread(FAR struct mtd_dev_s *dev, off_t offset,
+                                size_t nbytes, FAR uint8_t *buf);
+#ifdef CONFIG_MTD_BYTE_WRITE
+static ssize_t nullmtd_bytewrite(FAR struct mtd_dev_s *dev, off_t offset,
+                                 size_t nbytes, FAR const uint8_t *buf);
+#endif
+static int     nullmtd_ioctl(FAR struct mtd_dev_s *dev, int cmd,
+                             unsigned long arg);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nullmtd_erase
+ ****************************************************************************/
+
+static int nullmtd_erase(FAR struct mtd_dev_s *dev, off_t startblock,
+                         size_t nblocks)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+
+  DEBUGASSERT(dev);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  if (startblock >= priv->nblocks)
+    {
+      return 0;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bread
+ ****************************************************************************/
+
+static ssize_t nullmtd_bread(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks, FAR uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxblock;
+  size_t nbytes;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxblock = priv->nblocks * (priv->erasesize / priv->blocksize);
+  if (startblock >= maxblock)
+    {
+      return 0;
+    }
+
+  if (startblock + nblocks > maxblock)
+    {
+      nblocks = maxblock - startblock;
+    }
+
+  /* Get the size corresponding to the number of blocks.
+   */
+
+  nbytes = nblocks * priv->blocksize;
+
+  /* Then read the data from the file */
+
+  nullmtd_read(buf, nbytes);
+  return nblocks;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bwrite
+ ****************************************************************************/
+
+static ssize_t nullmtd_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
+                              size_t nblocks, FAR const uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxblock;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxblock = priv->nblocks * (priv->erasesize / priv->blocksize);
+  if (startblock >= maxblock)
+    {
+      return 0;
+    }
+
+  return nblocks;
+}
+
+/****************************************************************************
+ * Name: nullmtd_byteread
+ ****************************************************************************/
+
+static ssize_t nullmtd_byteread(FAR struct mtd_dev_s *dev, off_t offset,
+                                size_t nbytes, FAR uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let read read past end of buffer */
+
+  if (offset + nbytes > priv->nblocks * priv->erasesize)
+    {
+      return 0;
+    }
+
+  nullmtd_read(buf, nbytes);
+  return nbytes;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bytewrite
+ ****************************************************************************/
+
+#ifdef CONFIG_MTD_BYTE_WRITE
+static ssize_t nullmtd_bytewrite(FAR struct mtd_dev_s *dev, off_t offset,
+                                 size_t nbytes, FAR const uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxoffset;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxoffset = priv->nblocks * priv->erasesize;
+  if (offset + nbytes > maxoffset)
+    {
+      return 0;
+    }
+
+  return nbytes;
+}
+#endif
+
+/****************************************************************************
+ * Name: nullmtd_ioctl
+ ****************************************************************************/
+
+static int nullmtd_ioctl(FAR struct mtd_dev_s *dev, int cmd,
+                         unsigned long arg)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  int ret = -EINVAL; /* Assume good command with bad parameters */
+
+  switch (cmd)
+    {
+      case MTDIOC_GEOMETRY:
+        {
+          FAR struct mtd_geometry_s *geo =
+            (FAR struct mtd_geometry_s *)((uintptr_t)arg);
+
+          if (geo)
+            {
+              /* Populate the geometry structure with information need to
+               * know the capacity and how to access the device.
+               */
+
+              geo->blocksize    = priv->blocksize;
+              geo->erasesize    = priv->erasesize;
+              geo->neraseblocks = priv->nblocks;
+              ret               = OK;
+            }
+        }
+        break;
+
+      case BIOC_PARTINFO:
+        {
+          FAR struct partition_info_s *info =
+            (FAR struct partition_info_s *)arg;
+          if (info != NULL)
+            {
+              info->numsectors  = priv->nblocks *
+                                  priv->erasesize / priv->blocksize;
+              info->sectorsize  = priv->blocksize;
+              info->startsector = 0;
+              info->parent[0]   = '\0';
+              ret               = OK;
+            }
+        }
+        break;
+
+      case MTDIOC_BULKERASE:
+        {
+          /* Erase the entire device */
+
+          nullmtd_erase(dev, 0, priv->nblocks);
+          ret = OK;

Review comment:
       ret = nullmtd_erase(dev, 0, priv->nblocks);

##########
File path: drivers/mtd/nullmtd.c
##########
@@ -0,0 +1,395 @@
+/****************************************************************************
+ * drivers/mtd/nullmtd.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/mtd/mtd.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_NULLMTD_BLOCKSIZE
+#  define CONFIG_NULLMTD_BLOCKSIZE 512
+#endif
+
+#ifndef CONFIG_NULLMTD_ERASESIZE
+#  define CONFIG_NULLMTD_ERASESIZE 4096
+#endif
+
+#ifndef CONFIG_NULLMTD_ERASESTATE
+#  define CONFIG_NULLMTD_ERASESTATE 0xff
+#endif
+
+#if CONFIG_NULLMTD_ERASESTATE != 0xff && CONFIG_NULLMTD_ERASESTATE != 0x00
+#  error "Unsupported value for CONFIG_NULLMTD_ERASESTATE"
+#endif
+
+#if CONFIG_NULLMTD_BLOCKSIZE > CONFIG_NULLMTD_ERASESIZE
+#  error "Must have CONFIG_NULLMTD_BLOCKSIZE <= CONFIG_NULLMTD_ERASESIZE"
+#endif
+
+#undef  NULLMTD_BLKPER
+#define NULLMTD_BLKPER (CONFIG_NULLMTD_ERASESIZE/CONFIG_NULLMTD_BLOCKSIZE)
+
+#if NULLMTD_BLKPER*CONFIG_NULLMTD_BLOCKSIZE != CONFIG_NULLMTD_ERASESIZE
+#  error "CONFIG_NULLMTD_ERASESIZE must be an even multiple of CONFIG_NULLMTD_BLOCKSIZE"
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This type represents the state of the MTD device.  The struct mtd_dev_s
+ * must appear at the beginning of the definition so that you can freely
+ * cast between pointers to struct mtd_dev_s and struct null_dev_s.
+ */
+
+struct null_dev_s
+{
+  struct mtd_dev_s mtd;        /* MTD device */
+  size_t           nblocks;    /* Number of erase blocks */
+  size_t           erasesize;  /* Offset from start of file */
+  size_t           blocksize;  /* Offset from start of file */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#define nullmtd_read(dest, len) memset(dest, CONFIG_NULLMTD_ERASESTATE, len)
+
+/* MTD driver methods */
+
+static int     nullmtd_erase(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks);
+static ssize_t nullmtd_bread(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks, FAR uint8_t *buf);
+static ssize_t nullmtd_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
+                              size_t nblocks, FAR const uint8_t *buf);
+static ssize_t nullmtd_byteread(FAR struct mtd_dev_s *dev, off_t offset,
+                                size_t nbytes, FAR uint8_t *buf);
+#ifdef CONFIG_MTD_BYTE_WRITE
+static ssize_t nullmtd_bytewrite(FAR struct mtd_dev_s *dev, off_t offset,
+                                 size_t nbytes, FAR const uint8_t *buf);
+#endif
+static int     nullmtd_ioctl(FAR struct mtd_dev_s *dev, int cmd,
+                             unsigned long arg);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nullmtd_erase
+ ****************************************************************************/
+
+static int nullmtd_erase(FAR struct mtd_dev_s *dev, off_t startblock,
+                         size_t nblocks)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+
+  DEBUGASSERT(dev);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  if (startblock >= priv->nblocks)
+    {
+      return 0;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bread
+ ****************************************************************************/
+
+static ssize_t nullmtd_bread(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks, FAR uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxblock;
+  size_t nbytes;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxblock = priv->nblocks * (priv->erasesize / priv->blocksize);
+  if (startblock >= maxblock)
+    {
+      return 0;
+    }
+
+  if (startblock + nblocks > maxblock)
+    {
+      nblocks = maxblock - startblock;
+    }
+
+  /* Get the size corresponding to the number of blocks.
+   */
+
+  nbytes = nblocks * priv->blocksize;
+
+  /* Then read the data from the file */
+
+  nullmtd_read(buf, nbytes);
+  return nblocks;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bwrite
+ ****************************************************************************/
+
+static ssize_t nullmtd_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
+                              size_t nblocks, FAR const uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxblock;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxblock = priv->nblocks * (priv->erasesize / priv->blocksize);
+  if (startblock >= maxblock)
+    {
+      return 0;
+    }
+
+  return nblocks;
+}
+
+/****************************************************************************
+ * Name: nullmtd_byteread
+ ****************************************************************************/
+
+static ssize_t nullmtd_byteread(FAR struct mtd_dev_s *dev, off_t offset,
+                                size_t nbytes, FAR uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let read read past end of buffer */
+
+  if (offset + nbytes > priv->nblocks * priv->erasesize)
+    {
+      return 0;
+    }
+
+  nullmtd_read(buf, nbytes);
+  return nbytes;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bytewrite
+ ****************************************************************************/
+
+#ifdef CONFIG_MTD_BYTE_WRITE
+static ssize_t nullmtd_bytewrite(FAR struct mtd_dev_s *dev, off_t offset,
+                                 size_t nbytes, FAR const uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxoffset;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxoffset = priv->nblocks * priv->erasesize;
+  if (offset + nbytes > maxoffset)
+    {
+      return 0;

Review comment:
       Since null can't really write, should we always return error regardless the argument?

##########
File path: drivers/mtd/nullmtd.c
##########
@@ -0,0 +1,395 @@
+/****************************************************************************
+ * drivers/mtd/nullmtd.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/mtd/mtd.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_NULLMTD_BLOCKSIZE
+#  define CONFIG_NULLMTD_BLOCKSIZE 512
+#endif
+
+#ifndef CONFIG_NULLMTD_ERASESIZE
+#  define CONFIG_NULLMTD_ERASESIZE 4096
+#endif
+
+#ifndef CONFIG_NULLMTD_ERASESTATE
+#  define CONFIG_NULLMTD_ERASESTATE 0xff
+#endif
+
+#if CONFIG_NULLMTD_ERASESTATE != 0xff && CONFIG_NULLMTD_ERASESTATE != 0x00
+#  error "Unsupported value for CONFIG_NULLMTD_ERASESTATE"
+#endif
+
+#if CONFIG_NULLMTD_BLOCKSIZE > CONFIG_NULLMTD_ERASESIZE
+#  error "Must have CONFIG_NULLMTD_BLOCKSIZE <= CONFIG_NULLMTD_ERASESIZE"
+#endif
+
+#undef  NULLMTD_BLKPER
+#define NULLMTD_BLKPER (CONFIG_NULLMTD_ERASESIZE/CONFIG_NULLMTD_BLOCKSIZE)
+
+#if NULLMTD_BLKPER*CONFIG_NULLMTD_BLOCKSIZE != CONFIG_NULLMTD_ERASESIZE
+#  error "CONFIG_NULLMTD_ERASESIZE must be an even multiple of CONFIG_NULLMTD_BLOCKSIZE"
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This type represents the state of the MTD device.  The struct mtd_dev_s
+ * must appear at the beginning of the definition so that you can freely
+ * cast between pointers to struct mtd_dev_s and struct null_dev_s.
+ */
+
+struct null_dev_s
+{
+  struct mtd_dev_s mtd;        /* MTD device */
+  size_t           nblocks;    /* Number of erase blocks */
+  size_t           erasesize;  /* Offset from start of file */
+  size_t           blocksize;  /* Offset from start of file */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#define nullmtd_read(dest, len) memset(dest, CONFIG_NULLMTD_ERASESTATE, len)
+
+/* MTD driver methods */
+
+static int     nullmtd_erase(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks);
+static ssize_t nullmtd_bread(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks, FAR uint8_t *buf);
+static ssize_t nullmtd_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
+                              size_t nblocks, FAR const uint8_t *buf);
+static ssize_t nullmtd_byteread(FAR struct mtd_dev_s *dev, off_t offset,
+                                size_t nbytes, FAR uint8_t *buf);
+#ifdef CONFIG_MTD_BYTE_WRITE
+static ssize_t nullmtd_bytewrite(FAR struct mtd_dev_s *dev, off_t offset,
+                                 size_t nbytes, FAR const uint8_t *buf);
+#endif
+static int     nullmtd_ioctl(FAR struct mtd_dev_s *dev, int cmd,
+                             unsigned long arg);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nullmtd_erase
+ ****************************************************************************/
+
+static int nullmtd_erase(FAR struct mtd_dev_s *dev, off_t startblock,
+                         size_t nblocks)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+
+  DEBUGASSERT(dev);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  if (startblock >= priv->nblocks)
+    {
+      return 0;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bread
+ ****************************************************************************/
+
+static ssize_t nullmtd_bread(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks, FAR uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxblock;
+  size_t nbytes;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxblock = priv->nblocks * (priv->erasesize / priv->blocksize);
+  if (startblock >= maxblock)
+    {
+      return 0;
+    }
+
+  if (startblock + nblocks > maxblock)
+    {
+      nblocks = maxblock - startblock;
+    }
+
+  /* Get the size corresponding to the number of blocks.
+   */
+
+  nbytes = nblocks * priv->blocksize;
+
+  /* Then read the data from the file */
+
+  nullmtd_read(buf, nbytes);
+  return nblocks;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bwrite
+ ****************************************************************************/
+
+static ssize_t nullmtd_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
+                              size_t nblocks, FAR const uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxblock;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxblock = priv->nblocks * (priv->erasesize / priv->blocksize);
+  if (startblock >= maxblock)
+    {
+      return 0;
+    }
+
+  return nblocks;
+}
+
+/****************************************************************************
+ * Name: nullmtd_byteread
+ ****************************************************************************/
+
+static ssize_t nullmtd_byteread(FAR struct mtd_dev_s *dev, off_t offset,
+                                size_t nbytes, FAR uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let read read past end of buffer */
+
+  if (offset + nbytes > priv->nblocks * priv->erasesize)
+    {
+      return 0;
+    }
+

Review comment:
       ```
     off_t maxoffset;
   
     DEBUGASSERT(dev && buf);
   
     /* Don't let the erase exceed the configured size of the device */
   
     maxoffset = priv->nblocks * priv->erasesize;
     if (offset >= maxoffset)
       {
         return 0;
       }
   
     if (offset + nbytes > maxoffset)
       {
         offset = maxoffset - nbytes;
       }
   ```

##########
File path: drivers/mtd/nullmtd.c
##########
@@ -0,0 +1,395 @@
+/****************************************************************************
+ * drivers/mtd/nullmtd.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/mtd/mtd.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_NULLMTD_BLOCKSIZE
+#  define CONFIG_NULLMTD_BLOCKSIZE 512
+#endif
+
+#ifndef CONFIG_NULLMTD_ERASESIZE
+#  define CONFIG_NULLMTD_ERASESIZE 4096
+#endif
+
+#ifndef CONFIG_NULLMTD_ERASESTATE
+#  define CONFIG_NULLMTD_ERASESTATE 0xff
+#endif
+
+#if CONFIG_NULLMTD_ERASESTATE != 0xff && CONFIG_NULLMTD_ERASESTATE != 0x00
+#  error "Unsupported value for CONFIG_NULLMTD_ERASESTATE"
+#endif
+
+#if CONFIG_NULLMTD_BLOCKSIZE > CONFIG_NULLMTD_ERASESIZE
+#  error "Must have CONFIG_NULLMTD_BLOCKSIZE <= CONFIG_NULLMTD_ERASESIZE"
+#endif
+
+#undef  NULLMTD_BLKPER
+#define NULLMTD_BLKPER (CONFIG_NULLMTD_ERASESIZE/CONFIG_NULLMTD_BLOCKSIZE)
+
+#if NULLMTD_BLKPER*CONFIG_NULLMTD_BLOCKSIZE != CONFIG_NULLMTD_ERASESIZE
+#  error "CONFIG_NULLMTD_ERASESIZE must be an even multiple of CONFIG_NULLMTD_BLOCKSIZE"
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This type represents the state of the MTD device.  The struct mtd_dev_s
+ * must appear at the beginning of the definition so that you can freely
+ * cast between pointers to struct mtd_dev_s and struct null_dev_s.
+ */
+
+struct null_dev_s
+{
+  struct mtd_dev_s mtd;        /* MTD device */
+  size_t           nblocks;    /* Number of erase blocks */
+  size_t           erasesize;  /* Offset from start of file */
+  size_t           blocksize;  /* Offset from start of file */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#define nullmtd_read(dest, len) memset(dest, CONFIG_NULLMTD_ERASESTATE, len)
+
+/* MTD driver methods */
+
+static int     nullmtd_erase(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks);
+static ssize_t nullmtd_bread(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks, FAR uint8_t *buf);
+static ssize_t nullmtd_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
+                              size_t nblocks, FAR const uint8_t *buf);
+static ssize_t nullmtd_byteread(FAR struct mtd_dev_s *dev, off_t offset,
+                                size_t nbytes, FAR uint8_t *buf);
+#ifdef CONFIG_MTD_BYTE_WRITE
+static ssize_t nullmtd_bytewrite(FAR struct mtd_dev_s *dev, off_t offset,
+                                 size_t nbytes, FAR const uint8_t *buf);
+#endif
+static int     nullmtd_ioctl(FAR struct mtd_dev_s *dev, int cmd,
+                             unsigned long arg);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nullmtd_erase
+ ****************************************************************************/
+
+static int nullmtd_erase(FAR struct mtd_dev_s *dev, off_t startblock,
+                         size_t nblocks)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+
+  DEBUGASSERT(dev);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  if (startblock >= priv->nblocks)
+    {
+      return 0;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bread
+ ****************************************************************************/
+
+static ssize_t nullmtd_bread(FAR struct mtd_dev_s *dev, off_t startblock,
+                             size_t nblocks, FAR uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxblock;
+  size_t nbytes;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxblock = priv->nblocks * (priv->erasesize / priv->blocksize);
+  if (startblock >= maxblock)
+    {
+      return 0;
+    }
+
+  if (startblock + nblocks > maxblock)
+    {
+      nblocks = maxblock - startblock;
+    }
+
+  /* Get the size corresponding to the number of blocks.
+   */
+
+  nbytes = nblocks * priv->blocksize;
+
+  /* Then read the data from the file */
+
+  nullmtd_read(buf, nbytes);
+  return nblocks;
+}
+
+/****************************************************************************
+ * Name: nullmtd_bwrite
+ ****************************************************************************/
+
+static ssize_t nullmtd_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
+                              size_t nblocks, FAR const uint8_t *buf)
+{
+  FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev;
+  off_t maxblock;
+
+  DEBUGASSERT(dev && buf);
+
+  /* Don't let the erase exceed the configured size of the device */
+
+  maxblock = priv->nblocks * (priv->erasesize / priv->blocksize);
+  if (startblock >= maxblock)

Review comment:
       directly return error?

##########
File path: drivers/mtd/mtd_progmem.c
##########
@@ -371,7 +371,6 @@ static int progmem_ioctl(FAR struct mtd_dev_s *dev, int cmd,
       case MTDIOC_ERASESTATE:
         {
           FAR uint8_t *result = (FAR uint8_t *)arg;
-

Review comment:
       why change?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org