[SCSI] libfcoe: Host doesnt handle CVL to NPIV ports
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>
Fri, 11 Jun 2010 23:44:31 +0000 (16:44 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Tue, 27 Jul 2010 17:01:49 +0000 (12:01 -0500)
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>
drivers/scsi/fcoe/libfcoe.c

index db7185c0b9649e3fd2e22dfac11d98f4ec2bf517..ce651ca2a4bcef841147e6670437a034f2b02bd1 100644 (file)
@@ -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);
+               }
        }
 }