[PATCH rtems 08/14] Flashdev: Add IOCTL to get the erase size

berndmoessner80 at gmail.com berndmoessner80 at gmail.com
Tue Jan 2 20:45:29 UTC 2024


From: Bernd Moessner <berndmoessner80 at gmail.com>

---
 cpukit/dev/flash/flashdev.c                   | 24 +++++++++++++++
 cpukit/include/dev/flash/flashdev.h           | 21 +++++++++++++
 cpukit/libmisc/shell/main_flashdev.c          | 28 +++++++++++++++++
 testsuites/libtests/flashdev01/init.c         | 14 ++++++---
 .../libtests/flashdev01/test_flashdev.c       | 30 ++++++++++++++++++-
 .../libtests/flashdev01/test_flashdev.h       |  2 +-
 6 files changed, 113 insertions(+), 6 deletions(-)

diff --git a/cpukit/dev/flash/flashdev.c b/cpukit/dev/flash/flashdev.c
index f50d2235a1..2e6a2e3c19 100644
--- a/cpukit/dev/flash/flashdev.c
+++ b/cpukit/dev/flash/flashdev.c
@@ -129,6 +129,11 @@ static int rtems_flashdev_ioctl_get_min_write_size(
   void *arg
 );
 
+static int rtems_flashdev_ioctl_get_erase_size(
+  rtems_flashdev *flash,
+  void *arg
+);
+
 static int rtems_flashdev_get_addr(
   rtems_flashdev *flash,
   rtems_libio_t *iop,
@@ -420,6 +425,9 @@ static int rtems_flashdev_ioctl(
     case RTEMS_FLASHDEV_IOCTL_GET_MIN_WRITE_SIZE:
       err = rtems_flashdev_ioctl_get_min_write_size( flash, arg );
       break;
+    case RTEMS_FLASHDEV_IOCTL_GET_ERASE_SIZE:
+      err = rtems_flashdev_ioctl_get_erase_size( flash, arg );
+      break;
     default:
       err = EINVAL;
   }
@@ -545,6 +553,7 @@ static int rtems_flashdev_do_init(
   flash->get_page_info_by_index = NULL;
   flash->get_page_count = NULL;
   flash->get_min_write_size = NULL;
+  flash->get_erase_size = NULL;
   flash->region_table = NULL;
   return 0;
 }
@@ -901,6 +910,21 @@ static int rtems_flashdev_ioctl_get_min_write_size(
   }
 }
 
+static int rtems_flashdev_ioctl_get_erase_size(
+  rtems_flashdev *flash,
+  void *arg
+)
+{
+  if ( arg == NULL ) {
+    rtems_set_errno_and_return_minus_one( EINVAL );
+  }
+  if ( flash->get_erase_size == NULL ) {
+    return 0;
+  } else {
+    return ( *flash->get_erase_size )( flash, ( (size_t *) arg ) );
+  }
+}
+
 static uint32_t rtems_flashdev_find_unallocated_region(
   rtems_flashdev_region_table *region_table
 )
diff --git a/cpukit/include/dev/flash/flashdev.h b/cpukit/include/dev/flash/flashdev.h
index f6973df2a3..0b54fcc71e 100644
--- a/cpukit/include/dev/flash/flashdev.h
+++ b/cpukit/include/dev/flash/flashdev.h
@@ -144,6 +144,13 @@ typedef struct rtems_flashdev rtems_flashdev;
  */
 #define RTEMS_FLASHDEV_IOCTL_GET_MIN_WRITE_SIZE 10
 
+/**
+ * @brief Get the erase size supported by the driver.
+ *
+ * @param[out] count Integer containing the erase size.
+ */
+#define RTEMS_FLASHDEV_IOCTL_GET_ERASE_SIZE 11
+
 /**
  * @brief The maximum number of region limited file descriptors
  * allowed to be open at once.
@@ -364,6 +371,20 @@ struct rtems_flashdev {
     size_t *min_write_size
   );
 
+  /**
+   * @brief Call to device driver to return the erase size of the
+   * flash device.
+   *
+   * @param[out] erase_size The erase size of the flash device.
+   *
+   * @retval 0 Success.
+   * @retval non-zero Failed.
+   */
+  int ( *get_erase_size )(
+    rtems_flashdev *flashdev,
+    size_t *erase_size
+  );
+
   /**
    * @brief Destroys the flash device.
    *
diff --git a/cpukit/libmisc/shell/main_flashdev.c b/cpukit/libmisc/shell/main_flashdev.c
index 5851adfeef..e070642cca 100644
--- a/cpukit/libmisc/shell/main_flashdev.c
+++ b/cpukit/libmisc/shell/main_flashdev.c
@@ -41,6 +41,8 @@ static int flashdev_shell_get_page_by_off(char *dev_path, int argc, char *argv[]
 static int flashdev_shell_get_page_by_idx(char *dev_path, int argc, char *argv[]);
 static int flashdev_shell_get_pg_count(char *dev_path);
 static int flashdev_shell_get_min_write_size(char *dev_path);
+static int flashdev_shell_get_erase_size(char *dev_path);
+
 
 static int flashdev_shell_ioctl_value(
   char *dev_path,
@@ -68,6 +70,7 @@ static const char rtems_flashdev_shell_usage [] =
   "   -i <index>            Print the page information of page at index\n"
   "   -p                    Print the number of pages\n"
   "   -b                    Print the min. write size\n"
+  "   -z                    Print the erase size\n"
   "   -h                    Print this help\n";
 
 
@@ -115,6 +118,9 @@ static int rtems_flashdev_shell_main( int argc, char *argv[] ) {
       case ('b'):
         /* Get min write size */
         return flashdev_shell_get_min_write_size(dev_path);
+      case ('z'):
+        /* Get erase size */
+        return flashdev_shell_get_erase_size(dev_path);
       case ('h'):
       default:
         /* Help */
@@ -502,6 +508,28 @@ static int flashdev_shell_get_min_write_size( char *dev_path )
   return 0;
 }
 
+static int flashdev_shell_get_erase_size( char *dev_path )
+{
+  size_t ret;
+  int status;
+
+  /* Get Write Block Size */
+  status = flashdev_shell_ioctl_value(
+    dev_path,
+    RTEMS_FLASHDEV_IOCTL_GET_ERASE_SIZE,
+    &ret
+  );
+
+  /* Print Write Block Size */
+  if (status) {
+    printf("Failed to get erase size\n");
+    return status;
+  } else {
+    printf("Erase size: 0x%zx\n", ret);
+  }
+  return 0;
+}
+
 static int flashdev_shell_ioctl_value(
   char *dev_path,
   int ioctl_call,
diff --git a/testsuites/libtests/flashdev01/init.c b/testsuites/libtests/flashdev01/init.c
index dc174daa62..71ec4ae765 100644
--- a/testsuites/libtests/flashdev01/init.c
+++ b/testsuites/libtests/flashdev01/init.c
@@ -39,7 +39,7 @@
 #define TEST_DATA_SIZE (PAGE_SIZE * PAGE_COUNT)
 #define PAGE_COUNT 16
 #define PAGE_SIZE 128
-#define MIN_WRITE_SIZE 1
+#define ERASE_SIZE 4096
 
 const char rtems_test_name[] = "FLASHDEV 1";
 const char test_string[] = "My test string!";
@@ -62,13 +62,14 @@ static void run_test(void) {
   int page_count;
   int type;
   size_t min_write_size_in[] = {1,8,16};
-  size_t min_write_size_out;
+  size_t min_write_size_out = 0;
+  size_t erase_size = 0;
   const char flash_path[] = "/dev/flashdev0";
 
   for ( int loop = 0; loop <= 2; loop++)
   {
     /* Initalize the flash device driver and flashdev */
-    flash = test_flashdev_init(min_write_size_in[loop]);
+    flash = test_flashdev_init(min_write_size_in[loop], ERASE_SIZE);
     rtems_test_assert(flash != NULL);
 
     /* Register the flashdev as a device */
@@ -109,6 +110,11 @@ static void run_test(void) {
     fgets(buff, TEST_DATA_SIZE, file);
     rtems_test_assert(!strncmp(buff, test_string, sizeof(test_string)));
 
+    /* Test getting erase size */
+    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_ERASE_SIZE, &erase_size);
+    rtems_test_assert(!status);
+    rtems_test_assert(ERASE_SIZE == erase_size);
+
     /* Test Erasing */
     e_args.offset = 0x0;
     e_args.size = PAGE_SIZE;
@@ -166,7 +172,7 @@ static void run_test(void) {
   }
 
   /* Initalize the flash device driver and flashdev */
-  flash = test_flashdev_init(min_write_size_in[1]);
+  flash = test_flashdev_init(min_write_size_in[1], ERASE_SIZE);
   rtems_test_assert(flash != NULL);
 
   /* Register the flashdev as a device */
diff --git a/testsuites/libtests/flashdev01/test_flashdev.c b/testsuites/libtests/flashdev01/test_flashdev.c
index 0022210668..9b8d1dbba5 100644
--- a/testsuites/libtests/flashdev01/test_flashdev.c
+++ b/testsuites/libtests/flashdev01/test_flashdev.c
@@ -38,6 +38,7 @@
 #define NUM_BITALLOC ((MAX_NUM_REGIONS + BITALLOC_SIZE - 1) / BITALLOC_SIZE)
 
 static size_t g_min_write_size = 0;
+static size_t g_erase_size = 0;
 
 /**
  * This flash device driver is for testing flashdev
@@ -74,6 +75,11 @@ int test_flashdev_get_min_write_size(
   size_t *min_write_size
 );
 
+int test_flashdev_get_erase_size(
+  rtems_flashdev *flash,
+  size_t *erase_size
+);
+
 uint32_t test_flashdev_get_jedec_id(
   rtems_flashdev* flash
 );
@@ -149,6 +155,17 @@ int test_flashdev_get_min_write_size(
   return 0;
 }
 
+/* Get min. erase size handler */
+int test_flashdev_get_erase_size(
+  rtems_flashdev *flash,
+  size_t *erase_size
+)
+{
+  *erase_size = g_erase_size;
+  return 0;
+}
+
+
 /* JEDEC ID handler, this would normally require a READID
  * call to the physical flash device.
  */
@@ -231,13 +248,23 @@ int test_flashdev_erase(
 }
 
 /* Initialize Flashdev and underlying driver. */
-rtems_flashdev* test_flashdev_init(size_t min_write_size)
+rtems_flashdev* test_flashdev_init(size_t min_write_size, size_t erase_size)
 {
   if (0 == min_write_size) {
     return NULL;
   }
 
+  if (0 == erase_size) {
+    return NULL;
+  }
+
+  if (erase_size % min_write_size) {
+    return NULL;
+  }
+
   g_min_write_size = min_write_size;
+  g_erase_size = erase_size;
+
   rtems_flashdev *flash = rtems_flashdev_alloc_and_init(sizeof(rtems_flashdev));
 
   if (flash == NULL) {
@@ -275,6 +302,7 @@ rtems_flashdev* test_flashdev_init(size_t min_write_size)
   flash->get_page_info_by_index = &test_flashdev_get_page_by_index;
   flash->get_page_count = &test_flashdev_get_page_count;
   flash->get_min_write_size = &test_flashdev_get_min_write_size;
+  flash->get_erase_size = &test_flashdev_get_erase_size;
   flash->region_table = ftable;
 
   return flash;
diff --git a/testsuites/libtests/flashdev01/test_flashdev.h b/testsuites/libtests/flashdev01/test_flashdev.h
index ad995854ea..9c138331f5 100644
--- a/testsuites/libtests/flashdev01/test_flashdev.h
+++ b/testsuites/libtests/flashdev01/test_flashdev.h
@@ -30,7 +30,7 @@
 
 #include <dev/flash/flashdev.h>
 
-rtems_flashdev* test_flashdev_init(size_t min_write_size);
+rtems_flashdev* test_flashdev_init(size_t min_write_size, size_t erase_size);
 
 void test_flashdev_deinit(rtems_flashdev* flash);
 
-- 
2.34.1



More information about the devel mailing list