diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/agp/intel-agp.c | 3 | ||||
-rw-r--r-- | drivers/char/amiserial.c | 4 | ||||
-rw-r--r-- | drivers/char/hvc_console.c | 4 | ||||
-rw-r--r-- | drivers/char/i8k.c | 21 | ||||
-rw-r--r-- | drivers/char/isicom.c | 9 | ||||
-rw-r--r-- | drivers/char/istallion.c | 2 | ||||
-rw-r--r-- | drivers/char/mem.c | 10 | ||||
-rw-r--r-- | drivers/char/mxser.c | 9 | ||||
-rw-r--r-- | drivers/char/pcmcia/cm4000_cs.c | 8 | ||||
-rw-r--r-- | drivers/char/raw.c | 1 | ||||
-rw-r--r-- | drivers/char/riscom8.c | 1 | ||||
-rw-r--r-- | drivers/char/serial167.c | 2 | ||||
-rw-r--r-- | drivers/char/stallion.c | 7 | ||||
-rw-r--r-- | drivers/char/sysrq.c | 2 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 1 | ||||
-rw-r--r-- | drivers/char/virtio_console.c | 65 |
16 files changed, 97 insertions, 52 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index d41331bc2aa7..aa4248efc5d8 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -1817,8 +1817,6 @@ static int intel_845_configure(void) | |||
1817 | pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); | 1817 | pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); |
1818 | /* clear any possible error conditions */ | 1818 | /* clear any possible error conditions */ |
1819 | pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); | 1819 | pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); |
1820 | |||
1821 | intel_i830_setup_flush(); | ||
1822 | return 0; | 1820 | return 0; |
1823 | } | 1821 | } |
1824 | 1822 | ||
@@ -2188,7 +2186,6 @@ static const struct agp_bridge_driver intel_845_driver = { | |||
2188 | .agp_destroy_page = agp_generic_destroy_page, | 2186 | .agp_destroy_page = agp_generic_destroy_page, |
2189 | .agp_destroy_pages = agp_generic_destroy_pages, | 2187 | .agp_destroy_pages = agp_generic_destroy_pages, |
2190 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 2188 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
2191 | .chipset_flush = intel_i830_chipset_flush, | ||
2192 | }; | 2189 | }; |
2193 | 2190 | ||
2194 | static const struct agp_bridge_driver intel_850_driver = { | 2191 | static const struct agp_bridge_driver intel_850_driver = { |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 6c32fbf07164..56b27671adc4 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -2021,8 +2021,6 @@ static int __init rs_init(void) | |||
2021 | state->baud_base = amiga_colorclock; | 2021 | state->baud_base = amiga_colorclock; |
2022 | state->xmit_fifo_size = 1; | 2022 | state->xmit_fifo_size = 1; |
2023 | 2023 | ||
2024 | local_irq_save(flags); | ||
2025 | |||
2026 | /* set ISRs, and then disable the rx interrupts */ | 2024 | /* set ISRs, and then disable the rx interrupts */ |
2027 | error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state); | 2025 | error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state); |
2028 | if (error) | 2026 | if (error) |
@@ -2033,6 +2031,8 @@ static int __init rs_init(void) | |||
2033 | if (error) | 2031 | if (error) |
2034 | goto fail_free_irq; | 2032 | goto fail_free_irq; |
2035 | 2033 | ||
2034 | local_irq_save(flags); | ||
2035 | |||
2036 | /* turn off Rx and Tx interrupts */ | 2036 | /* turn off Rx and Tx interrupts */ |
2037 | custom.intena = IF_RBF | IF_TBE; | 2037 | custom.intena = IF_RBF | IF_TBE; |
2038 | mb(); | 2038 | mb(); |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index d3890e8d30e1..35cca4c7fb18 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -368,16 +368,12 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
368 | hp = tty->driver_data; | 368 | hp = tty->driver_data; |
369 | 369 | ||
370 | spin_lock_irqsave(&hp->lock, flags); | 370 | spin_lock_irqsave(&hp->lock, flags); |
371 | tty_kref_get(tty); | ||
372 | 371 | ||
373 | if (--hp->count == 0) { | 372 | if (--hp->count == 0) { |
374 | /* We are done with the tty pointer now. */ | 373 | /* We are done with the tty pointer now. */ |
375 | hp->tty = NULL; | 374 | hp->tty = NULL; |
376 | spin_unlock_irqrestore(&hp->lock, flags); | 375 | spin_unlock_irqrestore(&hp->lock, flags); |
377 | 376 | ||
378 | /* Put the ref obtained in hvc_open() */ | ||
379 | tty_kref_put(tty); | ||
380 | |||
381 | if (hp->ops->notifier_del) | 377 | if (hp->ops->notifier_del) |
382 | hp->ops->notifier_del(hp, hp->data); | 378 | hp->ops->notifier_del(hp, hp->data); |
383 | 379 | ||
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index fc8cf7ac7f2b..4cd8b227c11f 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
24 | #include <linux/dmi.h> | 24 | #include <linux/dmi.h> |
25 | #include <linux/capability.h> | 25 | #include <linux/capability.h> |
26 | #include <linux/smp_lock.h> | ||
26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | 29 | ||
@@ -82,8 +83,7 @@ module_param(fan_mult, int, 0); | |||
82 | MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with"); | 83 | MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with"); |
83 | 84 | ||
84 | static int i8k_open_fs(struct inode *inode, struct file *file); | 85 | static int i8k_open_fs(struct inode *inode, struct file *file); |
85 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, | 86 | static long i8k_ioctl(struct file *, unsigned int, unsigned long); |
86 | unsigned long); | ||
87 | 87 | ||
88 | static const struct file_operations i8k_fops = { | 88 | static const struct file_operations i8k_fops = { |
89 | .owner = THIS_MODULE, | 89 | .owner = THIS_MODULE, |
@@ -91,7 +91,7 @@ static const struct file_operations i8k_fops = { | |||
91 | .read = seq_read, | 91 | .read = seq_read, |
92 | .llseek = seq_lseek, | 92 | .llseek = seq_lseek, |
93 | .release = single_release, | 93 | .release = single_release, |
94 | .ioctl = i8k_ioctl, | 94 | .unlocked_ioctl = i8k_ioctl, |
95 | }; | 95 | }; |
96 | 96 | ||
97 | struct smm_regs { | 97 | struct smm_regs { |
@@ -307,8 +307,8 @@ static int i8k_get_dell_signature(int req_fn) | |||
307 | return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1; | 307 | return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1; |
308 | } | 308 | } |
309 | 309 | ||
310 | static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, | 310 | static int |
311 | unsigned long arg) | 311 | i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg) |
312 | { | 312 | { |
313 | int val = 0; | 313 | int val = 0; |
314 | int speed; | 314 | int speed; |
@@ -395,6 +395,17 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, | |||
395 | return 0; | 395 | return 0; |
396 | } | 396 | } |
397 | 397 | ||
398 | static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) | ||
399 | { | ||
400 | long ret; | ||
401 | |||
402 | lock_kernel(); | ||
403 | ret = i8k_ioctl_unlocked(fp, cmd, arg); | ||
404 | unlock_kernel(); | ||
405 | |||
406 | return ret; | ||
407 | } | ||
408 | |||
398 | /* | 409 | /* |
399 | * Print the information for /proc/i8k. | 410 | * Print the information for /proc/i8k. |
400 | */ | 411 | */ |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 0fa2e4a0835d..c1ab303455cf 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -879,8 +879,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) | |||
879 | if (tport == NULL) | 879 | if (tport == NULL) |
880 | return -ENODEV; | 880 | return -ENODEV; |
881 | port = container_of(tport, struct isi_port, port); | 881 | port = container_of(tport, struct isi_port, port); |
882 | card = &isi_card[BOARD(tty->index)]; | ||
883 | 882 | ||
883 | tty->driver_data = port; | ||
884 | return tty_port_open(tport, tty, filp); | 884 | return tty_port_open(tport, tty, filp); |
885 | } | 885 | } |
886 | 886 | ||
@@ -936,7 +936,12 @@ static void isicom_shutdown(struct tty_port *port) | |||
936 | static void isicom_close(struct tty_struct *tty, struct file *filp) | 936 | static void isicom_close(struct tty_struct *tty, struct file *filp) |
937 | { | 937 | { |
938 | struct isi_port *ip = tty->driver_data; | 938 | struct isi_port *ip = tty->driver_data; |
939 | struct tty_port *port = &ip->port; | 939 | struct tty_port *port; |
940 | |||
941 | if (ip == NULL) | ||
942 | return; | ||
943 | |||
944 | port = &ip->port; | ||
940 | if (isicom_paranoia_check(ip, tty->name, "isicom_close")) | 945 | if (isicom_paranoia_check(ip, tty->name, "isicom_close")) |
941 | return; | 946 | return; |
942 | tty_port_close(port, tty, filp); | 947 | tty_port_close(port, tty, filp); |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 4cd6c527ee41..4e395c956a09 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -827,6 +827,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
827 | return -ENODEV; | 827 | return -ENODEV; |
828 | if (portp->devnr < 1) | 828 | if (portp->devnr < 1) |
829 | return -ENODEV; | 829 | return -ENODEV; |
830 | |||
831 | tty->driver_data = portp; | ||
830 | return tty_port_open(&portp->port, tty, filp); | 832 | return tty_port_open(&portp->port, tty, filp); |
831 | } | 833 | } |
832 | 834 | ||
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 1f3215ac085b..f54dab8acdcd 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -225,6 +225,7 @@ int __weak phys_mem_access_prot_allowed(struct file *file, | |||
225 | * outside of main memory. | 225 | * outside of main memory. |
226 | * | 226 | * |
227 | */ | 227 | */ |
228 | #ifdef pgprot_noncached | ||
228 | static int uncached_access(struct file *file, unsigned long addr) | 229 | static int uncached_access(struct file *file, unsigned long addr) |
229 | { | 230 | { |
230 | #if defined(CONFIG_IA64) | 231 | #if defined(CONFIG_IA64) |
@@ -251,6 +252,7 @@ static int uncached_access(struct file *file, unsigned long addr) | |||
251 | return addr >= __pa(high_memory); | 252 | return addr >= __pa(high_memory); |
252 | #endif | 253 | #endif |
253 | } | 254 | } |
255 | #endif | ||
254 | 256 | ||
255 | static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | 257 | static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, |
256 | unsigned long size, pgprot_t vma_prot) | 258 | unsigned long size, pgprot_t vma_prot) |
@@ -710,11 +712,6 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig) | |||
710 | switch (orig) { | 712 | switch (orig) { |
711 | case SEEK_CUR: | 713 | case SEEK_CUR: |
712 | offset += file->f_pos; | 714 | offset += file->f_pos; |
713 | if ((unsigned long long)offset < | ||
714 | (unsigned long long)file->f_pos) { | ||
715 | ret = -EOVERFLOW; | ||
716 | break; | ||
717 | } | ||
718 | case SEEK_SET: | 715 | case SEEK_SET: |
719 | /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */ | 716 | /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */ |
720 | if ((unsigned long long)offset >= ~0xFFFULL) { | 717 | if ((unsigned long long)offset >= ~0xFFFULL) { |
@@ -908,6 +905,9 @@ static int __init chr_dev_init(void) | |||
908 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); | 905 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); |
909 | 906 | ||
910 | mem_class = class_create(THIS_MODULE, "mem"); | 907 | mem_class = class_create(THIS_MODULE, "mem"); |
908 | if (IS_ERR(mem_class)) | ||
909 | return PTR_ERR(mem_class); | ||
910 | |||
911 | mem_class->devnode = mem_devnode; | 911 | mem_class->devnode = mem_devnode; |
912 | for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) { | 912 | for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) { |
913 | if (!devlist[minor].name) | 913 | if (!devlist[minor].name) |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 95c9f54f3d30..d2692d443f7b 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -1011,6 +1011,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
1011 | if (!info->ioaddr) | 1011 | if (!info->ioaddr) |
1012 | return -ENODEV; | 1012 | return -ENODEV; |
1013 | 1013 | ||
1014 | tty->driver_data = info; | ||
1014 | return tty_port_open(&info->port, tty, filp); | 1015 | return tty_port_open(&info->port, tty, filp); |
1015 | } | 1016 | } |
1016 | 1017 | ||
@@ -1074,7 +1075,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1074 | struct mxser_port *info = tty->driver_data; | 1075 | struct mxser_port *info = tty->driver_data; |
1075 | struct tty_port *port = &info->port; | 1076 | struct tty_port *port = &info->port; |
1076 | 1077 | ||
1077 | if (tty->index == MXSER_PORTS) | 1078 | if (tty->index == MXSER_PORTS || info == NULL) |
1078 | return; | 1079 | return; |
1079 | if (tty_port_close_start(port, tty, filp) == 0) | 1080 | if (tty_port_close_start(port, tty, filp) == 0) |
1080 | return; | 1081 | return; |
@@ -1768,7 +1769,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1768 | int len, lsr; | 1769 | int len, lsr; |
1769 | 1770 | ||
1770 | len = mxser_chars_in_buffer(tty); | 1771 | len = mxser_chars_in_buffer(tty); |
1771 | spin_lock(&info->slock); | 1772 | spin_lock_irq(&info->slock); |
1772 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE; | 1773 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE; |
1773 | spin_unlock_irq(&info->slock); | 1774 | spin_unlock_irq(&info->slock); |
1774 | len += (lsr ? 0 : 1); | 1775 | len += (lsr ? 0 : 1); |
@@ -1778,12 +1779,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1778 | case MOXA_ASPP_MON: { | 1779 | case MOXA_ASPP_MON: { |
1779 | int mcr, status; | 1780 | int mcr, status; |
1780 | 1781 | ||
1781 | spin_lock(&info->slock); | 1782 | spin_lock_irq(&info->slock); |
1782 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | 1783 | status = mxser_get_msr(info->ioaddr, 1, tty->index); |
1783 | mxser_check_modem_status(tty, info, status); | 1784 | mxser_check_modem_status(tty, info, status); |
1784 | 1785 | ||
1785 | mcr = inb(info->ioaddr + UART_MCR); | 1786 | mcr = inb(info->ioaddr + UART_MCR); |
1786 | spin_unlock(&info->slock); | 1787 | spin_unlock_irq(&info->slock); |
1787 | 1788 | ||
1788 | if (mcr & MOXA_MUST_MCR_XON_FLAG) | 1789 | if (mcr & MOXA_MUST_MCR_XON_FLAG) |
1789 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; | 1790 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index c9bc896d68af..90b199f97bec 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, | |||
1026 | 1026 | ||
1027 | xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */ | 1027 | xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */ |
1028 | /* last check before exit */ | 1028 | /* last check before exit */ |
1029 | if (!io_detect_cm4000(iobase, dev)) | 1029 | if (!io_detect_cm4000(iobase, dev)) { |
1030 | count = -ENODEV; | 1030 | rc = -ENODEV; |
1031 | goto release_io; | ||
1032 | } | ||
1031 | 1033 | ||
1032 | if (test_bit(IS_INVREV, &dev->flags) && count > 0) | 1034 | if (test_bit(IS_INVREV, &dev->flags) && count > 0) |
1033 | str_invert_revert(dev->rbuf, count); | 1035 | str_invert_revert(dev->rbuf, count); |
1034 | 1036 | ||
1035 | if (copy_to_user(buf, dev->rbuf, count)) | 1037 | if (copy_to_user(buf, dev->rbuf, count)) |
1036 | return -EFAULT; | 1038 | rc = -EFAULT; |
1037 | 1039 | ||
1038 | release_io: | 1040 | release_io: |
1039 | clear_bit(LOCK_IO, &dev->flags); | 1041 | clear_bit(LOCK_IO, &dev->flags); |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index d331c59b571c..8756ab0daa8b 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -248,6 +248,7 @@ static const struct file_operations raw_fops = { | |||
248 | .aio_read = generic_file_aio_read, | 248 | .aio_read = generic_file_aio_read, |
249 | .write = do_sync_write, | 249 | .write = do_sync_write, |
250 | .aio_write = blkdev_aio_write, | 250 | .aio_write = blkdev_aio_write, |
251 | .fsync = blkdev_fsync, | ||
251 | .open = raw_open, | 252 | .open = raw_open, |
252 | .release= raw_release, | 253 | .release= raw_release, |
253 | .ioctl = raw_ioctl, | 254 | .ioctl = raw_ioctl, |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 0a8d1e56c993..b02332a5412f 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -909,6 +909,7 @@ static int rc_open(struct tty_struct *tty, struct file *filp) | |||
909 | if (error) | 909 | if (error) |
910 | return error; | 910 | return error; |
911 | 911 | ||
912 | tty->driver_data = port; | ||
912 | return tty_port_open(&port->port, tty, filp); | 913 | return tty_port_open(&port->port, tty, filp); |
913 | } | 914 | } |
914 | 915 | ||
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 8dfd24721a82..78a62ebe75c7 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -627,7 +627,6 @@ static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id) | |||
627 | char data; | 627 | char data; |
628 | int char_count; | 628 | int char_count; |
629 | int save_cnt; | 629 | int save_cnt; |
630 | int len; | ||
631 | 630 | ||
632 | /* determine the channel and change to that context */ | 631 | /* determine the channel and change to that context */ |
633 | channel = (u_short) (base_addr[CyLICR] >> 2); | 632 | channel = (u_short) (base_addr[CyLICR] >> 2); |
@@ -1528,7 +1527,6 @@ static int | |||
1528 | cy_ioctl(struct tty_struct *tty, struct file *file, | 1527 | cy_ioctl(struct tty_struct *tty, struct file *file, |
1529 | unsigned int cmd, unsigned long arg) | 1528 | unsigned int cmd, unsigned long arg) |
1530 | { | 1529 | { |
1531 | unsigned long val; | ||
1532 | struct cyclades_port *info = tty->driver_data; | 1530 | struct cyclades_port *info = tty->driver_data; |
1533 | int ret_val = 0; | 1531 | int ret_val = 0; |
1534 | void __user *argp = (void __user *)arg; | 1532 | void __user *argp = (void __user *)arg; |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 0e511d61f544..6049fd731924 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -724,7 +724,6 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
724 | { | 724 | { |
725 | struct stlport *portp; | 725 | struct stlport *portp; |
726 | struct stlbrd *brdp; | 726 | struct stlbrd *brdp; |
727 | struct tty_port *port; | ||
728 | unsigned int minordev, brdnr, panelnr; | 727 | unsigned int minordev, brdnr, panelnr; |
729 | int portnr; | 728 | int portnr; |
730 | 729 | ||
@@ -754,7 +753,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
754 | portp = brdp->panels[panelnr]->ports[portnr]; | 753 | portp = brdp->panels[panelnr]->ports[portnr]; |
755 | if (portp == NULL) | 754 | if (portp == NULL) |
756 | return -ENODEV; | 755 | return -ENODEV; |
757 | port = &portp->port; | 756 | |
757 | tty->driver_data = portp; | ||
758 | return tty_port_open(&portp->port, tty, filp); | 758 | return tty_port_open(&portp->port, tty, filp); |
759 | 759 | ||
760 | } | 760 | } |
@@ -841,7 +841,8 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
841 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); | 841 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); |
842 | 842 | ||
843 | portp = tty->driver_data; | 843 | portp = tty->driver_data; |
844 | BUG_ON(portp == NULL); | 844 | if(portp == NULL) |
845 | return; | ||
845 | tty_port_close(&portp->port, tty, filp); | 846 | tty_port_close(&portp->port, tty, filp); |
846 | } | 847 | } |
847 | 848 | ||
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 59de2525d303..d4e8b213a462 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -289,7 +289,7 @@ static struct sysrq_key_op sysrq_showstate_blocked_op = { | |||
289 | 289 | ||
290 | static void sysrq_ftrace_dump(int key, struct tty_struct *tty) | 290 | static void sysrq_ftrace_dump(int key, struct tty_struct *tty) |
291 | { | 291 | { |
292 | ftrace_dump(); | 292 | ftrace_dump(DUMP_ALL); |
293 | } | 293 | } |
294 | static struct sysrq_key_op sysrq_ftrace_dump_op = { | 294 | static struct sysrq_key_op sysrq_ftrace_dump_op = { |
295 | .handler = sysrq_ftrace_dump, | 295 | .handler = sysrq_ftrace_dump, |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 6da962c9b21c..d71f0fc34b46 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1875,6 +1875,7 @@ got_driver: | |||
1875 | */ | 1875 | */ |
1876 | if (filp->f_op == &hung_up_tty_fops) | 1876 | if (filp->f_op == &hung_up_tty_fops) |
1877 | filp->f_op = &tty_fops; | 1877 | filp->f_op = &tty_fops; |
1878 | unlock_kernel(); | ||
1878 | goto retry_open; | 1879 | goto retry_open; |
1879 | } | 1880 | } |
1880 | unlock_kernel(); | 1881 | unlock_kernel(); |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 026ea6c27e07..196428c2287a 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -33,6 +33,35 @@ | |||
33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
34 | #include "hvc_console.h" | 34 | #include "hvc_console.h" |
35 | 35 | ||
36 | /* Moved here from .h file in order to disable MULTIPORT. */ | ||
37 | #define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */ | ||
38 | |||
39 | struct virtio_console_multiport_conf { | ||
40 | struct virtio_console_config config; | ||
41 | /* max. number of ports this device can hold */ | ||
42 | __u32 max_nr_ports; | ||
43 | /* number of ports added so far */ | ||
44 | __u32 nr_ports; | ||
45 | } __attribute__((packed)); | ||
46 | |||
47 | /* | ||
48 | * A message that's passed between the Host and the Guest for a | ||
49 | * particular port. | ||
50 | */ | ||
51 | struct virtio_console_control { | ||
52 | __u32 id; /* Port number */ | ||
53 | __u16 event; /* The kind of control event (see below) */ | ||
54 | __u16 value; /* Extra information for the key */ | ||
55 | }; | ||
56 | |||
57 | /* Some events for control messages */ | ||
58 | #define VIRTIO_CONSOLE_PORT_READY 0 | ||
59 | #define VIRTIO_CONSOLE_CONSOLE_PORT 1 | ||
60 | #define VIRTIO_CONSOLE_RESIZE 2 | ||
61 | #define VIRTIO_CONSOLE_PORT_OPEN 3 | ||
62 | #define VIRTIO_CONSOLE_PORT_NAME 4 | ||
63 | #define VIRTIO_CONSOLE_PORT_REMOVE 5 | ||
64 | |||
36 | /* | 65 | /* |
37 | * This is a global struct for storing common data for all the devices | 66 | * This is a global struct for storing common data for all the devices |
38 | * this driver handles. | 67 | * this driver handles. |
@@ -121,7 +150,7 @@ struct ports_device { | |||
121 | spinlock_t cvq_lock; | 150 | spinlock_t cvq_lock; |
122 | 151 | ||
123 | /* The current config space is stored here */ | 152 | /* The current config space is stored here */ |
124 | struct virtio_console_config config; | 153 | struct virtio_console_multiport_conf config; |
125 | 154 | ||
126 | /* The virtio device we're associated with */ | 155 | /* The virtio device we're associated with */ |
127 | struct virtio_device *vdev; | 156 | struct virtio_device *vdev; |
@@ -416,20 +445,16 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count) | |||
416 | out_vq->vq_ops->kick(out_vq); | 445 | out_vq->vq_ops->kick(out_vq); |
417 | 446 | ||
418 | if (ret < 0) { | 447 | if (ret < 0) { |
419 | len = 0; | 448 | in_count = 0; |
420 | goto fail; | 449 | goto fail; |
421 | } | 450 | } |
422 | 451 | ||
423 | /* | 452 | /* Wait till the host acknowledges it pushed out the data we sent. */ |
424 | * Wait till the host acknowledges it pushed out the data we | ||
425 | * sent. Also ensure we return to userspace the number of | ||
426 | * bytes that were successfully consumed by the host. | ||
427 | */ | ||
428 | while (!out_vq->vq_ops->get_buf(out_vq, &len)) | 453 | while (!out_vq->vq_ops->get_buf(out_vq, &len)) |
429 | cpu_relax(); | 454 | cpu_relax(); |
430 | fail: | 455 | fail: |
431 | /* We're expected to return the amount of data we wrote */ | 456 | /* We're expected to return the amount of data we wrote */ |
432 | return len; | 457 | return in_count; |
433 | } | 458 | } |
434 | 459 | ||
435 | /* | 460 | /* |
@@ -646,13 +671,13 @@ static int put_chars(u32 vtermno, const char *buf, int count) | |||
646 | { | 671 | { |
647 | struct port *port; | 672 | struct port *port; |
648 | 673 | ||
674 | if (unlikely(early_put_chars)) | ||
675 | return early_put_chars(vtermno, buf, count); | ||
676 | |||
649 | port = find_port_by_vtermno(vtermno); | 677 | port = find_port_by_vtermno(vtermno); |
650 | if (!port) | 678 | if (!port) |
651 | return 0; | 679 | return 0; |
652 | 680 | ||
653 | if (unlikely(early_put_chars)) | ||
654 | return early_put_chars(vtermno, buf, count); | ||
655 | |||
656 | return send_buf(port, (void *)buf, count); | 681 | return send_buf(port, (void *)buf, count); |
657 | } | 682 | } |
658 | 683 | ||
@@ -1218,7 +1243,7 @@ fail: | |||
1218 | */ | 1243 | */ |
1219 | static void config_work_handler(struct work_struct *work) | 1244 | static void config_work_handler(struct work_struct *work) |
1220 | { | 1245 | { |
1221 | struct virtio_console_config virtconconf; | 1246 | struct virtio_console_multiport_conf virtconconf; |
1222 | struct ports_device *portdev; | 1247 | struct ports_device *portdev; |
1223 | struct virtio_device *vdev; | 1248 | struct virtio_device *vdev; |
1224 | int err; | 1249 | int err; |
@@ -1227,7 +1252,8 @@ static void config_work_handler(struct work_struct *work) | |||
1227 | 1252 | ||
1228 | vdev = portdev->vdev; | 1253 | vdev = portdev->vdev; |
1229 | vdev->config->get(vdev, | 1254 | vdev->config->get(vdev, |
1230 | offsetof(struct virtio_console_config, nr_ports), | 1255 | offsetof(struct virtio_console_multiport_conf, |
1256 | nr_ports), | ||
1231 | &virtconconf.nr_ports, | 1257 | &virtconconf.nr_ports, |
1232 | sizeof(virtconconf.nr_ports)); | 1258 | sizeof(virtconconf.nr_ports)); |
1233 | 1259 | ||
@@ -1419,16 +1445,19 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) | |||
1419 | multiport = false; | 1445 | multiport = false; |
1420 | portdev->config.nr_ports = 1; | 1446 | portdev->config.nr_ports = 1; |
1421 | portdev->config.max_nr_ports = 1; | 1447 | portdev->config.max_nr_ports = 1; |
1448 | #if 0 /* Multiport is not quite ready yet --RR */ | ||
1422 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { | 1449 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { |
1423 | multiport = true; | 1450 | multiport = true; |
1424 | vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT; | 1451 | vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT; |
1425 | 1452 | ||
1426 | vdev->config->get(vdev, offsetof(struct virtio_console_config, | 1453 | vdev->config->get(vdev, |
1427 | nr_ports), | 1454 | offsetof(struct virtio_console_multiport_conf, |
1455 | nr_ports), | ||
1428 | &portdev->config.nr_ports, | 1456 | &portdev->config.nr_ports, |
1429 | sizeof(portdev->config.nr_ports)); | 1457 | sizeof(portdev->config.nr_ports)); |
1430 | vdev->config->get(vdev, offsetof(struct virtio_console_config, | 1458 | vdev->config->get(vdev, |
1431 | max_nr_ports), | 1459 | offsetof(struct virtio_console_multiport_conf, |
1460 | max_nr_ports), | ||
1432 | &portdev->config.max_nr_ports, | 1461 | &portdev->config.max_nr_ports, |
1433 | sizeof(portdev->config.max_nr_ports)); | 1462 | sizeof(portdev->config.max_nr_ports)); |
1434 | if (portdev->config.nr_ports > portdev->config.max_nr_ports) { | 1463 | if (portdev->config.nr_ports > portdev->config.max_nr_ports) { |
@@ -1444,6 +1473,7 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) | |||
1444 | 1473 | ||
1445 | /* Let the Host know we support multiple ports.*/ | 1474 | /* Let the Host know we support multiple ports.*/ |
1446 | vdev->config->finalize_features(vdev); | 1475 | vdev->config->finalize_features(vdev); |
1476 | #endif | ||
1447 | 1477 | ||
1448 | err = init_vqs(portdev); | 1478 | err = init_vqs(portdev); |
1449 | if (err < 0) { | 1479 | if (err < 0) { |
@@ -1526,7 +1556,6 @@ static struct virtio_device_id id_table[] = { | |||
1526 | 1556 | ||
1527 | static unsigned int features[] = { | 1557 | static unsigned int features[] = { |
1528 | VIRTIO_CONSOLE_F_SIZE, | 1558 | VIRTIO_CONSOLE_F_SIZE, |
1529 | VIRTIO_CONSOLE_F_MULTIPORT, | ||
1530 | }; | 1559 | }; |
1531 | 1560 | ||
1532 | static struct virtio_driver virtio_console = { | 1561 | static struct virtio_driver virtio_console = { |