^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Functions used by both the SCSI initiator code and the SCSI target code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef _SCSI_COMMON_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define _SCSI_COMMON_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <scsi/scsi_proto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static inline unsigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) scsi_varlen_cdb_length(const void *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) extern const unsigned char scsi_command_size_tbl[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static inline unsigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) scsi_command_size(const unsigned char *cmnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static inline unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) scsi_command_control(const unsigned char *cmnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) cmnd[1] : cmnd[COMMAND_SIZE(cmnd[0]) - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Returns a human-readable name for the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) extern const char *scsi_device_type(unsigned type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) extern void int_to_scsilun(u64, struct scsi_lun *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) extern u64 scsilun_to_int(struct scsi_lun *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * This is a slightly modified SCSI sense "descriptor" format header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * The addition is to allow the 0x70 and 0x71 response codes. The idea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * is to place the salient data from either "fixed" or "descriptor" sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * format into one structure to ease application processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * The original sense buffer should be kept around for those cases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * in which more information is required (e.g. the LBA of a MEDIUM ERROR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct scsi_sense_hdr { /* See SPC-3 section 4.5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u8 sense_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u8 asc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u8 ascq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u8 byte4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u8 byte5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u8 byte6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u8 additional_length; /* always 0 for fixed sense format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static inline bool scsi_sense_valid(const struct scsi_sense_hdr *sshdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!sshdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return (sshdr->response_code & 0x70) == 0x70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct scsi_sense_hdr *sshdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int scsi_set_sense_information(u8 *buf, int buf_len, u64 info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int desc_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #endif /* _SCSI_COMMON_H_ */