aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/agp/backend.c7
-rw-r--r--drivers/char/applicom.c24
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/ftape/lowlevel/fdc-io.c6
-rw-r--r--drivers/char/hangcheck-timer.c3
-rw-r--r--drivers/char/hpet.c4
-rw-r--r--drivers/char/hw_random.c5
-rw-r--r--drivers/char/ip2/i2lib.c6
-rw-r--r--drivers/char/ip2main.c3
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c5
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c18
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c6
-rw-r--r--drivers/char/istallion.c2
-rw-r--r--drivers/char/keyboard.c3
-rw-r--r--drivers/char/lcd.c7
-rw-r--r--drivers/char/lp.c3
-rw-r--r--drivers/char/mxser.c12
-rw-r--r--drivers/char/n_tty.c2
-rw-r--r--drivers/char/pcmcia/synclink_cs.c16
-rw-r--r--drivers/char/pty.c5
-rw-r--r--drivers/char/synclink.c29
-rw-r--r--drivers/char/synclinkmp.c41
-rw-r--r--drivers/char/tty_io.c87
-rw-r--r--drivers/char/vt.c37
-rw-r--r--drivers/char/watchdog/mixcomwd.c2
26 files changed, 198 insertions, 141 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 2bc9d64db106..c29365d5b524 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD
80 80
81config COMPUTONE 81config COMPUTONE
82 tristate "Computone IntelliPort Plus serial support" 82 tristate "Computone IntelliPort Plus serial support"
83 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (BROKEN || !SPARC32) 83 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
84 ---help--- 84 ---help---
85 This driver supports the entire family of Intelliport II/Plus 85 This driver supports the entire family of Intelliport II/Plus
86 controllers with the exception of the MicroChannel controllers and 86 controllers with the exception of the MicroChannel controllers and
@@ -208,7 +208,7 @@ config SYNCLINK
208 208
209config SYNCLINKMP 209config SYNCLINKMP
210 tristate "SyncLink Multiport support" 210 tristate "SyncLink Multiport support"
211 depends on SERIAL_NONSTANDARD && (BROKEN || !SPARC32) 211 depends on SERIAL_NONSTANDARD
212 help 212 help
213 Enable support for the SyncLink Multiport (2 or 4 ports) 213 Enable support for the SyncLink Multiport (2 or 4 ports)
214 serial adapter, running asynchronous and HDLC communications up 214 serial adapter, running asynchronous and HDLC communications up
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 4d4e602fdc7e..82b43c541c8d 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -206,10 +206,9 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
206 bridge->driver->cleanup(); 206 bridge->driver->cleanup();
207 if (bridge->driver->free_gatt_table) 207 if (bridge->driver->free_gatt_table)
208 bridge->driver->free_gatt_table(bridge); 208 bridge->driver->free_gatt_table(bridge);
209 if (bridge->key_list) { 209
210 vfree(bridge->key_list); 210 vfree(bridge->key_list);
211 bridge->key_list = NULL; 211 bridge->key_list = NULL;
212 }
213 212
214 if (bridge->driver->agp_destroy_page && 213 if (bridge->driver->agp_destroy_page &&
215 bridge->driver->needs_scratch_page) 214 bridge->driver->needs_scratch_page)
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 11f9ee581124..927a5bbe112c 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -172,7 +172,7 @@ static int ac_register_board(unsigned long physloc, void __iomem *loc,
172 172
173void cleanup_module(void) 173void cleanup_module(void)
174{ 174{
175 int i; 175 unsigned int i;
176 176
177 misc_deregister(&ac_miscdev); 177 misc_deregister(&ac_miscdev);
178 178
@@ -195,7 +195,7 @@ int __init applicom_init(void)
195 int i, numisa = 0; 195 int i, numisa = 0;
196 struct pci_dev *dev = NULL; 196 struct pci_dev *dev = NULL;
197 void __iomem *RamIO; 197 void __iomem *RamIO;
198 int boardno; 198 int boardno, ret;
199 199
200 printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $\n"); 200 printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $\n");
201 201
@@ -294,7 +294,8 @@ int __init applicom_init(void)
294 } 294 }
295 295
296 if (!numisa) 296 if (!numisa)
297 printk(KERN_WARNING"ac.o: No valid ISA Applicom boards found at mem 0x%lx\n",mem); 297 printk(KERN_WARNING "ac.o: No valid ISA Applicom boards found "
298 "at mem 0x%lx\n", mem);
298 299
299 fin: 300 fin:
300 init_waitqueue_head(&FlagSleepRec); 301 init_waitqueue_head(&FlagSleepRec);
@@ -304,7 +305,11 @@ int __init applicom_init(void)
304 DeviceErrorCount = 0; 305 DeviceErrorCount = 0;
305 306
306 if (numboards) { 307 if (numboards) {
307 misc_register(&ac_miscdev); 308 ret = misc_register(&ac_miscdev);
309 if (ret) {
310 printk(KERN_WARNING "ac.o: Unable to register misc device\n");
311 goto out;
312 }
308 for (i = 0; i < MAX_BOARD; i++) { 313 for (i = 0; i < MAX_BOARD; i++) {
309 int serial; 314 int serial;
310 char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1]; 315 char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1];
@@ -337,6 +342,17 @@ int __init applicom_init(void)
337 342
338 else 343 else
339 return -ENXIO; 344 return -ENXIO;
345
346out:
347 for (i = 0; i < MAX_BOARD; i++) {
348 if (!apbs[i].RamIO)
349 continue;
350 if (apbs[i].irq)
351 free_irq(apbs[i].irq, &dummy);
352 iounmap(apbs[i].RamIO);
353 }
354 pci_disable_device(dev);
355 return ret;
340} 356}
341 357
342 358
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6a5337bf0936..cf4c3648463d 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -865,7 +865,7 @@ static void cyz_poll(unsigned long);
865static long cyz_polling_cycle = CZ_DEF_POLL; 865static long cyz_polling_cycle = CZ_DEF_POLL;
866 866
867static int cyz_timeron = 0; 867static int cyz_timeron = 0;
868static struct timer_list cyz_timerlist = TIMER_INITIALIZER(cyz_poll, 0, 0); 868static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
869 869
870#else /* CONFIG_CYZ_INTR */ 870#else /* CONFIG_CYZ_INTR */
871static void cyz_rx_restart(unsigned long); 871static void cyz_rx_restart(unsigned long);
diff --git a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c
index 1704a2a57048..b2e0928e8428 100644
--- a/drivers/char/ftape/lowlevel/fdc-io.c
+++ b/drivers/char/ftape/lowlevel/fdc-io.c
@@ -387,10 +387,8 @@ int fdc_interrupt_wait(unsigned int time)
387 387
388 set_current_state(TASK_INTERRUPTIBLE); 388 set_current_state(TASK_INTERRUPTIBLE);
389 add_wait_queue(&ftape_wait_intr, &wait); 389 add_wait_queue(&ftape_wait_intr, &wait);
390 while (!ft_interrupt_seen && timeout) { 390 while (!ft_interrupt_seen && timeout)
391 set_current_state(TASK_INTERRUPTIBLE); 391 timeout = schedule_timeout_interruptible(timeout);
392 timeout = schedule_timeout(timeout);
393 }
394 392
395 spin_lock_irq(&current->sighand->siglock); 393 spin_lock_irq(&current->sighand->siglock);
396 current->blocked = old_sigmask; 394 current->blocked = old_sigmask;
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 81d811edf3c5..a54bc93353af 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -149,8 +149,7 @@ static unsigned long long hangcheck_tsc, hangcheck_tsc_margin;
149 149
150static void hangcheck_fire(unsigned long); 150static void hangcheck_fire(unsigned long);
151 151
152static struct timer_list hangcheck_ticktock = 152static DEFINE_TIMER(hangcheck_ticktock, hangcheck_fire, 0, 0);
153 TIMER_INITIALIZER(hangcheck_fire, 0, 0);
154 153
155 154
156static void hangcheck_fire(unsigned long data) 155static void hangcheck_fire(unsigned long data)
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 5fe8461271fc..de0379b6d502 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -100,14 +100,14 @@ static struct hpets *hpets;
100#endif 100#endif
101 101
102#ifndef readq 102#ifndef readq
103static unsigned long long __inline readq(void __iomem *addr) 103static inline unsigned long long readq(void __iomem *addr)
104{ 104{
105 return readl(addr) | (((unsigned long long)readl(addr + 4)) << 32LL); 105 return readl(addr) | (((unsigned long long)readl(addr + 4)) << 32LL);
106} 106}
107#endif 107#endif
108 108
109#ifndef writeq 109#ifndef writeq
110static void __inline writeq(unsigned long long v, void __iomem *addr) 110static inline void writeq(unsigned long long v, void __iomem *addr)
111{ 111{
112 writel(v & 0xffffffff, addr); 112 writel(v & 0xffffffff, addr);
113 writel(v >> 32, addr + 4); 113 writel(v >> 32, addr + 4);
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
index 3480535a09c5..6f673d2de0b1 100644
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -513,10 +513,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
513 return ret ? : -EAGAIN; 513 return ret ? : -EAGAIN;
514 514
515 if(need_resched()) 515 if(need_resched())
516 { 516 schedule_timeout_interruptible(1);
517 current->state = TASK_INTERRUPTIBLE;
518 schedule_timeout(1);
519 }
520 else 517 else
521 udelay(200); /* FIXME: We could poll for 250uS ?? */ 518 udelay(200); /* FIXME: We could poll for 250uS ?? */
522 519
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 82c5f30375ac..ba85eb1b6ec7 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -655,8 +655,7 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
655 timeout--; // So negative values == forever 655 timeout--; // So negative values == forever
656 656
657 if (!in_interrupt()) { 657 if (!in_interrupt()) {
658 current->state = TASK_INTERRUPTIBLE; 658 schedule_timeout_interruptible(1); // short nap
659 schedule_timeout(1); // short nap
660 } else { 659 } else {
661 // we cannot sched/sleep in interrrupt silly 660 // we cannot sched/sleep in interrrupt silly
662 return 0; 661 return 0;
@@ -1132,8 +1131,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
1132 1131
1133 ip2trace (CHANN, ITRC_OUTPUT, 61, 0 ); 1132 ip2trace (CHANN, ITRC_OUTPUT, 61, 0 );
1134 1133
1135 current->state = TASK_INTERRUPTIBLE; 1134 schedule_timeout_interruptible(2);
1136 schedule_timeout(2);
1137 if (signal_pending(current)) { 1135 if (signal_pending(current)) {
1138 break; 1136 break;
1139 } 1137 }
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index cf0cd58d6305..9e4e26aef94e 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -120,7 +120,6 @@
120 120
121#include <linux/vmalloc.h> 121#include <linux/vmalloc.h>
122#include <linux/init.h> 122#include <linux/init.h>
123#include <asm/serial.h>
124 123
125#include <asm/uaccess.h> 124#include <asm/uaccess.h>
126 125
@@ -255,7 +254,7 @@ static unsigned long bh_counter = 0;
255 * selected, the board is serviced periodically to see if anything needs doing. 254 * selected, the board is serviced periodically to see if anything needs doing.
256 */ 255 */
257#define POLL_TIMEOUT (jiffies + 1) 256#define POLL_TIMEOUT (jiffies + 1)
258static struct timer_list PollTimer = TIMER_INITIALIZER(ip2_poll, 0, 0); 257static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
259static char TimerOn; 258static char TimerOn;
260 259
261#ifdef IP2DEBUG_TRACE 260#ifdef IP2DEBUG_TRACE
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 883ac4352be4..a09ff1080687 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -735,7 +735,8 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
735 case COMPAT_IPMICTL_RECEIVE_MSG: 735 case COMPAT_IPMICTL_RECEIVE_MSG:
736 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC: 736 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
737 { 737 {
738 struct ipmi_recv *precv64, recv64; 738 struct ipmi_recv __user *precv64;
739 struct ipmi_recv recv64;
739 740
740 if (get_compat_ipmi_recv(&recv64, compat_ptr(arg))) 741 if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
741 return -EFAULT; 742 return -EFAULT;
@@ -748,7 +749,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
748 ((cmd == COMPAT_IPMICTL_RECEIVE_MSG) 749 ((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
749 ? IPMICTL_RECEIVE_MSG 750 ? IPMICTL_RECEIVE_MSG
750 : IPMICTL_RECEIVE_MSG_TRUNC), 751 : IPMICTL_RECEIVE_MSG_TRUNC),
751 (long) precv64); 752 (unsigned long) precv64);
752 if (rc != 0) 753 if (rc != 0)
753 return rc; 754 return rc;
754 755
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 278f84104996..b6e5cbfb09f8 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1920,8 +1920,7 @@ static int try_get_dev_id(struct smi_info *smi_info)
1920 for (;;) 1920 for (;;)
1921 { 1921 {
1922 if (smi_result == SI_SM_CALL_WITH_DELAY) { 1922 if (smi_result == SI_SM_CALL_WITH_DELAY) {
1923 set_current_state(TASK_UNINTERRUPTIBLE); 1923 schedule_timeout_uninterruptible(1);
1924 schedule_timeout(1);
1925 smi_result = smi_info->handlers->event( 1924 smi_result = smi_info->handlers->event(
1926 smi_info->si_sm, 100); 1925 smi_info->si_sm, 100);
1927 } 1926 }
@@ -2256,10 +2255,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
2256 2255
2257 /* Wait for the timer to stop. This avoids problems with race 2256 /* Wait for the timer to stop. This avoids problems with race
2258 conditions removing the timer here. */ 2257 conditions removing the timer here. */
2259 while (! new_smi->timer_stopped) { 2258 while (!new_smi->timer_stopped)
2260 set_current_state(TASK_UNINTERRUPTIBLE); 2259 schedule_timeout_uninterruptible(1);
2261 schedule_timeout(1);
2262 }
2263 2260
2264 out_err: 2261 out_err:
2265 if (new_smi->intf) 2262 if (new_smi->intf)
@@ -2379,17 +2376,14 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
2379 2376
2380 /* Wait for the timer to stop. This avoids problems with race 2377 /* Wait for the timer to stop. This avoids problems with race
2381 conditions removing the timer here. */ 2378 conditions removing the timer here. */
2382 while (! to_clean->timer_stopped) { 2379 while (!to_clean->timer_stopped)
2383 set_current_state(TASK_UNINTERRUPTIBLE); 2380 schedule_timeout_uninterruptible(1);
2384 schedule_timeout(1);
2385 }
2386 2381
2387 /* Interrupts and timeouts are stopped, now make sure the 2382 /* Interrupts and timeouts are stopped, now make sure the
2388 interface is in a clean state. */ 2383 interface is in a clean state. */
2389 while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { 2384 while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
2390 poll(to_clean); 2385 poll(to_clean);
2391 set_current_state(TASK_UNINTERRUPTIBLE); 2386 schedule_timeout_uninterruptible(1);
2392 schedule_timeout(1);
2393 } 2387 }
2394 2388
2395 rv = ipmi_unregister_smi(to_clean->intf); 2389 rv = ipmi_unregister_smi(to_clean->intf);
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index e71aaae855ad..2da64bf7469c 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -1037,10 +1037,8 @@ static __exit void ipmi_unregister_watchdog(void)
1037 /* Wait to make sure the message makes it out. The lower layer has 1037 /* Wait to make sure the message makes it out. The lower layer has
1038 pointers to our buffers, we want to make sure they are done before 1038 pointers to our buffers, we want to make sure they are done before
1039 we release our memory. */ 1039 we release our memory. */
1040 while (atomic_read(&set_timeout_tofree)) { 1040 while (atomic_read(&set_timeout_tofree))
1041 set_current_state(TASK_UNINTERRUPTIBLE); 1041 schedule_timeout_uninterruptible(1);
1042 schedule_timeout(1);
1043 }
1044 1042
1045 /* Disconnect from IPMI. */ 1043 /* Disconnect from IPMI. */
1046 rv = ipmi_destroy_user(watchdog_user); 1044 rv = ipmi_destroy_user(watchdog_user);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 52a073eee201..9c19e5435a11 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -780,7 +780,7 @@ static struct file_operations stli_fsiomem = {
780 * much cheaper on host cpu than using interrupts. It turns out to 780 * much cheaper on host cpu than using interrupts. It turns out to
781 * not increase character latency by much either... 781 * not increase character latency by much either...
782 */ 782 */
783static struct timer_list stli_timerlist = TIMER_INITIALIZER(stli_poll, 0, 0); 783static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0);
784 784
785static int stli_timeron; 785static int stli_timeron;
786 786
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 523fd3c8bbaa..1745065d8f78 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -233,8 +233,7 @@ static void kd_nosound(unsigned long ignored)
233 } 233 }
234} 234}
235 235
236static struct timer_list kd_mksound_timer = 236static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
237 TIMER_INITIALIZER(kd_nosound, 0, 0);
238 237
239void kd_mksound(unsigned int hz, unsigned int ticks) 238void kd_mksound(unsigned int hz, unsigned int ticks)
240{ 239{
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index cf01a720eb2e..b77161146144 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -613,10 +613,15 @@ static struct miscdevice lcd_dev = {
613 613
614static int lcd_init(void) 614static int lcd_init(void)
615{ 615{
616 int ret;
616 unsigned long data; 617 unsigned long data;
617 618
618 pr_info("%s\n", LCD_DRIVER); 619 pr_info("%s\n", LCD_DRIVER);
619 misc_register(&lcd_dev); 620 ret = misc_register(&lcd_dev);
621 if (ret) {
622 printk(KERN_WARNING LCD "Unable to register misc device.\n");
623 return ret;
624 }
620 625
621 /* Check region? Naaah! Just snarf it up. */ 626 /* Check region? Naaah! Just snarf it up. */
622/* request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/ 627/* request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 59eebe5a035f..2afb9038dbc5 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -128,6 +128,7 @@
128#include <linux/console.h> 128#include <linux/console.h>
129#include <linux/device.h> 129#include <linux/device.h>
130#include <linux/wait.h> 130#include <linux/wait.h>
131#include <linux/jiffies.h>
131 132
132#include <linux/parport.h> 133#include <linux/parport.h>
133#undef LP_STATS 134#undef LP_STATS
@@ -307,7 +308,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
307 (LP_F(minor) & LP_ABORT)); 308 (LP_F(minor) & LP_ABORT));
308 309
309#ifdef LP_STATS 310#ifdef LP_STATS
310 if (jiffies-lp_table[minor].lastcall > LP_TIME(minor)) 311 if (time_after(jiffies, lp_table[minor].lastcall + LP_TIME(minor)))
311 lp_table[minor].runchars = 0; 312 lp_table[minor].runchars = 0;
312 313
313 lp_table[minor].lastcall = jiffies; 314 lp_table[minor].lastcall = jiffies;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index d0ef1ae41298..45d012d85e8c 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1058,8 +1058,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1058 */ 1058 */
1059 timeout = jiffies + HZ; 1059 timeout = jiffies + HZ;
1060 while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) { 1060 while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) {
1061 set_current_state(TASK_INTERRUPTIBLE); 1061 schedule_timeout_interruptible(5);
1062 schedule_timeout(5);
1063 if (time_after(jiffies, timeout)) 1062 if (time_after(jiffies, timeout))
1064 break; 1063 break;
1065 } 1064 }
@@ -1080,10 +1079,8 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1080 info->event = 0; 1079 info->event = 0;
1081 info->tty = NULL; 1080 info->tty = NULL;
1082 if (info->blocked_open) { 1081 if (info->blocked_open) {
1083 if (info->close_delay) { 1082 if (info->close_delay)
1084 set_current_state(TASK_INTERRUPTIBLE); 1083 schedule_timeout_interruptible(info->close_delay);
1085 schedule_timeout(info->close_delay);
1086 }
1087 wake_up_interruptible(&info->open_wait); 1084 wake_up_interruptible(&info->open_wait);
1088 } 1085 }
1089 1086
@@ -1801,8 +1798,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
1801#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT 1798#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1802 printk("lsr = %d (jiff=%lu)...", lsr, jiffies); 1799 printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
1803#endif 1800#endif
1804 set_current_state(TASK_INTERRUPTIBLE); 1801 schedule_timeout_interruptible(char_time);
1805 schedule_timeout(char_time);
1806 if (signal_pending(current)) 1802 if (signal_pending(current))
1807 break; 1803 break;
1808 if (timeout && time_after(jiffies, orig_jiffies + timeout)) 1804 if (timeout && time_after(jiffies, orig_jiffies + timeout))
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 09103b3d8f05..c9bdf544ed2c 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -62,7 +62,7 @@
62 62
63static inline unsigned char *alloc_buf(void) 63static inline unsigned char *alloc_buf(void)
64{ 64{
65 int prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; 65 unsigned int prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
66 66
67 if (PAGE_SIZE != N_TTY_BUF_SIZE) 67 if (PAGE_SIZE != N_TTY_BUF_SIZE)
68 return kmalloc(N_TTY_BUF_SIZE, prio); 68 return kmalloc(N_TTY_BUF_SIZE, prio);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 7a0c74648124..02d7f046c10a 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/char/pcmcia/synclink_cs.c 2 * linux/drivers/char/pcmcia/synclink_cs.c
3 * 3 *
4 * $Id: synclink_cs.c,v 4.26 2004/08/11 19:30:02 paulkf Exp $ 4 * $Id: synclink_cs.c,v 4.34 2005/09/08 13:20:54 paulkf Exp $
5 * 5 *
6 * Device driver for Microgate SyncLink PC Card 6 * Device driver for Microgate SyncLink PC Card
7 * multiprotocol serial adapter. 7 * multiprotocol serial adapter.
@@ -472,7 +472,7 @@ module_param_array(dosyncppp, int, NULL, 0);
472MODULE_LICENSE("GPL"); 472MODULE_LICENSE("GPL");
473 473
474static char *driver_name = "SyncLink PC Card driver"; 474static char *driver_name = "SyncLink PC Card driver";
475static char *driver_version = "$Revision: 4.26 $"; 475static char *driver_version = "$Revision: 4.34 $";
476 476
477static struct tty_driver *serial_driver; 477static struct tty_driver *serial_driver;
478 478
@@ -1457,6 +1457,8 @@ static int startup(MGSLPC_INFO * info)
1457 1457
1458 info->pending_bh = 0; 1458 info->pending_bh = 0;
1459 1459
1460 memset(&info->icount, 0, sizeof(info->icount));
1461
1460 init_timer(&info->tx_timer); 1462 init_timer(&info->tx_timer);
1461 info->tx_timer.data = (unsigned long)info; 1463 info->tx_timer.data = (unsigned long)info;
1462 info->tx_timer.function = tx_timeout; 1464 info->tx_timer.function = tx_timeout;
@@ -1946,9 +1948,13 @@ static int get_stats(MGSLPC_INFO * info, struct mgsl_icount __user *user_icount)
1946 int err; 1948 int err;
1947 if (debug_level >= DEBUG_LEVEL_INFO) 1949 if (debug_level >= DEBUG_LEVEL_INFO)
1948 printk("get_params(%s)\n", info->device_name); 1950 printk("get_params(%s)\n", info->device_name);
1949 COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount)); 1951 if (!user_icount) {
1950 if (err) 1952 memset(&info->icount, 0, sizeof(info->icount));
1951 return -EFAULT; 1953 } else {
1954 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
1955 if (err)
1956 return -EFAULT;
1957 }
1952 return 0; 1958 return 0;
1953} 1959}
1954 1960
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index da32889d22c0..49f3997fd251 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -149,15 +149,14 @@ static int pty_write_room(struct tty_struct *tty)
149static int pty_chars_in_buffer(struct tty_struct *tty) 149static int pty_chars_in_buffer(struct tty_struct *tty)
150{ 150{
151 struct tty_struct *to = tty->link; 151 struct tty_struct *to = tty->link;
152 ssize_t (*chars_in_buffer)(struct tty_struct *);
153 int count; 152 int count;
154 153
155 /* We should get the line discipline lock for "tty->link" */ 154 /* We should get the line discipline lock for "tty->link" */
156 if (!to || !(chars_in_buffer = to->ldisc.chars_in_buffer)) 155 if (!to || !to->ldisc.chars_in_buffer)
157 return 0; 156 return 0;
158 157
159 /* The ldisc must report 0 if no characters available to be read */ 158 /* The ldisc must report 0 if no characters available to be read */
160 count = chars_in_buffer(to); 159 count = to->ldisc.chars_in_buffer(to);
161 160
162 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; 161 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
163 162
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 37c8bea8e2b0..ea2d54be4843 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/char/synclink.c 2 * linux/drivers/char/synclink.c
3 * 3 *
4 * $Id: synclink.c,v 4.28 2004/08/11 19:30:01 paulkf Exp $ 4 * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $
5 * 5 *
6 * Device driver for Microgate SyncLink ISA and PCI 6 * Device driver for Microgate SyncLink ISA and PCI
7 * high speed multiprotocol serial adapters. 7 * high speed multiprotocol serial adapters.
@@ -141,9 +141,9 @@ static MGSL_PARAMS default_params = {
141typedef struct _DMABUFFERENTRY 141typedef struct _DMABUFFERENTRY
142{ 142{
143 u32 phys_addr; /* 32-bit flat physical address of data buffer */ 143 u32 phys_addr; /* 32-bit flat physical address of data buffer */
144 u16 count; /* buffer size/data count */ 144 volatile u16 count; /* buffer size/data count */
145 u16 status; /* Control/status field */ 145 volatile u16 status; /* Control/status field */
146 u16 rcc; /* character count field */ 146 volatile u16 rcc; /* character count field */
147 u16 reserved; /* padding required by 16C32 */ 147 u16 reserved; /* padding required by 16C32 */
148 u32 link; /* 32-bit flat link to next buffer entry */ 148 u32 link; /* 32-bit flat link to next buffer entry */
149 char *virt_addr; /* virtual address of data buffer */ 149 char *virt_addr; /* virtual address of data buffer */
@@ -896,7 +896,7 @@ module_param_array(txdmabufs, int, NULL, 0);
896module_param_array(txholdbufs, int, NULL, 0); 896module_param_array(txholdbufs, int, NULL, 0);
897 897
898static char *driver_name = "SyncLink serial driver"; 898static char *driver_name = "SyncLink serial driver";
899static char *driver_version = "$Revision: 4.28 $"; 899static char *driver_version = "$Revision: 4.37 $";
900 900
901static int synclink_init_one (struct pci_dev *dev, 901static int synclink_init_one (struct pci_dev *dev,
902 const struct pci_device_id *ent); 902 const struct pci_device_id *ent);
@@ -1814,6 +1814,8 @@ static int startup(struct mgsl_struct * info)
1814 1814
1815 info->pending_bh = 0; 1815 info->pending_bh = 0;
1816 1816
1817 memset(&info->icount, 0, sizeof(info->icount));
1818
1817 init_timer(&info->tx_timer); 1819 init_timer(&info->tx_timer);
1818 info->tx_timer.data = (unsigned long)info; 1820 info->tx_timer.data = (unsigned long)info;
1819 info->tx_timer.function = mgsl_tx_timeout; 1821 info->tx_timer.function = mgsl_tx_timeout;
@@ -2470,12 +2472,12 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *
2470 printk("%s(%d):mgsl_get_params(%s)\n", 2472 printk("%s(%d):mgsl_get_params(%s)\n",
2471 __FILE__,__LINE__, info->device_name); 2473 __FILE__,__LINE__, info->device_name);
2472 2474
2473 COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount)); 2475 if (!user_icount) {
2474 if (err) { 2476 memset(&info->icount, 0, sizeof(info->icount));
2475 if ( debug_level >= DEBUG_LEVEL_INFO ) 2477 } else {
2476 printk( "%s(%d):mgsl_get_stats(%s) user buffer copy failed\n", 2478 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
2477 __FILE__,__LINE__,info->device_name); 2479 if (err)
2478 return -EFAULT; 2480 return -EFAULT;
2479 } 2481 }
2480 2482
2481 return 0; 2483 return 0;
@@ -6149,6 +6151,11 @@ static void usc_set_async_mode( struct mgsl_struct *info )
6149 usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); 6151 usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12));
6150 } 6152 }
6151 6153
6154 if (info->params.loopback) {
6155 info->loopback_bits = 0x300;
6156 outw(0x0300, info->io_base + CCAR);
6157 }
6158
6152} /* end of usc_set_async_mode() */ 6159} /* end of usc_set_async_mode() */
6153 6160
6154/* usc_loopback_frame() 6161/* usc_loopback_frame()
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index ec949e4c070f..6fb165cf8a61 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: synclinkmp.c,v 4.34 2005/03/04 15:07:10 paulkf Exp $ 2 * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $
3 * 3 *
4 * Device driver for Microgate SyncLink Multiport 4 * Device driver for Microgate SyncLink Multiport
5 * high speed multiprotocol serial adapter. 5 * high speed multiprotocol serial adapter.
@@ -55,7 +55,6 @@
55#include <linux/netdevice.h> 55#include <linux/netdevice.h>
56#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
57#include <linux/init.h> 57#include <linux/init.h>
58#include <asm/serial.h>
59#include <linux/delay.h> 58#include <linux/delay.h>
60#include <linux/ioctl.h> 59#include <linux/ioctl.h>
61 60
@@ -487,7 +486,7 @@ module_param_array(maxframe, int, NULL, 0);
487module_param_array(dosyncppp, int, NULL, 0); 486module_param_array(dosyncppp, int, NULL, 0);
488 487
489static char *driver_name = "SyncLink MultiPort driver"; 488static char *driver_name = "SyncLink MultiPort driver";
490static char *driver_version = "$Revision: 4.34 $"; 489static char *driver_version = "$Revision: 4.38 $";
491 490
492static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); 491static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
493static void synclinkmp_remove_one(struct pci_dev *dev); 492static void synclinkmp_remove_one(struct pci_dev *dev);
@@ -556,7 +555,6 @@ static int set_txidle(SLMP_INFO *info, int idle_mode);
556static int tx_enable(SLMP_INFO *info, int enable); 555static int tx_enable(SLMP_INFO *info, int enable);
557static int tx_abort(SLMP_INFO *info); 556static int tx_abort(SLMP_INFO *info);
558static int rx_enable(SLMP_INFO *info, int enable); 557static int rx_enable(SLMP_INFO *info, int enable);
559static int map_status(int signals);
560static int modem_input_wait(SLMP_INFO *info,int arg); 558static int modem_input_wait(SLMP_INFO *info,int arg);
561static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr); 559static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
562static int tiocmget(struct tty_struct *tty, struct file *file); 560static int tiocmget(struct tty_struct *tty, struct file *file);
@@ -645,7 +643,7 @@ static unsigned char tx_active_fifo_level = 16; // tx request FIFO activation le
645static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes 643static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes
646 644
647static u32 misc_ctrl_value = 0x007e4040; 645static u32 misc_ctrl_value = 0x007e4040;
648static u32 lcr1_brdr_value = 0x00800029; 646static u32 lcr1_brdr_value = 0x00800028;
649 647
650static u32 read_ahead_count = 8; 648static u32 read_ahead_count = 8;
651 649
@@ -2750,6 +2748,8 @@ static int startup(SLMP_INFO * info)
2750 2748
2751 info->pending_bh = 0; 2749 info->pending_bh = 0;
2752 2750
2751 memset(&info->icount, 0, sizeof(info->icount));
2752
2753 /* program hardware for current parameters */ 2753 /* program hardware for current parameters */
2754 reset_port(info); 2754 reset_port(info);
2755 2755
@@ -2953,12 +2953,12 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
2953 printk("%s(%d):%s get_params()\n", 2953 printk("%s(%d):%s get_params()\n",
2954 __FILE__,__LINE__, info->device_name); 2954 __FILE__,__LINE__, info->device_name);
2955 2955
2956 COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount)); 2956 if (!user_icount) {
2957 if (err) { 2957 memset(&info->icount, 0, sizeof(info->icount));
2958 if ( debug_level >= DEBUG_LEVEL_INFO ) 2958 } else {
2959 printk( "%s(%d):%s get_stats() user buffer copy failed\n", 2959 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
2960 __FILE__,__LINE__,info->device_name); 2960 if (err)
2961 return -EFAULT; 2961 return -EFAULT;
2962 } 2962 }
2963 2963
2964 return 0; 2964 return 0;
@@ -3109,16 +3109,6 @@ static int rx_enable(SLMP_INFO * info, int enable)
3109 return 0; 3109 return 0;
3110} 3110}
3111 3111
3112static int map_status(int signals)
3113{
3114 /* Map status bits to API event bits */
3115
3116 return ((signals & SerialSignal_DSR) ? MgslEvent_DsrActive : MgslEvent_DsrInactive) +
3117 ((signals & SerialSignal_CTS) ? MgslEvent_CtsActive : MgslEvent_CtsInactive) +
3118 ((signals & SerialSignal_DCD) ? MgslEvent_DcdActive : MgslEvent_DcdInactive) +
3119 ((signals & SerialSignal_RI) ? MgslEvent_RiActive : MgslEvent_RiInactive);
3120}
3121
3122/* wait for specified event to occur 3112/* wait for specified event to occur
3123 */ 3113 */
3124static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr) 3114static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
@@ -3145,7 +3135,7 @@ static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
3145 3135
3146 /* return immediately if state matches requested events */ 3136 /* return immediately if state matches requested events */
3147 get_signals(info); 3137 get_signals(info);
3148 s = map_status(info->serial_signals); 3138 s = info->serial_signals;
3149 3139
3150 events = mask & 3140 events = mask &
3151 ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + 3141 ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
@@ -4489,11 +4479,13 @@ void async_mode(SLMP_INFO *info)
4489 /* MD2, Mode Register 2 4479 /* MD2, Mode Register 2
4490 * 4480 *
4491 * 07..02 Reserved, must be 0 4481 * 07..02 Reserved, must be 0
4492 * 01..00 CNCT<1..0> Channel connection, 0=normal 4482 * 01..00 CNCT<1..0> Channel connection, 00=normal 11=local loopback
4493 * 4483 *
4494 * 0000 0000 4484 * 0000 0000
4495 */ 4485 */
4496 RegValue = 0x00; 4486 RegValue = 0x00;
4487 if (info->params.loopback)
4488 RegValue |= (BIT1 + BIT0);
4497 write_reg(info, MD2, RegValue); 4489 write_reg(info, MD2, RegValue);
4498 4490
4499 /* RXS, Receive clock source 4491 /* RXS, Receive clock source
@@ -4574,9 +4566,6 @@ void async_mode(SLMP_INFO *info)
4574 write_reg(info, IE2, info->ie2_value); 4566 write_reg(info, IE2, info->ie2_value);
4575 4567
4576 set_rate( info, info->params.data_rate * 16 ); 4568 set_rate( info, info->params.data_rate * 16 );
4577
4578 if (info->params.loopback)
4579 enable_loopback(info,1);
4580} 4569}
4581 4570
4582/* Program the SCA for HDLC communications. 4571/* Program the SCA for HDLC communications.
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 9d657127f313..e5953f3433f3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -469,21 +469,19 @@ static void tty_ldisc_enable(struct tty_struct *tty)
469 469
470static int tty_set_ldisc(struct tty_struct *tty, int ldisc) 470static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
471{ 471{
472 int retval = 0; 472 int retval = 0;
473 struct tty_ldisc o_ldisc; 473 struct tty_ldisc o_ldisc;
474 char buf[64]; 474 char buf[64];
475 int work; 475 int work;
476 unsigned long flags; 476 unsigned long flags;
477 struct tty_ldisc *ld; 477 struct tty_ldisc *ld;
478 struct tty_struct *o_tty;
478 479
479 if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) 480 if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
480 return -EINVAL; 481 return -EINVAL;
481 482
482restart: 483restart:
483 484
484 if (tty->ldisc.num == ldisc)
485 return 0; /* We are already in the desired discipline */
486
487 ld = tty_ldisc_get(ldisc); 485 ld = tty_ldisc_get(ldisc);
488 /* Eduardo Blanco <ejbs@cs.cs.com.uy> */ 486 /* Eduardo Blanco <ejbs@cs.cs.com.uy> */
489 /* Cyrus Durgin <cider@speakeasy.org> */ 487 /* Cyrus Durgin <cider@speakeasy.org> */
@@ -494,45 +492,74 @@ restart:
494 if (ld == NULL) 492 if (ld == NULL)
495 return -EINVAL; 493 return -EINVAL;
496 494
497 o_ldisc = tty->ldisc;
498
499 tty_wait_until_sent(tty, 0); 495 tty_wait_until_sent(tty, 0);
500 496
497 if (tty->ldisc.num == ldisc) {
498 tty_ldisc_put(ldisc);
499 return 0;
500 }
501
502 o_ldisc = tty->ldisc;
503 o_tty = tty->link;
504
501 /* 505 /*
502 * Make sure we don't change while someone holds a 506 * Make sure we don't change while someone holds a
503 * reference to the line discipline. The TTY_LDISC bit 507 * reference to the line discipline. The TTY_LDISC bit
504 * prevents anyone taking a reference once it is clear. 508 * prevents anyone taking a reference once it is clear.
505 * We need the lock to avoid racing reference takers. 509 * We need the lock to avoid racing reference takers.
506 */ 510 */
507 511
508 spin_lock_irqsave(&tty_ldisc_lock, flags); 512 spin_lock_irqsave(&tty_ldisc_lock, flags);
509 if(tty->ldisc.refcount) 513 if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
510 { 514 if(tty->ldisc.refcount) {
511 /* Free the new ldisc we grabbed. Must drop the lock 515 /* Free the new ldisc we grabbed. Must drop the lock
512 first. */ 516 first. */
517 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
518 tty_ldisc_put(ldisc);
519 /*
520 * There are several reasons we may be busy, including
521 * random momentary I/O traffic. We must therefore
522 * retry. We could distinguish between blocking ops
523 * and retries if we made tty_ldisc_wait() smarter. That
524 * is up for discussion.
525 */
526 if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
527 return -ERESTARTSYS;
528 goto restart;
529 }
530 if(o_tty && o_tty->ldisc.refcount) {
531 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
532 tty_ldisc_put(ldisc);
533 if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
534 return -ERESTARTSYS;
535 goto restart;
536 }
537 }
538
539 /* if the TTY_LDISC bit is set, then we are racing against another ldisc change */
540
541 if (!test_bit(TTY_LDISC, &tty->flags)) {
513 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 542 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
514 tty_ldisc_put(ldisc); 543 tty_ldisc_put(ldisc);
515 /* 544 ld = tty_ldisc_ref_wait(tty);
516 * There are several reasons we may be busy, including 545 tty_ldisc_deref(ld);
517 * random momentary I/O traffic. We must therefore
518 * retry. We could distinguish between blocking ops
519 * and retries if we made tty_ldisc_wait() smarter. That
520 * is up for discussion.
521 */
522 if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
523 return -ERESTARTSYS;
524 goto restart; 546 goto restart;
525 } 547 }
526 clear_bit(TTY_LDISC, &tty->flags); 548
549 clear_bit(TTY_LDISC, &tty->flags);
527 clear_bit(TTY_DONT_FLIP, &tty->flags); 550 clear_bit(TTY_DONT_FLIP, &tty->flags);
551 if (o_tty) {
552 clear_bit(TTY_LDISC, &o_tty->flags);
553 clear_bit(TTY_DONT_FLIP, &o_tty->flags);
554 }
528 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 555 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
529 556
530 /* 557 /*
531 * From this point on we know nobody has an ldisc 558 * From this point on we know nobody has an ldisc
532 * usage reference, nor can they obtain one until 559 * usage reference, nor can they obtain one until
533 * we say so later on. 560 * we say so later on.
534 */ 561 */
535 562
536 work = cancel_delayed_work(&tty->flip.work); 563 work = cancel_delayed_work(&tty->flip.work);
537 /* 564 /*
538 * Wait for ->hangup_work and ->flip.work handlers to terminate 565 * Wait for ->hangup_work and ->flip.work handlers to terminate
@@ -583,10 +610,12 @@ restart:
583 */ 610 */
584 611
585 tty_ldisc_enable(tty); 612 tty_ldisc_enable(tty);
613 if (o_tty)
614 tty_ldisc_enable(o_tty);
586 615
587 /* Restart it in case no characters kick it off. Safe if 616 /* Restart it in case no characters kick it off. Safe if
588 already running */ 617 already running */
589 if(work) 618 if (work)
590 schedule_delayed_work(&tty->flip.work, 1); 619 schedule_delayed_work(&tty->flip.work, 1);
591 return retval; 620 return retval;
592} 621}
@@ -2425,6 +2454,7 @@ static void __do_SAK(void *arg)
2425 int i; 2454 int i;
2426 struct file *filp; 2455 struct file *filp;
2427 struct tty_ldisc *disc; 2456 struct tty_ldisc *disc;
2457 struct fdtable *fdt;
2428 2458
2429 if (!tty) 2459 if (!tty)
2430 return; 2460 return;
@@ -2450,8 +2480,9 @@ static void __do_SAK(void *arg)
2450 } 2480 }
2451 task_lock(p); 2481 task_lock(p);
2452 if (p->files) { 2482 if (p->files) {
2453 spin_lock(&p->files->file_lock); 2483 rcu_read_lock();
2454 for (i=0; i < p->files->max_fds; i++) { 2484 fdt = files_fdtable(p->files);
2485 for (i=0; i < fdt->max_fds; i++) {
2455 filp = fcheck_files(p->files, i); 2486 filp = fcheck_files(p->files, i);
2456 if (!filp) 2487 if (!filp)
2457 continue; 2488 continue;
@@ -2464,7 +2495,7 @@ static void __do_SAK(void *arg)
2464 break; 2495 break;
2465 } 2496 }
2466 } 2497 }
2467 spin_unlock(&p->files->file_lock); 2498 rcu_read_unlock();
2468 } 2499 }
2469 task_unlock(p); 2500 task_unlock(p);
2470 } while_each_task_pid(session, PIDTYPE_SID, p); 2501 } while_each_task_pid(session, PIDTYPE_SID, p);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index b8d0c290b0db..1e33cb032e07 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -751,6 +751,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
751 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; 751 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
752 unsigned int old_cols, old_rows, old_row_size, old_screen_size; 752 unsigned int old_cols, old_rows, old_row_size, old_screen_size;
753 unsigned int new_cols, new_rows, new_row_size, new_screen_size; 753 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
754 unsigned int end;
754 unsigned short *newscreen; 755 unsigned short *newscreen;
755 756
756 WARN_CONSOLE_UNLOCKED(); 757 WARN_CONSOLE_UNLOCKED();
@@ -794,20 +795,44 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
794 old_origin = vc->vc_origin; 795 old_origin = vc->vc_origin;
795 new_origin = (long) newscreen; 796 new_origin = (long) newscreen;
796 new_scr_end = new_origin + new_screen_size; 797 new_scr_end = new_origin + new_screen_size;
797 if (new_rows < old_rows) 798
798 old_origin += (old_rows - new_rows) * old_row_size; 799 if (vc->vc_y > new_rows) {
800 if (old_rows - vc->vc_y < new_rows) {
801 /*
802 * Cursor near the bottom, copy contents from the
803 * bottom of buffer
804 */
805 old_origin += (old_rows - new_rows) * old_row_size;
806 end = vc->vc_scr_end;
807 } else {
808 /*
809 * Cursor is in no man's land, copy 1/2 screenful
810 * from the top and bottom of cursor position
811 */
812 old_origin += (vc->vc_y - new_rows/2) * old_row_size;
813 end = old_origin + new_screen_size;
814 }
815 } else
816 /*
817 * Cursor near the top, copy contents from the top of buffer
818 */
819 end = (old_rows > new_rows) ? old_origin + new_screen_size :
820 vc->vc_scr_end;
799 821
800 update_attr(vc); 822 update_attr(vc);
801 823
802 while (old_origin < vc->vc_scr_end) { 824 while (old_origin < end) {
803 scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth); 825 scr_memcpyw((unsigned short *) new_origin,
826 (unsigned short *) old_origin, rlth);
804 if (rrem) 827 if (rrem)
805 scr_memsetw((void *)(new_origin + rlth), vc->vc_video_erase_char, rrem); 828 scr_memsetw((void *)(new_origin + rlth),
829 vc->vc_video_erase_char, rrem);
806 old_origin += old_row_size; 830 old_origin += old_row_size;
807 new_origin += new_row_size; 831 new_origin += new_row_size;
808 } 832 }
809 if (new_scr_end > new_origin) 833 if (new_scr_end > new_origin)
810 scr_memsetw((void *)new_origin, vc->vc_video_erase_char, new_scr_end - new_origin); 834 scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
835 new_scr_end - new_origin);
811 if (vc->vc_kmalloced) 836 if (vc->vc_kmalloced)
812 kfree(vc->vc_screenbuf); 837 kfree(vc->vc_screenbuf);
813 vc->vc_screenbuf = newscreen; 838 vc->vc_screenbuf = newscreen;
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index c9b301dccec3..7fc2188386d9 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -59,7 +59,7 @@ static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */
59 59
60static int watchdog_port; 60static int watchdog_port;
61static int mixcomwd_timer_alive; 61static int mixcomwd_timer_alive;
62static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0); 62static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0);
63static char expect_close; 63static char expect_close;
64 64
65static int nowayout = WATCHDOG_NOWAYOUT; 65static int nowayout = WATCHDOG_NOWAYOUT;