]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/tape: Remove support for 3590/3592 models
authorJan Höppner <hoeppner@linux.ibm.com>
Mon, 2 Feb 2026 13:48:39 +0000 (14:48 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Wed, 4 Feb 2026 07:31:29 +0000 (08:31 +0100)
Physical 3590/3592 tape models are not supported anymore for a very long
time. The Virtual Tape Server (VTS) emulates and presents only 3490E
models to the host. This is the only supported model and storage server.

Remove the entire code base for 3590/3592 models as it can be considered
dead code for quite some time already.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/include/uapi/asm/tape390.h
drivers/s390/char/Kconfig
drivers/s390/char/Makefile
drivers/s390/char/tape.h
drivers/s390/char/tape_3590.c [deleted file]
drivers/s390/char/tape_3590.h [deleted file]
drivers/s390/char/tape_core.c
drivers/s390/char/tape_std.h

index 90266c6964868533ea88f3895566cd7e0f9b83ed..880065cfa0393a238742a0ab80bc05183b159fa1 100644 (file)
@@ -36,68 +36,4 @@ typedef struct display_struct {
         char message2[8];
 } display_struct;
 
-/*
- * Tape encryption support
- */
-
-struct tape390_crypt_info {
-       char capability;
-       char status;
-       char medium_status;
-} __attribute__ ((packed));
-
-
-/* Macros for "capable" field */
-#define TAPE390_CRYPT_SUPPORTED_MASK 0x01
-#define TAPE390_CRYPT_SUPPORTED(x) \
-       ((x.capability & TAPE390_CRYPT_SUPPORTED_MASK))
-
-/* Macros for "status" field */
-#define TAPE390_CRYPT_ON_MASK 0x01
-#define TAPE390_CRYPT_ON(x) (((x.status) & TAPE390_CRYPT_ON_MASK))
-
-/* Macros for "medium status" field */
-#define TAPE390_MEDIUM_LOADED_MASK 0x01
-#define TAPE390_MEDIUM_ENCRYPTED_MASK 0x02
-#define TAPE390_MEDIUM_ENCRYPTED(x) \
-       (((x.medium_status) & TAPE390_MEDIUM_ENCRYPTED_MASK))
-#define TAPE390_MEDIUM_LOADED(x) \
-       (((x.medium_status) & TAPE390_MEDIUM_LOADED_MASK))
-
-/*
- * The TAPE390_CRYPT_SET ioctl is used to switch on/off encryption.
- * The "encryption_capable" and "tape_status" fields are ignored for this ioctl!
- */
-#define TAPE390_CRYPT_SET _IOW('d', 2, struct tape390_crypt_info)
-
-/*
- * The TAPE390_CRYPT_QUERY ioctl is used to query the encryption state.
- */
-#define TAPE390_CRYPT_QUERY _IOR('d', 3, struct tape390_crypt_info)
-
-/* Values for "kekl1/2_type" and "kekl1/2_type_on_tape" fields */
-#define TAPE390_KEKL_TYPE_NONE 0
-#define TAPE390_KEKL_TYPE_LABEL 1
-#define TAPE390_KEKL_TYPE_HASH 2
-
-struct tape390_kekl {
-       unsigned char type;
-       unsigned char type_on_tape;
-       char label[65];
-} __attribute__ ((packed));
-
-struct tape390_kekl_pair {
-       struct tape390_kekl kekl[2];
-} __attribute__ ((packed));
-
-/*
- * The TAPE390_KEKL_SET ioctl is used to set Key Encrypting Key labels.
- */
-#define TAPE390_KEKL_SET _IOW('d', 4, struct tape390_kekl_pair)
-
-/*
- * The TAPE390_KEKL_QUERY ioctl is used to query Key Encrypting Key labels.
- */
-#define TAPE390_KEKL_QUERY _IOR('d', 5, struct tape390_kekl_pair)
-
 #endif 
index 80c4e5101c9712f2421e6ebec01b91153ebeaa82..d57083209c95d32fdda7d81f2644d226af42e20b 100644 (file)
@@ -130,15 +130,6 @@ config S390_TAPE_34XX
          tape subsystems and 100% compatibles.
          It is safe to say "Y" here.
 
-config S390_TAPE_3590
-       def_tristate m
-       prompt "Support for 3590 tape hardware"
-       depends on S390_TAPE
-       help
-         Select this option if you want to access IBM 3590 magnetic
-         tape subsystems and 100% compatibles.
-         It is safe to say "Y" here.
-
 config VMLOGRDR
        def_tristate m
        prompt "Support for the z/VM recording system services (VM only)"
index dcbd51152ee3f8f4e0a0e4b42b68d187363bc4da..60b9911653f3363e123dc2a68cdec749f27aec9a 100644 (file)
@@ -42,7 +42,6 @@ tape-$(CONFIG_PROC_FS) += tape_proc.o
 tape-objs := tape_core.o tape_std.o tape_char.o $(tape-y)
 obj-$(CONFIG_S390_TAPE) += tape.o tape_class.o
 obj-$(CONFIG_S390_TAPE_34XX) += tape_34xx.o
-obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o
 obj-$(CONFIG_MONREADER) += monreader.o
 obj-$(CONFIG_MONWRITER) += monwriter.o
 obj-$(CONFIG_S390_VMUR) += vmur.o
index 3953b31b0c559e0844be2fa3fc09fec0e628b295..b65a18f3dc9490675df74a1058492f12d5e93280 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- *    tape device driver for 3480/3490E/3590 tapes.
+ *    tape device driver for 3480/3490E tapes.
  *
  *  S390 and zSeries version
  *    Copyright IBM Corp. 2001, 2009
@@ -98,10 +98,6 @@ enum tape_op {
        TO_DIS,         /* Tape display */
        TO_ASSIGN,      /* Assign tape to channel path */
        TO_UNASSIGN,    /* Unassign tape from channel path */
-       TO_CRYPT_ON,    /* Enable encrpytion */
-       TO_CRYPT_OFF,   /* Disable encrpytion */
-       TO_KEKL_SET,    /* Set KEK label */
-       TO_KEKL_QUERY,  /* Query KEK label */
        TO_RDC,         /* Read device characteristics */
        TO_SIZE,        /* #entries in tape_op_t */
 };
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
deleted file mode 100644 (file)
index 0d80f43..0000000
+++ /dev/null
@@ -1,1612 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *    tape device discipline for 3590 tapes.
- *
- *    Copyright IBM Corp. 2001, 2009
- *    Author(s): Stefan Bader <shbader@de.ibm.com>
- *              Michael Holzheu <holzheu@de.ibm.com>
- *              Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#define pr_fmt(fmt) "tape_3590: " fmt
-
-#include <linux/export.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/bio.h>
-#include <asm/ebcdic.h>
-
-#define TAPE_DBF_AREA  tape_3590_dbf
-#define BUFSIZE 512    /* size of buffers for dynamic generated messages */
-
-#include "tape.h"
-#include "tape_std.h"
-#include "tape_3590.h"
-
-static struct workqueue_struct *tape_3590_wq;
-
-/*
- * Pointer to debug area.
- */
-debug_info_t *TAPE_DBF_AREA = NULL;
-EXPORT_SYMBOL(TAPE_DBF_AREA);
-
-/*******************************************************************
- * Error Recovery functions:
- * - Read Opposite:             implemented
- * - Read Device (buffered) log: BRA
- * - Read Library log:          BRA
- * - Swap Devices:              BRA
- * - Long Busy:                         implemented
- * - Special Intercept:                 BRA
- * - Read Alternate:            implemented
- *******************************************************************/
-
-static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = {
-       [0x00] = "",
-       [0x10] = "Lost Sense",
-       [0x11] = "Assigned Elsewhere",
-       [0x12] = "Allegiance Reset",
-       [0x13] = "Shared Access Violation",
-       [0x20] = "Command Reject",
-       [0x21] = "Configuration Error",
-       [0x22] = "Protection Exception",
-       [0x23] = "Write Protect",
-       [0x24] = "Write Length",
-       [0x25] = "Read-Only Format",
-       [0x31] = "Beginning of Partition",
-       [0x33] = "End of Partition",
-       [0x34] = "End of Data",
-       [0x35] = "Block not found",
-       [0x40] = "Device Intervention",
-       [0x41] = "Loader Intervention",
-       [0x42] = "Library Intervention",
-       [0x50] = "Write Error",
-       [0x51] = "Erase Error",
-       [0x52] = "Formatting Error",
-       [0x53] = "Read Error",
-       [0x54] = "Unsupported Format",
-       [0x55] = "No Formatting",
-       [0x56] = "Positioning lost",
-       [0x57] = "Read Length",
-       [0x60] = "Unsupported Medium",
-       [0x61] = "Medium Length Error",
-       [0x62] = "Medium removed",
-       [0x64] = "Load Check",
-       [0x65] = "Unload Check",
-       [0x70] = "Equipment Check",
-       [0x71] = "Bus out Check",
-       [0x72] = "Protocol Error",
-       [0x73] = "Interface Error",
-       [0x74] = "Overrun",
-       [0x75] = "Halt Signal",
-       [0x90] = "Device fenced",
-       [0x91] = "Device Path fenced",
-       [0xa0] = "Volume misplaced",
-       [0xa1] = "Volume inaccessible",
-       [0xa2] = "Volume in input",
-       [0xa3] = "Volume ejected",
-       [0xa4] = "All categories reserved",
-       [0xa5] = "Duplicate Volume",
-       [0xa6] = "Library Manager Offline",
-       [0xa7] = "Library Output Station full",
-       [0xa8] = "Vision System non-operational",
-       [0xa9] = "Library Manager Equipment Check",
-       [0xaa] = "Library Equipment Check",
-       [0xab] = "All Library Cells full",
-       [0xac] = "No Cleaner Volumes in Library",
-       [0xad] = "I/O Station door open",
-       [0xae] = "Subsystem environmental alert",
-};
-
-static int crypt_supported(struct tape_device *device)
-{
-       return TAPE390_CRYPT_SUPPORTED(TAPE_3590_CRYPT_INFO(device));
-}
-
-static int crypt_enabled(struct tape_device *device)
-{
-       return TAPE390_CRYPT_ON(TAPE_3590_CRYPT_INFO(device));
-}
-
-static void ext_to_int_kekl(struct tape390_kekl *in,
-                           struct tape3592_kekl *out)
-{
-       int len;
-
-       memset(out, 0, sizeof(*out));
-       if (in->type == TAPE390_KEKL_TYPE_HASH)
-               out->flags |= 0x40;
-       if (in->type_on_tape == TAPE390_KEKL_TYPE_HASH)
-               out->flags |= 0x80;
-       len = min(sizeof(out->label), strlen(in->label));
-       memcpy(out->label, in->label, len);
-       memset(out->label + len, ' ', sizeof(out->label) - len);
-       ASCEBC(out->label, sizeof(out->label));
-}
-
-static void int_to_ext_kekl(struct tape3592_kekl *in,
-                           struct tape390_kekl *out)
-{
-       memset(out, 0, sizeof(*out));
-       if(in->flags & 0x40)
-               out->type = TAPE390_KEKL_TYPE_HASH;
-       else
-               out->type = TAPE390_KEKL_TYPE_LABEL;
-       if(in->flags & 0x80)
-               out->type_on_tape = TAPE390_KEKL_TYPE_HASH;
-       else
-               out->type_on_tape = TAPE390_KEKL_TYPE_LABEL;
-       memcpy(out->label, in->label, sizeof(in->label));
-       EBCASC(out->label, sizeof(in->label));
-       strim(out->label);
-}
-
-static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in,
-                                struct tape390_kekl_pair *out)
-{
-       if (in->count == 0) {
-               out->kekl[0].type = TAPE390_KEKL_TYPE_NONE;
-               out->kekl[0].type_on_tape = TAPE390_KEKL_TYPE_NONE;
-               out->kekl[1].type = TAPE390_KEKL_TYPE_NONE;
-               out->kekl[1].type_on_tape = TAPE390_KEKL_TYPE_NONE;
-       } else if (in->count == 1) {
-               int_to_ext_kekl(&in->kekl[0], &out->kekl[0]);
-               out->kekl[1].type = TAPE390_KEKL_TYPE_NONE;
-               out->kekl[1].type_on_tape = TAPE390_KEKL_TYPE_NONE;
-       } else if (in->count == 2) {
-               int_to_ext_kekl(&in->kekl[0], &out->kekl[0]);
-               int_to_ext_kekl(&in->kekl[1], &out->kekl[1]);
-       } else {
-               printk("Invalid KEKL number: %d\n", in->count);
-               BUG();
-       }
-}
-
-static int check_ext_kekl(struct tape390_kekl *kekl)
-{
-       if (kekl->type == TAPE390_KEKL_TYPE_NONE)
-               goto invalid;
-       if (kekl->type > TAPE390_KEKL_TYPE_HASH)
-               goto invalid;
-       if (kekl->type_on_tape == TAPE390_KEKL_TYPE_NONE)
-               goto invalid;
-       if (kekl->type_on_tape > TAPE390_KEKL_TYPE_HASH)
-               goto invalid;
-       if ((kekl->type == TAPE390_KEKL_TYPE_HASH) &&
-           (kekl->type_on_tape == TAPE390_KEKL_TYPE_LABEL))
-               goto invalid;
-
-       return 0;
-invalid:
-       return -EINVAL;
-}
-
-static int check_ext_kekl_pair(struct tape390_kekl_pair *kekls)
-{
-       if (check_ext_kekl(&kekls->kekl[0]))
-               goto invalid;
-       if (check_ext_kekl(&kekls->kekl[1]))
-               goto invalid;
-
-       return 0;
-invalid:
-       return -EINVAL;
-}
-
-/*
- * Query KEKLs
- */
-static int tape_3592_kekl_query(struct tape_device *device,
-                               struct tape390_kekl_pair *ext_kekls)
-{
-       struct tape_request *request;
-       struct tape3592_kekl_query_order *order;
-       struct tape3592_kekl_query_data *int_kekls;
-       int rc;
-
-       DBF_EVENT(6, "tape3592_kekl_query\n");
-       int_kekls = kmalloc(sizeof(*int_kekls), GFP_KERNEL|GFP_DMA);
-       if (!int_kekls)
-               return -ENOMEM;
-       request = tape_alloc_request(2, sizeof(*order));
-       if (IS_ERR(request)) {
-               rc = PTR_ERR(request);
-               goto fail_malloc;
-       }
-       order = request->cpdata;
-       memset(order,0,sizeof(*order));
-       order->code = 0xe2;
-       order->max_count = 2;
-       request->op = TO_KEKL_QUERY;
-       tape_ccw_cc(request->cpaddr, PERF_SUBSYS_FUNC, sizeof(*order), order);
-       tape_ccw_end(request->cpaddr + 1, READ_SS_DATA, sizeof(*int_kekls),
-                    int_kekls);
-       rc = tape_do_io(device, request);
-       if (rc)
-               goto fail_request;
-       int_to_ext_kekl_pair(&int_kekls->kekls, ext_kekls);
-
-       rc = 0;
-fail_request:
-       tape_free_request(request);
-fail_malloc:
-       kfree(int_kekls);
-       return rc;
-}
-
-/*
- * IOCTL: Query KEKLs
- */
-static int tape_3592_ioctl_kekl_query(struct tape_device *device,
-                                     unsigned long arg)
-{
-       int rc;
-       struct tape390_kekl_pair *ext_kekls;
-
-       DBF_EVENT(6, "tape_3592_ioctl_kekl_query\n");
-       if (!crypt_supported(device))
-               return -ENOSYS;
-       if (!crypt_enabled(device))
-               return -EUNATCH;
-       ext_kekls = kmalloc(sizeof(*ext_kekls), GFP_KERNEL);
-       if (!ext_kekls)
-               return -ENOMEM;
-       rc = tape_3592_kekl_query(device, ext_kekls);
-       if (rc != 0)
-               goto fail;
-       if (copy_to_user((char __user *) arg, ext_kekls, sizeof(*ext_kekls))) {
-               rc = -EFAULT;
-               goto fail;
-       }
-       rc = 0;
-fail:
-       kfree(ext_kekls);
-       return rc;
-}
-
-static int tape_3590_mttell(struct tape_device *device, int mt_count);
-
-/*
- * Set KEKLs
- */
-static int tape_3592_kekl_set(struct tape_device *device,
-                             struct tape390_kekl_pair *ext_kekls)
-{
-       struct tape_request *request;
-       struct tape3592_kekl_set_order *order;
-
-       DBF_EVENT(6, "tape3592_kekl_set\n");
-       if (check_ext_kekl_pair(ext_kekls)) {
-               DBF_EVENT(6, "invalid kekls\n");
-               return -EINVAL;
-       }
-       if (tape_3590_mttell(device, 0) != 0)
-               return -EBADSLT;
-       request = tape_alloc_request(1, sizeof(*order));
-       if (IS_ERR(request))
-               return PTR_ERR(request);
-       order = request->cpdata;
-       memset(order, 0, sizeof(*order));
-       order->code = 0xe3;
-       order->kekls.count = 2;
-       ext_to_int_kekl(&ext_kekls->kekl[0], &order->kekls.kekl[0]);
-       ext_to_int_kekl(&ext_kekls->kekl[1], &order->kekls.kekl[1]);
-       request->op = TO_KEKL_SET;
-       tape_ccw_end(request->cpaddr, PERF_SUBSYS_FUNC, sizeof(*order), order);
-
-       return tape_do_io_free(device, request);
-}
-
-/*
- * IOCTL: Set KEKLs
- */
-static int tape_3592_ioctl_kekl_set(struct tape_device *device,
-                                   unsigned long arg)
-{
-       int rc;
-       struct tape390_kekl_pair *ext_kekls;
-
-       DBF_EVENT(6, "tape_3592_ioctl_kekl_set\n");
-       if (!crypt_supported(device))
-               return -ENOSYS;
-       if (!crypt_enabled(device))
-               return -EUNATCH;
-       ext_kekls = memdup_user((char __user *)arg, sizeof(*ext_kekls));
-       if (IS_ERR(ext_kekls))
-               return PTR_ERR(ext_kekls);
-       rc = tape_3592_kekl_set(device, ext_kekls);
-       kfree(ext_kekls);
-       return rc;
-}
-
-/*
- * Enable encryption
- */
-static struct tape_request *__tape_3592_enable_crypt(struct tape_device *device)
-{
-       struct tape_request *request;
-       char *data;
-
-       DBF_EVENT(6, "tape_3592_enable_crypt\n");
-       if (!crypt_supported(device))
-               return ERR_PTR(-ENOSYS);
-       request = tape_alloc_request(2, 72);
-       if (IS_ERR(request))
-               return request;
-       data = request->cpdata;
-       memset(data,0,72);
-
-       data[0]       = 0x05;
-       data[36 + 0]  = 0x03;
-       data[36 + 1]  = 0x03;
-       data[36 + 4]  = 0x40;
-       data[36 + 6]  = 0x01;
-       data[36 + 14] = 0x2f;
-       data[36 + 18] = 0xc3;
-       data[36 + 35] = 0x72;
-       request->op = TO_CRYPT_ON;
-       tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
-       tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
-       return request;
-}
-
-static int tape_3592_enable_crypt(struct tape_device *device)
-{
-       struct tape_request *request;
-
-       request = __tape_3592_enable_crypt(device);
-       if (IS_ERR(request))
-               return PTR_ERR(request);
-       return tape_do_io_free(device, request);
-}
-
-static void tape_3592_enable_crypt_async(struct tape_device *device)
-{
-       struct tape_request *request;
-
-       request = __tape_3592_enable_crypt(device);
-       if (!IS_ERR(request))
-               tape_do_io_async_free(device, request);
-}
-
-/*
- * Disable encryption
- */
-static struct tape_request *__tape_3592_disable_crypt(struct tape_device *device)
-{
-       struct tape_request *request;
-       char *data;
-
-       DBF_EVENT(6, "tape_3592_disable_crypt\n");
-       if (!crypt_supported(device))
-               return ERR_PTR(-ENOSYS);
-       request = tape_alloc_request(2, 72);
-       if (IS_ERR(request))
-               return request;
-       data = request->cpdata;
-       memset(data,0,72);
-
-       data[0]       = 0x05;
-       data[36 + 0]  = 0x03;
-       data[36 + 1]  = 0x03;
-       data[36 + 35] = 0x32;
-
-       request->op = TO_CRYPT_OFF;
-       tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
-       tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
-
-       return request;
-}
-
-static int tape_3592_disable_crypt(struct tape_device *device)
-{
-       struct tape_request *request;
-
-       request = __tape_3592_disable_crypt(device);
-       if (IS_ERR(request))
-               return PTR_ERR(request);
-       return tape_do_io_free(device, request);
-}
-
-static void tape_3592_disable_crypt_async(struct tape_device *device)
-{
-       struct tape_request *request;
-
-       request = __tape_3592_disable_crypt(device);
-       if (!IS_ERR(request))
-               tape_do_io_async_free(device, request);
-}
-
-/*
- * IOCTL: Set encryption status
- */
-static int tape_3592_ioctl_crypt_set(struct tape_device *device,
-                                    unsigned long arg)
-{
-       struct tape390_crypt_info info;
-
-       DBF_EVENT(6, "tape_3592_ioctl_crypt_set\n");
-       if (!crypt_supported(device))
-               return -ENOSYS;
-       if (copy_from_user(&info, (char __user *)arg, sizeof(info)))
-               return -EFAULT;
-       if (info.status & ~TAPE390_CRYPT_ON_MASK)
-               return -EINVAL;
-       if (info.status & TAPE390_CRYPT_ON_MASK)
-               return tape_3592_enable_crypt(device);
-       else
-               return tape_3592_disable_crypt(device);
-}
-
-static int tape_3590_sense_medium(struct tape_device *device);
-
-/*
- * IOCTL: Query enryption status
- */
-static int tape_3592_ioctl_crypt_query(struct tape_device *device,
-                                      unsigned long arg)
-{
-       DBF_EVENT(6, "tape_3592_ioctl_crypt_query\n");
-       if (!crypt_supported(device))
-               return -ENOSYS;
-       tape_3590_sense_medium(device);
-       if (copy_to_user((char __user *) arg, &TAPE_3590_CRYPT_INFO(device),
-               sizeof(TAPE_3590_CRYPT_INFO(device))))
-               return -EFAULT;
-       else
-               return 0;
-}
-
-/*
- * 3590 IOCTL Overload
- */
-static int
-tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)
-{
-       switch (cmd) {
-       case TAPE390_DISPLAY: {
-               struct display_struct disp;
-
-               if (copy_from_user(&disp, (char __user *) arg, sizeof(disp)))
-                       return -EFAULT;
-
-               return tape_std_display(device, &disp);
-       }
-       case TAPE390_KEKL_SET:
-               return tape_3592_ioctl_kekl_set(device, arg);
-       case TAPE390_KEKL_QUERY:
-               return tape_3592_ioctl_kekl_query(device, arg);
-       case TAPE390_CRYPT_SET:
-               return tape_3592_ioctl_crypt_set(device, arg);
-       case TAPE390_CRYPT_QUERY:
-               return tape_3592_ioctl_crypt_query(device, arg);
-       default:
-               return -EINVAL; /* no additional ioctls */
-       }
-}
-
-/*
- * SENSE Medium: Get Sense data about medium state
- */
-static int tape_3590_sense_medium(struct tape_device *device)
-{
-       struct tape_request *request;
-
-       request = tape_alloc_request(1, 128);
-       if (IS_ERR(request))
-               return PTR_ERR(request);
-       request->op = TO_MSEN;
-       tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata);
-       return tape_do_io_free(device, request);
-}
-
-static void tape_3590_sense_medium_async(struct tape_device *device)
-{
-       struct tape_request *request;
-
-       request = tape_alloc_request(1, 128);
-       if (IS_ERR(request))
-               return;
-       request->op = TO_MSEN;
-       tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata);
-       tape_do_io_async_free(device, request);
-}
-
-/*
- * MTTELL: Tell block. Return the number of block relative to current file.
- */
-static int
-tape_3590_mttell(struct tape_device *device, int mt_count)
-{
-       __u64 block_id;
-       int rc;
-
-       rc = tape_std_read_block_id(device, &block_id);
-       if (rc)
-               return rc;
-       return block_id >> 32;
-}
-
-/*
- * MTSEEK: seek to the specified block.
- */
-static int
-tape_3590_mtseek(struct tape_device *device, int count)
-{
-       struct tape_request *request;
-
-       DBF_EVENT(6, "xsee id: %x\n", count);
-       request = tape_alloc_request(3, 4);
-       if (IS_ERR(request))
-               return PTR_ERR(request);
-       request->op = TO_LBL;
-       tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
-       *(__u32 *) request->cpdata = count;
-       tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);
-       tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
-       return tape_do_io_free(device, request);
-}
-
-/*
- * Read Attention Msg
- * This should be done after an interrupt with attention bit (0x80)
- * in device state.
- *
- * After a "read attention message" request there are two possible
- * results:
- *
- * 1. A unit check is presented, when attention sense is present (e.g. when
- * a medium has been unloaded). The attention sense comes then
- * together with the unit check. The recovery action is either "retry"
- * (in case there is an attention message pending) or "permanent error".
- *
- * 2. The attention msg is written to the "read subsystem data" buffer.
- * In this case we probably should print it to the console.
- */
-static void tape_3590_read_attmsg_async(struct tape_device *device)
-{
-       struct tape_request *request;
-       char *buf;
-
-       request = tape_alloc_request(3, 4096);
-       if (IS_ERR(request))
-               return;
-       request->op = TO_READ_ATTMSG;
-       buf = request->cpdata;
-       buf[0] = PREP_RD_SS_DATA;
-       buf[6] = RD_ATTMSG;     /* read att msg */
-       tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf);
-       tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12);
-       tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
-       tape_do_io_async_free(device, request);
-}
-
-/*
- * These functions are used to schedule follow-up actions from within an
- * interrupt context (like unsolicited interrupts).
- * Note: the work handler is called by the system work queue. The tape
- * commands started by the handler need to be asynchrounous, otherwise
- * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq).
- */
-struct work_handler_data {
-       struct tape_device *device;
-       enum tape_op        op;
-       struct work_struct  work;
-};
-
-static void
-tape_3590_work_handler(struct work_struct *work)
-{
-       struct work_handler_data *p =
-               container_of(work, struct work_handler_data, work);
-
-       switch (p->op) {
-       case TO_MSEN:
-               tape_3590_sense_medium_async(p->device);
-               break;
-       case TO_READ_ATTMSG:
-               tape_3590_read_attmsg_async(p->device);
-               break;
-       case TO_CRYPT_ON:
-               tape_3592_enable_crypt_async(p->device);
-               break;
-       case TO_CRYPT_OFF:
-               tape_3592_disable_crypt_async(p->device);
-               break;
-       default:
-               DBF_EVENT(3, "T3590: work handler undefined for "
-                         "operation 0x%02x\n", p->op);
-       }
-       tape_put_device(p->device);
-       kfree(p);
-}
-
-static int
-tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
-{
-       struct work_handler_data *p;
-
-       if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
-               return -ENOMEM;
-
-       INIT_WORK(&p->work, tape_3590_work_handler);
-
-       p->device = tape_get_device(device);
-       p->op = op;
-
-       queue_work(tape_3590_wq, &p->work);
-       return 0;
-}
-
-static void tape_3590_med_state_set(struct tape_device *device,
-                                   struct tape_3590_med_sense *sense)
-{
-       struct tape390_crypt_info *c_info;
-
-       c_info = &TAPE_3590_CRYPT_INFO(device);
-
-       DBF_EVENT(6, "medium state: %x:%x\n", sense->macst, sense->masst);
-       switch (sense->macst) {
-       case 0x04:
-       case 0x05:
-       case 0x06:
-               tape_med_state_set(device, MS_UNLOADED);
-               TAPE_3590_CRYPT_INFO(device).medium_status = 0;
-               return;
-       case 0x08:
-       case 0x09:
-               tape_med_state_set(device, MS_LOADED);
-               break;
-       default:
-               tape_med_state_set(device, MS_UNKNOWN);
-               return;
-       }
-       c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
-       if (sense->flags & MSENSE_CRYPT_MASK) {
-               DBF_EVENT(6, "Medium is encrypted (%04x)\n", sense->flags);
-               c_info->medium_status |= TAPE390_MEDIUM_ENCRYPTED_MASK;
-       } else  {
-               DBF_EVENT(6, "Medium is not encrypted %04x\n", sense->flags);
-               c_info->medium_status &= ~TAPE390_MEDIUM_ENCRYPTED_MASK;
-       }
-}
-
-/*
- * The done handler is called at device/channel end and wakes up the sleeping
- * process
- */
-static int
-tape_3590_done(struct tape_device *device, struct tape_request *request)
-{
-
-       DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);
-
-       switch (request->op) {
-       case TO_BSB:
-       case TO_BSF:
-       case TO_DSE:
-       case TO_FSB:
-       case TO_FSF:
-       case TO_LBL:
-       case TO_RFO:
-       case TO_RBA:
-       case TO_REW:
-       case TO_WRI:
-       case TO_WTM:
-       case TO_BLOCK:
-       case TO_LOAD:
-               tape_med_state_set(device, MS_LOADED);
-               break;
-       case TO_RUN:
-               tape_med_state_set(device, MS_UNLOADED);
-               tape_3590_schedule_work(device, TO_CRYPT_OFF);
-               break;
-       case TO_MSEN:
-               tape_3590_med_state_set(device, request->cpdata);
-               break;
-       case TO_CRYPT_ON:
-               TAPE_3590_CRYPT_INFO(device).status
-                       |= TAPE390_CRYPT_ON_MASK;
-               *(device->modeset_byte) |= 0x03;
-               break;
-       case TO_CRYPT_OFF:
-               TAPE_3590_CRYPT_INFO(device).status
-                       &= ~TAPE390_CRYPT_ON_MASK;
-               *(device->modeset_byte) &= ~0x03;
-               break;
-       case TO_RBI:    /* RBI seems to succeed even without medium loaded. */
-       case TO_NOP:    /* Same to NOP. */
-       case TO_READ_CONFIG:
-       case TO_READ_ATTMSG:
-       case TO_DIS:
-       case TO_ASSIGN:
-       case TO_UNASSIGN:
-       case TO_SIZE:
-       case TO_KEKL_SET:
-       case TO_KEKL_QUERY:
-       case TO_RDC:
-               break;
-       }
-       return TAPE_IO_SUCCESS;
-}
-
-/*
- * This function is called, when error recovery was successful
- */
-static inline int
-tape_3590_erp_succeeded(struct tape_device *device, struct tape_request *request)
-{
-       DBF_EVENT(3, "Error Recovery successful for %s\n",
-                 tape_op_verbose[request->op]);
-       return tape_3590_done(device, request);
-}
-
-/*
- * This function is called, when error recovery was not successful
- */
-static inline int
-tape_3590_erp_failed(struct tape_device *device, struct tape_request *request,
-                    struct irb *irb, int rc)
-{
-       DBF_EVENT(3, "Error Recovery failed for %s\n",
-                 tape_op_verbose[request->op]);
-       tape_dump_sense_dbf(device, request, irb);
-       return rc;
-}
-
-/*
- * Error Recovery do retry
- */
-static inline int
-tape_3590_erp_retry(struct tape_device *device, struct tape_request *request,
-                   struct irb *irb)
-{
-       DBF_EVENT(2, "Retry: %s\n", tape_op_verbose[request->op]);
-       tape_dump_sense_dbf(device, request, irb);
-       return TAPE_IO_RETRY;
-}
-
-/*
- * Handle unsolicited interrupts
- */
-static int
-tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb)
-{
-       if (irb->scsw.cmd.dstat == DEV_STAT_CHN_END)
-               /* Probably result of halt ssch */
-               return TAPE_IO_PENDING;
-       else if (irb->scsw.cmd.dstat == 0x85)
-               /* Device Ready */
-               DBF_EVENT(3, "unsol.irq! tape ready: %08x\n", device->cdev_id);
-       else if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
-               tape_3590_schedule_work(device, TO_READ_ATTMSG);
-       } else {
-               DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
-               tape_dump_sense_dbf(device, NULL, irb);
-       }
-       /* check medium state */
-       tape_3590_schedule_work(device, TO_MSEN);
-       return TAPE_IO_SUCCESS;
-}
-
-/*
- * Basic Recovery routine
- */
-static int
-tape_3590_erp_basic(struct tape_device *device, struct tape_request *request,
-                   struct irb *irb, int rc)
-{
-       struct tape_3590_sense *sense;
-
-       sense = (struct tape_3590_sense *) irb->ecw;
-
-       switch (sense->bra) {
-       case SENSE_BRA_PER:
-               return tape_3590_erp_failed(device, request, irb, rc);
-       case SENSE_BRA_CONT:
-               return tape_3590_erp_succeeded(device, request);
-       case SENSE_BRA_RE:
-               return tape_3590_erp_retry(device, request, irb);
-       case SENSE_BRA_DRE:
-               return tape_3590_erp_failed(device, request, irb, rc);
-       default:
-               BUG();
-               return TAPE_IO_STOP;
-       }
-}
-
-/*
- *  RDL: Read Device (buffered) log
- */
-static int
-tape_3590_erp_read_buf_log(struct tape_device *device,
-                          struct tape_request *request, struct irb *irb)
-{
-       /*
-        * We just do the basic error recovery at the moment (retry).
-        * Perhaps in the future, we read the log and dump it somewhere...
-        */
-       return tape_3590_erp_basic(device, request, irb, -EIO);
-}
-
-/*
- *  SWAP: Swap Devices
- */
-static int
-tape_3590_erp_swap(struct tape_device *device, struct tape_request *request,
-                  struct irb *irb)
-{
-       /*
-        * This error recovery should swap the tapes
-        * if the original has a problem. The operation
-        * should proceed with the new tape... this
-        * should probably be done in user space!
-        */
-       dev_warn (&device->cdev->dev, "The tape medium must be loaded into a "
-               "different tape unit\n");
-       return tape_3590_erp_basic(device, request, irb, -EIO);
-}
-
-/*
- *  LBY: Long Busy
- */
-static int
-tape_3590_erp_long_busy(struct tape_device *device,
-                       struct tape_request *request, struct irb *irb)
-{
-       DBF_EVENT(6, "Device is busy\n");
-       return TAPE_IO_LONG_BUSY;
-}
-
-/*
- *  SPI: Special Intercept
- */
-static int
-tape_3590_erp_special_interrupt(struct tape_device *device,
-                               struct tape_request *request, struct irb *irb)
-{
-       return tape_3590_erp_basic(device, request, irb, -EIO);
-}
-
-/*
- * Print an MIM (Media Information  Message) (message code f0)
- */
-static void
-tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb)
-{
-       struct tape_3590_sense *sense;
-       char *exception, *service;
-
-       exception = kmalloc(BUFSIZE, GFP_ATOMIC);
-       service = kmalloc(BUFSIZE, GFP_ATOMIC);
-
-       if (!exception || !service)
-               goto out_nomem;
-
-       sense = (struct tape_3590_sense *) irb->ecw;
-       /* Exception Message */
-       switch (sense->fmt.f70.emc) {
-       case 0x02:
-               snprintf(exception, BUFSIZE, "Data degraded");
-               break;
-       case 0x03:
-               snprintf(exception, BUFSIZE, "Data degraded in partition %i",
-                       sense->fmt.f70.mp);
-               break;
-       case 0x04:
-               snprintf(exception, BUFSIZE, "Medium degraded");
-               break;
-       case 0x05:
-               snprintf(exception, BUFSIZE, "Medium degraded in partition %i",
-                       sense->fmt.f70.mp);
-               break;
-       case 0x06:
-               snprintf(exception, BUFSIZE, "Block 0 Error");
-               break;
-       case 0x07:
-               snprintf(exception, BUFSIZE, "Medium Exception 0x%02x",
-                       sense->fmt.f70.md);
-               break;
-       default:
-               snprintf(exception, BUFSIZE, "0x%02x",
-                       sense->fmt.f70.emc);
-               break;
-       }
-       /* Service Message */
-       switch (sense->fmt.f70.smc) {
-       case 0x02:
-               snprintf(service, BUFSIZE, "Reference Media maintenance "
-                       "procedure %i", sense->fmt.f70.md);
-               break;
-       default:
-               snprintf(service, BUFSIZE, "0x%02x",
-                       sense->fmt.f70.smc);
-               break;
-       }
-
-       dev_warn (&device->cdev->dev, "Tape media information: exception %s, "
-               "service %s\n", exception, service);
-
-out_nomem:
-       kfree(exception);
-       kfree(service);
-}
-
-/*
- * Print an I/O Subsystem Service Information Message (message code f1)
- */
-static void
-tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb)
-{
-       struct tape_3590_sense *sense;
-       char *exception, *service;
-
-       exception = kmalloc(BUFSIZE, GFP_ATOMIC);
-       service = kmalloc(BUFSIZE, GFP_ATOMIC);
-
-       if (!exception || !service)
-               goto out_nomem;
-
-       sense = (struct tape_3590_sense *) irb->ecw;
-       /* Exception Message */
-       switch (sense->fmt.f71.emc) {
-       case 0x01:
-               snprintf(exception, BUFSIZE, "Effect of failure is unknown");
-               break;
-       case 0x02:
-               snprintf(exception, BUFSIZE, "CU Exception - no performance "
-                       "impact");
-               break;
-       case 0x03:
-               snprintf(exception, BUFSIZE, "CU Exception on channel "
-                       "interface 0x%02x", sense->fmt.f71.md[0]);
-               break;
-       case 0x04:
-               snprintf(exception, BUFSIZE, "CU Exception on device path "
-                       "0x%02x", sense->fmt.f71.md[0]);
-               break;
-       case 0x05:
-               snprintf(exception, BUFSIZE, "CU Exception on library path "
-                       "0x%02x", sense->fmt.f71.md[0]);
-               break;
-       case 0x06:
-               snprintf(exception, BUFSIZE, "CU Exception on node 0x%02x",
-                       sense->fmt.f71.md[0]);
-               break;
-       case 0x07:
-               snprintf(exception, BUFSIZE, "CU Exception on partition "
-                       "0x%02x", sense->fmt.f71.md[0]);
-               break;
-       default:
-               snprintf(exception, BUFSIZE, "0x%02x",
-                       sense->fmt.f71.emc);
-       }
-       /* Service Message */
-       switch (sense->fmt.f71.smc) {
-       case 0x01:
-               snprintf(service, BUFSIZE, "Repair impact is unknown");
-               break;
-       case 0x02:
-               snprintf(service, BUFSIZE, "Repair will not impact cu "
-                       "performance");
-               break;
-       case 0x03:
-               if (sense->fmt.f71.mdf == 0)
-                       snprintf(service, BUFSIZE, "Repair will disable node "
-                               "0x%x on CU", sense->fmt.f71.md[1]);
-               else
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "nodes (0x%x-0x%x) on CU", sense->fmt.f71.md[1],
-                               sense->fmt.f71.md[2]);
-               break;
-       case 0x04:
-               if (sense->fmt.f71.mdf == 0)
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "channel path 0x%x on CU",
-                               sense->fmt.f71.md[1]);
-               else
-                       snprintf(service, BUFSIZE, "Repair will disable channel"
-                               " paths (0x%x-0x%x) on CU",
-                               sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
-               break;
-       case 0x05:
-               if (sense->fmt.f71.mdf == 0)
-                       snprintf(service, BUFSIZE, "Repair will disable device"
-                               " path 0x%x on CU", sense->fmt.f71.md[1]);
-               else
-                       snprintf(service, BUFSIZE, "Repair will disable device"
-                               " paths (0x%x-0x%x) on CU",
-                               sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
-               break;
-       case 0x06:
-               if (sense->fmt.f71.mdf == 0)
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "library path 0x%x on CU",
-                               sense->fmt.f71.md[1]);
-               else
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "library paths (0x%x-0x%x) on CU",
-                               sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
-               break;
-       case 0x07:
-               snprintf(service, BUFSIZE, "Repair will disable access to CU");
-               break;
-       default:
-               snprintf(service, BUFSIZE, "0x%02x",
-                       sense->fmt.f71.smc);
-       }
-
-       dev_warn (&device->cdev->dev, "I/O subsystem information: exception"
-               " %s, service %s\n", exception, service);
-out_nomem:
-       kfree(exception);
-       kfree(service);
-}
-
-/*
- * Print an Device Subsystem Service Information Message (message code f2)
- */
-static void
-tape_3590_print_dev_sim_msg_f2(struct tape_device *device, struct irb *irb)
-{
-       struct tape_3590_sense *sense;
-       char *exception, *service;
-
-       exception = kmalloc(BUFSIZE, GFP_ATOMIC);
-       service = kmalloc(BUFSIZE, GFP_ATOMIC);
-
-       if (!exception || !service)
-               goto out_nomem;
-
-       sense = (struct tape_3590_sense *) irb->ecw;
-       /* Exception Message */
-       switch (sense->fmt.f71.emc) {
-       case 0x01:
-               snprintf(exception, BUFSIZE, "Effect of failure is unknown");
-               break;
-       case 0x02:
-               snprintf(exception, BUFSIZE, "DV Exception - no performance"
-                       " impact");
-               break;
-       case 0x03:
-               snprintf(exception, BUFSIZE, "DV Exception on channel "
-                       "interface 0x%02x", sense->fmt.f71.md[0]);
-               break;
-       case 0x04:
-               snprintf(exception, BUFSIZE, "DV Exception on loader 0x%02x",
-                       sense->fmt.f71.md[0]);
-               break;
-       case 0x05:
-               snprintf(exception, BUFSIZE, "DV Exception on message display"
-                       " 0x%02x", sense->fmt.f71.md[0]);
-               break;
-       case 0x06:
-               snprintf(exception, BUFSIZE, "DV Exception in tape path");
-               break;
-       case 0x07:
-               snprintf(exception, BUFSIZE, "DV Exception in drive");
-               break;
-       default:
-               snprintf(exception, BUFSIZE, "0x%02x",
-                       sense->fmt.f71.emc);
-       }
-       /* Service Message */
-       switch (sense->fmt.f71.smc) {
-       case 0x01:
-               snprintf(service, BUFSIZE, "Repair impact is unknown");
-               break;
-       case 0x02:
-               snprintf(service, BUFSIZE, "Repair will not impact device "
-                       "performance");
-               break;
-       case 0x03:
-               if (sense->fmt.f71.mdf == 0)
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "channel path 0x%x on DV",
-                               sense->fmt.f71.md[1]);
-               else
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "channel path (0x%x-0x%x) on DV",
-                               sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
-               break;
-       case 0x04:
-               if (sense->fmt.f71.mdf == 0)
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "interface 0x%x on DV", sense->fmt.f71.md[1]);
-               else
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "interfaces (0x%x-0x%x) on DV",
-                               sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
-               break;
-       case 0x05:
-               if (sense->fmt.f71.mdf == 0)
-                       snprintf(service, BUFSIZE, "Repair will disable loader"
-                               " 0x%x on DV", sense->fmt.f71.md[1]);
-               else
-                       snprintf(service, BUFSIZE, "Repair will disable loader"
-                               " (0x%x-0x%x) on DV",
-                               sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
-               break;
-       case 0x07:
-               snprintf(service, BUFSIZE, "Repair will disable access to DV");
-               break;
-       case 0x08:
-               if (sense->fmt.f71.mdf == 0)
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "message display 0x%x on DV",
-                               sense->fmt.f71.md[1]);
-               else
-                       snprintf(service, BUFSIZE, "Repair will disable "
-                               "message displays (0x%x-0x%x) on DV",
-                                sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
-               break;
-       case 0x09:
-               snprintf(service, BUFSIZE, "Clean DV");
-               break;
-       default:
-               snprintf(service, BUFSIZE, "0x%02x",
-                       sense->fmt.f71.smc);
-       }
-
-       dev_warn (&device->cdev->dev, "Device subsystem information: exception"
-               " %s, service %s\n", exception, service);
-out_nomem:
-       kfree(exception);
-       kfree(service);
-}
-
-/*
- * Print standard ERA Message
- */
-static void
-tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
-{
-       struct tape_3590_sense *sense;
-
-       sense = (struct tape_3590_sense *) irb->ecw;
-       if (sense->mc == 0)
-               return;
-       if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) {
-               if (tape_3590_msg[sense->mc] != NULL)
-                       dev_warn (&device->cdev->dev, "The tape unit has "
-                               "issued sense message %s\n",
-                               tape_3590_msg[sense->mc]);
-               else
-                       dev_warn (&device->cdev->dev, "The tape unit has "
-                               "issued an unknown sense message code 0x%x\n",
-                               sense->mc);
-               return;
-       }
-       if (sense->mc == 0xf0) {
-               /* Standard Media Information Message */
-               dev_warn (&device->cdev->dev, "MIM SEV=%i, MC=%02x, ES=%x/%x, "
-                       "RC=%02x-%04x-%02x\n", sense->fmt.f70.sev, sense->mc,
-                       sense->fmt.f70.emc, sense->fmt.f70.smc,
-                       sense->fmt.f70.refcode, sense->fmt.f70.mid,
-                       sense->fmt.f70.fid);
-               tape_3590_print_mim_msg_f0(device, irb);
-               return;
-       }
-       if (sense->mc == 0xf1) {
-               /* Standard I/O Subsystem Service Information Message */
-               dev_warn (&device->cdev->dev, "IOSIM SEV=%i, DEVTYPE=3590/%02x,"
-                       " MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
-                       sense->fmt.f71.sev, device->cdev->id.dev_model,
-                       sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
-                       sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
-                       sense->fmt.f71.refcode3);
-               tape_3590_print_io_sim_msg_f1(device, irb);
-               return;
-       }
-       if (sense->mc == 0xf2) {
-               /* Standard Device Service Information Message */
-               dev_warn (&device->cdev->dev, "DEVSIM SEV=%i, DEVTYPE=3590/%02x"
-                       ", MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
-                       sense->fmt.f71.sev, device->cdev->id.dev_model,
-                       sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
-                       sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
-                       sense->fmt.f71.refcode3);
-               tape_3590_print_dev_sim_msg_f2(device, irb);
-               return;
-       }
-       if (sense->mc == 0xf3) {
-               /* Standard Library Service Information Message */
-               return;
-       }
-       dev_warn (&device->cdev->dev, "The tape unit has issued an unknown "
-               "sense message code %x\n", sense->mc);
-}
-
-static int tape_3590_crypt_error(struct tape_device *device,
-                                struct tape_request *request, struct irb *irb)
-{
-       u8 cu_rc;
-       u16 ekm_rc2;
-       char *sense;
-
-       sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data;
-       cu_rc = sense[0];
-       ekm_rc2 = *((u16*) &sense[10]);
-       if ((cu_rc == 0) && (ekm_rc2 == 0xee31))
-               /* key not defined on EKM */
-               return tape_3590_erp_basic(device, request, irb, -EKEYREJECTED);
-       if ((cu_rc == 1) || (cu_rc == 2))
-               /* No connection to EKM */
-               return tape_3590_erp_basic(device, request, irb, -ENOTCONN);
-
-       dev_err (&device->cdev->dev, "The tape unit failed to obtain the "
-               "encryption key from EKM\n");
-
-       return tape_3590_erp_basic(device, request, irb, -ENOKEY);
-}
-
-/*
- *  3590 error Recovery routine:
- *  If possible, it tries to recover from the error. If this is not possible,
- *  inform the user about the problem.
- */
-static int
-tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
-                    struct irb *irb)
-{
-       struct tape_3590_sense *sense;
-
-       sense = (struct tape_3590_sense *) irb->ecw;
-
-       DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc);
-
-       /*
-        * First check all RC-QRCs where we want to do something special
-        *   - "break":     basic error recovery is done
-        *   - "goto out:": just print error message if available
-        */
-       switch (sense->rc_rqc) {
-
-       case 0x1110:
-               tape_3590_print_era_msg(device, irb);
-               return tape_3590_erp_read_buf_log(device, request, irb);
-
-       case 0x2230:
-       case 0x2231:
-               tape_3590_print_era_msg(device, irb);
-               return tape_3590_erp_special_interrupt(device, request, irb);
-       case 0x2240:
-               return tape_3590_crypt_error(device, request, irb);
-
-       case 0x3010:
-               DBF_EVENT(2, "(%08x): Backward at Beginning of Partition\n",
-                         device->cdev_id);
-               return tape_3590_erp_basic(device, request, irb, -ENOSPC);
-       case 0x3012:
-               DBF_EVENT(2, "(%08x): Forward at End of Partition\n",
-                         device->cdev_id);
-               return tape_3590_erp_basic(device, request, irb, -ENOSPC);
-       case 0x3020:
-               DBF_EVENT(2, "(%08x): End of Data Mark\n", device->cdev_id);
-               return tape_3590_erp_basic(device, request, irb, -ENOSPC);
-
-       case 0x3122:
-               DBF_EVENT(2, "(%08x): Rewind Unload initiated\n",
-                         device->cdev_id);
-               return tape_3590_erp_basic(device, request, irb, -EIO);
-       case 0x3123:
-               DBF_EVENT(2, "(%08x): Rewind Unload complete\n",
-                         device->cdev_id);
-               tape_med_state_set(device, MS_UNLOADED);
-               tape_3590_schedule_work(device, TO_CRYPT_OFF);
-               return tape_3590_erp_basic(device, request, irb, 0);
-
-       case 0x4010:
-               /*
-                * print additional msg since default msg
-                * "device intervention" is not very meaningfull
-                */
-               tape_med_state_set(device, MS_UNLOADED);
-               tape_3590_schedule_work(device, TO_CRYPT_OFF);
-               return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
-       case 0x4012:            /* Device Long Busy */
-               /* XXX: Also use long busy handling here? */
-               DBF_EVENT(6, "(%08x): LONG BUSY\n", device->cdev_id);
-               tape_3590_print_era_msg(device, irb);
-               return tape_3590_erp_basic(device, request, irb, -EBUSY);
-       case 0x4014:
-               DBF_EVENT(6, "(%08x): Crypto LONG BUSY\n", device->cdev_id);
-               return tape_3590_erp_long_busy(device, request, irb);
-
-       case 0x5010:
-               if (sense->rac == 0xd0) {
-                       /* Swap */
-                       tape_3590_print_era_msg(device, irb);
-                       return tape_3590_erp_swap(device, request, irb);
-               }
-               return tape_3590_erp_basic(device, request, irb, -EIO);
-       case 0x5020:
-       case 0x5021:
-       case 0x5022:
-       case 0x5040:
-       case 0x5041:
-       case 0x5042:
-               tape_3590_print_era_msg(device, irb);
-               return tape_3590_erp_swap(device, request, irb);
-
-       case 0x5110:
-       case 0x5111:
-               return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE);
-
-       case 0x5120:
-       case 0x1120:
-               tape_med_state_set(device, MS_UNLOADED);
-               tape_3590_schedule_work(device, TO_CRYPT_OFF);
-               return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
-
-       case 0x6020:
-               return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE);
-
-       case 0x8011:
-               return tape_3590_erp_basic(device, request, irb, -EPERM);
-       case 0x8013:
-               dev_warn (&device->cdev->dev, "A different host has privileged"
-                       " access to the tape unit\n");
-               return tape_3590_erp_basic(device, request, irb, -EPERM);
-       default:
-               return tape_3590_erp_basic(device, request, irb, -EIO);
-       }
-}
-
-/*
- * 3590 interrupt handler:
- */
-static int
-tape_3590_irq(struct tape_device *device, struct tape_request *request,
-             struct irb *irb)
-{
-       if (request == NULL)
-               return tape_3590_unsolicited_irq(device, irb);
-
-       if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) &&
-           (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
-           (request->op == TO_WRI)) {
-               /* Write at end of volume */
-               DBF_EVENT(2, "End of volume\n");
-               return tape_3590_erp_failed(device, request, irb, -ENOSPC);
-       }
-
-       if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
-               return tape_3590_unit_check(device, request, irb);
-
-       if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {
-               if (irb->scsw.cmd.dstat == DEV_STAT_UNIT_EXCEP) {
-                       if (request->op == TO_FSB || request->op == TO_BSB)
-                               request->rescnt++;
-                       else
-                               DBF_EVENT(5, "Unit Exception!\n");
-               }
-
-               return tape_3590_done(device, request);
-       }
-
-       if (irb->scsw.cmd.dstat & DEV_STAT_CHN_END) {
-               DBF_EVENT(2, "channel end\n");
-               return TAPE_IO_PENDING;
-       }
-
-       if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
-               DBF_EVENT(2, "Unit Attention when busy..\n");
-               return TAPE_IO_PENDING;
-       }
-
-       DBF_EVENT(6, "xunknownirq\n");
-       tape_dump_sense_dbf(device, request, irb);
-       return TAPE_IO_STOP;
-}
-
-
-static int tape_3590_read_dev_chars(struct tape_device *device,
-                                   struct tape_3590_rdc_data *rdc_data)
-{
-       int rc;
-       struct tape_request *request;
-
-       request = tape_alloc_request(1, sizeof(*rdc_data));
-       if (IS_ERR(request))
-               return PTR_ERR(request);
-       request->op = TO_RDC;
-       tape_ccw_end(request->cpaddr, CCW_CMD_RDC, sizeof(*rdc_data),
-                    request->cpdata);
-       rc = tape_do_io(device, request);
-       if (rc == 0)
-               memcpy(rdc_data, request->cpdata, sizeof(*rdc_data));
-       tape_free_request(request);
-       return rc;
-}
-
-/*
- * Setup device function
- */
-static int
-tape_3590_setup_device(struct tape_device *device)
-{
-       int rc;
-       struct tape_3590_disc_data *data;
-       struct tape_3590_rdc_data *rdc_data;
-
-       DBF_EVENT(6, "3590 device setup\n");
-       data = kzalloc(sizeof(struct tape_3590_disc_data), GFP_KERNEL | GFP_DMA);
-       if (data == NULL)
-               return -ENOMEM;
-       data->read_back_op = READ_PREVIOUS;
-       device->discdata = data;
-
-       rdc_data = kmalloc(sizeof(*rdc_data), GFP_KERNEL | GFP_DMA);
-       if (!rdc_data) {
-               rc = -ENOMEM;
-               goto fail_kmalloc;
-       }
-       rc = tape_3590_read_dev_chars(device, rdc_data);
-       if (rc) {
-               DBF_LH(3, "Read device characteristics failed!\n");
-               goto fail_rdc_data;
-       }
-       rc = tape_std_assign(device);
-       if (rc)
-               goto fail_rdc_data;
-       if (rdc_data->data[31] == 0x13) {
-               data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK;
-               tape_3592_disable_crypt(device);
-       } else {
-               DBF_EVENT(6, "Device has NO crypto support\n");
-       }
-       /* Try to find out if medium is loaded */
-       rc = tape_3590_sense_medium(device);
-       if (rc) {
-               DBF_LH(3, "3590 medium sense returned %d\n", rc);
-               goto fail_rdc_data;
-       }
-       return 0;
-
-fail_rdc_data:
-       kfree(rdc_data);
-fail_kmalloc:
-       kfree(data);
-       return rc;
-}
-
-/*
- * Cleanup device function
- */
-static void
-tape_3590_cleanup_device(struct tape_device *device)
-{
-       flush_workqueue(tape_3590_wq);
-       tape_std_unassign(device);
-
-       kfree(device->discdata);
-       device->discdata = NULL;
-}
-
-/*
- * List of 3590 magnetic tape commands.
- */
-static tape_mtop_fn tape_3590_mtop[TAPE_NR_MTOPS] = {
-       [MTRESET]        = tape_std_mtreset,
-       [MTFSF]          = tape_std_mtfsf,
-       [MTBSF]          = tape_std_mtbsf,
-       [MTFSR]          = tape_std_mtfsr,
-       [MTBSR]          = tape_std_mtbsr,
-       [MTWEOF]         = tape_std_mtweof,
-       [MTREW]          = tape_std_mtrew,
-       [MTOFFL]         = tape_std_mtoffl,
-       [MTNOP]          = tape_std_mtnop,
-       [MTRETEN]        = tape_std_mtreten,
-       [MTBSFM]         = tape_std_mtbsfm,
-       [MTFSFM]         = tape_std_mtfsfm,
-       [MTEOM]          = tape_std_mteom,
-       [MTERASE]        = tape_std_mterase,
-       [MTRAS1]         = NULL,
-       [MTRAS2]         = NULL,
-       [MTRAS3]         = NULL,
-       [MTSETBLK]       = tape_std_mtsetblk,
-       [MTSETDENSITY]   = NULL,
-       [MTSEEK]         = tape_3590_mtseek,
-       [MTTELL]         = tape_3590_mttell,
-       [MTSETDRVBUFFER] = NULL,
-       [MTFSS]          = NULL,
-       [MTBSS]          = NULL,
-       [MTWSM]          = NULL,
-       [MTLOCK]         = NULL,
-       [MTUNLOCK]       = NULL,
-       [MTLOAD]         = tape_std_mtload,
-       [MTUNLOAD]       = tape_std_mtunload,
-       [MTCOMPRESSION]  = tape_std_mtcompression,
-       [MTSETPART]      = NULL,
-       [MTMKPART]       = NULL
-};
-
-/*
- * Tape discipline structure for 3590.
- */
-static struct tape_discipline tape_discipline_3590 = {
-       .owner = THIS_MODULE,
-       .setup_device = tape_3590_setup_device,
-       .cleanup_device = tape_3590_cleanup_device,
-       .process_eov = tape_std_process_eov,
-       .irq = tape_3590_irq,
-       .read_block = tape_std_read_block,
-       .write_block = tape_std_write_block,
-       .ioctl_fn = tape_3590_ioctl,
-       .mtop_array = tape_3590_mtop
-};
-
-static struct ccw_device_id tape_3590_ids[] = {
-       {CCW_DEVICE_DEVTYPE(0x3590, 0, 0x3590, 0), .driver_info = tape_3590},
-       {CCW_DEVICE_DEVTYPE(0x3592, 0, 0x3592, 0), .driver_info = tape_3592},
-       { /* end of list */ }
-};
-
-static int
-tape_3590_online(struct ccw_device *cdev)
-{
-       return tape_generic_online(dev_get_drvdata(&cdev->dev),
-                                  &tape_discipline_3590);
-}
-
-static struct ccw_driver tape_3590_driver = {
-       .driver = {
-               .name = "tape_3590",
-               .owner = THIS_MODULE,
-       },
-       .ids = tape_3590_ids,
-       .probe = tape_generic_probe,
-       .remove = tape_generic_remove,
-       .set_offline = tape_generic_offline,
-       .set_online = tape_3590_online,
-       .int_class = IRQIO_TAP,
-};
-
-/*
- * Setup discipline structure.
- */
-static int
-tape_3590_init(void)
-{
-       int rc;
-
-       TAPE_DBF_AREA = debug_register("tape_3590", 2, 2, 4 * sizeof(long));
-       debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
-#ifdef DBF_LIKE_HELL
-       debug_set_level(TAPE_DBF_AREA, 6);
-#endif
-
-       DBF_EVENT(3, "3590 init\n");
-
-       tape_3590_wq = alloc_workqueue("tape_3590", WQ_PERCPU, 0);
-       if (!tape_3590_wq)
-               return -ENOMEM;
-
-       /* Register driver for 3590 tapes. */
-       rc = ccw_driver_register(&tape_3590_driver);
-       if (rc) {
-               destroy_workqueue(tape_3590_wq);
-               DBF_EVENT(3, "3590 init failed\n");
-       } else
-               DBF_EVENT(3, "3590 registered\n");
-       return rc;
-}
-
-static void
-tape_3590_exit(void)
-{
-       ccw_driver_unregister(&tape_3590_driver);
-       destroy_workqueue(tape_3590_wq);
-       debug_unregister(TAPE_DBF_AREA);
-}
-
-MODULE_DEVICE_TABLE(ccw, tape_3590_ids);
-MODULE_AUTHOR("(C) 2001,2006 IBM Corporation");
-MODULE_DESCRIPTION("Linux on zSeries channel attached 3590 tape device driver");
-MODULE_LICENSE("GPL");
-
-module_init(tape_3590_init);
-module_exit(tape_3590_exit);
diff --git a/drivers/s390/char/tape_3590.h b/drivers/s390/char/tape_3590.h
deleted file mode 100644 (file)
index b398d8a..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *    tape device discipline for 3590 tapes.
- *
- *    Copyright IBM Corp. 2001, 2006
- *    Author(s): Stefan Bader <shbader@de.ibm.com>
- *              Michael Holzheu <holzheu@de.ibm.com>
- *              Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#ifndef _TAPE_3590_H
-#define _TAPE_3590_H
-
-#define MEDIUM_SENSE   0xc2
-#define READ_PREVIOUS  0x0a
-#define MODE_SENSE     0xcf
-#define PERFORM_SS_FUNC 0x77
-#define READ_SS_DATA   0x3e
-
-#define PREP_RD_SS_DATA 0x18
-#define RD_ATTMSG      0x3
-
-#define SENSE_BRA_PER  0
-#define SENSE_BRA_CONT 1
-#define SENSE_BRA_RE   2
-#define SENSE_BRA_DRE  3
-
-#define SENSE_FMT_LIBRARY      0x23
-#define SENSE_FMT_UNSOLICITED  0x40
-#define SENSE_FMT_COMMAND_REJ  0x41
-#define SENSE_FMT_COMMAND_EXEC0 0x50
-#define SENSE_FMT_COMMAND_EXEC1 0x51
-#define SENSE_FMT_EVENT0       0x60
-#define SENSE_FMT_EVENT1       0x61
-#define SENSE_FMT_MIM          0x70
-#define SENSE_FMT_SIM          0x71
-
-#define MSENSE_UNASSOCIATED     0x00
-#define MSENSE_ASSOCIATED_MOUNT         0x01
-#define MSENSE_ASSOCIATED_UMOUNT 0x02
-#define MSENSE_CRYPT_MASK       0x00000010
-
-#define TAPE_3590_MAX_MSG       0xb0
-
-/* Datatypes */
-
-struct tape_3590_disc_data {
-       struct tape390_crypt_info crypt_info;
-       int read_back_op;
-};
-
-#define TAPE_3590_CRYPT_INFO(device) \
-       ((struct tape_3590_disc_data*)(device->discdata))->crypt_info
-#define TAPE_3590_READ_BACK_OP(device) \
-       ((struct tape_3590_disc_data*)(device->discdata))->read_back_op
-
-struct tape_3590_sense {
-
-       unsigned int command_rej:1;
-       unsigned int interv_req:1;
-       unsigned int bus_out_check:1;
-       unsigned int eq_check:1;
-       unsigned int data_check:1;
-       unsigned int overrun:1;
-       unsigned int def_unit_check:1;
-       unsigned int assgnd_elsew:1;
-
-       unsigned int locate_fail:1;
-       unsigned int inst_online:1;
-       unsigned int reserved:1;
-       unsigned int blk_seq_err:1;
-       unsigned int begin_part:1;
-       unsigned int wr_mode:1;
-       unsigned int wr_prot:1;
-       unsigned int not_cap:1;
-
-       unsigned int bra:2;
-       unsigned int lc:3;
-       unsigned int vlf_active:1;
-       unsigned int stm:1;
-       unsigned int med_pos:1;
-
-       unsigned int rac:8;
-
-       unsigned int rc_rqc:16;
-
-       unsigned int mc:8;
-
-       unsigned int sense_fmt:8;
-
-       union {
-               struct {
-                       unsigned int emc:4;
-                       unsigned int smc:4;
-                       unsigned int sev:2;
-                       unsigned int reserved:6;
-                       unsigned int md:8;
-                       unsigned int refcode:8;
-                       unsigned int mid:16;
-                       unsigned int mp:16;
-                       unsigned char volid[6];
-                       unsigned int fid:8;
-               } f70;
-               struct {
-                       unsigned int emc:4;
-                       unsigned int smc:4;
-                       unsigned int sev:2;
-                       unsigned int reserved1:5;
-                       unsigned int mdf:1;
-                       unsigned char md[3];
-                       unsigned int simid:8;
-                       unsigned int uid:16;
-                       unsigned int refcode1:16;
-                       unsigned int refcode2:16;
-                       unsigned int refcode3:16;
-                       unsigned int reserved2:8;
-               } f71;
-               unsigned char data[14];
-       } fmt;
-       unsigned char pad[10];
-
-} __attribute__ ((packed));
-
-struct tape_3590_med_sense {
-       unsigned int macst:4;
-       unsigned int masst:4;
-       char pad1[7];
-       unsigned int flags;
-       char pad2[116];
-} __attribute__ ((packed));
-
-struct tape_3590_rdc_data {
-       char data[64];
-} __attribute__ ((packed));
-
-/* Datastructures for 3592 encryption support */
-
-struct tape3592_kekl {
-       __u8 flags;
-       char label[64];
-} __attribute__ ((packed));
-
-struct tape3592_kekl_pair {
-       __u8 count;
-       struct tape3592_kekl kekl[2];
-} __attribute__ ((packed));
-
-struct tape3592_kekl_query_data {
-       __u16 len;
-       __u8  fmt;
-       __u8  mc;
-       __u32 id;
-       __u8  flags;
-       struct tape3592_kekl_pair kekls;
-       char reserved[116];
-} __attribute__ ((packed));
-
-struct tape3592_kekl_query_order {
-       __u8 code;
-       __u8 flags;
-       char reserved1[2];
-       __u8 max_count;
-       char reserved2[35];
-} __attribute__ ((packed));
-
-struct tape3592_kekl_set_order {
-       __u8 code;
-       __u8 flags;
-       char reserved1[2];
-       __u8 op;
-       struct tape3592_kekl_pair kekls;
-       char reserved2[120];
-} __attribute__ ((packed));
-
-#endif /* _TAPE_3590_H */
index 0250076a7d9f0acbfc5df3abfa0231dcf89bc474..7cf7167dcf56f5ed9736ce94227bc0b9d2d51440 100644 (file)
@@ -74,9 +74,7 @@ const char *tape_op_verbose[TO_SIZE] =
        [TO_LOAD] = "LOA",      [TO_READ_CONFIG] = "RCF",
        [TO_READ_ATTMSG] = "RAT",
        [TO_DIS] = "DIS",       [TO_ASSIGN] = "ASS",
-       [TO_UNASSIGN] = "UAS",  [TO_CRYPT_ON] = "CON",
-       [TO_CRYPT_OFF] = "COF", [TO_KEKL_SET] = "KLS",
-       [TO_KEKL_QUERY] = "KLQ",[TO_RDC] = "RDC",
+       [TO_UNASSIGN] = "UAS",  [TO_RDC] = "RDC",
 };
 
 static int devid_to_int(struct ccw_dev_id *dev_id)
index 2cf9f725b3b3fa0ca7debd09e837397d7a83dd07..5fef8b28309c4a3e8b3bbf50d38b71f8a48edb83 100644 (file)
@@ -135,8 +135,6 @@ void tape_std_process_eov(struct tape_device *);
 enum s390_tape_type {
         tape_3480,
         tape_3490,
-        tape_3590,
-        tape_3592,
 };
 
 #endif // _TAPE_STD_H