diff options
Diffstat (limited to 'drivers/s390/char/tape_3590.c')
| -rw-r--r-- | drivers/s390/char/tape_3590.c | 126 |
1 files changed, 16 insertions, 110 deletions
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 327cb19ad0b0..0d80f43b175d 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * tape device discipline for 3590 tapes. * @@ -7,9 +8,9 @@ * Martin Schwidefsky <schwidefsky@de.ibm.com> */ -#define KMSG_COMPONENT "tape_3590" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape_3590: " fmt +#include <linux/export.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/init.h> @@ -112,16 +113,16 @@ static int crypt_enabled(struct tape_device *device) static void ext_to_int_kekl(struct tape390_kekl *in, struct tape3592_kekl *out) { - int i; + 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; - strncpy(out->label, in->label, 64); - for (i = strlen(in->label); i < sizeof(out->label); i++) - out->label[i] = ' '; + 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)); } @@ -312,15 +313,10 @@ static int tape_3592_ioctl_kekl_set(struct tape_device *device, return -ENOSYS; if (!crypt_enabled(device)) return -EUNATCH; - ext_kekls = kmalloc(sizeof(*ext_kekls), GFP_KERNEL); - if (!ext_kekls) - return -ENOMEM; - if (copy_from_user(ext_kekls, (char __user *)arg, sizeof(*ext_kekls))) { - rc = -EFAULT; - goto out; - } + 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); -out: kfree(ext_kekls); return rc; } @@ -554,31 +550,6 @@ tape_3590_mtseek(struct tape_device *device, int count) } /* - * Read Opposite Error Recovery Function: - * Used, when Read Forward does not work - */ -static void -tape_3590_read_opposite(struct tape_device *device, - struct tape_request *request) -{ - struct tape_3590_disc_data *data; - - /* - * We have allocated 4 ccws in tape_std_read, so we can now - * transform the request to a read backward, followed by a - * forward space block. - */ - request->op = TO_RBA; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - data = device->discdata; - tape_ccw_cc_idal(request->cpaddr + 1, data->read_back_op, - device->char_data.idal_buf); - tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL); - tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL); - DBF_EVENT(6, "xrop ccwg\n"); -} - -/* * Read Attention Msg * This should be done after an interrupt with attention bit (0x80) * in device state. @@ -765,7 +736,7 @@ tape_3590_done(struct tape_device *device, struct tape_request *request) * This function is called, when error recovery was successful */ static inline int -tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request) +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]); @@ -835,7 +806,7 @@ tape_3590_erp_basic(struct tape_device *device, struct tape_request *request, case SENSE_BRA_PER: return tape_3590_erp_failed(device, request, irb, rc); case SENSE_BRA_CONT: - return tape_3590_erp_succeded(device, request); + return tape_3590_erp_succeeded(device, request); case SENSE_BRA_RE: return tape_3590_erp_retry(device, request, irb); case SENSE_BRA_DRE: @@ -900,60 +871,6 @@ tape_3590_erp_special_interrupt(struct tape_device *device, } /* - * RDA: Read Alternate - */ -static int -tape_3590_erp_read_alternate(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - struct tape_3590_disc_data *data; - - /* - * The issued Read Backward or Read Previous command is not - * supported by the device - * The recovery action should be to issue another command: - * Read Revious: if Read Backward is not supported - * Read Backward: if Read Previous is not supported - */ - data = device->discdata; - if (data->read_back_op == READ_PREVIOUS) { - DBF_EVENT(2, "(%08x): No support for READ_PREVIOUS command\n", - device->cdev_id); - data->read_back_op = READ_BACKWARD; - } else { - DBF_EVENT(2, "(%08x): No support for READ_BACKWARD command\n", - device->cdev_id); - data->read_back_op = READ_PREVIOUS; - } - tape_3590_read_opposite(device, request); - return tape_3590_erp_retry(device, request, irb); -} - -/* - * Error Recovery read opposite - */ -static int -tape_3590_erp_read_opposite(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - switch (request->op) { - case TO_RFO: - /* - * We did read forward, but the data could not be read. - * We will read backward and then skip forward again. - */ - tape_3590_read_opposite(device, request); - return tape_3590_erp_retry(device, request, irb); - case TO_RBA: - /* We tried to read forward and backward, but hat no success */ - return tape_3590_erp_failed(device, request, irb, -EIO); - break; - default: - return tape_3590_erp_failed(device, request, irb, -EIO); - } -} - -/* * Print an MIM (Media Information Message) (message code f0) */ static void @@ -975,7 +892,7 @@ tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb) snprintf(exception, BUFSIZE, "Data degraded"); break; case 0x03: - snprintf(exception, BUFSIZE, "Data degraded in partion %i", + snprintf(exception, BUFSIZE, "Data degraded in partition %i", sense->fmt.f70.mp); break; case 0x04: @@ -1090,7 +1007,7 @@ tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb) "channel path 0x%x on CU", sense->fmt.f71.md[1]); else - snprintf(service, BUFSIZE, "Repair will disable cannel" + 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; @@ -1351,10 +1268,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, tape_3590_print_era_msg(device, irb); return tape_3590_erp_read_buf_log(device, request, irb); - case 0x2011: - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_alternate(device, request, irb); - case 0x2230: case 0x2231: tape_3590_print_era_msg(device, irb); @@ -1408,12 +1321,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, tape_3590_print_era_msg(device, irb); return tape_3590_erp_swap(device, request, irb); } - if (sense->rac == 0x26) { - /* Read Opposite */ - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_opposite(device, request, - irb); - } return tape_3590_erp_basic(device, request, irb, -EIO); case 0x5020: case 0x5021: @@ -1481,7 +1388,7 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request, } if (irb->scsw.cmd.dstat & DEV_STAT_CHN_END) { - DBF_EVENT(2, "cannel end\n"); + DBF_EVENT(2, "channel end\n"); return TAPE_IO_PENDING; } @@ -1655,7 +1562,6 @@ static struct ccw_driver tape_3590_driver = { .remove = tape_generic_remove, .set_offline = tape_generic_offline, .set_online = tape_3590_online, - .freeze = tape_generic_pm_suspend, .int_class = IRQIO_TAP, }; @@ -1675,7 +1581,7 @@ tape_3590_init(void) DBF_EVENT(3, "3590 init\n"); - tape_3590_wq = alloc_workqueue("tape_3590", 0, 0); + tape_3590_wq = alloc_workqueue("tape_3590", WQ_PERCPU, 0); if (!tape_3590_wq) return -ENOMEM; |
