^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * standard tape device functions for ibm tapes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * S390 and zSeries version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright IBM Corp. 2001, 2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author(s): Carsten Otte <cotte@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Michael Holzheu <holzheu@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Tuan Ngo-Anh <ngoanh@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Martin Schwidefsky <schwidefsky@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Stefan Bader <shbader@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define KMSG_COMPONENT "tape"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/idals.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/ebcdic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/tape390.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define TAPE_DBF_AREA tape_core_dbf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "tape.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "tape_std.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * tape_std_assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) tape_std_assign_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct tape_request * request = from_timer(request, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct tape_device * device = request->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) BUG_ON(!device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) device->cdev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) rc = tape_cancel_io(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if(rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) DBF_EVENT(3, "(%08x): Assign timeout: Cancel failed with rc = "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) "%i\n", device->cdev_id, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) tape_std_assign(struct tape_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) request = tape_alloc_request(2, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) request->op = TO_ASSIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) tape_ccw_cc(request->cpaddr, ASSIGN, 11, request->cpdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * The assign command sometimes blocks if the device is assigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * to another host (actually this shouldn't happen but it does).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * So we set up a timeout for this call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) timer_setup(&request->timer, tape_std_assign_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) mod_timer(&request->timer, jiffies + msecs_to_jiffies(2000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) rc = tape_do_io_interruptible(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) del_timer_sync(&request->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) device->cdev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) DBF_EVENT(3, "%08x: Tape assigned\n", device->cdev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) tape_free_request(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * tape_std_unassign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) tape_std_unassign (struct tape_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (device->tape_state == TS_NOT_OPER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) DBF_EVENT(3, "(%08x): Can't unassign device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) device->cdev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) request = tape_alloc_request(2, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) request->op = TO_UNASSIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) tape_ccw_cc(request->cpaddr, UNASSIGN, 11, request->cpdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if ((rc = tape_do_io(device, request)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) tape_free_request(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * TAPE390_DISPLAY: Show a string on the tape display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) tape_std_display(struct tape_device *device, struct display_struct *disp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) request = tape_alloc_request(2, 17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (IS_ERR(request)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) DBF_EVENT(3, "TAPE: load display failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) request->op = TO_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *(unsigned char *) request->cpdata = disp->cntrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) DBF_EVENT(5, "TAPE: display cntrl=%04x\n", disp->cntrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) memcpy(((unsigned char *) request->cpdata) + 1, disp->message1, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) memcpy(((unsigned char *) request->cpdata) + 9, disp->message2, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ASCEBC(((unsigned char*) request->cpdata) + 1, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) tape_ccw_cc(request->cpaddr, LOAD_DISPLAY, 17, request->cpdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) rc = tape_do_io_interruptible(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) tape_free_request(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * Read block id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) tape_std_read_block_id(struct tape_device *device, __u64 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) request = tape_alloc_request(3, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) request->op = TO_RBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) tape_ccw_cc(request->cpaddr + 1, READ_BLOCK_ID, 8, request->cpdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) rc = tape_do_io(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Get result from read buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) *id = *(__u64 *) request->cpdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) tape_free_request(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) tape_std_terminate_write(struct tape_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if(device->required_tapemarks == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) DBF_LH(5, "tape%d: terminate write %dxEOF\n", device->first_minor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) device->required_tapemarks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) rc = tape_mtop(device, MTWEOF, device->required_tapemarks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) device->required_tapemarks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return tape_mtop(device, MTBSR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * MTLOAD: Loads the tape.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * The default implementation just wait until the tape medium state changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * to MS_LOADED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) tape_std_mtload(struct tape_device *device, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return wait_event_interruptible(device->state_change_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) (device->medium_state == MS_LOADED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * MTSETBLK: Set block size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) tape_std_mtsetblk(struct tape_device *device, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct idal_buffer *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) DBF_LH(6, "tape_std_mtsetblk(%d)\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (count <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * Just set block_size to 0. tapechar_read/tapechar_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * will realloc the idal buffer if a bigger one than the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * current is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) device->char_data.block_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (device->char_data.idal_buf != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) device->char_data.idal_buf->size == count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* We already have a idal buffer of that size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (count > MAX_BLOCKSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) count, MAX_BLOCKSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Allocate a new idal buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) new = idal_buffer_alloc(count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (IS_ERR(new))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (device->char_data.idal_buf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) idal_buffer_free(device->char_data.idal_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) device->char_data.idal_buf = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) device->char_data.block_size = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * MTRESET: Set block size to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) tape_std_mtreset(struct tape_device *device, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) DBF_EVENT(6, "TCHAR:devreset:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) device->char_data.block_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * MTFSF: Forward space over 'count' file marks. The tape is positioned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * at the EOT (End of Tape) side of the file mark.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) tape_std_mtfsf(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct ccw1 *ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) request = tape_alloc_request(mt_count + 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) request->op = TO_FSF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ccw = tape_ccw_end(ccw, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * MTFSR: Forward space over 'count' tape blocks (blocksize is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * via MTSETBLK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) tape_std_mtfsr(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct ccw1 *ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) request = tape_alloc_request(mt_count + 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) request->op = TO_FSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ccw = tape_ccw_repeat(ccw, FORSPACEBLOCK, mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ccw = tape_ccw_end(ccw, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) rc = tape_do_io(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (rc == 0 && request->rescnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) DBF_LH(3, "FSR over tapemark\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) tape_free_request(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * MTBSR: Backward space over 'count' tape blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * (blocksize is set via MTSETBLK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) tape_std_mtbsr(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct ccw1 *ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) request = tape_alloc_request(mt_count + 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) request->op = TO_BSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ccw = tape_ccw_repeat(ccw, BACKSPACEBLOCK, mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ccw = tape_ccw_end(ccw, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) rc = tape_do_io(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (rc == 0 && request->rescnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) DBF_LH(3, "BSR over tapemark\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) tape_free_request(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * MTWEOF: Write 'count' file marks at the current position.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) tape_std_mtweof(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct ccw1 *ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) request = tape_alloc_request(mt_count + 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) request->op = TO_WTM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ccw = tape_ccw_repeat(ccw, WRITETAPEMARK, mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ccw = tape_ccw_end(ccw, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * MTBSFM: Backward space over 'count' file marks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * The tape is positioned at the BOT (Begin Of Tape) side of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * last skipped file mark.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) tape_std_mtbsfm(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct ccw1 *ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) request = tape_alloc_request(mt_count + 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) request->op = TO_BSF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ccw = tape_ccw_end(ccw, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * MTBSF: Backward space over 'count' file marks. The tape is positioned at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * the EOT (End of Tape) side of the last skipped file mark.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) tape_std_mtbsf(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct ccw1 *ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) request = tape_alloc_request(mt_count + 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) request->op = TO_BSF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ccw = tape_ccw_end(ccw, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) rc = tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) rc = tape_mtop(device, MTFSR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (rc > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * MTFSFM: Forward space over 'count' file marks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * The tape is positioned at the BOT (Begin Of Tape) side
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * of the last skipped file mark.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) tape_std_mtfsfm(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct ccw1 *ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) request = tape_alloc_request(mt_count + 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) request->op = TO_FSF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ccw = tape_ccw_end(ccw, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) rc = tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) rc = tape_mtop(device, MTBSR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (rc > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * MTREW: Rewind the tape.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) tape_std_mtrew(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) request = tape_alloc_request(3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) request->op = TO_REW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * MTOFFL: Rewind the tape and put the drive off-line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * Implement 'rewind unload'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) tape_std_mtoffl(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) request = tape_alloc_request(3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) request->op = TO_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) tape_ccw_cc(request->cpaddr + 1, REWIND_UNLOAD, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * MTNOP: 'No operation'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) tape_std_mtnop(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) request = tape_alloc_request(2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) request->op = TO_NOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * MTEOM: positions at the end of the portion of the tape already used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * for recordind data. MTEOM positions after the last file mark, ready for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * appending another file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) tape_std_mteom(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * Seek from the beginning of tape (rewind).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if ((rc = tape_mtop(device, MTREW, 1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * The logical end of volume is given by two sewuential tapemarks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * Look for this by skipping to the next file (over one tapemark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * and then test for another one (fsr returns 1 if a tapemark was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * encountered).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if ((rc = tape_mtop(device, MTFSF, 1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if ((rc = tape_mtop(device, MTFSR, 1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) } while (rc == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return tape_mtop(device, MTBSR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) tape_std_mtreten(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) request = tape_alloc_request(4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) request->op = TO_FSF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) tape_ccw_cc(request->cpaddr + 1,FORSPACEFILE, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* execute it, MTRETEN rc gets ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) tape_do_io_interruptible(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) tape_free_request(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return tape_mtop(device, MTREW, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * MTERASE: erases the tape.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) tape_std_mterase(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) request = tape_alloc_request(6, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) request->op = TO_DSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) tape_ccw_cc(request->cpaddr + 2, ERASE_GAP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) tape_ccw_cc(request->cpaddr + 3, DATA_SEC_ERASE, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) tape_ccw_cc(request->cpaddr + 4, REWIND, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) tape_ccw_end(request->cpaddr + 5, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * MTUNLOAD: Rewind the tape and unload it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) tape_std_mtunload(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return tape_mtop(device, MTOFFL, mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * MTCOMPRESSION: used to enable compression.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * Sets the IDRC on/off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) tape_std_mtcompression(struct tape_device *device, int mt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (mt_count < 0 || mt_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) DBF_EXCEPTION(6, "xcom parm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) request = tape_alloc_request(2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (IS_ERR(request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return PTR_ERR(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) request->op = TO_NOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* setup ccws */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (mt_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) *device->modeset_byte &= ~0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) *device->modeset_byte |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* execute it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return tape_do_io_free(device, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * Read Block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct tape_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) tape_std_read_block(struct tape_device *device, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * We have to alloc 4 ccws in order to be able to transform request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * into a read backward request in error case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) request = tape_alloc_request(4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (IS_ERR(request)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) DBF_EXCEPTION(6, "xrbl fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) request->op = TO_RFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) tape_ccw_end_idal(request->cpaddr + 1, READ_FORWARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) device->char_data.idal_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) DBF_EVENT(6, "xrbl ccwg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * Read Block backward transformation function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) tape_std_read_backward(struct tape_device *device, struct tape_request *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * We have allocated 4 ccws in tape_std_read, so we can now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * transform the request to a read backward, followed by a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * forward space block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) request->op = TO_RBA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) tape_ccw_cc_idal(request->cpaddr + 1, READ_BACKWARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) device->char_data.idal_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) DBF_EVENT(6, "xrop ccwg");}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * Write Block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct tape_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) tape_std_write_block(struct tape_device *device, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct tape_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) request = tape_alloc_request(2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (IS_ERR(request)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) DBF_EXCEPTION(6, "xwbl fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) request->op = TO_WRI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) tape_ccw_end_idal(request->cpaddr + 1, WRITE_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) device->char_data.idal_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) DBF_EVENT(6, "xwbl ccwg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * This routine is called by frontend after an ENOSP on write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) tape_std_process_eov(struct tape_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * End of volume: We have to backspace the last written record, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * we TRY to write a tapemark and then backspace over the written TM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (tape_mtop(device, MTBSR, 1) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) tape_mtop(device, MTWEOF, 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) tape_mtop(device, MTBSR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) EXPORT_SYMBOL(tape_std_assign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) EXPORT_SYMBOL(tape_std_unassign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) EXPORT_SYMBOL(tape_std_display);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) EXPORT_SYMBOL(tape_std_read_block_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) EXPORT_SYMBOL(tape_std_mtload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) EXPORT_SYMBOL(tape_std_mtsetblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) EXPORT_SYMBOL(tape_std_mtreset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) EXPORT_SYMBOL(tape_std_mtfsf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) EXPORT_SYMBOL(tape_std_mtfsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) EXPORT_SYMBOL(tape_std_mtbsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) EXPORT_SYMBOL(tape_std_mtweof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) EXPORT_SYMBOL(tape_std_mtbsfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) EXPORT_SYMBOL(tape_std_mtbsf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) EXPORT_SYMBOL(tape_std_mtfsfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) EXPORT_SYMBOL(tape_std_mtrew);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) EXPORT_SYMBOL(tape_std_mtoffl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) EXPORT_SYMBOL(tape_std_mtnop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) EXPORT_SYMBOL(tape_std_mteom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) EXPORT_SYMBOL(tape_std_mtreten);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) EXPORT_SYMBOL(tape_std_mterase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) EXPORT_SYMBOL(tape_std_mtunload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) EXPORT_SYMBOL(tape_std_mtcompression);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) EXPORT_SYMBOL(tape_std_read_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) EXPORT_SYMBOL(tape_std_read_backward);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) EXPORT_SYMBOL(tape_std_write_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) EXPORT_SYMBOL(tape_std_process_eov);