diff options
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 48 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 1 |
2 files changed, 49 insertions, 0 deletions
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 | */ |
56 | struct fc_exch_mgr { | 56 | struct 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 | ||
88 | struct fc_exch_mgr_anchor { | ||
89 | struct list_head ema_list; | ||
90 | struct fc_exch_mgr *mp; | ||
91 | bool (*match)(struct fc_frame *); | ||
92 | }; | ||
93 | |||
87 | static void fc_exch_rrq(struct fc_exch *); | 94 | static void fc_exch_rrq(struct fc_exch *); |
88 | static void fc_seq_ls_acc(struct fc_seq *); | 95 | static void fc_seq_ls_acc(struct fc_seq *); |
89 | static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason, | 96 | static 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 | ||
1739 | struct 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 | } | ||
1756 | EXPORT_SYMBOL(fc_exch_mgr_add); | ||
1757 | |||
1758 | static 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 | |||
1771 | void 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 | } | ||
1778 | EXPORT_SYMBOL(fc_exch_mgr_del); | ||
1779 | |||
1732 | struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, | 1780 | struct 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 | } |
1623 | EXPORT_SYMBOL(fc_lport_init); | 1624 | EXPORT_SYMBOL(fc_lport_init); |