From e353546e447feb838db2d1b23bac23cb90755993 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 21 Sep 2012 17:26:07 -0700 Subject: [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 Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfad_bsg.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'drivers/scsi/bfa/bfad_bsg.c') 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 @@ -1746,6 +1746,52 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) return 0; } +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) { @@ -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; -- cgit v1.2.3