This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 7a97eef679b9a6ed80b914615180966a34dcd426 Author: fangzhenwei <[email protected]> AuthorDate: Thu Nov 2 11:55:47 2023 +0800 serial: use dev references count make sure the driver only opened once Signed-off-by: fangzhenwei <[email protected]> --- drivers/serial/uart_bth4.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/serial/uart_bth4.c b/drivers/serial/uart_bth4.c index 88301a68d8..45b2098ea0 100644 --- a/drivers/serial/uart_bth4.c +++ b/drivers/serial/uart_bth4.c @@ -59,6 +59,8 @@ struct uart_bth4_s uint8_t sendbuf[CONFIG_UART_BTH4_TXBUFSIZE]; size_t sendlen; mutex_t sendlock; + mutex_t openlock; + uint8_t refcnt; FAR struct pollfd *fds[CONFIG_UART_BTH4_NPOLLWAITERS]; }; @@ -173,14 +175,35 @@ static int uart_bth4_open(FAR struct file *filep) FAR struct inode *inode = filep->f_inode; FAR struct uart_bth4_s *dev = inode->i_private; int ret; + uint8_t tmp; - ret = dev->drv->open(dev->drv); + ret = nxmutex_lock(&dev->openlock); if (ret < 0) { return ret; } - dev->sendlen = 0; + tmp = dev->refcnt + 1; + if (tmp == 0) + { + nxmutex_unlock(&dev->openlock); + return -EMFILE; + } + + if (tmp == 1) + { + ret = dev->drv->open(dev->drv); + if (ret < 0) + { + nxmutex_unlock(&dev->openlock); + return ret; + } + + dev->sendlen = 0; + } + + dev->refcnt = tmp; + nxmutex_unlock(&dev->openlock); return OK; } @@ -190,9 +213,19 @@ static int uart_bth4_close(FAR struct file *filep) FAR struct inode *inode = filep->f_inode; FAR struct uart_bth4_s *dev = inode->i_private; - dev->drv->close(dev->drv); + nxmutex_lock(&dev->openlock); + if (dev->refcnt > 1) + { + dev->refcnt--; + nxmutex_unlock(&dev->openlock); + return OK; + } + dev->refcnt = 0; + dev->drv->close(dev->drv); uart_bth4_pollnotify(dev, POLLIN | POLLOUT); + nxmutex_unlock(&dev->openlock); + return OK; } @@ -436,12 +469,14 @@ int uart_bth4_register(FAR const char *path, FAR struct bt_driver_s *drv) drv->priv = dev; nxmutex_init(&dev->sendlock); + nxmutex_init(&dev->openlock); nxsem_init(&dev->recvsem, 0, 0); ret = register_driver(path, &g_uart_bth4_ops, 0666, dev); if (ret < 0) { nxmutex_destroy(&dev->sendlock); + nxmutex_destroy(&dev->openlock); nxsem_destroy(&dev->recvsem); circbuf_uninit(&dev->circbuf); kmm_free(dev);
