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/gfp.h>
28#include <linux/err.h>
29
30#include <scsi/fc/fc_fc2.h>
31
32#include <scsi/libfc.h>
33#include <scsi/fc_encode.h>
34
35u16 fc_cpu_mask;
36EXPORT_SYMBOL(fc_cpu_mask);
37static u16 fc_cpu_order;
38static struct kmem_cache *fc_em_cachep;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60struct fc_exch_pool {
61 u16 next_index;
62 u16 total_exches;
63 spinlock_t lock;
64 struct list_head ex_list;
65};
66
67
68
69
70
71
72
73struct fc_exch_mgr {
74 enum fc_class class;
75 struct kref kref;
76 u16 min_xid;
77 u16 max_xid;
78 struct list_head ex_list;
79 mempool_t *ep_pool;
80 u16 pool_max_index;
81 struct fc_exch_pool *pool;
82
83
84
85
86
87
88 struct {
89 atomic_t no_free_exch;
90 atomic_t no_free_exch_xid;
91 atomic_t xid_not_found;
92 atomic_t xid_busy;
93 atomic_t seq_not_found;
94 atomic_t non_bls_resp;
95 } stats;
96};
97#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
98
99struct fc_exch_mgr_anchor {
100 struct list_head ema_list;
101 struct fc_exch_mgr *mp;
102 bool (*match)(struct fc_frame *);
103};
104
105static void fc_exch_rrq(struct fc_exch *);
106static void fc_seq_ls_acc(struct fc_seq *);
107static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason,
108 enum fc_els_rjt_explan);
109static void fc_exch_els_rec(struct fc_seq *, struct fc_frame *);
110static void fc_exch_els_rrq(struct fc_seq *, struct fc_frame *);
111static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp);
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
195static char *fc_exch_rctl_names[] = FC_RCTL_NAMES_INIT;
196
197#define FC_TABLE_SIZE(x) (sizeof(x) / sizeof(x[0]))
198
199static inline const char *fc_exch_name_lookup(unsigned int op, char **table,
200 unsigned int max_index)
201{
202 const char *name = NULL;
203
204 if (op < max_index)
205 name = table[op];
206 if (!name)
207 name = "unknown";
208 return name;
209}
210
211static const char *fc_exch_rctl_name(unsigned int op)
212{
213 return fc_exch_name_lookup(op, fc_exch_rctl_names,
214 FC_TABLE_SIZE(fc_exch_rctl_names));
215}
216
217
218
219
220static void fc_exch_hold(struct fc_exch *ep)
221{
222 atomic_inc(&ep->ex_refcnt);
223}
224
225
226
227
228
229
230
231static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp,
232 u32 f_ctl)
233{
234 struct fc_frame_header *fh = fc_frame_header_get(fp);
235 u16 fill;
236
237 fr_sof(fp) = ep->class;
238 if (ep->seq.cnt)
239 fr_sof(fp) = fc_sof_normal(ep->class);
240
241 if (f_ctl & FC_FC_END_SEQ) {
242 fr_eof(fp) = FC_EOF_T;
243 if (fc_sof_needs_ack(ep->class))
244 fr_eof(fp) = FC_EOF_N;
245
246
247
248
249
250
251
252
253
254 fill = fr_len(fp) & 3;
255 if (fill) {
256 fill = 4 - fill;
257
258 skb_put(fp_skb(fp), fill);
259 hton24(fh->fh_f_ctl, f_ctl | fill);
260 }
261 } else {
262 WARN_ON(fr_len(fp) % 4 != 0);
263 fr_eof(fp) = FC_EOF_N;
264 }
265
266
267
268
269
270 fh->fh_ox_id = htons(ep->oxid);
271 fh->fh_rx_id = htons(ep->rxid);
272 fh->fh_seq_id = ep->seq.id;
273 fh->fh_seq_cnt = htons(ep->seq.cnt);
274}
275
276
277
278
279
280
281static void fc_exch_release(struct fc_exch *ep)
282{
283 struct fc_exch_mgr *mp;
284
285 if (atomic_dec_and_test(&ep->ex_refcnt)) {
286 mp = ep->em;
287 if (ep->destructor)
288 ep->destructor(&ep->seq, ep->arg);
289 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE));
290 mempool_free(ep, mp->ep_pool);
291 }
292}
293
294static int fc_exch_done_locked(struct fc_exch *ep)
295{
296 int rc = 1;
297
298
299
300
301
302
303
304 ep->resp = NULL;
305 if (ep->state & FC_EX_DONE)
306 return rc;
307 ep->esb_stat |= ESB_ST_COMPLETE;
308
309 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
310 ep->state |= FC_EX_DONE;
311 if (cancel_delayed_work(&ep->timeout_work))
312 atomic_dec(&ep->ex_refcnt);
313 rc = 0;
314 }
315 return rc;
316}
317
318static inline struct fc_exch *fc_exch_ptr_get(struct fc_exch_pool *pool,
319 u16 index)
320{
321 struct fc_exch **exches = (struct fc_exch **)(pool + 1);
322 return exches[index];
323}
324
325static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
326 struct fc_exch *ep)
327{
328 ((struct fc_exch **)(pool + 1))[index] = ep;
329}
330
331static void fc_exch_delete(struct fc_exch *ep)
332{
333 struct fc_exch_pool *pool;
334
335 pool = ep->pool;
336 spin_lock_bh(&pool->lock);
337 WARN_ON(pool->total_exches <= 0);
338 pool->total_exches--;
339 fc_exch_ptr_set(pool, (ep->xid - ep->em->min_xid) >> fc_cpu_order,
340 NULL);
341 list_del(&ep->ex_list);
342 spin_unlock_bh(&pool->lock);
343 fc_exch_release(ep);
344}
345
346
347
348
349static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
350 unsigned int timer_msec)
351{
352 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
353 return;
354
355 FC_EXCH_DBG(ep, "Exchange timer armed\n");
356
357 if (schedule_delayed_work(&ep->timeout_work,
358 msecs_to_jiffies(timer_msec)))
359 fc_exch_hold(ep);
360}
361
362
363
364
365
366
367
368
369static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec)
370{
371 spin_lock_bh(&ep->ex_lock);
372 fc_exch_timer_set_locked(ep, timer_msec);
373 spin_unlock_bh(&ep->ex_lock);
374}
375
376int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec)
377{
378 struct fc_seq *sp;
379 struct fc_exch *ep;
380 struct fc_frame *fp;
381 int error;
382
383 ep = fc_seq_exch(req_sp);
384
385 spin_lock_bh(&ep->ex_lock);
386 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) ||
387 ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) {
388 spin_unlock_bh(&ep->ex_lock);
389 return -ENXIO;
390 }
391
392
393
394
395 sp = fc_seq_start_next_locked(&ep->seq);
396 if (!sp) {
397 spin_unlock_bh(&ep->ex_lock);
398 return -ENOMEM;
399 }
400
401 ep->esb_stat |= ESB_ST_SEQ_INIT | ESB_ST_ABNORMAL;
402 if (timer_msec)
403 fc_exch_timer_set_locked(ep, timer_msec);
404 spin_unlock_bh(&ep->ex_lock);
405
406
407
408
409
410 if (!ep->sid)
411 return 0;
412
413
414
415
416 fp = fc_frame_alloc(ep->lp, 0);
417 if (fp) {
418 fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
419 FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
420 error = fc_seq_send(ep->lp, sp, fp);
421 } else
422 error = -ENOBUFS;
423 return error;
424}
425EXPORT_SYMBOL(fc_seq_exch_abort);
426
427
428
429
430
431static void fc_exch_timeout(struct work_struct *work)
432{
433 struct fc_exch *ep = container_of(work, struct fc_exch,
434 timeout_work.work);
435 struct fc_seq *sp = &ep->seq;
436 void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
437 void *arg;
438 u32 e_stat;
439 int rc = 1;
440
441 FC_EXCH_DBG(ep, "Exchange timed out\n");
442
443 spin_lock_bh(&ep->ex_lock);
444 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
445 goto unlock;
446
447 e_stat = ep->esb_stat;
448 if (e_stat & ESB_ST_COMPLETE) {
449 ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL;
450 spin_unlock_bh(&ep->ex_lock);
451 if (e_stat & ESB_ST_REC_QUAL)
452 fc_exch_rrq(ep);
453 goto done;
454 } else {
455 resp = ep->resp;
456 arg = ep->arg;
457 ep->resp = NULL;
458 if (e_stat & ESB_ST_ABNORMAL)
459 rc = fc_exch_done_locked(ep);
460 spin_unlock_bh(&ep->ex_lock);
461 if (!rc)
462 fc_exch_delete(ep);
463 if (resp)
464 resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg);
465 fc_seq_exch_abort(sp, 2 * ep->r_a_tov);
466 goto done;
467 }
468unlock:
469 spin_unlock_bh(&ep->ex_lock);
470done:
471
472
473
474 fc_exch_release(ep);
475}
476
477
478
479
480
481
482
483
484static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
485{
486 struct fc_seq *sp;
487
488 sp = &ep->seq;
489 sp->ssb_stat = 0;
490 sp->cnt = 0;
491 sp->id = seq_id;
492 return sp;
493}
494
495
496
497
498
499
500
501
502static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
503 struct fc_exch_mgr *mp)
504{
505 struct fc_exch *ep;
506 unsigned int cpu;
507 u16 index;
508 struct fc_exch_pool *pool;
509
510
511 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
512 if (!ep) {
513 atomic_inc(&mp->stats.no_free_exch);
514 goto out;
515 }
516 memset(ep, 0, sizeof(*ep));
517
518 cpu = smp_processor_id();
519 pool = per_cpu_ptr(mp->pool, cpu);
520 spin_lock_bh(&pool->lock);
521 index = pool->next_index;
522
523 while (fc_exch_ptr_get(pool, index)) {
524 index = index == mp->pool_max_index ? 0 : index + 1;
525 if (index == pool->next_index)
526 goto err;
527 }
528 pool->next_index = index == mp->pool_max_index ? 0 : index + 1;
529
530 fc_exch_hold(ep);
531 spin_lock_init(&ep->ex_lock);
532
533
534
535
536
537 spin_lock_bh(&ep->ex_lock);
538
539 fc_exch_ptr_set(pool, index, ep);
540 list_add_tail(&ep->ex_list, &pool->ex_list);
541 fc_seq_alloc(ep, ep->seq_id++);
542 pool->total_exches++;
543 spin_unlock_bh(&pool->lock);
544
545
546
547
548 ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid;
549 ep->em = mp;
550 ep->pool = pool;
551 ep->lp = lport;
552 ep->f_ctl = FC_FC_FIRST_SEQ;
553 ep->rxid = FC_XID_UNKNOWN;
554 ep->class = mp->class;
555 INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout);
556out:
557 return ep;
558err:
559 spin_unlock_bh(&pool->lock);
560 atomic_inc(&mp->stats.no_free_exch_xid);
561 mempool_free(ep, mp->ep_pool);
562 return NULL;
563}
564
565
566
567
568
569
570
571
572
573
574
575struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp)
576{
577 struct fc_exch_mgr_anchor *ema;
578 struct fc_exch *ep;
579
580 list_for_each_entry(ema, &lport->ema_list, ema_list) {
581 if (!ema->match || ema->match(fp)) {
582 ep = fc_exch_em_alloc(lport, ema->mp);
583 if (ep)
584 return ep;
585 }
586 }
587 return NULL;
588}
589EXPORT_SYMBOL(fc_exch_alloc);
590
591
592
593
594static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid)
595{
596 struct fc_exch_pool *pool;
597 struct fc_exch *ep = NULL;
598
599 if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) {
600 pool = per_cpu_ptr(mp->pool, xid & fc_cpu_mask);
601 spin_lock_bh(&pool->lock);
602 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order);
603 if (ep) {
604 fc_exch_hold(ep);
605 WARN_ON(ep->xid != xid);
606 }
607 spin_unlock_bh(&pool->lock);
608 }
609 return ep;
610}
611
612void fc_exch_done(struct fc_seq *sp)
613{
614 struct fc_exch *ep = fc_seq_exch(sp);
615 int rc;
616
617 spin_lock_bh(&ep->ex_lock);
618 rc = fc_exch_done_locked(ep);
619 spin_unlock_bh(&ep->ex_lock);
620 if (!rc)
621 fc_exch_delete(ep);
622}
623EXPORT_SYMBOL(fc_exch_done);
624
625
626
627
628
629static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
630 struct fc_exch_mgr *mp,
631 struct fc_frame *fp)
632{
633 struct fc_exch *ep;
634 struct fc_frame_header *fh;
635
636 ep = fc_exch_alloc(lport, fp);
637 if (ep) {
638 ep->class = fc_frame_class(fp);
639
640
641
642
643 ep->f_ctl |= FC_FC_EX_CTX;
644 ep->f_ctl &= ~FC_FC_FIRST_SEQ;
645 fh = fc_frame_header_get(fp);
646 ep->sid = ntoh24(fh->fh_d_id);
647 ep->did = ntoh24(fh->fh_s_id);
648 ep->oid = ep->did;
649
650
651
652
653
654
655 ep->rxid = ep->xid;
656 ep->oxid = ntohs(fh->fh_ox_id);
657 ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT;
658 if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0)
659 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
660
661 fc_exch_hold(ep);
662 spin_unlock_bh(&ep->ex_lock);
663 }
664 return ep;
665}
666
667
668
669
670
671
672static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
673 struct fc_exch_mgr *mp,
674 struct fc_frame *fp)
675{
676 struct fc_frame_header *fh = fc_frame_header_get(fp);
677 struct fc_exch *ep = NULL;
678 struct fc_seq *sp = NULL;
679 enum fc_pf_rjt_reason reject = FC_RJT_NONE;
680 u32 f_ctl;
681 u16 xid;
682
683 f_ctl = ntoh24(fh->fh_f_ctl);
684 WARN_ON((f_ctl & FC_FC_SEQ_CTX) != 0);
685
686
687
688
689 if (f_ctl & FC_FC_EX_CTX) {
690 xid = ntohs(fh->fh_ox_id);
691 ep = fc_exch_find(mp, xid);
692 if (!ep) {
693 atomic_inc(&mp->stats.xid_not_found);
694 reject = FC_RJT_OX_ID;
695 goto out;
696 }
697 if (ep->rxid == FC_XID_UNKNOWN)
698 ep->rxid = ntohs(fh->fh_rx_id);
699 else if (ep->rxid != ntohs(fh->fh_rx_id)) {
700 reject = FC_RJT_OX_ID;
701 goto rel;
702 }
703 } else {
704 xid = ntohs(fh->fh_rx_id);
705
706
707
708
709
710
711 if (xid == 0 && fh->fh_r_ctl == FC_RCTL_ELS_REQ &&
712 fc_frame_payload_op(fp) == ELS_TEST) {
713 fh->fh_rx_id = htons(FC_XID_UNKNOWN);
714 xid = FC_XID_UNKNOWN;
715 }
716
717
718
719
720 ep = fc_exch_find(mp, xid);
721 if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
722 if (ep) {
723 atomic_inc(&mp->stats.xid_busy);
724 reject = FC_RJT_RX_ID;
725 goto rel;
726 }
727 ep = fc_exch_resp(lport, mp, fp);
728 if (!ep) {
729 reject = FC_RJT_EXCH_EST;
730 goto out;
731 }
732 xid = ep->xid;
733 } else if (!ep) {
734 atomic_inc(&mp->stats.xid_not_found);
735 reject = FC_RJT_RX_ID;
736 goto out;
737 }
738 }
739
740
741
742
743
744 if (fc_sof_is_init(fr_sof(fp))) {
745 sp = fc_seq_start_next(&ep->seq);
746 if (!sp) {
747 reject = FC_RJT_SEQ_XS;
748 goto rel;
749 }
750 sp->id = fh->fh_seq_id;
751 sp->ssb_stat |= SSB_ST_RESP;
752 } else {
753 sp = &ep->seq;
754 if (sp->id != fh->fh_seq_id) {
755 atomic_inc(&mp->stats.seq_not_found);
756 reject = FC_RJT_SEQ_ID;
757 goto rel;
758 }
759 }
760 WARN_ON(ep != fc_seq_exch(sp));
761
762 if (f_ctl & FC_FC_SEQ_INIT)
763 ep->esb_stat |= ESB_ST_SEQ_INIT;
764
765 fr_seq(fp) = sp;
766out:
767 return reject;
768rel:
769 fc_exch_done(&ep->seq);
770 fc_exch_release(ep);
771 return reject;
772}
773
774
775
776
777
778
779
780static struct fc_seq *fc_seq_lookup_orig(struct fc_exch_mgr *mp,
781 struct fc_frame *fp)
782{
783 struct fc_frame_header *fh = fc_frame_header_get(fp);
784 struct fc_exch *ep;
785 struct fc_seq *sp = NULL;
786 u32 f_ctl;
787 u16 xid;
788
789 f_ctl = ntoh24(fh->fh_f_ctl);
790 WARN_ON((f_ctl & FC_FC_SEQ_CTX) != FC_FC_SEQ_CTX);
791 xid = ntohs((f_ctl & FC_FC_EX_CTX) ? fh->fh_ox_id : fh->fh_rx_id);
792 ep = fc_exch_find(mp, xid);
793 if (!ep)
794 return NULL;
795 if (ep->seq.id == fh->fh_seq_id) {
796
797
798
799 sp = &ep->seq;
800 if ((f_ctl & FC_FC_EX_CTX) != 0 &&
801 ep->rxid == FC_XID_UNKNOWN) {
802 ep->rxid = ntohs(fh->fh_rx_id);
803 }
804 }
805 fc_exch_release(ep);
806 return sp;
807}
808
809
810
811
812
813static void fc_exch_set_addr(struct fc_exch *ep,
814 u32 orig_id, u32 resp_id)
815{
816 ep->oid = orig_id;
817 if (ep->esb_stat & ESB_ST_RESP) {
818 ep->sid = resp_id;
819 ep->did = orig_id;
820 } else {
821 ep->sid = orig_id;
822 ep->did = resp_id;
823 }
824}
825
826static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
827{
828 struct fc_exch *ep = fc_seq_exch(sp);
829
830 sp = fc_seq_alloc(ep, ep->seq_id++);
831 FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
832 ep->f_ctl, sp->id);
833 return sp;
834}
835
836
837
838
839struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
840{
841 struct fc_exch *ep = fc_seq_exch(sp);
842
843 spin_lock_bh(&ep->ex_lock);
844 sp = fc_seq_start_next_locked(sp);
845 spin_unlock_bh(&ep->ex_lock);
846
847 return sp;
848}
849EXPORT_SYMBOL(fc_seq_start_next);
850
851int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp)
852{
853 struct fc_exch *ep;
854 struct fc_frame_header *fh = fc_frame_header_get(fp);
855 int error;
856 u32 f_ctl;
857
858 ep = fc_seq_exch(sp);
859 WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
860
861 f_ctl = ntoh24(fh->fh_f_ctl);
862 fc_exch_setup_hdr(ep, fp, f_ctl);
863
864
865
866
867
868
869 if (fr_max_payload(fp))
870 sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
871 fr_max_payload(fp));
872 else
873 sp->cnt++;
874
875
876
877
878 error = lp->tt.frame_send(lp, fp);
879
880
881
882
883
884
885 spin_lock_bh(&ep->ex_lock);
886 ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;
887 if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT))
888 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
889 spin_unlock_bh(&ep->ex_lock);
890 return error;
891}
892EXPORT_SYMBOL(fc_seq_send);
893
894void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
895 struct fc_seq_els_data *els_data)
896{
897 switch (els_cmd) {
898 case ELS_LS_RJT:
899 fc_seq_ls_rjt(sp, els_data->reason, els_data->explan);
900 break;
901 case ELS_LS_ACC:
902 fc_seq_ls_acc(sp);
903 break;
904 case ELS_RRQ:
905 fc_exch_els_rrq(sp, els_data->fp);
906 break;
907 case ELS_REC:
908 fc_exch_els_rec(sp, els_data->fp);
909 break;
910 default:
911 FC_EXCH_DBG(fc_seq_exch(sp), "Invalid ELS CMD:%x\n", els_cmd);
912 }
913}
914EXPORT_SYMBOL(fc_seq_els_rsp_send);
915
916
917
918
919static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
920 enum fc_rctl rctl, enum fc_fh_type fh_type)
921{
922 u32 f_ctl;
923 struct fc_exch *ep = fc_seq_exch(sp);
924
925 f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
926 f_ctl |= ep->f_ctl;
927 fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0);
928 fc_seq_send(ep->lp, sp, fp);
929}
930
931
932
933
934
935static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
936{
937 struct fc_frame *fp;
938 struct fc_frame_header *rx_fh;
939 struct fc_frame_header *fh;
940 struct fc_exch *ep = fc_seq_exch(sp);
941 struct fc_lport *lp = ep->lp;
942 unsigned int f_ctl;
943
944
945
946
947 if (fc_sof_needs_ack(fr_sof(rx_fp))) {
948 fp = fc_frame_alloc(lp, 0);
949 if (!fp)
950 return;
951
952 fh = fc_frame_header_get(fp);
953 fh->fh_r_ctl = FC_RCTL_ACK_1;
954 fh->fh_type = FC_TYPE_BLS;
955
956
957
958
959
960
961
962
963 rx_fh = fc_frame_header_get(rx_fp);
964 f_ctl = ntoh24(rx_fh->fh_f_ctl);
965 f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX |
966 FC_FC_FIRST_SEQ | FC_FC_LAST_SEQ |
967 FC_FC_END_SEQ | FC_FC_END_CONN | FC_FC_SEQ_INIT |
968 FC_FC_RETX_SEQ | FC_FC_UNI_TX;
969 f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
970 hton24(fh->fh_f_ctl, f_ctl);
971
972 fc_exch_setup_hdr(ep, fp, f_ctl);
973 fh->fh_seq_id = rx_fh->fh_seq_id;
974 fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
975 fh->fh_parm_offset = htonl(1);
976
977 fr_sof(fp) = fr_sof(rx_fp);
978 if (f_ctl & FC_FC_END_SEQ)
979 fr_eof(fp) = FC_EOF_T;
980 else
981 fr_eof(fp) = FC_EOF_N;
982
983 (void) lp->tt.frame_send(lp, fp);
984 }
985}
986
987
988
989
990
991static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
992 enum fc_ba_rjt_reason reason,
993 enum fc_ba_rjt_explan explan)
994{
995 struct fc_frame *fp;
996 struct fc_frame_header *rx_fh;
997 struct fc_frame_header *fh;
998 struct fc_ba_rjt *rp;
999 struct fc_lport *lp;
1000 unsigned int f_ctl;
1001
1002 lp = fr_dev(rx_fp);
1003 fp = fc_frame_alloc(lp, sizeof(*rp));
1004 if (!fp)
1005 return;
1006 fh = fc_frame_header_get(fp);
1007 rx_fh = fc_frame_header_get(rx_fp);
1008
1009 memset(fh, 0, sizeof(*fh) + sizeof(*rp));
1010
1011 rp = fc_frame_payload_get(fp, sizeof(*rp));
1012 rp->br_reason = reason;
1013 rp->br_explan = explan;
1014
1015
1016
1017
1018 memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3);
1019 memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3);
1020 fh->fh_ox_id = rx_fh->fh_ox_id;
1021 fh->fh_rx_id = rx_fh->fh_rx_id;
1022 fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
1023 fh->fh_r_ctl = FC_RCTL_BA_RJT;
1024 fh->fh_type = FC_TYPE_BLS;
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034 f_ctl = ntoh24(rx_fh->fh_f_ctl);
1035 f_ctl &= FC_FC_EX_CTX | FC_FC_SEQ_CTX |
1036 FC_FC_END_CONN | FC_FC_SEQ_INIT |
1037 FC_FC_RETX_SEQ | FC_FC_UNI_TX;
1038 f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
1039 f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ;
1040 f_ctl &= ~FC_FC_FIRST_SEQ;
1041 hton24(fh->fh_f_ctl, f_ctl);
1042
1043 fr_sof(fp) = fc_sof_class(fr_sof(rx_fp));
1044 fr_eof(fp) = FC_EOF_T;
1045 if (fc_sof_needs_ack(fr_sof(fp)))
1046 fr_eof(fp) = FC_EOF_N;
1047
1048 (void) lp->tt.frame_send(lp, fp);
1049}
1050
1051
1052
1053
1054
1055
1056static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
1057{
1058 struct fc_frame *fp;
1059 struct fc_ba_acc *ap;
1060 struct fc_frame_header *fh;
1061 struct fc_seq *sp;
1062
1063 if (!ep)
1064 goto reject;
1065 spin_lock_bh(&ep->ex_lock);
1066 if (ep->esb_stat & ESB_ST_COMPLETE) {
1067 spin_unlock_bh(&ep->ex_lock);
1068 goto reject;
1069 }
1070 if (!(ep->esb_stat & ESB_ST_REC_QUAL))
1071 fc_exch_hold(ep);
1072 ep->esb_stat |= ESB_ST_ABNORMAL | ESB_ST_REC_QUAL;
1073 fc_exch_timer_set_locked(ep, ep->r_a_tov);
1074
1075 fp = fc_frame_alloc(ep->lp, sizeof(*ap));
1076 if (!fp) {
1077 spin_unlock_bh(&ep->ex_lock);
1078 goto free;
1079 }
1080 fh = fc_frame_header_get(fp);
1081 ap = fc_frame_payload_get(fp, sizeof(*ap));
1082 memset(ap, 0, sizeof(*ap));
1083 sp = &ep->seq;
1084 ap->ba_high_seq_cnt = htons(0xffff);
1085 if (sp->ssb_stat & SSB_ST_RESP) {
1086 ap->ba_seq_id = sp->id;
1087 ap->ba_seq_id_val = FC_BA_SEQ_ID_VAL;
1088 ap->ba_high_seq_cnt = fh->fh_seq_cnt;
1089 ap->ba_low_seq_cnt = htons(sp->cnt);
1090 }
1091 sp = fc_seq_start_next_locked(sp);
1092 spin_unlock_bh(&ep->ex_lock);
1093 fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
1094 fc_frame_free(rx_fp);
1095 return;
1096
1097reject:
1098 fc_exch_send_ba_rjt(rx_fp, FC_BA_RJT_UNABLE, FC_BA_RJT_INV_XID);
1099free:
1100 fc_frame_free(rx_fp);
1101}
1102
1103
1104
1105
1106static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
1107 struct fc_frame *fp)
1108{
1109 struct fc_frame_header *fh = fc_frame_header_get(fp);
1110 struct fc_seq *sp = NULL;
1111 struct fc_exch *ep = NULL;
1112 enum fc_sof sof;
1113 enum fc_eof eof;
1114 u32 f_ctl;
1115 enum fc_pf_rjt_reason reject;
1116
1117 fr_seq(fp) = NULL;
1118 reject = fc_seq_lookup_recip(lp, mp, fp);
1119 if (reject == FC_RJT_NONE) {
1120 sp = fr_seq(fp);
1121 ep = fc_seq_exch(sp);
1122 sof = fr_sof(fp);
1123 eof = fr_eof(fp);
1124 f_ctl = ntoh24(fh->fh_f_ctl);
1125 fc_seq_send_ack(sp, fp);
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138 if (ep->resp)
1139 ep->resp(sp, fp, ep->arg);
1140 else
1141 lp->tt.lport_recv(lp, sp, fp);
1142 fc_exch_release(ep);
1143 } else {
1144 FC_LPORT_DBG(lp, "exch/seq lookup failed: reject %x\n", reject);
1145 fc_frame_free(fp);
1146 }
1147}
1148
1149
1150
1151
1152
1153static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1154{
1155 struct fc_frame_header *fh = fc_frame_header_get(fp);
1156 struct fc_seq *sp;
1157 struct fc_exch *ep;
1158 enum fc_sof sof;
1159 u32 f_ctl;
1160 void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
1161 void *ex_resp_arg;
1162 int rc;
1163
1164 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
1165 if (!ep) {
1166 atomic_inc(&mp->stats.xid_not_found);
1167 goto out;
1168 }
1169 if (ep->esb_stat & ESB_ST_COMPLETE) {
1170 atomic_inc(&mp->stats.xid_not_found);
1171 goto out;
1172 }
1173 if (ep->rxid == FC_XID_UNKNOWN)
1174 ep->rxid = ntohs(fh->fh_rx_id);
1175 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
1176 atomic_inc(&mp->stats.xid_not_found);
1177 goto rel;
1178 }
1179 if (ep->did != ntoh24(fh->fh_s_id) &&
1180 ep->did != FC_FID_FLOGI) {
1181 atomic_inc(&mp->stats.xid_not_found);
1182 goto rel;
1183 }
1184 sof = fr_sof(fp);
1185 if (fc_sof_is_init(sof)) {
1186 sp = fc_seq_start_next(&ep->seq);
1187 sp->id = fh->fh_seq_id;
1188 sp->ssb_stat |= SSB_ST_RESP;
1189 } else {
1190 sp = &ep->seq;
1191 if (sp->id != fh->fh_seq_id) {
1192 atomic_inc(&mp->stats.seq_not_found);
1193 goto rel;
1194 }
1195 }
1196 f_ctl = ntoh24(fh->fh_f_ctl);
1197 fr_seq(fp) = sp;
1198 if (f_ctl & FC_FC_SEQ_INIT)
1199 ep->esb_stat |= ESB_ST_SEQ_INIT;
1200
1201 if (fc_sof_needs_ack(sof))
1202 fc_seq_send_ack(sp, fp);
1203 resp = ep->resp;
1204 ex_resp_arg = ep->arg;
1205
1206 if (fh->fh_type != FC_TYPE_FCP && fr_eof(fp) == FC_EOF_T &&
1207 (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
1208 (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
1209 spin_lock_bh(&ep->ex_lock);
1210 rc = fc_exch_done_locked(ep);
1211 WARN_ON(fc_seq_exch(sp) != ep);
1212 spin_unlock_bh(&ep->ex_lock);
1213 if (!rc)
1214 fc_exch_delete(ep);
1215 }
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230 if (resp)
1231 resp(sp, fp, ex_resp_arg);
1232 else
1233 fc_frame_free(fp);
1234 fc_exch_release(ep);
1235 return;
1236rel:
1237 fc_exch_release(ep);
1238out:
1239 fc_frame_free(fp);
1240}
1241
1242
1243
1244
1245static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1246{
1247 struct fc_seq *sp;
1248
1249 sp = fc_seq_lookup_orig(mp, fp);
1250
1251 if (!sp)
1252 atomic_inc(&mp->stats.xid_not_found);
1253 else
1254 atomic_inc(&mp->stats.non_bls_resp);
1255
1256 fc_frame_free(fp);
1257}
1258
1259
1260
1261
1262
1263static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
1264{
1265 void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
1266 void *ex_resp_arg;
1267 struct fc_frame_header *fh;
1268 struct fc_ba_acc *ap;
1269 struct fc_seq *sp;
1270 u16 low;
1271 u16 high;
1272 int rc = 1, has_rec = 0;
1273
1274 fh = fc_frame_header_get(fp);
1275 FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl,
1276 fc_exch_rctl_name(fh->fh_r_ctl));
1277
1278 if (cancel_delayed_work_sync(&ep->timeout_work))
1279 fc_exch_release(ep);
1280
1281 spin_lock_bh(&ep->ex_lock);
1282 switch (fh->fh_r_ctl) {
1283 case FC_RCTL_BA_ACC:
1284 ap = fc_frame_payload_get(fp, sizeof(*ap));
1285 if (!ap)
1286 break;
1287
1288
1289
1290
1291
1292
1293 low = ntohs(ap->ba_low_seq_cnt);
1294 high = ntohs(ap->ba_high_seq_cnt);
1295 if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 &&
1296 (ap->ba_seq_id_val != FC_BA_SEQ_ID_VAL ||
1297 ap->ba_seq_id == ep->seq_id) && low != high) {
1298 ep->esb_stat |= ESB_ST_REC_QUAL;
1299 fc_exch_hold(ep);
1300 has_rec = 1;
1301 }
1302 break;
1303 case FC_RCTL_BA_RJT:
1304 break;
1305 default:
1306 break;
1307 }
1308
1309 resp = ep->resp;
1310 ex_resp_arg = ep->arg;
1311
1312
1313
1314
1315 sp = &ep->seq;
1316
1317
1318
1319 if (ep->fh_type != FC_TYPE_FCP &&
1320 ntoh24(fh->fh_f_ctl) & FC_FC_LAST_SEQ)
1321 rc = fc_exch_done_locked(ep);
1322 spin_unlock_bh(&ep->ex_lock);
1323 if (!rc)
1324 fc_exch_delete(ep);
1325
1326 if (resp)
1327 resp(sp, fp, ex_resp_arg);
1328 else
1329 fc_frame_free(fp);
1330
1331 if (has_rec)
1332 fc_exch_timer_set(ep, ep->r_a_tov);
1333
1334}
1335
1336
1337
1338
1339
1340
1341static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
1342{
1343 struct fc_frame_header *fh;
1344 struct fc_exch *ep;
1345 u32 f_ctl;
1346
1347 fh = fc_frame_header_get(fp);
1348 f_ctl = ntoh24(fh->fh_f_ctl);
1349 fr_seq(fp) = NULL;
1350
1351 ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ?
1352 ntohs(fh->fh_ox_id) : ntohs(fh->fh_rx_id));
1353 if (ep && (f_ctl & FC_FC_SEQ_INIT)) {
1354 spin_lock_bh(&ep->ex_lock);
1355 ep->esb_stat |= ESB_ST_SEQ_INIT;
1356 spin_unlock_bh(&ep->ex_lock);
1357 }
1358 if (f_ctl & FC_FC_SEQ_CTX) {
1359
1360
1361
1362
1363 switch (fh->fh_r_ctl) {
1364 case FC_RCTL_ACK_1:
1365 case FC_RCTL_ACK_0:
1366 break;
1367 default:
1368 FC_EXCH_DBG(ep, "BLS rctl %x - %s received",
1369 fh->fh_r_ctl,
1370 fc_exch_rctl_name(fh->fh_r_ctl));
1371 break;
1372 }
1373 fc_frame_free(fp);
1374 } else {
1375 switch (fh->fh_r_ctl) {
1376 case FC_RCTL_BA_RJT:
1377 case FC_RCTL_BA_ACC:
1378 if (ep)
1379 fc_exch_abts_resp(ep, fp);
1380 else
1381 fc_frame_free(fp);
1382 break;
1383 case FC_RCTL_BA_ABTS:
1384 fc_exch_recv_abts(ep, fp);
1385 break;
1386 default:
1387 fc_frame_free(fp);
1388 break;
1389 }
1390 }
1391 if (ep)
1392 fc_exch_release(ep);
1393}
1394
1395
1396
1397
1398
1399
1400static void fc_seq_ls_acc(struct fc_seq *req_sp)
1401{
1402 struct fc_seq *sp;
1403 struct fc_els_ls_acc *acc;
1404 struct fc_frame *fp;
1405
1406 sp = fc_seq_start_next(req_sp);
1407 fp = fc_frame_alloc(fc_seq_exch(sp)->lp, sizeof(*acc));
1408 if (fp) {
1409 acc = fc_frame_payload_get(fp, sizeof(*acc));
1410 memset(acc, 0, sizeof(*acc));
1411 acc->la_cmd = ELS_LS_ACC;
1412 fc_seq_send_last(sp, fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
1413 }
1414}
1415
1416
1417
1418
1419
1420
1421static void fc_seq_ls_rjt(struct fc_seq *req_sp, enum fc_els_rjt_reason reason,
1422 enum fc_els_rjt_explan explan)
1423{
1424 struct fc_seq *sp;
1425 struct fc_els_ls_rjt *rjt;
1426 struct fc_frame *fp;
1427
1428 sp = fc_seq_start_next(req_sp);
1429 fp = fc_frame_alloc(fc_seq_exch(sp)->lp, sizeof(*rjt));
1430 if (fp) {
1431 rjt = fc_frame_payload_get(fp, sizeof(*rjt));
1432 memset(rjt, 0, sizeof(*rjt));
1433 rjt->er_cmd = ELS_LS_RJT;
1434 rjt->er_reason = reason;
1435 rjt->er_explan = explan;
1436 fc_seq_send_last(sp, fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
1437 }
1438}
1439
1440static void fc_exch_reset(struct fc_exch *ep)
1441{
1442 struct fc_seq *sp;
1443 void (*resp)(struct fc_seq *, struct fc_frame *, void *);
1444 void *arg;
1445 int rc = 1;
1446
1447 spin_lock_bh(&ep->ex_lock);
1448 ep->state |= FC_EX_RST_CLEANUP;
1449
1450
1451
1452
1453
1454
1455 if (cancel_delayed_work(&ep->timeout_work))
1456 atomic_dec(&ep->ex_refcnt);
1457 resp = ep->resp;
1458 ep->resp = NULL;
1459 if (ep->esb_stat & ESB_ST_REC_QUAL)
1460 atomic_dec(&ep->ex_refcnt);
1461 ep->esb_stat &= ~ESB_ST_REC_QUAL;
1462 arg = ep->arg;
1463 sp = &ep->seq;
1464 rc = fc_exch_done_locked(ep);
1465 spin_unlock_bh(&ep->ex_lock);
1466 if (!rc)
1467 fc_exch_delete(ep);
1468
1469 if (resp)
1470 resp(sp, ERR_PTR(-FC_EX_CLOSED), arg);
1471}
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485static void fc_exch_pool_reset(struct fc_lport *lport,
1486 struct fc_exch_pool *pool,
1487 u32 sid, u32 did)
1488{
1489 struct fc_exch *ep;
1490 struct fc_exch *next;
1491
1492 spin_lock_bh(&pool->lock);
1493restart:
1494 list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) {
1495 if ((lport == ep->lp) &&
1496 (sid == 0 || sid == ep->sid) &&
1497 (did == 0 || did == ep->did)) {
1498 fc_exch_hold(ep);
1499 spin_unlock_bh(&pool->lock);
1500
1501 fc_exch_reset(ep);
1502
1503 fc_exch_release(ep);
1504 spin_lock_bh(&pool->lock);
1505
1506
1507
1508
1509
1510 goto restart;
1511 }
1512 }
1513 spin_unlock_bh(&pool->lock);
1514}
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527void fc_exch_mgr_reset(struct fc_lport *lport, u32 sid, u32 did)
1528{
1529 struct fc_exch_mgr_anchor *ema;
1530 unsigned int cpu;
1531
1532 list_for_each_entry(ema, &lport->ema_list, ema_list) {
1533 for_each_possible_cpu(cpu)
1534 fc_exch_pool_reset(lport,
1535 per_cpu_ptr(ema->mp->pool, cpu),
1536 sid, did);
1537 }
1538}
1539EXPORT_SYMBOL(fc_exch_mgr_reset);
1540
1541
1542
1543
1544
1545static void fc_exch_els_rec(struct fc_seq *sp, struct fc_frame *rfp)
1546{
1547 struct fc_frame *fp;
1548 struct fc_exch *ep;
1549 struct fc_exch_mgr *em;
1550 struct fc_els_rec *rp;
1551 struct fc_els_rec_acc *acc;
1552 enum fc_els_rjt_reason reason = ELS_RJT_LOGIC;
1553 enum fc_els_rjt_explan explan;
1554 u32 sid;
1555 u16 rxid;
1556 u16 oxid;
1557
1558 rp = fc_frame_payload_get(rfp, sizeof(*rp));
1559 explan = ELS_EXPL_INV_LEN;
1560 if (!rp)
1561 goto reject;
1562 sid = ntoh24(rp->rec_s_id);
1563 rxid = ntohs(rp->rec_rx_id);
1564 oxid = ntohs(rp->rec_ox_id);
1565
1566
1567
1568
1569
1570
1571
1572 em = fc_seq_exch(sp)->em;
1573 ep = fc_exch_find(em, oxid);
1574 explan = ELS_EXPL_OXID_RXID;
1575 if (ep && ep->oid == sid) {
1576 if (ep->rxid != FC_XID_UNKNOWN &&
1577 rxid != FC_XID_UNKNOWN &&
1578 ep->rxid != rxid)
1579 goto rel;
1580 } else {
1581 if (ep)
1582 fc_exch_release(ep);
1583 ep = NULL;
1584 if (rxid != FC_XID_UNKNOWN)
1585 ep = fc_exch_find(em, rxid);
1586 if (!ep)
1587 goto reject;
1588 }
1589
1590 fp = fc_frame_alloc(fc_seq_exch(sp)->lp, sizeof(*acc));
1591 if (!fp) {
1592 fc_exch_done(sp);
1593 goto out;
1594 }
1595 sp = fc_seq_start_next(sp);
1596 acc = fc_frame_payload_get(fp, sizeof(*acc));
1597 memset(acc, 0, sizeof(*acc));
1598 acc->reca_cmd = ELS_LS_ACC;
1599 acc->reca_ox_id = rp->rec_ox_id;
1600 memcpy(acc->reca_ofid, rp->rec_s_id, 3);
1601 acc->reca_rx_id = htons(ep->rxid);
1602 if (ep->sid == ep->oid)
1603 hton24(acc->reca_rfid, ep->did);
1604 else
1605 hton24(acc->reca_rfid, ep->sid);
1606 acc->reca_fc4value = htonl(ep->seq.rec_data);
1607 acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP |
1608 ESB_ST_SEQ_INIT |
1609 ESB_ST_COMPLETE));
1610 sp = fc_seq_start_next(sp);
1611 fc_seq_send_last(sp, fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
1612out:
1613 fc_exch_release(ep);
1614 fc_frame_free(rfp);
1615 return;
1616
1617rel:
1618 fc_exch_release(ep);
1619reject:
1620 fc_seq_ls_rjt(sp, reason, explan);
1621 fc_frame_free(rfp);
1622}
1623
1624
1625
1626
1627
1628
1629
1630
1631static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
1632{
1633 struct fc_exch *aborted_ep = arg;
1634 unsigned int op;
1635
1636 if (IS_ERR(fp)) {
1637 int err = PTR_ERR(fp);
1638
1639 if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT)
1640 goto cleanup;
1641 FC_EXCH_DBG(aborted_ep, "Cannot process RRQ, "
1642 "frame error %d\n", err);
1643 return;
1644 }
1645
1646 op = fc_frame_payload_op(fp);
1647 fc_frame_free(fp);
1648
1649 switch (op) {
1650 case ELS_LS_RJT:
1651 FC_EXCH_DBG(aborted_ep, "LS_RJT for RRQ");
1652
1653 case ELS_LS_ACC:
1654 goto cleanup;
1655 default:
1656 FC_EXCH_DBG(aborted_ep, "unexpected response op %x "
1657 "for RRQ", op);
1658 return;
1659 }
1660
1661cleanup:
1662 fc_exch_done(&aborted_ep->seq);
1663
1664 fc_exch_release(aborted_ep);
1665}
1666
1667
1668
1669
1670
1671
1672static void fc_exch_rrq(struct fc_exch *ep)
1673{
1674 struct fc_lport *lp;
1675 struct fc_els_rrq *rrq;
1676 struct fc_frame *fp;
1677 u32 did;
1678
1679 lp = ep->lp;
1680
1681 fp = fc_frame_alloc(lp, sizeof(*rrq));
1682 if (!fp)
1683 goto retry;
1684
1685 rrq = fc_frame_payload_get(fp, sizeof(*rrq));
1686 memset(rrq, 0, sizeof(*rrq));
1687 rrq->rrq_cmd = ELS_RRQ;
1688 hton24(rrq->rrq_s_id, ep->sid);
1689 rrq->rrq_ox_id = htons(ep->oxid);
1690 rrq->rrq_rx_id = htons(ep->rxid);
1691
1692 did = ep->did;
1693 if (ep->esb_stat & ESB_ST_RESP)
1694 did = ep->sid;
1695
1696 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did,
1697 fc_host_port_id(lp->host), FC_TYPE_ELS,
1698 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
1699
1700 if (fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep, lp->e_d_tov))
1701 return;
1702
1703retry:
1704 spin_lock_bh(&ep->ex_lock);
1705 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) {
1706 spin_unlock_bh(&ep->ex_lock);
1707
1708 fc_exch_release(ep);
1709 return;
1710 }
1711 ep->esb_stat |= ESB_ST_REC_QUAL;
1712 fc_exch_timer_set_locked(ep, ep->r_a_tov);
1713 spin_unlock_bh(&ep->ex_lock);
1714}
1715
1716
1717
1718
1719
1720static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp)
1721{
1722 struct fc_exch *ep;
1723 struct fc_els_rrq *rp;
1724 u32 sid;
1725 u16 xid;
1726 enum fc_els_rjt_explan explan;
1727
1728 rp = fc_frame_payload_get(fp, sizeof(*rp));
1729 explan = ELS_EXPL_INV_LEN;
1730 if (!rp)
1731 goto reject;
1732
1733
1734
1735
1736 ep = fc_seq_exch(sp);
1737 sid = ntoh24(rp->rrq_s_id);
1738 xid = ep->did == sid ? ntohs(rp->rrq_ox_id) : ntohs(rp->rrq_rx_id);
1739 ep = fc_exch_find(ep->em, xid);
1740
1741 explan = ELS_EXPL_OXID_RXID;
1742 if (!ep)
1743 goto reject;
1744 spin_lock_bh(&ep->ex_lock);
1745 if (ep->oxid != ntohs(rp->rrq_ox_id))
1746 goto unlock_reject;
1747 if (ep->rxid != ntohs(rp->rrq_rx_id) &&
1748 ep->rxid != FC_XID_UNKNOWN)
1749 goto unlock_reject;
1750 explan = ELS_EXPL_SID;
1751 if (ep->sid != sid)
1752 goto unlock_reject;
1753
1754
1755
1756
1757 if (ep->esb_stat & ESB_ST_REC_QUAL) {
1758 ep->esb_stat &= ~ESB_ST_REC_QUAL;
1759 atomic_dec(&ep->ex_refcnt);
1760 }
1761 if (ep->esb_stat & ESB_ST_COMPLETE) {
1762 if (cancel_delayed_work(&ep->timeout_work))
1763 atomic_dec(&ep->ex_refcnt);
1764 }
1765
1766 spin_unlock_bh(&ep->ex_lock);
1767
1768
1769
1770
1771 fc_seq_ls_acc(sp);
1772 fc_frame_free(fp);
1773 return;
1774
1775unlock_reject:
1776 spin_unlock_bh(&ep->ex_lock);
1777 fc_exch_release(ep);
1778reject:
1779 fc_seq_ls_rjt(sp, ELS_RJT_LOGIC, explan);
1780 fc_frame_free(fp);
1781}
1782
1783struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
1784 struct fc_exch_mgr *mp,
1785 bool (*match)(struct fc_frame *))
1786{
1787 struct fc_exch_mgr_anchor *ema;
1788
1789 ema = kmalloc(sizeof(*ema), GFP_ATOMIC);
1790 if (!ema)
1791 return ema;
1792
1793 ema->mp = mp;
1794 ema->match = match;
1795
1796 list_add_tail(&ema->ema_list, &lport->ema_list);
1797 kref_get(&mp->kref);
1798 return ema;
1799}
1800EXPORT_SYMBOL(fc_exch_mgr_add);
1801
1802static void fc_exch_mgr_destroy(struct kref *kref)
1803{
1804 struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
1805
1806 mempool_destroy(mp->ep_pool);
1807 free_percpu(mp->pool);
1808 kfree(mp);
1809}
1810
1811void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
1812{
1813
1814 list_del(&ema->ema_list);
1815 kref_put(&ema->mp->kref, fc_exch_mgr_destroy);
1816 kfree(ema);
1817}
1818EXPORT_SYMBOL(fc_exch_mgr_del);
1819
1820struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
1821 enum fc_class class,
1822 u16 min_xid, u16 max_xid,
1823 bool (*match)(struct fc_frame *))
1824{
1825 struct fc_exch_mgr *mp;
1826 u16 pool_exch_range;
1827 size_t pool_size;
1828 unsigned int cpu;
1829 struct fc_exch_pool *pool;
1830
1831 if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN ||
1832 (min_xid & fc_cpu_mask) != 0) {
1833 FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
1834 min_xid, max_xid);
1835 return NULL;
1836 }
1837
1838
1839
1840
1841 mp = kzalloc(sizeof(struct fc_exch_mgr), GFP_ATOMIC);
1842 if (!mp)
1843 return NULL;
1844
1845 mp->class = class;
1846
1847 mp->min_xid = min_xid;
1848 mp->max_xid = max_xid;
1849
1850 mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep);
1851 if (!mp->ep_pool)
1852 goto free_mp;
1853
1854
1855
1856
1857
1858
1859 pool_exch_range = (mp->max_xid - mp->min_xid + 1) / (fc_cpu_mask + 1);
1860 mp->pool_max_index = pool_exch_range - 1;
1861
1862
1863
1864
1865 pool_size = sizeof(*pool) + pool_exch_range * sizeof(struct fc_exch *);
1866 mp->pool = __alloc_percpu(pool_size, __alignof__(struct fc_exch_pool));
1867 if (!mp->pool)
1868 goto free_mempool;
1869 for_each_possible_cpu(cpu) {
1870 pool = per_cpu_ptr(mp->pool, cpu);
1871 spin_lock_init(&pool->lock);
1872 INIT_LIST_HEAD(&pool->ex_list);
1873 }
1874
1875 kref_init(&mp->kref);
1876 if (!fc_exch_mgr_add(lp, mp, match)) {
1877 free_percpu(mp->pool);
1878 goto free_mempool;
1879 }
1880
1881
1882
1883
1884
1885
1886 kref_put(&mp->kref, fc_exch_mgr_destroy);
1887 return mp;
1888
1889free_mempool:
1890 mempool_destroy(mp->ep_pool);
1891free_mp:
1892 kfree(mp);
1893 return NULL;
1894}
1895EXPORT_SYMBOL(fc_exch_mgr_alloc);
1896
1897void fc_exch_mgr_free(struct fc_lport *lport)
1898{
1899 struct fc_exch_mgr_anchor *ema, *next;
1900
1901 list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list)
1902 fc_exch_mgr_del(ema);
1903}
1904EXPORT_SYMBOL(fc_exch_mgr_free);
1905
1906
1907struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
1908 struct fc_frame *fp,
1909 void (*resp)(struct fc_seq *,
1910 struct fc_frame *fp,
1911 void *arg),
1912 void (*destructor)(struct fc_seq *, void *),
1913 void *arg, u32 timer_msec)
1914{
1915 struct fc_exch *ep;
1916 struct fc_seq *sp = NULL;
1917 struct fc_frame_header *fh;
1918 int rc = 1;
1919
1920 ep = fc_exch_alloc(lp, fp);
1921 if (!ep) {
1922 fc_frame_free(fp);
1923 return NULL;
1924 }
1925 ep->esb_stat |= ESB_ST_SEQ_INIT;
1926 fh = fc_frame_header_get(fp);
1927 fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
1928 ep->resp = resp;
1929 ep->destructor = destructor;
1930 ep->arg = arg;
1931 ep->r_a_tov = FC_DEF_R_A_TOV;
1932 ep->lp = lp;
1933 sp = &ep->seq;
1934
1935 ep->fh_type = fh->fh_type;
1936 ep->f_ctl = ntoh24(fh->fh_f_ctl);
1937 fc_exch_setup_hdr(ep, fp, ep->f_ctl);
1938 sp->cnt++;
1939
1940 if (ep->xid <= lp->lro_xid)
1941 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
1942
1943 if (unlikely(lp->tt.frame_send(lp, fp)))
1944 goto err;
1945
1946 if (timer_msec)
1947 fc_exch_timer_set_locked(ep, timer_msec);
1948 ep->f_ctl &= ~FC_FC_FIRST_SEQ;
1949
1950 if (ep->f_ctl & FC_FC_SEQ_INIT)
1951 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
1952 spin_unlock_bh(&ep->ex_lock);
1953 return sp;
1954err:
1955 rc = fc_exch_done_locked(ep);
1956 spin_unlock_bh(&ep->ex_lock);
1957 if (!rc)
1958 fc_exch_delete(ep);
1959 return NULL;
1960}
1961EXPORT_SYMBOL(fc_exch_seq_send);
1962
1963
1964
1965
1966void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp)
1967{
1968 struct fc_frame_header *fh = fc_frame_header_get(fp);
1969 struct fc_exch_mgr_anchor *ema;
1970 u32 f_ctl, found = 0;
1971 u16 oxid;
1972
1973
1974 if (!lp || lp->state == LPORT_ST_DISABLED) {
1975 FC_LPORT_DBG(lp, "Receiving frames for an lport that "
1976 "has not been initialized correctly\n");
1977 fc_frame_free(fp);
1978 return;
1979 }
1980
1981 f_ctl = ntoh24(fh->fh_f_ctl);
1982 oxid = ntohs(fh->fh_ox_id);
1983 if (f_ctl & FC_FC_EX_CTX) {
1984 list_for_each_entry(ema, &lp->ema_list, ema_list) {
1985 if ((oxid >= ema->mp->min_xid) &&
1986 (oxid <= ema->mp->max_xid)) {
1987 found = 1;
1988 break;
1989 }
1990 }
1991
1992 if (!found) {
1993 FC_LPORT_DBG(lp, "Received response for out "
1994 "of range oxid:%hx\n", oxid);
1995 fc_frame_free(fp);
1996 return;
1997 }
1998 } else
1999 ema = list_entry(lp->ema_list.prev, typeof(*ema), ema_list);
2000
2001
2002
2003
2004 switch (fr_eof(fp)) {
2005 case FC_EOF_T:
2006 if (f_ctl & FC_FC_END_SEQ)
2007 skb_trim(fp_skb(fp), fr_len(fp) - FC_FC_FILL(f_ctl));
2008
2009 case FC_EOF_N:
2010 if (fh->fh_type == FC_TYPE_BLS)
2011 fc_exch_recv_bls(ema->mp, fp);
2012 else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) ==
2013 FC_FC_EX_CTX)
2014 fc_exch_recv_seq_resp(ema->mp, fp);
2015 else if (f_ctl & FC_FC_SEQ_CTX)
2016 fc_exch_recv_resp(ema->mp, fp);
2017 else
2018 fc_exch_recv_req(lp, ema->mp, fp);
2019 break;
2020 default:
2021 FC_LPORT_DBG(lp, "dropping invalid frame (eof %x)", fr_eof(fp));
2022 fc_frame_free(fp);
2023 }
2024}
2025EXPORT_SYMBOL(fc_exch_recv);
2026
2027int fc_exch_init(struct fc_lport *lp)
2028{
2029 if (!lp->tt.seq_start_next)
2030 lp->tt.seq_start_next = fc_seq_start_next;
2031
2032 if (!lp->tt.exch_seq_send)
2033 lp->tt.exch_seq_send = fc_exch_seq_send;
2034
2035 if (!lp->tt.seq_send)
2036 lp->tt.seq_send = fc_seq_send;
2037
2038 if (!lp->tt.seq_els_rsp_send)
2039 lp->tt.seq_els_rsp_send = fc_seq_els_rsp_send;
2040
2041 if (!lp->tt.exch_done)
2042 lp->tt.exch_done = fc_exch_done;
2043
2044 if (!lp->tt.exch_mgr_reset)
2045 lp->tt.exch_mgr_reset = fc_exch_mgr_reset;
2046
2047 if (!lp->tt.seq_exch_abort)
2048 lp->tt.seq_exch_abort = fc_seq_exch_abort;
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064 fc_cpu_mask = 1;
2065 fc_cpu_order = 0;
2066 while (fc_cpu_mask < nr_cpu_ids) {
2067 fc_cpu_mask <<= 1;
2068 fc_cpu_order++;
2069 }
2070 fc_cpu_mask--;
2071
2072 return 0;
2073}
2074EXPORT_SYMBOL(fc_exch_init);
2075
2076int fc_setup_exch_mgr(void)
2077{
2078 fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
2079 0, SLAB_HWCACHE_ALIGN, NULL);
2080 if (!fc_em_cachep)
2081 return -ENOMEM;
2082 return 0;
2083}
2084
2085void fc_destroy_exch_mgr(void)
2086{
2087 kmem_cache_destroy(fc_em_cachep);
2088}
2089