blob: 2a7fd5afecca5328affe2cad44c6ada97e278485 [file] [log] [blame]
Robert Love42e9a922008-12-09 15:10:17 -08001/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 * Copyright(c) 2008 Red Hat, Inc. All rights reserved.
4 * Copyright(c) 2008 Mike Christie
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Maintained at www.Open-FCoE.org
20 */
21
22/*
23 * Fibre Channel exchange and sequence handling.
24 */
25
26#include <linux/timer.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090027#include <linux/slab.h>
Robert Love42e9a922008-12-09 15:10:17 -080028#include <linux/err.h>
Paul Gortmaker09703662011-05-27 09:37:25 -040029#include <linux/export.h>
Bart Van Asschea84ea8c2013-08-14 15:33:35 +000030#include <linux/log2.h>
Robert Love42e9a922008-12-09 15:10:17 -080031
32#include <scsi/fc/fc_fc2.h>
33
34#include <scsi/libfc.h>
35#include <scsi/fc_encode.h>
36
Robert Love8866a5d2009-11-03 11:45:58 -080037#include "fc_libfc.h"
38
Vasu Deve4bc50b2009-08-25 13:58:47 -070039u16 fc_cpu_mask; /* cpu mask for possible cpus */
40EXPORT_SYMBOL(fc_cpu_mask);
41static u16 fc_cpu_order; /* 2's power to represent total possible cpus */
Robert Love3a3b42b2009-11-03 11:47:39 -080042static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
Randy Dunlap55204902011-01-28 16:03:57 -080043static struct workqueue_struct *fc_exch_workqueue;
Robert Love42e9a922008-12-09 15:10:17 -080044
45/*
46 * Structure and function definitions for managing Fibre Channel Exchanges
47 * and Sequences.
48 *
49 * The three primary structures used here are fc_exch_mgr, fc_exch, and fc_seq.
50 *
51 * fc_exch_mgr holds the exchange state for an N port
52 *
53 * fc_exch holds state for one exchange and links to its active sequence.
54 *
55 * fc_seq holds the state for an individual sequence.
56 */
57
Robert Love3a3b42b2009-11-03 11:47:39 -080058/**
59 * struct fc_exch_pool - Per cpu exchange pool
60 * @next_index: Next possible free exchange index
61 * @total_exches: Total allocated exchanges
62 * @lock: Exch pool lock
63 * @ex_list: List of exchanges
Vasu Deve4bc50b2009-08-25 13:58:47 -070064 *
65 * This structure manages per cpu exchanges in array of exchange pointers.
66 * This array is allocated followed by struct fc_exch_pool memory for
67 * assigned range of exchanges to per cpu pool.
68 */
69struct fc_exch_pool {
Vasu Deve17b4af2011-09-27 21:38:08 -070070 spinlock_t lock;
71 struct list_head ex_list;
Robert Love3a3b42b2009-11-03 11:47:39 -080072 u16 next_index;
73 u16 total_exches;
Hillf Danton2034c192010-11-30 16:18:17 -080074
75 /* two cache of free slot in exch array */
76 u16 left;
77 u16 right;
Vasu Deve17b4af2011-09-27 21:38:08 -070078} ____cacheline_aligned_in_smp;
Vasu Deve4bc50b2009-08-25 13:58:47 -070079
Robert Love3a3b42b2009-11-03 11:47:39 -080080/**
81 * struct fc_exch_mgr - The Exchange Manager (EM).
82 * @class: Default class for new sequences
83 * @kref: Reference counter
84 * @min_xid: Minimum exchange ID
85 * @max_xid: Maximum exchange ID
86 * @ep_pool: Reserved exchange pointers
87 * @pool_max_index: Max exch array index in exch pool
88 * @pool: Per cpu exch pool
89 * @stats: Statistics structure
Robert Love42e9a922008-12-09 15:10:17 -080090 *
91 * This structure is the center for creating exchanges and sequences.
92 * It manages the allocation of exchange IDs.
93 */
94struct fc_exch_mgr {
Bart Van Asschec6b21c92012-01-13 17:26:20 -080095 struct fc_exch_pool __percpu *pool;
Vasu Deve17b4af2011-09-27 21:38:08 -070096 mempool_t *ep_pool;
Robert Love3a3b42b2009-11-03 11:47:39 -080097 enum fc_class class;
98 struct kref kref;
99 u16 min_xid;
100 u16 max_xid;
Robert Love3a3b42b2009-11-03 11:47:39 -0800101 u16 pool_max_index;
Robert Love42e9a922008-12-09 15:10:17 -0800102
Robert Love42e9a922008-12-09 15:10:17 -0800103 struct {
104 atomic_t no_free_exch;
105 atomic_t no_free_exch_xid;
106 atomic_t xid_not_found;
107 atomic_t xid_busy;
108 atomic_t seq_not_found;
109 atomic_t non_bls_resp;
110 } stats;
Robert Love42e9a922008-12-09 15:10:17 -0800111};
Robert Love42e9a922008-12-09 15:10:17 -0800112
Robert Love3a3b42b2009-11-03 11:47:39 -0800113/**
114 * struct fc_exch_mgr_anchor - primary structure for list of EMs
115 * @ema_list: Exchange Manager Anchor list
116 * @mp: Exchange Manager associated with this anchor
117 * @match: Routine to determine if this anchor's EM should be used
118 *
119 * When walking the list of anchors the match routine will be called
120 * for each anchor to determine if that EM should be used. The last
121 * anchor in the list will always match to handle any exchanges not
122 * handled by other EMs. The non-default EMs would be added to the
Vasu Dev1bd49b42012-05-25 10:26:43 -0700123 * anchor list by HW that provides offloads.
Robert Love3a3b42b2009-11-03 11:47:39 -0800124 */
Vasu Dev96316092009-07-29 17:05:00 -0700125struct fc_exch_mgr_anchor {
126 struct list_head ema_list;
127 struct fc_exch_mgr *mp;
128 bool (*match)(struct fc_frame *);
129};
130
Robert Love42e9a922008-12-09 15:10:17 -0800131static void fc_exch_rrq(struct fc_exch *);
Joe Eykholt922611562010-07-20 15:21:12 -0700132static void fc_seq_ls_acc(struct fc_frame *);
133static void fc_seq_ls_rjt(struct fc_frame *, enum fc_els_rjt_reason,
Robert Love42e9a922008-12-09 15:10:17 -0800134 enum fc_els_rjt_explan);
Joe Eykholt922611562010-07-20 15:21:12 -0700135static void fc_exch_els_rec(struct fc_frame *);
136static void fc_exch_els_rrq(struct fc_frame *);
Robert Love42e9a922008-12-09 15:10:17 -0800137
138/*
139 * Internal implementation notes.
140 *
141 * The exchange manager is one by default in libfc but LLD may choose
142 * to have one per CPU. The sequence manager is one per exchange manager
143 * and currently never separated.
144 *
145 * Section 9.8 in FC-FS-2 specifies: "The SEQ_ID is a one-byte field
146 * assigned by the Sequence Initiator that shall be unique for a specific
147 * D_ID and S_ID pair while the Sequence is open." Note that it isn't
148 * qualified by exchange ID, which one might think it would be.
149 * In practice this limits the number of open sequences and exchanges to 256
150 * per session. For most targets we could treat this limit as per exchange.
151 *
152 * The exchange and its sequence are freed when the last sequence is received.
153 * It's possible for the remote port to leave an exchange open without
154 * sending any sequences.
155 *
156 * Notes on reference counts:
157 *
158 * Exchanges are reference counted and exchange gets freed when the reference
159 * count becomes zero.
160 *
161 * Timeouts:
162 * Sequences are timed out for E_D_TOV and R_A_TOV.
163 *
164 * Sequence event handling:
165 *
166 * The following events may occur on initiator sequences:
167 *
168 * Send.
169 * For now, the whole thing is sent.
170 * Receive ACK
171 * This applies only to class F.
172 * The sequence is marked complete.
173 * ULP completion.
174 * The upper layer calls fc_exch_done() when done
175 * with exchange and sequence tuple.
176 * RX-inferred completion.
177 * When we receive the next sequence on the same exchange, we can
178 * retire the previous sequence ID. (XXX not implemented).
179 * Timeout.
180 * R_A_TOV frees the sequence ID. If we're waiting for ACK,
181 * E_D_TOV causes abort and calls upper layer response handler
182 * with FC_EX_TIMEOUT error.
183 * Receive RJT
184 * XXX defer.
185 * Send ABTS
186 * On timeout.
187 *
188 * The following events may occur on recipient sequences:
189 *
190 * Receive
191 * Allocate sequence for first frame received.
192 * Hold during receive handler.
193 * Release when final frame received.
194 * Keep status of last N of these for the ELS RES command. XXX TBD.
195 * Receive ABTS
196 * Deallocate sequence
197 * Send RJT
198 * Deallocate
199 *
200 * For now, we neglect conditions where only part of a sequence was
201 * received or transmitted, or where out-of-order receipt is detected.
202 */
203
204/*
205 * Locking notes:
206 *
207 * The EM code run in a per-CPU worker thread.
208 *
209 * To protect against concurrency between a worker thread code and timers,
210 * sequence allocation and deallocation must be locked.
211 * - exchange refcnt can be done atomicly without locks.
212 * - sequence allocation must be locked by exch lock.
Vasu Devb2f00912009-08-25 13:58:53 -0700213 * - If the EM pool lock and ex_lock must be taken at the same time, then the
214 * EM pool lock must be taken before the ex_lock.
Robert Love42e9a922008-12-09 15:10:17 -0800215 */
216
217/*
218 * opcode names for debugging.
219 */
220static char *fc_exch_rctl_names[] = FC_RCTL_NAMES_INIT;
221
Robert Love3a3b42b2009-11-03 11:47:39 -0800222/**
223 * fc_exch_name_lookup() - Lookup name by opcode
224 * @op: Opcode to be looked up
225 * @table: Opcode/name table
226 * @max_index: Index not to be exceeded
227 *
228 * This routine is used to determine a human-readable string identifying
229 * a R_CTL opcode.
230 */
Robert Love42e9a922008-12-09 15:10:17 -0800231static inline const char *fc_exch_name_lookup(unsigned int op, char **table,
232 unsigned int max_index)
233{
234 const char *name = NULL;
235
236 if (op < max_index)
237 name = table[op];
238 if (!name)
239 name = "unknown";
240 return name;
241}
242
Robert Love3a3b42b2009-11-03 11:47:39 -0800243/**
244 * fc_exch_rctl_name() - Wrapper routine for fc_exch_name_lookup()
245 * @op: The opcode to be looked up
246 */
Robert Love42e9a922008-12-09 15:10:17 -0800247static const char *fc_exch_rctl_name(unsigned int op)
248{
249 return fc_exch_name_lookup(op, fc_exch_rctl_names,
Kulikov Vasiliy7156fff2010-06-28 15:55:12 +0400250 ARRAY_SIZE(fc_exch_rctl_names));
Robert Love42e9a922008-12-09 15:10:17 -0800251}
252
Robert Love3a3b42b2009-11-03 11:47:39 -0800253/**
254 * fc_exch_hold() - Increment an exchange's reference count
255 * @ep: Echange to be held
Robert Love42e9a922008-12-09 15:10:17 -0800256 */
Robert Love3a3b42b2009-11-03 11:47:39 -0800257static inline void fc_exch_hold(struct fc_exch *ep)
Robert Love42e9a922008-12-09 15:10:17 -0800258{
259 atomic_inc(&ep->ex_refcnt);
260}
261
Robert Love3a3b42b2009-11-03 11:47:39 -0800262/**
263 * fc_exch_setup_hdr() - Initialize a FC header by initializing some fields
264 * and determine SOF and EOF.
265 * @ep: The exchange to that will use the header
266 * @fp: The frame whose header is to be modified
267 * @f_ctl: F_CTL bits that will be used for the frame header
268 *
269 * The fields initialized by this routine are: fh_ox_id, fh_rx_id,
270 * fh_seq_id, fh_seq_cnt and the SOF and EOF.
Robert Love42e9a922008-12-09 15:10:17 -0800271 */
272static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp,
273 u32 f_ctl)
274{
275 struct fc_frame_header *fh = fc_frame_header_get(fp);
276 u16 fill;
277
278 fr_sof(fp) = ep->class;
279 if (ep->seq.cnt)
280 fr_sof(fp) = fc_sof_normal(ep->class);
281
282 if (f_ctl & FC_FC_END_SEQ) {
283 fr_eof(fp) = FC_EOF_T;
284 if (fc_sof_needs_ack(ep->class))
285 fr_eof(fp) = FC_EOF_N;
286 /*
Robert Love3a3b42b2009-11-03 11:47:39 -0800287 * From F_CTL.
Robert Love42e9a922008-12-09 15:10:17 -0800288 * The number of fill bytes to make the length a 4-byte
289 * multiple is the low order 2-bits of the f_ctl.
290 * The fill itself will have been cleared by the frame
291 * allocation.
292 * After this, the length will be even, as expected by
293 * the transport.
294 */
295 fill = fr_len(fp) & 3;
296 if (fill) {
297 fill = 4 - fill;
298 /* TODO, this may be a problem with fragmented skb */
299 skb_put(fp_skb(fp), fill);
300 hton24(fh->fh_f_ctl, f_ctl | fill);
301 }
302 } else {
303 WARN_ON(fr_len(fp) % 4 != 0); /* no pad to non last frame */
304 fr_eof(fp) = FC_EOF_N;
305 }
306
Bart Van Asschec1d45422013-08-14 15:31:52 +0000307 /* Initialize remaining fh fields from fc_fill_fc_hdr */
Robert Love42e9a922008-12-09 15:10:17 -0800308 fh->fh_ox_id = htons(ep->oxid);
309 fh->fh_rx_id = htons(ep->rxid);
310 fh->fh_seq_id = ep->seq.id;
311 fh->fh_seq_cnt = htons(ep->seq.cnt);
312}
313
Robert Love3a3b42b2009-11-03 11:47:39 -0800314/**
315 * fc_exch_release() - Decrement an exchange's reference count
316 * @ep: Exchange to be released
317 *
318 * If the reference count reaches zero and the exchange is complete,
319 * it is freed.
Robert Love42e9a922008-12-09 15:10:17 -0800320 */
321static void fc_exch_release(struct fc_exch *ep)
322{
323 struct fc_exch_mgr *mp;
324
325 if (atomic_dec_and_test(&ep->ex_refcnt)) {
326 mp = ep->em;
327 if (ep->destructor)
328 ep->destructor(&ep->seq, ep->arg);
Julia Lawallaa6cd292009-02-04 22:17:29 +0100329 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE));
Robert Love42e9a922008-12-09 15:10:17 -0800330 mempool_free(ep, mp->ep_pool);
331 }
332}
333
Robert Love3a3b42b2009-11-03 11:47:39 -0800334/**
Vasu Devb29a4f32012-07-06 10:40:10 -0700335 * fc_exch_timer_cancel() - cancel exch timer
336 * @ep: The exchange whose timer to be canceled
337 */
Robert Love4a80f082013-06-11 07:28:03 +0000338static inline void fc_exch_timer_cancel(struct fc_exch *ep)
Vasu Devb29a4f32012-07-06 10:40:10 -0700339{
340 if (cancel_delayed_work(&ep->timeout_work)) {
341 FC_EXCH_DBG(ep, "Exchange timer canceled\n");
342 atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
343 }
344}
345
346/**
347 * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the
348 * the exchange lock held
349 * @ep: The exchange whose timer will start
350 * @timer_msec: The timeout period
351 *
352 * Used for upper level protocols to time out the exchange.
353 * The timer is cancelled when it fires or when the exchange completes.
354 */
355static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
356 unsigned int timer_msec)
357{
358 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
359 return;
360
361 FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec);
362
Bart Van Asscheb8678862013-08-14 15:35:29 +0000363 fc_exch_hold(ep); /* hold for timer */
364 if (!queue_delayed_work(fc_exch_workqueue, &ep->timeout_work,
365 msecs_to_jiffies(timer_msec)))
366 fc_exch_release(ep);
Vasu Devb29a4f32012-07-06 10:40:10 -0700367}
368
369/**
370 * fc_exch_timer_set() - Lock the exchange and set the timer
371 * @ep: The exchange whose timer will start
372 * @timer_msec: The timeout period
373 */
374static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec)
375{
376 spin_lock_bh(&ep->ex_lock);
377 fc_exch_timer_set_locked(ep, timer_msec);
378 spin_unlock_bh(&ep->ex_lock);
379}
380
381/**
Robert Love3a3b42b2009-11-03 11:47:39 -0800382 * fc_exch_done_locked() - Complete an exchange with the exchange lock held
383 * @ep: The exchange that is complete
384 */
Robert Love42e9a922008-12-09 15:10:17 -0800385static int fc_exch_done_locked(struct fc_exch *ep)
386{
387 int rc = 1;
388
389 /*
390 * We must check for completion in case there are two threads
391 * tyring to complete this. But the rrq code will reuse the
392 * ep, and in that case we only clear the resp and set it as
393 * complete, so it can be reused by the timer to send the rrq.
394 */
395 ep->resp = NULL;
396 if (ep->state & FC_EX_DONE)
397 return rc;
398 ep->esb_stat |= ESB_ST_COMPLETE;
399
400 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
401 ep->state |= FC_EX_DONE;
Vasu Devb29a4f32012-07-06 10:40:10 -0700402 fc_exch_timer_cancel(ep);
Robert Love42e9a922008-12-09 15:10:17 -0800403 rc = 0;
404 }
405 return rc;
406}
407
Robert Love3a3b42b2009-11-03 11:47:39 -0800408/**
409 * fc_exch_ptr_get() - Return an exchange from an exchange pool
410 * @pool: Exchange Pool to get an exchange from
411 * @index: Index of the exchange within the pool
412 *
413 * Use the index to get an exchange from within an exchange pool. exches
414 * will point to an array of exchange pointers. The index will select
415 * the exchange within the array.
416 */
Vasu Deve4bc50b2009-08-25 13:58:47 -0700417static inline struct fc_exch *fc_exch_ptr_get(struct fc_exch_pool *pool,
418 u16 index)
419{
420 struct fc_exch **exches = (struct fc_exch **)(pool + 1);
421 return exches[index];
422}
423
Robert Love3a3b42b2009-11-03 11:47:39 -0800424/**
425 * fc_exch_ptr_set() - Assign an exchange to a slot in an exchange pool
426 * @pool: The pool to assign the exchange to
427 * @index: The index in the pool where the exchange will be assigned
428 * @ep: The exchange to assign to the pool
429 */
Vasu Deve4bc50b2009-08-25 13:58:47 -0700430static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
431 struct fc_exch *ep)
432{
433 ((struct fc_exch **)(pool + 1))[index] = ep;
434}
435
Robert Love3a3b42b2009-11-03 11:47:39 -0800436/**
437 * fc_exch_delete() - Delete an exchange
438 * @ep: The exchange to be deleted
439 */
Vasu Devb2f00912009-08-25 13:58:53 -0700440static void fc_exch_delete(struct fc_exch *ep)
Robert Love42e9a922008-12-09 15:10:17 -0800441{
Vasu Devb2f00912009-08-25 13:58:53 -0700442 struct fc_exch_pool *pool;
Hillf Danton2034c192010-11-30 16:18:17 -0800443 u16 index;
Robert Love42e9a922008-12-09 15:10:17 -0800444
Vasu Devb2f00912009-08-25 13:58:53 -0700445 pool = ep->pool;
446 spin_lock_bh(&pool->lock);
447 WARN_ON(pool->total_exches <= 0);
448 pool->total_exches--;
Hillf Danton2034c192010-11-30 16:18:17 -0800449
450 /* update cache of free slot */
451 index = (ep->xid - ep->em->min_xid) >> fc_cpu_order;
452 if (pool->left == FC_XID_UNKNOWN)
453 pool->left = index;
454 else if (pool->right == FC_XID_UNKNOWN)
455 pool->right = index;
456 else
457 pool->next_index = index;
458
459 fc_exch_ptr_set(pool, index, NULL);
Robert Love42e9a922008-12-09 15:10:17 -0800460 list_del(&ep->ex_list);
Vasu Devb2f00912009-08-25 13:58:53 -0700461 spin_unlock_bh(&pool->lock);
Robert Love42e9a922008-12-09 15:10:17 -0800462 fc_exch_release(ep); /* drop hold for exch in mp */
463}
464
Neil Hormanfb00cc22013-05-03 19:34:15 +0000465static int fc_seq_send_locked(struct fc_lport *lport, struct fc_seq *sp,
Bart Van Asschecae7b6d2013-08-14 15:37:52 +0000466 struct fc_frame *fp)
Robert Love1a7b75a2009-11-03 11:45:47 -0800467{
468 struct fc_exch *ep;
469 struct fc_frame_header *fh = fc_frame_header_get(fp);
Bart Van Asschecae7b6d2013-08-14 15:37:52 +0000470 int error = -ENXIO;
Robert Love3a3b42b2009-11-03 11:47:39 -0800471 u32 f_ctl;
Vasu Dev14fc3152011-10-28 11:34:12 -0700472 u8 fh_type = fh->fh_type;
Robert Love1a7b75a2009-11-03 11:45:47 -0800473
474 ep = fc_seq_exch(sp);
Bart Van Asschecae7b6d2013-08-14 15:37:52 +0000475
476 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL)) {
477 fc_frame_free(fp);
478 goto out;
479 }
480
Neil Hormanfb00cc22013-05-03 19:34:15 +0000481 WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT));
Robert Love1a7b75a2009-11-03 11:45:47 -0800482
483 f_ctl = ntoh24(fh->fh_f_ctl);
484 fc_exch_setup_hdr(ep, fp, f_ctl);
Joe Eykholtf60e12e2010-07-20 15:20:14 -0700485 fr_encaps(fp) = ep->encaps;
Robert Love1a7b75a2009-11-03 11:45:47 -0800486
487 /*
488 * update sequence count if this frame is carrying
489 * multiple FC frames when sequence offload is enabled
490 * by LLD.
491 */
492 if (fr_max_payload(fp))
493 sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
494 fr_max_payload(fp));
495 else
496 sp->cnt++;
497
498 /*
499 * Send the frame.
500 */
Robert Love3a3b42b2009-11-03 11:47:39 -0800501 error = lport->tt.frame_send(lport, fp);
Robert Love1a7b75a2009-11-03 11:45:47 -0800502
Vasu Dev14fc3152011-10-28 11:34:12 -0700503 if (fh_type == FC_TYPE_BLS)
Neil Hormanfb00cc22013-05-03 19:34:15 +0000504 goto out;
Vasu Dev77a2b732011-08-25 12:40:52 -0700505
Robert Love1a7b75a2009-11-03 11:45:47 -0800506 /*
507 * Update the exchange and sequence flags,
508 * assuming all frames for the sequence have been sent.
509 * We can only be called to send once for each sequence.
510 */
Robert Love1a7b75a2009-11-03 11:45:47 -0800511 ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */
Joe Eykholtcc3593d2010-03-12 16:08:29 -0800512 if (f_ctl & FC_FC_SEQ_INIT)
Robert Love1a7b75a2009-11-03 11:45:47 -0800513 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
Neil Hormanfb00cc22013-05-03 19:34:15 +0000514out:
515 return error;
516}
517
518/**
519 * fc_seq_send() - Send a frame using existing sequence/exchange pair
520 * @lport: The local port that the exchange will be sent on
521 * @sp: The sequence to be sent
522 * @fp: The frame to be sent on the exchange
Bart Van Asschecae7b6d2013-08-14 15:37:52 +0000523 *
524 * Note: The frame will be freed either by a direct call to fc_frame_free(fp)
525 * or indirectly by calling libfc_function_template.frame_send().
Neil Hormanfb00cc22013-05-03 19:34:15 +0000526 */
527static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
528 struct fc_frame *fp)
529{
530 struct fc_exch *ep;
531 int error;
532 ep = fc_seq_exch(sp);
533 spin_lock_bh(&ep->ex_lock);
534 error = fc_seq_send_locked(lport, sp, fp);
Robert Love1a7b75a2009-11-03 11:45:47 -0800535 spin_unlock_bh(&ep->ex_lock);
536 return error;
537}
538
539/**
Robert Love3a3b42b2009-11-03 11:47:39 -0800540 * fc_seq_alloc() - Allocate a sequence for a given exchange
541 * @ep: The exchange to allocate a new sequence for
542 * @seq_id: The sequence ID to be used
Robert Love1a7b75a2009-11-03 11:45:47 -0800543 *
544 * We don't support multiple originated sequences on the same exchange.
545 * By implication, any previously originated sequence on this exchange
546 * is complete, and we reallocate the same sequence.
547 */
548static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
549{
550 struct fc_seq *sp;
551
552 sp = &ep->seq;
553 sp->ssb_stat = 0;
554 sp->cnt = 0;
555 sp->id = seq_id;
556 return sp;
557}
558
Robert Love3a3b42b2009-11-03 11:47:39 -0800559/**
560 * fc_seq_start_next_locked() - Allocate a new sequence on the same
561 * exchange as the supplied sequence
562 * @sp: The sequence/exchange to get a new sequence for
563 */
Robert Love1a7b75a2009-11-03 11:45:47 -0800564static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
565{
566 struct fc_exch *ep = fc_seq_exch(sp);
567
568 sp = fc_seq_alloc(ep, ep->seq_id++);
569 FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
570 ep->f_ctl, sp->id);
571 return sp;
572}
573
574/**
Robert Love3a3b42b2009-11-03 11:47:39 -0800575 * fc_seq_start_next() - Lock the exchange and get a new sequence
576 * for a given sequence/exchange pair
577 * @sp: The sequence/exchange to get a new exchange for
Robert Love1a7b75a2009-11-03 11:45:47 -0800578 */
579static struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
580{
581 struct fc_exch *ep = fc_seq_exch(sp);
582
583 spin_lock_bh(&ep->ex_lock);
584 sp = fc_seq_start_next_locked(sp);
585 spin_unlock_bh(&ep->ex_lock);
586
587 return sp;
588}
589
Joe Eykholt1a5c2d72011-01-28 16:04:08 -0800590/*
591 * Set the response handler for the exchange associated with a sequence.
592 */
593static void fc_seq_set_resp(struct fc_seq *sp,
594 void (*resp)(struct fc_seq *, struct fc_frame *,
595 void *),
596 void *arg)
597{
598 struct fc_exch *ep = fc_seq_exch(sp);
599
600 spin_lock_bh(&ep->ex_lock);
601 ep->resp = resp;
602 ep->arg = arg;
603 spin_unlock_bh(&ep->ex_lock);
604}
605
Robert Love1a7b75a2009-11-03 11:45:47 -0800606/**
Vasu Dev77a2b732011-08-25 12:40:52 -0700607 * fc_exch_abort_locked() - Abort an exchange
608 * @ep: The exchange to be aborted
Robert Love3a3b42b2009-11-03 11:47:39 -0800609 * @timer_msec: The period of time to wait before aborting
610 *
Vasu Dev77a2b732011-08-25 12:40:52 -0700611 * Locking notes: Called with exch lock held
612 *
613 * Return value: 0 on success else error code
Robert Love1a7b75a2009-11-03 11:45:47 -0800614 */
Vasu Dev77a2b732011-08-25 12:40:52 -0700615static int fc_exch_abort_locked(struct fc_exch *ep,
616 unsigned int timer_msec)
Robert Love42e9a922008-12-09 15:10:17 -0800617{
618 struct fc_seq *sp;
Robert Love42e9a922008-12-09 15:10:17 -0800619 struct fc_frame *fp;
620 int error;
621
Robert Love42e9a922008-12-09 15:10:17 -0800622 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) ||
Vasu Dev77a2b732011-08-25 12:40:52 -0700623 ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP))
Robert Love42e9a922008-12-09 15:10:17 -0800624 return -ENXIO;
Robert Love42e9a922008-12-09 15:10:17 -0800625
626 /*
627 * Send the abort on a new sequence if possible.
628 */
629 sp = fc_seq_start_next_locked(&ep->seq);
Vasu Dev77a2b732011-08-25 12:40:52 -0700630 if (!sp)
Robert Love42e9a922008-12-09 15:10:17 -0800631 return -ENOMEM;
Robert Love42e9a922008-12-09 15:10:17 -0800632
Robert Love42e9a922008-12-09 15:10:17 -0800633 if (timer_msec)
634 fc_exch_timer_set_locked(ep, timer_msec);
Robert Love42e9a922008-12-09 15:10:17 -0800635
Bart Van Asschecae7b6d2013-08-14 15:37:52 +0000636 if (ep->sid) {
637 /*
638 * Send an abort for the sequence that timed out.
639 */
640 fp = fc_frame_alloc(ep->lp, 0);
641 if (fp) {
642 ep->esb_stat |= ESB_ST_SEQ_INIT;
643 fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
644 FC_TYPE_BLS, FC_FC_END_SEQ |
645 FC_FC_SEQ_INIT, 0);
646 error = fc_seq_send_locked(ep->lp, sp, fp);
647 } else {
648 error = -ENOBUFS;
649 }
650 } else {
651 /*
652 * If not logged into the fabric, don't send ABTS but leave
653 * sequence active until next timeout.
654 */
655 error = 0;
656 }
657 ep->esb_stat |= ESB_ST_ABNORMAL;
Robert Love42e9a922008-12-09 15:10:17 -0800658 return error;
659}
Robert Love42e9a922008-12-09 15:10:17 -0800660
Robert Love3a3b42b2009-11-03 11:47:39 -0800661/**
Vasu Dev77a2b732011-08-25 12:40:52 -0700662 * fc_seq_exch_abort() - Abort an exchange and sequence
663 * @req_sp: The sequence to be aborted
664 * @timer_msec: The period of time to wait before aborting
665 *
666 * Generally called because of a timeout or an abort from the upper layer.
667 *
668 * Return value: 0 on success else error code
669 */
670static int fc_seq_exch_abort(const struct fc_seq *req_sp,
671 unsigned int timer_msec)
672{
673 struct fc_exch *ep;
674 int error;
675
676 ep = fc_seq_exch(req_sp);
677 spin_lock_bh(&ep->ex_lock);
678 error = fc_exch_abort_locked(ep, timer_msec);
679 spin_unlock_bh(&ep->ex_lock);
680 return error;
681}
682
683/**
Robert Love3a3b42b2009-11-03 11:47:39 -0800684 * fc_exch_timeout() - Handle exchange timer expiration
685 * @work: The work_struct identifying the exchange that timed out
Robert Love42e9a922008-12-09 15:10:17 -0800686 */
687static void fc_exch_timeout(struct work_struct *work)
688{
689 struct fc_exch *ep = container_of(work, struct fc_exch,
690 timeout_work.work);
691 struct fc_seq *sp = &ep->seq;
692 void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
693 void *arg;
694 u32 e_stat;
695 int rc = 1;
696
Robert Lovecd305ce2009-08-25 13:58:37 -0700697 FC_EXCH_DBG(ep, "Exchange timed out\n");
698
Robert Love42e9a922008-12-09 15:10:17 -0800699 spin_lock_bh(&ep->ex_lock);
700 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
701 goto unlock;
702
703 e_stat = ep->esb_stat;
704 if (e_stat & ESB_ST_COMPLETE) {
705 ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL;
Vasu Deva0cc1ec2009-07-28 17:33:37 -0700706 spin_unlock_bh(&ep->ex_lock);
Robert Love42e9a922008-12-09 15:10:17 -0800707 if (e_stat & ESB_ST_REC_QUAL)
708 fc_exch_rrq(ep);
Robert Love42e9a922008-12-09 15:10:17 -0800709 goto done;
710 } else {
711 resp = ep->resp;
712 arg = ep->arg;
713 ep->resp = NULL;
714 if (e_stat & ESB_ST_ABNORMAL)
715 rc = fc_exch_done_locked(ep);
716 spin_unlock_bh(&ep->ex_lock);
Parikh, Neeravf3162482011-02-25 15:02:56 -0800717 if (!rc)
718 fc_exch_delete(ep);
Robert Love42e9a922008-12-09 15:10:17 -0800719 if (resp)
720 resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg);
721 fc_seq_exch_abort(sp, 2 * ep->r_a_tov);
722 goto done;
723 }
724unlock:
725 spin_unlock_bh(&ep->ex_lock);
726done:
727 /*
728 * This release matches the hold taken when the timer was set.
729 */
730 fc_exch_release(ep);
731}
732
Vasu Dev52ff8782009-07-29 17:05:10 -0700733/**
Robert Love3a3b42b2009-11-03 11:47:39 -0800734 * fc_exch_em_alloc() - Allocate an exchange from a specified EM.
735 * @lport: The local port that the exchange is for
736 * @mp: The exchange manager that will allocate the exchange
Robert Love42e9a922008-12-09 15:10:17 -0800737 *
Vasu Devd7179682009-07-29 17:05:21 -0700738 * Returns pointer to allocated fc_exch with exch lock held.
Robert Love42e9a922008-12-09 15:10:17 -0800739 */
Vasu Dev52ff8782009-07-29 17:05:10 -0700740static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
Vasu Devd7179682009-07-29 17:05:21 -0700741 struct fc_exch_mgr *mp)
Robert Love42e9a922008-12-09 15:10:17 -0800742{
743 struct fc_exch *ep;
Vasu Devb2f00912009-08-25 13:58:53 -0700744 unsigned int cpu;
745 u16 index;
746 struct fc_exch_pool *pool;
Robert Love42e9a922008-12-09 15:10:17 -0800747
748 /* allocate memory for exchange */
749 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
750 if (!ep) {
751 atomic_inc(&mp->stats.no_free_exch);
752 goto out;
753 }
754 memset(ep, 0, sizeof(*ep));
755
Joe Eykholtf018b732010-03-12 16:08:55 -0800756 cpu = get_cpu();
Vasu Devb2f00912009-08-25 13:58:53 -0700757 pool = per_cpu_ptr(mp->pool, cpu);
758 spin_lock_bh(&pool->lock);
Joe Eykholtf018b732010-03-12 16:08:55 -0800759 put_cpu();
Hillf Danton2034c192010-11-30 16:18:17 -0800760
761 /* peek cache of free slot */
762 if (pool->left != FC_XID_UNKNOWN) {
763 index = pool->left;
764 pool->left = FC_XID_UNKNOWN;
765 goto hit;
766 }
767 if (pool->right != FC_XID_UNKNOWN) {
768 index = pool->right;
769 pool->right = FC_XID_UNKNOWN;
770 goto hit;
771 }
772
Vasu Devb2f00912009-08-25 13:58:53 -0700773 index = pool->next_index;
774 /* allocate new exch from pool */
775 while (fc_exch_ptr_get(pool, index)) {
776 index = index == mp->pool_max_index ? 0 : index + 1;
777 if (index == pool->next_index)
Robert Love42e9a922008-12-09 15:10:17 -0800778 goto err;
Robert Love42e9a922008-12-09 15:10:17 -0800779 }
Vasu Devb2f00912009-08-25 13:58:53 -0700780 pool->next_index = index == mp->pool_max_index ? 0 : index + 1;
Hillf Danton2034c192010-11-30 16:18:17 -0800781hit:
Robert Love42e9a922008-12-09 15:10:17 -0800782 fc_exch_hold(ep); /* hold for exch in mp */
783 spin_lock_init(&ep->ex_lock);
784 /*
785 * Hold exch lock for caller to prevent fc_exch_reset()
786 * from releasing exch while fc_exch_alloc() caller is
787 * still working on exch.
788 */
789 spin_lock_bh(&ep->ex_lock);
790
Vasu Devb2f00912009-08-25 13:58:53 -0700791 fc_exch_ptr_set(pool, index, ep);
792 list_add_tail(&ep->ex_list, &pool->ex_list);
Robert Love42e9a922008-12-09 15:10:17 -0800793 fc_seq_alloc(ep, ep->seq_id++);
Vasu Devb2f00912009-08-25 13:58:53 -0700794 pool->total_exches++;
795 spin_unlock_bh(&pool->lock);
Robert Love42e9a922008-12-09 15:10:17 -0800796
797 /*
798 * update exchange
799 */
Vasu Devb2f00912009-08-25 13:58:53 -0700800 ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid;
Robert Love42e9a922008-12-09 15:10:17 -0800801 ep->em = mp;
Vasu Devb2f00912009-08-25 13:58:53 -0700802 ep->pool = pool;
Vasu Dev52ff8782009-07-29 17:05:10 -0700803 ep->lp = lport;
Robert Love42e9a922008-12-09 15:10:17 -0800804 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */
805 ep->rxid = FC_XID_UNKNOWN;
806 ep->class = mp->class;
807 INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout);
808out:
809 return ep;
810err:
Vasu Devb2f00912009-08-25 13:58:53 -0700811 spin_unlock_bh(&pool->lock);
Robert Love42e9a922008-12-09 15:10:17 -0800812 atomic_inc(&mp->stats.no_free_exch_xid);
813 mempool_free(ep, mp->ep_pool);
814 return NULL;
815}
Vasu Dev52ff8782009-07-29 17:05:10 -0700816
817/**
Robert Love3a3b42b2009-11-03 11:47:39 -0800818 * fc_exch_alloc() - Allocate an exchange from an EM on a
819 * local port's list of EMs.
820 * @lport: The local port that will own the exchange
821 * @fp: The FC frame that the exchange will be for
Vasu Dev52ff8782009-07-29 17:05:10 -0700822 *
Robert Love3a3b42b2009-11-03 11:47:39 -0800823 * This function walks the list of exchange manager(EM)
824 * anchors to select an EM for a new exchange allocation. The
825 * EM is selected when a NULL match function pointer is encountered
826 * or when a call to a match function returns true.
Vasu Dev52ff8782009-07-29 17:05:10 -0700827 */
Vasu Dev3e227602010-03-12 16:08:39 -0800828static inline struct fc_exch *fc_exch_alloc(struct fc_lport *lport,
829 struct fc_frame *fp)
Vasu Dev52ff8782009-07-29 17:05:10 -0700830{
831 struct fc_exch_mgr_anchor *ema;
Vasu Dev52ff8782009-07-29 17:05:10 -0700832
Vasu Dev3e227602010-03-12 16:08:39 -0800833 list_for_each_entry(ema, &lport->ema_list, ema_list)
834 if (!ema->match || ema->match(fp))
835 return fc_exch_em_alloc(lport, ema->mp);
Vasu Dev52ff8782009-07-29 17:05:10 -0700836 return NULL;
837}
Robert Love42e9a922008-12-09 15:10:17 -0800838
Robert Love3a3b42b2009-11-03 11:47:39 -0800839/**
840 * fc_exch_find() - Lookup and hold an exchange
841 * @mp: The exchange manager to lookup the exchange from
842 * @xid: The XID of the exchange to look up
Robert Love42e9a922008-12-09 15:10:17 -0800843 */
844static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid)
845{
Vasu Devb2f00912009-08-25 13:58:53 -0700846 struct fc_exch_pool *pool;
Robert Love42e9a922008-12-09 15:10:17 -0800847 struct fc_exch *ep = NULL;
848
849 if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) {
Vasu Devb2f00912009-08-25 13:58:53 -0700850 pool = per_cpu_ptr(mp->pool, xid & fc_cpu_mask);
851 spin_lock_bh(&pool->lock);
852 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order);
Bart Van Assche8d080232013-08-17 20:20:07 +0000853 if (ep) {
854 WARN_ON(ep->xid != xid);
Robert Love42e9a922008-12-09 15:10:17 -0800855 fc_exch_hold(ep);
Bart Van Assche8d080232013-08-17 20:20:07 +0000856 }
Vasu Devb2f00912009-08-25 13:58:53 -0700857 spin_unlock_bh(&pool->lock);
Robert Love42e9a922008-12-09 15:10:17 -0800858 }
859 return ep;
860}
861
Robert Love1a7b75a2009-11-03 11:45:47 -0800862
863/**
864 * fc_exch_done() - Indicate that an exchange/sequence tuple is complete and
Robert Love3a3b42b2009-11-03 11:47:39 -0800865 * the memory allocated for the related objects may be freed.
866 * @sp: The sequence that has completed
Robert Love1a7b75a2009-11-03 11:45:47 -0800867 */
868static void fc_exch_done(struct fc_seq *sp)
Robert Love42e9a922008-12-09 15:10:17 -0800869{
870 struct fc_exch *ep = fc_seq_exch(sp);
871 int rc;
872
873 spin_lock_bh(&ep->ex_lock);
874 rc = fc_exch_done_locked(ep);
875 spin_unlock_bh(&ep->ex_lock);
876 if (!rc)
Vasu Devb2f00912009-08-25 13:58:53 -0700877 fc_exch_delete(ep);
Robert Love42e9a922008-12-09 15:10:17 -0800878}
Robert Love42e9a922008-12-09 15:10:17 -0800879
Robert Love3a3b42b2009-11-03 11:47:39 -0800880/**
881 * fc_exch_resp() - Allocate a new exchange for a response frame
882 * @lport: The local port that the exchange was for
883 * @mp: The exchange manager to allocate the exchange from
884 * @fp: The response frame
885 *
Robert Love42e9a922008-12-09 15:10:17 -0800886 * Sets the responder ID in the frame header.
887 */
Vasu Dev52ff8782009-07-29 17:05:10 -0700888static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
889 struct fc_exch_mgr *mp,
890 struct fc_frame *fp)
Robert Love42e9a922008-12-09 15:10:17 -0800891{
892 struct fc_exch *ep;
893 struct fc_frame_header *fh;
Robert Love42e9a922008-12-09 15:10:17 -0800894
Vasu Dev52ff8782009-07-29 17:05:10 -0700895 ep = fc_exch_alloc(lport, fp);
Robert Love42e9a922008-12-09 15:10:17 -0800896 if (ep) {
897 ep->class = fc_frame_class(fp);
898
899 /*
900 * Set EX_CTX indicating we're responding on this exchange.
901 */
902 ep->f_ctl |= FC_FC_EX_CTX; /* we're responding */
903 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not new */
904 fh = fc_frame_header_get(fp);
905 ep->sid = ntoh24(fh->fh_d_id);
906 ep->did = ntoh24(fh->fh_s_id);
907 ep->oid = ep->did;
908
909 /*
910 * Allocated exchange has placed the XID in the
911 * originator field. Move it to the responder field,
912 * and set the originator XID from the frame.
913 */
914 ep->rxid = ep->xid;
915 ep->oxid = ntohs(fh->fh_ox_id);
916 ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT;
917 if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0)
918 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
919
Robert Love42e9a922008-12-09 15:10:17 -0800920 fc_exch_hold(ep); /* hold for caller */
Vasu Dev52ff8782009-07-29 17:05:10 -0700921 spin_unlock_bh(&ep->ex_lock); /* lock from fc_exch_alloc */
Robert Love42e9a922008-12-09 15:10:17 -0800922 }
923 return ep;
924}
925
Robert Love3a3b42b2009-11-03 11:47:39 -0800926/**
927 * fc_seq_lookup_recip() - Find a sequence where the other end
928 * originated the sequence
929 * @lport: The local port that the frame was sent to
930 * @mp: The Exchange Manager to lookup the exchange from
931 * @fp: The frame associated with the sequence we're looking for
932 *
Robert Love42e9a922008-12-09 15:10:17 -0800933 * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold
934 * on the ep that should be released by the caller.
935 */
Vasu Dev52ff8782009-07-29 17:05:10 -0700936static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
937 struct fc_exch_mgr *mp,
Robert Loveb2ab99c2009-02-27 10:55:50 -0800938 struct fc_frame *fp)
Robert Love42e9a922008-12-09 15:10:17 -0800939{
940 struct fc_frame_header *fh = fc_frame_header_get(fp);
941 struct fc_exch *ep = NULL;
942 struct fc_seq *sp = NULL;
943 enum fc_pf_rjt_reason reject = FC_RJT_NONE;
944 u32 f_ctl;
945 u16 xid;
946
947 f_ctl = ntoh24(fh->fh_f_ctl);
948 WARN_ON((f_ctl & FC_FC_SEQ_CTX) != 0);
949
950 /*
951 * Lookup or create the exchange if we will be creating the sequence.
952 */
953 if (f_ctl & FC_FC_EX_CTX) {
954 xid = ntohs(fh->fh_ox_id); /* we originated exch */
955 ep = fc_exch_find(mp, xid);
956 if (!ep) {
957 atomic_inc(&mp->stats.xid_not_found);
958 reject = FC_RJT_OX_ID;
959 goto out;
960 }
961 if (ep->rxid == FC_XID_UNKNOWN)
962 ep->rxid = ntohs(fh->fh_rx_id);
963 else if (ep->rxid != ntohs(fh->fh_rx_id)) {
964 reject = FC_RJT_OX_ID;
965 goto rel;
966 }
967 } else {
968 xid = ntohs(fh->fh_rx_id); /* we are the responder */
969
970 /*
971 * Special case for MDS issuing an ELS TEST with a
972 * bad rxid of 0.
973 * XXX take this out once we do the proper reject.
974 */
975 if (xid == 0 && fh->fh_r_ctl == FC_RCTL_ELS_REQ &&
976 fc_frame_payload_op(fp) == ELS_TEST) {
977 fh->fh_rx_id = htons(FC_XID_UNKNOWN);
978 xid = FC_XID_UNKNOWN;
979 }
980
981 /*
982 * new sequence - find the exchange
983 */
984 ep = fc_exch_find(mp, xid);
985 if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
986 if (ep) {
987 atomic_inc(&mp->stats.xid_busy);
988 reject = FC_RJT_RX_ID;
989 goto rel;
990 }
Vasu Dev52ff8782009-07-29 17:05:10 -0700991 ep = fc_exch_resp(lport, mp, fp);
Robert Love42e9a922008-12-09 15:10:17 -0800992 if (!ep) {
993 reject = FC_RJT_EXCH_EST; /* XXX */
994 goto out;
995 }
996 xid = ep->xid; /* get our XID */
997 } else if (!ep) {
998 atomic_inc(&mp->stats.xid_not_found);
999 reject = FC_RJT_RX_ID; /* XID not found */
1000 goto out;
1001 }
1002 }
1003
Bart Van Assche5d73bea2013-08-14 15:37:08 +00001004 spin_lock_bh(&ep->ex_lock);
Robert Love42e9a922008-12-09 15:10:17 -08001005 /*
1006 * At this point, we have the exchange held.
1007 * Find or create the sequence.
1008 */
1009 if (fc_sof_is_init(fr_sof(fp))) {
Vasu Deva104c842010-03-12 16:08:34 -08001010 sp = &ep->seq;
Robert Love42e9a922008-12-09 15:10:17 -08001011 sp->ssb_stat |= SSB_ST_RESP;
Joe Eykholtb3667f92010-05-07 15:18:13 -07001012 sp->id = fh->fh_seq_id;
Robert Love42e9a922008-12-09 15:10:17 -08001013 } else {
1014 sp = &ep->seq;
1015 if (sp->id != fh->fh_seq_id) {
1016 atomic_inc(&mp->stats.seq_not_found);
Kiran Patile3e65c62011-06-20 16:59:30 -07001017 if (f_ctl & FC_FC_END_SEQ) {
1018 /*
1019 * Update sequence_id based on incoming last
1020 * frame of sequence exchange. This is needed
Vasu Dev1bd49b42012-05-25 10:26:43 -07001021 * for FC target where DDP has been used
Kiran Patile3e65c62011-06-20 16:59:30 -07001022 * on target where, stack is indicated only
1023 * about last frame's (payload _header) header.
1024 * Whereas "seq_id" which is part of
1025 * frame_header is allocated by initiator
1026 * which is totally different from "seq_id"
1027 * allocated when XFER_RDY was sent by target.
1028 * To avoid false -ve which results into not
1029 * sending RSP, hence write request on other
1030 * end never finishes.
1031 */
Kiran Patile3e65c62011-06-20 16:59:30 -07001032 sp->ssb_stat |= SSB_ST_RESP;
1033 sp->id = fh->fh_seq_id;
Kiran Patile3e65c62011-06-20 16:59:30 -07001034 } else {
Bart Van Assche5d73bea2013-08-14 15:37:08 +00001035 spin_unlock_bh(&ep->ex_lock);
1036
Kiran Patile3e65c62011-06-20 16:59:30 -07001037 /* sequence/exch should exist */
1038 reject = FC_RJT_SEQ_ID;
1039 goto rel;
1040 }
Robert Love42e9a922008-12-09 15:10:17 -08001041 }
1042 }
1043 WARN_ON(ep != fc_seq_exch(sp));
1044
1045 if (f_ctl & FC_FC_SEQ_INIT)
1046 ep->esb_stat |= ESB_ST_SEQ_INIT;
Bart Van Assche5d73bea2013-08-14 15:37:08 +00001047 spin_unlock_bh(&ep->ex_lock);
Robert Love42e9a922008-12-09 15:10:17 -08001048
1049 fr_seq(fp) = sp;
1050out:
1051 return reject;
1052rel:
1053 fc_exch_done(&ep->seq);
1054 fc_exch_release(ep); /* hold from fc_exch_find/fc_exch_resp */
1055 return reject;
1056}
1057
Robert Love3a3b42b2009-11-03 11:47:39 -08001058/**
1059 * fc_seq_lookup_orig() - Find a sequence where this end
1060 * originated the sequence
1061 * @mp: The Exchange Manager to lookup the exchange from
1062 * @fp: The frame associated with the sequence we're looking for
1063 *
Robert Love42e9a922008-12-09 15:10:17 -08001064 * Does not hold the sequence for the caller.
1065 */
1066static struct fc_seq *fc_seq_lookup_orig(struct fc_exch_mgr *mp,
1067 struct fc_frame *fp)
1068{
1069 struct fc_frame_header *fh = fc_frame_header_get(fp);
1070 struct fc_exch *ep;
1071 struct fc_seq *sp = NULL;
1072 u32 f_ctl;
1073 u16 xid;
1074
1075 f_ctl = ntoh24(fh->fh_f_ctl);
1076 WARN_ON((f_ctl & FC_FC_SEQ_CTX) != FC_FC_SEQ_CTX);
1077 xid = ntohs((f_ctl & FC_FC_EX_CTX) ? fh->fh_ox_id : fh->fh_rx_id);
1078 ep = fc_exch_find(mp, xid);
1079 if (!ep)
1080 return NULL;
1081 if (ep->seq.id == fh->fh_seq_id) {
1082 /*
1083 * Save the RX_ID if we didn't previously know it.
1084 */
1085 sp = &ep->seq;
1086 if ((f_ctl & FC_FC_EX_CTX) != 0 &&
1087 ep->rxid == FC_XID_UNKNOWN) {
1088 ep->rxid = ntohs(fh->fh_rx_id);
1089 }
1090 }
1091 fc_exch_release(ep);
1092 return sp;
1093}
1094
Robert Love3a3b42b2009-11-03 11:47:39 -08001095/**
1096 * fc_exch_set_addr() - Set the source and destination IDs for an exchange
1097 * @ep: The exchange to set the addresses for
1098 * @orig_id: The originator's ID
1099 * @resp_id: The responder's ID
1100 *
Robert Love42e9a922008-12-09 15:10:17 -08001101 * Note this must be done before the first sequence of the exchange is sent.
1102 */
1103static void fc_exch_set_addr(struct fc_exch *ep,
1104 u32 orig_id, u32 resp_id)
1105{
1106 ep->oid = orig_id;
1107 if (ep->esb_stat & ESB_ST_RESP) {
1108 ep->sid = resp_id;
1109 ep->did = orig_id;
1110 } else {
1111 ep->sid = orig_id;
1112 ep->did = resp_id;
1113 }
1114}
1115
Robert Love1a7b75a2009-11-03 11:45:47 -08001116/**
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001117 * fc_seq_els_rsp_send() - Send an ELS response using information from
Robert Love3a3b42b2009-11-03 11:47:39 -08001118 * the existing sequence/exchange.
Joe Eykholt922611562010-07-20 15:21:12 -07001119 * @fp: The received frame
Robert Love3a3b42b2009-11-03 11:47:39 -08001120 * @els_cmd: The ELS command to be sent
1121 * @els_data: The ELS data to be sent
Joe Eykholt922611562010-07-20 15:21:12 -07001122 *
1123 * The received frame is not freed.
Robert Love42e9a922008-12-09 15:10:17 -08001124 */
Joe Eykholt922611562010-07-20 15:21:12 -07001125static void fc_seq_els_rsp_send(struct fc_frame *fp, enum fc_els_cmd els_cmd,
Robert Love1a7b75a2009-11-03 11:45:47 -08001126 struct fc_seq_els_data *els_data)
Robert Love42e9a922008-12-09 15:10:17 -08001127{
1128 switch (els_cmd) {
1129 case ELS_LS_RJT:
Joe Eykholt922611562010-07-20 15:21:12 -07001130 fc_seq_ls_rjt(fp, els_data->reason, els_data->explan);
Robert Love42e9a922008-12-09 15:10:17 -08001131 break;
1132 case ELS_LS_ACC:
Joe Eykholt922611562010-07-20 15:21:12 -07001133 fc_seq_ls_acc(fp);
Robert Love42e9a922008-12-09 15:10:17 -08001134 break;
1135 case ELS_RRQ:
Joe Eykholt922611562010-07-20 15:21:12 -07001136 fc_exch_els_rrq(fp);
Robert Love42e9a922008-12-09 15:10:17 -08001137 break;
1138 case ELS_REC:
Joe Eykholt922611562010-07-20 15:21:12 -07001139 fc_exch_els_rec(fp);
Robert Love42e9a922008-12-09 15:10:17 -08001140 break;
1141 default:
Joe Eykholt922611562010-07-20 15:21:12 -07001142 FC_LPORT_DBG(fr_dev(fp), "Invalid ELS CMD:%x\n", els_cmd);
Robert Love42e9a922008-12-09 15:10:17 -08001143 }
1144}
Robert Love42e9a922008-12-09 15:10:17 -08001145
Robert Love3a3b42b2009-11-03 11:47:39 -08001146/**
1147 * fc_seq_send_last() - Send a sequence that is the last in the exchange
1148 * @sp: The sequence that is to be sent
1149 * @fp: The frame that will be sent on the sequence
1150 * @rctl: The R_CTL information to be sent
1151 * @fh_type: The frame header type
Robert Love42e9a922008-12-09 15:10:17 -08001152 */
1153static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
1154 enum fc_rctl rctl, enum fc_fh_type fh_type)
1155{
1156 u32 f_ctl;
1157 struct fc_exch *ep = fc_seq_exch(sp);
1158
1159 f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
1160 f_ctl |= ep->f_ctl;
1161 fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0);
Neil Hormanfb00cc22013-05-03 19:34:15 +00001162 fc_seq_send_locked(ep->lp, sp, fp);
Robert Love42e9a922008-12-09 15:10:17 -08001163}
1164
Robert Love3a3b42b2009-11-03 11:47:39 -08001165/**
1166 * fc_seq_send_ack() - Send an acknowledgement that we've received a frame
1167 * @sp: The sequence to send the ACK on
1168 * @rx_fp: The received frame that is being acknoledged
1169 *
Robert Love42e9a922008-12-09 15:10:17 -08001170 * Send ACK_1 (or equiv.) indicating we received something.
Robert Love42e9a922008-12-09 15:10:17 -08001171 */
1172static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
1173{
1174 struct fc_frame *fp;
1175 struct fc_frame_header *rx_fh;
1176 struct fc_frame_header *fh;
1177 struct fc_exch *ep = fc_seq_exch(sp);
Robert Love3a3b42b2009-11-03 11:47:39 -08001178 struct fc_lport *lport = ep->lp;
Robert Love42e9a922008-12-09 15:10:17 -08001179 unsigned int f_ctl;
1180
1181 /*
1182 * Don't send ACKs for class 3.
1183 */
1184 if (fc_sof_needs_ack(fr_sof(rx_fp))) {
Robert Love3a3b42b2009-11-03 11:47:39 -08001185 fp = fc_frame_alloc(lport, 0);
Robert Love42e9a922008-12-09 15:10:17 -08001186 if (!fp)
1187 return;
1188
1189 fh = fc_frame_header_get(fp);
1190 fh->fh_r_ctl = FC_RCTL_ACK_1;
1191 fh->fh_type = FC_TYPE_BLS;
1192
1193 /*
1194 * Form f_ctl by inverting EX_CTX and SEQ_CTX (bits 23, 22).
1195 * Echo FIRST_SEQ, LAST_SEQ, END_SEQ, END_CONN, SEQ_INIT.
1196 * Bits 9-8 are meaningful (retransmitted or unidirectional).
1197 * Last ACK uses bits 7-6 (continue sequence),
1198 * bits 5-4 are meaningful (what kind of ACK to use).
1199 */
1200 rx_fh = fc_frame_header_get(rx_fp);
1201 f_ctl = ntoh24(rx_fh->fh_f_ctl);
1202 f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX |
1203 FC_FC_FIRST_SEQ | FC_FC_LAST_SEQ |
1204 FC_FC_END_SEQ | FC_FC_END_CONN | FC_FC_SEQ_INIT |
1205 FC_FC_RETX_SEQ | FC_FC_UNI_TX;
1206 f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
1207 hton24(fh->fh_f_ctl, f_ctl);
1208
1209 fc_exch_setup_hdr(ep, fp, f_ctl);
1210 fh->fh_seq_id = rx_fh->fh_seq_id;
1211 fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
1212 fh->fh_parm_offset = htonl(1); /* ack single frame */
1213
1214 fr_sof(fp) = fr_sof(rx_fp);
1215 if (f_ctl & FC_FC_END_SEQ)
1216 fr_eof(fp) = FC_EOF_T;
1217 else
1218 fr_eof(fp) = FC_EOF_N;
1219
Robert Love3a3b42b2009-11-03 11:47:39 -08001220 lport->tt.frame_send(lport, fp);
Robert Love42e9a922008-12-09 15:10:17 -08001221 }
1222}
1223
Robert Love3a3b42b2009-11-03 11:47:39 -08001224/**
1225 * fc_exch_send_ba_rjt() - Send BLS Reject
1226 * @rx_fp: The frame being rejected
1227 * @reason: The reason the frame is being rejected
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001228 * @explan: The explanation for the rejection
Robert Love3a3b42b2009-11-03 11:47:39 -08001229 *
Robert Love42e9a922008-12-09 15:10:17 -08001230 * This is for rejecting BA_ABTS only.
1231 */
Robert Loveb2ab99c2009-02-27 10:55:50 -08001232static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
1233 enum fc_ba_rjt_reason reason,
1234 enum fc_ba_rjt_explan explan)
Robert Love42e9a922008-12-09 15:10:17 -08001235{
1236 struct fc_frame *fp;
1237 struct fc_frame_header *rx_fh;
1238 struct fc_frame_header *fh;
1239 struct fc_ba_rjt *rp;
Robert Love3a3b42b2009-11-03 11:47:39 -08001240 struct fc_lport *lport;
Robert Love42e9a922008-12-09 15:10:17 -08001241 unsigned int f_ctl;
1242
Robert Love3a3b42b2009-11-03 11:47:39 -08001243 lport = fr_dev(rx_fp);
1244 fp = fc_frame_alloc(lport, sizeof(*rp));
Robert Love42e9a922008-12-09 15:10:17 -08001245 if (!fp)
1246 return;
1247 fh = fc_frame_header_get(fp);
1248 rx_fh = fc_frame_header_get(rx_fp);
1249
1250 memset(fh, 0, sizeof(*fh) + sizeof(*rp));
1251
1252 rp = fc_frame_payload_get(fp, sizeof(*rp));
1253 rp->br_reason = reason;
1254 rp->br_explan = explan;
1255
1256 /*
1257 * seq_id, cs_ctl, df_ctl and param/offset are zero.
1258 */
1259 memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3);
1260 memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3);
Joe Eykholt1d490ce2009-08-25 14:04:03 -07001261 fh->fh_ox_id = rx_fh->fh_ox_id;
1262 fh->fh_rx_id = rx_fh->fh_rx_id;
Robert Love42e9a922008-12-09 15:10:17 -08001263 fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
1264 fh->fh_r_ctl = FC_RCTL_BA_RJT;
1265 fh->fh_type = FC_TYPE_BLS;
1266
1267 /*
1268 * Form f_ctl by inverting EX_CTX and SEQ_CTX (bits 23, 22).
1269 * Echo FIRST_SEQ, LAST_SEQ, END_SEQ, END_CONN, SEQ_INIT.
1270 * Bits 9-8 are meaningful (retransmitted or unidirectional).
1271 * Last ACK uses bits 7-6 (continue sequence),
1272 * bits 5-4 are meaningful (what kind of ACK to use).
1273 * Always set LAST_SEQ, END_SEQ.
1274 */
1275 f_ctl = ntoh24(rx_fh->fh_f_ctl);
1276 f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX |
1277 FC_FC_END_CONN | FC_FC_SEQ_INIT |
1278 FC_FC_RETX_SEQ | FC_FC_UNI_TX;
1279 f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
1280 f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ;
1281 f_ctl &= ~FC_FC_FIRST_SEQ;
1282 hton24(fh->fh_f_ctl, f_ctl);
1283
1284 fr_sof(fp) = fc_sof_class(fr_sof(rx_fp));
1285 fr_eof(fp) = FC_EOF_T;
1286 if (fc_sof_needs_ack(fr_sof(fp)))
1287 fr_eof(fp) = FC_EOF_N;
1288
Robert Love3a3b42b2009-11-03 11:47:39 -08001289 lport->tt.frame_send(lport, fp);
Robert Love42e9a922008-12-09 15:10:17 -08001290}
1291
Robert Love3a3b42b2009-11-03 11:47:39 -08001292/**
1293 * fc_exch_recv_abts() - Handle an incoming ABTS
1294 * @ep: The exchange the abort was on
1295 * @rx_fp: The ABTS frame
1296 *
1297 * This would be for target mode usually, but could be due to lost
1298 * FCP transfer ready, confirm or RRQ. We always handle this as an
1299 * exchange abort, ignoring the parameter.
Robert Love42e9a922008-12-09 15:10:17 -08001300 */
1301static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
1302{
1303 struct fc_frame *fp;
1304 struct fc_ba_acc *ap;
1305 struct fc_frame_header *fh;
1306 struct fc_seq *sp;
1307
1308 if (!ep)
1309 goto reject;
1310 spin_lock_bh(&ep->ex_lock);
1311 if (ep->esb_stat & ESB_ST_COMPLETE) {
1312 spin_unlock_bh(&ep->ex_lock);
1313 goto reject;
1314 }
Bart Van Asschecae7b6d2013-08-14 15:37:52 +00001315 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
1316 ep->esb_stat |= ESB_ST_REC_QUAL;
Robert Love42e9a922008-12-09 15:10:17 -08001317 fc_exch_hold(ep); /* hold for REC_QUAL */
Bart Van Asschecae7b6d2013-08-14 15:37:52 +00001318 }
Robert Love42e9a922008-12-09 15:10:17 -08001319 fc_exch_timer_set_locked(ep, ep->r_a_tov);
1320
1321 fp = fc_frame_alloc(ep->lp, sizeof(*ap));
1322 if (!fp) {
1323 spin_unlock_bh(&ep->ex_lock);
1324 goto free;
1325 }
1326 fh = fc_frame_header_get(fp);
1327 ap = fc_frame_payload_get(fp, sizeof(*ap));
1328 memset(ap, 0, sizeof(*ap));
1329 sp = &ep->seq;
1330 ap->ba_high_seq_cnt = htons(0xffff);
1331 if (sp->ssb_stat & SSB_ST_RESP) {
1332 ap->ba_seq_id = sp->id;
1333 ap->ba_seq_id_val = FC_BA_SEQ_ID_VAL;
1334 ap->ba_high_seq_cnt = fh->fh_seq_cnt;
1335 ap->ba_low_seq_cnt = htons(sp->cnt);
1336 }
Vasu Deva7e84f22009-02-27 10:54:51 -08001337 sp = fc_seq_start_next_locked(sp);
Robert Love42e9a922008-12-09 15:10:17 -08001338 fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
Bart Van Asschecae7b6d2013-08-14 15:37:52 +00001339 ep->esb_stat |= ESB_ST_ABNORMAL;
Neil Hormanfb00cc22013-05-03 19:34:15 +00001340 spin_unlock_bh(&ep->ex_lock);
Robert Love42e9a922008-12-09 15:10:17 -08001341 fc_frame_free(rx_fp);
1342 return;
1343
1344reject:
1345 fc_exch_send_ba_rjt(rx_fp, FC_BA_RJT_UNABLE, FC_BA_RJT_INV_XID);
1346free:
1347 fc_frame_free(rx_fp);
1348}
1349
Robert Love3a3b42b2009-11-03 11:47:39 -08001350/**
Joe Eykholt239e8102010-07-20 15:21:07 -07001351 * fc_seq_assign() - Assign exchange and sequence for incoming request
1352 * @lport: The local port that received the request
1353 * @fp: The request frame
1354 *
1355 * On success, the sequence pointer will be returned and also in fr_seq(@fp).
Joe Eykholt62bdb642011-01-28 16:04:34 -08001356 * A reference will be held on the exchange/sequence for the caller, which
1357 * must call fc_seq_release().
Joe Eykholt239e8102010-07-20 15:21:07 -07001358 */
1359static struct fc_seq *fc_seq_assign(struct fc_lport *lport, struct fc_frame *fp)
1360{
1361 struct fc_exch_mgr_anchor *ema;
1362
1363 WARN_ON(lport != fr_dev(fp));
1364 WARN_ON(fr_seq(fp));
1365 fr_seq(fp) = NULL;
1366
1367 list_for_each_entry(ema, &lport->ema_list, ema_list)
1368 if ((!ema->match || ema->match(fp)) &&
Hillf Danton530994d2010-11-30 16:18:28 -08001369 fc_seq_lookup_recip(lport, ema->mp, fp) == FC_RJT_NONE)
Joe Eykholt239e8102010-07-20 15:21:07 -07001370 break;
1371 return fr_seq(fp);
1372}
1373
1374/**
Joe Eykholt62bdb642011-01-28 16:04:34 -08001375 * fc_seq_release() - Release the hold
1376 * @sp: The sequence.
1377 */
1378static void fc_seq_release(struct fc_seq *sp)
1379{
1380 fc_exch_release(fc_seq_exch(sp));
1381}
1382
1383/**
Joe Eykholt922611562010-07-20 15:21:12 -07001384 * fc_exch_recv_req() - Handler for an incoming request
Robert Love3a3b42b2009-11-03 11:47:39 -08001385 * @lport: The local port that received the request
1386 * @mp: The EM that the exchange is on
1387 * @fp: The request frame
Joe Eykholt922611562010-07-20 15:21:12 -07001388 *
1389 * This is used when the other end is originating the exchange
1390 * and the sequence.
Robert Love42e9a922008-12-09 15:10:17 -08001391 */
Robert Love3a3b42b2009-11-03 11:47:39 -08001392static void fc_exch_recv_req(struct fc_lport *lport, struct fc_exch_mgr *mp,
Robert Love42e9a922008-12-09 15:10:17 -08001393 struct fc_frame *fp)
1394{
1395 struct fc_frame_header *fh = fc_frame_header_get(fp);
1396 struct fc_seq *sp = NULL;
1397 struct fc_exch *ep = NULL;
Robert Love42e9a922008-12-09 15:10:17 -08001398 enum fc_pf_rjt_reason reject;
1399
Chris Leech174e1eb2009-11-03 11:46:14 -08001400 /* We can have the wrong fc_lport at this point with NPIV, which is a
1401 * problem now that we know a new exchange needs to be allocated
1402 */
Robert Love3a3b42b2009-11-03 11:47:39 -08001403 lport = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
1404 if (!lport) {
Chris Leech174e1eb2009-11-03 11:46:14 -08001405 fc_frame_free(fp);
1406 return;
1407 }
Joe Eykholt922611562010-07-20 15:21:12 -07001408 fr_dev(fp) = lport;
Chris Leech174e1eb2009-11-03 11:46:14 -08001409
Joe Eykholt922611562010-07-20 15:21:12 -07001410 BUG_ON(fr_seq(fp)); /* XXX remove later */
1411
1412 /*
1413 * If the RX_ID is 0xffff, don't allocate an exchange.
1414 * The upper-level protocol may request one later, if needed.
1415 */
1416 if (fh->fh_rx_id == htons(FC_XID_UNKNOWN))
1417 return lport->tt.lport_recv(lport, fp);
1418
Robert Love3a3b42b2009-11-03 11:47:39 -08001419 reject = fc_seq_lookup_recip(lport, mp, fp);
Robert Love42e9a922008-12-09 15:10:17 -08001420 if (reject == FC_RJT_NONE) {
1421 sp = fr_seq(fp); /* sequence will be held */
1422 ep = fc_seq_exch(sp);
Robert Love42e9a922008-12-09 15:10:17 -08001423 fc_seq_send_ack(sp, fp);
Joe Eykholtf60e12e2010-07-20 15:20:14 -07001424 ep->encaps = fr_encaps(fp);
Robert Love42e9a922008-12-09 15:10:17 -08001425
1426 /*
1427 * Call the receive function.
1428 *
1429 * The receive function may allocate a new sequence
1430 * over the old one, so we shouldn't change the
1431 * sequence after this.
1432 *
1433 * The frame will be freed by the receive function.
1434 * If new exch resp handler is valid then call that
1435 * first.
1436 */
1437 if (ep->resp)
1438 ep->resp(sp, fp, ep->arg);
1439 else
Joe Eykholt922611562010-07-20 15:21:12 -07001440 lport->tt.lport_recv(lport, fp);
Robert Love42e9a922008-12-09 15:10:17 -08001441 fc_exch_release(ep); /* release from lookup */
1442 } else {
Robert Love3a3b42b2009-11-03 11:47:39 -08001443 FC_LPORT_DBG(lport, "exch/seq lookup failed: reject %x\n",
1444 reject);
Robert Love42e9a922008-12-09 15:10:17 -08001445 fc_frame_free(fp);
1446 }
1447}
1448
Robert Love3a3b42b2009-11-03 11:47:39 -08001449/**
1450 * fc_exch_recv_seq_resp() - Handler for an incoming response where the other
1451 * end is the originator of the sequence that is a
1452 * response to our initial exchange
1453 * @mp: The EM that the exchange is on
1454 * @fp: The response frame
Robert Love42e9a922008-12-09 15:10:17 -08001455 */
1456static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1457{
1458 struct fc_frame_header *fh = fc_frame_header_get(fp);
1459 struct fc_seq *sp;
1460 struct fc_exch *ep;
1461 enum fc_sof sof;
1462 u32 f_ctl;
1463 void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
1464 void *ex_resp_arg;
1465 int rc;
1466
1467 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
1468 if (!ep) {
1469 atomic_inc(&mp->stats.xid_not_found);
1470 goto out;
1471 }
Steve Ma30121d12009-05-06 10:52:29 -07001472 if (ep->esb_stat & ESB_ST_COMPLETE) {
1473 atomic_inc(&mp->stats.xid_not_found);
Hillf Danton82365542010-11-30 16:18:12 -08001474 goto rel;
Steve Ma30121d12009-05-06 10:52:29 -07001475 }
Robert Love42e9a922008-12-09 15:10:17 -08001476 if (ep->rxid == FC_XID_UNKNOWN)
1477 ep->rxid = ntohs(fh->fh_rx_id);
1478 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
1479 atomic_inc(&mp->stats.xid_not_found);
1480 goto rel;
1481 }
1482 if (ep->did != ntoh24(fh->fh_s_id) &&
1483 ep->did != FC_FID_FLOGI) {
1484 atomic_inc(&mp->stats.xid_not_found);
1485 goto rel;
1486 }
1487 sof = fr_sof(fp);
Vasu Deva104c842010-03-12 16:08:34 -08001488 sp = &ep->seq;
Joe Eykholtb3667f92010-05-07 15:18:13 -07001489 if (fc_sof_is_init(sof)) {
Robert Love42e9a922008-12-09 15:10:17 -08001490 sp->ssb_stat |= SSB_ST_RESP;
Joe Eykholtb3667f92010-05-07 15:18:13 -07001491 sp->id = fh->fh_seq_id;
1492 } else if (sp->id != fh->fh_seq_id) {
1493 atomic_inc(&mp->stats.seq_not_found);
1494 goto rel;
Robert Love42e9a922008-12-09 15:10:17 -08001495 }
Vasu Deva104c842010-03-12 16:08:34 -08001496
Robert Love42e9a922008-12-09 15:10:17 -08001497 f_ctl = ntoh24(fh->fh_f_ctl);
1498 fr_seq(fp) = sp;
Bart Van Assche5d73bea2013-08-14 15:37:08 +00001499
1500 spin_lock_bh(&ep->ex_lock);
Robert Love42e9a922008-12-09 15:10:17 -08001501 if (f_ctl & FC_FC_SEQ_INIT)
1502 ep->esb_stat |= ESB_ST_SEQ_INIT;
Bart Van Assche5d73bea2013-08-14 15:37:08 +00001503 spin_unlock_bh(&ep->ex_lock);
Robert Love42e9a922008-12-09 15:10:17 -08001504
1505 if (fc_sof_needs_ack(sof))
1506 fc_seq_send_ack(sp, fp);
1507 resp = ep->resp;
1508 ex_resp_arg = ep->arg;
1509
1510 if (fh->fh_type != FC_TYPE_FCP && fr_eof(fp) == FC_EOF_T &&
1511 (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
1512 (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
1513 spin_lock_bh(&ep->ex_lock);
Vasu Dev8d23f4b2011-05-16 16:45:45 -07001514 resp = ep->resp;
Robert Love42e9a922008-12-09 15:10:17 -08001515 rc = fc_exch_done_locked(ep);
1516 WARN_ON(fc_seq_exch(sp) != ep);
1517 spin_unlock_bh(&ep->ex_lock);
1518 if (!rc)
Vasu Devb2f00912009-08-25 13:58:53 -07001519 fc_exch_delete(ep);
Robert Love42e9a922008-12-09 15:10:17 -08001520 }
1521
1522 /*
1523 * Call the receive function.
1524 * The sequence is held (has a refcnt) for us,
1525 * but not for the receive function.
1526 *
1527 * The receive function may allocate a new sequence
1528 * over the old one, so we shouldn't change the
1529 * sequence after this.
1530 *
1531 * The frame will be freed by the receive function.
1532 * If new exch resp handler is valid then call that
1533 * first.
1534 */
1535 if (resp)
1536 resp(sp, fp, ex_resp_arg);
1537 else
1538 fc_frame_free(fp);
1539 fc_exch_release(ep);
1540 return;
1541rel:
1542 fc_exch_release(ep);
1543out:
1544 fc_frame_free(fp);
1545}
1546
Robert Love3a3b42b2009-11-03 11:47:39 -08001547/**
1548 * fc_exch_recv_resp() - Handler for a sequence where other end is
1549 * responding to our sequence
1550 * @mp: The EM that the exchange is on
1551 * @fp: The response frame
Robert Love42e9a922008-12-09 15:10:17 -08001552 */
1553static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1554{
1555 struct fc_seq *sp;
1556
1557 sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */
Robert Loved459b7e2009-07-29 17:05:05 -07001558
1559 if (!sp)
Robert Love42e9a922008-12-09 15:10:17 -08001560 atomic_inc(&mp->stats.xid_not_found);
Robert Loved459b7e2009-07-29 17:05:05 -07001561 else
Robert Love42e9a922008-12-09 15:10:17 -08001562 atomic_inc(&mp->stats.non_bls_resp);
Robert Loved459b7e2009-07-29 17:05:05 -07001563
Robert Love42e9a922008-12-09 15:10:17 -08001564 fc_frame_free(fp);
1565}
1566
Robert Love3a3b42b2009-11-03 11:47:39 -08001567/**
1568 * fc_exch_abts_resp() - Handler for a response to an ABT
1569 * @ep: The exchange that the frame is on
1570 * @fp: The response frame
1571 *
1572 * This response would be to an ABTS cancelling an exchange or sequence.
1573 * The response can be either BA_ACC or BA_RJT
Robert Love42e9a922008-12-09 15:10:17 -08001574 */
1575static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
1576{
1577 void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
1578 void *ex_resp_arg;
1579 struct fc_frame_header *fh;
1580 struct fc_ba_acc *ap;
1581 struct fc_seq *sp;
1582 u16 low;
1583 u16 high;
1584 int rc = 1, has_rec = 0;
1585
1586 fh = fc_frame_header_get(fp);
Robert Love74147052009-06-10 15:31:10 -07001587 FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl,
1588 fc_exch_rctl_name(fh->fh_r_ctl));
Robert Love42e9a922008-12-09 15:10:17 -08001589
Vasu Devb29a4f32012-07-06 10:40:10 -07001590 if (cancel_delayed_work_sync(&ep->timeout_work)) {
Robert Love3a292602013-06-11 07:28:09 +00001591 FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n");
Robert Love42e9a922008-12-09 15:10:17 -08001592 fc_exch_release(ep); /* release from pending timer hold */
Vasu Devb29a4f32012-07-06 10:40:10 -07001593 }
Robert Love42e9a922008-12-09 15:10:17 -08001594
1595 spin_lock_bh(&ep->ex_lock);
1596 switch (fh->fh_r_ctl) {
1597 case FC_RCTL_BA_ACC:
1598 ap = fc_frame_payload_get(fp, sizeof(*ap));
1599 if (!ap)
1600 break;
1601
1602 /*
1603 * Decide whether to establish a Recovery Qualifier.
1604 * We do this if there is a non-empty SEQ_CNT range and
1605 * SEQ_ID is the same as the one we aborted.
1606 */
1607 low = ntohs(ap->ba_low_seq_cnt);
1608 high = ntohs(ap->ba_high_seq_cnt);
1609 if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 &&
1610 (ap->ba_seq_id_val != FC_BA_SEQ_ID_VAL ||
1611 ap->ba_seq_id == ep->seq_id) && low != high) {
1612 ep->esb_stat |= ESB_ST_REC_QUAL;
1613 fc_exch_hold(ep); /* hold for recovery qualifier */
1614 has_rec = 1;
1615 }
1616 break;
1617 case FC_RCTL_BA_RJT:
1618 break;
1619 default:
1620 break;
1621 }
1622
1623 resp = ep->resp;
1624 ex_resp_arg = ep->arg;
1625
1626 /* do we need to do some other checks here. Can we reuse more of
1627 * fc_exch_recv_seq_resp
1628 */
1629 sp = &ep->seq;
1630 /*
1631 * do we want to check END_SEQ as well as LAST_SEQ here?
1632 */
1633 if (ep->fh_type != FC_TYPE_FCP &&
1634 ntoh24(fh->fh_f_ctl) & FC_FC_LAST_SEQ)
1635 rc = fc_exch_done_locked(ep);
1636 spin_unlock_bh(&ep->ex_lock);
1637 if (!rc)
Vasu Devb2f00912009-08-25 13:58:53 -07001638 fc_exch_delete(ep);
Robert Love42e9a922008-12-09 15:10:17 -08001639
1640 if (resp)
1641 resp(sp, fp, ex_resp_arg);
1642 else
1643 fc_frame_free(fp);
1644
1645 if (has_rec)
1646 fc_exch_timer_set(ep, ep->r_a_tov);
1647
1648}
1649
Robert Love3a3b42b2009-11-03 11:47:39 -08001650/**
1651 * fc_exch_recv_bls() - Handler for a BLS sequence
1652 * @mp: The EM that the exchange is on
1653 * @fp: The request frame
1654 *
1655 * The BLS frame is always a sequence initiated by the remote side.
Robert Love42e9a922008-12-09 15:10:17 -08001656 * We may be either the originator or recipient of the exchange.
1657 */
1658static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
1659{
1660 struct fc_frame_header *fh;
1661 struct fc_exch *ep;
1662 u32 f_ctl;
1663
1664 fh = fc_frame_header_get(fp);
1665 f_ctl = ntoh24(fh->fh_f_ctl);
1666 fr_seq(fp) = NULL;
1667
1668 ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ?
1669 ntohs(fh->fh_ox_id) : ntohs(fh->fh_rx_id));
1670 if (ep && (f_ctl & FC_FC_SEQ_INIT)) {
1671 spin_lock_bh(&ep->ex_lock);
1672 ep->esb_stat |= ESB_ST_SEQ_INIT;
1673 spin_unlock_bh(&ep->ex_lock);
1674 }
1675 if (f_ctl & FC_FC_SEQ_CTX) {
1676 /*
1677 * A response to a sequence we initiated.
1678 * This should only be ACKs for class 2 or F.
1679 */
1680 switch (fh->fh_r_ctl) {
1681 case FC_RCTL_ACK_1:
1682 case FC_RCTL_ACK_0:
1683 break;
1684 default:
Bhanu Prakash Gollapudid4042e92012-02-10 17:18:51 -08001685 if (ep)
Bart Van Asscheb20d9bf2013-08-14 15:32:51 +00001686 FC_EXCH_DBG(ep, "BLS rctl %x - %s received\n",
Bhanu Prakash Gollapudid4042e92012-02-10 17:18:51 -08001687 fh->fh_r_ctl,
1688 fc_exch_rctl_name(fh->fh_r_ctl));
Robert Love42e9a922008-12-09 15:10:17 -08001689 break;
1690 }
1691 fc_frame_free(fp);
1692 } else {
1693 switch (fh->fh_r_ctl) {
1694 case FC_RCTL_BA_RJT:
1695 case FC_RCTL_BA_ACC:
1696 if (ep)
1697 fc_exch_abts_resp(ep, fp);
1698 else
1699 fc_frame_free(fp);
1700 break;
1701 case FC_RCTL_BA_ABTS:
1702 fc_exch_recv_abts(ep, fp);
1703 break;
1704 default: /* ignore junk */
1705 fc_frame_free(fp);
1706 break;
1707 }
1708 }
1709 if (ep)
1710 fc_exch_release(ep); /* release hold taken by fc_exch_find */
1711}
1712
Robert Love3a3b42b2009-11-03 11:47:39 -08001713/**
1714 * fc_seq_ls_acc() - Accept sequence with LS_ACC
Joe Eykholt922611562010-07-20 15:21:12 -07001715 * @rx_fp: The received frame, not freed here.
Robert Love3a3b42b2009-11-03 11:47:39 -08001716 *
Robert Love42e9a922008-12-09 15:10:17 -08001717 * If this fails due to allocation or transmit congestion, assume the
1718 * originator will repeat the sequence.
1719 */
Joe Eykholt922611562010-07-20 15:21:12 -07001720static void fc_seq_ls_acc(struct fc_frame *rx_fp)
Robert Love42e9a922008-12-09 15:10:17 -08001721{
Joe Eykholt922611562010-07-20 15:21:12 -07001722 struct fc_lport *lport;
Robert Love42e9a922008-12-09 15:10:17 -08001723 struct fc_els_ls_acc *acc;
1724 struct fc_frame *fp;
1725
Joe Eykholt922611562010-07-20 15:21:12 -07001726 lport = fr_dev(rx_fp);
1727 fp = fc_frame_alloc(lport, sizeof(*acc));
1728 if (!fp)
1729 return;
1730 acc = fc_frame_payload_get(fp, sizeof(*acc));
1731 memset(acc, 0, sizeof(*acc));
1732 acc->la_cmd = ELS_LS_ACC;
1733 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
1734 lport->tt.frame_send(lport, fp);
Robert Love42e9a922008-12-09 15:10:17 -08001735}
1736
Robert Love3a3b42b2009-11-03 11:47:39 -08001737/**
1738 * fc_seq_ls_rjt() - Reject a sequence with ELS LS_RJT
Joe Eykholt922611562010-07-20 15:21:12 -07001739 * @rx_fp: The received frame, not freed here.
Robert Love3a3b42b2009-11-03 11:47:39 -08001740 * @reason: The reason the sequence is being rejected
Joe Eykholt922611562010-07-20 15:21:12 -07001741 * @explan: The explanation for the rejection
Robert Love3a3b42b2009-11-03 11:47:39 -08001742 *
Robert Love42e9a922008-12-09 15:10:17 -08001743 * If this fails due to allocation or transmit congestion, assume the
1744 * originator will repeat the sequence.
1745 */
Joe Eykholt922611562010-07-20 15:21:12 -07001746static void fc_seq_ls_rjt(struct fc_frame *rx_fp, enum fc_els_rjt_reason reason,
Robert Love42e9a922008-12-09 15:10:17 -08001747 enum fc_els_rjt_explan explan)
1748{
Joe Eykholt922611562010-07-20 15:21:12 -07001749 struct fc_lport *lport;
Robert Love42e9a922008-12-09 15:10:17 -08001750 struct fc_els_ls_rjt *rjt;
1751 struct fc_frame *fp;
1752
Joe Eykholt922611562010-07-20 15:21:12 -07001753 lport = fr_dev(rx_fp);
1754 fp = fc_frame_alloc(lport, sizeof(*rjt));
1755 if (!fp)
1756 return;
1757 rjt = fc_frame_payload_get(fp, sizeof(*rjt));
1758 memset(rjt, 0, sizeof(*rjt));
1759 rjt->er_cmd = ELS_LS_RJT;
1760 rjt->er_reason = reason;
1761 rjt->er_explan = explan;
1762 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
1763 lport->tt.frame_send(lport, fp);
Robert Love42e9a922008-12-09 15:10:17 -08001764}
1765
Robert Love3a3b42b2009-11-03 11:47:39 -08001766/**
1767 * fc_exch_reset() - Reset an exchange
1768 * @ep: The exchange to be reset
1769 */
Robert Love42e9a922008-12-09 15:10:17 -08001770static void fc_exch_reset(struct fc_exch *ep)
1771{
1772 struct fc_seq *sp;
1773 void (*resp)(struct fc_seq *, struct fc_frame *, void *);
1774 void *arg;
1775 int rc = 1;
1776
1777 spin_lock_bh(&ep->ex_lock);
Vasu Dev77a2b732011-08-25 12:40:52 -07001778 fc_exch_abort_locked(ep, 0);
Robert Love42e9a922008-12-09 15:10:17 -08001779 ep->state |= FC_EX_RST_CLEANUP;
Vasu Devb29a4f32012-07-06 10:40:10 -07001780 fc_exch_timer_cancel(ep);
Robert Love42e9a922008-12-09 15:10:17 -08001781 resp = ep->resp;
1782 ep->resp = NULL;
1783 if (ep->esb_stat & ESB_ST_REC_QUAL)
1784 atomic_dec(&ep->ex_refcnt); /* drop hold for rec_qual */
1785 ep->esb_stat &= ~ESB_ST_REC_QUAL;
1786 arg = ep->arg;
1787 sp = &ep->seq;
1788 rc = fc_exch_done_locked(ep);
1789 spin_unlock_bh(&ep->ex_lock);
1790 if (!rc)
Vasu Devb2f00912009-08-25 13:58:53 -07001791 fc_exch_delete(ep);
Robert Love42e9a922008-12-09 15:10:17 -08001792
1793 if (resp)
1794 resp(sp, ERR_PTR(-FC_EX_CLOSED), arg);
1795}
1796
Vasu Devb2f00912009-08-25 13:58:53 -07001797/**
Robert Love3a3b42b2009-11-03 11:47:39 -08001798 * fc_exch_pool_reset() - Reset a per cpu exchange pool
1799 * @lport: The local port that the exchange pool is on
1800 * @pool: The exchange pool to be reset
1801 * @sid: The source ID
1802 * @did: The destination ID
Vasu Devb2f00912009-08-25 13:58:53 -07001803 *
Robert Love3a3b42b2009-11-03 11:47:39 -08001804 * Resets a per cpu exches pool, releasing all of its sequences
1805 * and exchanges. If sid is non-zero then reset only exchanges
1806 * we sourced from the local port's FID. If did is non-zero then
1807 * only reset exchanges destined for the local port's FID.
Robert Love42e9a922008-12-09 15:10:17 -08001808 */
Vasu Devb2f00912009-08-25 13:58:53 -07001809static void fc_exch_pool_reset(struct fc_lport *lport,
1810 struct fc_exch_pool *pool,
1811 u32 sid, u32 did)
Robert Love42e9a922008-12-09 15:10:17 -08001812{
1813 struct fc_exch *ep;
1814 struct fc_exch *next;
Robert Love42e9a922008-12-09 15:10:17 -08001815
Vasu Devb2f00912009-08-25 13:58:53 -07001816 spin_lock_bh(&pool->lock);
Robert Love42e9a922008-12-09 15:10:17 -08001817restart:
Vasu Devb2f00912009-08-25 13:58:53 -07001818 list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) {
1819 if ((lport == ep->lp) &&
1820 (sid == 0 || sid == ep->sid) &&
1821 (did == 0 || did == ep->did)) {
1822 fc_exch_hold(ep);
1823 spin_unlock_bh(&pool->lock);
Robert Love42e9a922008-12-09 15:10:17 -08001824
Vasu Devb2f00912009-08-25 13:58:53 -07001825 fc_exch_reset(ep);
Robert Love42e9a922008-12-09 15:10:17 -08001826
Vasu Devb2f00912009-08-25 13:58:53 -07001827 fc_exch_release(ep);
1828 spin_lock_bh(&pool->lock);
Robert Love42e9a922008-12-09 15:10:17 -08001829
Vasu Devb2f00912009-08-25 13:58:53 -07001830 /*
1831 * must restart loop incase while lock
1832 * was down multiple eps were released.
1833 */
1834 goto restart;
Robert Love42e9a922008-12-09 15:10:17 -08001835 }
Vasu Devb2f00912009-08-25 13:58:53 -07001836 }
Vasu Devb6e3c842011-10-28 11:34:17 -07001837 pool->next_index = 0;
1838 pool->left = FC_XID_UNKNOWN;
1839 pool->right = FC_XID_UNKNOWN;
Vasu Devb2f00912009-08-25 13:58:53 -07001840 spin_unlock_bh(&pool->lock);
1841}
1842
1843/**
Robert Love3a3b42b2009-11-03 11:47:39 -08001844 * fc_exch_mgr_reset() - Reset all EMs of a local port
1845 * @lport: The local port whose EMs are to be reset
1846 * @sid: The source ID
1847 * @did: The destination ID
Vasu Devb2f00912009-08-25 13:58:53 -07001848 *
Robert Love3a3b42b2009-11-03 11:47:39 -08001849 * Reset all EMs associated with a given local port. Release all
1850 * sequences and exchanges. If sid is non-zero then reset only the
1851 * exchanges sent from the local port's FID. If did is non-zero then
1852 * reset only exchanges destined for the local port's FID.
Vasu Devb2f00912009-08-25 13:58:53 -07001853 */
1854void fc_exch_mgr_reset(struct fc_lport *lport, u32 sid, u32 did)
1855{
1856 struct fc_exch_mgr_anchor *ema;
1857 unsigned int cpu;
1858
1859 list_for_each_entry(ema, &lport->ema_list, ema_list) {
1860 for_each_possible_cpu(cpu)
1861 fc_exch_pool_reset(lport,
1862 per_cpu_ptr(ema->mp->pool, cpu),
1863 sid, did);
Robert Love42e9a922008-12-09 15:10:17 -08001864 }
Robert Love42e9a922008-12-09 15:10:17 -08001865}
1866EXPORT_SYMBOL(fc_exch_mgr_reset);
1867
Robert Love3a3b42b2009-11-03 11:47:39 -08001868/**
Joe Eykholt922611562010-07-20 15:21:12 -07001869 * fc_exch_lookup() - find an exchange
1870 * @lport: The local port
1871 * @xid: The exchange ID
1872 *
1873 * Returns exchange pointer with hold for caller, or NULL if not found.
1874 */
1875static struct fc_exch *fc_exch_lookup(struct fc_lport *lport, u32 xid)
1876{
1877 struct fc_exch_mgr_anchor *ema;
1878
1879 list_for_each_entry(ema, &lport->ema_list, ema_list)
1880 if (ema->mp->min_xid <= xid && xid <= ema->mp->max_xid)
1881 return fc_exch_find(ema->mp, xid);
1882 return NULL;
1883}
1884
1885/**
Robert Love3a3b42b2009-11-03 11:47:39 -08001886 * fc_exch_els_rec() - Handler for ELS REC (Read Exchange Concise) requests
Joe Eykholt922611562010-07-20 15:21:12 -07001887 * @rfp: The REC frame, not freed here.
Robert Love3a3b42b2009-11-03 11:47:39 -08001888 *
Robert Love42e9a922008-12-09 15:10:17 -08001889 * Note that the requesting port may be different than the S_ID in the request.
1890 */
Joe Eykholt922611562010-07-20 15:21:12 -07001891static void fc_exch_els_rec(struct fc_frame *rfp)
Robert Love42e9a922008-12-09 15:10:17 -08001892{
Joe Eykholt922611562010-07-20 15:21:12 -07001893 struct fc_lport *lport;
Robert Love42e9a922008-12-09 15:10:17 -08001894 struct fc_frame *fp;
1895 struct fc_exch *ep;
Robert Love42e9a922008-12-09 15:10:17 -08001896 struct fc_els_rec *rp;
1897 struct fc_els_rec_acc *acc;
1898 enum fc_els_rjt_reason reason = ELS_RJT_LOGIC;
1899 enum fc_els_rjt_explan explan;
1900 u32 sid;
1901 u16 rxid;
1902 u16 oxid;
1903
Joe Eykholt922611562010-07-20 15:21:12 -07001904 lport = fr_dev(rfp);
Robert Love42e9a922008-12-09 15:10:17 -08001905 rp = fc_frame_payload_get(rfp, sizeof(*rp));
1906 explan = ELS_EXPL_INV_LEN;
1907 if (!rp)
1908 goto reject;
1909 sid = ntoh24(rp->rec_s_id);
1910 rxid = ntohs(rp->rec_rx_id);
1911 oxid = ntohs(rp->rec_ox_id);
1912
Joe Eykholt922611562010-07-20 15:21:12 -07001913 ep = fc_exch_lookup(lport,
1914 sid == fc_host_port_id(lport->host) ? oxid : rxid);
Robert Love42e9a922008-12-09 15:10:17 -08001915 explan = ELS_EXPL_OXID_RXID;
Joe Eykholt922611562010-07-20 15:21:12 -07001916 if (!ep)
1917 goto reject;
1918 if (ep->oid != sid || oxid != ep->oxid)
1919 goto rel;
1920 if (rxid != FC_XID_UNKNOWN && rxid != ep->rxid)
1921 goto rel;
1922 fp = fc_frame_alloc(lport, sizeof(*acc));
1923 if (!fp)
Robert Love42e9a922008-12-09 15:10:17 -08001924 goto out;
Joe Eykholt922611562010-07-20 15:21:12 -07001925
Robert Love42e9a922008-12-09 15:10:17 -08001926 acc = fc_frame_payload_get(fp, sizeof(*acc));
1927 memset(acc, 0, sizeof(*acc));
1928 acc->reca_cmd = ELS_LS_ACC;
1929 acc->reca_ox_id = rp->rec_ox_id;
1930 memcpy(acc->reca_ofid, rp->rec_s_id, 3);
1931 acc->reca_rx_id = htons(ep->rxid);
1932 if (ep->sid == ep->oid)
1933 hton24(acc->reca_rfid, ep->did);
1934 else
1935 hton24(acc->reca_rfid, ep->sid);
1936 acc->reca_fc4value = htonl(ep->seq.rec_data);
1937 acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP |
1938 ESB_ST_SEQ_INIT |
1939 ESB_ST_COMPLETE));
Joe Eykholt922611562010-07-20 15:21:12 -07001940 fc_fill_reply_hdr(fp, rfp, FC_RCTL_ELS_REP, 0);
1941 lport->tt.frame_send(lport, fp);
Robert Love42e9a922008-12-09 15:10:17 -08001942out:
1943 fc_exch_release(ep);
Robert Love42e9a922008-12-09 15:10:17 -08001944 return;
1945
1946rel:
1947 fc_exch_release(ep);
1948reject:
Joe Eykholt922611562010-07-20 15:21:12 -07001949 fc_seq_ls_rjt(rfp, reason, explan);
Robert Love42e9a922008-12-09 15:10:17 -08001950}
1951
Robert Love3a3b42b2009-11-03 11:47:39 -08001952/**
1953 * fc_exch_rrq_resp() - Handler for RRQ responses
1954 * @sp: The sequence that the RRQ is on
1955 * @fp: The RRQ frame
1956 * @arg: The exchange that the RRQ is on
Robert Love42e9a922008-12-09 15:10:17 -08001957 *
1958 * TODO: fix error handler.
1959 */
1960static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
1961{
1962 struct fc_exch *aborted_ep = arg;
1963 unsigned int op;
1964
1965 if (IS_ERR(fp)) {
1966 int err = PTR_ERR(fp);
1967
Vasu Dev78342da2009-02-27 10:54:46 -08001968 if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT)
Robert Love42e9a922008-12-09 15:10:17 -08001969 goto cleanup;
Robert Love74147052009-06-10 15:31:10 -07001970 FC_EXCH_DBG(aborted_ep, "Cannot process RRQ, "
1971 "frame error %d\n", err);
Robert Love42e9a922008-12-09 15:10:17 -08001972 return;
1973 }
1974
1975 op = fc_frame_payload_op(fp);
1976 fc_frame_free(fp);
1977
1978 switch (op) {
1979 case ELS_LS_RJT:
Bart Van Asscheb20d9bf2013-08-14 15:32:51 +00001980 FC_EXCH_DBG(aborted_ep, "LS_RJT for RRQ\n");
Robert Love42e9a922008-12-09 15:10:17 -08001981 /* fall through */
1982 case ELS_LS_ACC:
1983 goto cleanup;
1984 default:
Bart Van Asscheb20d9bf2013-08-14 15:32:51 +00001985 FC_EXCH_DBG(aborted_ep, "unexpected response op %x for RRQ\n",
1986 op);
Robert Love42e9a922008-12-09 15:10:17 -08001987 return;
1988 }
1989
1990cleanup:
1991 fc_exch_done(&aborted_ep->seq);
1992 /* drop hold for rec qual */
1993 fc_exch_release(aborted_ep);
1994}
1995
Robert Love1a7b75a2009-11-03 11:45:47 -08001996
1997/**
Robert Love3a3b42b2009-11-03 11:47:39 -08001998 * fc_exch_seq_send() - Send a frame using a new exchange and sequence
1999 * @lport: The local port to send the frame on
2000 * @fp: The frame to be sent
2001 * @resp: The response handler for this request
2002 * @destructor: The destructor for the exchange
2003 * @arg: The argument to be passed to the response handler
2004 * @timer_msec: The timeout period for the exchange
2005 *
2006 * The frame pointer with some of the header's fields must be
2007 * filled before calling this routine, those fields are:
2008 *
2009 * - routing control
2010 * - FC port did
2011 * - FC port sid
2012 * - FC header type
2013 * - frame control
2014 * - parameter or relative offset
Robert Love1a7b75a2009-11-03 11:45:47 -08002015 */
Robert Love3a3b42b2009-11-03 11:47:39 -08002016static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
Robert Love1a7b75a2009-11-03 11:45:47 -08002017 struct fc_frame *fp,
2018 void (*resp)(struct fc_seq *,
2019 struct fc_frame *fp,
2020 void *arg),
2021 void (*destructor)(struct fc_seq *,
2022 void *),
2023 void *arg, u32 timer_msec)
2024{
2025 struct fc_exch *ep;
2026 struct fc_seq *sp = NULL;
2027 struct fc_frame_header *fh;
Yi Zou3ee17f52011-08-25 12:41:03 -07002028 struct fc_fcp_pkt *fsp = NULL;
Robert Love1a7b75a2009-11-03 11:45:47 -08002029 int rc = 1;
2030
Robert Love3a3b42b2009-11-03 11:47:39 -08002031 ep = fc_exch_alloc(lport, fp);
Robert Love1a7b75a2009-11-03 11:45:47 -08002032 if (!ep) {
2033 fc_frame_free(fp);
2034 return NULL;
2035 }
2036 ep->esb_stat |= ESB_ST_SEQ_INIT;
2037 fh = fc_frame_header_get(fp);
2038 fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
2039 ep->resp = resp;
2040 ep->destructor = destructor;
2041 ep->arg = arg;
2042 ep->r_a_tov = FC_DEF_R_A_TOV;
Robert Love3a3b42b2009-11-03 11:47:39 -08002043 ep->lp = lport;
Robert Love1a7b75a2009-11-03 11:45:47 -08002044 sp = &ep->seq;
2045
2046 ep->fh_type = fh->fh_type; /* save for possbile timeout handling */
2047 ep->f_ctl = ntoh24(fh->fh_f_ctl);
2048 fc_exch_setup_hdr(ep, fp, ep->f_ctl);
2049 sp->cnt++;
2050
Yi Zou3ee17f52011-08-25 12:41:03 -07002051 if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) {
2052 fsp = fr_fsp(fp);
Robert Love1a7b75a2009-11-03 11:45:47 -08002053 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
Yi Zou3ee17f52011-08-25 12:41:03 -07002054 }
Robert Love1a7b75a2009-11-03 11:45:47 -08002055
Robert Love3a3b42b2009-11-03 11:47:39 -08002056 if (unlikely(lport->tt.frame_send(lport, fp)))
Robert Love1a7b75a2009-11-03 11:45:47 -08002057 goto err;
2058
2059 if (timer_msec)
2060 fc_exch_timer_set_locked(ep, timer_msec);
2061 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */
2062
2063 if (ep->f_ctl & FC_FC_SEQ_INIT)
2064 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
2065 spin_unlock_bh(&ep->ex_lock);
2066 return sp;
2067err:
Yi Zou3ee17f52011-08-25 12:41:03 -07002068 if (fsp)
2069 fc_fcp_ddp_done(fsp);
Robert Love1a7b75a2009-11-03 11:45:47 -08002070 rc = fc_exch_done_locked(ep);
2071 spin_unlock_bh(&ep->ex_lock);
2072 if (!rc)
2073 fc_exch_delete(ep);
2074 return NULL;
2075}
2076
Robert Love3a3b42b2009-11-03 11:47:39 -08002077/**
2078 * fc_exch_rrq() - Send an ELS RRQ (Reinstate Recovery Qualifier) command
2079 * @ep: The exchange to send the RRQ on
2080 *
Robert Love42e9a922008-12-09 15:10:17 -08002081 * This tells the remote port to stop blocking the use of
2082 * the exchange and the seq_cnt range.
2083 */
2084static void fc_exch_rrq(struct fc_exch *ep)
2085{
Robert Love3a3b42b2009-11-03 11:47:39 -08002086 struct fc_lport *lport;
Robert Love42e9a922008-12-09 15:10:17 -08002087 struct fc_els_rrq *rrq;
2088 struct fc_frame *fp;
Robert Love42e9a922008-12-09 15:10:17 -08002089 u32 did;
2090
Robert Love3a3b42b2009-11-03 11:47:39 -08002091 lport = ep->lp;
Robert Love42e9a922008-12-09 15:10:17 -08002092
Robert Love3a3b42b2009-11-03 11:47:39 -08002093 fp = fc_frame_alloc(lport, sizeof(*rrq));
Robert Love42e9a922008-12-09 15:10:17 -08002094 if (!fp)
Vasu Deva0cc1ec2009-07-28 17:33:37 -07002095 goto retry;
2096
Robert Love42e9a922008-12-09 15:10:17 -08002097 rrq = fc_frame_payload_get(fp, sizeof(*rrq));
2098 memset(rrq, 0, sizeof(*rrq));
2099 rrq->rrq_cmd = ELS_RRQ;
2100 hton24(rrq->rrq_s_id, ep->sid);
2101 rrq->rrq_ox_id = htons(ep->oxid);
2102 rrq->rrq_rx_id = htons(ep->rxid);
2103
2104 did = ep->did;
2105 if (ep->esb_stat & ESB_ST_RESP)
2106 did = ep->sid;
2107
2108 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did,
Robert Love7b2787e2010-05-07 15:18:41 -07002109 lport->port_id, FC_TYPE_ELS,
Robert Love42e9a922008-12-09 15:10:17 -08002110 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
2111
Robert Love3a3b42b2009-11-03 11:47:39 -08002112 if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep,
2113 lport->e_d_tov))
Vasu Deva0cc1ec2009-07-28 17:33:37 -07002114 return;
2115
2116retry:
2117 spin_lock_bh(&ep->ex_lock);
2118 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) {
2119 spin_unlock_bh(&ep->ex_lock);
2120 /* drop hold for rec qual */
2121 fc_exch_release(ep);
Robert Love42e9a922008-12-09 15:10:17 -08002122 return;
2123 }
Vasu Deva0cc1ec2009-07-28 17:33:37 -07002124 ep->esb_stat |= ESB_ST_REC_QUAL;
2125 fc_exch_timer_set_locked(ep, ep->r_a_tov);
2126 spin_unlock_bh(&ep->ex_lock);
Robert Love42e9a922008-12-09 15:10:17 -08002127}
2128
Robert Love3a3b42b2009-11-03 11:47:39 -08002129/**
2130 * fc_exch_els_rrq() - Handler for ELS RRQ (Reset Recovery Qualifier) requests
Joe Eykholt922611562010-07-20 15:21:12 -07002131 * @fp: The RRQ frame, not freed here.
Robert Love42e9a922008-12-09 15:10:17 -08002132 */
Joe Eykholt922611562010-07-20 15:21:12 -07002133static void fc_exch_els_rrq(struct fc_frame *fp)
Robert Love42e9a922008-12-09 15:10:17 -08002134{
Joe Eykholt922611562010-07-20 15:21:12 -07002135 struct fc_lport *lport;
Vasu Dev3f127ad2009-10-21 16:27:33 -07002136 struct fc_exch *ep = NULL; /* request or subject exchange */
Robert Love42e9a922008-12-09 15:10:17 -08002137 struct fc_els_rrq *rp;
2138 u32 sid;
2139 u16 xid;
2140 enum fc_els_rjt_explan explan;
2141
Joe Eykholt922611562010-07-20 15:21:12 -07002142 lport = fr_dev(fp);
Robert Love42e9a922008-12-09 15:10:17 -08002143 rp = fc_frame_payload_get(fp, sizeof(*rp));
2144 explan = ELS_EXPL_INV_LEN;
2145 if (!rp)
2146 goto reject;
2147
2148 /*
2149 * lookup subject exchange.
2150 */
Robert Love42e9a922008-12-09 15:10:17 -08002151 sid = ntoh24(rp->rrq_s_id); /* subject source */
Joe Eykholt922611562010-07-20 15:21:12 -07002152 xid = fc_host_port_id(lport->host) == sid ?
2153 ntohs(rp->rrq_ox_id) : ntohs(rp->rrq_rx_id);
2154 ep = fc_exch_lookup(lport, xid);
Robert Love42e9a922008-12-09 15:10:17 -08002155 explan = ELS_EXPL_OXID_RXID;
2156 if (!ep)
2157 goto reject;
2158 spin_lock_bh(&ep->ex_lock);
2159 if (ep->oxid != ntohs(rp->rrq_ox_id))
2160 goto unlock_reject;
2161 if (ep->rxid != ntohs(rp->rrq_rx_id) &&
2162 ep->rxid != FC_XID_UNKNOWN)
2163 goto unlock_reject;
2164 explan = ELS_EXPL_SID;
2165 if (ep->sid != sid)
2166 goto unlock_reject;
2167
2168 /*
2169 * Clear Recovery Qualifier state, and cancel timer if complete.
2170 */
2171 if (ep->esb_stat & ESB_ST_REC_QUAL) {
2172 ep->esb_stat &= ~ESB_ST_REC_QUAL;
2173 atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */
2174 }
Vasu Devb29a4f32012-07-06 10:40:10 -07002175 if (ep->esb_stat & ESB_ST_COMPLETE)
2176 fc_exch_timer_cancel(ep);
Robert Love42e9a922008-12-09 15:10:17 -08002177
2178 spin_unlock_bh(&ep->ex_lock);
2179
2180 /*
2181 * Send LS_ACC.
2182 */
Joe Eykholt922611562010-07-20 15:21:12 -07002183 fc_seq_ls_acc(fp);
Vasu Dev3f127ad2009-10-21 16:27:33 -07002184 goto out;
Robert Love42e9a922008-12-09 15:10:17 -08002185
2186unlock_reject:
2187 spin_unlock_bh(&ep->ex_lock);
Robert Love42e9a922008-12-09 15:10:17 -08002188reject:
Joe Eykholt922611562010-07-20 15:21:12 -07002189 fc_seq_ls_rjt(fp, ELS_RJT_LOGIC, explan);
Vasu Dev3f127ad2009-10-21 16:27:33 -07002190out:
Vasu Dev3f127ad2009-10-21 16:27:33 -07002191 if (ep)
2192 fc_exch_release(ep); /* drop hold from fc_exch_find */
Robert Love42e9a922008-12-09 15:10:17 -08002193}
2194
Robert Love3a3b42b2009-11-03 11:47:39 -08002195/**
Vasu Dev4e5fae72012-05-25 10:26:54 -07002196 * fc_exch_update_stats() - update exches stats to lport
2197 * @lport: The local port to update exchange manager stats
2198 */
2199void fc_exch_update_stats(struct fc_lport *lport)
2200{
2201 struct fc_host_statistics *st;
2202 struct fc_exch_mgr_anchor *ema;
2203 struct fc_exch_mgr *mp;
2204
2205 st = &lport->host_stats;
2206
2207 list_for_each_entry(ema, &lport->ema_list, ema_list) {
2208 mp = ema->mp;
2209 st->fc_no_free_exch += atomic_read(&mp->stats.no_free_exch);
2210 st->fc_no_free_exch_xid +=
2211 atomic_read(&mp->stats.no_free_exch_xid);
2212 st->fc_xid_not_found += atomic_read(&mp->stats.xid_not_found);
2213 st->fc_xid_busy += atomic_read(&mp->stats.xid_busy);
2214 st->fc_seq_not_found += atomic_read(&mp->stats.seq_not_found);
2215 st->fc_non_bls_resp += atomic_read(&mp->stats.non_bls_resp);
2216 }
2217}
2218EXPORT_SYMBOL(fc_exch_update_stats);
2219
2220/**
Robert Love3a3b42b2009-11-03 11:47:39 -08002221 * fc_exch_mgr_add() - Add an exchange manager to a local port's list of EMs
2222 * @lport: The local port to add the exchange manager to
2223 * @mp: The exchange manager to be added to the local port
2224 * @match: The match routine that indicates when this EM should be used
2225 */
Vasu Dev96316092009-07-29 17:05:00 -07002226struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
2227 struct fc_exch_mgr *mp,
2228 bool (*match)(struct fc_frame *))
2229{
2230 struct fc_exch_mgr_anchor *ema;
2231
2232 ema = kmalloc(sizeof(*ema), GFP_ATOMIC);
2233 if (!ema)
2234 return ema;
2235
2236 ema->mp = mp;
2237 ema->match = match;
2238 /* add EM anchor to EM anchors list */
2239 list_add_tail(&ema->ema_list, &lport->ema_list);
2240 kref_get(&mp->kref);
2241 return ema;
2242}
2243EXPORT_SYMBOL(fc_exch_mgr_add);
2244
Robert Love3a3b42b2009-11-03 11:47:39 -08002245/**
2246 * fc_exch_mgr_destroy() - Destroy an exchange manager
2247 * @kref: The reference to the EM to be destroyed
2248 */
Vasu Dev96316092009-07-29 17:05:00 -07002249static void fc_exch_mgr_destroy(struct kref *kref)
2250{
2251 struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
2252
Vasu Dev96316092009-07-29 17:05:00 -07002253 mempool_destroy(mp->ep_pool);
Vasu Deve4bc50b2009-08-25 13:58:47 -07002254 free_percpu(mp->pool);
Vasu Dev96316092009-07-29 17:05:00 -07002255 kfree(mp);
2256}
2257
Robert Love3a3b42b2009-11-03 11:47:39 -08002258/**
2259 * fc_exch_mgr_del() - Delete an EM from a local port's list
2260 * @ema: The exchange manager anchor identifying the EM to be deleted
2261 */
Vasu Dev96316092009-07-29 17:05:00 -07002262void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
2263{
2264 /* remove EM anchor from EM anchors list */
2265 list_del(&ema->ema_list);
2266 kref_put(&ema->mp->kref, fc_exch_mgr_destroy);
2267 kfree(ema);
2268}
2269EXPORT_SYMBOL(fc_exch_mgr_del);
2270
Chris Leech174e1eb2009-11-03 11:46:14 -08002271/**
Robert Love3a3b42b2009-11-03 11:47:39 -08002272 * fc_exch_mgr_list_clone() - Share all exchange manager objects
2273 * @src: Source lport to clone exchange managers from
2274 * @dst: New lport that takes references to all the exchange managers
Chris Leech174e1eb2009-11-03 11:46:14 -08002275 */
2276int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst)
2277{
2278 struct fc_exch_mgr_anchor *ema, *tmp;
2279
2280 list_for_each_entry(ema, &src->ema_list, ema_list) {
2281 if (!fc_exch_mgr_add(dst, ema->mp, ema->match))
2282 goto err;
2283 }
2284 return 0;
2285err:
2286 list_for_each_entry_safe(ema, tmp, &dst->ema_list, ema_list)
2287 fc_exch_mgr_del(ema);
2288 return -ENOMEM;
2289}
Vasu Dev72fa3962011-02-25 15:03:01 -08002290EXPORT_SYMBOL(fc_exch_mgr_list_clone);
Chris Leech174e1eb2009-11-03 11:46:14 -08002291
Robert Love3a3b42b2009-11-03 11:47:39 -08002292/**
2293 * fc_exch_mgr_alloc() - Allocate an exchange manager
2294 * @lport: The local port that the new EM will be associated with
2295 * @class: The default FC class for new exchanges
2296 * @min_xid: The minimum XID for exchanges from the new EM
2297 * @max_xid: The maximum XID for exchanges from the new EM
2298 * @match: The match routine for the new EM
2299 */
2300struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
Robert Love42e9a922008-12-09 15:10:17 -08002301 enum fc_class class,
Vasu Dev52ff8782009-07-29 17:05:10 -07002302 u16 min_xid, u16 max_xid,
2303 bool (*match)(struct fc_frame *))
Robert Love42e9a922008-12-09 15:10:17 -08002304{
2305 struct fc_exch_mgr *mp;
Vasu Deve4bc50b2009-08-25 13:58:47 -07002306 u16 pool_exch_range;
2307 size_t pool_size;
2308 unsigned int cpu;
2309 struct fc_exch_pool *pool;
Robert Love42e9a922008-12-09 15:10:17 -08002310
Vasu Deve4bc50b2009-08-25 13:58:47 -07002311 if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN ||
2312 (min_xid & fc_cpu_mask) != 0) {
Robert Love3a3b42b2009-11-03 11:47:39 -08002313 FC_LPORT_DBG(lport, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
Robert Love74147052009-06-10 15:31:10 -07002314 min_xid, max_xid);
Robert Love42e9a922008-12-09 15:10:17 -08002315 return NULL;
2316 }
2317
2318 /*
Vasu Devb2f00912009-08-25 13:58:53 -07002319 * allocate memory for EM
Robert Love42e9a922008-12-09 15:10:17 -08002320 */
Vasu Devb2f00912009-08-25 13:58:53 -07002321 mp = kzalloc(sizeof(struct fc_exch_mgr), GFP_ATOMIC);
Robert Love42e9a922008-12-09 15:10:17 -08002322 if (!mp)
2323 return NULL;
2324
2325 mp->class = class;
Robert Love42e9a922008-12-09 15:10:17 -08002326 /* adjust em exch xid range for offload */
2327 mp->min_xid = min_xid;
Steven Clark011a9002012-03-09 14:50:30 -08002328
2329 /* reduce range so per cpu pool fits into PCPU_MIN_UNIT_SIZE pool */
2330 pool_exch_range = (PCPU_MIN_UNIT_SIZE - sizeof(*pool)) /
2331 sizeof(struct fc_exch *);
2332 if ((max_xid - min_xid + 1) / (fc_cpu_mask + 1) > pool_exch_range) {
2333 mp->max_xid = pool_exch_range * (fc_cpu_mask + 1) +
2334 min_xid - 1;
2335 } else {
2336 mp->max_xid = max_xid;
2337 pool_exch_range = (mp->max_xid - mp->min_xid + 1) /
2338 (fc_cpu_mask + 1);
2339 }
Robert Love42e9a922008-12-09 15:10:17 -08002340
2341 mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep);
2342 if (!mp->ep_pool)
2343 goto free_mp;
2344
Vasu Deve4bc50b2009-08-25 13:58:47 -07002345 /*
2346 * Setup per cpu exch pool with entire exchange id range equally
2347 * divided across all cpus. The exch pointers array memory is
2348 * allocated for exch range per pool.
2349 */
Vasu Deve4bc50b2009-08-25 13:58:47 -07002350 mp->pool_max_index = pool_exch_range - 1;
2351
2352 /*
2353 * Allocate and initialize per cpu exch pool
2354 */
2355 pool_size = sizeof(*pool) + pool_exch_range * sizeof(struct fc_exch *);
2356 mp->pool = __alloc_percpu(pool_size, __alignof__(struct fc_exch_pool));
2357 if (!mp->pool)
2358 goto free_mempool;
2359 for_each_possible_cpu(cpu) {
2360 pool = per_cpu_ptr(mp->pool, cpu);
Vasu Devb6e3c842011-10-28 11:34:17 -07002361 pool->next_index = 0;
Hillf Danton2034c192010-11-30 16:18:17 -08002362 pool->left = FC_XID_UNKNOWN;
2363 pool->right = FC_XID_UNKNOWN;
Vasu Deve4bc50b2009-08-25 13:58:47 -07002364 spin_lock_init(&pool->lock);
2365 INIT_LIST_HEAD(&pool->ex_list);
2366 }
2367
Vasu Dev52ff8782009-07-29 17:05:10 -07002368 kref_init(&mp->kref);
Robert Love3a3b42b2009-11-03 11:47:39 -08002369 if (!fc_exch_mgr_add(lport, mp, match)) {
Vasu Deve4bc50b2009-08-25 13:58:47 -07002370 free_percpu(mp->pool);
2371 goto free_mempool;
Vasu Dev52ff8782009-07-29 17:05:10 -07002372 }
2373
2374 /*
2375 * Above kref_init() sets mp->kref to 1 and then
2376 * call to fc_exch_mgr_add incremented mp->kref again,
2377 * so adjust that extra increment.
2378 */
2379 kref_put(&mp->kref, fc_exch_mgr_destroy);
Robert Love42e9a922008-12-09 15:10:17 -08002380 return mp;
2381
Vasu Deve4bc50b2009-08-25 13:58:47 -07002382free_mempool:
2383 mempool_destroy(mp->ep_pool);
Robert Love42e9a922008-12-09 15:10:17 -08002384free_mp:
2385 kfree(mp);
2386 return NULL;
2387}
2388EXPORT_SYMBOL(fc_exch_mgr_alloc);
2389
Robert Love3a3b42b2009-11-03 11:47:39 -08002390/**
2391 * fc_exch_mgr_free() - Free all exchange managers on a local port
2392 * @lport: The local port whose EMs are to be freed
2393 */
Vasu Dev52ff8782009-07-29 17:05:10 -07002394void fc_exch_mgr_free(struct fc_lport *lport)
Robert Love42e9a922008-12-09 15:10:17 -08002395{
Vasu Dev52ff8782009-07-29 17:05:10 -07002396 struct fc_exch_mgr_anchor *ema, *next;
2397
Vasu Dev4ae1e192009-11-03 11:50:10 -08002398 flush_workqueue(fc_exch_workqueue);
Vasu Dev52ff8782009-07-29 17:05:10 -07002399 list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list)
2400 fc_exch_mgr_del(ema);
Robert Love42e9a922008-12-09 15:10:17 -08002401}
2402EXPORT_SYMBOL(fc_exch_mgr_free);
2403
Robert Love3a3b42b2009-11-03 11:47:39 -08002404/**
Kiran Patil6c8cc1c2011-01-28 16:04:39 -08002405 * fc_find_ema() - Lookup and return appropriate Exchange Manager Anchor depending
2406 * upon 'xid'.
2407 * @f_ctl: f_ctl
2408 * @lport: The local port the frame was received on
2409 * @fh: The received frame header
2410 */
2411static struct fc_exch_mgr_anchor *fc_find_ema(u32 f_ctl,
2412 struct fc_lport *lport,
2413 struct fc_frame_header *fh)
2414{
2415 struct fc_exch_mgr_anchor *ema;
2416 u16 xid;
2417
2418 if (f_ctl & FC_FC_EX_CTX)
2419 xid = ntohs(fh->fh_ox_id);
2420 else {
2421 xid = ntohs(fh->fh_rx_id);
2422 if (xid == FC_XID_UNKNOWN)
2423 return list_entry(lport->ema_list.prev,
2424 typeof(*ema), ema_list);
2425 }
2426
2427 list_for_each_entry(ema, &lport->ema_list, ema_list) {
2428 if ((xid >= ema->mp->min_xid) &&
2429 (xid <= ema->mp->max_xid))
2430 return ema;
2431 }
2432 return NULL;
2433}
2434/**
Robert Love3a3b42b2009-11-03 11:47:39 -08002435 * fc_exch_recv() - Handler for received frames
2436 * @lport: The local port the frame was received on
Kiran Patil6c8cc1c2011-01-28 16:04:39 -08002437 * @fp: The received frame
Robert Love42e9a922008-12-09 15:10:17 -08002438 */
Robert Love3a3b42b2009-11-03 11:47:39 -08002439void fc_exch_recv(struct fc_lport *lport, struct fc_frame *fp)
Robert Love42e9a922008-12-09 15:10:17 -08002440{
2441 struct fc_frame_header *fh = fc_frame_header_get(fp);
Vasu Dev52ff8782009-07-29 17:05:10 -07002442 struct fc_exch_mgr_anchor *ema;
Kiran Patil6c8cc1c2011-01-28 16:04:39 -08002443 u32 f_ctl;
Robert Love42e9a922008-12-09 15:10:17 -08002444
2445 /* lport lock ? */
Robert Love3a3b42b2009-11-03 11:47:39 -08002446 if (!lport || lport->state == LPORT_ST_DISABLED) {
2447 FC_LPORT_DBG(lport, "Receiving frames for an lport that "
Robert Love74147052009-06-10 15:31:10 -07002448 "has not been initialized correctly\n");
Robert Love42e9a922008-12-09 15:10:17 -08002449 fc_frame_free(fp);
2450 return;
2451 }
2452
Vasu Dev52ff8782009-07-29 17:05:10 -07002453 f_ctl = ntoh24(fh->fh_f_ctl);
Kiran Patil6c8cc1c2011-01-28 16:04:39 -08002454 ema = fc_find_ema(f_ctl, lport, fh);
2455 if (!ema) {
2456 FC_LPORT_DBG(lport, "Unable to find Exchange Manager Anchor,"
2457 "fc_ctl <0x%x>, xid <0x%x>\n",
2458 f_ctl,
2459 (f_ctl & FC_FC_EX_CTX) ?
2460 ntohs(fh->fh_ox_id) :
2461 ntohs(fh->fh_rx_id));
2462 fc_frame_free(fp);
2463 return;
2464 }
Vasu Dev52ff8782009-07-29 17:05:10 -07002465
Robert Love42e9a922008-12-09 15:10:17 -08002466 /*
2467 * If frame is marked invalid, just drop it.
2468 */
Robert Love42e9a922008-12-09 15:10:17 -08002469 switch (fr_eof(fp)) {
2470 case FC_EOF_T:
2471 if (f_ctl & FC_FC_END_SEQ)
2472 skb_trim(fp_skb(fp), fr_len(fp) - FC_FC_FILL(f_ctl));
2473 /* fall through */
2474 case FC_EOF_N:
2475 if (fh->fh_type == FC_TYPE_BLS)
Vasu Dev52ff8782009-07-29 17:05:10 -07002476 fc_exch_recv_bls(ema->mp, fp);
Robert Love42e9a922008-12-09 15:10:17 -08002477 else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) ==
2478 FC_FC_EX_CTX)
Vasu Dev52ff8782009-07-29 17:05:10 -07002479 fc_exch_recv_seq_resp(ema->mp, fp);
Robert Love42e9a922008-12-09 15:10:17 -08002480 else if (f_ctl & FC_FC_SEQ_CTX)
Vasu Dev52ff8782009-07-29 17:05:10 -07002481 fc_exch_recv_resp(ema->mp, fp);
Joe Eykholt922611562010-07-20 15:21:12 -07002482 else /* no EX_CTX and no SEQ_CTX */
Robert Love3a3b42b2009-11-03 11:47:39 -08002483 fc_exch_recv_req(lport, ema->mp, fp);
Robert Love42e9a922008-12-09 15:10:17 -08002484 break;
2485 default:
Robert Love3a3b42b2009-11-03 11:47:39 -08002486 FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)",
2487 fr_eof(fp));
Robert Love42e9a922008-12-09 15:10:17 -08002488 fc_frame_free(fp);
Robert Love42e9a922008-12-09 15:10:17 -08002489 }
2490}
2491EXPORT_SYMBOL(fc_exch_recv);
2492
Robert Love3a3b42b2009-11-03 11:47:39 -08002493/**
2494 * fc_exch_init() - Initialize the exchange layer for a local port
2495 * @lport: The local port to initialize the exchange layer for
2496 */
2497int fc_exch_init(struct fc_lport *lport)
Robert Love42e9a922008-12-09 15:10:17 -08002498{
Robert Love3a3b42b2009-11-03 11:47:39 -08002499 if (!lport->tt.seq_start_next)
2500 lport->tt.seq_start_next = fc_seq_start_next;
Robert Love42e9a922008-12-09 15:10:17 -08002501
Joe Eykholt1a5c2d72011-01-28 16:04:08 -08002502 if (!lport->tt.seq_set_resp)
2503 lport->tt.seq_set_resp = fc_seq_set_resp;
2504
Robert Love3a3b42b2009-11-03 11:47:39 -08002505 if (!lport->tt.exch_seq_send)
2506 lport->tt.exch_seq_send = fc_exch_seq_send;
Robert Love42e9a922008-12-09 15:10:17 -08002507
Robert Love3a3b42b2009-11-03 11:47:39 -08002508 if (!lport->tt.seq_send)
2509 lport->tt.seq_send = fc_seq_send;
Robert Love42e9a922008-12-09 15:10:17 -08002510
Robert Love3a3b42b2009-11-03 11:47:39 -08002511 if (!lport->tt.seq_els_rsp_send)
2512 lport->tt.seq_els_rsp_send = fc_seq_els_rsp_send;
Robert Love42e9a922008-12-09 15:10:17 -08002513
Robert Love3a3b42b2009-11-03 11:47:39 -08002514 if (!lport->tt.exch_done)
2515 lport->tt.exch_done = fc_exch_done;
Robert Love42e9a922008-12-09 15:10:17 -08002516
Robert Love3a3b42b2009-11-03 11:47:39 -08002517 if (!lport->tt.exch_mgr_reset)
2518 lport->tt.exch_mgr_reset = fc_exch_mgr_reset;
Robert Love42e9a922008-12-09 15:10:17 -08002519
Robert Love3a3b42b2009-11-03 11:47:39 -08002520 if (!lport->tt.seq_exch_abort)
2521 lport->tt.seq_exch_abort = fc_seq_exch_abort;
Robert Love42e9a922008-12-09 15:10:17 -08002522
Joe Eykholt239e8102010-07-20 15:21:07 -07002523 if (!lport->tt.seq_assign)
2524 lport->tt.seq_assign = fc_seq_assign;
2525
Joe Eykholt62bdb642011-01-28 16:04:34 -08002526 if (!lport->tt.seq_release)
2527 lport->tt.seq_release = fc_seq_release;
2528
Vasu Dev89f19a52009-10-21 16:27:28 -07002529 return 0;
2530}
2531EXPORT_SYMBOL(fc_exch_init);
2532
2533/**
2534 * fc_setup_exch_mgr() - Setup an exchange manager
2535 */
Randy Dunlap55204902011-01-28 16:03:57 -08002536int fc_setup_exch_mgr(void)
Vasu Dev89f19a52009-10-21 16:27:28 -07002537{
2538 fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
2539 0, SLAB_HWCACHE_ALIGN, NULL);
2540 if (!fc_em_cachep)
2541 return -ENOMEM;
2542
Vasu Deve4bc50b2009-08-25 13:58:47 -07002543 /*
2544 * Initialize fc_cpu_mask and fc_cpu_order. The
2545 * fc_cpu_mask is set for nr_cpu_ids rounded up
2546 * to order of 2's * power and order is stored
2547 * in fc_cpu_order as this is later required in
2548 * mapping between an exch id and exch array index
2549 * in per cpu exch pool.
2550 *
2551 * This round up is required to align fc_cpu_mask
2552 * to exchange id's lower bits such that all incoming
2553 * frames of an exchange gets delivered to the same
2554 * cpu on which exchange originated by simple bitwise
2555 * AND operation between fc_cpu_mask and exchange id.
2556 */
Bart Van Asschea84ea8c2013-08-14 15:33:35 +00002557 fc_cpu_order = ilog2(roundup_pow_of_two(nr_cpu_ids));
2558 fc_cpu_mask = (1 << fc_cpu_order) - 1;
Vasu Deve4bc50b2009-08-25 13:58:47 -07002559
Vasu Dev4ae1e192009-11-03 11:50:10 -08002560 fc_exch_workqueue = create_singlethread_workqueue("fc_exch_workqueue");
2561 if (!fc_exch_workqueue)
Hillf Danton6f06e3a2011-07-27 15:10:34 -07002562 goto err;
Robert Love42e9a922008-12-09 15:10:17 -08002563 return 0;
Hillf Danton6f06e3a2011-07-27 15:10:34 -07002564err:
2565 kmem_cache_destroy(fc_em_cachep);
2566 return -ENOMEM;
Robert Love42e9a922008-12-09 15:10:17 -08002567}
Robert Love42e9a922008-12-09 15:10:17 -08002568
Robert Love3a3b42b2009-11-03 11:47:39 -08002569/**
2570 * fc_destroy_exch_mgr() - Destroy an exchange manager
2571 */
Randy Dunlap55204902011-01-28 16:03:57 -08002572void fc_destroy_exch_mgr(void)
Robert Love42e9a922008-12-09 15:10:17 -08002573{
Vasu Dev4ae1e192009-11-03 11:50:10 -08002574 destroy_workqueue(fc_exch_workqueue);
Robert Love42e9a922008-12-09 15:10:17 -08002575 kmem_cache_destroy(fc_em_cachep);
2576}