mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 09:14:19 +08:00
[SCSI] bfa: Added support to configure lunmasking
- Added support to enable / disable lunmasking on Brocade adapter ports. - Added support to query / clear lunmasking configuration. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
83763d591b
commit
4c5d22bf7b
@ -175,11 +175,15 @@ enum bfa_status {
|
||||
BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */
|
||||
BFA_STATUS_PHY_NOT_PRESENT = 183, /* PHY module not present */
|
||||
BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */
|
||||
BFA_STATUS_ENTRY_EXISTS = 193, /* Entry already exists */
|
||||
BFA_STATUS_ENTRY_NOT_EXISTS = 194, /* Entry does not exist */
|
||||
BFA_STATUS_NO_CHANGE = 195, /* Feature already in that state */
|
||||
BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */
|
||||
BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */
|
||||
BFA_STATUS_FAA_ACQUIRED = 199, /* FAA is already acquired */
|
||||
BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */
|
||||
BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */
|
||||
BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */
|
||||
BFA_STATUS_MAX_VAL /* Unknown error code */
|
||||
};
|
||||
#define bfa_status_t enum bfa_status
|
||||
|
@ -2553,6 +2553,200 @@ bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn, wwn_t rp_wwn,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* set UA for all active luns in LM DB
|
||||
*/
|
||||
static void
|
||||
bfa_ioim_lm_set_ua(struct bfa_s *bfa)
|
||||
{
|
||||
struct bfa_lun_mask_s *lunm_list;
|
||||
int i;
|
||||
|
||||
lunm_list = bfa_get_lun_mask_list(bfa);
|
||||
for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
|
||||
if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
|
||||
continue;
|
||||
lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
|
||||
}
|
||||
}
|
||||
|
||||
bfa_status_t
|
||||
bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 update)
|
||||
{
|
||||
struct bfa_lunmask_cfg_s *lun_mask;
|
||||
|
||||
bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
|
||||
if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
|
||||
return BFA_STATUS_FAILED;
|
||||
|
||||
if (bfa_get_lun_mask_status(bfa) == update)
|
||||
return BFA_STATUS_NO_CHANGE;
|
||||
|
||||
lun_mask = bfa_get_lun_mask(bfa);
|
||||
lun_mask->status = update;
|
||||
|
||||
if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED)
|
||||
bfa_ioim_lm_set_ua(bfa);
|
||||
|
||||
return bfa_dconf_update(bfa);
|
||||
}
|
||||
|
||||
bfa_status_t
|
||||
bfa_fcpim_lunmask_clear(struct bfa_s *bfa)
|
||||
{
|
||||
int i;
|
||||
struct bfa_lun_mask_s *lunm_list;
|
||||
|
||||
bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
|
||||
if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
|
||||
return BFA_STATUS_FAILED;
|
||||
|
||||
lunm_list = bfa_get_lun_mask_list(bfa);
|
||||
for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
|
||||
if (lunm_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) {
|
||||
if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID)
|
||||
bfa_rport_unset_lunmask(bfa,
|
||||
BFA_RPORT_FROM_TAG(bfa, lunm_list[i].rp_tag));
|
||||
}
|
||||
}
|
||||
|
||||
memset(lunm_list, 0, sizeof(struct bfa_lun_mask_s) * MAX_LUN_MASK_CFG);
|
||||
return bfa_dconf_update(bfa);
|
||||
}
|
||||
|
||||
bfa_status_t
|
||||
bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf)
|
||||
{
|
||||
struct bfa_lunmask_cfg_s *lun_mask;
|
||||
|
||||
bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
|
||||
if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
|
||||
return BFA_STATUS_FAILED;
|
||||
|
||||
lun_mask = bfa_get_lun_mask(bfa);
|
||||
memcpy(buf, lun_mask, sizeof(struct bfa_lunmask_cfg_s));
|
||||
return BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
bfa_status_t
|
||||
bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn,
|
||||
wwn_t rpwwn, struct scsi_lun lun)
|
||||
{
|
||||
struct bfa_lun_mask_s *lunm_list;
|
||||
struct bfa_rport_s *rp = NULL;
|
||||
int i, free_index = MAX_LUN_MASK_CFG + 1;
|
||||
struct bfa_fcs_lport_s *port = NULL;
|
||||
struct bfa_fcs_rport_s *rp_fcs;
|
||||
|
||||
bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
|
||||
if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
|
||||
return BFA_STATUS_FAILED;
|
||||
|
||||
port = bfa_fcs_lookup_port(&((struct bfad_s *)bfa->bfad)->bfa_fcs,
|
||||
vf_id, *pwwn);
|
||||
if (port) {
|
||||
*pwwn = port->port_cfg.pwwn;
|
||||
rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
|
||||
rp = rp_fcs->bfa_rport;
|
||||
}
|
||||
|
||||
lunm_list = bfa_get_lun_mask_list(bfa);
|
||||
/* if entry exists */
|
||||
for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
|
||||
if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
|
||||
free_index = i;
|
||||
if ((lunm_list[i].lp_wwn == *pwwn) &&
|
||||
(lunm_list[i].rp_wwn == rpwwn) &&
|
||||
(scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) ==
|
||||
scsilun_to_int((struct scsi_lun *)&lun)))
|
||||
return BFA_STATUS_ENTRY_EXISTS;
|
||||
}
|
||||
|
||||
if (free_index > MAX_LUN_MASK_CFG)
|
||||
return BFA_STATUS_MAX_ENTRY_REACHED;
|
||||
|
||||
if (rp) {
|
||||
lunm_list[free_index].lp_tag = bfa_lps_get_tag_from_pid(bfa,
|
||||
rp->rport_info.local_pid);
|
||||
lunm_list[free_index].rp_tag = rp->rport_tag;
|
||||
} else {
|
||||
lunm_list[free_index].lp_tag = BFA_LP_TAG_INVALID;
|
||||
lunm_list[free_index].rp_tag = BFA_RPORT_TAG_INVALID;
|
||||
}
|
||||
|
||||
lunm_list[free_index].lp_wwn = *pwwn;
|
||||
lunm_list[free_index].rp_wwn = rpwwn;
|
||||
lunm_list[free_index].lun = lun;
|
||||
lunm_list[free_index].state = BFA_IOIM_LUN_MASK_ACTIVE;
|
||||
|
||||
/* set for all luns in this rp */
|
||||
for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
|
||||
if ((lunm_list[i].lp_wwn == *pwwn) &&
|
||||
(lunm_list[i].rp_wwn == rpwwn))
|
||||
lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
|
||||
}
|
||||
|
||||
return bfa_dconf_update(bfa);
|
||||
}
|
||||
|
||||
bfa_status_t
|
||||
bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn,
|
||||
wwn_t rpwwn, struct scsi_lun lun)
|
||||
{
|
||||
struct bfa_lun_mask_s *lunm_list;
|
||||
struct bfa_rport_s *rp = NULL;
|
||||
struct bfa_fcs_lport_s *port = NULL;
|
||||
struct bfa_fcs_rport_s *rp_fcs;
|
||||
int i;
|
||||
|
||||
/* in min cfg lunm_list could be NULL but no commands should run. */
|
||||
if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
|
||||
return BFA_STATUS_FAILED;
|
||||
|
||||
bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
|
||||
bfa_trc(bfa, *pwwn);
|
||||
bfa_trc(bfa, rpwwn);
|
||||
bfa_trc(bfa, scsilun_to_int((struct scsi_lun *)&lun));
|
||||
|
||||
if (*pwwn == 0) {
|
||||
port = bfa_fcs_lookup_port(
|
||||
&((struct bfad_s *)bfa->bfad)->bfa_fcs,
|
||||
vf_id, *pwwn);
|
||||
if (port) {
|
||||
*pwwn = port->port_cfg.pwwn;
|
||||
rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
|
||||
rp = rp_fcs->bfa_rport;
|
||||
}
|
||||
}
|
||||
|
||||
lunm_list = bfa_get_lun_mask_list(bfa);
|
||||
for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
|
||||
if ((lunm_list[i].lp_wwn == *pwwn) &&
|
||||
(lunm_list[i].rp_wwn == rpwwn) &&
|
||||
(scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) ==
|
||||
scsilun_to_int((struct scsi_lun *)&lun))) {
|
||||
lunm_list[i].lp_wwn = 0;
|
||||
lunm_list[i].rp_wwn = 0;
|
||||
int_to_scsilun(0, &lunm_list[i].lun);
|
||||
lunm_list[i].state = BFA_IOIM_LUN_MASK_INACTIVE;
|
||||
if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID) {
|
||||
lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID;
|
||||
lunm_list[i].lp_tag = BFA_LP_TAG_INVALID;
|
||||
}
|
||||
return bfa_dconf_update(bfa);
|
||||
}
|
||||
}
|
||||
|
||||
/* set for all luns in this rp */
|
||||
for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
|
||||
if ((lunm_list[i].lp_wwn == *pwwn) &&
|
||||
(lunm_list[i].rp_wwn == rpwwn))
|
||||
lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
|
||||
}
|
||||
|
||||
return BFA_STATUS_ENTRY_NOT_EXISTS;
|
||||
}
|
||||
|
||||
static void
|
||||
__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
|
||||
{
|
||||
|
@ -416,5 +416,12 @@ void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
|
||||
|
||||
void bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn,
|
||||
wwn_t rp_wwn, u16 rp_tag, u8 lp_tag);
|
||||
bfa_status_t bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 on_off);
|
||||
bfa_status_t bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf);
|
||||
bfa_status_t bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id,
|
||||
wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun);
|
||||
bfa_status_t bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id,
|
||||
wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun);
|
||||
bfa_status_t bfa_fcpim_lunmask_clear(struct bfa_s *bfa);
|
||||
|
||||
#endif /* __BFA_FCPIM_H__ */
|
||||
|
@ -2394,6 +2394,56 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd)
|
||||
{
|
||||
struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE)
|
||||
iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_TRUE);
|
||||
else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE)
|
||||
iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_FALSE);
|
||||
else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR)
|
||||
iocmd->status = bfa_fcpim_lunmask_clear(&bfad->bfa);
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bfad_iocmd_fcpim_lunmask_query(struct bfad_s *bfad, void *cmd)
|
||||
{
|
||||
struct bfa_bsg_fcpim_lunmask_query_s *iocmd =
|
||||
(struct bfa_bsg_fcpim_lunmask_query_s *)cmd;
|
||||
struct bfa_lunmask_cfg_s *lun_mask = &iocmd->lun_mask;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
iocmd->status = bfa_fcpim_lunmask_query(&bfad->bfa, lun_mask);
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bfad_iocmd_fcpim_cfg_lunmask(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
|
||||
{
|
||||
struct bfa_bsg_fcpim_lunmask_s *iocmd =
|
||||
(struct bfa_bsg_fcpim_lunmask_s *)cmd;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
if (v_cmd == IOCMD_FCPIM_LUNMASK_ADD)
|
||||
iocmd->status = bfa_fcpim_lunmask_add(&bfad->bfa, iocmd->vf_id,
|
||||
&iocmd->pwwn, iocmd->rpwwn, iocmd->lun);
|
||||
else if (v_cmd == IOCMD_FCPIM_LUNMASK_DELETE)
|
||||
iocmd->status = bfa_fcpim_lunmask_delete(&bfad->bfa,
|
||||
iocmd->vf_id, &iocmd->pwwn,
|
||||
iocmd->rpwwn, iocmd->lun);
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
|
||||
unsigned int payload_len)
|
||||
@ -2712,6 +2762,18 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
|
||||
case IOCMD_VF_RESET_STATS:
|
||||
rc = bfad_iocmd_vf_clr_stats(bfad, iocmd);
|
||||
break;
|
||||
case IOCMD_FCPIM_LUNMASK_ENABLE:
|
||||
case IOCMD_FCPIM_LUNMASK_DISABLE:
|
||||
case IOCMD_FCPIM_LUNMASK_CLEAR:
|
||||
rc = bfad_iocmd_lunmask(bfad, iocmd, cmd);
|
||||
break;
|
||||
case IOCMD_FCPIM_LUNMASK_QUERY:
|
||||
rc = bfad_iocmd_fcpim_lunmask_query(bfad, iocmd);
|
||||
break;
|
||||
case IOCMD_FCPIM_LUNMASK_ADD:
|
||||
case IOCMD_FCPIM_LUNMASK_DELETE:
|
||||
rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, iocmd, cmd);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
|
@ -137,6 +137,12 @@ enum {
|
||||
IOCMD_QOS_RESET_STATS,
|
||||
IOCMD_VF_GET_STATS,
|
||||
IOCMD_VF_RESET_STATS,
|
||||
IOCMD_FCPIM_LUNMASK_ENABLE,
|
||||
IOCMD_FCPIM_LUNMASK_DISABLE,
|
||||
IOCMD_FCPIM_LUNMASK_CLEAR,
|
||||
IOCMD_FCPIM_LUNMASK_QUERY,
|
||||
IOCMD_FCPIM_LUNMASK_ADD,
|
||||
IOCMD_FCPIM_LUNMASK_DELETE,
|
||||
};
|
||||
|
||||
struct bfa_bsg_gen_s {
|
||||
@ -701,6 +707,21 @@ struct bfa_bsg_vf_reset_stats_s {
|
||||
u16 vf_id;
|
||||
};
|
||||
|
||||
struct bfa_bsg_fcpim_lunmask_query_s {
|
||||
bfa_status_t status;
|
||||
u16 bfad_num;
|
||||
struct bfa_lunmask_cfg_s lun_mask;
|
||||
};
|
||||
|
||||
struct bfa_bsg_fcpim_lunmask_s {
|
||||
bfa_status_t status;
|
||||
u16 bfad_num;
|
||||
u16 vf_id;
|
||||
wwn_t pwwn;
|
||||
wwn_t rpwwn;
|
||||
struct scsi_lun lun;
|
||||
};
|
||||
|
||||
struct bfa_bsg_fcpt_s {
|
||||
bfa_status_t status;
|
||||
u16 vf_id;
|
||||
|
Loading…
Reference in New Issue
Block a user