^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) file Documentation/scsi/st.rst for more information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) History:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) Contribution and ideas from several people including (in alphabetical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) order) Klaus Ehrenfried, Eugene Exarevsky, Eric Lee Green, Wolfgang Denk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) Michael Schaefer, J"org Weule, and Eric Youngdale.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) Copyright 1992 - 2016 Kai Makisara
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) email Kai.Makisara@kolumbus.fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) Some small formal changes - aeb, 950809
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static const char *verstr = "20160209";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/mtio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/cdrom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <scsi/scsi_dbg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <scsi/scsi_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <scsi/scsi_eh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <scsi/scsi_ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <scsi/sg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* The driver prints some debugging information on the console if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) is defined and non-zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define DEBUG 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define NO_DEBUG 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define ST_DEB_MSG KERN_NOTICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* The message level for the debug messages is currently set to KERN_NOTICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) so that people can easily see the messages. Later when the debugging messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define DEB(a) a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define DEBC(a) if (debugging) { a ; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define DEB(a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define DEBC(a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define ST_KILOBYTE 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include "st_options.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include "st.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int buffer_kbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int max_sg_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int try_direct_io = TRY_DIRECT_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int try_rdio = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static int try_wdio = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static int debug_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static struct class st_sysfs_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static const struct attribute_group *st_dev_groups[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static const struct attribute_group *st_drv_groups[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) MODULE_AUTHOR("Kai Makisara");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MODULE_DESCRIPTION("SCSI tape (st) driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* Set 'perm' (4th argument) to 0 to disable module_param's definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * of sysfs parameters (which module_param doesn't yet support).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * Sysfs parameters defined explicitly later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) module_param_named(buffer_kbs, buffer_kbs, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size for fixed block mode (KB; 32)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) module_param_named(max_sg_segs, max_sg_segs, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (256)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) module_param_named(try_direct_io, try_direct_io, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) MODULE_PARM_DESC(try_direct_io, "Try direct I/O between user buffer and tape drive (1)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) module_param_named(debug_flag, debug_flag, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) MODULE_PARM_DESC(debug_flag, "Enable DEBUG, same as setting debugging=1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* Extra parameters for testing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) module_param_named(try_rdio, try_rdio, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) MODULE_PARM_DESC(try_rdio, "Try direct read i/o when possible");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) module_param_named(try_wdio, try_wdio, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) MODULE_PARM_DESC(try_wdio, "Try direct write i/o when possible");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int write_threshold_kbs; /* retained for compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static struct st_dev_parm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) } parms[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "buffer_kbs", &buffer_kbs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) { /* Retained for compatibility with 2.4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "write_threshold_kbs", &write_threshold_kbs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "max_sg_segs", NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) "try_direct_io", &try_direct_io
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "debug_flag", &debug_flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Restrict the number of modes so that names for all are assigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #if ST_NBR_MODES > 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #error "Maximum number of modes is 16"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* Bit reversed order to get same names for same minors with all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mode counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static const char *st_formats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) "", "r", "k", "s", "l", "t", "o", "u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) "m", "v", "p", "x", "a", "y", "q", "z"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* The default definitions have been moved to st_options.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define ST_FIXED_BUFFER_SIZE (ST_FIXED_BUFFER_BLOCKS * ST_KILOBYTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* The buffer size should fit into the 24 bits for length in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 6-byte SCSI read and write commands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #if ST_FIXED_BUFFER_SIZE >= (2 << 24 - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int debugging = DEBUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define MAX_RETRIES 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define MAX_WRITE_RETRIES 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define MAX_READY_RETRIES 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define NO_TAPE NOT_READY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define ST_TIMEOUT (900 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define ST_LONG_TIMEOUT (14000 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Remove mode bits and auto-rewind bit (7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define TAPE_NR(x) ( ((iminor(x) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) (iminor(x) & ((1 << ST_MODE_SHIFT)-1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Construct the minor number from the device (d), mode (m), and non-rewind (n) data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define TAPE_MINOR(d, m, n) (((d & ~(255 >> (ST_NBR_MODE_BITS + 1))) << (ST_NBR_MODE_BITS + 1)) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) (d & (255 >> (ST_NBR_MODE_BITS + 1))) | (m << ST_MODE_SHIFT) | ((n != 0) << 7) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 24 bits) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define SET_DENS_AND_BLK 0x10001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int st_max_sg_segs = ST_MAX_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static int modes_defined;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int enlarge_buffer(struct st_buffer *, int, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void clear_buffer(struct st_buffer *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static void normalize_buffer(struct st_buffer *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static int append_to_buffer(const char __user *, struct st_buffer *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int from_buffer(struct st_buffer *, char __user *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static void move_buffer_data(struct st_buffer *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int sgl_map_user_pages(struct st_buffer *, const unsigned int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned long, size_t, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int st_probe(struct device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int st_remove(struct device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static struct scsi_driver st_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .gendrv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .name = "st",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .probe = st_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .remove = st_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .groups = st_drv_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static int st_compression(struct scsi_tape *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int find_partition(struct scsi_tape *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int switch_partition(struct scsi_tape *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void scsi_tape_release(struct kref *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static DEFINE_MUTEX(st_ref_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static DEFINE_SPINLOCK(st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static DEFINE_SPINLOCK(st_use_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static DEFINE_IDR(st_index_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #ifndef SIGS_FROM_OSST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define SIGS_FROM_OSST \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {"OnStream", "SC-", "", "osst"}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {"OnStream", "DI-", "", "osst"}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {"OnStream", "DP-", "", "osst"}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {"OnStream", "USB", "", "osst"}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {"OnStream", "FW-", "", "osst"}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static struct scsi_tape *scsi_tape_get(int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct scsi_tape *STp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) mutex_lock(&st_ref_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) spin_lock(&st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) STp = idr_find(&st_index_idr, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!STp) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) kref_get(&STp->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!STp->device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (scsi_device_get(STp->device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) kref_put(&STp->kref, scsi_tape_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) STp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) spin_unlock(&st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) mutex_unlock(&st_ref_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return STp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static void scsi_tape_put(struct scsi_tape *STp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct scsi_device *sdev = STp->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) mutex_lock(&st_ref_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) kref_put(&STp->kref, scsi_tape_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) scsi_device_put(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) mutex_unlock(&st_ref_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct st_reject_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) char *vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) char *model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) char *rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) char *driver_hint; /* Name of the correct driver, NULL if unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static struct st_reject_data reject_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* {"XXX", "Yy-", "", NULL}, example */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) SIGS_FROM_OSST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {NULL, }};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* If the device signature is on the list of incompatible drives, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) function returns a pointer to the name of the correct driver (if known) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static char * st_incompatible(struct scsi_device* SDp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct st_reject_data *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (rp->driver_hint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return rp->driver_hint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static inline char *tape_name(struct scsi_tape *tape)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return tape->disk->disk_name;
^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) #define st_printk(prefix, t, fmt, a...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) sdev_prefix_printk(prefix, (t)->device, tape_name(t), fmt, ##a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) #define DEBC_printk(t, fmt, a...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (debugging) { st_printk(ST_DEB_MSG, t, fmt, ##a ); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #define DEBC_printk(t, fmt, a...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) const u8 *ucp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) const u8 *sense = SRpnt->sense;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) s->have_sense = scsi_normalize_sense(SRpnt->sense,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) s->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (s->have_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) s->deferred = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) s->remainder_valid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) switch (sense[0] & 0x7f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case 0x71:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) s->deferred = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) case 0x70:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) s->fixed_format = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) s->flags = sense[2] & 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case 0x73:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) s->deferred = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case 0x72:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) s->fixed_format = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) s->flags = ucp ? (ucp[3] & 0xe0) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* Convert the result to success code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int result = SRpnt->result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u8 scode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) DEB(const char *stp;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) char *name = tape_name(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct st_cmdstatus *cmdstatp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (!result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) cmdstatp = &STp->buffer->cmdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) st_analyze_sense(SRpnt, cmdstatp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (cmdstatp->have_sense)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) scode = STp->buffer->cmdstat.sense_hdr.sense_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) scode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (debugging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) "Error: %x, cmd: %x %x %x %x %x %x\n", result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (cmdstatp->have_sense)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) __scsi_print_sense(STp->device, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) } ) /* end DEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!debugging) { /* Abnormal conditions for tape */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!cmdstatp->have_sense)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) "Error %x (driver bt 0x%x, host bt 0x%x).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) result, driver_byte(result), host_byte(result));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) else if (cmdstatp->have_sense &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) scode != NO_SENSE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) scode != RECOVERED_ERROR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* scode != UNIT_ATTENTION && */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) scode != BLANK_CHECK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) scode != VOLUME_OVERFLOW &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) SRpnt->cmd[0] != MODE_SENSE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) SRpnt->cmd[0] != TEST_UNIT_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) __scsi_print_sense(STp->device, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (cmdstatp->fixed_format &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (STp->cln_sense_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) STp->cln_sense_mask) == STp->cln_sense_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) STp->cln_sense_mask) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (cmdstatp->have_sense &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) STp->pos_unknown |= STp->device->was_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (cmdstatp->have_sense &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) scode == RECOVERED_ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) #if ST_RECOVERED_WRITE_FATAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) && SRpnt->cmd[0] != WRITE_6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) && SRpnt->cmd[0] != WRITE_FILEMARKS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) STp->recover_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) STp->recover_reg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (debugging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (SRpnt->cmd[0] == READ_6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) stp = "read";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) else if (SRpnt->cmd[0] == WRITE_6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) stp = "write";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) stp = "ioctl";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) "Recovered %s error (%d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) stp, STp->recover_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) } ) /* end DEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (cmdstatp->flags == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static struct st_request *st_allocate_request(struct scsi_tape *stp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct st_request *streq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) streq = kzalloc(sizeof(*streq), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (streq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) streq->stp = stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) st_printk(KERN_ERR, stp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) "Can't get SCSI request.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) stp->buffer->syscall_result = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) stp->buffer->syscall_result = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return streq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static void st_release_request(struct st_request *streq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) kfree(streq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static void st_do_stats(struct scsi_tape *STp, struct request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ktime_t now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) now = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (scsi_req(req)->cmd[0] == WRITE_6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) now = ktime_sub(now, STp->stats->write_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) atomic64_add(ktime_to_ns(now), &STp->stats->tot_write_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) atomic64_inc(&STp->stats->write_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (scsi_req(req)->result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) atomic64_add(atomic_read(&STp->stats->last_write_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) - STp->buffer->cmdstat.residual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) &STp->stats->write_byte_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (STp->buffer->cmdstat.residual > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) atomic64_inc(&STp->stats->resid_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) atomic64_add(atomic_read(&STp->stats->last_write_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) &STp->stats->write_byte_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) } else if (scsi_req(req)->cmd[0] == READ_6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) now = ktime_sub(now, STp->stats->read_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) atomic64_add(ktime_to_ns(now), &STp->stats->tot_read_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) atomic64_inc(&STp->stats->read_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (scsi_req(req)->result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) atomic64_add(atomic_read(&STp->stats->last_read_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) - STp->buffer->cmdstat.residual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) &STp->stats->read_byte_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (STp->buffer->cmdstat.residual > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) atomic64_inc(&STp->stats->resid_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) atomic64_add(atomic_read(&STp->stats->last_read_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) &STp->stats->read_byte_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) now = ktime_sub(now, STp->stats->other_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) atomic64_inc(&STp->stats->other_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) atomic64_dec(&STp->stats->in_flight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static void st_scsi_execute_end(struct request *req, blk_status_t status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct st_request *SRpnt = req->end_io_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct scsi_request *rq = scsi_req(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct scsi_tape *STp = SRpnt->stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct bio *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) STp->buffer->cmdstat.midlevel_result = SRpnt->result = rq->result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) STp->buffer->cmdstat.residual = rq->resid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) st_do_stats(STp, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) tmp = SRpnt->bio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (rq->sense_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) memcpy(SRpnt->sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (SRpnt->waiting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) complete(SRpnt->waiting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) blk_rq_unmap_user(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) blk_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) int data_direction, void *buffer, unsigned bufflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int timeout, int retries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct scsi_request *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct scsi_tape *STp = SRpnt->stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) req = blk_get_request(SRpnt->stp->device->request_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) data_direction == DMA_TO_DEVICE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return DRIVER_ERROR << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) rq = scsi_req(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) req->rq_flags |= RQF_QUIET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) mdata->null_mapped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (bufflen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) blk_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return DRIVER_ERROR << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) atomic64_inc(&STp->stats->in_flight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (cmd[0] == WRITE_6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) atomic_set(&STp->stats->last_write_size, bufflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) STp->stats->write_time = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) } else if (cmd[0] == READ_6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) atomic_set(&STp->stats->last_read_size, bufflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) STp->stats->read_time = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) STp->stats->other_time = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) SRpnt->bio = req->bio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) rq->cmd_len = COMMAND_SIZE(cmd[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) memset(rq->cmd, 0, BLK_MAX_CDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) memcpy(rq->cmd, cmd, rq->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) req->timeout = timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) rq->retries = retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) req->end_io_data = SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* Do the scsi command. Waits until command performed if do_wait is true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) Otherwise write_behind_check() is used to check that the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) has finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static struct st_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) int bytes, int direction, int timeout, int retries, int do_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct completion *waiting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct rq_map_data *mdata = &STp->buffer->map_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* if async, make sure there's no command outstanding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (!do_wait && ((STp->buffer)->last_SRpnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) st_printk(KERN_ERR, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) "Async command already active.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) (STp->buffer)->syscall_result = (-EINTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) (STp->buffer)->syscall_result = (-EBUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (!SRpnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) SRpnt = st_allocate_request(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /* If async IO, set last_SRpnt. This ptr tells write_behind_check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) which IO is outstanding. It's nulled out when the IO completes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (!do_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) (STp->buffer)->last_SRpnt = SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) waiting = &STp->wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) init_completion(waiting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) SRpnt->waiting = waiting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (STp->buffer->do_dio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) mdata->page_order = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) mdata->nr_entries = STp->buffer->sg_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) mdata->pages = STp->buffer->mapped_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) mdata->page_order = STp->buffer->reserved_page_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) mdata->nr_entries =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) mdata->pages = STp->buffer->reserved_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) mdata->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) STp->buffer->cmdstat.have_sense = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) STp->buffer->syscall_result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* could not allocate the buffer or request was too large */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) (STp->buffer)->syscall_result = (-EBUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) (STp->buffer)->last_SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) } else if (do_wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) wait_for_completion(waiting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) SRpnt->waiting = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) write has been correct but EOM early warning reached, -EIO if write ended in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) error or zero if write successful. Asynchronous writes are used only in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) variable block mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int write_behind_check(struct scsi_tape * STp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct st_buffer *STbuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct st_cmdstatus *cmdstatp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) STbuffer = STp->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (!STbuffer->writing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (STp->write_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) STp->nbr_waits++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) STp->nbr_finished++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) ) /* end DEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) wait_for_completion(&(STp->wait));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) SRpnt = STbuffer->last_SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) STbuffer->last_SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) SRpnt->waiting = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) STbuffer->buffer_bytes -= STbuffer->writing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (STps->drv_block >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) STps->drv_block++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) STps->drv_block += STbuffer->writing / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) cmdstatp = &STbuffer->cmdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (STbuffer->syscall_result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (cmdstatp->have_sense && !cmdstatp->deferred &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) (cmdstatp->flags & SENSE_EOM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* EOM at write-behind, has all data been written? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!cmdstatp->remainder_valid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) cmdstatp->uremainder64 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) retval = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (retval == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) STps->drv_block = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) STbuffer->writing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) DEB(if (debugging && retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) "Async write error %x, return value %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /* Step over EOF if it has been inadvertently crossed (ioctl not used because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) it messes up the block number). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) static int cross_eof(struct scsi_tape * STp, int forward)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) cmd[0] = SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) cmd[1] = 0x01; /* Space FileMarks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (forward) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) cmd[2] = cmd[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) cmd[4] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) cmd[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) DEBC_printk(STp, "Stepping over filemark %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) forward ? "forward" : "backward");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) STp->device->request_queue->rq_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) MAX_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if ((STp->buffer)->cmdstat.midlevel_result != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) st_printk(KERN_ERR, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) "Stepping over filemark %s failed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) forward ? "forward" : "backward");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* Flush the write buffer (never need to write if variable blocksize). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static int st_flush_write_buffer(struct scsi_tape * STp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) int transfer, blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) result = write_behind_check(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (STp->dirty == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) transfer = STp->buffer->buffer_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) DEBC_printk(STp, "Flushing %d bytes.\n", transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) memset(cmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) cmd[0] = WRITE_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) cmd[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) blks = transfer / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) cmd[2] = blks >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) cmd[3] = blks >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) cmd[4] = blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) STp->device->request_queue->rq_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) MAX_WRITE_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if ((STp->buffer)->syscall_result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (cmdstatp->have_sense && !cmdstatp->deferred &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) (cmdstatp->flags & SENSE_EOM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) (!cmdstatp->remainder_valid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) STp->dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) (STp->buffer)->buffer_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (STps->drv_block >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) STps->drv_block += blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) result = (-ENOSPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) st_printk(KERN_ERR, STp, "Error on flush.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) STps->drv_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) result = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (STps->drv_block >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) STps->drv_block += blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) STp->dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) (STp->buffer)->buffer_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* Flush the tape buffer. The tape will be positioned correctly unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) seek_next is true. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static int flush_buffer(struct scsi_tape *STp, int seek_next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) int backspace, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * If there was a bus reset, block further access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * to this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (STp->pos_unknown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (STp->ready != ST_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (STps->rw == ST_WRITING) /* Writing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return st_flush_write_buffer(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) backspace = ((STp->buffer)->buffer_bytes +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) (STp->buffer)->read_pointer) / STp->block_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) ((STp->buffer)->read_pointer + STp->block_size - 1) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) (STp->buffer)->buffer_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) (STp->buffer)->read_pointer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!seek_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (STps->eof == ST_FM_HIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) result = cross_eof(STp, 0); /* Back over the EOF hit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (!result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) STps->drv_file++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (!result && backspace > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) result = st_int_ioctl(STp, MTBSR, backspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) } else if (STps->eof == ST_FM_HIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) STps->drv_file++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* Set the mode parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) int set_it = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) unsigned long arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (!STp->density_changed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) STm->default_density >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) STm->default_density != STp->density) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) arg = STm->default_density;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) set_it = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) arg = STp->density;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) arg <<= MT_ST_DENSITY_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (!STp->blksize_changed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) STm->default_blksize >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) STm->default_blksize != STp->block_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) arg |= STm->default_blksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) set_it = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) arg |= STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (set_it &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) "Can't set default block size to %d bytes "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) "and density %x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) STm->default_blksize, STm->default_density);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (modes_defined)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /* Lock or unlock the drive door. Don't use when st_request allocated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) static int do_door_lock(struct scsi_tape * STp, int do_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) DEBC_printk(STp, "%socking drive door.\n", do_lock ? "L" : "Unl");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) retval = scsi_set_medium_removal(STp->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) do_lock ? SCSI_REMOVAL_PREVENT : SCSI_REMOVAL_ALLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) STp->door_locked = ST_LOCK_FAILS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) /* Set the internal state after reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) static void reset_state(struct scsi_tape *STp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) STp->pos_unknown = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) for (i = 0; i < ST_NBR_PARTITIONS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) STps = &(STp->ps[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) STps->rw = ST_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) STps->at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) STps->last_block_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) STps->drv_block = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) STps->drv_file = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (STp->can_partitions) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) STp->partition = find_partition(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (STp->partition < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) STp->partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) STp->new_partition = STp->partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /* Test if the drive is ready. Returns either one of the codes below or a negative system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) error code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) #define CHKRES_READY 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) #define CHKRES_NEW_SESSION 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) #define CHKRES_NOT_READY 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) #define CHKRES_NO_TAPE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) #define MAX_ATTENTIONS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static int test_ready(struct scsi_tape *STp, int do_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) int attentions, waits, max_wait, scode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int retval = CHKRES_READY, new_session = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct st_request *SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) for (attentions=waits=0; ; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) cmd[0] = TEST_UNIT_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) STp->long_timeout, MAX_READY_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (!SRpnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) retval = (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (cmdstatp->have_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) scode = cmdstatp->sense_hdr.sense_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (scode == UNIT_ATTENTION) { /* New media? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) new_session = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (attentions < MAX_ATTENTIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) attentions++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (scode == NOT_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (waits < max_wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (msleep_interruptible(1000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) retval = (-EINTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) waits++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if ((STp->device)->scsi_level >= SCSI_2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) retval = CHKRES_NO_TAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) retval = CHKRES_NOT_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) retval = (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (SRpnt != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* See if the drive is ready and gather information about the tape. Return values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) < 0 negative error code from errno.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 0 drive ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 1 drive not ready (possibly no tape)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static int check_tape(struct scsi_tape *STp, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) int i, retval, new_session = 0, do_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) unsigned short st_flags = filp->f_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct st_request *SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct st_modedef *STm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) int mode = TAPE_MODE(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) STp->ready = ST_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (mode != STp->current_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) DEBC_printk(STp, "Mode change from %d to %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) STp->current_mode, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) new_session = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) STp->current_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) STm = &(STp->modes[STp->current_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) saved_cleaning = STp->cleaning_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) STp->cleaning_req = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) retval = test_ready(STp, do_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (retval == CHKRES_NEW_SESSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) STp->pos_unknown = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) STp->partition = STp->new_partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (STp->can_partitions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) STp->nbr_partitions = 1; /* This guess will be updated later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) for (i = 0; i < ST_NBR_PARTITIONS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) STps = &(STp->ps[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) STps->rw = ST_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) STps->at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) STps->last_block_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) STps->drv_file = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) new_session = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) STp->cleaning_req |= saved_cleaning;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (retval == CHKRES_NO_TAPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) STp->ready = ST_NO_TAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) STp->ready = ST_NOT_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) STp->density = 0; /* Clear the erroneous "residue" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) STp->write_prot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) STp->block_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) STp->partition = STp->new_partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) STp->door_locked = ST_UNLOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return CHKRES_NOT_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (STp->omit_blklims)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) STp->min_block = STp->max_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) cmd[0] = READ_BLOCK_LIMITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) STp->device->request_queue->rq_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) MAX_READY_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (!SRpnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) retval = (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) STp->max_block = ((STp->buffer)->b_data[1] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) STp->min_block = ((STp->buffer)->b_data[4] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) (STp->buffer)->b_data[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if ( DEB( debugging || ) !STp->inited)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) st_printk(KERN_INFO, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) "Block limits %d - %d bytes.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) STp->min_block, STp->max_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) STp->min_block = STp->max_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) DEBC_printk(STp, "Can't read block limits.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) cmd[0] = MODE_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) cmd[4] = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) STp->device->request_queue->rq_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) MAX_READY_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (!SRpnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) retval = (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if ((STp->buffer)->syscall_result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) DEBC_printk(STp, "No Mode Sense.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) STp->drv_write_prot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) DEBC_printk(STp,"Mode sense. Length %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) "medium %x, WBS %x, BLL %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) (STp->buffer)->b_data[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) (STp->buffer)->b_data[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) (STp->buffer)->b_data[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) (STp->buffer)->b_data[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if ((STp->buffer)->b_data[3] >= 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) STp->density = (STp->buffer)->b_data[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) STp->block_size = (STp->buffer)->b_data[9] * 65536 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) DEBC_printk(STp, "Density %x, tape length: %x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) "drv buffer: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) STp->density,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) (STp->buffer)->b_data[5] * 65536 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) (STp->buffer)->b_data[6] * 256 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) (STp->buffer)->b_data[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) STp->drv_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (!STp->drv_buffer && STp->immediate_filemark) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) "non-buffered tape: disabling "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) "writing immediate filemarks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) STp->immediate_filemark = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) STp->inited = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (STp->block_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) (STp->buffer)->buffer_blocks =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) (STp->buffer)->buffer_size / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) (STp->buffer)->buffer_blocks = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) DEBC_printk(STp, "Block size: %d, buffer size: %d (%d blocks).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) STp->block_size, (STp->buffer)->buffer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) (STp->buffer)->buffer_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (STp->drv_write_prot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) STp->write_prot = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) DEBC_printk(STp, "Write protected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (do_wait &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ((st_flags & O_ACCMODE) == O_WRONLY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) (st_flags & O_ACCMODE) == O_RDWR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) retval = (-EROFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (STp->can_partitions && STp->nbr_partitions < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) /* This code is reached when the device is opened for the first time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) after the driver has been initialized with tape in the drive and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) partition support has been enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) DEBC_printk(STp, "Updating partition number in status.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if ((STp->partition = find_partition(STp)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) retval = STp->partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) STp->new_partition = STp->partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) STp->nbr_partitions = 1; /* This guess will be updated when necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (new_session) { /* Change the drive parameters for the new mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) STp->density_changed = STp->blksize_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) STp->compression_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (!(STm->defaults_for_writes) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) (retval = set_mode_densblk(STp, STm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (STp->default_drvbuffer != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) "Can't set default drive "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) "buffering to %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) STp->default_drvbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return CHKRES_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) module count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static int st_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) int i, retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) int resumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct scsi_tape *STp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) int dev = TAPE_NR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) * We really want to do nonseekable_open(inode, filp); here, but some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * versions of tar incorrectly call lseek on tapes and bail out if that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) * fails. So we disallow pread() and pwrite(), but permit lseeks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) if (!(STp = scsi_tape_get(dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) filp->private_data = STp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) spin_lock(&st_use_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (STp->in_use) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) spin_unlock(&st_use_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) DEBC_printk(STp, "Device already in use.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) scsi_tape_put(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return (-EBUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) STp->in_use = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) spin_unlock(&st_use_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (scsi_autopm_get_device(STp->device) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) resumed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (!scsi_block_when_processing_errors(STp->device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) retval = (-ENXIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /* See that we have at least a one page buffer available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) "Can't allocate one page tape buffer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) retval = (-EOVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) (STp->buffer)->cleared = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) (STp->buffer)->writing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) (STp->buffer)->syscall_result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) STp->dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) for (i = 0; i < ST_NBR_PARTITIONS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) STps = &(STp->ps[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) STps->rw = ST_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) STp->try_dio_now = STp->try_dio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) STp->recover_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) DEB( STp->nbr_waits = STp->nbr_finished = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) retval = check_tape(STp, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if ((filp->f_flags & O_NONBLOCK) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) retval != CHKRES_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (STp->ready == NO_TAPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) retval = (-ENOMEDIUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) normalize_buffer(STp->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) spin_lock(&st_use_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) STp->in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) spin_unlock(&st_use_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (resumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) scsi_autopm_put_device(STp->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) scsi_tape_put(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) /* Flush the tape buffer before close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) static int st_flush(struct file *filp, fl_owner_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) int result = 0, result2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) struct scsi_tape *STp = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct st_modedef *STm = &(STp->modes[STp->current_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) struct st_partstat *STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (file_count(filp) > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (STps->rw == ST_WRITING && !STp->pos_unknown) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) result = st_flush_write_buffer(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (result != 0 && result != (-ENOSPC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (STp->can_partitions &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) (result2 = switch_partition(STp)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) DEBC_printk(STp, "switch_partition at close failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (result == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) result = result2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) DEBC( if (STp->nbr_requests)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) st_printk(KERN_DEBUG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) "Number of r/w requests %d, dio used in %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) "pages %d.\n", STp->nbr_requests, STp->nbr_dio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) STp->nbr_pages));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (STps->rw == ST_WRITING && !STp->pos_unknown) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) DEBC_printk(STp, "Async write waits %d, finished %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) STp->nbr_waits, STp->nbr_finished);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) memset(cmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) cmd[0] = WRITE_FILEMARKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (STp->immediate_filemark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) cmd[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) cmd[4] = 1 + STp->two_fm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) STp->device->request_queue->rq_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) MAX_WRITE_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (!SRpnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) result = (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (STp->buffer->syscall_result == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) (cmdstatp->have_sense && !cmdstatp->deferred &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) (cmdstatp->flags & SENSE_EOM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) /* Write successful at EOM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) STps->drv_file++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (STp->two_fm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) cross_eof(STp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) STps->eof = ST_FM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) else { /* Write error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) st_printk(KERN_ERR, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) "Error on write filemark.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (result == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) result = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) DEBC_printk(STp, "Buffer flushed, %d EOF(s) written\n", cmd[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) } else if (!STp->rew_at_close) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (!STm->sysv || STps->rw != ST_READING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (STp->can_bsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) result = flush_buffer(STp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) else if (STps->eof == ST_FM_HIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) result = cross_eof(STp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) STps->drv_file++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) STps->eof = ST_FM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) } else if ((STps->eof == ST_NOEOF &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) !(result = cross_eof(STp, 1))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) STps->eof == ST_FM_HIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) STps->drv_file++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) STps->eof = ST_FM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (STp->rew_at_close) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) result2 = st_int_ioctl(STp, MTREW, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (result == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) result = result2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) /* Close the device and release it. BKL is not needed: this is the only thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) accessing this tape. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) static int st_release(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct scsi_tape *STp = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (STp->door_locked == ST_LOCKED_AUTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) do_door_lock(STp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) normalize_buffer(STp->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) spin_lock(&st_use_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) STp->in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) spin_unlock(&st_use_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) scsi_autopm_put_device(STp->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) scsi_tape_put(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /* The checks common to both reading and writing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) ssize_t retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) * If we are in the middle of error recovery, don't let anyone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) * else try and use this device. Also, if error recovery fails, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) * may try and take the device offline, in which case all further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) * access to the device is prohibited.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (!scsi_block_when_processing_errors(STp->device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) retval = (-ENXIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (STp->ready != ST_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (STp->ready == ST_NO_TAPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) retval = (-ENOMEDIUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (! STp->modes[STp->current_mode].defined) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) retval = (-ENXIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * If there was a bus reset, block further access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * to this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (STp->pos_unknown) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (!STp->in_use) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) "Incorrect device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) } ) /* end DEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (STp->can_partitions &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) (retval = switch_partition(STp)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (STp->block_size == 0 && STp->max_block > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) (count < STp->min_block || count > STp->max_block)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) !do_door_lock(STp, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) STp->door_locked = ST_LOCKED_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) size_t count, int is_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) int i, bufsize, retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct st_buffer *STbp = STp->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (is_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) i = STp->try_dio_now && try_rdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) i = STp->try_dio_now && try_wdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (i && ((unsigned long)buf & queue_dma_alignment(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) STp->device->request_queue)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) count, (is_read ? READ : WRITE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) if (i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) STbp->do_dio = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) STbp->buffer_bytes = 0; /* can be used as transfer counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) STbp->do_dio = 0; /* fall back to buffering with any error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) STbp->sg_segs = STbp->do_dio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) if (STbp->do_dio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) STp->nbr_dio++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) STp->nbr_pages += STbp->do_dio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) STbp->do_dio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) DEB( STp->nbr_requests++; )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (!STbp->do_dio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) if (STp->block_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) bufsize = STp->block_size > st_fixed_buffer_size ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) STp->block_size : st_fixed_buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) bufsize = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) /* Make sure that data from previous user is not leaked even if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) HBA does not return correct residual */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (is_read && STp->sili && !STbp->cleared)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) clear_buffer(STbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) if (bufsize > STbp->buffer_size &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) "Can't allocate %d byte tape buffer.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) bufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) retval = (-EOVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (STp->block_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) STbp->buffer_blocks = bufsize / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) /* Can be called more than once after each setup_buffer() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) static void release_buffering(struct scsi_tape *STp, int is_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) struct st_buffer *STbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) STbp = STp->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (STbp->do_dio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) STbp->do_dio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) STbp->sg_segs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) /* Write command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) ssize_t total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) ssize_t i, do_count, blks, transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) ssize_t retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) int undone, retry_eot = 0, scode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) int async_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) const char __user *b_point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) struct st_request *SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) struct scsi_tape *STp = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) struct st_modedef *STm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) struct st_buffer *STbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if (mutex_lock_interruptible(&STp->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) retval = rw_checks(STp, filp, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (retval || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) /* Write must be integral number of blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (STp->block_size != 0 && (count % STp->block_size) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) "Write not multiple of tape block size.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) STm = &(STp->modes[STp->current_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (STp->write_prot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) retval = (-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (STps->rw == ST_READING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) retval = flush_buffer(STp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) STps->rw = ST_WRITING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) } else if (STps->rw != ST_WRITING &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) STps->drv_file == 0 && STps->drv_block == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if ((retval = set_mode_densblk(STp, STm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (STm->default_compression != ST_DONT_TOUCH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) !(STp->compression_changed)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (st_compression(STp, (STm->default_compression == ST_YES))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) "Can't set default compression.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (modes_defined) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) STbp = STp->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) i = write_behind_check(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) if (i == -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) STps->eof = ST_EOM_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) STps->eof = ST_EOM_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) if (STps->eof == ST_EOM_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) STps->eof = ST_EOD_1; /* allow next write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) retval = (-ENOSPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) else if (STps->eof == ST_EOM_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) /* Check the buffer readability in cases where copy_user might catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) the problems after some tape movement. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (STp->block_size != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) !STbp->do_dio &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) (copy_from_user(&i, buf, 1) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) copy_from_user(&i, buf + count - 1, 1) != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) retval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) retval = setup_buffering(STp, buf, count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) total = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) memset(cmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) cmd[0] = WRITE_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) cmd[1] = (STp->block_size != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) STps->rw = ST_WRITING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) b_point = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) while (count > 0 && !retry_eot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) if (STbp->do_dio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) do_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) do_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) do_count = STbp->buffer_blocks * STp->block_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) STbp->buffer_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) if (do_count > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) do_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) i = append_to_buffer(b_point, STbp, do_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) if (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) count -= do_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) b_point += do_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) async_write = STp->block_size == 0 && !STbp->do_dio &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) STm->do_async_writes && STps->eof < ST_EOM_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) if (STp->block_size != 0 && STm->do_buffer_writes &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) STbp->buffer_bytes < STbp->buffer_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) STp->dirty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) /* Don't write a buffer that is not full enough. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) if (!async_write && count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) retry_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) blks = transfer = do_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) if (!STbp->do_dio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) blks = STbp->buffer_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) blks = do_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) blks /= STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) transfer = blks * STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) cmd[2] = blks >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) cmd[3] = blks >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) cmd[4] = blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) STp->device->request_queue->rq_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) MAX_WRITE_RETRIES, !async_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) if (!SRpnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) retval = STbp->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if (async_write && !STbp->syscall_result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) STbp->writing = transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) STp->dirty = !(STbp->writing ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) STbp->buffer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) SRpnt = NULL; /* Prevent releasing this request! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) DEB( STp->write_pending = 1; )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (STbp->syscall_result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) DEBC_printk(STp, "Error on write:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) scode = cmdstatp->sense_hdr.sense_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (cmdstatp->remainder_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) undone = (int)cmdstatp->uremainder64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) else if (STp->block_size == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) scode == VOLUME_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) undone = transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) undone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) if (STp->block_size != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) undone *= STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (undone <= do_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) /* Only data from this write is not written */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) count += undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) b_point -= undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) do_count -= undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if (STp->block_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) blks = (transfer - undone) / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) STps->eof = ST_EOM_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) /* Continue in fixed block mode if all written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) in this request but still something left to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) (retval left to zero)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) if (STp->block_size == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) undone > 0 || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) retval = (-ENOSPC); /* EOM within current request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) DEBC_printk(STp, "EOM with %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) "bytes unwritten.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) (int)count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) /* EOT within data buffered earlier (possible only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) in fixed block mode without direct i/o) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) if (!retry_eot && !cmdstatp->deferred &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) move_buffer_data(STp->buffer, transfer - undone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) retry_eot = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (STps->drv_block >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) STps->drv_block += (transfer - undone) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) STps->eof = ST_EOM_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) DEBC_printk(STp, "Retry "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) "write of %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) "bytes at EOM.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) STp->buffer->buffer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) goto retry_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) /* Either error within data buffered by driver or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) failed retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) count -= do_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) blks = do_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) STps->eof = ST_EOM_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) STps->drv_block = (-1); /* Too cautious? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) retval = (-EIO); /* EOM for old data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) DEBC_printk(STp, "EOM with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) "lost data.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) count += do_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) STps->drv_block = (-1); /* Too cautious? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) retval = STbp->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (STps->drv_block >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) STps->drv_block += (do_count > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) STps->drv_block += blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) STbp->buffer_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) STp->dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (retval || retry_eot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) if (count < total)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) retval = total - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (STps->eof == ST_EOD_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) STps->eof = ST_EOM_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) else if (STps->eof != ST_EOM_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) retval = total - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) if (SRpnt != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) release_buffering(STp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) mutex_unlock(&STp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) /* Read data from the tape. Returns zero in the normal case, one if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) eof status has changed, and the negative error code in case of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) fatal error. Otherwise updates the buffer and the eof state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) Does release user buffer mapping if it is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) static long read_tape(struct scsi_tape *STp, long count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) struct st_request ** aSRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) int transfer, blks, bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) struct st_modedef *STm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) struct st_buffer *STbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) STm = &(STp->modes[STp->current_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (STps->eof == ST_FM_HIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) STbp = STp->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) blks = bytes = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) blks = (STp->buffer)->buffer_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) bytes = blks * STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) bytes = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) bytes = (STp->buffer)->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) blks = bytes / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) bytes = blks * STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) memset(cmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) cmd[0] = READ_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) cmd[1] = (STp->block_size != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (!cmd[1] && STp->sili)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) cmd[1] |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) cmd[2] = blks >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) cmd[3] = blks >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) cmd[4] = blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) SRpnt = *aSRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) STp->device->request_queue->rq_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) MAX_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) release_buffering(STp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) *aSRpnt = SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) return STbp->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) STbp->read_pointer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) STps->at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) /* Something to check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (STbp->syscall_result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) retval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) DEBC_printk(STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) "Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) SRpnt->sense[0], SRpnt->sense[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) SRpnt->sense[2], SRpnt->sense[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) SRpnt->sense[4], SRpnt->sense[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) SRpnt->sense[6], SRpnt->sense[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) if (cmdstatp->have_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /* Compute the residual count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) if (cmdstatp->remainder_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) transfer = (int)cmdstatp->uremainder64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) transfer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) if (cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) transfer = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) /* Some drives set ILI with MEDIUM ERROR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) cmdstatp->flags &= ~SENSE_ILI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (cmdstatp->flags & SENSE_ILI) { /* ILI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (STp->block_size == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) transfer < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) st_printk(KERN_NOTICE, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) "Failed to read %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) "byte block with %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) "byte transfer.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) bytes - transfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) if (STps->drv_block >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) STps->drv_block += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) STbp->buffer_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return (-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) } else if (STp->block_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) STbp->buffer_bytes = bytes - transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) SRpnt = *aSRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) if (transfer == blks) { /* We did not get anything, error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) st_printk(KERN_NOTICE, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) "Incorrect "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) "block size.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (STps->drv_block >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) STps->drv_block += blks - transfer + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) st_int_ioctl(STp, MTBSR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) /* We have some data, deliver it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) STbp->buffer_bytes = (blks - transfer) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) DEBC_printk(STp, "ILI but "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) "enough data "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) "received %ld "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) "%d.\n", count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) STbp->buffer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) if (STps->drv_block >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) STps->drv_block += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (st_int_ioctl(STp, MTBSR, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (STps->eof != ST_FM_HIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) STps->eof = ST_FM_HIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) STps->eof = ST_EOD_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) STbp->buffer_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) STbp->buffer_bytes =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) bytes - transfer * STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) DEBC_printk(STp, "EOF detected (%d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) "bytes read).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) STbp->buffer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) } else if (cmdstatp->flags & SENSE_EOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) if (STps->eof == ST_FM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) STps->eof = ST_EOD_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) STps->eof = ST_EOM_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) STbp->buffer_bytes = bytes - transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) STbp->buffer_bytes =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) bytes - transfer * STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) DEBC_printk(STp, "EOM detected (%d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) "bytes read).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) STbp->buffer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) /* end of EOF, EOM, ILI test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) else { /* nonzero sense key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) DEBC_printk(STp, "Tape error while reading.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) STps->drv_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) if (STps->eof == ST_FM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) DEBC_printk(STp, "Zero returned for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) "first BLANK CHECK "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) "after EOF.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) } else /* Some other extended sense code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) STbp->buffer_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) /* End of extended sense test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) else { /* Non-extended sense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) retval = STbp->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) /* End of error handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) else { /* Read successful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) STbp->buffer_bytes = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (STp->sili) /* In fixed block mode residual is always zero here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if (STps->drv_block >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) STps->drv_block++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) STps->drv_block += STbp->buffer_bytes / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) /* Read command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) ssize_t total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) ssize_t retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) ssize_t i, transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) int special, do_dio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) struct st_request *SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) struct scsi_tape *STp = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) struct st_modedef *STm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) struct st_buffer *STbp = STp->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) if (mutex_lock_interruptible(&STp->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) retval = rw_checks(STp, filp, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (retval || count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) STm = &(STp->modes[STp->current_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) if (STp->block_size != 0 && (count % STp->block_size) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) if (!STm->do_read_ahead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) retval = (-EINVAL); /* Read must be integral number of blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (STps->rw == ST_WRITING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) retval = flush_buffer(STp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) STps->rw = ST_READING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) if (debugging && STps->eof != ST_NOEOF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) "EOF/EOM flag up (%d). Bytes %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) STps->eof, STbp->buffer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) ) /* end DEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) retval = setup_buffering(STp, buf, count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) do_dio = STbp->do_dio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) if (STbp->buffer_bytes == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) STps->eof >= ST_EOD_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if (STps->eof < ST_EOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) STps->eof += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) retval = (-EIO); /* EOM or Blank Check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) if (do_dio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) /* Check the buffer writability before any tape movement. Don't alter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) buffer data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (copy_from_user(&i, buf, 1) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) copy_to_user(buf, &i, 1) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) copy_from_user(&i, buf + count - 1, 1) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) copy_to_user(buf + count - 1, &i, 1) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) retval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) STps->rw = ST_READING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) /* Loop until enough data in buffer or a special condition found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) for (total = 0, special = 0; total < count && !special;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) /* Get new data if the buffer is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) if (STbp->buffer_bytes == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) special = read_tape(STp, count - total, &SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) if (special < 0) { /* No need to continue read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) retval = special;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) /* Move the data from driver buffer to user buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) if (STbp->buffer_bytes > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) if (debugging && STps->eof != ST_NOEOF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) "EOF up (%d). Left %d, needed %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) STps->eof, STbp->buffer_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) (int)(count - total));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) ) /* end DEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) transfer = STbp->buffer_bytes < count - total ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) STbp->buffer_bytes : count - total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) if (!do_dio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) i = from_buffer(STbp, buf, transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) buf += transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) total += transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) if (STp->block_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) break; /* Read only one variable length block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) } /* for (total = 0, special = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) total < count && !special; ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) /* Change the eof state if no data from tape or buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (total == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) if (STps->eof == ST_FM_HIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) STps->eof = ST_FM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) STps->drv_file++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) } else if (STps->eof == ST_EOD_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) STps->eof = ST_EOD_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) STps->drv_file++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) } else if (STps->eof == ST_EOD_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) STps->eof = ST_EOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) } else if (STps->eof == ST_FM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) retval = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) if (SRpnt != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) if (do_dio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) release_buffering(STp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) STbp->buffer_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) mutex_unlock(&STp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) /* Set the driver options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) if (debugging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) st_printk(KERN_INFO, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) "Mode %d options: buffer writes: %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) "async writes: %d, read ahead: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) STp->current_mode, STm->do_buffer_writes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) STm->do_async_writes, STm->do_read_ahead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) st_printk(KERN_INFO, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) " can bsr: %d, two FMs: %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) "fast mteom: %d, auto lock: %d,\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) STp->can_bsr, STp->two_fm, STp->fast_mteom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) STp->do_auto_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) st_printk(KERN_INFO, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) " defs for wr: %d, no block limits: %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) "partitions: %d, s2 log: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) STm->defaults_for_writes, STp->omit_blklims,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) STp->can_partitions, STp->scsi2_logical);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) st_printk(KERN_INFO, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) " sysv: %d nowait: %d sili: %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) "nowait_filemark: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) STm->sysv, STp->immediate, STp->sili,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) STp->immediate_filemark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) st_printk(KERN_INFO, STp, " debugging: %d\n", debugging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) static int st_set_options(struct scsi_tape *STp, long options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) long code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) struct st_modedef *STm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) struct cdev *cd0, *cd1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) struct device *d0, *d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) STm = &(STp->modes[STp->current_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) if (!STm->defined) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) cd0 = STm->cdevs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) cd1 = STm->cdevs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) d0 = STm->devs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) d1 = STm->devs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) STm->cdevs[0] = cd0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) STm->cdevs[1] = cd1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) STm->devs[0] = d0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) STm->devs[1] = d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) modes_defined = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) DEBC_printk(STp, "Initialized mode %d definition from mode 0\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) STp->current_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) code = options & MT_ST_OPTIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) if (code == MT_ST_BOOLEANS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) STp->two_fm = (options & MT_ST_TWO_FM) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if ((STp->device)->scsi_level >= SCSI_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) STp->immediate = (options & MT_ST_NOWAIT) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) STp->immediate_filemark = (options & MT_ST_NOWAIT_EOF) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) STm->sysv = (options & MT_ST_SYSV) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) STp->sili = (options & MT_ST_SILI) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) st_log_options(STp, STm); )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) value = (code == MT_ST_SETBOOLEANS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) if ((options & MT_ST_BUFFER_WRITES) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) STm->do_buffer_writes = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) if ((options & MT_ST_ASYNC_WRITES) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) STm->do_async_writes = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) if ((options & MT_ST_DEF_WRITES) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) STm->defaults_for_writes = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) if ((options & MT_ST_READ_AHEAD) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) STm->do_read_ahead = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) if ((options & MT_ST_TWO_FM) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) STp->two_fm = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) if ((options & MT_ST_FAST_MTEOM) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) STp->fast_mteom = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) if ((options & MT_ST_AUTO_LOCK) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) STp->do_auto_lock = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) if ((options & MT_ST_CAN_BSR) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) STp->can_bsr = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) if ((options & MT_ST_NO_BLKLIMS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) STp->omit_blklims = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) if ((STp->device)->scsi_level >= SCSI_2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) (options & MT_ST_CAN_PARTITIONS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) STp->can_partitions = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) if ((options & MT_ST_SCSI2LOGICAL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) STp->scsi2_logical = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) if ((options & MT_ST_NOWAIT) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) STp->immediate = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) if ((options & MT_ST_NOWAIT_EOF) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) STp->immediate_filemark = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) if ((options & MT_ST_SYSV) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) STm->sysv = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) if ((options & MT_ST_SILI) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) STp->sili = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) if ((options & MT_ST_DEBUGGING) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) debugging = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) st_log_options(STp, STm); )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) } else if (code == MT_ST_WRITE_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) /* Retained for compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) } else if (code == MT_ST_DEF_BLKSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) value = (options & ~MT_ST_OPTIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) if (value == ~MT_ST_OPTIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) STm->default_blksize = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) DEBC_printk(STp, "Default block size disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) STm->default_blksize = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) DEBC_printk(STp,"Default block size set to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) "%d bytes.\n", STm->default_blksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) if (STp->ready == ST_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) STp->blksize_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) set_mode_densblk(STp, STm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) } else if (code == MT_ST_TIMEOUTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) value = (options & ~MT_ST_OPTIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) DEBC_printk(STp, "Long timeout set to %d seconds.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) (value & ~MT_ST_SET_LONG_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) blk_queue_rq_timeout(STp->device->request_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) value * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) DEBC_printk(STp, "Normal timeout set to %d seconds.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) } else if (code == MT_ST_SET_CLN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) value = (options & ~MT_ST_OPTIONS) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) if (value != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) (value < EXTENDED_SENSE_START ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) value >= SCSI_SENSE_BUFFERSIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) STp->cln_mode = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) STp->cln_sense_mask = (options >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) STp->cln_sense_value = (options >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) st_printk(KERN_INFO, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) "Cleaning request mode %d, mask %02x, value %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) value, STp->cln_sense_mask, STp->cln_sense_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) } else if (code == MT_ST_DEF_OPTIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) code = (options & ~MT_ST_CLEAR_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) value = (options & MT_ST_CLEAR_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) if (code == MT_ST_DEF_DENSITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) if (value == MT_ST_CLEAR_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) STm->default_density = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) DEBC_printk(STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) "Density default disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) STm->default_density = value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) DEBC_printk(STp, "Density default set to %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) STm->default_density);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) if (STp->ready == ST_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) STp->density_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) set_mode_densblk(STp, STm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) } else if (code == MT_ST_DEF_DRVBUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) if (value == MT_ST_CLEAR_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) STp->default_drvbuffer = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) DEBC_printk(STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) "Drive buffer default disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) STp->default_drvbuffer = value & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) DEBC_printk(STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) "Drive buffer default set to %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) STp->default_drvbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) if (STp->ready == ST_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) } else if (code == MT_ST_DEF_COMPRESSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) if (value == MT_ST_CLEAR_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) STm->default_compression = ST_DONT_TOUCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) DEBC_printk(STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) "Compression default disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) if ((value & 0xff00) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) STp->c_algo = (value & 0xff00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) DEBC_printk(STp, "Compression "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) "algorithm set to 0x%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) STp->c_algo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) if ((value & 0xff) != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) STm->default_compression = (value & 1 ? ST_YES : ST_NO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) DEBC_printk(STp, "Compression default "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) "set to %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) (value & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) if (STp->ready == ST_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) STp->compression_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) st_compression(STp, (STm->default_compression == ST_YES));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) #define MODE_HEADER_LENGTH 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) /* Mode header and page byte offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) #define MH_OFF_DATA_LENGTH 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) #define MH_OFF_MEDIUM_TYPE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) #define MH_OFF_DEV_SPECIFIC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) #define MH_OFF_BDESCS_LENGTH 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) #define MP_OFF_PAGE_NBR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) #define MP_OFF_PAGE_LENGTH 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) /* Mode header and page bit masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) #define MH_BIT_WP 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) #define MP_MSK_PAGE_NBR 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) /* Don't return block descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) #define MODE_SENSE_OMIT_BDESCS 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) #define MODE_SELECT_PAGE_FORMAT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) /* Read a mode page into the tape buffer. The block descriptors are included
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) if incl_block_descs is true. The page control is ored to the page number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) parameter, if necessary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) memset(cmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) cmd[0] = MODE_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) if (omit_block_descs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) cmd[1] = MODE_SENSE_OMIT_BDESCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) cmd[2] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) cmd[4] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_FROM_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) STp->device->request_queue->rq_timeout, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) if (SRpnt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) return STp->buffer->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) /* Send the mode page in the tape buffer to the drive. Assumes that the mode data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) static int write_mode_page(struct scsi_tape *STp, int page, int slow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) int pgo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) memset(cmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) cmd[0] = MODE_SELECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) cmd[1] = MODE_SELECT_PAGE_FORMAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) /* Clear reserved fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) timeout = slow ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) STp->long_timeout : STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_TO_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) timeout, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) if (SRpnt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) return STp->buffer->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) #define COMPRESSION_PAGE 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) #define COMPRESSION_PAGE_LENGTH 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) #define CP_OFF_DCE_DCC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) #define CP_OFF_C_ALGO 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) #define DCE_MASK 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) #define DCC_MASK 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) #define RED_MASK 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) /* Control the compression with mode page 15. Algorithm not changed if zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) The block descriptors are read and written because Sony SDT-7000 does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) Including block descriptors should not cause any harm to other drives. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) static int st_compression(struct scsi_tape * STp, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) int mpoffs; /* Offset to mode page start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) unsigned char *b_data = (STp->buffer)->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (STp->ready != ST_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) /* Read the current page contents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) DEBC_printk(STp, "Compression mode page not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) DEBC_printk(STp, "Compression state is %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) /* Check if compression can be changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) DEBC_printk(STp, "Compression not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) /* Do the change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) if (STp->c_algo != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) if (STp->c_algo != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) DEBC_printk(STp, "Compression change failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) DEBC_printk(STp, "Compression state changed to %d.\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) STp->compression_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) /* Process the load and unload commands (does unload if the load code is zero) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) int retval = (-EIO), timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) if (STp->ready != ST_READY && !load_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) if (STp->ready == ST_NO_TAPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) return (-ENOMEDIUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) memset(cmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) cmd[0] = START_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) if (load_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) cmd[4] |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) DEBC_printk(STp, " Enhanced %sload slot %2d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) (cmd[4]) ? "" : "un",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) load_code - MT_ST_HPLOADER_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) if (STp->immediate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) cmd[1] = 1; /* Don't wait for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) timeout = STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) timeout = STp->long_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) DEBC(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) if (!load_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) st_printk(ST_DEB_MSG, STp, "Unloading tape.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) st_printk(ST_DEB_MSG, STp, "Loading tape.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) timeout, MAX_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) retval = (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) if (!retval) { /* SCSI command successful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) if (!load_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) STp->rew_at_close = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) STp->ready = ST_NO_TAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) STp->rew_at_close = STp->autorew_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) retval = check_tape(STp, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) if (retval > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) STps->drv_file = STps->drv_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) #define ST_DEB_FORWARD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) #define ST_DEB_BACKWARD 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) static void deb_space_print(struct scsi_tape *STp, int direction, char *units, unsigned char *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) s32 sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) if (!debugging)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) sc = sign_extend32(get_unaligned_be24(&cmd[2]), 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) if (direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) sc = -sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) st_printk(ST_DEB_MSG, STp, "Spacing tape %s over %d %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) direction ? "backward" : "forward", sc, units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) #define ST_DEB_FORWARD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) #define ST_DEB_BACKWARD 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) static void deb_space_print(struct scsi_tape *STp, int direction, char *units, unsigned char *cmd) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) /* Internal ioctl function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) long ltmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) int ioctl_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) int chg_eof = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) unsigned char cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) int fileno, blkno, at_sm, undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) int datalen = 0, direction = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) WARN_ON(STp->buffer->do_dio != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) if (STp->ready != ST_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) if (STp->ready == ST_NO_TAPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) return (-ENOMEDIUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) timeout = STp->long_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) fileno = STps->drv_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) blkno = STps->drv_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) at_sm = STps->at_sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) memset(cmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) switch (cmd_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) case MTFSFM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) chg_eof = 0; /* Changed from the FSF after this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) case MTFSF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) cmd[0] = SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) cmd[1] = 0x01; /* Space FileMarks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) cmd[2] = (arg >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) cmd[3] = (arg >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) cmd[4] = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) deb_space_print(STp, ST_DEB_FORWARD, "filemarks", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) if (fileno >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) fileno += arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) blkno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) at_sm &= (arg == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) case MTBSFM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) chg_eof = 0; /* Changed from the FSF after this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) case MTBSF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) cmd[0] = SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) cmd[1] = 0x01; /* Space FileMarks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) ltmp = (-arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) cmd[2] = (ltmp >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) cmd[3] = (ltmp >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) cmd[4] = ltmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) deb_space_print(STp, ST_DEB_BACKWARD, "filemarks", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) if (fileno >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) fileno -= arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) blkno = (-1); /* We can't know the block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) at_sm &= (arg == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) case MTFSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) cmd[0] = SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) cmd[1] = 0x00; /* Space Blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) cmd[2] = (arg >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) cmd[3] = (arg >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) cmd[4] = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) deb_space_print(STp, ST_DEB_FORWARD, "blocks", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) if (blkno >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) blkno += arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) at_sm &= (arg == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) case MTBSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) cmd[0] = SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) cmd[1] = 0x00; /* Space Blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) ltmp = (-arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) cmd[2] = (ltmp >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) cmd[3] = (ltmp >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) cmd[4] = ltmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) deb_space_print(STp, ST_DEB_BACKWARD, "blocks", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) if (blkno >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) blkno -= arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) at_sm &= (arg == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) case MTFSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) cmd[0] = SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) cmd[1] = 0x04; /* Space Setmarks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) cmd[2] = (arg >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) cmd[3] = (arg >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) cmd[4] = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) deb_space_print(STp, ST_DEB_FORWARD, "setmarks", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) if (arg != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) blkno = fileno = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) at_sm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) case MTBSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) cmd[0] = SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) cmd[1] = 0x04; /* Space Setmarks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) ltmp = (-arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) cmd[2] = (ltmp >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) cmd[3] = (ltmp >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) cmd[4] = ltmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) deb_space_print(STp, ST_DEB_BACKWARD, "setmarks", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) if (arg != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) blkno = fileno = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) at_sm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) case MTWEOF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) case MTWEOFI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) case MTWSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) if (STp->write_prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) return (-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) cmd[0] = WRITE_FILEMARKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) if (cmd_in == MTWSM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) cmd[1] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) if (cmd_in == MTWEOFI ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) (cmd_in == MTWEOF && STp->immediate_filemark))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) cmd[1] |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) cmd[2] = (arg >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) cmd[3] = (arg >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) cmd[4] = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) timeout = STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) DEBC(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) if (cmd_in != MTWSM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) "Writing %d filemarks.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) cmd[2] * 65536 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) cmd[3] * 256 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) cmd[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) "Writing %d setmarks.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) cmd[2] * 65536 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) cmd[3] * 256 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) cmd[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) if (fileno >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) fileno += arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) blkno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) at_sm = (cmd_in == MTWSM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) case MTREW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) cmd[0] = REZERO_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) if (STp->immediate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) cmd[1] = 1; /* Don't wait for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) timeout = STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) DEBC_printk(STp, "Rewinding tape.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) fileno = blkno = at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) case MTNOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) DEBC_printk(STp, "No op on tape.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) return 0; /* Should do something ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) case MTRETEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) cmd[0] = START_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) if (STp->immediate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) cmd[1] = 1; /* Don't wait for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) timeout = STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) cmd[4] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) DEBC_printk(STp, "Retensioning tape.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) fileno = blkno = at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) case MTEOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) if (!STp->fast_mteom) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) /* space to the end of tape */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) fileno = STps->drv_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) if (STps->eof >= ST_EOD_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) /* The next lines would hide the number of spaced FileMarks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) That's why I inserted the previous lines. I had no luck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) with detecting EOM with FSF, so we go now to EOM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) Joerg Weule */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) fileno = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) cmd[0] = SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) cmd[1] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) DEBC_printk(STp, "Spacing to end of recorded medium.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) blkno = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) case MTERASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) if (STp->write_prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) return (-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) cmd[0] = ERASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) if (STp->immediate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) cmd[1] |= 2; /* Don't wait for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) timeout = STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) timeout = STp->long_timeout * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) DEBC_printk(STp, "Erasing tape.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) fileno = blkno = at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) case MTSETBLK: /* Set block length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) case MTSETDENSITY: /* Set tape density */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) case MTSETDRVBUFFER: /* Set drive buffering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) case SET_DENS_AND_BLK: /* Set density and block size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) chg_eof = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) return (-EIO); /* Not allowed if data in buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) (arg & MT_ST_BLKSIZE_MASK) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) STp->max_block > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) st_printk(KERN_WARNING, STp, "Illegal block size.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) cmd[0] = MODE_SELECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) if ((STp->use_pf & USE_PF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) cmd[1] = MODE_SELECT_PAGE_FORMAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) cmd[4] = datalen = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) direction = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) memset((STp->buffer)->b_data, 0, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) if (cmd_in == MTSETDRVBUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) (STp->buffer)->b_data[2] = (arg & 7) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) (STp->buffer)->b_data[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) STp->drv_buffer << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) (STp->buffer)->b_data[3] = 8; /* block descriptor length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) if (cmd_in == MTSETDENSITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) (STp->buffer)->b_data[4] = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) STp->density_changed = 1; /* At least we tried ;-) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) } else if (cmd_in == SET_DENS_AND_BLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) (STp->buffer)->b_data[4] = arg >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) (STp->buffer)->b_data[4] = STp->density;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) ltmp = arg & MT_ST_BLKSIZE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) if (cmd_in == MTSETBLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) STp->blksize_changed = 1; /* At least we tried ;-) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) ltmp = STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) (STp->buffer)->b_data[9] = (ltmp >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) (STp->buffer)->b_data[10] = (ltmp >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) (STp->buffer)->b_data[11] = ltmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) timeout = STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) DEBC(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) "Setting block size to %d bytes.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) (STp->buffer)->b_data[9] * 65536 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) (STp->buffer)->b_data[10] * 256 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) (STp->buffer)->b_data[11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) "Setting density code to %x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) (STp->buffer)->b_data[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) if (cmd_in == MTSETDRVBUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) st_printk(ST_DEB_MSG, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) "Setting drive buffer code to %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) ((STp->buffer)->b_data[2] >> 4) & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) return (-ENOSYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) timeout, MAX_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) ioctl_result = (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) if (!ioctl_result) { /* SCSI command successful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) STps->drv_block = blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) STps->drv_file = fileno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) STps->at_sm = at_sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) if (cmd_in == MTBSFM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) ioctl_result = st_int_ioctl(STp, MTFSF, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) else if (cmd_in == MTFSFM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) ioctl_result = st_int_ioctl(STp, MTBSF, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) STp->block_size = arg & MT_ST_BLKSIZE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) if (STp->block_size != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) (STp->buffer)->buffer_blocks =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) (STp->buffer)->buffer_size / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) if (cmd_in == SET_DENS_AND_BLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) STp->density = arg >> MT_ST_DENSITY_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) } else if (cmd_in == MTSETDRVBUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) STp->drv_buffer = (arg & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) else if (cmd_in == MTSETDENSITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) STp->density = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) if (cmd_in == MTEOM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) STps->eof = ST_EOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) else if (cmd_in == MTFSF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) STps->eof = ST_FM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) else if (chg_eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) if (cmd_in == MTWEOF || cmd_in == MTWEOFI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) STps->rw = ST_IDLE; /* prevent automatic WEOF at close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) } else { /* SCSI command was not completely successful. Don't return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) from this block without releasing the SCSI command block! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) if (cmdstatp->flags & SENSE_EOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) if (cmd_in != MTBSF && cmd_in != MTBSFM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) cmd_in != MTBSR && cmd_in != MTBSS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) STps->eof = ST_EOM_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) if (cmdstatp->remainder_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) undone = (int)cmdstatp->uremainder64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) undone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) if ((cmd_in == MTWEOF || cmd_in == MTWEOFI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) cmdstatp->have_sense &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) (cmdstatp->flags & SENSE_EOM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) ioctl_result = 0; /* EOF(s) written successfully at EOM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) } else { /* Writing EOF(s) failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) if (fileno >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) fileno -= undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) if (undone < arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) STps->drv_file = fileno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) if (fileno >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) STps->drv_file = fileno - undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) STps->drv_file = fileno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) STps->drv_block = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) if (arg > 0 && undone < 0) /* Some drives get this wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) undone = (-undone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) STps->drv_file = fileno + undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) } else if (cmd_in == MTFSR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) STps->drv_file++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) STps->drv_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) STps->eof = ST_FM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) if (blkno >= undone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) STps->drv_block = blkno - undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) STps->drv_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) } else if (cmd_in == MTBSR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) STps->drv_file--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) STps->drv_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) if (arg > 0 && undone < 0) /* Some drives get this wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) undone = (-undone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) if (STps->drv_block >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) STps->drv_block = blkno + undone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) } else if (cmd_in == MTEOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) STps->drv_file = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) STps->drv_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) STps->eof = ST_EOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) } else if (cmd_in == MTSETBLK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) cmd_in == MTSETDENSITY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) cmd_in == MTSETDRVBUFFER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) cmd_in == SET_DENS_AND_BLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) !(STp->use_pf & PF_TESTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) /* Try the other possible state of Page Format if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) already tried */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) return st_int_ioctl(STp, cmd_in, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) } else if (chg_eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) STps->eof = ST_EOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) return ioctl_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) /* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) int logical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) unsigned char scmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) if (STp->ready != ST_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) memset(scmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) if ((STp->device)->scsi_level < SCSI_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) scmd[0] = QFA_REQUEST_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) scmd[4] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) scmd[0] = READ_POSITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) if (!logical && !STp->scsi2_logical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) scmd[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) STp->device->request_queue->rq_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) MAX_READY_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) if ((STp->buffer)->syscall_result != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) (STp->device->scsi_level >= SCSI_2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) ((STp->buffer)->b_data[0] & 4) != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) *block = *partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) DEBC_printk(STp, " Can't read tape position.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) result = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) if ((STp->device)->scsi_level < SCSI_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) *block = ((STp->buffer)->b_data[0] << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) + ((STp->buffer)->b_data[1] << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) + (STp->buffer)->b_data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) *partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) *block = ((STp->buffer)->b_data[4] << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) + ((STp->buffer)->b_data[5] << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) + ((STp->buffer)->b_data[6] << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) + (STp->buffer)->b_data[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) *partition = (STp->buffer)->b_data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) if (((STp->buffer)->b_data[0] & 0x80) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) DEBC_printk(STp, "Got tape pos. blk %d part %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) *block, *partition);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) /* Set the tape block and partition. Negative partition means that only the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) block should be set in vendor specific way. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) int logical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) int result, p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) unsigned int blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) unsigned char scmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) if (STp->ready != ST_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) timeout = STp->long_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) DEBC_printk(STp, "Setting block to %d and partition to %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) block, partition);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) DEB(if (partition < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) return (-EIO); )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) /* Update the location at the partition we are leaving */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) if ((!STp->can_partitions && partition != 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) partition >= ST_NBR_PARTITIONS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) if (partition != STp->partition) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) if (get_location(STp, &blk, &p, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) STps->last_block_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) STps->last_block_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) STps->last_block_visited = blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) DEBC_printk(STp, "Visited block %d for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) "partition %d saved.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) blk, STp->partition);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) memset(scmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) if ((STp->device)->scsi_level < SCSI_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) scmd[0] = QFA_SEEK_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) scmd[2] = (block >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) scmd[3] = (block >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) scmd[4] = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) scmd[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) scmd[0] = SEEK_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) scmd[3] = (block >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) scmd[4] = (block >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) scmd[5] = (block >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) scmd[6] = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) if (!logical && !STp->scsi2_logical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) scmd[1] = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) if (STp->partition != partition) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) scmd[1] |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) scmd[8] = partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) DEBC_printk(STp, "Trying to change partition "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) "from %d to %d\n", STp->partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) partition);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) if (STp->immediate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) scmd[1] |= 1; /* Don't wait for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) timeout = STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) timeout, MAX_READY_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) return (STp->buffer)->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) STps->drv_block = STps->drv_file = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) if ((STp->buffer)->syscall_result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) result = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) if (STp->can_partitions &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) (STp->device)->scsi_level >= SCSI_2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) (p = find_partition(STp)) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) STp->partition = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) if (STp->can_partitions) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) STp->partition = partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) STps = &(STp->ps[partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) if (!STps->last_block_valid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) STps->last_block_visited != block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) STps->at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) STps->rw = ST_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) STps->at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) if (block == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) STps->drv_block = STps->drv_file = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) st_release_request(SRpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) /* Find the current partition number for the drive status. Called from open and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) returns either partition number of negative error code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) static int find_partition(struct scsi_tape *STp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) int i, partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) unsigned int block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) if ((i = get_location(STp, &block, &partition, 1)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) if (partition >= ST_NBR_PARTITIONS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) return partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) /* Change the partition if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) static int switch_partition(struct scsi_tape *STp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) if (STp->partition == STp->new_partition)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) STps = &(STp->ps[STp->new_partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) if (!STps->last_block_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) STps->last_block_visited = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) /* Functions for reading and writing the medium partition mode page. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) #define PART_PAGE 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) #define PART_PAGE_FIXED_LENGTH 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) #define PP_OFF_MAX_ADD_PARTS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) #define PP_OFF_NBR_ADD_PARTS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) #define PP_OFF_FLAGS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) #define PP_OFF_PART_UNITS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) #define PP_OFF_RESERVED 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) #define PP_BIT_IDP 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) #define PP_BIT_FDP 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) #define PP_MSK_PSUM_MB 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) #define PP_MSK_PSUM_UNITS 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) #define PP_MSK_POFM 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) /* Get the number of partitions on the tape. As a side effect reads the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) mode page into the tape buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) static int nbr_partitions(struct scsi_tape *STp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) if (STp->ready != ST_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) result = read_mode_page(STp, PART_PAGE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) DEBC_printk(STp, "Can't read medium partition page.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) result = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) PP_OFF_NBR_ADD_PARTS] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) DEBC_printk(STp, "Number of partitions %d.\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) static int format_medium(struct scsi_tape *STp, int format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) int timeout = STp->long_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) unsigned char scmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) struct st_request *SRpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) memset(scmd, 0, MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) scmd[0] = FORMAT_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) scmd[2] = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) if (STp->immediate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) scmd[1] |= 1; /* Don't wait for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) timeout = STp->device->request_queue->rq_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) DEBC_printk(STp, "Sending FORMAT MEDIUM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) timeout, MAX_RETRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) if (!SRpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) result = STp->buffer->syscall_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) /* Partition the tape into two partitions if size > 0 or one partition if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) size == 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) The block descriptors are read and written because Sony SDT-7000 does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) My HP C1533A drive returns only one partition size field. This is used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) set the size of partition 1. There is no size field for the default partition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) The following algorithm is used to accommodate both drives: if the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) partition size fields is greater than the maximum number of additional partitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) in the mode page, the second field is used. Otherwise the first field is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) For Seagate DDS drives the page length must be 8 when no partitions is defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) and 10 when 1 partition is defined (information from Eric Lee Green). This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) is acceptable also to some other old drives and enforced if the first partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) size field is used for the first additional partition size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) For drives that advertize SCSI-3 or newer, use the SSC-3 methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) static int partition_tape(struct scsi_tape *STp, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) int target_partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) bool scsi3 = STp->device->scsi_level >= SCSI_3, needs_format = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) int pgo, psd_cnt, psdo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) int psum = PP_MSK_PSUM_MB, units = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) unsigned char *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) result = read_mode_page(STp, PART_PAGE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) DEBC_printk(STp, "Can't read partition mode page.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) target_partition = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) if (size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) target_partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) size = -size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) /* The mode page is in the buffer. Let's modify it and write it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) bp = (STp->buffer)->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) DEBC_printk(STp, "Partition page length is %d bytes.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) bp[pgo + MP_OFF_PAGE_LENGTH] + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) if (scsi3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) needs_format = (bp[pgo + PP_OFF_FLAGS] & PP_MSK_POFM) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) if (needs_format && size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) /* No need to write the mode page when clearing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) * partitioning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) DEBC_printk(STp, "Formatting tape with one partition.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) result = format_medium(STp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) if (needs_format) /* Leave the old value for HP DATs claiming SCSI_3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) psd_cnt = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) if ((bp[pgo + PP_OFF_FLAGS] & PP_MSK_PSUM_UNITS) == PP_MSK_PSUM_UNITS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) /* Use units scaling for large partitions if the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) * suggests it and no precision lost. Required for IBM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) * TS1140/50 drives that don't support MB units.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) if (size >= 1000 && (size % 1000) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) size /= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) psum = PP_MSK_PSUM_UNITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) units = 9; /* GB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) /* Try it anyway if too large to specify in MB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) if (psum == PP_MSK_PSUM_MB && size >= 65534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) size /= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) psum = PP_MSK_PSUM_UNITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) units = 9; /* GB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) if (size >= 65535 || /* Does not fit into two bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) (target_partition == 0 && psd_cnt < 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) psdo = pgo + PART_PAGE_FIXED_LENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) /* The second condition is for HP DDS which use only one partition size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) * descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) if (target_partition > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) bp[pgo + PP_OFF_MAX_ADD_PARTS] != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) bp[psdo] = bp[psdo + 1] = 0xff; /* Rest to partition 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) psdo += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) DEBC_printk(STp, "psd_cnt %d, max.parts %d, nbr_parts %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) bp[pgo + PP_OFF_NBR_ADD_PARTS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) if (size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) DEBC_printk(STp, "Formatting tape with one partition.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) bp[psdo] = (size >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) bp[psdo + 1] = size & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) if (target_partition == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) bp[psdo + 2] = bp[psdo + 3] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) bp[pgo + 3] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) DEBC_printk(STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) "Formatting tape with two partitions (%i = %d MB).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) target_partition, units > 0 ? size * 1000 : size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) bp[pgo + PP_OFF_PART_UNITS] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) bp[pgo + PP_OFF_RESERVED] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) if (size != 1 || units != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | psum |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) (bp[pgo + PP_OFF_FLAGS] & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) bp[pgo + PP_OFF_PART_UNITS] = units;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) bp[pgo + PP_OFF_FLAGS] = PP_BIT_FDP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) (bp[pgo + PP_OFF_FLAGS] & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) bp[pgo + MP_OFF_PAGE_LENGTH] = 6 + psd_cnt * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) result = write_mode_page(STp, PART_PAGE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) if (!result && needs_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) result = format_medium(STp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) st_printk(KERN_INFO, STp, "Partitioning of tape failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) result = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) /* The ioctl command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) static long st_ioctl_common(struct file *file, unsigned int cmd_in, void __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) int i, cmd_nr, cmd_type, bt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) unsigned int blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) struct scsi_tape *STp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) struct st_modedef *STm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) if (mutex_lock_interruptible(&STp->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) DEB(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) if (debugging && !STp->in_use) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) st_printk(ST_DEB_MSG, STp, "Incorrect device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) } ) /* end DEB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) STm = &(STp->modes[STp->current_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) STps = &(STp->ps[STp->partition]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) * If we are in the middle of error recovery, don't let anyone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) * else try and use this device. Also, if error recovery fails, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) * may try and take the device offline, in which case all further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) * access to the device is prohibited.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) retval = scsi_ioctl_block_when_processing_errors(STp->device, cmd_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) file->f_flags & O_NDELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) cmd_type = _IOC_TYPE(cmd_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) cmd_nr = _IOC_NR(cmd_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) struct mtop mtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) i = copy_from_user(&mtc, p, sizeof(struct mtop));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) if (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) retval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) st_printk(KERN_WARNING, STp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) "MTSETDRVBUFFER only allowed for root.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) retval = (-EPERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) if (!STm->defined &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) (mtc.mt_op != MTSETDRVBUFFER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) retval = (-ENXIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) if (!STp->pos_unknown) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) if (STps->eof == ST_FM_HIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) mtc.mt_op == MTEOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) mtc.mt_count -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) STps->drv_file += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) mtc.mt_count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) if (STps->drv_file >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) STps->drv_file += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) if (mtc.mt_op == MTSEEK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) /* Old position must be restored if partition will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) i = !STp->can_partitions ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) (STp->new_partition != STp->partition);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) mtc.mt_op == MTCOMPRESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) i = flush_buffer(STp, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) if (STps->rw == ST_WRITING &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) mtc.mt_op == MTSEEK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) i = st_int_ioctl(STp, MTWEOF, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) mtc.mt_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) STps->rw = ST_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) * If there was a bus reset, block further access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) * to this device. If the user wants to rewind the tape,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) * then reset the flag and allow access again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) if (mtc.mt_op != MTREW &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) mtc.mt_op != MTOFFL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) mtc.mt_op != MTRETEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) mtc.mt_op != MTERASE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) mtc.mt_op != MTSEEK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) mtc.mt_op != MTEOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) reset_state(STp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) /* remove this when the midlevel properly clears was_reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) STp->device->was_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) do_door_lock(STp, 0); /* Ignore result! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) if (mtc.mt_op == MTSETDRVBUFFER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) (mtc.mt_count & MT_ST_OPTIONS) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) retval = st_set_options(STp, mtc.mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) if (mtc.mt_op == MTSETPART) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) if (!STp->can_partitions ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) if (mtc.mt_count >= STp->nbr_partitions &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) retval = (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) if (mtc.mt_count >= STp->nbr_partitions) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) STp->new_partition = mtc.mt_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) if (mtc.mt_op == MTMKPART) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) if (!STp->can_partitions) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) i = do_load_unload(STp, file, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) i = partition_tape(STp, mtc.mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) for (i = 0; i < ST_NBR_PARTITIONS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) STp->ps[i].rw = ST_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) STp->ps[i].at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) STp->ps[i].last_block_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) STp->partition = STp->new_partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) STp->nbr_partitions = mtc.mt_count != 0 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) STps->drv_block = STps->drv_file = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) if (mtc.mt_op == MTSEEK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) if (!STp->can_partitions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) STp->ps[0].rw = ST_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) retval = do_load_unload(STp, file, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) if (mtc.mt_op == MTLOAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) retval = do_load_unload(STp, file, max(1, mtc.mt_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) if (STp->can_partitions && STp->ready == ST_READY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) (i = switch_partition(STp)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) if (mtc.mt_op == MTCOMPRESSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) retval = st_compression(STp, (mtc.mt_count & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) if (!STm->defined) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) retval = (-ENXIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) if ((i = flush_buffer(STp, 0)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) if (STp->can_partitions &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) (i = switch_partition(STp)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) struct mtget mt_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) mt_status.mt_type = STp->tape_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) mt_status.mt_dsreg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) mt_status.mt_blkno = STps->drv_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) mt_status.mt_fileno = STps->drv_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) if (STp->block_size != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) if (STps->rw == ST_WRITING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) mt_status.mt_blkno +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) (STp->buffer)->buffer_bytes / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) else if (STps->rw == ST_READING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) mt_status.mt_blkno -=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) ((STp->buffer)->buffer_bytes +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) STp->block_size - 1) / STp->block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) mt_status.mt_gstat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) if (STp->drv_write_prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) if (mt_status.mt_blkno == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) if (mt_status.mt_fileno == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) mt_status.mt_gstat |= GMT_BOT(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) mt_status.mt_gstat |= GMT_EOF(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) mt_status.mt_resid = STp->partition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) mt_status.mt_gstat |= GMT_EOT(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) else if (STps->eof >= ST_EOM_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) mt_status.mt_gstat |= GMT_EOD(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) if (STp->density == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) mt_status.mt_gstat |= GMT_D_800(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) else if (STp->density == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) else if (STp->density == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) if (STp->ready == ST_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) if (STp->ready == ST_NO_TAPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) if (STps->at_sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) mt_status.mt_gstat |= GMT_SM(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) if (STm->do_async_writes ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) (STm->do_buffer_writes && STp->block_size != 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) STp->drv_buffer != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) if (STp->cleaning_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) mt_status.mt_gstat |= GMT_CLN(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) retval = put_user_mtget(p, &mt_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) STp->recover_reg = 0; /* Clear after read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) } /* End of MTIOCGET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) struct mtpos mt_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) retval = (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) retval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) mt_pos.mt_blkno = blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) retval = put_user_mtpos(p, &mt_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) mutex_unlock(&STp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) switch (cmd_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) case SCSI_IOCTL_STOP_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) /* unload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) retval = scsi_ioctl(STp->device, cmd_in, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) if (!retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) STp->rew_at_close = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) STp->ready = ST_NO_TAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) case SCSI_IOCTL_GET_IDLUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) case SCSI_IOCTL_GET_BUS_NUMBER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) if ((cmd_in == SG_IO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) cmd_in == SCSI_IOCTL_SEND_COMMAND ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) cmd_in == CDROM_SEND_PACKET) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) !capable(CAP_SYS_RAWIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) i = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) file->f_mode, cmd_in, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) if (i != -ENOTTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) mutex_unlock(&STp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) void __user *p = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) struct scsi_tape *STp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) ret = st_ioctl_common(file, cmd_in, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) if (ret != -ENOTTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) return scsi_ioctl(STp->device, cmd_in, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) static long st_compat_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) void __user *p = compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) struct scsi_tape *STp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) /* argument conversion is handled using put_user_mtpos/put_user_mtget */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) switch (cmd_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) case MTIOCPOS32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) return st_ioctl_common(file, MTIOCPOS, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) case MTIOCGET32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) return st_ioctl_common(file, MTIOCGET, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) ret = st_ioctl_common(file, cmd_in, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) if (ret != -ENOTTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) return scsi_compat_ioctl(STp->device, cmd_in, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) /* Try to allocate a new tape buffer. Calling function must not hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) dev_arr_lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) struct st_buffer *tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) tb = kzalloc(sizeof(struct st_buffer), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) if (!tb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) tb->frp_segs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) tb->use_sg = max_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) tb->dma = need_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) tb->buffer_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) tb->reserved_pages = kcalloc(max_sg, sizeof(struct page *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) if (!tb->reserved_pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) kfree(tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) return tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) /* Try to allocate enough space in the tape buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) #define ST_MAX_ORDER 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) int segs, max_segs, b_size, order, got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) gfp_t priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) if (new_size <= STbuffer->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) if (STbuffer->buffer_size <= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) normalize_buffer(STbuffer); /* Avoid extra segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) max_segs = STbuffer->use_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) priority = GFP_KERNEL | __GFP_NOWARN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) if (need_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) priority |= GFP_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) if (STbuffer->cleared)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) priority |= __GFP_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) if (STbuffer->frp_segs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) order = STbuffer->reserved_page_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) b_size = PAGE_SIZE << order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) for (b_size = PAGE_SIZE, order = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) order < ST_MAX_ORDER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) max_segs * (PAGE_SIZE << order) < new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) order++, b_size *= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) ; /* empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) STbuffer->reserved_page_order = order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) if (max_segs * (PAGE_SIZE << order) < new_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) if (order == ST_MAX_ORDER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) normalize_buffer(STbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) return enlarge_buffer(STbuffer, new_size, need_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) segs < max_segs && got < new_size;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) page = alloc_pages(priority, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) if (!page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) DEB(STbuffer->buffer_size = got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) normalize_buffer(STbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) STbuffer->frp_segs += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) got += b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) STbuffer->buffer_size = got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) STbuffer->reserved_pages[segs] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) segs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) /* Make sure that no data from previous user is in the internal buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) static void clear_buffer(struct st_buffer * st_bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) for (i=0; i < st_bp->frp_segs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) memset(page_address(st_bp->reserved_pages[i]), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) PAGE_SIZE << st_bp->reserved_page_order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) st_bp->cleared = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) /* Release the extra buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) static void normalize_buffer(struct st_buffer * STbuffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) int i, order = STbuffer->reserved_page_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) for (i = 0; i < STbuffer->frp_segs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) __free_pages(STbuffer->reserved_pages[i], order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) STbuffer->buffer_size -= (PAGE_SIZE << order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) STbuffer->frp_segs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) STbuffer->sg_segs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) STbuffer->reserved_page_order = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) STbuffer->map_data.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) /* Move data from the user buffer to the tape buffer. Returns zero (success) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) negative error code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) int i, cnt, res, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) int length = PAGE_SIZE << st_bp->reserved_page_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) for (i = 0, offset = st_bp->buffer_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) i < st_bp->frp_segs && offset >= length; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) offset -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) if (i == st_bp->frp_segs) { /* Should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) for (; i < st_bp->frp_segs && do_count > 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) struct page *page = st_bp->reserved_pages[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) cnt = length - offset < do_count ? length - offset : do_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) res = copy_from_user(page_address(page) + offset, ubp, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) do_count -= cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) st_bp->buffer_bytes += cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) ubp += cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) if (do_count) /* Should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) /* Move data from the tape buffer to the user buffer. Returns zero (success) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) negative error code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) int i, cnt, res, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) int length = PAGE_SIZE << st_bp->reserved_page_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) for (i = 0, offset = st_bp->read_pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) i < st_bp->frp_segs && offset >= length; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) offset -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) if (i == st_bp->frp_segs) { /* Should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) printk(KERN_WARNING "st: from_buffer offset overflow.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) for (; i < st_bp->frp_segs && do_count > 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) struct page *page = st_bp->reserved_pages[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) cnt = length - offset < do_count ? length - offset : do_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) res = copy_to_user(ubp, page_address(page) + offset, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) do_count -= cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) st_bp->buffer_bytes -= cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) st_bp->read_pointer += cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) ubp += cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) if (do_count) /* Should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) return (-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) /* Move data towards start of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) static void move_buffer_data(struct st_buffer * st_bp, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) int src_seg, dst_seg, src_offset = 0, dst_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) int count, total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) int length = PAGE_SIZE << st_bp->reserved_page_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) if (offset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) total=st_bp->buffer_bytes - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) src_offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) if (src_offset < length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) offset -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) st_bp->buffer_bytes = st_bp->read_pointer = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) for (dst_seg=dst_offset=0; total > 0; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) struct page *dpage = st_bp->reserved_pages[dst_seg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) struct page *spage = st_bp->reserved_pages[src_seg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) count = min(length - dst_offset, length - src_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) memmove(page_address(dpage) + dst_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) page_address(spage) + src_offset, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) src_offset += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) if (src_offset >= length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) src_seg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) src_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) dst_offset += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) if (dst_offset >= length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) dst_seg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) dst_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) total -= count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) /* Validate the options from command line or module parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) static void validate_options(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) if (buffer_kbs > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) if (max_sg_segs >= ST_FIRST_SG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) st_max_sg_segs = max_sg_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) /* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) static int __init st_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) int i, len, ints[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) char *stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) stp = get_options(str, ARRAY_SIZE(ints), ints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) if (ints[0] > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) if (parms[i].val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) *parms[i].val = ints[i + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) while (stp != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) for (i = 0; i < ARRAY_SIZE(parms); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) len = strlen(parms[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) if (!strncmp(stp, parms[i].name, len) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) (*(stp + len) == ':' || *(stp + len) == '=')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) if (parms[i].val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) *parms[i].val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) simple_strtoul(stp + len + 1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) printk(KERN_WARNING "st: Obsolete parameter %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) parms[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) if (i >= ARRAY_SIZE(parms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) printk(KERN_WARNING "st: invalid parameter in '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) stp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) stp = strchr(stp, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) if (stp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) stp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) validate_options();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) __setup("st=", st_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) static const struct file_operations st_fops =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) .read = st_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) .write = st_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) .unlocked_ioctl = st_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) .compat_ioctl = st_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) .open = st_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) .flush = st_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) .release = st_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) int i, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) dev_t cdev_devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) struct cdev *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) struct st_modedef *STm = &(tape->modes[mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) char name[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) int dev_num = tape->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) cdev_devno = MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, rew));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) cdev = cdev_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) if (!cdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) pr_err("st%d: out of memory. Device not attached.\n", dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) cdev->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) cdev->ops = &st_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) STm->cdevs[rew] = cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) error = cdev_add(cdev, cdev_devno, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) pr_err("st%d: Can't add %s-rewind mode %d\n", dev_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) rew ? "non" : "auto", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) pr_err("st%d: Device not attached.\n", dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) i = mode << (4 - ST_NBR_MODE_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) snprintf(name, 10, "%s%s%s", rew ? "n" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) tape->disk->disk_name, st_formats[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) dev = device_create(&st_sysfs_class, &tape->device->sdev_gendev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) cdev_devno, &tape->modes[mode], "%s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) if (IS_ERR(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) pr_err("st%d: device_create failed\n", dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) error = PTR_ERR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) STm->devs[rew] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) cdev_del(STm->cdevs[rew]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) STm->cdevs[rew] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) STm->devs[rew] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) static int create_cdevs(struct scsi_tape *tape)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) int mode, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) for (mode = 0; mode < ST_NBR_MODES; ++mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) error = create_one_cdev(tape, mode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) error = create_one_cdev(tape, mode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) return sysfs_create_link(&tape->device->sdev_gendev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) &tape->modes[0].devs[0]->kobj, "tape");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) static void remove_cdevs(struct scsi_tape *tape)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) int mode, rew;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) sysfs_remove_link(&tape->device->sdev_gendev.kobj, "tape");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) for (mode = 0; mode < ST_NBR_MODES; mode++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) struct st_modedef *STm = &(tape->modes[mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) for (rew = 0; rew < 2; rew++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) if (STm->cdevs[rew])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) cdev_del(STm->cdevs[rew]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) if (STm->devs[rew])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) device_unregister(STm->devs[rew]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) static int st_probe(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) struct scsi_device *SDp = to_scsi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) struct gendisk *disk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) struct scsi_tape *tpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) struct st_modedef *STm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) struct st_partstat *STps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) struct st_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) int i, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) char *stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) if (SDp->type != TYPE_TAPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) if ((stp = st_incompatible(SDp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) sdev_printk(KERN_INFO, SDp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) "OnStream tapes are no longer supported;\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) sdev_printk(KERN_INFO, SDp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) "please mail to linux-scsi@vger.kernel.org.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) scsi_autopm_get_device(SDp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) i = queue_max_segments(SDp->request_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) if (st_max_sg_segs < i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) i = st_max_sg_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) if (buffer == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) sdev_printk(KERN_ERR, SDp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) "st: Can't allocate new tape buffer. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) "Device not attached.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) disk = alloc_disk(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) if (!disk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) sdev_printk(KERN_ERR, SDp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) "st: out of memory. Device not attached.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) goto out_buffer_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) tpnt = kzalloc(sizeof(struct scsi_tape), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) if (tpnt == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) sdev_printk(KERN_ERR, SDp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) "st: Can't allocate device descriptor.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) goto out_put_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) kref_init(&tpnt->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) tpnt->disk = disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) disk->private_data = &tpnt->driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) /* SCSI tape doesn't register this gendisk via add_disk(). Manually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) * take queue reference that release_disk() expects. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) if (!blk_get_queue(SDp->request_queue))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) goto out_put_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) disk->queue = SDp->request_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) tpnt->driver = &st_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) tpnt->device = SDp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) if (SDp->scsi_level <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) tpnt->tape_type = MT_ISSCSI1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) tpnt->tape_type = MT_ISSCSI2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) tpnt->buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) tpnt->buffer->last_SRpnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) tpnt->inited = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) tpnt->dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) tpnt->in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) tpnt->density = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) tpnt->do_auto_lock = ST_AUTO_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) tpnt->can_partitions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) tpnt->two_fm = ST_TWO_FM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) tpnt->fast_mteom = ST_FAST_MTEOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) tpnt->scsi2_logical = ST_SCSI2LOGICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) tpnt->sili = ST_SILI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) tpnt->immediate = ST_NOWAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) tpnt->immediate_filemark = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) tpnt->default_drvbuffer = 0xff; /* No forced buffering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) tpnt->partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) tpnt->new_partition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) tpnt->nbr_partitions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) tpnt->long_timeout = ST_LONG_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) for (i = 0; i < ST_NBR_MODES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) STm = &(tpnt->modes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) STm->defined = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) STm->sysv = ST_SYSV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) STm->defaults_for_writes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) STm->do_async_writes = ST_ASYNC_WRITES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) STm->do_buffer_writes = ST_BUFFER_WRITES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) STm->do_read_ahead = ST_READ_AHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) STm->default_compression = ST_DONT_TOUCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) STm->default_blksize = (-1); /* No forced size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) STm->default_density = (-1); /* No forced density */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) STm->tape = tpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) for (i = 0; i < ST_NBR_PARTITIONS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) STps = &(tpnt->ps[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) STps->rw = ST_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) STps->eof = ST_NOEOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) STps->at_sm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) STps->last_block_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) STps->drv_block = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) STps->drv_file = (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) tpnt->current_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) tpnt->modes[0].defined = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) tpnt->density_changed = tpnt->compression_changed =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) tpnt->blksize_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) mutex_init(&tpnt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) idr_preload(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) spin_lock(&st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) error = idr_alloc(&st_index_idr, tpnt, 0, ST_MAX_TAPES + 1, GFP_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) spin_unlock(&st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) idr_preload_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) pr_warn("st: idr allocation failed: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) goto out_put_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) tpnt->index = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) sprintf(disk->disk_name, "st%d", tpnt->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) tpnt->stats = kzalloc(sizeof(struct scsi_tape_stats), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) if (tpnt->stats == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) sdev_printk(KERN_ERR, SDp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) "st: Can't allocate statistics.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) goto out_idr_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) dev_set_drvdata(dev, tpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) error = create_cdevs(tpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) goto out_remove_devs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) scsi_autopm_put_device(SDp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) sdev_printk(KERN_NOTICE, SDp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) "Attached scsi tape %s\n", tape_name(tpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) queue_dma_alignment(SDp->request_queue) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) out_remove_devs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) remove_cdevs(tpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) kfree(tpnt->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) out_idr_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) spin_lock(&st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) idr_remove(&st_index_idr, tpnt->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) spin_unlock(&st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) out_put_queue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) blk_put_queue(disk->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) out_put_disk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) put_disk(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) kfree(tpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) out_buffer_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) scsi_autopm_put_device(SDp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) static int st_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) struct scsi_tape *tpnt = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) int index = tpnt->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) scsi_autopm_get_device(to_scsi_device(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) remove_cdevs(tpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) mutex_lock(&st_ref_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) kref_put(&tpnt->kref, scsi_tape_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) mutex_unlock(&st_ref_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) spin_lock(&st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) idr_remove(&st_index_idr, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) spin_unlock(&st_index_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) * scsi_tape_release - Called to free the Scsi_Tape structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) * @kref: pointer to embedded kref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) * st_ref_mutex must be held entering this routine. Because it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) * called on last put, you should always use the scsi_tape_get()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) * scsi_tape_put() helpers which manipulate the semaphore directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) * and never do a direct kref_put().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) static void scsi_tape_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) struct scsi_tape *tpnt = to_scsi_tape(kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) struct gendisk *disk = tpnt->disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) tpnt->device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) if (tpnt->buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) normalize_buffer(tpnt->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) kfree(tpnt->buffer->reserved_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) kfree(tpnt->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) disk->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) put_disk(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) kfree(tpnt->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) kfree(tpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) static struct class st_sysfs_class = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) .name = "scsi_tape",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) .dev_groups = st_dev_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) static int __init init_st(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) validate_options();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) verstr, st_fixed_buffer_size, st_max_sg_segs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) debugging = (debug_flag > 0) ? debug_flag : NO_DEBUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) if (debugging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) printk(KERN_INFO "st: Debugging enabled debug_flag = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) debugging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) err = class_register(&st_sysfs_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) pr_err("Unable register sysfs class for SCSI tapes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) ST_MAX_TAPE_ENTRIES, "st");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) SCSI_TAPE_MAJOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) goto err_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) err = scsi_register_driver(&st_template.gendrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) goto err_chrdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) err_chrdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) ST_MAX_TAPE_ENTRIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) err_class:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) class_unregister(&st_sysfs_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) static void __exit exit_st(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) scsi_unregister_driver(&st_template.gendrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) ST_MAX_TAPE_ENTRIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) class_unregister(&st_sysfs_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) idr_destroy(&st_index_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) printk(KERN_INFO "st: Unloaded.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) module_init(init_st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) module_exit(exit_st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) /* The sysfs driver interface. Read-only at the moment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) static ssize_t try_direct_io_show(struct device_driver *ddp, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) return scnprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) static DRIVER_ATTR_RO(try_direct_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) static ssize_t fixed_buffer_size_show(struct device_driver *ddp, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) return scnprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) static DRIVER_ATTR_RO(fixed_buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) static ssize_t max_sg_segs_show(struct device_driver *ddp, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) return scnprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) static DRIVER_ATTR_RO(max_sg_segs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) static ssize_t version_show(struct device_driver *ddd, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) return scnprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) static DRIVER_ATTR_RO(version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) static ssize_t debug_flag_store(struct device_driver *ddp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) /* We only care what the first byte of the data is the rest is unused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) * if it's a '1' we turn on debug and if it's a '0' we disable it. All
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) * other values have -EINVAL returned if they are passed in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) if (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) if (buf[0] == '0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) debugging = NO_DEBUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) } else if (buf[0] == '1') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) debugging = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) static ssize_t debug_flag_show(struct device_driver *ddp, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) return scnprintf(buf, PAGE_SIZE, "%d\n", debugging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) static DRIVER_ATTR_RW(debug_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) static struct attribute *st_drv_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) &driver_attr_try_direct_io.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) &driver_attr_fixed_buffer_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) &driver_attr_max_sg_segs.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) &driver_attr_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) &driver_attr_debug_flag.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) ATTRIBUTE_GROUPS(st_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) /* The sysfs simple class interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) defined_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) ssize_t l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) return l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) static DEVICE_ATTR_RO(defined);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) default_blksize_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) ssize_t l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) return l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) static DEVICE_ATTR_RO(default_blksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) default_density_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) ssize_t l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) char *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) return l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) static DEVICE_ATTR_RO(default_density);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) default_compression_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) ssize_t l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) return l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) static DEVICE_ATTR_RO(default_compression);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) options_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) struct scsi_tape *STp = STm->tape;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) int options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) ssize_t l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) options |= STp->two_fm ? MT_ST_TWO_FM : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) options |= STm->sysv ? MT_ST_SYSV : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) options |= STp->immediate ? MT_ST_NOWAIT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) options |= STp->immediate_filemark ? MT_ST_NOWAIT_EOF : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) options |= STp->sili ? MT_ST_SILI : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) return l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) static DEVICE_ATTR_RO(options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) /* Support for tape stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) * read_cnt_show - return read count - count of reads made from tape drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) static ssize_t read_cnt_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) (long long)atomic64_read(&STm->tape->stats->read_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) static DEVICE_ATTR_RO(read_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) * read_byte_cnt_show - return read byte count - tape drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) * may use blocks less than 512 bytes this gives the raw byte count of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) * of data read from the tape drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) static ssize_t read_byte_cnt_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) (long long)atomic64_read(&STm->tape->stats->read_byte_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) static DEVICE_ATTR_RO(read_byte_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) * read_ns_show - return read ns - overall time spent waiting on reads in ns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) static ssize_t read_ns_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) (long long)atomic64_read(&STm->tape->stats->tot_read_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) static DEVICE_ATTR_RO(read_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) * write_cnt_show - write count - number of user calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) * to write(2) that have written data to tape.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) static ssize_t write_cnt_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) (long long)atomic64_read(&STm->tape->stats->write_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) static DEVICE_ATTR_RO(write_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) * write_byte_cnt_show - write byte count - raw count of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) * bytes written to tape.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) static ssize_t write_byte_cnt_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) (long long)atomic64_read(&STm->tape->stats->write_byte_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) static DEVICE_ATTR_RO(write_byte_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) * write_ns_show - write ns - number of nanoseconds waiting on write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) * requests to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) static ssize_t write_ns_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) (long long)atomic64_read(&STm->tape->stats->tot_write_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) static DEVICE_ATTR_RO(write_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) * in_flight_show - number of I/Os currently in flight -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) * in most cases this will be either 0 or 1. It may be higher if someone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) * has also issued other SCSI commands such as via an ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) static ssize_t in_flight_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) (long long)atomic64_read(&STm->tape->stats->in_flight));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) static DEVICE_ATTR_RO(in_flight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) * io_ns_show - io wait ns - this is the number of ns spent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) * waiting on all I/O to complete. This includes tape movement commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) * such as rewinding, seeking to end of file or tape, it also includes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) * read and write. To determine the time spent on tape movement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) * subtract the read and write ns from this value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) static ssize_t io_ns_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) (long long)atomic64_read(&STm->tape->stats->tot_io_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) static DEVICE_ATTR_RO(io_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) * other_cnt_show - other io count - this is the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) * I/O requests other than read and write requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) * Typically these are tape movement requests but will include driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) * tape movement. This includes only requests issued by the st driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) static ssize_t other_cnt_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) (long long)atomic64_read(&STm->tape->stats->other_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) static DEVICE_ATTR_RO(other_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) * resid_cnt_show - A count of the number of times we get a residual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) * count - this should indicate someone issuing reads larger than the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) * block size on tape.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) * @attr: attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) * @buf: buffer to return formatted data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) static ssize_t resid_cnt_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) struct st_modedef *STm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) return sprintf(buf, "%lld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) (long long)atomic64_read(&STm->tape->stats->resid_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) static DEVICE_ATTR_RO(resid_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) static struct attribute *st_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) &dev_attr_defined.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) &dev_attr_default_blksize.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) &dev_attr_default_density.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) &dev_attr_default_compression.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) &dev_attr_options.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) static struct attribute *st_stats_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) &dev_attr_read_cnt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) &dev_attr_read_byte_cnt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) &dev_attr_read_ns.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) &dev_attr_write_cnt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) &dev_attr_write_byte_cnt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) &dev_attr_write_ns.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) &dev_attr_in_flight.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) &dev_attr_io_ns.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) &dev_attr_other_cnt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) &dev_attr_resid_cnt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) static struct attribute_group stats_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) .name = "stats",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) .attrs = st_stats_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) static struct attribute_group st_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) .attrs = st_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) static const struct attribute_group *st_dev_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) &st_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) &stats_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) /* The following functions may be useful for a larger audience. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) static int sgl_map_user_pages(struct st_buffer *STbp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) const unsigned int max_pages, unsigned long uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) size_t count, int rw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) unsigned long start = uaddr >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) const int nr_pages = end - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) int res, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) struct rq_map_data *mdata = &STbp->map_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) /* User attempted Overflow! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) if ((uaddr + count) < uaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) /* Too big */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) if (nr_pages > max_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) /* Hmm? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) pages = kmalloc_array(max_pages, sizeof(*pages), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) if (pages == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) /* Try to fault in all of the necessary pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) /* rw==READ means read from drive, write into memory area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) res = pin_user_pages_fast(uaddr, nr_pages, rw == READ ? FOLL_WRITE : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) /* Errors and no page mapped should return here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) if (res < nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) for (i=0; i < nr_pages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) /* FIXME: flush superflous for rw==READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) * probably wrong function for rw==WRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) flush_dcache_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) mdata->offset = uaddr & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) STbp->mapped_pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) return nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) if (res > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) unpin_user_pages(pages, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) kfree(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) /* And unmap them... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) static int sgl_unmap_user_pages(struct st_buffer *STbp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) const unsigned int nr_pages, int dirtied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) /* FIXME: cache flush missing for rw==READ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) unpin_user_pages_dirty_lock(STbp->mapped_pages, nr_pages, dirtied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) kfree(STbp->mapped_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) STbp->mapped_pages = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) }