summaryrefslogtreecommitdiff
path: root/nuttx/drivers/bch/bchdev_driver.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-16 01:57:16 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-16 01:57:16 +0000
commit07d4b44782830707067d8955f8d8a4c69dccbd6f (patch)
tree6548d2d672b122aa2f308463a49f17184f9cdd15 /nuttx/drivers/bch/bchdev_driver.c
parentfd8cf5088ad9d355baa5bfad15617b0f2459a7a9 (diff)
downloadpx4-nuttx-07d4b44782830707067d8955f8d8a4c69dccbd6f.tar.gz
px4-nuttx-07d4b44782830707067d8955f8d8a4c69dccbd6f.tar.bz2
px4-nuttx-07d4b44782830707067d8955f8d8a4c69dccbd6f.zip
Flush dirty cache on close
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1250 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/drivers/bch/bchdev_driver.c')
-rw-r--r--nuttx/drivers/bch/bchdev_driver.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/nuttx/drivers/bch/bchdev_driver.c b/nuttx/drivers/bch/bchdev_driver.c
index 33e26032f..9f579bbab 100644
--- a/nuttx/drivers/bch/bchdev_driver.c
+++ b/nuttx/drivers/bch/bchdev_driver.c
@@ -102,9 +102,26 @@ struct file_operations bch_fops =
static int bch_open(FAR struct file *filp)
{
FAR struct inode *inode = filp->f_inode;
+ FAR struct bchlib_s *bch;
+ int ret;
DEBUGASSERT(inode && inode->i_private);
- return bchlib_incref((FAR struct bchlib_s *)inode->i_private);
+ bch = (FAR struct bchlib_s *)inode->i_private;
+
+ /* Increment the reference count */
+
+ bchlib_semtake(bch);
+ if (bch->refs == MAX_OPENCNT)
+ {
+ return -EMFILE;
+ }
+ else
+ {
+ bch->refs++;
+ }
+ bchlib_semgive(bch);
+
+ return ret;
}
/****************************************************************************
@@ -117,9 +134,32 @@ static int bch_open(FAR struct file *filp)
static int bch_close(FAR struct file *filp)
{
FAR struct inode *inode = filp->f_inode;
+ FAR struct bchlib_s *bch;
+ int ret;
DEBUGASSERT(inode && inode->i_private);
- return bchlib_decref((FAR struct bchlib_s *)inode->i_private);
+ bch = (FAR struct bchlib_s *)inode->i_private;
+
+ /* Flush any dirty pages remaining in the cache */
+
+ bchlib_semtake(bch);
+ (void)bchlib_flushsector(bch);
+
+ /* Decrement the reference count (I don't use bchlib_decref() because I
+ * want the entire close operation to be atomic wrt other driver operations.
+ */
+
+ if (bch->refs == 0)
+ {
+ ret = -EIO;
+ }
+ else
+ {
+ bch->refs--;
+ }
+ bchlib_semgive(bch);
+
+ return ret;
}
/****************************************************************************
@@ -192,15 +232,17 @@ static int bch_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
{
FAR struct bchlib_s **bchr = (FAR struct bchlib_s **)arg;
- if (!bchr)
+ bchlib_semtake(bch);
+ if (!bchr && bch->refs < 255)
{
ret = -EINVAL;
}
else
{
- ret = bchlib_incref(bch);
+ bch->refs++;
*bchr = bch;
}
+ bchlib_semgive(bch);
}
return ret;