linux/include/scsi/sas.h

/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * SAS structures and definitions header file
 *
 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
 * Copyright (C) 2005 Luben Tuikov <[email protected]>
 */

#ifndef _SAS_H_
#define _SAS_H_

#include <linux/types.h>
#include <asm/byteorder.h>

#define SAS_ADDR_SIZE
#define HASHED_SAS_ADDR_SIZE
#define SAS_ADDR(_sa)

#define SMP_REQUEST
#define SMP_RESPONSE

#define SSP_DATA
#define SSP_XFER_RDY
#define SSP_COMMAND
#define SSP_RESPONSE
#define SSP_TASK

#define SMP_REPORT_GENERAL
#define SMP_REPORT_MANUF_INFO
#define SMP_READ_GPIO_REG
#define SMP_DISCOVER
#define SMP_REPORT_PHY_ERR_LOG
#define SMP_REPORT_PHY_SATA
#define SMP_REPORT_ROUTE_INFO
#define SMP_WRITE_GPIO_REG
#define SMP_CONF_ROUTE_INFO
#define SMP_PHY_CONTROL
#define SMP_PHY_TEST_FUNCTION

#define SMP_RESP_FUNC_ACC
#define SMP_RESP_FUNC_UNK
#define SMP_RESP_FUNC_FAILED
#define SMP_RESP_INV_FRM_LEN
#define SMP_RESP_NO_PHY
#define SMP_RESP_NO_INDEX
#define SMP_RESP_PHY_NO_SATA
#define SMP_RESP_PHY_UNK_OP
#define SMP_RESP_PHY_UNK_TESTF
#define SMP_RESP_PHY_TEST_INPROG
#define SMP_RESP_PHY_VACANT

/* SAM TMFs */
#define TMF_ABORT_TASK
#define TMF_ABORT_TASK_SET
#define TMF_CLEAR_TASK_SET
#define TMF_LU_RESET
#define TMF_CLEAR_ACA
#define TMF_QUERY_TASK

/* SAS TMF responses */
#define TMF_RESP_FUNC_COMPLETE
#define TMF_RESP_INVALID_FRAME
#define TMF_RESP_FUNC_ESUPP
#define TMF_RESP_FUNC_FAILED
#define TMF_RESP_FUNC_SUCC
#define TMF_RESP_NO_LUN
#define TMF_RESP_OVERLAPPED_TAG

enum sas_oob_mode {};

/* See sas_discover.c if you plan on changing these */
enum sas_device_type {};

enum sas_protocol {};

/* From the spec; local phys only */
enum phy_func {};

/* SAS LLDD would need to report only _very_few_ of those, like BROADCAST.
 * Most of those are here for completeness.
 */
enum sas_prim {};

enum sas_open_rej_reason {};

enum sas_gpio_reg_type {};

/* Response frame DATAPRES field */
enum {};

struct  dev_to_host_fis {} __attribute__ ((packed));

struct host_to_dev_fis {} __attribute__ ((packed));

/* Prefer to have code clarity over header file clarity.
 */
#ifdef __LITTLE_ENDIAN_BITFIELD
struct sas_identify_frame {} __attribute__ ((packed));

struct ssp_frame_hdr {} __attribute__ ((packed));

struct ssp_response_iu {} __attribute__ ((packed));

struct ssp_command_iu {} __attribute__ ((packed));

struct xfer_rdy_iu {} __attribute__ ((packed));

struct ssp_tmf_iu {} __attribute__ ((packed));

/* ---------- SMP ---------- */

struct report_general_resp {} __attribute__ ((packed));

struct discover_resp {} __attribute__ ((packed));

struct report_phy_sata_resp {} __attribute__ ((packed));

#elif defined(__BIG_ENDIAN_BITFIELD)
struct sas_identify_frame {
	/* Byte 0 */
	u8  _un0:1;
	u8  dev_type:3;
	u8  frame_type:4;

	/* Byte 1 */
	u8  _un1;

	/* Byte 2 */
	union {
		struct {
			u8  _un247:4;
			u8  ssp_iport:1;
			u8  stp_iport:1;
			u8  smp_iport:1;
			u8  _un20:1;
		};
		u8 initiator_bits;
	};

	/* Byte 3 */
	union {
		struct {
			u8 _un347:4;
			u8 ssp_tport:1;
			u8 stp_tport:1;
			u8 smp_tport:1;
			u8 _un30:1;
		};
		u8 target_bits;
	};

	/* Byte 4 - 11 */
	u8 _un4_11[8];

	/* Byte 12 - 19 */
	u8 sas_addr[SAS_ADDR_SIZE];

	/* Byte 20 */
	u8 phy_id;

	u8 _un21_27[7];

	__be32 crc;
} __attribute__ ((packed));

struct ssp_frame_hdr {
	u8     frame_type;
	u8     hashed_dest_addr[HASHED_SAS_ADDR_SIZE];
	u8     _r_a;
	u8     hashed_src_addr[HASHED_SAS_ADDR_SIZE];
	__be16 _r_b;

	u8     _r_c:5;
	u8     retry_data_frames:1;
	u8     retransmit:1;
	u8     changing_data_ptr:1;

	u8     _r_d:6;
	u8     num_fill_bytes:2;

	u32    _r_e;
	__be16 tag;
	__be16 tptt;
	__be32 data_offs;
} __attribute__ ((packed));

struct ssp_response_iu {
	u8     _r_a[10];

	u8     _r_b:6;
	u8     datapres:2;

	u8     status;

	u32    _r_c;

	__be32 sense_data_len;
	__be32 response_data_len;

	union {
		DECLARE_FLEX_ARRAY(u8, resp_data);
		DECLARE_FLEX_ARRAY(u8, sense_data);
	};
} __attribute__ ((packed));

struct ssp_command_iu {
	u8     lun[8];
	u8     _r_a;

	union {
		struct {
			u8  efb:1;
			u8  prio:4;
			u8  attr:3;
		};
		u8 efb_prio_attr;
	};

	u8    _r_b;

	u8    add_cdb_len:6;
	u8    _r_c:2;

	u8    cdb[16];
	u8    add_cdb[];
} __attribute__ ((packed));

struct xfer_rdy_iu {
	__be32 requested_offset;
	__be32 write_data_len;
	__be32 _r_a;
} __attribute__ ((packed));

struct ssp_tmf_iu {
	u8     lun[8];
	u16    _r_a;
	u8     tmf;
	u8     _r_b;
	__be16 tag;
	u8     _r_c[14];
} __attribute__ ((packed));

/* ---------- SMP ---------- */

struct report_general_resp {
	__be16  change_count;
	__be16  route_indexes;
	u8      _r_a;
	u8      num_phys;

	u8	t2t_supp:1;
	u8	zone_config:1;
	u8	self_config:1;
	u8	stp_cont_awt:1;
	u8	orej_retry_supp:1;
	u8	config_others:1;
	u8      configuring:1;
	u8      conf_route_table:1;

	u8      _r_c;

	u8      enclosure_logical_id[8];

	u8      _r_d[12];
} __attribute__ ((packed));

struct discover_resp {
	u8    _r_a[5];

	u8    phy_id;
	__be16 _r_b;

	u8    _r_d:1;
	u8    attached_dev_type:3;
	u8    _r_c:4;

	u8    _r_e:4;
	u8    linkrate:4;

	u8    _r_f:4;
	u8    iproto:3;
	u8    attached_sata_host:1;

	u8    attached_sata_ps:1;
	u8    _r_g:3;
	u8    tproto:3;
	u8    attached_sata_dev:1;

	u8    sas_addr[8];
	u8    attached_sas_addr[8];
	u8    attached_phy_id;

	u8    _r_h[7];

	u8    pmin_linkrate:4;
	u8    hmin_linkrate:4;
	u8    pmax_linkrate:4;
	u8    hmax_linkrate:4;

	u8    change_count;

	u8    virtual:1;
	u8    _r_i:3;
	u8    pptv:4;

	u8    _r_j:4;
	u8    routing_attr:4;

	u8    conn_type;
	u8    conn_el_index;
	u8    conn_phy_link;

	u8    _r_k[8];
} __attribute__ ((packed));

struct report_phy_sata_resp {
	u8    _r_a[5];

	u8    phy_id;
	u8    _r_b;

	u8    _r_c:6;
	u8    affil_supp:1;
	u8    affil_valid:1;

	u32   _r_d;

	u8    stp_sas_addr[8];

	struct dev_to_host_fis fis;

	u32   _r_e;

	u8    affil_stp_ini_addr[8];

	__be32 crc;
} __attribute__ ((packed));

#else
#error "Bitfield order not defined!"
#endif

struct smp_rg_resp {} __attribute__ ((packed));

struct smp_disc_resp {} __attribute__ ((packed));

struct smp_rps_resp {} __attribute__ ((packed));

#endif /* _SAS_H_ */