diff --git a/bsps/shared/dev/flash/flash_sim_flashdev.c b/bsps/shared/dev/flash/flash_sim_flashdev.c index ca4086cc93..fe1704cb7e 100644 --- a/bsps/shared/dev/flash/flash_sim_flashdev.c +++ b/bsps/shared/dev/flash/flash_sim_flashdev.c @@ -282,9 +282,7 @@ static int flash_sim_oob_read( uint64_t start_time = rtems_clock_get_uptime_nanoseconds(); struct nand_priv_data *flash_driver = (struct nand_priv_data *) flash->driver; struct flash_sim_flashdev_attributes *attr = &flash_driver->attr; - uint32_t page_index = offset / attr->page_size_bytes; - uint32_t oob_offset = page_index * attr->page_oob_bytes; - unsigned char *chunk = &flash_driver->oob[ oob_offset ]; + unsigned char *chunk = &flash_driver->oob[ offset ]; memcpy( buffer, chunk, size_of_buffer ); @@ -303,9 +301,7 @@ static int flash_sim_oob_write( uint64_t start_time = rtems_clock_get_uptime_nanoseconds(); struct nand_priv_data *flash_driver = (struct nand_priv_data *) flash->driver; struct flash_sim_flashdev_attributes *attr = &flash_driver->attr; - uint32_t page_index = offset / attr->page_size_bytes; - uint32_t oob_offset = page_index * attr->page_oob_bytes; - unsigned char *chunk = &flash_driver->oob[ oob_offset ]; + unsigned char *chunk = &flash_driver->oob[ offset ]; const uint8_t *cbuff = buffer; size_t i; diff --git a/bsps/shared/dev/flash/jffs2_flashdev.c b/bsps/shared/dev/flash/jffs2_flashdev.c index 3dbc31e78e..818d47272a 100644 --- a/bsps/shared/dev/flash/jffs2_flashdev.c +++ b/bsps/shared/dev/flash/jffs2_flashdev.c @@ -141,6 +141,36 @@ static int do_block_mark_bad( return ioctl(fd, RTEMS_FLASHDEV_IOCTL_REGION_SECTOR_MARK_BAD, &o_offset); } +static uint32_t do_get_oob_size( + rtems_jffs2_flash_control *super +) +{ + int rv; + int fd = fileno(get_flash_control( super )->handle); + size_t bytes_per_page = 0; + + rv = ioctl(fd, RTEMS_FLASHDEV_IOCTL_OOB_BYTES_PER_PAGE, &bytes_per_page); + + if (rv != 0) { + return 0; + } + + return bytes_per_page; +} + +static uint32_t page_offset_to_oob_offset( + rtems_jffs2_flash_control *super, + uint32_t page_offset +) +{ + uint32_t page_size = super->write_size; + uint32_t oob_bytes_per_page = do_get_oob_size(super); + uint32_t page_index = page_offset / page_size; + + /* JFFS2 only makes these requests on even page boundaries */ + return page_index * oob_bytes_per_page; +} + static int do_read_oob( rtems_jffs2_flash_control *super, uint32_t offset, @@ -151,7 +181,7 @@ static int do_read_oob( int fd = fileno(get_flash_control( super )->handle); rtems_flashdev_ioctl_oob_rw_info args; - args.offset = offset; + args.offset = page_offset_to_oob_offset(super, offset); args.count = ooblen; args.buffer = oobbuf; @@ -168,30 +198,13 @@ static int do_write_oob( int fd = fileno(get_flash_control( super )->handle); rtems_flashdev_ioctl_oob_rw_info args; - args.offset = offset; + args.offset = page_offset_to_oob_offset(super, offset); args.count = ooblen; args.buffer = oobbuf; return ioctl(fd, RTEMS_FLASHDEV_IOCTL_REGION_OOB_WRITE, &args); } -static uint32_t do_get_oob_size( - rtems_jffs2_flash_control *super -) -{ - int rv; - int fd = fileno(get_flash_control( super )->handle); - size_t bytes_per_page = 0; - - rv = ioctl(fd, RTEMS_FLASHDEV_IOCTL_OOB_BYTES_PER_PAGE, &bytes_per_page); - - if (rv != 0) { - return 0; - } - - return bytes_per_page; -} - static void do_destroy( rtems_jffs2_flash_control *super ) { flash_control *self = get_flash_control( super ); diff --git a/bsps/shared/dev/flash/xnandpsu_flashdev.c b/bsps/shared/dev/flash/xnandpsu_flashdev.c index cce1933b58..1655f1247c 100644 --- a/bsps/shared/dev/flash/xnandpsu_flashdev.c +++ b/bsps/shared/dev/flash/xnandpsu_flashdev.c @@ -331,8 +331,8 @@ static int xnandpsu_oob_read( return -EIO; } - /* Get page index */ - uint32_t PageIndex = offset / nandpsu->Geometry.BytesPerPage; + /* Get page index, offset is in oob-space */ + uint32_t PageIndex = offset / nandpsu->Geometry.SpareBytesPerPage; spare_bytes = rtems_malloc( SpareBytesPerPage ); if ( spare_bytes == NULL ) { @@ -402,8 +402,8 @@ static int xnandpsu_oob_write( memcpy( buffer, oobbuf, ooblen ); } - /* Get page index */ - uint32_t PageIndex = offset / nandpsu->Geometry.BytesPerPage; + /* Get page index, offset is in oob-space */ + uint32_t PageIndex = offset / nandpsu->Geometry.SpareBytesPerPage; sc = XNandPsu_WriteSpareBytes( nandpsu, PageIndex, buffer ); free( spare_bytes ); diff --git a/cpukit/dev/flash/flashdev.c b/cpukit/dev/flash/flashdev.c index 54138199db..57d9f4b957 100644 --- a/cpukit/dev/flash/flashdev.c +++ b/cpukit/dev/flash/flashdev.c @@ -1100,6 +1100,10 @@ static int get_region_first_page_index( return 0; } +/* + * This converts a region-relative OOB space offset to a device-global OOB + * space offset + */ static int rtems_flashdev_get_region_oob_addr( rtems_flashdev *flash, rtems_libio_t *iop, diff --git a/cpukit/include/dev/flash/flashdev.h b/cpukit/include/dev/flash/flashdev.h index 51b33e665c..282f9c2c90 100644 --- a/cpukit/include/dev/flash/flashdev.h +++ b/cpukit/include/dev/flash/flashdev.h @@ -337,7 +337,7 @@ typedef struct rtems_flashdev_ioctl_sector_health { */ typedef struct rtems_flashdev_ioctl_oob_rw_info { /** - * @brief Offset at which to operate. + * @brief Offset into contiguous OOB space at which to operate. */ off_t offset; @@ -552,6 +552,9 @@ struct rtems_flashdev { * @brief Call to the device driver to read the out of band space of the flash * device. * + * The offset specified is relative to a contiguous out of band space, not to + * normal data space. + * * @param[in] flash Pointer to flash device. * @param[in] offset Address to read from. * @param[in] count Number of bytes to read. @@ -571,6 +574,9 @@ struct rtems_flashdev { * @brief Call to the device driver to write to the out of band space of the * flash device. * + * The offset specified is relative to a contiguous out of band space, not to + * normal data space. + * * @param[in] flash Pointer to flash device. * @param[in] offset Address to write to. * @param[in] count Number of bytes to read.