Contributors: 18
Author Tokens Token Proportion Commits Commit Proportion
James Bottomley 92 23.12% 4 14.29%
Boaz Harrosh 86 21.61% 1 3.57%
Michael Christie 49 12.31% 2 7.14%
Hannes Reinecke 28 7.04% 4 14.29%
Bart Van Assche 26 6.53% 3 10.71%
FUJITA Tomonori 21 5.28% 1 3.57%
James Smart 15 3.77% 1 3.57%
Roman Bolshakov 14 3.52% 1 3.57%
David Disseldorp 12 3.02% 1 3.57%
Sagi Grimberg 12 3.02% 2 7.14%
Martin K. Petersen 10 2.51% 1 3.57%
Matthew Wilcox 10 2.51% 1 3.57%
Douglas Gilbert 9 2.26% 1 3.57%
Linus Torvalds (pre-git) 4 1.01% 1 3.57%
Linus Torvalds 4 1.01% 1 3.57%
Christof Schmitt 3 0.75% 1 3.57%
Subhash Jadavani 2 0.50% 1 3.57%
Greg Kroah-Hartman 1 0.25% 1 3.57%
Total 398 28


/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Functions used by both the SCSI initiator code and the SCSI target code.
 */

#ifndef _SCSI_COMMON_H_
#define _SCSI_COMMON_H_

#include <linux/types.h>
#include <uapi/linux/pr.h>
#include <scsi/scsi_proto.h>

/* From the standard INQUIRY data description in SPC-6. */
#define INQUIRY_VENDOR_OFFSET	8
#define INQUIRY_VENDOR_LEN	8
#define INQUIRY_MODEL_OFFSET	16
#define INQUIRY_MODEL_LEN	16
#define INQUIRY_REVISION_OFFSET	32
#define INQUIRY_REVISION_LEN	4

enum scsi_pr_type {
	SCSI_PR_WRITE_EXCLUSIVE			= 0x01,
	SCSI_PR_EXCLUSIVE_ACCESS		= 0x03,
	SCSI_PR_WRITE_EXCLUSIVE_REG_ONLY	= 0x05,
	SCSI_PR_EXCLUSIVE_ACCESS_REG_ONLY	= 0x06,
	SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS	= 0x07,
	SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS	= 0x08,
};

enum scsi_pr_type block_pr_type_to_scsi(enum pr_type type);
enum pr_type scsi_pr_type_to_block(enum scsi_pr_type type);

static inline unsigned
scsi_varlen_cdb_length(const void *hdr)
{
	return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8;
}

extern const unsigned char scsi_command_size_tbl[8];
#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7]

static inline unsigned
scsi_command_size(const unsigned char *cmnd)
{
	return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
		scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);
}

static inline unsigned char
scsi_command_control(const unsigned char *cmnd)
{
	return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
		cmnd[1] : cmnd[COMMAND_SIZE(cmnd[0]) - 1];
}

/* Returns a human-readable name for the device */
extern const char *scsi_device_type(unsigned type);

extern void int_to_scsilun(u64, struct scsi_lun *);
extern u64 scsilun_to_int(struct scsi_lun *);

/*
 * This is a slightly modified SCSI sense "descriptor" format header.
 * The addition is to allow the 0x70 and 0x71 response codes. The idea
 * is to place the salient data from either "fixed" or "descriptor" sense
 * format into one structure to ease application processing.
 *
 * The original sense buffer should be kept around for those cases
 * in which more information is required (e.g. the LBA of a MEDIUM ERROR).
 */
struct scsi_sense_hdr {		/* See SPC-3 section 4.5 */
	u8 response_code;	/* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
	u8 sense_key;
	u8 asc;
	u8 ascq;
	u8 byte4;
	u8 byte5;
	u8 byte6;
	u8 additional_length;	/* always 0 for fixed sense format */
};

static inline bool scsi_sense_valid(const struct scsi_sense_hdr *sshdr)
{
	if (!sshdr)
		return false;

	return (sshdr->response_code & 0x70) == 0x70;
}

extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
				 struct scsi_sense_hdr *sshdr);

extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq);
int scsi_set_sense_information(u8 *buf, int buf_len, u64 info);
int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd);
extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
				       int desc_type);

#endif /* _SCSI_COMMON_H_ */