aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/fcoe/fcoe.c14
-rw-r--r--drivers/scsi/libfc/fc_exch.c48
-rw-r--r--drivers/scsi/libfc/fc_lport.c1
3 files changed, 56 insertions, 7 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 14a4017a153..719a99d4a43 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -603,18 +603,18 @@ static int fcoe_if_create(struct net_device *netdev)
603 goto out_netdev_cleanup; 603 goto out_netdev_cleanup;
604 } 604 }
605 605
606 /* lport exch manager allocation */ 606 /* Initialize the library */
607 rc = fcoe_em_config(lp); 607 rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
608 if (rc) { 608 if (rc) {
609 FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the " 609 FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the "
610 "interface\n"); 610 "interface\n");
611 goto out_netdev_cleanup; 611 goto out_lp_destroy;
612 } 612 }
613 613
614 /* Initialize the library */ 614 /* lport exch manager allocation */
615 rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ); 615 rc = fcoe_em_config(lp);
616 if (rc) { 616 if (rc) {
617 FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " 617 FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
618 "interface\n"); 618 "interface\n");
619 goto out_lp_destroy; 619 goto out_lp_destroy;
620 } 620 }
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index cab54996375..f1fa2b196e9 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -55,6 +55,7 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
55 */ 55 */
56struct fc_exch_mgr { 56struct fc_exch_mgr {
57 enum fc_class class; /* default class for sequences */ 57 enum fc_class class; /* default class for sequences */
58 struct kref kref; /* exchange mgr reference count */
58 spinlock_t em_lock; /* exchange manager lock, 59 spinlock_t em_lock; /* exchange manager lock,
59 must be taken before ex_lock */ 60 must be taken before ex_lock */
60 u16 last_xid; /* last allocated exchange ID */ 61 u16 last_xid; /* last allocated exchange ID */
@@ -84,6 +85,12 @@ struct fc_exch_mgr {
84}; 85};
85#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) 86#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
86 87
88struct fc_exch_mgr_anchor {
89 struct list_head ema_list;
90 struct fc_exch_mgr *mp;
91 bool (*match)(struct fc_frame *);
92};
93
87static void fc_exch_rrq(struct fc_exch *); 94static void fc_exch_rrq(struct fc_exch *);
88static void fc_seq_ls_acc(struct fc_seq *); 95static void fc_seq_ls_acc(struct fc_seq *);
89static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason, 96static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason,
@@ -1729,6 +1736,47 @@ reject:
1729 fc_frame_free(fp); 1736 fc_frame_free(fp);
1730} 1737}
1731 1738
1739struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
1740 struct fc_exch_mgr *mp,
1741 bool (*match)(struct fc_frame *))
1742{
1743 struct fc_exch_mgr_anchor *ema;
1744
1745 ema = kmalloc(sizeof(*ema), GFP_ATOMIC);
1746 if (!ema)
1747 return ema;
1748
1749 ema->mp = mp;
1750 ema->match = match;
1751 /* add EM anchor to EM anchors list */
1752 list_add_tail(&ema->ema_list, &lport->ema_list);
1753 kref_get(&mp->kref);
1754 return ema;
1755}
1756EXPORT_SYMBOL(fc_exch_mgr_add);
1757
1758static void fc_exch_mgr_destroy(struct kref *kref)
1759{
1760 struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
1761
1762 /*
1763 * The total exch count must be zero
1764 * before freeing exchange manager.
1765 */
1766 WARN_ON(mp->total_exches != 0);
1767 mempool_destroy(mp->ep_pool);
1768 kfree(mp);
1769}
1770
1771void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
1772{
1773 /* remove EM anchor from EM anchors list */
1774 list_del(&ema->ema_list);
1775 kref_put(&ema->mp->kref, fc_exch_mgr_destroy);
1776 kfree(ema);
1777}
1778EXPORT_SYMBOL(fc_exch_mgr_del);
1779
1732struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, 1780struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
1733 enum fc_class class, 1781 enum fc_class class,
1734 u16 min_xid, u16 max_xid) 1782 u16 min_xid, u16 max_xid)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index a430335ebf5..ca8ea264b68 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1618,6 +1618,7 @@ int fc_lport_init(struct fc_lport *lport)
1618 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT) 1618 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
1619 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT; 1619 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
1620 1620
1621 INIT_LIST_HEAD(&lport->ema_list);
1621 return 0; 1622 return 0;
1622} 1623}
1623EXPORT_SYMBOL(fc_lport_init); 1624EXPORT_SYMBOL(fc_lport_init);