serial: use dev references count make sure the driver only opened once

Signed-off-by: fangzhenwei <fangzhenwei@xiaomi.com>
This commit is contained in:
fangzhenwei
2023-11-02 11:55:47 +08:00
committed by Xiang Xiao
parent dfbeba3536
commit 7a97eef679
+38 -3
View File
@@ -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);