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