]> git.hungrycats.org Git - linux/commitdiff
[PATCH] s390: old tape file.
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Sun, 15 Dec 2002 04:02:51 +0000 (20:02 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 15 Dec 2002 04:02:51 +0000 (20:02 -0800)
Remove last remaining file of the old tape driver.

drivers/s390/char/tape.c [deleted file]

diff --git a/drivers/s390/char/tape.c b/drivers/s390/char/tape.c
deleted file mode 100644 (file)
index ff31dc5..0000000
+++ /dev/null
@@ -1,1907 +0,0 @@
-/***********************************************************************
- *  drivers/s390/char/tape.c
- *    tape device driver for S/390 and zSeries tapes.
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Michael Holzheu <holzheu@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- ***********************************************************************
- */
-
-#include "tapedefs.h" // kernel 2.2 compatibility defines
-
-#include <linux/stddef.h>    // defines NULL
-#include <linux/proc_fs.h>   // for /proc/tapedevices
-#include <linux/init.h>      // for kernel parameters
-#include <linux/kmod.h>      // for requesting modules
-#include <linux/spinlock.h>  // for locks
-#include <asm/types.h>       // for variable types
-#ifdef CONFIG_S390_TAPE_DYNAMIC
-#include <asm/s390dyn.h>
-#endif
-#include "tape.h"
-#ifdef CONFIG_S390_TAPE_3590
-#include "tape3590.h"
-#endif
-#ifdef CONFIG_S390_TAPE_3490
-#include "tape3490.h"
-#endif
-#ifdef CONFIG_S390_TAPE_3480
-#include "tape3480.h"
-#endif
-#ifdef CONFIG_S390_TAPE_BLOCK
-#include "tapeblock.h"
-#endif
-#ifdef CONFIG_S390_TAPE_CHAR
-#include "tapechar.h"
-#endif
-#ifdef CONFIG_PROC_FS
-#include <linux/vmalloc.h>
-#endif
-#define PRINTK_HEADER "T390:"
-#define TAPE_MAX_DEVREGS        (256 / TAPE_MINORS_PER_DEV)
-
-#define TAPE_NO_IO          0
-#define TAPE_DO_IO          1
-
-#define TAPE_CIO_PRIVATE_DATA
-
-#ifdef CONFIG_KMOD
-#define tape_request_module(a) request_module(a)
-#else
-#define tape_request_module(a)
-#endif
-
-/*******************************************************************
- * Internal Prototypes
- *******************************************************************/
-
-static void tape_do_irq (int irq, void *int_parm, struct pt_regs *regs);
-static inline int tape_halt_io(tape_dev_t* td);
-static void tape_wait(tape_ccw_req_t* treq);
-#ifdef CONFIG_S390_TAPE_DYNAMIC
-/* functions for dyn. dev. attach/detach */
-static int tape_oper_handler ( int irq, struct _devreg *dreg);
-static void tape_noper_handler ( int irq, int status );
-#endif
-static inline void tape_disable_device(tape_dev_t* td);
-static inline int tape_enable_device(tape_dev_t* td);
-
-
-/*******************************************************************
- * GLOBALS
- *******************************************************************/
-
-static devreg_t          *tape_devreg[TAPE_MAX_DEVREGS];
-static int               tape_devregct=0;
-static int               tape_autoprobe = 1;
-static tape_discipline_t *tape_first_disc = NULL;
-tape_dev_t               *tape_first_dev = NULL;
-tape_frontend_t          *tape_first_front = NULL;
-char                     *tape[256] = { NULL, }; 
-
-/*
- * Lock hirarchy:
- * tape_discipline_lock > tape_dev_lock > td->lock
- */
-
-rwlock_t   tape_dev_lock=RW_LOCK_UNLOCKED;
-static rwlock_t   tape_discipline_lock=RW_LOCK_UNLOCKED;
-
-#ifdef TAPE_DEBUG
-debug_info_t *tape_dbf_area = NULL;
-#endif
-
-const char* tape_med_st_verbose[MS_SIZE]={
-       "UNKNOWN ",
-       "LOADED  ",
-       "UNLOADED"
-};
-
-const char* tape_state_verbose[TS_SIZE]={
-       "UNUSED",
-       "IN_USE", 
-       "INIT  ",
-       "NOT_OP"
-};
-
-const char* tape_op_verbose[TO_SIZE] = {
-       "BLK",
-       "BSB",
-       "BSF",
-       "DSE",
-       "EGA",
-       "FSB",
-       "FSF",
-       "LDI",
-       "LBL",
-       "MSE",
-       "NOP",
-       "RBA",
-       "RBI",
-       "RBU",
-       "RBL",
-       "RDC",
-       "RFO",
-       "RSD",
-       "REW",
-       "RUN",
-       "SEN",
-       "SID",
-       "SNP",
-       "SPG",
-       "SWI",
-       "SMR",
-       "SYN",
-       "TIO",
-       "UNA",
-       "WRI",
-       "WTM",
-       "MSN",
-       "LOA",
-       "RCF", /* 3590 */
-       "RAT", /* 3590 */
-       "NOT"
-};
-
-/*******************************************************************
- * DEVFS Functions
- *******************************************************************/
-
-#ifdef CONFIG_DEVFS_FS
-
-/*
- * Create devfs root entry (devno in hex) for device td
- */
-
-static inline devfs_handle_t
-tape_mkdevfsroot (tape_dev_t* td) 
-{
-    char devno [10];
-    sprintf (devno,"tape/%04x",td->devinfo.devno);
-    return devfs_mk_dir(NULL, devno, NULL);
-}
-
-/*
- * Remove devfs root entry for device td
- */
-
-static inline void
-tape_rmdevfsroot (tape_dev_t* td)
-{
-    devfs_remove("tape/%04x", td->devinfo.devno);
-}
-
-#endif
-
-/*******************************************************************
- * PROCFS Functions
- *******************************************************************/
-
-#ifdef CONFIG_PROC_FS
-/* functions used in tape_proc_file_ops */
-static ssize_t tape_proc_devices_read (struct file *file, char *user_buf, size_t user_len, loff_t * offset);
-static int tape_proc_devices_open (struct inode *inode, struct file *file);
-static int tape_proc_devices_release (struct inode *inode, struct file *file);
-
-/* our proc tapedevices entry */
-static struct proc_dir_entry *tape_proc_devices;
-
-typedef struct {
-       char *data;
-       int len;
-} tape_procinfo_t;
-
-static struct file_operations tape_proc_devices_file_ops =
-{
-       .owner = THIS_MODULE,
-       .read = tape_proc_devices_read, /* read */
-       .open = tape_proc_devices_open, /* open */
-       .release = tape_proc_devices_release,   /* close */
-};
-
-/* 
- * Initialize procfs stuff on startup
- */
-
-static inline void
-tape_proc_init (void) {
-       tape_proc_devices = create_proc_entry ("tapedevices",
-                                               S_IFREG | S_IRUGO | S_IWUSR,
-                                               &proc_root);
-       if (tape_proc_devices == NULL) 
-               goto error;
-       tape_proc_devices->proc_fops = &tape_proc_devices_file_ops;
-       tape_proc_devices->proc_iops = &tape_proc_devices_inode_ops;
-       return;
- error:
-       PRINT_WARN ("tape: Cannot register procfs entry tapedevices\n");
-       return;
-}
-
-/*
- * Open function for /proc/tapedevices
- */
-
-static int
-tape_proc_devices_open (struct inode *inode, struct file *file)
-{
-       tape_dev_t* td;
-       tape_procinfo_t* procinfo;
-       char* data = NULL;
-       int size=0,check_size = -1;
-       int pos=0;
-       int rc=0;
-       long lockflags,lockflags2;
-       tape_ccw_req_t *treq;
-
-       procinfo = kmalloc (sizeof(tape_procinfo_t),GFP_KERNEL);
-       if (!procinfo){
-               rc = -ENOMEM;
-               goto out_no_lock;
-       }
-
-       /* Find out mem size for output, ensure that after releasing lock   */
-       /* (vmalloc must not be called with interrupts disabled) no devices */
-       /* have been added/removed                                          */
-
-       do{
-               size = 100; // Headline
-               read_lock_irqsave(&tape_dev_lock,lockflags);
-
-               for (td=tape_first_dev;td!=NULL;td=td->next)
-                       size+=100; // FIXME: Guess better!
-
-               if(size == check_size)
-                        break;
-
-               read_unlock_irqrestore(&tape_dev_lock,lockflags);
-
-               if(data)
-                       vfree(data);
-               data=vmalloc(size);
-               if (!data) {
-                    kfree (procinfo);
-                    rc = -ENOMEM;
-                    goto out_no_lock;
-               }
-               check_size = size;
-       }while (1);
-
-       // We have the tape_dev lock now
-
-#ifdef CONFIG_S390_TAPE_CHAR
-       pos+=sprintf(data+pos,"TapeNo\tDevNo\tCuType\tCuModel\tDevType\tDevMod\tBlkSize\tState\tOp\tMedState\n");
-#else
-       pos+=sprintf(data+pos,"TapeNo\tDevNo\tCuType\tCuModel\tDevType\tDevMod\tState\tOp\tMedState\n");
-#endif
-
-       for (td=tape_first_dev;td!=NULL;td=td->next) {
-               s390irq_spin_lock_irqsave (td->devinfo.irq,lockflags2);
-               treq = tape_get_active_ccw_req(td);
-               pos+=sprintf(data+pos,"%d\t",td->first_minor/TAPE_MINORS_PER_DEV);
-               pos+=sprintf(data+pos,"%04X\t",td->devinfo.devno);
-               pos+=sprintf(data+pos,"%04X\t",td->devinfo.sid_data.cu_type);
-               pos+=sprintf(data+pos,"%02X\t",td->devinfo.sid_data.cu_model);
-               pos+=sprintf(data+pos,"%04X\t",td->devinfo.sid_data.dev_type);
-               pos+=sprintf(data+pos,"%02X\t",td->devinfo.sid_data.dev_model);
-#ifdef CONFIG_S390_TAPE_CHAR
-               if(td->char_data.block_size == 0)
-                       pos+=sprintf(data+pos,"auto\t");
-               else
-                       pos+=sprintf(data+pos,"%i\t",td->char_data.block_size);
-#endif
-               pos+=sprintf(data+pos,"%s\t",((tape_state_get(td) >= 0) &&
-                       (tape_state_get(td) < TS_SIZE)) ?
-                       tape_state_verbose[tape_state_get (td)] : "UNKNOWN");
-               pos+=sprintf(data+pos,"%s\t",(treq != NULL) ? 
-                       tape_op_verbose[treq->op] : "---");
-               pos+=sprintf(data+pos,"%s\n",tape_med_st_verbose[td->medium_state]);
-               s390irq_spin_unlock_irqrestore (td->devinfo.irq,lockflags2);
-       }
-
-       procinfo->data=data;
-       procinfo->len=pos;
-        if (pos>size) BUG(); // we've overwritten some memory
-       file->private_data= (void*) procinfo;
-       read_unlock_irqrestore(&tape_dev_lock,lockflags);
-out_no_lock:
-       return rc;
-}
-
-/*
- * Read function for /proc/tapedevices
- */
-
-static ssize_t
-tape_proc_devices_read (struct file *file, char *user_buf, size_t user_len, loff_t * offset)
-{
-       loff_t len = 0;
-       tape_procinfo_t *p_info = (tape_procinfo_t *) file->private_data;
-
-       if (*offset >= p_info->len) {
-               goto out; /* EOF */
-       } else {
-               len =  user_len<(p_info->len - *offset)?user_len:(p_info->len - *offset);
-               if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
-                       return -EFAULT;
-               (*offset) += len;
-       }
-out:
-       return len;
-}
-
-/*
- * Close function for /proc/tapedevices
- */
-
-static int
-tape_proc_devices_release (struct inode *inode, struct file *file)
-{
-       int rc = 0;
-       tape_procinfo_t *p_info = (tape_procinfo_t *) file->private_data;
-        vfree(p_info->data);
-        kfree (p_info);
-       return rc;
-}
-
-/*
- * Cleanup all stuff registered to the procfs
- */
-static inline void
-tape_proc_cleanup (void)
-{
-        if (tape_proc_devices != NULL)
-               remove_proc_entry ("tapedevices", &proc_root);
-}
-
-#endif /* CONFIG_PROC_FS */
-
-/*******************************************************************
- * Wait/Wakeup Functions
- *******************************************************************/
-
-static void tape_wake_up_remove(tape_ccw_req_t* treq){
-       tape_remove_ccw_req(treq->tape_dev,treq);
-       tape_free_ccw_req(treq);
-}
-static void tape_wake_up(tape_ccw_req_t* treq){
-        treq->wakeup = NULL;
-        wake_up(&treq->wq);
-}
-static void tape_wake_up_interruptible(tape_ccw_req_t* treq){
-        treq->wakeup = NULL;
-        wake_up_interruptible(&treq->wq);
-}
-#ifdef CONFIG_S390_TAPE_BLOCK
-static void tape_schedule_tapeblock(tape_ccw_req_t* treq){
-        treq->wakeup = NULL;
-        tapeblock_schedule_exec_io((tape_dev_t*)(treq->tape_dev));;
-}
-#endif
-static void tape_wait_event(tape_ccw_req_t* treq){
-        wait_event (treq->wq,(treq->wakeup == NULL));
-}
-static void tape_wait_event_interruptible(tape_ccw_req_t* treq){
-        wait_event_interruptible(treq->wq,(treq->wakeup == NULL));
-       if (signal_pending (current)) {
-               treq->rc = tape_halt_io(treq->tape_dev);
-               if(treq->rc == -ERESTARTSYS)
-                       PRINT_INFO("IO stopped on irq %d\n",treq->tape_dev->devinfo.irq); /* FIXME: only put into dbf */
-                else if(treq->rc == 0)
-                       PRINT_INFO("could not stop IO,irq was faster on irq %d\n",treq->tape_dev->devinfo.irq); /* FIXME: only put into dbf */
-                else
-                       PRINT_WARN("IO error while stopping IO on irq %d\n",treq->tape_dev->devinfo.irq);
-       }
-}
-
-static void tape_wait_event_interruptible_nohaltio(tape_ccw_req_t* treq){
-       wait_event_interruptible(treq->wq,(treq->wakeup == NULL));
-}
-
-/*******************************************************************
- * DYNAMIC ATTACH/DETACH Functions
- *******************************************************************/
-
-static inline void
-tape_init_devregs(void)
-{
-        long lockflags;
-       write_lock_irqsave(&tape_dev_lock,lockflags);
-       memset(tape_devreg,0,sizeof(devreg_t*) * TAPE_MAX_DEVREGS);
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-}
-
-/*
- * Alloc a devreg for a devno
- */
-
-static inline devreg_t *
-tape_create_devno_devreg (int devno)
-{
-        devreg_t *devreg = kmalloc (sizeof (devreg_t), GFP_KERNEL);
-        if (devreg != NULL) {
-                memset (devreg, 0, sizeof (devreg_t));
-                devreg->ci.devno = devno;
-                devreg->flag = DEVREG_TYPE_DEVNO;
-                devreg->oper_func = tape_oper_handler;
-        }
-        return devreg;
-}
-
-/*
- * Alloc a devreg for a cu-type 
- */
-static inline devreg_t *
-tape_create_cu_devreg (int cu_type)
-{
-        devreg_t *devreg = kmalloc (sizeof (devreg_t), GFP_KERNEL);
-        if (devreg != NULL) {
-                memset (devreg, 0, sizeof (devreg_t));
-                devreg->ci.hc.ctype = cu_type;
-                devreg->flag = DEVREG_MATCH_CU_TYPE | DEVREG_TYPE_DEVCHARS;
-                devreg->oper_func = tape_oper_handler;
-        }
-        return devreg;
-}
-
-/*
- * Create devregs for device numbers from "from" to "to"
- */
-static inline void
-tape_create_devregs_range(int from, int to)
-{
-       int i;
-       long lockflags;
-       write_lock_irqsave(&tape_dev_lock,lockflags);
-       for (i=from;i<=to;i++) {
-               // register for attch/detach of a devno
-               if(tape_devregct >= TAPE_MAX_DEVREGS){
-                       PRINT_WARN ("Could not create devregs for devno range %04x - %04x.\n",i,to);
-                       PRINT_WARN ("These devices cannot be used. Use autoprobe\n");
-                       PRINT_WARN ("or specify device ranges more precisely!\n");
-                       break;
-               }
-               tape_devreg[tape_devregct]=tape_create_devno_devreg(i);
-               if (tape_devreg[tape_devregct]!=NULL) {
-                        s390_device_register (tape_devreg[tape_devregct++]);
-               } else {
-                       PRINT_WARN ("Could not create devreg for devno %04x, dyn. attach for this devno deactivated.\n",i);
-               }
-       }
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-        return;
-}
-
-/*
- * Create a devreg for a discipline
- */
-
-static inline void
-tape_create_devreg_for_disc(tape_discipline_t *disc)
-{
-       int devreg_nr;
-       long lockflags;
-       write_lock_irqsave(&tape_dev_lock,lockflags);
-       for(devreg_nr = 0; devreg_nr < TAPE_MAX_DEVREGS; devreg_nr++){
-               if(tape_devreg[devreg_nr] == NULL)
-                       break;
-       }
-       if(devreg_nr == TAPE_MAX_DEVREGS){
-               PRINT_WARN ("Could not create devreg for discipline (%x), dyn. attach for this discipline deactivated.\n",disc->cu_type);
-               goto out_unlock;
-       }
-       tape_devreg[devreg_nr] = tape_create_cu_devreg(disc->cu_type);
-       if (tape_devreg[devreg_nr] != NULL) {
-               s390_device_register(tape_devreg[devreg_nr]);
-       } else {
-               PRINT_WARN("Could not alloc devreg: Out of memory\n");
-               PRINT_WARN("Dynamic attach/detach will not work!\n");
-       }
-out_unlock:
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-       return;
-}
-
-/*
- * Free all devregs
- */ 
-
-static inline void
-tape_delete_all_devregs(void)
-{
-       int i;
-       long lockflags;
-
-       write_lock_irqsave(&tape_dev_lock,lockflags);
-
-       for(i = 0; i < TAPE_MAX_DEVREGS; i++){
-               if(tape_devreg[i]){
-                       s390_device_unregister(tape_devreg[i]);
-                       kfree(tape_devreg[i]);
-               }
-       }
-       memset(tape_devreg,0,sizeof(devreg_t*) * TAPE_MAX_DEVREGS);
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-}
-
-/*
- * Free Devregs for a discipline
- */
-
-static inline void
-tape_delete_devreg_for_disc(tape_discipline_t* disc)
-{
-       int i;
-       long lockflags;
-       write_lock_irqsave(&tape_dev_lock,lockflags);
-       for(i = 0; i < TAPE_MAX_DEVREGS; i++){
-               if(tape_devreg[i]){
-                       if(tape_devreg[i]->ci.hc.ctype == disc->cu_type){
-                               s390_device_unregister(tape_devreg[i]);
-                               kfree(tape_devreg[i]);
-                               tape_devreg[i] = NULL;
-                       }
-               }
-       }
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-}
-
-/*******************************************************************
- * Module/Kernel Parameter Handling
- *******************************************************************/
-
-#ifndef MODULE
-static char tape_parm_string[1024] __initdata = { 0, };
-
-/*
- * Get Kernel parameters (str) seperated by ","
- * and store them into the tape[] array
- */
-
-static void
-tape_split_parm_string (char *str)
-{
-       char *tmp = str;
-       int count = 0;
-       while (tmp != NULL && *tmp != '\0') {
-               char *end;
-               int len;
-               end = strchr (tmp, ',');
-               if (end == NULL) {
-                       len = strlen (tmp) + 1;
-               } else {
-                       len = (long) end - (long) tmp + 1;
-                       *end = '\0';
-                       end++;
-               }
-               tape[count] = kmalloc (len * sizeof (char), GFP_ATOMIC);
-               if (tape[count] == NULL) {
-                       printk (KERN_WARNING PRINTK_HEADER
-                               "can't store tape= parameter no %d\n",
-                               count + 1);
-                       break;
-               }
-               memcpy (tape[count], tmp, len * sizeof (char));
-               count++;
-               tmp = end;
-       };
-}
-
-/*
- * This function is called for each "tape=" Kernel parameter
- * at Kernel initialization. We need tape_parm_setup because of
- * 2.2 compatibility (At least I assume this :-))
- */
-void __init
-tape_parm_setup (char *str, int *ints)
-{
-       int len = strlen (tape_parm_string);
-       if (len != 0) {
-               strcat (tape_parm_string, ",");
-       }
-       strcat (tape_parm_string, str);
-}
-
-int __init
-tape_parm_call_setup (char *str)
-{
-       int dummy;
-       tape_parm_setup (str, &dummy);
-       return 1;
-}
-
-__setup("tape=", tape_parm_call_setup);
-#endif   /* not defined MODULE */
-
-
-/*
- * Convert string to int
- */
-
-static inline int
-tape_parm_strtoul (char *str, char **stra)
-{
-       char *temp = str;
-       int val;
-       if (*temp == '0') {
-               temp++;         /* strip leading zero */
-               if (*temp == 'x')
-                       temp++; /* strip leading x */
-       }
-       val = simple_strtoul (temp, &temp, 16); /* interpret anything as hex */
-       *stra = temp;
-       return val;
-}
-
-/*
- * Parse Kernel/Module Parameters and create devregs for dynamic attach/detach
- */ 
-
-static inline void
-tape_parm_parse (char **str)
-{
-       char *temp;
-       int from, to;
-       if (*str==NULL) {
-               /* no params present -> leave */
-               return;
-       }
-       while (*str) {
-               temp = *str;
-               from = 0;
-               to = 0;
-               from = tape_parm_strtoul (temp, &temp);
-               to = from;
-               if (*temp == '-') {
-                       temp++;
-                       to = tape_parm_strtoul (temp, &temp);
-               }
-               tape_create_devregs_range(from,to);
-               str++;
-       }
-}
-
-/*******************************************************************
- * Tape device (td) functions for create, free, enq, deq, enable,
- * disable, get and put
- *******************************************************************/
-
-/*
- * Enable Device
- */
-
-static inline int 
-tape_enable_device(tape_dev_t* td)
-{
-#ifdef CONFIG_DEVFS_FS
-       tape_frontend_t* frontend;
-#endif
-       int rc = 0;
-
-       if(td->discipline->setup_device(td) != 0){
-               rc = -ENOMEM;
-               goto out;
-       }
-
-       /* Register IRQ */
-
-#ifdef TAPE_CIO_PRIVATE_DATA
-       #ifdef CONFIG_S390_TAPE_DYNAMIC
-               rc = s390_request_irq_special (td->devinfo.irq, tape_do_irq,
-                       tape_noper_handler,0, TAPE_MAGIC, &(td->devstat));
-       #else
-               rc = s390_request_irq (td->devinfo.irq, tape_do_irq, 0, TAPE_MAGIC, &(td->devstat));
-       #endif
-#else
-       #ifdef CONFIG_S390_TAPE_DYNAMIC
-               rc = s390_request_irq_special (td->devinfo.irq, tape_do_irq,
-                       tape_noper_handler,0, (char*)td, &(td->devstat));
-       #else
-               rc = s390_request_irq (td->devinfo.irq, tape_do_irq, 0, (char*)td, &(td->devstat));
-       #endif
-#endif /* TAPE_CIO_PRIVATE_DATA */
-       if (rc){
-               PRINT_WARN ("Cannot register irq %d, rc=%d\n", td->devinfo.irq, rc);
-               td->discipline->cleanup_device(td);
-               goto out;
-       }
-       /* Create devfs entries */
-#ifdef CONFIG_DEVFS_FS
-       if (tape_mkdevfsroot(td)==NULL){
-               PRINT_WARN ("Cannot create a devfs directory for device %04x\n",td->devinfo.devno);
-               goto out_undo;
-       }
-               
-       for (frontend=tape_first_front;frontend!=NULL;frontend=frontend->next){
-               if(frontend->mkdevfstree(td) == NULL){
-                       goto out_undo;
-               }
-       }
-#endif
-#ifdef TAPE_CIO_PRIVATE_DATA
-       s390_set_private_data(td->devinfo.irq,td);
-#endif
-out:
-       return rc;
-out_undo:
-        tape_disable_device(td);
-        return -ENOMEM;        
-}
-
-/*
- * Disable Device
- */
-
-static inline void
-tape_disable_device(tape_dev_t* td)
-{
-#ifdef CONFIG_DEVFS_FS
-       tape_frontend_t* frontend;
-#endif
-       td->discipline->cleanup_device(td);
-#ifdef TAPE_CIO_PRIVATE_DATA 
-       s390_set_private_data(td->devinfo.irq,NULL);
-#else
-       ioinfo[td->devinfo.irq]->irq_desc.name = NULL;
-#endif
-
-       free_irq (td->devinfo.irq, &(td->devstat)); 
-#ifdef CONFIG_DEVFS_FS
-        for (frontend=tape_first_front;frontend!=NULL;frontend=frontend->next)
-                frontend->rmdevfstree(td);
-        tape_rmdevfsroot(td);
-#endif
-       tape_state_set(td,TS_NOT_OPER);
-}
-
-/*
- * Append Tape device (td) to our tape info list
- * Must be called with hold tape_dev_lock
- */
-static inline void
-tape_enq_device(tape_dev_t* td)
-{
-       tape_dev_t *temptd = NULL;
-       if (tape_first_dev == NULL) {
-               tape_first_dev = td;
-       } else {
-               temptd = tape_first_dev;
-               while (temptd->next != NULL)
-                       temptd = temptd->next;
-               temptd->next = td;
-       }
-}
-/*
- * Remove Tape device (td) from our tape info list
- * Must be called with hold tape_dev_lock
- */
-static inline void
-tape_deq_device(tape_dev_t* td)
-{
-       tape_dev_t* lasttd;
-       if (td==tape_first_dev) {
-               tape_first_dev=td->next;
-       } else {
-               lasttd=tape_first_dev;
-               while (lasttd->next!=td) lasttd=lasttd->next;
-               lasttd->next=td->next;
-       }
-}
-
-
-/*
- * Get Free minor number
- * Must be called with held tape_dev_lock
- */
-
-static inline int
-tape_get_new_minor(int devno)
-{
-       int i,tape_num = -1;
-       tape_dev_t* newtape;
-
-       if(!tape_autoprobe){
-               /* we have static device ranges, so fingure out the */
-               /* tape_num of the attached tape                    */
-               for (i=0;i<tape_devregct;i++){
-                       if (tape_devreg[i]->ci.devno==devno) {
-                               tape_num=TAPE_MINORS_PER_DEV*i;
-                               goto out;
-                       }
-               }
-       } else {
-               /* we are running in autoprobe mode, find a free */
-               /* tape_num */
-               i = 0;
-               newtape=tape_first_dev;
-               while (newtape!=NULL) {
-                       if (newtape->first_minor==i) {
-                               /* tape num in use. try next one */
-                               i+=TAPE_MINORS_PER_DEV;
-                               newtape=tape_first_dev;
-                       } else {
-                               /* tape num not used by newtape. look at next */
-                               /* tape info */
-                               newtape=newtape->next;
-                       }
-               }
-               if(i>255) /* No more minor available */
-                       tape_num = -1;
-               else
-                       tape_num = i;
-       }
-out:
-       return tape_num;
-}
-
-
-/*
- * Create device: Alloc, enable and enq device
- */
-
-static inline tape_dev_t*
-tape_create_device(int irq, int devno, tape_discipline_t* disc)
-{
-       int rc = 0;
-       int tape_num;
-       tape_dev_t *td;
-       long lockflags;
-
-       write_lock_irqsave(&tape_dev_lock,lockflags);
-
-       td = kmalloc (sizeof (tape_dev_t), GFP_ATOMIC);
-       if (td == NULL) {
-               tape_sprintf_exception (tape_dbf_area,2,"ti:no mem \n");
-               PRINT_INFO ("tape: can't allocate memory for "
-                       "tape info structure\n");
-               goto error;
-       }
-       memset(td,0,sizeof(tape_dev_t));
-        tape_num = tape_get_new_minor(devno);
-        if(tape_num == -1){
-                PRINT_WARN("tape: could not get minor for tape %x\n",devno);
-                goto error;
-        }
-       rc = get_dev_info_by_irq (irq, &(td->devinfo));
-       if (rc == -ENODEV) {    /* end of device list */
-               goto error;
-       }
-       td->discipline = disc;
-       atomic_set(&(td->use_count),1);
-       td->first_minor = tape_num;
-       td->medium_state = MS_UNKNOWN;
-       td->next = NULL;
-       td->discdata = td->treq = NULL;
-       tape_state_set (td, TS_INIT);
-       td->discdata=NULL;
-       td->last_op = TO_NOTHING;
-
-       if(td->discipline->setup_device(td) != 0)
-               goto error;
-       if(tape_enable_device(td) !=0)  
-               goto error;
-       tape_enq_device(td);
-       PRINT_INFO ("using devno %04x with discipline %04x on irq %d as tape device %d\n",devno,disc->cu_type,irq,tape_num/2);
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-       return td;
-error:
-       tape_sprintf_event (tape_dbf_area,3,"tsetup err: %x\n",rc);
-       if(td)
-               kfree (td);
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-       return NULL;
-}
-
-/*
- * Free Device storage
- */
-
-static void
-tape_free_device(tape_dev_t* td)
-{
-        if (TAPE_BUSY(td)) 
-               BUG(); /* one should _not_ free the device when a request is pending */
-       tape_sprintf_event (tape_dbf_area,6,"free irq: %x\n",td->devinfo.irq);
-        kfree(td);
-}
-
-/*
- * Decrement use count of tape structure
- * if use count == 0 tape structure is freed
- */
-inline void
-tape_put_device(tape_dev_t* td)
-{
-       if (td==NULL)
-               BUG();
-       if(atomic_dec_and_test(&(td->use_count)))
-               tape_free_device(td);
-}
-
-/*
- * Find the tape_dev_t structure associated with member
- * and increase use count:
- *
- * member:    TAPE_MEMB_IRQ, TAPE_MEMB_MINOR
- */
-
-tape_dev_t *
-__tape_get_device_by_member(unsigned long value, int member)
-{
-       tape_dev_t *td = NULL;
-       long lockflags;
-       read_lock_irqsave(&tape_dev_lock,lockflags);
-       td = tape_first_dev;
-       while(td != NULL) {
-               switch(member){
-                       case TAPE_MEMB_IRQ:
-                               if(td->devinfo.irq == value)
-                                       goto out;
-                               break;
-                       case TAPE_MEMB_MINOR:
-                               if((value >= td->first_minor)  && 
-                                   (value < (td->first_minor + TAPE_MINORS_PER_DEV)) )
-                                       goto out;
-                               break;
-                       case TAPE_MEMB_QUEUE:
-                               if(((unsigned long)(&td->blk_data.request_queue)) == value)
-                                       goto out;
-                               break;
-                       default:
-                               BUG();
-               }
-               td = td->next;
-       }
-out:
-       if(td) // found!
-               atomic_inc(&(td->use_count));
-       read_unlock_irqrestore(&tape_dev_lock,lockflags);
-       return td;
-}
-
-/*
- * Scan all irqs an create tape devices for all matching cu types
- */
-
-static inline void
-tape_create_devs_for_disc(tape_discipline_t* disc)
-{
-       int irq,i;
-       tape_dev_t* td = NULL;
-       s390_dev_info_t dinfo;
-
-       for (irq = get_irq_first(); irq!=-ENODEV; irq=get_irq_next(irq)) {
-               if(get_dev_info_by_irq (irq, &dinfo) == -ENODEV)
-                       continue;
-               if(disc->cu_type != dinfo.sid_data.cu_type)
-                       /* Wrong type - try next one */
-                       continue;
-
-               tape_sprintf_event (tape_dbf_area,3,"det irq:  %x\n",irq);
-               tape_sprintf_event (tape_dbf_area,3,"cu     :  %x\n",disc->cu_type);
-
-
-               if(!tape_autoprobe) {
-                       for( i=0; i<tape_devregct; i++ ) {
-                               if(tape_devreg[i]->ci.devno == dinfo.devno) {
-                                       td = tape_create_device(irq, dinfo.devno, disc);
-                                       if(!td) {
-                                               PRINT_WARN( "Could not initialize tape 0x%x\n",dinfo.devno);
-                                               continue;
-                                       }
-                                       if(disc->init_device)
-                                               disc->init_device(td); /* XXX */
-                                       tape_state_set (td, TS_UNUSED);
-                                       break;
-                               }
-                       }
-               }
-               else {
-                       td = tape_create_device(irq,dinfo.devno,disc);
-                 
-                       if(!td){
-                               PRINT_WARN( "Could not initialize tape 0x%x\n",dinfo.devno);
-                               continue;
-                       }
-                       if(disc->init_device)
-                               disc->init_device(td); /* XXX */
-                       tape_state_set (td, TS_UNUSED); 
-               }
-       }
-}
-
-/*
- * Go through our tape info list and disable, deq and free all devices with 
- * matching cu type
- */
-
-static inline void
-tape_delete_devs_for_disc(tape_discipline_t* disc)
-{
-       tape_dev_t *td;
-       long lockflags;
-
-       write_lock_irqsave(&tape_dev_lock,lockflags);
-       td = tape_first_dev;
-       while (td !=NULL){
-               if(td->discipline == disc){
-                       tape_deq_device(td);
-                       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-                       tape_disable_device(td);
-                       tape_put_device(td);
-                       write_lock_irqsave(&tape_dev_lock,lockflags);
-                       td = tape_first_dev;
-               } else {
-                       td=td->next;
-               }
-       }
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-}
-               
-/*******************************************************************
- * TAPE Request and IO Functions
- *******************************************************************/
-
-/*
- * Allocate a new tape ccw request
- */
-
-inline tape_ccw_req_t *
-tape_alloc_ccw_req (int cplength, int datasize,int idal_buf_size, tape_op_t operation)
-{
-       tape_ccw_req_t* treq;
-       int kmalloc_flags;
-       if(in_interrupt())
-               kmalloc_flags = GFP_ATOMIC;
-       else
-               kmalloc_flags = GFP_KERNEL;
-
-       treq = (tape_ccw_req_t*) kmalloc(sizeof(tape_ccw_req_t),kmalloc_flags);
-       if(!treq)
-               goto error;
-       memset(treq,0,sizeof(tape_ccw_req_t));
-       treq->kernbuf_size = datasize;
-       treq->userbuf_size = datasize;
-       treq->op           = operation;
-       treq->cplength     = cplength;
-       init_waitqueue_head (&treq->wq); 
-
-       // alloc small kernel buffer
-
-       if(datasize > PAGE_SIZE)
-               BUG();
-       if(datasize > 0){
-               // the kernbuf must be below 2GB --> GFP_DMA
-               treq->kernbuf = kmalloc(datasize,kmalloc_flags | GFP_DMA); 
-               if(!treq->kernbuf)
-                       goto error;
-               memset(treq->kernbuf, 0, datasize);
-       }
-
-       // alloc idal kernel buffer
-
-       if(idal_buf_size > 0){
-               treq->idal_buf = idalbuf_alloc(idal_buf_size);
-               if(!treq->idal_buf)
-                       goto error;
-       }
-               
-       if(cplength < 0)
-               BUG();
-
-       // the channel program must be below 2GB --> GFP_DMA
-       treq->cpaddr = kmalloc(cplength * sizeof(ccw1_t), kmalloc_flags | GFP_DMA);
-       if(!treq->cpaddr)
-               goto error;
-       memset(treq->cpaddr, 0, cplength*sizeof(ccw1_t));
-       return treq;
-error:
-       tape_sprintf_exception (tape_dbf_area,1,"cqra nomem\n");
-       if(treq)
-               tape_free_ccw_req(treq);
-       return NULL;
-}
-
-/*
- * Free tape ccw request
- */
-
-void
-tape_free_ccw_req (tape_ccw_req_t * treq)
-{
-       if(!treq)
-                BUG();
-       if(treq->cpaddr)
-               kfree(treq->cpaddr);
-       if(treq->kernbuf)
-               kfree(treq->kernbuf);
-       if(treq->idal_buf)
-               idalbuf_free(treq->idal_buf);
-       kfree(treq);
-}
-
-/*
- * Add request to request queue (At the moment queue length = 1)
- */
-
-static inline int
-tape_add_ccw_req(tape_dev_t* td,tape_ccw_req_t* treq)
-{
-       if(td->treq)
-               return -1;
-       td->treq = treq;
-       treq->tape_dev = td;
-       return 0;
-}
-
-/*
- * Remove request from request queue (At the moment queue length = 1)
- */
-
-int
-tape_remove_ccw_req(tape_dev_t* td,tape_ccw_req_t* treq)
-{
-       if(treq != td->treq)
-               BUG();
-       td->last_op = treq->op;
-        td->treq=NULL;
-       treq->tape_dev=NULL;
-        return 0;
-}
-
-/*
- * Get the active ccw request
- */
-
-tape_ccw_req_t*
-tape_get_active_ccw_req(tape_dev_t* td)
-{
-       return td->treq;
-}
-
-/*
- * Stop the active ccw request
- */
-
-static inline int
-tape_halt_io(tape_dev_t* td)
-{
-       int retries = 0;
-       int irq = td->devinfo.irq;
-       int rc = 0;
-       long lockflags;
-       tape_ccw_req_t* treq;
-
-       s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-       treq = tape_get_active_ccw_req(td);
-       /* check if interrupt has already been processed */
-       if(!treq)
-               goto out;
-       if(treq->wakeup == NULL)
-               goto out;
-       while (retries < 5){
-               if ( retries < 2 )
-                       rc = halt_IO(irq, (long)treq, treq->options);
-               else
-                       rc = clear_IO(irq, (long)treq, treq->options);
-               switch (rc) {
-               case 0:         /* termination successful */
-                       rc = -ERESTARTSYS;
-                       goto out;
-               case -ENODEV:
-                       PRINT_INFO ("device gone, retry\n"); /* FIXME: s390dbf only */
-                       break;
-               case -EIO:
-                       PRINT_INFO ("I/O error, retry\n"); /* FIXME: s390dbf only */
-                       break;
-               case -EBUSY:
-                       PRINT_INFO ( "device busy, retry later\n"); /* FIXME: s390dbf only */
-                       break;
-               default:
-                       PRINT_ERR ( "line %d unknown RC=%d, please report"
-                                   " to linux390@de.ibm.com\n", __LINE__, rc);
-                       BUG ();
-               }
-               retries ++;
-       }
-out:
-       s390irq_spin_unlock_irqrestore(td->devinfo.irq, lockflags);
-       return rc;
-}
-
-
-/*
- * The tape IO function:
- * tape_do_io MUST be called with locked td lock!
- */
-static inline int
-__tape_do_io(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type,int io)
-{
-       int rc = 0;
-        if ((td==NULL) || (treq==NULL)) 
-                BUG();
-
-       if(tape_state_get(td) == TS_NOT_OPER){
-               rc = -ENODEV;
-               goto out;
-       }
-       if(TAPE_BUSY(td)){
-               tape_sprintf_event (tape_dbf_area,1,"tape: IRQ - Tape busy\n"); 
-               rc = -EBUSY;
-               goto out;
-       }
-       tape_add_ccw_req(td,treq);
-       switch(type){
-               case TAPE_REMOVE_REQ_ON_WAKEUP:
-                       treq->wakeup = tape_wake_up_remove;
-                       break;
-               case TAPE_NO_WAIT: 
-                       // needed for retry
-                       break; 
-               case TAPE_WAIT:
-                       treq->wakeup = tape_wake_up;
-                       treq->wait   = tape_wait_event;
-                       break;
-               case TAPE_WAIT_INTERRUPTIBLE:
-                       treq->wakeup = tape_wake_up_interruptible;
-                       treq->wait   = tape_wait_event_interruptible;
-                       break;
-               case TAPE_WAIT_INTERRUPTIBLE_NOHALTIO:
-                       // neded for dummy load 
-                       treq->wakeup = tape_wake_up_interruptible;
-                       treq->wait   = tape_wait_event_interruptible_nohaltio;
-                       break;
-#ifdef CONFIG_S390_TAPE_BLOCK
-               case TAPE_SCHED_BLOCK:
-                       treq->wakeup = tape_schedule_tapeblock;
-                       treq->wait   = NULL;
-                       break;
-#endif
-               default:
-                        BUG();
-       }
-       if(io)
-               rc = do_IO(td->devinfo.irq,treq->cpaddr,
-               (unsigned long)treq, 0x00, treq->options);
-       if(rc) {
-               tape_sprintf_event (tape_dbf_area,1,"tape: DOIO failed with er = %i\n",rc);
-               treq->wakeup = NULL;
-               treq->wait   = NULL; /*XXX ??*/
-               tape_remove_ccw_req(td,treq);
-       }
-out:
-       return rc;
-}
-
-/*
- * Do the io request and wait for it
- */
-
-int
-tape_do_io_and_wait(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type)
-{
-       int rc = 0;
-       long lockflags;
-        if (td==NULL) 
-                BUG();
-       s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-       rc = __tape_do_io(td,treq,type,TAPE_DO_IO);
-       s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
-       if(rc == 0)
-               tape_wait(treq);
-       return rc;
-}
-
-/*
- * Needed for MTLOAD: Just create a wait request without doing io
- */
-
-int
-tape_do_wait_req(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type)
-{
-       int rc = 0;
-       long lockflags;
-        if (td==NULL)
-                BUG();
-       s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-       rc = __tape_do_io(td,treq,type,TAPE_NO_IO);
-       s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
-       tape_wait(treq);
-       return rc;
-}
-
-/*
- * Just do the io
- */
-
-int
-tape_do_io(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type)
-{
-       int rc = 0;
-       long lockflags;
-       s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-       rc = __tape_do_io(td,treq,type,TAPE_DO_IO);
-       s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
-       return rc;
-}
-
-/*
- * Just do the io, but we are already locked here (in irq)
- */
-
-int
-tape_do_io_irq(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type)
-{
-        return __tape_do_io(td,treq,type,TAPE_DO_IO);
-}
-
-/*
- * Wait for an io request
- */
-
-static void
-tape_wait(tape_ccw_req_t* treq)
-{
-       tape_dev_t* td;
-       if(treq==NULL)
-                BUG();
-       td = treq->tape_dev;
-        if (td==NULL)
-                BUG();       
-       if(treq->wait==NULL)
-                BUG();
-        treq->wait(treq);
-       tape_remove_ccw_req(td,treq);
-}
-
-/*
- * Tape interrupt routine, called from Ingo's I/O layer
- */
-
-static void
-tape_do_irq (int irq, void *int_parm, struct pt_regs *regs)
-{
-       tape_dev_t *td;
-#ifdef TAPE_CIO_PRIVATE_DATA
-       td = (tape_dev_t*)s390_get_private_data(irq);
-#else
-       td = (tape_dev_t*)ioinfo[irq]->irq_desc.name;
-#endif
-       if(!td) {
-               PRINT_ERR ("tape: could not get device structure for irq %d in interrupt\n",irq);
-               goto out;
-       }
-       if(td->devstat.dstat != 0x0c){
-               tape_sprintf_event (tape_dbf_area,3,"-- Tape Interrupthandler --\n");
-               tape_dump_sense_dbf(td);
-       }
-       if (tape_state_get(td) == TS_NOT_OPER) {
-               tape_sprintf_event (tape_dbf_area,6,"tape:device is not operational\n");
-               goto out;
-       }
-       td->discipline->irq(td);
-out:
-       return;
-}
-
-/*
- * Oper Handler is called from Ingo's I/O layer when a new tape device is 
- * attached. We create a new devinfo for the new device, enable and enq it.
- */
-
-static int 
-tape_oper_handler ( int irq, struct _devreg *dreg) {
-       tape_dev_t* td=tape_first_dev;
-       int rc=0;
-       s390_dev_info_t dinfo;
-       tape_discipline_t* disc;
-       long lockflags;
-
-       td = tape_get_device_by_irq(irq);
-       if (td!=NULL) {
-               // irq is (still) used by tape. tell ingo to try again later
-               PRINT_ERR ("tape:Oper handler for irq %d called, but irq is still (internally) used.\n",irq);
-               rc = -EAGAIN;
-               goto out;
-       }
-
-       rc = get_dev_info_by_irq (irq, &dinfo);
-       if (rc == -ENODEV) {
-                PRINT_ERR ("tape: Cannot get dev info for irq %d in the oper handler.\n",irq);
-                rc = -EAGAIN;
-                goto out;
-       }
-
-       read_lock_irqsave(&tape_discipline_lock,lockflags);
-
-       disc = tape_first_disc;
-       while ((disc != NULL) && (disc->cu_type != dinfo.sid_data.cu_type))
-               disc = (tape_discipline_t *) (disc->next);
-
-       if (disc == NULL){
-               PRINT_WARN ("tape: No matching discipline for cu_type %x found in the oper handler, ignoring device %04x.\n",dinfo.sid_data.cu_type,dinfo.devno);
-               rc = -ENODEV;
-               goto out_unlock;
-       }
-
-       /* Allocate tape structure  */
-       td = tape_create_device(irq,dinfo.devno,disc);
-
-       if (td == NULL) {
-               PRINT_WARN( "Could not initialize tape 0x%x\n",dinfo.devno);
-               rc = -ENOBUFS;
-               goto out_unlock;
-       } else {
-               if(disc->init_device)
-                       disc->init_device(td);
-       }
-       tape_state_set (td, TS_UNUSED); 
-out_unlock:
-        read_unlock_irqrestore(&tape_discipline_lock,lockflags);
-out:
-       return rc;
-}
-
-/*
- * Not Oper Handler is called from Ingo's IO layer, when a tape device
- * is detached. We deq, disable and free the tape info for this device
- */
-
-static void
-tape_noper_handler ( int irq, int status ) {
-       tape_dev_t *td;
-       long lockflags;
-       tape_ccw_req_t *treq;
-
-       td = tape_get_device_by_irq(irq);
-       if (td==NULL) {
-                PRINT_ERR("tape: not operational handler called for irq %x, but tape does not hold this irq.\n",irq);
-                goto error;
-        }
-
-       write_lock_irqsave(&tape_dev_lock,lockflags);
-       tape_deq_device(td);
-       write_unlock_irqrestore(&tape_dev_lock,lockflags);
-
-       tape_disable_device(td);
-
-       s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-       treq = tape_get_active_ccw_req(td);
-       if (treq) {
-               // device is in use!
-                treq->rc= -ENODEV;
-               if(treq->wakeup)
-                       treq->wakeup (treq);
-               PRINT_WARN ("Tape #%d is detached while it was busy.\n",td->first_minor/TAPE_MINORS_PER_DEV);
-       } else {
-               // device is unused!
-               PRINT_WARN ("Tape #%d is detached now.\n",td->first_minor/TAPE_MINORS_PER_DEV);
-       }
-
-       s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);    
-
-       /* decrement use count twice ! */       
-       tape_put_device(td);
-       tape_put_device(td);
-error:
-       return;
-}
-
-/*
- * Write sense data to dbf
- */
-
-void tape_dump_sense_dbf(tape_dev_t* td)
-{
-       devstat_t *stat = &td->devstat;
-       const char* op;
-       if(TAPE_BUSY(td))
-               op = tape_op_verbose[tape_get_active_ccw_req(td)->op];
-       else
-               op = "---";
-       tape_sprintf_event (tape_dbf_area,3,"DSTAT : %02x   CSTAT: %02x\n",stat->dstat,stat->cstat);
-       tape_sprintf_event (tape_dbf_area,3,"DEVICE: %04x OP   : %s\n",td->devinfo.devno,op);
-       tape_sprintf_event (tape_dbf_area,3,"%08x %08x\n",*((unsigned int*)&stat->ii.sense.data[0]),*((unsigned int*)&stat->ii.sense.data[4]));
-       tape_sprintf_event (tape_dbf_area,3,"%08x %08x\n",*((unsigned int*)&stat->ii.sense.data[8]),*((unsigned int*)&stat->ii.sense.data[12]));
-       tape_sprintf_event (tape_dbf_area,3,"%08x %08x\n",*((unsigned int*)&stat->ii.sense.data[16]),*((unsigned int*)&stat->ii.sense.data[20]));
-       tape_sprintf_event (tape_dbf_area,3,"%08x %08x\n",*((unsigned int*)&stat->ii.sense.data[24]),*((unsigned int*)&stat->ii.sense.data[28]));
-}
-
-/*
- * Write sense data to console/dbf
- */
-
-void
-tape_dump_sense (tape_dev_t* td)
-{
-       devstat_t *stat = &td->devstat;
-#if 1 /* XXX */
-       PRINT_INFO ("-------------------------------------------------\n");
-       PRINT_INFO ("DSTAT : %02x  CSTAT: %02x  CPA: %04x\n",stat->dstat,stat->cstat,stat->cpa);
-       PRINT_INFO ("DEVICE: %04x\n",td->devinfo.devno);
-       if(TAPE_BUSY(td))
-               PRINT_INFO("OP    : %s\n",tape_op_verbose[tape_get_active_ccw_req(td)->op]);
-               
-       PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
-                   " %02X%02X%02X%02X %02X%02X%02X%02X \n",
-                   stat->ii.sense.data[0], stat->ii.sense.data[1],
-                   stat->ii.sense.data[2], stat->ii.sense.data[3],
-                   stat->ii.sense.data[4], stat->ii.sense.data[5],
-                   stat->ii.sense.data[6], stat->ii.sense.data[7],
-                   stat->ii.sense.data[8], stat->ii.sense.data[9],
-                   stat->ii.sense.data[10], stat->ii.sense.data[11],
-                   stat->ii.sense.data[12], stat->ii.sense.data[13],
-                   stat->ii.sense.data[14], stat->ii.sense.data[15]);
-       PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
-                   " %02X%02X%02X%02X %02X%02X%02X%02X \n",
-                   stat->ii.sense.data[16], stat->ii.sense.data[17],
-                   stat->ii.sense.data[18], stat->ii.sense.data[19],
-                   stat->ii.sense.data[20], stat->ii.sense.data[21],
-                   stat->ii.sense.data[22], stat->ii.sense.data[23],
-                   stat->ii.sense.data[24], stat->ii.sense.data[25],
-                   stat->ii.sense.data[26], stat->ii.sense.data[27],
-                   stat->ii.sense.data[28], stat->ii.sense.data[29],
-                   stat->ii.sense.data[30], stat->ii.sense.data[31]);
-       PRINT_INFO ("--------------------------------------------------\n");
-#endif
-}
-
-/*******************************************************************
- * TAPE Discipline functions
- *******************************************************************/
-
-/*
- * Register backend discipline
- */
-
-int
-tape_register_discipline(tape_discipline_t *disc)
-{
-        tape_discipline_t *disc_ptr;
-       long lockflags;
-
-        disc->next = NULL;
-
-       write_lock_irqsave(&tape_discipline_lock,lockflags);
-
-        if (tape_first_disc == NULL) {
-            tape_first_disc = disc;
-        } else {
-                for(disc_ptr = tape_first_disc; disc_ptr->next!=NULL; disc_ptr=(tape_discipline_t*)disc_ptr->next);
-                disc_ptr->next = disc;
-        }
-
-       tape_create_devs_for_disc(disc);
-       if(tape_autoprobe)
-               tape_create_devreg_for_disc(disc);
-
-       write_unlock_irqrestore(&tape_discipline_lock,lockflags);
-        return 0;
-}
-
-/*
- * Unregister backend discipline
- */
-
-void 
-tape_unregister_discipline(tape_discipline_t* disc)
-{
-       tape_discipline_t* lastdisc;
-       long lockflags;
-
-       write_lock_irqsave(&tape_discipline_lock,lockflags);
-
-       tape_delete_devs_for_disc(disc);
-       if(tape_autoprobe)
-               tape_delete_devreg_for_disc(disc);
-
-       if (disc==tape_first_disc) {
-               tape_first_disc=disc->next;
-        } else {
-               lastdisc=tape_first_disc;
-               while (lastdisc->next!=disc) lastdisc=lastdisc->next;
-               lastdisc->next=disc->next;
-       }
-       
-       disc->shutdown();
-
-       write_unlock_irqrestore(&tape_discipline_lock,lockflags);
-}
-
-/*
- * Cleanup all registered disciplines
- */
-
-static inline void
-tape_cleanup_disciplines (void) 
-{
-        long lockflags;
-        tape_discipline_t* disc;
-       /* Unregister all backend disciplines - this also deletes the devices */
-
-       write_lock_irqsave(&tape_discipline_lock,lockflags);
-        disc=tape_first_disc;
-        while (disc != NULL) {
-               write_unlock_irqrestore(&tape_discipline_lock,lockflags);
-               tape_unregister_discipline(disc);
-               kfree(disc);
-               write_lock_irqsave(&tape_discipline_lock,lockflags);
-               disc=tape_first_disc; 
-        }
-       write_unlock_irqrestore(&tape_discipline_lock,lockflags);
-}
-
-
-/*******************************************************************
- * TAPE Init Functions
- *******************************************************************/
-
-/*
- *      tape_print_banner will be called on initialisation and print a nice banner
- */
-
-static inline void 
-tape_print_banner (void) 
-{
-        char *opt_char,*opt_block;
-
-        /* print banner */        
-        PRINT_WARN ("IBM zSeries Tape Device Driver (v%d.%02d).\n",TAPE_VERSION_MAJOR,TAPE_VERSION_MINOR);
-        PRINT_WARN ("(C) IBM Deutschland Entwicklung GmbH, 2000 - 2001\n");
-        opt_char=opt_block="not present";
-#ifdef CONFIG_S390_TAPE_CHAR
-        opt_char="built in";
-#endif
-#ifdef CONFIG_S390_TAPE_BLOCK
-        opt_block="built in";
-#endif
-        /* print feature info */
-        PRINT_WARN ("character device frontend   : %s\n",opt_char);
-        PRINT_WARN ("block device frontend       : %s\n",opt_block);
-}
-
-/*
- *      tape_init will register the driver for each tape.
- */
-
-int
-tape_init (void)
-{
-        static int initialized=0;
-
-        if (initialized) // Only init the devices once
-            return 0;
-        initialized=1;
-
-       tape_init_devregs();
-#ifdef TAPE_DEBUG
-        tape_dbf_area = debug_register ( "tape", 2, 2, 3*sizeof(long));
-        debug_register_view(tape_dbf_area,&debug_sprintf_view);
-        tape_sprintf_event (tape_dbf_area,3,"begin init\n");
-#endif /* TAPE_DEBUG */
-       tape_print_banner();
-#ifndef MODULE
-        tape_split_parm_string(tape_parm_string);
-#endif
-#ifdef CONFIG_DEVFS_FS
-        devfs_mk_dir (NULL, "tape", NULL);
-#endif /* CONFIG_DEVFS_FS */
-
-        tape_sprintf_event (tape_dbf_area,3,"dev detect\n");
-       /* Allocate the tape structures */
-        if (*tape!=NULL) { /* if parameters are present */
-               PRINT_INFO ("Using ranges supplied in parameters, disabling autoprobe mode.\n");
-               tape_parm_parse (tape);
-               tape_autoprobe = 0;
-       } else {
-               PRINT_INFO ("No parameters supplied, enabling autoprobe mode for all supported devices.\n");
-               tape_autoprobe = 1;
-       }
-#ifdef CONFIG_PROC_FS
-       tape_proc_init();
-#endif /* CONFIG_PROC_FS */
-#ifdef  CONFIG_S390_TAPE_3480 
-       tape_register_discipline(tape3480_init());
-#else
-#ifndef CONFIG_S390_TAPE
-       tape_request_module("tape_3480_mod");
-#endif
-#endif /* CONFIG_S390_TAPE_3480 */
-
-#ifdef CONFIG_S390_TAPE_3490
-        tape_register_discipline(tape3490_init());
-#else
-#ifndef CONFIG_S390_TAPE
-        tape_request_module("tape_3490_mod");
-#endif
-#endif /* CONFIG_S390_TAPE_3490 */
-
-#ifdef CONFIG_S390_TAPE_3590
-        tape_register_discipline(tape3590_init());
-#else
-#ifndef CONFIG_S390_TAPE
-        tape_request_module("tape_3590_mod");
-#endif
-#endif /* CONFIG_S390_TAPE_3590 */
-       return 0;
-}
-
-/*******************************************************************
- * TAPE Module functions
- *******************************************************************/
-
-#ifdef MODULE
-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");
-MODULE_PARM (tape, "1-" __MODULE_STRING (256) "s");
-
-/*
- * The famous init_module
- */
-
-int
-init_module (void)
-{
-#ifdef CONFIG_S390_TAPE_CHAR
-       tapechar_init ();
-#endif
-#ifdef CONFIG_S390_TAPE_BLOCK
-       tapeblock_init ();
-#endif
-        return 0;
-}
-
-/*
- * Cleanup the frontends
- */
-static inline void
-tape_cleanup_frontends(void) 
-{
-        tape_frontend_t* frontend, *tempfe;
-
-       /* Now get rid of the frontends */
-#ifdef CONFIG_S390_TAPE_CHAR
-       tapechar_uninit();
-#endif
-#ifdef CONFIG_S390_TAPE_BLOCK
-        tapeblock_uninit();
-#endif
-        frontend=tape_first_front;
-       while (frontend != NULL) {
-               tempfe = frontend;
-               frontend = frontend->next;
-               kfree (tempfe);
-       }
-}
-
-
-/*
- * Cleanup module
- */
-
-void
-cleanup_module (void)
-{
-        tape_sprintf_event (tape_dbf_area,6,"cleaup mod");
-       tape_cleanup_disciplines();
-#ifdef CONFIG_DEVFS_FS
-       devfs_remove("tape"); /* devfs checks for NULL */
-#endif CONFIG_DEVFS_FS
-#ifdef CONFIG_PROC_FS
-       tape_proc_cleanup();
-#endif 
-       tape_cleanup_frontends();
-       /* Deallocate devregs in case of not autoprobe */
-       if(!tape_autoprobe)
-               tape_delete_all_devregs();
-#ifdef TAPE_DEBUG
-        debug_unregister (tape_dbf_area);
-#endif /* TAPE_DEBUG */
-}
-#endif                         /* MODULE */
-
-
-/*******************************************************************
- * TAPE Tapestate functions
- *******************************************************************/
-
-inline void
-tape_state_set (tape_dev_t * td, tape_state_t newstate)
-{
-    if (td->tape_state == TS_NOT_OPER) {
-        tape_sprintf_event(tape_dbf_area,3,"ts_set err: not oper\n");
-    } else {
-        tape_sprintf_event(tape_dbf_area,4,"ts. dev:  %x\n",td->first_minor);
-        tape_sprintf_event(tape_dbf_area,4,"old ts:   %s\n",(((tape_state_get (td) < TO_SIZE) && (tape_state_get (td) >=0 )) ?  tape_state_verbose[tape_state_get (td)] : "UNKNOWN TS"));
-        tape_sprintf_event(tape_dbf_area,4,"%s\n", 
-                       (((tape_state_get (td) < TO_SIZE) &&
-                       (tape_state_get (td) >=0 )) ?
-                       tape_state_verbose[tape_state_get (td)] :
-                       "UNKNOWN TS"));
-        tape_sprintf_event (tape_dbf_area,4,"new ts:   \n");
-        tape_sprintf_event (tape_dbf_area,4,"%s\n",(((newstate < TO_SIZE) &&
-                                              (newstate >= 0)) ?
-                                             tape_state_verbose[newstate] :
-                                             "UNKNOWN TS"));
-       td->tape_state = newstate;
-    }
-}
-
-inline tape_state_t
-tape_state_get (tape_dev_t * td)
-{
-       return (td->tape_state);
-}
-
-inline void
-tape_med_state_set(tape_dev_t * td, tape_medium_state_t newstate)
-{
-       if(td->medium_state == newstate)
-               goto out;
-       switch(newstate){
-               case MS_UNLOADED:
-                       PRINT_INFO("(%x): Tape is unloaded\n",td->devstat.devno);
-                       break;
-               case MS_LOADED:
-                       PRINT_INFO("(%x): Tape has been mounted\n",td->devstat.devno);
-                       break;
-               default:
-                       // print nothing
-                       break;
-       }
-       td->medium_state = newstate;
-out:
-       return;
-}
-       
-
-/*******************************************************************
- * TAPE Exported Functions 
- *******************************************************************/
-
-EXPORT_SYMBOL(tape_register_discipline);
-EXPORT_SYMBOL(tape_unregister_discipline);
-EXPORT_SYMBOL(tape_dbf_area);
-EXPORT_SYMBOL(tape_alloc_ccw_req);
-EXPORT_SYMBOL(tape_free_ccw_req); 
-EXPORT_SYMBOL(tape_state_set);
-EXPORT_SYMBOL(tape_state_get);
-EXPORT_SYMBOL(tape_med_state_set);
-EXPORT_SYMBOL(tape_state_verbose);
-EXPORT_SYMBOL(tape_op_verbose);
-EXPORT_SYMBOL(tape_dump_sense);
-EXPORT_SYMBOL(tape_dump_sense_dbf);
-EXPORT_SYMBOL(tape_do_io);
-EXPORT_SYMBOL(tape_do_io_irq);
-EXPORT_SYMBOL(tape_do_io_and_wait);
-EXPORT_SYMBOL(tape_remove_ccw_req);
-EXPORT_SYMBOL(tape_get_active_ccw_req);