diff options
author | Alan Cox <alan@redhat.com> | 2008-07-22 06:18:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-22 16:03:28 -0400 |
commit | 9e98966c7bb94355689478bc84cc3e0c190f977e (patch) | |
tree | 928aebbfee524a48aa94a3d3def5249c8846a79a /drivers/char | |
parent | abbe629ae4011d2020047f41bea9f9e4b0ec4361 (diff) |
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>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/Kconfig | 2 | ||||
-rw-r--r-- | drivers/char/amiserial.c | 3 | ||||
-rw-r--r-- | drivers/char/cyclades.c | 8 | ||||
-rw-r--r-- | drivers/char/esp.c | 5 | ||||
-rw-r--r-- | drivers/char/istallion.c | 11 | ||||
-rw-r--r-- | drivers/char/moxa.c | 3 | ||||
-rw-r--r-- | drivers/char/mxser.c | 3 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 5 | ||||
-rw-r--r-- | drivers/char/rocket.c | 5 | ||||
-rw-r--r-- | drivers/char/sx.c | 3 | ||||
-rw-r--r-- | drivers/char/synclink.c | 7 | ||||
-rw-r--r-- | drivers/char/synclink_gt.c | 9 | ||||
-rw-r--r-- | drivers/char/synclinkmp.c | 9 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 71 | ||||
-rw-r--r-- | drivers/char/vme_scc.c | 5 |
15 files changed, 73 insertions, 76 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index ba8782b9c217..a185263b5862 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -218,7 +218,7 @@ config MOXA_SMARTIO | |||
218 | 218 | ||
219 | config ISI | 219 | config ISI |
220 | tristate "Multi-Tech multiport card support (EXPERIMENTAL)" | 220 | tristate "Multi-Tech multiport card support (EXPERIMENTAL)" |
221 | depends on SERIAL_NONSTANDARD && PCI | 221 | depends on SERIAL_NONSTANDARD && PCI && BROKEN |
222 | select FW_LOADER | 222 | select FW_LOADER |
223 | help | 223 | help |
224 | This is a driver for the Multi-Tech cards which provide several | 224 | This is a driver for the Multi-Tech cards which provide several |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 37457e5a4f2b..3530ff417a51 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1248,7 +1248,7 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file, | |||
1248 | /* | 1248 | /* |
1249 | * rs_break() --- routine which turns the break handling on or off | 1249 | * rs_break() --- routine which turns the break handling on or off |
1250 | */ | 1250 | */ |
1251 | static void rs_break(struct tty_struct *tty, int break_state) | 1251 | static int rs_break(struct tty_struct *tty, int break_state) |
1252 | { | 1252 | { |
1253 | struct async_struct * info = (struct async_struct *)tty->driver_data; | 1253 | struct async_struct * info = (struct async_struct *)tty->driver_data; |
1254 | unsigned long flags; | 1254 | unsigned long flags; |
@@ -1263,6 +1263,7 @@ static void rs_break(struct tty_struct *tty, int break_state) | |||
1263 | custom.adkcon = AC_UARTBRK; | 1263 | custom.adkcon = AC_UARTBRK; |
1264 | mb(); | 1264 | mb(); |
1265 | local_irq_restore(flags); | 1265 | local_irq_restore(flags); |
1266 | return 0; | ||
1266 | } | 1267 | } |
1267 | 1268 | ||
1268 | 1269 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index e991dc85f2fb..fe6d774fe2e4 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -3700,14 +3700,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3700 | /* | 3700 | /* |
3701 | * cy_break() --- routine which turns the break handling on or off | 3701 | * cy_break() --- routine which turns the break handling on or off |
3702 | */ | 3702 | */ |
3703 | static void cy_break(struct tty_struct *tty, int break_state) | 3703 | static int cy_break(struct tty_struct *tty, int break_state) |
3704 | { | 3704 | { |
3705 | struct cyclades_port *info = tty->driver_data; | 3705 | struct cyclades_port *info = tty->driver_data; |
3706 | struct cyclades_card *card; | 3706 | struct cyclades_card *card; |
3707 | unsigned long flags; | 3707 | unsigned long flags; |
3708 | int retval = 0; | ||
3708 | 3709 | ||
3709 | if (serial_paranoia_check(info, tty->name, "cy_break")) | 3710 | if (serial_paranoia_check(info, tty->name, "cy_break")) |
3710 | return; | 3711 | return -EINVAL; |
3711 | 3712 | ||
3712 | card = info->card; | 3713 | card = info->card; |
3713 | 3714 | ||
@@ -3736,8 +3737,6 @@ static void cy_break(struct tty_struct *tty, int break_state) | |||
3736 | } | 3737 | } |
3737 | } | 3738 | } |
3738 | } else { | 3739 | } else { |
3739 | int retval; | ||
3740 | |||
3741 | if (break_state == -1) { | 3740 | if (break_state == -1) { |
3742 | retval = cyz_issue_cmd(card, | 3741 | retval = cyz_issue_cmd(card, |
3743 | info->line - card->first_line, | 3742 | info->line - card->first_line, |
@@ -3758,6 +3757,7 @@ static void cy_break(struct tty_struct *tty, int break_state) | |||
3758 | } | 3757 | } |
3759 | } | 3758 | } |
3760 | spin_unlock_irqrestore(&card->card_lock, flags); | 3759 | spin_unlock_irqrestore(&card->card_lock, flags); |
3760 | return retval; | ||
3761 | } /* cy_break */ | 3761 | } /* cy_break */ |
3762 | 3762 | ||
3763 | static int get_mon_info(struct cyclades_port *info, | 3763 | static int get_mon_info(struct cyclades_port *info, |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 2eaf09f93e3d..7f077c0097f6 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -1725,13 +1725,13 @@ static int esp_tiocmset(struct tty_struct *tty, struct file *file, | |||
1725 | /* | 1725 | /* |
1726 | * rs_break() --- routine which turns the break handling on or off | 1726 | * rs_break() --- routine which turns the break handling on or off |
1727 | */ | 1727 | */ |
1728 | static void esp_break(struct tty_struct *tty, int break_state) | 1728 | static int esp_break(struct tty_struct *tty, int break_state) |
1729 | { | 1729 | { |
1730 | struct esp_struct *info = tty->driver_data; | 1730 | struct esp_struct *info = tty->driver_data; |
1731 | unsigned long flags; | 1731 | unsigned long flags; |
1732 | 1732 | ||
1733 | if (serial_paranoia_check(info, tty->name, "esp_break")) | 1733 | if (serial_paranoia_check(info, tty->name, "esp_break")) |
1734 | return; | 1734 | return -EINVAL; |
1735 | 1735 | ||
1736 | if (break_state == -1) { | 1736 | if (break_state == -1) { |
1737 | spin_lock_irqsave(&info->lock, flags); | 1737 | spin_lock_irqsave(&info->lock, flags); |
@@ -1747,6 +1747,7 @@ static void esp_break(struct tty_struct *tty, int break_state) | |||
1747 | serial_out(info, UART_ESI_CMD2, 0x00); | 1747 | serial_out(info, UART_ESI_CMD2, 0x00); |
1748 | spin_unlock_irqrestore(&info->lock, flags); | 1748 | spin_unlock_irqrestore(&info->lock, flags); |
1749 | } | 1749 | } |
1750 | return 0; | ||
1750 | } | 1751 | } |
1751 | 1752 | ||
1752 | static int rs_ioctl(struct tty_struct *tty, struct file *file, | 1753 | static int rs_ioctl(struct tty_struct *tty, struct file *file, |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 7930fba4bafc..63d22b5ebc0d 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -609,7 +609,7 @@ static void stli_unthrottle(struct tty_struct *tty); | |||
609 | static void stli_stop(struct tty_struct *tty); | 609 | static void stli_stop(struct tty_struct *tty); |
610 | static void stli_start(struct tty_struct *tty); | 610 | static void stli_start(struct tty_struct *tty); |
611 | static void stli_flushbuffer(struct tty_struct *tty); | 611 | static void stli_flushbuffer(struct tty_struct *tty); |
612 | static void stli_breakctl(struct tty_struct *tty, int state); | 612 | static int stli_breakctl(struct tty_struct *tty, int state); |
613 | static void stli_waituntilsent(struct tty_struct *tty, int timeout); | 613 | static void stli_waituntilsent(struct tty_struct *tty, int timeout); |
614 | static void stli_sendxchar(struct tty_struct *tty, char ch); | 614 | static void stli_sendxchar(struct tty_struct *tty, char ch); |
615 | static void stli_hangup(struct tty_struct *tty); | 615 | static void stli_hangup(struct tty_struct *tty); |
@@ -1909,7 +1909,7 @@ static void stli_flushbuffer(struct tty_struct *tty) | |||
1909 | 1909 | ||
1910 | /*****************************************************************************/ | 1910 | /*****************************************************************************/ |
1911 | 1911 | ||
1912 | static void stli_breakctl(struct tty_struct *tty, int state) | 1912 | static int stli_breakctl(struct tty_struct *tty, int state) |
1913 | { | 1913 | { |
1914 | struct stlibrd *brdp; | 1914 | struct stlibrd *brdp; |
1915 | struct stliport *portp; | 1915 | struct stliport *portp; |
@@ -1917,15 +1917,16 @@ static void stli_breakctl(struct tty_struct *tty, int state) | |||
1917 | 1917 | ||
1918 | portp = tty->driver_data; | 1918 | portp = tty->driver_data; |
1919 | if (portp == NULL) | 1919 | if (portp == NULL) |
1920 | return; | 1920 | return -EINVAL; |
1921 | if (portp->brdnr >= stli_nrbrds) | 1921 | if (portp->brdnr >= stli_nrbrds) |
1922 | return; | 1922 | return -EINVAL; |
1923 | brdp = stli_brds[portp->brdnr]; | 1923 | brdp = stli_brds[portp->brdnr]; |
1924 | if (brdp == NULL) | 1924 | if (brdp == NULL) |
1925 | return; | 1925 | return -EINVAL; |
1926 | 1926 | ||
1927 | arg = (state == -1) ? BREAKON : BREAKOFF; | 1927 | arg = (state == -1) ? BREAKON : BREAKOFF; |
1928 | stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); | 1928 | stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); |
1929 | return 0; | ||
1929 | } | 1930 | } |
1930 | 1931 | ||
1931 | /*****************************************************************************/ | 1932 | /*****************************************************************************/ |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 2bba250ffc8e..d3d7864e0c1e 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -374,12 +374,13 @@ copy: | |||
374 | return ret; | 374 | return ret; |
375 | } | 375 | } |
376 | 376 | ||
377 | static void moxa_break_ctl(struct tty_struct *tty, int state) | 377 | static int moxa_break_ctl(struct tty_struct *tty, int state) |
378 | { | 378 | { |
379 | struct moxa_port *port = tty->driver_data; | 379 | struct moxa_port *port = tty->driver_data; |
380 | 380 | ||
381 | moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak, | 381 | moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak, |
382 | Magic_code); | 382 | Magic_code); |
383 | return 0; | ||
383 | } | 384 | } |
384 | 385 | ||
385 | static const struct tty_operations moxa_ops = { | 386 | static const struct tty_operations moxa_ops = { |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 1fb25571bf85..f04c3c58a05a 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -2183,7 +2183,7 @@ static void mxser_hangup(struct tty_struct *tty) | |||
2183 | /* | 2183 | /* |
2184 | * mxser_rs_break() --- routine which turns the break handling on or off | 2184 | * mxser_rs_break() --- routine which turns the break handling on or off |
2185 | */ | 2185 | */ |
2186 | static void mxser_rs_break(struct tty_struct *tty, int break_state) | 2186 | static int mxser_rs_break(struct tty_struct *tty, int break_state) |
2187 | { | 2187 | { |
2188 | struct mxser_port *info = tty->driver_data; | 2188 | struct mxser_port *info = tty->driver_data; |
2189 | unsigned long flags; | 2189 | unsigned long flags; |
@@ -2196,6 +2196,7 @@ static void mxser_rs_break(struct tty_struct *tty, int break_state) | |||
2196 | outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, | 2196 | outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, |
2197 | info->ioaddr + UART_LCR); | 2197 | info->ioaddr + UART_LCR); |
2198 | spin_unlock_irqrestore(&info->slock, flags); | 2198 | spin_unlock_irqrestore(&info->slock, flags); |
2199 | return 0; | ||
2199 | } | 2200 | } |
2200 | 2201 | ||
2201 | static void mxser_receive_chars(struct mxser_port *port, int *status) | 2202 | static void mxser_receive_chars(struct mxser_port *port, int *status) |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index b694d430f10e..d1fceabe3aef 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -2230,7 +2230,7 @@ static int tiocmset(struct tty_struct *tty, struct file *file, | |||
2230 | * Arguments: tty pointer to tty instance data | 2230 | * Arguments: tty pointer to tty instance data |
2231 | * break_state -1=set break condition, 0=clear | 2231 | * break_state -1=set break condition, 0=clear |
2232 | */ | 2232 | */ |
2233 | static void mgslpc_break(struct tty_struct *tty, int break_state) | 2233 | static int mgslpc_break(struct tty_struct *tty, int break_state) |
2234 | { | 2234 | { |
2235 | MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; | 2235 | MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; |
2236 | unsigned long flags; | 2236 | unsigned long flags; |
@@ -2240,7 +2240,7 @@ static void mgslpc_break(struct tty_struct *tty, int break_state) | |||
2240 | __FILE__,__LINE__, info->device_name, break_state); | 2240 | __FILE__,__LINE__, info->device_name, break_state); |
2241 | 2241 | ||
2242 | if (mgslpc_paranoia_check(info, tty->name, "mgslpc_break")) | 2242 | if (mgslpc_paranoia_check(info, tty->name, "mgslpc_break")) |
2243 | return; | 2243 | return -EINVAL; |
2244 | 2244 | ||
2245 | spin_lock_irqsave(&info->lock,flags); | 2245 | spin_lock_irqsave(&info->lock,flags); |
2246 | if (break_state == -1) | 2246 | if (break_state == -1) |
@@ -2248,6 +2248,7 @@ static void mgslpc_break(struct tty_struct *tty, int break_state) | |||
2248 | else | 2248 | else |
2249 | clear_reg_bits(info, CHA+DAFO, BIT6); | 2249 | clear_reg_bits(info, CHA+DAFO, BIT6); |
2250 | spin_unlock_irqrestore(&info->lock,flags); | 2250 | spin_unlock_irqrestore(&info->lock,flags); |
2251 | return 0; | ||
2251 | } | 2252 | } |
2252 | 2253 | ||
2253 | /* Service an IOCTL request | 2254 | /* Service an IOCTL request |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index e670eae2f510..584d791e84a6 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -1236,13 +1236,13 @@ static void rp_set_termios(struct tty_struct *tty, | |||
1236 | } | 1236 | } |
1237 | } | 1237 | } |
1238 | 1238 | ||
1239 | static void rp_break(struct tty_struct *tty, int break_state) | 1239 | static int rp_break(struct tty_struct *tty, int break_state) |
1240 | { | 1240 | { |
1241 | struct r_port *info = (struct r_port *) tty->driver_data; | 1241 | struct r_port *info = (struct r_port *) tty->driver_data; |
1242 | unsigned long flags; | 1242 | unsigned long flags; |
1243 | 1243 | ||
1244 | if (rocket_paranoia_check(info, "rp_break")) | 1244 | if (rocket_paranoia_check(info, "rp_break")) |
1245 | return; | 1245 | return -EINVAL; |
1246 | 1246 | ||
1247 | spin_lock_irqsave(&info->slock, flags); | 1247 | spin_lock_irqsave(&info->slock, flags); |
1248 | if (break_state == -1) | 1248 | if (break_state == -1) |
@@ -1250,6 +1250,7 @@ static void rp_break(struct tty_struct *tty, int break_state) | |||
1250 | else | 1250 | else |
1251 | sClrBreak(&info->channel); | 1251 | sClrBreak(&info->channel); |
1252 | spin_unlock_irqrestore(&info->slock, flags); | 1252 | spin_unlock_irqrestore(&info->slock, flags); |
1253 | return 0; | ||
1253 | } | 1254 | } |
1254 | 1255 | ||
1255 | /* | 1256 | /* |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index d5cffcd6a572..2162439bbe48 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -1840,7 +1840,7 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp, | |||
1840 | return rc; | 1840 | return rc; |
1841 | } | 1841 | } |
1842 | 1842 | ||
1843 | static void sx_break(struct tty_struct *tty, int flag) | 1843 | static int sx_break(struct tty_struct *tty, int flag) |
1844 | { | 1844 | { |
1845 | struct sx_port *port = tty->driver_data; | 1845 | struct sx_port *port = tty->driver_data; |
1846 | int rv; | 1846 | int rv; |
@@ -1857,6 +1857,7 @@ static void sx_break(struct tty_struct *tty, int flag) | |||
1857 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); | 1857 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); |
1858 | unlock_kernel(); | 1858 | unlock_kernel(); |
1859 | func_exit(); | 1859 | func_exit(); |
1860 | return 0; | ||
1860 | } | 1861 | } |
1861 | 1862 | ||
1862 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) | 1863 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 527d220aa4aa..ef6706f09061 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -2897,9 +2897,9 @@ static int tiocmset(struct tty_struct *tty, struct file *file, | |||
2897 | * | 2897 | * |
2898 | * Arguments: tty pointer to tty instance data | 2898 | * Arguments: tty pointer to tty instance data |
2899 | * break_state -1=set break condition, 0=clear | 2899 | * break_state -1=set break condition, 0=clear |
2900 | * Return Value: None | 2900 | * Return Value: error code |
2901 | */ | 2901 | */ |
2902 | static void mgsl_break(struct tty_struct *tty, int break_state) | 2902 | static int mgsl_break(struct tty_struct *tty, int break_state) |
2903 | { | 2903 | { |
2904 | struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data; | 2904 | struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data; |
2905 | unsigned long flags; | 2905 | unsigned long flags; |
@@ -2909,7 +2909,7 @@ static void mgsl_break(struct tty_struct *tty, int break_state) | |||
2909 | __FILE__,__LINE__, info->device_name, break_state); | 2909 | __FILE__,__LINE__, info->device_name, break_state); |
2910 | 2910 | ||
2911 | if (mgsl_paranoia_check(info, tty->name, "mgsl_break")) | 2911 | if (mgsl_paranoia_check(info, tty->name, "mgsl_break")) |
2912 | return; | 2912 | return -EINVAL; |
2913 | 2913 | ||
2914 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2914 | spin_lock_irqsave(&info->irq_spinlock,flags); |
2915 | if (break_state == -1) | 2915 | if (break_state == -1) |
@@ -2917,6 +2917,7 @@ static void mgsl_break(struct tty_struct *tty, int break_state) | |||
2917 | else | 2917 | else |
2918 | usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7)); | 2918 | usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7)); |
2919 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 2919 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
2920 | return 0; | ||
2920 | 2921 | ||
2921 | } /* end of mgsl_break() */ | 2922 | } /* end of mgsl_break() */ |
2922 | 2923 | ||
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 2c3e43bb2cc9..cf87bb89a77d 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -165,7 +165,7 @@ static int read_proc(char *page, char **start, off_t off, int count,int *eof, v | |||
165 | static int chars_in_buffer(struct tty_struct *tty); | 165 | static int chars_in_buffer(struct tty_struct *tty); |
166 | static void throttle(struct tty_struct * tty); | 166 | static void throttle(struct tty_struct * tty); |
167 | static void unthrottle(struct tty_struct * tty); | 167 | static void unthrottle(struct tty_struct * tty); |
168 | static void set_break(struct tty_struct *tty, int break_state); | 168 | static int set_break(struct tty_struct *tty, int break_state); |
169 | 169 | ||
170 | /* | 170 | /* |
171 | * generic HDLC support and callbacks | 171 | * generic HDLC support and callbacks |
@@ -513,7 +513,7 @@ static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr); | |||
513 | static int tiocmget(struct tty_struct *tty, struct file *file); | 513 | static int tiocmget(struct tty_struct *tty, struct file *file); |
514 | static int tiocmset(struct tty_struct *tty, struct file *file, | 514 | static int tiocmset(struct tty_struct *tty, struct file *file, |
515 | unsigned int set, unsigned int clear); | 515 | unsigned int set, unsigned int clear); |
516 | static void set_break(struct tty_struct *tty, int break_state); | 516 | static int set_break(struct tty_struct *tty, int break_state); |
517 | static int get_interface(struct slgt_info *info, int __user *if_mode); | 517 | static int get_interface(struct slgt_info *info, int __user *if_mode); |
518 | static int set_interface(struct slgt_info *info, int if_mode); | 518 | static int set_interface(struct slgt_info *info, int if_mode); |
519 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 519 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
@@ -1452,14 +1452,14 @@ static void unthrottle(struct tty_struct * tty) | |||
1452 | * set or clear transmit break condition | 1452 | * set or clear transmit break condition |
1453 | * break_state -1=set break condition, 0=clear | 1453 | * break_state -1=set break condition, 0=clear |
1454 | */ | 1454 | */ |
1455 | static void set_break(struct tty_struct *tty, int break_state) | 1455 | static int set_break(struct tty_struct *tty, int break_state) |
1456 | { | 1456 | { |
1457 | struct slgt_info *info = tty->driver_data; | 1457 | struct slgt_info *info = tty->driver_data; |
1458 | unsigned short value; | 1458 | unsigned short value; |
1459 | unsigned long flags; | 1459 | unsigned long flags; |
1460 | 1460 | ||
1461 | if (sanity_check(info, tty->name, "set_break")) | 1461 | if (sanity_check(info, tty->name, "set_break")) |
1462 | return; | 1462 | return -EINVAL; |
1463 | DBGINFO(("%s set_break(%d)\n", info->device_name, break_state)); | 1463 | DBGINFO(("%s set_break(%d)\n", info->device_name, break_state)); |
1464 | 1464 | ||
1465 | spin_lock_irqsave(&info->lock,flags); | 1465 | spin_lock_irqsave(&info->lock,flags); |
@@ -1470,6 +1470,7 @@ static void set_break(struct tty_struct *tty, int break_state) | |||
1470 | value &= ~BIT6; | 1470 | value &= ~BIT6; |
1471 | wr_reg16(info, TCR, value); | 1471 | wr_reg16(info, TCR, value); |
1472 | spin_unlock_irqrestore(&info->lock,flags); | 1472 | spin_unlock_irqrestore(&info->lock,flags); |
1473 | return 0; | ||
1473 | } | 1474 | } |
1474 | 1475 | ||
1475 | #if SYNCLINK_GENERIC_HDLC | 1476 | #if SYNCLINK_GENERIC_HDLC |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 5768c4136342..c0490cbd0db2 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -527,7 +527,7 @@ static int read_proc(char *page, char **start, off_t off, int count,int *eof, v | |||
527 | static int chars_in_buffer(struct tty_struct *tty); | 527 | static int chars_in_buffer(struct tty_struct *tty); |
528 | static void throttle(struct tty_struct * tty); | 528 | static void throttle(struct tty_struct * tty); |
529 | static void unthrottle(struct tty_struct * tty); | 529 | static void unthrottle(struct tty_struct * tty); |
530 | static void set_break(struct tty_struct *tty, int break_state); | 530 | static int set_break(struct tty_struct *tty, int break_state); |
531 | 531 | ||
532 | #if SYNCLINK_GENERIC_HDLC | 532 | #if SYNCLINK_GENERIC_HDLC |
533 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) | 533 | #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); | |||
552 | static int tiocmget(struct tty_struct *tty, struct file *file); | 552 | static int tiocmget(struct tty_struct *tty, struct file *file); |
553 | static int tiocmset(struct tty_struct *tty, struct file *file, | 553 | static int tiocmset(struct tty_struct *tty, struct file *file, |
554 | unsigned int set, unsigned int clear); | 554 | unsigned int set, unsigned int clear); |
555 | static void set_break(struct tty_struct *tty, int break_state); | 555 | static int set_break(struct tty_struct *tty, int break_state); |
556 | 556 | ||
557 | static void add_device(SLMP_INFO *info); | 557 | static void add_device(SLMP_INFO *info); |
558 | static void device_init(int adapter_num, struct pci_dev *pdev); | 558 | static void device_init(int adapter_num, struct pci_dev *pdev); |
@@ -1587,7 +1587,7 @@ static void unthrottle(struct tty_struct * tty) | |||
1587 | /* set or clear transmit break condition | 1587 | /* set or clear transmit break condition |
1588 | * break_state -1=set break condition, 0=clear | 1588 | * break_state -1=set break condition, 0=clear |
1589 | */ | 1589 | */ |
1590 | static void set_break(struct tty_struct *tty, int break_state) | 1590 | static int set_break(struct tty_struct *tty, int break_state) |
1591 | { | 1591 | { |
1592 | unsigned char RegValue; | 1592 | unsigned char RegValue; |
1593 | SLMP_INFO * info = (SLMP_INFO *)tty->driver_data; | 1593 | SLMP_INFO * info = (SLMP_INFO *)tty->driver_data; |
@@ -1598,7 +1598,7 @@ static void set_break(struct tty_struct *tty, int break_state) | |||
1598 | __FILE__,__LINE__, info->device_name, break_state); | 1598 | __FILE__,__LINE__, info->device_name, break_state); |
1599 | 1599 | ||
1600 | if (sanity_check(info, tty->name, "set_break")) | 1600 | if (sanity_check(info, tty->name, "set_break")) |
1601 | return; | 1601 | return -EINVAL; |
1602 | 1602 | ||
1603 | spin_lock_irqsave(&info->lock,flags); | 1603 | spin_lock_irqsave(&info->lock,flags); |
1604 | RegValue = read_reg(info, CTL); | 1604 | RegValue = read_reg(info, CTL); |
@@ -1608,6 +1608,7 @@ static void set_break(struct tty_struct *tty, int break_state) | |||
1608 | RegValue &= ~BIT3; | 1608 | RegValue &= ~BIT3; |
1609 | write_reg(info, CTL, RegValue); | 1609 | write_reg(info, CTL, RegValue); |
1610 | spin_unlock_irqrestore(&info->lock,flags); | 1610 | spin_unlock_irqrestore(&info->lock,flags); |
1611 | return 0; | ||
1611 | } | 1612 | } |
1612 | 1613 | ||
1613 | #if SYNCLINK_GENERIC_HDLC | 1614 | #if SYNCLINK_GENERIC_HDLC |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index d27a08b374d0..d94cd8410c53 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -2849,16 +2849,29 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) | |||
2849 | 2849 | ||
2850 | static int send_break(struct tty_struct *tty, unsigned int duration) | 2850 | static int send_break(struct tty_struct *tty, unsigned int duration) |
2851 | { | 2851 | { |
2852 | if (tty_write_lock(tty, 0) < 0) | 2852 | int retval; |
2853 | return -EINTR; | 2853 | |
2854 | tty->ops->break_ctl(tty, -1); | 2854 | if (tty->ops->break_ctl == NULL) |
2855 | if (!signal_pending(current)) | 2855 | return 0; |
2856 | msleep_interruptible(duration); | 2856 | |
2857 | tty->ops->break_ctl(tty, 0); | 2857 | if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) |
2858 | tty_write_unlock(tty); | 2858 | retval = tty->ops->break_ctl(tty, duration); |
2859 | if (signal_pending(current)) | 2859 | else { |
2860 | return -EINTR; | 2860 | /* Do the work ourselves */ |
2861 | return 0; | 2861 | if (tty_write_lock(tty, 0) < 0) |
2862 | return -EINTR; | ||
2863 | retval = tty->ops->break_ctl(tty, -1); | ||
2864 | if (retval) | ||
2865 | goto out; | ||
2866 | if (!signal_pending(current)) | ||
2867 | msleep_interruptible(duration); | ||
2868 | retval = tty->ops->break_ctl(tty, 0); | ||
2869 | out: | ||
2870 | tty_write_unlock(tty); | ||
2871 | if (signal_pending(current)) | ||
2872 | retval = -EINTR; | ||
2873 | } | ||
2874 | return retval; | ||
2862 | } | 2875 | } |
2863 | 2876 | ||
2864 | /** | 2877 | /** |
@@ -2949,36 +2962,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2949 | tty->driver->subtype == PTY_TYPE_MASTER) | 2962 | tty->driver->subtype == PTY_TYPE_MASTER) |
2950 | real_tty = tty->link; | 2963 | real_tty = tty->link; |
2951 | 2964 | ||
2952 | /* | ||
2953 | * Break handling by driver | ||
2954 | */ | ||
2955 | |||
2956 | retval = -EINVAL; | ||
2957 | |||
2958 | if (!tty->ops->break_ctl) { | ||
2959 | switch (cmd) { | ||
2960 | case TIOCSBRK: | ||
2961 | case TIOCCBRK: | ||
2962 | if (tty->ops->ioctl) | ||
2963 | retval = tty->ops->ioctl(tty, file, cmd, arg); | ||
2964 | if (retval != -EINVAL && retval != -ENOIOCTLCMD) | ||
2965 | printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name); | ||
2966 | return retval; | ||
2967 | |||
2968 | /* These two ioctl's always return success; even if */ | ||
2969 | /* the driver doesn't support them. */ | ||
2970 | case TCSBRK: | ||
2971 | case TCSBRKP: | ||
2972 | if (!tty->ops->ioctl) | ||
2973 | return 0; | ||
2974 | retval = tty->ops->ioctl(tty, file, cmd, arg); | ||
2975 | if (retval != -EINVAL && retval != -ENOIOCTLCMD) | ||
2976 | printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name); | ||
2977 | if (retval == -ENOIOCTLCMD) | ||
2978 | retval = 0; | ||
2979 | return retval; | ||
2980 | } | ||
2981 | } | ||
2982 | 2965 | ||
2983 | /* | 2966 | /* |
2984 | * Factor out some common prep work | 2967 | * Factor out some common prep work |
@@ -3000,6 +2983,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3000 | break; | 2983 | break; |
3001 | } | 2984 | } |
3002 | 2985 | ||
2986 | /* | ||
2987 | * Now do the stuff. | ||
2988 | */ | ||
3003 | switch (cmd) { | 2989 | switch (cmd) { |
3004 | case TIOCSTI: | 2990 | case TIOCSTI: |
3005 | return tiocsti(tty, p); | 2991 | return tiocsti(tty, p); |
@@ -3043,12 +3029,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3043 | */ | 3029 | */ |
3044 | case TIOCSBRK: /* Turn break on, unconditionally */ | 3030 | case TIOCSBRK: /* Turn break on, unconditionally */ |
3045 | if (tty->ops->break_ctl) | 3031 | if (tty->ops->break_ctl) |
3046 | tty->ops->break_ctl(tty, -1); | 3032 | return tty->ops->break_ctl(tty, -1); |
3047 | return 0; | 3033 | return 0; |
3048 | |||
3049 | case TIOCCBRK: /* Turn break off, unconditionally */ | 3034 | case TIOCCBRK: /* Turn break off, unconditionally */ |
3050 | if (tty->ops->break_ctl) | 3035 | if (tty->ops->break_ctl) |
3051 | tty->ops->break_ctl(tty, 0); | 3036 | return tty->ops->break_ctl(tty, 0); |
3052 | return 0; | 3037 | return 0; |
3053 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 3038 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
3054 | /* non-zero arg means wait for all output data | 3039 | /* non-zero arg means wait for all output data |
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index f17ac043b551..69c5afe97f19 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c | |||
@@ -85,7 +85,7 @@ static irqreturn_t scc_rx_int(int irq, void *data); | |||
85 | static irqreturn_t scc_stat_int(int irq, void *data); | 85 | static irqreturn_t scc_stat_int(int irq, void *data); |
86 | static irqreturn_t scc_spcond_int(int irq, void *data); | 86 | static irqreturn_t scc_spcond_int(int irq, void *data); |
87 | static void scc_setsignals(struct scc_port *port, int dtr, int rts); | 87 | static void scc_setsignals(struct scc_port *port, int dtr, int rts); |
88 | static void scc_break_ctl(struct tty_struct *tty, int break_state); | 88 | static int scc_break_ctl(struct tty_struct *tty, int break_state); |
89 | 89 | ||
90 | static struct tty_driver *scc_driver; | 90 | static struct tty_driver *scc_driver; |
91 | 91 | ||
@@ -942,7 +942,7 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file, | |||
942 | } | 942 | } |
943 | 943 | ||
944 | 944 | ||
945 | static void scc_break_ctl(struct tty_struct *tty, int break_state) | 945 | static int scc_break_ctl(struct tty_struct *tty, int break_state) |
946 | { | 946 | { |
947 | struct scc_port *port = (struct scc_port *)tty->driver_data; | 947 | struct scc_port *port = (struct scc_port *)tty->driver_data; |
948 | unsigned long flags; | 948 | unsigned long flags; |
@@ -952,6 +952,7 @@ static void scc_break_ctl(struct tty_struct *tty, int break_state) | |||
952 | SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, | 952 | SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, |
953 | break_state ? TCR_SEND_BREAK : 0); | 953 | break_state ? TCR_SEND_BREAK : 0); |
954 | local_irq_restore(flags); | 954 | local_irq_restore(flags); |
955 | return 0; | ||
955 | } | 956 | } |
956 | 957 | ||
957 | 958 | ||