static void rwb_wrflush(struct rwbuffer_s *rwb) { int ret; fvdbg("Timeout!\n"); rwb_semtake(&rwb->wrsem); if (rwb->wrnblocks > 0) { fvdbg("Flushing: blockstart=0x%08lx nblocks=%d from buffer=%p\n", (long)rwb->wrblockstart, rwb->wrnblocks, rwb->wrbuffer); /* Flush cache. On success, the flush method will return the number * of blocks written. Anything other than the number requested is * an error. */ ret = rwb->wrflush(rwb->dev, rwb->wrbuffer, rwb->wrblockstart, rwb->wrnblocks); if (ret != rwb->wrnblocks) { fdbg("ERROR: Error flushing write buffer: %d\n", ret); } rwb_resetwrbuffer(rwb); } rwb_semgive(&rwb->wrsem); }
static ssize_t rwb_writebuffer(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks, FAR const uint8_t *wrbuffer) { int ret; /* Write writebuffer Logic */ rwb_wrcanceltimeout(rwb); /* First: Should we flush out our cache? We would do that if (1) we already * buffering blocks and the next block writing is not in the same sequence, * or (2) the number of blocks would exceed our allocated buffer capacity */ if (((startblock != rwb->wrexpectedblock) && (rwb->wrnblocks)) || ((rwb->wrnblocks + nblocks) > rwb->wrmaxblocks)) { fvdbg("writebuffer miss, expected: %08x, given: %08x\n", rwb->wrexpectedblock, startblock); /* Flush the write buffer */ ret = rwb->wrflush(rwb, rwb->wrbuffer, rwb->wrblockstart, rwb->wrnblocks); if (ret < 0) { fdbg("ERROR: Error writing multiple from cache: %d\n", -ret); return ret; } rwb_resetwrbuffer(rwb); } /* writebuffer is empty? Then initialize it */ if (rwb->wrnblocks == 0) { fvdbg("Fresh cache starting at block: 0x%08x\n", startblock); rwb->wrblockstart = startblock; } /* Add data to cache */ fvdbg("writebuffer: copying %d bytes from %p to %p\n", nblocks * rwb->blocksize, wrbuffer, &rwb->wrbuffer[rwb->wrnblocks * rwb->blocksize]); memcpy(&rwb->wrbuffer[rwb->wrnblocks * rwb->blocksize], wrbuffer, nblocks * rwb->blocksize); rwb->wrnblocks += nblocks; rwb->wrexpectedblock = rwb->wrblockstart + rwb->wrnblocks; rwb_wrstarttimeout(rwb); return nblocks; }
int rwb_mediaremoved(FAR struct rwbuffer_s *rwb) { #ifdef CONFIG_FS_WRITEBUFFER rwb_semtake(&rwb->wrsem); rwb_resetwrbuffer(rwb); rwb_semgive(&rwb->wrsem); #endif #ifdef CONFIG_FS_READAHEAD rwb_semtake(&rwb->rhsem); rwb_resetrhbuffer(rwb); rwb_semgive(&rwb->rhsem); #endif return 0; }
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 (rwb->rhmaxblocks > 0) { rwb_semtake(&rwb->rhsem); rwb_resetrhbuffer(rwb); rwb_semgive(&rwb->rhsem); } #endif return OK; }
int rwb_initialize(FAR struct rwbuffer_s *rwb) { uint32_t allocsize; /* Sanity checking */ DEBUGASSERT(rwb != NULL); DEBUGASSERT(rwb->blocksize > 0); DEBUGASSERT(rwb->nblocks > 0); DEBUGASSERT(rwb->dev != NULL); /* Setup so that rwb_uninitialize can handle a failure */ #ifdef CONFIG_DRVR_WRITEBUFFER DEBUGASSERT(rwb->wrflush!= NULL); rwb->wrbuffer = NULL; #endif #ifdef CONFIG_DRVR_READAHEAD DEBUGASSERT(rwb->rhreload != NULL); rwb->rhbuffer = NULL; #endif #ifdef CONFIG_DRVR_WRITEBUFFER if (rwb->wrmaxblocks > 0) { fvdbg("Initialize the write buffer\n"); /* Initialize the write buffer access semaphore */ sem_init(&rwb->wrsem, 0, 1); /* Initialize write buffer parameters */ rwb_resetwrbuffer(rwb); /* Allocate the write buffer */ rwb->wrbuffer = NULL; if (rwb->wrmaxblocks > 0) { allocsize = rwb->wrmaxblocks * rwb->blocksize; rwb->wrbuffer = kmm_malloc(allocsize); if (!rwb->wrbuffer) { fdbg("Write buffer kmm_malloc(%d) failed\n", allocsize); return -ENOMEM; } } fvdbg("Write buffer size: %d bytes\n", allocsize); } #endif /* CONFIG_DRVR_WRITEBUFFER */ #ifdef CONFIG_DRVR_READAHEAD if (rhmaxblocks > 0) { fvdbg("Initialize the read-ahead buffer\n"); /* Initialize the read-ahead buffer access semaphore */ sem_init(&rwb->rhsem, 0, 1); /* Initialize read-ahead buffer parameters */ rwb_resetrhbuffer(rwb); /* Allocate the read-ahead buffer */ rwb->rhbuffer = NULL; if (rwb->rhmaxblocks > 0) { allocsize = rwb->rhmaxblocks * rwb->blocksize; rwb->rhbuffer = kmm_malloc(allocsize); if (!rwb->rhbuffer) { fdbg("Read-ahead buffer kmm_malloc(%d) failed\n", allocsize); return -ENOMEM; } } fvdbg("Read-ahead buffer size: %d bytes\n", allocsize); } #endif /* CONFIG_DRVR_READAHEAD */ return OK; }