diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2012-09-21 17:26:07 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-10-07 11:17:27 +0100 |
commit | e353546e447feb838db2d1b23bac23cb90755993 (patch) | |
tree | f2762c0aedd4bb0ef4ebdca889c782b180ecdddc /drivers/scsi/bfa/bfad_bsg.c | |
parent | 1306e31d417df05c25053c5632b26d1c1b22d1ed (diff) |
[SCSI] bfa: Add diagnostic port (D-Port) support
- Introduced support for D-Port which is a new port mode during which
link level diagnostics can be run.
- Provided mechanism to dynamically configure D-Port and initiate diagnostic
tests to isolate any link level issues.
- In D-Port mode, the HBA port does not participate in fabric or login to the
remote device or run data traffic.
- Diagnostic tests include running various loopback tests in conjunction with
the attached device.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfad_bsg.c')
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 8ddd7e8be977..69b1ba9e58f6 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -1747,6 +1747,52 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) } int +bfad_iocmd_diag_cfg_dport(struct bfad_s *bfad, unsigned int cmd, void *pcmd) +{ + struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; + unsigned long flags; + struct bfad_hal_comp fcomp; + + init_completion(&fcomp.comp); + spin_lock_irqsave(&bfad->bfad_lock, flags); + if (cmd == IOCMD_DIAG_DPORT_ENABLE) + iocmd->status = bfa_dport_enable(&bfad->bfa, + bfad_hcb_comp, &fcomp); + else if (cmd == IOCMD_DIAG_DPORT_DISABLE) + iocmd->status = bfa_dport_disable(&bfad->bfa, + bfad_hcb_comp, &fcomp); + else { + bfa_trc(bfad, 0); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + return -EINVAL; + } + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + if (iocmd->status != BFA_STATUS_OK) + bfa_trc(bfad, iocmd->status); + else { + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; + } + + return 0; +} + +int +bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd) +{ + struct bfa_bsg_diag_dport_get_state_s *iocmd = + (struct bfa_bsg_diag_dport_get_state_s *)pcmd; + unsigned long flags; + + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + return 0; +} + +int bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) { struct bfa_bsg_phy_attr_s *iocmd = @@ -2172,6 +2218,9 @@ bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) spin_lock_irqsave(&bfad->bfad_lock, flags); + if (bfa_fcport_is_dport(&bfad->bfa)) + return BFA_STATUS_DPORT_ERR; + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; @@ -2702,6 +2751,13 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, case IOCMD_DIAG_LB_STAT: rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); break; + case IOCMD_DIAG_DPORT_ENABLE: + case IOCMD_DIAG_DPORT_DISABLE: + rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd); + break; + case IOCMD_DIAG_DPORT_GET_STATE: + rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd); + break; case IOCMD_PHY_GET_ATTR: rc = bfad_iocmd_phy_get_attr(bfad, iocmd); break; |