I thought that erase size was in the page information returned by the
relevant IOCTLs, but I apparently overlooked that. You'll need to implement
this similarly to how the page information retrieval is implemented or
possibly merge block/sector information in with that returned data. IIRC,
NOR devices can have different erase sizes depending on where you are in
the device which is why the page information is implemented based on
offset/index.

Kinsey

On Thu, Jan 4, 2024 at 12:35 PM <berndmoessne...@gmail.com> wrote:

> From: Bernd Moessner <berndmoessne...@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
>
> _______________________________________________
> devel mailing list
> devel@rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to