diff --git a/drivers/bch/bch_internal.h b/drivers/bch/bch.h similarity index 90% rename from drivers/bch/bch_internal.h rename to drivers/bch/bch.h index 653a2767b0..5463518349 100644 --- a/drivers/bch/bch_internal.h +++ b/drivers/bch/bch.h @@ -1,7 +1,7 @@ /**************************************************************************** - * drivers/bch/bch_internal.h + * drivers/bch/bch.h * - * Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __FS_BCH_INTERNAL_H -#define __FS_BCH_INTERNAL_H +#ifndef __DRIVERS_BCH_BCH_H +#define __DRIVERS_BCH_BCH_H /**************************************************************************** * Included Files @@ -67,8 +67,9 @@ struct bchlib_s size_t sector; /* The current sector in the buffer */ uint16_t sectsize; /* The size of one sector on the device */ uint8_t refs; /* Number of references */ - bool dirty; /* Data has been written to the buffer */ - bool readonly; /* true: Only read operations are supported */ + bool dirty; /* true: Data has been written to the buffer */ + bool readonly; /* true: Only read operations are supported */ + bool unlinked; /* true: The driver has been unlinked */ FAR uint8_t *buffer; /* One sector buffer */ #if defined(CONFIG_BCH_ENCRYPTION) @@ -103,4 +104,4 @@ EXTERN int bchlib_readsector(FAR struct bchlib_s *bch, size_t sector); } #endif -#endif /* __FS_BCH_INTERNAL_H */ +#endif /* __DRIVERS_BCH_BCH_H */ diff --git a/drivers/bch/bchdev_driver.c b/drivers/bch/bchdev_driver.c index 14ee267d99..577128b039 100644 --- a/drivers/bch/bchdev_driver.c +++ b/drivers/bch/bchdev_driver.c @@ -58,7 +58,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Pre-processor Definitions @@ -77,6 +77,9 @@ static ssize_t bch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int bch_unlink(FAR struct inode *inode); +#endif /**************************************************************************** * Public Data @@ -84,14 +87,17 @@ static int bch_ioctl(FAR struct file *filep, int cmd, const struct file_operations bch_fops = { - bch_open, /* open */ - bch_close, /* close */ - bch_read, /* read */ - bch_write, /* write */ - bch_seek, /* seek */ - bch_ioctl /* ioctl */ + bch_open, /* open */ + bch_close, /* close */ + bch_read, /* read */ + bch_write, /* write */ + bch_seek, /* seek */ + bch_ioctl /* ioctl */ #ifndef CONFIG_DISABLE_POLL - , 0 /* poll */ + , 0 /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , bch_unlink /* unlink */ #endif }; @@ -152,7 +158,8 @@ static int bch_close(FAR struct file *filep) (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. + * want the entire close operation to be atomic wrt other driver + * operations. */ if (bch->refs == 0) @@ -162,6 +169,30 @@ static int bch_close(FAR struct file *filep) else { bch->refs--; + + /* If the reference count decremented to zero AND if the character + * driver has been unlinked, then teardown the BCH device now. + */ + + if (bch->refs == 0 && bch->unlinked) + { + /* Tear the driver down now. */ + + ret = bchlib_teardown((FAR void *)bch); + + /* bchlib_teardown() would only fail if there are outstanding + * references on the device. Since we know that is not true, it + * should not fail at all. + */ + + DEBUGASSERT(ret >= 0); + if (ret >= 0) + { + /* Return without releasing the stale semaphore */ + + return OK; + } + } } bchlib_semgive(bch); @@ -349,6 +380,59 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg) return ret; } +/**************************************************************************** + * Name: bch_unlink + * + * Handle unlinking of the BCH device + * + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int bch_unlink(FAR struct inode *inode) +{ + FAR struct bchlib_s *bch; + int ret = OK; + + DEBUGASSERT(inode && inode->i_private); + bch = (FAR struct bchlib_s *)inode->i_private; + + /* Get exclusive access to the BCH device */ + + bchlib_semtake(bch); + + /* Indicate that the driver has been unlinked */ + + bch->unlinked = true; + + /* If there are no open references to the drvier then teardown the BCH + * device now. + */ + + if (bch->refs == 0) + { + /* Tear the driver down now. */ + + ret = bchlib_teardown((FAR void *)bch); + + /* bchlib_teardown() would only fail if there are outstanding + * references on the device. Since we know that is not true, it + * should not fail at all. + */ + + DEBUGASSERT(ret >= 0); + if (ret >= 0) + { + /* Return without releasing the stale semaphore */ + + return OK; + } + } + + bchlib_semgive(bch); + return ret; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/drivers/bch/bchdev_register.c b/drivers/bch/bchdev_register.c index 924977371e..139c292576 100644 --- a/drivers/bch/bchdev_register.c +++ b/drivers/bch/bchdev_register.c @@ -44,7 +44,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Pre-processor Definitions diff --git a/drivers/bch/bchdev_unregister.c b/drivers/bch/bchdev_unregister.c index 8c7360882b..0c6a35d4b1 100644 --- a/drivers/bch/bchdev_unregister.c +++ b/drivers/bch/bchdev_unregister.c @@ -52,7 +52,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Pre-processor Definitions diff --git a/drivers/bch/bchlib_cache.c b/drivers/bch/bchlib_cache.c index 009a3eb631..8ad543b4b0 100644 --- a/drivers/bch/bchlib_cache.c +++ b/drivers/bch/bchlib_cache.c @@ -47,7 +47,7 @@ #include -#include "bch_internal.h" +#include "bch.h" #if defined(CONFIG_BCH_ENCRYPTION) # include diff --git a/drivers/bch/bchlib_read.c b/drivers/bch/bchlib_read.c index e275d5943b..d534d84919 100644 --- a/drivers/bch/bchlib_read.c +++ b/drivers/bch/bchlib_read.c @@ -48,7 +48,7 @@ #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Private Types diff --git a/drivers/bch/bchlib_sem.c b/drivers/bch/bchlib_sem.c index 1698ed0a54..ff221d934f 100644 --- a/drivers/bch/bchlib_sem.c +++ b/drivers/bch/bchlib_sem.c @@ -43,7 +43,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Pre-processor Definitions diff --git a/drivers/bch/bchlib_setup.c b/drivers/bch/bchlib_setup.c index 8dfcbbbf5b..6ec7a878a6 100644 --- a/drivers/bch/bchlib_setup.c +++ b/drivers/bch/bchlib_setup.c @@ -52,7 +52,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Private Types diff --git a/drivers/bch/bchlib_teardown.c b/drivers/bch/bchlib_teardown.c index 8d1f45ed9b..d97d3b8ffc 100644 --- a/drivers/bch/bchlib_teardown.c +++ b/drivers/bch/bchlib_teardown.c @@ -47,7 +47,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Private Types diff --git a/drivers/bch/bchlib_write.c b/drivers/bch/bchlib_write.c index 2336b11dda..b1636c6d45 100644 --- a/drivers/bch/bchlib_write.c +++ b/drivers/bch/bchlib_write.c @@ -49,7 +49,7 @@ #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Private Types