From: Vasu Dev <[email protected]>

The lport needs to allow multiple EMs to be attached to it so that
there can be one EM for offloaded exchanges and another for all other
exchanges.

Aside from the list addition this patch also adjusts the EM resetting
code such that it handles multiple EMs per lport.

Signed-off-by: Vasu Dev <[email protected]>
Signed-off-by: Robert Love <[email protected]>
---

 drivers/scsi/fcoe/fcoe.c     |   15 +++++++-------
 drivers/scsi/libfc/fc_exch.c |   46 +++++++++++++++++++++++++-----------------
 include/scsi/libfc.h         |    1 +
 3 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index f2d1612..9fe1ead 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -590,13 +590,6 @@ static int fcoe_if_create(struct net_device *netdev)
                goto out_netdev_cleanup;
        }
 
-       /* lport exch manager allocation */
-       rc = fcoe_em_config(lp);
-       if (rc) {
-               FC_DBG("Could not configure em for lport\n");
-               goto out_netdev_cleanup;
-       }
-
        /* Initialize the library */
        rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
        if (rc) {
@@ -604,6 +597,14 @@ static int fcoe_if_create(struct net_device *netdev)
                goto out_lp_destroy;
        }
 
+       /* lport exch manager allocation */
+       rc = fcoe_em_config(lp);
+       if (rc) {
+               FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
+                               "interface\n");
+               goto out_lp_destroy;
+       }
+
        /* add to lports list */
        fcoe_hostlist_add(lp);
 
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 992af05..08ad41f 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -75,6 +75,7 @@ struct fc_exch_mgr {
        u16             last_read;      /* last xid allocated for read */
        u32     total_exches;           /* total allocated exchanges */
        struct list_head        ex_list;        /* allocated exchanges list */
+       struct list_head        em_list;        /* fc_exch_mgr list */
        struct fc_lport *lp;            /* fc device instance */
        mempool_t       *ep_pool;       /* reserve ep's */
 
@@ -1469,29 +1470,31 @@ void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, 
u32 did)
 {
        struct fc_exch *ep;
        struct fc_exch *next;
-       struct fc_exch_mgr *mp = lp->emp;
+       struct fc_exch_mgr *mp;
 
-       spin_lock_bh(&mp->em_lock);
+       list_for_each_entry(mp, &lp->em_list, em_list) {
+               spin_lock_bh(&mp->em_lock);
 restart:
-       list_for_each_entry_safe(ep, next, &mp->ex_list, ex_list) {
-               if ((sid == 0 || sid == ep->sid) &&
-                   (did == 0 || did == ep->did)) {
-                       fc_exch_hold(ep);
-                       spin_unlock_bh(&mp->em_lock);
-
-                       fc_exch_reset(ep);
-
-                       fc_exch_release(ep);
-                       spin_lock_bh(&mp->em_lock);
-
-                       /*
-                        * must restart loop incase while lock was down
-                        * multiple eps were released.
-                        */
-                       goto restart;
+               list_for_each_entry_safe(ep, next, &mp->ex_list, ex_list) {
+                       if ((sid == 0 || sid == ep->sid) &&
+                           (did == 0 || did == ep->did)) {
+                               fc_exch_hold(ep);
+                               spin_unlock_bh(&mp->em_lock);
+
+                               fc_exch_reset(ep);
+
+                               fc_exch_release(ep);
+                               spin_lock_bh(&mp->em_lock);
+
+                               /*
+                                * must restart loop incase while lock
+                                * was down multiple eps were released.
+                                */
+                               goto restart;
+                       }
                }
+               spin_unlock_bh(&mp->em_lock);
        }
-       spin_unlock_bh(&mp->em_lock);
 }
 EXPORT_SYMBOL(fc_exch_mgr_reset);
 
@@ -1778,6 +1781,8 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
        if (!mp->ep_pool)
                goto free_mp;
 
+       /* add em to the em_list */
+       list_add_tail(&mp->em_list, &lp->em_list);
        return mp;
 
 free_mp:
@@ -1794,6 +1799,8 @@ void fc_exch_mgr_free(struct fc_exch_mgr *mp)
         * before freeing exchange manager.
         */
        WARN_ON(mp->total_exches != 0);
+       /* remove em from the em_list */
+       list_del(&mp->em_list);
        mempool_destroy(mp->ep_pool);
        kfree(mp);
 }
@@ -1939,6 +1946,7 @@ int fc_exch_init(struct fc_lport *lp)
        if (!lp->tt.seq_exch_abort)
                lp->tt.seq_exch_abort = fc_seq_exch_abort;
 
+       INIT_LIST_HEAD(&lp->em_list);
        return 0;
 }
 EXPORT_SYMBOL(fc_exch_init);
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 0303a6a..712fcaf 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -649,6 +649,7 @@ struct fc_lport {
        /* Associations */
        struct Scsi_Host        *host;
        struct fc_exch_mgr      *emp;
+       struct list_head        em_list;
        struct fc_rport         *dns_rp;
        struct fc_rport         *ptp_rp;
        void                    *scsi_priv;

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to