diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-11-16 01:57:16 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-11-16 01:57:16 +0000 |
commit | 07d4b44782830707067d8955f8d8a4c69dccbd6f (patch) | |
tree | 6548d2d672b122aa2f308463a49f17184f9cdd15 /nuttx/drivers/bch/bchdev_driver.c | |
parent | fd8cf5088ad9d355baa5bfad15617b0f2459a7a9 (diff) | |
download | px4-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.c | 50 |
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; |