
From: Heiko Carstens <heiko.carstens@de.ibm.com>

From: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
From: Stefan Bader <shbader@de.ibm.com>

character device driver changes:
 - tape: Correct module count usage.
 - 3270: Use mod_timer only when timer is pending.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/s390/char/con3270.c   |    6 ++++--
 25-akpm/drivers/s390/char/tape_core.c |   11 +++++++++--
 25-akpm/drivers/s390/char/tty3270.c   |    5 +++--
 3 files changed, 16 insertions(+), 6 deletions(-)

diff -puN drivers/s390/char/con3270.c~s390-character-device-drivers drivers/s390/char/con3270.c
--- 25/drivers/s390/char/con3270.c~s390-character-device-drivers	2004-12-28 00:39:20.529720600 -0800
+++ 25-akpm/drivers/s390/char/con3270.c	2004-12-28 00:39:20.537719384 -0800
@@ -73,10 +73,12 @@ void
 con3270_set_timer(struct con3270 *cp, int expires)
 {
 	if (expires == 0) {
-		del_timer(&cp->timer);
+		if (timer_pending(&cp->timer))
+			del_timer(&cp->timer);
 		return;
 	}
-	if (mod_timer(&cp->timer, jiffies + expires))
+	if (timer_pending(&cp->timer) &&
+	    mod_timer(&cp->timer, jiffies + expires))
 		return;
 	cp->timer.function = (void (*)(unsigned long)) con3270_update;
 	cp->timer.data = (unsigned long) cp;
diff -puN drivers/s390/char/tape_core.c~s390-character-device-drivers drivers/s390/char/tape_core.c
--- 25/drivers/s390/char/tape_core.c~s390-character-device-drivers	2004-12-28 00:39:20.531720296 -0800
+++ 25-akpm/drivers/s390/char/tape_core.c	2004-12-28 00:39:20.538719232 -0800
@@ -349,6 +349,11 @@ tape_generic_online(struct tape_device *
 
 	/* Let the discipline have a go at the device. */
 	device->discipline = discipline;
+	if (!try_module_get(discipline->owner)) {
+		PRINT_ERR("Cannot get module. Module gone.\n");
+		return -EINVAL;
+	}
+
 	rc = discipline->setup_device(device);
 	if (rc)
 		goto out;
@@ -377,6 +382,7 @@ out_discipline:
 out_minor:
 	tape_remove_minor(device);
 out:
+	module_put(discipline->owner);
 	return rc;
 }
 
@@ -386,6 +392,7 @@ tape_cleanup_device(struct tape_device *
 	tapeblock_cleanup_device(device);
 	tapechar_cleanup_device(device);
 	device->discipline->cleanup_device(device);
+	module_put(device->discipline->owner);
 	tape_remove_minor(device);
 	tape_med_state_set(device, MS_UNKNOWN);
 }
@@ -1184,7 +1191,7 @@ tape_init (void)
 #ifdef DBF_LIKE_HELL
 	debug_set_level(TAPE_DBF_AREA, 6);
 #endif
-	DBF_EVENT(3, "tape init: ($Revision: 1.50 $)\n");
+	DBF_EVENT(3, "tape init: ($Revision: 1.51 $)\n");
 	tape_proc_init();
 	tapechar_init ();
 	tapeblock_init ();
@@ -1209,7 +1216,7 @@ tape_exit(void)
 MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
 	      "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
 MODULE_DESCRIPTION("Linux on zSeries channel attached "
-		   "tape device driver ($Revision: 1.50 $)");
+		   "tape device driver ($Revision: 1.51 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_init);
diff -puN drivers/s390/char/tty3270.c~s390-character-device-drivers drivers/s390/char/tty3270.c
--- 25/drivers/s390/char/tty3270.c~s390-character-device-drivers	2004-12-28 00:39:20.533719992 -0800
+++ 25-akpm/drivers/s390/char/tty3270.c	2004-12-28 00:39:20.540718928 -0800
@@ -124,11 +124,12 @@ void
 tty3270_set_timer(struct tty3270 *tp, int expires)
 {
 	if (expires == 0) {
-		if (del_timer(&tp->timer))
+		if (timer_pending(&tp->timer) && del_timer(&tp->timer))
 			raw3270_put_view(&tp->view);
 		return;
 	}
-	if (mod_timer(&tp->timer, jiffies + expires))
+	if (timer_pending(&tp->timer) &&
+	    mod_timer(&tp->timer, jiffies + expires))
 		return;
 	raw3270_get_view(&tp->view);
 	tp->timer.function = (void (*)(unsigned long)) tty3270_update;
_
