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 12:55:55 UTC

[GitHub] [incubator-nuttx] pkarashchenko opened a new pull request #4937: drivers/mtd: add MTD null driver support

pkarashchenko opened a new pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937


   ## Summary
   - add MTD null driver support
   - fix memory leak during RAM MTD initialization
   - fix calculations for FILE MTD device with customized
     block and erase sizes
   
   ## Impact
   Devices that use RAM and FILE MTD drivers
   
   ## Testing
   - PreCI pass
   - MTD null driver tested on SAME70-QMTECH board


-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762466601



##########
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?
   
   I tried to implement something like `/dev/null` that `null device is a device file that discards all data written to it but reports that the write operation succeeded`. Maybe it is not 100% correct and this device should be named `zeromtd` as it will discard whatever is written to with MTD, but read operation will always return erased values. What do you think?
   
   > Unfortunately the error is not reported, please take a look at drivers/mtd/filemtd.c search for file_write
   > Did you try to erase a size that exceed the size of the device?
   
   No I didn't tried erasing a size that exceeds the size of the device, but this is not an erase API, but byte write API, so by design it reports that the write operation succeeded if it is withing the boundaries of a configured device.




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762466601



##########
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?
   
   I tried to implement something like `/dev/null` that `null device is a device file that discards all data written to it but reports that the write operation succeeded`. Maybe it is not 100% correct and this device should be named `zeromtd` as it will discard whatever is written to with MTD, but read operation will always return erased values.
   
   > Unfortunately the error is not reported, please take a look at drivers/mtd/filemtd.c search for file_write
   > Did you try to erase a size that exceed the size of the device?
   
   No I didn't tried erasing a size that exceeds the size of the device, but this is not an erase API, but byte write API, so by design it reports that the write operation succeeded if it is withing the boundaries of a configured device.




-- 
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



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

Posted by GitBox <gi...@apache.org>.
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762432867



##########
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:
       I copied that from a FILE MTD and there is not debug message there. I think that returning `0`is enough to indicate an error and there is not need for additional debug message




-- 
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



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

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762433827



##########
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:
       > 
   
   Unfortunately the error is not reported, please take a look at drivers/mtd/filemtd.c search for file_write
   Did you try to erase a size that exceed the size of the device?




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762466601



##########
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?
   I tried to implement something like `/dev/null` that `null device is a device file that discards all data written to it but reports that the write operation succeeded`. Maybe it is not 100% correct and this device should be named `zeromtd` as it will discard whatever is written to with MTD, but read operation will always return erased values.
   
   > Unfortunately the error is not reported, please take a look at drivers/mtd/filemtd.c search for file_write
   > Did you try to erase a size that exceed the size of the device?
   No I didn't tried erasing a size that exceeds the size of the device, but this is not an erase API, but byte write API, so by design it reports that the write operation succeeded if it is withing the boundaries of a configured device.




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762468421



##########
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:
       What do you mean? In case of such situation we return `0` blocks witten




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762467397



##########
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:
       Maybe
   ```
   if (offset + nbytes > maxoffset)
     {
       nbytes = maxoffset - offset;
     }
   ```
   ???




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762468498



##########
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:
       Done




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762432974



##########
File path: drivers/mtd/Kconfig
##########
@@ -329,6 +329,29 @@ config FILEMTD_ERASESTATE
 
 endif # FILEMTD
 
+config NULLMTD
+	bool "MTD null driver"
+	default n
+	---help---
+		Build support for a MTD null driver.  It simulates an always errased

Review comment:
       Done




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762468612



##########
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:
       I agree if you recommend to rename it to `zeromtd`




-- 
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



[GitHub] [incubator-nuttx] xiaoxiang781216 merged pull request #4937: drivers/mtd: add MTD null driver support

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 merged pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937


   


-- 
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



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

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762426774



##########
File path: drivers/mtd/Kconfig
##########
@@ -329,6 +329,29 @@ config FILEMTD_ERASESTATE
 
 endif # FILEMTD
 
+config NULLMTD
+	bool "MTD null driver"
+	default n
+	---help---
+		Build support for a MTD null driver.  It simulates an always errased

Review comment:
       errased -> erased

##########
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:
       Please include a debug error message here




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762468213



##########
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:
       done. thanks!




-- 
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



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

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on a change in pull request #4937:
URL: https://github.com/apache/incubator-nuttx/pull/4937#discussion_r762465053



##########
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:
       Just sync style across multiple files:
   https://github.com/apache/incubator-nuttx/blob/af72376773aa1434fe247ccb7c578abea9373fe7/drivers/mtd/rammtd.c#L430..L436
   https://github.com/apache/incubator-nuttx/blob/af72376773aa1434fe247ccb7c578abea9373fe7/drivers/mtd/filemtd.c#L464..L470
   https://github.com/apache/incubator-nuttx/blob/a59aae69270f547d976651da82543daccaa4bb3c/arch/risc-v/src/esp32c3/esp32c3_spiflash.c#L889..896
   and many others




-- 
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