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