aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe
diff options
context:
space:
mode:
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>2010-06-11 16:44:31 -0700
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 12:01:49 -0500
commit5550fda73d8bd3bed454e28c46f5a4e5288769bb (patch)
treef93fe89292524836fe0ecb7107533e546c100aab /drivers/scsi/fcoe
parent[SCSI] libfcoe: Handle duplicate critical descriptors (diff)
downloadlinux-dev-5550fda73d8bd3bed454e28c46f5a4e5288769bb.tar.xz
linux-dev-5550fda73d8bd3bed454e28c46f5a4e5288769bb.zip
[SCSI] libfcoe: Host doesnt handle CVL to NPIV ports
Clear virtual link for NPIV ports is now handled by resetting the matching vnport. Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r--drivers/scsi/fcoe/libfcoe.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index db7185c0b964..ce651ca2a4bc 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -989,7 +989,9 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
size_t dlen;
struct fcoe_fcf *fcf = fip->sel_fcf;
struct fc_lport *lport = fip->lp;
- u32 desc_mask;
+ struct fc_lport *vn_port = NULL;
+ u32 desc_mask;
+ int is_vn_port = 0;
LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n");
@@ -1038,8 +1040,26 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
if (compare_ether_addr(vp->fd_mac,
fip->get_src_addr(lport)) == 0 &&
get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn &&
- ntoh24(vp->fd_fc_id) == lport->port_id)
+ ntoh24(vp->fd_fc_id) == lport->port_id) {
desc_mask &= ~BIT(FIP_DT_VN_ID);
+ break;
+ }
+ /* check if clr_vlink is for NPIV port */
+ mutex_lock(&lport->lp_mutex);
+ list_for_each_entry(vn_port, &lport->vports, list) {
+ if (compare_ether_addr(vp->fd_mac,
+ fip->get_src_addr(vn_port)) == 0 &&
+ (get_unaligned_be64(&vp->fd_wwpn)
+ == vn_port->wwpn) &&
+ (ntoh24(vp->fd_fc_id) ==
+ fc_host_port_id(vn_port->host))) {
+ desc_mask &= ~BIT(FIP_DT_VN_ID);
+ is_vn_port = 1;
+ break;
+ }
+ }
+ mutex_unlock(&lport->lp_mutex);
+
break;
default:
/* standard says ignore unknown descriptors >= 128 */
@@ -1060,14 +1080,18 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
} else {
LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n");
- spin_lock_bh(&fip->lock);
- per_cpu_ptr(lport->dev_stats,
- smp_processor_id())->VLinkFailureCount++;
- fcoe_ctlr_reset(fip);
- spin_unlock_bh(&fip->lock);
+ if (is_vn_port)
+ fc_lport_reset(vn_port);
+ else {
+ spin_lock_bh(&fip->lock);
+ per_cpu_ptr(lport->dev_stats,
+ smp_processor_id())->VLinkFailureCount++;
+ fcoe_ctlr_reset(fip);
+ spin_unlock_bh(&fip->lock);
- fc_lport_reset(fip->lp);
- fcoe_ctlr_solicit(fip, NULL);
+ fc_lport_reset(fip->lp);
+ fcoe_ctlr_solicit(fip, NULL);
+ }
}
}