diff options
Diffstat (limited to 'include/scsi')
44 files changed, 2976 insertions, 2365 deletions
diff --git a/include/scsi/Kbuild b/include/scsi/Kbuild deleted file mode 100644 index f2b94918994..00000000000 --- a/include/scsi/Kbuild +++ /dev/null @@ -1,4 +0,0 @@ -header-y += scsi_netlink.h -header-y += scsi_netlink_fc.h -header-y += scsi_bsg_fc.h -header-y += fc/ diff --git a/include/scsi/fc/Kbuild b/include/scsi/fc/Kbuild index 56603813c6c..e69de29bb2d 100644 --- a/include/scsi/fc/Kbuild +++ b/include/scsi/fc/Kbuild @@ -1,4 +0,0 @@ -header-y += fc_els.h -header-y += fc_fs.h -header-y += fc_gs.h -header-y += fc_ns.h diff --git a/include/scsi/fc/fc_els.h b/include/scsi/fc/fc_els.h deleted file mode 100644 index 481abbd48e3..00000000000 --- a/include/scsi/fc/fc_els.h +++ /dev/null @@ -1,831 +0,0 @@ -/* - * Copyright(c) 2007 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Maintained at www.Open-FCoE.org - */ - -#ifndef _FC_ELS_H_ -#define	_FC_ELS_H_ - -#include <linux/types.h> - -/* - * Fibre Channel Switch - Enhanced Link Services definitions. - * From T11 FC-LS Rev 1.2 June 7, 2005. - */ - -/* - * ELS Command codes - byte 0 of the frame payload - */ -enum fc_els_cmd { -	ELS_LS_RJT =	0x01,	/* ESL reject */ -	ELS_LS_ACC =	0x02,	/* ESL Accept */ -	ELS_PLOGI =	0x03,	/* N_Port login */ -	ELS_FLOGI =	0x04,	/* F_Port login */ -	ELS_LOGO =	0x05,	/* Logout */ -	ELS_ABTX =	0x06,	/* Abort exchange - obsolete */ -	ELS_RCS =	0x07,	/* read connection status */ -	ELS_RES =	0x08,	/* read exchange status block */ -	ELS_RSS =	0x09,	/* read sequence status block */ -	ELS_RSI =	0x0a,	/* read sequence initiative */ -	ELS_ESTS =	0x0b,	/* establish streaming */ -	ELS_ESTC =	0x0c,	/* estimate credit */ -	ELS_ADVC =	0x0d,	/* advise credit */ -	ELS_RTV =	0x0e,	/* read timeout value */ -	ELS_RLS =	0x0f,	/* read link error status block */ -	ELS_ECHO =	0x10,	/* echo */ -	ELS_TEST =	0x11,	/* test */ -	ELS_RRQ =	0x12,	/* reinstate recovery qualifier */ -	ELS_REC =	0x13,	/* read exchange concise */ -	ELS_SRR =	0x14,	/* sequence retransmission request */ -	ELS_PRLI =	0x20,	/* process login */ -	ELS_PRLO =	0x21,	/* process logout */ -	ELS_SCN =	0x22,	/* state change notification */ -	ELS_TPLS =	0x23,	/* test process login state */ -	ELS_TPRLO =	0x24,	/* third party process logout */ -	ELS_LCLM =	0x25,	/* login control list mgmt (obs) */ -	ELS_GAID =	0x30,	/* get alias_ID */ -	ELS_FACT =	0x31,	/* fabric activate alias_id */ -	ELS_FDACDT =	0x32,	/* fabric deactivate alias_id */ -	ELS_NACT =	0x33,	/* N-port activate alias_id */ -	ELS_NDACT =	0x34,	/* N-port deactivate alias_id */ -	ELS_QOSR =	0x40,	/* quality of service request */ -	ELS_RVCS =	0x41,	/* read virtual circuit status */ -	ELS_PDISC =	0x50,	/* discover N_port service params */ -	ELS_FDISC =	0x51,	/* discover F_port service params */ -	ELS_ADISC =	0x52,	/* discover address */ -	ELS_RNC =	0x53,	/* report node cap (obs) */ -	ELS_FARP_REQ =	0x54,	/* FC ARP request */ -	ELS_FARP_REPL =	0x55,	/* FC ARP reply */ -	ELS_RPS =	0x56,	/* read port status block */ -	ELS_RPL =	0x57,	/* read port list */ -	ELS_RPBC =	0x58,	/* read port buffer condition */ -	ELS_FAN =	0x60,	/* fabric address notification */ -	ELS_RSCN =	0x61,	/* registered state change notification */ -	ELS_SCR =	0x62,	/* state change registration */ -	ELS_RNFT =	0x63,	/* report node FC-4 types */ -	ELS_CSR =	0x68,	/* clock synch. request */ -	ELS_CSU =	0x69,	/* clock synch. update */ -	ELS_LINIT =	0x70,	/* loop initialize */ -	ELS_LSTS =	0x72,	/* loop status */ -	ELS_RNID =	0x78,	/* request node ID data */ -	ELS_RLIR =	0x79,	/* registered link incident report */ -	ELS_LIRR =	0x7a,	/* link incident record registration */ -	ELS_SRL =	0x7b,	/* scan remote loop */ -	ELS_SBRP =	0x7c,	/* set bit-error reporting params */ -	ELS_RPSC =	0x7d,	/* report speed capabilities */ -	ELS_QSA =	0x7e,	/* query security attributes */ -	ELS_EVFP =	0x7f,	/* exchange virt. fabrics params */ -	ELS_LKA =	0x80,	/* link keep-alive */ -	ELS_AUTH_ELS =	0x90,	/* authentication ELS */ -}; - -/* - * Initializer useful for decoding table. - * Please keep this in sync with the above definitions. - */ -#define	FC_ELS_CMDS_INIT {			\ -	[ELS_LS_RJT] =	"LS_RJT",		\ -	[ELS_LS_ACC] =	"LS_ACC",		\ -	[ELS_PLOGI] =	"PLOGI",		\ -	[ELS_FLOGI] =	"FLOGI",		\ -	[ELS_LOGO] =	"LOGO",			\ -	[ELS_ABTX] =	"ABTX",			\ -	[ELS_RCS] =	"RCS",			\ -	[ELS_RES] =	"RES",			\ -	[ELS_RSS] =	"RSS",			\ -	[ELS_RSI] =	"RSI",			\ -	[ELS_ESTS] =	"ESTS",			\ -	[ELS_ESTC] =	"ESTC",			\ -	[ELS_ADVC] =	"ADVC",			\ -	[ELS_RTV] =	"RTV",			\ -	[ELS_RLS] =	"RLS",			\ -	[ELS_ECHO] =	"ECHO",			\ -	[ELS_TEST] =	"TEST",			\ -	[ELS_RRQ] =	"RRQ",			\ -	[ELS_REC] =	"REC",			\ -	[ELS_SRR] =	"SRR",			\ -	[ELS_PRLI] =	"PRLI",			\ -	[ELS_PRLO] =	"PRLO",			\ -	[ELS_SCN] =	"SCN",			\ -	[ELS_TPLS] =	"TPLS",			\ -	[ELS_TPRLO] =	"TPRLO",		\ -	[ELS_LCLM] =	"LCLM",			\ -	[ELS_GAID] =	"GAID",			\ -	[ELS_FACT] =	"FACT",			\ -	[ELS_FDACDT] =	"FDACDT",		\ -	[ELS_NACT] =	"NACT",			\ -	[ELS_NDACT] =	"NDACT",		\ -	[ELS_QOSR] =	"QOSR",			\ -	[ELS_RVCS] =	"RVCS",			\ -	[ELS_PDISC] =	"PDISC",		\ -	[ELS_FDISC] =	"FDISC",		\ -	[ELS_ADISC] =	"ADISC",		\ -	[ELS_RNC] =	"RNC",			\ -	[ELS_FARP_REQ] = "FARP_REQ",		\ -	[ELS_FARP_REPL] =  "FARP_REPL",		\ -	[ELS_RPS] =	"RPS",			\ -	[ELS_RPL] =	"RPL",			\ -	[ELS_RPBC] =	"RPBC",			\ -	[ELS_FAN] =	"FAN",			\ -	[ELS_RSCN] =	"RSCN",			\ -	[ELS_SCR] =	"SCR",			\ -	[ELS_RNFT] =	"RNFT",			\ -	[ELS_CSR] =	"CSR",			\ -	[ELS_CSU] =	"CSU",			\ -	[ELS_LINIT] =	"LINIT",		\ -	[ELS_LSTS] =	"LSTS",			\ -	[ELS_RNID] =	"RNID",			\ -	[ELS_RLIR] =	"RLIR",			\ -	[ELS_LIRR] =	"LIRR",			\ -	[ELS_SRL] =	"SRL",			\ -	[ELS_SBRP] =	"SBRP",			\ -	[ELS_RPSC] =	"RPSC",			\ -	[ELS_QSA] =	"QSA",			\ -	[ELS_EVFP] =	"EVFP",			\ -	[ELS_LKA] =	"LKA",			\ -	[ELS_AUTH_ELS] = "AUTH_ELS",		\ -} - -/* - * LS_ACC payload. - */ -struct fc_els_ls_acc { -	__u8          la_cmd;		/* command code ELS_LS_ACC */ -	__u8          la_resv[3];	/* reserved */ -}; - -/* - * ELS reject payload. - */ -struct fc_els_ls_rjt { -	__u8	er_cmd;		/* command code ELS_LS_RJT */ -	__u8	er_resv[4];	/* reserved must be zero */ -	__u8	er_reason;	/* reason (enum fc_els_rjt_reason below) */ -	__u8	er_explan;	/* explanation (enum fc_els_rjt_explan below) */ -	__u8	er_vendor;	/* vendor specific code */ -}; - -/* - * ELS reject reason codes (er_reason). - */ -enum fc_els_rjt_reason { -	ELS_RJT_NONE =		0,	/* no reject - not to be sent */ -	ELS_RJT_INVAL =		0x01,	/* invalid ELS command code */ -	ELS_RJT_LOGIC =		0x03,	/* logical error */ -	ELS_RJT_BUSY =		0x05,	/* logical busy */ -	ELS_RJT_PROT =		0x07,	/* protocol error */ -	ELS_RJT_UNAB =		0x09,	/* unable to perform command request */ -	ELS_RJT_UNSUP =		0x0b,	/* command not supported */ -	ELS_RJT_INPROG =	0x0e,	/* command already in progress */ -	ELS_RJT_FIP =		0x20,	/* FIP error */ -	ELS_RJT_VENDOR =	0xff,	/* vendor specific error */ -}; - - -/* - * reason code explanation (er_explan). - */ -enum fc_els_rjt_explan { -	ELS_EXPL_NONE =		0x00,	/* No additional explanation */ -	ELS_EXPL_SPP_OPT_ERR =	0x01,	/* service parameter error - options */ -	ELS_EXPL_SPP_ICTL_ERR =	0x03,	/* service parm error - initiator ctl */ -	ELS_EXPL_AH =		0x11,	/* invalid association header */ -	ELS_EXPL_AH_REQ =	0x13,	/* association_header required */ -	ELS_EXPL_SID =		0x15,	/* invalid originator S_ID */ -	ELS_EXPL_OXID_RXID =	0x17,	/* invalid OX_ID-RX_ID combination */ -	ELS_EXPL_INPROG =	0x19,	/* Request already in progress */ -	ELS_EXPL_PLOGI_REQD =	0x1e,	/* N_Port login required */ -	ELS_EXPL_INSUF_RES =	0x29,	/* insufficient resources */ -	ELS_EXPL_UNAB_DATA =	0x2a,	/* unable to supply requested data */ -	ELS_EXPL_UNSUPR =	0x2c,	/* Request not supported */ -	ELS_EXPL_INV_LEN =	0x2d,	/* Invalid payload length */ -	ELS_EXPL_NOT_NEIGHBOR = 0x62,	/* VN2VN_Port not in neighbor set */ -	/* TBD - above definitions incomplete */ -}; - -/* - * Common service parameters (N ports). - */ -struct fc_els_csp { -	__u8		sp_hi_ver;	/* highest version supported (obs.) */ -	__u8		sp_lo_ver;	/* highest version supported (obs.) */ -	__be16		sp_bb_cred;	/* buffer-to-buffer credits */ -	__be16		sp_features;	/* common feature flags */ -	__be16		sp_bb_data;	/* b-b state number and data field sz */ -	union { -		struct { -			__be16	_sp_tot_seq; /* total concurrent sequences */ -			__be16	_sp_rel_off; /* rel. offset by info cat */ -		} sp_plogi; -		struct { -			__be32	_sp_r_a_tov; /* resource alloc. timeout msec */ -		} sp_flogi_acc; -	} sp_u; -	__be32		sp_e_d_tov;	/* error detect timeout value */ -}; -#define	sp_tot_seq	sp_u.sp_plogi._sp_tot_seq -#define	sp_rel_off	sp_u.sp_plogi._sp_rel_off -#define	sp_r_a_tov	sp_u.sp_flogi_acc._sp_r_a_tov - -#define	FC_SP_BB_DATA_MASK 0xfff /* mask for data field size in sp_bb_data */ - -/* - * Minimum and maximum values for max data field size in service parameters. - */ -#define	FC_SP_MIN_MAX_PAYLOAD	FC_MIN_MAX_PAYLOAD -#define	FC_SP_MAX_MAX_PAYLOAD	FC_MAX_PAYLOAD - -/* - * sp_features - */ -#define	FC_SP_FT_NPIV	0x8000	/* multiple N_Port_ID support (FLOGI) */ -#define	FC_SP_FT_CIRO	0x8000	/* continuously increasing rel off (PLOGI) */ -#define	FC_SP_FT_CLAD	0x8000	/* clean address (in FLOGI LS_ACC) */ -#define	FC_SP_FT_RAND	0x4000	/* random relative offset */ -#define	FC_SP_FT_VAL	0x2000	/* valid vendor version level */ -#define	FC_SP_FT_NPIV_ACC	0x2000	/* NPIV assignment (FLOGI LS_ACC) */ -#define	FC_SP_FT_FPORT	0x1000	/* F port (1) vs. N port (0) */ -#define	FC_SP_FT_ABB	0x0800	/* alternate BB_credit management */ -#define	FC_SP_FT_EDTR	0x0400	/* E_D_TOV Resolution is nanoseconds */ -#define	FC_SP_FT_MCAST	0x0200	/* multicast */ -#define	FC_SP_FT_BCAST	0x0100	/* broadcast */ -#define	FC_SP_FT_HUNT	0x0080	/* hunt group */ -#define	FC_SP_FT_SIMP	0x0040	/* dedicated simplex */ -#define	FC_SP_FT_SEC	0x0020	/* reserved for security */ -#define	FC_SP_FT_CSYN	0x0010	/* clock synch. supported */ -#define	FC_SP_FT_RTTOV	0x0008	/* R_T_TOV value 100 uS, else 100 mS */ -#define	FC_SP_FT_HALF	0x0004	/* dynamic half duplex */ -#define	FC_SP_FT_SEQC	0x0002	/* SEQ_CNT */ -#define	FC_SP_FT_PAYL	0x0001	/* FLOGI payload length 256, else 116 */ - -/* - * Class-specific service parameters. - */ -struct fc_els_cssp { -	__be16		cp_class;	/* class flags */ -	__be16		cp_init;	/* initiator flags */ -	__be16		cp_recip;	/* recipient flags */ -	__be16		cp_rdfs;	/* receive data field size */ -	__be16		cp_con_seq;	/* concurrent sequences */ -	__be16		cp_ee_cred;	/* N-port end-to-end credit */ -	__u8		cp_resv1;	/* reserved */ -	__u8		cp_open_seq;	/* open sequences per exchange */ -	__u8		_cp_resv2[2];	/* reserved */ -}; - -/* - * cp_class flags. - */ -#define	FC_CPC_VALID	0x8000		/* class valid */ -#define	FC_CPC_IMIX	0x4000		/* intermix mode */ -#define	FC_CPC_SEQ	0x0800		/* sequential delivery */ -#define	FC_CPC_CAMP	0x0200		/* camp-on */ -#define	FC_CPC_PRI	0x0080		/* priority */ - -/* - * cp_init flags. - * (TBD: not all flags defined here). - */ -#define	FC_CPI_CSYN	0x0010		/* clock synch. capable */ - -/* - * cp_recip flags. - */ -#define	FC_CPR_CSYN	0x0008		/* clock synch. capable */ - -/* - * NFC_ELS_FLOGI: Fabric login request. - * NFC_ELS_PLOGI: Port login request (same format). - */ -struct fc_els_flogi { -	__u8		fl_cmd;		/* command */ -	__u8		_fl_resvd[3];	/* must be zero */ -	struct fc_els_csp fl_csp;	/* common service parameters */ -	__be64		fl_wwpn;	/* port name */ -	__be64		fl_wwnn;	/* node name */ -	struct fc_els_cssp fl_cssp[4];	/* class 1-4 service parameters */ -	__u8		fl_vend[16];	/* vendor version level */ -} __attribute__((__packed__)); - -/* - * Process login service parameter page. - */ -struct fc_els_spp { -	__u8		spp_type;	/* type code or common service params */ -	__u8		spp_type_ext;	/* type code extension */ -	__u8		spp_flags; -	__u8		_spp_resvd; -	__be32		spp_orig_pa;	/* originator process associator */ -	__be32		spp_resp_pa;	/* responder process associator */ -	__be32		spp_params;	/* service parameters */ -}; - -/* - * spp_flags. - */ -#define	FC_SPP_OPA_VAL	    0x80	/* originator proc. assoc. valid */ -#define	FC_SPP_RPA_VAL	    0x40	/* responder proc. assoc. valid */ -#define	FC_SPP_EST_IMG_PAIR 0x20	/* establish image pair */ -#define	FC_SPP_RESP_MASK    0x0f	/* mask for response code (below) */ - -/* - * SPP response code in spp_flags - lower 4 bits. - */ -enum fc_els_spp_resp { -	FC_SPP_RESP_ACK	=	1,	/* request executed */ -	FC_SPP_RESP_RES =	2,	/* unable due to lack of resources */ -	FC_SPP_RESP_INIT =	3,	/* initialization not complete */ -	FC_SPP_RESP_NO_PA = 	4,	/* unknown process associator */ -	FC_SPP_RESP_CONF = 	5,	/* configuration precludes image pair */ -	FC_SPP_RESP_COND = 	6,	/* request completed conditionally */ -	FC_SPP_RESP_MULT = 	7,	/* unable to handle multiple SPPs */ -	FC_SPP_RESP_INVL = 	8,	/* SPP is invalid */ -}; - -/* - * ELS_RRQ - Reinstate Recovery Qualifier - */ -struct fc_els_rrq { -	__u8		rrq_cmd;	/* command (0x12) */ -	__u8		rrq_zero[3];	/* specified as zero - part of cmd */ -	__u8		rrq_resvd;	/* reserved */ -	__u8		rrq_s_id[3];	/* originator FID */ -	__be16		rrq_ox_id;	/* originator exchange ID */ -	__be16		rrq_rx_id;	/* responders exchange ID */ -}; - -/* - * ELS_REC - Read exchange concise. - */ -struct fc_els_rec { -	__u8		rec_cmd;	/* command (0x13) */ -	__u8		rec_zero[3];	/* specified as zero - part of cmd */ -	__u8		rec_resvd;	/* reserved */ -	__u8		rec_s_id[3];	/* originator FID */ -	__be16		rec_ox_id;	/* originator exchange ID */ -	__be16		rec_rx_id;	/* responders exchange ID */ -}; - -/* - * ELS_REC LS_ACC payload. - */ -struct fc_els_rec_acc { -	__u8		reca_cmd;	/* accept (0x02) */ -	__u8		reca_zero[3];	/* specified as zero - part of cmd */ -	__be16		reca_ox_id;	/* originator exchange ID */ -	__be16		reca_rx_id;	/* responders exchange ID */ -	__u8		reca_resvd1;	/* reserved */ -	__u8		reca_ofid[3];	/* originator FID */ -	__u8		reca_resvd2;	/* reserved */ -	__u8		reca_rfid[3];	/* responder FID */ -	__be32		reca_fc4value;	/* FC4 value */ -	__be32		reca_e_stat;	/* ESB (exchange status block) status */ -}; - -/* - * ELS_PRLI - Process login request and response. - */ -struct fc_els_prli { -	__u8		prli_cmd;	/* command */ -	__u8		prli_spp_len;	/* length of each serv. parm. page */ -	__be16		prli_len;	/* length of entire payload */ -	/* service parameter pages follow */ -}; - -/* - * ELS_PRLO - Process logout request and response. - */ -struct fc_els_prlo { -	__u8            prlo_cmd;       /* command */ -	__u8            prlo_obs;       /* obsolete, but shall be set to 10h */ -	__be16          prlo_len;       /* payload length */ -}; - -/* - * ELS_ADISC payload - */ -struct fc_els_adisc { -	__u8		adisc_cmd; -	__u8		adisc_resv[3]; -	__u8            adisc_resv1; -	__u8            adisc_hard_addr[3]; -	__be64          adisc_wwpn; -	__be64          adisc_wwnn; -	__u8            adisc_resv2; -	__u8            adisc_port_id[3]; -} __attribute__((__packed__)); - -/* - * ELS_LOGO - process or fabric logout. - */ -struct fc_els_logo { -	__u8		fl_cmd;		/* command code */ -	__u8		fl_zero[3];	/* specified as zero - part of cmd */ -	__u8		fl_resvd;	/* reserved */ -	__u8		fl_n_port_id[3];/* N port ID */ -	__be64		fl_n_port_wwn;	/* port name */ -}; - -/* - * ELS_RTV - read timeout value. - */ -struct fc_els_rtv { -	__u8		rtv_cmd;	/* command code 0x0e */ -	__u8		rtv_zero[3];	/* specified as zero - part of cmd */ -}; - -/* - * LS_ACC for ELS_RTV - read timeout value. - */ -struct fc_els_rtv_acc { -	__u8		rtv_cmd;	/* command code 0x02 */ -	__u8		rtv_zero[3];	/* specified as zero - part of cmd */ -	__be32		rtv_r_a_tov;	/* resource allocation timeout value */ -	__be32		rtv_e_d_tov;	/* error detection timeout value */ -	__be32		rtv_toq;	/* timeout qualifier (see below) */ -}; - -/* - * rtv_toq bits. - */ -#define	FC_ELS_RTV_EDRES (1 << 26)	/* E_D_TOV resolution is nS else mS */ -#define	FC_ELS_RTV_RTTOV (1 << 19)	/* R_T_TOV is 100 uS else 100 mS */ - -/* - * ELS_SCR - state change registration payload. - */ -struct fc_els_scr { -	__u8		scr_cmd;	/* command code */ -	__u8		scr_resv[6];	/* reserved */ -	__u8		scr_reg_func;	/* registration function (see below) */ -}; - -enum fc_els_scr_func { -	ELS_SCRF_FAB =	1,	/* fabric-detected registration */ -	ELS_SCRF_NPORT = 2,	/* Nx_Port-detected registration */ -	ELS_SCRF_FULL =	3,	/* full registration */ -	ELS_SCRF_CLEAR = 255,	/* remove any current registrations */ -}; - -/* - * ELS_RSCN - registered state change notification payload. - */ -struct fc_els_rscn { -	__u8		rscn_cmd;	/* RSCN opcode (0x61) */ -	__u8		rscn_page_len;	/* page length (4) */ -	__be16		rscn_plen;	/* payload length including this word */ - -	/* followed by 4-byte generic affected Port_ID pages */ -}; - -struct fc_els_rscn_page { -	__u8		rscn_page_flags; /* event and address format */ -	__u8		rscn_fid[3];	/* fabric ID */ -}; - -#define	ELS_RSCN_EV_QUAL_BIT	2	/* shift count for event qualifier */ -#define	ELS_RSCN_EV_QUAL_MASK	0xf	/* mask for event qualifier */ -#define	ELS_RSCN_ADDR_FMT_BIT	0	/* shift count for address format */ -#define	ELS_RSCN_ADDR_FMT_MASK	0x3	/* mask for address format */ - -enum fc_els_rscn_ev_qual { -	ELS_EV_QUAL_NONE = 0,		/* unspecified */ -	ELS_EV_QUAL_NS_OBJ = 1,		/* changed name server object */ -	ELS_EV_QUAL_PORT_ATTR = 2,	/* changed port attribute */ -	ELS_EV_QUAL_SERV_OBJ = 3,	/* changed service object */ -	ELS_EV_QUAL_SW_CONFIG = 4,	/* changed switch configuration */ -	ELS_EV_QUAL_REM_OBJ = 5,	/* removed object */ -}; - -enum fc_els_rscn_addr_fmt { -	ELS_ADDR_FMT_PORT = 0,	/* rscn_fid is a port address */ -	ELS_ADDR_FMT_AREA = 1,	/* rscn_fid is a area address */ -	ELS_ADDR_FMT_DOM = 2,	/* rscn_fid is a domain address */ -	ELS_ADDR_FMT_FAB = 3,	/* anything on fabric may have changed */ -}; - -/* - * ELS_RNID - request Node ID. - */ -struct fc_els_rnid { -	__u8		rnid_cmd;	/* RNID opcode (0x78) */ -	__u8		rnid_resv[3];	/* reserved */ -	__u8		rnid_fmt;	/* data format */ -	__u8		rnid_resv2[3];	/* reserved */ -}; - -/* - * Node Identification Data formats (rnid_fmt) - */ -enum fc_els_rnid_fmt { -	ELS_RNIDF_NONE = 0,		/* no specific identification data */ -	ELS_RNIDF_GEN = 0xdf,		/* general topology discovery format */ -}; - -/* - * ELS_RNID response. - */ -struct fc_els_rnid_resp { -	__u8		rnid_cmd;	/* response code (LS_ACC) */ -	__u8		rnid_resv[3];	/* reserved */ -	__u8		rnid_fmt;	/* data format */ -	__u8		rnid_cid_len;	/* common ID data length */ -	__u8		rnid_resv2;	/* reserved */ -	__u8		rnid_sid_len;	/* specific ID data length */ -}; - -struct fc_els_rnid_cid { -	__be64		rnid_wwpn;	/* N port name */ -	__be64		rnid_wwnn;	/* node name */ -}; - -struct fc_els_rnid_gen { -	__u8		rnid_vend_id[16]; /* vendor-unique ID */ -	__be32		rnid_atype;	/* associated type (see below) */ -	__be32		rnid_phys_port;	/* physical port number */ -	__be32		rnid_att_nodes;	/* number of attached nodes */ -	__u8		rnid_node_mgmt;	/* node management (see below) */ -	__u8		rnid_ip_ver;	/* IP version (see below) */ -	__be16		rnid_prot_port;	/* UDP / TCP port number */ -	__be32		rnid_ip_addr[4]; /* IP address */ -	__u8		rnid_resvd[2];	/* reserved */ -	__be16		rnid_vend_spec;	/* vendor-specific field */ -}; - -enum fc_els_rnid_atype { -	ELS_RNIDA_UNK =		0x01,	/* unknown */ -	ELS_RNIDA_OTHER =	0x02,	/* none of the following */ -	ELS_RNIDA_HUB =		0x03, -	ELS_RNIDA_SWITCH =	0x04, -	ELS_RNIDA_GATEWAY =	0x05, -	ELS_RNIDA_CONV =	0x06,   /* Obsolete, do not use this value */ -	ELS_RNIDA_HBA =	        0x07,   /* Obsolete, do not use this value */ -	ELS_RNIDA_PROXY =       0x08,   /* Obsolete, do not use this value */ -	ELS_RNIDA_STORAGE =	0x09, -	ELS_RNIDA_HOST =	0x0a, -	ELS_RNIDA_SUBSYS =	0x0b,	/* storage subsystem (e.g., RAID) */ -	ELS_RNIDA_ACCESS =	0x0e,	/* access device (e.g. media changer) */ -	ELS_RNIDA_NAS =		0x11,	/* NAS server */ -	ELS_RNIDA_BRIDGE =	0x12,	/* bridge */ -	ELS_RNIDA_VIRT =	0x13,	/* virtualization device */ -	ELS_RNIDA_MF =		0xff,	/* multifunction device (bits below) */ -	ELS_RNIDA_MF_HUB =	1UL << 31, 	/* hub */ -	ELS_RNIDA_MF_SW =	1UL << 30, 	/* switch */ -	ELS_RNIDA_MF_GW =	1UL << 29,	/* gateway */ -	ELS_RNIDA_MF_ST =	1UL << 28,	/* storage */ -	ELS_RNIDA_MF_HOST =	1UL << 27,	/* host */ -	ELS_RNIDA_MF_SUB =	1UL << 26,	/* storage subsystem */ -	ELS_RNIDA_MF_ACC =	1UL << 25,	/* storage access dev */ -	ELS_RNIDA_MF_WDM =	1UL << 24,	/* wavelength division mux */ -	ELS_RNIDA_MF_NAS =	1UL << 23,	/* NAS server */ -	ELS_RNIDA_MF_BR =	1UL << 22,	/* bridge */ -	ELS_RNIDA_MF_VIRT =	1UL << 21,	/* virtualization device */ -}; - -enum fc_els_rnid_mgmt { -	ELS_RNIDM_SNMP =	0, -	ELS_RNIDM_TELNET =	1, -	ELS_RNIDM_HTTP =	2, -	ELS_RNIDM_HTTPS =	3, -	ELS_RNIDM_XML =		4,	/* HTTP + XML */ -}; - -enum fc_els_rnid_ipver { -	ELS_RNIDIP_NONE =	0,	/* no IP support or node mgmt. */ -	ELS_RNIDIP_V4 =		1,	/* IPv4 */ -	ELS_RNIDIP_V6 =		2,	/* IPv6 */ -}; - -/* - * ELS RPL - Read Port List. - */ -struct fc_els_rpl { -	__u8		rpl_cmd;	/* command */ -	__u8		rpl_resv[5];	/* reserved - must be zero */ -	__be16		rpl_max_size;	/* maximum response size or zero */ -	__u8		rpl_resv1;	/* reserved - must be zero */ -	__u8		rpl_index[3];	/* starting index */ -}; - -/* - * Port number block in RPL response. - */ -struct fc_els_pnb { -	__be32		pnb_phys_pn;	/* physical port number */ -	__u8		pnb_resv;	/* reserved */ -	__u8		pnb_port_id[3];	/* port ID */ -	__be64		pnb_wwpn;	/* port name */ -}; - -/* - * RPL LS_ACC response. - */ -struct fc_els_rpl_resp { -	__u8		rpl_cmd;	/* ELS_LS_ACC */ -	__u8		rpl_resv1;	/* reserved - must be zero */ -	__be16		rpl_plen;	/* payload length */ -	__u8		rpl_resv2;	/* reserved - must be zero */ -	__u8		rpl_llen[3];	/* list length */ -	__u8		rpl_resv3;	/* reserved - must be zero */ -	__u8		rpl_index[3];	/* starting index */ -	struct fc_els_pnb rpl_pnb[1];	/* variable number of PNBs */ -}; - -/* - * Link Error Status Block. - */ -struct fc_els_lesb { -	__be32		lesb_link_fail;	/* link failure count */ -	__be32		lesb_sync_loss;	/* loss of synchronization count */ -	__be32		lesb_sig_loss;	/* loss of signal count */ -	__be32		lesb_prim_err;	/* primitive sequence error count */ -	__be32		lesb_inv_word;	/* invalid transmission word count */ -	__be32		lesb_inv_crc;	/* invalid CRC count */ -}; - -/* - * ELS RPS - Read Port Status Block request. - */ -struct fc_els_rps { -	__u8		rps_cmd;	/* command */ -	__u8		rps_resv[2];	/* reserved - must be zero */ -	__u8		rps_flag;	/* flag - see below */ -	__be64		rps_port_spec;	/* port selection */ -}; - -enum fc_els_rps_flag { -	FC_ELS_RPS_DID =	0x00,	/* port identified by D_ID of req. */ -	FC_ELS_RPS_PPN =	0x01,	/* port_spec is physical port number */ -	FC_ELS_RPS_WWPN =	0x02,	/* port_spec is port WWN */ -}; - -/* - * ELS RPS LS_ACC response. - */ -struct fc_els_rps_resp { -	__u8		rps_cmd;	/* command - LS_ACC */ -	__u8		rps_resv[2];	/* reserved - must be zero */ -	__u8		rps_flag;	/* flag - see below */ -	__u8		rps_resv2[2];	/* reserved */ -	__be16		rps_status;	/* port status - see below */ -	struct fc_els_lesb rps_lesb;	/* link error status block */ -}; - -enum fc_els_rps_resp_flag { -	FC_ELS_RPS_LPEV =	0x01,	/* L_port extension valid */ -}; - -enum fc_els_rps_resp_status { -	FC_ELS_RPS_PTP =	1 << 5,	/* point-to-point connection */ -	FC_ELS_RPS_LOOP =	1 << 4,	/* loop mode */ -	FC_ELS_RPS_FAB =	1 << 3,	/* fabric present */ -	FC_ELS_RPS_NO_SIG =	1 << 2,	/* loss of signal */ -	FC_ELS_RPS_NO_SYNC =	1 << 1,	/* loss of synchronization */ -	FC_ELS_RPS_RESET =	1 << 0,	/* in link reset protocol */ -}; - -/* - * ELS LIRR - Link Incident Record Registration request. - */ -struct fc_els_lirr { -	__u8		lirr_cmd;	/* command */ -	__u8		lirr_resv[3];	/* reserved - must be zero */ -	__u8		lirr_func;	/* registration function */ -	__u8		lirr_fmt;	/* FC-4 type of RLIR requested */ -	__u8		lirr_resv2[2];	/* reserved - must be zero */ -}; - -enum fc_els_lirr_func { -	ELS_LIRR_SET_COND = 	0x01,	/* set - conditionally receive */ -	ELS_LIRR_SET_UNCOND = 	0x02,	/* set - unconditionally receive */ -	ELS_LIRR_CLEAR = 	0xff	/* clear registration */ -}; - -/* - * ELS SRL - Scan Remote Loop request. - */ -struct fc_els_srl { -	__u8		srl_cmd;	/* command */ -	__u8		srl_resv[3];	/* reserved - must be zero */ -	__u8		srl_flag;	/* flag - see below */ -	__u8		srl_flag_param[3];	/* flag parameter */ -}; - -enum fc_els_srl_flag { -	FC_ELS_SRL_ALL =	0x00,	/* scan all FL ports */ -	FC_ELS_SRL_ONE =	0x01,	/* scan specified loop */ -	FC_ELS_SRL_EN_PER =	0x02,	/* enable periodic scanning (param) */ -	FC_ELS_SRL_DIS_PER =	0x03,	/* disable periodic scanning */ -}; - -/* - * ELS RLS - Read Link Error Status Block request. - */ -struct fc_els_rls { -	__u8		rls_cmd;	/* command */ -	__u8		rls_resv[4];	/* reserved - must be zero */ -	__u8		rls_port_id[3];	/* port ID */ -}; - -/* - * ELS RLS LS_ACC Response. - */ -struct fc_els_rls_resp { -	__u8		rls_cmd;	/* ELS_LS_ACC */ -	__u8		rls_resv[3];	/* reserved - must be zero */ -	struct fc_els_lesb rls_lesb;	/* link error status block */ -}; - -/* - * ELS RLIR - Registered Link Incident Report. - * This is followed by the CLIR and the CLID, described below. - */ -struct fc_els_rlir { -	__u8		rlir_cmd;	/* command */ -	__u8		rlir_resv[3];	/* reserved - must be zero */ -	__u8		rlir_fmt;	/* format (FC4-type if type specific) */ -	__u8		rlir_clr_len;	/* common link incident record length */ -	__u8		rlir_cld_len;	/* common link incident desc. length */ -	__u8		rlir_slr_len;	/* spec. link incident record length */ -}; - -/* - * CLIR - Common Link Incident Record Data. - Sent via RLIR. - */ -struct fc_els_clir { -	__be64		clir_wwpn;	/* incident port name */ -	__be64		clir_wwnn;	/* incident port node name */ -	__u8		clir_port_type;	/* incident port type */ -	__u8		clir_port_id[3];	/* incident port ID */ - -	__be64		clir_conn_wwpn;	/* connected port name */ -	__be64		clir_conn_wwnn;	/* connected node name */ -	__be64		clir_fab_name;	/* fabric name */ -	__be32		clir_phys_port;	/* physical port number */ -	__be32		clir_trans_id;	/* transaction ID */ -	__u8		clir_resv[3];	/* reserved */ -	__u8		clir_ts_fmt;	/* time stamp format */ -	__be64		clir_timestamp;	/* time stamp */ -}; - -/* - * CLIR clir_ts_fmt - time stamp format values. - */ -enum fc_els_clir_ts_fmt { -	ELS_CLIR_TS_UNKNOWN = 	0,	/* time stamp field unknown */ -	ELS_CLIR_TS_SEC_FRAC = 	1,	/* time in seconds and fractions */ -	ELS_CLIR_TS_CSU =	2,	/* time in clock synch update format */ -}; - -/* - * Common Link Incident Descriptor - sent via RLIR. - */ -struct fc_els_clid { -	__u8		clid_iq;	/* incident qualifier flags */ -	__u8		clid_ic;	/* incident code */ -	__be16		clid_epai;	/* domain/area of ISL */ -}; - -/* - * CLID incident qualifier flags. - */ -enum fc_els_clid_iq { -	ELS_CLID_SWITCH =	0x20,	/* incident port is a switch node */ -	ELS_CLID_E_PORT =	0x10,	/* incident is an ISL (E) port */ -	ELS_CLID_SEV_MASK =	0x0c,	/* severity 2-bit field mask */ -	ELS_CLID_SEV_INFO =	0x00,	/* report is informational */ -	ELS_CLID_SEV_INOP =	0x08,	/* link not operational */ -	ELS_CLID_SEV_DEG =	0x04,	/* link degraded but operational */ -	ELS_CLID_LASER =	0x02,	/* subassembly is a laser */ -	ELS_CLID_FRU =		0x01,	/* format can identify a FRU */ -}; - -/* - * CLID incident code. - */ -enum fc_els_clid_ic { -	ELS_CLID_IC_IMPL =	1,	/* implicit incident */ -	ELS_CLID_IC_BER =	2,	/* bit-error-rate threshold exceeded */ -	ELS_CLID_IC_LOS =	3,	/* loss of synch or signal */ -	ELS_CLID_IC_NOS =	4,	/* non-operational primitive sequence */ -	ELS_CLID_IC_PST =	5,	/* primitive sequence timeout */ -	ELS_CLID_IC_INVAL =	6,	/* invalid primitive sequence */ -	ELS_CLID_IC_LOOP_TO =	7,	/* loop initialization time out */ -	ELS_CLID_IC_LIP =	8,	/* receiving LIP */ -}; - -#endif /* _FC_ELS_H_ */ diff --git a/include/scsi/fc/fc_fc2.h b/include/scsi/fc/fc_fc2.h index f87777d0d5b..0b267143130 100644 --- a/include/scsi/fc/fc_fc2.h +++ b/include/scsi/fc/fc_fc2.h @@ -104,7 +104,7 @@ struct fc_esb {   * esb_e_stat - flags from FC-FS-2 T11/1619-D Rev 0.90.   */  #define ESB_ST_RESP         (1 << 31)   /* responder to exchange */ -#define ESB_ST_SEQ_INIT     (1 << 30)   /* port holds sequence initiaive */ +#define ESB_ST_SEQ_INIT     (1 << 30)   /* port holds sequence initiative */  #define ESB_ST_COMPLETE     (1 << 29)   /* exchange is complete */  #define ESB_ST_ABNORMAL     (1 << 28)   /* abnormal ending condition */  #define ESB_ST_REC_QUAL     (1 << 26)   /* recovery qualifier active */ diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h index 8e9b222251c..9c8702942b6 100644 --- a/include/scsi/fc/fc_fcp.h +++ b/include/scsi/fc/fc_fcp.h @@ -20,6 +20,8 @@  #ifndef _FC_FCP_H_  #define	_FC_FCP_H_ +#include <scsi/scsi.h> +  /*   * Fibre Channel Protocol for SCSI.   * From T10 FCP-3, T10 project 1560-D Rev 4, Sept. 13, 2005. @@ -45,8 +47,8 @@   * FCP_CMND IU Payload.   */  struct fcp_cmnd { -	__u8		fc_lun[8];	/* logical unit number */ -	__u8		fc_cmdref;	/* commmand reference number */ +	struct scsi_lun	fc_lun;		/* logical unit number */ +	__u8		fc_cmdref;	/* command reference number */  	__u8		fc_pri_ta;	/* priority and task attribute */  	__u8		fc_tm_flags;	/* task management flags */  	__u8		fc_flags;	/* additional len & flags */ @@ -57,8 +59,8 @@ struct fcp_cmnd {  #define	FCP_CMND_LEN	32	/* expected length of structure */  struct fcp_cmnd32 { -	__u8		fc_lun[8];	/* logical unit number */ -	__u8		fc_cmdref;	/* commmand reference number */ +	struct scsi_lun	fc_lun;		/* logical unit number */ +	__u8		fc_cmdref;	/* command reference number */  	__u8		fc_pri_ta;	/* priority and task attribute */  	__u8		fc_tm_flags;	/* task management flags */  	__u8		fc_flags;	/* additional len & flags */ @@ -75,7 +77,7 @@ struct fcp_cmnd32 {  #define	FCP_PTA_SIMPLE	    0	/* simple task attribute */  #define	FCP_PTA_HEADQ	    1	/* head of queue task attribute */  #define	FCP_PTA_ORDERED     2	/* ordered task attribute */ -#define	FCP_PTA_ACA	    4	/* auto. contigent allegiance */ +#define	FCP_PTA_ACA	    4	/* auto. contingent allegiance */  #define	FCP_PTA_MASK	    7	/* mask for task attribute field */  #define	FCP_PRI_SHIFT	    3	/* priority field starts in bit 3 */  #define	FCP_PRI_RESVD_MASK  0x80	/* reserved bits in priority field */ @@ -125,6 +127,9 @@ struct fcp_txrdy {   *   * All response frames will always contain the fcp_resp template.  Some   * will also include the fcp_resp_len template. + * + * From Table 23, the FCP_RSP_INFO can either be 4 bytes or 8 bytes, both + * are valid length.   */  struct fcp_resp {  	__u8		_fr_resvd[8];	/* reserved */ @@ -154,6 +159,9 @@ struct fcp_resp_rsp_info {      __u8      _fr_resvd2[4];      /* reserved */  }; +#define FCP_RESP_RSP_INFO_LEN4    4 /* without reserved field */ +#define FCP_RESP_RSP_INFO_LEN8    8 /* with reserved field */ +  struct fcp_resp_with_ext {  	struct fcp_resp resp;  	struct fcp_resp_ext ext; diff --git a/include/scsi/fc/fc_fs.h b/include/scsi/fc/fc_fs.h deleted file mode 100644 index 50f28b14345..00000000000 --- a/include/scsi/fc/fc_fs.h +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright(c) 2007 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Maintained at www.Open-FCoE.org - */ - -#ifndef _FC_FS_H_ -#define _FC_FS_H_ - -#include <linux/types.h> - -/* - * Fibre Channel Framing and Signalling definitions. - * From T11 FC-FS-2 Rev 0.90 - 9 August 2005. - */ - -/* - * Frame header - */ -struct fc_frame_header { -	__u8          fh_r_ctl;	/* routing control */ -	__u8          fh_d_id[3];	/* Destination ID */ - -	__u8          fh_cs_ctl;	/* class of service control / pri */ -	__u8          fh_s_id[3];	/* Source ID */ - -	__u8          fh_type;		/* see enum fc_fh_type below */ -	__u8          fh_f_ctl[3];	/* frame control */ - -	__u8          fh_seq_id;	/* sequence ID */ -	__u8          fh_df_ctl;	/* data field control */ -	__be16        fh_seq_cnt;	/* sequence count */ - -	__be16        fh_ox_id;		/* originator exchange ID */ -	__be16        fh_rx_id;		/* responder exchange ID */ -	__be32        fh_parm_offset;	/* parameter or relative offset */ -}; - -#define FC_FRAME_HEADER_LEN 24	/* expected length of structure */ - -#define FC_MAX_PAYLOAD  2112U		/* max payload length in bytes */ -#define FC_MIN_MAX_PAYLOAD  256U 	/* lower limit on max payload */ - -#define FC_MAX_FRAME	(FC_MAX_PAYLOAD + FC_FRAME_HEADER_LEN) -#define FC_MIN_MAX_FRAME (FC_MIN_MAX_PAYLOAD + FC_FRAME_HEADER_LEN) - -/* - * fh_r_ctl - Routing control definitions. - */ -    /* -     * FC-4 device_data. -     */ -enum fc_rctl { -	FC_RCTL_DD_UNCAT = 0x00,	/* uncategorized information */ -	FC_RCTL_DD_SOL_DATA = 0x01,	/* solicited data */ -	FC_RCTL_DD_UNSOL_CTL = 0x02,	/* unsolicited control */ -	FC_RCTL_DD_SOL_CTL = 0x03,	/* solicited control or reply */ -	FC_RCTL_DD_UNSOL_DATA = 0x04,	/* unsolicited data */ -	FC_RCTL_DD_DATA_DESC = 0x05,	/* data descriptor */ -	FC_RCTL_DD_UNSOL_CMD = 0x06,	/* unsolicited command */ -	FC_RCTL_DD_CMD_STATUS = 0x07,	/* command status */ - -#define FC_RCTL_ILS_REQ FC_RCTL_DD_UNSOL_CTL	/* ILS request */ -#define FC_RCTL_ILS_REP FC_RCTL_DD_SOL_CTL	/* ILS reply */ - -	/* -	 * Extended Link_Data -	 */ -	FC_RCTL_ELS_REQ = 0x22,	/* extended link services request */ -	FC_RCTL_ELS_REP = 0x23,	/* extended link services reply */ -	FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */ -	FC_RCTL_ELS4_REP = 0x33, /* FC-4 ELS reply */ -	/* -	 * Optional Extended Headers -	 */ -	FC_RCTL_VFTH = 0x50,	/* virtual fabric tagging header */ -	FC_RCTL_IFRH = 0x51,	/* inter-fabric routing header */ -	FC_RCTL_ENCH = 0x52,	/* encapsulation header */ -	/* -	 * Basic Link Services fh_r_ctl values. -	 */ -	FC_RCTL_BA_NOP = 0x80,	/* basic link service NOP */ -	FC_RCTL_BA_ABTS = 0x81,	/* basic link service abort */ -	FC_RCTL_BA_RMC = 0x82,	/* remove connection */ -	FC_RCTL_BA_ACC = 0x84,	/* basic accept */ -	FC_RCTL_BA_RJT = 0x85,	/* basic reject */ -	FC_RCTL_BA_PRMT = 0x86,	/* dedicated connection preempted */ -	/* -	 * Link Control Information. -	 */ -	FC_RCTL_ACK_1 = 0xc0,	/* acknowledge_1 */ -	FC_RCTL_ACK_0 = 0xc1,	/* acknowledge_0 */ -	FC_RCTL_P_RJT = 0xc2,	/* port reject */ -	FC_RCTL_F_RJT = 0xc3,	/* fabric reject */ -	FC_RCTL_P_BSY = 0xc4,	/* port busy */ -	FC_RCTL_F_BSY = 0xc5,	/* fabric busy to data frame */ -	FC_RCTL_F_BSYL = 0xc6,	/* fabric busy to link control frame */ -	FC_RCTL_LCR = 0xc7,	/* link credit reset */ -	FC_RCTL_END = 0xc9,	/* end */ -}; -				    /* incomplete list of definitions */ - -/* - * R_CTL names initializer. - * Please keep this matching the above definitions. - */ -#define FC_RCTL_NAMES_INIT { \ -	[FC_RCTL_DD_UNCAT] =		"uncat",			\ -	[FC_RCTL_DD_SOL_DATA] =		"sol data",			\ -	[FC_RCTL_DD_UNSOL_CTL] =	"unsol ctl",			\ -	[FC_RCTL_DD_SOL_CTL] =		"sol ctl/reply",		\ -	[FC_RCTL_DD_UNSOL_DATA] =	"unsol data",			\ -	[FC_RCTL_DD_DATA_DESC] =	"data desc",			\ -	[FC_RCTL_DD_UNSOL_CMD] =	"unsol cmd",			\ -	[FC_RCTL_DD_CMD_STATUS] =	"cmd status",			\ -	[FC_RCTL_ELS_REQ] =		"ELS req",			\ -	[FC_RCTL_ELS_REP] =		"ELS rep",			\ -	[FC_RCTL_ELS4_REQ] =		"FC-4 ELS req",			\ -	[FC_RCTL_ELS4_REP] =		"FC-4 ELS rep",			\ -	[FC_RCTL_BA_NOP] =		"BLS NOP",			\ -	[FC_RCTL_BA_ABTS] =		"BLS abort",			\ -	[FC_RCTL_BA_RMC] =		"BLS remove connection",	\ -	[FC_RCTL_BA_ACC] =		"BLS accept",			\ -	[FC_RCTL_BA_RJT] =		"BLS reject",			\ -	[FC_RCTL_BA_PRMT] =		"BLS dedicated connection preempted", \ -	[FC_RCTL_ACK_1] =		"LC ACK_1",			\ -	[FC_RCTL_ACK_0] =		"LC ACK_0",			\ -	[FC_RCTL_P_RJT] =		"LC port reject",		\ -	[FC_RCTL_F_RJT] =		"LC fabric reject",		\ -	[FC_RCTL_P_BSY] =		"LC port busy",			\ -	[FC_RCTL_F_BSY] =		"LC fabric busy to data frame",	\ -	[FC_RCTL_F_BSYL] =		"LC fabric busy to link control frame",\ -	[FC_RCTL_LCR] =			"LC link credit reset",		\ -	[FC_RCTL_END] =			"LC end",			\ -} - -/* - * Well-known fabric addresses. - */ -enum fc_well_known_fid { -	FC_FID_NONE =           0x000000,       /* No destination */ -	FC_FID_BCAST =		0xffffff,	/* broadcast */ -	FC_FID_FLOGI =		0xfffffe,	/* fabric login */ -	FC_FID_FCTRL =		0xfffffd,	/* fabric controller */ -	FC_FID_DIR_SERV =	0xfffffc,	/* directory server */ -	FC_FID_TIME_SERV =	0xfffffb,	/* time server */ -	FC_FID_MGMT_SERV =	0xfffffa,	/* management server */ -	FC_FID_QOS =		0xfffff9,	/* QoS Facilitator */ -	FC_FID_ALIASES =	0xfffff8,	/* alias server (FC-PH2) */ -	FC_FID_SEC_KEY =	0xfffff7,	/* Security key dist. server */ -	FC_FID_CLOCK =		0xfffff6,	/* clock synch server */ -	FC_FID_MCAST_SERV =	0xfffff5,	/* multicast server */ -}; - -#define	FC_FID_WELL_KNOWN_MAX	0xffffff /* highest well-known fabric ID */ -#define	FC_FID_WELL_KNOWN_BASE	0xfffff5 /* start of well-known fabric ID */ - -/* - * Other well-known addresses, outside the above contiguous range. - */ -#define	FC_FID_DOM_MGR		0xfffc00	/* domain manager base */ - -/* - * Fabric ID bytes. - */ -#define	FC_FID_DOMAIN		0 -#define	FC_FID_PORT		1 -#define	FC_FID_LINK		2 - -/* - * fh_type codes - */ -enum fc_fh_type { -	FC_TYPE_BLS =	0x00,	/* basic link service */ -	FC_TYPE_ELS =	0x01,	/* extended link service */ -	FC_TYPE_IP =	0x05,	/* IP over FC, RFC 4338 */ -	FC_TYPE_FCP =	0x08,	/* SCSI FCP */ -	FC_TYPE_CT =	0x20,	/* Fibre Channel Services (FC-CT) */ -	FC_TYPE_ILS =	0x22,	/* internal link service */ -}; - -/* - * FC_TYPE names initializer. - * Please keep this matching the above definitions. - */ -#define FC_TYPE_NAMES_INIT {				\ -	[FC_TYPE_BLS] =		"BLS",			\ -	[FC_TYPE_ELS] =		"ELS",			\ -	[FC_TYPE_IP] =		"IP",			\ -	[FC_TYPE_FCP] =		"FCP",			\ -	[FC_TYPE_CT] =		"CT",			\ -	[FC_TYPE_ILS] =		"ILS",			\ -} - -/* - * Exchange IDs. - */ -#define FC_XID_UNKNOWN  0xffff	/* unknown exchange ID */ -#define FC_XID_MIN	0x0	/* supported min exchange ID */ -#define FC_XID_MAX	0xfffe	/* supported max exchange ID */ - -/* - * fh_f_ctl - Frame control flags. - */ -#define	FC_FC_EX_CTX	(1 << 23)	/* sent by responder to exchange */ -#define	FC_FC_SEQ_CTX	(1 << 22)	/* sent by responder to sequence */ -#define	FC_FC_FIRST_SEQ (1 << 21)	/* first sequence of this exchange */ -#define	FC_FC_LAST_SEQ	(1 << 20)	/* last sequence of this exchange */ -#define	FC_FC_END_SEQ	(1 << 19)	/* last frame of sequence */ -#define	FC_FC_END_CONN	(1 << 18)	/* end of class 1 connection pending */ -#define	FC_FC_RES_B17	(1 << 17)	/* reserved */ -#define	FC_FC_SEQ_INIT	(1 << 16)	/* transfer of sequence initiative */ -#define	FC_FC_X_ID_REASS (1 << 15)	/* exchange ID has been changed */ -#define	FC_FC_X_ID_INVAL (1 << 14)	/* exchange ID invalidated */ - -#define	FC_FC_ACK_1	(1 << 12)	/* 13:12 = 1: ACK_1 expected */ -#define	FC_FC_ACK_N	(2 << 12)	/* 13:12 = 2: ACK_N expected */ -#define	FC_FC_ACK_0	(3 << 12)	/* 13:12 = 3: ACK_0 expected */ - -#define	FC_FC_RES_B11	(1 << 11)	/* reserved */ -#define	FC_FC_RES_B10	(1 << 10)	/* reserved */ -#define	FC_FC_RETX_SEQ	(1 << 9)	/* retransmitted sequence */ -#define	FC_FC_UNI_TX	(1 << 8)	/* unidirectional transmit (class 1) */ -#define	FC_FC_CONT_SEQ(i) ((i) << 6) -#define	FC_FC_ABT_SEQ(i) ((i) << 4) -#define	FC_FC_REL_OFF	(1 << 3)	/* parameter is relative offset */ -#define	FC_FC_RES2	(1 << 2)	/* reserved */ -#define	FC_FC_FILL(i)	((i) & 3)	/* 1:0: bytes of trailing fill */ - -/* - * BA_ACC payload. - */ -struct fc_ba_acc { -	__u8		ba_seq_id_val;	/* SEQ_ID validity */ -#define FC_BA_SEQ_ID_VAL 0x80 -	__u8		ba_seq_id;	/* SEQ_ID of seq last deliverable */ -	__u8		ba_resvd[2];	/* reserved */ -	__be16		ba_ox_id;	/* OX_ID for aborted seq or exch */ -	__be16		ba_rx_id;	/* RX_ID for aborted seq or exch */ -	__be16		ba_low_seq_cnt;	/* low SEQ_CNT of aborted seq */ -	__be16		ba_high_seq_cnt; /* high SEQ_CNT of aborted seq */ -}; - -/* - * BA_RJT: Basic Reject payload. - */ -struct fc_ba_rjt { -	__u8		br_resvd;	/* reserved */ -	__u8		br_reason;	/* reason code */ -	__u8		br_explan;	/* reason explanation */ -	__u8		br_vendor;	/* vendor unique code */ -}; - -/* - * BA_RJT reason codes. - * From FS-2. - */ -enum fc_ba_rjt_reason { -	FC_BA_RJT_NONE =	0,	/* in software this means no reject */ -	FC_BA_RJT_INVL_CMD =	0x01,	/* invalid command code */ -	FC_BA_RJT_LOG_ERR =	0x03,	/* logical error */ -	FC_BA_RJT_LOG_BUSY =	0x05,	/* logical busy */ -	FC_BA_RJT_PROTO_ERR =	0x07,	/* protocol error */ -	FC_BA_RJT_UNABLE =	0x09,	/* unable to perform request */ -	FC_BA_RJT_VENDOR =	0xff,	/* vendor-specific (see br_vendor) */ -}; - -/* - * BA_RJT reason code explanations. - */ -enum fc_ba_rjt_explan { -	FC_BA_RJT_EXP_NONE =	0x00,	/* no additional expanation */ -	FC_BA_RJT_INV_XID =	0x03,	/* invalid OX_ID-RX_ID combination */ -	FC_BA_RJT_ABT =		0x05,	/* sequence aborted, no seq info */ -}; - -/* - * P_RJT or F_RJT: Port Reject or Fabric Reject parameter field. - */ -struct fc_pf_rjt { -	__u8		rj_action;	/* reserved */ -	__u8		rj_reason;	/* reason code */ -	__u8		rj_resvd;	/* reserved */ -	__u8		rj_vendor;	/* vendor unique code */ -}; - -/* - * P_RJT and F_RJT reject reason codes. - */ -enum fc_pf_rjt_reason { -	FC_RJT_NONE =		0,	/* non-reject (reserved by standard) */ -	FC_RJT_INVL_DID =	0x01,	/* invalid destination ID */ -	FC_RJT_INVL_SID =	0x02,	/* invalid source ID */ -	FC_RJT_P_UNAV_T =	0x03,	/* port unavailable, temporary */ -	FC_RJT_P_UNAV =		0x04,	/* port unavailable, permanent */ -	FC_RJT_CLS_UNSUP =	0x05,	/* class not supported */ -	FC_RJT_DEL_USAGE =	0x06,	/* delimiter usage error */ -	FC_RJT_TYPE_UNSUP =	0x07,	/* type not supported */ -	FC_RJT_LINK_CTL =	0x08,	/* invalid link control */ -	FC_RJT_R_CTL =		0x09,	/* invalid R_CTL field */ -	FC_RJT_F_CTL =		0x0a,	/* invalid F_CTL field */ -	FC_RJT_OX_ID =		0x0b,	/* invalid originator exchange ID */ -	FC_RJT_RX_ID =		0x0c,	/* invalid responder exchange ID */ -	FC_RJT_SEQ_ID =		0x0d,	/* invalid sequence ID */ -	FC_RJT_DF_CTL =		0x0e,	/* invalid DF_CTL field */ -	FC_RJT_SEQ_CNT =	0x0f,	/* invalid SEQ_CNT field */ -	FC_RJT_PARAM =		0x10,	/* invalid parameter field */ -	FC_RJT_EXCH_ERR =	0x11,	/* exchange error */ -	FC_RJT_PROTO =		0x12,	/* protocol error */ -	FC_RJT_LEN =		0x13,	/* incorrect length */ -	FC_RJT_UNEXP_ACK =	0x14,	/* unexpected ACK */ -	FC_RJT_FAB_CLASS =	0x15,	/* class unsupported by fabric entity */ -	FC_RJT_LOGI_REQ =	0x16,	/* login required */ -	FC_RJT_SEQ_XS =		0x17,	/* excessive sequences attempted */ -	FC_RJT_EXCH_EST =	0x18,	/* unable to establish exchange */ -	FC_RJT_FAB_UNAV =	0x1a,	/* fabric unavailable */ -	FC_RJT_VC_ID =		0x1b,	/* invalid VC_ID (class 4) */ -	FC_RJT_CS_CTL =		0x1c,	/* invalid CS_CTL field */ -	FC_RJT_INSUF_RES =	0x1d,	/* insuff. resources for VC (Class 4) */ -	FC_RJT_INVL_CLS =	0x1f,	/* invalid class of service */ -	FC_RJT_PREEMT_RJT =	0x20,	/* preemption request rejected */ -	FC_RJT_PREEMT_DIS =	0x21,	/* preemption not enabled */ -	FC_RJT_MCAST_ERR =	0x22,	/* multicast error */ -	FC_RJT_MCAST_ET =	0x23,	/* multicast error terminate */ -	FC_RJT_PRLI_REQ =	0x24,	/* process login required */ -	FC_RJT_INVL_ATT =	0x25,	/* invalid attachment */ -	FC_RJT_VENDOR =		0xff,	/* vendor specific reject */ -}; - -/* default timeout values */ - -#define FC_DEF_E_D_TOV	2000UL -#define FC_DEF_R_A_TOV	10000UL - -#endif /* _FC_FS_H_ */ diff --git a/include/scsi/fc/fc_gs.h b/include/scsi/fc/fc_gs.h deleted file mode 100644 index a37346d47eb..00000000000 --- a/include/scsi/fc/fc_gs.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright(c) 2007 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Maintained at www.Open-FCoE.org - */ - -#ifndef _FC_GS_H_ -#define	_FC_GS_H_ - -#include <linux/types.h> - -/* - * Fibre Channel Services - Common Transport. - * From T11.org FC-GS-2 Rev 5.3 November 1998. - */ - -struct fc_ct_hdr { -	__u8		ct_rev;		/* revision */ -	__u8		ct_in_id[3];	/* N_Port ID of original requestor */ -	__u8		ct_fs_type;	/* type of fibre channel service */ -	__u8		ct_fs_subtype;	/* subtype */ -	__u8		ct_options; -	__u8		_ct_resvd1; -	__be16		ct_cmd;		/* command / response code */ -	__be16		ct_mr_size;	/* maximum / residual size */ -	__u8		_ct_resvd2; -	__u8		ct_reason;	/* reject reason */ -	__u8		ct_explan;	/* reason code explanation */ -	__u8		ct_vendor;	/* vendor unique data */ -}; - -#define	FC_CT_HDR_LEN	16	/* expected sizeof (struct fc_ct_hdr) */ - -enum fc_ct_rev { -	FC_CT_REV = 1		/* common transport revision */ -}; - -/* - * ct_fs_type values. - */ -enum fc_ct_fs_type { -	FC_FST_ALIAS =	0xf8,	/* alias service */ -	FC_FST_MGMT =	0xfa,	/* management service */ -	FC_FST_TIME =	0xfb,	/* time service */ -	FC_FST_DIR =	0xfc,	/* directory service */ -}; - -/* - * ct_cmd: Command / response codes - */ -enum fc_ct_cmd { -	FC_FS_RJT =	0x8001,	/* reject */ -	FC_FS_ACC =	0x8002,	/* accept */ -}; - -/* - * FS_RJT reason codes. - */ -enum fc_ct_reason { -	FC_FS_RJT_CMD =		0x01,	/* invalid command code */ -	FC_FS_RJT_VER =		0x02,	/* invalid version level */ -	FC_FS_RJT_LOG =		0x03,	/* logical error */ -	FC_FS_RJT_IUSIZ =	0x04,	/* invalid IU size */ -	FC_FS_RJT_BSY =		0x05,	/* logical busy */ -	FC_FS_RJT_PROTO =	0x07,	/* protocol error */ -	FC_FS_RJT_UNABL =	0x09,	/* unable to perform command request */ -	FC_FS_RJT_UNSUP =	0x0b,	/* command not supported */ -}; - -/* - * FS_RJT reason code explanations. - */ -enum fc_ct_explan { -	FC_FS_EXP_NONE =	0x00,	/* no additional explanation */ -	FC_FS_EXP_PID =		0x01,	/* port ID not registered */ -	FC_FS_EXP_PNAM =	0x02,	/* port name not registered */ -	FC_FS_EXP_NNAM =	0x03,	/* node name not registered */ -	FC_FS_EXP_COS =		0x04,	/* class of service not registered */ -	FC_FS_EXP_FTNR =	0x07,	/* FC-4 types not registered */ -	/* definitions not complete */ -}; - -#endif /* _FC_GS_H_ */ diff --git a/include/scsi/fc/fc_ms.h b/include/scsi/fc/fc_ms.h new file mode 100644 index 00000000000..f52b921b5c7 --- /dev/null +++ b/include/scsi/fc/fc_ms.h @@ -0,0 +1,213 @@ +/* * Copyright(c) 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_MS_H_ +#define	_FC_MS_H_ + +#include <linux/types.h> + +/* + * Fibre Channel Services - Management Service (MS) + * From T11.org FC-GS-4 Rev 7.91 February 4, 2004 + */ + +/* + * Fabric Device Management Interface + */ + +/* + * Common-transport sub-type for FDMI + */ +#define	FC_FDMI_SUBTYPE	    0x10 /* fs_ct_hdr.ct_fs_subtype */ + +/* + * Management server FDMI Requests. + */ +enum fc_fdmi_req { +	FC_FDMI_GRHL = 0x0100,	/* Get Registered HBA List */ +	FC_FDMI_GHAT = 0x0101,	/* Get HBA Attributes */ +	FC_FDMI_GRPL = 0x0102,	/* Get Registered Port List */ +	FC_FDMI_GPAT = 0x0110,	/* Get Port Attributes */ +	FC_FDMI_RHBA = 0x0200,	/* Register HBA */ +	FC_FDMI_RHAT = 0x0201,	/* Register HBA Attributes */ +	FC_FDMI_RPRT = 0x0210,	/* Register Port */ +	FC_FDMI_RPA = 0x0211,	/* Register Port Attributes */ +	FC_FDMI_DHBA = 0x0300,	/* Deregister HBA */ +	FC_FDMI_DHAT = 0x0301,	/* Deregister HBA Attributes */ +	FC_FDMI_DPRT = 0x0310,	/* Deregister Port */ +	FC_FDMI_DPA = 0x0311,	/* Deregister Port Attributes */ +}; + +/* + * HBA Attribute Entry Type + */ +enum fc_fdmi_hba_attr_type { +	FC_FDMI_HBA_ATTR_NODENAME = 0x0001, +	FC_FDMI_HBA_ATTR_MANUFACTURER = 0x0002, +	FC_FDMI_HBA_ATTR_SERIALNUMBER = 0x0003, +	FC_FDMI_HBA_ATTR_MODEL = 0x0004, +	FC_FDMI_HBA_ATTR_MODELDESCRIPTION = 0x0005, +	FC_FDMI_HBA_ATTR_HARDWAREVERSION = 0x0006, +	FC_FDMI_HBA_ATTR_DRIVERVERSION = 0x0007, +	FC_FDMI_HBA_ATTR_OPTIONROMVERSION = 0x0008, +	FC_FDMI_HBA_ATTR_FIRMWAREVERSION = 0x0009, +	FC_FDMI_HBA_ATTR_OSNAMEVERSION = 0x000A, +	FC_FDMI_HBA_ATTR_MAXCTPAYLOAD = 0x000B, +}; + +/* + * HBA Attribute Length + */ +#define FC_FDMI_HBA_ATTR_NODENAME_LEN		8 +#define FC_FDMI_HBA_ATTR_MANUFACTURER_LEN	64 +#define FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN	64 +#define FC_FDMI_HBA_ATTR_MODEL_LEN		256 +#define FC_FDMI_HBA_ATTR_MODELDESCR_LEN		256 +#define FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN	256 +#define FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN	256 +#define FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN	256 +#define FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN	256 +#define FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN	256 +#define FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN	4 + +/* + * Port Attribute Type + */ +enum fc_fdmi_port_attr_type { +	FC_FDMI_PORT_ATTR_FC4TYPES = 0x0001, +	FC_FDMI_PORT_ATTR_SUPPORTEDSPEED = 0x0002, +	FC_FDMI_PORT_ATTR_CURRENTPORTSPEED = 0x0003, +	FC_FDMI_PORT_ATTR_MAXFRAMESIZE = 0x0004, +	FC_FDMI_PORT_ATTR_OSDEVICENAME = 0x0005, +	FC_FDMI_PORT_ATTR_HOSTNAME = 0x0006, +}; + +/* + * Port Attribute Length + */ +#define FC_FDMI_PORT_ATTR_FC4TYPES_LEN		32 +#define FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN	4 +#define FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN	4 +#define FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN	4 +#define FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN	256 +#define FC_FDMI_PORT_ATTR_HOSTNAME_LEN		256 + +/* + * HBA Attribute ID + */ +struct fc_fdmi_hba_identifier { +	__be64		id; +}; + +/* + * Port Name + */ +struct fc_fdmi_port_name { +	__be64		portname; +}; + +/* + * Attribute Entry Block for HBA/Port Attributes + */ +#define FC_FDMI_ATTR_ENTRY_HEADER_LEN	4 +struct fc_fdmi_attr_entry { +	__be16		type; +	__be16		len; +	__u8		value[1]; +} __attribute__((__packed__)); + +/* + * Common for HBA/Port Attributes + */ +struct fs_fdmi_attrs { +	__be32				numattrs; +	struct fc_fdmi_attr_entry	attr[1]; +} __attribute__((__packed__)); + +/* + * Registered Port List + */ +struct fc_fdmi_rpl { +	__be32				numport; +	struct fc_fdmi_port_name	port[1]; +} __attribute__((__packed__)); + +/* + * Register HBA (RHBA) + */ +struct fc_fdmi_rhba { +	struct fc_fdmi_hba_identifier hbaid; +	struct fc_fdmi_rpl		 port; +	struct fs_fdmi_attrs		 hba_attrs; +} __attribute__((__packed__)); + +/* + * Register HBA Attributes (RHAT) + */ +struct fc_fdmi_rhat { +	struct fc_fdmi_hba_identifier hbaid; +	struct fs_fdmi_attrs		 hba_attrs; +} __attribute__((__packed__)); + +/* + * Register Port (RPRT) + */ +struct fc_fdmi_rprt { +	struct fc_fdmi_hba_identifier hbaid; +	struct fc_fdmi_port_name	 port; +	struct fs_fdmi_attrs		 hba_attrs; +} __attribute__((__packed__)); + +/* + * Register Port Attributes (RPA) + */ +struct fc_fdmi_rpa { +	struct fc_fdmi_port_name	 port; +	struct fs_fdmi_attrs		 hba_attrs; +} __attribute__((__packed__)); + +/* + * Deregister Port (DPRT) + */ +struct fc_fdmi_dprt { +	struct fc_fdmi_port_name	 port; +} __attribute__((__packed__)); + +/* + * Deregister Port Attributes (DPA) + */ +struct fc_fdmi_dpa { +	struct fc_fdmi_port_name	 port; +	struct fs_fdmi_attrs		 hba_attrs; +} __attribute__((__packed__)); + +/* + * Deregister HBA Attributes (DHAT) + */ +struct fc_fdmi_dhat { +	struct fc_fdmi_hba_identifier hbaid; +} __attribute__((__packed__)); + +/* + * Deregister HBA (DHBA) + */ +struct fc_fdmi_dhba { +	struct fc_fdmi_hba_identifier hbaid; +} __attribute__((__packed__)); + +#endif /* _FC_MS_H_ */ diff --git a/include/scsi/fc/fc_ns.h b/include/scsi/fc/fc_ns.h deleted file mode 100644 index 185015dd116..00000000000 --- a/include/scsi/fc/fc_ns.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright(c) 2007 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Maintained at www.Open-FCoE.org - */ - -#ifndef _FC_NS_H_ -#define	_FC_NS_H_ - -#include <linux/types.h> - -/* - * Fibre Channel Services - Name Service (dNS) - * From T11.org FC-GS-2 Rev 5.3 November 1998. - */ - -/* - * Common-transport sub-type for Name Server. - */ -#define	FC_NS_SUBTYPE	    2	/* fs_ct_hdr.ct_fs_subtype */ - -/* - * Name server Requests. - * Note:  this is an incomplete list, some unused requests are omitted. - */ -enum fc_ns_req { -	FC_NS_GA_NXT =	0x0100,		/* get all next */ -	FC_NS_GI_A =	0x0101,		/* get identifiers - scope */ -	FC_NS_GPN_ID =	0x0112,		/* get port name by ID */ -	FC_NS_GNN_ID =	0x0113,		/* get node name by ID */ -	FC_NS_GID_PN =	0x0121,		/* get ID for port name */ -	FC_NS_GID_NN =	0x0131,		/* get IDs for node name */ -	FC_NS_GID_FT =	0x0171,		/* get IDs by FC4 type */ -	FC_NS_GPN_FT =	0x0172,		/* get port names by FC4 type */ -	FC_NS_GID_PT =	0x01a1,		/* get IDs by port type */ -	FC_NS_RPN_ID =	0x0212,		/* reg port name for ID */ -	FC_NS_RNN_ID =	0x0213,		/* reg node name for ID */ -	FC_NS_RFT_ID =	0x0217,		/* reg FC4 type for ID */ -	FC_NS_RSPN_ID =	0x0218,		/* reg symbolic port name */ -	FC_NS_RFF_ID =	0x021f,		/* reg FC4 Features for ID */ -	FC_NS_RSNN_NN =	0x0239,		/* reg symbolic node name */ -}; - -/* - * Port type values. - */ -enum fc_ns_pt { -	FC_NS_UNID_PORT = 0x00,	/* unidentified */ -	FC_NS_N_PORT =	0x01,	/* N port */ -	FC_NS_NL_PORT =	0x02,	/* NL port */ -	FC_NS_FNL_PORT = 0x03,	/* F/NL port */ -	FC_NS_NX_PORT =	0x7f,	/* Nx port */ -	FC_NS_F_PORT =	0x81,	/* F port */ -	FC_NS_FL_PORT =	0x82,	/* FL port */ -	FC_NS_E_PORT =	0x84,	/* E port */ -	FC_NS_B_PORT =	0x85,	/* B port */ -}; - -/* - * Port type object. - */ -struct fc_ns_pt_obj { -	__u8		pt_type; -}; - -/* - * Port ID object - */ -struct fc_ns_fid { -	__u8		fp_flags;	/* flags for responses only */ -	__u8		fp_fid[3]; -}; - -/* - * fp_flags in port ID object, for responses only. - */ -#define	FC_NS_FID_LAST	0x80		/* last object */ - -/* - * FC4-types object. - */ -#define	FC_NS_TYPES	256	/* number of possible FC-4 types */ -#define	FC_NS_BPW	32	/* bits per word in bitmap */ - -struct fc_ns_fts { -	__be32	ff_type_map[FC_NS_TYPES / FC_NS_BPW]; /* bitmap of FC-4 types */ -}; - -/* - * FC4-features object. - */ -struct fc_ns_ff	{ -	__be32	fd_feat[FC_NS_TYPES * 4 / FC_NS_BPW]; /* 4-bits per FC-type */ -}; - -/* - * GID_PT request. - */ -struct fc_ns_gid_pt { -	__u8		fn_pt_type; -	__u8		fn_domain_id_scope; -	__u8		fn_area_id_scope; -	__u8		fn_resvd; -}; - -/* - * GID_FT or GPN_FT request. - */ -struct fc_ns_gid_ft { -	__u8		fn_resvd; -	__u8		fn_domain_id_scope; -	__u8		fn_area_id_scope; -	__u8		fn_fc4_type; -}; - -/* - * GPN_FT response. - */ -struct fc_gpn_ft_resp { -	__u8		fp_flags;	/* see fp_flags definitions above */ -	__u8		fp_fid[3];	/* port ID */ -	__be32		fp_resvd; -	__be64		fp_wwpn;	/* port name */ -}; - -/* - * GID_PN request - */ -struct fc_ns_gid_pn { -	__be64     fn_wwpn;    /* port name */ -}; - -/* - * GID_PN response - */ -struct fc_gid_pn_resp { -	__u8      fp_resvd; -	__u8      fp_fid[3];     /* port ID */ -}; - -/* - * RFT_ID request - register FC-4 types for ID. - */ -struct fc_ns_rft_id { -	struct fc_ns_fid fr_fid;	/* port ID object */ -	struct fc_ns_fts fr_fts;	/* FC-4 types object */ -}; - -/* - * RPN_ID request - register port name for ID. - * RNN_ID request - register node name for ID. - */ -struct fc_ns_rn_id { -	struct fc_ns_fid fr_fid;	/* port ID object */ -	__be64		fr_wwn;		/* node name or port name */ -} __attribute__((__packed__)); - -/* - * RSNN_NN request - register symbolic node name - */ -struct fc_ns_rsnn { -	__be64		fr_wwn;		/* node name */ -	__u8		fr_name_len; -	char		fr_name[]; -} __attribute__((__packed__)); - -/* - * RSPN_ID request - register symbolic port name - */ -struct fc_ns_rspn { -	struct fc_ns_fid fr_fid;	/* port ID object */ -	__u8		fr_name_len; -	char		fr_name[]; -} __attribute__((__packed__)); - -/* - * RFF_ID request - register FC-4 Features for ID. - */ -struct fc_ns_rff_id { -	struct fc_ns_fid fr_fid;	/* port ID object */ -	__u8		fr_resvd[2]; -	__u8		fr_feat;	/* FC-4 Feature bits */ -	__u8		fr_type;	/* FC-4 type */ -} __attribute__((__packed__)); - -#endif /* _FC_NS_H_ */ diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h index 6d293c846a4..35fd4744f3e 100644 --- a/include/scsi/fc_encode.h +++ b/include/scsi/fc_encode.h @@ -20,6 +20,7 @@  #ifndef _FC_ENCODE_H_  #define _FC_ENCODE_H_  #include <asm/unaligned.h> +#include <linux/utsname.h>  /*   * F_CTL values for simple requests and responses. @@ -43,19 +44,18 @@ struct fc_ct_req {  		struct fc_ns_fid fid;  		struct fc_ns_rsnn snn;  		struct fc_ns_rspn spn; +		struct fc_fdmi_rhba rhba; +		struct fc_fdmi_rpa  rpa; +		struct fc_fdmi_dprt dprt; +		struct fc_fdmi_dhba dhba;  	} payload;  }; -/** - * fill FC header fields in specified fc_frame - */ -static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, -				  u32 did, u32 sid, enum fc_fh_type type, -				  u32 f_ctl, u32 parm_offset) +static inline void __fc_fill_fc_hdr(struct fc_frame_header *fh, +				    enum fc_rctl r_ctl, +				    u32 did, u32 sid, enum fc_fh_type type, +				    u32 f_ctl, u32 parm_offset)  { -	struct fc_frame_header *fh; - -	fh = fc_frame_header_get(fp);  	WARN_ON(r_ctl == 0);  	fh->fh_r_ctl = r_ctl;  	hton24(fh->fh_d_id, did); @@ -68,6 +68,19 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,  }  /** + * fill FC header fields in specified fc_frame + */ +static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, +				  u32 did, u32 sid, enum fc_fh_type type, +				  u32 f_ctl, u32 parm_offset) +{ +	struct fc_frame_header *fh; + +	fh = fc_frame_header_get(fp); +	__fc_fill_fc_hdr(fh, r_ctl, did, sid, type, f_ctl, parm_offset); +} + +/**   * fc_adisc_fill() - Fill in adisc request frame   * @lport: local port.   * @fp: fc frame where payload will be placed. @@ -89,7 +102,9 @@ static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)   * returns pointer to ct request.   */  static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, -					       unsigned int op, size_t req_size) +					       unsigned int op, size_t req_size, +					       enum fc_ct_fs_type fs_type, +					       u8 subtype)  {  	struct fc_ct_req *ct;  	size_t ct_plen; @@ -98,14 +113,14 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,  	ct = fc_frame_payload_get(fp, ct_plen);  	memset(ct, 0, ct_plen);  	ct->hdr.ct_rev = FC_CT_REV; -	ct->hdr.ct_fs_type = FC_FST_DIR; -	ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; +	ct->hdr.ct_fs_type = fs_type; +	ct->hdr.ct_fs_subtype = subtype;  	ct->hdr.ct_cmd = htons((u16) op);  	return ct;  }  /** - * fc_ct_fill() - Fill in a name service request frame + * fc_ct_ns_fill() - Fill in a name service request frame   * @lport: local port.   * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.   * @fp: frame to contain payload. @@ -113,7 +128,7 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,   * @r_ctl: pointer to FC header R_CTL.   * @fh_type: pointer to FC-4 type.   */ -static inline int fc_ct_fill(struct fc_lport *lport, +static inline int fc_ct_ns_fill(struct fc_lport *lport,  		      u32 fc_id, struct fc_frame *fp,  		      unsigned int op, enum fc_rctl *r_ctl,  		      enum fc_fh_type *fh_type) @@ -123,23 +138,28 @@ static inline int fc_ct_fill(struct fc_lport *lport,  	switch (op) {  	case FC_NS_GPN_FT: -		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); +		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft), +				    FC_FST_DIR, FC_NS_SUBTYPE);  		ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;  		break;  	case FC_NS_GPN_ID: -		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid)); +		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid), +				    FC_FST_DIR, FC_NS_SUBTYPE); +		ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;  		hton24(ct->payload.fid.fp_fid, fc_id);  		break;  	case FC_NS_RFT_ID: -		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); +		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft), +				    FC_FST_DIR, FC_NS_SUBTYPE);  		hton24(ct->payload.rft.fid.fp_fid, lport->port_id);  		ct->payload.rft.fts = lport->fcts;  		break;  	case FC_NS_RFF_ID: -		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id)); +		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id), +				    FC_FST_DIR, FC_NS_SUBTYPE);  		hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);  		ct->payload.rff.fr_type = FC_TYPE_FCP;  		if (lport->service_params & FCP_SPPF_INIT_FCN) @@ -149,14 +169,16 @@ static inline int fc_ct_fill(struct fc_lport *lport,  		break;  	case FC_NS_RNN_ID: -		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); +		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id), +				    FC_FST_DIR, FC_NS_SUBTYPE);  		hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);  		put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);  		break;  	case FC_NS_RSPN_ID:  		len = strnlen(fc_host_symbolic_name(lport->host), 255); -		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len); +		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len, +				    FC_FST_DIR, FC_NS_SUBTYPE);  		hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);  		strncpy(ct->payload.spn.fr_name,  			fc_host_symbolic_name(lport->host), len); @@ -165,7 +187,8 @@ static inline int fc_ct_fill(struct fc_lport *lport,  	case FC_NS_RSNN_NN:  		len = strnlen(fc_host_symbolic_name(lport->host), 255); -		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len); +		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len, +				    FC_FST_DIR, FC_NS_SUBTYPE);  		put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);  		strncpy(ct->payload.snn.fr_name,  			fc_host_symbolic_name(lport->host), len); @@ -181,6 +204,330 @@ static inline int fc_ct_fill(struct fc_lport *lport,  }  /** + * fc_ct_ms_fill() - Fill in a mgmt service request frame + * @lport: local port. + * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. + * @fp: frame to contain payload. + * @op: CT opcode. + * @r_ctl: pointer to FC header R_CTL. + * @fh_type: pointer to FC-4 type. + */ +static inline int fc_ct_ms_fill(struct fc_lport *lport, +		      u32 fc_id, struct fc_frame *fp, +		      unsigned int op, enum fc_rctl *r_ctl, +		      enum fc_fh_type *fh_type) +{ +	struct fc_ct_req *ct; +	size_t len; +	struct fc_fdmi_attr_entry *entry; +	struct fs_fdmi_attrs *hba_attrs; +	int numattrs = 0; + +	switch (op) { +	case FC_FDMI_RHBA: +		numattrs = 10; +		len = sizeof(struct fc_fdmi_rhba); +		len -= sizeof(struct fc_fdmi_attr_entry); +		len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); +		len += FC_FDMI_HBA_ATTR_NODENAME_LEN; +		len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN; +		len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN; +		len += FC_FDMI_HBA_ATTR_MODEL_LEN; +		len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN; +		len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN; +		len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN; +		len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN; +		len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN; +		len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN; +		ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT, +				    FC_FDMI_SUBTYPE); + +		/* HBA Identifier */ +		put_unaligned_be64(lport->wwpn, &ct->payload.rhba.hbaid.id); +		/* Number of Ports - always 1 */ +		put_unaligned_be32(1, &ct->payload.rhba.port.numport); +		/* Port Name */ +		put_unaligned_be64(lport->wwpn, +				   &ct->payload.rhba.port.port[0].portname); + +		/* HBA Attributes */ +		put_unaligned_be32(numattrs, +				   &ct->payload.rhba.hba_attrs.numattrs); +		hba_attrs = &ct->payload.rhba.hba_attrs; +		entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr; +		/* NodeName*/ +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_NODENAME_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_NODENAME, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		put_unaligned_be64(lport->wwnn, +				   (__be64 *)&entry->value[0]); + +		/* Manufacturer */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_NODENAME_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_MANUFACTURER, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		strncpy((char *)&entry->value, +			fc_host_manufacturer(lport->host), +			FC_FDMI_HBA_ATTR_MANUFACTURER_LEN); + +		/* SerialNumber */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_MANUFACTURER_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_SERIALNUMBER, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		strncpy((char *)&entry->value, +			fc_host_serial_number(lport->host), +			FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN); + +		/* Model */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_MODEL_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_MODEL, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		strncpy((char *)&entry->value, +			fc_host_model(lport->host), +			FC_FDMI_HBA_ATTR_MODEL_LEN); + +		/* Model Description */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_MODEL_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_MODELDESCRIPTION, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		strncpy((char *)&entry->value, +			fc_host_model_description(lport->host), +			FC_FDMI_HBA_ATTR_MODELDESCR_LEN); + +		/* Hardware Version */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_MODELDESCR_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_HARDWAREVERSION, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		strncpy((char *)&entry->value, +			fc_host_hardware_version(lport->host), +			FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN); + +		/* Driver Version */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_DRIVERVERSION, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		strncpy((char *)&entry->value, +			fc_host_driver_version(lport->host), +			FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN); + +		/* OptionROM Version */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_OPTIONROMVERSION, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		strncpy((char *)&entry->value, +			fc_host_optionrom_version(lport->host), +			FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN); + +		/* Firmware Version */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_FIRMWAREVERSION, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		strncpy((char *)&entry->value, +			fc_host_firmware_version(lport->host), +			FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN); + +		/* OS Name and Version */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN; +		put_unaligned_be16(FC_FDMI_HBA_ATTR_OSNAMEVERSION, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		snprintf((char *)&entry->value, +			FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN, +			"%s v%s", +			init_utsname()->sysname, +			init_utsname()->release); +		break; +	case FC_FDMI_RPA: +		numattrs = 6; +		len = sizeof(struct fc_fdmi_rpa); +		len -= sizeof(struct fc_fdmi_attr_entry); +		len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN); +		len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN; +		len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN; +		len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN; +		len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN; +		len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN; +		len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN; +		ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT, +				    FC_FDMI_SUBTYPE); + +		/* Port Name */ +		put_unaligned_be64(lport->wwpn, +				   &ct->payload.rpa.port.portname); + +		/* Port Attributes */ +		put_unaligned_be32(numattrs, +				   &ct->payload.rpa.hba_attrs.numattrs); + +		hba_attrs = &ct->payload.rpa.hba_attrs; +		entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr; + +		/* FC4 types */ +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN; +		put_unaligned_be16(FC_FDMI_PORT_ATTR_FC4TYPES, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		memcpy(&entry->value, fc_host_supported_fc4s(lport->host), +		       FC_FDMI_PORT_ATTR_FC4TYPES_LEN); + +		/* Supported Speed */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_PORT_ATTR_FC4TYPES_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN; +		put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDSPEED, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); + +		put_unaligned_be32(fc_host_supported_speeds(lport->host), +				   &entry->value); + +		/* Current Port Speed */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN; +		put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTPORTSPEED, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		put_unaligned_be32(lport->link_speed, +				   &entry->value); + +		/* Max Frame Size */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN; +		put_unaligned_be16(FC_FDMI_PORT_ATTR_MAXFRAMESIZE, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		put_unaligned_be32(fc_host_maxframe_size(lport->host), +				   &entry->value); + +		/* OS Device Name */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN; +		put_unaligned_be16(FC_FDMI_PORT_ATTR_OSDEVICENAME, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		/* Use the sysfs device name */ +		strncpy((char *)&entry->value, +			dev_name(&lport->host->shost_gendev), +			strnlen(dev_name(&lport->host->shost_gendev), +				FC_FDMI_PORT_ATTR_HOSTNAME_LEN)); + +		/* Host Name */ +		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value + +					FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN); +		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN; +		len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN; +		put_unaligned_be16(FC_FDMI_PORT_ATTR_HOSTNAME, +				   &entry->type); +		put_unaligned_be16(len, &entry->len); +		if (strlen(fc_host_system_hostname(lport->host))) +			strncpy((char *)&entry->value, +				fc_host_system_hostname(lport->host), +				strnlen(fc_host_system_hostname(lport->host), +					FC_FDMI_PORT_ATTR_HOSTNAME_LEN)); +		else +			strncpy((char *)&entry->value, +				init_utsname()->nodename, +				FC_FDMI_PORT_ATTR_HOSTNAME_LEN); +		break; +	case FC_FDMI_DPRT: +		len = sizeof(struct fc_fdmi_dprt); +		ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT, +				    FC_FDMI_SUBTYPE); +		/* Port Name */ +		put_unaligned_be64(lport->wwpn, +				   &ct->payload.dprt.port.portname); +		break; +	case FC_FDMI_DHBA: +		len = sizeof(struct fc_fdmi_dhba); +		ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT, +				    FC_FDMI_SUBTYPE); +		/* HBA Identifier */ +		put_unaligned_be64(lport->wwpn, &ct->payload.dhba.hbaid.id); +		break; +	default: +		return -EINVAL; +	} +	*r_ctl = FC_RCTL_DD_UNSOL_CTL; +	*fh_type = FC_TYPE_CT; +	return 0; +} + +/** + * fc_ct_fill() - Fill in a common transport service request frame + * @lport: local port. + * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries. + * @fp: frame to contain payload. + * @op: CT opcode. + * @r_ctl: pointer to FC header R_CTL. + * @fh_type: pointer to FC-4 type. + */ +static inline int fc_ct_fill(struct fc_lport *lport, +		      u32 fc_id, struct fc_frame *fp, +		      unsigned int op, enum fc_rctl *r_ctl, +		      enum fc_fh_type *fh_type, u32 *did) +{ +	int rc = -EINVAL; + +	switch (fc_id) { +	case FC_FID_MGMT_SERV: +		rc = fc_ct_ms_fill(lport, fc_id, fp, op, r_ctl, fh_type); +		*did = FC_FID_MGMT_SERV; +		break; +	case FC_FID_DIR_SERV: +	default: +		rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type); +		*did = FC_FID_DIR_SERV; +		break; +	} + +	return rc; +} +/**   * fc_plogi_fill - Fill in plogi request frame   */  static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp, diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h index 4ad02041b66..8225d8063ec 100644 --- a/include/scsi/fc_frame.h +++ b/include/scsi/fc_frame.h @@ -78,7 +78,6 @@ struct fc_frame {  };  struct fcoe_rcv_info { -	struct packet_type  *ptype;  	struct fc_lport	*fr_dev;	/* transport layer private pointer */  	struct fc_seq	*fr_seq;	/* for use with exchange manager */  	struct fc_fcp_pkt *fr_fsp;	/* for the corresponding fcp I/O */ diff --git a/include/scsi/fcoe_sysfs.h b/include/scsi/fcoe_sysfs.h new file mode 100644 index 00000000000..7e231487034 --- /dev/null +++ b/include/scsi/fcoe_sysfs.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2011-2012 Intel Corporation.  All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef FCOE_SYSFS +#define FCOE_SYSFS + +#include <linux/if_ether.h> +#include <linux/device.h> +#include <scsi/fc/fc_fcoe.h> + +struct fcoe_ctlr_device; +struct fcoe_fcf_device; + +struct fcoe_sysfs_function_template { +	void (*get_fcoe_ctlr_link_fail)(struct fcoe_ctlr_device *); +	void (*get_fcoe_ctlr_vlink_fail)(struct fcoe_ctlr_device *); +	void (*get_fcoe_ctlr_miss_fka)(struct fcoe_ctlr_device *); +	void (*get_fcoe_ctlr_symb_err)(struct fcoe_ctlr_device *); +	void (*get_fcoe_ctlr_err_block)(struct fcoe_ctlr_device *); +	void (*get_fcoe_ctlr_fcs_error)(struct fcoe_ctlr_device *); +	void (*set_fcoe_ctlr_mode)(struct fcoe_ctlr_device *); +	int  (*set_fcoe_ctlr_enabled)(struct fcoe_ctlr_device *); +	void (*get_fcoe_fcf_selected)(struct fcoe_fcf_device *); +	void (*get_fcoe_fcf_vlan_id)(struct fcoe_fcf_device *); +}; + +#define dev_to_ctlr(d)					\ +	container_of((d), struct fcoe_ctlr_device, dev) + +enum fip_conn_type { +	FIP_CONN_TYPE_UNKNOWN, +	FIP_CONN_TYPE_FABRIC, +	FIP_CONN_TYPE_VN2VN, +}; + +enum ctlr_enabled_state { +	FCOE_CTLR_ENABLED, +	FCOE_CTLR_DISABLED, +	FCOE_CTLR_UNUSED, +}; + +struct fcoe_ctlr_device { +	u32				id; + +	struct device			dev; +	struct fcoe_sysfs_function_template *f; + +	struct list_head		fcfs; +	char				work_q_name[20]; +	struct workqueue_struct		*work_q; +	char				devloss_work_q_name[20]; +	struct workqueue_struct		*devloss_work_q; +	struct mutex			lock; + +	int                             fcf_dev_loss_tmo; +	enum fip_conn_type              mode; + +	enum ctlr_enabled_state         enabled; + +	/* expected in host order for displaying */ +	struct fcoe_fc_els_lesb         lesb; +}; + +static inline void *fcoe_ctlr_device_priv(const struct fcoe_ctlr_device *ctlr) +{ +	return (void *)(ctlr + 1); +} + +/* fcf states */ +enum fcf_state { +	FCOE_FCF_STATE_UNKNOWN, +	FCOE_FCF_STATE_DISCONNECTED, +	FCOE_FCF_STATE_CONNECTED, +	FCOE_FCF_STATE_DELETED, +}; + +struct fcoe_fcf_device { +	u32		    id; +	struct device	    dev; +	struct list_head    peers; +	struct work_struct  delete_work; +	struct delayed_work dev_loss_work; +	u32		    dev_loss_tmo; +	void                *priv; +	enum fcf_state      state; + +	u64                 fabric_name; +	u64                 switch_name; +	u32                 fc_map; +	u16                 vfid; +	u8                  mac[ETH_ALEN]; +	u8                  priority; +	u32                 fka_period; +	u8                  selected; +	u16                 vlan_id; +}; + +#define dev_to_fcf(d)					\ +	container_of((d), struct fcoe_fcf_device, dev) +/* parentage should never be missing */ +#define fcoe_fcf_dev_to_ctlr_dev(x)		\ +	dev_to_ctlr((x)->dev.parent) +#define fcoe_fcf_device_priv(x)			\ +	((x)->priv) + +struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent, +			    struct fcoe_sysfs_function_template *f, +			    int priv_size); +void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *); +struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *, +					    struct fcoe_fcf_device *); +void fcoe_fcf_device_delete(struct fcoe_fcf_device *); + +int __init fcoe_sysfs_setup(void); +void __exit fcoe_sysfs_teardown(void); + +#endif /* FCOE_SYSFS */ diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index a8631acd37c..fd0421c6d40 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -59,6 +59,18 @@ enum iscsi_uevent_e {  	ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST	= UEVENT_BASE + 19,  	ISCSI_UEVENT_PATH_UPDATE	= UEVENT_BASE + 20, +	ISCSI_UEVENT_SET_IFACE_PARAMS	= UEVENT_BASE + 21, +	ISCSI_UEVENT_PING		= UEVENT_BASE + 22, +	ISCSI_UEVENT_GET_CHAP		= UEVENT_BASE + 23, +	ISCSI_UEVENT_DELETE_CHAP	= UEVENT_BASE + 24, +	ISCSI_UEVENT_SET_FLASHNODE_PARAMS	= UEVENT_BASE + 25, +	ISCSI_UEVENT_NEW_FLASHNODE	= UEVENT_BASE + 26, +	ISCSI_UEVENT_DEL_FLASHNODE	= UEVENT_BASE + 27, +	ISCSI_UEVENT_LOGIN_FLASHNODE	= UEVENT_BASE + 28, +	ISCSI_UEVENT_LOGOUT_FLASHNODE	= UEVENT_BASE + 29, +	ISCSI_UEVENT_LOGOUT_FLASHNODE_SID	= UEVENT_BASE + 30, +	ISCSI_UEVENT_SET_CHAP		= UEVENT_BASE + 31, +	ISCSI_UEVENT_GET_HOST_STATS	= UEVENT_BASE + 32,  	/* up events */  	ISCSI_KEVENT_RECV_PDU		= KEVENT_BASE + 1, @@ -70,6 +82,9 @@ enum iscsi_uevent_e {  	ISCSI_KEVENT_PATH_REQ		= KEVENT_BASE + 7,  	ISCSI_KEVENT_IF_DOWN		= KEVENT_BASE + 8, +	ISCSI_KEVENT_CONN_LOGIN_STATE   = KEVENT_BASE + 9, +	ISCSI_KEVENT_HOST_EVENT		= KEVENT_BASE + 10, +	ISCSI_KEVENT_PING_COMP		= KEVENT_BASE + 11,  };  enum iscsi_tgt_dscvr { @@ -78,6 +93,13 @@ enum iscsi_tgt_dscvr {  	ISCSI_TGT_DSCVR_SLP		= 3,  }; +enum iscsi_host_event_code { +	ISCSI_EVENT_LINKUP		= 1, +	ISCSI_EVENT_LINKDOWN, +	/* must always be last */ +	ISCSI_EVENT_MAX, +}; +  struct iscsi_uevent {  	uint32_t type; /* k/u events type */  	uint32_t iferror; /* carries interface or resource errors */ @@ -172,6 +194,58 @@ struct iscsi_uevent {  		struct msg_set_path {  			uint32_t	host_no;  		} set_path; +		struct msg_set_iface_params { +			uint32_t	host_no; +			uint32_t	count; +		} set_iface_params; +		struct msg_iscsi_ping { +			uint32_t        host_no; +			uint32_t        iface_num; +			uint32_t        iface_type; +			uint32_t        payload_size; +			uint32_t	pid;	/* unique ping id associated +						   with each ping request */ +		} iscsi_ping; +		struct msg_get_chap { +			uint32_t	host_no; +			uint32_t	num_entries; /* number of CHAP entries +						      * on request, number of +						      * valid CHAP entries on +						      * response */ +			uint16_t	chap_tbl_idx; +		} get_chap; +		struct msg_delete_chap { +		       uint32_t        host_no; +		       uint16_t        chap_tbl_idx; +		} delete_chap; +		struct msg_set_flashnode_param { +			uint32_t	host_no; +			uint32_t	flashnode_idx; +			uint32_t	count; +		} set_flashnode; +		struct msg_new_flashnode { +			uint32_t	host_no; +			uint32_t	len; +		} new_flashnode; +		struct msg_del_flashnode { +			uint32_t	host_no; +			uint32_t	flashnode_idx; +		} del_flashnode; +		struct msg_login_flashnode { +			uint32_t	host_no; +			uint32_t	flashnode_idx; +		} login_flashnode; +		struct msg_logout_flashnode { +			uint32_t	host_no; +			uint32_t	flashnode_idx; +		} logout_flashnode; +		struct msg_logout_flashnode_sid { +			uint32_t	host_no; +			uint32_t	sid; +		} logout_flashnode_sid; +		struct msg_get_host_stats { +			uint32_t host_no; +		} get_host_stats;  	} u;  	union {  		/* messages k -> u */ @@ -193,6 +267,11 @@ struct iscsi_uevent {  			uint32_t	cid;  			uint64_t	recv_handle;  		} recv_req; +		struct msg_conn_login { +			uint32_t        sid; +			uint32_t        cid; +			uint32_t        state; /* enum iscsi_conn_state */ +		} conn_login;  		struct msg_conn_error {  			uint32_t	sid;  			uint32_t	cid; @@ -211,9 +290,50 @@ struct iscsi_uevent {  		struct msg_notify_if_down {  			uint32_t	host_no;  		} notify_if_down; +		struct msg_host_event { +			uint32_t	host_no; +			uint32_t	data_size; +			enum iscsi_host_event_code code; +		} host_event; +		struct msg_ping_comp { +			uint32_t        host_no; +			uint32_t        status; /* enum +						 * iscsi_ping_status_code */ +			uint32_t	pid;	/* unique ping id associated +						   with each ping request */ +			uint32_t        data_size; +		} ping_comp; +		struct msg_new_flashnode_ret { +			uint32_t	flashnode_idx; +		} new_flashnode_ret;  	} r;  } __attribute__ ((aligned (sizeof(uint64_t)))); +enum iscsi_param_type { +	ISCSI_PARAM,		/* iscsi_param (session, conn, target, LU) */ +	ISCSI_HOST_PARAM,	/* iscsi_host_param */ +	ISCSI_NET_PARAM,	/* iscsi_net_param */ +	ISCSI_FLASHNODE_PARAM,	/* iscsi_flashnode_param */ +	ISCSI_CHAP_PARAM,	/* iscsi_chap_param */ +	ISCSI_IFACE_PARAM,	/* iscsi_iface_param */ +}; + +/* structure for minimalist usecase */ +struct iscsi_param_info { +	uint32_t len;		/* Actual length of the param value */ +	uint16_t param;		/* iscsi param */ +	uint8_t value[0];	/* length sized value follows */ +} __packed; + +struct iscsi_iface_param_info { +	uint32_t iface_num;	/* iface number, 0 - n */ +	uint32_t len;		/* Actual length of the param */ +	uint16_t param;		/* iscsi param value */ +	uint8_t iface_type;	/* IPv4 or IPv6 */ +	uint8_t param_type;	/* iscsi_param_type */ +	uint8_t value[0];	/* length sized value follows */ +} __packed; +  /*   * To keep the struct iscsi_uevent size the same for userspace code   * compatibility, the main structure for ISCSI_UEVENT_PATH_UPDATE and @@ -237,6 +357,149 @@ struct iscsi_path {  	uint16_t	pmtu;  } __attribute__ ((aligned (sizeof(uint64_t)))); +/* iscsi iface enabled/disabled setting */ +#define ISCSI_IFACE_DISABLE	0x01 +#define ISCSI_IFACE_ENABLE	0x02 + +/* ipv4 bootproto */ +#define ISCSI_BOOTPROTO_STATIC		0x01 +#define ISCSI_BOOTPROTO_DHCP		0x02 + +/* ipv6 addr autoconfig type */ +#define ISCSI_IPV6_AUTOCFG_DISABLE		0x01 +#define ISCSI_IPV6_AUTOCFG_ND_ENABLE		0x02 +#define ISCSI_IPV6_AUTOCFG_DHCPV6_ENABLE	0x03 + +/* ipv6 link local addr type */ +#define ISCSI_IPV6_LINKLOCAL_AUTOCFG_ENABLE	0x01 +#define ISCSI_IPV6_LINKLOCAL_AUTOCFG_DISABLE	0x02 + +/* ipv6 router addr type */ +#define ISCSI_IPV6_ROUTER_AUTOCFG_ENABLE	0x01 +#define ISCSI_IPV6_ROUTER_AUTOCFG_DISABLE	0x02 + +#define ISCSI_IFACE_TYPE_IPV4		0x01 +#define ISCSI_IFACE_TYPE_IPV6		0x02 + +#define ISCSI_MAX_VLAN_ID		4095 +#define ISCSI_MAX_VLAN_PRIORITY		7 + +/* iscsi vlan enable/disabled setting */ +#define ISCSI_VLAN_DISABLE	0x01 +#define ISCSI_VLAN_ENABLE	0x02 + +/* iscsi generic enable/disabled setting for various features */ +#define ISCSI_NET_PARAM_DISABLE		0x01 +#define ISCSI_NET_PARAM_ENABLE		0x02 + +/* iSCSI network params */ +enum iscsi_net_param { +	ISCSI_NET_PARAM_IPV4_ADDR		= 1, +	ISCSI_NET_PARAM_IPV4_SUBNET, +	ISCSI_NET_PARAM_IPV4_GW, +	ISCSI_NET_PARAM_IPV4_BOOTPROTO, +	ISCSI_NET_PARAM_MAC, +	ISCSI_NET_PARAM_IPV6_LINKLOCAL, +	ISCSI_NET_PARAM_IPV6_ADDR, +	ISCSI_NET_PARAM_IPV6_ROUTER, +	ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG, +	ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG, +	ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG, +	ISCSI_NET_PARAM_IFACE_ENABLE, +	ISCSI_NET_PARAM_VLAN_ID, +	ISCSI_NET_PARAM_VLAN_PRIORITY, +	ISCSI_NET_PARAM_VLAN_ENABLED, +	ISCSI_NET_PARAM_VLAN_TAG, +	ISCSI_NET_PARAM_IFACE_TYPE, +	ISCSI_NET_PARAM_IFACE_NAME, +	ISCSI_NET_PARAM_MTU, +	ISCSI_NET_PARAM_PORT, +	ISCSI_NET_PARAM_IPADDR_STATE, +	ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE, +	ISCSI_NET_PARAM_IPV6_ROUTER_STATE, +	ISCSI_NET_PARAM_DELAYED_ACK_EN, +	ISCSI_NET_PARAM_TCP_NAGLE_DISABLE, +	ISCSI_NET_PARAM_TCP_WSF_DISABLE, +	ISCSI_NET_PARAM_TCP_WSF, +	ISCSI_NET_PARAM_TCP_TIMER_SCALE, +	ISCSI_NET_PARAM_TCP_TIMESTAMP_EN, +	ISCSI_NET_PARAM_CACHE_ID, +	ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN, +	ISCSI_NET_PARAM_IPV4_TOS_EN, +	ISCSI_NET_PARAM_IPV4_TOS, +	ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID, +	ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID, +	ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN, +	ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE, +	ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN, +	ISCSI_NET_PARAM_IPV4_TTL, +	ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN, +	ISCSI_NET_PARAM_IPV6_MLD_EN, +	ISCSI_NET_PARAM_IPV6_FLOW_LABEL, +	ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS, +	ISCSI_NET_PARAM_IPV6_HOP_LIMIT, +	ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO, +	ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME, +	ISCSI_NET_PARAM_IPV6_ND_STALE_TMO, +	ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT, +	ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU, +	ISCSI_NET_PARAM_REDIRECT_EN, +}; + +enum iscsi_ipaddress_state { +	ISCSI_IPDDRESS_STATE_UNCONFIGURED, +	ISCSI_IPDDRESS_STATE_ACQUIRING, +	ISCSI_IPDDRESS_STATE_TENTATIVE, +	ISCSI_IPDDRESS_STATE_VALID, +	ISCSI_IPDDRESS_STATE_DISABLING, +	ISCSI_IPDDRESS_STATE_INVALID, +	ISCSI_IPDDRESS_STATE_DEPRECATED, +}; + +enum iscsi_router_state { +	ISCSI_ROUTER_STATE_UNKNOWN, +	ISCSI_ROUTER_STATE_ADVERTISED, +	ISCSI_ROUTER_STATE_MANUAL, +	ISCSI_ROUTER_STATE_STALE, +}; + +/* iSCSI specific settings params for iface */ +enum iscsi_iface_param { +	ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO, +	ISCSI_IFACE_PARAM_HDRDGST_EN, +	ISCSI_IFACE_PARAM_DATADGST_EN, +	ISCSI_IFACE_PARAM_IMM_DATA_EN, +	ISCSI_IFACE_PARAM_INITIAL_R2T_EN, +	ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN, +	ISCSI_IFACE_PARAM_PDU_INORDER_EN, +	ISCSI_IFACE_PARAM_ERL, +	ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH, +	ISCSI_IFACE_PARAM_FIRST_BURST, +	ISCSI_IFACE_PARAM_MAX_R2T, +	ISCSI_IFACE_PARAM_MAX_BURST, +	ISCSI_IFACE_PARAM_CHAP_AUTH_EN, +	ISCSI_IFACE_PARAM_BIDI_CHAP_EN, +	ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL, +	ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN, +	ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN, +	ISCSI_IFACE_PARAM_INITIATOR_NAME, +}; + +enum iscsi_conn_state { +	ISCSI_CONN_STATE_FREE, +	ISCSI_CONN_STATE_XPT_WAIT, +	ISCSI_CONN_STATE_IN_LOGIN, +	ISCSI_CONN_STATE_LOGGED_IN, +	ISCSI_CONN_STATE_IN_LOGOUT, +	ISCSI_CONN_STATE_LOGOUT_REQUESTED, +	ISCSI_CONN_STATE_CLEANUP_WAIT, +}; +  /*   * Common error codes   */ @@ -263,6 +526,7 @@ enum iscsi_err {  	ISCSI_ERR_INVALID_HOST		= ISCSI_ERR_BASE + 18,  	ISCSI_ERR_XMIT_FAILED		= ISCSI_ERR_BASE + 19,  	ISCSI_ERR_TCP_CONN_CLOSE	= ISCSI_ERR_BASE + 20, +	ISCSI_ERR_SCSI_EH_SESSION_RST	= ISCSI_ERR_BASE + 21,  };  /* @@ -291,7 +555,7 @@ enum iscsi_param {  	ISCSI_PARAM_PERSISTENT_PORT,  	ISCSI_PARAM_SESS_RECOVERY_TMO, -	/* pased in through bind conn using transport_fd */ +	/* passed in through bind conn using transport_fd */  	ISCSI_PARAM_CONN_PORT,  	ISCSI_PARAM_CONN_ADDRESS, @@ -314,61 +578,172 @@ enum iscsi_param {  	ISCSI_PARAM_TGT_RESET_TMO,  	ISCSI_PARAM_TARGET_ALIAS, + +	ISCSI_PARAM_CHAP_IN_IDX, +	ISCSI_PARAM_CHAP_OUT_IDX, + +	ISCSI_PARAM_BOOT_ROOT, +	ISCSI_PARAM_BOOT_NIC, +	ISCSI_PARAM_BOOT_TARGET, + +	ISCSI_PARAM_AUTO_SND_TGT_DISABLE, +	ISCSI_PARAM_DISCOVERY_SESS, +	ISCSI_PARAM_PORTAL_TYPE, +	ISCSI_PARAM_CHAP_AUTH_EN, +	ISCSI_PARAM_DISCOVERY_LOGOUT_EN, +	ISCSI_PARAM_BIDI_CHAP_EN, +	ISCSI_PARAM_DISCOVERY_AUTH_OPTIONAL, + +	ISCSI_PARAM_DEF_TIME2WAIT, +	ISCSI_PARAM_DEF_TIME2RETAIN, +	ISCSI_PARAM_MAX_SEGMENT_SIZE, +	ISCSI_PARAM_STATSN, +	ISCSI_PARAM_KEEPALIVE_TMO, +	ISCSI_PARAM_LOCAL_PORT, +	ISCSI_PARAM_TSID, +	ISCSI_PARAM_DEF_TASKMGMT_TMO, + +	ISCSI_PARAM_TCP_TIMESTAMP_STAT, +	ISCSI_PARAM_TCP_WSF_DISABLE, +	ISCSI_PARAM_TCP_NAGLE_DISABLE, +	ISCSI_PARAM_TCP_TIMER_SCALE, +	ISCSI_PARAM_TCP_TIMESTAMP_EN, +	ISCSI_PARAM_TCP_XMIT_WSF, +	ISCSI_PARAM_TCP_RECV_WSF, +	ISCSI_PARAM_IP_FRAGMENT_DISABLE, +	ISCSI_PARAM_IPV4_TOS, +	ISCSI_PARAM_IPV6_TC, +	ISCSI_PARAM_IPV6_FLOW_LABEL, +	ISCSI_PARAM_IS_FW_ASSIGNED_IPV6, + +	ISCSI_PARAM_DISCOVERY_PARENT_IDX, +	ISCSI_PARAM_DISCOVERY_PARENT_TYPE, +	ISCSI_PARAM_LOCAL_IPADDR,  	/* must always be last */  	ISCSI_PARAM_MAX,  }; -#define ISCSI_MAX_RECV_DLENGTH		(1ULL << ISCSI_PARAM_MAX_RECV_DLENGTH) -#define ISCSI_MAX_XMIT_DLENGTH		(1ULL << ISCSI_PARAM_MAX_XMIT_DLENGTH) -#define ISCSI_HDRDGST_EN		(1ULL << ISCSI_PARAM_HDRDGST_EN) -#define ISCSI_DATADGST_EN		(1ULL << ISCSI_PARAM_DATADGST_EN) -#define ISCSI_INITIAL_R2T_EN		(1ULL << ISCSI_PARAM_INITIAL_R2T_EN) -#define ISCSI_MAX_R2T			(1ULL << ISCSI_PARAM_MAX_R2T) -#define ISCSI_IMM_DATA_EN		(1ULL << ISCSI_PARAM_IMM_DATA_EN) -#define ISCSI_FIRST_BURST		(1ULL << ISCSI_PARAM_FIRST_BURST) -#define ISCSI_MAX_BURST			(1ULL << ISCSI_PARAM_MAX_BURST) -#define ISCSI_PDU_INORDER_EN		(1ULL << ISCSI_PARAM_PDU_INORDER_EN) -#define ISCSI_DATASEQ_INORDER_EN	(1ULL << ISCSI_PARAM_DATASEQ_INORDER_EN) -#define ISCSI_ERL			(1ULL << ISCSI_PARAM_ERL) -#define ISCSI_IFMARKER_EN		(1ULL << ISCSI_PARAM_IFMARKER_EN) -#define ISCSI_OFMARKER_EN		(1ULL << ISCSI_PARAM_OFMARKER_EN) -#define ISCSI_EXP_STATSN		(1ULL << ISCSI_PARAM_EXP_STATSN) -#define ISCSI_TARGET_NAME		(1ULL << ISCSI_PARAM_TARGET_NAME) -#define ISCSI_TPGT			(1ULL << ISCSI_PARAM_TPGT) -#define ISCSI_PERSISTENT_ADDRESS	(1ULL << ISCSI_PARAM_PERSISTENT_ADDRESS) -#define ISCSI_PERSISTENT_PORT		(1ULL << ISCSI_PARAM_PERSISTENT_PORT) -#define ISCSI_SESS_RECOVERY_TMO		(1ULL << ISCSI_PARAM_SESS_RECOVERY_TMO) -#define ISCSI_CONN_PORT			(1ULL << ISCSI_PARAM_CONN_PORT) -#define ISCSI_CONN_ADDRESS		(1ULL << ISCSI_PARAM_CONN_ADDRESS) -#define ISCSI_USERNAME			(1ULL << ISCSI_PARAM_USERNAME) -#define ISCSI_USERNAME_IN		(1ULL << ISCSI_PARAM_USERNAME_IN) -#define ISCSI_PASSWORD			(1ULL << ISCSI_PARAM_PASSWORD) -#define ISCSI_PASSWORD_IN		(1ULL << ISCSI_PARAM_PASSWORD_IN) -#define ISCSI_FAST_ABORT		(1ULL << ISCSI_PARAM_FAST_ABORT) -#define ISCSI_ABORT_TMO			(1ULL << ISCSI_PARAM_ABORT_TMO) -#define ISCSI_LU_RESET_TMO		(1ULL << ISCSI_PARAM_LU_RESET_TMO) -#define ISCSI_HOST_RESET_TMO		(1ULL << ISCSI_PARAM_HOST_RESET_TMO) -#define ISCSI_PING_TMO			(1ULL << ISCSI_PARAM_PING_TMO) -#define ISCSI_RECV_TMO			(1ULL << ISCSI_PARAM_RECV_TMO) -#define ISCSI_IFACE_NAME		(1ULL << ISCSI_PARAM_IFACE_NAME) -#define ISCSI_ISID			(1ULL << ISCSI_PARAM_ISID) -#define ISCSI_INITIATOR_NAME		(1ULL << ISCSI_PARAM_INITIATOR_NAME) -#define ISCSI_TGT_RESET_TMO		(1ULL << ISCSI_PARAM_TGT_RESET_TMO) -#define ISCSI_TARGET_ALIAS		(1ULL << ISCSI_PARAM_TARGET_ALIAS) -  /* iSCSI HBA params */  enum iscsi_host_param {  	ISCSI_HOST_PARAM_HWADDRESS,  	ISCSI_HOST_PARAM_INITIATOR_NAME,  	ISCSI_HOST_PARAM_NETDEV_NAME,  	ISCSI_HOST_PARAM_IPADDRESS, +	ISCSI_HOST_PARAM_PORT_STATE, +	ISCSI_HOST_PARAM_PORT_SPEED,  	ISCSI_HOST_PARAM_MAX,  }; -#define ISCSI_HOST_HWADDRESS		(1ULL << ISCSI_HOST_PARAM_HWADDRESS) -#define ISCSI_HOST_INITIATOR_NAME	(1ULL << ISCSI_HOST_PARAM_INITIATOR_NAME) -#define ISCSI_HOST_NETDEV_NAME		(1ULL << ISCSI_HOST_PARAM_NETDEV_NAME) -#define ISCSI_HOST_IPADDRESS		(1ULL << ISCSI_HOST_PARAM_IPADDRESS) +/* portal type */ +#define PORTAL_TYPE_IPV4	"ipv4" +#define PORTAL_TYPE_IPV6	"ipv6" + +/* iSCSI Flash Target params */ +enum iscsi_flashnode_param { +	ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6, +	ISCSI_FLASHNODE_PORTAL_TYPE, +	ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE, +	ISCSI_FLASHNODE_DISCOVERY_SESS, +	ISCSI_FLASHNODE_ENTRY_EN, +	ISCSI_FLASHNODE_HDR_DGST_EN, +	ISCSI_FLASHNODE_DATA_DGST_EN, +	ISCSI_FLASHNODE_IMM_DATA_EN, +	ISCSI_FLASHNODE_INITIAL_R2T_EN, +	ISCSI_FLASHNODE_DATASEQ_INORDER, +	ISCSI_FLASHNODE_PDU_INORDER, +	ISCSI_FLASHNODE_CHAP_AUTH_EN, +	ISCSI_FLASHNODE_SNACK_REQ_EN, +	ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN, +	ISCSI_FLASHNODE_BIDI_CHAP_EN, +	/* make authentication for discovery sessions optional */ +	ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL, +	ISCSI_FLASHNODE_ERL, +	ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT, +	ISCSI_FLASHNODE_TCP_NAGLE_DISABLE, +	ISCSI_FLASHNODE_TCP_WSF_DISABLE, +	ISCSI_FLASHNODE_TCP_TIMER_SCALE, +	ISCSI_FLASHNODE_TCP_TIMESTAMP_EN, +	ISCSI_FLASHNODE_IP_FRAG_DISABLE, +	ISCSI_FLASHNODE_MAX_RECV_DLENGTH, +	ISCSI_FLASHNODE_MAX_XMIT_DLENGTH, +	ISCSI_FLASHNODE_FIRST_BURST, +	ISCSI_FLASHNODE_DEF_TIME2WAIT, +	ISCSI_FLASHNODE_DEF_TIME2RETAIN, +	ISCSI_FLASHNODE_MAX_R2T, +	ISCSI_FLASHNODE_KEEPALIVE_TMO, +	ISCSI_FLASHNODE_ISID, +	ISCSI_FLASHNODE_TSID, +	ISCSI_FLASHNODE_PORT, +	ISCSI_FLASHNODE_MAX_BURST, +	ISCSI_FLASHNODE_DEF_TASKMGMT_TMO, +	ISCSI_FLASHNODE_IPADDR, +	ISCSI_FLASHNODE_ALIAS, +	ISCSI_FLASHNODE_REDIRECT_IPADDR, +	ISCSI_FLASHNODE_MAX_SEGMENT_SIZE, +	ISCSI_FLASHNODE_LOCAL_PORT, +	ISCSI_FLASHNODE_IPV4_TOS, +	ISCSI_FLASHNODE_IPV6_TC, +	ISCSI_FLASHNODE_IPV6_FLOW_LABEL, +	ISCSI_FLASHNODE_NAME, +	ISCSI_FLASHNODE_TPGT, +	ISCSI_FLASHNODE_LINK_LOCAL_IPV6, +	ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX, +	ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE, +	ISCSI_FLASHNODE_TCP_XMIT_WSF, +	ISCSI_FLASHNODE_TCP_RECV_WSF, +	ISCSI_FLASHNODE_CHAP_IN_IDX, +	ISCSI_FLASHNODE_CHAP_OUT_IDX, +	ISCSI_FLASHNODE_USERNAME, +	ISCSI_FLASHNODE_USERNAME_IN, +	ISCSI_FLASHNODE_PASSWORD, +	ISCSI_FLASHNODE_PASSWORD_IN, +	ISCSI_FLASHNODE_STATSN, +	ISCSI_FLASHNODE_EXP_STATSN, +	ISCSI_FLASHNODE_IS_BOOT_TGT, + +	ISCSI_FLASHNODE_MAX, +}; + +struct iscsi_flashnode_param_info { +	uint32_t len;		/* Actual length of the param */ +	uint16_t param;		/* iscsi param value */ +	uint8_t value[0];	/* length sized value follows */ +} __packed; + +enum iscsi_discovery_parent_type { +	ISCSI_DISC_PARENT_UNKNOWN	= 0x1, +	ISCSI_DISC_PARENT_SENDTGT	= 0x2, +	ISCSI_DISC_PARENT_ISNS		= 0x3, +}; + +/* iSCSI port Speed */ +enum iscsi_port_speed { +	ISCSI_PORT_SPEED_UNKNOWN	= 0x1, +	ISCSI_PORT_SPEED_10MBPS		= 0x2, +	ISCSI_PORT_SPEED_100MBPS	= 0x4, +	ISCSI_PORT_SPEED_1GBPS		= 0x8, +	ISCSI_PORT_SPEED_10GBPS		= 0x10, +}; + +/* iSCSI port state */ +enum iscsi_port_state { +	ISCSI_PORT_STATE_DOWN		= 0x1, +	ISCSI_PORT_STATE_UP		= 0x2, +}; + +/* iSCSI PING status/error code */ +enum iscsi_ping_status_code { +	ISCSI_PING_SUCCESS			= 0, +	ISCSI_PING_FW_DISABLED			= 0x1, +	ISCSI_PING_IPADDR_INVALID		= 0x2, +	ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID	= 0x3, +	ISCSI_PING_TIMEOUT			= 0x4, +	ISCSI_PING_INVALID_DEST_ADDR		= 0x5, +	ISCSI_PING_OVERSIZE_PACKET		= 0x6, +	ISCSI_PING_ICMP_ERROR			= 0x7, +	ISCSI_PING_MAX_REQ_EXCEEDED		= 0x8, +	ISCSI_PING_NO_ARP_RECEIVED		= 0x9, +};  #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)  #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) @@ -391,6 +766,7 @@ enum iscsi_host_param {  #define CAP_DIGEST_OFFLOAD	0x1000	/* offload hdr and data digests */  #define CAP_PADDING_OFFLOAD	0x2000	/* offload padding insertion, removal,  					 and verification */ +#define CAP_LOGIN_OFFLOAD	0x4000  /* offload session login */  /*   * These flags describes reason of stop_conn() call @@ -451,4 +827,135 @@ struct iscsi_stats {  		__attribute__ ((aligned (sizeof(uint64_t))));  }; +enum chap_type_e { +	CHAP_TYPE_OUT, +	CHAP_TYPE_IN, +}; + +enum iscsi_chap_param { +	ISCSI_CHAP_PARAM_INDEX, +	ISCSI_CHAP_PARAM_CHAP_TYPE, +	ISCSI_CHAP_PARAM_USERNAME, +	ISCSI_CHAP_PARAM_PASSWORD, +	ISCSI_CHAP_PARAM_PASSWORD_LEN +}; + +#define ISCSI_CHAP_AUTH_NAME_MAX_LEN	256 +#define ISCSI_CHAP_AUTH_SECRET_MAX_LEN	256 +struct iscsi_chap_rec { +	uint16_t chap_tbl_idx; +	enum chap_type_e chap_type; +	char username[ISCSI_CHAP_AUTH_NAME_MAX_LEN]; +	uint8_t password[ISCSI_CHAP_AUTH_SECRET_MAX_LEN]; +	uint8_t password_length; +}; + +#define ISCSI_HOST_STATS_CUSTOM_MAX             32 +#define ISCSI_HOST_STATS_CUSTOM_DESC_MAX        64 +struct iscsi_host_stats_custom { +	char desc[ISCSI_HOST_STATS_CUSTOM_DESC_MAX]; +	uint64_t value; +}; + +/* struct iscsi_offload_host_stats: Host statistics, + * Include statistics for MAC, IP, TCP & iSCSI. + */ +struct iscsi_offload_host_stats { +	/* MAC */ +	uint64_t mactx_frames; +	uint64_t mactx_bytes; +	uint64_t mactx_multicast_frames; +	uint64_t mactx_broadcast_frames; +	uint64_t mactx_pause_frames; +	uint64_t mactx_control_frames; +	uint64_t mactx_deferral; +	uint64_t mactx_excess_deferral; +	uint64_t mactx_late_collision; +	uint64_t mactx_abort; +	uint64_t mactx_single_collision; +	uint64_t mactx_multiple_collision; +	uint64_t mactx_collision; +	uint64_t mactx_frames_dropped; +	uint64_t mactx_jumbo_frames; +	uint64_t macrx_frames; +	uint64_t macrx_bytes; +	uint64_t macrx_unknown_control_frames; +	uint64_t macrx_pause_frames; +	uint64_t macrx_control_frames; +	uint64_t macrx_dribble; +	uint64_t macrx_frame_length_error; +	uint64_t macrx_jabber; +	uint64_t macrx_carrier_sense_error; +	uint64_t macrx_frame_discarded; +	uint64_t macrx_frames_dropped; +	uint64_t mac_crc_error; +	uint64_t mac_encoding_error; +	uint64_t macrx_length_error_large; +	uint64_t macrx_length_error_small; +	uint64_t macrx_multicast_frames; +	uint64_t macrx_broadcast_frames; +	/* IP */ +	uint64_t iptx_packets; +	uint64_t iptx_bytes; +	uint64_t iptx_fragments; +	uint64_t iprx_packets; +	uint64_t iprx_bytes; +	uint64_t iprx_fragments; +	uint64_t ip_datagram_reassembly; +	uint64_t ip_invalid_address_error; +	uint64_t ip_error_packets; +	uint64_t ip_fragrx_overlap; +	uint64_t ip_fragrx_outoforder; +	uint64_t ip_datagram_reassembly_timeout; +	uint64_t ipv6tx_packets; +	uint64_t ipv6tx_bytes; +	uint64_t ipv6tx_fragments; +	uint64_t ipv6rx_packets; +	uint64_t ipv6rx_bytes; +	uint64_t ipv6rx_fragments; +	uint64_t ipv6_datagram_reassembly; +	uint64_t ipv6_invalid_address_error; +	uint64_t ipv6_error_packets; +	uint64_t ipv6_fragrx_overlap; +	uint64_t ipv6_fragrx_outoforder; +	uint64_t ipv6_datagram_reassembly_timeout; +	/* TCP */ +	uint64_t tcptx_segments; +	uint64_t tcptx_bytes; +	uint64_t tcprx_segments; +	uint64_t tcprx_byte; +	uint64_t tcp_duplicate_ack_retx; +	uint64_t tcp_retx_timer_expired; +	uint64_t tcprx_duplicate_ack; +	uint64_t tcprx_pure_ackr; +	uint64_t tcptx_delayed_ack; +	uint64_t tcptx_pure_ack; +	uint64_t tcprx_segment_error; +	uint64_t tcprx_segment_outoforder; +	uint64_t tcprx_window_probe; +	uint64_t tcprx_window_update; +	uint64_t tcptx_window_probe_persist; +	/* ECC */ +	uint64_t ecc_error_correction; +	/* iSCSI */ +	uint64_t iscsi_pdu_tx; +	uint64_t iscsi_data_bytes_tx; +	uint64_t iscsi_pdu_rx; +	uint64_t iscsi_data_bytes_rx; +	uint64_t iscsi_io_completed; +	uint64_t iscsi_unexpected_io_rx; +	uint64_t iscsi_format_error; +	uint64_t iscsi_hdr_digest_error; +	uint64_t iscsi_data_digest_error; +	uint64_t iscsi_sequence_error; +	/* +	 * iSCSI Custom Host Statistics support, i.e. Transport could +	 * extend existing host statistics with its own specific statistics +	 * up to ISCSI_HOST_STATS_CUSTOM_MAX +	 */ +	uint32_t custom_length; +	struct iscsi_host_stats_custom custom[0] +		__aligned(sizeof(uint64_t)); +}; +  #endif diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h index dd0a52cea95..c1260d80ef3 100644 --- a/include/scsi/iscsi_proto.h +++ b/include/scsi/iscsi_proto.h @@ -29,10 +29,40 @@  /* default iSCSI listen port for incoming connections */  #define ISCSI_LISTEN_PORT	3260 +/* iSCSI header length */ +#define ISCSI_HDR_LEN		48 + +/* iSCSI CRC32C length */ +#define ISCSI_CRC_LEN		4 +  /* Padding word length */  #define ISCSI_PAD_LEN		4  /* + * Serial Number Arithmetic, 32 bits, RFC1982 + */ + +static inline int iscsi_sna_lt(u32 n1, u32 n2) +{ +	return (s32)(n1 - n2) < 0; +} + +static inline int iscsi_sna_lte(u32 n1, u32 n2) +{ +	return (s32)(n1 - n2) <= 0; +} + +static inline int iscsi_sna_gt(u32 n1, u32 n2) +{ +	return (s32)(n1 - n2) > 0; +} + +static inline int iscsi_sna_gte(u32 n1, u32 n2) +{ +	return (s32)(n1 - n2) >= 0; +} + +/*   * useful common(control and data pathes) macro   */  #define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) @@ -60,7 +90,7 @@ struct iscsi_hdr {  	uint8_t		rsvd2[2];  	uint8_t		hlength;	/* AHSs total length */  	uint8_t		dlength[3];	/* Data length */ -	uint8_t		lun[8]; +	struct scsi_lun	lun;  	itt_t		itt;		/* Initiator Task Tag, opaque for target */  	__be32		ttt;		/* Target Task Tag */  	__be32		statsn; @@ -116,13 +146,13 @@ struct iscsi_ahs_hdr {  #define ISCSI_CDB_SIZE			16  /* iSCSI PDU Header */ -struct iscsi_cmd { +struct iscsi_scsi_req {  	uint8_t opcode;  	uint8_t flags;  	__be16 rsvd2;  	uint8_t hlength;  	uint8_t dlength[3]; -	uint8_t lun[8]; +	struct scsi_lun lun;  	itt_t	 itt;	/* Initiator Task Tag */  	__be32 data_length;  	__be32 cmdsn; @@ -161,7 +191,7 @@ struct iscsi_ecdb_ahdr {  };  /* SCSI Response Header */ -struct iscsi_cmd_rsp { +struct iscsi_scsi_rsp {  	uint8_t opcode;  	uint8_t flags;  	uint8_t response; @@ -198,7 +228,7 @@ struct iscsi_async {  	uint8_t rsvd2[2];  	uint8_t rsvd3;  	uint8_t dlength[3]; -	uint8_t lun[8]; +	struct scsi_lun	lun;  	uint8_t rsvd4[8];  	__be32	statsn;  	__be32	exp_cmdsn; @@ -226,7 +256,7 @@ struct iscsi_nopout {  	__be16	rsvd2;  	uint8_t rsvd3;  	uint8_t dlength[3]; -	uint8_t lun[8]; +	struct scsi_lun	lun;  	itt_t	 itt;	/* Initiator Task Tag */  	__be32	ttt;	/* Target Transfer Tag */  	__be32	cmdsn; @@ -241,7 +271,7 @@ struct iscsi_nopin {  	__be16	rsvd2;  	uint8_t rsvd3;  	uint8_t dlength[3]; -	uint8_t lun[8]; +	struct scsi_lun	lun;  	itt_t	 itt;	/* Initiator Task Tag */  	__be32	ttt;	/* Target Transfer Tag */  	__be32	statsn; @@ -257,7 +287,7 @@ struct iscsi_tm {  	uint8_t rsvd1[2];  	uint8_t hlength;  	uint8_t dlength[3]; -	uint8_t lun[8]; +	struct scsi_lun lun;  	itt_t	 itt;	/* Initiator Task Tag */  	itt_t	 rtt;	/* Reference Task Tag */  	__be32	cmdsn; @@ -315,7 +345,7 @@ struct iscsi_r2t_rsp {  	uint8_t rsvd2[2];  	uint8_t	hlength;  	uint8_t	dlength[3]; -	uint8_t lun[8]; +	struct scsi_lun	lun;  	itt_t	 itt;	/* Initiator Task Tag */  	__be32	ttt;	/* Target Transfer Tag */  	__be32	statsn; @@ -333,7 +363,7 @@ struct iscsi_data {  	uint8_t rsvd2[2];  	uint8_t rsvd3;  	uint8_t dlength[3]; -	uint8_t lun[8]; +	struct scsi_lun lun;  	itt_t	 itt;  	__be32	ttt;  	__be32	rsvd4; @@ -353,7 +383,7 @@ struct iscsi_data_rsp {  	uint8_t cmd_status;  	uint8_t hlength;  	uint8_t dlength[3]; -	uint8_t lun[8]; +	struct scsi_lun	lun;  	itt_t	 itt;  	__be32	ttt;  	__be32	statsn; @@ -406,7 +436,7 @@ struct iscsi_text_rsp {  };  /* Login Header */ -struct iscsi_login { +struct iscsi_login_req {  	uint8_t opcode;  	uint8_t flags;  	uint8_t max_version;	/* Max. version supported */ @@ -427,7 +457,13 @@ struct iscsi_login {  #define ISCSI_FLAG_LOGIN_TRANSIT		0x80  #define ISCSI_FLAG_LOGIN_CONTINUE		0x40  #define ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK	0x0C	/* 2 bits */ +#define ISCSI_FLAG_LOGIN_CURRENT_STAGE1		0x04 +#define ISCSI_FLAG_LOGIN_CURRENT_STAGE2		0x08 +#define ISCSI_FLAG_LOGIN_CURRENT_STAGE3		0x0C  #define ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK	0x03	/* 2 bits */ +#define ISCSI_FLAG_LOGIN_NEXT_STAGE1		0x01 +#define ISCSI_FLAG_LOGIN_NEXT_STAGE2		0x02 +#define ISCSI_FLAG_LOGIN_NEXT_STAGE3		0x03  #define ISCSI_LOGIN_CURRENT_STAGE(flags) \  	((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2) @@ -550,17 +586,25 @@ struct iscsi_logout_rsp {  struct iscsi_snack {  	uint8_t opcode;  	uint8_t flags; -	uint8_t rsvd2[14]; +	uint8_t rsvd2[2]; +	uint8_t hlength; +	uint8_t dlength[3]; +	uint8_t lun[8];  	itt_t	 itt; +	__be32  ttt; +	uint8_t rsvd3[4]; +	__be32  exp_statsn; +	uint8_t rsvd4[8];  	__be32	begrun;  	__be32	runlength; -	__be32	exp_statsn; -	__be32	rsvd3; -	__be32	exp_datasn; -	uint8_t rsvd6[8];  };  /* SNACK PDU flags */ +#define ISCSI_FLAG_SNACK_TYPE_DATA		0 +#define ISCSI_FLAG_SNACK_TYPE_R2T		0 +#define ISCSI_FLAG_SNACK_TYPE_STATUS		1 +#define ISCSI_FLAG_SNACK_TYPE_DATA_ACK		2 +#define ISCSI_FLAG_SNACK_TYPE_RDATA		3  #define ISCSI_FLAG_SNACK_TYPE_MASK	0x0F	/* 4 bits */  /* Reject Message Header */ @@ -617,6 +661,8 @@ struct iscsi_reject {  #define ISCSI_DEF_TIME2WAIT			2 +#define ISCSI_NAME_LEN				224 +  /************************* RFC 3720 End *****************************/  #endif /* ISCSI_PROTO_H */ diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index f986ab7ffe6..52beadf9a29 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -30,11 +30,14 @@  #include <scsi/fc/fc_fcp.h>  #include <scsi/fc/fc_ns.h> +#include <scsi/fc/fc_ms.h>  #include <scsi/fc/fc_els.h>  #include <scsi/fc/fc_gs.h>  #include <scsi/fc_frame.h> +#define	FC_FC4_PROV_SIZE	(FC_TYPE_FCP + 1)	/* size of tables */ +  /*   * libfc error codes   */ @@ -50,6 +53,8 @@   * @LPORT_ST_RPN_ID:   Register port name by ID (RPN_ID) sent   * @LPORT_ST_RFT_ID:   Register Fibre Channel types by ID (RFT_ID) sent   * @LPORT_ST_RFF_ID:   Register FC-4 Features by ID (RFF_ID) sent + * @LPORT_ST_FDMI:     Waiting for mgmt server rport to become ready + * @LPORT_ST_RHBA:   * @LPORT_ST_SCR:      State Change Register (SCR) sent   * @LPORT_ST_READY:    Ready for use   * @LPORT_ST_LOGO:     Local port logout (LOGO) sent @@ -64,6 +69,11 @@ enum fc_lport_state {  	LPORT_ST_RSPN_ID,  	LPORT_ST_RFT_ID,  	LPORT_ST_RFF_ID, +	LPORT_ST_FDMI, +	LPORT_ST_RHBA, +	LPORT_ST_RPA, +	LPORT_ST_DHBA, +	LPORT_ST_DPRT,  	LPORT_ST_SCR,  	LPORT_ST_READY,  	LPORT_ST_LOGO, @@ -156,6 +166,7 @@ struct fc_rport_libfc_priv {  	#define FC_RP_FLAGS_REC_SUPPORTED	(1 << 0)  	#define FC_RP_FLAGS_RETRY		(1 << 1)  	#define FC_RP_STARTED			(1 << 2) +	#define FC_RP_FLAGS_CONF_REQ		(1 << 3)  	unsigned int	           e_d_tov;  	unsigned int	           r_a_tov;  }; @@ -179,6 +190,7 @@ struct fc_rport_libfc_priv {   * @rp_mutex:       The mutex that protects the remote port   * @retry_work:     Handle for retries   * @event_callback: Callback when READY, FAILED or LOGO states complete + * @prli_count:     Count of open PRLI sessions in providers   * @rcu:	    Structure used for freeing in an RCU-safe manner   */  struct fc_rport_priv { @@ -202,11 +214,17 @@ struct fc_rport_priv {  	struct list_head            peers;  	struct work_struct          event_work;  	u32			    supported_classes; +	u16                         prli_count;  	struct rcu_head		    rcu; +	u16			    sp_features; +	u8			    spp_type; +	void			    (*lld_event_callback)(struct fc_lport *, +						      struct fc_rport_priv *, +						      enum fc_rport_event);  };  /** - * struct fcoe_dev_stats - fcoe stats structure + * struct fc_stats - fc stats structure   * @SecondsSinceLastReset: Seconds since the last reset   * @TxFrames:              Number of transmitted frames   * @TxWords:               Number of transmitted words @@ -214,6 +232,9 @@ struct fc_rport_priv {   * @RxWords:               Number of received words   * @ErrorFrames:           Number of received error frames   * @DumpedFrames:          Number of dumped frames + * @FcpPktAllocFails:      Number of fcp packet allocation failures + * @FcpPktAborts:          Number of fcp packet aborts + * @FcpFrameAllocFails:    Number of fcp frame allocation failures   * @LinkFailureCount:      Number of link failures   * @LossOfSignalCount:     Number for signal losses   * @InvalidTxWordCount:    Number of invalid transmitted words @@ -221,12 +242,12 @@ struct fc_rport_priv {   * @InputRequests:         Number of input requests   * @OutputRequests:        Number of output requests   * @ControlRequests:       Number of control requests - * @InputMegabytes:        Number of received megabytes - * @OutputMegabytes:       Number of transmitted megabytes + * @InputBytes:            Number of received bytes + * @OutputBytes:           Number of transmitted bytes   * @VLinkFailureCount:     Number of virtual link failures   * @MissDiscAdvCount:      Number of missing FIP discovery advertisement   */ -struct fcoe_dev_stats { +struct fc_stats {  	u64		SecondsSinceLastReset;  	u64		TxFrames;  	u64		TxWords; @@ -234,6 +255,9 @@ struct fcoe_dev_stats {  	u64		RxWords;  	u64		ErrorFrames;  	u64		DumpedFrames; +	u64		FcpPktAllocFails; +	u64		FcpPktAborts; +	u64		FcpFrameAllocFails;  	u64		LinkFailureCount;  	u64		LossOfSignalCount;  	u64		InvalidTxWordCount; @@ -241,8 +265,8 @@ struct fcoe_dev_stats {  	u64		InputRequests;  	u64		OutputRequests;  	u64		ControlRequests; -	u64		InputMegabytes; -	u64		OutputMegabytes; +	u64		InputBytes; +	u64		OutputBytes;  	u64		VLinkFailureCount;  	u64		MissDiscAdvCount;  }; @@ -250,7 +274,7 @@ struct fcoe_dev_stats {  /**   * struct fc_seq_els_data - ELS data used for passing ELS specific responses   * @reason: The reason for rejection - * @explan: The explaination of the rejection + * @explan: The explanation of the rejection   *   * Mainly used by the exchange manager layer.   */ @@ -263,7 +287,6 @@ struct fc_seq_els_data {   * struct fc_fcp_pkt - FCP request structure (one for each scsi_cmnd request)   * @lp:              The associated local port   * @state:           The state of the I/O - * @tgt_flags:       Target's flags   * @ref_cnt:         Reference count   * @scsi_pkt_lock:   Lock to protect the SCSI packet (must be taken before the   *                   host_lock if both are to be held at the same time) @@ -272,9 +295,6 @@ struct fc_seq_els_data {   * @timer:           The command timer   * @tm_done:         Completion indicator   * @wait_for_comp:   Indicator to wait for completion of the I/O (in jiffies) - * @start_time:      Timestamp indicating the start of the I/O (in jiffies) - * @end_time:        Timestamp indicating the end of the I/O (in jiffies) - * @last_pkt_time:   Timestamp of the last frame received (in jiffies)   * @data_len:        The length of the data   * @cdb_cmd:         The CDB command   * @xfer_len:        The transfer length @@ -295,51 +315,46 @@ struct fc_seq_els_data {   * @recov_seq:       The sequence for REC or SRR   */  struct fc_fcp_pkt { -	/* Housekeeping information */ -	struct fc_lport   *lp; -	u16		  state; -	u16		  tgt_flags; -	atomic_t	  ref_cnt;  	spinlock_t	  scsi_pkt_lock; +	atomic_t	  ref_cnt; + +	/* SCSI command and data transfer information */ +	u32		  data_len;  	/* SCSI I/O related information */  	struct scsi_cmnd  *cmd;  	struct list_head  list; -	/* Timeout related information */ -	struct timer_list timer; -	struct completion tm_done; -	int	          wait_for_comp; -	unsigned long	  start_time; -	unsigned long	  end_time; -	unsigned long	  last_pkt_time; - -	/* SCSI command and data transfer information */ -	u32		  data_len; - -	/* Transport related veriables */ -	struct fcp_cmnd   cdb_cmd; -	size_t		  xfer_len; -	u16		  xfer_ddp; -	u32		  xfer_contig_end; -	u16		  max_payload; +	/* Housekeeping information */ +	struct fc_lport   *lp; +	u8		  state;  	/* SCSI/FCP return status */ -	u32		  io_status;  	u8		  cdb_status;  	u8		  status_code;  	u8		  scsi_comp_flags; +	u32		  io_status;  	u32		  req_flags;  	u32		  scsi_resid; +	/* Transport related veriables */ +	size_t		  xfer_len; +	struct fcp_cmnd   cdb_cmd; +	u32		  xfer_contig_end; +	u16		  max_payload; +	u16		  xfer_ddp; +  	/* Associated structures */  	struct fc_rport	  *rport;  	struct fc_seq	  *seq_ptr; -	/* Error Processing information */ -	u8		  recov_retry; +	/* Timeout/error related information */ +	struct timer_list timer; +	int	          wait_for_comp; +	u32		  recov_retry;  	struct fc_seq	  *recov_seq; -}; +	struct completion tm_done; +} ____cacheline_aligned_in_smp;  /*   * Structure and function definitions for managing Fibre Channel Exchanges @@ -395,6 +410,12 @@ struct fc_seq {   * @fh_type:      The frame type   * @class:        The class of service   * @seq:          The sequence in use on this exchange + * @resp_active:  Number of tasks that are concurrently executing @resp(). + * @resp_task:    If @resp_active > 0, either the task executing @resp(), the + *                task that has been interrupted to execute the soft-IRQ + *                executing @resp() or NULL if more than one task is executing + *                @resp concurrently. + * @resp_wq:      Waitqueue for the tasks waiting on @resp_active.   * @resp:         Callback for responses on this exchange   * @destructor:   Called when destroying the exchange   * @arg:          Passed as a void pointer to the resp() callback @@ -405,35 +426,35 @@ struct fc_seq {   *	sequence allocation   */  struct fc_exch { +	spinlock_t	    ex_lock; +	atomic_t	    ex_refcnt; +	enum fc_class	    class;  	struct fc_exch_mgr  *em;  	struct fc_exch_pool *pool; -	u32		    state; -	u16		    xid;  	struct list_head    ex_list; -	spinlock_t	    ex_lock; -	atomic_t	    ex_refcnt; -	struct delayed_work timeout_work;  	struct fc_lport	    *lp; +	u32		    esb_stat; +	u8		    state; +	u8		    fh_type; +	u8		    seq_id; +	u8		    encaps; +	u16		    xid;  	u16		    oxid;  	u16		    rxid;  	u32		    oid;  	u32		    sid;  	u32		    did; -	u32		    esb_stat;  	u32		    r_a_tov; -	u8		    seq_id; -	u8		    encaps;  	u32		    f_ctl; -	u8		    fh_type; -	enum fc_class	    class; -	struct fc_seq	    seq; - +	struct fc_seq       seq; +	int		    resp_active; +	struct task_struct  *resp_task; +	wait_queue_head_t   resp_wq;  	void		    (*resp)(struct fc_seq *, struct fc_frame *, void *);  	void		    *arg; -  	void		    (*destructor)(struct fc_seq *, void *); - -}; +	struct delayed_work timeout_work; +} ____cacheline_aligned_in_smp;  #define	fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) @@ -503,6 +524,14 @@ struct libfc_function_template {  	 */  	int (*ddp_done)(struct fc_lport *, u16);  	/* +	 * Sets up the DDP context for a given exchange id on the given +	 * scatterlist if LLD supports DDP for target. +	 * +	 * STATUS: OPTIONAL +	 */ +	int (*ddp_target)(struct fc_lport *, u16, struct scatterlist *, +			  unsigned int); +	/*  	 * Allow LLD to fill its own Link Error Status Block  	 *  	 * STATUS: OPTIONAL @@ -517,7 +546,7 @@ struct libfc_function_template {  			struct fc_frame *);  	/* -	 * Send an ELS response using infomation from the received frame. +	 * Send an ELS response using information from the received frame.  	 *  	 * STATUS: OPTIONAL  	 */ @@ -553,6 +582,16 @@ struct libfc_function_template {  	struct fc_seq *(*seq_start_next)(struct fc_seq *);  	/* +	 * Set a response handler for the exchange of the sequence. +	 * +	 * STATUS: OPTIONAL +	 */ +	void (*seq_set_resp)(struct fc_seq *sp, +			     void (*resp)(struct fc_seq *, struct fc_frame *, +					  void *), +			     void *arg); + +	/*  	 * Assign a sequence for an incoming request frame.  	 *  	 * STATUS: OPTIONAL @@ -560,6 +599,13 @@ struct libfc_function_template {  	struct fc_seq *(*seq_assign)(struct fc_lport *, struct fc_frame *);  	/* +	 * Release the reference on the sequence returned by seq_assign(). +	 * +	 * STATUS: OPTIONAL +	 */ +	void (*seq_release)(struct fc_seq *); + +	/*  	 * Reset an exchange manager, completing all sequences and exchanges.  	 * If s_id is non-zero, reset only exchanges originating from that FID.  	 * If d_id is non-zero, reset only exchanges sending to that FID. @@ -638,7 +684,7 @@ struct libfc_function_template {  	int (*rport_logoff)(struct fc_rport_priv *);  	/* -	 * Recieve a request from a remote port. +	 * Receive a request from a remote port.  	 *  	 * STATUS: OPTIONAL  	 */ @@ -658,6 +704,15 @@ struct libfc_function_template {  	void (*rport_destroy)(struct kref *);  	/* +	 * Callback routine after the remote port is logged in +	 * +	 * STATUS: OPTIONAL +	 */ +	void (*rport_event_callback)(struct fc_lport *, +				     struct fc_rport_priv *, +				     enum fc_rport_event); + +	/*  	 * Send a fcp cmd from fsp pkt.  	 * Called with the SCSI host lock unlocked and irqs disabled.  	 * @@ -670,7 +725,7 @@ struct libfc_function_template {  					 void *));  	/* -	 * Cleanup the FCP layer, used durring link down and reset +	 * Cleanup the FCP layer, used during link down and reset  	 *  	 * STATUS: OPTIONAL  	 */ @@ -751,11 +806,21 @@ struct fc_disc {  			      enum fc_disc_event);  }; +/* + * Local port notifier and events. + */ +extern struct blocking_notifier_head fc_lport_notifier_head; +enum fc_lport_event { +	FC_LPORT_EV_ADD, +	FC_LPORT_EV_DEL, +}; +  /**   * struct fc_lport - Local port   * @host:                  The SCSI host associated with a local port   * @ema_list:              Exchange manager anchor list   * @dns_rdata:             The directory server remote port + * @ms_rdata:		   The management server remote port   * @ptp_rdata:             Point to point remote port   * @scsi_priv:             FCP layer internal data   * @disc:                  Discovery context @@ -767,8 +832,7 @@ struct fc_disc {   * @state:                 Identifies the state   * @boot_time:             Timestamp indicating when the local port came online   * @host_stats:            SCSI host statistics - * @dev_stats:             FCoE device stats (TODO: libfc should not be - *                         FCoE aware) + * @stats:                 FC local port stats (TODO separate libfc LLD stats)   * @retry_count:           Number of retries in the current state   * @port_id:               FC Port ID   * @wwpn:                  World Wide Port Name @@ -791,14 +855,17 @@ struct fc_disc {   * @lso_max:               The maximum large offload send size   * @fcts:                  FC-4 type mask   * @lp_mutex:              Mutex to protect the local port - * @list:                  Handle for list of local ports + * @list:                  Linkage on list of vport peers   * @retry_work:            Handle to local port for delayed retry context + * @prov:		   Pointers available for use by passive FC-4 providers + * @lport_list:            Linkage on module-wide list of local ports   */  struct fc_lport {  	/* Associations */  	struct Scsi_Host	       *host;  	struct list_head	       ema_list;  	struct fc_rport_priv	       *dns_rdata; +	struct fc_rport_priv	       *ms_rdata;  	struct fc_rport_priv	       *ptp_rdata;  	void			       *scsi_priv;  	struct fc_disc                 disc; @@ -814,7 +881,7 @@ struct fc_lport {  	enum fc_lport_state	       state;  	unsigned long		       boot_time;  	struct fc_host_statistics      host_stats; -	struct fcoe_dev_stats	       *dev_stats; +	struct fc_stats	__percpu       *stats;  	u8			       retry_count;  	/* Fabric information */ @@ -834,6 +901,7 @@ struct fc_lport {  	u32			       does_npiv:1;  	u32			       npiv_enabled:1;  	u32			       point_to_multipoint:1; +	u32			       fdmi_enabled:1;  	u32			       mfs;  	u8			       max_retry_count;  	u8			       max_rport_retry_count; @@ -848,8 +916,32 @@ struct fc_lport {  	struct mutex                   lp_mutex;  	struct list_head               list;  	struct delayed_work	       retry_work; +	void			       *prov[FC_FC4_PROV_SIZE]; +	struct list_head               lport_list;  }; +/** + * struct fc4_prov - FC-4 provider registration + * @prli:               Handler for incoming PRLI + * @prlo:               Handler for session reset + * @recv:		Handler for incoming request + * @module:		Pointer to module.  May be NULL. + */ +struct fc4_prov { +	int (*prli)(struct fc_rport_priv *, u32 spp_len, +		    const struct fc_els_spp *spp_in, +		    struct fc_els_spp *spp_out); +	void (*prlo)(struct fc_rport_priv *); +	void (*recv)(struct fc_lport *, struct fc_frame *); +	struct module *module; +}; + +/* + * Register FC-4 provider with libfc. + */ +int fc_fc4_register_provider(enum fc_fh_type type, struct fc4_prov *); +void fc_fc4_deregister_provider(enum fc_fh_type type, struct fc4_prov *); +  /*   * FC_LPORT HELPER FUNCTIONS   *****************************/ @@ -902,8 +994,8 @@ static inline void fc_lport_state_enter(struct fc_lport *lport,   */  static inline int fc_lport_init_stats(struct fc_lport *lport)  { -	lport->dev_stats = alloc_percpu(struct fcoe_dev_stats); -	if (!lport->dev_stats) +	lport->stats = alloc_percpu(struct fc_stats); +	if (!lport->stats)  		return -ENOMEM;  	return 0;  } @@ -914,7 +1006,7 @@ static inline int fc_lport_init_stats(struct fc_lport *lport)   */  static inline void fc_lport_free_stats(struct fc_lport *lport)  { -	free_percpu(lport->dev_stats); +	free_percpu(lport->stats);  }  /** @@ -980,6 +1072,7 @@ struct fc_lport *libfc_vport_create(struct fc_vport *, int privsize);  struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id);  int fc_lport_bsg_request(struct fc_bsg_job *);  void fc_lport_set_local_id(struct fc_lport *, u32 port_id); +void fc_lport_iterate(void (*func)(struct fc_lport *, void *), void *);  /*   * REMOTE PORT LAYER @@ -990,7 +1083,8 @@ void fc_rport_terminate_io(struct fc_rport *);  /*   * DISCOVERY LAYER   *****************************/ -int fc_disc_init(struct fc_lport *); +void fc_disc_init(struct fc_lport *); +void fc_disc_config(struct fc_lport *, void *);  static inline struct fc_lport *fc_disc_lport(struct fc_disc *disc)  { @@ -1006,8 +1100,7 @@ void fc_fcp_destroy(struct fc_lport *);  /*   * SCSI INTERACTION LAYER   *****************************/ -int fc_queuecommand(struct scsi_cmnd *, -		    void (*done)(struct scsi_cmnd *)); +int fc_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);  int fc_eh_abort(struct scsi_cmnd *);  int fc_eh_device_reset(struct scsi_cmnd *);  int fc_eh_host_reset(struct scsi_cmnd *); @@ -1038,6 +1131,7 @@ void fc_fill_hdr(struct fc_frame *, const struct fc_frame *,   * EXCHANGE MANAGER LAYER   *****************************/  int fc_exch_init(struct fc_lport *); +void fc_exch_update_stats(struct fc_lport *lport);  struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *,  					   struct fc_exch_mgr *,  					   bool (*match)(struct fc_frame *)); diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 06f1b5a8ed1..de7e3ee60f0 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -29,10 +29,17 @@  #include <linux/random.h>  #include <scsi/fc/fc_fcoe.h>  #include <scsi/libfc.h> +#include <scsi/fcoe_sysfs.h>  #define FCOE_MAX_CMD_LEN	16	/* Supported CDB length */  /* + * Max MTU for FCoE: 14 (FCoE header) + 24 (FC header) + 2112 (max FC payload) + * + 4 (FC CRC) + 4 (FCoE trailer) =  2158 bytes + */ +#define FCOE_MTU	2158 + +/*   * FIP tunable parameters.   */  #define FCOE_CTLR_START_DELAY	2000	/* mS after first adv. to choose FCF */ @@ -83,6 +90,7 @@ enum fip_state {   * @lp:		   &fc_lport: libfc local port.   * @sel_fcf:	   currently selected FCF, or NULL.   * @fcfs:	   list of discovered FCFs. + * @cdev:          (Optional) pointer to sysfs fcoe_ctlr_device.   * @fcf_count:	   number of discovered FCF entries.   * @sol_time:	   time when a multicast solicitation was last sent.   * @sel_time:	   time after which to select an FCF. @@ -92,10 +100,12 @@ enum fip_state {   * @timer_work:	   &work_struct for doing keep-alives and resets.   * @recv_work:	   &work_struct for receiving FIP frames.   * @fip_recv_list: list of received FIP frames. + * @flogi_req:	   clone of FLOGI request sent   * @rnd_state:	   state for pseudo-random number generator.   * @port_id:	   proposed or selected local-port ID.   * @user_mfs:	   configured maximum FC frame size, including FC header.   * @flogi_oxid:    exchange ID of most recent fabric login. + * @flogi_req_send: send of FLOGI requested   * @flogi_count:   number of FLOGI attempts in AUTO mode.   * @map_dest:	   use the FC_MAP mode for destination MAC addresses.   * @spma:	   supports SPMA server-provided MACs mode @@ -106,6 +116,7 @@ enum fip_state {   * @update_mac:    LLD-supplied function to handle changes to MAC addresses.   * @get_src_addr:  LLD-supplied function to supply a source MAC address.   * @ctlr_mutex:	   lock protecting this structure. + * @ctlr_lock:     spinlock covering flogi_req   *   * This structure is used by all FCoE drivers.  It contains information   * needed by all FCoE low-level drivers (LLDs) as well as internal state @@ -117,6 +128,7 @@ struct fcoe_ctlr {  	struct fc_lport *lp;  	struct fcoe_fcf *sel_fcf;  	struct list_head fcfs; +	struct fcoe_ctlr_device *cdev;  	u16 fcf_count;  	unsigned long sol_time;  	unsigned long sel_time; @@ -126,16 +138,19 @@ struct fcoe_ctlr {  	struct work_struct timer_work;  	struct work_struct recv_work;  	struct sk_buff_head fip_recv_list; +	struct sk_buff *flogi_req;  	struct rnd_state rnd_state;  	u32 port_id;  	u16 user_mfs;  	u16 flogi_oxid; +	u8 flogi_req_send;  	u8 flogi_count;  	u8 map_dest;  	u8 spma;  	u8 probe_tries; +	u8 priority;  	u8 dest_addr[ETH_ALEN];  	u8 ctl_src_addr[ETH_ALEN]; @@ -143,18 +158,40 @@ struct fcoe_ctlr {  	void (*update_mac)(struct fc_lport *, u8 *addr);  	u8 * (*get_src_addr)(struct fc_lport *);  	struct mutex ctlr_mutex; +	spinlock_t ctlr_lock;  };  /** + * fcoe_ctlr_priv() - Return the private data from a fcoe_ctlr + * @cltr: The fcoe_ctlr whose private data will be returned + */ +static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr) +{ +	return (void *)(ctlr + 1); +} + +/* + * This assumes that the fcoe_ctlr (x) is allocated with the fcoe_ctlr_device. + */ +#define fcoe_ctlr_to_ctlr_dev(x)					\ +	(x)->cdev + +/**   * struct fcoe_fcf - Fibre-Channel Forwarder   * @list:	 list linkage + * @event_work:  Work for FC Transport actions queue + * @event:       The event to be processed + * @fip:         The controller that the FCF was discovered on + * @fcf_dev:     The associated fcoe_fcf_device instance   * @time:	 system time (jiffies) when an advertisement was last received   * @switch_name: WWN of switch from advertisement   * @fabric_name: WWN of fabric from advertisement   * @fc_map:	 FC_MAP value from advertisement - * @fcf_mac:	 Ethernet address of the FCF + * @fcf_mac:	 Ethernet address of the FCF for FIP traffic + * @fcoe_mac:	 Ethernet address of the FCF for FCoE traffic   * @vfid:	 virtual fabric ID   * @pri:	 selection priority, smaller values are better + * @flogi_sent:	 current FLOGI sent to this FCF   * @flags:	 flags received from advertisement   * @fka_period:	 keep-alive period, in jiffies   * @@ -167,6 +204,9 @@ struct fcoe_ctlr {   */  struct fcoe_fcf {  	struct list_head list; +	struct work_struct event_work; +	struct fcoe_ctlr *fip; +	struct fcoe_fcf_device *fcf_dev;  	unsigned long time;  	u64 switch_name; @@ -174,13 +214,18 @@ struct fcoe_fcf {  	u32 fc_map;  	u16 vfid;  	u8 fcf_mac[ETH_ALEN]; +	u8 fcoe_mac[ETH_ALEN];  	u8 pri; +	u8 flogi_sent;  	u16 flags;  	u32 fka_period;  	u8 fd_flags:1;  }; +#define fcoe_fcf_to_fcf_dev(x)			\ +	((x)->fcf_dev) +  /**   * struct fcoe_rport - VN2VN remote port   * @time:	time of create or last beacon packet received from node @@ -213,6 +258,16 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *,  u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);  int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *,  		      const struct libfc_function_template *, int init_fcp); +u32 fcoe_fc_crc(struct fc_frame *fp); +int fcoe_start_io(struct sk_buff *skb); +int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type); +void __fcoe_get_lesb(struct fc_lport *lport, struct fc_els_lesb *fc_lesb, +		     struct net_device *netdev); +void fcoe_wwn_to_str(u64 wwn, char *buf, int len); +int fcoe_validate_vport_create(struct fc_vport *vport); +int fcoe_link_speed_update(struct fc_lport *); +void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *); +void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev);  /**   * is_fip_mode() - returns true if FIP mode selected. @@ -223,5 +278,131 @@ static inline bool is_fip_mode(struct fcoe_ctlr *fip)  	return fip->state == FIP_ST_ENABLED;  } +/* helper for FCoE SW HBA drivers, can include subven and subdev if needed. The + * modpost would use pci_device_id table to auto-generate formatted module alias + * into the corresponding .mod.c file, but there may or may not be a pci device + * id table for FCoE drivers so we use the following helper for build the fcoe + * driver module alias. + */ +#define MODULE_ALIAS_FCOE_PCI(ven, dev) \ +	MODULE_ALIAS("fcoe-pci:"	\ +		"v" __stringify(ven)	\ +		"d" __stringify(dev) "sv*sd*bc*sc*i*") + +/* the name of the default FCoE transport driver fcoe.ko */ +#define FCOE_TRANSPORT_DEFAULT	"fcoe" + +/* struct fcoe_transport - The FCoE transport interface + * @name:	a vendor specific name for their FCoE transport driver + * @attached:	whether this transport is already attached + * @list:	list linkage to all attached transports + * @match:	handler to allow the transport driver to match up a given netdev + * @alloc:      handler to allocate per-instance FCoE structures + *		(no discovery or login) + * @create:	handler to sysfs entry of create for FCoE instances + * @destroy:    handler to delete per-instance FCoE structures + *		(frees all memory) + * @enable:	handler to sysfs entry of enable for FCoE instances + * @disable:	handler to sysfs entry of disable for FCoE instances + */ +struct fcoe_transport { +	char name[IFNAMSIZ]; +	bool attached; +	struct list_head list; +	bool (*match) (struct net_device *device); +	int (*alloc) (struct net_device *device); +	int (*create) (struct net_device *device, enum fip_state fip_mode); +	int (*destroy) (struct net_device *device); +	int (*enable) (struct net_device *device); +	int (*disable) (struct net_device *device); +}; + +/** + * struct fcoe_percpu_s - The context for FCoE receive thread(s) + * @thread:	    The thread context + * @fcoe_rx_list:   The queue of pending packets to process + * @page:	    The memory page for calculating frame trailer CRCs + * @crc_eof_offset: The offset into the CRC page pointing to available + *		    memory for a new trailer + */ +struct fcoe_percpu_s { +	struct task_struct *thread; +	struct sk_buff_head fcoe_rx_list; +	struct page *crc_eof_page; +	int crc_eof_offset; +}; + +/** + * struct fcoe_port - The FCoE private structure + * @priv:		       The associated fcoe interface. The structure is + *			       defined by the low level driver + * @lport:		       The associated local port + * @fcoe_pending_queue:	       The pending Rx queue of skbs + * @fcoe_pending_queue_active: Indicates if the pending queue is active + * @max_queue_depth:	       Max queue depth of pending queue + * @min_queue_depth:	       Min queue depth of pending queue + * @timer:		       The queue timer + * @destroy_work:	       Handle for work context + *			       (to prevent RTNL deadlocks) + * @data_srt_addr:	       Source address for data + * + * An instance of this structure is to be allocated along with the + * Scsi_Host and libfc fc_lport structures. + */ +struct fcoe_port { +	void		      *priv; +	struct fc_lport	      *lport; +	struct sk_buff_head   fcoe_pending_queue; +	u8		      fcoe_pending_queue_active; +	u32		      max_queue_depth; +	u32		      min_queue_depth; +	struct timer_list     timer; +	struct work_struct    destroy_work; +	u8		      data_src_addr[ETH_ALEN]; +	struct net_device * (*get_netdev)(const struct fc_lport *lport); +}; + +/** + * fcoe_get_netdev() - Return the net device associated with a local port + * @lport: The local port to get the net device from + */ +static inline struct net_device *fcoe_get_netdev(const struct fc_lport *lport) +{ +	struct fcoe_port *port = ((struct fcoe_port *)lport_priv(lport)); + +	return (port->get_netdev) ? port->get_netdev(lport) : NULL; +} + +void fcoe_clean_pending_queue(struct fc_lport *); +void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb); +void fcoe_queue_timer(ulong lport); +int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen, +			   struct fcoe_percpu_s *fps); + +/* FCoE Sysfs helpers */ +void fcoe_fcf_get_selected(struct fcoe_fcf_device *); +void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *); + +/** + * struct netdev_list + * A mapping from netdevice to fcoe_transport + */ +struct fcoe_netdev_mapping { +	struct list_head list; +	struct net_device *netdev; +	struct fcoe_transport *ft; +}; + +/* fcoe transports registration and deregistration */ +int fcoe_transport_attach(struct fcoe_transport *ft); +int fcoe_transport_detach(struct fcoe_transport *ft); + +/* sysfs store handler for ctrl_control interface */ +ssize_t fcoe_ctlr_create_store(struct bus_type *bus, +			       const char *buf, size_t count); +ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus, +				const char *buf, size_t count);  #endif /* _LIBFCOE_H */ + + diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index ae5196aae1a..728c9ad9feb 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -62,6 +62,8 @@ enum {  	TMF_NOT_FOUND,  }; +#define ISID_SIZE			6 +  /* Connection suspend "bit" */  #define ISCSI_SUSPEND_BIT		1 @@ -89,6 +91,7 @@ enum {  	ISCSI_TASK_RUNNING,  	ISCSI_TASK_ABRT_TMF,		/* aborted due to TMF */  	ISCSI_TASK_ABRT_SESS_RECOV,	/* aborted due to session recovery */ +	ISCSI_TASK_REQUEUE_SCSIQ,	/* qcmd requeueing to scsi-ml */  };  struct iscsi_r2t_info { @@ -114,7 +117,7 @@ struct iscsi_task {  	/* copied values in case we need to send tmfs */  	itt_t			hdr_itt;  	__be32			cmdsn; -	uint8_t			lun[8]; +	struct scsi_lun		lun;  	int			itt;		/* this ITT */ @@ -130,6 +133,10 @@ struct iscsi_task {  	unsigned long		last_xfer;  	unsigned long		last_timeout;  	bool			have_checked_conn; + +	/* T10 protection information */ +	bool			protected; +  	/* state set/tested under session->lock */  	int			state;  	atomic_t		refcount; @@ -172,6 +179,7 @@ struct iscsi_conn {  	/* iSCSI connection-wide sequencing */  	uint32_t		exp_statsn; +	uint32_t		statsn;  	/* control data */  	int			id;		/* CID */ @@ -211,9 +219,23 @@ struct iscsi_conn {  	/* values userspace uses to id a conn */  	int			persistent_port;  	char			*persistent_address; -	/* remote portal currently connected to */ -	int			portal_port; -	char			portal_address[ISCSI_ADDRESS_BUF_LEN]; + +	unsigned		max_segment_size; +	unsigned		tcp_xmit_wsf; +	unsigned		tcp_recv_wsf; +	uint16_t		keepalive_tmo; +	uint16_t		local_port; +	uint8_t			tcp_timestamp_stat; +	uint8_t			tcp_nagle_disable; +	uint8_t			tcp_wsf_disable; +	uint8_t			tcp_timer_scale; +	uint8_t			tcp_timestamp_en; +	uint8_t			fragment_disable; +	uint8_t			ipv4_tos; +	uint8_t			ipv6_traffic_class; +	uint8_t			ipv6_flow_label; +	uint8_t			is_fw_assigned_ipv6; +	char			*local_ipaddr;  	/* MIB-statistics */  	uint64_t		txdata_octets; @@ -270,7 +292,7 @@ struct iscsi_session {  	int			lu_reset_timeout;  	int			tgt_reset_timeout;  	int			initial_r2t_en; -	unsigned		max_r2t; +	unsigned short		max_r2t;  	int			imm_data_en;  	unsigned		first_burst;  	unsigned		max_burst; @@ -286,18 +308,42 @@ struct iscsi_session {  	char			*password;  	char			*password_in;  	char			*targetname; +	char			*targetalias;  	char			*ifacename;  	char			*initiatorname; +	char			*boot_root; +	char			*boot_nic; +	char			*boot_target; +	char			*portal_type; +	char			*discovery_parent_type; +	uint16_t		discovery_parent_idx; +	uint16_t		def_taskmgmt_tmo; +	uint16_t		tsid; +	uint8_t			auto_snd_tgt_disable; +	uint8_t			discovery_sess; +	uint8_t			chap_auth_en; +	uint8_t			discovery_logout_en; +	uint8_t			bidi_chap_en; +	uint8_t			discovery_auth_optional; +	uint8_t			isid[ISID_SIZE]; +  	/* control data */  	struct iscsi_transport	*tt;  	struct Scsi_Host	*host;  	struct iscsi_conn	*leadconn;	/* leading connection */ -	spinlock_t		lock;		/* protects session state, * -						 * sequence numbers,       * +	/* Between the forward and the backward locks exists a strict locking +	 * hierarchy. The mutual exclusion zone protected by the forward lock +	 * can enclose the mutual exclusion zone protected by the backward lock +	 * but not vice versa. +	 */ +	spinlock_t		frwd_lock;	/* protects session state, * +						 * cmdsn, queued_cmdsn     *  						 * session resources:      * -						 * - cmdpool,		   * -						 * - mgmtpool,		   * -						 * - r2tpool		   */ +						 * - cmdpool kfifo_out ,   * +						 * - mgmtpool,		   */ +	spinlock_t		back_lock;	/* protects cmdsn_exp      * +						 * cmdsn_max,              * +						 * cmdpool kfifo_in        */  	int			state;		/* session state           */  	int			age;		/* counts session re-opens */ @@ -318,9 +364,6 @@ struct iscsi_host {  	/* hw address or netdev iscsi connection is bound to */  	char			*hwaddress;  	char			*netdev; -	/* local address */ -	int			local_port; -	char			local_address[ISCSI_ADDRESS_BUF_LEN];  	wait_queue_head_t	session_removal_wq;  	/* protects sessions and state */ @@ -341,8 +384,7 @@ extern int iscsi_eh_abort(struct scsi_cmnd *sc);  extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);  extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);  extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); -extern int iscsi_queuecommand(struct scsi_cmnd *sc, -			      void (*done)(struct scsi_cmnd *)); +extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);  /*   * iSCSI host helpers. @@ -394,6 +436,8 @@ extern void iscsi_session_failure(struct iscsi_session *session,  				  enum iscsi_err err);  extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,  				enum iscsi_param param, char *buf); +extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr, +				     enum iscsi_param param, char *buf);  extern void iscsi_suspend_tx(struct iscsi_conn *conn);  extern void iscsi_suspend_queue(struct iscsi_conn *conn);  extern void iscsi_conn_queue_work(struct iscsi_conn *conn); @@ -420,6 +464,7 @@ extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);  extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);  extern void iscsi_requeue_task(struct iscsi_task *task);  extern void iscsi_put_task(struct iscsi_task *task); +extern void __iscsi_put_task(struct iscsi_task *task);  extern void __iscsi_get_task(struct iscsi_task *task);  extern void iscsi_complete_scsi_task(struct iscsi_task *task,  				     uint32_t exp_cmdsn, uint32_t max_cmdsn); @@ -429,6 +474,7 @@ extern void iscsi_complete_scsi_task(struct iscsi_task *task,   */  extern void iscsi_pool_free(struct iscsi_pool *);  extern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int); +extern int iscsi_switch_str_param(char **, char *);  /*   * inline functions to deal with padding. diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index 741ae7ed439..2a7aa75dd00 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h @@ -47,11 +47,12 @@ struct iscsi_segment {  	struct scatterlist	*sg;  	void			*sg_mapped;  	unsigned int		sg_offset; +	bool			atomic_mapped;  	iscsi_segment_done_fn_t	*done;  }; -/* Socket connection recieve helper */ +/* Socket connection receive helper */  struct iscsi_tcp_recv {  	struct iscsi_hdr	*hdr;  	struct iscsi_segment	segment; @@ -82,6 +83,8 @@ struct iscsi_tcp_task {  	struct iscsi_pool	r2tpool;  	struct kfifo		r2tqueue;  	void			*dd_data; +	spinlock_t		pool2queue; +	spinlock_t		queue2pool;  };  enum { @@ -127,7 +130,7 @@ extern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn);  /* misc helpers */  extern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session);  extern void iscsi_tcp_r2tpool_free(struct iscsi_session *session); - +extern int iscsi_tcp_set_max_r2t(struct iscsi_conn *conn, char *buf);  extern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,  				     struct iscsi_stats *stats);  #endif /* LIBISCSI_TCP_H */ diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 3dec1949f69..ef7872c20da 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -79,14 +79,19 @@ enum phy_event {  	PHYE_OOB_DONE         = 1,  	PHYE_OOB_ERROR        = 2,  	PHYE_SPINUP_HOLD      = 3, /* hot plug SATA, no COMWAKE sent */ -	PHY_NUM_EVENTS        = 4, +	PHYE_RESUME_TIMEOUT   = 4, +	PHY_NUM_EVENTS        = 5,  };  enum discover_event {  	DISCE_DISCOVER_DOMAIN   = 0U,  	DISCE_REVALIDATE_DOMAIN = 1,  	DISCE_PORT_GONE         = 2, -	DISC_NUM_EVENTS 	= 3, +	DISCE_PROBE		= 3, +	DISCE_SUSPEND		= 4, +	DISCE_RESUME		= 5, +	DISCE_DESTRUCT		= 6, +	DISC_NUM_EVENTS		= 7,  };  /* ---------- Expander Devices ---------- */ @@ -113,7 +118,7 @@ struct ex_phy {  	enum ex_phy_state phy_state; -	enum sas_dev_type attached_dev_type; +	enum sas_device_type attached_dev_type;  	enum sas_linkrate linkrate;  	u8   attached_sata_host:1; @@ -126,7 +131,7 @@ struct ex_phy {  	u8   attached_sas_addr[SAS_ADDR_SIZE];  	u8   attached_phy_id; -	u8   phy_change_count; +	int phy_change_count;  	enum routing_attribute routing_attr;  	u8   virtual:1; @@ -139,15 +144,20 @@ struct ex_phy {  struct expander_device {  	struct list_head children; -	u16    ex_change_count; +	int    ex_change_count;  	u16    max_route_indexes;  	u8     num_phys; + +	u8     t2t_supp:1;  	u8     configuring:1;  	u8     conf_route_table:1; +  	u8     enclosure_logical_id[8];  	struct ex_phy *ex_phy;  	struct sas_port *parent_port; + +	struct mutex cmd_mutex;  };  /* ---------- SATA device ---------- */ @@ -156,26 +166,35 @@ enum ata_command_set {          ATAPI_COMMAND_SET = 1,  }; +#define ATA_RESP_FIS_SIZE 24 +  struct sata_device {          enum   ata_command_set command_set;          struct smp_resp        rps_resp; /* report_phy_sata_resp */ -        __le16 *identify_device; -        __le16 *identify_packet_device; -          u8     port_no;        /* port number, if this is a PM (Port) */ -        struct list_head children; /* PM Ports if this is a PM */  	struct ata_port *ap;  	struct ata_host ata_host; -	struct ata_taskfile tf; -	u32 sstatus; -	u32 serror; -	u32 scontrol; +	u8     fis[ATA_RESP_FIS_SIZE]; +}; + +struct ssp_device { +	struct list_head eh_list_node; /* pending a user requested eh action */ +	struct scsi_lun reset_lun; +}; + +enum { +	SAS_DEV_GONE, +	SAS_DEV_FOUND, /* device notified to lldd */ +	SAS_DEV_DESTROY, +	SAS_DEV_EH_PENDING, +	SAS_DEV_LU_RESET, +	SAS_DEV_RESET,  }; -/* ---------- Domain device ---------- */  struct domain_device { -        enum sas_dev_type dev_type; +	spinlock_t done_lock; +	enum sas_device_type dev_type;          enum sas_linkrate linkrate;          enum sas_linkrate min_linkrate; @@ -186,8 +205,10 @@ struct domain_device {          struct domain_device *parent;          struct list_head siblings; /* devices on the same level */          struct asd_sas_port *port;        /* shortcut to root of the tree */ +	struct sas_phy *phy;          struct list_head dev_list_node; +	struct list_head disco_list_node; /* awaiting probe or destruct */          enum sas_protocol    iproto;          enum sas_protocol    tproto; @@ -202,19 +223,38 @@ struct domain_device {          union {                  struct expander_device ex_dev;                  struct sata_device     sata_dev; /* STP & directly attached */ +		struct ssp_device      ssp_dev;          };          void *lldd_dev; -	int gone; +	unsigned long state; +	struct kref kref;  }; -struct sas_discovery_event { +struct sas_work { +	struct list_head drain_node;  	struct work_struct work; +}; + +static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *)) +{ +	INIT_WORK(&sw->work, fn); +	INIT_LIST_HEAD(&sw->drain_node); +} + +struct sas_discovery_event { +	struct sas_work work;  	struct asd_sas_port *port;  }; +static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work) +{ +	struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work); + +	return ev; +} +  struct sas_discovery { -	spinlock_t disc_event_lock;  	struct sas_discovery_event disc_work[DISC_NUM_EVENTS];  	unsigned long    pending;  	u8     fanout_sas_addr[8]; @@ -223,7 +263,6 @@ struct sas_discovery {  	int    max_level;  }; -  /* The port struct is Class:RW, driver:RO */  struct asd_sas_port {  /* private: */ @@ -233,10 +272,12 @@ struct asd_sas_port {  	struct domain_device *port_dev;  	spinlock_t dev_list_lock;  	struct list_head dev_list; +	struct list_head disco_list; +	struct list_head destroy_list;  	enum   sas_linkrate linkrate; -	struct sas_phy *phy; -	struct work_struct work; +	struct sas_work work; +	int suspended;  /* public: */  	int id; @@ -262,16 +303,22 @@ struct asd_sas_port {  };  struct asd_sas_event { -	struct work_struct work; +	struct sas_work work;  	struct asd_sas_phy *phy;  }; +static inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work) +{ +	struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work); + +	return ev; +} +  /* The phy pretty much is controlled by the LLDD.   * The class only reads those fields.   */  struct asd_sas_phy {  /* private: */ -	/* protected by ha->event_lock */  	struct asd_sas_event   port_events[PORT_NUM_EVENTS];  	struct asd_sas_event   phy_events[PHY_NUM_EVENTS]; @@ -279,6 +326,7 @@ struct asd_sas_phy {  	unsigned long phy_events_pending;  	int error; +	int suspended;  	struct sas_phy *phy; @@ -317,6 +365,7 @@ struct asd_sas_phy {  struct scsi_core {  	struct Scsi_Host *shost; +	struct mutex	  task_queue_flush;  	spinlock_t        task_queue_lock;  	struct list_head  task_queue;  	int               task_queue_size; @@ -325,23 +374,38 @@ struct scsi_core {  };  struct sas_ha_event { -	struct work_struct work; +	struct sas_work work;  	struct sas_ha_struct *ha;  }; +static inline struct sas_ha_event *to_sas_ha_event(struct work_struct *work) +{ +	struct sas_ha_event *ev = container_of(work, typeof(*ev), work.work); + +	return ev; +} +  enum sas_ha_state {  	SAS_HA_REGISTERED, -	SAS_HA_UNREGISTERED +	SAS_HA_DRAINING, +	SAS_HA_ATA_EH_ACTIVE, +	SAS_HA_FROZEN,  };  struct sas_ha_struct {  /* private: */ -	spinlock_t       event_lock;  	struct sas_ha_event ha_events[HA_NUM_EVENTS];  	unsigned long	 pending; -	enum sas_ha_state state; -	spinlock_t 	  state_lock; +	struct list_head  defer_q; /* work queued while draining */ +	struct mutex	  drain_mutex; +	unsigned long	  state; +	spinlock_t	  lock; +	int		  eh_active; +	wait_queue_head_t eh_wait_q; +	struct list_head  eh_dev_q; + +	struct mutex disco_mutex;  	struct scsi_core core; @@ -361,6 +425,8 @@ struct sas_ha_struct {  	/* The class calls this to send a task for execution. */  	int lldd_max_execute_num;  	int lldd_queue_size; +	int strict_wide_ports; /* both sas_addr and attached_sas_addr must match +				* their siblings when forming wide ports */  	/* LLDD calls these to notify the class of an event. */  	void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event); @@ -369,7 +435,8 @@ struct sas_ha_struct {  	void *lldd_ha;		  /* not touched by sas class code */ -	struct list_head eh_done_q; +	struct list_head eh_done_q;  /* complete via scsi_eh_flush_done_q */ +	struct list_head eh_ata_q; /* scmds to promote from sas to ata eh */  };  #define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata) @@ -384,6 +451,11 @@ sdev_to_domain_dev(struct scsi_device *sdev) {  	return starget_to_domain_dev(sdev->sdev_target);  } +static inline struct ata_device *sas_to_ata_dev(struct domain_device *dev) +{ +	return &dev->sata_dev.ap->link.device[0]; +} +  static inline struct domain_device *  cmd_to_domain_dev(struct scsi_cmnd *cmd)  { @@ -403,6 +475,25 @@ static inline void sas_phy_disconnected(struct asd_sas_phy *phy)  	phy->linkrate = SAS_LINK_RATE_UNKNOWN;  } +static inline unsigned int to_sas_gpio_od(int device, int bit) +{ +	return 3 * device + bit; +} + +static inline void sas_put_local_phy(struct sas_phy *phy) +{ +	put_device(&phy->dev); +} + +#ifdef CONFIG_SCSI_SAS_HOST_SMP +int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count); +#else +static inline int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count) +{ +	return -1; +} +#endif +  /* ---------- Tasks ---------- */  /*        service_response |  SAS_TASK_COMPLETE  |  SAS_TASK_UNDELIVERED | @@ -423,7 +514,10 @@ enum service_response {  };  enum exec_status { -	/* The SAM_STAT_.. codes fit in the lower 6 bits */ +	/* The SAM_STAT_.. codes fit in the lower 6 bits, alias some of +	 * them here to silence 'case value not in enumerated type' warnings +	 */ +	__SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,  	SAS_DEV_NO_RESPONSE = 0x80,  	SAS_DATA_UNDERRUN, @@ -462,11 +556,7 @@ enum exec_status {   */  struct ata_task_resp {  	u16  frame_len; -	u8   ending_fis[24];	  /* dev to host or data-in */ -	u32  sstatus; -	u32  serror; -	u32  scontrol; -	u32  sactive; +	u8   ending_fis[ATA_RESP_FIS_SIZE];	  /* dev to host or data-in */  };  #define SAS_STATUS_BUF_SIZE 96 @@ -517,7 +607,7 @@ struct sas_ssp_task {  	u8     enable_first_burst:1;  	enum   task_attribute task_attr;  	u8     task_prio; -	u8     cdb[16]; +	struct scsi_cmnd *cmd;  };  struct sas_task { @@ -529,10 +619,6 @@ struct sas_task {  	enum   sas_protocol      task_proto; -	/* Used by the discovery code. */ -	struct timer_list     timer; -	struct completion     completion; -  	union {  		struct sas_ata_task ata_task;  		struct sas_smp_task smp_task; @@ -549,11 +635,16 @@ struct sas_task {  	void   *lldd_task;	  /* for use by LLDDs */  	void   *uldd_task; - -	struct work_struct abort_work; +	struct sas_task_slow *slow_task;  }; -extern struct kmem_cache *sas_task_cache; +struct sas_task_slow { +	/* standard/extra infrastructure for slow path commands (SMP and +	 * internal lldd commands +	 */ +	struct timer_list     timer; +	struct completion     completion; +};  #define SAS_TASK_STATE_PENDING      1  #define SAS_TASK_STATE_DONE         2 @@ -561,28 +652,9 @@ extern struct kmem_cache *sas_task_cache;  #define SAS_TASK_NEED_DEV_RESET     8  #define SAS_TASK_AT_INITIATOR       16 -static inline struct sas_task *sas_alloc_task(gfp_t flags) -{ -	struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags); - -	if (task) { -		INIT_LIST_HEAD(&task->list); -		spin_lock_init(&task->task_state_lock); -		task->task_state_flags = SAS_TASK_STATE_PENDING; -		init_timer(&task->timer); -		init_completion(&task->completion); -	} - -	return task; -} - -static inline void sas_free_task(struct sas_task *task) -{ -	if (task) { -		BUG_ON(!list_empty(&task->list)); -		kmem_cache_free(sas_task_cache, task); -	} -} +extern struct sas_task *sas_alloc_task(gfp_t flags); +extern struct sas_task *sas_alloc_slow_task(gfp_t flags); +extern void sas_free_task(struct sas_task *task);  struct sas_domain_function_template {  	/* The class calls these to notify the LLDD of an event. */ @@ -602,6 +674,8 @@ struct sas_domain_function_template {  	int (*lldd_clear_aca)(struct domain_device *, u8 *lun);  	int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);  	int (*lldd_I_T_nexus_reset)(struct domain_device *); +	int (*lldd_ata_check_ready)(struct domain_device *); +	void (*lldd_ata_set_dmamode)(struct domain_device *);  	int (*lldd_lu_reset)(struct domain_device *, u8 *lun);  	int (*lldd_query_task)(struct sas_task *); @@ -611,22 +685,25 @@ struct sas_domain_function_template {  	/* Phy management */  	int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *); + +	/* GPIO support */ +	int (*lldd_write_gpio)(struct sas_ha_struct *, u8 reg_type, +			       u8 reg_index, u8 reg_count, u8 *write_data);  };  extern int sas_register_ha(struct sas_ha_struct *);  extern int sas_unregister_ha(struct sas_ha_struct *); +extern void sas_prep_resume_ha(struct sas_ha_struct *sas_ha); +extern void sas_resume_ha(struct sas_ha_struct *sas_ha); +extern void sas_suspend_ha(struct sas_ha_struct *sas_ha);  int sas_set_phy_speed(struct sas_phy *phy,  		      struct sas_phy_linkrates *rates); -int sas_phy_enable(struct sas_phy *phy, int enabled);  int sas_phy_reset(struct sas_phy *phy, int hard_reset);  int sas_queue_up(struct sas_task *task); -extern int sas_queuecommand(struct scsi_cmnd *, -		     void (*scsi_done)(struct scsi_cmnd *)); +extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);  extern int sas_target_alloc(struct scsi_target *); -extern int sas_slave_alloc(struct scsi_device *);  extern int sas_slave_configure(struct scsi_device *); -extern void sas_slave_destroy(struct scsi_device *);  extern int sas_change_queue_depth(struct scsi_device *, int new_depth,  				  int reason);  extern int sas_change_queue_type(struct scsi_device *, int qt); @@ -643,32 +720,33 @@ void sas_init_ex_attr(void);  int  sas_ex_revalidate_domain(struct domain_device *); -void sas_unregister_domain_devices(struct asd_sas_port *port); +void sas_unregister_domain_devices(struct asd_sas_port *port, int gone);  void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);  int  sas_discover_event(struct asd_sas_port *, enum discover_event ev);  int  sas_discover_sata(struct domain_device *);  int  sas_discover_end_dev(struct domain_device *); -void sas_unregister_dev(struct domain_device *); +void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *);  void sas_init_dev(struct domain_device *);  void sas_task_abort(struct sas_task *); -int __sas_task_abort(struct sas_task *); +int sas_eh_abort_handler(struct scsi_cmnd *cmd);  int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);  int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd);  extern void sas_target_destroy(struct scsi_target *);  extern int sas_slave_alloc(struct scsi_device *);  extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); +extern int sas_drain_work(struct sas_ha_struct *ha);  extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,  			   struct request *req);  extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,  				  struct ssp_response_iu *iu); -struct sas_phy *sas_find_local_phy(struct domain_device *dev); +struct sas_phy *sas_get_local_phy(struct domain_device *dev);  int sas_request_addr(struct Scsi_Host *shost, u8 *addr); diff --git a/include/scsi/osd_attributes.h b/include/scsi/osd_attributes.h index 56e920ade32..303ba1118a4 100644 --- a/include/scsi/osd_attributes.h +++ b/include/scsi/osd_attributes.h @@ -1,7 +1,7 @@  #ifndef __OSD_ATTRIBUTES_H__  #define __OSD_ATTRIBUTES_H__ -#include "osd_protocol.h" +#include <scsi/osd_protocol.h>  /*   * Contains types and constants that define attribute pages and attribute diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h index 53a9e886612..b2e85fdd2ae 100644 --- a/include/scsi/osd_initiator.h +++ b/include/scsi/osd_initiator.h @@ -14,8 +14,8 @@  #ifndef __OSD_INITIATOR_H__  #define __OSD_INITIATOR_H__ -#include "osd_protocol.h" -#include "osd_types.h" +#include <scsi/osd_protocol.h> +#include <scsi/osd_types.h>  #include <linux/blkdev.h>  #include <scsi/scsi_device.h> @@ -262,10 +262,10 @@ int osd_execute_request_async(struct osd_request *or,   * osd_req_decode_sense_full - Decode sense information after execution.   *   * @or:           - osd_request to examine - * @osi           - Recievs a more detailed error report information (optional). + * @osi           - Receives a more detailed error report information (optional).   * @silent        - Do not print to dmsg (Even if enabled)   * @bad_obj_list  - Some commands act on multiple objects. Failed objects will - *                  be recieved here (optional) + *                  be received here (optional)   * @max_obj       - Size of @bad_obj_list.   * @bad_attr_list - List of failing attributes (optional)   * @max_attr      - Size of @bad_attr_list. diff --git a/include/scsi/osd_ore.h b/include/scsi/osd_ore.h new file mode 100644 index 00000000000..6ca3265a4dc --- /dev/null +++ b/include/scsi/osd_ore.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2011 + * Boaz Harrosh <bharrosh@panasas.com> + * + * Public Declarations of the ORE API + * + * This file is part of the ORE (Object Raid Engine) library. + * + * ORE is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. (GPL v2) + * + * ORE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the ORE; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA + */ +#ifndef __ORE_H__ +#define __ORE_H__ + +#include <scsi/osd_initiator.h> +#include <scsi/osd_attributes.h> +#include <scsi/osd_sec.h> +#include <linux/pnfs_osd_xdr.h> +#include <linux/bug.h> + +struct ore_comp { +	struct osd_obj_id	obj; +	u8			cred[OSD_CAP_LEN]; +}; + +struct ore_layout { +	/* Our way of looking at the data_map */ +	enum pnfs_osd_raid_algorithm4 +		 raid_algorithm; +	unsigned stripe_unit; +	unsigned mirrors_p1; + +	unsigned group_width; +	unsigned parity; +	u64	 group_depth; +	unsigned group_count; + +	/* Cached often needed calculations filled in by +	 * ore_verify_layout +	 */ +	unsigned long max_io_length;	/* Max length that should be passed to +					 * ore_get_rw_state +					 */ +}; + +struct ore_dev { +	struct osd_dev *od; +}; + +struct ore_components { +	unsigned	first_dev;		/* First logical device no    */ +	unsigned	numdevs;		/* Num of devices in array    */ +	/* If @single_comp == EC_SINGLE_COMP, @comps points to a single +	 * component. else there are @numdevs components +	 */ +	enum EC_COMP_USAGE { +		EC_SINGLE_COMP = 0, EC_MULTPLE_COMPS = 0xffffffff +	}		single_comp; +	struct ore_comp	*comps; + +	/* Array of pointers to ore_dev-* . User will usually have these pointed +	 * too a bigger struct which contain an "ore_dev ored" member and use +	 * container_of(oc->ods[i], struct foo_dev, ored) to access the bigger +	 * structure. +	 */ +	struct ore_dev	**ods; +}; + +/* ore_comp_dev Recievies a logical device index */ +static inline struct osd_dev *ore_comp_dev( +	const struct ore_components *oc, unsigned i) +{ +	BUG_ON((i < oc->first_dev) || (oc->first_dev + oc->numdevs <= i)); +	return oc->ods[i - oc->first_dev]->od; +} + +static inline void ore_comp_set_dev( +	struct ore_components *oc, unsigned i, struct osd_dev *od) +{ +	oc->ods[i - oc->first_dev]->od = od; +} + +struct ore_striping_info { +	u64 offset; +	u64 obj_offset; +	u64 length; +	u64 first_stripe_start; /* only used in raid writes */ +	u64 M; /* for truncate */ +	unsigned bytes_in_stripe; +	unsigned dev; +	unsigned par_dev; +	unsigned unit_off; +	unsigned cur_pg; +	unsigned cur_comp; +	unsigned maxdevUnits; +}; + +struct ore_io_state; +typedef void (*ore_io_done_fn)(struct ore_io_state *ios, void *private); +struct _ore_r4w_op { +	/* @Priv given here is passed ios->private */ +	struct page * (*get_page)(void *priv, u64 page_index, bool *uptodate); +	void (*put_page)(void *priv, struct page *page); +}; + +struct ore_io_state { +	struct kref		kref; +	struct ore_striping_info si; + +	void			*private; +	ore_io_done_fn	done; + +	struct ore_layout	*layout; +	struct ore_components	*oc; + +	/* Global read/write IO*/ +	loff_t			offset; +	unsigned long		length; +	void			*kern_buff; + +	struct page		**pages; +	unsigned		nr_pages; +	unsigned		pgbase; +	unsigned		pages_consumed; + +	/* Attributes */ +	unsigned		in_attr_len; +	struct osd_attr		*in_attr; +	unsigned		out_attr_len; +	struct osd_attr		*out_attr; + +	bool			reading; + +	/* House keeping of Parity pages */ +	bool			extra_part_alloc; +	struct page		**parity_pages; +	unsigned		max_par_pages; +	unsigned		cur_par_page; +	unsigned		sgs_per_dev; +	struct __stripe_pages_2d *sp2d; +	struct ore_io_state	 *ios_read_4_write; +	const struct _ore_r4w_op *r4w; + +	/* Variable array of size numdevs */ +	unsigned numdevs; +	struct ore_per_dev_state { +		struct osd_request *or; +		struct bio *bio; +		loff_t offset; +		unsigned length; +		unsigned last_sgs_total; +		unsigned dev; +		struct osd_sg_entry *sglist; +		unsigned cur_sg; +	} per_dev[]; +}; + +static inline unsigned ore_io_state_size(unsigned numdevs) +{ +	return sizeof(struct ore_io_state) + +		sizeof(struct ore_per_dev_state) * numdevs; +} + +/* ore.c */ +int ore_verify_layout(unsigned total_comps, struct ore_layout *layout); +void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, +			  u64 length, struct ore_striping_info *si); +int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps, +		     bool is_reading, u64 offset, u64 length, +		     struct ore_io_state **ios); +int ore_get_io_state(struct ore_layout *layout, struct ore_components *comps, +		     struct ore_io_state **ios); +void ore_put_io_state(struct ore_io_state *ios); + +typedef void (*ore_on_dev_error)(struct ore_io_state *ios, struct ore_dev *od, +	unsigned dev_index, enum osd_err_priority oep, +	u64 dev_offset, u64  dev_len); +int ore_check_io(struct ore_io_state *ios, ore_on_dev_error rep); + +int ore_create(struct ore_io_state *ios); +int ore_remove(struct ore_io_state *ios); +int ore_write(struct ore_io_state *ios); +int ore_read(struct ore_io_state *ios); +int ore_truncate(struct ore_layout *layout, struct ore_components *comps, +		 u64 size); + +int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr); + +extern const struct osd_attr g_attr_logical_length; + +#endif diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h index a6026da25f3..a2594afe05c 100644 --- a/include/scsi/osd_protocol.h +++ b/include/scsi/osd_protocol.h @@ -107,7 +107,7 @@ enum osd_attributes_mode {   *		int exponent: 04;   *	}   */ -typedef __be32 __bitwise osd_cdb_offset; +typedef __be32 osd_cdb_offset;  enum {  	OSD_OFFSET_UNUSED = 0xFFFFFFFF, @@ -263,16 +263,16 @@ static inline struct osd_cdb_head *osd_cdb_head(struct osd_cdb *ocdb)   * Ex name = FORMAT_OSD we have OSD_ACT_FORMAT_OSD && OSDv1_ACT_FORMAT_OSD   */  #define OSD_ACT___(Name, Num) \ -	OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num), \ -	OSDv1_ACT_##Name = __constant_cpu_to_be16(0x8800 + Num), +	OSD_ACT_##Name = cpu_to_be16(0x8880 + Num), \ +	OSDv1_ACT_##Name = cpu_to_be16(0x8800 + Num),  /* V2 only actions */  #define OSD_ACT_V2(Name, Num) \ -	OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num), +	OSD_ACT_##Name = cpu_to_be16(0x8880 + Num),  #define OSD_ACT_V1_V2(Name, Num1, Num2) \ -	OSD_ACT_##Name = __constant_cpu_to_be16(Num2), \ -	OSDv1_ACT_##Name = __constant_cpu_to_be16(Num1), +	OSD_ACT_##Name = cpu_to_be16(Num2), \ +	OSDv1_ACT_##Name = cpu_to_be16(Num1),  enum osd_service_actions {  	OSD_ACT_V2(OBJECT_STRUCTURE_CHECK,	0x00) diff --git a/include/scsi/osd_sec.h b/include/scsi/osd_sec.h index 4c09fee8ae1..f96151c9c9e 100644 --- a/include/scsi/osd_sec.h +++ b/include/scsi/osd_sec.h @@ -14,8 +14,8 @@  #ifndef __OSD_SEC_H__  #define __OSD_SEC_H__ -#include "osd_protocol.h" -#include "osd_types.h" +#include <scsi/osd_protocol.h> +#include <scsi/osd_types.h>  /*   * Contains types and constants of osd capabilities and security diff --git a/include/scsi/sas.h b/include/scsi/sas.h index e9fd0228138..0d2607d1238 100644 --- a/include/scsi/sas.h +++ b/include/scsi/sas.h @@ -89,25 +89,29 @@ enum sas_oob_mode {  	SAS_OOB_MODE  }; -/* See sas_discover.c if you plan on changing these. - */ -enum sas_dev_type { -	NO_DEVICE   = 0,	  /* protocol */ -	SAS_END_DEV = 1,	  /* protocol */ -	EDGE_DEV    = 2,	  /* protocol */ -	FANOUT_DEV  = 3,	  /* protocol */ -	SAS_HA      = 4, -	SATA_DEV    = 5, -	SATA_PM     = 7, -	SATA_PM_PORT= 8, +/* See sas_discover.c if you plan on changing these */ +enum sas_device_type { +	/* these are SAS protocol defined (attached device type field) */ +	SAS_PHY_UNUSED = 0, +	SAS_END_DEVICE = 1, +	SAS_EDGE_EXPANDER_DEVICE = 2, +	SAS_FANOUT_EXPANDER_DEVICE = 3, +	/* these are internal to libsas */ +	SAS_HA = 4, +	SAS_SATA_DEV = 5, +	SAS_SATA_PM = 7, +	SAS_SATA_PM_PORT = 8, +	SAS_SATA_PENDING = 9,  };  enum sas_protocol { +	SAS_PROTOCOL_NONE		= 0,  	SAS_PROTOCOL_SATA		= 0x01,  	SAS_PROTOCOL_SMP		= 0x02,  	SAS_PROTOCOL_STP		= 0x04,  	SAS_PROTOCOL_SSP		= 0x08,  	SAS_PROTOCOL_ALL		= 0x0E, +	SAS_PROTOCOL_STP_ALL		= SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA,  };  /* From the spec; local phys only */ @@ -121,6 +125,7 @@ enum phy_func {  	PHY_FUNC_TX_SATA_PS_SIGNAL,  	PHY_FUNC_RELEASE_SPINUP_HOLD = 0x10, /* LOCAL PORT ONLY! */  	PHY_FUNC_SET_LINK_RATE, +	PHY_FUNC_GET_EVENTS,  };  /* SAS LLDD would need to report only _very_few_ of those, like BROADCAST. @@ -195,6 +200,14 @@ enum sas_open_rej_reason {  	SAS_OREJ_RSVD_RETRY = 18,  }; +enum sas_gpio_reg_type { +	SAS_GPIO_REG_CFG   = 0, +	SAS_GPIO_REG_RX    = 1, +	SAS_GPIO_REG_RX_GP = 2, +	SAS_GPIO_REG_TX    = 3, +	SAS_GPIO_REG_TX_GP = 4, +}; +  struct  dev_to_host_fis {  	u8     fis_type;	  /* 0x34 */  	u8     flags; @@ -341,7 +354,12 @@ struct report_general_resp {  	u8      conf_route_table:1;  	u8      configuring:1; -	u8      _r_b:6; +	u8	config_others:1; +	u8	orej_retry_supp:1; +	u8	stp_cont_awt:1; +	u8	self_config:1; +	u8	zone_config:1; +	u8	t2t_supp:1;  	u8      _r_c; @@ -528,7 +546,12 @@ struct report_general_resp {  	u8      _r_a;  	u8      num_phys; -	u8      _r_b:6; +	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; diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h index c583193ae92..00f41aeeecf 100644 --- a/include/scsi/sas_ata.h +++ b/include/scsi/sas_ata.h @@ -32,14 +32,22 @@  static inline int dev_is_sata(struct domain_device *dev)  { -	return (dev->rphy->identify.target_port_protocols & SAS_PROTOCOL_SATA); +	return dev->dev_type == SAS_SATA_DEV || dev->dev_type == SAS_SATA_PM || +	       dev->dev_type == SAS_SATA_PM_PORT || dev->dev_type == SAS_SATA_PENDING;  } -int sas_ata_init_host_and_port(struct domain_device *found_dev, -			       struct scsi_target *starget); - +int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy); +int sas_ata_init(struct domain_device *dev);  void sas_ata_task_abort(struct sas_task *task); - +void sas_ata_strategy_handler(struct Scsi_Host *shost); +void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, +		struct list_head *done_q); +void sas_ata_schedule_reset(struct domain_device *dev); +void sas_ata_wait_eh(struct domain_device *dev); +void sas_probe_sata(struct asd_sas_port *port); +void sas_suspend_sata(struct asd_sas_port *port); +void sas_resume_sata(struct asd_sas_port *port); +void sas_ata_end_eh(struct ata_port *ap);  #else @@ -47,14 +55,51 @@ static inline int dev_is_sata(struct domain_device *dev)  {  	return 0;  } -static inline int sas_ata_init_host_and_port(struct domain_device *found_dev, -			       struct scsi_target *starget) +static inline int sas_ata_init(struct domain_device *dev)  {  	return 0;  }  static inline void sas_ata_task_abort(struct sas_task *task)  {  } + +static inline void sas_ata_strategy_handler(struct Scsi_Host *shost) +{ +} + +static inline void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, +			      struct list_head *done_q) +{ +} + +static inline void sas_ata_schedule_reset(struct domain_device *dev) +{ +} + +static inline void sas_ata_wait_eh(struct domain_device *dev) +{ +} + +static inline void sas_probe_sata(struct asd_sas_port *port) +{ +} + +static inline void sas_suspend_sata(struct asd_sas_port *port) +{ +} + +static inline void sas_resume_sata(struct asd_sas_port *port) +{ +} + +static inline int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy) +{ +	return 0; +} + +static inline void sas_ata_end_eh(struct ata_port *ap) +{ +}  #endif  #endif /* _SAS_ATA_H_ */ diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 216af8538cc..0a4edfe8af5 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -9,9 +9,15 @@  #define _SCSI_SCSI_H  #include <linux/types.h> +#include <linux/scatterlist.h> +#include <linux/kernel.h>  struct scsi_cmnd; +enum scsi_timeouts { +	SCSI_DEFAULT_EH_TIMEOUT		= 10 * HZ, +}; +  /*   * The maximum number of SG segments that we will put inside a   * scatterlist (unless chaining is used). Should ideally fit inside a @@ -104,6 +110,7 @@ struct scsi_cmnd;  #define UNMAP		      0x42  #define READ_TOC              0x43  #define READ_HEADER           0x44 +#define GET_EVENT_STATUS_NOTIFICATION 0x4a  #define LOG_SELECT            0x4c  #define LOG_SENSE             0x4d  #define XDWRITEREAD_10        0x53 @@ -115,33 +122,66 @@ struct scsi_cmnd;  #define PERSISTENT_RESERVE_OUT 0x5f  #define VARIABLE_LENGTH_CMD   0x7f  #define REPORT_LUNS           0xa0 +#define SECURITY_PROTOCOL_IN  0xa2  #define MAINTENANCE_IN        0xa3  #define MAINTENANCE_OUT       0xa4  #define MOVE_MEDIUM           0xa5  #define EXCHANGE_MEDIUM       0xa6  #define READ_12               0xa8  #define WRITE_12              0xaa +#define READ_MEDIA_SERIAL_NUMBER 0xab  #define WRITE_VERIFY_12       0xae  #define VERIFY_12	      0xaf  #define SEARCH_HIGH_12        0xb0  #define SEARCH_EQUAL_12       0xb1  #define SEARCH_LOW_12         0xb2 +#define SECURITY_PROTOCOL_OUT 0xb5  #define READ_ELEMENT_STATUS   0xb8  #define SEND_VOLUME_TAG       0xb6  #define WRITE_LONG_2          0xea +#define EXTENDED_COPY         0x83 +#define RECEIVE_COPY_RESULTS  0x84 +#define ACCESS_CONTROL_IN     0x86 +#define ACCESS_CONTROL_OUT    0x87  #define READ_16               0x88 +#define COMPARE_AND_WRITE     0x89  #define WRITE_16              0x8a +#define READ_ATTRIBUTE        0x8c +#define WRITE_ATTRIBUTE	      0x8d  #define VERIFY_16	      0x8f +#define SYNCHRONIZE_CACHE_16  0x91  #define WRITE_SAME_16	      0x93  #define SERVICE_ACTION_IN     0x9e  /* values for service action in */  #define	SAI_READ_CAPACITY_16  0x10  #define SAI_GET_LBA_STATUS    0x12 +#define SAI_REPORT_REFERRALS  0x13 +/* values for VARIABLE_LENGTH_CMD service action codes + * see spc4r17 Section D.3.5, table D.7 and D.8 */ +#define VLC_SA_RECEIVE_CREDENTIAL 0x1800  /* values for maintenance in */ +#define MI_REPORT_IDENTIFYING_INFORMATION 0x05  #define MI_REPORT_TARGET_PGS  0x0a +#define MI_REPORT_ALIASES     0x0b +#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c +#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d +#define MI_REPORT_PRIORITY   0x0e +#define MI_REPORT_TIMESTAMP  0x0f +#define MI_MANAGEMENT_PROTOCOL_IN 0x10 +/* value for MI_REPORT_TARGET_PGS ext header */ +#define MI_EXT_HDR_PARAM_FMT  0x20  /* values for maintenance out */ +#define MO_SET_IDENTIFYING_INFORMATION 0x06  #define MO_SET_TARGET_PGS     0x0a +#define MO_CHANGE_ALIASES     0x0b +#define MO_SET_PRIORITY       0x0e +#define MO_SET_TIMESTAMP      0x0f +#define MO_MANAGEMENT_PROTOCOL_OUT 0x10  /* values for variable length command */ +#define XDREAD_32	      0x03 +#define XDWRITE_32	      0x04 +#define XPWRITE_32	      0x06 +#define XDWRITEREAD_32	      0x07  #define READ_32		      0x09  #define VERIFY_32	      0x0a  #define WRITE_32	      0x0b @@ -183,6 +223,16 @@ scsi_command_size(const unsigned char *cmnd)  		scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);  } +#ifdef CONFIG_ACPI +struct acpi_bus_type; + +extern int +scsi_register_acpi_bus_type(struct acpi_bus_type *bus); + +extern void +scsi_unregister_acpi_bus_type(struct acpi_bus_type *bus); +#endif +  /*   *  SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft   *  T10/1561-D Revision 4 Draft dated 7th November 2002. @@ -405,6 +455,12 @@ static inline int scsi_is_wlun(unsigned int lun)  				      * recover the link. Transport class will  				      * retry or fail IO */  #define DID_TRANSPORT_FAILFAST	0x0f /* Transport class fastfailed the io */ +#define DID_TARGET_FAILURE 0x10 /* Permanent target failure, do not retry on +				 * other paths */ +#define DID_NEXUS_FAILURE 0x11  /* Permanent nexus failure, retry on other +				 * paths might yield different results */ +#define DID_ALLOC_FAILURE 0x12  /* Space allocation on the device failed */ +#define DID_MEDIUM_ERROR  0x13  /* Medium error */  #define DRIVER_OK       0x00	/* Driver status                           */  /* @@ -460,7 +516,7 @@ static inline int scsi_is_wlun(unsigned int lun)  #define sense_class(sense)  (((sense) >> 4) & 0x7)  #define sense_error(sense)  ((sense) & 0xf) -#define sense_valid(sense)  ((sense) & 0x80); +#define sense_valid(sense)  ((sense) & 0x80)  /*   * default timeouts diff --git a/include/scsi/scsi_bsg_fc.h b/include/scsi/scsi_bsg_fc.h deleted file mode 100644 index 91a4e4ff9a9..00000000000 --- a/include/scsi/scsi_bsg_fc.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - *  FC Transport BSG Interface - * - *  Copyright (C) 2008   James Smart, Emulex Corporation - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ - -#ifndef SCSI_BSG_FC_H -#define SCSI_BSG_FC_H - -/* - * This file intended to be included by both kernel and user space - */ - -#include <scsi/scsi.h> - -/* - * FC Transport SGIO v4 BSG Message Support - */ - -/* Default BSG request timeout (in seconds) */ -#define FC_DEFAULT_BSG_TIMEOUT		(10 * HZ) - - -/* - * Request Message Codes supported by the FC Transport - */ - -/* define the class masks for the message codes */ -#define FC_BSG_CLS_MASK		0xF0000000	/* find object class */ -#define FC_BSG_HST_MASK		0x80000000	/* fc host class */ -#define FC_BSG_RPT_MASK		0x40000000	/* fc rport class */ - -	/* fc_host Message Codes */ -#define FC_BSG_HST_ADD_RPORT		(FC_BSG_HST_MASK | 0x00000001) -#define FC_BSG_HST_DEL_RPORT		(FC_BSG_HST_MASK | 0x00000002) -#define FC_BSG_HST_ELS_NOLOGIN		(FC_BSG_HST_MASK | 0x00000003) -#define FC_BSG_HST_CT			(FC_BSG_HST_MASK | 0x00000004) -#define FC_BSG_HST_VENDOR		(FC_BSG_HST_MASK | 0x000000FF) - -	/* fc_rport Message Codes */ -#define FC_BSG_RPT_ELS			(FC_BSG_RPT_MASK | 0x00000001) -#define FC_BSG_RPT_CT			(FC_BSG_RPT_MASK | 0x00000002) - - - -/* - * FC Address Identifiers in Message Structures : - * - *   Whenever a command payload contains a FC Address Identifier - *   (aka port_id), the value is effectively in big-endian - *   order, thus the array elements are decoded as follows: - *     element [0] is bits 23:16 of the FC Address Identifier - *     element [1] is bits 15:8 of the FC Address Identifier - *     element [2] is bits 7:0 of the FC Address Identifier - */ - - -/* - * FC Host Messages - */ - -/* FC_BSG_HST_ADDR_PORT : */ - -/* Request: - * This message requests the FC host to login to the remote port - * at the specified N_Port_Id.  The remote port is to be enumerated - * with the transport upon completion of the login. - */ -struct fc_bsg_host_add_rport { -	uint8_t		reserved; - -	/* FC Address Identier of the remote port to login to */ -	uint8_t		port_id[3]; -}; - -/* Response: - * There is no additional response data - fc_bsg_reply->result is sufficient - */ - - -/* FC_BSG_HST_DEL_RPORT : */ - -/* Request: - * This message requests the FC host to remove an enumerated - * remote port and to terminate the login to it. - * - * Note: The driver is free to reject this request if it desires to - * remain logged in with the remote port. - */ -struct fc_bsg_host_del_rport { -	uint8_t		reserved; - -	/* FC Address Identier of the remote port to logout of */ -	uint8_t		port_id[3]; -}; - -/* Response: - * There is no additional response data - fc_bsg_reply->result is sufficient - */ - - -/* FC_BSG_HST_ELS_NOLOGIN : */ - -/* Request: - * This message requests the FC_Host to send an ELS to a specific - * N_Port_ID. The host does not need to log into the remote port, - * nor does it need to enumerate the rport for further traffic - * (although, the FC host is free to do so if it desires). - */ -struct fc_bsg_host_els { -	/* -	 * ELS Command Code being sent (must be the same as byte 0 -	 * of the payload) -	 */ -	uint8_t 	command_code; - -	/* FC Address Identier of the remote port to send the ELS to */ -	uint8_t		port_id[3]; -}; - -/* Response: - */ -/* fc_bsg_ctels_reply->status values */ -#define FC_CTELS_STATUS_OK	0x00000000 -#define FC_CTELS_STATUS_REJECT	0x00000001 -#define FC_CTELS_STATUS_P_RJT	0x00000002 -#define FC_CTELS_STATUS_F_RJT	0x00000003 -#define FC_CTELS_STATUS_P_BSY	0x00000004 -#define FC_CTELS_STATUS_F_BSY	0x00000006 -struct fc_bsg_ctels_reply { -	/* -	 * Note: An ELS LS_RJT may be reported in 2 ways: -	 *  a) A status of FC_CTELS_STATUS_OK is returned. The caller -	 *     is to look into the ELS receive payload to determine -	 *     LS_ACC or LS_RJT (by contents of word 0). The reject -	 *     data will be in word 1. -	 *  b) A status of FC_CTELS_STATUS_REJECT is returned, The -	 *     rjt_data field will contain valid data. -	 * -	 * Note: ELS LS_ACC is determined by an FC_CTELS_STATUS_OK, and -	 *   the receive payload word 0 indicates LS_ACC -	 *   (e.g. value is 0x02xxxxxx). -	 * -	 * Note: Similarly, a CT Reject may be reported in 2 ways: -	 *  a) A status of FC_CTELS_STATUS_OK is returned. The caller -	 *     is to look into the CT receive payload to determine -	 *     Accept or Reject (by contents of word 2). The reject -	 *     data will be in word 3. -	 *  b) A status of FC_CTELS_STATUS_REJECT is returned, The -	 *     rjt_data field will contain valid data. -	 * -	 * Note: x_RJT/BSY status will indicae that the rjt_data field -	 *   is valid and contains the reason/explanation values. -	 */ -	uint32_t	status;		/* See FC_CTELS_STATUS_xxx */ - -	/* valid if status is not FC_CTELS_STATUS_OK */ -	struct	{ -		uint8_t	action;		/* fragment_id for CT REJECT */ -		uint8_t	reason_code; -		uint8_t	reason_explanation; -		uint8_t	vendor_unique; -	} rjt_data; -}; - - -/* FC_BSG_HST_CT : */ - -/* Request: - * This message requests that a CT Request be performed with the - * indicated N_Port_ID. The driver is responsible for logging in with - * the fabric and/or N_Port_ID, etc as per FC rules. This request does - * not mandate that the driver must enumerate the destination in the - * transport. The driver is allowed to decide whether to enumerate it, - * and whether to tear it down after the request. - */ -struct fc_bsg_host_ct { -	uint8_t		reserved; - -	/* FC Address Identier of the remote port to send the ELS to */ -	uint8_t		port_id[3]; - -	/* -	 * We need words 0-2 of the generic preamble for the LLD's -	 */ -	uint32_t	preamble_word0;	/* revision & IN_ID */ -	uint32_t	preamble_word1;	/* GS_Type, GS_SubType, Options, Rsvd */ -	uint32_t	preamble_word2;	/* Cmd Code, Max Size */ - -}; -/* Response: - * - * The reply structure is an fc_bsg_ctels_reply structure - */ - - -/* FC_BSG_HST_VENDOR : */ - -/* Request: - * Note: When specifying vendor_id, be sure to read the Vendor Type and ID - *   formatting requirements specified in scsi_netlink.h - */ -struct fc_bsg_host_vendor { -	/* -	 * Identifies the vendor that the message is formatted for. This -	 * should be the recipient of the message. -	 */ -	uint64_t vendor_id; - -	/* start of vendor command area */ -	uint32_t vendor_cmd[0]; -}; - -/* Response: - */ -struct fc_bsg_host_vendor_reply { -	/* start of vendor response area */ -	uint32_t vendor_rsp[0]; -}; - - - -/* - * FC Remote Port Messages - */ - -/* FC_BSG_RPT_ELS : */ - -/* Request: - * This message requests that an ELS be performed with the rport. - */ -struct fc_bsg_rport_els { -	/* -	 * ELS Command Code being sent (must be the same as -	 * byte 0 of the payload) -	 */ -	uint8_t els_code; -}; - -/* Response: - * - * The reply structure is an fc_bsg_ctels_reply structure - */ - - -/* FC_BSG_RPT_CT : */ - -/* Request: - * This message requests that a CT Request be performed with the rport. - */ -struct fc_bsg_rport_ct { -	/* -	 * We need words 0-2 of the generic preamble for the LLD's -	 */ -	uint32_t	preamble_word0;	/* revision & IN_ID */ -	uint32_t	preamble_word1;	/* GS_Type, GS_SubType, Options, Rsvd */ -	uint32_t	preamble_word2;	/* Cmd Code, Max Size */ -}; -/* Response: - * - * The reply structure is an fc_bsg_ctels_reply structure - */ - - - - -/* request (CDB) structure of the sg_io_v4 */ -struct fc_bsg_request { -	uint32_t msgcode; -	union { -		struct fc_bsg_host_add_rport	h_addrport; -		struct fc_bsg_host_del_rport	h_delrport; -		struct fc_bsg_host_els		h_els; -		struct fc_bsg_host_ct		h_ct; -		struct fc_bsg_host_vendor	h_vendor; - -		struct fc_bsg_rport_els		r_els; -		struct fc_bsg_rport_ct		r_ct; -	} rqst_data; -} __attribute__((packed)); - - -/* response (request sense data) structure of the sg_io_v4 */ -struct fc_bsg_reply { -	/* -	 * The completion result. Result exists in two forms: -	 *  if negative, it is an -Exxx system errno value. There will -	 *    be no further reply information supplied. -	 *  else, it's the 4-byte scsi error result, with driver, host, -	 *    msg and status fields. The per-msgcode reply structure -	 *    will contain valid data. -	 */ -	uint32_t result; - -	/* If there was reply_payload, how much was recevied ? */ -	uint32_t reply_payload_rcv_len; - -	union { -		struct fc_bsg_host_vendor_reply		vendor_reply; - -		struct fc_bsg_ctels_reply		ctels_reply; -	} reply_data; -}; - - -#endif /* SCSI_BSG_FC_H */ - diff --git a/include/scsi/scsi_bsg_iscsi.h b/include/scsi/scsi_bsg_iscsi.h new file mode 100644 index 00000000000..fd5689d4c05 --- /dev/null +++ b/include/scsi/scsi_bsg_iscsi.h @@ -0,0 +1,110 @@ +/* + *  iSCSI Transport BSG Interface + * + *  Copyright (C) 2009   James Smart, Emulex Corporation + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef SCSI_BSG_ISCSI_H +#define SCSI_BSG_ISCSI_H + +/* + * This file intended to be included by both kernel and user space + */ + +#include <scsi/scsi.h> + +/* + * iSCSI Transport SGIO v4 BSG Message Support + */ + +/* Default BSG request timeout (in seconds) */ +#define ISCSI_DEFAULT_BSG_TIMEOUT      (10 * HZ) + + +/* + * Request Message Codes supported by the iSCSI Transport + */ + +/* define the class masks for the message codes */ +#define ISCSI_BSG_CLS_MASK     0xF0000000      /* find object class */ +#define ISCSI_BSG_HST_MASK     0x80000000      /* iscsi host class */ + +/* iscsi host Message Codes */ +#define ISCSI_BSG_HST_VENDOR           (ISCSI_BSG_HST_MASK | 0x000000FF) + + +/* + * iSCSI Host Messages + */ + +/* ISCSI_BSG_HST_VENDOR : */ + +/* Request: + * Note: When specifying vendor_id, be sure to read the Vendor Type and ID + *   formatting requirements specified in scsi_netlink.h + */ +struct iscsi_bsg_host_vendor { +	/* +	 * Identifies the vendor that the message is formatted for. This +	 * should be the recipient of the message. +	 */ +	uint64_t vendor_id; + +	/* start of vendor command area */ +	uint32_t vendor_cmd[0]; +}; + +/* Response: + */ +struct iscsi_bsg_host_vendor_reply { +	/* start of vendor response area */ +	uint32_t vendor_rsp[0]; +}; + + +/* request (CDB) structure of the sg_io_v4 */ +struct iscsi_bsg_request { +	uint32_t msgcode; +	union { +		struct iscsi_bsg_host_vendor    h_vendor; +	} rqst_data; +} __attribute__((packed)); + + +/* response (request sense data) structure of the sg_io_v4 */ +struct iscsi_bsg_reply { +	/* +	 * The completion result. Result exists in two forms: +	 * if negative, it is an -Exxx system errno value. There will +	 * be no further reply information supplied. +	 * else, it's the 4-byte scsi error result, with driver, host, +	 * msg and status fields. The per-msgcode reply structure +	 * will contain valid data. +	 */ +	uint32_t result; + +	/* If there was reply_payload, how much was recevied ? */ +	uint32_t reply_payload_rcv_len; + +	union { +		struct iscsi_bsg_host_vendor_reply      vendor_reply; +	} reply_data; +}; + + +#endif /* SCSI_BSG_ISCSI_H */ diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index a5e885a111d..e0ae7109814 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -7,9 +7,11 @@  #include <linux/types.h>  #include <linux/timer.h>  #include <linux/scatterlist.h> +#include <scsi/scsi_device.h>  struct Scsi_Host;  struct scsi_device; +struct scsi_driver;  /*   * MAX_COMMAND_SIZE is: @@ -54,6 +56,7 @@ struct scsi_cmnd {  	struct scsi_device *device;  	struct list_head list;  /* scsi_cmnd participates in queue lists */  	struct list_head eh_entry; /* entry for the host eh_cmd_q */ +	struct delayed_work abort_work;  	int eh_eflags;		/* Used by error handlr */  	/* @@ -131,11 +134,25 @@ struct scsi_cmnd {  	unsigned char tag;	/* SCSI-II queued command tag */  }; +/* + * Return the driver private allocation behind the command. + * Only works if cmd_size is set in the host template. + */ +static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd) +{ +	return cmd + 1; +} + +/* make sure not to use it with REQ_TYPE_BLOCK_PC commands */ +static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) +{ +	return *(struct scsi_driver **)cmd->request->rq_disk->private_data; +} +  extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);  extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t);  extern void scsi_put_command(struct scsi_cmnd *); -extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, -			       struct device *); +extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *);  extern void scsi_finish_command(struct scsi_cmnd *cmd);  extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, @@ -148,9 +165,6 @@ extern void scsi_release_buffers(struct scsi_cmnd *cmd);  extern int scsi_dma_map(struct scsi_cmnd *cmd);  extern void scsi_dma_unmap(struct scsi_cmnd *cmd); -struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask); -void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd); -  static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)  {  	return cmd->sdb.table.nents; @@ -289,17 +303,33 @@ static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd)  static inline void set_msg_byte(struct scsi_cmnd *cmd, char status)  { -	cmd->result |= status << 8; +	cmd->result = (cmd->result & 0xffff00ff) | (status << 8);  }  static inline void set_host_byte(struct scsi_cmnd *cmd, char status)  { -	cmd->result |= status << 16; +	cmd->result = (cmd->result & 0xff00ffff) | (status << 16);  }  static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)  { -	cmd->result |= status << 24; +	cmd->result = (cmd->result & 0x00ffffff) | (status << 24); +} + +static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) +{ +	unsigned int xfer_len = scsi_out(scmd)->length; +	unsigned int prot_op = scsi_get_prot_op(scmd); +	unsigned int sector_size = scmd->device->sector_size; + +	switch (prot_op) { +	case SCSI_PROT_NORMAL: +	case SCSI_PROT_WRITE_STRIP: +	case SCSI_PROT_READ_INSERT: +		return xfer_len; +	} + +	return xfer_len + (xfer_len >> ilog2(sector_size)) * 8;  }  #endif /* _SCSI_SCSI_CMND_H */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 85867dcde33..27ab31017f0 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -1,14 +1,14 @@  #ifndef _SCSI_SCSI_DEVICE_H  #define _SCSI_SCSI_DEVICE_H -#include <linux/device.h>  #include <linux/list.h>  #include <linux/spinlock.h>  #include <linux/workqueue.h>  #include <linux/blkdev.h>  #include <scsi/scsi.h> -#include <asm/atomic.h> +#include <linux/atomic.h> +struct device;  struct request_queue;  struct scsi_cmnd;  struct scsi_lun; @@ -42,6 +42,7 @@ enum scsi_device_state {  				 * originate in the mid-layer) */  	SDEV_OFFLINE,		/* Device offlined (by error handling or  				 * user request */ +	SDEV_TRANSPORT_OFFLINE,	/* Offlined by transport class error handler */  	SDEV_BLOCK,		/* Device blocked by scsi lld.  No  				 * scsi commands from user or midlayer  				 * should be issued to the scsi @@ -51,8 +52,15 @@ enum scsi_device_state {  enum scsi_device_event {  	SDEV_EVT_MEDIA_CHANGE	= 1,	/* media has changed */ +	SDEV_EVT_INQUIRY_CHANGE_REPORTED,		/* 3F 03  UA reported */ +	SDEV_EVT_CAPACITY_CHANGE_REPORTED,		/* 2A 09  UA reported */ +	SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED,	/* 38 07  UA reported */ +	SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED,	/* 2A 01  UA reported */ +	SDEV_EVT_LUN_CHANGE_REPORTED,			/* 3F 0E  UA reported */ + +	SDEV_EVT_FIRST		= SDEV_EVT_MEDIA_CHANGE, +	SDEV_EVT_LAST		= SDEV_EVT_LUN_CHANGE_REPORTED, -	SDEV_EVT_LAST		= SDEV_EVT_MEDIA_CHANGE,  	SDEV_EVT_MAXBITS	= SDEV_EVT_LAST + 1  }; @@ -105,6 +113,12 @@ struct scsi_device {  	const char * vendor;		/* [back_compat] point into 'inquiry' ... */  	const char * model;		/* ... after scan; point to static string */  	const char * rev;		/* ... "nullnullnullnull" before scan */ + +#define SCSI_VPD_PG_LEN                255 +	int vpd_pg83_len; +	unsigned char *vpd_pg83; +	int vpd_pg80_len; +	unsigned char *vpd_pg80;  	unsigned char current_tag;	/* current tag */  	struct scsi_target      *sdev_target;   /* used only for single_lun */ @@ -112,6 +126,7 @@ struct scsi_device {  				 * scsi_devinfo.[hc]. For now used only to  				 * pass settings from slave_alloc to scsi  				 * core. */ +	unsigned int eh_timeout; /* Error handling timeout */  	unsigned writeable:1;  	unsigned removable:1;  	unsigned changed:1;	/* Data invalid due to media change */ @@ -134,8 +149,12 @@ struct scsi_device {  				     * because we did a bus reset. */  	unsigned use_10_for_rw:1; /* first try 10-byte read / write */  	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ +	unsigned no_report_opcodes:1;	/* no REPORT SUPPORTED OPERATION CODES */ +	unsigned no_write_same:1;	/* no WRITE SAME command */ +	unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */  	unsigned skip_ms_page_8:1;	/* do not use MODE SENSE page 0x08 */  	unsigned skip_ms_page_3f:1;	/* do not use MODE SENSE page 0x3f */ +	unsigned skip_vpd_pages:1;	/* do not read VPD pages */  	unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */  	unsigned no_start_on_add:1;	/* do not issue start on add */  	unsigned allow_restart:1; /* issue START_UNIT in error handler */ @@ -150,9 +169,16 @@ struct scsi_device {  					   SD_LAST_BUGGY_SECTORS */  	unsigned no_read_disc_info:1;	/* Avoid READ_DISC_INFO cmds */  	unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */ +	unsigned try_rc_10_first:1;	/* Try READ_CAPACACITY_10 first */  	unsigned is_visible:1;	/* is the device visible in sysfs */ +	unsigned wce_default_on:1;	/* Cache is ON by default */ +	unsigned no_dif:1;	/* T10 PI (DIF) should be disabled */ +	unsigned broken_fua:1;		/* Don't set FUA bit */ + +	atomic_t disk_events_disable_depth; /* disable depth for disk events */  	DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ +	DECLARE_BITMAP(pending_events, SDEV_EVT_MAXBITS); /* pending events */  	struct list_head event_list;	/* asserted events */  	struct work_struct event_work; @@ -169,6 +195,7 @@ struct scsi_device {  				sdev_dev;  	struct execute_work	ew; /* used to get process context on put */ +	struct work_struct	requeue_work;  	struct scsi_dh_data	*scsi_dh_data;  	enum scsi_device_state sdev_state; @@ -195,6 +222,7 @@ struct scsi_device_handler {  	int (*activate)(struct scsi_device *, activate_complete, void *);  	int (*prep_fn)(struct scsi_device *, struct request *);  	int (*set_params)(struct scsi_device *, const char *); +	bool (*match)(struct scsi_device *);  };  struct scsi_dh_data { @@ -214,12 +242,24 @@ struct scsi_dh_data {  #define sdev_printk(prefix, sdev, fmt, a...)	\  	dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a) +#define sdev_dbg(sdev, fmt, a...) \ +	dev_dbg(&(sdev)->sdev_gendev, fmt, ##a) +  #define scmd_printk(prefix, scmd, fmt, a...)				\          (scmd)->request->rq_disk ?					\  	sdev_printk(prefix, (scmd)->device, "[%s] " fmt,		\  		    (scmd)->request->rq_disk->disk_name, ##a) :		\  	sdev_printk(prefix, (scmd)->device, fmt, ##a) +#define scmd_dbg(scmd, fmt, a...)					   \ +	do {								   \ +		if ((scmd)->request->rq_disk)				   \ +			sdev_dbg((scmd)->device, "[%s] " fmt,		   \ +				 (scmd)->request->rq_disk->disk_name, ##a);\ +		else							   \ +			sdev_dbg((scmd)->device, fmt, ##a);		   \ +	} while (0) +  enum scsi_target_state {  	STARGET_CREATED = 1,  	STARGET_RUNNING, @@ -236,7 +276,7 @@ struct scsi_target {  	struct list_head	siblings;  	struct list_head	devices;  	struct device		dev; -	unsigned int		reap_ref; /* protected by the host lock */ +	struct kref		reap_ref; /* last put renders target invisible */  	unsigned int		channel;  	unsigned int		id; /* target id ... replace  				     * scsi_device.id eventually */ @@ -244,8 +284,13 @@ struct scsi_target {  	unsigned int		single_lun:1;	/* Indicates we should only  						 * allow I/O to one of the luns  						 * for the device at a time. */ -	unsigned int		pdt_1f_for_no_lun;	/* PDT = 0x1f */ -						/* means no lun present */ +	unsigned int		pdt_1f_for_no_lun:1;	/* PDT = 0x1f +						 * means no lun present. */ +	unsigned int		no_report_luns:1;	/* Don't use +						 * REPORT LUNS for scanning. */ +	unsigned int		expecting_lun_change:1;	/* A device has reported +						 * a 3F/0E UA, other devices on +						 * the same target will also. */  	/* commands actually active on LLD. protected by host lock. */  	unsigned int		target_busy;  	/* @@ -258,7 +303,6 @@ struct scsi_target {  #define SCSI_DEFAULT_TARGET_BLOCKED	3  	char			scsi_level; -	struct execute_work	ew;  	enum scsi_target_state	state;  	void 			*hostdata; /* available to low-level driver */  	unsigned long		starget_data[0]; /* for the transport */ @@ -283,6 +327,7 @@ extern int scsi_add_device(struct Scsi_Host *host, uint channel,  extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh);  extern void scsi_remove_device(struct scsi_device *);  extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); +void scsi_attach_vpd(struct scsi_device *sdev);  extern int scsi_device_get(struct scsi_device *);  extern void scsi_device_put(struct scsi_device *); @@ -352,6 +397,8 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,  				int retries, struct scsi_sense_hdr *sshdr);  extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf,  			     int buf_len); +extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, +			      unsigned int len, unsigned char opcode);  extern int scsi_device_set_state(struct scsi_device *sdev,  				 enum scsi_device_state state);  extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, @@ -367,7 +414,7 @@ extern void scsi_scan_target(struct device *parent, unsigned int channel,  			     unsigned int id, unsigned int lun, int rescan);  extern void scsi_target_reap(struct scsi_target *);  extern void scsi_target_block(struct device *); -extern void scsi_target_unblock(struct device *); +extern void scsi_target_unblock(struct device *, enum scsi_device_state);  extern void scsi_remove_target(struct device *);  extern void int_to_scsilun(unsigned int, struct scsi_lun *);  extern int scsilun_to_int(struct scsi_lun *); @@ -377,11 +424,21 @@ extern int scsi_is_target_device(const struct device *);  extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,  			int data_direction, void *buffer, unsigned bufflen,  			unsigned char *sense, int timeout, int retries, -			int flag, int *resid); -extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, -			    int data_direction, void *buffer, unsigned bufflen, -			    struct scsi_sense_hdr *, int timeout, int retries, -			    int *resid); +			u64 flags, int *resid); +extern int scsi_execute_req_flags(struct scsi_device *sdev, +	const unsigned char *cmd, int data_direction, void *buffer, +	unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, +	int retries, int *resid, u64 flags); +static inline int scsi_execute_req(struct scsi_device *sdev, +	const unsigned char *cmd, int data_direction, void *buffer, +	unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, +	int retries, int *resid) +{ +	return scsi_execute_req_flags(sdev, cmd, data_direction, buffer, +		bufflen, sshdr, timeout, retries, resid, 0); +} +extern void sdev_disable_disk_events(struct scsi_device *sdev); +extern void sdev_enable_disk_events(struct scsi_device *sdev);  #ifdef CONFIG_PM_RUNTIME  extern int scsi_autopm_get_device(struct scsi_device *); @@ -415,6 +472,7 @@ static inline unsigned int sdev_id(struct scsi_device *sdev)  static inline int scsi_device_online(struct scsi_device *sdev)  {  	return (sdev->sdev_state != SDEV_OFFLINE && +		sdev->sdev_state != SDEV_TRANSPORT_OFFLINE &&  		sdev->sdev_state != SDEV_DEL);  }  static inline int scsi_device_blocked(struct scsi_device *sdev) @@ -461,14 +519,22 @@ static inline int scsi_device_qas(struct scsi_device *sdev)  }  static inline int scsi_device_enclosure(struct scsi_device *sdev)  { -	return sdev->inquiry[6] & (1<<6); +	return sdev->inquiry ? (sdev->inquiry[6] & (1<<6)) : 1;  }  static inline int scsi_device_protection(struct scsi_device *sdev)  { +	if (sdev->no_dif) +		return 0; +  	return sdev->scsi_level > SCSI_2 && sdev->inquiry[5] & (1<<0);  } +static inline int scsi_device_tpgs(struct scsi_device *sdev) +{ +	return sdev->inquiry ? (sdev->inquiry[5] >> 4) & 0x3 : 0; +} +  #define MODULE_ALIAS_SCSI_DEVICE(type) \  	MODULE_ALIAS("scsi:t-" __stringify(type) "*")  #define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h index b4ddd3b18b4..447d2d7466f 100644 --- a/include/scsi/scsi_devinfo.h +++ b/include/scsi/scsi_devinfo.h @@ -30,4 +30,6 @@  #define BLIST_RETRY_HWERROR	0x400000 /* retry HARDWARE_ERROR */  #define BLIST_MAX_512		0x800000 /* maximum 512 sector cdb length */  #define BLIST_ATTACH_PQ3	0x1000000 /* Scan: Attach to PQ3 devices */ +#define BLIST_NO_DIF		0x2000000 /* Disable T10 PI (DIF) */ +#define BLIST_SKIP_VPD_PAGES	0x4000000 /* Ignore SBC-3 VPD pages */  #endif diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h index e3f2db212dd..620c723ee8e 100644 --- a/include/scsi/scsi_dh.h +++ b/include/scsi/scsi_dh.h @@ -60,6 +60,7 @@ extern int scsi_dh_activate(struct request_queue *, activate_complete, void *);  extern int scsi_dh_handler_exist(const char *);  extern int scsi_dh_attach(struct request_queue *, const char *);  extern void scsi_dh_detach(struct request_queue *); +extern const char *scsi_dh_attached_handler_name(struct request_queue *, gfp_t);  extern int scsi_dh_set_params(struct request_queue *, const char *);  #else  static inline int scsi_dh_activate(struct request_queue *req, @@ -80,6 +81,11 @@ static inline void scsi_dh_detach(struct request_queue *q)  {  	return;  } +static inline const char *scsi_dh_attached_handler_name(struct request_queue *q, +							gfp_t gfp) +{ +	return NULL; +}  static inline int scsi_dh_set_params(struct request_queue *req, const char *params)  {  	return -SCSI_DH_NOSYS; diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 9fd6702f02e..36c4114ed9b 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -4,18 +4,19 @@  #include <linux/device.h>  struct module; +struct request;  struct scsi_cmnd;  struct scsi_device; -struct request; -struct request_queue; -  struct scsi_driver {  	struct module		*owner;  	struct device_driver	gendrv;  	void (*rescan)(struct device *); +	int (*init_command)(struct scsi_cmnd *); +	void (*uninit_command)(struct scsi_cmnd *);  	int (*done)(struct scsi_cmnd *); +	int (*eh_action)(struct scsi_cmnd *, int);  };  #define to_scsi_driver(drv) \  	container_of((drv), struct scsi_driver, gendrv) @@ -30,8 +31,5 @@ extern int scsi_register_interface(struct class_interface *);  int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req);  int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); -int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); -int scsi_prep_return(struct request_queue *q, struct request *req, int ret); -int scsi_prep_fn(struct request_queue *, struct request *);  #endif /* _SCSI_SCSI_DRIVER_H */ diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index d0a6a845f20..94844fc77b9 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -6,6 +6,7 @@  #include <linux/types.h>  #include <linux/workqueue.h>  #include <linux/mutex.h> +#include <linux/seq_file.h>  #include <scsi/scsi.h>  struct request_queue; @@ -14,6 +15,7 @@ struct completion;  struct module;  struct scsi_cmnd;  struct scsi_device; +struct scsi_host_cmd_pool;  struct scsi_target;  struct Scsi_Host;  struct scsi_host_cmd_pool; @@ -46,7 +48,7 @@ struct blk_queue_tags;  enum {  	SCSI_QDEPTH_DEFAULT,	/* default requested change, e.g. from sysfs */  	SCSI_QDEPTH_QFULL,	/* scsi-ml requested due to queue full */ -	SCSI_QDEPTH_RAMP_UP,	/* scsi-ml requested due to threshhold event */ +	SCSI_QDEPTH_RAMP_UP,	/* scsi-ml requested due to threshold event */  };  struct scsi_host_template { @@ -127,8 +129,7 @@ struct scsi_host_template {  	 *  	 * STATUS: REQUIRED  	 */ -	int (* queuecommand)(struct scsi_cmnd *, -			     void (*done)(struct scsi_cmnd *)); +	int (* queuecommand)(struct Scsi_Host *, struct scsi_cmnd *);  	/*  	 * The transfer functions are used to queue a scsi command to @@ -341,7 +342,8 @@ struct scsi_host_template {  	 *  	 * Status: OBSOLETE  	 */ -	int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int); +	int (*show_info)(struct seq_file *, struct Scsi_Host *); +	int (*write_info)(struct Scsi_Host *, char *, int);  	/*  	 * This is an optional routine that allows the transport to become @@ -356,6 +358,19 @@ struct scsi_host_template {  	 */  	enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *); +	/* This is an optional routine that allows transport to initiate +	 * LLD adapter or firmware reset using sysfs attribute. +	 * +	 * Return values: 0 on success, -ve value on failure. +	 * +	 * Status: OPTIONAL +	 */ + +	int (*host_reset)(struct Scsi_Host *shost, int reset_type); +#define SCSI_ADAPTER_RESET	1 +#define SCSI_FIRMWARE_RESET	2 + +  	/*  	 * Name of proc directory  	 */ @@ -363,7 +378,7 @@ struct scsi_host_template {  	/*  	 * Used to store the procfs directory if a driver implements the -	 * proc_info method. +	 * show_info method.  	 */  	struct proc_dir_entry *proc_dir; @@ -461,6 +476,14 @@ struct scsi_host_template {  	 */  	unsigned ordered_tag:1; +	/* True if the controller does not support WRITE SAME */ +	unsigned no_write_same:1; + +	/* +	 * True if asynchronous aborts are not supported +	 */ +	unsigned no_async_abort:1; +  	/*  	 * Countdown for host blocking with no commands outstanding.  	 */ @@ -502,9 +525,34 @@ struct scsi_host_template {  	 *   scsi_netlink.h  	 */  	u64 vendor_id; + +	/* +	 * Additional per-command data allocated for the driver. +	 */ +	unsigned int cmd_size; +	struct scsi_host_cmd_pool *cmd_pool;  };  /* + * Temporary #define for host lock push down. Can be removed when all + * drivers have been updated to take advantage of unlocked + * queuecommand. + * + */ +#define DEF_SCSI_QCMD(func_name) \ +	int func_name(struct Scsi_Host *shost, struct scsi_cmnd *cmd)	\ +	{								\ +		unsigned long irq_flags;				\ +		int rc;							\ +		spin_lock_irqsave(shost->host_lock, irq_flags);		\ +		scsi_cmd_get_serial(shost, cmd);			\ +		rc = func_name##_lck (cmd, cmd->scsi_done);			\ +		spin_unlock_irqrestore(shost->host_lock, irq_flags);	\ +		return rc;						\ +	} + + +/*   * shost state: If you alter this, you also need to alter scsi_sysfs.c   * (for the ascii descriptions) and the state model enforcer:   * scsi_host_set_state() @@ -565,9 +613,12 @@ struct Scsi_Host {  	unsigned int host_eh_scheduled;    /* EH scheduled without command */  	unsigned int host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ -	int resetting; /* if set, it means that last_reset is a valid value */ + +	/* next two fields are used to bound the time spent in error handling */ +	int eh_deadline;  	unsigned long last_reset; +  	/*  	 * These three parameters can be used to allow for wide scsi,  	 * and for host adapters that support multiple busses @@ -638,6 +689,12 @@ struct Scsi_Host {  	/* Asynchronous scan in progress */  	unsigned async_scan:1; +	/* Don't resume host in EH */ +	unsigned eh_noresume:1; + +	/* The controller does not support WRITE SAME */ +	unsigned no_write_same:1; +  	/*  	 * Optional work queue to be utilized by the transport  	 */ @@ -645,6 +702,11 @@ struct Scsi_Host {  	struct workqueue_struct *work_q;  	/* +	 * Task management function work queue +	 */ +	struct workqueue_struct *tmf_work_q; + +	/*  	 * Host has rejected a command because it was busy.  	 */  	unsigned int host_blocked; @@ -752,6 +814,7 @@ extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);  extern void scsi_host_put(struct Scsi_Host *t);  extern struct Scsi_Host *scsi_host_lookup(unsigned short);  extern const char *scsi_host_state_name(enum scsi_host_state); +extern void scsi_cmd_get_serial(struct Scsi_Host *, struct scsi_cmnd *);  extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *); @@ -772,7 +835,8 @@ static inline struct device *scsi_get_device(struct Scsi_Host *shost)   **/  static inline int scsi_host_scan_allowed(struct Scsi_Host *shost)  { -	return shost->shost_state == SHOST_RUNNING; +	return shost->shost_state == SHOST_RUNNING || +	       shost->shost_state == SHOST_RECOVERY;  }  extern void scsi_unblock_requests(struct Scsi_Host *); @@ -837,6 +901,9 @@ static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsign  				       SHOST_DIF_TYPE2_PROTECTION,  				       SHOST_DIF_TYPE3_PROTECTION }; +	if (target_type >= ARRAY_SIZE(cap)) +		return 0; +  	return shost->prot_capabilities & cap[target_type] ? target_type : 0;  } @@ -848,6 +915,9 @@ static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsign  				       SHOST_DIX_TYPE2_PROTECTION,  				       SHOST_DIX_TYPE3_PROTECTION }; +	if (target_type >= ARRAY_SIZE(cap)) +		return 0; +  	return shost->prot_capabilities & cap[target_type];  #endif  	return 0; diff --git a/include/scsi/scsi_netlink.h b/include/scsi/scsi_netlink.h deleted file mode 100644 index 58ce8fe4478..00000000000 --- a/include/scsi/scsi_netlink.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - *  SCSI Transport Netlink Interface - *    Used for the posting of outbound SCSI transport events - * - *  Copyright (C) 2006   James Smart, Emulex Corporation - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#ifndef SCSI_NETLINK_H -#define SCSI_NETLINK_H - -#include <linux/netlink.h> - - -/* - * This file intended to be included by both kernel and user space - */ - -/* Single Netlink Message type to send all SCSI Transport messages */ -#define SCSI_TRANSPORT_MSG		NLMSG_MIN_TYPE + 1 - -/* SCSI Transport Broadcast Groups */ -	/* leaving groups 0 and 1 unassigned */ -#define SCSI_NL_GRP_FC_EVENTS		(1<<2)		/* Group 2 */ -#define SCSI_NL_GRP_CNT			3 - - -/* SCSI_TRANSPORT_MSG event message header */ -struct scsi_nl_hdr { -	uint8_t version; -	uint8_t transport; -	uint16_t magic; -	uint16_t msgtype; -	uint16_t msglen; -} __attribute__((aligned(sizeof(uint64_t)))); - -/* scsi_nl_hdr->version value */ -#define SCSI_NL_VERSION				1 - -/* scsi_nl_hdr->magic value */ -#define SCSI_NL_MAGIC				0xA1B2 - -/* scsi_nl_hdr->transport value */ -#define SCSI_NL_TRANSPORT			0 -#define SCSI_NL_TRANSPORT_FC			1 -#define SCSI_NL_MAX_TRANSPORTS			2 - -/* Transport-based scsi_nl_hdr->msgtype values are defined in each transport */ - -/* - * GENERIC SCSI scsi_nl_hdr->msgtype Values - */ -	/* kernel -> user */ -#define SCSI_NL_SHOST_VENDOR			0x0001 -	/* user -> kernel */ -/* SCSI_NL_SHOST_VENDOR msgtype is kernel->user and user->kernel */ - - -/* - * Message Structures : - */ - -/* macro to round up message lengths to 8byte boundary */ -#define SCSI_NL_MSGALIGN(len)		(((len) + 7) & ~7) - - -/* - * SCSI HOST Vendor Unique messages : - *   SCSI_NL_SHOST_VENDOR - * - * Note: The Vendor Unique message payload will begin directly after - * 	 this structure, with the length of the payload per vmsg_datalen. - * - * Note: When specifying vendor_id, be sure to read the Vendor Type and ID - *   formatting requirements specified below - */ -struct scsi_nl_host_vendor_msg { -	struct scsi_nl_hdr snlh;		/* must be 1st element ! */ -	uint64_t vendor_id; -	uint16_t host_no; -	uint16_t vmsg_datalen; -} __attribute__((aligned(sizeof(uint64_t)))); - - -/* - * Vendor ID: - *   If transports post vendor-unique events, they must pass a well-known - *   32-bit vendor identifier. This identifier consists of 8 bits indicating - *   the "type" of identifier contained, and 24 bits of id data. - * - *   Identifiers for each type: - *    PCI :  ID data is the 16 bit PCI Registered Vendor ID - */ -#define SCSI_NL_VID_TYPE_SHIFT		56 -#define SCSI_NL_VID_TYPE_MASK		((__u64)0xFF << SCSI_NL_VID_TYPE_SHIFT) -#define SCSI_NL_VID_TYPE_PCI		((__u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) -#define SCSI_NL_VID_ID_MASK		(~ SCSI_NL_VID_TYPE_MASK) - - -#define INIT_SCSI_NL_HDR(hdr, t, mtype, mlen)			\ -	{							\ -	(hdr)->version = SCSI_NL_VERSION;			\ -	(hdr)->transport = t;					\ -	(hdr)->magic = SCSI_NL_MAGIC;				\ -	(hdr)->msgtype = mtype;					\ -	(hdr)->msglen = mlen;					\ -	} - - -#ifdef __KERNEL__ - -#include <scsi/scsi_host.h> - -/* Exported Kernel Interfaces */ -int scsi_nl_add_transport(u8 tport, -	 int (*msg_handler)(struct sk_buff *), -	void (*event_handler)(struct notifier_block *, unsigned long, void *)); -void scsi_nl_remove_transport(u8 tport); - -int scsi_nl_add_driver(u64 vendor_id, struct scsi_host_template *hostt, -	int (*nlmsg_handler)(struct Scsi_Host *shost, void *payload, -				 u32 len, u32 pid), -	void (*nlevt_handler)(struct notifier_block *nb, -				 unsigned long event, void *notify_ptr)); -void scsi_nl_remove_driver(u64 vendor_id); - -void scsi_nl_send_transport_msg(u32 pid, struct scsi_nl_hdr *hdr); -int scsi_nl_send_vendor_msg(u32 pid, unsigned short host_no, u64 vendor_id, -			 char *data_buf, u32 data_len); - -#endif /* __KERNEL__ */ - -#endif /* SCSI_NETLINK_H */ - diff --git a/include/scsi/scsi_netlink_fc.h b/include/scsi/scsi_netlink_fc.h deleted file mode 100644 index cbf76e47976..00000000000 --- a/include/scsi/scsi_netlink_fc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - *  FC Transport Netlink Interface - * - *  Copyright (C) 2006   James Smart, Emulex Corporation - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#ifndef SCSI_NETLINK_FC_H -#define SCSI_NETLINK_FC_H - -#include <scsi/scsi_netlink.h> - -/* - * This file intended to be included by both kernel and user space - */ - -/* - * FC Transport Message Types - */ -	/* kernel -> user */ -#define FC_NL_ASYNC_EVENT			0x0100 -	/* user -> kernel */ -/* none */ - - -/* - * Message Structures : - */ - -/* macro to round up message lengths to 8byte boundary */ -#define FC_NL_MSGALIGN(len)		(((len) + 7) & ~7) - - -/* - * FC Transport Broadcast Event Message : - *   FC_NL_ASYNC_EVENT - * - * Note: if Vendor Unique message, &event_data will be  start of - * 	 vendor unique payload, and the length of the payload is - *       per event_datalen - * - * Note: When specifying vendor_id, be sure to read the Vendor Type and ID - *   formatting requirements specified in scsi_netlink.h - */ -struct fc_nl_event { -	struct scsi_nl_hdr snlh;		/* must be 1st element ! */ -	uint64_t seconds; -	uint64_t vendor_id; -	uint16_t host_no; -	uint16_t event_datalen; -	uint32_t event_num; -	uint32_t event_code; -	uint32_t event_data; -} __attribute__((aligned(sizeof(uint64_t)))); - - -#endif /* SCSI_NETLINK_FC_H */ - diff --git a/include/scsi/scsi_scan.h b/include/scsi/scsi_scan.h deleted file mode 100644 index 78898889243..00000000000 --- a/include/scsi/scsi_scan.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _SCSI_SCSI_SCAN_H -#define _SCSI_SCSI_SCAN_H - -#ifdef CONFIG_SCSI -/* drivers/scsi/scsi_scan.c */ -extern int scsi_complete_async_scans(void); -#else -static inline int scsi_complete_async_scans(void) { return 0; } -#endif - -#endif /* _SCSI_SCSI_SCAN_H */ diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h index d6e7994aa63..81dd12edc38 100644 --- a/include/scsi/scsi_tcq.h +++ b/include/scsi/scsi_tcq.h @@ -9,6 +9,7 @@  #define MSG_SIMPLE_TAG	0x20  #define MSG_HEAD_TAG	0x21  #define MSG_ORDERED_TAG	0x22 +#define MSG_ACA_TAG	0x24	/* unsupported */  #define SCSI_NO_TAG	(-1)    /* identify no tag in use */ diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h index 0de32cd4e8a..af244f4bba5 100644 --- a/include/scsi/scsi_transport.h +++ b/include/scsi/scsi_transport.h @@ -22,6 +22,7 @@  #include <linux/transport_class.h>  #include <linux/blkdev.h> +#include <linux/bug.h>  #include <scsi/scsi_host.h>  #include <scsi/scsi_device.h> diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 59816fe31e6..8c79980dc8f 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -126,10 +126,11 @@ enum fc_vport_state {  					     incapable of reporting */  #define FC_PORTSPEED_1GBIT		1  #define FC_PORTSPEED_2GBIT		2 -#define FC_PORTSPEED_4GBIT		4 -#define FC_PORTSPEED_10GBIT		8 +#define FC_PORTSPEED_10GBIT		4 +#define FC_PORTSPEED_4GBIT		8  #define FC_PORTSPEED_8GBIT		0x10  #define FC_PORTSPEED_16GBIT		0x20 +#define FC_PORTSPEED_32GBIT		0x40  #define FC_PORTSPEED_NOT_NEGOTIATED	(1 << 15) /* Speed not established */  /* @@ -192,9 +193,9 @@ struct fc_vport_identifiers {   *   * This structure exists for each FC port is a virtual FC port. Virtual   * ports share the physical link with the Physical port. Each virtual - * ports has a unique presense on the SAN, and may be instantiated via + * ports has a unique presence on the SAN, and may be instantiated via   * NPIV, Virtual Fabrics, or via additional ALPAs. As the vport is a - * unique presense, each vport has it's own view of the fabric, + * unique presence, each vport has it's own view of the fabric,   * authentication privilege, and priorities.   *   * A virtual port may support 1 or more FC4 roles. Typically it is a @@ -370,7 +371,7 @@ struct fc_rport {	/* aka fc_starget_attrs */  /*   * FC SCSI Target Attributes   * - * The SCSI Target is considered an extention of a remote port (as + * The SCSI Target is considered an extension of a remote port (as   * a remote port can be more than a SCSI Target). Within the scsi   * subsystem, we leave the Target as a separate entity. Doing so   * provides backward compatibility with prior FC transport api's, @@ -426,6 +427,18 @@ struct fc_host_statistics {  	u64 fcp_control_requests;  	u64 fcp_input_megabytes;  	u64 fcp_output_megabytes; +	u64 fcp_packet_alloc_failures;	/* fcp packet allocation failures */ +	u64 fcp_packet_aborts;		/* fcp packet aborted */ +	u64 fcp_frame_alloc_failures;	/* fcp frame allocation failures */ + +	/* fc exches statistics */ +	u64 fc_no_free_exch;		/* no free exch memory */ +	u64 fc_no_free_exch_xid;	/* no free exch id */ +	u64 fc_xid_not_found;		/* exch not found for a response */ +	u64 fc_xid_busy;		/* exch exist for new a request */ +	u64 fc_seq_not_found;		/* seq is not found for exchange */ +	u64 fc_non_bls_resp;		/* a non BLS response frame with +					   a sequence responder in new exch */  }; @@ -486,6 +499,13 @@ struct fc_host_attrs {  	u32 maxframe_size;  	u16 max_npiv_vports;  	char serial_number[FC_SERIAL_NUMBER_SIZE]; +	char manufacturer[FC_SERIAL_NUMBER_SIZE]; +	char model[FC_SYMBOLIC_NAME_SIZE]; +	char model_description[FC_SYMBOLIC_NAME_SIZE]; +	char hardware_version[FC_VERSION_STRING_SIZE]; +	char driver_version[FC_VERSION_STRING_SIZE]; +	char firmware_version[FC_VERSION_STRING_SIZE]; +	char optionrom_version[FC_VERSION_STRING_SIZE];  	/* Dynamic Attributes */  	u32 port_id; @@ -541,6 +561,20 @@ struct fc_host_attrs {  	(((struct fc_host_attrs *)(x)->shost_data)->max_npiv_vports)  #define fc_host_serial_number(x)	\  	(((struct fc_host_attrs *)(x)->shost_data)->serial_number) +#define fc_host_manufacturer(x)	\ +	(((struct fc_host_attrs *)(x)->shost_data)->manufacturer) +#define fc_host_model(x)	\ +	(((struct fc_host_attrs *)(x)->shost_data)->model) +#define fc_host_model_description(x)	\ +	(((struct fc_host_attrs *)(x)->shost_data)->model_description) +#define fc_host_hardware_version(x)	\ +	(((struct fc_host_attrs *)(x)->shost_data)->hardware_version) +#define fc_host_driver_version(x)	\ +	(((struct fc_host_attrs *)(x)->shost_data)->driver_version) +#define fc_host_firmware_version(x)	\ +	(((struct fc_host_attrs *)(x)->shost_data)->firmware_version) +#define fc_host_optionrom_version(x)	\ +	(((struct fc_host_attrs *)(x)->shost_data)->optionrom_version)  #define fc_host_port_id(x)	\  	(((struct fc_host_attrs *)(x)->shost_data)->port_id)  #define fc_host_port_type(x)	\ @@ -700,6 +734,13 @@ struct fc_function_template {  	unsigned long	show_host_supported_speeds:1;  	unsigned long	show_host_maxframe_size:1;  	unsigned long	show_host_serial_number:1; +	unsigned long	show_host_manufacturer:1; +	unsigned long	show_host_model:1; +	unsigned long	show_host_model_description:1; +	unsigned long	show_host_hardware_version:1; +	unsigned long	show_host_driver_version:1; +	unsigned long	show_host_firmware_version:1; +	unsigned long	show_host_optionrom_version:1;  	/* host dynamic attributes */  	unsigned long	show_host_port_id:1;  	unsigned long	show_host_port_type:1; diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 7fff94b3b2a..2555ee5343f 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -37,6 +37,10 @@ struct iscsi_cls_conn;  struct iscsi_conn;  struct iscsi_task;  struct sockaddr; +struct iscsi_iface; +struct bsg_job; +struct iscsi_bus_flash_session; +struct iscsi_bus_flash_conn;  /**   * struct iscsi_transport - iSCSI Transport template @@ -84,9 +88,7 @@ struct iscsi_transport {  	struct module *owner;  	char *name;  	unsigned int caps; -	/* LLD sets this to indicate what values it can export to sysfs */ -	uint64_t param_mask; -	uint64_t host_param_mask; +  	struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep,  					uint16_t cmds_max, uint16_t qdepth,  					uint32_t sn); @@ -101,6 +103,8 @@ struct iscsi_transport {  	void (*destroy_conn) (struct iscsi_cls_conn *conn);  	int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param,  			  char *buf, int buflen); +	int (*get_ep_param) (struct iscsi_endpoint *ep, enum iscsi_param param, +			     char *buf);  	int (*get_conn_param) (struct iscsi_cls_conn *conn,  			       enum iscsi_param param, char *buf);  	int (*get_session_param) (struct iscsi_cls_session *session, @@ -135,6 +139,35 @@ struct iscsi_transport {  	int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,  			  uint32_t enable, struct sockaddr *dst_addr);  	int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params); +	int (*set_iface_param) (struct Scsi_Host *shost, void *data, +				uint32_t len); +	int (*get_iface_param) (struct iscsi_iface *iface, +				enum iscsi_param_type param_type, +				int param, char *buf); +	umode_t (*attr_is_visible)(int param_type, int param); +	int (*bsg_request)(struct bsg_job *job); +	int (*send_ping) (struct Scsi_Host *shost, uint32_t iface_num, +			  uint32_t iface_type, uint32_t payload_size, +			  uint32_t pid, struct sockaddr *dst_addr); +	int (*get_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx, +			 uint32_t *num_entries, char *buf); +	int (*delete_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx); +	int (*set_chap) (struct Scsi_Host *shost, void *data, int len); +	int (*get_flashnode_param) (struct iscsi_bus_flash_session *fnode_sess, +				    int param, char *buf); +	int (*set_flashnode_param) (struct iscsi_bus_flash_session *fnode_sess, +				    struct iscsi_bus_flash_conn *fnode_conn, +				    void *data, int len); +	int (*new_flashnode) (struct Scsi_Host *shost, const char *buf, +			      int len); +	int (*del_flashnode) (struct iscsi_bus_flash_session *fnode_sess); +	int (*login_flashnode) (struct iscsi_bus_flash_session *fnode_sess, +				struct iscsi_bus_flash_conn *fnode_conn); +	int (*logout_flashnode) (struct iscsi_bus_flash_session *fnode_sess, +				 struct iscsi_bus_flash_conn *fnode_conn); +	int (*logout_flashnode_sid) (struct iscsi_cls_session *cls_sess); +	int (*get_host_stats) (struct Scsi_Host *shost, char *buf, int len); +	u8 (*check_protection)(struct iscsi_task *task, sector_t *sector);  };  /* @@ -148,6 +181,8 @@ extern int iscsi_unregister_transport(struct iscsi_transport *tt);   */  extern void iscsi_conn_error_event(struct iscsi_cls_conn *conn,  				   enum iscsi_err error); +extern void iscsi_conn_login_event(struct iscsi_cls_conn *conn, +				   enum iscsi_conn_state state);  extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,  			  char *data, uint32_t data_size); @@ -155,19 +190,34 @@ extern int iscsi_offload_mesg(struct Scsi_Host *shost,  			      struct iscsi_transport *transport, uint32_t type,  			      char *data, uint16_t data_size); +extern void iscsi_post_host_event(uint32_t host_no, +				  struct iscsi_transport *transport, +				  enum iscsi_host_event_code code, +				  uint32_t data_size, +				  uint8_t *data); + +extern void iscsi_ping_comp_event(uint32_t host_no, +				  struct iscsi_transport *transport, +				  uint32_t status, uint32_t pid, +				  uint32_t data_size, uint8_t *data); +  struct iscsi_cls_conn {  	struct list_head conn_list;	/* item in connlist */  	void *dd_data;			/* LLD private data */  	struct iscsi_transport *transport;  	uint32_t cid;			/* connection id */ +	struct mutex ep_mutex; +	struct iscsi_endpoint *ep; -	int active;			/* must be accessed with the connlock */  	struct device dev;		/* sysfs transport/container device */  };  #define iscsi_dev_to_conn(_dev) \  	container_of(_dev, struct iscsi_cls_conn, dev) +#define transport_class_to_conn(_cdev) \ +	iscsi_dev_to_conn(_cdev->parent) +  #define iscsi_conn_to_session(_conn) \  	iscsi_dev_to_session(_conn->dev.parent) @@ -194,7 +244,13 @@ struct iscsi_cls_session {  	struct delayed_work recovery_work;  	unsigned int target_id; +	bool ida_used; +	/* +	 * pid of userspace process that created session or -1 if +	 * created by the kernel. +	 */ +	pid_t creator;  	int state;  	int sid;				/* session id */  	void *dd_data;				/* LLD private data */ @@ -204,6 +260,9 @@ struct iscsi_cls_session {  #define iscsi_dev_to_session(_dev) \  	container_of(_dev, struct iscsi_cls_session, dev) +#define transport_class_to_session(_cdev) \ +	iscsi_dev_to_session(_cdev->parent) +  #define iscsi_session_to_shost(_session) \  	dev_to_shost(_session->dev.parent) @@ -213,8 +272,14 @@ struct iscsi_cls_session {  struct iscsi_cls_host {  	atomic_t nr_scans;  	struct mutex mutex; +	struct request_queue *bsg_q; +	uint32_t port_speed; +	uint32_t port_state;  }; +#define iscsi_job_to_shost(_job) \ +        dev_to_shost(_job->dev) +  extern void iscsi_host_for_each_session(struct Scsi_Host *shost,  				void (*fn)(struct iscsi_cls_session *)); @@ -222,8 +287,129 @@ struct iscsi_endpoint {  	void *dd_data;			/* LLD private data */  	struct device dev;  	uint64_t id; +	struct iscsi_cls_conn *conn; +}; + +struct iscsi_iface { +	struct device dev; +	struct iscsi_transport *transport; +	uint32_t iface_type;	/* IPv4 or IPv6 */ +	uint32_t iface_num;	/* iface number, 0 - n */ +	void *dd_data;		/* LLD private data */ +}; + +#define iscsi_dev_to_iface(_dev) \ +	container_of(_dev, struct iscsi_iface, dev) + +#define iscsi_iface_to_shost(_iface) \ +	dev_to_shost(_iface->dev.parent) + + +struct iscsi_bus_flash_conn { +	struct list_head conn_list;	/* item in connlist */ +	void *dd_data;			/* LLD private data */ +	struct iscsi_transport *transport; +	struct device dev;		/* sysfs transport/container device */ +	/* iscsi connection parameters */ +	uint32_t		exp_statsn; +	uint32_t		statsn; +	unsigned		max_recv_dlength; /* initiator_max_recv_dsl*/ +	unsigned		max_xmit_dlength; /* target_max_recv_dsl */ +	unsigned		max_segment_size; +	unsigned		tcp_xmit_wsf; +	unsigned		tcp_recv_wsf; +	int			hdrdgst_en; +	int			datadgst_en; +	int			port; +	char			*ipaddress; +	char			*link_local_ipv6_addr; +	char			*redirect_ipaddr; +	uint16_t		keepalive_timeout; +	uint16_t		local_port; +	uint8_t			snack_req_en; +	/* tcp timestamp negotiation status */ +	uint8_t			tcp_timestamp_stat; +	uint8_t			tcp_nagle_disable; +	/* tcp window scale factor */ +	uint8_t			tcp_wsf_disable; +	uint8_t			tcp_timer_scale; +	uint8_t			tcp_timestamp_en; +	uint8_t			ipv4_tos; +	uint8_t			ipv6_traffic_class; +	uint8_t			ipv6_flow_label; +	uint8_t			fragment_disable; +	/* Link local IPv6 address is assigned by firmware or driver */ +	uint8_t			is_fw_assigned_ipv6;  }; +#define iscsi_dev_to_flash_conn(_dev) \ +	container_of(_dev, struct iscsi_bus_flash_conn, dev) + +#define iscsi_flash_conn_to_flash_session(_conn) \ +	iscsi_dev_to_flash_session(_conn->dev.parent) + +#define ISID_SIZE 6 + +struct iscsi_bus_flash_session { +	struct list_head sess_list;		/* item in session_list */ +	struct iscsi_transport *transport; +	unsigned int target_id; +	int flash_state;	/* persistent or non-persistent */ +	void *dd_data;				/* LLD private data */ +	struct device dev;	/* sysfs transport/container device */ +	/* iscsi session parameters */ +	unsigned		first_burst; +	unsigned		max_burst; +	unsigned short		max_r2t; +	int			default_taskmgmt_timeout; +	int			initial_r2t_en; +	int			imm_data_en; +	int			time2wait; +	int			time2retain; +	int			pdu_inorder_en; +	int			dataseq_inorder_en; +	int			erl; +	int			tpgt; +	char			*username; +	char			*username_in; +	char			*password; +	char			*password_in; +	char			*targetname; +	char			*targetalias; +	char			*portal_type; +	uint16_t		tsid; +	uint16_t		chap_in_idx; +	uint16_t		chap_out_idx; +	/* index of iSCSI discovery session if the entry is +	 * discovered by iSCSI discovery session +	 */ +	uint16_t		discovery_parent_idx; +	/* indicates if discovery was done through iSNS discovery service +	 * or through sendTarget */ +	uint16_t		discovery_parent_type; +	/* Firmware auto sendtarget discovery disable */ +	uint8_t			auto_snd_tgt_disable; +	uint8_t			discovery_sess; +	/* indicates if this flashnode entry is enabled or disabled */ +	uint8_t			entry_state; +	uint8_t			chap_auth_en; +	/* enables firmware to auto logout the discovery session on discovery +	 * completion +	 */ +	uint8_t			discovery_logout_en; +	uint8_t			bidi_chap_en; +	/* makes authentication for discovery session optional */ +	uint8_t			discovery_auth_optional; +	uint8_t			isid[ISID_SIZE]; +	uint8_t			is_boot_target; +}; + +#define iscsi_dev_to_flash_session(_dev) \ +	container_of(_dev, struct iscsi_bus_flash_session, dev) + +#define iscsi_flash_session_to_shost(_session) \ +	dev_to_shost(_session->dev.parent) +  /*   * session and connection functions that can be used by HW iSCSI LLDs   */ @@ -234,6 +420,7 @@ struct iscsi_endpoint {  	dev_printk(prefix, &(_cls_conn)->dev, fmt, ##a)  extern int iscsi_session_chkready(struct iscsi_cls_session *session); +extern int iscsi_is_session_online(struct iscsi_cls_session *session);  extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost,  				struct iscsi_transport *transport, int dd_size);  extern int iscsi_add_session(struct iscsi_cls_session *session, @@ -257,5 +444,43 @@ extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);  extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);  extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);  extern int iscsi_block_scsi_eh(struct scsi_cmnd *cmd); +extern struct iscsi_iface *iscsi_create_iface(struct Scsi_Host *shost, +					      struct iscsi_transport *t, +					      uint32_t iface_type, +					      uint32_t iface_num, int dd_size); +extern void iscsi_destroy_iface(struct iscsi_iface *iface); +extern struct iscsi_iface *iscsi_lookup_iface(int handle); +extern char *iscsi_get_port_speed_name(struct Scsi_Host *shost); +extern char *iscsi_get_port_state_name(struct Scsi_Host *shost); +extern int iscsi_is_session_dev(const struct device *dev); + +extern char *iscsi_get_discovery_parent_name(int parent_type); +extern struct device * +iscsi_find_flashnode(struct Scsi_Host *shost, void *data, +		     int (*fn)(struct device *dev, void *data)); + +extern struct iscsi_bus_flash_session * +iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index, +			    struct iscsi_transport *transport, int dd_size); + +extern struct iscsi_bus_flash_conn * +iscsi_create_flashnode_conn(struct Scsi_Host *shost, +			    struct iscsi_bus_flash_session *fnode_sess, +			    struct iscsi_transport *transport, int dd_size); + +extern void +iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess); + +extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost); +extern int iscsi_flashnode_bus_match(struct device *dev, +				     struct device_driver *drv); +extern struct device * +iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, +			  int (*fn)(struct device *dev, void *data)); +extern struct device * +iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess); +extern char * +iscsi_get_ipaddress_state_name(enum iscsi_ipaddress_state port_state); +extern char *iscsi_get_router_state_name(enum iscsi_router_state router_state);  #endif diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index ffeebc34a4f..0bd71e2702e 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -10,13 +10,6 @@ struct scsi_transport_template;  struct sas_rphy;  struct request; -enum sas_device_type { -	SAS_PHY_UNUSED = 0, -	SAS_END_DEVICE = 1, -	SAS_EDGE_EXPANDER_DEVICE = 2, -	SAS_FANOUT_EXPANDER_DEVICE = 3, -}; -  static inline int sas_protocol_ata(enum sas_protocol proto)  {  	return ((proto & SAS_PROTOCOL_SATA) || @@ -36,6 +29,7 @@ enum sas_linkrate {  	SAS_LINK_RATE_3_0_GBPS = 9,  	SAS_LINK_RATE_G2 = SAS_LINK_RATE_3_0_GBPS,  	SAS_LINK_RATE_6_0_GBPS = 10, +	SAS_LINK_RATE_12_0_GBPS = 11,  	/* These are virtual to the transport class and may never  	 * be signalled normally since the standard defined field  	 * is only 4 bits */ @@ -75,7 +69,8 @@ struct sas_phy {  	/* for the list of phys belonging to a port */  	struct list_head	port_siblings; -	struct work_struct      reset_work; +	/* available to the lldd */ +	void			*hostdata;  };  #define dev_to_phy(d) \ @@ -169,6 +164,8 @@ struct sas_function_template {  	int (*get_bay_identifier)(struct sas_rphy *);  	int (*phy_reset)(struct sas_phy *, int);  	int (*phy_enable)(struct sas_phy *, int); +	int (*phy_setup)(struct sas_phy *); +	void (*phy_release)(struct sas_phy *);  	int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *);  	int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);  }; @@ -194,6 +191,7 @@ void sas_rphy_free(struct sas_rphy *);  extern int sas_rphy_add(struct sas_rphy *);  extern void sas_rphy_remove(struct sas_rphy *);  extern void sas_rphy_delete(struct sas_rphy *); +extern void sas_rphy_unlink(struct sas_rphy *);  extern int scsi_is_sas_rphy(const struct device *);  struct sas_port *sas_port_alloc(struct device *, int); @@ -205,6 +203,12 @@ void sas_port_add_phy(struct sas_port *, struct sas_phy *);  void sas_port_delete_phy(struct sas_port *, struct sas_phy *);  void sas_port_mark_backlink(struct sas_port *);  int scsi_is_sas_port(const struct device *); +struct sas_phy *sas_port_get_phy(struct sas_port *port); +static inline void sas_port_put_phy(struct sas_phy *phy) +{ +	if (phy) +		put_device(&phy->dev); +}  extern struct scsi_transport_template *  sas_attach_transport(struct sas_function_template *); diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h index 9c60ca1c08c..cdb05dd1d44 100644 --- a/include/scsi/scsi_transport_srp.h +++ b/include/scsi/scsi_transport_srp.h @@ -13,14 +13,96 @@ struct srp_rport_identifiers {  	u8 roles;  }; +/** + * enum srp_rport_state - SRP transport layer state + * @SRP_RPORT_RUNNING:   Transport layer operational. + * @SRP_RPORT_BLOCKED:   Transport layer not operational; fast I/O fail timer + *                       is running and I/O has been blocked. + * @SRP_RPORT_FAIL_FAST: Fast I/O fail timer has expired; fail I/O fast. + * @SRP_RPORT_LOST:      Port is being removed. + */ +enum srp_rport_state { +	SRP_RPORT_RUNNING, +	SRP_RPORT_BLOCKED, +	SRP_RPORT_FAIL_FAST, +	SRP_RPORT_LOST, +}; + +/** + * struct srp_rport - SRP initiator or target port + * + * Fields that are relevant for SRP initiator and SRP target drivers: + * @dev:               Device associated with this rport. + * @port_id:           16-byte port identifier. + * @roles:             Role of this port - initiator or target. + * + * Fields that are only relevant for SRP initiator drivers: + * @lld_data:          LLD private data. + * @mutex:             Protects against concurrent rport reconnect / + *                     fast_io_fail / dev_loss_tmo activity. + * @state:             rport state. + * @reconnect_delay:   Reconnect delay in seconds. + * @failed_reconnects: Number of failed reconnect attempts. + * @reconnect_work:    Work structure used for scheduling reconnect attempts. + * @fast_io_fail_tmo:  Fast I/O fail timeout in seconds. + * @dev_loss_tmo:      Device loss timeout in seconds. + * @fast_io_fail_work: Work structure used for scheduling fast I/O fail work. + * @dev_loss_work:     Work structure used for scheduling device loss work. + */  struct srp_rport { +	/* for initiator and target drivers */ +  	struct device dev;  	u8 port_id[16];  	u8 roles; + +	/* for initiator drivers */ + +	void			*lld_data; + +	struct mutex		mutex; +	enum srp_rport_state	state; +	int			reconnect_delay; +	int			failed_reconnects; +	struct delayed_work	reconnect_work; +	int			fast_io_fail_tmo; +	int			dev_loss_tmo; +	struct delayed_work	fast_io_fail_work; +	struct delayed_work	dev_loss_work;  }; +/** + * struct srp_function_template + * + * Fields that are only relevant for SRP initiator drivers: + * @has_rport_state: Whether or not to create the state, fast_io_fail_tmo and + *     dev_loss_tmo sysfs attribute for an rport. + * @reset_timer_if_blocked: Whether or srp_timed_out() should reset the command + *     timer if the device on which it has been queued is blocked. + * @reconnect_delay: If not NULL, points to the default reconnect_delay value. + * @fast_io_fail_tmo: If not NULL, points to the default fast_io_fail_tmo value. + * @dev_loss_tmo: If not NULL, points to the default dev_loss_tmo value. + * @reconnect: Callback function for reconnecting to the target. See also + *     srp_reconnect_rport(). + * @terminate_rport_io: Callback function for terminating all outstanding I/O + *     requests for an rport. + * @rport_delete: Callback function that deletes an rport. + * + * Fields that are only relevant for SRP target drivers: + * @tsk_mgmt_response: Callback function for sending a task management response. + * @it_nexus_response: Callback function for processing an IT nexus response. + */  struct srp_function_template { +	/* for initiator drivers */ +	bool has_rport_state; +	bool reset_timer_if_blocked; +	int *reconnect_delay; +	int *fast_io_fail_tmo; +	int *dev_loss_tmo; +	int (*reconnect)(struct srp_rport *rport); +	void (*terminate_rport_io)(struct srp_rport *rport); +	void (*rport_delete)(struct srp_rport *rport);  	/* for target drivers */  	int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int);  	int (* it_nexus_response)(struct Scsi_Host *, u64, int); @@ -30,10 +112,38 @@ extern struct scsi_transport_template *  srp_attach_transport(struct srp_function_template *);  extern void srp_release_transport(struct scsi_transport_template *); +extern void srp_rport_get(struct srp_rport *rport); +extern void srp_rport_put(struct srp_rport *rport);  extern struct srp_rport *srp_rport_add(struct Scsi_Host *,  				       struct srp_rport_identifiers *);  extern void srp_rport_del(struct srp_rport *); - +extern int srp_tmo_valid(int reconnect_delay, int fast_io_fail_tmo, +			 int dev_loss_tmo); +extern int srp_reconnect_rport(struct srp_rport *rport); +extern void srp_start_tl_fail_timers(struct srp_rport *rport);  extern void srp_remove_host(struct Scsi_Host *); +extern void srp_stop_rport_timers(struct srp_rport *rport); + +/** + * srp_chkready() - evaluate the transport layer state before I/O + * @rport: SRP target port pointer. + * + * Returns a SCSI result code that can be returned by the LLD queuecommand() + * implementation. The role of this function is similar to that of + * fc_remote_port_chkready(). + */ +static inline int srp_chkready(struct srp_rport *rport) +{ +	switch (rport->state) { +	case SRP_RPORT_RUNNING: +	case SRP_RPORT_BLOCKED: +	default: +		return 0; +	case SRP_RPORT_FAIL_FAST: +		return DID_TRANSPORT_FAILFAST << 16; +	case SRP_RPORT_LOST: +		return DID_NO_CONNECT << 16; +	} +}  #endif  | 
