summary refs log tree commit diff
diff options
context:
space:
mode:
-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)
 			tty_kref_put(tty);
 			return -ENODEV;
 		}
-		minor = tty->index + RAW3270_FIRSTMINOR;
+		minor = tty->index;
 		tty_kref_put(tty);
 	}
 	mutex_lock(&fs3270_mutex);
@@ -524,6 +524,25 @@ static const struct file_operations fs3270_fops = {
 	.llseek		= no_llseek,
 };
 
+void fs3270_create_cb(int minor)
+{
+	__register_chrdev(IBM_FS3270_MAJOR, minor, 1, "tub", &fs3270_fops);
+	device_create(class3270, NULL, MKDEV(IBM_FS3270_MAJOR, minor),
+		      NULL, "3270/tub%d", minor);
+}
+
+void fs3270_destroy_cb(int minor)
+{
+	device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, minor));
+	__unregister_chrdev(IBM_FS3270_MAJOR, minor, 1, "tub");
+}
+
+struct raw3270_notifier fs3270_notifier =
+{
+	.create = fs3270_create_cb,
+	.destroy = fs3270_destroy_cb,
+};
+
 /*
  * 3270 fullscreen driver initialization.
  */
@@ -532,16 +551,20 @@ fs3270_init(void)
 {
 	int rc;
 
-	rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops);
+	rc = __register_chrdev(IBM_FS3270_MAJOR, 0, 1, "fs3270", &fs3270_fops);
 	if (rc)
 		return rc;
+	device_create(class3270, NULL, MKDEV(IBM_FS3270_MAJOR, 0),
+		      NULL, "3270/tub");
+	raw3270_register_notifier(&fs3270_notifier);
 	return 0;
 }
 
 static void __exit
 fs3270_exit(void)
 {
-	unregister_chrdev(IBM_FS3270_MAJOR, "fs3270");
+	raw3270_unregister_notifier(&fs3270_notifier);
+	__unregister_chrdev(IBM_FS3270_MAJOR, 0, 1, "fs3270");
 }
 
 MODULE_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 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 
-static struct class *class3270;
+struct class *class3270;
 
 /* The main 3270 data structure. */
 struct raw3270 {
@@ -46,8 +46,6 @@ struct raw3270 {
 	struct timer_list timer;	/* Device timer. */
 
 	unsigned char *ascebc;		/* ascii -> ebcdic table */
-	struct device *clttydev;	/* 3270-class tty device ptr */
-	struct device *cltubdev;	/* 3270-class tub device ptr */
 
 	struct raw3270_request init_request;
 	unsigned char init_data[256];
@@ -1072,10 +1070,6 @@ raw3270_delete_device(struct raw3270 *rp)
 
 	/* Remove from device chain. */
 	mutex_lock(&raw3270_mutex);
-	if (rp->clttydev && !IS_ERR(rp->clttydev))
-		device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
-	if (rp->cltubdev && !IS_ERR(rp->cltubdev))
-		device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, rp->minor));
 	list_del_init(&rp->list);
 	mutex_unlock(&raw3270_mutex);
 
@@ -1139,75 +1133,34 @@ static struct attribute_group raw3270_attr_group = {
 
 static int raw3270_create_attributes(struct raw3270 *rp)
 {
-	int rc;
-
-	rc = sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
-	if (rc)
-		goto out;
-
-	rp->clttydev = device_create(class3270, &rp->cdev->dev,
-				     MKDEV(IBM_TTY3270_MAJOR, rp->minor), NULL,
-				     "tty%s", dev_name(&rp->cdev->dev));
-	if (IS_ERR(rp->clttydev)) {
-		rc = PTR_ERR(rp->clttydev);
-		goto out_ttydev;
-	}
-
-	rp->cltubdev = device_create(class3270, &rp->cdev->dev,
-				     MKDEV(IBM_FS3270_MAJOR, rp->minor), NULL,
-				     "tub%s", dev_name(&rp->cdev->dev));
-	if (!IS_ERR(rp->cltubdev))
-		goto out;
-
-	rc = PTR_ERR(rp->cltubdev);
-	device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
-
-out_ttydev:
-	sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
-out:
-	return rc;
+	return sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
 }
 
 /*
  * Notifier for device addition/removal
  */
-struct raw3270_notifier {
-	struct list_head list;
-	void (*notifier)(int, int);
-};
-
 static LIST_HEAD(raw3270_notifier);
 
-int raw3270_register_notifier(void (*notifier)(int, int))
+int raw3270_register_notifier(struct raw3270_notifier *notifier)
 {
-	struct raw3270_notifier *np;
 	struct raw3270 *rp;
 
-	np = kmalloc(sizeof(struct raw3270_notifier), GFP_KERNEL);
-	if (!np)
-		return -ENOMEM;
-	np->notifier = notifier;
 	mutex_lock(&raw3270_mutex);
-	list_add_tail(&np->list, &raw3270_notifier);
-	list_for_each_entry(rp, &raw3270_devices, list) {
-		get_device(&rp->cdev->dev);
-		notifier(rp->minor, 1);
-	}
+	list_add_tail(&notifier->list, &raw3270_notifier);
+	list_for_each_entry(rp, &raw3270_devices, list)
+		notifier->create(rp->minor);
 	mutex_unlock(&raw3270_mutex);
 	return 0;
 }
 
-void raw3270_unregister_notifier(void (*notifier)(int, int))
+void raw3270_unregister_notifier(struct raw3270_notifier *notifier)
 {
-	struct raw3270_notifier *np;
+	struct raw3270 *rp;
 
 	mutex_lock(&raw3270_mutex);
-	list_for_each_entry(np, &raw3270_notifier, list)
-		if (np->notifier == notifier) {
-			list_del(&np->list);
-			kfree(np);
-			break;
-		}
+	list_for_each_entry(rp, &raw3270_devices, list)
+		notifier->destroy(rp->minor);
+	list_del(&notifier->list);
 	mutex_unlock(&raw3270_mutex);
 }
 
@@ -1217,8 +1170,8 @@ void raw3270_unregister_notifier(void (*notifier)(int, int))
 static int
 raw3270_set_online (struct ccw_device *cdev)
 {
-	struct raw3270 *rp;
 	struct raw3270_notifier *np;
+	struct raw3270 *rp;
 	int rc;
 
 	rp = raw3270_create_device(cdev);
@@ -1239,7 +1192,7 @@ raw3270_set_online (struct ccw_device *cdev)
 	set_bit(RAW3270_FLAGS_READY, &rp->flags);
 	mutex_lock(&raw3270_mutex);
 	list_for_each_entry(np, &raw3270_notifier, list)
-		np->notifier(rp->minor, 1);
+		np->create(rp->minor);
 	mutex_unlock(&raw3270_mutex);
 	return 0;
 
@@ -1290,7 +1243,7 @@ raw3270_remove (struct ccw_device *cdev)
 
 	mutex_lock(&raw3270_mutex);
 	list_for_each_entry(np, &raw3270_notifier, list)
-		np->notifier(rp->minor, 0);
+		np->destroy(rp->minor);
 	mutex_unlock(&raw3270_mutex);
 
 	/* Reset 3270 device. */
@@ -1434,6 +1387,7 @@ MODULE_LICENSE("GPL");
 module_init(raw3270_init);
 module_exit(raw3270_exit);
 
+EXPORT_SYMBOL(class3270);
 EXPORT_SYMBOL(raw3270_request_alloc);
 EXPORT_SYMBOL(raw3270_request_free);
 EXPORT_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 {
 
 struct raw3270;
 struct raw3270_view;
+extern struct class *class3270;
 
 /* 3270 CCW request */
 struct raw3270_request {
@@ -192,8 +193,14 @@ struct raw3270 *raw3270_setup_console(struct ccw_device *cdev);
 void raw3270_wait_cons_dev(struct raw3270 *);
 
 /* Notifier for device addition/removal */
-int raw3270_register_notifier(void (*notifier)(int, int));
-void raw3270_unregister_notifier(void (*notifier)(int, int));
+struct raw3270_notifier {
+	struct list_head list;
+	void (*create)(int minor);
+	void (*destroy)(int minor);
+};
+
+int raw3270_register_notifier(struct raw3270_notifier *);
+void raw3270_unregister_notifier(struct raw3270_notifier *);
 void raw3270_pm_unfreeze(struct raw3270_view *);
 
 /*
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)
 {
 	int i;
 
-	for (i = 0; i < tty3270_max_index; i++) {
-		struct raw3270_view *view =
-			raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
+	for (i = RAW3270_FIRSTMINOR; i <= tty3270_max_index; i++) {
+		struct raw3270_view *view = raw3270_find_view(&tty3270_fn, i);
 		if (!IS_ERR(view))
 			raw3270_del_view(view);
 	}
@@ -855,8 +854,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
 	int i, rc;
 
 	/* Check if the tty3270 is already there. */
-	view = raw3270_find_view(&tty3270_fn,
-				  tty->index + RAW3270_FIRSTMINOR);
+	view = raw3270_find_view(&tty3270_fn, tty->index);
 	if (!IS_ERR(view)) {
 		tp = container_of(view, struct tty3270, view);
 		tty->driver_data = tp;
@@ -868,8 +866,8 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
 		tp->inattr = TF_INPUT;
 		return tty_port_install(&tp->port, driver, tty);
 	}
-	if (tty3270_max_index < tty->index + 1)
-		tty3270_max_index = tty->index + 1;
+	if (tty3270_max_index < tty->index)
+		tty3270_max_index = tty->index;
 
 	/* Quick exit if there is no device for tty->index. */
 	if (PTR_ERR(view) == -ENODEV)
@@ -880,8 +878,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
 	if (IS_ERR(tp))
 		return PTR_ERR(tp);
 
-	rc = raw3270_add_view(&tp->view, &tty3270_fn,
-			      tty->index + RAW3270_FIRSTMINOR);
+	rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index);
 	if (rc) {
 		tty3270_free_view(tp);
 		return rc;
@@ -1788,6 +1785,22 @@ static const struct tty_operations tty3270_ops = {
 	.set_termios = tty3270_set_termios
 };
 
+void tty3270_create_cb(int minor)
+{
+	tty_register_device(tty3270_driver, minor, NULL);
+}
+
+void tty3270_destroy_cb(int minor)
+{
+	tty_unregister_device(tty3270_driver, minor);
+}
+
+struct raw3270_notifier tty3270_notifier =
+{
+	.create = tty3270_create_cb,
+	.destroy = tty3270_destroy_cb,
+};
+
 /*
  * 3270 tty registration code called from tty_init().
  * Most kernel services (incl. kmalloc) are available at this poimt.
@@ -1797,23 +1810,25 @@ static int __init tty3270_init(void)
 	struct tty_driver *driver;
 	int ret;
 
-	driver = alloc_tty_driver(RAW3270_MAXDEVS);
-	if (!driver)
-		return -ENOMEM;
+	driver = tty_alloc_driver(RAW3270_MAXDEVS,
+				  TTY_DRIVER_REAL_RAW |
+				  TTY_DRIVER_DYNAMIC_DEV |
+				  TTY_DRIVER_RESET_TERMIOS);
+	if (IS_ERR(driver))
+		return PTR_ERR(driver);
 
 	/*
 	 * Initialize the tty_driver structure
 	 * Entries in tty3270_driver that are NOT initialized:
 	 * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
 	 */
-	driver->driver_name = "ttyTUB";
-	driver->name = "ttyTUB";
+	driver->driver_name = "tty3270";
+	driver->name = "3270/tty";
 	driver->major = IBM_TTY3270_MAJOR;
-	driver->minor_start = RAW3270_FIRSTMINOR;
+	driver->minor_start = 0;
 	driver->type = TTY_DRIVER_TYPE_SYSTEM;
 	driver->subtype = SYSTEM_TYPE_TTY;
 	driver->init_termios = tty_std_termios;
-	driver->flags = TTY_DRIVER_RESET_TERMIOS;
 	tty_set_operations(driver, &tty3270_ops);
 	ret = tty_register_driver(driver);
 	if (ret) {
@@ -1821,6 +1836,7 @@ static int __init tty3270_init(void)
 		return ret;
 	}
 	tty3270_driver = driver;
+	raw3270_register_notifier(&tty3270_notifier);
 	return 0;
 }
 
@@ -1829,6 +1845,7 @@ tty3270_exit(void)
 {
 	struct tty_driver *driver;
 
+	raw3270_unregister_notifier(&tty3270_notifier);
 	driver = tty3270_driver;
 	tty3270_driver = NULL;
 	tty_unregister_driver(driver);