serial:need check old config before setting tty

Signed-off-by: zhangwenjian <zhangwenjian@xiaomi.com>
This commit is contained in:
zhangwenjian 2024-07-12 10:30:09 +08:00 committed by Xiang Xiao
parent df5c876932
commit 7532a0e833
1 changed files with 49 additions and 8 deletions

View File

@ -159,6 +159,45 @@ static struct work_s g_serial_work;
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: uart_is_termios_hw_change
*
* Description:
* Return true if the termios hw change
*
****************************************************************************/
static bool uart_is_termios_hw_change(FAR struct file *filep,
FAR const struct termios *new)
{
FAR struct inode *inode = filep->f_inode;
FAR uart_dev_t *dev = inode->i_private;
struct termios old;
int ret;
if (new == NULL)
{
return false;
}
memset(&old, 0, sizeof(old));
ret = dev->ops->ioctl(filep, TCGETS, (unsigned long)(uintptr_t)&old);
if (ret >= 0)
{
if (old.c_speed != new->c_speed)
{
return true;
}
if ((old.c_cflag ^ new->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
{
return true;
}
}
return false;
}
/****************************************************************************
* Name: uart_poll_notify
****************************************************************************/
@ -1444,12 +1483,20 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
FAR struct inode *inode = filep->f_inode;
FAR uart_dev_t *dev = inode->i_private;
FAR struct termios *termiosp = (FAR struct termios *)(uintptr_t)arg;
int ret = -ENOTTY;
/* Handle TTY-level IOCTLs here */
/* Let low-level driver handle the call first */
/* Let low-level driver handle the call first,
* but skip TCSETS if no hardware change.
*/
int ret = dev->ops->ioctl ? dev->ops->ioctl(filep, cmd, arg) : -ENOTTY;
if (dev->ops->ioctl && (cmd != TCSETS ||
uart_is_termios_hw_change(filep, termiosp)))
{
ret = dev->ops->ioctl(filep, cmd, arg);
}
/* The device ioctl() handler returns -ENOTTY when it doesn't know
* how to handle the command. Check if we can handle it here.
@ -1629,9 +1676,6 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
case TCGETS:
{
FAR struct termios *termiosp = (FAR struct termios *)
(uintptr_t)arg;
if (!termiosp)
{
ret = -EINVAL;
@ -1654,9 +1698,6 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
case TCSETS:
{
FAR struct termios *termiosp = (FAR struct termios *)
(uintptr_t)arg;
if (!termiosp)
{
ret = -EINVAL;