162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * This header file contains public constants and structures used by
462306a36Sopenharmony_ci * the SCSI initiator code.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef _SCSI_SCSI_H
762306a36Sopenharmony_ci#define _SCSI_SCSI_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/types.h>
1062306a36Sopenharmony_ci#include <linux/scatterlist.h>
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include <scsi/scsi_common.h>
1362306a36Sopenharmony_ci#include <scsi/scsi_proto.h>
1462306a36Sopenharmony_ci#include <scsi/scsi_status.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistruct scsi_cmnd;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cienum scsi_timeouts {
1962306a36Sopenharmony_ci	SCSI_DEFAULT_EH_TIMEOUT		= 10 * HZ,
2062306a36Sopenharmony_ci};
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/*
2362306a36Sopenharmony_ci * DIX-capable adapters effectively support infinite chaining for the
2462306a36Sopenharmony_ci * protection information scatterlist
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci#define SCSI_MAX_PROT_SG_SEGMENTS	0xFFFF
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/*
2962306a36Sopenharmony_ci * Special value for scanning to specify scanning or rescanning of all
3062306a36Sopenharmony_ci * possible channels, (target) ids, or luns on a given shost.
3162306a36Sopenharmony_ci */
3262306a36Sopenharmony_ci#define SCAN_WILD_CARD	~0
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/*
3562306a36Sopenharmony_ci * standard mode-select header prepended to all mode-select commands
3662306a36Sopenharmony_ci */
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistruct ccs_modesel_head {
3962306a36Sopenharmony_ci	__u8 _r1;			/* reserved */
4062306a36Sopenharmony_ci	__u8 medium;		/* device-specific medium type */
4162306a36Sopenharmony_ci	__u8 _r2;			/* reserved */
4262306a36Sopenharmony_ci	__u8 block_desc_length;	/* block descriptor length */
4362306a36Sopenharmony_ci	__u8 density;		/* device-specific density code */
4462306a36Sopenharmony_ci	__u8 number_blocks_hi;	/* number of blocks in this block desc */
4562306a36Sopenharmony_ci	__u8 number_blocks_med;
4662306a36Sopenharmony_ci	__u8 number_blocks_lo;
4762306a36Sopenharmony_ci	__u8 _r3;
4862306a36Sopenharmony_ci	__u8 block_length_hi;	/* block length for blocks in this desc */
4962306a36Sopenharmony_ci	__u8 block_length_med;
5062306a36Sopenharmony_ci	__u8 block_length_lo;
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/*
5462306a36Sopenharmony_ci * The Well Known LUNS (SAM-3) in our int representation of a LUN
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_ci#define SCSI_W_LUN_BASE 0xc100
5762306a36Sopenharmony_ci#define SCSI_W_LUN_REPORT_LUNS (SCSI_W_LUN_BASE + 1)
5862306a36Sopenharmony_ci#define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2)
5962306a36Sopenharmony_ci#define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3)
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic inline int scsi_is_wlun(u64 lun)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	return (lun & 0xff00) == SCSI_W_LUN_BASE;
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/**
6762306a36Sopenharmony_ci * scsi_status_is_check_condition - check the status return.
6862306a36Sopenharmony_ci *
6962306a36Sopenharmony_ci * @status: the status passed up from the driver (including host and
7062306a36Sopenharmony_ci *          driver components)
7162306a36Sopenharmony_ci *
7262306a36Sopenharmony_ci * This returns true if the status code is SAM_STAT_CHECK_CONDITION.
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_cistatic inline int scsi_status_is_check_condition(int status)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	if (status < 0)
7762306a36Sopenharmony_ci		return false;
7862306a36Sopenharmony_ci	status &= 0xfe;
7962306a36Sopenharmony_ci	return status == SAM_STAT_CHECK_CONDITION;
8062306a36Sopenharmony_ci}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci/*
8362306a36Sopenharmony_ci *  Extended message codes.
8462306a36Sopenharmony_ci */
8562306a36Sopenharmony_ci#define     EXTENDED_MODIFY_DATA_POINTER    0x00
8662306a36Sopenharmony_ci#define     EXTENDED_SDTR                   0x01
8762306a36Sopenharmony_ci#define     EXTENDED_EXTENDED_IDENTIFY      0x02    /* SCSI-I only */
8862306a36Sopenharmony_ci#define     EXTENDED_WDTR                   0x03
8962306a36Sopenharmony_ci#define     EXTENDED_PPR                    0x04
9062306a36Sopenharmony_ci#define     EXTENDED_MODIFY_BIDI_DATA_PTR   0x05
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/*
9362306a36Sopenharmony_ci * Internal return values.
9462306a36Sopenharmony_ci */
9562306a36Sopenharmony_cienum scsi_disposition {
9662306a36Sopenharmony_ci	NEEDS_RETRY		= 0x2001,
9762306a36Sopenharmony_ci	SUCCESS			= 0x2002,
9862306a36Sopenharmony_ci	FAILED			= 0x2003,
9962306a36Sopenharmony_ci	QUEUED			= 0x2004,
10062306a36Sopenharmony_ci	SOFT_ERROR		= 0x2005,
10162306a36Sopenharmony_ci	ADD_TO_MLQUEUE		= 0x2006,
10262306a36Sopenharmony_ci	TIMEOUT_ERROR		= 0x2007,
10362306a36Sopenharmony_ci	SCSI_RETURN_NOT_HANDLED	= 0x2008,
10462306a36Sopenharmony_ci	FAST_IO_FAIL		= 0x2009,
10562306a36Sopenharmony_ci};
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/*
10862306a36Sopenharmony_ci * Midlevel queue return values.
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_ci#define SCSI_MLQUEUE_HOST_BUSY   0x1055
11162306a36Sopenharmony_ci#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
11262306a36Sopenharmony_ci#define SCSI_MLQUEUE_EH_RETRY    0x1057
11362306a36Sopenharmony_ci#define SCSI_MLQUEUE_TARGET_BUSY 0x1058
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci/*
11662306a36Sopenharmony_ci *  Use these to separate status msg and our bytes
11762306a36Sopenharmony_ci *
11862306a36Sopenharmony_ci *  These are set by:
11962306a36Sopenharmony_ci *
12062306a36Sopenharmony_ci *      status byte = set from target device
12162306a36Sopenharmony_ci *      msg_byte    (unused)
12262306a36Sopenharmony_ci *      host_byte   = set by low-level driver to indicate status.
12362306a36Sopenharmony_ci */
12462306a36Sopenharmony_ci#define status_byte(result) (result & 0xff)
12562306a36Sopenharmony_ci#define host_byte(result)   (((result) >> 16) & 0xff)
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#define sense_class(sense)  (((sense) >> 4) & 0x7)
12862306a36Sopenharmony_ci#define sense_error(sense)  ((sense) & 0xf)
12962306a36Sopenharmony_ci#define sense_valid(sense)  ((sense) & 0x80)
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci/*
13262306a36Sopenharmony_ci * default timeouts
13362306a36Sopenharmony_ci*/
13462306a36Sopenharmony_ci#define FORMAT_UNIT_TIMEOUT		(2 * 60 * 60 * HZ)
13562306a36Sopenharmony_ci#define START_STOP_TIMEOUT		(60 * HZ)
13662306a36Sopenharmony_ci#define MOVE_MEDIUM_TIMEOUT		(5 * 60 * HZ)
13762306a36Sopenharmony_ci#define READ_ELEMENT_STATUS_TIMEOUT	(5 * 60 * HZ)
13862306a36Sopenharmony_ci#define READ_DEFECT_DATA_TIMEOUT	(60 * HZ )
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci#define IDENTIFY_BASE       0x80
14262306a36Sopenharmony_ci#define IDENTIFY(can_disconnect, lun)   (IDENTIFY_BASE |\
14362306a36Sopenharmony_ci		     ((can_disconnect) ?  0x40 : 0) |\
14462306a36Sopenharmony_ci		     ((lun) & 0x07))
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci/*
14762306a36Sopenharmony_ci *  struct scsi_device::scsi_level values. For SCSI devices other than those
14862306a36Sopenharmony_ci *  prior to SCSI-2 (i.e. over 12 years old) this value is (resp[2] + 1)
14962306a36Sopenharmony_ci *  where "resp" is a byte array of the response to an INQUIRY. The scsi_level
15062306a36Sopenharmony_ci *  variable is visible to the user via sysfs.
15162306a36Sopenharmony_ci */
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci#define SCSI_UNKNOWN    0
15462306a36Sopenharmony_ci#define SCSI_1          1
15562306a36Sopenharmony_ci#define SCSI_1_CCS      2
15662306a36Sopenharmony_ci#define SCSI_2          3
15762306a36Sopenharmony_ci#define SCSI_3          4        /* SPC */
15862306a36Sopenharmony_ci#define SCSI_SPC_2      5
15962306a36Sopenharmony_ci#define SCSI_SPC_3      6
16062306a36Sopenharmony_ci#define SCSI_SPC_4	7
16162306a36Sopenharmony_ci#define SCSI_SPC_5	8
16262306a36Sopenharmony_ci#define SCSI_SPC_6	14
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci/*
16562306a36Sopenharmony_ci * INQ PERIPHERAL QUALIFIERS
16662306a36Sopenharmony_ci */
16762306a36Sopenharmony_ci#define SCSI_INQ_PQ_CON         0x00
16862306a36Sopenharmony_ci#define SCSI_INQ_PQ_NOT_CON     0x01
16962306a36Sopenharmony_ci#define SCSI_INQ_PQ_NOT_CAP     0x03
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci/*
17362306a36Sopenharmony_ci * Here are some scsi specific ioctl commands which are sometimes useful.
17462306a36Sopenharmony_ci *
17562306a36Sopenharmony_ci * Note that include/linux/cdrom.h also defines IOCTL 0x5300 - 0x5395
17662306a36Sopenharmony_ci */
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci/* Used to obtain PUN and LUN info.  Conflicts with CDROMAUDIOBUFSIZ */
17962306a36Sopenharmony_ci#define SCSI_IOCTL_GET_IDLUN		0x5382
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci/* 0x5383 and 0x5384 were used for SCSI_IOCTL_TAGGED_{ENABLE,DISABLE} */
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/* Used to obtain the host number of a device. */
18462306a36Sopenharmony_ci#define SCSI_IOCTL_PROBE_HOST		0x5385
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci/* Used to obtain the bus number for a device */
18762306a36Sopenharmony_ci#define SCSI_IOCTL_GET_BUS_NUMBER	0x5386
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci/* Used to obtain the PCI location of a device */
19062306a36Sopenharmony_ci#define SCSI_IOCTL_GET_PCI		0x5387
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci/** scsi_status_is_good - check the status return.
19362306a36Sopenharmony_ci *
19462306a36Sopenharmony_ci * @status: the status passed up from the driver (including host and
19562306a36Sopenharmony_ci *          driver components)
19662306a36Sopenharmony_ci *
19762306a36Sopenharmony_ci * This returns true for known good conditions that may be treated as
19862306a36Sopenharmony_ci * command completed normally
19962306a36Sopenharmony_ci */
20062306a36Sopenharmony_cistatic inline bool scsi_status_is_good(int status)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	if (status < 0)
20362306a36Sopenharmony_ci		return false;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	if (host_byte(status) == DID_NO_CONNECT)
20662306a36Sopenharmony_ci		return false;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	/*
20962306a36Sopenharmony_ci	 * FIXME: bit0 is listed as reserved in SCSI-2, but is
21062306a36Sopenharmony_ci	 * significant in SCSI-3.  For now, we follow the SCSI-2
21162306a36Sopenharmony_ci	 * behaviour and ignore reserved bits.
21262306a36Sopenharmony_ci	 */
21362306a36Sopenharmony_ci	status &= 0xfe;
21462306a36Sopenharmony_ci	return ((status == SAM_STAT_GOOD) ||
21562306a36Sopenharmony_ci		(status == SAM_STAT_CONDITION_MET) ||
21662306a36Sopenharmony_ci		/* Next two "intermediate" statuses are obsolete in SAM-4 */
21762306a36Sopenharmony_ci		(status == SAM_STAT_INTERMEDIATE) ||
21862306a36Sopenharmony_ci		(status == SAM_STAT_INTERMEDIATE_CONDITION_MET) ||
21962306a36Sopenharmony_ci		/* FIXME: this is obsolete in SAM-3 */
22062306a36Sopenharmony_ci		(status == SAM_STAT_COMMAND_TERMINATED));
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci#endif /* _SCSI_SCSI_H */
224