Commit 83763d59 authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley

[SCSI] bfa: Introduced initiator based lun masking feature.

- Added support to enable initiator based lun masking.
- Initiator based Lun masking works similar to zoning where
  initiator port is allowed to see only those LUNs which are
  configured to be seen.
Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 45c5dc1d
......@@ -382,6 +382,22 @@ int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
#define bfa_get_fw_clock_res(__bfa) \
((__bfa)->iocfc.cfgrsp->fwcfg.fw_tick_res)
/*
* lun mask macros return NULL when min cfg is enabled and there is
* no memory allocated for lunmask.
*/
#define bfa_get_lun_mask(__bfa) \
((&(__bfa)->modules.dconf_mod)->min_cfg) ? NULL : \
(&(BFA_DCONF_MOD(__bfa)->dconf->lun_mask))
#define bfa_get_lun_mask_list(_bfa) \
((&(_bfa)->modules.dconf_mod)->min_cfg) ? NULL : \
(bfa_get_lun_mask(_bfa)->lun_list)
#define bfa_get_lun_mask_status(_bfa) \
(((&(_bfa)->modules.dconf_mod)->min_cfg) \
? BFA_LUNMASK_MINCFG : ((bfa_get_lun_mask(_bfa))->status))
void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids);
void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg);
void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg);
......
......@@ -672,6 +672,12 @@ struct bfa_itnim_iostats_s {
u32 tm_iocdowns; /* TM cleaned-up due to IOC down */
u32 tm_cleanups; /* TM cleanup requests */
u32 tm_cleanup_comps; /* TM cleanup completions */
u32 lm_lun_across_sg; /* LM lun is across sg data buf */
u32 lm_lun_not_sup; /* LM lun not supported */
u32 lm_rpl_data_changed; /* LM report-lun data changed */
u32 lm_wire_residue_changed; /* LM report-lun rsp residue changed */
u32 lm_small_buf_addresidue; /* LM buf smaller than reported cnt */
u32 lm_lun_not_rdy; /* LM lun not ready */
};
/* Modify char* port_stt[] in bfal_port.c if a new state was added */
......@@ -787,6 +793,28 @@ enum bfa_port_linkstate_rsn {
CEE_ISCSI_PRI_PFC_OFF = 42,
CEE_ISCSI_PRI_OVERLAP_FCOE_PRI = 43
};
#define MAX_LUN_MASK_CFG 16
/*
* Initially flash content may be fff. On making LUN mask enable and disable
* state chnage. when report lun command is being processed it goes from
* BFA_LUN_MASK_ACTIVE to BFA_LUN_MASK_FETCH and comes back to
* BFA_LUN_MASK_ACTIVE.
*/
enum bfa_ioim_lun_mask_state_s {
BFA_IOIM_LUN_MASK_INACTIVE = 0,
BFA_IOIM_LUN_MASK_ACTIVE = 1,
BFA_IOIM_LUN_MASK_FETCHED = 2,
};
enum bfa_lunmask_state_s {
BFA_LUNMASK_DISABLED = 0x00,
BFA_LUNMASK_ENABLED = 0x01,
BFA_LUNMASK_MINCFG = 0x02,
BFA_LUNMASK_UNINITIALIZED = 0xff,
};
#pragma pack(1)
/*
* LUN mask configuration
......@@ -794,7 +822,7 @@ enum bfa_port_linkstate_rsn {
struct bfa_lun_mask_s {
wwn_t lp_wwn;
wwn_t rp_wwn;
lun_t lun;
struct scsi_lun lun;
u8 ua;
u8 rsvd[3];
u16 rp_tag;
......
......@@ -21,7 +21,6 @@
#include "bfad_drv.h"
typedef u64 wwn_t;
typedef u64 lun_t;
#define WWN_NULL (0)
#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
......@@ -57,6 +56,161 @@ struct scsi_cdb_s {
#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length */
#define SCSI_SENSE_CUR_ERR 0x70
#define SCSI_SENSE_DEF_ERR 0x71
/*
* SCSI additional sense codes
*/
#define SCSI_ASC_LUN_NOT_READY 0x04
#define SCSI_ASC_LUN_NOT_SUPPORTED 0x25
#define SCSI_ASC_TOCC 0x3F
/*
* SCSI additional sense code qualifiers
*/
#define SCSI_ASCQ_MAN_INTR_REQ 0x03 /* manual intervention req */
#define SCSI_ASCQ_RL_DATA_CHANGED 0x0E /* report luns data changed */
/*
* Methods of reporting informational exceptions
*/
#define SCSI_MP_IEC_UNIT_ATTN 0x2 /* generate unit attention */
struct scsi_report_luns_data_s {
u32 lun_list_length; /* length of LUN list length */
u32 reserved;
struct scsi_lun lun[1]; /* first LUN in lun list */
};
struct scsi_inquiry_vendor_s {
u8 vendor_id[8];
};
struct scsi_inquiry_prodid_s {
u8 product_id[16];
};
struct scsi_inquiry_prodrev_s {
u8 product_rev[4];
};
struct scsi_inquiry_data_s {
#ifdef __BIG_ENDIAN
u8 peripheral_qual:3; /* peripheral qualifier */
u8 device_type:5; /* peripheral device type */
u8 rmb:1; /* removable medium bit */
u8 device_type_mod:7; /* device type modifier */
u8 version;
u8 aenc:1; /* async evt notification capability */
u8 trm_iop:1; /* terminate I/O process */
u8 norm_aca:1; /* normal ACA supported */
u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
u8 rsp_data_format:4;
u8 additional_len;
u8 sccs:1;
u8 reserved1:7;
u8 reserved2:1;
u8 enc_serv:1; /* enclosure service component */
u8 reserved3:1;
u8 multi_port:1; /* multi-port device */
u8 m_chngr:1; /* device in medium transport element */
u8 ack_req_q:1; /* SIP specific bit */
u8 addr32:1; /* SIP specific bit */
u8 addr16:1; /* SIP specific bit */
u8 rel_adr:1; /* relative address */
u8 w_bus32:1;
u8 w_bus16:1;
u8 synchronous:1;
u8 linked_commands:1;
u8 trans_dis:1;
u8 cmd_queue:1; /* command queueing supported */
u8 soft_reset:1; /* soft reset alternative (VS) */
#else
u8 device_type:5; /* peripheral device type */
u8 peripheral_qual:3; /* peripheral qualifier */
u8 device_type_mod:7; /* device type modifier */
u8 rmb:1; /* removable medium bit */
u8 version;
u8 rsp_data_format:4;
u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
u8 norm_aca:1; /* normal ACA supported */
u8 terminate_iop:1;/* terminate I/O process */
u8 aenc:1; /* async evt notification capability */
u8 additional_len;
u8 reserved1:7;
u8 sccs:1;
u8 addr16:1; /* SIP specific bit */
u8 addr32:1; /* SIP specific bit */
u8 ack_req_q:1; /* SIP specific bit */
u8 m_chngr:1; /* device in medium transport element */
u8 multi_port:1; /* multi-port device */
u8 reserved3:1; /* TBD - Vendor Specific */
u8 enc_serv:1; /* enclosure service component */
u8 reserved2:1;
u8 soft_seset:1; /* soft reset alternative (VS) */
u8 cmd_queue:1; /* command queueing supported */
u8 trans_dis:1;
u8 linked_commands:1;
u8 synchronous:1;
u8 w_bus16:1;
u8 w_bus32:1;
u8 rel_adr:1; /* relative address */
#endif
struct scsi_inquiry_vendor_s vendor_id;
struct scsi_inquiry_prodid_s product_id;
struct scsi_inquiry_prodrev_s product_rev;
u8 vendor_specific[20];
u8 reserved4[40];
};
/*
* SCSI sense data format
*/
struct scsi_sense_s {
#ifdef __BIG_ENDIAN
u8 valid:1;
u8 rsp_code:7;
#else
u8 rsp_code:7;
u8 valid:1;
#endif
u8 seg_num;
#ifdef __BIG_ENDIAN
u8 file_mark:1;
u8 eom:1; /* end of media */
u8 ili:1; /* incorrect length indicator */
u8 reserved:1;
u8 sense_key:4;
#else
u8 sense_key:4;
u8 reserved:1;
u8 ili:1; /* incorrect length indicator */
u8 eom:1; /* end of media */
u8 file_mark:1;
#endif
u8 information[4]; /* device-type or cmd specific info */
u8 add_sense_length; /* additional sense length */
u8 command_info[4];/* command specific information */
u8 asc; /* additional sense code */
u8 ascq; /* additional sense code qualifier */
u8 fru_code; /* field replaceable unit code */
#ifdef __BIG_ENDIAN
u8 sksv:1; /* sense key specific valid */
u8 c_d:1; /* command/data bit */
u8 res1:2;
u8 bpv:1; /* bit pointer valid */
u8 bpointer:3; /* bit pointer */
#else
u8 bpointer:3; /* bit pointer */
u8 bpv:1; /* bit pointer valid */
u8 res1:2;
u8 c_d:1; /* command/data bit */
u8 sksv:1; /* sense key specific valid */
#endif
u8 fpointer[2]; /* field pointer */
};
/*
* Fibre Channel Header Structure (FCHS) definition
*/
......
This diff is collapsed.
......@@ -110,6 +110,7 @@ struct bfad_ioim_s;
struct bfad_tskim_s;
typedef void (*bfa_fcpim_profile_t) (struct bfa_ioim_s *ioim);
typedef bfa_boolean_t (*bfa_ioim_lm_proc_rsp_data_t) (struct bfa_ioim_s *ioim);
struct bfa_fcpim_s {
struct bfa_s *bfa;
......@@ -123,7 +124,7 @@ struct bfa_fcpim_s {
u32 path_tov;
u16 q_depth;
u8 reqq; /* Request queue to be used */
u8 rsvd;
u8 lun_masking_pending;
struct list_head itnim_q; /* queue of active itnim */
struct list_head ioim_resfree_q; /* IOs waiting for f/w */
struct list_head ioim_comp_q; /* IO global comp Q */
......@@ -178,7 +179,9 @@ struct bfa_ioim_s {
bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
u8 reqq; /* Request queue for I/O */
u8 mode; /* IO is passthrough or not */
u64 start_time; /* IO's Profile start val */
bfa_ioim_lm_proc_rsp_data_t proc_rsp_data; /* RSP data adjust */
};
struct bfa_ioim_sp_s {
......@@ -258,6 +261,10 @@ struct bfa_itnim_s {
(__ioim)->iotag |= k << BFA_IOIM_RETRY_TAG_OFFSET; \
} while (0)
#define BFA_IOIM_TO_LPS(__ioim) \
BFA_LPS_FROM_TAG(BFA_LPS_MOD(__ioim->bfa), \
__ioim->itnim->rport->rport_info.lp_tag)
static inline bfa_boolean_t
bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim)
{
......@@ -407,4 +414,7 @@ void bfa_tskim_start(struct bfa_tskim_s *tskim,
void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
enum bfi_tskim_status tsk_status);
void bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn,
wwn_t rp_wwn, u16 rp_tag, u8 lp_tag);
#endif /* __BFA_FCPIM_H__ */
......@@ -4677,6 +4677,7 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
rp->fw_handle = msg.create_rsp->fw_handle;
rp->qos_attr = msg.create_rsp->qos_attr;
bfa_rport_set_lunmask(bfa, rp);
WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
break;
......@@ -4684,6 +4685,7 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
case BFI_RPORT_I2H_DELETE_RSP:
rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
bfa_rport_unset_lunmask(bfa, rp);
bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
break;
......@@ -4764,6 +4766,37 @@ bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
}
/* Set Rport LUN Mask */
void
bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp)
{
struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa);
wwn_t lp_wwn, rp_wwn;
u8 lp_tag = (u8)rp->rport_info.lp_tag;
rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn;
lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn;
BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask =
rp->lun_mask = BFA_TRUE;
bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, rp->rport_tag, lp_tag);
}
/* Unset Rport LUN mask */
void
bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp)
{
struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa);
wwn_t lp_wwn, rp_wwn;
rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn;
lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn;
BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask =
rp->lun_mask = BFA_FALSE;
bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn,
BFA_RPORT_TAG_INVALID, BFA_LP_TAG_INVALID);
}
/*
* SGPG related functions
......
......@@ -297,6 +297,7 @@ struct bfa_rport_s {
void *rport_drv; /* fcs/driver rport object */
u16 fw_handle; /* firmware rport handle */
u16 rport_tag; /* BFA rport tag */
u8 lun_mask; /* LUN mask flag */
struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */
......@@ -404,6 +405,7 @@ struct bfa_lps_s {
u8 bb_scn; /* local BB_SCN */
u8 lsrjt_rsn; /* LSRJT reason */
u8 lsrjt_expl; /* LSRJT explanation */
u8 lun_mask; /* LUN mask flag */
wwn_t pwwn; /* port wwn of lport */
wwn_t nwwn; /* node wwn of lport */
wwn_t pr_pwwn; /* port wwn of lport peer */
......@@ -573,6 +575,19 @@ void bfa_cb_rport_qos_scn_prio(void *rport,
struct bfa_rport_qos_attr_s old_qos_attr,
struct bfa_rport_qos_attr_s new_qos_attr);
/*
* Rport LUN masking related
*/
#define BFA_RPORT_TAG_INVALID 0xffff
#define BFA_LP_TAG_INVALID 0xff
void bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp);
void bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp);
bfa_boolean_t bfa_rport_lunmask_active(struct bfa_rport_s *rp);
wwn_t bfa_rport_get_pwwn(struct bfa_s *bfa, struct bfa_rport_s *rp);
struct bfa_rport_s *bfa_rport_get_by_wwn(struct bfa_s *bfa, u16 vf_id,
wwn_t *lpwwn, wwn_t rpwwn);
void *bfa_cb_get_rp_by_wwn(void *arg, u16 vf_id, wwn_t *lpwwn, wwn_t rpwwn);
/*
* bfa fcxp API functions
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment