mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-04 04:02:26 +00:00
tty/serial driver fixes for 6.11-rc3
Here are some small tty and serial driver fixes for reported problems for 6.11-rc3. Included in here are: - sc16is7xx serial driver fixes - uartclk bugfix for a divide by zero issue - conmakehash userspace build issue fix All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZri5gA8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylCCgCfS612Ty+xRL/CbTznTobArGq5hbMAoLT3hqkN 1Mi7sbRC//FiN2HOFc8I =x19f -----END PGP SIGNATURE----- Merge tag 'tty-6.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty Pull tty / serial driver fixes from Greg KH: "Here are some small tty and serial driver fixes for reported problems for 6.11-rc3. Included in here are: - sc16is7xx serial driver fixes - uartclk bugfix for a divide by zero issue - conmakehash userspace build issue fix All of these have been in linux-next for a while with no reported issues" * tag 'tty-6.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: tty: vt: conmakehash: cope with abs_srctree no longer in env serial: sc16is7xx: fix invalid FIFO access with special register set serial: sc16is7xx: fix TX fifo corruption serial: core: check uartclk for zero to avoid divide by zero
This commit is contained in:
commit
42b34a8de3
@ -327,6 +327,7 @@ struct sc16is7xx_one {
|
||||
struct kthread_work reg_work;
|
||||
struct kthread_delayed_work ms_work;
|
||||
struct sc16is7xx_one_config config;
|
||||
unsigned char buf[SC16IS7XX_FIFO_SIZE]; /* Rx buffer. */
|
||||
unsigned int old_mctrl;
|
||||
u8 old_lcr; /* Value before EFR access. */
|
||||
bool irda_mode;
|
||||
@ -340,7 +341,6 @@ struct sc16is7xx_port {
|
||||
unsigned long gpio_valid_mask;
|
||||
#endif
|
||||
u8 mctrl_mask;
|
||||
unsigned char buf[SC16IS7XX_FIFO_SIZE];
|
||||
struct kthread_worker kworker;
|
||||
struct task_struct *kworker_task;
|
||||
struct sc16is7xx_one p[];
|
||||
@ -592,6 +592,8 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
|
||||
SC16IS7XX_MCR_CLKSEL_BIT,
|
||||
prescaler == 1 ? 0 : SC16IS7XX_MCR_CLKSEL_BIT);
|
||||
|
||||
mutex_lock(&one->efr_lock);
|
||||
|
||||
/* Backup LCR and access special register set (DLL/DLH) */
|
||||
lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG);
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
|
||||
@ -606,24 +608,26 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
|
||||
/* Restore LCR and access to general register set */
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
|
||||
|
||||
mutex_unlock(&one->efr_lock);
|
||||
|
||||
return DIV_ROUND_CLOSEST((clk / prescaler) / 16, div);
|
||||
}
|
||||
|
||||
static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,
|
||||
unsigned int iir)
|
||||
{
|
||||
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
|
||||
struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
|
||||
unsigned int lsr = 0, bytes_read, i;
|
||||
bool read_lsr = (iir == SC16IS7XX_IIR_RLSE_SRC) ? true : false;
|
||||
u8 ch, flag;
|
||||
|
||||
if (unlikely(rxlen >= sizeof(s->buf))) {
|
||||
if (unlikely(rxlen >= sizeof(one->buf))) {
|
||||
dev_warn_ratelimited(port->dev,
|
||||
"ttySC%i: Possible RX FIFO overrun: %d\n",
|
||||
port->line, rxlen);
|
||||
port->icount.buf_overrun++;
|
||||
/* Ensure sanity of RX level */
|
||||
rxlen = sizeof(s->buf);
|
||||
rxlen = sizeof(one->buf);
|
||||
}
|
||||
|
||||
while (rxlen) {
|
||||
@ -636,10 +640,10 @@ static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,
|
||||
lsr = 0;
|
||||
|
||||
if (read_lsr) {
|
||||
s->buf[0] = sc16is7xx_port_read(port, SC16IS7XX_RHR_REG);
|
||||
one->buf[0] = sc16is7xx_port_read(port, SC16IS7XX_RHR_REG);
|
||||
bytes_read = 1;
|
||||
} else {
|
||||
sc16is7xx_fifo_read(port, s->buf, rxlen);
|
||||
sc16is7xx_fifo_read(port, one->buf, rxlen);
|
||||
bytes_read = rxlen;
|
||||
}
|
||||
|
||||
@ -672,7 +676,7 @@ static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,
|
||||
}
|
||||
|
||||
for (i = 0; i < bytes_read; ++i) {
|
||||
ch = s->buf[i];
|
||||
ch = one->buf[i];
|
||||
if (uart_handle_sysrq_char(port, ch))
|
||||
continue;
|
||||
|
||||
@ -690,10 +694,10 @@ static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,
|
||||
|
||||
static void sc16is7xx_handle_tx(struct uart_port *port)
|
||||
{
|
||||
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
|
||||
struct tty_port *tport = &port->state->port;
|
||||
unsigned long flags;
|
||||
unsigned int txlen;
|
||||
unsigned char *tail;
|
||||
|
||||
if (unlikely(port->x_char)) {
|
||||
sc16is7xx_port_write(port, SC16IS7XX_THR_REG, port->x_char);
|
||||
@ -718,8 +722,9 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
|
||||
txlen = 0;
|
||||
}
|
||||
|
||||
txlen = uart_fifo_out(port, s->buf, txlen);
|
||||
sc16is7xx_fifo_write(port, s->buf, txlen);
|
||||
txlen = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail, txlen);
|
||||
sc16is7xx_fifo_write(port, tail, txlen);
|
||||
uart_xmit_advance(port, txlen);
|
||||
|
||||
uart_port_lock_irqsave(port, &flags);
|
||||
if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
|
||||
|
@ -881,6 +881,14 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
|
||||
new_flags = (__force upf_t)new_info->flags;
|
||||
old_custom_divisor = uport->custom_divisor;
|
||||
|
||||
if (!(uport->flags & UPF_FIXED_PORT)) {
|
||||
unsigned int uartclk = new_info->baud_base * 16;
|
||||
/* check needs to be done here before other settings made */
|
||||
if (uartclk == 0) {
|
||||
retval = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
if (!capable(CAP_SYS_ADMIN)) {
|
||||
retval = -EPERM;
|
||||
if (change_irq || change_port ||
|
||||
|
@ -11,6 +11,8 @@
|
||||
* Copyright (C) 1995-1997 H. Peter Anvin
|
||||
*/
|
||||
|
||||
#include <libgen.h>
|
||||
#include <linux/limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sysexits.h>
|
||||
@ -76,8 +78,8 @@ static void addpair(int fp, int un)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *ctbl;
|
||||
const char *tblname, *rel_tblname;
|
||||
const char *abs_srctree;
|
||||
const char *tblname;
|
||||
char base_tblname[PATH_MAX];
|
||||
char buffer[65536];
|
||||
int fontlen;
|
||||
int i, nuni, nent;
|
||||
@ -102,16 +104,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
abs_srctree = getenv("abs_srctree");
|
||||
if (abs_srctree && !strncmp(abs_srctree, tblname, strlen(abs_srctree)))
|
||||
{
|
||||
rel_tblname = tblname + strlen(abs_srctree);
|
||||
while (*rel_tblname == '/')
|
||||
++rel_tblname;
|
||||
}
|
||||
else
|
||||
rel_tblname = tblname;
|
||||
|
||||
/* For now we assume the default font is always 256 characters. */
|
||||
fontlen = 256;
|
||||
|
||||
@ -253,6 +245,8 @@ int main(int argc, char *argv[])
|
||||
for ( i = 0 ; i < fontlen ; i++ )
|
||||
nuni += unicount[i];
|
||||
|
||||
strncpy(base_tblname, tblname, PATH_MAX);
|
||||
base_tblname[PATH_MAX - 1] = 0;
|
||||
printf("\
|
||||
/*\n\
|
||||
* Do not edit this file; it was automatically generated by\n\
|
||||
@ -264,7 +258,7 @@ int main(int argc, char *argv[])
|
||||
#include <linux/types.h>\n\
|
||||
\n\
|
||||
u8 dfont_unicount[%d] = \n\
|
||||
{\n\t", rel_tblname, fontlen);
|
||||
{\n\t", basename(base_tblname), fontlen);
|
||||
|
||||
for ( i = 0 ; i < fontlen ; i++ )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user