diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/Kconfig | 4 | ||||
-rw-r--r-- | drivers/char/agp/backend.c | 7 | ||||
-rw-r--r-- | drivers/char/applicom.c | 24 | ||||
-rw-r--r-- | drivers/char/cyclades.c | 2 | ||||
-rw-r--r-- | drivers/char/ftape/lowlevel/fdc-io.c | 6 | ||||
-rw-r--r-- | drivers/char/hangcheck-timer.c | 3 | ||||
-rw-r--r-- | drivers/char/hpet.c | 4 | ||||
-rw-r--r-- | drivers/char/hw_random.c | 5 | ||||
-rw-r--r-- | drivers/char/ip2/i2lib.c | 6 | ||||
-rw-r--r-- | drivers/char/ip2main.c | 3 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_devintf.c | 5 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 18 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 6 | ||||
-rw-r--r-- | drivers/char/istallion.c | 2 | ||||
-rw-r--r-- | drivers/char/keyboard.c | 3 | ||||
-rw-r--r-- | drivers/char/lcd.c | 7 | ||||
-rw-r--r-- | drivers/char/lp.c | 3 | ||||
-rw-r--r-- | drivers/char/mxser.c | 12 | ||||
-rw-r--r-- | drivers/char/n_tty.c | 2 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 16 | ||||
-rw-r--r-- | drivers/char/pty.c | 5 | ||||
-rw-r--r-- | drivers/char/synclink.c | 29 | ||||
-rw-r--r-- | drivers/char/synclinkmp.c | 41 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 87 | ||||
-rw-r--r-- | drivers/char/vt.c | 37 | ||||
-rw-r--r-- | drivers/char/watchdog/mixcomwd.c | 2 |
26 files changed, 198 insertions, 141 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 2bc9d64db10..c29365d5b52 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD config COMPUTONE tristate "Computone IntelliPort Plus serial support" - depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (BROKEN || !SPARC32) + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP ---help--- This driver supports the entire family of Intelliport II/Plus controllers with the exception of the MicroChannel controllers and @@ -208,7 +208,7 @@ config SYNCLINK config SYNCLINKMP tristate "SyncLink Multiport support" - depends on SERIAL_NONSTANDARD && (BROKEN || !SPARC32) + depends on SERIAL_NONSTANDARD help Enable support for the SyncLink Multiport (2 or 4 ports) serial adapter, running asynchronous and HDLC communications up diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 4d4e602fdc7..82b43c541c8 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) bridge->driver->cleanup(); if (bridge->driver->free_gatt_table) bridge->driver->free_gatt_table(bridge); - if (bridge->key_list) { - vfree(bridge->key_list); - bridge->key_list = NULL; - } + + vfree(bridge->key_list); + bridge->key_list = NULL; if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 11f9ee58112..927a5bbe112 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, void cleanup_module(void) { - int i; + unsigned int i; misc_deregister(&ac_miscdev); @@ -195,7 +195,7 @@ int __init applicom_init(void) int i, numisa = 0; struct pci_dev *dev = NULL; void __iomem *RamIO; - int boardno; + int boardno, ret; printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $\n"); @@ -294,7 +294,8 @@ int __init applicom_init(void) } if (!numisa) - printk(KERN_WARNING"ac.o: No valid ISA Applicom boards found at mem 0x%lx\n",mem); + printk(KERN_WARNING "ac.o: No valid ISA Applicom boards found " + "at mem 0x%lx\n", mem); fin: init_waitqueue_head(&FlagSleepRec); @@ -304,7 +305,11 @@ int __init applicom_init(void) DeviceErrorCount = 0; if (numboards) { - misc_register(&ac_miscdev); + ret = misc_register(&ac_miscdev); + if (ret) { + printk(KERN_WARNING "ac.o: Unable to register misc device\n"); + goto out; + } for (i = 0; i < MAX_BOARD; i++) { int serial; char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1]; @@ -337,6 +342,17 @@ int __init applicom_init(void) else return -ENXIO; + +out: + for (i = 0; i < MAX_BOARD; i++) { + if (!apbs[i].RamIO) + continue; + if (apbs[i].irq) + free_irq(apbs[i].irq, &dummy); + iounmap(apbs[i].RamIO); + } + pci_disable_device(dev); + return ret; } diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 6a5337bf093..cf4c3648463 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -865,7 +865,7 @@ static void cyz_poll(unsigned long); static long cyz_polling_cycle = CZ_DEF_POLL; static int cyz_timeron = 0; -static struct timer_list cyz_timerlist = TIMER_INITIALIZER(cyz_poll, 0, 0); +static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); #else /* CONFIG_CYZ_INTR */ static 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 1704a2a5704..b2e0928e842 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) set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&ftape_wait_intr, &wait); - while (!ft_interrupt_seen && timeout) { - set_current_state(TASK_INTERRUPTIBLE); - timeout = schedule_timeout(timeout); - } + while (!ft_interrupt_seen && timeout) + timeout = schedule_timeout_interruptible(timeout); spin_lock_irq(¤t->sighand->siglock); current->blocked = old_sigmask; diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index 81d811edf3c..a54bc93353a 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; static void hangcheck_fire(unsigned long); -static struct timer_list hangcheck_ticktock = - TIMER_INITIALIZER(hangcheck_fire, 0, 0); +static DEFINE_TIMER(hangcheck_ticktock, hangcheck_fire, 0, 0); static void hangcheck_fire(unsigned long data) diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 5fe8461271f..de0379b6d50 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -100,14 +100,14 @@ static struct hpets *hpets; #endif #ifndef readq -static unsigned long long __inline readq(void __iomem *addr) +static inline unsigned long long readq(void __iomem *addr) { return readl(addr) | (((unsigned long long)readl(addr + 4)) << 32LL); } #endif #ifndef writeq -static void __inline writeq(unsigned long long v, void __iomem *addr) +static inline void writeq(unsigned long long v, void __iomem *addr) { writel(v & 0xffffffff, addr); writel(v >> 32, addr + 4); diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c index 3480535a09c..6f673d2de0b 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, return ret ? : -EAGAIN; if(need_resched()) - { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - } + schedule_timeout_interruptible(1); else udelay(200); /* FIXME: We could poll for 250uS ?? */ diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c index 82c5f30375a..ba85eb1b6ec 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, timeout--; // So negative values == forever if (!in_interrupt()) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); // short nap + schedule_timeout_interruptible(1); // short nap } else { // we cannot sched/sleep in interrrupt silly return 0; @@ -1132,8 +1131,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user ) ip2trace (CHANN, ITRC_OUTPUT, 61, 0 ); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(2); + schedule_timeout_interruptible(2); if (signal_pending(current)) { break; } diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index cf0cd58d630..9e4e26aef94 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c @@ -120,7 +120,6 @@ #include <linux/vmalloc.h> #include <linux/init.h> -#include <asm/serial.h> #include <asm/uaccess.h> @@ -255,7 +254,7 @@ static unsigned long bh_counter = 0; * selected, the board is serviced periodically to see if anything needs doing. */ #define POLL_TIMEOUT (jiffies + 1) -static struct timer_list PollTimer = TIMER_INITIALIZER(ip2_poll, 0, 0); +static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); static char TimerOn; #ifdef IP2DEBUG_TRACE diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 883ac4352be..a09ff108068 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, case COMPAT_IPMICTL_RECEIVE_MSG: case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC: { - struct ipmi_recv *precv64, recv64; + struct ipmi_recv __user *precv64; + struct ipmi_recv recv64; if (get_compat_ipmi_recv(&recv64, compat_ptr(arg))) return -EFAULT; @@ -748,7 +749,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, ((cmd == COMPAT_IPMICTL_RECEIVE_MSG) ? IPMICTL_RECEIVE_MSG : IPMICTL_RECEIVE_MSG_TRUNC), - (long) precv64); + (unsigned long) precv64); if (rc != 0) return rc; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 278f8410499..b6e5cbfb09f 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) for (;;) { if (smi_result == SI_SM_CALL_WITH_DELAY) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); + schedule_timeout_uninterruptible(1); smi_result = smi_info->handlers->event( smi_info->si_sm, 100); } @@ -2256,10 +2255,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi) /* Wait for the timer to stop. This avoids problems with race conditions removing the timer here. */ - while (! new_smi->timer_stopped) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); - } + while (!new_smi->timer_stopped) + schedule_timeout_uninterruptible(1); out_err: if (new_smi->intf) @@ -2379,17 +2376,14 @@ static void __exit cleanup_one_si(struct smi_info *to_clean) /* Wait for the timer to stop. This avoids problems with race conditions removing the timer here. */ - while (! to_clean->timer_stopped) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); - } + while (!to_clean->timer_stopped) + schedule_timeout_uninterruptible(1); /* Interrupts and timeouts are stopped, now make sure the interface is in a clean state. */ while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { poll(to_clean); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } rv = ipmi_unregister_smi(to_clean->intf); diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index e71aaae855a..2da64bf7469 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) /* Wait to make sure the message makes it out. The lower layer has pointers to our buffers, we want to make sure they are done before we release our memory. */ - while (atomic_read(&set_timeout_tofree)) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); - } + while (atomic_read(&set_timeout_tofree)) + schedule_timeout_uninterruptible(1); /* Disconnect from IPMI. */ rv = ipmi_destroy_user(watchdog_user); diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 52a073eee20..9c19e5435a1 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -780,7 +780,7 @@ static struct file_operations stli_fsiomem = { * much cheaper on host cpu than using interrupts. It turns out to * not increase character latency by much either... */ -static struct timer_list stli_timerlist = TIMER_INITIALIZER(stli_poll, 0, 0); +static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0); static int stli_timeron; diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 523fd3c8bba..1745065d8f7 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -233,8 +233,7 @@ static void kd_nosound(unsigned long ignored) } } -static struct timer_list kd_mksound_timer = - TIMER_INITIALIZER(kd_nosound, 0, 0); +static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0); void kd_mksound(unsigned int hz, unsigned int ticks) { diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index cf01a720eb2..b7716114614 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c @@ -613,10 +613,15 @@ static struct miscdevice lcd_dev = { static int lcd_init(void) { + int ret; unsigned long data; pr_info("%s\n", LCD_DRIVER); - misc_register(&lcd_dev); + ret = misc_register(&lcd_dev); + if (ret) { + printk(KERN_WARNING LCD "Unable to register misc device.\n"); + return ret; + } /* Check region? Naaah! Just snarf it up. */ /* request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/ diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 59eebe5a035..2afb9038dbc 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -128,6 +128,7 @@ #include <linux/console.h> #include <linux/device.h> #include <linux/wait.h> +#include <linux/jiffies.h> #include <linux/parport.h> #undef LP_STATS @@ -307,7 +308,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf, (LP_F(minor) & LP_ABORT)); #ifdef LP_STATS - if (jiffies-lp_table[minor].lastcall > LP_TIME(minor)) + if (time_after(jiffies, lp_table[minor].lastcall + LP_TIME(minor))) lp_table[minor].runchars = 0; lp_table[minor].lastcall = jiffies; diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index d0ef1ae4129..45d012d85e8 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) */ timeout = jiffies + HZ; while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(5); + schedule_timeout_interruptible(5); if (time_after(jiffies, timeout)) break; } @@ -1080,10 +1079,8 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) info->event = 0; info->tty = NULL; if (info->blocked_open) { - if (info->close_delay) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(info->close_delay); - } + if (info->close_delay) + schedule_timeout_interruptible(info->close_delay); wake_up_interruptible(&info->open_wait); } @@ -1801,8 +1798,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk("lsr = %d (jiff=%lu)...", lsr, jiffies); #endif - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(char_time); + schedule_timeout_interruptible(char_time); if (signal_pending(current)) break; if (timeout && time_after(jiffies, orig_jiffies + timeout)) diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 09103b3d8f0..c9bdf544ed2 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -62,7 +62,7 @@ static inline unsigned char *alloc_buf(void) { - int prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; + unsigned int prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; if (PAGE_SIZE != N_TTY_BUF_SIZE) return kmalloc(N_TTY_BUF_SIZE, prio); diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 7a0c7464812..02d7f046c10 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -1,7 +1,7 @@ /* * linux/drivers/char/pcmcia/synclink_cs.c * - * $Id: synclink_cs.c,v 4.26 2004/08/11 19:30:02 paulkf Exp $ + * $Id: synclink_cs.c,v 4.34 2005/09/08 13:20:54 paulkf Exp $ * * Device driver for Microgate SyncLink PC Card * multiprotocol serial adapter. @@ -472,7 +472,7 @@ module_param_array(dosyncppp, int, NULL, 0); MODULE_LICENSE("GPL"); static char *driver_name = "SyncLink PC Card driver"; -static char *driver_version = "$Revision: 4.26 $"; +static char *driver_version = "$Revision: 4.34 $"; static struct tty_driver *serial_driver; @@ -1457,6 +1457,8 @@ static int startup(MGSLPC_INFO * info) info->pending_bh = 0; + memset(&info->icount, 0, sizeof(info->icount)); + init_timer(&info->tx_timer); info->tx_timer.data = (unsigned long)info; info->tx_timer.function = tx_timeout; @@ -1946,9 +1948,13 @@ static int get_stats(MGSLPC_INFO * info, struct mgsl_icount __user *user_icount) int err; if (debug_level >= DEBUG_LEVEL_INFO) printk("get_params(%s)\n", info->device_name); - COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount)); - if (err) - return -EFAULT; + if (!user_icount) { + memset(&info->icount, 0, sizeof(info->icount)); + } else { + COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); + if (err) + return -EFAULT; + } return 0; } diff --git a/drivers/char/pty.c b/drivers/char/pty.c index da32889d22c..49f3997fd25 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -149,15 +149,14 @@ static int pty_write_room(struct tty_struct *tty) static int pty_chars_in_buffer(struct tty_struct *tty) { struct tty_struct *to = tty->link; - ssize_t (*chars_in_buffer)(struct tty_struct *); int count; /* We should get the line discipline lock for "tty->link" */ - if (!to || !(chars_in_buffer = to->ldisc.chars_in_buffer)) + if (!to || !to->ldisc.chars_in_buffer) return 0; /* The ldisc must report 0 if no characters available to be read */ - count = chars_in_buffer(to); + count = to->ldisc.chars_in_buffer(to); if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 37c8bea8e2b..ea2d54be484 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -1,7 +1,7 @@ /* * linux/drivers/char/synclink.c * - * $Id: synclink.c,v 4.28 2004/08/11 19:30:01 paulkf Exp $ + * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $ * * Device driver for Microgate SyncLink ISA and PCI * high speed multiprotocol serial adapters. @@ -141,9 +141,9 @@ static MGSL_PARAMS default_params = { typedef struct _DMABUFFERENTRY { u32 phys_addr; /* 32-bit flat physical address of data buffer */ - u16 count; /* buffer size/data count */ - u16 status; /* Control/status field */ - u16 rcc; /* character count field */ + volatile u16 count; /* buffer size/data count */ + volatile u16 status; /* Control/status field */ + volatile u16 rcc; /* character count field */ u16 reserved; /* padding required by 16C32 */ u32 link; /* 32-bit flat link to next buffer entry */ char *virt_addr; /* virtual address of data buffer */ @@ -896,7 +896,7 @@ module_param_array(txdmabufs, int, NULL, 0); module_param_array(txholdbufs, int, NULL, 0); static char *driver_name = "SyncLink serial driver"; -static char *driver_version = "$Revision: 4.28 $"; +static char *driver_version = "$Revision: 4.37 $"; static int synclink_init_one (struct pci_dev *dev, const struct pci_device_id *ent); @@ -1814,6 +1814,8 @@ static int startup(struct mgsl_struct * info) info->pending_bh = 0; + memset(&info->icount, 0, sizeof(info->icount)); + init_timer(&info->tx_timer); info->tx_timer.data = (unsigned long)info; info->tx_timer.function = mgsl_tx_timeout; @@ -2470,12 +2472,12 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user * printk("%s(%d):mgsl_get_params(%s)\n", __FILE__,__LINE__, info->device_name); - COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount)); - if (err) { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_get_stats(%s) user buffer copy failed\n", - __FILE__,__LINE__,info->device_name); - return -EFAULT; + if (!user_icount) { + memset(&info->icount, 0, sizeof(info->icount)); + } else { + COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); + if (err) + return -EFAULT; } return 0; @@ -6149,6 +6151,11 @@ static void usc_set_async_mode( struct mgsl_struct *info ) usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); } + if (info->params.loopback) { + info->loopback_bits = 0x300; + outw(0x0300, info->io_base + CCAR); + } + } /* end of usc_set_async_mode() */ /* usc_loopback_frame() diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index ec949e4c070..6fb165cf8a6 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c @@ -1,5 +1,5 @@ /* - * $Id: synclinkmp.c,v 4.34 2005/03/04 15:07:10 paulkf Exp $ + * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $ * * Device driver for Microgate SyncLink Multiport * high speed multiprotocol serial adapter. @@ -55,7 +55,6 @@ #include <linux/netdevice.h> #include <linux/vmalloc.h> #include <linux/init.h> -#include <asm/serial.h> #include <linux/delay.h> #include <linux/ioctl.h> @@ -487,7 +486,7 @@ module_param_array(maxframe, int, NULL, 0); module_param_array(dosyncppp, int, NULL, 0); static char *driver_name = "SyncLink MultiPort driver"; -static char *driver_version = "$Revision: 4.34 $"; +static char *driver_version = "$Revision: 4.38 $"; static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); static void synclinkmp_remove_one(struct pci_dev *dev); @@ -556,7 +555,6 @@ static int set_txidle(SLMP_INFO *info, int idle_mode); static int tx_enable(SLMP_INFO *info, int enable); static int tx_abort(SLMP_INFO *info); static int rx_enable(SLMP_INFO *info, int enable); -static int map_status(int signals); static int modem_input_wait(SLMP_INFO *info,int arg); static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr); static 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 static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes static u32 misc_ctrl_value = 0x007e4040; -static u32 lcr1_brdr_value = 0x00800029; +static u32 lcr1_brdr_value = 0x00800028; static u32 read_ahead_count = 8; @@ -2750,6 +2748,8 @@ static int startup(SLMP_INFO * info) info->pending_bh = 0; + memset(&info->icount, 0, sizeof(info->icount)); + /* program hardware for current parameters */ reset_port(info); @@ -2953,12 +2953,12 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount) printk("%s(%d):%s get_params()\n", __FILE__,__LINE__, info->device_name); - COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount)); - if (err) { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s get_stats() user buffer copy failed\n", - __FILE__,__LINE__,info->device_name); - return -EFAULT; + if (!user_icount) { + memset(&info->icount, 0, sizeof(info->icount)); + } else { + COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); + if (err) + return -EFAULT; } return 0; @@ -3109,16 +3109,6 @@ static int rx_enable(SLMP_INFO * info, int enable) return 0; } -static int map_status(int signals) -{ - /* Map status bits to API event bits */ - - return ((signals & SerialSignal_DSR) ? MgslEvent_DsrActive : MgslEvent_DsrInactive) + - ((signals & SerialSignal_CTS) ? MgslEvent_CtsActive : MgslEvent_CtsInactive) + - ((signals & SerialSignal_DCD) ? MgslEvent_DcdActive : MgslEvent_DcdInactive) + - ((signals & SerialSignal_RI) ? MgslEvent_RiActive : MgslEvent_RiInactive); -} - /* wait for specified event to occur */ static 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) /* return immediately if state matches requested events */ get_signals(info); - s = map_status(info->serial_signals); + s = info->serial_signals; events = mask & ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + @@ -4489,11 +4479,13 @@ void async_mode(SLMP_INFO *info) /* MD2, Mode Register 2 * * 07..02 Reserved, must be 0 - * 01..00 CNCT<1..0> Channel connection, 0=normal + * 01..00 CNCT<1..0> Channel connection, 00=normal 11=local loopback * * 0000 0000 */ RegValue = 0x00; + if (info->params.loopback) + RegValue |= (BIT1 + BIT0); write_reg(info, MD2, RegValue); /* RXS, Receive clock source @@ -4574,9 +4566,6 @@ void async_mode(SLMP_INFO *info) write_reg(info, IE2, info->ie2_value); set_rate( info, info->params.data_rate * 16 ); - - if (info->params.loopback) - enable_loopback(info,1); } /* Program the SCA for HDLC communications. diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 9d657127f31..e5953f3433f 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) static int tty_set_ldisc(struct tty_struct *tty, int ldisc) { - int retval = 0; - struct tty_ldisc o_ldisc; + int retval = 0; + struct tty_ldisc o_ldisc; char buf[64]; int work; unsigned long flags; struct tty_ldisc *ld; + struct tty_struct *o_tty; if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) return -EINVAL; restart: - if (tty->ldisc.num == ldisc) - return 0; /* We are already in the desired discipline */ - ld = tty_ldisc_get(ldisc); /* Eduardo Blanco <ejbs@cs.cs.com.uy> */ /* Cyrus Durgin <cider@speakeasy.org> */ @@ -494,45 +492,74 @@ restart: if (ld == NULL) return -EINVAL; - o_ldisc = tty->ldisc; - tty_wait_until_sent(tty, 0); + if (tty->ldisc.num == ldisc) { + tty_ldisc_put(ldisc); + return 0; + } + + o_ldisc = tty->ldisc; + o_tty = tty->link; + /* * Make sure we don't change while someone holds a * reference to the line discipline. The TTY_LDISC bit * prevents anyone taking a reference once it is clear. * We need the lock to avoid racing reference takers. */ - + spin_lock_irqsave(&tty_ldisc_lock, flags); - if(tty->ldisc.refcount) - { - /* Free the new ldisc we grabbed. Must drop the lock - first. */ + if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) { + if(tty->ldisc.refcount) { + /* Free the new ldisc we grabbed. Must drop the lock + first. */ + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + tty_ldisc_put(ldisc); + /* + * There are several reasons we may be busy, including + * random momentary I/O traffic. We must therefore + * retry. We could distinguish between blocking ops + * and retries if we made tty_ldisc_wait() smarter. That + * is up for discussion. + */ + if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0) + return -ERESTARTSYS; + goto restart; + } + if(o_tty && o_tty->ldisc.refcount) { + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + tty_ldisc_put(ldisc); + if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0) + return -ERESTARTSYS; + goto restart; + } + } + + /* if the TTY_LDISC bit is set, then we are racing against another ldisc change */ + + if (!test_bit(TTY_LDISC, &tty->flags)) { spin_unlock_irqrestore(&tty_ldisc_lock, flags); tty_ldisc_put(ldisc); - /* - * There are several reasons we may be busy, including - * random momentary I/O traffic. We must therefore - * retry. We could distinguish between blocking ops - * and retries if we made tty_ldisc_wait() smarter. That - * is up for discussion. - */ - if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0) - return -ERESTARTSYS; + ld = tty_ldisc_ref_wait(tty); + tty_ldisc_deref(ld); goto restart; } - clear_bit(TTY_LDISC, &tty->flags); + + clear_bit(TTY_LDISC, &tty->flags); clear_bit(TTY_DONT_FLIP, &tty->flags); + if (o_tty) { + clear_bit(TTY_LDISC, &o_tty->flags); + clear_bit(TTY_DONT_FLIP, &o_tty->flags); + } spin_unlock_irqrestore(&tty_ldisc_lock, flags); - + /* * From this point on we know nobody has an ldisc * usage reference, nor can they obtain one until * we say so later on. */ - + work = cancel_delayed_work(&tty->flip.work); /* * Wait for ->hangup_work and ->flip.work handlers to terminate @@ -583,10 +610,12 @@ restart: */ tty_ldisc_enable(tty); + if (o_tty) + tty_ldisc_enable(o_tty); /* Restart it in case no characters kick it off. Safe if already running */ - if(work) + if (work) schedule_delayed_work(&tty->flip.work, 1); return retval; } @@ -2425,6 +2454,7 @@ static void __do_SAK(void *arg) int i; struct file *filp; struct tty_ldisc *disc; + struct fdtable *fdt; if (!tty) return; @@ -2450,8 +2480,9 @@ static void __do_SAK(void *arg) } task_lock(p); if (p->files) { - spin_lock(&p->files->file_lock); - for (i=0; i < p->files->max_fds; i++) { + rcu_read_lock(); + fdt = files_fdtable(p->files); + for (i=0; i < fdt->max_fds; i++) { filp = fcheck_files(p->files, i); if (!filp) continue; @@ -2464,7 +2495,7 @@ static void __do_SAK(void *arg) break; } } - spin_unlock(&p->files->file_lock); + rcu_read_unlock(); } task_unlock(p); } while_each_task_pid(session, PIDTYPE_SID, p); diff --git a/drivers/char/vt.c b/drivers/char/vt.c index b8d0c290b0d..1e33cb032e0 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) unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; unsigned int old_cols, old_rows, old_row_size, old_screen_size; unsigned int new_cols, new_rows, new_row_size, new_screen_size; + unsigned int end; unsigned short *newscreen; WARN_CONSOLE_UNLOCKED(); @@ -794,20 +795,44 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) old_origin = vc->vc_origin; new_origin = (long) newscreen; new_scr_end = new_origin + new_screen_size; - if (new_rows < old_rows) - old_origin += (old_rows - new_rows) * old_row_size; + + if (vc->vc_y > new_rows) { + if (old_rows - vc->vc_y < new_rows) { + /* + * Cursor near the bottom, copy contents from the + * bottom of buffer + */ + old_origin += (old_rows - new_rows) * old_row_size; + end = vc->vc_scr_end; + } else { + /* + * Cursor is in no man's land, copy 1/2 screenful + * from the top and bottom of cursor position + */ + old_origin += (vc->vc_y - new_rows/2) * old_row_size; + end = old_origin + new_screen_size; + } + } else + /* + * Cursor near the top, copy contents from the top of buffer + */ + end = (old_rows > new_rows) ? old_origin + new_screen_size : + vc->vc_scr_end; update_attr(vc); - while (old_origin < vc->vc_scr_end) { - scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth); + while (old_origin < end) { + scr_memcpyw((unsigned short *) new_origin, + (unsigned short *) old_origin, rlth); if (rrem) - scr_memsetw((void *)(new_origin + rlth), vc->vc_video_erase_char, rrem); + scr_memsetw((void *)(new_origin + rlth), + vc->vc_video_erase_char, rrem); old_origin += old_row_size; new_origin += new_row_size; } if (new_scr_end > new_origin) - scr_memsetw((void *)new_origin, vc->vc_video_erase_char, new_scr_end - new_origin); + scr_memsetw((void *)new_origin, vc->vc_video_erase_char, + new_scr_end - new_origin); if (vc->vc_kmalloced) kfree(vc->vc_screenbuf); vc->vc_screenbuf = newscreen; diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c index c9b301dccec..7fc2188386d 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 */ static int watchdog_port; static int mixcomwd_timer_alive; -static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0); static char expect_close; static int nowayout = WATCHDOG_NOWAYOUT; |