162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (c) 2005 Cisco Systems.  All rights reserved.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * This software is available to you under a choice of one of two
562306a36Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
662306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
762306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the
862306a36Sopenharmony_ci * OpenIB.org BSD license below:
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
1162306a36Sopenharmony_ci *     without modification, are permitted provided that the following
1262306a36Sopenharmony_ci *     conditions are met:
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci *      - Redistributions of source code must retain the above
1562306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
1662306a36Sopenharmony_ci *        disclaimer.
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
1962306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
2062306a36Sopenharmony_ci *        disclaimer in the documentation and/or other materials
2162306a36Sopenharmony_ci *        provided with the distribution.
2262306a36Sopenharmony_ci *
2362306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2462306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2562306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2662306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2762306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2862306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2962306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3062306a36Sopenharmony_ci * SOFTWARE.
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * $Id$
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#ifndef SCSI_SRP_H
3662306a36Sopenharmony_ci#define SCSI_SRP_H
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/*
3962306a36Sopenharmony_ci * Structures and constants for the SCSI RDMA Protocol (SRP) as
4062306a36Sopenharmony_ci * defined by the INCITS T10 committee.  This file was written using
4162306a36Sopenharmony_ci * draft Revision 16a of the SRP standard.
4262306a36Sopenharmony_ci */
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#include <linux/types.h>
4562306a36Sopenharmony_ci#include <scsi/scsi.h>
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cienum {
4862306a36Sopenharmony_ci	SRP_LOGIN_REQ	= 0x00,
4962306a36Sopenharmony_ci	SRP_TSK_MGMT	= 0x01,
5062306a36Sopenharmony_ci	SRP_CMD		= 0x02,
5162306a36Sopenharmony_ci	SRP_I_LOGOUT	= 0x03,
5262306a36Sopenharmony_ci	SRP_LOGIN_RSP	= 0xc0,
5362306a36Sopenharmony_ci	SRP_RSP		= 0xc1,
5462306a36Sopenharmony_ci	SRP_LOGIN_REJ	= 0xc2,
5562306a36Sopenharmony_ci	SRP_T_LOGOUT	= 0x80,
5662306a36Sopenharmony_ci	SRP_CRED_REQ	= 0x81,
5762306a36Sopenharmony_ci	SRP_AER_REQ	= 0x82,
5862306a36Sopenharmony_ci	SRP_CRED_RSP	= 0x41,
5962306a36Sopenharmony_ci	SRP_AER_RSP	= 0x42
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cienum {
6362306a36Sopenharmony_ci	SRP_BUF_FORMAT_DIRECT	= 1 << 1,
6462306a36Sopenharmony_ci	SRP_BUF_FORMAT_INDIRECT	= 1 << 2
6562306a36Sopenharmony_ci};
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cienum {
6862306a36Sopenharmony_ci	SRP_NO_DATA_DESC	= 0,
6962306a36Sopenharmony_ci	SRP_DATA_DESC_DIRECT	= 1,
7062306a36Sopenharmony_ci	SRP_DATA_DESC_INDIRECT	= 2,
7162306a36Sopenharmony_ci	SRP_DATA_DESC_IMM	= 3,	/* new in SRP2 */
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cienum {
7562306a36Sopenharmony_ci	SRP_TSK_ABORT_TASK	= 0x01,
7662306a36Sopenharmony_ci	SRP_TSK_ABORT_TASK_SET	= 0x02,
7762306a36Sopenharmony_ci	SRP_TSK_CLEAR_TASK_SET	= 0x04,
7862306a36Sopenharmony_ci	SRP_TSK_LUN_RESET	= 0x08,
7962306a36Sopenharmony_ci	SRP_TSK_CLEAR_ACA	= 0x40
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cienum srp_login_rej_reason {
8362306a36Sopenharmony_ci	SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL		= 0x00010000,
8462306a36Sopenharmony_ci	SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES		= 0x00010001,
8562306a36Sopenharmony_ci	SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE	= 0x00010002,
8662306a36Sopenharmony_ci	SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL		= 0x00010003,
8762306a36Sopenharmony_ci	SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT	= 0x00010004,
8862306a36Sopenharmony_ci	SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED		= 0x00010005,
8962306a36Sopenharmony_ci	SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED		= 0x00010006
9062306a36Sopenharmony_ci};
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cienum {
9362306a36Sopenharmony_ci	SRP_REV10_IB_IO_CLASS	= 0xff00,
9462306a36Sopenharmony_ci	SRP_REV16A_IB_IO_CLASS	= 0x0100
9562306a36Sopenharmony_ci};
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistruct srp_direct_buf {
9862306a36Sopenharmony_ci	__be64	va;
9962306a36Sopenharmony_ci	__be32	key;
10062306a36Sopenharmony_ci	__be32  len;
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/*
10462306a36Sopenharmony_ci * We need the packed attribute because the SRP spec puts the list of
10562306a36Sopenharmony_ci * descriptors at an offset of 20, which is not aligned to the size of
10662306a36Sopenharmony_ci * struct srp_direct_buf.  The whole structure must be packed to avoid
10762306a36Sopenharmony_ci * having the 20-byte structure padded to 24 bytes on 64-bit architectures.
10862306a36Sopenharmony_ci */
10962306a36Sopenharmony_cistruct srp_indirect_buf {
11062306a36Sopenharmony_ci	struct srp_direct_buf	table_desc __packed __aligned(4);
11162306a36Sopenharmony_ci	__be32			len;
11262306a36Sopenharmony_ci	struct srp_direct_buf	desc_list[] __packed __aligned(4);
11362306a36Sopenharmony_ci};
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci/* Immediate data buffer descriptor as defined in SRP2. */
11662306a36Sopenharmony_cistruct srp_imm_buf {
11762306a36Sopenharmony_ci	__be32	len;
11862306a36Sopenharmony_ci};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/* srp_login_req.flags */
12162306a36Sopenharmony_cienum {
12262306a36Sopenharmony_ci	SRP_MULTICHAN_SINGLE = 0,
12362306a36Sopenharmony_ci	SRP_MULTICHAN_MULTI  = 1,
12462306a36Sopenharmony_ci	SRP_IMMED_REQUESTED  = 0x80,	/* new in SRP2 */
12562306a36Sopenharmony_ci};
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistruct srp_login_req {
12862306a36Sopenharmony_ci	u8	opcode;
12962306a36Sopenharmony_ci	u8	reserved1[7];
13062306a36Sopenharmony_ci	u64	tag;
13162306a36Sopenharmony_ci	__be32	req_it_iu_len;
13262306a36Sopenharmony_ci	u8	reserved2[4];
13362306a36Sopenharmony_ci	__be16	req_buf_fmt;
13462306a36Sopenharmony_ci	u8	req_flags;
13562306a36Sopenharmony_ci	u8	reserved3[1];
13662306a36Sopenharmony_ci	__be16	imm_data_offset;	/* new in SRP2 */
13762306a36Sopenharmony_ci	u8	reserved4[2];
13862306a36Sopenharmony_ci	u8	initiator_port_id[16];
13962306a36Sopenharmony_ci	u8	target_port_id[16];
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/**
14362306a36Sopenharmony_ci * struct srp_login_req_rdma - RDMA/CM login parameters.
14462306a36Sopenharmony_ci *
14562306a36Sopenharmony_ci * RDMA/CM over InfiniBand can only carry 92 - 36 = 56 bytes of private
14662306a36Sopenharmony_ci * data. The %srp_login_req_rdma structure contains the same information as
14762306a36Sopenharmony_ci * %srp_login_req but with the reserved data removed.
14862306a36Sopenharmony_ci */
14962306a36Sopenharmony_cistruct srp_login_req_rdma {
15062306a36Sopenharmony_ci	u64	tag;
15162306a36Sopenharmony_ci	__be16	req_buf_fmt;
15262306a36Sopenharmony_ci	u8	req_flags;
15362306a36Sopenharmony_ci	u8	opcode;
15462306a36Sopenharmony_ci	__be32	req_it_iu_len;
15562306a36Sopenharmony_ci	u8	initiator_port_id[16];
15662306a36Sopenharmony_ci	u8	target_port_id[16];
15762306a36Sopenharmony_ci	__be16	imm_data_offset;
15862306a36Sopenharmony_ci	u8	reserved[6];
15962306a36Sopenharmony_ci};
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci/* srp_login_rsp.rsp_flags */
16262306a36Sopenharmony_cienum {
16362306a36Sopenharmony_ci	SRP_LOGIN_RSP_MULTICHAN_NO_CHAN	   = 0x0,
16462306a36Sopenharmony_ci	SRP_LOGIN_RSP_MULTICHAN_TERMINATED = 0x1,
16562306a36Sopenharmony_ci	SRP_LOGIN_RSP_MULTICHAN_MAINTAINED = 0x2,
16662306a36Sopenharmony_ci	SRP_LOGIN_RSP_IMMED_SUPP	   = 0x80, /* new in SRP2 */
16762306a36Sopenharmony_ci};
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/*
17062306a36Sopenharmony_ci * The SRP spec defines the size of the LOGIN_RSP structure to be 52
17162306a36Sopenharmony_ci * bytes, so it needs to be packed to avoid having it padded to 56
17262306a36Sopenharmony_ci * bytes on 64-bit architectures.
17362306a36Sopenharmony_ci */
17462306a36Sopenharmony_cistruct srp_login_rsp {
17562306a36Sopenharmony_ci	u8	opcode;
17662306a36Sopenharmony_ci	u8	reserved1[3];
17762306a36Sopenharmony_ci	__be32	req_lim_delta;
17862306a36Sopenharmony_ci	u64	tag __packed __aligned(4);
17962306a36Sopenharmony_ci	__be32	max_it_iu_len;
18062306a36Sopenharmony_ci	__be32	max_ti_iu_len;
18162306a36Sopenharmony_ci	__be16	buf_fmt;
18262306a36Sopenharmony_ci	u8	rsp_flags;
18362306a36Sopenharmony_ci	u8	reserved2[25];
18462306a36Sopenharmony_ci};
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_cistruct srp_login_rej {
18762306a36Sopenharmony_ci	u8	opcode;
18862306a36Sopenharmony_ci	u8	reserved1[3];
18962306a36Sopenharmony_ci	__be32	reason;
19062306a36Sopenharmony_ci	u64	tag;
19162306a36Sopenharmony_ci	u8	reserved2[8];
19262306a36Sopenharmony_ci	__be16	buf_fmt;
19362306a36Sopenharmony_ci	u8	reserved3[6];
19462306a36Sopenharmony_ci};
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistruct srp_i_logout {
19762306a36Sopenharmony_ci	u8	opcode;
19862306a36Sopenharmony_ci	u8	reserved[7];
19962306a36Sopenharmony_ci	u64	tag;
20062306a36Sopenharmony_ci};
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cistruct srp_t_logout {
20362306a36Sopenharmony_ci	u8	opcode;
20462306a36Sopenharmony_ci	u8	sol_not;
20562306a36Sopenharmony_ci	u8	reserved[2];
20662306a36Sopenharmony_ci	__be32	reason;
20762306a36Sopenharmony_ci	u64	tag;
20862306a36Sopenharmony_ci};
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistruct srp_tsk_mgmt {
21162306a36Sopenharmony_ci	u8	opcode;
21262306a36Sopenharmony_ci	u8	sol_not;
21362306a36Sopenharmony_ci	u8	reserved1[6];
21462306a36Sopenharmony_ci	u64	tag;
21562306a36Sopenharmony_ci	u8	reserved2[4];
21662306a36Sopenharmony_ci	struct scsi_lun	lun;
21762306a36Sopenharmony_ci	u8	reserved3[2];
21862306a36Sopenharmony_ci	u8	tsk_mgmt_func;
21962306a36Sopenharmony_ci	u8	reserved4;
22062306a36Sopenharmony_ci	u64	task_tag;
22162306a36Sopenharmony_ci	u8	reserved5[8];
22262306a36Sopenharmony_ci};
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_cistruct srp_cmd {
22562306a36Sopenharmony_ci	u8	opcode;
22662306a36Sopenharmony_ci	u8	sol_not;
22762306a36Sopenharmony_ci	u8	reserved1[3];
22862306a36Sopenharmony_ci	u8	buf_fmt;
22962306a36Sopenharmony_ci	u8	data_out_desc_cnt;
23062306a36Sopenharmony_ci	u8	data_in_desc_cnt;
23162306a36Sopenharmony_ci	u64	tag;
23262306a36Sopenharmony_ci	u8	reserved2[4];
23362306a36Sopenharmony_ci	struct scsi_lun	lun;
23462306a36Sopenharmony_ci	u8	reserved3;
23562306a36Sopenharmony_ci	u8	task_attr;
23662306a36Sopenharmony_ci	u8	reserved4;
23762306a36Sopenharmony_ci	u8	add_cdb_len;
23862306a36Sopenharmony_ci	u8	cdb[16];
23962306a36Sopenharmony_ci	u8	add_data[];
24062306a36Sopenharmony_ci};
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_cienum {
24362306a36Sopenharmony_ci	SRP_RSP_FLAG_RSPVALID = 1 << 0,
24462306a36Sopenharmony_ci	SRP_RSP_FLAG_SNSVALID = 1 << 1,
24562306a36Sopenharmony_ci	SRP_RSP_FLAG_DOOVER   = 1 << 2,
24662306a36Sopenharmony_ci	SRP_RSP_FLAG_DOUNDER  = 1 << 3,
24762306a36Sopenharmony_ci	SRP_RSP_FLAG_DIOVER   = 1 << 4,
24862306a36Sopenharmony_ci	SRP_RSP_FLAG_DIUNDER  = 1 << 5
24962306a36Sopenharmony_ci};
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci/*
25262306a36Sopenharmony_ci * The SRP spec defines the size of the RSP structure to be 36 bytes,
25362306a36Sopenharmony_ci * so it needs to be packed to avoid having it padded to 40 bytes on
25462306a36Sopenharmony_ci * 64-bit architectures.
25562306a36Sopenharmony_ci */
25662306a36Sopenharmony_cistruct srp_rsp {
25762306a36Sopenharmony_ci	u8	opcode;
25862306a36Sopenharmony_ci	u8	sol_not;
25962306a36Sopenharmony_ci	u8	reserved1[2];
26062306a36Sopenharmony_ci	__be32	req_lim_delta;
26162306a36Sopenharmony_ci	u64	tag __packed __aligned(4);
26262306a36Sopenharmony_ci	u8	reserved2[2];
26362306a36Sopenharmony_ci	u8	flags;
26462306a36Sopenharmony_ci	u8	status;
26562306a36Sopenharmony_ci	__be32	data_out_res_cnt;
26662306a36Sopenharmony_ci	__be32	data_in_res_cnt;
26762306a36Sopenharmony_ci	__be32	sense_data_len;
26862306a36Sopenharmony_ci	__be32	resp_data_len;
26962306a36Sopenharmony_ci	u8	data[];
27062306a36Sopenharmony_ci};
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_cistruct srp_cred_req {
27362306a36Sopenharmony_ci	u8	opcode;
27462306a36Sopenharmony_ci	u8	sol_not;
27562306a36Sopenharmony_ci	u8	reserved[2];
27662306a36Sopenharmony_ci	__be32	req_lim_delta;
27762306a36Sopenharmony_ci	u64	tag;
27862306a36Sopenharmony_ci};
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_cistruct srp_cred_rsp {
28162306a36Sopenharmony_ci	u8	opcode;
28262306a36Sopenharmony_ci	u8	reserved[7];
28362306a36Sopenharmony_ci	u64	tag;
28462306a36Sopenharmony_ci};
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci/*
28762306a36Sopenharmony_ci * The SRP spec defines the fixed portion of the AER_REQ structure to be
28862306a36Sopenharmony_ci * 36 bytes, so it needs to be packed to avoid having it padded to 40 bytes
28962306a36Sopenharmony_ci * on 64-bit architectures.
29062306a36Sopenharmony_ci */
29162306a36Sopenharmony_cistruct srp_aer_req {
29262306a36Sopenharmony_ci	u8	opcode;
29362306a36Sopenharmony_ci	u8	sol_not;
29462306a36Sopenharmony_ci	u8	reserved[2];
29562306a36Sopenharmony_ci	__be32	req_lim_delta;
29662306a36Sopenharmony_ci	u64	tag __packed __aligned(4);
29762306a36Sopenharmony_ci	u32	reserved2;
29862306a36Sopenharmony_ci	struct scsi_lun	lun;
29962306a36Sopenharmony_ci	__be32	sense_data_len;
30062306a36Sopenharmony_ci	u32	reserved3;
30162306a36Sopenharmony_ci	u8	sense_data[];
30262306a36Sopenharmony_ci};
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_cistruct srp_aer_rsp {
30562306a36Sopenharmony_ci	u8	opcode;
30662306a36Sopenharmony_ci	u8	reserved[7];
30762306a36Sopenharmony_ci	u64	tag;
30862306a36Sopenharmony_ci};
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci#endif /* SCSI_SRP_H */
311