[PATCH rtems6 - v2 13/16] flashdev: fix erase function

berndmoessner80 at gmail.com berndmoessner80 at gmail.com
Sun Jan 7 18:18:47 UTC 2024


From: Bernd Moessner <berndmoessner80 at gmail.com>

Erase function must take erase size and alignment into account

Updates #4981
---
 cpukit/dev/flash/flashdev.c           | 49 ++++++++++++++++++++++++++-
 testsuites/libtests/flashdev01/init.c | 18 +++++++++-
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/cpukit/dev/flash/flashdev.c b/cpukit/dev/flash/flashdev.c
index e10daace99..d18d14b2f8 100644
--- a/cpukit/dev/flash/flashdev.c
+++ b/cpukit/dev/flash/flashdev.c
@@ -60,6 +60,12 @@ static int rtems_flashdev_read_write(
   size_t count
 );
 
+static int rtems_check_erase_valid(
+  rtems_flashdev* flash,
+  off_t offset,
+  size_t count
+);
+
 static int rtems_flashdev_ioctl_erase(
   rtems_flashdev *flash,
   rtems_libio_t *iop,
@@ -341,6 +347,41 @@ static int rtems_flashdev_read_write(
   return rtems_flashdev_update_and_return( iop, status, count );
 }
 
+static int rtems_check_erase_valid(
+  rtems_flashdev* flash,
+  off_t offset,
+  size_t count
+)
+{
+  rtems_flashdev_ioctl_page_info page_info;
+  page_info.location = offset;
+  off_t offset_max = offset + count;
+
+  while(page_info.location < offset_max)
+  {
+    ( *flash->get_page_info_by_offset )( flash,
+                                          page_info.location,
+                                          &page_info.page_info.offset,
+                                          &page_info.page_info.size,
+                                          &page_info.erase_info.offset,
+                                          &page_info.erase_info.size );
+
+    if (page_info.erase_info.offset != page_info.location)
+    {
+      rtems_set_errno_and_return_minus_one( EINVAL );
+    }
+
+    page_info.location += page_info.erase_info.size;
+  }
+
+  if (offset_max != page_info.location)
+  {
+    rtems_set_errno_and_return_minus_one( EINVAL );
+  }
+
+  return 0;
+}
+
 static int rtems_flashdev_ioctl(
   rtems_libio_t *iop,
   ioctl_command_t command,
@@ -643,8 +684,14 @@ static int rtems_flashdev_ioctl_erase(
   if ( status < 0 ) {
     return status;
   }
+  status = rtems_check_erase_valid( flash, new_offset, erase_args_1->size );
+  if ( status < 0 ) {
+    return status;
+  }
 
-  /* Erase flash */
+  /* Erase flash, not fragmented as the driver might want to use even
+   * a different erase size for speed
+   */
   status = ( *flash->erase )( flash, new_offset, erase_args_1->size );
   return status;
 }
diff --git a/testsuites/libtests/flashdev01/init.c b/testsuites/libtests/flashdev01/init.c
index 84e2c7859d..fd3bda769e 100644
--- a/testsuites/libtests/flashdev01/init.c
+++ b/testsuites/libtests/flashdev01/init.c
@@ -112,10 +112,26 @@ static void run_test(void) {
     fgets(buff, TEST_DATA_SIZE, file);
     rtems_test_assert(!strncmp(buff, test_string, sizeof(test_string)));
 
-    /* Test Erasing */
+    /* Test Erasing - this one must fail */
     e_args.offset = 0x0;
     e_args.size = PAGE_SIZE;
     status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &e_args);
+    rtems_test_assert(status);
+
+    /* Test Erasing - this one must fail */
+    e_args.offset = 0x1;
+    e_args.size = ERASE_BLOCK_SIZE;
+    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &e_args);
+    rtems_test_assert(status);
+
+    /* Test Erasing - this one must pass */
+    e_args.offset = 0x0;
+    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &e_args);
+    rtems_test_assert(!status);
+
+    /* Test Erasing - this one must pass */
+    e_args.size = 2*ERASE_BLOCK_SIZE;
+    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &e_args);
     rtems_test_assert(!status);
 
     fseek(file, 0x0, SEEK_SET);
-- 
2.34.1



More information about the devel mailing list