162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#ifndef _ST_H
462306a36Sopenharmony_ci#define _ST_H
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/completion.h>
762306a36Sopenharmony_ci#include <linux/mutex.h>
862306a36Sopenharmony_ci#include <linux/kref.h>
962306a36Sopenharmony_ci#include <scsi/scsi_cmnd.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/* Descriptor for analyzed sense data */
1262306a36Sopenharmony_cistruct st_cmdstatus {
1362306a36Sopenharmony_ci	int midlevel_result;
1462306a36Sopenharmony_ci	struct scsi_sense_hdr sense_hdr;
1562306a36Sopenharmony_ci	int have_sense;
1662306a36Sopenharmony_ci	int residual;
1762306a36Sopenharmony_ci	u64 uremainder64;
1862306a36Sopenharmony_ci	u8 flags;
1962306a36Sopenharmony_ci	u8 remainder_valid;
2062306a36Sopenharmony_ci	u8 fixed_format;
2162306a36Sopenharmony_ci	u8 deferred;
2262306a36Sopenharmony_ci};
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct scsi_tape;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci/* scsi tape command */
2762306a36Sopenharmony_cistruct st_request {
2862306a36Sopenharmony_ci	unsigned char cmd[MAX_COMMAND_SIZE];
2962306a36Sopenharmony_ci	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
3062306a36Sopenharmony_ci	int result;
3162306a36Sopenharmony_ci	struct scsi_tape *stp;
3262306a36Sopenharmony_ci	struct completion *waiting;
3362306a36Sopenharmony_ci	struct bio *bio;
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/* The tape buffer descriptor. */
3762306a36Sopenharmony_cistruct st_buffer {
3862306a36Sopenharmony_ci	unsigned char cleared;  /* internal buffer cleared after open? */
3962306a36Sopenharmony_ci	unsigned short do_dio;  /* direct i/o set up? */
4062306a36Sopenharmony_ci	int buffer_size;
4162306a36Sopenharmony_ci	int buffer_blocks;
4262306a36Sopenharmony_ci	int buffer_bytes;
4362306a36Sopenharmony_ci	int read_pointer;
4462306a36Sopenharmony_ci	int writing;
4562306a36Sopenharmony_ci	int syscall_result;
4662306a36Sopenharmony_ci	struct st_request *last_SRpnt;
4762306a36Sopenharmony_ci	struct st_cmdstatus cmdstat;
4862306a36Sopenharmony_ci	struct page **reserved_pages;
4962306a36Sopenharmony_ci	int reserved_page_order;
5062306a36Sopenharmony_ci	struct page **mapped_pages;
5162306a36Sopenharmony_ci	struct rq_map_data map_data;
5262306a36Sopenharmony_ci	unsigned char *b_data;
5362306a36Sopenharmony_ci	unsigned short use_sg;	/* zero or max number of s/g segments for this adapter */
5462306a36Sopenharmony_ci	unsigned short sg_segs;		/* number of segments in s/g list */
5562306a36Sopenharmony_ci	unsigned short frp_segs;	/* number of buffer segments */
5662306a36Sopenharmony_ci};
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/* The tape mode definition */
5962306a36Sopenharmony_cistruct st_modedef {
6062306a36Sopenharmony_ci	unsigned char defined;
6162306a36Sopenharmony_ci	unsigned char sysv;	/* SYS V semantics? */
6262306a36Sopenharmony_ci	unsigned char do_async_writes;
6362306a36Sopenharmony_ci	unsigned char do_buffer_writes;
6462306a36Sopenharmony_ci	unsigned char do_read_ahead;
6562306a36Sopenharmony_ci	unsigned char defaults_for_writes;
6662306a36Sopenharmony_ci	unsigned char default_compression;	/* 0 = don't touch, etc */
6762306a36Sopenharmony_ci	short default_density;	/* Forced density, -1 = no value */
6862306a36Sopenharmony_ci	int default_blksize;	/* Forced blocksize, -1 = no value */
6962306a36Sopenharmony_ci	struct scsi_tape *tape;
7062306a36Sopenharmony_ci	struct device *devs[2];  /* Auto-rewind and non-rewind devices */
7162306a36Sopenharmony_ci	struct cdev *cdevs[2];  /* Auto-rewind and non-rewind devices */
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci/* Number of modes can be changed by changing ST_NBR_MODE_BITS. The maximum
7562306a36Sopenharmony_ci   number of modes is 16 (ST_NBR_MODE_BITS 4) */
7662306a36Sopenharmony_ci#define ST_NBR_MODE_BITS 2
7762306a36Sopenharmony_ci#define ST_NBR_MODES (1 << ST_NBR_MODE_BITS)
7862306a36Sopenharmony_ci#define ST_MODE_SHIFT (7 - ST_NBR_MODE_BITS)
7962306a36Sopenharmony_ci#define ST_MODE_MASK ((ST_NBR_MODES - 1) << ST_MODE_SHIFT)
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#define ST_MAX_TAPES (1 << (20 - (ST_NBR_MODE_BITS + 1)))
8262306a36Sopenharmony_ci#define ST_MAX_TAPE_ENTRIES  (ST_MAX_TAPES << (ST_NBR_MODE_BITS + 1))
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/* The status related to each partition */
8562306a36Sopenharmony_cistruct st_partstat {
8662306a36Sopenharmony_ci	unsigned char rw;
8762306a36Sopenharmony_ci	unsigned char eof;
8862306a36Sopenharmony_ci	unsigned char at_sm;
8962306a36Sopenharmony_ci	unsigned char last_block_valid;
9062306a36Sopenharmony_ci	u32 last_block_visited;
9162306a36Sopenharmony_ci	int drv_block;		/* The block where the drive head is */
9262306a36Sopenharmony_ci	int drv_file;
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/* Tape statistics */
9662306a36Sopenharmony_cistruct scsi_tape_stats {
9762306a36Sopenharmony_ci	atomic64_t read_byte_cnt;  /* bytes read */
9862306a36Sopenharmony_ci	atomic64_t write_byte_cnt; /* bytes written */
9962306a36Sopenharmony_ci	atomic64_t in_flight;      /* Number of I/Os in flight */
10062306a36Sopenharmony_ci	atomic64_t read_cnt;       /* Count of read requests */
10162306a36Sopenharmony_ci	atomic64_t write_cnt;      /* Count of write requests */
10262306a36Sopenharmony_ci	atomic64_t other_cnt;      /* Count of other requests either
10362306a36Sopenharmony_ci				    * implicit or from user space
10462306a36Sopenharmony_ci				    * ioctl. */
10562306a36Sopenharmony_ci	atomic64_t resid_cnt;      /* Count of resid_len > 0 */
10662306a36Sopenharmony_ci	atomic64_t tot_read_time;  /* ktime spent completing reads */
10762306a36Sopenharmony_ci	atomic64_t tot_write_time; /* ktime spent completing writes */
10862306a36Sopenharmony_ci	atomic64_t tot_io_time;    /* ktime spent doing any I/O */
10962306a36Sopenharmony_ci	ktime_t read_time;         /* holds ktime request was queued */
11062306a36Sopenharmony_ci	ktime_t write_time;        /* holds ktime request was queued */
11162306a36Sopenharmony_ci	ktime_t other_time;        /* holds ktime request was queued */
11262306a36Sopenharmony_ci	atomic_t last_read_size;   /* Number of bytes issued for last read */
11362306a36Sopenharmony_ci	atomic_t last_write_size;  /* Number of bytes issued for last write */
11462306a36Sopenharmony_ci};
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci#define ST_NBR_PARTITIONS 4
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci/* The tape drive descriptor */
11962306a36Sopenharmony_cistruct scsi_tape {
12062306a36Sopenharmony_ci	struct scsi_device *device;
12162306a36Sopenharmony_ci	struct mutex lock;	/* For serialization */
12262306a36Sopenharmony_ci	struct completion wait;	/* For SCSI commands */
12362306a36Sopenharmony_ci	struct st_buffer *buffer;
12462306a36Sopenharmony_ci	int index;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	/* Drive characteristics */
12762306a36Sopenharmony_ci	unsigned char omit_blklims;
12862306a36Sopenharmony_ci	unsigned char do_auto_lock;
12962306a36Sopenharmony_ci	unsigned char can_bsr;
13062306a36Sopenharmony_ci	unsigned char can_partitions;
13162306a36Sopenharmony_ci	unsigned char two_fm;
13262306a36Sopenharmony_ci	unsigned char fast_mteom;
13362306a36Sopenharmony_ci	unsigned char immediate;
13462306a36Sopenharmony_ci	unsigned char scsi2_logical;
13562306a36Sopenharmony_ci	unsigned char default_drvbuffer;	/* 0xff = don't touch, value 3 bits */
13662306a36Sopenharmony_ci	unsigned char cln_mode;			/* 0 = none, otherwise sense byte nbr */
13762306a36Sopenharmony_ci	unsigned char cln_sense_value;
13862306a36Sopenharmony_ci	unsigned char cln_sense_mask;
13962306a36Sopenharmony_ci	unsigned char use_pf;			/* Set Page Format bit in all mode selects? */
14062306a36Sopenharmony_ci	unsigned char try_dio;			/* try direct i/o in general? */
14162306a36Sopenharmony_ci	unsigned char try_dio_now;		/* try direct i/o before next close? */
14262306a36Sopenharmony_ci	unsigned char c_algo;			/* compression algorithm */
14362306a36Sopenharmony_ci	unsigned char pos_unknown;			/* after reset position unknown */
14462306a36Sopenharmony_ci	unsigned char sili;			/* use SILI when reading in variable b mode */
14562306a36Sopenharmony_ci	unsigned char immediate_filemark;	/* write filemark immediately */
14662306a36Sopenharmony_ci	int tape_type;
14762306a36Sopenharmony_ci	int long_timeout;	/* timeout for commands known to take long time */
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	/* Mode characteristics */
15062306a36Sopenharmony_ci	struct st_modedef modes[ST_NBR_MODES];
15162306a36Sopenharmony_ci	int current_mode;
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	/* Status variables */
15462306a36Sopenharmony_ci	int partition;
15562306a36Sopenharmony_ci	int new_partition;
15662306a36Sopenharmony_ci	int nbr_partitions;	/* zero until partition support enabled */
15762306a36Sopenharmony_ci	struct st_partstat ps[ST_NBR_PARTITIONS];
15862306a36Sopenharmony_ci	unsigned char dirty;
15962306a36Sopenharmony_ci	unsigned char ready;
16062306a36Sopenharmony_ci	unsigned char write_prot;
16162306a36Sopenharmony_ci	unsigned char drv_write_prot;
16262306a36Sopenharmony_ci	unsigned char in_use;
16362306a36Sopenharmony_ci	unsigned char blksize_changed;
16462306a36Sopenharmony_ci	unsigned char density_changed;
16562306a36Sopenharmony_ci	unsigned char compression_changed;
16662306a36Sopenharmony_ci	unsigned char drv_buffer;
16762306a36Sopenharmony_ci	unsigned char density;
16862306a36Sopenharmony_ci	unsigned char door_locked;
16962306a36Sopenharmony_ci	unsigned char autorew_dev;   /* auto-rewind device */
17062306a36Sopenharmony_ci	unsigned char rew_at_close;  /* rewind necessary at close */
17162306a36Sopenharmony_ci	unsigned char inited;
17262306a36Sopenharmony_ci	unsigned char cleaning_req;  /* cleaning requested? */
17362306a36Sopenharmony_ci	int block_size;
17462306a36Sopenharmony_ci	int min_block;
17562306a36Sopenharmony_ci	int max_block;
17662306a36Sopenharmony_ci	int recover_count;     /* From tape opening */
17762306a36Sopenharmony_ci	int recover_reg;       /* From last status call */
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci#if DEBUG
18062306a36Sopenharmony_ci	unsigned char write_pending;
18162306a36Sopenharmony_ci	int nbr_finished;
18262306a36Sopenharmony_ci	int nbr_waits;
18362306a36Sopenharmony_ci	int nbr_requests;
18462306a36Sopenharmony_ci	int nbr_dio;
18562306a36Sopenharmony_ci	int nbr_pages;
18662306a36Sopenharmony_ci	unsigned char last_cmnd[6];
18762306a36Sopenharmony_ci	unsigned char last_sense[16];
18862306a36Sopenharmony_ci#endif
18962306a36Sopenharmony_ci	char name[DISK_NAME_LEN];
19062306a36Sopenharmony_ci	struct kref     kref;
19162306a36Sopenharmony_ci	struct scsi_tape_stats *stats;
19262306a36Sopenharmony_ci};
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci/* Bit masks for use_pf */
19562306a36Sopenharmony_ci#define USE_PF      1
19662306a36Sopenharmony_ci#define PF_TESTED   2
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci/* Values of eof */
19962306a36Sopenharmony_ci#define	ST_NOEOF	0
20062306a36Sopenharmony_ci#define ST_FM_HIT       1
20162306a36Sopenharmony_ci#define ST_FM           2
20262306a36Sopenharmony_ci#define ST_EOM_OK       3
20362306a36Sopenharmony_ci#define ST_EOM_ERROR	4
20462306a36Sopenharmony_ci#define	ST_EOD_1        5
20562306a36Sopenharmony_ci#define ST_EOD_2        6
20662306a36Sopenharmony_ci#define ST_EOD		7
20762306a36Sopenharmony_ci/* EOD hit while reading => ST_EOD_1 => return zero => ST_EOD_2 =>
20862306a36Sopenharmony_ci   return zero => ST_EOD, return ENOSPC */
20962306a36Sopenharmony_ci/* When writing: ST_EOM_OK == early warning found, write OK
21062306a36Sopenharmony_ci		 ST_EOD_1  == allow trying new write after early warning
21162306a36Sopenharmony_ci		 ST_EOM_ERROR == early warning found, not able to write all */
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci/* Values of rw */
21462306a36Sopenharmony_ci#define	ST_IDLE		0
21562306a36Sopenharmony_ci#define	ST_READING	1
21662306a36Sopenharmony_ci#define	ST_WRITING	2
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci/* Values of ready state */
21962306a36Sopenharmony_ci#define ST_READY	0
22062306a36Sopenharmony_ci#define ST_NOT_READY	1
22162306a36Sopenharmony_ci#define ST_NO_TAPE	2
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci/* Values for door lock state */
22462306a36Sopenharmony_ci#define ST_UNLOCKED	0
22562306a36Sopenharmony_ci#define ST_LOCKED_EXPLICIT 1
22662306a36Sopenharmony_ci#define ST_LOCKED_AUTO  2
22762306a36Sopenharmony_ci#define ST_LOCK_FAILS   3
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci/* Positioning SCSI-commands for Tandberg, etc. drives */
23062306a36Sopenharmony_ci#define	QFA_REQUEST_BLOCK	0x02
23162306a36Sopenharmony_ci#define	QFA_SEEK_BLOCK		0x0c
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci/* Setting the binary options */
23462306a36Sopenharmony_ci#define ST_DONT_TOUCH  0
23562306a36Sopenharmony_ci#define ST_NO          1
23662306a36Sopenharmony_ci#define ST_YES         2
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci#define EXTENDED_SENSE_START  18
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci/* Masks for some conditions in the sense data */
24162306a36Sopenharmony_ci#define SENSE_FMK   0x80
24262306a36Sopenharmony_ci#define SENSE_EOM   0x40
24362306a36Sopenharmony_ci#define SENSE_ILI   0x20
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci#endif
246