Skip to content

Commit

Permalink
tty: rework break handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alan Cox authored and torvalds committed Jul 22, 2008
1 parent abbe629 commit 9e98966
Show file tree
Hide file tree
Showing 20 changed files with 97 additions and 84 deletions.
2 changes: 1 addition & 1 deletion drivers/char/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ config MOXA_SMARTIO

config ISI
tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
depends on SERIAL_NONSTANDARD && PCI
depends on SERIAL_NONSTANDARD && PCI && BROKEN
select FW_LOADER
help
This is a driver for the Multi-Tech cards which provide several
Expand Down
3 changes: 2 additions & 1 deletion drivers/char/amiserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
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;
unsigned long flags;
Expand All @@ -1263,6 +1263,7 @@ static void rs_break(struct tty_struct *tty, int break_state)
custom.adkcon = AC_UARTBRK;
mb();
local_irq_restore(flags);
return 0;
}


Expand Down
8 changes: 4 additions & 4 deletions drivers/char/cyclades.c
Original file line number Diff line number Diff line change
Expand Up @@ -3700,14 +3700,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
/*
* 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_card *card;
unsigned long flags;
int retval = 0;

if (serial_paranoia_check(info, tty->name, "cy_break"))
return;
return -EINVAL;

card = info->card;

Expand Down Expand Up @@ -3736,8 +3737,6 @@ static void cy_break(struct tty_struct *tty, int break_state)
}
}
} else {
int retval;

if (break_state == -1) {
retval = cyz_issue_cmd(card,
info->line - card->first_line,
Expand All @@ -3758,6 +3757,7 @@ static void cy_break(struct tty_struct *tty, int break_state)
}
}
spin_unlock_irqrestore(&card->card_lock, flags);
return retval;
} /* cy_break */

static int get_mon_info(struct cyclades_port *info,
Expand Down
5 changes: 3 additions & 2 deletions drivers/char/esp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
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;
unsigned long flags;

if (serial_paranoia_check(info, tty->name, "esp_break"))
return;
return -EINVAL;

if (break_state == -1) {
spin_lock_irqsave(&info->lock, flags);
Expand All @@ -1747,6 +1747,7 @@ static void esp_break(struct tty_struct *tty, int break_state)
serial_out(info, UART_ESI_CMD2, 0x00);
spin_unlock_irqrestore(&info->lock, flags);
}
return 0;
}

static int rs_ioctl(struct tty_struct *tty, struct file *file,
Expand Down
11 changes: 6 additions & 5 deletions drivers/char/istallion.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ static void stli_unthrottle(struct tty_struct *tty);
static void stli_stop(struct tty_struct *tty);
static void stli_start(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_sendxchar(struct tty_struct *tty, char ch);
static void stli_hangup(struct tty_struct *tty);
Expand Down Expand Up @@ -1909,23 +1909,24 @@ 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 stliport *portp;
long arg;

portp = tty->driver_data;
if (portp == NULL)
return;
return -EINVAL;
if (portp->brdnr >= stli_nrbrds)
return;
return -EINVAL;
brdp = stli_brds[portp->brdnr];
if (brdp == NULL)
return;
return -EINVAL;

arg = (state == -1) ? BREAKON : BREAKOFF;
stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);
return 0;
}

/*****************************************************************************/
Expand Down
3 changes: 2 additions & 1 deletion drivers/char/moxa.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,12 +374,13 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
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;

moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak,
Magic_code);
return 0;
}

static const struct tty_operations moxa_ops = {
Expand Down
3 changes: 2 additions & 1 deletion drivers/char/mxser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2183,7 +2183,7 @@ static void mxser_hangup(struct tty_struct *tty)
/*
* 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;
unsigned long flags;
Expand All @@ -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,
info->ioaddr + UART_LCR);
spin_unlock_irqrestore(&info->slock, flags);
return 0;
}

static void mxser_receive_chars(struct mxser_port *port, int *status)
Expand Down
5 changes: 3 additions & 2 deletions drivers/char/pcmcia/synclink_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2230,7 +2230,7 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
* Arguments: tty pointer to tty instance data
* 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;
unsigned long flags;
Expand All @@ -2240,14 +2240,15 @@ static void mgslpc_break(struct tty_struct *tty, int break_state)
__FILE__,__LINE__, info->device_name, break_state);

if (mgslpc_paranoia_check(info, tty->name, "mgslpc_break"))
return;
return -EINVAL;

spin_lock_irqsave(&info->lock,flags);
if (break_state == -1)
set_reg_bits(info, CHA+DAFO, BIT6);
else
clear_reg_bits(info, CHA+DAFO, BIT6);
spin_unlock_irqrestore(&info->lock,flags);
return 0;
}

/* Service an IOCTL request
Expand Down
5 changes: 3 additions & 2 deletions drivers/char/rocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,20 +1236,21 @@ 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;
unsigned long flags;

if (rocket_paranoia_check(info, "rp_break"))
return;
return -EINVAL;

spin_lock_irqsave(&info->slock, flags);
if (break_state == -1)
sSendBreak(&info->channel);
else
sClrBreak(&info->channel);
spin_unlock_irqrestore(&info->slock, flags);
return 0;
}

/*
Expand Down
3 changes: 2 additions & 1 deletion drivers/char/sx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1840,7 +1840,7 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
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;
int rv;
Expand All @@ -1857,6 +1857,7 @@ static void sx_break(struct tty_struct *tty, int flag)
read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat)));
unlock_kernel();
func_exit();
return 0;
}

static int sx_tiocmget(struct tty_struct *tty, struct file *file)
Expand Down
7 changes: 4 additions & 3 deletions drivers/char/synclink.c
Original file line number Diff line number Diff line change
Expand Up @@ -2897,9 +2897,9 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
*
* Arguments: tty pointer to tty instance data
* 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;
unsigned long flags;
Expand All @@ -2909,14 +2909,15 @@ static void mgsl_break(struct tty_struct *tty, int break_state)
__FILE__,__LINE__, info->device_name, break_state);

if (mgsl_paranoia_check(info, tty->name, "mgsl_break"))
return;
return -EINVAL;

spin_lock_irqsave(&info->irq_spinlock,flags);
if (break_state == -1)
usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) | BIT7));
else
usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7));
spin_unlock_irqrestore(&info->irq_spinlock,flags);
return 0;

} /* end of mgsl_break() */

Expand Down
9 changes: 5 additions & 4 deletions drivers/char/synclink_gt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 void throttle(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
Expand Down Expand Up @@ -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 tiocmset(struct tty_struct *tty, struct file *file,
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 set_interface(struct slgt_info *info, int if_mode);
static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
Expand Down Expand Up @@ -1452,14 +1452,14 @@ static void unthrottle(struct tty_struct * tty)
* set or clear transmit break condition
* 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;
unsigned short value;
unsigned long flags;

if (sanity_check(info, tty->name, "set_break"))
return;
return -EINVAL;
DBGINFO(("%s set_break(%d)\n", info->device_name, break_state));

spin_lock_irqsave(&info->lock,flags);
Expand All @@ -1470,6 +1470,7 @@ static void set_break(struct tty_struct *tty, int break_state)
value &= ~BIT6;
wr_reg16(info, TCR, value);
spin_unlock_irqrestore(&info->lock,flags);
return 0;
}

#if SYNCLINK_GENERIC_HDLC
Expand Down
9 changes: 5 additions & 4 deletions drivers/char/synclinkmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 void throttle(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
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
Expand All @@ -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 tiocmset(struct tty_struct *tty, struct file *file,
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 device_init(int adapter_num, struct pci_dev *pdev);
Expand Down Expand Up @@ -1587,7 +1587,7 @@ static void unthrottle(struct tty_struct * tty)
/* set or clear transmit break condition
* 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;
SLMP_INFO * info = (SLMP_INFO *)tty->driver_data;
Expand All @@ -1598,7 +1598,7 @@ static void set_break(struct tty_struct *tty, int break_state)
__FILE__,__LINE__, info->device_name, break_state);

if (sanity_check(info, tty->name, "set_break"))
return;
return -EINVAL;

spin_lock_irqsave(&info->lock,flags);
RegValue = read_reg(info, CTL);
Expand All @@ -1608,6 +1608,7 @@ static void set_break(struct tty_struct *tty, int break_state)
RegValue &= ~BIT3;
write_reg(info, CTL, RegValue);
spin_unlock_irqrestore(&info->lock,flags);
return 0;
}

#if SYNCLINK_GENERIC_HDLC
Expand Down
Loading

0 comments on commit 9e98966

Please sign in to comment.