Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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;
}