vserver 1.9.5.x5
[linux-2.6.git] / drivers / s390 / char / tape_core.c
index 6d7c5c0..e51046a 100644 (file)
@@ -20,6 +20,8 @@
 
 #include <asm/types.h>      // for variable types
 
+#define TAPE_DBF_AREA  tape_core_dbf
+
 #include "tape.h"
 #include "tape_std.h"
 
@@ -34,12 +36,13 @@ static void __tape_remove_request(struct tape_device *, struct tape_request *);
  * The list is protected by the rwlock
  */
 static struct list_head tape_device_list = LIST_HEAD_INIT(tape_device_list);
-static rwlock_t tape_device_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(tape_device_lock);
 
 /*
  * Pointer to debug area.
  */
-debug_info_t *tape_dbf_area = NULL;
+debug_info_t *TAPE_DBF_AREA = NULL;
+EXPORT_SYMBOL(TAPE_DBF_AREA);
 
 /*
  * Printable strings for tape enumerations.
@@ -346,6 +349,11 @@ tape_generic_online(struct tape_device *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;
@@ -374,6 +382,7 @@ out_discipline:
 out_minor:
        tape_remove_minor(device);
 out:
+       module_put(discipline->owner);
        return rc;
 }
 
@@ -383,6 +392,7 @@ tape_cleanup_device(struct tape_device *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);
 }
@@ -1176,12 +1186,12 @@ tape_mtop(struct tape_device *device, int mt_op, int mt_count)
 static int
 tape_init (void)
 {
-       tape_dbf_area = debug_register ( "tape", 1, 2, 4*sizeof(long));
-       debug_register_view(tape_dbf_area, &debug_sprintf_view);
+       TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long));
+       debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
 #ifdef DBF_LIKE_HELL
-       debug_set_level(tape_dbf_area, 6);
+       debug_set_level(TAPE_DBF_AREA, 6);
 #endif
-       DBF_EVENT(3, "tape init: ($Revision: 1.49 $)\n");
+       DBF_EVENT(3, "tape init: ($Revision: 1.51 $)\n");
        tape_proc_init();
        tapechar_init ();
        tapeblock_init ();
@@ -1200,19 +1210,18 @@ tape_exit(void)
        tapechar_exit();
        tapeblock_exit();
        tape_proc_cleanup();
-       debug_unregister (tape_dbf_area);
+       debug_unregister (TAPE_DBF_AREA);
 }
 
 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.49 $)");
+                  "tape device driver ($Revision: 1.51 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_init);
 module_exit(tape_exit);
 
-EXPORT_SYMBOL(tape_dbf_area);
 EXPORT_SYMBOL(tape_generic_remove);
 EXPORT_SYMBOL(tape_generic_probe);
 EXPORT_SYMBOL(tape_generic_online);