Lines Matching refs:ep
248 static inline void fc_exch_hold(struct fc_exch *ep) in fc_exch_hold() argument
250 atomic_inc(&ep->ex_refcnt); in fc_exch_hold()
263 static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp, in fc_exch_setup_hdr() argument
269 fr_sof(fp) = ep->class; in fc_exch_setup_hdr()
270 if (ep->seq.cnt) in fc_exch_setup_hdr()
271 fr_sof(fp) = fc_sof_normal(ep->class); in fc_exch_setup_hdr()
275 if (fc_sof_needs_ack(ep->class)) in fc_exch_setup_hdr()
299 fh->fh_ox_id = htons(ep->oxid); in fc_exch_setup_hdr()
300 fh->fh_rx_id = htons(ep->rxid); in fc_exch_setup_hdr()
301 fh->fh_seq_id = ep->seq.id; in fc_exch_setup_hdr()
302 fh->fh_seq_cnt = htons(ep->seq.cnt); in fc_exch_setup_hdr()
312 static void fc_exch_release(struct fc_exch *ep) in fc_exch_release() argument
316 if (atomic_dec_and_test(&ep->ex_refcnt)) { in fc_exch_release()
317 mp = ep->em; in fc_exch_release()
318 if (ep->destructor) in fc_exch_release()
319 ep->destructor(&ep->seq, ep->arg); in fc_exch_release()
320 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE)); in fc_exch_release()
321 mempool_free(ep, mp->ep_pool); in fc_exch_release()
329 static inline void fc_exch_timer_cancel(struct fc_exch *ep) in fc_exch_timer_cancel() argument
331 if (cancel_delayed_work(&ep->timeout_work)) { in fc_exch_timer_cancel()
332 FC_EXCH_DBG(ep, "Exchange timer canceled\n"); in fc_exch_timer_cancel()
333 atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ in fc_exch_timer_cancel()
346 static inline void fc_exch_timer_set_locked(struct fc_exch *ep, in fc_exch_timer_set_locked() argument
349 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) in fc_exch_timer_set_locked()
352 FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec); in fc_exch_timer_set_locked()
354 fc_exch_hold(ep); /* hold for timer */ in fc_exch_timer_set_locked()
355 if (!queue_delayed_work(fc_exch_workqueue, &ep->timeout_work, in fc_exch_timer_set_locked()
357 FC_EXCH_DBG(ep, "Exchange already queued\n"); in fc_exch_timer_set_locked()
358 fc_exch_release(ep); in fc_exch_timer_set_locked()
367 static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) in fc_exch_timer_set() argument
369 spin_lock_bh(&ep->ex_lock); in fc_exch_timer_set()
370 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_timer_set()
371 spin_unlock_bh(&ep->ex_lock); in fc_exch_timer_set()
380 static int fc_exch_done_locked(struct fc_exch *ep) in fc_exch_done_locked() argument
390 if (ep->state & FC_EX_DONE) in fc_exch_done_locked()
392 ep->esb_stat |= ESB_ST_COMPLETE; in fc_exch_done_locked()
394 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { in fc_exch_done_locked()
395 ep->state |= FC_EX_DONE; in fc_exch_done_locked()
396 fc_exch_timer_cancel(ep); in fc_exch_done_locked()
427 struct fc_exch *ep) in fc_exch_ptr_set() argument
429 ((struct fc_exch **)(pool + 1))[index] = ep; in fc_exch_ptr_set()
436 static void fc_exch_delete(struct fc_exch *ep) in fc_exch_delete() argument
441 pool = ep->pool; in fc_exch_delete()
447 index = (ep->xid - ep->em->min_xid) >> fc_cpu_order; in fc_exch_delete()
448 if (!(ep->state & FC_EX_QUARANTINE)) { in fc_exch_delete()
459 list_del(&ep->ex_list); in fc_exch_delete()
461 fc_exch_release(ep); /* drop hold for exch in mp */ in fc_exch_delete()
467 struct fc_exch *ep; in fc_seq_send_locked() local
473 ep = fc_seq_exch(sp); in fc_seq_send_locked()
475 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL)) { in fc_seq_send_locked()
480 WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT)); in fc_seq_send_locked()
483 fc_exch_setup_hdr(ep, fp, f_ctl); in fc_seq_send_locked()
484 fr_encaps(fp) = ep->encaps; in fc_seq_send_locked()
510 ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ in fc_seq_send_locked()
512 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_seq_send_locked()
528 struct fc_exch *ep; in fc_seq_send() local
530 ep = fc_seq_exch(sp); in fc_seq_send()
531 spin_lock_bh(&ep->ex_lock); in fc_seq_send()
533 spin_unlock_bh(&ep->ex_lock); in fc_seq_send()
547 static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id) in fc_seq_alloc() argument
551 sp = &ep->seq; in fc_seq_alloc()
565 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_start_next_locked() local
567 sp = fc_seq_alloc(ep, ep->seq_id++); in fc_seq_start_next_locked()
568 FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n", in fc_seq_start_next_locked()
569 ep->f_ctl, sp->id); in fc_seq_start_next_locked()
580 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_start_next() local
582 spin_lock_bh(&ep->ex_lock); in fc_seq_start_next()
584 spin_unlock_bh(&ep->ex_lock); in fc_seq_start_next()
599 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_set_resp() local
602 spin_lock_bh(&ep->ex_lock); in fc_seq_set_resp()
603 while (ep->resp_active && ep->resp_task != current) { in fc_seq_set_resp()
604 prepare_to_wait(&ep->resp_wq, &wait, TASK_UNINTERRUPTIBLE); in fc_seq_set_resp()
605 spin_unlock_bh(&ep->ex_lock); in fc_seq_set_resp()
609 spin_lock_bh(&ep->ex_lock); in fc_seq_set_resp()
611 finish_wait(&ep->resp_wq, &wait); in fc_seq_set_resp()
612 ep->resp = resp; in fc_seq_set_resp()
613 ep->arg = arg; in fc_seq_set_resp()
614 spin_unlock_bh(&ep->ex_lock); in fc_seq_set_resp()
634 static int fc_exch_abort_locked(struct fc_exch *ep, in fc_exch_abort_locked() argument
641 FC_EXCH_DBG(ep, "exch: abort, time %d msecs\n", timer_msec); in fc_exch_abort_locked()
642 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) || in fc_exch_abort_locked()
643 ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) { in fc_exch_abort_locked()
644 FC_EXCH_DBG(ep, "exch: already completed esb %x state %x\n", in fc_exch_abort_locked()
645 ep->esb_stat, ep->state); in fc_exch_abort_locked()
652 sp = fc_seq_start_next_locked(&ep->seq); in fc_exch_abort_locked()
657 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_abort_locked()
659 if (ep->sid) { in fc_exch_abort_locked()
663 fp = fc_frame_alloc(ep->lp, 0); in fc_exch_abort_locked()
665 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_abort_locked()
666 fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid, in fc_exch_abort_locked()
669 error = fc_seq_send_locked(ep->lp, sp, fp); in fc_exch_abort_locked()
680 ep->esb_stat |= ESB_ST_ABNORMAL; in fc_exch_abort_locked()
695 struct fc_exch *ep; in fc_seq_exch_abort() local
698 ep = fc_seq_exch(req_sp); in fc_seq_exch_abort()
699 spin_lock_bh(&ep->ex_lock); in fc_seq_exch_abort()
700 error = fc_exch_abort_locked(ep, timer_msec); in fc_seq_exch_abort()
701 spin_unlock_bh(&ep->ex_lock); in fc_seq_exch_abort()
730 static bool fc_invoke_resp(struct fc_exch *ep, struct fc_seq *sp, in fc_invoke_resp() argument
737 spin_lock_bh(&ep->ex_lock); in fc_invoke_resp()
738 ep->resp_active++; in fc_invoke_resp()
739 if (ep->resp_task != current) in fc_invoke_resp()
740 ep->resp_task = !ep->resp_task ? current : NULL; in fc_invoke_resp()
741 resp = ep->resp; in fc_invoke_resp()
742 arg = ep->arg; in fc_invoke_resp()
743 spin_unlock_bh(&ep->ex_lock); in fc_invoke_resp()
750 spin_lock_bh(&ep->ex_lock); in fc_invoke_resp()
751 if (--ep->resp_active == 0) in fc_invoke_resp()
752 ep->resp_task = NULL; in fc_invoke_resp()
753 spin_unlock_bh(&ep->ex_lock); in fc_invoke_resp()
755 if (ep->resp_active == 0) in fc_invoke_resp()
756 wake_up(&ep->resp_wq); in fc_invoke_resp()
767 struct fc_exch *ep = container_of(work, struct fc_exch, in fc_exch_timeout() local
769 struct fc_seq *sp = &ep->seq; in fc_exch_timeout()
773 FC_EXCH_DBG(ep, "Exchange timed out state %x\n", ep->state); in fc_exch_timeout()
775 spin_lock_bh(&ep->ex_lock); in fc_exch_timeout()
776 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) in fc_exch_timeout()
779 e_stat = ep->esb_stat; in fc_exch_timeout()
781 ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; in fc_exch_timeout()
782 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
784 fc_exch_rrq(ep); in fc_exch_timeout()
788 rc = fc_exch_done_locked(ep); in fc_exch_timeout()
789 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
791 fc_exch_delete(ep); in fc_exch_timeout()
792 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_TIMEOUT)); in fc_exch_timeout()
793 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_timeout()
794 fc_seq_exch_abort(sp, 2 * ep->r_a_tov); in fc_exch_timeout()
798 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
803 fc_exch_release(ep); in fc_exch_timeout()
816 struct fc_exch *ep; in fc_exch_em_alloc() local
822 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC); in fc_exch_em_alloc()
823 if (!ep) { in fc_exch_em_alloc()
827 memset(ep, 0, sizeof(*ep)); in fc_exch_em_alloc()
859 fc_exch_hold(ep); /* hold for exch in mp */ in fc_exch_em_alloc()
860 spin_lock_init(&ep->ex_lock); in fc_exch_em_alloc()
866 spin_lock_bh(&ep->ex_lock); in fc_exch_em_alloc()
868 fc_exch_ptr_set(pool, index, ep); in fc_exch_em_alloc()
869 list_add_tail(&ep->ex_list, &pool->ex_list); in fc_exch_em_alloc()
870 fc_seq_alloc(ep, ep->seq_id++); in fc_exch_em_alloc()
877 ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid; in fc_exch_em_alloc()
878 ep->em = mp; in fc_exch_em_alloc()
879 ep->pool = pool; in fc_exch_em_alloc()
880 ep->lp = lport; in fc_exch_em_alloc()
881 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */ in fc_exch_em_alloc()
882 ep->rxid = FC_XID_UNKNOWN; in fc_exch_em_alloc()
883 ep->class = mp->class; in fc_exch_em_alloc()
884 ep->resp_active = 0; in fc_exch_em_alloc()
885 init_waitqueue_head(&ep->resp_wq); in fc_exch_em_alloc()
886 INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout); in fc_exch_em_alloc()
888 return ep; in fc_exch_em_alloc()
892 mempool_free(ep, mp->ep_pool); in fc_exch_em_alloc()
911 struct fc_exch *ep; in fc_exch_alloc() local
915 ep = fc_exch_em_alloc(lport, ema->mp); in fc_exch_alloc()
916 if (ep) in fc_exch_alloc()
917 return ep; in fc_exch_alloc()
932 struct fc_exch *ep = NULL; in fc_exch_find() local
947 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order); in fc_exch_find()
948 if (ep == &fc_quarantine_exch) { in fc_exch_find()
950 ep = NULL; in fc_exch_find()
952 if (ep) { in fc_exch_find()
953 WARN_ON(ep->xid != xid); in fc_exch_find()
954 fc_exch_hold(ep); in fc_exch_find()
958 return ep; in fc_exch_find()
971 struct fc_exch *ep = fc_seq_exch(sp); in fc_exch_done() local
974 spin_lock_bh(&ep->ex_lock); in fc_exch_done()
975 rc = fc_exch_done_locked(ep); in fc_exch_done()
976 spin_unlock_bh(&ep->ex_lock); in fc_exch_done()
978 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_done()
980 fc_exch_delete(ep); in fc_exch_done()
996 struct fc_exch *ep; in fc_exch_resp() local
999 ep = fc_exch_alloc(lport, fp); in fc_exch_resp()
1000 if (ep) { in fc_exch_resp()
1001 ep->class = fc_frame_class(fp); in fc_exch_resp()
1006 ep->f_ctl |= FC_FC_EX_CTX; /* we're responding */ in fc_exch_resp()
1007 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not new */ in fc_exch_resp()
1009 ep->sid = ntoh24(fh->fh_d_id); in fc_exch_resp()
1010 ep->did = ntoh24(fh->fh_s_id); in fc_exch_resp()
1011 ep->oid = ep->did; in fc_exch_resp()
1018 ep->rxid = ep->xid; in fc_exch_resp()
1019 ep->oxid = ntohs(fh->fh_ox_id); in fc_exch_resp()
1020 ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT; in fc_exch_resp()
1022 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_exch_resp()
1024 fc_exch_hold(ep); /* hold for caller */ in fc_exch_resp()
1025 spin_unlock_bh(&ep->ex_lock); /* lock from fc_exch_alloc */ in fc_exch_resp()
1027 return ep; in fc_exch_resp()
1045 struct fc_exch *ep = NULL; in fc_seq_lookup_recip() local
1059 ep = fc_exch_find(mp, xid); in fc_seq_lookup_recip()
1060 if (!ep) { in fc_seq_lookup_recip()
1065 if (ep->rxid == FC_XID_UNKNOWN) in fc_seq_lookup_recip()
1066 ep->rxid = ntohs(fh->fh_rx_id); in fc_seq_lookup_recip()
1067 else if (ep->rxid != ntohs(fh->fh_rx_id)) { in fc_seq_lookup_recip()
1088 ep = fc_exch_find(mp, xid); in fc_seq_lookup_recip()
1090 if (ep) { in fc_seq_lookup_recip()
1095 ep = fc_exch_resp(lport, mp, fp); in fc_seq_lookup_recip()
1096 if (!ep) { in fc_seq_lookup_recip()
1100 xid = ep->xid; /* get our XID */ in fc_seq_lookup_recip()
1101 } else if (!ep) { in fc_seq_lookup_recip()
1108 spin_lock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1114 sp = &ep->seq; in fc_seq_lookup_recip()
1118 sp = &ep->seq; in fc_seq_lookup_recip()
1139 spin_unlock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1147 WARN_ON(ep != fc_seq_exch(sp)); in fc_seq_lookup_recip()
1150 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_seq_lookup_recip()
1151 spin_unlock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1157 fc_exch_done(&ep->seq); in fc_seq_lookup_recip()
1158 fc_exch_release(ep); /* hold from fc_exch_find/fc_exch_resp */ in fc_seq_lookup_recip()
1174 struct fc_exch *ep; in fc_seq_lookup_orig() local
1182 ep = fc_exch_find(mp, xid); in fc_seq_lookup_orig()
1183 if (!ep) in fc_seq_lookup_orig()
1185 if (ep->seq.id == fh->fh_seq_id) { in fc_seq_lookup_orig()
1189 sp = &ep->seq; in fc_seq_lookup_orig()
1191 ep->rxid == FC_XID_UNKNOWN) { in fc_seq_lookup_orig()
1192 ep->rxid = ntohs(fh->fh_rx_id); in fc_seq_lookup_orig()
1195 fc_exch_release(ep); in fc_seq_lookup_orig()
1207 static void fc_exch_set_addr(struct fc_exch *ep, in fc_exch_set_addr() argument
1210 ep->oid = orig_id; in fc_exch_set_addr()
1211 if (ep->esb_stat & ESB_ST_RESP) { in fc_exch_set_addr()
1212 ep->sid = resp_id; in fc_exch_set_addr()
1213 ep->did = orig_id; in fc_exch_set_addr()
1215 ep->sid = orig_id; in fc_exch_set_addr()
1216 ep->did = resp_id; in fc_exch_set_addr()
1262 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_send_last() local
1265 f_ctl |= ep->f_ctl; in fc_seq_send_last()
1266 fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0); in fc_seq_send_last()
1267 fc_seq_send_locked(ep->lp, sp, fp); in fc_seq_send_last()
1282 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_send_ack() local
1283 struct fc_lport *lport = ep->lp; in fc_seq_send_ack()
1292 FC_EXCH_DBG(ep, "Drop ACK request, out of memory\n"); in fc_seq_send_ack()
1316 fc_exch_setup_hdr(ep, fp, f_ctl); in fc_seq_send_ack()
1413 static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp) in fc_exch_recv_abts() argument
1420 if (!ep) in fc_exch_recv_abts()
1423 FC_EXCH_DBG(ep, "exch: ABTS received\n"); in fc_exch_recv_abts()
1424 fp = fc_frame_alloc(ep->lp, sizeof(*ap)); in fc_exch_recv_abts()
1426 FC_EXCH_DBG(ep, "Drop ABTS request, out of memory\n"); in fc_exch_recv_abts()
1430 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1431 if (ep->esb_stat & ESB_ST_COMPLETE) { in fc_exch_recv_abts()
1432 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1433 FC_EXCH_DBG(ep, "exch: ABTS rejected, exchange complete\n"); in fc_exch_recv_abts()
1437 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { in fc_exch_recv_abts()
1438 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_recv_abts()
1439 fc_exch_hold(ep); /* hold for REC_QUAL */ in fc_exch_recv_abts()
1441 fc_exch_timer_set_locked(ep, ep->r_a_tov); in fc_exch_recv_abts()
1445 sp = &ep->seq; in fc_exch_recv_abts()
1455 ep->esb_stat |= ESB_ST_ABNORMAL; in fc_exch_recv_abts()
1456 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1516 struct fc_exch *ep = NULL; in fc_exch_recv_req() local
1541 ep = fc_seq_exch(sp); in fc_exch_recv_req()
1543 ep->encaps = fr_encaps(fp); in fc_exch_recv_req()
1556 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_recv_req()
1558 fc_exch_release(ep); /* release from lookup */ in fc_exch_recv_req()
1577 struct fc_exch *ep; in fc_exch_recv_seq_resp() local
1582 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id)); in fc_exch_recv_seq_resp()
1583 if (!ep) { in fc_exch_recv_seq_resp()
1587 if (ep->esb_stat & ESB_ST_COMPLETE) { in fc_exch_recv_seq_resp()
1591 if (ep->rxid == FC_XID_UNKNOWN) in fc_exch_recv_seq_resp()
1592 ep->rxid = ntohs(fh->fh_rx_id); in fc_exch_recv_seq_resp()
1593 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) { in fc_exch_recv_seq_resp()
1597 if (ep->did != ntoh24(fh->fh_s_id) && in fc_exch_recv_seq_resp()
1598 ep->did != FC_FID_FLOGI) { in fc_exch_recv_seq_resp()
1603 sp = &ep->seq; in fc_exch_recv_seq_resp()
1612 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1614 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_recv_seq_resp()
1615 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1623 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1624 rc = fc_exch_done_locked(ep); in fc_exch_recv_seq_resp()
1625 WARN_ON(fc_seq_exch(sp) != ep); in fc_exch_recv_seq_resp()
1626 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1628 fc_exch_delete(ep); in fc_exch_recv_seq_resp()
1630 FC_EXCH_DBG(ep, "ep is completed already," in fc_exch_recv_seq_resp()
1649 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_recv_seq_resp()
1653 fc_exch_release(ep); in fc_exch_recv_seq_resp()
1656 fc_exch_release(ep); in fc_exch_recv_seq_resp()
1689 static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) in fc_exch_abts_resp() argument
1699 FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, in fc_exch_abts_resp()
1702 if (cancel_delayed_work_sync(&ep->timeout_work)) { in fc_exch_abts_resp()
1703 FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n"); in fc_exch_abts_resp()
1704 fc_exch_release(ep); /* release from pending timer hold */ in fc_exch_abts_resp()
1707 spin_lock_bh(&ep->ex_lock); in fc_exch_abts_resp()
1721 if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 && in fc_exch_abts_resp()
1723 ap->ba_seq_id == ep->seq_id) && low != high) { in fc_exch_abts_resp()
1724 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_abts_resp()
1725 fc_exch_hold(ep); /* hold for recovery qualifier */ in fc_exch_abts_resp()
1738 sp = &ep->seq; in fc_exch_abts_resp()
1742 if (ep->fh_type != FC_TYPE_FCP && in fc_exch_abts_resp()
1744 rc = fc_exch_done_locked(ep); in fc_exch_abts_resp()
1745 spin_unlock_bh(&ep->ex_lock); in fc_exch_abts_resp()
1747 fc_exch_hold(ep); in fc_exch_abts_resp()
1749 fc_exch_delete(ep); in fc_exch_abts_resp()
1750 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_abts_resp()
1753 fc_exch_timer_set(ep, ep->r_a_tov); in fc_exch_abts_resp()
1754 fc_exch_release(ep); in fc_exch_abts_resp()
1768 struct fc_exch *ep; in fc_exch_recv_bls() local
1775 ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ? in fc_exch_recv_bls()
1777 if (ep && (f_ctl & FC_FC_SEQ_INIT)) { in fc_exch_recv_bls()
1778 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_bls()
1779 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_recv_bls()
1780 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_bls()
1792 if (ep) in fc_exch_recv_bls()
1793 FC_EXCH_DBG(ep, "BLS rctl %x - %s received\n", in fc_exch_recv_bls()
1803 if (ep) in fc_exch_recv_bls()
1804 fc_exch_abts_resp(ep, fp); in fc_exch_recv_bls()
1809 if (ep) in fc_exch_recv_bls()
1810 fc_exch_recv_abts(ep, fp); in fc_exch_recv_bls()
1819 if (ep) in fc_exch_recv_bls()
1820 fc_exch_release(ep); /* release hold taken by fc_exch_find */ in fc_exch_recv_bls()
1892 static void fc_exch_reset(struct fc_exch *ep) in fc_exch_reset() argument
1897 spin_lock_bh(&ep->ex_lock); in fc_exch_reset()
1898 ep->state |= FC_EX_RST_CLEANUP; in fc_exch_reset()
1899 fc_exch_timer_cancel(ep); in fc_exch_reset()
1900 if (ep->esb_stat & ESB_ST_REC_QUAL) in fc_exch_reset()
1901 atomic_dec(&ep->ex_refcnt); /* drop hold for rec_qual */ in fc_exch_reset()
1902 ep->esb_stat &= ~ESB_ST_REC_QUAL; in fc_exch_reset()
1903 sp = &ep->seq; in fc_exch_reset()
1904 rc = fc_exch_done_locked(ep); in fc_exch_reset()
1905 spin_unlock_bh(&ep->ex_lock); in fc_exch_reset()
1907 fc_exch_hold(ep); in fc_exch_reset()
1910 fc_exch_delete(ep); in fc_exch_reset()
1912 FC_EXCH_DBG(ep, "ep is completed already," in fc_exch_reset()
1917 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED)); in fc_exch_reset()
1919 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_reset()
1920 fc_exch_release(ep); in fc_exch_reset()
1939 struct fc_exch *ep; in fc_exch_pool_reset() local
1944 list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) { in fc_exch_pool_reset()
1945 if ((lport == ep->lp) && in fc_exch_pool_reset()
1946 (sid == 0 || sid == ep->sid) && in fc_exch_pool_reset()
1947 (did == 0 || did == ep->did)) { in fc_exch_pool_reset()
1948 fc_exch_hold(ep); in fc_exch_pool_reset()
1951 fc_exch_reset(ep); in fc_exch_pool_reset()
1953 fc_exch_release(ep); in fc_exch_pool_reset()
2021 struct fc_exch *ep; in fc_exch_els_rec() local
2049 ep = fc_exch_lookup(lport, xid); in fc_exch_els_rec()
2050 if (!ep) { in fc_exch_els_rec()
2056 FC_EXCH_DBG(ep, "REC request from %x: rxid %x oxid %x\n", in fc_exch_els_rec()
2058 if (ep->oid != sid || oxid != ep->oxid) in fc_exch_els_rec()
2060 if (rxid != FC_XID_UNKNOWN && rxid != ep->rxid) in fc_exch_els_rec()
2064 FC_EXCH_DBG(ep, "Drop REC request, out of memory\n"); in fc_exch_els_rec()
2073 acc->reca_rx_id = htons(ep->rxid); in fc_exch_els_rec()
2074 if (ep->sid == ep->oid) in fc_exch_els_rec()
2075 hton24(acc->reca_rfid, ep->did); in fc_exch_els_rec()
2077 hton24(acc->reca_rfid, ep->sid); in fc_exch_els_rec()
2078 acc->reca_fc4value = htonl(ep->seq.rec_data); in fc_exch_els_rec()
2079 acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP | in fc_exch_els_rec()
2085 fc_exch_release(ep); in fc_exch_els_rec()
2089 fc_exch_release(ep); in fc_exch_els_rec()
2184 struct fc_exch *ep; in fc_exch_seq_send() local
2190 ep = fc_exch_alloc(lport, fp); in fc_exch_seq_send()
2191 if (!ep) { in fc_exch_seq_send()
2195 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_seq_send()
2197 fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id)); in fc_exch_seq_send()
2198 ep->resp = resp; in fc_exch_seq_send()
2199 ep->destructor = destructor; in fc_exch_seq_send()
2200 ep->arg = arg; in fc_exch_seq_send()
2201 ep->r_a_tov = lport->r_a_tov; in fc_exch_seq_send()
2202 ep->lp = lport; in fc_exch_seq_send()
2203 sp = &ep->seq; in fc_exch_seq_send()
2205 ep->fh_type = fh->fh_type; /* save for possbile timeout handling */ in fc_exch_seq_send()
2206 ep->f_ctl = ntoh24(fh->fh_f_ctl); in fc_exch_seq_send()
2207 fc_exch_setup_hdr(ep, fp, ep->f_ctl); in fc_exch_seq_send()
2210 if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) { in fc_exch_seq_send()
2212 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); in fc_exch_seq_send()
2219 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_seq_send()
2220 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */ in fc_exch_seq_send()
2222 if (ep->f_ctl & FC_FC_SEQ_INIT) in fc_exch_seq_send()
2223 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_exch_seq_send()
2224 spin_unlock_bh(&ep->ex_lock); in fc_exch_seq_send()
2229 rc = fc_exch_done_locked(ep); in fc_exch_seq_send()
2230 spin_unlock_bh(&ep->ex_lock); in fc_exch_seq_send()
2232 fc_exch_delete(ep); in fc_exch_seq_send()
2244 static void fc_exch_rrq(struct fc_exch *ep) in fc_exch_rrq() argument
2251 lport = ep->lp; in fc_exch_rrq()
2260 hton24(rrq->rrq_s_id, ep->sid); in fc_exch_rrq()
2261 rrq->rrq_ox_id = htons(ep->oxid); in fc_exch_rrq()
2262 rrq->rrq_rx_id = htons(ep->rxid); in fc_exch_rrq()
2264 did = ep->did; in fc_exch_rrq()
2265 if (ep->esb_stat & ESB_ST_RESP) in fc_exch_rrq()
2266 did = ep->sid; in fc_exch_rrq()
2272 if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep, in fc_exch_rrq()
2277 FC_EXCH_DBG(ep, "exch: RRQ send failed\n"); in fc_exch_rrq()
2278 spin_lock_bh(&ep->ex_lock); in fc_exch_rrq()
2279 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) { in fc_exch_rrq()
2280 spin_unlock_bh(&ep->ex_lock); in fc_exch_rrq()
2282 fc_exch_release(ep); in fc_exch_rrq()
2285 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_rrq()
2286 fc_exch_timer_set_locked(ep, ep->r_a_tov); in fc_exch_rrq()
2287 spin_unlock_bh(&ep->ex_lock); in fc_exch_rrq()
2297 struct fc_exch *ep = NULL; /* request or subject exchange */ in fc_exch_els_rrq() local
2315 ep = fc_exch_lookup(lport, xid); in fc_exch_els_rrq()
2317 if (!ep) in fc_exch_els_rrq()
2319 spin_lock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2320 FC_EXCH_DBG(ep, "RRQ request from %x: xid %x rxid %x oxid %x\n", in fc_exch_els_rrq()
2322 if (ep->oxid != ntohs(rp->rrq_ox_id)) in fc_exch_els_rrq()
2324 if (ep->rxid != ntohs(rp->rrq_rx_id) && in fc_exch_els_rrq()
2325 ep->rxid != FC_XID_UNKNOWN) in fc_exch_els_rrq()
2328 if (ep->sid != sid) in fc_exch_els_rrq()
2334 if (ep->esb_stat & ESB_ST_REC_QUAL) { in fc_exch_els_rrq()
2335 ep->esb_stat &= ~ESB_ST_REC_QUAL; in fc_exch_els_rrq()
2336 atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ in fc_exch_els_rrq()
2338 if (ep->esb_stat & ESB_ST_COMPLETE) in fc_exch_els_rrq()
2339 fc_exch_timer_cancel(ep); in fc_exch_els_rrq()
2341 spin_unlock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2350 spin_unlock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2354 if (ep) in fc_exch_els_rrq()
2355 fc_exch_release(ep); /* drop hold from fc_exch_find */ in fc_exch_els_rrq()