// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright(c) 2007 Intel Corporation. All rights reserved.
 * Copyright(c) 2008 Red Hat, Inc.  All rights reserved.
 * Copyright(c) 2008 Mike Christie
 *
 * Maintained at www.Open-FCoE.org
 */

/*
 * Fibre Channel exchange and sequence handling.
 */

#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/log2.h>

#include <scsi/fc/fc_fc2.h>

#include <scsi/libfc.h>
#include <scsi/fc_encode.h>

#include "fc_libfc.h"

u16	fc_cpu_mask;		/* cpu mask for possible cpus */
EXPORT_SYMBOL(fc_cpu_mask);
static u16	fc_cpu_order;	/* 2's power to represent total possible cpus */
static struct kmem_cache *fc_em_cachep;	       /* cache for exchanges */
static struct workqueue_struct *fc_exch_workqueue;

/*
 * Structure and function definitions for managing Fibre Channel Exchanges
 * and Sequences.
 *
 * The three primary structures used here are fc_exch_mgr, fc_exch, and fc_seq.
 *
 * fc_exch_mgr holds the exchange state for an N port
 *
 * fc_exch holds state for one exchange and links to its active sequence.
 *
 * fc_seq holds the state for an individual sequence.
 */

/**
 * struct fc_exch_pool - Per cpu exchange pool
 * @next_index:	  Next possible free exchange index
 * @total_exches: Total allocated exchanges
 * @lock:	  Exch pool lock
 * @ex_list:	  List of exchanges
 *
 * This structure manages per cpu exchanges in array of exchange pointers.
 * This array is allocated followed by struct fc_exch_pool memory for
 * assigned range of exchanges to per cpu pool.
 */
struct fc_exch_pool {
	spinlock_t	 lock;
	struct list_head ex_list;
	u16		 next_index;
	u16		 total_exches;

	/* two cache of free slot in exch array */
	u16		 left;
	u16		 right;
} ____cacheline_aligned_in_smp;

/**
 * struct fc_exch_mgr - The Exchange Manager (EM).
 * @class:	    Default class for new sequences
 * @kref:	    Reference counter
 * @min_xid:	    Minimum exchange ID
 * @max_xid:	    Maximum exchange ID
 * @ep_pool:	    Reserved exchange pointers
 * @pool_max_index: Max exch array index in exch pool
 * @pool:	    Per cpu exch pool
 * @stats:	    Statistics structure
 *
 * This structure is the center for creating exchanges and sequences.
 * It manages the allocation of exchange IDs.
 */
struct fc_exch_mgr {
	struct fc_exch_pool __percpu *pool;
	mempool_t	*ep_pool;
	struct fc_lport	*lport;
	enum fc_class	class;
	struct kref	kref;
	u16		min_xid;
	u16		max_xid;
	u16		pool_max_index;

	struct {
		atomic_t no_free_exch;
		atomic_t no_free_exch_xid;
		atomic_t xid_not_found;
		atomic_t xid_busy;
		atomic_t seq_not_found;
		atomic_t non_bls_resp;
	} stats;
};

/**
 * struct fc_exch_mgr_anchor - primary structure for list of EMs
 * @ema_list: Exchange Manager Anchor list
 * @mp:	      Exchange Manager associated with this anchor
 * @match:    Routine to determine if this anchor's EM should be used
 *
 * When walking the list of anchors the match routine will be called
 * for each anchor to determine if that EM should be used. The last
 * anchor in the list will always match to handle any exchanges not
 * handled by other EMs. The non-default EMs would be added to the
 * anchor list by HW that provides offloads.
 */
struct fc_exch_mgr_anchor {
	struct list_head ema_list;
	struct fc_exch_mgr *mp;
	bool (*match)(struct fc_frame *);
};

static void fc_exch_rrq(struct fc_exch *);
static void fc_seq_ls_acc(struct fc_frame *);
static void fc_seq_ls_rjt(struct fc_frame *, enum fc_els_rjt_reason,
			  enum fc_els_rjt_explan);
static void fc_exch_els_rec(struct fc_frame *);
static void fc_exch_els_rrq(struct fc_frame *);

/*
 * Internal implementation notes.
 *
 * The exchange manager is one by default in libfc but LLD may choose
 * to have one per CPU. The sequence manager is one per exchange manager
 * and currently never separated.
 *
 * Section 9.8 in FC-FS-2 specifies:  "The SEQ_ID is a one-byte field
 * assigned by the Sequence Initiator that shall be unique for a specific
 * D_ID and S_ID pair while the Sequence is open."   Note that it isn't
 * qualified by exchange ID, which one might think it would be.
 * In practice this limits the number of open sequences and exchanges to 256
 * per session.	 For most targets we could treat this limit as per exchange.
 *
 * The exchange and its sequence are freed when the last sequence is received.
 * It's possible for the remote port to leave an exchange open without
 * sending any sequences.
 *
 * Notes on reference counts:
 *
 * Exchanges are reference counted and exchange gets freed when the reference
 * count becomes zero.
 *
 * Timeouts:
 * Sequences are timed out for E_D_TOV and R_A_TOV.
 *
 * Sequence event handling:
 *
 * The following events may occur on initiator sequences:
 *
 *	Send.
 *	    For now, the whole thing is sent.
 *	Receive ACK
 *	    This applies only to class F.
 *	    The sequence is marked complete.
 *	ULP completion.
 *	    The upper layer calls fc_exch_done() when done
 *	    with exchange and sequence tuple.
 *	RX-inferred completion.
 *	    When we receive the next sequence on the same exchange, we can
 *	    retire the previous sequence ID.  (XXX not implemented).
 *	Timeout.
 *	    R_A_TOV frees the sequence ID.  If we're waiting for ACK,
 *	    E_D_TOV causes abort and calls upper layer response handler
 *	    with FC_EX_TIMEOUT error.
 *	Receive RJT
 *	    XXX defer.
 *	Send ABTS
 *	    On timeout.
 *
 * The following events may occur on recipient sequences:
 *
 *	Receive
 *	    Allocate sequence for first frame received.
 *	    Hold during receive handler.
 *	    Release when final frame received.
 *	    Keep status of last N of these for the ELS RES command.  XXX TBD.
 *	Receive ABTS
 *	    Deallocate sequence
 *	Send RJT
 *	    Deallocate
 *
 * For now, we neglect conditions where only part of a sequence was
 * received or transmitted, or where out-of-order receipt is detected.
 */

/*
 * Locking notes:
 *
 * The EM code run in a per-CPU worker thread.
 *
 * To protect against concurrency between a worker thread code and timers,
 * sequence allocation and deallocation must be locked.
 *  - exchange refcnt can be done atomicly without locks.
 *  - sequence allocation must be locked by exch lock.
 *  - If the EM pool lock and ex_lock must be taken at the same time, then the
 *    EM pool lock must be taken before the ex_lock.
 */

/*
 * opcode names for debugging.
 */
static char *fc_exch_rctl_names[] = FC_RCTL_NAMES_INIT;

/**
 * fc_exch_name_lookup() - Lookup name by opcode
 * @op:	       Opcode to be looked up
 * @table:     Opcode/name table
 * @max_index: Index not to be exceeded
 *
 * This routine is used to determine a human-readable string identifying
 * a R_CTL opcode.
 */
static inline const char *fc_exch_name_lookup(unsigned int op, char **table,
					      unsigned int max_index)
{
	const char *name = NULL;

	if (op < max_index)
		name = table[op];
	if (!name)
		name = "unknown";
	return name;
}

/**
 * fc_exch_rctl_name() - Wrapper routine for fc_exch_name_lookup()
 * @op: The opcode to be looked up
 */
static const char *fc_exch_rctl_name(unsigned int op)
{
	return fc_exch_name_lookup(op, fc_exch_rctl_names,
				   ARRAY_SIZE(fc_exch_rctl_names));
}

/**
 * fc_exch_hold() - Increment an exchange's reference count
 * @ep: Echange to be held
 */
static inline void fc_exch_hold(struct fc_exch *ep)
{
	atomic_inc(&ep->ex_refcnt);
}

/**
 * fc_exch_setup_hdr() - Initialize a FC header by initializing some fields
 *			 and determine SOF and EOF.
 * @ep:	   The exchange to that will use the header
 * @fp:	   The frame whose header is to be modified
 * @f_ctl: F_CTL bits that will be used for the frame header
 *
 * The fields initialized by this routine are: fh_ox_id, fh_rx_id,
 * fh_seq_id, fh_seq_cnt and the SOF and EOF.
 */
static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp,
			      u32 f_ctl)
{
	struct fc_frame_header *fh = fc_frame_header_get(fp);
	u16 fill;

	fr_sof(fp) = ep->class;
	if (ep->seq.cnt)
		fr_sof(fp) = fc_sof_normal(ep->class);

	if (f_ctl & FC_FC_END_SEQ) {
		fr_eof(fp) = FC_EOF_T;
		if (fc_sof_needs_ack(ep->class))
			fr_eof(fp) = FC_EOF_N;
		/*
		 * From F_CTL.
		 * The number of fill bytes to make the length a 4-byte
		 * multiple is the low order 2-bits of the f_ctl.
		 * The fill itself will have been cleared by the frame
		 * allocation.
		 * After this, the length will be even, as expected by
		 * the transport.
		 */
		fill = fr_len(fp) & 3;
		if (fill) {
			fill = 4 - fill;
			/* TODO, this may be a problem with fragmented skb */
			skb_put(fp_skb(fp), fill);
			hton24(fh->fh_f_ctl, f_ctl | fill);
		}
	} else {
		WARN_ON(fr_len(fp) % 4 != 0);	/* no pad to non last frame */
		fr_eof(fp) = FC_EOF_N;
	}

	/* Initialize remaining fh fields from fc_fill_fc_hdr */
	fh->fh_ox_id = htons(ep->oxid);
	fh->fh_rx_id = htons(ep->rxid);
	fh->fh_seq_id = ep->seq.id;
	fh->fh_seq_cnt = htons(ep->seq.cnt);
}

/**
 * fc_exch_release() - Decrement an exchange's reference count
 * @ep: Exchange to be released
 *
 * If the reference count reaches zero and the exchange is complete,
 * it is freed.
 */
static void fc_exch_release(struct fc_exch *ep)
{
	struct fc_exch_mgr *mp;

	if (atomic_dec_and_test(&ep->ex_refcnt)) {
		mp = ep->em;
		if (ep->destructor)
			ep->destructor(&ep->seq, ep->arg);
		WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE));
		mempool_free(ep, mp->ep_pool);
	}
}

/**
 * fc_exch_timer_cancel() - cancel exch timer
 * @ep:		The exchange whose timer to be canceled
 */
static inline void fc_exch_timer_cancel(struct fc_exch *ep)
{
	if (cancel_delayed_work(&ep->timeout_work)) {
		FC_EXCH_DBG(ep, "Exchange timer canceled\n");
		atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
	}
}

/**
 * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the
 *				the exchange lock held
 * @ep:		The exchange whose timer will start
 * @timer_msec: The timeout period
 *
 * Used for upper level protocols to time out the exchange.
 * The timer is cancelled when it fires or when the exchange completes.
 */
static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
					    unsigned int timer_msec)
{
	if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
		return;

	FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec);

	fc_exch_hold(ep);		/* hold for timer */
	if (!queue_delayed_work(fc_exch_workqueue, &ep->timeout_work,
				msecs_to_jiffies(timer_msec))) {
		FC_EXCH_DBG(ep, "Exchange already queued\n");
		fc_exch_release(ep);
	}
}

/**
 * fc_exch_timer_set() - Lock the exchange and set the timer
 * @ep:		The exchange whose timer will start
 * @timer_msec: The timeout period
 */
static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec)
{
	spin_lock_bh(&ep->ex_lock);
	fc_exch_timer_set_locked(ep, timer_msec);
	spin_unlock_bh(&ep->ex_lock);
}

/**
 * fc_exch_done_locked() - Complete an exchange with the exchange lock held
 * @ep: The exchange that is complete
 *
 * Note: May sleep if invoked from outside a response handler.
 */
static int fc_exch_done_locked(struct fc_exch *ep)
{
	int rc = 1;

	/*
	 * We must check for completion in case there are two threads
	 * tyring to complete this. But the rrq code will reuse the
	 * ep, and in that case we only clear the resp and set it as
	 * complete, so it can be reused by the timer to send the rrq.
	 */
	if (ep->state & FC_EX_DONE)
		return rc;
	ep->esb_stat |= ESB_ST_COMPLETE;

	if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
		ep->state |= FC_EX_DONE;
		fc_exch_timer_cancel(ep);
		rc = 0;
	}
	return rc;
}

static struct fc_exch fc_quarantine_exch;

/**
 * fc_exch_ptr_get() - Return an exchange from an exchange pool
 * @pool:  Exchange Pool to get an exchange from
 * @index: Index of the exchange within the pool
 *
 * Use the index to get an exchange from within an exchange pool. exches
 * will point to an array of exchange pointers. The index will select
 * the exchange within the array.
 */
static inline struct fc_exch *fc_exch_ptr_get(struct fc_exch_pool *pool,
					      u16 index)
{
	struct fc_exch **exches = (struct fc_exch **)(pool + 1);
	return exches[index];
}

/**
 * fc_exch_ptr_set() - Assign an exchange to a slot in an exchange pool
 * @pool:  The pool to assign the exchange to
 * @index: The index in the pool where the exchange will be assigned
 * @ep:	   The exchange to assign to the pool
 */
static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
				   struct fc_exch *ep)
{
	((struct fc_exch **)(pool + 1))[index] = ep;
}

/**
 * fc_exch_delete() - Delete an exchange
 * @ep: The exchange to be deleted
 */
static void fc_exch_delete(struct fc_exch *ep)
{
	struct fc_exch_pool *pool;
	u16 index;

	pool = ep->pool;
	spin_lock_bh(&pool->lock);
	WARN_ON(pool->total_exches <= 0);
	pool->total_exches--;

	/* update cache of free slot */
	index = (ep->xid - ep->em->min_xid) >> fc_cpu_order;
	if (!(ep->state & FC_EX_QUARANTINE)) {
		if (pool->left == FC_XID_UNKNOWN)
			pool->left = index;
		else if (pool->right == FC_XID_UNKNOWN)
			pool->right = index;
		else
			pool->next_index = index;
		fc_exch_ptr_set(pool, index, NULL);
	} else {
		fc_exch_ptr_set(pool, index, &fc_quarantine_exch);
	}
	list_del(&ep->ex_list);
	spin_unlock_bh(&pool->lock);
	fc_exch_release(ep);	/* drop hold for exch in mp */
}

static int fc_seq_send_locked(struct fc_lport *lport, struct fc_seq *sp,
			      struct fc_frame *fp)
{
	struct fc_exch *ep;
	struct fc_frame_header *fh = fc_frame_header_get(fp);
	int error = -ENXIO;
	u32 f_ctl;
	u8 fh_type = fh->fh_type;

	ep = fc_seq_exch(sp);

	if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL)) {
		fc_frame_free(fp);
		goto out;
	}

	WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT));

	f_ctl = ntoh24(fh->fh_f_ctl);
	fc_exch_setup_hdr(ep, fp, f_ctl);
	fr_encaps(fp) = ep->encaps;

	/*
	 * update sequence count if this frame is carrying
	 * multiple FC frames when sequence offload is enabled
	 * by LLD.
	 */
	if (fr_max_payload(fp))
		sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
					fr_max_payload(fp));
	else
		sp->cnt++;

	/*
	 * Send the frame.
	 */
	error = lport->tt.frame_send(lport, fp);

	if (fh_type == FC_TYPE_BLS)
		goto out;

	/*
	 * Update the exchange and sequence flags,
	 * assuming all frames for the sequence have been sent.
	 * We can only be called to send once for each sequence.
	 */
	ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;	/* not first seq */
	if (f_ctl & FC_FC_SEQ_INIT)
		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
out:
	return error;
}

/**
 * fc_seq_send() - Send a frame using existing sequence/exchange pair
 * @lport: The local port that the exchange will be sent on
 * @sp:	   The sequence to be sent
 * @fp:	   The frame to be sent on the exchange
 *
 * Note: The frame will be freed either by a direct call to fc_frame_free(fp)
 * or indirectly by calling libfc_function_template.frame_send().
 */
int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, struct fc_frame *fp)
{
	struct fc_exch *ep;
	int error;
	ep = fc_seq_exch(sp);
	spin_lock_bh(&ep->ex_lock);
	error = fc_seq_send_locked(lport, sp, fp);
	spin_unlock_bh(&ep->ex_lock);
	return error;
}
EXPORT_SYMBOL(fc_seq_send);

/**
 * fc_seq_alloc() - Allocate a sequence for a given exchange
 * @ep:	    The exchange to allocate a new sequence for
 * @seq_id: The sequence ID to be used
 *
 * We don't support multiple originated sequences on the same exchange.
 * By implication, any previously originated sequence on this exchange
 * is complete, and we reallocate the same sequence.
 */
static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
{
	struct fc_seq *sp;

	sp = &ep->seq;
	sp->ssb_stat = 0;
	sp->cnt = 0;
	sp->id = seq_id;
	return sp;
}

/**
 * fc_seq_start_next_locked() - Allocate a new sequence on the same
 *				exchange as the supplied sequence
 * @sp: The sequence/exchange to get a new sequence for
 */
static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
{
	struct fc_exch *ep = fc_seq_exch(sp);

	sp = fc_seq_alloc(ep, ep->seq_id++);
	FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
		    ep->f_ctl, sp->id);
	return sp;
}

/**
 * fc_seq_start_next() - Lock the exchange and get a new sequence
 *			 for a given sequence/exchange pair
 * @sp: The sequence/exchange to get a new exchange for
 */
struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
{
	struct fc_exch *ep = fc_seq_exch(sp);

	spin_lock_bh(&ep->ex_lock);
	sp = fc_seq_start_next_locked(sp);
	spin_unlock_bh(&ep->ex_lock);

	return sp;
}
EXPORT_SYMBOL(fc_seq_start_next);

/*
 * Set the response handler for the exchange associated with a sequence.
 *
 * Note: May sleep if invoked from outside a response handler.
 */
void fc_seq_set_resp(struct fc_seq *sp,
		     void (*resp)(struct fc_seq *, struct fc_frame *, void *),
		     void *arg)
{
	struct fc_exch *ep = fc_seq_exch(sp);
	DEFINE_WAIT(wait);

	spin_lock_bh(&ep->ex_lock);
	while (ep->resp_active && ep->resp_task != current) {
		prepare_to_wait(&ep->resp_wq, &wait, TASK_UNINTERRUPTIBLE);
		spin_unlock_bh(&ep->ex_lock);

		schedule();

		spin_lock_bh(&ep->ex_lock);
	}
	finish_wait(&ep->resp_wq, &wait);
	ep->resp = resp;
	ep->arg = arg;
	spin_unlock_bh(&ep->ex_lock);
}
EXPORT_SYMBOL(fc_seq_set_resp);

/**
 * fc_exch_abort_locked() - Abort an exchange
 * @ep:	The exchange to be aborted
 * @timer_msec: The period of time to wait before aborting
 *
 * Abort an exchange and sequence. Generally called because of a
 * exchange timeout or an abort from the upper layer.
 *
 * A timer_msec can be specified for abort timeout, if non-zero
 * timer_msec value is specified then exchange resp handler
 * will be called with timeout error if no response to abort.
 *
 * Locking notes:  Called with exch lock held
 *
 * Return value: 0 on success else error code
 */
static int fc_exch_abort_locked(struct fc_exch *ep,
				unsigned int timer_msec)
{
	struct fc_seq *sp;
	struct fc_frame *fp;
	int error;

	FC_EXCH_DBG(ep, "exch: abort, time %d msecs\n", timer_msec);
	if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) ||
	    ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) {
		FC_EXCH_DBG(ep, "exch: already completed esb %x state %x\n",
			    ep->esb_stat, ep->state);
		return -ENXIO;
	}

	/*
	 * Send the abort on a new sequence if possible.
	 */
	sp = fc_seq_start_next_locked(&ep->seq);
	if (!sp)
		return -ENOMEM;

	if (timer_msec)
		fc_exch_timer_set_locked(ep, timer_msec);

	if (ep->sid) {
		/*
		 * Send an abort for the sequence that timed out.
		 */
		fp = fc_frame_alloc(ep->lp, 0);
		if (fp) {
			ep->esb_stat |= ESB_ST_SEQ_INIT;
			fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
				       FC_TYPE_BLS, FC_FC_END_SEQ |
				       FC_FC_SEQ_INIT, 0);
			error = fc_seq_send_locked(ep->lp, sp, fp);
		} else {
			error = -ENOBUFS;
		}
	} else {
		/*
		 * If not logged into the fabric, don't send ABTS but leave
		 * sequence active until next timeout.
		 */
		error = 0;
	}
	ep->esb_stat |= ESB_ST_ABNORMAL;
	return error;
}

/**
 * fc_seq_exch_abort() - Abort an exchange and sequence
 * @req_sp:	The sequence to be aborted
 * @timer_msec: The period of time to wait before aborting
 *
 * Generally called because of a timeout or an abort from the upper layer.
 *
 * Return value: 0 on success else error code
 */
int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec)
{
	struct fc_exch *ep;
	int error;

	ep = fc_seq_exch(req_sp);
	spin_lock_bh(&ep->ex_lock);
	error = fc_exch_abort_locked(ep, timer_msec);
	spin_unlock_bh(&ep->ex_lock);
	return error;
}

/**
 * fc_invoke_resp() - invoke ep->resp()
 *
 * Notes:
 * It is assumed that after initialization finished (this means the
 * first unlock of ex_lock after fc_exch_alloc()) ep->resp and ep->arg are
 * modified only via fc_seq_set_resp(). This guarantees that none of these
 * two variables changes if ep->resp_active > 0.
 *
 * If an fc_seq_set_resp() call is busy modifying ep->resp and ep->arg when
 * this function is invoked, the first spin_lock_bh() call in this function
 * will wait until fc_seq_set_resp() has finished modifying these variables.
 *
 * Since fc_exch_done() invokes fc_seq_set_resp() it is guaranteed that that
 * ep->resp() won't be invoked after fc_exch_done() has returned.
 *
 * The response handler itself may invoke fc_exch_done(), which will clear the
 * ep->resp pointer.
 *
 * Return value:
 * Returns true if and only if ep->resp has been invoked.
 */
static bool fc_invoke_resp(struct fc_exch *ep, struct fc_seq *sp,
			   struct fc_frame *fp)
{
	void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
	void *arg;
	bool res = false;

	spin_lock_bh(&ep->ex_lock);
	ep->resp_active++;
	if (ep->resp_task != current)
		ep->resp_task = !ep->resp_task ? current : NULL;
	resp = ep->resp;
	arg = ep->arg;
	spin_unlock_bh(&ep->ex_lock);

	if (resp) {
		resp(sp, fp, arg);
		res = true;
	}

	spin_lock_bh(&ep->ex_lock);
	if (--ep->resp_active == 0)
		ep->resp_task = NULL;
	spin_unlock_bh(&ep->ex_lock);

	if (ep->resp_active == 0)
		wake_up(&ep->resp_wq);

	return res;
}

/**
 * fc_exch_timeout() - Handle exchange timer expiration
 * @work: The work_struct identifying the exchange that timed out
 */
static void fc_exch_timeout(struct work_struct *work)
{
	struct fc_exch *ep = container_of(work, struct fc_exch,
					  timeout_work.work);
	struct fc_seq *sp = &ep->seq;
	u32 e_stat;
	int rc = 1;

	FC_EXCH_DBG(ep, "Exchange timed out state %x\n", ep->state);

	spin_lock_bh(&ep->ex_lock);
	if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
		goto unlock;

	e_stat = ep->esb_stat;
	if (e_stat & ESB_ST_COMPLETE) {
		ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL;
		spin_unlock_bh(&ep->ex_lock);
		if (e_stat & ESB_ST_REC_QUAL)
			fc_exch_rrq(ep);
		goto done;
	} else {
		if (e_stat & ESB_ST_ABNORMAL)
			rc = fc_exch_done_locked(ep);
		spin_unlock_bh(&ep->ex_lock);
		if (!rc)
			fc_exch_delete(ep);
		fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_TIMEOUT));
		fc_seq_set_resp(sp, NULL, ep->arg);
		fc_seq_exch_abort(sp, 2 * ep->r_a_tov);
		goto done;
	}
unlock:
	spin_unlock_bh(&ep->ex_lock);
done:
	/*
	 * This release matches the hold taken when the timer was set.
	 */
	fc_exch_release(ep);
}

/**
 * fc_exch_em_alloc() - Allocate an exchange from a specified EM.
 * @lport: The local port that the exchange is for
 * @mp:	   The exchange manager that will allocate the exchange
 *
 * Returns pointer to allocated fc_exch with exch lock held.
 */
static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
					struct fc_exch_mgr *mp)
{
	struct fc_exch *ep;
	unsigned int cpu;
	u16 index;
	struct fc_exch_pool *pool;

	/* allocate memory for exchange */
	ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
	if (!ep) {
		atomic_inc(&mp->stats.no_free_exch);
		goto out;
	}
	memset(ep, 0, sizeof(*ep));

	cpu = get_cpu();
	pool = per_cpu_ptr(mp->pool, cpu);
	spin_lock_bh(&pool->lock);
	put_cpu();

	/* peek cache of free slot */
	if (pool->left != FC_XID_UNKNOWN) {
		if (!WARN_ON(fc_exch_ptr_get(pool, pool->left))) {
			index = pool->left;
			pool->left = FC_XID_UNKNOWN;
			goto hit;
		}
	}
	if (pool->right != FC_XID_UNKNOWN) {
		if (!WARN_ON(fc_exch_ptr_get(pool, pool->right))) {
			index = pool->right;
			pool->right = FC_XID_UNKNOWN;
			goto hit;
		}
	}

	index = pool->next_index;
	/* allocate new exch from pool */
	while (fc_exch_ptr_get(pool, index)) {
		index = index == mp->pool_max_index ? 0 : index + 1;
		if (index == pool->next_index)
			goto err;
	}
	pool->next_index = index == mp->pool_max_index ? 0 : index + 1;
hit:
	fc_exch_hold(ep);	/* hold for exch in mp */
	spin_lock_init(&ep->ex_lock);
	/*
	 * Hold exch lock for caller to prevent fc_exch_reset()
	 * from releasing exch	while fc_exch_alloc() caller is
	 * still working on exch.
	 */
	spin_lock_bh(&ep->ex_lock);

	fc_exch_ptr_set(pool, index, ep);
	list_add_tail(&ep->ex_list, &pool->ex_list);
	fc_seq_alloc(ep, ep->seq_id++);
	pool->total_exches++;
	spin_unlock_bh(&pool->lock);

	/*
	 *  update exchange
	 */
	ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid;
	ep->em = mp;
	ep->pool = pool;
	ep->lp = lport;
	ep->f_ctl = FC_FC_FIRST_SEQ;	/* next seq is first seq */
	ep->rxid = FC_XID_UNKNOWN;
	ep->class = mp->class;
	ep->resp_active = 0;
	init_waitqueue_head(&ep->resp_wq);
	INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout);
out:
	return ep;
err:
	spin_unlock_bh(&pool->lock);
	atomic_inc(&mp->stats.no_free_exch_xid);
	mempool_free(ep, mp->ep_pool);
	return NULL;
}

/**
 * fc_exch_alloc() - Allocate an exchange from an EM on a
 *		     local port's list of EMs.
 * @lport: The local port that will own the exchange
 * @fp:	   The FC frame that the exchange will be for
 *
 * This function walks the list of exchange manager(EM)
 * anchors to select an EM for a new exchange allocation. The
 * EM is selected when a NULL match function pointer is encountered
 * or when a call to a match function returns true.
 */
static struct fc_exch *fc_exch_alloc(struct fc_lport *lport,
				     struct fc_frame *fp)
{
	struct fc_exch_mgr_anchor *ema;
	struct fc_exch *ep;

	list_for_each_entry(ema, &lport->ema_list, ema_list) {
		if (!ema->match || ema->match(fp)) {
			ep = fc_exch_em_alloc(lport, ema->mp);
			if (ep)
				return ep;
		}
	}
	return NULL;
}

/**
 * fc_exch_find() - Lookup and hold an exchange
 * @mp:	 The exchange manager to lookup the exchange from
 * @xid: The XID of the exchange to look up
 */
static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid)
{
	struct fc_lport *lport = mp->lport;
	struct fc_exch_pool *pool;
	struct fc_exch *ep = NULL;
	u16 cpu = xid & fc_cpu_mask;

	if (xid == FC_XID_UNKNOWN)
		return NULL;

	if (cpu >= nr_cpu_ids || !cpu_possible(cpu)) {
		pr_err("host%u: lport %6.6x: xid %d invalid CPU %d\n:",
		       lport->host->host_no, lport->port_id, xid, cpu);
		return NULL;
	}

	if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) {
		pool = per_cpu_ptr(mp->pool, cpu);
		spin_lock_bh(&pool->lock);
		ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order);
		if (ep == &fc_quarantine_exch) {
			FC_LPORT_DBG(lport, "xid %x quarantined\n", xid);
			ep = NULL;
		}
		if (ep) {
			WARN_ON(ep->xid != xid);
			fc_exch_hold(ep);
		}
		spin_unlock_bh(&pool->lock);
	}
	return ep;
}


/**
 * fc_exch_done() - Indicate that an exchange/sequence tuple is complete and
 *		    the memory allocated for the related objects may be freed.
 * @sp: The sequence that has completed
 *
 * Note: May sleep if invoked from outside a response handler.
 */
void fc_exch_done(struct fc_seq *sp)
{
	struct fc_exch *ep = fc_seq_exch(sp);
	int rc;

	spin_lock_bh(&ep->ex_lock);
	rc = fc_exch_done_locked(ep);
	spin_unlock_bh(&ep->ex_lock);

	fc_seq_set_resp(sp, NULL, ep->arg);
	if (!rc)
		fc_exch_delete(ep);
}
EXPORT_SYMBOL(fc_exch_done);

/**
 * fc_exch_resp() - Allocate a new exchange for a response frame
 * @lport: The local port that the exchange was for
 * @mp:	   The exchange manager to allocate the exchange from
 * @fp:	   The response frame
 *
 * Sets the responder ID in the frame header.
 */
static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
				    struct fc_exch_mgr *mp,
				    struct fc_frame *fp)
{
	struct fc_exch *ep;
	struct fc_frame_header *fh;

	ep = fc_exch_alloc(lport, fp);
	if (ep) {
		ep->class = fc_frame_class(fp);

		/*
		 * Set EX_CTX indicating we're responding on this exchange.
		 */
		ep->f_ctl |= FC_FC_EX_CTX;	/* we're responding */
		ep->f_ctl &= ~FC_FC_FIRST_SEQ;	/* not new */
		fh = fc_frame_header_get(fp);
		ep->sid = ntoh24(fh->fh_d_id);
		ep->did = ntoh24(fh->fh_s_id);
		ep->oid = ep->did;

		/*
		 * Allocated exchange has placed the XID in the
		 * originator field. Move it to the responder field,
		 * and set the originator XID from the frame.
		 */
		ep->rxid = ep->xid;
		ep->oxid = ntohs(fh->fh_ox_id);
		ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT;
		if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0)
			ep->esb_stat &= ~ESB_ST_SEQ_INIT;

		fc_exch_hold(ep);	/* hold for caller */
		spin_unlock_bh(&ep->ex_lock);	/* lock from fc_exch_alloc */
	}
	return ep;
}

/**
 * fc_seq_lookup_recip() - Find a sequence where the other end
 *			   originated the sequence
 * @lport: The local port that the frame was sent to
 * @mp:	   The Exchange Manager to lookup the exchange from
 * @fp:	   The frame associated with the sequence we're looking for
 *
 * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold
 * on the ep that should be released by the caller.
 */
static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
						 struct fc_exch_mgr *mp,
						 struct fc_frame *fp)
{
	struct fc_frame_header *fh = fc_frame_header_get(fp);
	struct fc_exch *ep = NULL;
	struct fc_seq *sp = NULL;
	enum fc_pf_rjt_reason reject = FC_RJT_NONE;
	u32 f_ctl;
	u16 xid;

	f_ctl = ntoh24(fh->fh_f_ctl);
	WARN_ON((f_ctl & FC_FC_SEQ_CTX) != 0);

	/*
	 * Lookup or create the exchange if we will be creating the sequence.
	 */
	if (f_ctl & FC_FC_EX_CTX) {
		xid = ntohs(fh->fh_ox_id);	/* we originated exch */
		ep = fc_exch_find(mp, xid);
		if (!ep) {
			atomic_inc(&mp->stats.xid_not_found);
			reject = FC_RJT_OX_ID;
			goto out;
		}
		if (ep->rxid == FC_XID_UNKNOWN)
			ep->rxid = ntohs(fh->fh_rx_id);
		else if (ep->rxid != ntohs(fh->fh_rx_id)) {
			reject = FC_RJT_OX_ID;
			goto rel;
		}
	} else {
		xid = ntohs(fh->fh_rx_id);	/* we are the responder */

		/*
		 * Special case for MDS issuing an ELS TEST with a
		 * bad rxid of 0.
		 * XXX take this out once we do the proper reject.
		 */
		if (xid == 0 && fh->fh_r_ctl == FC_RCTL_ELS_REQ &&
		    fc_frame_payload_op(fp) == ELS_TEST) {
			fh->fh_rx_id = htons(FC_XID_UNKNOWN);
			xid = FC_XID_UNKNOWN;
		}

		/*
		 * new sequence - find the exchange
		 */
		ep = fc_exch_find(mp, xid);
		if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
			if (ep) {
				atomic_inc(&mp->stats.xid_busy);
				reject = FC_RJT_RX_ID;
				goto rel;
			}
			ep = fc_exch_resp(lport, mp, fp);
			if (!ep) {
				reject = FC_RJT_EXCH_EST;	/* XXX */
				goto out;
			}
			xid = ep->xid;	/* get our XID */
		} else if (!ep) {
			atomic_inc(&mp->stats.xid_not_found);
			reject = FC_RJT_RX_ID;	/* XID not found */
			goto out;
		}
	}

	spin_lock_bh(&ep->ex_lock);
	/*
	 * At this point, we have the exchange held.
	 * Find or create the sequence.
	 */
	if (fc_sof_is_init(fr_sof(fp))) {
		sp = &ep->seq;
		sp->ssb_stat |= SSB_ST_RESP;
		sp->id = fh->fh_seq_id;
	} else {
		sp = &ep->seq;
		if (sp->id != fh->fh_seq_id) {
			atomic_inc(&mp->stats.seq_not_found);
			if (f_ctl & FC_FC_END_SEQ) {
				/*
				 * Update sequence_id based on incoming last
				 * frame of sequence exchange. This is needed
				 * for FC target where DDP has been used
				 * on target where, stack is indicated only
				 * about last frame's (payload _header) header.
				 * Whereas "seq_id" which is part of
				 * frame_header is allocated by initiator
				 * which is totally different from "seq_id"
				 * allocated when XFER_RDY was sent by target.
				 * To avoid false -ve which results into not
				 * sending RSP, hence write request on other
				 * end never finishes.
				 */
				sp->ssb_stat |= SSB_ST_RESP;
				sp->id = fh->fh_seq_id;
			} else {
				spin_unlock_bh(&ep->ex_lock);

				/* sequence/exch should exist */
				reject = FC_RJT_SEQ_ID;
				goto rel;
			}
		}
	}
	WARN_ON(ep != fc_seq_exch(sp));

	if (f_ctl & FC_FC_SEQ_INIT)
		ep->esb_stat |= ESB_ST_SEQ_INIT;
	spin_unlock_bh(&ep->ex_lock);

	fr_seq(fp) = sp;
out:
	return reject;
rel:
	fc_exch_done(&ep->seq);
	fc_exch_release(ep);	/* hold from fc_exch_find/fc_exch_resp */
	return reject;
}

/**
 * fc_seq_lookup_orig() - Find a sequence where this end
 *			  originated the sequence
 * @mp:	   The Exchange Manager to lookup the exchange from
 * @fp:	   The frame associated with the sequence we're looking for
 *
 * Does not hold the sequence for the caller.
 */
static struct fc_seq *fc_seq_lookup_orig(struct fc_exch_mgr *mp,
					 struct fc_frame *fp)
{
	struct fc_frame_header *fh = fc_frame_header_get(fp);
	struct fc_exch *ep;
	struct fc_seq *sp = NULL;
	u32 f_ctl;
	u16 xid;

	f_ctl = ntoh24(fh->fh_f_ctl);
	WARN_ON((f_ctl & FC_FC_SEQ_CTX) != FC_FC_SEQ_CTX);
	xid = ntohs((f_ctl & FC_FC_EX_CTX) ? fh->fh_ox_id : fh->fh_rx_id);
	ep = fc_exch_find(mp, xid);
	if (!ep)
		return NULL;
	if (ep->seq.id == fh->fh_seq_id) {
		/*
		 * Save the RX_ID if we didn't previously know it.
		 */
		sp = &ep->seq;
		if ((f_ctl & FC_FC_EX_CTX) != 0 &&
		    ep->rxid == FC_XID_UNKNOWN) {
			ep->rxid = ntohs(fh->fh_rx_id);
		}
	}
	fc_exch_release(ep);
	return sp;
}

/**
 * fc_exch_set_addr() - Set the source and destination IDs for an exchange
 * @ep:	     The exchange to set the addresses for
 * @orig_id: The originator's ID
 * @resp_id: The responder's ID
 *
 * Note this must be done before the first sequence of the exchange is sent.
 */
static void fc_exch_set_addr(struct fc_exch *ep,
			     u32 orig_id, u32 resp_id)
{
	ep->oid = orig_id;
	if (ep->esb_stat & ESB_ST_RESP) {
		ep->sid = resp_id;
		ep->did = orig_id;
	} else {
		ep->sid = orig_id;
		ep->did = resp_id;
	}
}

/**
 * fc_seq_els_rsp_send() - Send an ELS response using information from
 *			   the existing sequence/exchange.
 * @fp:	      The received frame
 * @els_cmd:  The ELS command to be sent
 * @els_data: The ELS data to be sent
 *
 * The received frame is not freed.
 */
void fc_seq_els_rsp_send(struct fc_frame *fp, enum fc_els_cmd els_cmd,
			 struct fc_seq_els_data *els_data)
{
	switch (els_cmd) {
	case ELS_LS_RJT:
		fc_seq_ls_rjt(fp, els_data->reason, els_data->explan);
		break;
	case ELS_LS_ACC:
		fc_seq_ls_acc(fp);
		break;
	case ELS_RRQ:
		fc_exch_els_rrq(fp);
		break;
	case ELS_REC:
		fc_exch_els_rec(fp);
		break;
	default:
		FC_LPORT_DBG(fr_dev(fp), "Invalid ELS CMD:%x\n", els_cmd);
	}
}
EXPORT_SYMBOL_GPL(fc_seq_els_rsp_send);

/**
 * fc_seq_send_last() - Send a sequence that is the last in the exchange
 * @sp:	     The sequence that is to be sent
 * @fp:	     The frame that will be sent on the sequence
 * @rctl:    The R_CTL information to be sent
 * @fh_type: The frame header type
 */
static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
			     enum fc_rctl rctl, enum fc_fh_type fh_type)
{
	u32 f_ctl;
	struct fc_exch *ep = fc_seq_exch(sp);

	f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
	f_ctl |= ep->f_ctl;
	fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0);
	fc_seq_send_locked(ep->lp, sp, fp);
}

/**
 * fc_seq_send_ack() - Send an acknowledgement that we've received a frame
 * @sp:	   The sequence to send the ACK on
 * @rx_fp: The received frame that is being acknoledged
 *
 * Send ACK_1 (or equiv.) indicating we received something.
 */
static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
{
	struct fc_frame *fp;
	struct fc_frame_header *rx_fh;
	struct fc_frame_header *fh;
	struct fc_exch *ep = fc_seq_exch(sp);
	struct fc_lport *lport = ep->lp;
	unsigned int f_ctl;

	/*
	 * Don't send ACKs for class 3.
	 */
	if (fc_sof_needs_ack(fr_sof(rx_fp))) {
		fp = fc_frame_alloc(lport, 0);
		if (!fp) {
			FC_EXCH_DBG(ep, "Drop ACK request, out of memory\n");
			return;
		}

		fh = fc_frame_header_get(fp);
		fh->fh_r_ctl = FC_RCTL_ACK_1;
		fh->fh_type = FC_TYPE_BLS;

		/*
		 * Form f_ctl by inverting EX_CTX and SEQ_CTX (bits 23, 22).
		 * Echo FIRST_SEQ, LAST_SEQ, END_SEQ, END_CONN, SEQ_INIT.
		 * Bits 9-8 are meaningful (retransmitted or unidirectional).
		 * Last ACK uses bits 7-6 (continue sequence),
		 * bits 5-4 are meaningful (what kind of ACK to use).
		 */
		rx_fh = fc_frame_header_get(rx_fp);
		f_ctl = ntoh24(rx_fh->fh_f_ctl);
		f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX |
			FC_FC_FIRST_SEQ | FC_FC_LAST_SEQ |
			FC_FC_END_SEQ | FC_FC_END_CONN | FC_FC_SEQ_INIT |
			FC_FC_RETX_SEQ | FC_FC_UNI_TX;
		f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
		hton24(fh->fh_f_ctl, f_ctl);

		fc_exch_setup_hdr(ep, fp, f_ctl);
		fh->fh_seq_id = rx_fh->fh_seq_id;
		fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
		fh->fh_parm_offset = htonl(1);	/* ack single frame */

		fr_sof(fp) = fr_sof(rx_fp);
		if (f_ctl & FC_FC_END_SEQ)
			fr_eof(fp) = FC_EOF_T;
		else
			fr_eof(fp) = FC_EOF_N;

		lport->tt.frame_send(lport, fp);
	}
}

/**
 * fc_exch_send_ba_rjt() - Send BLS Reject
 * @rx_fp:  The frame being rejected
 * @reason: The reason the frame is being rejected
 * @explan: The explanation for the rejection
 *
 * This is for rejecting BA_ABTS only.
 */
static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
				enum fc_ba_rjt_reason reason,
				enum fc_ba_rjt_explan explan)
{
	struct fc_frame *fp;
	struct fc_frame_header *rx_fh;
	struct fc_frame_header *fh;
	struct fc_ba_rjt *rp;
	struct fc_seq *sp;
	struct fc_lport *lport;
	unsigned int f_ctl;

	lport = fr_dev(rx_fp);
	sp = fr_seq(rx_fp);
	fp = fc_frame_alloc(lport, sizeof(*rp));
	if (!fp) {
		FC_EXCH_DBG(fc_seq_exch(sp),
			     "Drop BA_RJT request, out of memory\n");
		return;
	}
	fh = fc_frame_header_get(fp);
	rx_fh = fc_frame_header_get(rx_fp);

	memset(fh, 0, sizeof(*fh) + sizeof(*rp));

	rp = fc_frame_payload_get(fp, sizeof(*rp));
	rp->br_reason = reason;
	rp->br_explan = explan;

	/*
	 * seq_id, cs_ctl, df_ctl and param/offset are zero.
	 */
	memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3);
	memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3);
	fh->fh_ox_id = rx_fh->fh_ox_id;
	fh->fh_rx_id = rx_fh->fh_rx_id;
	fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
	fh->fh_r_ctl = FC_RCTL_BA_RJT;
	fh->fh_type = FC_TYPE_BLS;

	/*
	 * Form f_ctl by inverting EX_CTX and SEQ_CTX (bits 23, 22).
	 * Echo FIRST_SEQ, LAST_SEQ, END_SEQ, END_CONN, SEQ_INIT.
	 * Bits 9-8 are meaningful (retransmitted or unidirectional).
	 * Last ACK uses bits 7-6 (continue sequence),
	 * bits 5-4 are meaningful (what kind of ACK to use).
	 * Always set LAST_SEQ, END_SEQ.
	 */
	f_ctl = ntoh24(rx_fh->fh_f_ctl);
	f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX |
		FC_FC_END_CONN | FC_FC_SEQ_INIT |
		FC_FC_RETX_SEQ | FC_FC_UNI_TX;
	f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
	f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ;
	f_ctl &= ~FC_FC_FIRST_SEQ;
	hton24(fh->fh_f_ctl, f_ctl);

	fr_sof(fp) = fc_sof_class(fr_sof(rx_fp));
	fr_eof(fp) = FC_EOF_T;
	if (fc_sof_needs_ack(fr_sof(fp)))
		fr_eof(fp) = FC_EOF_N;

	lport->tt.frame_send(lport, fp);
}

/**
 * fc_exch_recv_abts() - Handle an incoming ABTS
 * @ep:	   The exchange the abort was on
 * @rx_fp: The ABTS frame
 *
 * This would be for target mode usually, but could be due to lost
 * FCP transfer ready, confirm or RRQ. We always handle this as an
 * exchange abort, ignoring the parameter.
 */
static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
{
	struct fc_frame *fp;
	struct fc_ba_acc *ap;
	struct fc_frame_header *fh;
	struct fc_seq *sp;

	if (!ep)
		goto reject;

	FC_EXCH_DBG(ep, "exch: ABTS received\n");
	fp = fc_frame_alloc(ep->lp, sizeof(*ap));
	if (!fp) {
		FC_EXCH_DBG(ep, "Drop ABTS request, out of memory\n");
		goto free;
	}

	spin_lock_bh(&ep->ex_lock);
	if (ep->esb_stat & ESB_ST_COMPLETE) {
		spin_unlock_bh(&ep->ex_lock);
		FC_EXCH_DBG(ep, "exch: ABTS rejected, exchange complete\n");
		fc_frame_free(fp);
		goto reject;
	}
	if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
		ep->esb_stat |= ESB_ST_REC_QUAL;
		fc_exch_hold(ep);		/* hold for REC_QUAL */
	}
	fc_exch_timer_set_locked(ep, ep->r_a_tov);
	fh = fc_frame_header_get(fp);
	ap = fc_frame_payload_get(fp, sizeof(*ap));
	memset(ap, 0, sizeof(*ap));
	sp = &ep->seq;
	ap->ba_high_seq_cnt = htons(0xffff);
	if (sp->ssb_stat & SSB_ST_RESP) {
		ap->ba_seq_id = sp->id;
		ap->ba_seq_id_val = FC_BA_SEQ_ID_VAL;
		ap->ba_high_seq_cnt = fh->fh_seq_cnt;
		ap->ba_low_seq_cnt = htons(sp->cnt);
	}
	sp = fc_seq_start_next_locked(sp);
	fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
	ep->esb_stat |= ESB_ST_ABNORMAL;
	spin_unlock_bh(&ep->ex_lock);

free:
	fc_frame_free(rx_fp);
	return;

reject:
	fc_exch_send_ba_rjt(rx_fp, FC_BA_RJT_UNABLE, FC_BA_RJT_INV_XID);
	goto free;
}

/**
 * fc_seq_assign() - Assign exchange and sequence for incoming request
 * @lport: The local port that received the request
 * @fp:    The request frame
 *
 * On success, the sequence pointer will be returned and also in fr_seq(@fp).
 * A reference will be held on the exchange/sequence for the caller, which
 * must call fc_seq_release().
 */
struct fc_seq *fc_seq_assign(struct fc_lport *lport, struct fc_frame *fp)
{
	struct fc_exch_mgr_anchor *ema;

	WARN_ON(lport != fr_dev(fp));
	WARN_ON(fr_seq(fp));
	fr_seq(fp) = NULL;

	list_for_each_entry(ema, &lport->ema_list, ema_list)
		if ((!ema->match || ema->match(fp)) &&
		    fc_seq_lookup_recip(lport, ema->mp, fp) == FC_RJT_NONE)
			break;
	return fr_seq(fp);
}
EXPORT_SYMBOL(fc_seq_assign);

/**
 * fc_seq_release() - Release the hold
 * @sp:    The sequence.
 */
void fc_seq_release(struct fc_seq *sp)
{
	fc_exch_release(fc_seq_exch(sp));
}
EXPORT_SYMBOL(fc_seq_release);

/**
 * fc_exch_recv_req() - Handler for an incoming request
 * @lport: The local port that received the request
 * @mp:	   The EM that the exchange is on
 * @fp:	   The request frame
 *
 * This is used when the other end is originating the exchange
 * and the sequence.
 */
static void fc_exch_recv_req(struct fc_lport *lport, struct fc_exch_mgr *mp,
			     struct fc_frame *fp)
{
	struct fc_frame_header *fh = fc_frame_header_get(fp);
	struct fc_seq *sp = NULL;
	struct fc_exch *ep = NULL;
	enum fc_pf_rjt_reason reject;

	/* We can have the wrong fc_lport at this point with NPIV, which is a
	 * problem now that we know a new exchange needs to be allocated
	 */
	lport = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
	if (!lport) {
		fc_frame_free(fp);
		return;
	}
	fr_dev(fp) = lport;

	BUG_ON(fr_seq(fp));		/* XXX remove later */

	/*
	 * If the RX_ID is 0xffff, don't allocate an exchange.
	 * The upper-level protocol may request one later, if needed.
	 */
	if (fh->fh_rx_id == htons(FC_XID_UNKNOWN))
		return fc_lport_recv(lport, fp);

	reject = fc_seq_lookup_recip(lport, mp, fp);
	if (reject == FC_RJT_NONE) {
		sp = fr_seq(fp);	/* sequence will be held */
		ep = fc_seq_exch(sp);
		fc_seq_send_ack(sp, fp);
		ep->encaps = fr_encaps(fp);

		/*
		 * Call the receive function.
		 *
		 * The receive function may allocate a new sequence
		 * over the old one, so we shouldn't change the
		 * sequence after this.
		 *
		 * The frame will be freed by the receive function.
		 * If new exch resp handler is valid then call that
		 * first.
		 */
		if (!fc_invoke_resp(ep, sp, fp))
			fc_lport_recv(lport, fp);
		fc_exch_release(ep);	/* release from lookup */
	} else {
		FC_LPORT_DBG(lport, "exch/seq lookup failed: reject %x\n",
			     reject);
		fc_frame_free(fp);
	}
}

/**
 * fc_exch_recv_seq_resp() - Handler for an incoming response where the other
 *			     end is the originator of the sequence that is a
 *			     response to our initial exchange
 * @mp: The EM that the exchange is on
 * @fp: The response frame
 */
static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
{
	struct fc_frame_header *fh = fc_frame_header_get(fp);
	struct fc_seq *sp;
	struct fc_exch *ep;
	enum fc_sof sof;
	u32 f_ctl;
	int rc;

	ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
	if (!ep) {
		atomic_inc(&mp->stats.xid_not_found);
		goto out;
	}
	if (ep->esb_stat & ESB_ST_COMPLETE) {
		atomic_inc(&mp->stats.xid_not_found);
		goto rel;
	}
	if (ep->rxid == FC_XID_UNKNOWN)
		ep->rxid = ntohs(fh->fh_rx_id);
	if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
		atomic_inc(&mp->stats.xid_not_found);
		goto rel;
	}
	if (ep->did != ntoh24(fh->fh_s_id) &&
	    ep->did != FC_FID_FLOGI) {
		atomic_inc(&mp->stats.xid_not_found);
		goto rel;
	}
	sof = fr_sof(fp);
	sp = &ep->seq;
	if (fc_sof_is_init(sof)) {
		sp->ssb_stat |= SSB_ST_RESP;
		sp->id = fh->fh_seq_id;
	}

	f_ctl = ntoh24(fh->fh_f_ctl);
	fr_seq(fp) = sp;

	spin_lock_bh(&ep->ex_lock);
	if (f_ctl & FC_FC_SEQ_INIT)
		ep->esb_stat |= ESB_ST_SEQ_INIT;
	spin_unlock_bh(&ep->ex_lock);

	if (fc_sof_needs_ack(sof))
		fc_seq_send_ack(sp, fp);

	if (fh->fh_type != FC_TYPE_FCP && fr_eof(fp) == FC_EOF_T &&
	    (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
	    (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
		spin_lock_bh(&ep->ex_lock);
		rc = fc_exch_done_locked(ep);
		WARN_ON(fc_seq_exch(sp) != ep);
		spin_unlock_bh(&ep->ex_lock);
		if (!rc) {
			fc_exch_delete(ep);
		} else {
			FC_EXCH_DBG(ep, "ep is completed already,"
					"hence skip calling the resp\n");
			goto skip_resp;
		}
	}

	/*
	 * Call the receive function.
	 * The sequence is held (has a refcnt) for us,
	 * but not for the receive function.
	 *
	 * The receive function may allocate a new sequence
	 * over the old one, so we shouldn't change the
	 * sequence after this.
	 *
	 * The frame will be freed by the receive function.
	 * If new exch resp handler is valid then call that
	 * first.
	 */
	if (!fc_invoke_resp(ep, sp, fp))
		fc_frame_free(fp);

skip_resp:
	fc_exch_release(ep);
	return;
rel:
	fc_exch_release(ep);
out:
	fc_frame_free(fp);
}

/**
 * fc_exch_recv_resp() - Handler for a sequence where other end is
 *			 responding to our sequence
 * @mp: The EM that the exchange is on
 * @fp: The response frame
 */
static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
{
	struct fc_seq *sp;

	sp = fc_seq_lookup_orig(mp, fp);	/* doesn't hold sequence */

	if (!sp)
		atomic_inc(&mp->stats.xid_not_found);
	else
		atomic_inc(&mp->stats.non_bls_resp);

	fc_frame_free(fp);
}

/**
 * fc_exch_abts_resp() - Handler for a response to an ABT
 * @ep: The exchange that the frame is on
 * @fp: The response frame
 *
 * This response would be to an ABTS cancelling an exchange or sequence.
 * The response can be either BA_ACC or BA_RJT
 */
static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
{
	struct fc_frame_header *fh;
	struct fc_ba_acc *ap;
	struct fc_seq *sp;
	u16 low;
	u16 high;
	int rc = 1, has_rec = 0;

	fh = fc_frame_header_get(fp);
	FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl,
		    fc_exch_rctl_name(fh->fh_r_ctl));

	if (cancel_delayed_work_sync(&ep->timeout_work)) {
		FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n");
		fc_exch_release(ep);	/* release from pending timer hold */
		return;
	}

	spin_lock_bh(&ep->ex_lock);
	switch (fh->fh_r_ctl) {
	case FC_RCTL_BA_ACC:
		ap = fc_frame_payload_get(fp, sizeof(*ap));
		if (!ap)
			break;

		/*
		 * Decide whether to establish a Recovery Qualifier.
		 * We do this if there is a non-empty SEQ_CNT range and
		 * SEQ_ID is the same as the one we aborted.
		 */
		low = ntohs(ap->ba_low_seq_cnt);
		high = ntohs(ap->ba_high_seq_cnt);
		if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 &&
		    (ap->ba_seq_id_val != FC_BA_SEQ_ID_VAL ||
		     ap->ba_seq_id == ep->seq_id) && low != high) {
			ep->esb_stat |= ESB_ST_REC_QUAL;
			fc_exch_hold(ep);  /* hold for recovery qualifier */
			has_rec = 1;
		}
		break;
	case FC_RCTL_BA_RJT:
		break;
	default:
		break;
	}

	/* do we need to do some other checks here. Can we reuse more of
	 * fc_exch_recv_seq_resp
	 */
	sp = &ep->seq;
	/*
	 * do we want to check END_SEQ as well as LAST_SEQ here?
	 */
	if (ep->fh_type != FC_TYPE_FCP &&
	    ntoh24(fh->fh_f_ctl) & FC_FC_LAST_SEQ)
		rc = fc_exch_done_locked(ep);
	spin_unlock_bh(&ep->ex_lock);

	fc_exch_hold(ep);
	if (!rc)
		fc_exch_delete(ep);
	if (!fc_invoke_resp(ep, sp, fp))
		fc_frame_free(fp);
	if (has_rec)
		fc_exch_timer_set(ep, ep->r_a_tov);
	fc_exch_release(ep);
}

/**
 * fc_exch_recv_bls() - Handler for a BLS sequence
 * @mp: The EM that the exchange is on
 * @fp: The request frame
 *
 * The BLS frame is always a sequence initiated by the remote side.
 * We may be either the originator or recipient of the exchange.
 */
static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
{
	struct fc_frame_header *fh;
	struct fc_exch *ep;
	u32 f_ctl;

	fh = fc_frame_header_get(fp);
	f_ctl = ntoh24(fh->fh_f_ctl);
	fr_seq(fp) = NULL;

	ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ?
			  ntohs(fh->fh_ox_id) : ntohs(fh->fh_rx_id));
	if (ep && (f_ctl & FC_FC_SEQ_INIT)) {
		spin_lock_bh(&ep->ex_lock);
		ep->esb_stat |= ESB_ST_SEQ_INIT;
		spin_unlock_bh(&ep->ex_lock);
	}
	if (f_ctl & FC_FC_SEQ_CTX) {
		/*
		 * A response to a sequence we initiated.
		 * This should only be ACKs for class 2 or F.
		 */
		switch (fh->fh_r_ctl) {
		case FC_RCTL_ACK_1:
		case FC_RCTL_ACK_0:
			break;
		default:
			if (ep)
				FC_EXCH_DBG(ep, "BLS rctl %x - %s received\n",
					    fh->fh_r_ctl,
					    fc_exch_rctl_name(fh->fh_r_ctl));
			break;
		}
		fc_frame_free(fp);
	} else {
		switch (fh->fh_r_ctl) {
		case FC_RCTL_BA_RJT:
		case FC_RCTL_BA_ACC:
			if (ep)
				fc_exch_abts_resp(ep, fp);
			else
				fc_frame_free(fp);
			break;
		case FC_RCTL_BA_ABTS:
			if (ep)
				fc_exch_recv_abts(ep, fp);
			else
				fc_frame_free(fp);
			break;
		default:			/* ignore junk */
			fc_frame_free(fp);
			break;
		}
	}
	if (ep)
		fc_exch_release(ep);	/* release hold taken by fc_exch_find */
}

/**
 * fc_seq_ls_acc() - Accept sequence with LS_ACC
 * @rx_fp: The received frame, not freed here.
 *
 * If this fails due to allocation or transmit congestion, assume the
 * originator will repeat the sequence.
 */
static void fc_seq_ls_acc(struct fc_frame *rx_fp)
{
	struct fc_lport *lport;
	struct fc_els_ls_acc *acc;
	struct fc_frame *fp;
	struct fc_seq *sp;

	lport = fr_dev(rx_fp);
	sp = fr_seq(rx_fp);
	fp = fc_frame_alloc(lport, sizeof(*acc));
	if (!fp) {
		FC_EXCH_DBG(fc_seq_exch(sp),
			    "exch: drop LS_ACC, out of memory\n");
		return;
	}
	acc = fc_frame_payload_get(fp, sizeof(*acc));
	memset(acc, 0, sizeof(*acc));
	acc->la_cmd = ELS_LS_ACC;
	fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
}

/**
 * fc_seq_ls_rjt() - Reject a sequence with ELS LS_RJT
 * @rx_fp: The received frame, not freed here.
 * @reason: The reason the sequence is being rejected
 * @explan: The explanation for the rejection
 *
 * If this fails due to allocation or transmit congestion, assume the
 * originator will repeat the sequence.
 */
static void fc_seq_ls_rjt(struct fc_frame *rx_fp, enum fc_els_rjt_reason reason,
			  enum fc_els_rjt_explan explan)
{
	struct fc_lport *lport;
	struct fc_els_ls_rjt *rjt;
	struct fc_frame *fp;
	struct fc_seq *sp;

	lport = fr_dev(rx_fp);
	sp = fr_seq(rx_fp);
	fp = fc_frame_alloc(lport, sizeof(*rjt));
	if (!fp) {
		FC_EXCH_DBG(fc_seq_exch(sp),
			    "exch: drop LS_ACC, out of memory\n");
		return;
	}
	rjt = fc_frame_payload_get(fp, sizeof(*rjt));
	memset(rjt, 0, sizeof(*rjt));
	rjt->er_cmd = ELS_LS_RJT;
	rjt->er_reason = reason;
	rjt->er_explan = explan;
	fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
}

/**
 * fc_exch_reset() - Reset an exchange
 * @ep: The exchange to be reset
 *
 * Note: May sleep if invoked from outside a response handler.
 */
static void fc_exch_reset(struct fc_exch *ep)
{
	struct fc_seq *sp;
	int rc = 1;

	spin_lock_bh(&ep->ex_lock);
	ep->state |= FC_EX_RST_CLEANUP;
	fc_exch_timer_cancel(ep);
	if (ep->esb_stat & ESB_ST_REC_QUAL)
		atomic_dec(&ep->ex_refcnt);	/* drop hold for rec_qual */
	ep->esb_stat &= ~ESB_ST_REC_QUAL;
	sp = &ep->seq;
	rc = fc_exch_done_locked(ep);
	spin_unlock_bh(&ep->ex_lock);

	fc_exch_hold(ep);

	if (!rc) {
		fc_exch_delete(ep);
	} else {
		FC_EXCH_DBG(ep, "ep is completed already,"
				"hence skip calling the resp\n");
		goto skip_resp;
	}

	fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED));
skip_resp:
	fc_seq_set_resp(sp, NULL, ep->arg);
	fc_exch_release(ep);
}

/**
 * fc_exch_pool_reset() - Reset a per cpu exchange pool
 * @lport: The local port that the exchange pool is on
 * @pool:  The exchange pool to be reset
 * @sid:   The source ID
 * @did:   The destination ID
 *
 * Resets a per cpu exches pool, releasing all of its sequences
 * and exchanges. If sid is non-zero then reset only exchanges
 * we sourced from the local port's FID. If did is non-zero then
 * only reset exchanges destined for the local port's FID.
 */
static void fc_exch_pool_reset(struct fc_lport *lport,
			       struct fc_exch_pool *pool,
			       u32 sid, u32 did)
{
	struct fc_exch *ep;
	struct fc_exch *next;

	spin_lock_bh(&pool->lock);
restart:
	list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) {
		if ((lport == ep->lp) &&
		    (sid == 0 || sid == ep->sid) &&
		    (did == 0 || did == ep->did)) {
			fc_exch_hold(ep);
			spin_unlock_bh(&pool->lock);

			fc_exch_reset(ep);

			fc_exch_release(ep);
			spin_lock_bh(&pool->lock);

			/*
			 * must restart loop incase while lock
			 * was down multiple eps were released.
			 */
			goto restart;
		}
	}
	pool->next_index = 0;
	pool->left = FC_XID_UNKNOWN;
	pool->right = FC_XID_UNKNOWN;
	spin_unlock_bh(&pool->lock);
}

/**
 * fc_exch_mgr_reset() - Reset all EMs of a local port
 * @lport: The local port whose EMs are to be reset
 * @sid:   The source ID
 * @did:   The destination ID
 *
 * Reset all EMs associated with a given local port. Release all
 * sequences and exchanges. If sid is non-zero then reset only the
 * exchanges sent from the local port's FID. If did is non-zero then
 * reset only exchanges destined for the local port's FID.
 */
void fc_exch_mgr_reset(struct fc_lport *lport, u32 sid, u32 did)
{
	struct fc_exch_mgr_anchor *ema;
	unsigned int cpu;

	list_for_each_entry(ema, &lport->ema_list, ema_list) {
		for_each_possible_cpu(cpu)
			fc_exch_pool_reset(lport,
					   per_cpu_ptr(ema->mp->pool, cpu),
					   sid, did);
	}
}
EXPORT_SYMBOL(fc_exch_mgr_reset);

/**
 * fc_exch_lookup() - find an exchange
 * @lport: The local port
 * @xid: The exchange ID
 *
 * Returns exchange pointer with hold for caller, or NULL if not found.
 */
static struct fc_exch *fc_exch_lookup(struct fc_lport *lport, u32 xid)
{
	struct fc_exch_mgr_anchor *ema;

	list_for_each_entry(ema, &lport->ema_list, ema_list)
		if (ema->mp->min_xid <= xid && xid <= ema->mp->max_xid)
			return fc_exch_find(ema->mp, xid);
	return NULL;
}

/**
 * fc_exch_els_rec() - Handler for ELS REC (Read Exchange Concise) requests
 * @rfp: The REC frame, not freed here.
 *
 * Note that the requesting port may be different than the S_ID in the request.
 */
static void fc_exch_els_rec(struct fc_frame *rfp)
{
	struct fc_lport *lport;
	struct fc_frame *fp;
	struct fc_exch *ep;
	struct fc_els_rec *rp;
	struct fc_els_rec_acc *acc;
	enum fc_els_rjt_reason reason = ELS_RJT_LOGIC;
	enum fc_els_rjt_explan explan;
	u32 sid;
	u16 xid, rxid, oxid;

	lport = fr_dev(rfp);
	rp = fc_frame_payload_get(rfp, sizeof(*rp));
	explan = ELS_EXPL_INV_LEN;
	if (!rp)
		goto reject;
	sid = ntoh24(rp->rec_s_id);
	rxid = ntohs(rp->rec_rx_id);
	oxid = ntohs(rp->rec_ox_id);

	explan = ELS_EXPL_OXID_RXID;
	if (sid == fc_host_port_id(lport->host))
		xid = oxid;
	else
		xid = rxid;
	if (xid == FC_XID_UNKNOWN) {
		FC_LPORT_DBG(lport,
			     "REC request from %x: invalid rxid %x oxid %x\n",
			     sid, rxid, oxid);
		goto reject;
	}
	ep = fc_exch_lookup(lport, xid);
	if (!ep) {
		FC_LPORT_DBG(lport,
			     "REC request from %x: rxid %x oxid %x not found\n",
			     sid, rxid, oxid);
		goto reject;
	}
	FC_EXCH_DBG(ep, "REC request from %x: rxid %x oxid %x\n",
		    sid, rxid, oxid);
	if (ep->oid != sid || oxid != ep->oxid)
		goto rel;
	if (rxid != FC_XID_UNKNOWN && rxid != ep->rxid)
		goto rel;
	fp = fc_frame_alloc(lport, sizeof(*acc));
	if (!fp) {
		FC_EXCH_DBG(ep, "Drop REC request, out of memory\n");
		goto out;
	}

	acc = fc_frame_payload_get(fp, sizeof(*acc));
	memset(acc, 0, sizeof(*acc));
	acc->reca_cmd = ELS_LS_ACC;
	acc->reca_ox_id = rp->rec_ox_id;
	memcpy(acc->reca_ofid, rp->rec_s_id, 3);
	acc->reca_rx_id = htons(ep->rxid);
	if (ep->sid == ep->oid)
		hton24(acc->reca_rfid, ep->did);
	else
		hton24(acc->reca_rfid, ep->sid);
	acc->reca_fc4value = htonl(ep->seq.rec_data);
	acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP |
						 ESB_ST_SEQ_INIT |
						 ESB_ST_COMPLETE));
	fc_fill_reply_hdr(fp, rfp, FC_RCTL_ELS_REP, 0);
	lport->tt.frame_send(lport, fp);
out:
	fc_exch_release(ep);
	return;

rel:
	fc_exch_release(ep);
reject:
	fc_seq_ls_rjt(rfp, reason, explan);
}

/**
 * fc_exch_rrq_resp() - Handler for RRQ responses
 * @sp:	 The sequence that the RRQ is on
 * @fp:	 The RRQ frame
 * @arg: The exchange that the RRQ is on
 *
 * TODO: fix error handler.
 */
static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
{
	struct fc_exch *aborted_ep = arg;
	unsigned int op;

	if (IS_ERR(fp)) {
		int err = PTR_ERR(fp);

		if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT)
			goto cleanup;
		FC_EXCH_DBG(aborted_ep, "Cannot process RRQ, "
			    "frame error %d\n", err);
		return;
	}

	op = fc_frame_payload_op(fp);
	fc_frame_free(fp);

	switch (op) {
	case ELS_LS_RJT:
		FC_EXCH_DBG(aborted_ep, "LS_RJT for RRQ\n");
		/* fall through */
	case ELS_LS_ACC:
		goto cleanup;
	default:
		FC_EXCH_DBG(aborted_ep, "unexpected response op %x for RRQ\n",
			    op);
		return;
	}

cleanup:
	fc_exch_done(&aborted_ep->seq);
	/* drop hold for rec qual */
	fc_exch_release(aborted_ep);
}


/**
 * fc_exch_seq_send() - Send a frame using a new exchange and sequence
 * @lport:	The local port to send the frame on
 * @fp:		The frame to be sent
 * @resp:	The response handler for this request
 * @destructor: The destructor for the exchange
 * @arg:	The argument to be passed to the response handler
 * @timer_msec: The timeout period for the exchange
 *
 * The exchange response handler is set in this routine to resp()
 * function pointer. It can be called in two scenarios: if a timeout
 * occurs or if a response frame is received for the exchange. The
 * fc_frame pointer in response handler will also indicate timeout
 * as error using IS_ERR related macros.
 *
 * The exchange destructor handler is also set in this routine.
 * The destructor handler is invoked by EM layer when exchange
 * is about to free, this can be used by caller to free its
 * resources along with exchange free.
 *
 * The arg is passed back to resp and destructor handler.
 *
 * The timeout value (in msec) for an exchange is set if non zero
 * timer_msec argument is specified. The timer is canceled when
 * it fires or when the exchange is done. The exchange timeout handler
 * is registered by EM layer.
 *
 * The frame pointer with some of the header's fields must be
 * filled before calling this routine, those fields are:
 *
 * - routing control
 * - FC port did
 * - FC port sid
 * - FC header type
 * - frame control
 * - parameter or relative offset
 */
struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
				struct fc_frame *fp,
				void (*resp)(struct fc_seq *,
					     struct fc_frame *fp,
					     void *arg),
				void (*destructor)(struct fc_seq *, void *),
				void *arg, u32 timer_msec)
{
	struct fc_exch *ep;
	struct fc_seq *sp = NULL;
	struct fc_frame_header *fh;
	struct fc_fcp_pkt *fsp = NULL;
	int rc = 1;

	ep = fc_exch_alloc(lport, fp);
	if (!ep) {
		fc_frame_free(fp);
		return NULL;
	}
	ep->esb_stat |= ESB_ST_SEQ_INIT;
	fh = fc_frame_header_get(fp);
	fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
	ep->resp = resp;
	ep->destructor = destructor;
	ep->arg = arg;
	ep->r_a_tov = lport->r_a_tov;
	ep->lp = lport;
	sp = &ep->seq;

	ep->fh_type = fh->fh_type; /* save for possbile timeout handling */
	ep->f_ctl = ntoh24(fh->fh_f_ctl);
	fc_exch_setup_hdr(ep, fp, ep->f_ctl);
	sp->cnt++;

	if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) {
		fsp = fr_fsp(fp);
		fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
	}

	if (unlikely(lport->tt.frame_send(lport, fp)))
		goto err;

	if (timer_msec)
		fc_exch_timer_set_locked(ep, timer_msec);
	ep->f_ctl &= ~FC_FC_FIRST_SEQ;	/* not first seq */

	if (ep->f_ctl & FC_FC_SEQ_INIT)
		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
	spin_unlock_bh(&ep->ex_lock);
	return sp;
err:
	if (fsp)
		fc_fcp_ddp_done(fsp);
	rc = fc_exch_done_locked(ep);
	spin_unlock_bh(&ep->ex_lock);
	if (!rc)
		fc_exch_delete(ep);
	return NULL;
}
EXPORT_SYMBOL(fc_exch_seq_send);

/**
 * fc_exch_rrq() - Send an ELS RRQ (Reinstate Recovery Qualifier) command
 * @ep: The exchange to send the RRQ on
 *
 * This tells the remote port to stop blocking the use of
 * the exchange and the seq_cnt range.
 */
static void fc_exch_rrq(struct fc_exch *ep)
{
	struct fc_lport *lport;
	struct fc_els_rrq *rrq;
	struct fc_frame *fp;
	u32 did;

	lport = ep->lp;

	fp = fc_frame_alloc(lport, sizeof(*rrq));
	if (!fp)
		goto retry;

	rrq = fc_frame_payload_get(fp, sizeof(*rrq));
	memset(rrq, 0, sizeof(*rrq));
	rrq->rrq_cmd = ELS_RRQ;
	hton24(rrq->rrq_s_id, ep->sid);
	rrq->rrq_ox_id = htons(ep->oxid);
	rrq->rrq_rx_id = htons(ep->rxid);

	did = ep->did;
	if (ep->esb_stat & ESB_ST_RESP)
		did = ep->sid;

	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did,
		       lport->port_id, FC_TYPE_ELS,
		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);

	if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep,
			     lport->e_d_tov))
		return;

retry:
	FC_EXCH_DBG(ep, "exch: RRQ send failed\n");
	spin_lock_bh(&ep->ex_lock);
	if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) {
		spin_unlock_bh(&ep->ex_lock);
		/* drop hold for rec qual */
		fc_exch_release(ep);
		return;
	}
	ep->esb_stat |= ESB_ST_REC_QUAL;
	fc_exch_timer_set_locked(ep, ep->r_a_tov);
	spin_unlock_bh(&ep->ex_lock);
}

/**
 * fc_exch_els_rrq() - Handler for ELS RRQ (Reset Recovery Qualifier) requests
 * @fp: The RRQ frame, not freed here.
 */
static void fc_exch_els_rrq(struct fc_frame *fp)
{
	struct fc_lport *lport;
	struct fc_exch *ep = NULL;	/* request or subject exchange */
	struct fc_els_rrq *rp;
	u32 sid;
	u16 xid;
	enum fc_els_rjt_explan explan;

	lport = fr_dev(fp);
	rp = fc_frame_payload_get(fp, sizeof(*rp));
	explan = ELS_EXPL_INV_LEN;
	if (!rp)
		goto reject;

	/*
	 * lookup subject exchange.
	 */
	sid = ntoh24(rp->rrq_s_id);		/* subject source */
	xid = fc_host_port_id(lport->host) == sid ?
			ntohs(rp->rrq_ox_id) : ntohs(rp->rrq_rx_id);
	ep = fc_exch_lookup(lport, xid);
	explan = ELS_EXPL_OXID_RXID;
	if (!ep)
		goto reject;
	spin_lock_bh(&ep->ex_lock);
	FC_EXCH_DBG(ep, "RRQ request from %x: xid %x rxid %x oxid %x\n",
		    sid, xid, ntohs(rp->rrq_rx_id), ntohs(rp->rrq_ox_id));
	if (ep->oxid != ntohs(rp->rrq_ox_id))
		goto unlock_reject;
	if (ep->rxid != ntohs(rp->rrq_rx_id) &&
	    ep->rxid != FC_XID_UNKNOWN)
		goto unlock_reject;
	explan = ELS_EXPL_SID;
	if (ep->sid != sid)
		goto unlock_reject;

	/*
	 * Clear Recovery Qualifier state, and cancel timer if complete.
	 */
	if (ep->esb_stat & ESB_ST_REC_QUAL) {
		ep->esb_stat &= ~ESB_ST_REC_QUAL;
		atomic_dec(&ep->ex_refcnt);	/* drop hold for rec qual */
	}
	if (ep->esb_stat & ESB_ST_COMPLETE)
		fc_exch_timer_cancel(ep);

	spin_unlock_bh(&ep->ex_lock);

	/*
	 * Send LS_ACC.
	 */
	fc_seq_ls_acc(fp);
	goto out;

unlock_reject:
	spin_unlock_bh(&ep->ex_lock);
reject:
	fc_seq_ls_rjt(fp, ELS_RJT_LOGIC, explan);
out:
	if (ep)
		fc_exch_release(ep);	/* drop hold from fc_exch_find */
}

/**
 * fc_exch_update_stats() - update exches stats to lport
 * @lport: The local port to update exchange manager stats
 */
void fc_exch_update_stats(struct fc_lport *lport)
{
	struct fc_host_statistics *st;
	struct fc_exch_mgr_anchor *ema;
	struct fc_exch_mgr *mp;

	st = &lport->host_stats;

	list_for_each_entry(ema, &lport->ema_list, ema_list) {
		mp = ema->mp;
		st->fc_no_free_exch += atomic_read(&mp->stats.no_free_exch);
		st->fc_no_free_exch_xid +=
				atomic_read(&mp->stats.no_free_exch_xid);
		st->fc_xid_not_found += atomic_read(&mp->stats.xid_not_found);
		st->fc_xid_busy += atomic_read(&mp->stats.xid_busy);
		st->fc_seq_not_found += atomic_read(&mp->stats.seq_not_found);
		st->fc_non_bls_resp += atomic_read(&mp->stats.non_bls_resp);
	}
}
EXPORT_SYMBOL(fc_exch_update_stats);

/**
 * fc_exch_mgr_add() - Add an exchange manager to a local port's list of EMs
 * @lport: The local port to add the exchange manager to
 * @mp:	   The exchange manager to be added to the local port
 * @match: The match routine that indicates when this EM should be used
 */
struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
					   struct fc_exch_mgr *mp,
					   bool (*match)(struct fc_frame *))
{
	struct fc_exch_mgr_anchor *ema;

	ema = kmalloc(sizeof(*ema), GFP_ATOMIC);
	if (!ema)
		return ema;

	ema->mp = mp;
	ema->match = match;
	/* add EM anchor to EM anchors list */
	list_add_tail(&ema->ema_list, &lport->ema_list);
	kref_get(&mp->kref);
	return ema;
}
EXPORT_SYMBOL(fc_exch_mgr_add);

/**
 * fc_exch_mgr_destroy() - Destroy an exchange manager
 * @kref: The reference to the EM to be destroyed
 */
static void fc_exch_mgr_destroy(struct kref *kref)
{
	struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);

	mempool_destroy(mp->ep_pool);
	free_percpu(mp->pool);
	kfree(mp);
}

/**
 * fc_exch_mgr_del() - Delete an EM from a local port's list
 * @ema: The exchange manager anchor identifying the EM to be deleted
 */
void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
{
	/* remove EM anchor from EM anchors list */
	list_del(&ema->ema_list);
	kref_put(&ema->mp->kref, fc_exch_mgr_destroy);
	kfree(ema);
}
EXPORT_SYMBOL(fc_exch_mgr_del);

/**
 * fc_exch_mgr_list_clone() - Share all exchange manager objects
 * @src: Source lport to clone exchange managers from
 * @dst: New lport that takes references to all the exchange managers
 */
int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst)
{
	struct fc_exch_mgr_anchor *ema, *tmp;

	list_for_each_entry(ema, &src->ema_list, ema_list) {
		if (!fc_exch_mgr_add(dst, ema->mp, ema->match))
			goto err;
	}
	return 0;
err:
	list_for_each_entry_safe(ema, tmp, &dst->ema_list, ema_list)
		fc_exch_mgr_del(ema);
	return -ENOMEM;
}
EXPORT_SYMBOL(fc_exch_mgr_list_clone);

/**
 * fc_exch_mgr_alloc() - Allocate an exchange manager
 * @lport:   The local port that the new EM will be associated with
 * @class:   The default FC class for new exchanges
 * @min_xid: The minimum XID for exchanges from the new EM
 * @max_xid: The maximum XID for exchanges from the new EM
 * @match:   The match routine for the new EM
 */
struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
				      enum fc_class class,
				      u16 min_xid, u16 max_xid,
				      bool (*match)(struct fc_frame *))
{
	struct fc_exch_mgr *mp;
	u16 pool_exch_range;
	size_t pool_size;
	unsigned int cpu;
	struct fc_exch_pool *pool;

	if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN ||
	    (min_xid & fc_cpu_mask) != 0) {
		FC_LPORT_DBG(lport, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
			     min_xid, max_xid);
		return NULL;
	}

	/*
	 * allocate memory for EM
	 */
	mp = kzalloc(sizeof(struct fc_exch_mgr), GFP_ATOMIC);
	if (!mp)
		return NULL;

	mp->class = class;
	mp->lport = lport;
	/* adjust em exch xid range for offload */
	mp->min_xid = min_xid;

       /* reduce range so per cpu pool fits into PCPU_MIN_UNIT_SIZE pool */
	pool_exch_range = (PCPU_MIN_UNIT_SIZE - sizeof(*pool)) /
		sizeof(struct fc_exch *);
	if ((max_xid - min_xid + 1) / (fc_cpu_mask + 1) > pool_exch_range) {
		mp->max_xid = pool_exch_range * (fc_cpu_mask + 1) +
			min_xid - 1;
	} else {
		mp->max_xid = max_xid;
		pool_exch_range = (mp->max_xid - mp->min_xid + 1) /
			(fc_cpu_mask + 1);
	}

	mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep);
	if (!mp->ep_pool)
		goto free_mp;

	/*
	 * Setup per cpu exch pool with entire exchange id range equally
	 * divided across all cpus. The exch pointers array memory is
	 * allocated for exch range per pool.
	 */
	mp->pool_max_index = pool_exch_range - 1;

	/*
	 * Allocate and initialize per cpu exch pool
	 */
	pool_size = sizeof(*pool) + pool_exch_range * sizeof(struct fc_exch *);
	mp->pool = __alloc_percpu(pool_size, __alignof__(struct fc_exch_pool));
	if (!mp->pool)
		goto free_mempool;
	for_each_possible_cpu(cpu) {
		pool = per_cpu_ptr(mp->pool, cpu);
		pool->next_index = 0;
		pool->left = FC_XID_UNKNOWN;
		pool->right = FC_XID_UNKNOWN;
		spin_lock_init(&pool->lock);
		INIT_LIST_HEAD(&pool->ex_list);
	}

	kref_init(&mp->kref);
	if (!fc_exch_mgr_add(lport, mp, match)) {
		free_percpu(mp->pool);
		goto free_mempool;
	}

	/*
	 * Above kref_init() sets mp->kref to 1 and then
	 * call to fc_exch_mgr_add incremented mp->kref again,
	 * so adjust that extra increment.
	 */
	kref_put(&mp->kref, fc_exch_mgr_destroy);
	return mp;

free_mempool:
	mempool_destroy(mp->ep_pool);
free_mp:
	kfree(mp);
	return NULL;
}
EXPORT_SYMBOL(fc_exch_mgr_alloc);

/**
 * fc_exch_mgr_free() - Free all exchange managers on a local port
 * @lport: The local port whose EMs are to be freed
 */
void fc_exch_mgr_free(struct fc_lport *lport)
{
	struct fc_exch_mgr_anchor *ema, *next;

	flush_workqueue(fc_exch_workqueue);
	list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list)
		fc_exch_mgr_del(ema);
}
EXPORT_SYMBOL(fc_exch_mgr_free);

/**
 * fc_find_ema() - Lookup and return appropriate Exchange Manager Anchor depending
 * upon 'xid'.
 * @f_ctl: f_ctl
 * @lport: The local port the frame was received on
 * @fh: The received frame header
 */
static struct fc_exch_mgr_anchor *fc_find_ema(u32 f_ctl,
					      struct fc_lport *lport,
					      struct fc_frame_header *fh)
{
	struct fc_exch_mgr_anchor *ema;
	u16 xid;

	if (f_ctl & FC_FC_EX_CTX)
		xid = ntohs(fh->fh_ox_id);
	else {
		xid = ntohs(fh->fh_rx_id);
		if (xid == FC_XID_UNKNOWN)
			return list_entry(lport->ema_list.prev,
					  typeof(*ema), ema_list);
	}

	list_for_each_entry(ema, &lport->ema_list, ema_list) {
		if ((xid >= ema->mp->min_xid) &&
		    (xid <= ema->mp->max_xid))
			return ema;
	}
	return NULL;
}
/**
 * fc_exch_recv() - Handler for received frames
 * @lport: The local port the frame was received on
 * @fp:	The received frame
 */
void fc_exch_recv(struct fc_lport *lport, struct fc_frame *fp)
{
	struct fc_frame_header *fh = fc_frame_header_get(fp);
	struct fc_exch_mgr_anchor *ema;
	u32 f_ctl;

	/* lport lock ? */
	if (!lport || lport->state == LPORT_ST_DISABLED) {
		FC_LIBFC_DBG("Receiving frames for an lport that "
			     "has not been initialized correctly\n");
		fc_frame_free(fp);
		return;
	}

	f_ctl = ntoh24(fh->fh_f_ctl);
	ema = fc_find_ema(f_ctl, lport, fh);
	if (!ema) {
		FC_LPORT_DBG(lport, "Unable to find Exchange Manager Anchor,"
				    "fc_ctl <0x%x>, xid <0x%x>\n",
				     f_ctl,
				     (f_ctl & FC_FC_EX_CTX) ?
				     ntohs(fh->fh_ox_id) :
				     ntohs(fh->fh_rx_id));
		fc_frame_free(fp);
		return;
	}

	/*
	 * If frame is marked invalid, just drop it.
	 */
	switch (fr_eof(fp)) {
	case FC_EOF_T:
		if (f_ctl & FC_FC_END_SEQ)
			skb_trim(fp_skb(fp), fr_len(fp) - FC_FC_FILL(f_ctl));
		/* fall through */
	case FC_EOF_N:
		if (fh->fh_type == FC_TYPE_BLS)
			fc_exch_recv_bls(ema->mp, fp);
		else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) ==
			 FC_FC_EX_CTX)
			fc_exch_recv_seq_resp(ema->mp, fp);
		else if (f_ctl & FC_FC_SEQ_CTX)
			fc_exch_recv_resp(ema->mp, fp);
		else	/* no EX_CTX and no SEQ_CTX */
			fc_exch_recv_req(lport, ema->mp, fp);
		break;
	default:
		FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)",
			     fr_eof(fp));
		fc_frame_free(fp);
	}
}
EXPORT_SYMBOL(fc_exch_recv);

/**
 * fc_exch_init() - Initialize the exchange layer for a local port
 * @lport: The local port to initialize the exchange layer for
 */
int fc_exch_init(struct fc_lport *lport)
{
	if (!lport->tt.exch_mgr_reset)
		lport->tt.exch_mgr_reset = fc_exch_mgr_reset;

	return 0;
}
EXPORT_SYMBOL(fc_exch_init);

/**
 * fc_setup_exch_mgr() - Setup an exchange manager
 */
int fc_setup_exch_mgr(void)
{
	fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
					 0, SLAB_HWCACHE_ALIGN, NULL);
	if (!fc_em_cachep)
		return -ENOMEM;

	/*
	 * Initialize fc_cpu_mask and fc_cpu_order. The
	 * fc_cpu_mask is set for nr_cpu_ids rounded up
	 * to order of 2's * power and order is stored
	 * in fc_cpu_order as this is later required in
	 * mapping between an exch id and exch array index
	 * in per cpu exch pool.
	 *
	 * This round up is required to align fc_cpu_mask
	 * to exchange id's lower bits such that all incoming
	 * frames of an exchange gets delivered to the same
	 * cpu on which exchange originated by simple bitwise
	 * AND operation between fc_cpu_mask and exchange id.
	 */
	fc_cpu_order = ilog2(roundup_pow_of_two(nr_cpu_ids));
	fc_cpu_mask = (1 << fc_cpu_order) - 1;

	fc_exch_workqueue = create_singlethread_workqueue("fc_exch_workqueue");
	if (!fc_exch_workqueue)
		goto err;
	return 0;
err:
	kmem_cache_destroy(fc_em_cachep);
	return -ENOMEM;
}

/**
 * fc_destroy_exch_mgr() - Destroy an exchange manager
 */
void fc_destroy_exch_mgr(void)
{
	destroy_workqueue(fc_exch_workqueue);
	kmem_cache_destroy(fc_em_cachep);
}
