1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/timer.h>
15#include <linux/slab.h>
16#include <linux/err.h>
17#include <linux/export.h>
18#include <linux/log2.h>
19
20#include <scsi/fc/fc_fc2.h>
21
22#include <scsi/libfc.h>
23#include <scsi/fc_encode.h>
24
25#include "fc_libfc.h"
26
27u16 fc_cpu_mask;
28EXPORT_SYMBOL(fc_cpu_mask);
29static u16 fc_cpu_order;
30static struct kmem_cache *fc_em_cachep;
31static struct workqueue_struct *fc_exch_workqueue;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59struct fc_exch_pool {
60 spinlock_t lock;
61 struct list_head ex_list;
62 u16 next_index;
63 u16 total_exches;
64
65 u16 left;
66 u16 right;
67} ____cacheline_aligned_in_smp;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84struct fc_exch_mgr {
85 struct fc_exch_pool __percpu *pool;
86 mempool_t *ep_pool;
87 struct fc_lport *lport;
88 enum fc_class class;
89 struct kref kref;
90 u16 min_xid;
91 u16 max_xid;
92 u16 pool_max_index;
93
94 struct {
95 atomic_t no_free_exch;
96 atomic_t no_free_exch_xid;
97 atomic_t xid_not_found;
98 atomic_t xid_busy;
99 atomic_t seq_not_found;
100 atomic_t non_bls_resp;
101 } stats;
102};
103
104
105
106
107
108
109
110
111
112
113
114
115
116struct fc_exch_mgr_anchor {
117 struct list_head ema_list;
118 struct fc_exch_mgr *mp;
119 bool (*match)(struct fc_frame *);
120};
121
122static void fc_exch_rrq(struct fc_exch *);
123static void fc_seq_ls_acc(struct fc_frame *);
124static void fc_seq_ls_rjt(struct fc_frame *, enum fc_els_rjt_reason,
125 enum fc_els_rjt_explan);
126static void fc_exch_els_rec(struct fc_frame *);
127static void fc_exch_els_rrq(struct fc_frame *);
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211static char *fc_exch_rctl_names[] = FC_RCTL_NAMES_INIT;
212
213
214
215
216
217
218
219
220
221
222static inline const char *fc_exch_name_lookup(unsigned int op, char **table,
223 unsigned int max_index)
224{
225 const char *name = NULL;
226
227 if (op < max_index)
228 name = table[op];
229 if (!name)
230 name = "unknown";
231 return name;
232}
233
234
235
236
237
238static const char *fc_exch_rctl_name(unsigned int op)
239{
240 return fc_exch_name_lookup(op, fc_exch_rctl_names,
241 ARRAY_SIZE(fc_exch_rctl_names));
242}
243
244
245
246
247
248static inline void fc_exch_hold(struct fc_exch *ep)
249{
250 atomic_inc(&ep->ex_refcnt);
251}
252
253
254
255
256
257
258
259
260
261
262
263static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp,
264 u32 f_ctl)
265{
266 struct fc_frame_header *fh = fc_frame_header_get(fp);
267 u16 fill;
268
269 fr_sof(fp) = ep->class;
270 if (ep->seq.cnt)
271 fr_sof(fp) = fc_sof_normal(ep->class);
272
273 if (f_ctl & FC_FC_END_SEQ) {
274 fr_eof(fp) = FC_EOF_T;
275 if (fc_sof_needs_ack(ep->class))
276 fr_eof(fp) = FC_EOF_N;
277
278
279
280
281
282
283
284
285
286 fill = fr_len(fp) & 3;
287 if (fill) {
288 fill = 4 - fill;
289
290 skb_put(fp_skb(fp), fill);
291 hton24(fh->fh_f_ctl, f_ctl | fill);
292 }
293 } else {
294 WARN_ON(fr_len(fp) % 4 != 0);
295 fr_eof(fp) = FC_EOF_N;
296 }
297
298
299 fh->fh_ox_id = htons(ep->oxid);
300 fh->fh_rx_id = htons(ep->rxid);
301 fh->fh_seq_id = ep->seq.id;
302 fh->fh_seq_cnt = htons(ep->seq.cnt);
303}
304
305
306
307
308
309
310
311
312static void fc_exch_release(struct fc_exch *ep)
313{
314 struct fc_exch_mgr *mp;
315
316 if (atomic_dec_and_test(&ep->ex_refcnt)) {
317 mp = ep->em;
318 if (ep->destructor)
319 ep->destructor(&ep->seq, ep->arg);
320 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE));
321 mempool_free(ep, mp->ep_pool);
322 }
323}
324
325
326
327
328
329static inline void fc_exch_timer_cancel(struct fc_exch *ep)
330{
331 if (cancel_delayed_work(&ep->timeout_work)) {
332 FC_EXCH_DBG(ep, "Exchange timer canceled\n");
333 atomic_dec(&ep->ex_refcnt);
334 }
335}
336
337
338
339
340
341
342
343
344
345
346static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
347 unsigned int timer_msec)
348{
349 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
350 return;
351
352 FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec);
353
354 fc_exch_hold(ep);
355 if (!queue_delayed_work(fc_exch_workqueue, &ep->timeout_work,
356 msecs_to_jiffies(timer_msec))) {
357 FC_EXCH_DBG(ep, "Exchange already queued\n");
358 fc_exch_release(ep);
359 }
360}
361
362
363
364
365
366
367static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec)
368{
369 spin_lock_bh(&ep->ex_lock);
370 fc_exch_timer_set_locked(ep, timer_msec);
371 spin_unlock_bh(&ep->ex_lock);
372}
373
374
375
376
377
378
379
380static int fc_exch_done_locked(struct fc_exch *ep)
381{
382 int rc = 1;
383
384
385
386
387
388
389
390 if (ep->state & FC_EX_DONE)
391 return rc;
392 ep->esb_stat |= ESB_ST_COMPLETE;
393
394 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
395 ep->state |= FC_EX_DONE;
396 fc_exch_timer_cancel(ep);
397 rc = 0;
398 }
399 return rc;
400}
401
402static struct fc_exch fc_quarantine_exch;
403
404
405
406
407
408
409
410
411
412
413static inline struct fc_exch *fc_exch_ptr_get(struct fc_exch_pool *pool,
414 u16 index)
415{
416 struct fc_exch **exches = (struct fc_exch **)(pool + 1);
417 return exches[index];
418}
419
420
421
422
423
424
425
426static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
427 struct fc_exch *ep)
428{
429 ((struct fc_exch **)(pool + 1))[index] = ep;
430}
431
432
433
434
435
436static void fc_exch_delete(struct fc_exch *ep)
437{
438 struct fc_exch_pool *pool;
439 u16 index;
440
441 pool = ep->pool;
442 spin_lock_bh(&pool->lock);
443 WARN_ON(pool->total_exches <= 0);
444 pool->total_exches--;
445
446
447 index = (ep->xid - ep->em->min_xid) >> fc_cpu_order;
448 if (!(ep->state & FC_EX_QUARANTINE)) {
449 if (pool->left == FC_XID_UNKNOWN)
450 pool->left = index;
451 else if (pool->right == FC_XID_UNKNOWN)
452 pool->right = index;
453 else
454 pool->next_index = index;
455 fc_exch_ptr_set(pool, index, NULL);
456 } else {
457 fc_exch_ptr_set(pool, index, &fc_quarantine_exch);
458 }
459 list_del(&ep->ex_list);
460 spin_unlock_bh(&pool->lock);
461 fc_exch_release(ep);
462}
463
464static int fc_seq_send_locked(struct fc_lport *lport, struct fc_seq *sp,
465 struct fc_frame *fp)
466{
467 struct fc_exch *ep;
468 struct fc_frame_header *fh = fc_frame_header_get(fp);
469 int error = -ENXIO;
470 u32 f_ctl;
471 u8 fh_type = fh->fh_type;
472
473 ep = fc_seq_exch(sp);
474
475 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL)) {
476 fc_frame_free(fp);
477 goto out;
478 }
479
480 WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT));
481
482 f_ctl = ntoh24(fh->fh_f_ctl);
483 fc_exch_setup_hdr(ep, fp, f_ctl);
484 fr_encaps(fp) = ep->encaps;
485
486
487
488
489
490
491 if (fr_max_payload(fp))
492 sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
493 fr_max_payload(fp));
494 else
495 sp->cnt++;
496
497
498
499
500 error = lport->tt.frame_send(lport, fp);
501
502 if (fh_type == FC_TYPE_BLS)
503 goto out;
504
505
506
507
508
509
510 ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;
511 if (f_ctl & FC_FC_SEQ_INIT)
512 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
513out:
514 return error;
515}
516
517
518
519
520
521
522
523
524
525
526int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, struct fc_frame *fp)
527{
528 struct fc_exch *ep;
529 int error;
530 ep = fc_seq_exch(sp);
531 spin_lock_bh(&ep->ex_lock);
532 error = fc_seq_send_locked(lport, sp, fp);
533 spin_unlock_bh(&ep->ex_lock);
534 return error;
535}
536EXPORT_SYMBOL(fc_seq_send);
537
538
539
540
541
542
543
544
545
546
547static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
548{
549 struct fc_seq *sp;
550
551 sp = &ep->seq;
552 sp->ssb_stat = 0;
553 sp->cnt = 0;
554 sp->id = seq_id;
555 return sp;
556}
557
558
559
560
561
562
563static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
564{
565 struct fc_exch *ep = fc_seq_exch(sp);
566
567 sp = fc_seq_alloc(ep, ep->seq_id++);
568 FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
569 ep->f_ctl, sp->id);
570 return sp;
571}
572
573
574
575
576
577
578struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
579{
580 struct fc_exch *ep = fc_seq_exch(sp);
581
582 spin_lock_bh(&ep->ex_lock);
583 sp = fc_seq_start_next_locked(sp);
584 spin_unlock_bh(&ep->ex_lock);
585
586 return sp;
587}
588EXPORT_SYMBOL(fc_seq_start_next);
589
590
591
592
593
594
595void fc_seq_set_resp(struct fc_seq *sp,
596 void (*resp)(struct fc_seq *, struct fc_frame *, void *),
597 void *arg)
598{
599 struct fc_exch *ep = fc_seq_exch(sp);
600 DEFINE_WAIT(wait);
601
602 spin_lock_bh(&ep->ex_lock);
603 while (ep->resp_active && ep->resp_task != current) {
604 prepare_to_wait(&ep->resp_wq, &wait, TASK_UNINTERRUPTIBLE);
605 spin_unlock_bh(&ep->ex_lock);
606
607 schedule();
608
609 spin_lock_bh(&ep->ex_lock);
610 }
611 finish_wait(&ep->resp_wq, &wait);
612 ep->resp = resp;
613 ep->arg = arg;
614 spin_unlock_bh(&ep->ex_lock);
615}
616EXPORT_SYMBOL(fc_seq_set_resp);
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634static int fc_exch_abort_locked(struct fc_exch *ep,
635 unsigned int timer_msec)
636{
637 struct fc_seq *sp;
638 struct fc_frame *fp;
639 int error;
640
641 FC_EXCH_DBG(ep, "exch: abort, time %d msecs\n", timer_msec);
642 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) ||
643 ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) {
644 FC_EXCH_DBG(ep, "exch: already completed esb %x state %x\n",
645 ep->esb_stat, ep->state);
646 return -ENXIO;
647 }
648
649
650
651
652 sp = fc_seq_start_next_locked(&ep->seq);
653 if (!sp)
654 return -ENOMEM;
655
656 if (timer_msec)
657 fc_exch_timer_set_locked(ep, timer_msec);
658
659 if (ep->sid) {
660
661
662
663 fp = fc_frame_alloc(ep->lp, 0);
664 if (fp) {
665 ep->esb_stat |= ESB_ST_SEQ_INIT;
666 fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
667 FC_TYPE_BLS, FC_FC_END_SEQ |
668 FC_FC_SEQ_INIT, 0);
669 error = fc_seq_send_locked(ep->lp, sp, fp);
670 } else {
671 error = -ENOBUFS;
672 }
673 } else {
674
675
676
677
678 error = 0;
679 }
680 ep->esb_stat |= ESB_ST_ABNORMAL;
681 return error;
682}
683
684
685
686
687
688
689
690
691
692
693int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec)
694{
695 struct fc_exch *ep;
696 int error;
697
698 ep = fc_seq_exch(req_sp);
699 spin_lock_bh(&ep->ex_lock);
700 error = fc_exch_abort_locked(ep, timer_msec);
701 spin_unlock_bh(&ep->ex_lock);
702 return error;
703}
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730static bool fc_invoke_resp(struct fc_exch *ep, struct fc_seq *sp,
731 struct fc_frame *fp)
732{
733 void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
734 void *arg;
735 bool res = false;
736
737 spin_lock_bh(&ep->ex_lock);
738 ep->resp_active++;
739 if (ep->resp_task != current)
740 ep->resp_task = !ep->resp_task ? current : NULL;
741 resp = ep->resp;
742 arg = ep->arg;
743 spin_unlock_bh(&ep->ex_lock);
744
745 if (resp) {
746 resp(sp, fp, arg);
747 res = true;
748 }
749
750 spin_lock_bh(&ep->ex_lock);
751 if (--ep->resp_active == 0)
752 ep->resp_task = NULL;
753 spin_unlock_bh(&ep->ex_lock);
754
755 if (ep->resp_active == 0)
756 wake_up(&ep->resp_wq);
757
758 return res;
759}
760
761
762
763
764
765static void fc_exch_timeout(struct work_struct *work)
766{
767 struct fc_exch *ep = container_of(work, struct fc_exch,
768 timeout_work.work);
769 struct fc_seq *sp = &ep->seq;
770 u32 e_stat;
771 int rc = 1;
772
773 FC_EXCH_DBG(ep, "Exchange timed out state %x\n", ep->state);
774
775 spin_lock_bh(&ep->ex_lock);
776 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
777 goto unlock;
778
779 e_stat = ep->esb_stat;
780 if (e_stat & ESB_ST_COMPLETE) {
781 ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL;
782 spin_unlock_bh(&ep->ex_lock);
783 if (e_stat & ESB_ST_REC_QUAL)
784 fc_exch_rrq(ep);
785 goto done;
786 } else {
787 if (e_stat & ESB_ST_ABNORMAL)
788 rc = fc_exch_done_locked(ep);
789 spin_unlock_bh(&ep->ex_lock);
790 if (!rc)
791 fc_exch_delete(ep);
792 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_TIMEOUT));
793 fc_seq_set_resp(sp, NULL, ep->arg);
794 fc_seq_exch_abort(sp, 2 * ep->r_a_tov);
795 goto done;
796 }
797unlock:
798 spin_unlock_bh(&ep->ex_lock);
799done:
800
801
802
803 fc_exch_release(ep);
804}
805
806
807
808
809
810
811
812
813static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
814 struct fc_exch_mgr *mp)
815{
816 struct fc_exch *ep;
817 unsigned int cpu;
818 u16 index;
819 struct fc_exch_pool *pool;
820
821
822 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
823 if (!ep) {
824 atomic_inc(&mp->stats.no_free_exch);
825 goto out;
826 }
827 memset(ep, 0, sizeof(*ep));
828
829 cpu = get_cpu();
830 pool = per_cpu_ptr(mp->pool, cpu);
831 spin_lock_bh(&pool->lock);
832 put_cpu();
833
834
835 if (pool->left != FC_XID_UNKNOWN) {
836 if (!WARN_ON(fc_exch_ptr_get(pool, pool->left))) {
837 index = pool->left;
838 pool->left = FC_XID_UNKNOWN;
839 goto hit;
840 }
841 }
842 if (pool->right != FC_XID_UNKNOWN) {
843 if (!WARN_ON(fc_exch_ptr_get(pool, pool->right))) {
844 index = pool->right;
845 pool->right = FC_XID_UNKNOWN;
846 goto hit;
847 }
848 }
849
850 index = pool->next_index;
851
852 while (fc_exch_ptr_get(pool, index)) {
853 index = index == mp->pool_max_index ? 0 : index + 1;
854 if (index == pool->next_index)
855 goto err;
856 }
857 pool->next_index = index == mp->pool_max_index ? 0 : index + 1;
858hit:
859 fc_exch_hold(ep);
860 spin_lock_init(&ep->ex_lock);
861
862
863
864
865
866 spin_lock_bh(&ep->ex_lock);
867
868 fc_exch_ptr_set(pool, index, ep);
869 list_add_tail(&ep->ex_list, &pool->ex_list);
870 fc_seq_alloc(ep, ep->seq_id++);
871 pool->total_exches++;
872 spin_unlock_bh(&pool->lock);
873
874
875
876
877 ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid;
878 ep->em = mp;
879 ep->pool = pool;
880 ep->lp = lport;
881 ep->f_ctl = FC_FC_FIRST_SEQ;
882 ep->rxid = FC_XID_UNKNOWN;
883 ep->class = mp->class;
884 ep->resp_active = 0;
885 init_waitqueue_head(&ep->resp_wq);
886 INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout);
887out:
888 return ep;
889err:
890 spin_unlock_bh(&pool->lock);
891 atomic_inc(&mp->stats.no_free_exch_xid);
892 mempool_free(ep, mp->ep_pool);
893 return NULL;
894}
895
896
897
898
899
900
901
902
903
904
905
906
907static struct fc_exch *fc_exch_alloc(struct fc_lport *lport,
908 struct fc_frame *fp)
909{
910 struct fc_exch_mgr_anchor *ema;
911 struct fc_exch *ep;
912
913 list_for_each_entry(ema, &lport->ema_list, ema_list) {
914 if (!ema->match || ema->match(fp)) {
915 ep = fc_exch_em_alloc(lport, ema->mp);
916 if (ep)
917 return ep;
918 }
919 }
920 return NULL;
921}
922
923
924
925
926
927
928static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid)
929{
930 struct fc_lport *lport = mp->lport;
931 struct fc_exch_pool *pool;
932 struct fc_exch *ep = NULL;
933 u16 cpu = xid & fc_cpu_mask;
934
935 if (xid == FC_XID_UNKNOWN)
936 return NULL;
937
938 if (cpu >= nr_cpu_ids || !cpu_possible(cpu)) {
939 pr_err("host%u: lport %6.6x: xid %d invalid CPU %d\n:",
940 lport->host->host_no, lport->port_id, xid, cpu);
941 return NULL;
942 }
943
944 if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) {
945 pool = per_cpu_ptr(mp->pool, cpu);
946 spin_lock_bh(&pool->lock);
947 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order);
948 if (ep == &fc_quarantine_exch) {
949 FC_LPORT_DBG(lport, "xid %x quarantined\n", xid);
950 ep = NULL;
951 }
952 if (ep) {
953 WARN_ON(ep->xid != xid);
954 fc_exch_hold(ep);
955 }
956 spin_unlock_bh(&pool->lock);
957 }
958 return ep;
959}
960
961
962
963
964
965
966
967
968
969void fc_exch_done(struct fc_seq *sp)
970{
971 struct fc_exch *ep = fc_seq_exch(sp);
972 int rc;
973
974 spin_lock_bh(&ep->ex_lock);
975 rc = fc_exch_done_locked(ep);
976 spin_unlock_bh(&ep->ex_lock);
977
978 fc_seq_set_resp(sp, NULL, ep->arg);
979 if (!rc)
980 fc_exch_delete(ep);
981}
982EXPORT_SYMBOL(fc_exch_done);
983
984
985
986
987
988
989
990
991
992static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
993 struct fc_exch_mgr *mp,
994 struct fc_frame *fp)
995{
996 struct fc_exch *ep;
997 struct fc_frame_header *fh;
998
999 ep = fc_exch_alloc(lport, fp);
1000 if (ep) {
1001 ep->class = fc_frame_class(fp);
1002
1003
1004
1005
1006 ep->f_ctl |= FC_FC_EX_CTX;
1007 ep->f_ctl &= ~FC_FC_FIRST_SEQ;
1008 fh = fc_frame_header_get(fp);
1009 ep->sid = ntoh24(fh->fh_d_id);
1010 ep->did = ntoh24(fh->fh_s_id);
1011 ep->oid = ep->did;
1012
1013
1014
1015
1016
1017
1018 ep->rxid = ep->xid;
1019 ep->oxid = ntohs(fh->fh_ox_id);
1020 ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT;
1021 if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0)
1022 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
1023
1024 fc_exch_hold(ep);
1025 spin_unlock_bh(&ep->ex_lock);
1026 }
1027 return ep;
1028}
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
1041 struct fc_exch_mgr *mp,
1042 struct fc_frame *fp)
1043{
1044 struct fc_frame_header *fh = fc_frame_header_get(fp);
1045 struct fc_exch *ep = NULL;
1046 struct fc_seq *sp = NULL;
1047 enum fc_pf_rjt_reason reject = FC_RJT_NONE;
1048 u32 f_ctl;
1049 u16 xid;
1050
1051 f_ctl = ntoh24(fh->fh_f_ctl);
1052 WARN_ON((f_ctl & FC_FC_SEQ_CTX) != 0);
1053
1054
1055
1056
1057 if (f_ctl & FC_FC_EX_CTX) {
1058 xid = ntohs(fh->fh_ox_id);
1059 ep = fc_exch_find(mp, xid);
1060 if (!ep) {
1061 atomic_inc(&mp->stats.xid_not_found);
1062 reject = FC_RJT_OX_ID;
1063 goto out;
1064 }
1065 if (ep->rxid == FC_XID_UNKNOWN)
1066 ep->rxid = ntohs(fh->fh_rx_id);
1067 else if (ep->rxid != ntohs(fh->fh_rx_id)) {
1068 reject = FC_RJT_OX_ID;
1069 goto rel;
1070 }
1071 } else {
1072 xid = ntohs(fh->fh_rx_id);
1073
1074
1075
1076
1077
1078
1079 if (xid == 0 && fh->fh_r_ctl == FC_RCTL_ELS_REQ &&
1080 fc_frame_payload_op(fp) == ELS_TEST) {
1081 fh->fh_rx_id = htons(FC_XID_UNKNOWN);
1082 xid = FC_XID_UNKNOWN;
1083 }
1084
1085
1086
1087
1088 ep = fc_exch_find(mp, xid);
1089 if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
1090 if (ep) {
1091 atomic_inc(&mp->stats.xid_busy);
1092 reject = FC_RJT_RX_ID;
1093 goto rel;
1094 }
1095 ep = fc_exch_resp(lport, mp, fp);
1096 if (!ep) {
1097 reject = FC_RJT_EXCH_EST;
1098 goto out;
1099 }
1100 xid = ep->xid;
1101 } else if (!ep) {
1102 atomic_inc(&mp->stats.xid_not_found);
1103 reject = FC_RJT_RX_ID;
1104 goto out;
1105 }
1106 }
1107
1108 spin_lock_bh(&ep->ex_lock);
1109
1110
1111
1112
1113 if (fc_sof_is_init(fr_sof(fp))) {
1114 sp = &ep->seq;
1115 sp->ssb_stat |= SSB_ST_RESP;
1116 sp->id = fh->fh_seq_id;
1117 } else {
1118 sp = &ep->seq;
1119 if (sp->id != fh->fh_seq_id) {
1120 atomic_inc(&mp->stats.seq_not_found);
1121 if (f_ctl & FC_FC_END_SEQ) {
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136 sp->ssb_stat |= SSB_ST_RESP;
1137 sp->id = fh->fh_seq_id;
1138 } else {
1139 spin_unlock_bh(&ep->ex_lock);
1140
1141
1142 reject = FC_RJT_SEQ_ID;
1143 goto rel;
1144 }
1145 }
1146 }
1147 WARN_ON(ep != fc_seq_exch(sp));
1148
1149 if (f_ctl & FC_FC_SEQ_INIT)
1150 ep->esb_stat |= ESB_ST_SEQ_INIT;
1151 spin_unlock_bh(&ep->ex_lock);
1152
1153 fr_seq(fp) = sp;
1154out:
1155 return reject;
1156rel:
1157 fc_exch_done(&ep->seq);
1158 fc_exch_release(ep);
1159 return reject;
1160}
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170static struct fc_seq *fc_seq_lookup_orig(struct fc_exch_mgr *mp,
1171 struct fc_frame *fp)
1172{
1173 struct fc_frame_header *fh = fc_frame_header_get(fp);
1174 struct fc_exch *ep;
1175 struct fc_seq *sp = NULL;
1176 u32 f_ctl;
1177 u16 xid;
1178
1179 f_ctl = ntoh24(fh->fh_f_ctl);
1180 WARN_ON((f_ctl & FC_FC_SEQ_CTX) != FC_FC_SEQ_CTX);
1181 xid = ntohs((f_ctl & FC_FC_EX_CTX) ? fh->fh_ox_id : fh->fh_rx_id);
1182 ep = fc_exch_find(mp, xid);
1183 if (!ep)
1184 return NULL;
1185 if (ep->seq.id == fh->fh_seq_id) {
1186
1187
1188
1189 sp = &ep->seq;
1190 if ((f_ctl & FC_FC_EX_CTX) != 0 &&
1191 ep->rxid == FC_XID_UNKNOWN) {
1192 ep->rxid = ntohs(fh->fh_rx_id);
1193 }
1194 }
1195 fc_exch_release(ep);
1196 return sp;
1197}
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207static void fc_exch_set_addr(struct fc_exch *ep,
1208 u32 orig_id, u32 resp_id)
1209{
1210 ep->oid = orig_id;
1211 if (ep->esb_stat & ESB_ST_RESP) {
1212 ep->sid = resp_id;
1213 ep->did = orig_id;
1214 } else {
1215 ep->sid = orig_id;
1216 ep->did = resp_id;
1217 }
1218}
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229void fc_seq_els_rsp_send(struct fc_frame *fp, enum fc_els_cmd els_cmd,
1230 struct fc_seq_els_data *els_data)
1231{
1232 switch (els_cmd) {
1233 case ELS_LS_RJT:
1234 fc_seq_ls_rjt(fp, els_data->reason, els_data->explan);
1235 break;
1236 case ELS_LS_ACC:
1237 fc_seq_ls_acc(fp);
1238 break;
1239 case ELS_RRQ:
1240 fc_exch_els_rrq(fp);
1241 break;
1242 case ELS_REC:
1243 fc_exch_els_rec(fp);
1244 break;
1245 default:
1246 FC_LPORT_DBG(fr_dev(fp), "Invalid ELS CMD:%x\n", els_cmd);
1247 }
1248}
1249EXPORT_SYMBOL_GPL(fc_seq_els_rsp_send);
1250
1251
1252
1253
1254
1255
1256
1257
1258static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
1259 enum fc_rctl rctl, enum fc_fh_type fh_type)
1260{
1261 u32 f_ctl;
1262 struct fc_exch *ep = fc_seq_exch(sp);
1263
1264 f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
1265 f_ctl |= ep->f_ctl;
1266 fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0);
1267 fc_seq_send_locked(ep->lp, sp, fp);
1268}
1269
1270
1271
1272
1273
1274
1275
1276
1277static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
1278{
1279 struct fc_frame *fp;
1280 struct fc_frame_header *rx_fh;
1281 struct fc_frame_header *fh;
1282 struct fc_exch *ep = fc_seq_exch(sp);
1283 struct fc_lport *lport = ep->lp;
1284 unsigned int f_ctl;
1285
1286
1287
1288
1289 if (fc_sof_needs_ack(fr_sof(rx_fp))) {
1290 fp = fc_frame_alloc(lport, 0);
1291 if (!fp) {
1292 FC_EXCH_DBG(ep, "Drop ACK request, out of memory\n");
1293 return;
1294 }
1295
1296 fh = fc_frame_header_get(fp);
1297 fh->fh_r_ctl = FC_RCTL_ACK_1;
1298 fh->fh_type = FC_TYPE_BLS;
1299
1300
1301
1302
1303
1304
1305
1306
1307 rx_fh = fc_frame_header_get(rx_fp);
1308 f_ctl = ntoh24(rx_fh->fh_f_ctl);
1309 f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX |
1310 FC_FC_FIRST_SEQ | FC_FC_LAST_SEQ |
1311 FC_FC_END_SEQ | FC_FC_END_CONN | FC_FC_SEQ_INIT |
1312 FC_FC_RETX_SEQ | FC_FC_UNI_TX;
1313 f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
1314 hton24(fh->fh_f_ctl, f_ctl);
1315
1316 fc_exch_setup_hdr(ep, fp, f_ctl);
1317 fh->fh_seq_id = rx_fh->fh_seq_id;
1318 fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
1319 fh->fh_parm_offset = htonl(1);
1320
1321 fr_sof(fp) = fr_sof(rx_fp);
1322 if (f_ctl & FC_FC_END_SEQ)
1323 fr_eof(fp) = FC_EOF_T;
1324 else
1325 fr_eof(fp) = FC_EOF_N;
1326
1327 lport->tt.frame_send(lport, fp);
1328 }
1329}
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
1340 enum fc_ba_rjt_reason reason,
1341 enum fc_ba_rjt_explan explan)
1342{
1343 struct fc_frame *fp;
1344 struct fc_frame_header *rx_fh;
1345 struct fc_frame_header *fh;
1346 struct fc_ba_rjt *rp;
1347 struct fc_seq *sp;
1348 struct fc_lport *lport;
1349 unsigned int f_ctl;
1350
1351 lport = fr_dev(rx_fp);
1352 sp = fr_seq(rx_fp);
1353 fp = fc_frame_alloc(lport, sizeof(*rp));
1354 if (!fp) {
1355 FC_EXCH_DBG(fc_seq_exch(sp),
1356 "Drop BA_RJT request, out of memory\n");
1357 return;
1358 }
1359 fh = fc_frame_header_get(fp);
1360 rx_fh = fc_frame_header_get(rx_fp);
1361
1362 memset(fh, 0, sizeof(*fh) + sizeof(*rp));
1363
1364 rp = fc_frame_payload_get(fp, sizeof(*rp));
1365 rp->br_reason = reason;
1366 rp->br_explan = explan;
1367
1368
1369
1370
1371 memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3);
1372 memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3);
1373 fh->fh_ox_id = rx_fh->fh_ox_id;
1374 fh->fh_rx_id = rx_fh->fh_rx_id;
1375 fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
1376 fh->fh_r_ctl = FC_RCTL_BA_RJT;
1377 fh->fh_type = FC_TYPE_BLS;
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387 f_ctl = ntoh24(rx_fh->fh_f_ctl);
1388 f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX |
1389 FC_FC_END_CONN | FC_FC_SEQ_INIT |
1390 FC_FC_RETX_SEQ | FC_FC_UNI_TX;
1391 f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
1392 f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ;
1393 f_ctl &= ~FC_FC_FIRST_SEQ;
1394 hton24(fh->fh_f_ctl, f_ctl);
1395
1396 fr_sof(fp) = fc_sof_class(fr_sof(rx_fp));
1397 fr_eof(fp) = FC_EOF_T;
1398 if (fc_sof_needs_ack(fr_sof(fp)))
1399 fr_eof(fp) = FC_EOF_N;
1400
1401 lport->tt.frame_send(lport, fp);
1402}
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
1414{
1415 struct fc_frame *fp;
1416 struct fc_ba_acc *ap;
1417 struct fc_frame_header *fh;
1418 struct fc_seq *sp;
1419
1420 if (!ep)
1421 goto reject;
1422
1423 FC_EXCH_DBG(ep, "exch: ABTS received\n");
1424 fp = fc_frame_alloc(ep->lp, sizeof(*ap));
1425 if (!fp) {
1426 FC_EXCH_DBG(ep, "Drop ABTS request, out of memory\n");
1427 goto free;
1428 }
1429
1430 spin_lock_bh(&ep->ex_lock);
1431 if (ep->esb_stat & ESB_ST_COMPLETE) {
1432 spin_unlock_bh(&ep->ex_lock);
1433 FC_EXCH_DBG(ep, "exch: ABTS rejected, exchange complete\n");
1434 fc_frame_free(fp);
1435 goto reject;
1436 }
1437 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
1438 ep->esb_stat |= ESB_ST_REC_QUAL;
1439 fc_exch_hold(ep);
1440 }
1441 fc_exch_timer_set_locked(ep, ep->r_a_tov);
1442 fh = fc_frame_header_get(fp);
1443 ap = fc_frame_payload_get(fp, sizeof(*ap));
1444 memset(ap, 0, sizeof(*ap));
1445 sp = &ep->seq;
1446 ap->ba_high_seq_cnt = htons(0xffff);
1447 if (sp->ssb_stat & SSB_ST_RESP) {
1448 ap->ba_seq_id = sp->id;
1449 ap->ba_seq_id_val = FC_BA_SEQ_ID_VAL;
1450 ap->ba_high_seq_cnt = fh->fh_seq_cnt;
1451 ap->ba_low_seq_cnt = htons(sp->cnt);
1452 }
1453 sp = fc_seq_start_next_locked(sp);
1454 fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
1455 ep->esb_stat |= ESB_ST_ABNORMAL;
1456 spin_unlock_bh(&ep->ex_lock);
1457
1458free:
1459 fc_frame_free(rx_fp);
1460 return;
1461
1462reject:
1463 fc_exch_send_ba_rjt(rx_fp, FC_BA_RJT_UNABLE, FC_BA_RJT_INV_XID);
1464 goto free;
1465}
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476struct fc_seq *fc_seq_assign(struct fc_lport *lport, struct fc_frame *fp)
1477{
1478 struct fc_exch_mgr_anchor *ema;
1479
1480 WARN_ON(lport != fr_dev(fp));
1481 WARN_ON(fr_seq(fp));
1482 fr_seq(fp) = NULL;
1483
1484 list_for_each_entry(ema, &lport->ema_list, ema_list)
1485 if ((!ema->match || ema->match(fp)) &&
1486 fc_seq_lookup_recip(lport, ema->mp, fp) == FC_RJT_NONE)
1487 break;
1488 return fr_seq(fp);
1489}
1490EXPORT_SYMBOL(fc_seq_assign);
1491
1492
1493
1494
1495
1496void fc_seq_release(struct fc_seq *sp)
1497{
1498 fc_exch_release(fc_seq_exch(sp));
1499}
1500EXPORT_SYMBOL(fc_seq_release);
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511static void fc_exch_recv_req(struct fc_lport *lport, struct fc_exch_mgr *mp,
1512 struct fc_frame *fp)
1513{
1514 struct fc_frame_header *fh = fc_frame_header_get(fp);
1515 struct fc_seq *sp = NULL;
1516 struct fc_exch *ep = NULL;
1517 enum fc_pf_rjt_reason reject;
1518
1519
1520
1521
1522 lport = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
1523 if (!lport) {
1524 fc_frame_free(fp);
1525 return;
1526 }
1527 fr_dev(fp) = lport;
1528
1529 BUG_ON(fr_seq(fp));
1530
1531
1532
1533
1534
1535 if (fh->fh_rx_id == htons(FC_XID_UNKNOWN))
1536 return fc_lport_recv(lport, fp);
1537
1538 reject = fc_seq_lookup_recip(lport, mp, fp);
1539 if (reject == FC_RJT_NONE) {
1540 sp = fr_seq(fp);
1541 ep = fc_seq_exch(sp);
1542 fc_seq_send_ack(sp, fp);
1543 ep->encaps = fr_encaps(fp);
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556 if (!fc_invoke_resp(ep, sp, fp))
1557 fc_lport_recv(lport, fp);
1558 fc_exch_release(ep);
1559 } else {
1560 FC_LPORT_DBG(lport, "exch/seq lookup failed: reject %x\n",
1561 reject);
1562 fc_frame_free(fp);
1563 }
1564}
1565
1566
1567
1568
1569
1570
1571
1572
1573static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1574{
1575 struct fc_frame_header *fh = fc_frame_header_get(fp);
1576 struct fc_seq *sp;
1577 struct fc_exch *ep;
1578 enum fc_sof sof;
1579 u32 f_ctl;
1580 int rc;
1581
1582 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
1583 if (!ep) {
1584 atomic_inc(&mp->stats.xid_not_found);
1585 goto out;
1586 }
1587 if (ep->esb_stat & ESB_ST_COMPLETE) {
1588 atomic_inc(&mp->stats.xid_not_found);
1589 goto rel;
1590 }
1591 if (ep->rxid == FC_XID_UNKNOWN)
1592 ep->rxid = ntohs(fh->fh_rx_id);
1593 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
1594 atomic_inc(&mp->stats.xid_not_found);
1595 goto rel;
1596 }
1597 if (ep->did != ntoh24(fh->fh_s_id) &&
1598 ep->did != FC_FID_FLOGI) {
1599 atomic_inc(&mp->stats.xid_not_found);
1600 goto rel;
1601 }
1602 sof = fr_sof(fp);
1603 sp = &ep->seq;
1604 if (fc_sof_is_init(sof)) {
1605 sp->ssb_stat |= SSB_ST_RESP;
1606 sp->id = fh->fh_seq_id;
1607 }
1608
1609 f_ctl = ntoh24(fh->fh_f_ctl);
1610 fr_seq(fp) = sp;
1611
1612 spin_lock_bh(&ep->ex_lock);
1613 if (f_ctl & FC_FC_SEQ_INIT)
1614 ep->esb_stat |= ESB_ST_SEQ_INIT;
1615 spin_unlock_bh(&ep->ex_lock);
1616
1617 if (fc_sof_needs_ack(sof))
1618 fc_seq_send_ack(sp, fp);
1619
1620 if (fh->fh_type != FC_TYPE_FCP && fr_eof(fp) == FC_EOF_T &&
1621 (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
1622 (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
1623 spin_lock_bh(&ep->ex_lock);
1624 rc = fc_exch_done_locked(ep);
1625 WARN_ON(fc_seq_exch(sp) != ep);
1626 spin_unlock_bh(&ep->ex_lock);
1627 if (!rc)
1628 fc_exch_delete(ep);
1629 }
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644 if (!fc_invoke_resp(ep, sp, fp))
1645 fc_frame_free(fp);
1646
1647 fc_exch_release(ep);
1648 return;
1649rel:
1650 fc_exch_release(ep);
1651out:
1652 fc_frame_free(fp);
1653}
1654
1655
1656
1657
1658
1659
1660
1661static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1662{
1663 struct fc_seq *sp;
1664
1665 sp = fc_seq_lookup_orig(mp, fp);
1666
1667 if (!sp)
1668 atomic_inc(&mp->stats.xid_not_found);
1669 else
1670 atomic_inc(&mp->stats.non_bls_resp);
1671
1672 fc_frame_free(fp);
1673}
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
1684{
1685 struct fc_frame_header *fh;
1686 struct fc_ba_acc *ap;
1687 struct fc_seq *sp;
1688 u16 low;
1689 u16 high;
1690 int rc = 1, has_rec = 0;
1691
1692 fh = fc_frame_header_get(fp);
1693 FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl,
1694 fc_exch_rctl_name(fh->fh_r_ctl));
1695
1696 if (cancel_delayed_work_sync(&ep->timeout_work)) {
1697 FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n");
1698 fc_exch_release(ep);
1699 }
1700
1701 spin_lock_bh(&ep->ex_lock);
1702 switch (fh->fh_r_ctl) {
1703 case FC_RCTL_BA_ACC:
1704 ap = fc_frame_payload_get(fp, sizeof(*ap));
1705 if (!ap)
1706 break;
1707
1708
1709
1710
1711
1712
1713 low = ntohs(ap->ba_low_seq_cnt);
1714 high = ntohs(ap->ba_high_seq_cnt);
1715 if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 &&
1716 (ap->ba_seq_id_val != FC_BA_SEQ_ID_VAL ||
1717 ap->ba_seq_id == ep->seq_id) && low != high) {
1718 ep->esb_stat |= ESB_ST_REC_QUAL;
1719 fc_exch_hold(ep);
1720 has_rec = 1;
1721 }
1722 break;
1723 case FC_RCTL_BA_RJT:
1724 break;
1725 default:
1726 break;
1727 }
1728
1729
1730
1731
1732 sp = &ep->seq;
1733
1734
1735
1736 if (ep->fh_type != FC_TYPE_FCP &&
1737 ntoh24(fh->fh_f_ctl) & FC_FC_LAST_SEQ)
1738 rc = fc_exch_done_locked(ep);
1739 spin_unlock_bh(&ep->ex_lock);
1740
1741 fc_exch_hold(ep);
1742 if (!rc)
1743 fc_exch_delete(ep);
1744 if (!fc_invoke_resp(ep, sp, fp))
1745 fc_frame_free(fp);
1746 if (has_rec)
1747 fc_exch_timer_set(ep, ep->r_a_tov);
1748 fc_exch_release(ep);
1749}
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
1760{
1761 struct fc_frame_header *fh;
1762 struct fc_exch *ep;
1763 u32 f_ctl;
1764
1765 fh = fc_frame_header_get(fp);
1766 f_ctl = ntoh24(fh->fh_f_ctl);
1767 fr_seq(fp) = NULL;
1768
1769 ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ?
1770 ntohs(fh->fh_ox_id) : ntohs(fh->fh_rx_id));
1771 if (ep && (f_ctl & FC_FC_SEQ_INIT)) {
1772 spin_lock_bh(&ep->ex_lock);
1773 ep->esb_stat |= ESB_ST_SEQ_INIT;
1774 spin_unlock_bh(&ep->ex_lock);
1775 }
1776 if (f_ctl & FC_FC_SEQ_CTX) {
1777
1778
1779
1780
1781 switch (fh->fh_r_ctl) {
1782 case FC_RCTL_ACK_1:
1783 case FC_RCTL_ACK_0:
1784 break;
1785 default:
1786 if (ep)
1787 FC_EXCH_DBG(ep, "BLS rctl %x - %s received\n",
1788 fh->fh_r_ctl,
1789 fc_exch_rctl_name(fh->fh_r_ctl));
1790 break;
1791 }
1792 fc_frame_free(fp);
1793 } else {
1794 switch (fh->fh_r_ctl) {
1795 case FC_RCTL_BA_RJT:
1796 case FC_RCTL_BA_ACC:
1797 if (ep)
1798 fc_exch_abts_resp(ep, fp);
1799 else
1800 fc_frame_free(fp);
1801 break;
1802 case FC_RCTL_BA_ABTS:
1803 if (ep)
1804 fc_exch_recv_abts(ep, fp);
1805 else
1806 fc_frame_free(fp);
1807 break;
1808 default:
1809 fc_frame_free(fp);
1810 break;
1811 }
1812 }
1813 if (ep)
1814 fc_exch_release(ep);
1815}
1816
1817
1818
1819
1820
1821
1822
1823
1824static void fc_seq_ls_acc(struct fc_frame *rx_fp)
1825{
1826 struct fc_lport *lport;
1827 struct fc_els_ls_acc *acc;
1828 struct fc_frame *fp;
1829 struct fc_seq *sp;
1830
1831 lport = fr_dev(rx_fp);
1832 sp = fr_seq(rx_fp);
1833 fp = fc_frame_alloc(lport, sizeof(*acc));
1834 if (!fp) {
1835 FC_EXCH_DBG(fc_seq_exch(sp),
1836 "exch: drop LS_ACC, out of memory\n");
1837 return;
1838 }
1839 acc = fc_frame_payload_get(fp, sizeof(*acc));
1840 memset(acc, 0, sizeof(*acc));
1841 acc->la_cmd = ELS_LS_ACC;
1842 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
1843 lport->tt.frame_send(lport, fp);
1844}
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855static void fc_seq_ls_rjt(struct fc_frame *rx_fp, enum fc_els_rjt_reason reason,
1856 enum fc_els_rjt_explan explan)
1857{
1858 struct fc_lport *lport;
1859 struct fc_els_ls_rjt *rjt;
1860 struct fc_frame *fp;
1861 struct fc_seq *sp;
1862
1863 lport = fr_dev(rx_fp);
1864 sp = fr_seq(rx_fp);
1865 fp = fc_frame_alloc(lport, sizeof(*rjt));
1866 if (!fp) {
1867 FC_EXCH_DBG(fc_seq_exch(sp),
1868 "exch: drop LS_ACC, out of memory\n");
1869 return;
1870 }
1871 rjt = fc_frame_payload_get(fp, sizeof(*rjt));
1872 memset(rjt, 0, sizeof(*rjt));
1873 rjt->er_cmd = ELS_LS_RJT;
1874 rjt->er_reason = reason;
1875 rjt->er_explan = explan;
1876 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
1877 lport->tt.frame_send(lport, fp);
1878}
1879
1880
1881
1882
1883
1884
1885
1886static void fc_exch_reset(struct fc_exch *ep)
1887{
1888 struct fc_seq *sp;
1889 int rc = 1;
1890
1891 spin_lock_bh(&ep->ex_lock);
1892 ep->state |= FC_EX_RST_CLEANUP;
1893 fc_exch_timer_cancel(ep);
1894 if (ep->esb_stat & ESB_ST_REC_QUAL)
1895 atomic_dec(&ep->ex_refcnt);
1896 ep->esb_stat &= ~ESB_ST_REC_QUAL;
1897 sp = &ep->seq;
1898 rc = fc_exch_done_locked(ep);
1899 spin_unlock_bh(&ep->ex_lock);
1900
1901 fc_exch_hold(ep);
1902
1903 if (!rc)
1904 fc_exch_delete(ep);
1905
1906 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED));
1907 fc_seq_set_resp(sp, NULL, ep->arg);
1908 fc_exch_release(ep);
1909}
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923static void fc_exch_pool_reset(struct fc_lport *lport,
1924 struct fc_exch_pool *pool,
1925 u32 sid, u32 did)
1926{
1927 struct fc_exch *ep;
1928 struct fc_exch *next;
1929
1930 spin_lock_bh(&pool->lock);
1931restart:
1932 list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) {
1933 if ((lport == ep->lp) &&
1934 (sid == 0 || sid == ep->sid) &&
1935 (did == 0 || did == ep->did)) {
1936 fc_exch_hold(ep);
1937 spin_unlock_bh(&pool->lock);
1938
1939 fc_exch_reset(ep);
1940
1941 fc_exch_release(ep);
1942 spin_lock_bh(&pool->lock);
1943
1944
1945
1946
1947
1948 goto restart;
1949 }
1950 }
1951 pool->next_index = 0;
1952 pool->left = FC_XID_UNKNOWN;
1953 pool->right = FC_XID_UNKNOWN;
1954 spin_unlock_bh(&pool->lock);
1955}
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968void fc_exch_mgr_reset(struct fc_lport *lport, u32 sid, u32 did)
1969{
1970 struct fc_exch_mgr_anchor *ema;
1971 unsigned int cpu;
1972
1973 list_for_each_entry(ema, &lport->ema_list, ema_list) {
1974 for_each_possible_cpu(cpu)
1975 fc_exch_pool_reset(lport,
1976 per_cpu_ptr(ema->mp->pool, cpu),
1977 sid, did);
1978 }
1979}
1980EXPORT_SYMBOL(fc_exch_mgr_reset);
1981
1982
1983
1984
1985
1986
1987
1988
1989static struct fc_exch *fc_exch_lookup(struct fc_lport *lport, u32 xid)
1990{
1991 struct fc_exch_mgr_anchor *ema;
1992
1993 list_for_each_entry(ema, &lport->ema_list, ema_list)
1994 if (ema->mp->min_xid <= xid && xid <= ema->mp->max_xid)
1995 return fc_exch_find(ema->mp, xid);
1996 return NULL;
1997}
1998
1999
2000
2001
2002
2003
2004
2005static void fc_exch_els_rec(struct fc_frame *rfp)
2006{
2007 struct fc_lport *lport;
2008 struct fc_frame *fp;
2009 struct fc_exch *ep;
2010 struct fc_els_rec *rp;
2011 struct fc_els_rec_acc *acc;
2012 enum fc_els_rjt_reason reason = ELS_RJT_LOGIC;
2013 enum fc_els_rjt_explan explan;
2014 u32 sid;
2015 u16 xid, rxid, oxid;
2016
2017 lport = fr_dev(rfp);
2018 rp = fc_frame_payload_get(rfp, sizeof(*rp));
2019 explan = ELS_EXPL_INV_LEN;
2020 if (!rp)
2021 goto reject;
2022 sid = ntoh24(rp->rec_s_id);
2023 rxid = ntohs(rp->rec_rx_id);
2024 oxid = ntohs(rp->rec_ox_id);
2025
2026 explan = ELS_EXPL_OXID_RXID;
2027 if (sid == fc_host_port_id(lport->host))
2028 xid = oxid;
2029 else
2030 xid = rxid;
2031 if (xid == FC_XID_UNKNOWN) {
2032 FC_LPORT_DBG(lport,
2033 "REC request from %x: invalid rxid %x oxid %x\n",
2034 sid, rxid, oxid);
2035 goto reject;
2036 }
2037 ep = fc_exch_lookup(lport, xid);
2038 if (!ep) {
2039 FC_LPORT_DBG(lport,
2040 "REC request from %x: rxid %x oxid %x not found\n",
2041 sid, rxid, oxid);
2042 goto reject;
2043 }
2044 FC_EXCH_DBG(ep, "REC request from %x: rxid %x oxid %x\n",
2045 sid, rxid, oxid);
2046 if (ep->oid != sid || oxid != ep->oxid)
2047 goto rel;
2048 if (rxid != FC_XID_UNKNOWN && rxid != ep->rxid)
2049 goto rel;
2050 fp = fc_frame_alloc(lport, sizeof(*acc));
2051 if (!fp) {
2052 FC_EXCH_DBG(ep, "Drop REC request, out of memory\n");
2053 goto out;
2054 }
2055
2056 acc = fc_frame_payload_get(fp, sizeof(*acc));
2057 memset(acc, 0, sizeof(*acc));
2058 acc->reca_cmd = ELS_LS_ACC;
2059 acc->reca_ox_id = rp->rec_ox_id;
2060 memcpy(acc->reca_ofid, rp->rec_s_id, 3);
2061 acc->reca_rx_id = htons(ep->rxid);
2062 if (ep->sid == ep->oid)
2063 hton24(acc->reca_rfid, ep->did);
2064 else
2065 hton24(acc->reca_rfid, ep->sid);
2066 acc->reca_fc4value = htonl(ep->seq.rec_data);
2067 acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP |
2068 ESB_ST_SEQ_INIT |
2069 ESB_ST_COMPLETE));
2070 fc_fill_reply_hdr(fp, rfp, FC_RCTL_ELS_REP, 0);
2071 lport->tt.frame_send(lport, fp);
2072out:
2073 fc_exch_release(ep);
2074 return;
2075
2076rel:
2077 fc_exch_release(ep);
2078reject:
2079 fc_seq_ls_rjt(rfp, reason, explan);
2080}
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
2091{
2092 struct fc_exch *aborted_ep = arg;
2093 unsigned int op;
2094
2095 if (IS_ERR(fp)) {
2096 int err = PTR_ERR(fp);
2097
2098 if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT)
2099 goto cleanup;
2100 FC_EXCH_DBG(aborted_ep, "Cannot process RRQ, "
2101 "frame error %d\n", err);
2102 return;
2103 }
2104
2105 op = fc_frame_payload_op(fp);
2106 fc_frame_free(fp);
2107
2108 switch (op) {
2109 case ELS_LS_RJT:
2110 FC_EXCH_DBG(aborted_ep, "LS_RJT for RRQ\n");
2111 fallthrough;
2112 case ELS_LS_ACC:
2113 goto cleanup;
2114 default:
2115 FC_EXCH_DBG(aborted_ep, "unexpected response op %x for RRQ\n",
2116 op);
2117 return;
2118 }
2119
2120cleanup:
2121 fc_exch_done(&aborted_ep->seq);
2122
2123 fc_exch_release(aborted_ep);
2124}
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
2165 struct fc_frame *fp,
2166 void (*resp)(struct fc_seq *,
2167 struct fc_frame *fp,
2168 void *arg),
2169 void (*destructor)(struct fc_seq *, void *),
2170 void *arg, u32 timer_msec)
2171{
2172 struct fc_exch *ep;
2173 struct fc_seq *sp = NULL;
2174 struct fc_frame_header *fh;
2175 struct fc_fcp_pkt *fsp = NULL;
2176 int rc = 1;
2177
2178 ep = fc_exch_alloc(lport, fp);
2179 if (!ep) {
2180 fc_frame_free(fp);
2181 return NULL;
2182 }
2183 ep->esb_stat |= ESB_ST_SEQ_INIT;
2184 fh = fc_frame_header_get(fp);
2185 fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
2186 ep->resp = resp;
2187 ep->destructor = destructor;
2188 ep->arg = arg;
2189 ep->r_a_tov = lport->r_a_tov;
2190 ep->lp = lport;
2191 sp = &ep->seq;
2192
2193 ep->fh_type = fh->fh_type;
2194 ep->f_ctl = ntoh24(fh->fh_f_ctl);
2195 fc_exch_setup_hdr(ep, fp, ep->f_ctl);
2196 sp->cnt++;
2197
2198 if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) {
2199 fsp = fr_fsp(fp);
2200 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
2201 }
2202
2203 if (unlikely(lport->tt.frame_send(lport, fp)))
2204 goto err;
2205
2206 if (timer_msec)
2207 fc_exch_timer_set_locked(ep, timer_msec);
2208 ep->f_ctl &= ~FC_FC_FIRST_SEQ;
2209
2210 if (ep->f_ctl & FC_FC_SEQ_INIT)
2211 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
2212 spin_unlock_bh(&ep->ex_lock);
2213 return sp;
2214err:
2215 if (fsp)
2216 fc_fcp_ddp_done(fsp);
2217 rc = fc_exch_done_locked(ep);
2218 spin_unlock_bh(&ep->ex_lock);
2219 if (!rc)
2220 fc_exch_delete(ep);
2221 return NULL;
2222}
2223EXPORT_SYMBOL(fc_exch_seq_send);
2224
2225
2226
2227
2228
2229
2230
2231
2232static void fc_exch_rrq(struct fc_exch *ep)
2233{
2234 struct fc_lport *lport;
2235 struct fc_els_rrq *rrq;
2236 struct fc_frame *fp;
2237 u32 did;
2238
2239 lport = ep->lp;
2240
2241 fp = fc_frame_alloc(lport, sizeof(*rrq));
2242 if (!fp)
2243 goto retry;
2244
2245 rrq = fc_frame_payload_get(fp, sizeof(*rrq));
2246 memset(rrq, 0, sizeof(*rrq));
2247 rrq->rrq_cmd = ELS_RRQ;
2248 hton24(rrq->rrq_s_id, ep->sid);
2249 rrq->rrq_ox_id = htons(ep->oxid);
2250 rrq->rrq_rx_id = htons(ep->rxid);
2251
2252 did = ep->did;
2253 if (ep->esb_stat & ESB_ST_RESP)
2254 did = ep->sid;
2255
2256 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did,
2257 lport->port_id, FC_TYPE_ELS,
2258 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
2259
2260 if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep,
2261 lport->e_d_tov))
2262 return;
2263
2264retry:
2265 FC_EXCH_DBG(ep, "exch: RRQ send failed\n");
2266 spin_lock_bh(&ep->ex_lock);
2267 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) {
2268 spin_unlock_bh(&ep->ex_lock);
2269
2270 fc_exch_release(ep);
2271 return;
2272 }
2273 ep->esb_stat |= ESB_ST_REC_QUAL;
2274 fc_exch_timer_set_locked(ep, ep->r_a_tov);
2275 spin_unlock_bh(&ep->ex_lock);
2276}
2277
2278
2279
2280
2281
2282static void fc_exch_els_rrq(struct fc_frame *fp)
2283{
2284 struct fc_lport *lport;
2285 struct fc_exch *ep = NULL;
2286 struct fc_els_rrq *rp;
2287 u32 sid;
2288 u16 xid;
2289 enum fc_els_rjt_explan explan;
2290
2291 lport = fr_dev(fp);
2292 rp = fc_frame_payload_get(fp, sizeof(*rp));
2293 explan = ELS_EXPL_INV_LEN;
2294 if (!rp)
2295 goto reject;
2296
2297
2298
2299
2300 sid = ntoh24(rp->rrq_s_id);
2301 xid = fc_host_port_id(lport->host) == sid ?
2302 ntohs(rp->rrq_ox_id) : ntohs(rp->rrq_rx_id);
2303 ep = fc_exch_lookup(lport, xid);
2304 explan = ELS_EXPL_OXID_RXID;
2305 if (!ep)
2306 goto reject;
2307 spin_lock_bh(&ep->ex_lock);
2308 FC_EXCH_DBG(ep, "RRQ request from %x: xid %x rxid %x oxid %x\n",
2309 sid, xid, ntohs(rp->rrq_rx_id), ntohs(rp->rrq_ox_id));
2310 if (ep->oxid != ntohs(rp->rrq_ox_id))
2311 goto unlock_reject;
2312 if (ep->rxid != ntohs(rp->rrq_rx_id) &&
2313 ep->rxid != FC_XID_UNKNOWN)
2314 goto unlock_reject;
2315 explan = ELS_EXPL_SID;
2316 if (ep->sid != sid)
2317 goto unlock_reject;
2318
2319
2320
2321
2322 if (ep->esb_stat & ESB_ST_REC_QUAL) {
2323 ep->esb_stat &= ~ESB_ST_REC_QUAL;
2324 atomic_dec(&ep->ex_refcnt);
2325 }
2326 if (ep->esb_stat & ESB_ST_COMPLETE)
2327 fc_exch_timer_cancel(ep);
2328
2329 spin_unlock_bh(&ep->ex_lock);
2330
2331
2332
2333
2334 fc_seq_ls_acc(fp);
2335 goto out;
2336
2337unlock_reject:
2338 spin_unlock_bh(&ep->ex_lock);
2339reject:
2340 fc_seq_ls_rjt(fp, ELS_RJT_LOGIC, explan);
2341out:
2342 if (ep)
2343 fc_exch_release(ep);
2344}
2345
2346
2347
2348
2349
2350void fc_exch_update_stats(struct fc_lport *lport)
2351{
2352 struct fc_host_statistics *st;
2353 struct fc_exch_mgr_anchor *ema;
2354 struct fc_exch_mgr *mp;
2355
2356 st = &lport->host_stats;
2357
2358 list_for_each_entry(ema, &lport->ema_list, ema_list) {
2359 mp = ema->mp;
2360 st->fc_no_free_exch += atomic_read(&mp->stats.no_free_exch);
2361 st->fc_no_free_exch_xid +=
2362 atomic_read(&mp->stats.no_free_exch_xid);
2363 st->fc_xid_not_found += atomic_read(&mp->stats.xid_not_found);
2364 st->fc_xid_busy += atomic_read(&mp->stats.xid_busy);
2365 st->fc_seq_not_found += atomic_read(&mp->stats.seq_not_found);
2366 st->fc_non_bls_resp += atomic_read(&mp->stats.non_bls_resp);
2367 }
2368}
2369EXPORT_SYMBOL(fc_exch_update_stats);
2370
2371
2372
2373
2374
2375
2376
2377struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
2378 struct fc_exch_mgr *mp,
2379 bool (*match)(struct fc_frame *))
2380{
2381 struct fc_exch_mgr_anchor *ema;
2382
2383 ema = kmalloc(sizeof(*ema), GFP_ATOMIC);
2384 if (!ema)
2385 return ema;
2386
2387 ema->mp = mp;
2388 ema->match = match;
2389
2390 list_add_tail(&ema->ema_list, &lport->ema_list);
2391 kref_get(&mp->kref);
2392 return ema;
2393}
2394EXPORT_SYMBOL(fc_exch_mgr_add);
2395
2396
2397
2398
2399
2400static void fc_exch_mgr_destroy(struct kref *kref)
2401{
2402 struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
2403
2404 mempool_destroy(mp->ep_pool);
2405 free_percpu(mp->pool);
2406 kfree(mp);
2407}
2408
2409
2410
2411
2412
2413void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
2414{
2415
2416 list_del(&ema->ema_list);
2417 kref_put(&ema->mp->kref, fc_exch_mgr_destroy);
2418 kfree(ema);
2419}
2420EXPORT_SYMBOL(fc_exch_mgr_del);
2421
2422
2423
2424
2425
2426
2427int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst)
2428{
2429 struct fc_exch_mgr_anchor *ema, *tmp;
2430
2431 list_for_each_entry(ema, &src->ema_list, ema_list) {
2432 if (!fc_exch_mgr_add(dst, ema->mp, ema->match))
2433 goto err;
2434 }
2435 return 0;
2436err:
2437 list_for_each_entry_safe(ema, tmp, &dst->ema_list, ema_list)
2438 fc_exch_mgr_del(ema);
2439 return -ENOMEM;
2440}
2441EXPORT_SYMBOL(fc_exch_mgr_list_clone);
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
2452 enum fc_class class,
2453 u16 min_xid, u16 max_xid,
2454 bool (*match)(struct fc_frame *))
2455{
2456 struct fc_exch_mgr *mp;
2457 u16 pool_exch_range;
2458 size_t pool_size;
2459 unsigned int cpu;
2460 struct fc_exch_pool *pool;
2461
2462 if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN ||
2463 (min_xid & fc_cpu_mask) != 0) {
2464 FC_LPORT_DBG(lport, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
2465 min_xid, max_xid);
2466 return NULL;
2467 }
2468
2469
2470
2471
2472 mp = kzalloc(sizeof(struct fc_exch_mgr), GFP_ATOMIC);
2473 if (!mp)
2474 return NULL;
2475
2476 mp->class = class;
2477 mp->lport = lport;
2478
2479 mp->min_xid = min_xid;
2480
2481
2482 pool_exch_range = (PCPU_MIN_UNIT_SIZE - sizeof(*pool)) /
2483 sizeof(struct fc_exch *);
2484 if ((max_xid - min_xid + 1) / (fc_cpu_mask + 1) > pool_exch_range) {
2485 mp->max_xid = pool_exch_range * (fc_cpu_mask + 1) +
2486 min_xid - 1;
2487 } else {
2488 mp->max_xid = max_xid;
2489 pool_exch_range = (mp->max_xid - mp->min_xid + 1) /
2490 (fc_cpu_mask + 1);
2491 }
2492
2493 mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep);
2494 if (!mp->ep_pool)
2495 goto free_mp;
2496
2497
2498
2499
2500
2501
2502 mp->pool_max_index = pool_exch_range - 1;
2503
2504
2505
2506
2507 pool_size = sizeof(*pool) + pool_exch_range * sizeof(struct fc_exch *);
2508 mp->pool = __alloc_percpu(pool_size, __alignof__(struct fc_exch_pool));
2509 if (!mp->pool)
2510 goto free_mempool;
2511 for_each_possible_cpu(cpu) {
2512 pool = per_cpu_ptr(mp->pool, cpu);
2513 pool->next_index = 0;
2514 pool->left = FC_XID_UNKNOWN;
2515 pool->right = FC_XID_UNKNOWN;
2516 spin_lock_init(&pool->lock);
2517 INIT_LIST_HEAD(&pool->ex_list);
2518 }
2519
2520 kref_init(&mp->kref);
2521 if (!fc_exch_mgr_add(lport, mp, match)) {
2522 free_percpu(mp->pool);
2523 goto free_mempool;
2524 }
2525
2526
2527
2528
2529
2530
2531 kref_put(&mp->kref, fc_exch_mgr_destroy);
2532 return mp;
2533
2534free_mempool:
2535 mempool_destroy(mp->ep_pool);
2536free_mp:
2537 kfree(mp);
2538 return NULL;
2539}
2540EXPORT_SYMBOL(fc_exch_mgr_alloc);
2541
2542
2543
2544
2545
2546void fc_exch_mgr_free(struct fc_lport *lport)
2547{
2548 struct fc_exch_mgr_anchor *ema, *next;
2549
2550 flush_workqueue(fc_exch_workqueue);
2551 list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list)
2552 fc_exch_mgr_del(ema);
2553}
2554EXPORT_SYMBOL(fc_exch_mgr_free);
2555
2556
2557
2558
2559
2560
2561
2562
2563static struct fc_exch_mgr_anchor *fc_find_ema(u32 f_ctl,
2564 struct fc_lport *lport,
2565 struct fc_frame_header *fh)
2566{
2567 struct fc_exch_mgr_anchor *ema;
2568 u16 xid;
2569
2570 if (f_ctl & FC_FC_EX_CTX)
2571 xid = ntohs(fh->fh_ox_id);
2572 else {
2573 xid = ntohs(fh->fh_rx_id);
2574 if (xid == FC_XID_UNKNOWN)
2575 return list_entry(lport->ema_list.prev,
2576 typeof(*ema), ema_list);
2577 }
2578
2579 list_for_each_entry(ema, &lport->ema_list, ema_list) {
2580 if ((xid >= ema->mp->min_xid) &&
2581 (xid <= ema->mp->max_xid))
2582 return ema;
2583 }
2584 return NULL;
2585}
2586
2587
2588
2589
2590
2591void fc_exch_recv(struct fc_lport *lport, struct fc_frame *fp)
2592{
2593 struct fc_frame_header *fh = fc_frame_header_get(fp);
2594 struct fc_exch_mgr_anchor *ema;
2595 u32 f_ctl;
2596
2597
2598 if (!lport || lport->state == LPORT_ST_DISABLED) {
2599 FC_LIBFC_DBG("Receiving frames for an lport that "
2600 "has not been initialized correctly\n");
2601 fc_frame_free(fp);
2602 return;
2603 }
2604
2605 f_ctl = ntoh24(fh->fh_f_ctl);
2606 ema = fc_find_ema(f_ctl, lport, fh);
2607 if (!ema) {
2608 FC_LPORT_DBG(lport, "Unable to find Exchange Manager Anchor,"
2609 "fc_ctl <0x%x>, xid <0x%x>\n",
2610 f_ctl,
2611 (f_ctl & FC_FC_EX_CTX) ?
2612 ntohs(fh->fh_ox_id) :
2613 ntohs(fh->fh_rx_id));
2614 fc_frame_free(fp);
2615 return;
2616 }
2617
2618
2619
2620
2621 switch (fr_eof(fp)) {
2622 case FC_EOF_T:
2623 if (f_ctl & FC_FC_END_SEQ)
2624 skb_trim(fp_skb(fp), fr_len(fp) - FC_FC_FILL(f_ctl));
2625 fallthrough;
2626 case FC_EOF_N:
2627 if (fh->fh_type == FC_TYPE_BLS)
2628 fc_exch_recv_bls(ema->mp, fp);
2629 else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) ==
2630 FC_FC_EX_CTX)
2631 fc_exch_recv_seq_resp(ema->mp, fp);
2632 else if (f_ctl & FC_FC_SEQ_CTX)
2633 fc_exch_recv_resp(ema->mp, fp);
2634 else
2635 fc_exch_recv_req(lport, ema->mp, fp);
2636 break;
2637 default:
2638 FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)",
2639 fr_eof(fp));
2640 fc_frame_free(fp);
2641 }
2642}
2643EXPORT_SYMBOL(fc_exch_recv);
2644
2645
2646
2647
2648
2649int fc_exch_init(struct fc_lport *lport)
2650{
2651 if (!lport->tt.exch_mgr_reset)
2652 lport->tt.exch_mgr_reset = fc_exch_mgr_reset;
2653
2654 return 0;
2655}
2656EXPORT_SYMBOL(fc_exch_init);
2657
2658
2659
2660
2661int fc_setup_exch_mgr(void)
2662{
2663 fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
2664 0, SLAB_HWCACHE_ALIGN, NULL);
2665 if (!fc_em_cachep)
2666 return -ENOMEM;
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682 fc_cpu_order = ilog2(roundup_pow_of_two(nr_cpu_ids));
2683 fc_cpu_mask = (1 << fc_cpu_order) - 1;
2684
2685 fc_exch_workqueue = create_singlethread_workqueue("fc_exch_workqueue");
2686 if (!fc_exch_workqueue)
2687 goto err;
2688 return 0;
2689err:
2690 kmem_cache_destroy(fc_em_cachep);
2691 return -ENOMEM;
2692}
2693
2694
2695
2696
2697void fc_destroy_exch_mgr(void)
2698{
2699 destroy_workqueue(fc_exch_workqueue);
2700 kmem_cache_destroy(fc_em_cachep);
2701}
2702