tty: rework break handling
Some hardware needs to do break handling itself and may have partial support only. Make break_ctl return an error code. Add a tty driver flag so you can indicate driver hardware side break support. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
abbe629ae4
commit
9e98966c7b
20 changed files with 97 additions and 84 deletions
|
@ -218,7 +218,7 @@ config MOXA_SMARTIO
|
||||||
|
|
||||||
config ISI
|
config ISI
|
||||||
tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
|
tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
|
||||||
depends on SERIAL_NONSTANDARD && PCI
|
depends on SERIAL_NONSTANDARD && PCI && BROKEN
|
||||||
select FW_LOADER
|
select FW_LOADER
|
||||||
help
|
help
|
||||||
This is a driver for the Multi-Tech cards which provide several
|
This is a driver for the Multi-Tech cards which provide several
|
||||||
|
|
|
@ -1248,7 +1248,7 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
/*
|
/*
|
||||||
* rs_break() --- routine which turns the break handling on or off
|
* rs_break() --- routine which turns the break handling on or off
|
||||||
*/
|
*/
|
||||||
static void rs_break(struct tty_struct *tty, int break_state)
|
static int rs_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct async_struct * info = (struct async_struct *)tty->driver_data;
|
struct async_struct * info = (struct async_struct *)tty->driver_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -1263,6 +1263,7 @@ static void rs_break(struct tty_struct *tty, int break_state)
|
||||||
custom.adkcon = AC_UARTBRK;
|
custom.adkcon = AC_UARTBRK;
|
||||||
mb();
|
mb();
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3700,14 +3700,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
/*
|
/*
|
||||||
* cy_break() --- routine which turns the break handling on or off
|
* cy_break() --- routine which turns the break handling on or off
|
||||||
*/
|
*/
|
||||||
static void cy_break(struct tty_struct *tty, int break_state)
|
static int cy_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct cyclades_port *info = tty->driver_data;
|
struct cyclades_port *info = tty->driver_data;
|
||||||
struct cyclades_card *card;
|
struct cyclades_card *card;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
if (serial_paranoia_check(info, tty->name, "cy_break"))
|
if (serial_paranoia_check(info, tty->name, "cy_break"))
|
||||||
return;
|
return -EINVAL;
|
||||||
|
|
||||||
card = info->card;
|
card = info->card;
|
||||||
|
|
||||||
|
@ -3736,8 +3737,6 @@ static void cy_break(struct tty_struct *tty, int break_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int retval;
|
|
||||||
|
|
||||||
if (break_state == -1) {
|
if (break_state == -1) {
|
||||||
retval = cyz_issue_cmd(card,
|
retval = cyz_issue_cmd(card,
|
||||||
info->line - card->first_line,
|
info->line - card->first_line,
|
||||||
|
@ -3758,6 +3757,7 @@ static void cy_break(struct tty_struct *tty, int break_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||||
|
return retval;
|
||||||
} /* cy_break */
|
} /* cy_break */
|
||||||
|
|
||||||
static int get_mon_info(struct cyclades_port *info,
|
static int get_mon_info(struct cyclades_port *info,
|
||||||
|
|
|
@ -1725,13 +1725,13 @@ static int esp_tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
/*
|
/*
|
||||||
* rs_break() --- routine which turns the break handling on or off
|
* rs_break() --- routine which turns the break handling on or off
|
||||||
*/
|
*/
|
||||||
static void esp_break(struct tty_struct *tty, int break_state)
|
static int esp_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct esp_struct *info = tty->driver_data;
|
struct esp_struct *info = tty->driver_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (serial_paranoia_check(info, tty->name, "esp_break"))
|
if (serial_paranoia_check(info, tty->name, "esp_break"))
|
||||||
return;
|
return -EINVAL;
|
||||||
|
|
||||||
if (break_state == -1) {
|
if (break_state == -1) {
|
||||||
spin_lock_irqsave(&info->lock, flags);
|
spin_lock_irqsave(&info->lock, flags);
|
||||||
|
@ -1747,6 +1747,7 @@ static void esp_break(struct tty_struct *tty, int break_state)
|
||||||
serial_out(info, UART_ESI_CMD2, 0x00);
|
serial_out(info, UART_ESI_CMD2, 0x00);
|
||||||
spin_unlock_irqrestore(&info->lock, flags);
|
spin_unlock_irqrestore(&info->lock, flags);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rs_ioctl(struct tty_struct *tty, struct file *file,
|
static int rs_ioctl(struct tty_struct *tty, struct file *file,
|
||||||
|
|
|
@ -609,7 +609,7 @@ static void stli_unthrottle(struct tty_struct *tty);
|
||||||
static void stli_stop(struct tty_struct *tty);
|
static void stli_stop(struct tty_struct *tty);
|
||||||
static void stli_start(struct tty_struct *tty);
|
static void stli_start(struct tty_struct *tty);
|
||||||
static void stli_flushbuffer(struct tty_struct *tty);
|
static void stli_flushbuffer(struct tty_struct *tty);
|
||||||
static void stli_breakctl(struct tty_struct *tty, int state);
|
static int stli_breakctl(struct tty_struct *tty, int state);
|
||||||
static void stli_waituntilsent(struct tty_struct *tty, int timeout);
|
static void stli_waituntilsent(struct tty_struct *tty, int timeout);
|
||||||
static void stli_sendxchar(struct tty_struct *tty, char ch);
|
static void stli_sendxchar(struct tty_struct *tty, char ch);
|
||||||
static void stli_hangup(struct tty_struct *tty);
|
static void stli_hangup(struct tty_struct *tty);
|
||||||
|
@ -1909,7 +1909,7 @@ static void stli_flushbuffer(struct tty_struct *tty)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void stli_breakctl(struct tty_struct *tty, int state)
|
static int stli_breakctl(struct tty_struct *tty, int state)
|
||||||
{
|
{
|
||||||
struct stlibrd *brdp;
|
struct stlibrd *brdp;
|
||||||
struct stliport *portp;
|
struct stliport *portp;
|
||||||
|
@ -1917,15 +1917,16 @@ static void stli_breakctl(struct tty_struct *tty, int state)
|
||||||
|
|
||||||
portp = tty->driver_data;
|
portp = tty->driver_data;
|
||||||
if (portp == NULL)
|
if (portp == NULL)
|
||||||
return;
|
return -EINVAL;
|
||||||
if (portp->brdnr >= stli_nrbrds)
|
if (portp->brdnr >= stli_nrbrds)
|
||||||
return;
|
return -EINVAL;
|
||||||
brdp = stli_brds[portp->brdnr];
|
brdp = stli_brds[portp->brdnr];
|
||||||
if (brdp == NULL)
|
if (brdp == NULL)
|
||||||
return;
|
return -EINVAL;
|
||||||
|
|
||||||
arg = (state == -1) ? BREAKON : BREAKOFF;
|
arg = (state == -1) ? BREAKON : BREAKOFF;
|
||||||
stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);
|
stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -374,12 +374,13 @@ copy:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void moxa_break_ctl(struct tty_struct *tty, int state)
|
static int moxa_break_ctl(struct tty_struct *tty, int state)
|
||||||
{
|
{
|
||||||
struct moxa_port *port = tty->driver_data;
|
struct moxa_port *port = tty->driver_data;
|
||||||
|
|
||||||
moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak,
|
moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak,
|
||||||
Magic_code);
|
Magic_code);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct tty_operations moxa_ops = {
|
static const struct tty_operations moxa_ops = {
|
||||||
|
|
|
@ -2183,7 +2183,7 @@ static void mxser_hangup(struct tty_struct *tty)
|
||||||
/*
|
/*
|
||||||
* mxser_rs_break() --- routine which turns the break handling on or off
|
* mxser_rs_break() --- routine which turns the break handling on or off
|
||||||
*/
|
*/
|
||||||
static void mxser_rs_break(struct tty_struct *tty, int break_state)
|
static int mxser_rs_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct mxser_port *info = tty->driver_data;
|
struct mxser_port *info = tty->driver_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -2196,6 +2196,7 @@ static void mxser_rs_break(struct tty_struct *tty, int break_state)
|
||||||
outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC,
|
outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC,
|
||||||
info->ioaddr + UART_LCR);
|
info->ioaddr + UART_LCR);
|
||||||
spin_unlock_irqrestore(&info->slock, flags);
|
spin_unlock_irqrestore(&info->slock, flags);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mxser_receive_chars(struct mxser_port *port, int *status)
|
static void mxser_receive_chars(struct mxser_port *port, int *status)
|
||||||
|
|
|
@ -2230,7 +2230,7 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
* Arguments: tty pointer to tty instance data
|
* Arguments: tty pointer to tty instance data
|
||||||
* break_state -1=set break condition, 0=clear
|
* break_state -1=set break condition, 0=clear
|
||||||
*/
|
*/
|
||||||
static void mgslpc_break(struct tty_struct *tty, int break_state)
|
static int mgslpc_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
|
MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -2240,7 +2240,7 @@ static void mgslpc_break(struct tty_struct *tty, int break_state)
|
||||||
__FILE__,__LINE__, info->device_name, break_state);
|
__FILE__,__LINE__, info->device_name, break_state);
|
||||||
|
|
||||||
if (mgslpc_paranoia_check(info, tty->name, "mgslpc_break"))
|
if (mgslpc_paranoia_check(info, tty->name, "mgslpc_break"))
|
||||||
return;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irqsave(&info->lock,flags);
|
spin_lock_irqsave(&info->lock,flags);
|
||||||
if (break_state == -1)
|
if (break_state == -1)
|
||||||
|
@ -2248,6 +2248,7 @@ static void mgslpc_break(struct tty_struct *tty, int break_state)
|
||||||
else
|
else
|
||||||
clear_reg_bits(info, CHA+DAFO, BIT6);
|
clear_reg_bits(info, CHA+DAFO, BIT6);
|
||||||
spin_unlock_irqrestore(&info->lock,flags);
|
spin_unlock_irqrestore(&info->lock,flags);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Service an IOCTL request
|
/* Service an IOCTL request
|
||||||
|
|
|
@ -1236,13 +1236,13 @@ static void rp_set_termios(struct tty_struct *tty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rp_break(struct tty_struct *tty, int break_state)
|
static int rp_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct r_port *info = (struct r_port *) tty->driver_data;
|
struct r_port *info = (struct r_port *) tty->driver_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (rocket_paranoia_check(info, "rp_break"))
|
if (rocket_paranoia_check(info, "rp_break"))
|
||||||
return;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irqsave(&info->slock, flags);
|
spin_lock_irqsave(&info->slock, flags);
|
||||||
if (break_state == -1)
|
if (break_state == -1)
|
||||||
|
@ -1250,6 +1250,7 @@ static void rp_break(struct tty_struct *tty, int break_state)
|
||||||
else
|
else
|
||||||
sClrBreak(&info->channel);
|
sClrBreak(&info->channel);
|
||||||
spin_unlock_irqrestore(&info->slock, flags);
|
spin_unlock_irqrestore(&info->slock, flags);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1840,7 +1840,7 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sx_break(struct tty_struct *tty, int flag)
|
static int sx_break(struct tty_struct *tty, int flag)
|
||||||
{
|
{
|
||||||
struct sx_port *port = tty->driver_data;
|
struct sx_port *port = tty->driver_data;
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -1857,6 +1857,7 @@ static void sx_break(struct tty_struct *tty, int flag)
|
||||||
read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat)));
|
read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat)));
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
func_exit();
|
func_exit();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sx_tiocmget(struct tty_struct *tty, struct file *file)
|
static int sx_tiocmget(struct tty_struct *tty, struct file *file)
|
||||||
|
|
|
@ -2897,9 +2897,9 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
*
|
*
|
||||||
* Arguments: tty pointer to tty instance data
|
* Arguments: tty pointer to tty instance data
|
||||||
* break_state -1=set break condition, 0=clear
|
* break_state -1=set break condition, 0=clear
|
||||||
* Return Value: None
|
* Return Value: error code
|
||||||
*/
|
*/
|
||||||
static void mgsl_break(struct tty_struct *tty, int break_state)
|
static int mgsl_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data;
|
struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -2909,7 +2909,7 @@ static void mgsl_break(struct tty_struct *tty, int break_state)
|
||||||
__FILE__,__LINE__, info->device_name, break_state);
|
__FILE__,__LINE__, info->device_name, break_state);
|
||||||
|
|
||||||
if (mgsl_paranoia_check(info, tty->name, "mgsl_break"))
|
if (mgsl_paranoia_check(info, tty->name, "mgsl_break"))
|
||||||
return;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irqsave(&info->irq_spinlock,flags);
|
spin_lock_irqsave(&info->irq_spinlock,flags);
|
||||||
if (break_state == -1)
|
if (break_state == -1)
|
||||||
|
@ -2917,6 +2917,7 @@ static void mgsl_break(struct tty_struct *tty, int break_state)
|
||||||
else
|
else
|
||||||
usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7));
|
usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7));
|
||||||
spin_unlock_irqrestore(&info->irq_spinlock,flags);
|
spin_unlock_irqrestore(&info->irq_spinlock,flags);
|
||||||
|
return 0;
|
||||||
|
|
||||||
} /* end of mgsl_break() */
|
} /* end of mgsl_break() */
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ static int read_proc(char *page, char **start, off_t off, int count,int *eof, v
|
||||||
static int chars_in_buffer(struct tty_struct *tty);
|
static int chars_in_buffer(struct tty_struct *tty);
|
||||||
static void throttle(struct tty_struct * tty);
|
static void throttle(struct tty_struct * tty);
|
||||||
static void unthrottle(struct tty_struct * tty);
|
static void unthrottle(struct tty_struct * tty);
|
||||||
static void set_break(struct tty_struct *tty, int break_state);
|
static int set_break(struct tty_struct *tty, int break_state);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* generic HDLC support and callbacks
|
* generic HDLC support and callbacks
|
||||||
|
@ -513,7 +513,7 @@ static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr);
|
||||||
static int tiocmget(struct tty_struct *tty, struct file *file);
|
static int tiocmget(struct tty_struct *tty, struct file *file);
|
||||||
static int tiocmset(struct tty_struct *tty, struct file *file,
|
static int tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
unsigned int set, unsigned int clear);
|
unsigned int set, unsigned int clear);
|
||||||
static void set_break(struct tty_struct *tty, int break_state);
|
static int set_break(struct tty_struct *tty, int break_state);
|
||||||
static int get_interface(struct slgt_info *info, int __user *if_mode);
|
static int get_interface(struct slgt_info *info, int __user *if_mode);
|
||||||
static int set_interface(struct slgt_info *info, int if_mode);
|
static int set_interface(struct slgt_info *info, int if_mode);
|
||||||
static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
|
static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
|
||||||
|
@ -1452,14 +1452,14 @@ static void unthrottle(struct tty_struct * tty)
|
||||||
* set or clear transmit break condition
|
* set or clear transmit break condition
|
||||||
* break_state -1=set break condition, 0=clear
|
* break_state -1=set break condition, 0=clear
|
||||||
*/
|
*/
|
||||||
static void set_break(struct tty_struct *tty, int break_state)
|
static int set_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct slgt_info *info = tty->driver_data;
|
struct slgt_info *info = tty->driver_data;
|
||||||
unsigned short value;
|
unsigned short value;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (sanity_check(info, tty->name, "set_break"))
|
if (sanity_check(info, tty->name, "set_break"))
|
||||||
return;
|
return -EINVAL;
|
||||||
DBGINFO(("%s set_break(%d)\n", info->device_name, break_state));
|
DBGINFO(("%s set_break(%d)\n", info->device_name, break_state));
|
||||||
|
|
||||||
spin_lock_irqsave(&info->lock,flags);
|
spin_lock_irqsave(&info->lock,flags);
|
||||||
|
@ -1470,6 +1470,7 @@ static void set_break(struct tty_struct *tty, int break_state)
|
||||||
value &= ~BIT6;
|
value &= ~BIT6;
|
||||||
wr_reg16(info, TCR, value);
|
wr_reg16(info, TCR, value);
|
||||||
spin_unlock_irqrestore(&info->lock,flags);
|
spin_unlock_irqrestore(&info->lock,flags);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SYNCLINK_GENERIC_HDLC
|
#if SYNCLINK_GENERIC_HDLC
|
||||||
|
|
|
@ -527,7 +527,7 @@ static int read_proc(char *page, char **start, off_t off, int count,int *eof, v
|
||||||
static int chars_in_buffer(struct tty_struct *tty);
|
static int chars_in_buffer(struct tty_struct *tty);
|
||||||
static void throttle(struct tty_struct * tty);
|
static void throttle(struct tty_struct * tty);
|
||||||
static void unthrottle(struct tty_struct * tty);
|
static void unthrottle(struct tty_struct * tty);
|
||||||
static void set_break(struct tty_struct *tty, int break_state);
|
static int set_break(struct tty_struct *tty, int break_state);
|
||||||
|
|
||||||
#if SYNCLINK_GENERIC_HDLC
|
#if SYNCLINK_GENERIC_HDLC
|
||||||
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
|
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
|
||||||
|
@ -552,7 +552,7 @@ static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
|
||||||
static int tiocmget(struct tty_struct *tty, struct file *file);
|
static int tiocmget(struct tty_struct *tty, struct file *file);
|
||||||
static int tiocmset(struct tty_struct *tty, struct file *file,
|
static int tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
unsigned int set, unsigned int clear);
|
unsigned int set, unsigned int clear);
|
||||||
static void set_break(struct tty_struct *tty, int break_state);
|
static int set_break(struct tty_struct *tty, int break_state);
|
||||||
|
|
||||||
static void add_device(SLMP_INFO *info);
|
static void add_device(SLMP_INFO *info);
|
||||||
static void device_init(int adapter_num, struct pci_dev *pdev);
|
static void device_init(int adapter_num, struct pci_dev *pdev);
|
||||||
|
@ -1587,7 +1587,7 @@ static void unthrottle(struct tty_struct * tty)
|
||||||
/* set or clear transmit break condition
|
/* set or clear transmit break condition
|
||||||
* break_state -1=set break condition, 0=clear
|
* break_state -1=set break condition, 0=clear
|
||||||
*/
|
*/
|
||||||
static void set_break(struct tty_struct *tty, int break_state)
|
static int set_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
unsigned char RegValue;
|
unsigned char RegValue;
|
||||||
SLMP_INFO * info = (SLMP_INFO *)tty->driver_data;
|
SLMP_INFO * info = (SLMP_INFO *)tty->driver_data;
|
||||||
|
@ -1598,7 +1598,7 @@ static void set_break(struct tty_struct *tty, int break_state)
|
||||||
__FILE__,__LINE__, info->device_name, break_state);
|
__FILE__,__LINE__, info->device_name, break_state);
|
||||||
|
|
||||||
if (sanity_check(info, tty->name, "set_break"))
|
if (sanity_check(info, tty->name, "set_break"))
|
||||||
return;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irqsave(&info->lock,flags);
|
spin_lock_irqsave(&info->lock,flags);
|
||||||
RegValue = read_reg(info, CTL);
|
RegValue = read_reg(info, CTL);
|
||||||
|
@ -1608,6 +1608,7 @@ static void set_break(struct tty_struct *tty, int break_state)
|
||||||
RegValue &= ~BIT3;
|
RegValue &= ~BIT3;
|
||||||
write_reg(info, CTL, RegValue);
|
write_reg(info, CTL, RegValue);
|
||||||
spin_unlock_irqrestore(&info->lock,flags);
|
spin_unlock_irqrestore(&info->lock,flags);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SYNCLINK_GENERIC_HDLC
|
#if SYNCLINK_GENERIC_HDLC
|
||||||
|
|
|
@ -2849,16 +2849,29 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
|
||||||
|
|
||||||
static int send_break(struct tty_struct *tty, unsigned int duration)
|
static int send_break(struct tty_struct *tty, unsigned int duration)
|
||||||
{
|
{
|
||||||
if (tty_write_lock(tty, 0) < 0)
|
int retval;
|
||||||
return -EINTR;
|
|
||||||
tty->ops->break_ctl(tty, -1);
|
if (tty->ops->break_ctl == NULL)
|
||||||
if (!signal_pending(current))
|
return 0;
|
||||||
msleep_interruptible(duration);
|
|
||||||
tty->ops->break_ctl(tty, 0);
|
if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
|
||||||
tty_write_unlock(tty);
|
retval = tty->ops->break_ctl(tty, duration);
|
||||||
if (signal_pending(current))
|
else {
|
||||||
return -EINTR;
|
/* Do the work ourselves */
|
||||||
return 0;
|
if (tty_write_lock(tty, 0) < 0)
|
||||||
|
return -EINTR;
|
||||||
|
retval = tty->ops->break_ctl(tty, -1);
|
||||||
|
if (retval)
|
||||||
|
goto out;
|
||||||
|
if (!signal_pending(current))
|
||||||
|
msleep_interruptible(duration);
|
||||||
|
retval = tty->ops->break_ctl(tty, 0);
|
||||||
|
out:
|
||||||
|
tty_write_unlock(tty);
|
||||||
|
if (signal_pending(current))
|
||||||
|
retval = -EINTR;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2949,36 +2962,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
tty->driver->subtype == PTY_TYPE_MASTER)
|
tty->driver->subtype == PTY_TYPE_MASTER)
|
||||||
real_tty = tty->link;
|
real_tty = tty->link;
|
||||||
|
|
||||||
/*
|
|
||||||
* Break handling by driver
|
|
||||||
*/
|
|
||||||
|
|
||||||
retval = -EINVAL;
|
|
||||||
|
|
||||||
if (!tty->ops->break_ctl) {
|
|
||||||
switch (cmd) {
|
|
||||||
case TIOCSBRK:
|
|
||||||
case TIOCCBRK:
|
|
||||||
if (tty->ops->ioctl)
|
|
||||||
retval = tty->ops->ioctl(tty, file, cmd, arg);
|
|
||||||
if (retval != -EINVAL && retval != -ENOIOCTLCMD)
|
|
||||||
printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
/* These two ioctl's always return success; even if */
|
|
||||||
/* the driver doesn't support them. */
|
|
||||||
case TCSBRK:
|
|
||||||
case TCSBRKP:
|
|
||||||
if (!tty->ops->ioctl)
|
|
||||||
return 0;
|
|
||||||
retval = tty->ops->ioctl(tty, file, cmd, arg);
|
|
||||||
if (retval != -EINVAL && retval != -ENOIOCTLCMD)
|
|
||||||
printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
|
|
||||||
if (retval == -ENOIOCTLCMD)
|
|
||||||
retval = 0;
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Factor out some common prep work
|
* Factor out some common prep work
|
||||||
|
@ -3000,6 +2983,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now do the stuff.
|
||||||
|
*/
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TIOCSTI:
|
case TIOCSTI:
|
||||||
return tiocsti(tty, p);
|
return tiocsti(tty, p);
|
||||||
|
@ -3043,12 +3029,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
*/
|
*/
|
||||||
case TIOCSBRK: /* Turn break on, unconditionally */
|
case TIOCSBRK: /* Turn break on, unconditionally */
|
||||||
if (tty->ops->break_ctl)
|
if (tty->ops->break_ctl)
|
||||||
tty->ops->break_ctl(tty, -1);
|
return tty->ops->break_ctl(tty, -1);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case TIOCCBRK: /* Turn break off, unconditionally */
|
case TIOCCBRK: /* Turn break off, unconditionally */
|
||||||
if (tty->ops->break_ctl)
|
if (tty->ops->break_ctl)
|
||||||
tty->ops->break_ctl(tty, 0);
|
return tty->ops->break_ctl(tty, 0);
|
||||||
return 0;
|
return 0;
|
||||||
case TCSBRK: /* SVID version: non-zero arg --> no break */
|
case TCSBRK: /* SVID version: non-zero arg --> no break */
|
||||||
/* non-zero arg means wait for all output data
|
/* non-zero arg means wait for all output data
|
||||||
|
|
|
@ -85,7 +85,7 @@ static irqreturn_t scc_rx_int(int irq, void *data);
|
||||||
static irqreturn_t scc_stat_int(int irq, void *data);
|
static irqreturn_t scc_stat_int(int irq, void *data);
|
||||||
static irqreturn_t scc_spcond_int(int irq, void *data);
|
static irqreturn_t scc_spcond_int(int irq, void *data);
|
||||||
static void scc_setsignals(struct scc_port *port, int dtr, int rts);
|
static void scc_setsignals(struct scc_port *port, int dtr, int rts);
|
||||||
static void scc_break_ctl(struct tty_struct *tty, int break_state);
|
static int scc_break_ctl(struct tty_struct *tty, int break_state);
|
||||||
|
|
||||||
static struct tty_driver *scc_driver;
|
static struct tty_driver *scc_driver;
|
||||||
|
|
||||||
|
@ -942,7 +942,7 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void scc_break_ctl(struct tty_struct *tty, int break_state)
|
static int scc_break_ctl(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct scc_port *port = (struct scc_port *)tty->driver_data;
|
struct scc_port *port = (struct scc_port *)tty->driver_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -952,6 +952,7 @@ static void scc_break_ctl(struct tty_struct *tty, int break_state)
|
||||||
SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK,
|
SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK,
|
||||||
break_state ? TCR_SEND_BREAK : 0);
|
break_state ? TCR_SEND_BREAK : 0);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1302,11 +1302,12 @@ static void capinc_tty_hangup(struct tty_struct *tty)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capinc_tty_break_ctl(struct tty_struct *tty, int state)
|
static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG_TTYFUNCS
|
#ifdef _DEBUG_TTYFUNCS
|
||||||
printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
|
printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capinc_tty_flush_buffer(struct tty_struct *tty)
|
static void capinc_tty_flush_buffer(struct tty_struct *tty)
|
||||||
|
|
|
@ -934,7 +934,7 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_break_ctl(struct tty_struct *tty, int break_state)
|
static int uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
struct uart_port *port = state->port;
|
struct uart_port *port = state->port;
|
||||||
|
@ -945,6 +945,7 @@ static void uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||||
port->ops->break_ctl(port, break_state);
|
port->ops->break_ctl(port, break_state);
|
||||||
|
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&state->mutex);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uart_do_autoconfig(struct uart_state *state)
|
static int uart_do_autoconfig(struct uart_state *state)
|
||||||
|
|
|
@ -732,13 +732,16 @@ static void acm_tty_unthrottle(struct tty_struct *tty)
|
||||||
tasklet_schedule(&acm->urb_task);
|
tasklet_schedule(&acm->urb_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void acm_tty_break_ctl(struct tty_struct *tty, int state)
|
static int acm_tty_break_ctl(struct tty_struct *tty, int state)
|
||||||
{
|
{
|
||||||
struct acm *acm = tty->driver_data;
|
struct acm *acm = tty->driver_data;
|
||||||
|
int retval;
|
||||||
if (!ACM_READY(acm))
|
if (!ACM_READY(acm))
|
||||||
return;
|
return -EINVAL;
|
||||||
if (acm_send_break(acm, state ? 0xffff : 0))
|
retval = acm_send_break(acm, state ? 0xffff : 0);
|
||||||
|
if (retval < 0)
|
||||||
dbg("send break failed");
|
dbg("send break failed");
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file)
|
static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file)
|
||||||
|
|
|
@ -395,7 +395,7 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
|
||||||
tty_termios_copy_hw(tty->termios, old);
|
tty_termios_copy_hw(tty->termios, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serial_break(struct tty_struct *tty, int break_state)
|
static int serial_break(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct usb_serial_port *port = tty->driver_data;
|
struct usb_serial_port *port = tty->driver_data;
|
||||||
|
|
||||||
|
@ -409,6 +409,7 @@ static void serial_break(struct tty_struct *tty, int break_state)
|
||||||
port->serial->type->break_ctl(tty, break_state);
|
port->serial->type->break_ctl(tty, break_state);
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serial_read_proc(char *page, char **start, off_t off, int count,
|
static int serial_read_proc(char *page, char **start, off_t off, int count,
|
||||||
|
|
|
@ -135,7 +135,7 @@
|
||||||
*
|
*
|
||||||
* Optional:
|
* Optional:
|
||||||
*
|
*
|
||||||
* void (*break_ctl)(struct tty_stuct *tty, int state);
|
* int (*break_ctl)(struct tty_stuct *tty, int state);
|
||||||
*
|
*
|
||||||
* This optional routine requests the tty driver to turn on or
|
* This optional routine requests the tty driver to turn on or
|
||||||
* off BREAK status on the RS-232 port. If state is -1,
|
* off BREAK status on the RS-232 port. If state is -1,
|
||||||
|
@ -146,6 +146,10 @@
|
||||||
* handle the following ioctls: TCSBRK, TCSBRKP, TIOCSBRK,
|
* handle the following ioctls: TCSBRK, TCSBRKP, TIOCSBRK,
|
||||||
* TIOCCBRK.
|
* TIOCCBRK.
|
||||||
*
|
*
|
||||||
|
* If the driver sets TTY_DRIVER_HARDWARE_BREAK then the interface
|
||||||
|
* will also be called with actual times and the hardware is expected
|
||||||
|
* to do the delay work itself. 0 and -1 are still used for on/off.
|
||||||
|
*
|
||||||
* Optional: Required for TCSBRK/BRKP/etc handling.
|
* Optional: Required for TCSBRK/BRKP/etc handling.
|
||||||
*
|
*
|
||||||
* void (*wait_until_sent)(struct tty_struct *tty, int timeout);
|
* void (*wait_until_sent)(struct tty_struct *tty, int timeout);
|
||||||
|
@ -192,7 +196,7 @@ struct tty_operations {
|
||||||
void (*stop)(struct tty_struct *tty);
|
void (*stop)(struct tty_struct *tty);
|
||||||
void (*start)(struct tty_struct *tty);
|
void (*start)(struct tty_struct *tty);
|
||||||
void (*hangup)(struct tty_struct *tty);
|
void (*hangup)(struct tty_struct *tty);
|
||||||
void (*break_ctl)(struct tty_struct *tty, int state);
|
int (*break_ctl)(struct tty_struct *tty, int state);
|
||||||
void (*flush_buffer)(struct tty_struct *tty);
|
void (*flush_buffer)(struct tty_struct *tty);
|
||||||
void (*set_ldisc)(struct tty_struct *tty);
|
void (*set_ldisc)(struct tty_struct *tty);
|
||||||
void (*wait_until_sent)(struct tty_struct *tty, int timeout);
|
void (*wait_until_sent)(struct tty_struct *tty, int timeout);
|
||||||
|
@ -285,12 +289,18 @@ extern struct tty_driver *tty_find_polling_driver(char *name, int *line);
|
||||||
* TTY_DRIVER_DEVPTS_MEM -- don't use the standard arrays, instead
|
* TTY_DRIVER_DEVPTS_MEM -- don't use the standard arrays, instead
|
||||||
* use dynamic memory keyed through the devpts filesystem. This
|
* use dynamic memory keyed through the devpts filesystem. This
|
||||||
* is only applicable to the pty driver.
|
* is only applicable to the pty driver.
|
||||||
|
*
|
||||||
|
* TTY_DRIVER_HARDWARE_BREAK -- hardware handles break signals. Pass
|
||||||
|
* the requested timeout to the caller instead of using a simple
|
||||||
|
* on/off interface.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#define TTY_DRIVER_INSTALLED 0x0001
|
#define TTY_DRIVER_INSTALLED 0x0001
|
||||||
#define TTY_DRIVER_RESET_TERMIOS 0x0002
|
#define TTY_DRIVER_RESET_TERMIOS 0x0002
|
||||||
#define TTY_DRIVER_REAL_RAW 0x0004
|
#define TTY_DRIVER_REAL_RAW 0x0004
|
||||||
#define TTY_DRIVER_DYNAMIC_DEV 0x0008
|
#define TTY_DRIVER_DYNAMIC_DEV 0x0008
|
||||||
#define TTY_DRIVER_DEVPTS_MEM 0x0010
|
#define TTY_DRIVER_DEVPTS_MEM 0x0010
|
||||||
|
#define TTY_DRIVER_HARDWARE_BREAK 0x0020
|
||||||
|
|
||||||
/* tty driver types */
|
/* tty driver types */
|
||||||
#define TTY_DRIVER_TYPE_SYSTEM 0x0001
|
#define TTY_DRIVER_TYPE_SYSTEM 0x0001
|
||||||
|
|
Loading…
Add table
Reference in a new issue