Lines Matching refs:ep

246 static inline void fc_exch_hold(struct fc_exch *ep)  in fc_exch_hold()  argument
248 atomic_inc(&ep->ex_refcnt); in fc_exch_hold()
261 static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp, in fc_exch_setup_hdr() argument
267 fr_sof(fp) = ep->class; in fc_exch_setup_hdr()
268 if (ep->seq.cnt) in fc_exch_setup_hdr()
269 fr_sof(fp) = fc_sof_normal(ep->class); in fc_exch_setup_hdr()
273 if (fc_sof_needs_ack(ep->class)) in fc_exch_setup_hdr()
297 fh->fh_ox_id = htons(ep->oxid); in fc_exch_setup_hdr()
298 fh->fh_rx_id = htons(ep->rxid); in fc_exch_setup_hdr()
299 fh->fh_seq_id = ep->seq.id; in fc_exch_setup_hdr()
300 fh->fh_seq_cnt = htons(ep->seq.cnt); in fc_exch_setup_hdr()
310 static void fc_exch_release(struct fc_exch *ep) in fc_exch_release() argument
314 if (atomic_dec_and_test(&ep->ex_refcnt)) { in fc_exch_release()
315 mp = ep->em; in fc_exch_release()
316 if (ep->destructor) in fc_exch_release()
317 ep->destructor(&ep->seq, ep->arg); in fc_exch_release()
318 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE)); in fc_exch_release()
319 mempool_free(ep, mp->ep_pool); in fc_exch_release()
327 static inline void fc_exch_timer_cancel(struct fc_exch *ep) in fc_exch_timer_cancel() argument
329 if (cancel_delayed_work(&ep->timeout_work)) { in fc_exch_timer_cancel()
330 FC_EXCH_DBG(ep, "Exchange timer canceled\n"); in fc_exch_timer_cancel()
331 atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ in fc_exch_timer_cancel()
344 static inline void fc_exch_timer_set_locked(struct fc_exch *ep, in fc_exch_timer_set_locked() argument
347 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) in fc_exch_timer_set_locked()
350 FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec); in fc_exch_timer_set_locked()
352 fc_exch_hold(ep); /* hold for timer */ in fc_exch_timer_set_locked()
353 if (!queue_delayed_work(fc_exch_workqueue, &ep->timeout_work, in fc_exch_timer_set_locked()
355 FC_EXCH_DBG(ep, "Exchange already queued\n"); in fc_exch_timer_set_locked()
356 fc_exch_release(ep); in fc_exch_timer_set_locked()
365 static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) in fc_exch_timer_set() argument
367 spin_lock_bh(&ep->ex_lock); in fc_exch_timer_set()
368 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_timer_set()
369 spin_unlock_bh(&ep->ex_lock); in fc_exch_timer_set()
378 static int fc_exch_done_locked(struct fc_exch *ep) in fc_exch_done_locked() argument
388 if (ep->state & FC_EX_DONE) in fc_exch_done_locked()
390 ep->esb_stat |= ESB_ST_COMPLETE; in fc_exch_done_locked()
392 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { in fc_exch_done_locked()
393 ep->state |= FC_EX_DONE; in fc_exch_done_locked()
394 fc_exch_timer_cancel(ep); in fc_exch_done_locked()
425 struct fc_exch *ep) in fc_exch_ptr_set() argument
427 ((struct fc_exch **)(pool + 1))[index] = ep; in fc_exch_ptr_set()
434 static void fc_exch_delete(struct fc_exch *ep) in fc_exch_delete() argument
439 pool = ep->pool; in fc_exch_delete()
445 index = (ep->xid - ep->em->min_xid) >> fc_cpu_order; in fc_exch_delete()
446 if (!(ep->state & FC_EX_QUARANTINE)) { in fc_exch_delete()
457 list_del(&ep->ex_list); in fc_exch_delete()
459 fc_exch_release(ep); /* drop hold for exch in mp */ in fc_exch_delete()
465 struct fc_exch *ep; in fc_seq_send_locked() local
471 ep = fc_seq_exch(sp); in fc_seq_send_locked()
473 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL)) { in fc_seq_send_locked()
478 WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT)); in fc_seq_send_locked()
481 fc_exch_setup_hdr(ep, fp, f_ctl); in fc_seq_send_locked()
482 fr_encaps(fp) = ep->encaps; in fc_seq_send_locked()
508 ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ in fc_seq_send_locked()
510 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_seq_send_locked()
526 struct fc_exch *ep; in fc_seq_send() local
528 ep = fc_seq_exch(sp); in fc_seq_send()
529 spin_lock_bh(&ep->ex_lock); in fc_seq_send()
531 spin_unlock_bh(&ep->ex_lock); in fc_seq_send()
545 static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id) in fc_seq_alloc() argument
549 sp = &ep->seq; in fc_seq_alloc()
563 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_start_next_locked() local
565 sp = fc_seq_alloc(ep, ep->seq_id++); in fc_seq_start_next_locked()
566 FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n", in fc_seq_start_next_locked()
567 ep->f_ctl, sp->id); in fc_seq_start_next_locked()
578 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_start_next() local
580 spin_lock_bh(&ep->ex_lock); in fc_seq_start_next()
582 spin_unlock_bh(&ep->ex_lock); in fc_seq_start_next()
597 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_set_resp() local
600 spin_lock_bh(&ep->ex_lock); in fc_seq_set_resp()
601 while (ep->resp_active && ep->resp_task != current) { in fc_seq_set_resp()
602 prepare_to_wait(&ep->resp_wq, &wait, TASK_UNINTERRUPTIBLE); in fc_seq_set_resp()
603 spin_unlock_bh(&ep->ex_lock); in fc_seq_set_resp()
607 spin_lock_bh(&ep->ex_lock); in fc_seq_set_resp()
609 finish_wait(&ep->resp_wq, &wait); in fc_seq_set_resp()
610 ep->resp = resp; in fc_seq_set_resp()
611 ep->arg = arg; in fc_seq_set_resp()
612 spin_unlock_bh(&ep->ex_lock); in fc_seq_set_resp()
632 static int fc_exch_abort_locked(struct fc_exch *ep, in fc_exch_abort_locked() argument
639 FC_EXCH_DBG(ep, "exch: abort, time %d msecs\n", timer_msec); in fc_exch_abort_locked()
640 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) || in fc_exch_abort_locked()
641 ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) { in fc_exch_abort_locked()
642 FC_EXCH_DBG(ep, "exch: already completed esb %x state %x\n", in fc_exch_abort_locked()
643 ep->esb_stat, ep->state); in fc_exch_abort_locked()
650 sp = fc_seq_start_next_locked(&ep->seq); in fc_exch_abort_locked()
655 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_abort_locked()
657 if (ep->sid) { in fc_exch_abort_locked()
661 fp = fc_frame_alloc(ep->lp, 0); in fc_exch_abort_locked()
663 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_abort_locked()
664 fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid, in fc_exch_abort_locked()
667 error = fc_seq_send_locked(ep->lp, sp, fp); in fc_exch_abort_locked()
678 ep->esb_stat |= ESB_ST_ABNORMAL; in fc_exch_abort_locked()
693 struct fc_exch *ep; in fc_seq_exch_abort() local
696 ep = fc_seq_exch(req_sp); in fc_seq_exch_abort()
697 spin_lock_bh(&ep->ex_lock); in fc_seq_exch_abort()
698 error = fc_exch_abort_locked(ep, timer_msec); in fc_seq_exch_abort()
699 spin_unlock_bh(&ep->ex_lock); in fc_seq_exch_abort()
725 static bool fc_invoke_resp(struct fc_exch *ep, struct fc_seq *sp, in fc_invoke_resp() argument
732 spin_lock_bh(&ep->ex_lock); in fc_invoke_resp()
733 ep->resp_active++; in fc_invoke_resp()
734 if (ep->resp_task != current) in fc_invoke_resp()
735 ep->resp_task = !ep->resp_task ? current : NULL; in fc_invoke_resp()
736 resp = ep->resp; in fc_invoke_resp()
737 arg = ep->arg; in fc_invoke_resp()
738 spin_unlock_bh(&ep->ex_lock); in fc_invoke_resp()
745 spin_lock_bh(&ep->ex_lock); in fc_invoke_resp()
746 if (--ep->resp_active == 0) in fc_invoke_resp()
747 ep->resp_task = NULL; in fc_invoke_resp()
748 spin_unlock_bh(&ep->ex_lock); in fc_invoke_resp()
750 if (ep->resp_active == 0) in fc_invoke_resp()
751 wake_up(&ep->resp_wq); in fc_invoke_resp()
762 struct fc_exch *ep = container_of(work, struct fc_exch, in fc_exch_timeout() local
764 struct fc_seq *sp = &ep->seq; in fc_exch_timeout()
768 FC_EXCH_DBG(ep, "Exchange timed out state %x\n", ep->state); in fc_exch_timeout()
770 spin_lock_bh(&ep->ex_lock); in fc_exch_timeout()
771 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) in fc_exch_timeout()
774 e_stat = ep->esb_stat; in fc_exch_timeout()
776 ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; in fc_exch_timeout()
777 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
779 fc_exch_rrq(ep); in fc_exch_timeout()
783 rc = fc_exch_done_locked(ep); in fc_exch_timeout()
784 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
786 fc_exch_delete(ep); in fc_exch_timeout()
787 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_TIMEOUT)); in fc_exch_timeout()
788 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_timeout()
789 fc_seq_exch_abort(sp, 2 * ep->r_a_tov); in fc_exch_timeout()
793 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
798 fc_exch_release(ep); in fc_exch_timeout()
811 struct fc_exch *ep; in fc_exch_em_alloc() local
817 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC); in fc_exch_em_alloc()
818 if (!ep) { in fc_exch_em_alloc()
822 memset(ep, 0, sizeof(*ep)); in fc_exch_em_alloc()
854 fc_exch_hold(ep); /* hold for exch in mp */ in fc_exch_em_alloc()
855 spin_lock_init(&ep->ex_lock); in fc_exch_em_alloc()
861 spin_lock_bh(&ep->ex_lock); in fc_exch_em_alloc()
863 fc_exch_ptr_set(pool, index, ep); in fc_exch_em_alloc()
864 list_add_tail(&ep->ex_list, &pool->ex_list); in fc_exch_em_alloc()
865 fc_seq_alloc(ep, ep->seq_id++); in fc_exch_em_alloc()
872 ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid; in fc_exch_em_alloc()
873 ep->em = mp; in fc_exch_em_alloc()
874 ep->pool = pool; in fc_exch_em_alloc()
875 ep->lp = lport; in fc_exch_em_alloc()
876 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */ in fc_exch_em_alloc()
877 ep->rxid = FC_XID_UNKNOWN; in fc_exch_em_alloc()
878 ep->class = mp->class; in fc_exch_em_alloc()
879 ep->resp_active = 0; in fc_exch_em_alloc()
880 init_waitqueue_head(&ep->resp_wq); in fc_exch_em_alloc()
881 INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout); in fc_exch_em_alloc()
883 return ep; in fc_exch_em_alloc()
887 mempool_free(ep, mp->ep_pool); in fc_exch_em_alloc()
906 struct fc_exch *ep; in fc_exch_alloc() local
910 ep = fc_exch_em_alloc(lport, ema->mp); in fc_exch_alloc()
911 if (ep) in fc_exch_alloc()
912 return ep; in fc_exch_alloc()
927 struct fc_exch *ep = NULL; in fc_exch_find() local
942 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order); in fc_exch_find()
943 if (ep == &fc_quarantine_exch) { in fc_exch_find()
945 ep = NULL; in fc_exch_find()
947 if (ep) { in fc_exch_find()
948 WARN_ON(ep->xid != xid); in fc_exch_find()
949 fc_exch_hold(ep); in fc_exch_find()
953 return ep; in fc_exch_find()
966 struct fc_exch *ep = fc_seq_exch(sp); in fc_exch_done() local
969 spin_lock_bh(&ep->ex_lock); in fc_exch_done()
970 rc = fc_exch_done_locked(ep); in fc_exch_done()
971 spin_unlock_bh(&ep->ex_lock); in fc_exch_done()
973 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_done()
975 fc_exch_delete(ep); in fc_exch_done()
991 struct fc_exch *ep; in fc_exch_resp() local
994 ep = fc_exch_alloc(lport, fp); in fc_exch_resp()
995 if (ep) { in fc_exch_resp()
996 ep->class = fc_frame_class(fp); in fc_exch_resp()
1001 ep->f_ctl |= FC_FC_EX_CTX; /* we're responding */ in fc_exch_resp()
1002 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not new */ in fc_exch_resp()
1004 ep->sid = ntoh24(fh->fh_d_id); in fc_exch_resp()
1005 ep->did = ntoh24(fh->fh_s_id); in fc_exch_resp()
1006 ep->oid = ep->did; in fc_exch_resp()
1013 ep->rxid = ep->xid; in fc_exch_resp()
1014 ep->oxid = ntohs(fh->fh_ox_id); in fc_exch_resp()
1015 ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT; in fc_exch_resp()
1017 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_exch_resp()
1019 fc_exch_hold(ep); /* hold for caller */ in fc_exch_resp()
1020 spin_unlock_bh(&ep->ex_lock); /* lock from fc_exch_alloc */ in fc_exch_resp()
1022 return ep; in fc_exch_resp()
1040 struct fc_exch *ep = NULL; in fc_seq_lookup_recip() local
1054 ep = fc_exch_find(mp, xid); in fc_seq_lookup_recip()
1055 if (!ep) { in fc_seq_lookup_recip()
1060 if (ep->rxid == FC_XID_UNKNOWN) in fc_seq_lookup_recip()
1061 ep->rxid = ntohs(fh->fh_rx_id); in fc_seq_lookup_recip()
1062 else if (ep->rxid != ntohs(fh->fh_rx_id)) { in fc_seq_lookup_recip()
1083 ep = fc_exch_find(mp, xid); in fc_seq_lookup_recip()
1085 if (ep) { in fc_seq_lookup_recip()
1090 ep = fc_exch_resp(lport, mp, fp); in fc_seq_lookup_recip()
1091 if (!ep) { in fc_seq_lookup_recip()
1095 xid = ep->xid; /* get our XID */ in fc_seq_lookup_recip()
1096 } else if (!ep) { in fc_seq_lookup_recip()
1103 spin_lock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1109 sp = &ep->seq; in fc_seq_lookup_recip()
1113 sp = &ep->seq; in fc_seq_lookup_recip()
1134 spin_unlock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1142 WARN_ON(ep != fc_seq_exch(sp)); in fc_seq_lookup_recip()
1145 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_seq_lookup_recip()
1146 spin_unlock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1152 fc_exch_done(&ep->seq); in fc_seq_lookup_recip()
1153 fc_exch_release(ep); /* hold from fc_exch_find/fc_exch_resp */ in fc_seq_lookup_recip()
1169 struct fc_exch *ep; in fc_seq_lookup_orig() local
1177 ep = fc_exch_find(mp, xid); in fc_seq_lookup_orig()
1178 if (!ep) in fc_seq_lookup_orig()
1180 if (ep->seq.id == fh->fh_seq_id) { in fc_seq_lookup_orig()
1184 sp = &ep->seq; in fc_seq_lookup_orig()
1186 ep->rxid == FC_XID_UNKNOWN) { in fc_seq_lookup_orig()
1187 ep->rxid = ntohs(fh->fh_rx_id); in fc_seq_lookup_orig()
1190 fc_exch_release(ep); in fc_seq_lookup_orig()
1202 static void fc_exch_set_addr(struct fc_exch *ep, in fc_exch_set_addr() argument
1205 ep->oid = orig_id; in fc_exch_set_addr()
1206 if (ep->esb_stat & ESB_ST_RESP) { in fc_exch_set_addr()
1207 ep->sid = resp_id; in fc_exch_set_addr()
1208 ep->did = orig_id; in fc_exch_set_addr()
1210 ep->sid = orig_id; in fc_exch_set_addr()
1211 ep->did = resp_id; in fc_exch_set_addr()
1257 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_send_last() local
1260 f_ctl |= ep->f_ctl; in fc_seq_send_last()
1261 fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0); in fc_seq_send_last()
1262 fc_seq_send_locked(ep->lp, sp, fp); in fc_seq_send_last()
1277 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_send_ack() local
1278 struct fc_lport *lport = ep->lp; in fc_seq_send_ack()
1287 FC_EXCH_DBG(ep, "Drop ACK request, out of memory\n"); in fc_seq_send_ack()
1311 fc_exch_setup_hdr(ep, fp, f_ctl); in fc_seq_send_ack()
1408 static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp) in fc_exch_recv_abts() argument
1415 if (!ep) in fc_exch_recv_abts()
1418 FC_EXCH_DBG(ep, "exch: ABTS received\n"); in fc_exch_recv_abts()
1419 fp = fc_frame_alloc(ep->lp, sizeof(*ap)); in fc_exch_recv_abts()
1421 FC_EXCH_DBG(ep, "Drop ABTS request, out of memory\n"); in fc_exch_recv_abts()
1425 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1426 if (ep->esb_stat & ESB_ST_COMPLETE) { in fc_exch_recv_abts()
1427 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1428 FC_EXCH_DBG(ep, "exch: ABTS rejected, exchange complete\n"); in fc_exch_recv_abts()
1432 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { in fc_exch_recv_abts()
1433 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_recv_abts()
1434 fc_exch_hold(ep); /* hold for REC_QUAL */ in fc_exch_recv_abts()
1436 fc_exch_timer_set_locked(ep, ep->r_a_tov); in fc_exch_recv_abts()
1440 sp = &ep->seq; in fc_exch_recv_abts()
1450 ep->esb_stat |= ESB_ST_ABNORMAL; in fc_exch_recv_abts()
1451 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1511 struct fc_exch *ep = NULL; in fc_exch_recv_req() local
1536 ep = fc_seq_exch(sp); in fc_exch_recv_req()
1538 ep->encaps = fr_encaps(fp); in fc_exch_recv_req()
1551 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_recv_req()
1553 fc_exch_release(ep); /* release from lookup */ in fc_exch_recv_req()
1572 struct fc_exch *ep; in fc_exch_recv_seq_resp() local
1577 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id)); in fc_exch_recv_seq_resp()
1578 if (!ep) { in fc_exch_recv_seq_resp()
1582 if (ep->esb_stat & ESB_ST_COMPLETE) { in fc_exch_recv_seq_resp()
1586 if (ep->rxid == FC_XID_UNKNOWN) in fc_exch_recv_seq_resp()
1587 ep->rxid = ntohs(fh->fh_rx_id); in fc_exch_recv_seq_resp()
1588 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) { in fc_exch_recv_seq_resp()
1592 if (ep->did != ntoh24(fh->fh_s_id) && in fc_exch_recv_seq_resp()
1593 ep->did != FC_FID_FLOGI) { in fc_exch_recv_seq_resp()
1598 sp = &ep->seq; in fc_exch_recv_seq_resp()
1607 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1609 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_recv_seq_resp()
1610 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1618 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1619 rc = fc_exch_done_locked(ep); in fc_exch_recv_seq_resp()
1620 WARN_ON(fc_seq_exch(sp) != ep); in fc_exch_recv_seq_resp()
1621 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1623 fc_exch_delete(ep); in fc_exch_recv_seq_resp()
1639 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_recv_seq_resp()
1642 fc_exch_release(ep); in fc_exch_recv_seq_resp()
1645 fc_exch_release(ep); in fc_exch_recv_seq_resp()
1678 static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) in fc_exch_abts_resp() argument
1688 FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, in fc_exch_abts_resp()
1691 if (cancel_delayed_work_sync(&ep->timeout_work)) { in fc_exch_abts_resp()
1692 FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n"); in fc_exch_abts_resp()
1693 fc_exch_release(ep); /* release from pending timer hold */ in fc_exch_abts_resp()
1696 spin_lock_bh(&ep->ex_lock); in fc_exch_abts_resp()
1710 if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 && in fc_exch_abts_resp()
1712 ap->ba_seq_id == ep->seq_id) && low != high) { in fc_exch_abts_resp()
1713 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_abts_resp()
1714 fc_exch_hold(ep); /* hold for recovery qualifier */ in fc_exch_abts_resp()
1727 sp = &ep->seq; in fc_exch_abts_resp()
1731 if (ep->fh_type != FC_TYPE_FCP && in fc_exch_abts_resp()
1733 rc = fc_exch_done_locked(ep); in fc_exch_abts_resp()
1734 spin_unlock_bh(&ep->ex_lock); in fc_exch_abts_resp()
1736 fc_exch_hold(ep); in fc_exch_abts_resp()
1738 fc_exch_delete(ep); in fc_exch_abts_resp()
1739 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_abts_resp()
1742 fc_exch_timer_set(ep, ep->r_a_tov); in fc_exch_abts_resp()
1743 fc_exch_release(ep); in fc_exch_abts_resp()
1757 struct fc_exch *ep; in fc_exch_recv_bls() local
1764 ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ? in fc_exch_recv_bls()
1766 if (ep && (f_ctl & FC_FC_SEQ_INIT)) { in fc_exch_recv_bls()
1767 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_bls()
1768 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_recv_bls()
1769 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_bls()
1781 if (ep) in fc_exch_recv_bls()
1782 FC_EXCH_DBG(ep, "BLS rctl %x - %s received\n", in fc_exch_recv_bls()
1792 if (ep) in fc_exch_recv_bls()
1793 fc_exch_abts_resp(ep, fp); in fc_exch_recv_bls()
1798 if (ep) in fc_exch_recv_bls()
1799 fc_exch_recv_abts(ep, fp); in fc_exch_recv_bls()
1808 if (ep) in fc_exch_recv_bls()
1809 fc_exch_release(ep); /* release hold taken by fc_exch_find */ in fc_exch_recv_bls()
1881 static void fc_exch_reset(struct fc_exch *ep) in fc_exch_reset() argument
1886 spin_lock_bh(&ep->ex_lock); in fc_exch_reset()
1887 ep->state |= FC_EX_RST_CLEANUP; in fc_exch_reset()
1888 fc_exch_timer_cancel(ep); in fc_exch_reset()
1889 if (ep->esb_stat & ESB_ST_REC_QUAL) in fc_exch_reset()
1890 atomic_dec(&ep->ex_refcnt); /* drop hold for rec_qual */ in fc_exch_reset()
1891 ep->esb_stat &= ~ESB_ST_REC_QUAL; in fc_exch_reset()
1892 sp = &ep->seq; in fc_exch_reset()
1893 rc = fc_exch_done_locked(ep); in fc_exch_reset()
1894 spin_unlock_bh(&ep->ex_lock); in fc_exch_reset()
1896 fc_exch_hold(ep); in fc_exch_reset()
1899 fc_exch_delete(ep); in fc_exch_reset()
1901 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED)); in fc_exch_reset()
1902 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_reset()
1903 fc_exch_release(ep); in fc_exch_reset()
1922 struct fc_exch *ep; in fc_exch_pool_reset() local
1927 list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) { in fc_exch_pool_reset()
1928 if ((lport == ep->lp) && in fc_exch_pool_reset()
1929 (sid == 0 || sid == ep->sid) && in fc_exch_pool_reset()
1930 (did == 0 || did == ep->did)) { in fc_exch_pool_reset()
1931 fc_exch_hold(ep); in fc_exch_pool_reset()
1934 fc_exch_reset(ep); in fc_exch_pool_reset()
1936 fc_exch_release(ep); in fc_exch_pool_reset()
2004 struct fc_exch *ep; in fc_exch_els_rec() local
2032 ep = fc_exch_lookup(lport, xid); in fc_exch_els_rec()
2033 if (!ep) { in fc_exch_els_rec()
2039 FC_EXCH_DBG(ep, "REC request from %x: rxid %x oxid %x\n", in fc_exch_els_rec()
2041 if (ep->oid != sid || oxid != ep->oxid) in fc_exch_els_rec()
2043 if (rxid != FC_XID_UNKNOWN && rxid != ep->rxid) in fc_exch_els_rec()
2047 FC_EXCH_DBG(ep, "Drop REC request, out of memory\n"); in fc_exch_els_rec()
2056 acc->reca_rx_id = htons(ep->rxid); in fc_exch_els_rec()
2057 if (ep->sid == ep->oid) in fc_exch_els_rec()
2058 hton24(acc->reca_rfid, ep->did); in fc_exch_els_rec()
2060 hton24(acc->reca_rfid, ep->sid); in fc_exch_els_rec()
2061 acc->reca_fc4value = htonl(ep->seq.rec_data); in fc_exch_els_rec()
2062 acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP | in fc_exch_els_rec()
2068 fc_exch_release(ep); in fc_exch_els_rec()
2072 fc_exch_release(ep); in fc_exch_els_rec()
2167 struct fc_exch *ep; in fc_exch_seq_send() local
2173 ep = fc_exch_alloc(lport, fp); in fc_exch_seq_send()
2174 if (!ep) { in fc_exch_seq_send()
2178 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_seq_send()
2180 fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id)); in fc_exch_seq_send()
2181 ep->resp = resp; in fc_exch_seq_send()
2182 ep->destructor = destructor; in fc_exch_seq_send()
2183 ep->arg = arg; in fc_exch_seq_send()
2184 ep->r_a_tov = lport->r_a_tov; in fc_exch_seq_send()
2185 ep->lp = lport; in fc_exch_seq_send()
2186 sp = &ep->seq; in fc_exch_seq_send()
2188 ep->fh_type = fh->fh_type; /* save for possbile timeout handling */ in fc_exch_seq_send()
2189 ep->f_ctl = ntoh24(fh->fh_f_ctl); in fc_exch_seq_send()
2190 fc_exch_setup_hdr(ep, fp, ep->f_ctl); in fc_exch_seq_send()
2193 if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) { in fc_exch_seq_send()
2195 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); in fc_exch_seq_send()
2202 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_seq_send()
2203 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */ in fc_exch_seq_send()
2205 if (ep->f_ctl & FC_FC_SEQ_INIT) in fc_exch_seq_send()
2206 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_exch_seq_send()
2207 spin_unlock_bh(&ep->ex_lock); in fc_exch_seq_send()
2212 rc = fc_exch_done_locked(ep); in fc_exch_seq_send()
2213 spin_unlock_bh(&ep->ex_lock); in fc_exch_seq_send()
2215 fc_exch_delete(ep); in fc_exch_seq_send()
2227 static void fc_exch_rrq(struct fc_exch *ep) in fc_exch_rrq() argument
2234 lport = ep->lp; in fc_exch_rrq()
2243 hton24(rrq->rrq_s_id, ep->sid); in fc_exch_rrq()
2244 rrq->rrq_ox_id = htons(ep->oxid); in fc_exch_rrq()
2245 rrq->rrq_rx_id = htons(ep->rxid); in fc_exch_rrq()
2247 did = ep->did; in fc_exch_rrq()
2248 if (ep->esb_stat & ESB_ST_RESP) in fc_exch_rrq()
2249 did = ep->sid; in fc_exch_rrq()
2255 if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep, in fc_exch_rrq()
2260 FC_EXCH_DBG(ep, "exch: RRQ send failed\n"); in fc_exch_rrq()
2261 spin_lock_bh(&ep->ex_lock); in fc_exch_rrq()
2262 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) { in fc_exch_rrq()
2263 spin_unlock_bh(&ep->ex_lock); in fc_exch_rrq()
2265 fc_exch_release(ep); in fc_exch_rrq()
2268 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_rrq()
2269 fc_exch_timer_set_locked(ep, ep->r_a_tov); in fc_exch_rrq()
2270 spin_unlock_bh(&ep->ex_lock); in fc_exch_rrq()
2280 struct fc_exch *ep = NULL; /* request or subject exchange */ in fc_exch_els_rrq() local
2298 ep = fc_exch_lookup(lport, xid); in fc_exch_els_rrq()
2300 if (!ep) in fc_exch_els_rrq()
2302 spin_lock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2303 FC_EXCH_DBG(ep, "RRQ request from %x: xid %x rxid %x oxid %x\n", in fc_exch_els_rrq()
2305 if (ep->oxid != ntohs(rp->rrq_ox_id)) in fc_exch_els_rrq()
2307 if (ep->rxid != ntohs(rp->rrq_rx_id) && in fc_exch_els_rrq()
2308 ep->rxid != FC_XID_UNKNOWN) in fc_exch_els_rrq()
2311 if (ep->sid != sid) in fc_exch_els_rrq()
2317 if (ep->esb_stat & ESB_ST_REC_QUAL) { in fc_exch_els_rrq()
2318 ep->esb_stat &= ~ESB_ST_REC_QUAL; in fc_exch_els_rrq()
2319 atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ in fc_exch_els_rrq()
2321 if (ep->esb_stat & ESB_ST_COMPLETE) in fc_exch_els_rrq()
2322 fc_exch_timer_cancel(ep); in fc_exch_els_rrq()
2324 spin_unlock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2333 spin_unlock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2337 if (ep) in fc_exch_els_rrq()
2338 fc_exch_release(ep); /* drop hold from fc_exch_find */ in fc_exch_els_rrq()