Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);