diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index fbba8cbf9f..66b0260e98 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -156,7 +156,11 @@ static int ftl_open(FAR struct inode *inode) static int ftl_close(FAR struct inode *inode) { - finfo("Entry\n"); +#ifdef CONFIG_FTL_WRITEBUFFER + struct ftl_struct_s *dev = (struct ftl_struct_s *)inode->i_private; + rwb_flush(&dev->rwb); +#endif + return OK; } @@ -464,6 +468,8 @@ static int ftl_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) finfo("Entry\n"); DEBUGASSERT(inode && inode->i_private); + dev = (struct ftl_struct_s *)inode->i_private; + /* Only one block driver ioctl command is supported by this driver (and * that command is just passed on to the MTD driver in a slightly * different form). @@ -488,13 +494,18 @@ static int ftl_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) cmd = MTDIOC_XIPBASE; } +#ifdef CONFIG_FTL_WRITEBUFFER + else if (cmd == BIOC_FLUSH) + { + return rwb_flush(&dev->rwb); + } +#endif /* No other block driver ioctl commmands are not recognized by this * driver. Other possible MTD driver ioctl commands are passed through * to the MTD driver (unchanged). */ - dev = (struct ftl_struct_s *)inode->i_private; ret = MTD_IOCTL(dev->mtd, cmd, arg); if (ret < 0) { diff --git a/drivers/rwbuffer.c b/drivers/rwbuffer.c index 7020ecaa9f..e87fe5f51c 100644 --- a/drivers/rwbuffer.c +++ b/drivers/rwbuffer.c @@ -167,8 +167,6 @@ static void rwb_wrflush(struct rwbuffer_s *rwb) { int ret; - finfo("Timeout!\n"); - if (rwb->wrnblocks > 0) { finfo("Flushing: blockstart=0x%08lx nblocks=%d from buffer=%p\n", @@ -203,6 +201,8 @@ static void rwb_wrtimeout(FAR void *arg) FAR struct rwbuffer_s *rwb = (struct rwbuffer_s *)arg; DEBUGASSERT(rwb != NULL); + finfo("Timeout!\n"); + /* If a timeout elapses with with write buffer activity, this watchdog * handler function will be evoked on the thread of execution of the * worker thread. @@ -1123,5 +1123,25 @@ int rwb_invalidate(FAR struct rwbuffer_s *rwb, } #endif +/**************************************************************************** + * Name: rwb_flush + * + * Description: + * Flush the write buffer + * + ****************************************************************************/ + +#ifdef CONFIG_DRVR_WRITEBUFFER +int rwb_flush(FAR struct rwbuffer_s *rwb) +{ + rwb_semtake(&rwb->wrsem); + rwb_wrcanceltimeout(rwb); + rwb_wrflush(rwb); + rwb_semgive(&rwb->wrsem); + + return OK; +} +#endif + #endif /* CONFIG_DRVR_WRITEBUFFER || CONFIG_DRVR_READAHEAD */ diff --git a/include/nuttx/drivers/rwbuffer.h b/include/nuttx/drivers/rwbuffer.h index ebb45ab8a4..28bd70677c 100644 --- a/include/nuttx/drivers/rwbuffer.h +++ b/include/nuttx/drivers/rwbuffer.h @@ -202,6 +202,10 @@ int rwb_invalidate(FAR struct rwbuffer_s *rwb, off_t startblock, size_t blockcount); #endif +#ifdef CONFIG_DRVR_WRITEBUFFER +int rwb_flush(FAR struct rwbuffer_s *rwb); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h index 5b9005af3a..0e517350ad 100644 --- a/include/nuttx/fs/ioctl.h +++ b/include/nuttx/fs/ioctl.h @@ -257,6 +257,10 @@ * to return geometry. * OUT: Data return in user-provided * buffer. */ +#define BIOC_FLUSH _BIOC(0x000d) /* Flush the block device write buffer + * IN: None + * OUT: None (ioctl return value provides + * success/failure indication). */ /* NuttX MTD driver ioctl definitions ***************************************/