diff options
Diffstat (limited to 'nuttx/drivers/rwbuffer.c')
-rw-r--r-- | nuttx/drivers/rwbuffer.c | 601 |
1 files changed, 452 insertions, 149 deletions
diff --git a/nuttx/drivers/rwbuffer.c b/nuttx/drivers/rwbuffer.c index 0435440dd..c54277ddb 100644 --- a/nuttx/drivers/rwbuffer.c +++ b/nuttx/drivers/rwbuffer.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/rwbuffer.c * - * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011, 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -54,7 +54,7 @@ #include <nuttx/wqueue.h> #include <nuttx/rwbuffer.h> -#if defined(CONFIG_FS_WRITEBUFFER) || defined(CONFIG_FS_READAHEAD) +#if defined(CONFIG_DRVR_WRITEBUFFER) || defined(CONFIG_DRVR_READAHEAD) /**************************************************************************** * Preprocessor Definitions @@ -66,8 +66,8 @@ # error "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)" #endif -#ifndef CONFIG_FS_WRDELAY -# define CONFIG_FS_WRDELAY 350 +#ifndef CONFIG_DRVR_WRDELAY +# define CONFIG_DRVR_WRDELAY 350 #endif /**************************************************************************** @@ -137,7 +137,7 @@ static inline bool rwb_overlap(off_t blockstart1, size_t nblocks1, * Name: rwb_resetwrbuffer ****************************************************************************/ -#ifdef CONFIG_FS_WRITEBUFFER +#ifdef CONFIG_DRVR_WRITEBUFFER static inline void rwb_resetwrbuffer(struct rwbuffer_s *rwb) { /* We assume that the caller holds the wrsem */ @@ -152,7 +152,7 @@ static inline void rwb_resetwrbuffer(struct rwbuffer_s *rwb) * Name: rwb_wrflush ****************************************************************************/ -#ifdef CONFIG_FS_WRITEBUFFER +#ifdef CONFIG_DRVR_WRITEBUFFER static void rwb_wrflush(struct rwbuffer_s *rwb) { int ret; @@ -160,7 +160,7 @@ static void rwb_wrflush(struct rwbuffer_s *rwb) fvdbg("Timeout!\n"); rwb_semtake(&rwb->wrsem); - if (rwb->wrnblocks) + if (rwb->wrnblocks > 0) { fvdbg("Flushing: blockstart=0x%08lx nblocks=%d from buffer=%p\n", (long)rwb->wrblockstart, rwb->wrnblocks, rwb->wrbuffer); @@ -208,11 +208,11 @@ static void rwb_wrtimeout(FAR void *arg) static void rwb_wrstarttimeout(FAR struct rwbuffer_s *rwb) { - /* CONFIG_FS_WRDELAY provides the delay period in milliseconds. CLK_TCK + /* CONFIG_DRVR_WRDELAY provides the delay period in milliseconds. CLK_TCK * provides the clock tick of the system (frequency in Hz). */ - int ticks = (CONFIG_FS_WRDELAY + CLK_TCK/2) / CLK_TCK; + int ticks = (CONFIG_DRVR_WRDELAY + CLK_TCK/2) / CLK_TCK; (void)work_queue(LPWORK, &rwb->work, rwb_wrtimeout, (FAR void *)rwb, ticks); } @@ -229,7 +229,7 @@ static inline void rwb_wrcanceltimeout(struct rwbuffer_s *rwb) * Name: rwb_writebuffer ****************************************************************************/ -#ifdef CONFIG_FS_WRITEBUFFER +#ifdef CONFIG_DRVR_WRITEBUFFER static ssize_t rwb_writebuffer(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks, FAR const uint8_t *wrbuffer) @@ -265,7 +265,7 @@ static ssize_t rwb_writebuffer(FAR struct rwbuffer_s *rwb, /* writebuffer is empty? Then initialize it */ - if (!rwb->wrnblocks) + if (rwb->wrnblocks == 0) { fvdbg("Fresh cache starting at block: 0x%08x\n", startblock); rwb->wrblockstart = startblock; @@ -290,7 +290,7 @@ static ssize_t rwb_writebuffer(FAR struct rwbuffer_s *rwb, * Name: rwb_resetrhbuffer ****************************************************************************/ -#ifdef CONFIG_FS_READAHEAD +#ifdef CONFIG_DRVR_READAHEAD static inline void rwb_resetrhbuffer(struct rwbuffer_s *rwb) { /* We assume that the caller holds the readAheadBufferSemphore */ @@ -304,7 +304,7 @@ static inline void rwb_resetrhbuffer(struct rwbuffer_s *rwb) * Name: rwb_bufferread ****************************************************************************/ -#ifdef CONFIG_FS_READAHEAD +#ifdef CONFIG_DRVR_READAHEAD static inline void rwb_bufferread(struct rwbuffer_s *rwb, off_t startblock, size_t nblocks, uint8_t **rdbuffer) @@ -338,7 +338,7 @@ rwb_bufferread(struct rwbuffer_s *rwb, off_t startblock, * Name: rwb_rhreload ****************************************************************************/ -#ifdef CONFIG_FS_READAHEAD +#ifdef CONFIG_DRVR_READAHEAD static int rwb_rhreload(struct rwbuffer_s *rwb, off_t startblock) { /* Get the block number +1 of the last block that will fit in the @@ -382,6 +382,231 @@ static int rwb_rhreload(struct rwbuffer_s *rwb, off_t startblock) #endif /**************************************************************************** + * Name: rwb_invalidate_writebuffer + * + * Description: + * Invalidate a region of the write buffer + * + ****************************************************************************/ + +#ifdef CONFIG_DRVR_WRITEBUFFER +int rwb_invalidate_writebuffer(FAR struct rwbuffer_s *rwb, + off_t startblock, size_t blockcount) +{ + int ret; + + if (rwb->wrmaxblocks > 0 && wrnblocks > 0) + { + off_t wrbend; + off_t invend; + + fvdbg("startblock=%d blockcount=%p\n", startblock, blockcount); + + rwb_semtake(&rwb->wrsem); + + /* Now there are five cases: + * + * 1. We invalidate nothing + */ + + wrbend = rwb->wrblockstart + rwb->wrnblocks; + invend = startblock + blockcount; + + if (rwb->wrblockstart > invend || wrbend < startblock) + { + ret = OK; + } + + /* 2. We invalidate the entire write buffer. */ + + else if (rwb->wrblockstart >= startblock && wrbend <= invend) + { + rwb->wrnblocks = 0; + ret = OK; + } + + /* We are going to invalidate a subset of the write buffer. Three + * more cases to consider: + * + * 2. We invalidate a portion in the middle of the write buffer + */ + + else if (rwb->wrblockstart < startblock && wrbend > invend) + { + uint8_t *src; + off_t block; + off_t offset; + size_t nblocks; + + /* Write the blocks at the end of the media to hardware */ + + nblocks = wrbend - invend; + block = invend; + offset = block - rwb->wrblockstart; + src = rwb->wrbuffer + offset * rwb->blocksize; + + ret = rwb->wrflush(rwb->dev, block, nblocks, src); + if (ret < 0) + { + fdbg("ERROR: wrflush failed: %d\n", ret); + } + + /* Keep the blocks at the beginning of the buffer up the + * start of the invalidated region. + */ + else + { + rwb->wrnblocks = startblock - rwb->wrblockstart; + ret = OK; + } + } + + /* 3. We invalidate a portion at the end of the write buffer */ + + else if (wrbend > startblock && wrbend <= invend) + { + rwb->wrnblocks = wrbend - startblock; + ret = OK; + } + + /* 4. We invalidate a portion at the beginning of the write buffer */ + + else /* if (rwb->wrblockstart >= startblock && wrbend < invend) */ + { + uint8_t *src; + size_t ninval; + size_t nkeep; + + DEBUGASSERT(rwb->wrblockstart >= startblock && wrbend < invend); + + /* Copy the data from the uninvalidated region to the beginning + * of the write buffer. + * + * First calculate the source and destination of the transfer. + */ + + ninval = invend - rwb->wrblockstart; + src = rwb->wrbuffer + ninval * rwb->blocksize; + + /* Calculate the number of blocks we are keeping. We keep + * the ones that we don't invalidate. + */ + + nkeep = rwb->wrnblocks - ninval; + + /* Then move the data that we are keeping to the beginning + * the write buffer. + */ + + memcpy(rwb->wrbuffer, src, nkeep * rwb->blocksize); + + /* Update the block info. The first block is now the one just + * after the invalidation region and the number buffered blocks + * is the number that we kept. + */ + + rwb->wrblockstart = invend; + rwb->wrnblocks = nkeep; + ret = OK; + } + + rwb_semgive(&rwb->wrsem); + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: rwb_invalidate_readahead + * + * Description: + * Invalidate a region of the read-ahead buffer + * + ****************************************************************************/ + +#ifdef CONFIG_DRVR_READAHEAD +int rwb_invalidate_readahead(FAR struct rwbuffer_s *rwb, + off_t startblock, size_t blockcount) +{ + int ret; + + if (rwb->rhmaxblocks > 0 && rhnblocks > 0) + { + off_t rhbend; + off_t invend; + + fvdbg("startblock=%d blockcount=%p\n", startblock, blockcount); + + rwb_semtake(&rwb->rhsem); + + /* Now there are five cases: + * + * 1. We invalidate nothing + */ + + rhbend = rwb->rhblockstart + rwb->rhnblocks; + invend = startblock + blockcount; + + if (rwb->rhblockstart > invend || rhbend < startblock) + { + ret = OK; + } + + /* 2. We invalidate the entire read-ahead buffer. */ + + else if (rwb->rhblockstart >= startblock && rhbend <= invend) + { + rwb->rhnblocks = 0; + ret = OK; + } + + /* We are going to invalidate a subset of the read-ahead buffer. + * Three more cases to consider: + * + * 2. We invalidate a portion in the middle of the write buffer + */ + + else if (rwb->rhblockstart < startblock && rhbend > invend) + { + /* Keep the blocks at the beginning of the buffer up the + * start of the invalidated region. + */ + + rwb->rhnblocks = startblock - rwb->rhblockstart; + ret = OK; + } + + /* 3. We invalidate a portion at the end of the read-ahead buffer */ + + else if (rhbend > startblock && rhbend <= invend) + { + rwb->rhnblocks = rhbend - startblock; + ret = OK; + } + + /* 4. We invalidate a portion at the beginning of the write buffer */ + + else /* if (rwb->rhblockstart >= startblock && rhbend < invend) */ + { + /* Let's just force the whole read-ahead buffer to be reloaded. + * That might cost s small amount of performance, but well worth + * the lower complexity. + */ + + DEBUGASSERT(rwb->rhblockstart >= startblock && rhbend < invend); + rwb->rhnblocks = 0; + ret = OK; + } + + rwb_semgive(&rwb->rhsem); + } + + return ret; +} +#endif + +/**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** @@ -401,71 +626,78 @@ int rwb_initialize(FAR struct rwbuffer_s *rwb) /* Setup so that rwb_uninitialize can handle a failure */ -#ifdef CONFIG_FS_WRITEBUFFER +#ifdef CONFIG_DRVR_WRITEBUFFER DEBUGASSERT(rwb->wrflush!= NULL); rwb->wrbuffer = NULL; #endif -#ifdef CONFIG_FS_READAHEAD +#ifdef CONFIG_DRVR_READAHEAD DEBUGASSERT(rwb->rhreload != NULL); rwb->rhbuffer = NULL; #endif -#ifdef CONFIG_FS_WRITEBUFFER - fvdbg("Initialize the write buffer\n"); +#ifdef CONFIG_DRVR_WRITEBUFFER + if (rwb->wrmaxblocks > 0) + { + fvdbg("Initialize the write buffer\n"); - /* Initialize the write buffer access semaphore */ + /* Initialize the write buffer access semaphore */ - sem_init(&rwb->wrsem, 0, 1); + sem_init(&rwb->wrsem, 0, 1); - /* Initialize write buffer parameters */ + /* Initialize write buffer parameters */ - rwb_resetwrbuffer(rwb); + rwb_resetwrbuffer(rwb); - /* Allocate the write buffer */ + /* Allocate the write buffer */ - rwb->wrbuffer = NULL; - if (rwb->wrmaxblocks > 0) - { - allocsize = rwb->wrmaxblocks * rwb->blocksize; - rwb->wrbuffer = kmalloc(allocsize); - if (!rwb->wrbuffer) + rwb->wrbuffer = NULL; + if (rwb->wrmaxblocks > 0) { - fdbg("Write buffer kmalloc(%d) failed\n", allocsize); - return -ENOMEM; + allocsize = rwb->wrmaxblocks * rwb->blocksize; + rwb->wrbuffer = kmalloc(allocsize); + if (!rwb->wrbuffer) + { + fdbg("Write buffer kmalloc(%d) failed\n", allocsize); + return -ENOMEM; + } } - } - fvdbg("Write buffer size: %d bytes\n", allocsize); -#endif /* CONFIG_FS_WRITEBUFFER */ + fvdbg("Write buffer size: %d bytes\n", allocsize); + } +#endif /* CONFIG_DRVR_WRITEBUFFER */ -#ifdef CONFIG_FS_READAHEAD - fvdbg("Initialize the read-ahead buffer\n"); +#ifdef CONFIG_DRVR_READAHEAD + if (rhmaxblocks > 0) + { + fvdbg("Initialize the read-ahead buffer\n"); - /* Initialize the read-ahead buffer access semaphore */ + /* Initialize the read-ahead buffer access semaphore */ - sem_init(&rwb->rhsem, 0, 1); + sem_init(&rwb->rhsem, 0, 1); - /* Initialize read-ahead buffer parameters */ + /* Initialize read-ahead buffer parameters */ - rwb_resetrhbuffer(rwb); + rwb_resetrhbuffer(rwb); - /* Allocate the read-ahead buffer */ + /* Allocate the read-ahead buffer */ - rwb->rhbuffer = NULL; - if (rwb->rhmaxblocks > 0) - { - allocsize = rwb->rhmaxblocks * rwb->blocksize; - rwb->rhbuffer = kmalloc(allocsize); - if (!rwb->rhbuffer) + rwb->rhbuffer = NULL; + if (rwb->rhmaxblocks > 0) { - fdbg("Read-ahead buffer kmalloc(%d) failed\n", allocsize); - return -ENOMEM; + allocsize = rwb->rhmaxblocks * rwb->blocksize; + rwb->rhbuffer = kmalloc(allocsize); + if (!rwb->rhbuffer) + { + fdbg("Read-ahead buffer kmalloc(%d) failed\n", allocsize); + return -ENOMEM; + } } + + fvdbg("Read-ahead buffer size: %d bytes\n", allocsize); } +#endif /* CONFIG_DRVR_READAHEAD */ - fvdbg("Read-ahead buffer size: %d bytes\n", allocsize); -#endif /* CONFIG_FS_READAHEAD */ - return 0; + return OK; } /**************************************************************************** @@ -474,20 +706,26 @@ int rwb_initialize(FAR struct rwbuffer_s *rwb) void rwb_uninitialize(FAR struct rwbuffer_s *rwb) { -#ifdef CONFIG_FS_WRITEBUFFER - rwb_wrcanceltimeout(rwb); - sem_destroy(&rwb->wrsem); - if (rwb->wrbuffer) +#ifdef CONFIG_DRVR_WRITEBUFFER + if (rwb->wrmaxblocks > 0) { - kfree(rwb->wrbuffer); + rwb_wrcanceltimeout(rwb); + sem_destroy(&rwb->wrsem); + if (rwb->wrbuffer) + { + kfree(rwb->wrbuffer); + } } #endif -#ifdef CONFIG_FS_READAHEAD - sem_destroy(&rwb->rhsem); - if (rwb->rhbuffer) +#ifdef CONFIG_DRVR_READAHEAD + if (rhmaxblocks > 0) { - kfree(rwb->rhbuffer); + sem_destroy(&rwb->rhsem); + if (rwb->rhbuffer) + { + kfree(rwb->rhbuffer); + } } #endif } @@ -504,7 +742,7 @@ int rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks, fvdbg("startblock=%ld nblocks=%ld rdbuffer=%p\n", (long)startblock, (long)nblocks, rdbuffer); -#ifdef CONFIG_FS_WRITEBUFFER +#ifdef CONFIG_DRVR_WRITEBUFFER /* If the new read data overlaps any part of the write buffer, then * flush the write data onto the physical media before reading. We * could attempt some more exotic handling -- but this simple logic @@ -522,74 +760,86 @@ int rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks, { rwb_wrflush(rwb); } + rwb_semgive(&rwb->wrsem); } #endif -#ifdef CONFIG_FS_READAHEAD - /* Loop until we have read all of the requested blocks */ - - rwb_semtake(&rwb->rhsem); - for (remaining = nblocks; remaining > 0;) +#ifdef CONFIG_DRVR_READAHEAD + if (rhmaxblocks > 0) { - /* Is there anything in the read-ahead buffer? */ + /* Loop until we have read all of the requested blocks */ - if (rwb->rhnblocks > 0) + rwb_semtake(&rwb->rhsem); + for (remaining = nblocks; remaining > 0;) { - off_t startblock = startblock; - size_t nbufblocks = 0; - off_t bufferend; + /* Is there anything in the read-ahead buffer? */ - /* Loop for each block we find in the read-head buffer. Count the - * number of buffers that we can read from read-ahead buffer. - */ + if (rwb->rhnblocks > 0) + { + off_t startblock = startblock; + size_t nbufblocks = 0; + off_t bufferend; - bufferend = rwb->rhblockstart + rwb->rhnblocks; + /* Loop for each block we find in the read-head buffer. Count + * the number of buffers that we can read from read-ahead + * buffer. + */ - while ((startblock >= rwb->rhblockstart) && - (startblock < bufferend) && - (remaining > 0)) - { - /* This is one more that we will read from the read ahead buffer */ + bufferend = rwb->rhblockstart + rwb->rhnblocks; - nbufblocks++; + while ((startblock >= rwb->rhblockstart) && + (startblock < bufferend) && + (remaining > 0)) + { + /* This is one more that we will read from the read ahead + * buffer. + */ - /* And one less that we will read from the media */ + nbufblocks++; - startblock++; - remaining--; - } + /* And one less that we will read from the media */ - /* Then read the data from the read-ahead buffer */ + startblock++; + remaining--; + } - rwb_bufferread(rwb, startblock, nbufblocks, &rdbuffer); - } + /* Then read the data from the read-ahead buffer */ - /* If we did not get all of the data from the buffer, then we have to refill - * the buffer and try again. - */ + rwb_bufferread(rwb, startblock, nbufblocks, &rdbuffer); + } - if (remaining > 0) - { - int ret = rwb_rhreload(rwb, startblock); - if (ret < 0) + /* If we did not get all of the data from the buffer, then we have + * to refill the buffer and try again. + */ + + if (remaining > 0) { - fdbg("ERROR: Failed to fill the read-ahead buffer: %d\n", -ret); - return ret; + int ret = rwb_rhreload(rwb, startblock); + if (ret < 0) + { + fdbg("ERROR: Failed to fill the read-ahead buffer: %d\n", ret); + return ret; + } } } - } - /* On success, return the number of blocks that we were requested to read. - * This is for compatibility with the normal return of a block driver read - * method - */ + /* On success, return the number of blocks that we were requested to + * read. This is for compatibility with the normal return of a block + * driver read method + */ - rwb_semgive(&rwb->rhsem); - return 0; + rwb_semgive(&rwb->rhsem); + ret = nblocks; + } + else #else - return rwb->rhreload(rwb->dev, startblock, nblocks, rdbuffer); + { + ret = rwb->rhreload(rwb->dev, startblock, nblocks, rdbuffer); + } #endif + + return ret; } /**************************************************************************** @@ -601,82 +851,135 @@ int rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock, { int ret; -#ifdef CONFIG_FS_READAHEAD - /* If the new write data overlaps any part of the read buffer, then - * flush the data from the read buffer. We could attempt some more - * exotic handling -- but this simple logic is well-suited for simple - * streaming applications. - */ - - rwb_semtake(&rwb->rhsem); - if (rwb_overlap(rwb->rhblockstart, rwb->rhnblocks, startblock, nblocks)) +#ifdef CONFIG_DRVR_READAHEAD + if (rhmaxblocks > 0) { - rwb_resetrhbuffer(rwb); + /* If the new write data overlaps any part of the read buffer, then + * flush the data from the read buffer. We could attempt some more + * exotic handling -- but this simple logic is well-suited for simple + * streaming applications. + */ + + rwb_semtake(&rwb->rhsem); + if (rwb_overlap(rwb->rhblockstart, rwb->rhnblocks, startblock, nblocks)) + { + rwb_resetrhbuffer(rwb); + } + + rwb_semgive(&rwb->rhsem); } - rwb_semgive(&rwb->rhsem); #endif -#ifdef CONFIG_FS_WRITEBUFFER - fvdbg("startblock=%d wrbuffer=%p\n", startblock, wrbuffer); +#ifdef CONFIG_DRVR_WRITEBUFFER + if (rwb->wrmaxblocks > 0) + { + fvdbg("startblock=%d wrbuffer=%p\n", startblock, wrbuffer); - /* Use the block cache unless the buffer size is bigger than block cache */ + /* Use the block cache unless the buffer size is bigger than block cache */ - if (nblocks > rwb->wrmaxblocks) - { - /* First flush the cache */ + if (nblocks > rwb->wrmaxblocks) + { + /* First flush the cache */ - rwb_semtake(&rwb->wrsem); - rwb_wrflush(rwb); - rwb_semgive(&rwb->wrsem); + rwb_semtake(&rwb->wrsem); + rwb_wrflush(rwb); + rwb_semgive(&rwb->wrsem); - /* Then transfer the data directly to the media */ + /* Then transfer the data directly to the media */ - ret = rwb->wrflush(rwb->dev, startblock, nblocks, wrbuffer); + ret = rwb->wrflush(rwb->dev, startblock, nblocks, wrbuffer); + } + else + { + /* Buffer the data in the write buffer */ + + ret = rwb_writebuffer(rwb, startblock, nblocks, wrbuffer); + } + + /* On success, return the number of blocks that we were requested to + * write. This is for compatibility with the normal return of a block + * driver write method + */ } else +#else { - /* Buffer the data in the write buffer */ + /* No write buffer.. just pass the write operation through via the + * flush callback. + */ - ret = rwb_writebuffer(rwb, startblock, nblocks, wrbuffer); + ret = rwb->wrflush(rwb->dev, startblock, nblocks, wrbuffer); } - /* On success, return the number of blocks that we were requested to write. - * This is for compatibility with the normal return of a block driver write - * method - */ +#endif return ret; +} -#else +/**************************************************************************** + * Name: rwb_mediaremoved + * + * Description: + * The following function is called when media is removed + * + ****************************************************************************/ - return rwb->wrflush(rwb->dev, startblock, nblocks, wrbuffer); +int rwb_mediaremoved(FAR struct rwbuffer_s *rwb) +{ +#ifdef CONFIG_DRVR_WRITEBUFFER + if (rwb->wrmaxblocks > 0) + { + rwb_semtake(&rwb->wrsem); + rwb_resetwrbuffer(rwb); + rwb_semgive(&rwb->wrsem); + } +#endif +#ifdef CONFIG_DRVR_READAHEAD + if (rhmaxblocks > 0) + { + rwb_semtake(&rwb->rhsem); + rwb_resetrhbuffer(rwb); + rwb_semgive(&rwb->rhsem); + } #endif + + return OK; } /**************************************************************************** - * Name: rwb_mediaremoved + * Name: rwb_invalidate * * Description: - * The following function is called when media is removed + * Invalidate a region of the caches * ****************************************************************************/ -int rwb_mediaremoved(FAR struct rwbuffer_s *rwb) +int rwb_invalidate(FAR struct rwbuffer_s *rwb, + off_t startblock, size_t blockcount) { -#ifdef CONFIG_FS_WRITEBUFFER - rwb_semtake(&rwb->wrsem); - rwb_resetwrbuffer(rwb); - rwb_semgive(&rwb->wrsem); + int ret; + +#ifdef CONFIG_DRVR_WRITEBUFFER + ret = rwb_invalidate_writebuffer(rwb, startblock, blockcount); + if (ret < 0) + { + fdbg("ERROR: rwb_invalidate_writebuffer failed: %d\n", ret); + return ret; + } #endif -#ifdef CONFIG_FS_READAHEAD - rwb_semtake(&rwb->rhsem); - rwb_resetrhbuffer(rwb); - rwb_semgive(&rwb->rhsem); +#ifdef CONFIG_DRVR_READAHEAD + ret = rwb_invalidate_readahead(rwb, startblock, blockcount); + if (ret < 0) + { + fdbg("ERROR: rwb_invalidate_readahead failed: %d\n", ret); + return ret; + } #endif - return 0; + + return OK; } -#endif /* CONFIG_FS_WRITEBUFFER || CONFIG_FS_READAHEAD */ +#endif /* CONFIG_DRVR_WRITEBUFFER || CONFIG_DRVR_READAHEAD */ |