aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/hvc_iucv.c204
-rw-r--r--drivers/char/hvcs.c6
-rw-r--r--drivers/char/hw_random/core.c1
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c4
-rw-r--r--drivers/char/misc.c15
-rw-r--r--drivers/char/ps3flash.c296
-rw-r--r--drivers/char/pty.c53
-rw-r--r--drivers/char/raw.c6
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/tty_ioctl.c5
-rw-r--r--drivers/char/tty_ldisc.c9
-rw-r--r--drivers/char/vt.c13
12 files changed, 408 insertions, 206 deletions
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index 54481a887769..86105efb4eb6 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -4,7 +4,7 @@
4 * This HVC device driver provides terminal access using 4 * This HVC device driver provides terminal access using
5 * z/VM IUCV communication paths. 5 * z/VM IUCV communication paths.
6 * 6 *
7 * Copyright IBM Corp. 2008 7 * Copyright IBM Corp. 2008, 2009
8 * 8 *
9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> 9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
10 */ 10 */
@@ -15,6 +15,7 @@
15#include <asm/ebcdic.h> 15#include <asm/ebcdic.h>
16#include <linux/ctype.h> 16#include <linux/ctype.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/device.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/mempool.h> 20#include <linux/mempool.h>
20#include <linux/moduleparam.h> 21#include <linux/moduleparam.h>
@@ -74,6 +75,7 @@ struct hvc_iucv_private {
74 wait_queue_head_t sndbuf_waitq; /* wait for send completion */ 75 wait_queue_head_t sndbuf_waitq; /* wait for send completion */
75 struct list_head tty_outqueue; /* outgoing IUCV messages */ 76 struct list_head tty_outqueue; /* outgoing IUCV messages */
76 struct list_head tty_inqueue; /* incoming IUCV messages */ 77 struct list_head tty_inqueue; /* incoming IUCV messages */
78 struct device *dev; /* device structure */
77}; 79};
78 80
79struct iucv_tty_buffer { 81struct iucv_tty_buffer {
@@ -542,7 +544,68 @@ static void flush_sndbuf_sync(struct hvc_iucv_private *priv)
542 544
543 if (sync_wait) 545 if (sync_wait)
544 wait_event_timeout(priv->sndbuf_waitq, 546 wait_event_timeout(priv->sndbuf_waitq,
545 tty_outqueue_empty(priv), HZ); 547 tty_outqueue_empty(priv), HZ/10);
548}
549
550/**
551 * hvc_iucv_hangup() - Sever IUCV path and schedule hvc tty hang up
552 * @priv: Pointer to hvc_iucv_private structure
553 *
554 * This routine severs an existing IUCV communication path and hangs
555 * up the underlying HVC terminal device.
556 * The hang-up occurs only if an IUCV communication path is established;
557 * otherwise there is no need to hang up the terminal device.
558 *
559 * The IUCV HVC hang-up is separated into two steps:
560 * 1. After the IUCV path has been severed, the iucv_state is set to
561 * IUCV_SEVERED.
562 * 2. Later, when the HVC thread calls hvc_iucv_get_chars(), the
563 * IUCV_SEVERED state causes the tty hang-up in the HVC layer.
564 *
565 * If the tty has not yet been opened, clean up the hvc_iucv_private
566 * structure to allow re-connects.
567 * If the tty has been opened, let get_chars() return -EPIPE to signal
568 * the HVC layer to hang up the tty and, if so, wake up the HVC thread
569 * to call get_chars()...
570 *
571 * Special notes on hanging up a HVC terminal instantiated as console:
572 * Hang-up: 1. do_tty_hangup() replaces file ops (= hung_up_tty_fops)
573 * 2. do_tty_hangup() calls tty->ops->close() for console_filp
574 * => no hangup notifier is called by HVC (default)
575 * 2. hvc_close() returns because of tty_hung_up_p(filp)
576 * => no delete notifier is called!
577 * Finally, the back-end is not being notified, thus, the tty session is
578 * kept active (TTY_OPEN) to be ready for re-connects.
579 *
580 * Locking: spin_lock(&priv->lock) w/o disabling bh
581 */
582static void hvc_iucv_hangup(struct hvc_iucv_private *priv)
583{
584 struct iucv_path *path;
585
586 path = NULL;
587 spin_lock(&priv->lock);
588 if (priv->iucv_state == IUCV_CONNECTED) {
589 path = priv->path;
590 priv->path = NULL;
591 priv->iucv_state = IUCV_SEVERED;
592 if (priv->tty_state == TTY_CLOSED)
593 hvc_iucv_cleanup(priv);
594 else
595 /* console is special (see above) */
596 if (priv->is_console) {
597 hvc_iucv_cleanup(priv);
598 priv->tty_state = TTY_OPENED;
599 } else
600 hvc_kick();
601 }
602 spin_unlock(&priv->lock);
603
604 /* finally sever path (outside of priv->lock due to lock ordering) */
605 if (path) {
606 iucv_path_sever(path, NULL);
607 iucv_path_free(path);
608 }
546} 609}
547 610
548/** 611/**
@@ -735,11 +798,8 @@ out_path_handled:
735 * @ipuser: User specified data for this path 798 * @ipuser: User specified data for this path
736 * (AF_IUCV: port/service name and originator port) 799 * (AF_IUCV: port/service name and originator port)
737 * 800 *
738 * The function also severs the path (as required by the IUCV protocol) and 801 * This function calls the hvc_iucv_hangup() function for the
739 * sets the iucv state to IUCV_SEVERED for the associated struct 802 * respective IUCV HVC terminal.
740 * hvc_iucv_private instance. Later, the IUCV_SEVERED state triggers a tty
741 * hangup (hvc_iucv_get_chars() / hvc_iucv_write()).
742 * If tty portion of the HVC is closed, clean up the outqueue.
743 * 803 *
744 * Locking: struct hvc_iucv_private->lock 804 * Locking: struct hvc_iucv_private->lock
745 */ 805 */
@@ -747,33 +807,7 @@ static void hvc_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
747{ 807{
748 struct hvc_iucv_private *priv = path->private; 808 struct hvc_iucv_private *priv = path->private;
749 809
750 spin_lock(&priv->lock); 810 hvc_iucv_hangup(priv);
751 priv->iucv_state = IUCV_SEVERED;
752
753 /* If the tty has not yet been opened, clean up the hvc_iucv_private
754 * structure to allow re-connects.
755 * This is also done for our console device because console hangups
756 * are handled specially and no notifier is called by HVC.
757 * The tty session is active (TTY_OPEN) and ready for re-connects...
758 *
759 * If it has been opened, let get_chars() return -EPIPE to signal the
760 * HVC layer to hang up the tty.
761 * If so, we need to wake up the HVC thread to call get_chars()...
762 */
763 priv->path = NULL;
764 if (priv->tty_state == TTY_CLOSED)
765 hvc_iucv_cleanup(priv);
766 else
767 if (priv->is_console) {
768 hvc_iucv_cleanup(priv);
769 priv->tty_state = TTY_OPENED;
770 } else
771 hvc_kick();
772 spin_unlock(&priv->lock);
773
774 /* finally sever path (outside of priv->lock due to lock ordering) */
775 iucv_path_sever(path, ipuser);
776 iucv_path_free(path);
777} 811}
778 812
779/** 813/**
@@ -853,6 +887,37 @@ static void hvc_iucv_msg_complete(struct iucv_path *path,
853 destroy_tty_buffer_list(&list_remove); 887 destroy_tty_buffer_list(&list_remove);
854} 888}
855 889
890/**
891 * hvc_iucv_pm_freeze() - Freeze PM callback
892 * @dev: IUVC HVC terminal device
893 *
894 * Sever an established IUCV communication path and
895 * trigger a hang-up of the underlying HVC terminal.
896 */
897static int hvc_iucv_pm_freeze(struct device *dev)
898{
899 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
900
901 local_bh_disable();
902 hvc_iucv_hangup(priv);
903 local_bh_enable();
904
905 return 0;
906}
907
908/**
909 * hvc_iucv_pm_restore_thaw() - Thaw and restore PM callback
910 * @dev: IUVC HVC terminal device
911 *
912 * Wake up the HVC thread to trigger hang-up and respective
913 * HVC back-end notifier invocations.
914 */
915static int hvc_iucv_pm_restore_thaw(struct device *dev)
916{
917 hvc_kick();
918 return 0;
919}
920
856 921
857/* HVC operations */ 922/* HVC operations */
858static struct hv_ops hvc_iucv_ops = { 923static struct hv_ops hvc_iucv_ops = {
@@ -863,6 +928,20 @@ static struct hv_ops hvc_iucv_ops = {
863 .notifier_hangup = hvc_iucv_notifier_hangup, 928 .notifier_hangup = hvc_iucv_notifier_hangup,
864}; 929};
865 930
931/* Suspend / resume device operations */
932static struct dev_pm_ops hvc_iucv_pm_ops = {
933 .freeze = hvc_iucv_pm_freeze,
934 .thaw = hvc_iucv_pm_restore_thaw,
935 .restore = hvc_iucv_pm_restore_thaw,
936};
937
938/* IUCV HVC device driver */
939static struct device_driver hvc_iucv_driver = {
940 .name = KMSG_COMPONENT,
941 .bus = &iucv_bus,
942 .pm = &hvc_iucv_pm_ops,
943};
944
866/** 945/**
867 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance 946 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance
868 * @id: hvc_iucv_table index 947 * @id: hvc_iucv_table index
@@ -897,14 +976,12 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
897 /* set console flag */ 976 /* set console flag */
898 priv->is_console = is_console; 977 priv->is_console = is_console;
899 978
900 /* finally allocate hvc */ 979 /* allocate hvc device */
901 priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id, /* PAGE_SIZE */ 980 priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id, /* PAGE_SIZE */
902 HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256); 981 HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256);
903 if (IS_ERR(priv->hvc)) { 982 if (IS_ERR(priv->hvc)) {
904 rc = PTR_ERR(priv->hvc); 983 rc = PTR_ERR(priv->hvc);
905 free_page((unsigned long) priv->sndbuf); 984 goto out_error_hvc;
906 kfree(priv);
907 return rc;
908 } 985 }
909 986
910 /* notify HVC thread instead of using polling */ 987 /* notify HVC thread instead of using polling */
@@ -915,8 +992,45 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
915 memcpy(priv->srv_name, name, 8); 992 memcpy(priv->srv_name, name, 8);
916 ASCEBC(priv->srv_name, 8); 993 ASCEBC(priv->srv_name, 8);
917 994
995 /* create and setup device */
996 priv->dev = kzalloc(sizeof(*priv->dev), GFP_KERNEL);
997 if (!priv->dev) {
998 rc = -ENOMEM;
999 goto out_error_dev;
1000 }
1001 dev_set_name(priv->dev, "hvc_iucv%d", id);
1002 dev_set_drvdata(priv->dev, priv);
1003 priv->dev->bus = &iucv_bus;
1004 priv->dev->parent = iucv_root;
1005 priv->dev->driver = &hvc_iucv_driver;
1006 priv->dev->release = (void (*)(struct device *)) kfree;
1007 rc = device_register(priv->dev);
1008 if (rc) {
1009 kfree(priv->dev);
1010 goto out_error_dev;
1011 }
1012
918 hvc_iucv_table[id] = priv; 1013 hvc_iucv_table[id] = priv;
919 return 0; 1014 return 0;
1015
1016out_error_dev:
1017 hvc_remove(priv->hvc);
1018out_error_hvc:
1019 free_page((unsigned long) priv->sndbuf);
1020 kfree(priv);
1021
1022 return rc;
1023}
1024
1025/**
1026 * hvc_iucv_destroy() - Destroy and free hvc_iucv_private instances
1027 */
1028static void __init hvc_iucv_destroy(struct hvc_iucv_private *priv)
1029{
1030 hvc_remove(priv->hvc);
1031 device_unregister(priv->dev);
1032 free_page((unsigned long) priv->sndbuf);
1033 kfree(priv);
920} 1034}
921 1035
922/** 1036/**
@@ -1109,6 +1223,11 @@ static int __init hvc_iucv_init(void)
1109 goto out_error; 1223 goto out_error;
1110 } 1224 }
1111 1225
1226 /* register IUCV HVC device driver */
1227 rc = driver_register(&hvc_iucv_driver);
1228 if (rc)
1229 goto out_error;
1230
1112 /* parse hvc_iucv_allow string and create z/VM user ID filter list */ 1231 /* parse hvc_iucv_allow string and create z/VM user ID filter list */
1113 if (hvc_iucv_filter_string) { 1232 if (hvc_iucv_filter_string) {
1114 rc = hvc_iucv_setup_filter(hvc_iucv_filter_string); 1233 rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
@@ -1183,15 +1302,14 @@ out_error_iucv:
1183 iucv_unregister(&hvc_iucv_handler, 0); 1302 iucv_unregister(&hvc_iucv_handler, 0);
1184out_error_hvc: 1303out_error_hvc:
1185 for (i = 0; i < hvc_iucv_devices; i++) 1304 for (i = 0; i < hvc_iucv_devices; i++)
1186 if (hvc_iucv_table[i]) { 1305 if (hvc_iucv_table[i])
1187 if (hvc_iucv_table[i]->hvc) 1306 hvc_iucv_destroy(hvc_iucv_table[i]);
1188 hvc_remove(hvc_iucv_table[i]->hvc);
1189 kfree(hvc_iucv_table[i]);
1190 }
1191out_error_memory: 1307out_error_memory:
1192 mempool_destroy(hvc_iucv_mempool); 1308 mempool_destroy(hvc_iucv_mempool);
1193 kmem_cache_destroy(hvc_iucv_buffer_cache); 1309 kmem_cache_destroy(hvc_iucv_buffer_cache);
1194out_error: 1310out_error:
1311 if (hvc_iucv_filter)
1312 kfree(hvc_iucv_filter);
1195 hvc_iucv_devices = 0; /* ensure that we do not provide any device */ 1313 hvc_iucv_devices = 0; /* ensure that we do not provide any device */
1196 return rc; 1314 return rc;
1197} 1315}
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index c76bccf5354d..7d64e4230e66 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -347,7 +347,7 @@ static void __exit hvcs_module_exit(void);
347 347
348static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod) 348static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod)
349{ 349{
350 return viod->dev.driver_data; 350 return dev_get_drvdata(&viod->dev);
351} 351}
352/* The sysfs interface for the driver and devices */ 352/* The sysfs interface for the driver and devices */
353 353
@@ -785,7 +785,7 @@ static int __devinit hvcs_probe(
785 kref_init(&hvcsd->kref); 785 kref_init(&hvcsd->kref);
786 786
787 hvcsd->vdev = dev; 787 hvcsd->vdev = dev;
788 dev->dev.driver_data = hvcsd; 788 dev_set_drvdata(&dev->dev, hvcsd);
789 789
790 hvcsd->index = index; 790 hvcsd->index = index;
791 791
@@ -831,7 +831,7 @@ static int __devinit hvcs_probe(
831 831
832static int __devexit hvcs_remove(struct vio_dev *dev) 832static int __devexit hvcs_remove(struct vio_dev *dev)
833{ 833{
834 struct hvcs_struct *hvcsd = dev->dev.driver_data; 834 struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev);
835 unsigned long flags; 835 unsigned long flags;
836 struct tty_struct *tty; 836 struct tty_struct *tty;
837 837
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index e5d583c84e4f..fc93e2fc7c71 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -153,6 +153,7 @@ static const struct file_operations rng_chrdev_ops = {
153static struct miscdevice rng_miscdev = { 153static struct miscdevice rng_miscdev = {
154 .minor = RNG_MISCDEV_MINOR, 154 .minor = RNG_MISCDEV_MINOR,
155 .name = RNG_MODULE_NAME, 155 .name = RNG_MODULE_NAME,
156 .devnode = "hwrng",
156 .fops = &rng_chrdev_ops, 157 .fops = &rng_chrdev_ops,
157}; 158};
158 159
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 259644646b82..d2e698096ace 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2375,14 +2375,14 @@ static int __devinit ipmi_of_probe(struct of_device *dev,
2375 info->io.addr_data, info->io.regsize, info->io.regspacing, 2375 info->io.addr_data, info->io.regsize, info->io.regspacing,
2376 info->irq); 2376 info->irq);
2377 2377
2378 dev->dev.driver_data = (void *) info; 2378 dev_set_drvdata(&dev->dev, info);
2379 2379
2380 return try_smi_init(info); 2380 return try_smi_init(info);
2381} 2381}
2382 2382
2383static int __devexit ipmi_of_remove(struct of_device *dev) 2383static int __devexit ipmi_of_remove(struct of_device *dev)
2384{ 2384{
2385 cleanup_one_si(dev->dev.driver_data); 2385 cleanup_one_si(dev_get_drvdata(&dev->dev));
2386 return 0; 2386 return 0;
2387} 2387}
2388 2388
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index a5e0db9d7662..62c99fa59e2b 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -168,7 +168,6 @@ static const struct file_operations misc_fops = {
168 .open = misc_open, 168 .open = misc_open,
169}; 169};
170 170
171
172/** 171/**
173 * misc_register - register a miscellaneous device 172 * misc_register - register a miscellaneous device
174 * @misc: device structure 173 * @misc: device structure
@@ -217,8 +216,8 @@ int misc_register(struct miscdevice * misc)
217 misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); 216 misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
218 dev = MKDEV(MISC_MAJOR, misc->minor); 217 dev = MKDEV(MISC_MAJOR, misc->minor);
219 218
220 misc->this_device = device_create(misc_class, misc->parent, dev, NULL, 219 misc->this_device = device_create(misc_class, misc->parent, dev,
221 "%s", misc->name); 220 misc, "%s", misc->name);
222 if (IS_ERR(misc->this_device)) { 221 if (IS_ERR(misc->this_device)) {
223 err = PTR_ERR(misc->this_device); 222 err = PTR_ERR(misc->this_device);
224 goto out; 223 goto out;
@@ -264,6 +263,15 @@ int misc_deregister(struct miscdevice *misc)
264EXPORT_SYMBOL(misc_register); 263EXPORT_SYMBOL(misc_register);
265EXPORT_SYMBOL(misc_deregister); 264EXPORT_SYMBOL(misc_deregister);
266 265
266static char *misc_nodename(struct device *dev)
267{
268 struct miscdevice *c = dev_get_drvdata(dev);
269
270 if (c->devnode)
271 return kstrdup(c->devnode, GFP_KERNEL);
272 return NULL;
273}
274
267static int __init misc_init(void) 275static int __init misc_init(void)
268{ 276{
269 int err; 277 int err;
@@ -279,6 +287,7 @@ static int __init misc_init(void)
279 err = -EIO; 287 err = -EIO;
280 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) 288 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))
281 goto fail_printk; 289 goto fail_printk;
290 misc_class->nodename = misc_nodename;
282 return 0; 291 return 0;
283 292
284fail_printk: 293fail_printk:
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index afbe45676d71..f424d394a286 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -33,48 +33,64 @@
33 33
34struct ps3flash_private { 34struct ps3flash_private {
35 struct mutex mutex; /* Bounce buffer mutex */ 35 struct mutex mutex; /* Bounce buffer mutex */
36 u64 chunk_sectors;
37 int tag; /* Start sector of buffer, -1 if invalid */
38 bool dirty;
36}; 39};
37 40
38static struct ps3_storage_device *ps3flash_dev; 41static struct ps3_storage_device *ps3flash_dev;
39 42
40static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev, 43static int ps3flash_read_write_sectors(struct ps3_storage_device *dev,
41 u64 lpar, u64 start_sector, 44 u64 start_sector, int write)
42 u64 sectors, int write)
43{ 45{
44 u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, 46 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
47 u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar,
48 start_sector, priv->chunk_sectors,
45 write); 49 write);
46 if (res) { 50 if (res) {
47 dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, 51 dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
48 __LINE__, write ? "write" : "read", res); 52 __LINE__, write ? "write" : "read", res);
49 return -EIO; 53 return -EIO;
50 } 54 }
51 return sectors; 55 return 0;
52} 56}
53 57
54static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev, 58static int ps3flash_writeback(struct ps3_storage_device *dev)
55 u64 start_sector, u64 sectors,
56 unsigned int sector_offset)
57{ 59{
58 u64 max_sectors, lpar; 60 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
61 int res;
59 62
60 max_sectors = dev->bounce_size / dev->blk_size; 63 if (!priv->dirty || priv->tag < 0)
61 if (sectors > max_sectors) { 64 return 0;
62 dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %llu\n",
63 __func__, __LINE__, max_sectors);
64 sectors = max_sectors;
65 }
66 65
67 lpar = dev->bounce_lpar + sector_offset * dev->blk_size; 66 res = ps3flash_read_write_sectors(dev, priv->tag, 1);
68 return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors, 67 if (res)
69 0); 68 return res;
69
70 priv->dirty = false;
71 return 0;
70} 72}
71 73
72static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev, 74static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector)
73 u64 start_sector)
74{ 75{
75 u64 sectors = dev->bounce_size / dev->blk_size; 76 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
76 return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector, 77 int res;
77 sectors, 1); 78
79 if (start_sector == priv->tag)
80 return 0;
81
82 res = ps3flash_writeback(dev);
83 if (res)
84 return res;
85
86 priv->tag = -1;
87
88 res = ps3flash_read_write_sectors(dev, start_sector, 0);
89 if (res)
90 return res;
91
92 priv->tag = start_sector;
93 return 0;
78} 94}
79 95
80static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) 96static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
@@ -104,18 +120,19 @@ out:
104 return res; 120 return res;
105} 121}
106 122
107static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count, 123static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf,
108 loff_t *pos) 124 size_t count, loff_t *pos)
109{ 125{
110 struct ps3_storage_device *dev = ps3flash_dev; 126 struct ps3_storage_device *dev = ps3flash_dev;
111 struct ps3flash_private *priv = dev->sbd.core.driver_data; 127 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
112 u64 size, start_sector, end_sector, offset; 128 u64 size, sector, offset;
113 ssize_t sectors_read; 129 int res;
114 size_t remaining, n; 130 size_t remaining, n;
131 const void *src;
115 132
116 dev_dbg(&dev->sbd.core, 133 dev_dbg(&dev->sbd.core,
117 "%s:%u: Reading %zu bytes at position %lld to user 0x%p\n", 134 "%s:%u: Reading %zu bytes at position %lld to U0x%p/K0x%p\n",
118 __func__, __LINE__, count, *pos, buf); 135 __func__, __LINE__, count, *pos, userbuf, kernelbuf);
119 136
120 size = dev->regions[dev->region_idx].size*dev->blk_size; 137 size = dev->regions[dev->region_idx].size*dev->blk_size;
121 if (*pos >= size || !count) 138 if (*pos >= size || !count)
@@ -128,61 +145,63 @@ static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count,
128 count = size - *pos; 145 count = size - *pos;
129 } 146 }
130 147
131 start_sector = *pos / dev->blk_size; 148 sector = *pos / dev->bounce_size * priv->chunk_sectors;
132 offset = *pos % dev->blk_size; 149 offset = *pos % dev->bounce_size;
133 end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size);
134 150
135 remaining = count; 151 remaining = count;
136 do { 152 do {
153 n = min_t(u64, remaining, dev->bounce_size - offset);
154 src = dev->bounce_buf + offset;
155
137 mutex_lock(&priv->mutex); 156 mutex_lock(&priv->mutex);
138 157
139 sectors_read = ps3flash_read_sectors(dev, start_sector, 158 res = ps3flash_fetch(dev, sector);
140 end_sector-start_sector, 159 if (res)
141 0);
142 if (sectors_read < 0) {
143 mutex_unlock(&priv->mutex);
144 goto fail; 160 goto fail;
145 }
146 161
147 n = min_t(u64, remaining, sectors_read*dev->blk_size-offset);
148 dev_dbg(&dev->sbd.core, 162 dev_dbg(&dev->sbd.core,
149 "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n", 163 "%s:%u: copy %lu bytes from 0x%p to U0x%p/K0x%p\n",
150 __func__, __LINE__, n, dev->bounce_buf+offset, buf); 164 __func__, __LINE__, n, src, userbuf, kernelbuf);
151 if (copy_to_user(buf, dev->bounce_buf+offset, n)) { 165 if (userbuf) {
152 mutex_unlock(&priv->mutex); 166 if (copy_to_user(userbuf, src, n)) {
153 sectors_read = -EFAULT; 167 res = -EFAULT;
154 goto fail; 168 goto fail;
169 }
170 userbuf += n;
171 }
172 if (kernelbuf) {
173 memcpy(kernelbuf, src, n);
174 kernelbuf += n;
155 } 175 }
156 176
157 mutex_unlock(&priv->mutex); 177 mutex_unlock(&priv->mutex);
158 178
159 *pos += n; 179 *pos += n;
160 buf += n;
161 remaining -= n; 180 remaining -= n;
162 start_sector += sectors_read; 181 sector += priv->chunk_sectors;
163 offset = 0; 182 offset = 0;
164 } while (remaining > 0); 183 } while (remaining > 0);
165 184
166 return count; 185 return count;
167 186
168fail: 187fail:
169 return sectors_read; 188 mutex_unlock(&priv->mutex);
189 return res;
170} 190}
171 191
172static ssize_t ps3flash_write(struct file *file, const char __user *buf, 192static ssize_t ps3flash_write(const char __user *userbuf,
173 size_t count, loff_t *pos) 193 const void *kernelbuf, size_t count, loff_t *pos)
174{ 194{
175 struct ps3_storage_device *dev = ps3flash_dev; 195 struct ps3_storage_device *dev = ps3flash_dev;
176 struct ps3flash_private *priv = dev->sbd.core.driver_data; 196 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
177 u64 size, chunk_sectors, start_write_sector, end_write_sector, 197 u64 size, sector, offset;
178 end_read_sector, start_read_sector, head, tail, offset; 198 int res = 0;
179 ssize_t res;
180 size_t remaining, n; 199 size_t remaining, n;
181 unsigned int sec_off; 200 void *dst;
182 201
183 dev_dbg(&dev->sbd.core, 202 dev_dbg(&dev->sbd.core,
184 "%s:%u: Writing %zu bytes at position %lld from user 0x%p\n", 203 "%s:%u: Writing %zu bytes at position %lld from U0x%p/K0x%p\n",
185 __func__, __LINE__, count, *pos, buf); 204 __func__, __LINE__, count, *pos, userbuf, kernelbuf);
186 205
187 size = dev->regions[dev->region_idx].size*dev->blk_size; 206 size = dev->regions[dev->region_idx].size*dev->blk_size;
188 if (*pos >= size || !count) 207 if (*pos >= size || !count)
@@ -195,89 +214,46 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf,
195 count = size - *pos; 214 count = size - *pos;
196 } 215 }
197 216
198 chunk_sectors = dev->bounce_size / dev->blk_size; 217 sector = *pos / dev->bounce_size * priv->chunk_sectors;
199
200 start_write_sector = *pos / dev->bounce_size * chunk_sectors;
201 offset = *pos % dev->bounce_size; 218 offset = *pos % dev->bounce_size;
202 end_write_sector = DIV_ROUND_UP(*pos + count, dev->bounce_size) *
203 chunk_sectors;
204
205 end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size);
206 start_read_sector = (*pos + count) / dev->blk_size;
207
208 /*
209 * As we have to write in 256 KiB chunks, while we can read in blk_size
210 * (usually 512 bytes) chunks, we perform the following steps:
211 * 1. Read from start_write_sector to end_read_sector ("head")
212 * 2. Read from start_read_sector to end_write_sector ("tail")
213 * 3. Copy data to buffer
214 * 4. Write from start_write_sector to end_write_sector
215 * All of this is complicated by using only one 256 KiB bounce buffer.
216 */
217
218 head = end_read_sector - start_write_sector;
219 tail = end_write_sector - start_read_sector;
220 219
221 remaining = count; 220 remaining = count;
222 do { 221 do {
222 n = min_t(u64, remaining, dev->bounce_size - offset);
223 dst = dev->bounce_buf + offset;
224
223 mutex_lock(&priv->mutex); 225 mutex_lock(&priv->mutex);
224 226
225 if (end_read_sector >= start_read_sector) { 227 if (n != dev->bounce_size)
226 /* Merge head and tail */ 228 res = ps3flash_fetch(dev, sector);
227 dev_dbg(&dev->sbd.core, 229 else if (sector != priv->tag)
228 "Merged head and tail: %llu sectors at %llu\n", 230 res = ps3flash_writeback(dev);
229 chunk_sectors, start_write_sector); 231 if (res)
230 res = ps3flash_read_sectors(dev, start_write_sector, 232 goto fail;
231 chunk_sectors, 0); 233
232 if (res < 0) 234 dev_dbg(&dev->sbd.core,
235 "%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n",
236 __func__, __LINE__, n, userbuf, kernelbuf, dst);
237 if (userbuf) {
238 if (copy_from_user(dst, userbuf, n)) {
239 res = -EFAULT;
233 goto fail; 240 goto fail;
234 } else {
235 if (head) {
236 /* Read head */
237 dev_dbg(&dev->sbd.core,
238 "head: %llu sectors at %llu\n", head,
239 start_write_sector);
240 res = ps3flash_read_sectors(dev,
241 start_write_sector,
242 head, 0);
243 if (res < 0)
244 goto fail;
245 }
246 if (start_read_sector <
247 start_write_sector+chunk_sectors) {
248 /* Read tail */
249 dev_dbg(&dev->sbd.core,
250 "tail: %llu sectors at %llu\n", tail,
251 start_read_sector);
252 sec_off = start_read_sector-start_write_sector;
253 res = ps3flash_read_sectors(dev,
254 start_read_sector,
255 tail, sec_off);
256 if (res < 0)
257 goto fail;
258 } 241 }
242 userbuf += n;
259 } 243 }
260 244 if (kernelbuf) {
261 n = min_t(u64, remaining, dev->bounce_size-offset); 245 memcpy(dst, kernelbuf, n);
262 dev_dbg(&dev->sbd.core, 246 kernelbuf += n;
263 "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n",
264 __func__, __LINE__, n, buf, dev->bounce_buf+offset);
265 if (copy_from_user(dev->bounce_buf+offset, buf, n)) {
266 res = -EFAULT;
267 goto fail;
268 } 247 }
269 248
270 res = ps3flash_write_chunk(dev, start_write_sector); 249 priv->tag = sector;
271 if (res < 0) 250 priv->dirty = true;
272 goto fail;
273 251
274 mutex_unlock(&priv->mutex); 252 mutex_unlock(&priv->mutex);
275 253
276 *pos += n; 254 *pos += n;
277 buf += n;
278 remaining -= n; 255 remaining -= n;
279 start_write_sector += chunk_sectors; 256 sector += priv->chunk_sectors;
280 head = 0;
281 offset = 0; 257 offset = 0;
282 } while (remaining > 0); 258 } while (remaining > 0);
283 259
@@ -288,6 +264,51 @@ fail:
288 return res; 264 return res;
289} 265}
290 266
267static ssize_t ps3flash_user_read(struct file *file, char __user *buf,
268 size_t count, loff_t *pos)
269{
270 return ps3flash_read(buf, NULL, count, pos);
271}
272
273static ssize_t ps3flash_user_write(struct file *file, const char __user *buf,
274 size_t count, loff_t *pos)
275{
276 return ps3flash_write(buf, NULL, count, pos);
277}
278
279static ssize_t ps3flash_kernel_read(void *buf, size_t count, loff_t pos)
280{
281 return ps3flash_read(NULL, buf, count, &pos);
282}
283
284static ssize_t ps3flash_kernel_write(const void *buf, size_t count,
285 loff_t pos)
286{
287 ssize_t res;
288 int wb;
289
290 res = ps3flash_write(NULL, buf, count, &pos);
291 if (res < 0)
292 return res;
293
294 /* Make kernel writes synchronous */
295 wb = ps3flash_writeback(ps3flash_dev);
296 if (wb)
297 return wb;
298
299 return res;
300}
301
302static int ps3flash_flush(struct file *file, fl_owner_t id)
303{
304 return ps3flash_writeback(ps3flash_dev);
305}
306
307static int ps3flash_fsync(struct file *file, struct dentry *dentry,
308 int datasync)
309{
310 return ps3flash_writeback(ps3flash_dev);
311}
291 312
292static irqreturn_t ps3flash_interrupt(int irq, void *data) 313static irqreturn_t ps3flash_interrupt(int irq, void *data)
293{ 314{
@@ -312,12 +333,18 @@ static irqreturn_t ps3flash_interrupt(int irq, void *data)
312 return IRQ_HANDLED; 333 return IRQ_HANDLED;
313} 334}
314 335
315
316static const struct file_operations ps3flash_fops = { 336static const struct file_operations ps3flash_fops = {
317 .owner = THIS_MODULE, 337 .owner = THIS_MODULE,
318 .llseek = ps3flash_llseek, 338 .llseek = ps3flash_llseek,
319 .read = ps3flash_read, 339 .read = ps3flash_user_read,
320 .write = ps3flash_write, 340 .write = ps3flash_user_write,
341 .flush = ps3flash_flush,
342 .fsync = ps3flash_fsync,
343};
344
345static const struct ps3_os_area_flash_ops ps3flash_kernel_ops = {
346 .read = ps3flash_kernel_read,
347 .write = ps3flash_kernel_write,
321}; 348};
322 349
323static struct miscdevice ps3flash_misc = { 350static struct miscdevice ps3flash_misc = {
@@ -366,11 +393,13 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
366 goto fail; 393 goto fail;
367 } 394 }
368 395
369 dev->sbd.core.driver_data = priv; 396 ps3_system_bus_set_drvdata(&dev->sbd, priv);
370 mutex_init(&priv->mutex); 397 mutex_init(&priv->mutex);
398 priv->tag = -1;
371 399
372 dev->bounce_size = ps3flash_bounce_buffer.size; 400 dev->bounce_size = ps3flash_bounce_buffer.size;
373 dev->bounce_buf = ps3flash_bounce_buffer.address; 401 dev->bounce_buf = ps3flash_bounce_buffer.address;
402 priv->chunk_sectors = dev->bounce_size / dev->blk_size;
374 403
375 error = ps3stor_setup(dev, ps3flash_interrupt); 404 error = ps3stor_setup(dev, ps3flash_interrupt);
376 if (error) 405 if (error)
@@ -386,13 +415,15 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
386 415
387 dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n", 416 dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n",
388 __func__, __LINE__, ps3flash_misc.minor); 417 __func__, __LINE__, ps3flash_misc.minor);
418
419 ps3_os_area_flash_register(&ps3flash_kernel_ops);
389 return 0; 420 return 0;
390 421
391fail_teardown: 422fail_teardown:
392 ps3stor_teardown(dev); 423 ps3stor_teardown(dev);
393fail_free_priv: 424fail_free_priv:
394 kfree(priv); 425 kfree(priv);
395 dev->sbd.core.driver_data = NULL; 426 ps3_system_bus_set_drvdata(&dev->sbd, NULL);
396fail: 427fail:
397 ps3flash_dev = NULL; 428 ps3flash_dev = NULL;
398 return error; 429 return error;
@@ -402,10 +433,11 @@ static int ps3flash_remove(struct ps3_system_bus_device *_dev)
402{ 433{
403 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); 434 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
404 435
436 ps3_os_area_flash_register(NULL);
405 misc_deregister(&ps3flash_misc); 437 misc_deregister(&ps3flash_misc);
406 ps3stor_teardown(dev); 438 ps3stor_teardown(dev);
407 kfree(dev->sbd.core.driver_data); 439 kfree(ps3_system_bus_get_drvdata(&dev->sbd));
408 dev->sbd.core.driver_data = NULL; 440 ps3_system_bus_set_drvdata(&dev->sbd, NULL);
409 ps3flash_dev = NULL; 441 ps3flash_dev = NULL;
410 return 0; 442 return 0;
411} 443}
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 5acd29e6e043..daebe1ba43d4 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -95,23 +95,34 @@ static void pty_unthrottle(struct tty_struct *tty)
95 * a count. 95 * a count.
96 * 96 *
97 * FIXME: Our pty_write method is called with our ldisc lock held but 97 * FIXME: Our pty_write method is called with our ldisc lock held but
98 * not our partners. We can't just take the other one blindly without 98 * not our partners. We can't just wait on the other one blindly without
99 * risking deadlocks. 99 * risking deadlocks. At some point when everything has settled down we need
100 * to look into making pty_write at least able to sleep over an ldisc change.
101 *
102 * The return on no ldisc is a bit counter intuitive but the logic works
103 * like this. During an ldisc change the other end will flush its buffers. We
104 * thus return the full length which is identical to the case where we had
105 * proper locking and happened to queue the bytes just before the flush during
106 * the ldisc change.
100 */ 107 */
101static int pty_write(struct tty_struct *tty, const unsigned char *buf, 108static int pty_write(struct tty_struct *tty, const unsigned char *buf,
102 int count) 109 int count)
103{ 110{
104 struct tty_struct *to = tty->link; 111 struct tty_struct *to = tty->link;
105 int c; 112 struct tty_ldisc *ld;
113 int c = count;
106 114
107 if (!to || tty->stopped) 115 if (!to || tty->stopped)
108 return 0; 116 return 0;
109 117 ld = tty_ldisc_ref(to);
110 c = to->receive_room; 118
111 if (c > count) 119 if (ld) {
112 c = count; 120 c = to->receive_room;
113 to->ldisc->ops->receive_buf(to, buf, NULL, c); 121 if (c > count)
114 122 c = count;
123 ld->ops->receive_buf(to, buf, NULL, c);
124 tty_ldisc_deref(ld);
125 }
115 return c; 126 return c;
116} 127}
117 128
@@ -145,14 +156,23 @@ static int pty_write_room(struct tty_struct *tty)
145static int pty_chars_in_buffer(struct tty_struct *tty) 156static int pty_chars_in_buffer(struct tty_struct *tty)
146{ 157{
147 struct tty_struct *to = tty->link; 158 struct tty_struct *to = tty->link;
148 int count; 159 struct tty_ldisc *ld;
160 int count = 0;
149 161
150 /* We should get the line discipline lock for "tty->link" */ 162 /* We should get the line discipline lock for "tty->link" */
151 if (!to || !to->ldisc->ops->chars_in_buffer) 163 if (!to)
164 return 0;
165 /* We cannot take a sleeping reference here without deadlocking with
166 an ldisc change - but it doesn't really matter */
167 ld = tty_ldisc_ref(to);
168 if (ld == NULL)
152 return 0; 169 return 0;
153 170
154 /* The ldisc must report 0 if no characters available to be read */ 171 /* The ldisc must report 0 if no characters available to be read */
155 count = to->ldisc->ops->chars_in_buffer(to); 172 if (ld->ops->chars_in_buffer)
173 count = ld->ops->chars_in_buffer(to);
174
175 tty_ldisc_deref(ld);
156 176
157 if (tty->driver->subtype == PTY_TYPE_SLAVE) 177 if (tty->driver->subtype == PTY_TYPE_SLAVE)
158 return count; 178 return count;
@@ -182,12 +202,19 @@ static void pty_flush_buffer(struct tty_struct *tty)
182{ 202{
183 struct tty_struct *to = tty->link; 203 struct tty_struct *to = tty->link;
184 unsigned long flags; 204 unsigned long flags;
205 struct tty_ldisc *ld;
185 206
186 if (!to) 207 if (!to)
187 return; 208 return;
209 ld = tty_ldisc_ref(to);
210
211 /* The other end is changing discipline */
212 if (!ld)
213 return;
188 214
189 if (to->ldisc->ops->flush_buffer) 215 if (ld->ops->flush_buffer)
190 to->ldisc->ops->flush_buffer(to); 216 to->ldisc->ops->flush_buffer(to);
217 tty_ldisc_deref(ld);
191 218
192 if (to->packet) { 219 if (to->packet) {
193 spin_lock_irqsave(&tty->ctrl_lock, flags); 220 spin_lock_irqsave(&tty->ctrl_lock, flags);
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index db32f0e4c7dd..05f9d18b9361 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -261,6 +261,11 @@ static const struct file_operations raw_ctl_fops = {
261 261
262static struct cdev raw_cdev; 262static struct cdev raw_cdev;
263 263
264static char *raw_nodename(struct device *dev)
265{
266 return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev));
267}
268
264static int __init raw_init(void) 269static int __init raw_init(void)
265{ 270{
266 dev_t dev = MKDEV(RAW_MAJOR, 0); 271 dev_t dev = MKDEV(RAW_MAJOR, 0);
@@ -284,6 +289,7 @@ static int __init raw_init(void)
284 ret = PTR_ERR(raw_class); 289 ret = PTR_ERR(raw_class);
285 goto error_region; 290 goto error_region;
286 } 291 }
292 raw_class->nodename = raw_nodename;
287 device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); 293 device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
288 294
289 return 0; 295 return 0;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 939e198d7670..a3afa0c387cd 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1263,7 +1263,9 @@ static int tty_reopen(struct tty_struct *tty)
1263 tty->count++; 1263 tty->count++;
1264 tty->driver = driver; /* N.B. why do this every time?? */ 1264 tty->driver = driver; /* N.B. why do this every time?? */
1265 1265
1266 mutex_lock(&tty->ldisc_mutex);
1266 WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); 1267 WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
1268 mutex_unlock(&tty->ldisc_mutex);
1267 1269
1268 return 0; 1270 return 0;
1269} 1271}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 8116bb1c8f80..b24f6c6a1ea3 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -947,7 +947,6 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
947 void __user *p = (void __user *)arg; 947 void __user *p = (void __user *)arg;
948 int ret = 0; 948 int ret = 0;
949 struct ktermios kterm; 949 struct ktermios kterm;
950 struct termiox ktermx;
951 950
952 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 951 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
953 tty->driver->subtype == PTY_TYPE_MASTER) 952 tty->driver->subtype == PTY_TYPE_MASTER)
@@ -1049,7 +1048,8 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
1049 return ret; 1048 return ret;
1050#endif 1049#endif
1051#ifdef TCGETX 1050#ifdef TCGETX
1052 case TCGETX: 1051 case TCGETX: {
1052 struct termiox ktermx;
1053 if (real_tty->termiox == NULL) 1053 if (real_tty->termiox == NULL)
1054 return -EINVAL; 1054 return -EINVAL;
1055 mutex_lock(&real_tty->termios_mutex); 1055 mutex_lock(&real_tty->termios_mutex);
@@ -1058,6 +1058,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
1058 if (copy_to_user(p, &ktermx, sizeof(struct termiox))) 1058 if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
1059 ret = -EFAULT; 1059 ret = -EFAULT;
1060 return ret; 1060 return ret;
1061 }
1061 case TCSETX: 1062 case TCSETX:
1062 return set_termiox(real_tty, p, 0); 1063 return set_termiox(real_tty, p, 0);
1063 case TCSETXW: 1064 case TCSETXW:
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index 39c8f86dedd4..a19e935847b0 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -148,8 +148,10 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
148 } 148 }
149 } 149 }
150 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 150 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
151 if (err) 151 if (err) {
152 kfree(ld);
152 return ERR_PTR(err); 153 return ERR_PTR(err);
154 }
153 return ld; 155 return ld;
154} 156}
155 157
@@ -205,6 +207,7 @@ static void tty_ldisc_put(struct tty_ldisc *ld)
205 ldo->refcount--; 207 ldo->refcount--;
206 module_put(ldo->owner); 208 module_put(ldo->owner);
207 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 209 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
210 WARN_ON(ld->refcount);
208 kfree(ld); 211 kfree(ld);
209} 212}
210 213
@@ -262,7 +265,7 @@ const struct file_operations tty_ldiscs_proc_fops = {
262 * @ld: line discipline 265 * @ld: line discipline
263 * 266 *
264 * Install an instance of a line discipline into a tty structure. The 267 * Install an instance of a line discipline into a tty structure. The
265 * ldisc must have a reference count above zero to ensure it remains/ 268 * ldisc must have a reference count above zero to ensure it remains.
266 * The tty instance refcount starts at zero. 269 * The tty instance refcount starts at zero.
267 * 270 *
268 * Locking: 271 * Locking:
@@ -791,6 +794,8 @@ void tty_ldisc_hangup(struct tty_struct *tty)
791 /* Avoid racing set_ldisc */ 794 /* Avoid racing set_ldisc */
792 mutex_lock(&tty->ldisc_mutex); 795 mutex_lock(&tty->ldisc_mutex);
793 /* Switch back to N_TTY */ 796 /* Switch back to N_TTY */
797 tty_ldisc_halt(tty);
798 tty_ldisc_wait_idle(tty);
794 tty_ldisc_reinit(tty); 799 tty_ldisc_reinit(tty);
795 /* At this point we have a closed ldisc and we want to 800 /* At this point we have a closed ldisc and we want to
796 reopen it. We could defer this to the next open but 801 reopen it. We could defer this to the next open but
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index c796a86ab7f3..d9113b4c76e3 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -171,8 +171,9 @@ int do_poke_blanked_console;
171int console_blanked; 171int console_blanked;
172 172
173static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ 173static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
174static int blankinterval = 10*60*HZ;
175static int vesa_off_interval; 174static int vesa_off_interval;
175static int blankinterval = 10*60;
176core_param(consoleblank, blankinterval, int, 0444);
176 177
177static DECLARE_WORK(console_work, console_callback); 178static DECLARE_WORK(console_work, console_callback);
178 179
@@ -1485,7 +1486,7 @@ static void setterm_command(struct vc_data *vc)
1485 update_attr(vc); 1486 update_attr(vc);
1486 break; 1487 break;
1487 case 9: /* set blanking interval */ 1488 case 9: /* set blanking interval */
1488 blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ; 1489 blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60;
1489 poke_blanked_console(); 1490 poke_blanked_console();
1490 break; 1491 break;
1491 case 10: /* set bell frequency in Hz */ 1492 case 10: /* set bell frequency in Hz */
@@ -2871,7 +2872,7 @@ static int __init con_init(void)
2871 2872
2872 if (blankinterval) { 2873 if (blankinterval) {
2873 blank_state = blank_normal_wait; 2874 blank_state = blank_normal_wait;
2874 mod_timer(&console_timer, jiffies + blankinterval); 2875 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
2875 } 2876 }
2876 2877
2877 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { 2878 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
@@ -3677,7 +3678,7 @@ void do_unblank_screen(int leaving_gfx)
3677 return; /* but leave console_blanked != 0 */ 3678 return; /* but leave console_blanked != 0 */
3678 3679
3679 if (blankinterval) { 3680 if (blankinterval) {
3680 mod_timer(&console_timer, jiffies + blankinterval); 3681 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3681 blank_state = blank_normal_wait; 3682 blank_state = blank_normal_wait;
3682 } 3683 }
3683 3684
@@ -3711,7 +3712,7 @@ void unblank_screen(void)
3711static void blank_screen_t(unsigned long dummy) 3712static void blank_screen_t(unsigned long dummy)
3712{ 3713{
3713 if (unlikely(!keventd_up())) { 3714 if (unlikely(!keventd_up())) {
3714 mod_timer(&console_timer, jiffies + blankinterval); 3715 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3715 return; 3716 return;
3716 } 3717 }
3717 blank_timer_expired = 1; 3718 blank_timer_expired = 1;
@@ -3741,7 +3742,7 @@ void poke_blanked_console(void)
3741 if (console_blanked) 3742 if (console_blanked)
3742 unblank_screen(); 3743 unblank_screen();
3743 else if (blankinterval) { 3744 else if (blankinterval) {
3744 mod_timer(&console_timer, jiffies + blankinterval); 3745 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3745 blank_state = blank_normal_wait; 3746 blank_state = blank_normal_wait;
3746 } 3747 }
3747} 3748}