1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright (c) 2005 Cisco Systems. All rights reserved. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * This software is available to you under a choice of one of two 5*4882a593Smuzhiyun * licenses. You may choose to be licensed under the terms of the GNU 6*4882a593Smuzhiyun * General Public License (GPL) Version 2, available from the file 7*4882a593Smuzhiyun * COPYING in the main directory of this source tree, or the 8*4882a593Smuzhiyun * OpenIB.org BSD license below: 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or 11*4882a593Smuzhiyun * without modification, are permitted provided that the following 12*4882a593Smuzhiyun * conditions are met: 13*4882a593Smuzhiyun * 14*4882a593Smuzhiyun * - Redistributions of source code must retain the above 15*4882a593Smuzhiyun * copyright notice, this list of conditions and the following 16*4882a593Smuzhiyun * disclaimer. 17*4882a593Smuzhiyun * 18*4882a593Smuzhiyun * - Redistributions in binary form must reproduce the above 19*4882a593Smuzhiyun * copyright notice, this list of conditions and the following 20*4882a593Smuzhiyun * disclaimer in the documentation and/or other materials 21*4882a593Smuzhiyun * provided with the distribution. 22*4882a593Smuzhiyun * 23*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24*4882a593Smuzhiyun * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25*4882a593Smuzhiyun * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26*4882a593Smuzhiyun * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27*4882a593Smuzhiyun * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28*4882a593Smuzhiyun * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29*4882a593Smuzhiyun * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30*4882a593Smuzhiyun * SOFTWARE. 31*4882a593Smuzhiyun * 32*4882a593Smuzhiyun * $Id$ 33*4882a593Smuzhiyun */ 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun #ifndef SCSI_SRP_H 36*4882a593Smuzhiyun #define SCSI_SRP_H 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /* 39*4882a593Smuzhiyun * Structures and constants for the SCSI RDMA Protocol (SRP) as 40*4882a593Smuzhiyun * defined by the INCITS T10 committee. This file was written using 41*4882a593Smuzhiyun * draft Revision 16a of the SRP standard. 42*4882a593Smuzhiyun */ 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun #include <linux/types.h> 45*4882a593Smuzhiyun #include <scsi/scsi.h> 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun enum { 48*4882a593Smuzhiyun SRP_LOGIN_REQ = 0x00, 49*4882a593Smuzhiyun SRP_TSK_MGMT = 0x01, 50*4882a593Smuzhiyun SRP_CMD = 0x02, 51*4882a593Smuzhiyun SRP_I_LOGOUT = 0x03, 52*4882a593Smuzhiyun SRP_LOGIN_RSP = 0xc0, 53*4882a593Smuzhiyun SRP_RSP = 0xc1, 54*4882a593Smuzhiyun SRP_LOGIN_REJ = 0xc2, 55*4882a593Smuzhiyun SRP_T_LOGOUT = 0x80, 56*4882a593Smuzhiyun SRP_CRED_REQ = 0x81, 57*4882a593Smuzhiyun SRP_AER_REQ = 0x82, 58*4882a593Smuzhiyun SRP_CRED_RSP = 0x41, 59*4882a593Smuzhiyun SRP_AER_RSP = 0x42 60*4882a593Smuzhiyun }; 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun enum { 63*4882a593Smuzhiyun SRP_BUF_FORMAT_DIRECT = 1 << 1, 64*4882a593Smuzhiyun SRP_BUF_FORMAT_INDIRECT = 1 << 2 65*4882a593Smuzhiyun }; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun enum { 68*4882a593Smuzhiyun SRP_NO_DATA_DESC = 0, 69*4882a593Smuzhiyun SRP_DATA_DESC_DIRECT = 1, 70*4882a593Smuzhiyun SRP_DATA_DESC_INDIRECT = 2, 71*4882a593Smuzhiyun SRP_DATA_DESC_IMM = 3, /* new in SRP2 */ 72*4882a593Smuzhiyun }; 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun enum { 75*4882a593Smuzhiyun SRP_TSK_ABORT_TASK = 0x01, 76*4882a593Smuzhiyun SRP_TSK_ABORT_TASK_SET = 0x02, 77*4882a593Smuzhiyun SRP_TSK_CLEAR_TASK_SET = 0x04, 78*4882a593Smuzhiyun SRP_TSK_LUN_RESET = 0x08, 79*4882a593Smuzhiyun SRP_TSK_CLEAR_ACA = 0x40 80*4882a593Smuzhiyun }; 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun enum srp_login_rej_reason { 83*4882a593Smuzhiyun SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL = 0x00010000, 84*4882a593Smuzhiyun SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES = 0x00010001, 85*4882a593Smuzhiyun SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE = 0x00010002, 86*4882a593Smuzhiyun SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL = 0x00010003, 87*4882a593Smuzhiyun SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT = 0x00010004, 88*4882a593Smuzhiyun SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED = 0x00010005, 89*4882a593Smuzhiyun SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED = 0x00010006 90*4882a593Smuzhiyun }; 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun enum { 93*4882a593Smuzhiyun SRP_REV10_IB_IO_CLASS = 0xff00, 94*4882a593Smuzhiyun SRP_REV16A_IB_IO_CLASS = 0x0100 95*4882a593Smuzhiyun }; 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun struct srp_direct_buf { 98*4882a593Smuzhiyun __be64 va; 99*4882a593Smuzhiyun __be32 key; 100*4882a593Smuzhiyun __be32 len; 101*4882a593Smuzhiyun }; 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun /* 104*4882a593Smuzhiyun * We need the packed attribute because the SRP spec puts the list of 105*4882a593Smuzhiyun * descriptors at an offset of 20, which is not aligned to the size of 106*4882a593Smuzhiyun * struct srp_direct_buf. The whole structure must be packed to avoid 107*4882a593Smuzhiyun * having the 20-byte structure padded to 24 bytes on 64-bit architectures. 108*4882a593Smuzhiyun */ 109*4882a593Smuzhiyun struct srp_indirect_buf { 110*4882a593Smuzhiyun struct srp_direct_buf table_desc; 111*4882a593Smuzhiyun __be32 len; 112*4882a593Smuzhiyun struct srp_direct_buf desc_list[]; 113*4882a593Smuzhiyun } __attribute__((packed)); 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun /* Immediate data buffer descriptor as defined in SRP2. */ 116*4882a593Smuzhiyun struct srp_imm_buf { 117*4882a593Smuzhiyun __be32 len; 118*4882a593Smuzhiyun }; 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun /* srp_login_req.flags */ 121*4882a593Smuzhiyun enum { 122*4882a593Smuzhiyun SRP_MULTICHAN_SINGLE = 0, 123*4882a593Smuzhiyun SRP_MULTICHAN_MULTI = 1, 124*4882a593Smuzhiyun SRP_IMMED_REQUESTED = 0x80, /* new in SRP2 */ 125*4882a593Smuzhiyun }; 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun struct srp_login_req { 128*4882a593Smuzhiyun u8 opcode; 129*4882a593Smuzhiyun u8 reserved1[7]; 130*4882a593Smuzhiyun u64 tag; 131*4882a593Smuzhiyun __be32 req_it_iu_len; 132*4882a593Smuzhiyun u8 reserved2[4]; 133*4882a593Smuzhiyun __be16 req_buf_fmt; 134*4882a593Smuzhiyun u8 req_flags; 135*4882a593Smuzhiyun u8 reserved3[1]; 136*4882a593Smuzhiyun __be16 imm_data_offset; /* new in SRP2 */ 137*4882a593Smuzhiyun u8 reserved4[2]; 138*4882a593Smuzhiyun u8 initiator_port_id[16]; 139*4882a593Smuzhiyun u8 target_port_id[16]; 140*4882a593Smuzhiyun }; 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun /** 143*4882a593Smuzhiyun * struct srp_login_req_rdma - RDMA/CM login parameters. 144*4882a593Smuzhiyun * 145*4882a593Smuzhiyun * RDMA/CM over InfiniBand can only carry 92 - 36 = 56 bytes of private 146*4882a593Smuzhiyun * data. The %srp_login_req_rdma structure contains the same information as 147*4882a593Smuzhiyun * %srp_login_req but with the reserved data removed. 148*4882a593Smuzhiyun */ 149*4882a593Smuzhiyun struct srp_login_req_rdma { 150*4882a593Smuzhiyun u64 tag; 151*4882a593Smuzhiyun __be16 req_buf_fmt; 152*4882a593Smuzhiyun u8 req_flags; 153*4882a593Smuzhiyun u8 opcode; 154*4882a593Smuzhiyun __be32 req_it_iu_len; 155*4882a593Smuzhiyun u8 initiator_port_id[16]; 156*4882a593Smuzhiyun u8 target_port_id[16]; 157*4882a593Smuzhiyun __be16 imm_data_offset; 158*4882a593Smuzhiyun u8 reserved[6]; 159*4882a593Smuzhiyun }; 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun /* srp_login_rsp.rsp_flags */ 162*4882a593Smuzhiyun enum { 163*4882a593Smuzhiyun SRP_LOGIN_RSP_MULTICHAN_NO_CHAN = 0x0, 164*4882a593Smuzhiyun SRP_LOGIN_RSP_MULTICHAN_TERMINATED = 0x1, 165*4882a593Smuzhiyun SRP_LOGIN_RSP_MULTICHAN_MAINTAINED = 0x2, 166*4882a593Smuzhiyun SRP_LOGIN_RSP_IMMED_SUPP = 0x80, /* new in SRP2 */ 167*4882a593Smuzhiyun }; 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun /* 170*4882a593Smuzhiyun * The SRP spec defines the size of the LOGIN_RSP structure to be 52 171*4882a593Smuzhiyun * bytes, so it needs to be packed to avoid having it padded to 56 172*4882a593Smuzhiyun * bytes on 64-bit architectures. 173*4882a593Smuzhiyun */ 174*4882a593Smuzhiyun struct srp_login_rsp { 175*4882a593Smuzhiyun u8 opcode; 176*4882a593Smuzhiyun u8 reserved1[3]; 177*4882a593Smuzhiyun __be32 req_lim_delta; 178*4882a593Smuzhiyun u64 tag; 179*4882a593Smuzhiyun __be32 max_it_iu_len; 180*4882a593Smuzhiyun __be32 max_ti_iu_len; 181*4882a593Smuzhiyun __be16 buf_fmt; 182*4882a593Smuzhiyun u8 rsp_flags; 183*4882a593Smuzhiyun u8 reserved2[25]; 184*4882a593Smuzhiyun } __attribute__((packed)); 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun struct srp_login_rej { 187*4882a593Smuzhiyun u8 opcode; 188*4882a593Smuzhiyun u8 reserved1[3]; 189*4882a593Smuzhiyun __be32 reason; 190*4882a593Smuzhiyun u64 tag; 191*4882a593Smuzhiyun u8 reserved2[8]; 192*4882a593Smuzhiyun __be16 buf_fmt; 193*4882a593Smuzhiyun u8 reserved3[6]; 194*4882a593Smuzhiyun }; 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun struct srp_i_logout { 197*4882a593Smuzhiyun u8 opcode; 198*4882a593Smuzhiyun u8 reserved[7]; 199*4882a593Smuzhiyun u64 tag; 200*4882a593Smuzhiyun }; 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun struct srp_t_logout { 203*4882a593Smuzhiyun u8 opcode; 204*4882a593Smuzhiyun u8 sol_not; 205*4882a593Smuzhiyun u8 reserved[2]; 206*4882a593Smuzhiyun __be32 reason; 207*4882a593Smuzhiyun u64 tag; 208*4882a593Smuzhiyun }; 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun /* 211*4882a593Smuzhiyun * We need the packed attribute because the SRP spec only aligns the 212*4882a593Smuzhiyun * 8-byte LUN field to 4 bytes. 213*4882a593Smuzhiyun */ 214*4882a593Smuzhiyun struct srp_tsk_mgmt { 215*4882a593Smuzhiyun u8 opcode; 216*4882a593Smuzhiyun u8 sol_not; 217*4882a593Smuzhiyun u8 reserved1[6]; 218*4882a593Smuzhiyun u64 tag; 219*4882a593Smuzhiyun u8 reserved2[4]; 220*4882a593Smuzhiyun struct scsi_lun lun; 221*4882a593Smuzhiyun u8 reserved3[2]; 222*4882a593Smuzhiyun u8 tsk_mgmt_func; 223*4882a593Smuzhiyun u8 reserved4; 224*4882a593Smuzhiyun u64 task_tag; 225*4882a593Smuzhiyun u8 reserved5[8]; 226*4882a593Smuzhiyun }; 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun /* 229*4882a593Smuzhiyun * We need the packed attribute because the SRP spec only aligns the 230*4882a593Smuzhiyun * 8-byte LUN field to 4 bytes. 231*4882a593Smuzhiyun */ 232*4882a593Smuzhiyun struct srp_cmd { 233*4882a593Smuzhiyun u8 opcode; 234*4882a593Smuzhiyun u8 sol_not; 235*4882a593Smuzhiyun u8 reserved1[3]; 236*4882a593Smuzhiyun u8 buf_fmt; 237*4882a593Smuzhiyun u8 data_out_desc_cnt; 238*4882a593Smuzhiyun u8 data_in_desc_cnt; 239*4882a593Smuzhiyun u64 tag; 240*4882a593Smuzhiyun u8 reserved2[4]; 241*4882a593Smuzhiyun struct scsi_lun lun; 242*4882a593Smuzhiyun u8 reserved3; 243*4882a593Smuzhiyun u8 task_attr; 244*4882a593Smuzhiyun u8 reserved4; 245*4882a593Smuzhiyun u8 add_cdb_len; 246*4882a593Smuzhiyun u8 cdb[16]; 247*4882a593Smuzhiyun u8 add_data[]; 248*4882a593Smuzhiyun }; 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun enum { 251*4882a593Smuzhiyun SRP_RSP_FLAG_RSPVALID = 1 << 0, 252*4882a593Smuzhiyun SRP_RSP_FLAG_SNSVALID = 1 << 1, 253*4882a593Smuzhiyun SRP_RSP_FLAG_DOOVER = 1 << 2, 254*4882a593Smuzhiyun SRP_RSP_FLAG_DOUNDER = 1 << 3, 255*4882a593Smuzhiyun SRP_RSP_FLAG_DIOVER = 1 << 4, 256*4882a593Smuzhiyun SRP_RSP_FLAG_DIUNDER = 1 << 5 257*4882a593Smuzhiyun }; 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun /* 260*4882a593Smuzhiyun * The SRP spec defines the size of the RSP structure to be 36 bytes, 261*4882a593Smuzhiyun * so it needs to be packed to avoid having it padded to 40 bytes on 262*4882a593Smuzhiyun * 64-bit architectures. 263*4882a593Smuzhiyun */ 264*4882a593Smuzhiyun struct srp_rsp { 265*4882a593Smuzhiyun u8 opcode; 266*4882a593Smuzhiyun u8 sol_not; 267*4882a593Smuzhiyun u8 reserved1[2]; 268*4882a593Smuzhiyun __be32 req_lim_delta; 269*4882a593Smuzhiyun u64 tag; 270*4882a593Smuzhiyun u8 reserved2[2]; 271*4882a593Smuzhiyun u8 flags; 272*4882a593Smuzhiyun u8 status; 273*4882a593Smuzhiyun __be32 data_out_res_cnt; 274*4882a593Smuzhiyun __be32 data_in_res_cnt; 275*4882a593Smuzhiyun __be32 sense_data_len; 276*4882a593Smuzhiyun __be32 resp_data_len; 277*4882a593Smuzhiyun u8 data[]; 278*4882a593Smuzhiyun } __attribute__((packed)); 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun struct srp_cred_req { 281*4882a593Smuzhiyun u8 opcode; 282*4882a593Smuzhiyun u8 sol_not; 283*4882a593Smuzhiyun u8 reserved[2]; 284*4882a593Smuzhiyun __be32 req_lim_delta; 285*4882a593Smuzhiyun u64 tag; 286*4882a593Smuzhiyun }; 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun struct srp_cred_rsp { 289*4882a593Smuzhiyun u8 opcode; 290*4882a593Smuzhiyun u8 reserved[7]; 291*4882a593Smuzhiyun u64 tag; 292*4882a593Smuzhiyun }; 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun /* 295*4882a593Smuzhiyun * The SRP spec defines the fixed portion of the AER_REQ structure to be 296*4882a593Smuzhiyun * 36 bytes, so it needs to be packed to avoid having it padded to 40 bytes 297*4882a593Smuzhiyun * on 64-bit architectures. 298*4882a593Smuzhiyun */ 299*4882a593Smuzhiyun struct srp_aer_req { 300*4882a593Smuzhiyun u8 opcode; 301*4882a593Smuzhiyun u8 sol_not; 302*4882a593Smuzhiyun u8 reserved[2]; 303*4882a593Smuzhiyun __be32 req_lim_delta; 304*4882a593Smuzhiyun u64 tag; 305*4882a593Smuzhiyun u32 reserved2; 306*4882a593Smuzhiyun struct scsi_lun lun; 307*4882a593Smuzhiyun __be32 sense_data_len; 308*4882a593Smuzhiyun u32 reserved3; 309*4882a593Smuzhiyun u8 sense_data[]; 310*4882a593Smuzhiyun } __attribute__((packed)); 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun struct srp_aer_rsp { 313*4882a593Smuzhiyun u8 opcode; 314*4882a593Smuzhiyun u8 reserved[7]; 315*4882a593Smuzhiyun u64 tag; 316*4882a593Smuzhiyun }; 317*4882a593Smuzhiyun 318*4882a593Smuzhiyun #endif /* SCSI_SRP_H */ 319