aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-01-08 09:31:11 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-02-14 09:55:02 -0500
commitc95571e68086d36e8e3369597b03ec29c63abec9 (patch)
tree20cb4b0f1f9bbf49375ab6a6458668fd726f6841
parent57985d7e1e48f16548aa6904264e21bca15af0fc (diff)
s390/3270: introduce device notifier
Add a notifier to create / destroy the device nodes for the tty view and the fullscreen view. Only device nodes for online devices are created and the device names will follow the convention as outlined in Documentation/devices.txt: 3270/tty<x> for the tty nodes, 3270/tub<x> for hte fullscreen nodes and 3270/tub for the fullscreen control node. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/char/fs3270.c29
-rw-r--r--drivers/s390/char/raw3270.c76
-rw-r--r--drivers/s390/char/raw3270.h11
-rw-r--r--drivers/s390/char/tty3270.c49
4 files changed, 83 insertions, 82 deletions
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 911704571b9c..230697aac94b 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -443,7 +443,7 @@ fs3270_open(struct inode *inode, struct file *filp)
443 tty_kref_put(tty); 443 tty_kref_put(tty);
444 return -ENODEV; 444 return -ENODEV;
445 } 445 }
446 minor = tty->index + RAW3270_FIRSTMINOR; 446 minor = tty->index;
447 tty_kref_put(tty); 447 tty_kref_put(tty);
448 } 448 }
449 mutex_lock(&fs3270_mutex); 449 mutex_lock(&fs3270_mutex);
@@ -524,6 +524,25 @@ static const struct file_operations fs3270_fops = {
524 .llseek = no_llseek, 524 .llseek = no_llseek,
525}; 525};
526 526
527void fs3270_create_cb(int minor)
528{
529 __register_chrdev(IBM_FS3270_MAJOR, minor, 1, "tub", &fs3270_fops);
530 device_create(class3270, NULL, MKDEV(IBM_FS3270_MAJOR, minor),
531 NULL, "3270/tub%d", minor);
532}
533
534void fs3270_destroy_cb(int minor)
535{
536 device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, minor));
537 __unregister_chrdev(IBM_FS3270_MAJOR, minor, 1, "tub");
538}
539
540struct raw3270_notifier fs3270_notifier =
541{
542 .create = fs3270_create_cb,
543 .destroy = fs3270_destroy_cb,
544};
545
527/* 546/*
528 * 3270 fullscreen driver initialization. 547 * 3270 fullscreen driver initialization.
529 */ 548 */
@@ -532,16 +551,20 @@ fs3270_init(void)
532{ 551{
533 int rc; 552 int rc;
534 553
535 rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops); 554 rc = __register_chrdev(IBM_FS3270_MAJOR, 0, 1, "fs3270", &fs3270_fops);
536 if (rc) 555 if (rc)
537 return rc; 556 return rc;
557 device_create(class3270, NULL, MKDEV(IBM_FS3270_MAJOR, 0),
558 NULL, "3270/tub");
559 raw3270_register_notifier(&fs3270_notifier);
538 return 0; 560 return 0;
539} 561}
540 562
541static void __exit 563static void __exit
542fs3270_exit(void) 564fs3270_exit(void)
543{ 565{
544 unregister_chrdev(IBM_FS3270_MAJOR, "fs3270"); 566 raw3270_unregister_notifier(&fs3270_notifier);
567 __unregister_chrdev(IBM_FS3270_MAJOR, 0, 1, "fs3270");
545} 568}
546 569
547MODULE_LICENSE("GPL"); 570MODULE_LICENSE("GPL");
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 9a6c140c5f07..72f69fda9d01 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -28,7 +28,7 @@
28#include <linux/device.h> 28#include <linux/device.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30 30
31static struct class *class3270; 31struct class *class3270;
32 32
33/* The main 3270 data structure. */ 33/* The main 3270 data structure. */
34struct raw3270 { 34struct raw3270 {
@@ -46,8 +46,6 @@ struct raw3270 {
46 struct timer_list timer; /* Device timer. */ 46 struct timer_list timer; /* Device timer. */
47 47
48 unsigned char *ascebc; /* ascii -> ebcdic table */ 48 unsigned char *ascebc; /* ascii -> ebcdic table */
49 struct device *clttydev; /* 3270-class tty device ptr */
50 struct device *cltubdev; /* 3270-class tub device ptr */
51 49
52 struct raw3270_request init_request; 50 struct raw3270_request init_request;
53 unsigned char init_data[256]; 51 unsigned char init_data[256];
@@ -1072,10 +1070,6 @@ raw3270_delete_device(struct raw3270 *rp)
1072 1070
1073 /* Remove from device chain. */ 1071 /* Remove from device chain. */
1074 mutex_lock(&raw3270_mutex); 1072 mutex_lock(&raw3270_mutex);
1075 if (rp->clttydev && !IS_ERR(rp->clttydev))
1076 device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
1077 if (rp->cltubdev && !IS_ERR(rp->cltubdev))
1078 device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, rp->minor));
1079 list_del_init(&rp->list); 1073 list_del_init(&rp->list);
1080 mutex_unlock(&raw3270_mutex); 1074 mutex_unlock(&raw3270_mutex);
1081 1075
@@ -1139,75 +1133,34 @@ static struct attribute_group raw3270_attr_group = {
1139 1133
1140static int raw3270_create_attributes(struct raw3270 *rp) 1134static int raw3270_create_attributes(struct raw3270 *rp)
1141{ 1135{
1142 int rc; 1136 return sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
1143
1144 rc = sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
1145 if (rc)
1146 goto out;
1147
1148 rp->clttydev = device_create(class3270, &rp->cdev->dev,
1149 MKDEV(IBM_TTY3270_MAJOR, rp->minor), NULL,
1150 "tty%s", dev_name(&rp->cdev->dev));
1151 if (IS_ERR(rp->clttydev)) {
1152 rc = PTR_ERR(rp->clttydev);
1153 goto out_ttydev;
1154 }
1155
1156 rp->cltubdev = device_create(class3270, &rp->cdev->dev,
1157 MKDEV(IBM_FS3270_MAJOR, rp->minor), NULL,
1158 "tub%s", dev_name(&rp->cdev->dev));
1159 if (!IS_ERR(rp->cltubdev))
1160 goto out;
1161
1162 rc = PTR_ERR(rp->cltubdev);
1163 device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
1164
1165out_ttydev:
1166 sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
1167out:
1168 return rc;
1169} 1137}
1170 1138
1171/* 1139/*
1172 * Notifier for device addition/removal 1140 * Notifier for device addition/removal
1173 */ 1141 */
1174struct raw3270_notifier {
1175 struct list_head list;
1176 void (*notifier)(int, int);
1177};
1178
1179static LIST_HEAD(raw3270_notifier); 1142static LIST_HEAD(raw3270_notifier);
1180 1143
1181int raw3270_register_notifier(void (*notifier)(int, int)) 1144int raw3270_register_notifier(struct raw3270_notifier *notifier)
1182{ 1145{
1183 struct raw3270_notifier *np;
1184 struct raw3270 *rp; 1146 struct raw3270 *rp;
1185 1147
1186 np = kmalloc(sizeof(struct raw3270_notifier), GFP_KERNEL);
1187 if (!np)
1188 return -ENOMEM;
1189 np->notifier = notifier;
1190 mutex_lock(&raw3270_mutex); 1148 mutex_lock(&raw3270_mutex);
1191 list_add_tail(&np->list, &raw3270_notifier); 1149 list_add_tail(&notifier->list, &raw3270_notifier);
1192 list_for_each_entry(rp, &raw3270_devices, list) { 1150 list_for_each_entry(rp, &raw3270_devices, list)
1193 get_device(&rp->cdev->dev); 1151 notifier->create(rp->minor);
1194 notifier(rp->minor, 1);
1195 }
1196 mutex_unlock(&raw3270_mutex); 1152 mutex_unlock(&raw3270_mutex);
1197 return 0; 1153 return 0;
1198} 1154}
1199 1155
1200void raw3270_unregister_notifier(void (*notifier)(int, int)) 1156void raw3270_unregister_notifier(struct raw3270_notifier *notifier)
1201{ 1157{
1202 struct raw3270_notifier *np; 1158 struct raw3270 *rp;
1203 1159
1204 mutex_lock(&raw3270_mutex); 1160 mutex_lock(&raw3270_mutex);
1205 list_for_each_entry(np, &raw3270_notifier, list) 1161 list_for_each_entry(rp, &raw3270_devices, list)
1206 if (np->notifier == notifier) { 1162 notifier->destroy(rp->minor);
1207 list_del(&np->list); 1163 list_del(&notifier->list);
1208 kfree(np);
1209 break;
1210 }
1211 mutex_unlock(&raw3270_mutex); 1164 mutex_unlock(&raw3270_mutex);
1212} 1165}
1213 1166
@@ -1217,8 +1170,8 @@ void raw3270_unregister_notifier(void (*notifier)(int, int))
1217static int 1170static int
1218raw3270_set_online (struct ccw_device *cdev) 1171raw3270_set_online (struct ccw_device *cdev)
1219{ 1172{
1220 struct raw3270 *rp;
1221 struct raw3270_notifier *np; 1173 struct raw3270_notifier *np;
1174 struct raw3270 *rp;
1222 int rc; 1175 int rc;
1223 1176
1224 rp = raw3270_create_device(cdev); 1177 rp = raw3270_create_device(cdev);
@@ -1239,7 +1192,7 @@ raw3270_set_online (struct ccw_device *cdev)
1239 set_bit(RAW3270_FLAGS_READY, &rp->flags); 1192 set_bit(RAW3270_FLAGS_READY, &rp->flags);
1240 mutex_lock(&raw3270_mutex); 1193 mutex_lock(&raw3270_mutex);
1241 list_for_each_entry(np, &raw3270_notifier, list) 1194 list_for_each_entry(np, &raw3270_notifier, list)
1242 np->notifier(rp->minor, 1); 1195 np->create(rp->minor);
1243 mutex_unlock(&raw3270_mutex); 1196 mutex_unlock(&raw3270_mutex);
1244 return 0; 1197 return 0;
1245 1198
@@ -1290,7 +1243,7 @@ raw3270_remove (struct ccw_device *cdev)
1290 1243
1291 mutex_lock(&raw3270_mutex); 1244 mutex_lock(&raw3270_mutex);
1292 list_for_each_entry(np, &raw3270_notifier, list) 1245 list_for_each_entry(np, &raw3270_notifier, list)
1293 np->notifier(rp->minor, 0); 1246 np->destroy(rp->minor);
1294 mutex_unlock(&raw3270_mutex); 1247 mutex_unlock(&raw3270_mutex);
1295 1248
1296 /* Reset 3270 device. */ 1249 /* Reset 3270 device. */
@@ -1434,6 +1387,7 @@ MODULE_LICENSE("GPL");
1434module_init(raw3270_init); 1387module_init(raw3270_init);
1435module_exit(raw3270_exit); 1388module_exit(raw3270_exit);
1436 1389
1390EXPORT_SYMBOL(class3270);
1437EXPORT_SYMBOL(raw3270_request_alloc); 1391EXPORT_SYMBOL(raw3270_request_alloc);
1438EXPORT_SYMBOL(raw3270_request_free); 1392EXPORT_SYMBOL(raw3270_request_free);
1439EXPORT_SYMBOL(raw3270_request_reset); 1393EXPORT_SYMBOL(raw3270_request_reset);
diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
index ed34eb2199cc..a4c79d043cd3 100644
--- a/drivers/s390/char/raw3270.h
+++ b/drivers/s390/char/raw3270.h
@@ -91,6 +91,7 @@ struct raw3270_iocb {
91 91
92struct raw3270; 92struct raw3270;
93struct raw3270_view; 93struct raw3270_view;
94extern struct class *class3270;
94 95
95/* 3270 CCW request */ 96/* 3270 CCW request */
96struct raw3270_request { 97struct raw3270_request {
@@ -192,8 +193,14 @@ struct raw3270 *raw3270_setup_console(struct ccw_device *cdev);
192void raw3270_wait_cons_dev(struct raw3270 *); 193void raw3270_wait_cons_dev(struct raw3270 *);
193 194
194/* Notifier for device addition/removal */ 195/* Notifier for device addition/removal */
195int raw3270_register_notifier(void (*notifier)(int, int)); 196struct raw3270_notifier {
196void raw3270_unregister_notifier(void (*notifier)(int, int)); 197 struct list_head list;
198 void (*create)(int minor);
199 void (*destroy)(int minor);
200};
201
202int raw3270_register_notifier(struct raw3270_notifier *);
203void raw3270_unregister_notifier(struct raw3270_notifier *);
197void raw3270_pm_unfreeze(struct raw3270_view *); 204void raw3270_pm_unfreeze(struct raw3270_view *);
198 205
199/* 206/*
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 5e4b6fc49ae3..48767e6bab9d 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -829,9 +829,8 @@ tty3270_del_views(void)
829{ 829{
830 int i; 830 int i;
831 831
832 for (i = 0; i < tty3270_max_index; i++) { 832 for (i = RAW3270_FIRSTMINOR; i <= tty3270_max_index; i++) {
833 struct raw3270_view *view = 833 struct raw3270_view *view = raw3270_find_view(&tty3270_fn, i);
834 raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
835 if (!IS_ERR(view)) 834 if (!IS_ERR(view))
836 raw3270_del_view(view); 835 raw3270_del_view(view);
837 } 836 }
@@ -855,8 +854,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
855 int i, rc; 854 int i, rc;
856 855
857 /* Check if the tty3270 is already there. */ 856 /* Check if the tty3270 is already there. */
858 view = raw3270_find_view(&tty3270_fn, 857 view = raw3270_find_view(&tty3270_fn, tty->index);
859 tty->index + RAW3270_FIRSTMINOR);
860 if (!IS_ERR(view)) { 858 if (!IS_ERR(view)) {
861 tp = container_of(view, struct tty3270, view); 859 tp = container_of(view, struct tty3270, view);
862 tty->driver_data = tp; 860 tty->driver_data = tp;
@@ -868,8 +866,8 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
868 tp->inattr = TF_INPUT; 866 tp->inattr = TF_INPUT;
869 return tty_port_install(&tp->port, driver, tty); 867 return tty_port_install(&tp->port, driver, tty);
870 } 868 }
871 if (tty3270_max_index < tty->index + 1) 869 if (tty3270_max_index < tty->index)
872 tty3270_max_index = tty->index + 1; 870 tty3270_max_index = tty->index;
873 871
874 /* Quick exit if there is no device for tty->index. */ 872 /* Quick exit if there is no device for tty->index. */
875 if (PTR_ERR(view) == -ENODEV) 873 if (PTR_ERR(view) == -ENODEV)
@@ -880,8 +878,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
880 if (IS_ERR(tp)) 878 if (IS_ERR(tp))
881 return PTR_ERR(tp); 879 return PTR_ERR(tp);
882 880
883 rc = raw3270_add_view(&tp->view, &tty3270_fn, 881 rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index);
884 tty->index + RAW3270_FIRSTMINOR);
885 if (rc) { 882 if (rc) {
886 tty3270_free_view(tp); 883 tty3270_free_view(tp);
887 return rc; 884 return rc;
@@ -1788,6 +1785,22 @@ static const struct tty_operations tty3270_ops = {
1788 .set_termios = tty3270_set_termios 1785 .set_termios = tty3270_set_termios
1789}; 1786};
1790 1787
1788void tty3270_create_cb(int minor)
1789{
1790 tty_register_device(tty3270_driver, minor, NULL);
1791}
1792
1793void tty3270_destroy_cb(int minor)
1794{
1795 tty_unregister_device(tty3270_driver, minor);
1796}
1797
1798struct raw3270_notifier tty3270_notifier =
1799{
1800 .create = tty3270_create_cb,
1801 .destroy = tty3270_destroy_cb,
1802};
1803
1791/* 1804/*
1792 * 3270 tty registration code called from tty_init(). 1805 * 3270 tty registration code called from tty_init().
1793 * Most kernel services (incl. kmalloc) are available at this poimt. 1806 * Most kernel services (incl. kmalloc) are available at this poimt.
@@ -1797,23 +1810,25 @@ static int __init tty3270_init(void)
1797 struct tty_driver *driver; 1810 struct tty_driver *driver;
1798 int ret; 1811 int ret;
1799 1812
1800 driver = alloc_tty_driver(RAW3270_MAXDEVS); 1813 driver = tty_alloc_driver(RAW3270_MAXDEVS,
1801 if (!driver) 1814 TTY_DRIVER_REAL_RAW |
1802 return -ENOMEM; 1815 TTY_DRIVER_DYNAMIC_DEV |
1816 TTY_DRIVER_RESET_TERMIOS);
1817 if (IS_ERR(driver))
1818 return PTR_ERR(driver);
1803 1819
1804 /* 1820 /*
1805 * Initialize the tty_driver structure 1821 * Initialize the tty_driver structure
1806 * Entries in tty3270_driver that are NOT initialized: 1822 * Entries in tty3270_driver that are NOT initialized:
1807 * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc 1823 * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
1808 */ 1824 */
1809 driver->driver_name = "ttyTUB"; 1825 driver->driver_name = "tty3270";
1810 driver->name = "ttyTUB"; 1826 driver->name = "3270/tty";
1811 driver->major = IBM_TTY3270_MAJOR; 1827 driver->major = IBM_TTY3270_MAJOR;
1812 driver->minor_start = RAW3270_FIRSTMINOR; 1828 driver->minor_start = 0;
1813 driver->type = TTY_DRIVER_TYPE_SYSTEM; 1829 driver->type = TTY_DRIVER_TYPE_SYSTEM;
1814 driver->subtype = SYSTEM_TYPE_TTY; 1830 driver->subtype = SYSTEM_TYPE_TTY;
1815 driver->init_termios = tty_std_termios; 1831 driver->init_termios = tty_std_termios;
1816 driver->flags = TTY_DRIVER_RESET_TERMIOS;
1817 tty_set_operations(driver, &tty3270_ops); 1832 tty_set_operations(driver, &tty3270_ops);
1818 ret = tty_register_driver(driver); 1833 ret = tty_register_driver(driver);
1819 if (ret) { 1834 if (ret) {
@@ -1821,6 +1836,7 @@ static int __init tty3270_init(void)
1821 return ret; 1836 return ret;
1822 } 1837 }
1823 tty3270_driver = driver; 1838 tty3270_driver = driver;
1839 raw3270_register_notifier(&tty3270_notifier);
1824 return 0; 1840 return 0;
1825} 1841}
1826 1842
@@ -1829,6 +1845,7 @@ tty3270_exit(void)
1829{ 1845{
1830 struct tty_driver *driver; 1846 struct tty_driver *driver;
1831 1847
1848 raw3270_unregister_notifier(&tty3270_notifier);
1832 driver = tty3270_driver; 1849 driver = tty3270_driver;
1833 tty3270_driver = NULL; 1850 tty3270_driver = NULL;
1834 tty_unregister_driver(driver); 1851 tty_unregister_driver(driver);