Commit 2754a42e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tty-5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial fixes from Greg KH:
 "Here are some small TTY and Serial driver fixes for reported issues
  for 5.10-rc2. They include:

   - vt ioctl bugfix for reported problems

   - fsl_lpuart serial driver fix

   - 21285 serial driver bugfix

  All have been in linux-next with no reported issues"

* tag 'tty-5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  vt_ioctl: fix GIO_UNIMAP regression
  vt: keyboard, extend func_buf_lock to readers
  vt: keyboard, simplify vt_kdgkbsent
  tty: serial: fsl_lpuart: LS1021A has a FIFO size of 16 words, like LS1028A
  tty: serial: 21285: fix lockup on open
parents 9b5ff3c9 d5465479
......@@ -50,25 +50,25 @@ static const char serial21285_name[] = "Footbridge UART";
static bool is_enabled(struct uart_port *port, int bit)
{
unsigned long private_data = (unsigned long)port->private_data;
unsigned long *private_data = (unsigned long *)&port->private_data;
if (test_bit(bit, &private_data))
if (test_bit(bit, private_data))
return true;
return false;
}
static void enable(struct uart_port *port, int bit)
{
unsigned long private_data = (unsigned long)port->private_data;
unsigned long *private_data = (unsigned long *)&port->private_data;
set_bit(bit, &private_data);
set_bit(bit, private_data);
}
static void disable(struct uart_port *port, int bit)
{
unsigned long private_data = (unsigned long)port->private_data;
unsigned long *private_data = (unsigned long *)&port->private_data;
clear_bit(bit, &private_data);
clear_bit(bit, private_data);
}
#define is_tx_enabled(port) is_enabled(port, tx_enabled_bit)
......
......@@ -314,9 +314,10 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
/* Forward declare this for the dma callbacks*/
static void lpuart_dma_tx_complete(void *arg);
static inline bool is_ls1028a_lpuart(struct lpuart_port *sport)
static inline bool is_layerscape_lpuart(struct lpuart_port *sport)
{
return sport->devtype == LS1028A_LPUART;
return (sport->devtype == LS1021A_LPUART ||
sport->devtype == LS1028A_LPUART);
}
static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport)
......@@ -1701,11 +1702,11 @@ static int lpuart32_startup(struct uart_port *port)
UARTFIFO_FIFOSIZE_MASK);
/*
* The LS1028A has a fixed length of 16 words. Although it supports the
* RX/TXSIZE fields their encoding is different. Eg the reference manual
* states 0b101 is 16 words.
* The LS1021A and LS1028A have a fixed FIFO depth of 16 words.
* Although they support the RX/TXSIZE fields, their encoding is
* different. Eg the reference manual states 0b101 is 16 words.
*/
if (is_ls1028a_lpuart(sport)) {
if (is_layerscape_lpuart(sport)) {
sport->rxfifo_size = 16;
sport->txfifo_size = 16;
sport->port.fifosize = sport->txfifo_size;
......
......@@ -743,8 +743,13 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
return;
if ((unsigned)value < ARRAY_SIZE(func_table)) {
unsigned long flags;
spin_lock_irqsave(&func_buf_lock, flags);
if (func_table[value])
puts_queue(vc, func_table[value]);
spin_unlock_irqrestore(&func_buf_lock, flags);
} else
pr_err("k_fn called with value=%d\n", value);
}
......@@ -1991,13 +1996,11 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
#undef s
#undef v
/* FIXME: This one needs untangling and locking */
/* FIXME: This one needs untangling */
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
{
struct kbsentry *kbs;
char *p;
u_char *q;
u_char __user *up;
int sz, fnw_sz;
int delta;
char *first_free, *fj, *fnw;
......@@ -2023,23 +2026,19 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
switch (cmd) {
case KDGKBSENT:
sz = sizeof(kbs->kb_string) - 1; /* sz should have been
a struct member */
up = user_kdgkb->kb_string;
p = func_table[i];
if(p)
for ( ; *p && sz; p++, sz--)
if (put_user(*p, up++)) {
ret = -EFAULT;
goto reterr;
}
if (put_user('\0', up)) {
ret = -EFAULT;
goto reterr;
}
kfree(kbs);
return ((p && *p) ? -EOVERFLOW : 0);
case KDGKBSENT: {
/* size should have been a struct member */
ssize_t len = sizeof(user_kdgkb->kb_string);
spin_lock_irqsave(&func_buf_lock, flags);
len = strlcpy(kbs->kb_string, func_table[i] ? : "", len);
spin_unlock_irqrestore(&func_buf_lock, flags);
ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string,
len + 1) ? -EFAULT : 0;
goto reterr;
}
case KDSKBSENT:
if (!perm) {
ret = -EPERM;
......
......@@ -549,7 +549,7 @@ static int vt_io_fontreset(struct console_font_op *op)
}
static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
struct vc_data *vc)
bool perm, struct vc_data *vc)
{
struct unimapdesc tmp;
......@@ -557,9 +557,11 @@ static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
return -EFAULT;
switch (cmd) {
case PIO_UNIMAP:
if (!perm)
return -EPERM;
return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
case GIO_UNIMAP:
if (fg_console != vc->vc_num)
if (!perm && fg_console != vc->vc_num)
return -EPERM;
return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
tmp.entries);
......@@ -639,10 +641,7 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
case PIO_UNIMAP:
case GIO_UNIMAP:
if (!perm)
return -EPERM;
return do_unimap_ioctl(cmd, up, vc);
return do_unimap_ioctl(cmd, up, perm, vc);
default:
return -ENOIOCTLCMD;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment