Lines Matching refs:ep

258 static inline void fc_exch_hold(struct fc_exch *ep)  in fc_exch_hold()  argument
260 atomic_inc(&ep->ex_refcnt); in fc_exch_hold()
273 static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp, in fc_exch_setup_hdr() argument
279 fr_sof(fp) = ep->class; in fc_exch_setup_hdr()
280 if (ep->seq.cnt) in fc_exch_setup_hdr()
281 fr_sof(fp) = fc_sof_normal(ep->class); in fc_exch_setup_hdr()
285 if (fc_sof_needs_ack(ep->class)) in fc_exch_setup_hdr()
309 fh->fh_ox_id = htons(ep->oxid); in fc_exch_setup_hdr()
310 fh->fh_rx_id = htons(ep->rxid); in fc_exch_setup_hdr()
311 fh->fh_seq_id = ep->seq.id; in fc_exch_setup_hdr()
312 fh->fh_seq_cnt = htons(ep->seq.cnt); in fc_exch_setup_hdr()
322 static void fc_exch_release(struct fc_exch *ep) in fc_exch_release() argument
326 if (atomic_dec_and_test(&ep->ex_refcnt)) { in fc_exch_release()
327 mp = ep->em; in fc_exch_release()
328 if (ep->destructor) in fc_exch_release()
329 ep->destructor(&ep->seq, ep->arg); in fc_exch_release()
330 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE)); in fc_exch_release()
331 mempool_free(ep, mp->ep_pool); in fc_exch_release()
339 static inline void fc_exch_timer_cancel(struct fc_exch *ep) in fc_exch_timer_cancel() argument
341 if (cancel_delayed_work(&ep->timeout_work)) { in fc_exch_timer_cancel()
342 FC_EXCH_DBG(ep, "Exchange timer canceled\n"); in fc_exch_timer_cancel()
343 atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ in fc_exch_timer_cancel()
356 static inline void fc_exch_timer_set_locked(struct fc_exch *ep, in fc_exch_timer_set_locked() argument
359 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) in fc_exch_timer_set_locked()
362 FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec); in fc_exch_timer_set_locked()
364 fc_exch_hold(ep); /* hold for timer */ in fc_exch_timer_set_locked()
365 if (!queue_delayed_work(fc_exch_workqueue, &ep->timeout_work, in fc_exch_timer_set_locked()
367 FC_EXCH_DBG(ep, "Exchange already queued\n"); in fc_exch_timer_set_locked()
368 fc_exch_release(ep); in fc_exch_timer_set_locked()
377 static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) in fc_exch_timer_set() argument
379 spin_lock_bh(&ep->ex_lock); in fc_exch_timer_set()
380 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_timer_set()
381 spin_unlock_bh(&ep->ex_lock); in fc_exch_timer_set()
390 static int fc_exch_done_locked(struct fc_exch *ep) in fc_exch_done_locked() argument
400 if (ep->state & FC_EX_DONE) in fc_exch_done_locked()
402 ep->esb_stat |= ESB_ST_COMPLETE; in fc_exch_done_locked()
404 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { in fc_exch_done_locked()
405 ep->state |= FC_EX_DONE; in fc_exch_done_locked()
406 fc_exch_timer_cancel(ep); in fc_exch_done_locked()
437 struct fc_exch *ep) in fc_exch_ptr_set() argument
439 ((struct fc_exch **)(pool + 1))[index] = ep; in fc_exch_ptr_set()
446 static void fc_exch_delete(struct fc_exch *ep) in fc_exch_delete() argument
451 pool = ep->pool; in fc_exch_delete()
457 index = (ep->xid - ep->em->min_xid) >> fc_cpu_order; in fc_exch_delete()
458 if (!(ep->state & FC_EX_QUARANTINE)) { in fc_exch_delete()
469 list_del(&ep->ex_list); in fc_exch_delete()
471 fc_exch_release(ep); /* drop hold for exch in mp */ in fc_exch_delete()
477 struct fc_exch *ep; in fc_seq_send_locked() local
483 ep = fc_seq_exch(sp); in fc_seq_send_locked()
485 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL)) { in fc_seq_send_locked()
490 WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT)); in fc_seq_send_locked()
493 fc_exch_setup_hdr(ep, fp, f_ctl); in fc_seq_send_locked()
494 fr_encaps(fp) = ep->encaps; in fc_seq_send_locked()
520 ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ in fc_seq_send_locked()
522 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_seq_send_locked()
538 struct fc_exch *ep; in fc_seq_send() local
540 ep = fc_seq_exch(sp); in fc_seq_send()
541 spin_lock_bh(&ep->ex_lock); in fc_seq_send()
543 spin_unlock_bh(&ep->ex_lock); in fc_seq_send()
557 static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id) in fc_seq_alloc() argument
561 sp = &ep->seq; in fc_seq_alloc()
575 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_start_next_locked() local
577 sp = fc_seq_alloc(ep, ep->seq_id++); in fc_seq_start_next_locked()
578 FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n", in fc_seq_start_next_locked()
579 ep->f_ctl, sp->id); in fc_seq_start_next_locked()
590 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_start_next() local
592 spin_lock_bh(&ep->ex_lock); in fc_seq_start_next()
594 spin_unlock_bh(&ep->ex_lock); in fc_seq_start_next()
609 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_set_resp() local
612 spin_lock_bh(&ep->ex_lock); in fc_seq_set_resp()
613 while (ep->resp_active && ep->resp_task != current) { in fc_seq_set_resp()
614 prepare_to_wait(&ep->resp_wq, &wait, TASK_UNINTERRUPTIBLE); in fc_seq_set_resp()
615 spin_unlock_bh(&ep->ex_lock); in fc_seq_set_resp()
619 spin_lock_bh(&ep->ex_lock); in fc_seq_set_resp()
621 finish_wait(&ep->resp_wq, &wait); in fc_seq_set_resp()
622 ep->resp = resp; in fc_seq_set_resp()
623 ep->arg = arg; in fc_seq_set_resp()
624 spin_unlock_bh(&ep->ex_lock); in fc_seq_set_resp()
644 static int fc_exch_abort_locked(struct fc_exch *ep, in fc_exch_abort_locked() argument
651 FC_EXCH_DBG(ep, "exch: abort, time %d msecs\n", timer_msec); in fc_exch_abort_locked()
652 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) || in fc_exch_abort_locked()
653 ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) { in fc_exch_abort_locked()
654 FC_EXCH_DBG(ep, "exch: already completed esb %x state %x\n", in fc_exch_abort_locked()
655 ep->esb_stat, ep->state); in fc_exch_abort_locked()
662 sp = fc_seq_start_next_locked(&ep->seq); in fc_exch_abort_locked()
667 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_abort_locked()
669 if (ep->sid) { in fc_exch_abort_locked()
673 fp = fc_frame_alloc(ep->lp, 0); in fc_exch_abort_locked()
675 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_abort_locked()
676 fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid, in fc_exch_abort_locked()
679 error = fc_seq_send_locked(ep->lp, sp, fp); in fc_exch_abort_locked()
690 ep->esb_stat |= ESB_ST_ABNORMAL; in fc_exch_abort_locked()
705 struct fc_exch *ep; in fc_seq_exch_abort() local
708 ep = fc_seq_exch(req_sp); in fc_seq_exch_abort()
709 spin_lock_bh(&ep->ex_lock); in fc_seq_exch_abort()
710 error = fc_exch_abort_locked(ep, timer_msec); in fc_seq_exch_abort()
711 spin_unlock_bh(&ep->ex_lock); in fc_seq_exch_abort()
737 static bool fc_invoke_resp(struct fc_exch *ep, struct fc_seq *sp, in fc_invoke_resp() argument
744 spin_lock_bh(&ep->ex_lock); in fc_invoke_resp()
745 ep->resp_active++; in fc_invoke_resp()
746 if (ep->resp_task != current) in fc_invoke_resp()
747 ep->resp_task = !ep->resp_task ? current : NULL; in fc_invoke_resp()
748 resp = ep->resp; in fc_invoke_resp()
749 arg = ep->arg; in fc_invoke_resp()
750 spin_unlock_bh(&ep->ex_lock); in fc_invoke_resp()
757 spin_lock_bh(&ep->ex_lock); in fc_invoke_resp()
758 if (--ep->resp_active == 0) in fc_invoke_resp()
759 ep->resp_task = NULL; in fc_invoke_resp()
760 spin_unlock_bh(&ep->ex_lock); in fc_invoke_resp()
762 if (ep->resp_active == 0) in fc_invoke_resp()
763 wake_up(&ep->resp_wq); in fc_invoke_resp()
774 struct fc_exch *ep = container_of(work, struct fc_exch, in fc_exch_timeout() local
776 struct fc_seq *sp = &ep->seq; in fc_exch_timeout()
780 FC_EXCH_DBG(ep, "Exchange timed out state %x\n", ep->state); in fc_exch_timeout()
782 spin_lock_bh(&ep->ex_lock); in fc_exch_timeout()
783 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) in fc_exch_timeout()
786 e_stat = ep->esb_stat; in fc_exch_timeout()
788 ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; in fc_exch_timeout()
789 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
791 fc_exch_rrq(ep); in fc_exch_timeout()
795 rc = fc_exch_done_locked(ep); in fc_exch_timeout()
796 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
798 fc_exch_delete(ep); in fc_exch_timeout()
799 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_TIMEOUT)); in fc_exch_timeout()
800 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_timeout()
801 fc_seq_exch_abort(sp, 2 * ep->r_a_tov); in fc_exch_timeout()
805 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
810 fc_exch_release(ep); in fc_exch_timeout()
823 struct fc_exch *ep; in fc_exch_em_alloc() local
829 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC); in fc_exch_em_alloc()
830 if (!ep) { in fc_exch_em_alloc()
834 memset(ep, 0, sizeof(*ep)); in fc_exch_em_alloc()
866 fc_exch_hold(ep); /* hold for exch in mp */ in fc_exch_em_alloc()
867 spin_lock_init(&ep->ex_lock); in fc_exch_em_alloc()
873 spin_lock_bh(&ep->ex_lock); in fc_exch_em_alloc()
875 fc_exch_ptr_set(pool, index, ep); in fc_exch_em_alloc()
876 list_add_tail(&ep->ex_list, &pool->ex_list); in fc_exch_em_alloc()
877 fc_seq_alloc(ep, ep->seq_id++); in fc_exch_em_alloc()
884 ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid; in fc_exch_em_alloc()
885 ep->em = mp; in fc_exch_em_alloc()
886 ep->pool = pool; in fc_exch_em_alloc()
887 ep->lp = lport; in fc_exch_em_alloc()
888 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */ in fc_exch_em_alloc()
889 ep->rxid = FC_XID_UNKNOWN; in fc_exch_em_alloc()
890 ep->class = mp->class; in fc_exch_em_alloc()
891 ep->resp_active = 0; in fc_exch_em_alloc()
892 init_waitqueue_head(&ep->resp_wq); in fc_exch_em_alloc()
893 INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout); in fc_exch_em_alloc()
895 return ep; in fc_exch_em_alloc()
899 mempool_free(ep, mp->ep_pool); in fc_exch_em_alloc()
918 struct fc_exch *ep; in fc_exch_alloc() local
922 ep = fc_exch_em_alloc(lport, ema->mp); in fc_exch_alloc()
923 if (ep) in fc_exch_alloc()
924 return ep; in fc_exch_alloc()
939 struct fc_exch *ep = NULL; in fc_exch_find() local
954 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order); in fc_exch_find()
955 if (ep == &fc_quarantine_exch) { in fc_exch_find()
957 ep = NULL; in fc_exch_find()
959 if (ep) { in fc_exch_find()
960 WARN_ON(ep->xid != xid); in fc_exch_find()
961 fc_exch_hold(ep); in fc_exch_find()
965 return ep; in fc_exch_find()
978 struct fc_exch *ep = fc_seq_exch(sp); in fc_exch_done() local
981 spin_lock_bh(&ep->ex_lock); in fc_exch_done()
982 rc = fc_exch_done_locked(ep); in fc_exch_done()
983 spin_unlock_bh(&ep->ex_lock); in fc_exch_done()
985 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_done()
987 fc_exch_delete(ep); in fc_exch_done()
1003 struct fc_exch *ep; in fc_exch_resp() local
1006 ep = fc_exch_alloc(lport, fp); in fc_exch_resp()
1007 if (ep) { in fc_exch_resp()
1008 ep->class = fc_frame_class(fp); in fc_exch_resp()
1013 ep->f_ctl |= FC_FC_EX_CTX; /* we're responding */ in fc_exch_resp()
1014 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not new */ in fc_exch_resp()
1016 ep->sid = ntoh24(fh->fh_d_id); in fc_exch_resp()
1017 ep->did = ntoh24(fh->fh_s_id); in fc_exch_resp()
1018 ep->oid = ep->did; in fc_exch_resp()
1025 ep->rxid = ep->xid; in fc_exch_resp()
1026 ep->oxid = ntohs(fh->fh_ox_id); in fc_exch_resp()
1027 ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT; in fc_exch_resp()
1029 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_exch_resp()
1031 fc_exch_hold(ep); /* hold for caller */ in fc_exch_resp()
1032 spin_unlock_bh(&ep->ex_lock); /* lock from fc_exch_alloc */ in fc_exch_resp()
1034 return ep; in fc_exch_resp()
1052 struct fc_exch *ep = NULL; in fc_seq_lookup_recip() local
1066 ep = fc_exch_find(mp, xid); in fc_seq_lookup_recip()
1067 if (!ep) { in fc_seq_lookup_recip()
1072 if (ep->rxid == FC_XID_UNKNOWN) in fc_seq_lookup_recip()
1073 ep->rxid = ntohs(fh->fh_rx_id); in fc_seq_lookup_recip()
1074 else if (ep->rxid != ntohs(fh->fh_rx_id)) { in fc_seq_lookup_recip()
1095 ep = fc_exch_find(mp, xid); in fc_seq_lookup_recip()
1097 if (ep) { in fc_seq_lookup_recip()
1102 ep = fc_exch_resp(lport, mp, fp); in fc_seq_lookup_recip()
1103 if (!ep) { in fc_seq_lookup_recip()
1107 xid = ep->xid; /* get our XID */ in fc_seq_lookup_recip()
1108 } else if (!ep) { in fc_seq_lookup_recip()
1115 spin_lock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1121 sp = &ep->seq; in fc_seq_lookup_recip()
1125 sp = &ep->seq; in fc_seq_lookup_recip()
1146 spin_unlock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1154 WARN_ON(ep != fc_seq_exch(sp)); in fc_seq_lookup_recip()
1157 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_seq_lookup_recip()
1158 spin_unlock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1164 fc_exch_done(&ep->seq); in fc_seq_lookup_recip()
1165 fc_exch_release(ep); /* hold from fc_exch_find/fc_exch_resp */ in fc_seq_lookup_recip()
1181 struct fc_exch *ep; in fc_seq_lookup_orig() local
1189 ep = fc_exch_find(mp, xid); in fc_seq_lookup_orig()
1190 if (!ep) in fc_seq_lookup_orig()
1192 if (ep->seq.id == fh->fh_seq_id) { in fc_seq_lookup_orig()
1196 sp = &ep->seq; in fc_seq_lookup_orig()
1198 ep->rxid == FC_XID_UNKNOWN) { in fc_seq_lookup_orig()
1199 ep->rxid = ntohs(fh->fh_rx_id); in fc_seq_lookup_orig()
1202 fc_exch_release(ep); in fc_seq_lookup_orig()
1214 static void fc_exch_set_addr(struct fc_exch *ep, in fc_exch_set_addr() argument
1217 ep->oid = orig_id; in fc_exch_set_addr()
1218 if (ep->esb_stat & ESB_ST_RESP) { in fc_exch_set_addr()
1219 ep->sid = resp_id; in fc_exch_set_addr()
1220 ep->did = orig_id; in fc_exch_set_addr()
1222 ep->sid = orig_id; in fc_exch_set_addr()
1223 ep->did = resp_id; in fc_exch_set_addr()
1269 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_send_last() local
1272 f_ctl |= ep->f_ctl; in fc_seq_send_last()
1273 fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0); in fc_seq_send_last()
1274 fc_seq_send_locked(ep->lp, sp, fp); in fc_seq_send_last()
1289 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_send_ack() local
1290 struct fc_lport *lport = ep->lp; in fc_seq_send_ack()
1299 FC_EXCH_DBG(ep, "Drop ACK request, out of memory\n"); in fc_seq_send_ack()
1323 fc_exch_setup_hdr(ep, fp, f_ctl); in fc_seq_send_ack()
1420 static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp) in fc_exch_recv_abts() argument
1427 if (!ep) in fc_exch_recv_abts()
1430 FC_EXCH_DBG(ep, "exch: ABTS received\n"); in fc_exch_recv_abts()
1431 fp = fc_frame_alloc(ep->lp, sizeof(*ap)); in fc_exch_recv_abts()
1433 FC_EXCH_DBG(ep, "Drop ABTS request, out of memory\n"); in fc_exch_recv_abts()
1437 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1438 if (ep->esb_stat & ESB_ST_COMPLETE) { in fc_exch_recv_abts()
1439 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1440 FC_EXCH_DBG(ep, "exch: ABTS rejected, exchange complete\n"); in fc_exch_recv_abts()
1444 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { in fc_exch_recv_abts()
1445 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_recv_abts()
1446 fc_exch_hold(ep); /* hold for REC_QUAL */ in fc_exch_recv_abts()
1448 fc_exch_timer_set_locked(ep, ep->r_a_tov); in fc_exch_recv_abts()
1452 sp = &ep->seq; in fc_exch_recv_abts()
1462 ep->esb_stat |= ESB_ST_ABNORMAL; in fc_exch_recv_abts()
1463 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1523 struct fc_exch *ep = NULL; in fc_exch_recv_req() local
1548 ep = fc_seq_exch(sp); in fc_exch_recv_req()
1550 ep->encaps = fr_encaps(fp); in fc_exch_recv_req()
1563 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_recv_req()
1565 fc_exch_release(ep); /* release from lookup */ in fc_exch_recv_req()
1584 struct fc_exch *ep; in fc_exch_recv_seq_resp() local
1589 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id)); in fc_exch_recv_seq_resp()
1590 if (!ep) { in fc_exch_recv_seq_resp()
1594 if (ep->esb_stat & ESB_ST_COMPLETE) { in fc_exch_recv_seq_resp()
1598 if (ep->rxid == FC_XID_UNKNOWN) in fc_exch_recv_seq_resp()
1599 ep->rxid = ntohs(fh->fh_rx_id); in fc_exch_recv_seq_resp()
1600 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) { in fc_exch_recv_seq_resp()
1604 if (ep->did != ntoh24(fh->fh_s_id) && in fc_exch_recv_seq_resp()
1605 ep->did != FC_FID_FLOGI) { in fc_exch_recv_seq_resp()
1610 sp = &ep->seq; in fc_exch_recv_seq_resp()
1619 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1621 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_recv_seq_resp()
1622 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1630 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1631 rc = fc_exch_done_locked(ep); in fc_exch_recv_seq_resp()
1632 WARN_ON(fc_seq_exch(sp) != ep); in fc_exch_recv_seq_resp()
1633 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1635 fc_exch_delete(ep); in fc_exch_recv_seq_resp()
1651 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_recv_seq_resp()
1654 fc_exch_release(ep); in fc_exch_recv_seq_resp()
1657 fc_exch_release(ep); in fc_exch_recv_seq_resp()
1690 static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) in fc_exch_abts_resp() argument
1700 FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, in fc_exch_abts_resp()
1703 if (cancel_delayed_work_sync(&ep->timeout_work)) { in fc_exch_abts_resp()
1704 FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n"); in fc_exch_abts_resp()
1705 fc_exch_release(ep); /* release from pending timer hold */ in fc_exch_abts_resp()
1708 spin_lock_bh(&ep->ex_lock); in fc_exch_abts_resp()
1722 if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 && in fc_exch_abts_resp()
1724 ap->ba_seq_id == ep->seq_id) && low != high) { in fc_exch_abts_resp()
1725 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_abts_resp()
1726 fc_exch_hold(ep); /* hold for recovery qualifier */ in fc_exch_abts_resp()
1739 sp = &ep->seq; in fc_exch_abts_resp()
1743 if (ep->fh_type != FC_TYPE_FCP && in fc_exch_abts_resp()
1745 rc = fc_exch_done_locked(ep); in fc_exch_abts_resp()
1746 spin_unlock_bh(&ep->ex_lock); in fc_exch_abts_resp()
1748 fc_exch_hold(ep); in fc_exch_abts_resp()
1750 fc_exch_delete(ep); in fc_exch_abts_resp()
1751 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_abts_resp()
1754 fc_exch_timer_set(ep, ep->r_a_tov); in fc_exch_abts_resp()
1755 fc_exch_release(ep); in fc_exch_abts_resp()
1769 struct fc_exch *ep; in fc_exch_recv_bls() local
1776 ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ? in fc_exch_recv_bls()
1778 if (ep && (f_ctl & FC_FC_SEQ_INIT)) { in fc_exch_recv_bls()
1779 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_bls()
1780 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_recv_bls()
1781 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_bls()
1793 if (ep) in fc_exch_recv_bls()
1794 FC_EXCH_DBG(ep, "BLS rctl %x - %s received\n", in fc_exch_recv_bls()
1804 if (ep) in fc_exch_recv_bls()
1805 fc_exch_abts_resp(ep, fp); in fc_exch_recv_bls()
1810 if (ep) in fc_exch_recv_bls()
1811 fc_exch_recv_abts(ep, fp); in fc_exch_recv_bls()
1820 if (ep) in fc_exch_recv_bls()
1821 fc_exch_release(ep); /* release hold taken by fc_exch_find */ in fc_exch_recv_bls()
1893 static void fc_exch_reset(struct fc_exch *ep) in fc_exch_reset() argument
1898 spin_lock_bh(&ep->ex_lock); in fc_exch_reset()
1899 ep->state |= FC_EX_RST_CLEANUP; in fc_exch_reset()
1900 fc_exch_timer_cancel(ep); in fc_exch_reset()
1901 if (ep->esb_stat & ESB_ST_REC_QUAL) in fc_exch_reset()
1902 atomic_dec(&ep->ex_refcnt); /* drop hold for rec_qual */ in fc_exch_reset()
1903 ep->esb_stat &= ~ESB_ST_REC_QUAL; in fc_exch_reset()
1904 sp = &ep->seq; in fc_exch_reset()
1905 rc = fc_exch_done_locked(ep); in fc_exch_reset()
1906 spin_unlock_bh(&ep->ex_lock); in fc_exch_reset()
1908 fc_exch_hold(ep); in fc_exch_reset()
1911 fc_exch_delete(ep); in fc_exch_reset()
1913 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED)); in fc_exch_reset()
1914 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_reset()
1915 fc_exch_release(ep); in fc_exch_reset()
1934 struct fc_exch *ep; in fc_exch_pool_reset() local
1939 list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) { in fc_exch_pool_reset()
1940 if ((lport == ep->lp) && in fc_exch_pool_reset()
1941 (sid == 0 || sid == ep->sid) && in fc_exch_pool_reset()
1942 (did == 0 || did == ep->did)) { in fc_exch_pool_reset()
1943 fc_exch_hold(ep); in fc_exch_pool_reset()
1946 fc_exch_reset(ep); in fc_exch_pool_reset()
1948 fc_exch_release(ep); in fc_exch_pool_reset()
2016 struct fc_exch *ep; in fc_exch_els_rec() local
2044 ep = fc_exch_lookup(lport, xid); in fc_exch_els_rec()
2045 if (!ep) { in fc_exch_els_rec()
2051 FC_EXCH_DBG(ep, "REC request from %x: rxid %x oxid %x\n", in fc_exch_els_rec()
2053 if (ep->oid != sid || oxid != ep->oxid) in fc_exch_els_rec()
2055 if (rxid != FC_XID_UNKNOWN && rxid != ep->rxid) in fc_exch_els_rec()
2059 FC_EXCH_DBG(ep, "Drop REC request, out of memory\n"); in fc_exch_els_rec()
2068 acc->reca_rx_id = htons(ep->rxid); in fc_exch_els_rec()
2069 if (ep->sid == ep->oid) in fc_exch_els_rec()
2070 hton24(acc->reca_rfid, ep->did); in fc_exch_els_rec()
2072 hton24(acc->reca_rfid, ep->sid); in fc_exch_els_rec()
2073 acc->reca_fc4value = htonl(ep->seq.rec_data); in fc_exch_els_rec()
2074 acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP | in fc_exch_els_rec()
2080 fc_exch_release(ep); in fc_exch_els_rec()
2084 fc_exch_release(ep); in fc_exch_els_rec()
2179 struct fc_exch *ep; in fc_exch_seq_send() local
2185 ep = fc_exch_alloc(lport, fp); in fc_exch_seq_send()
2186 if (!ep) { in fc_exch_seq_send()
2190 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_seq_send()
2192 fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id)); in fc_exch_seq_send()
2193 ep->resp = resp; in fc_exch_seq_send()
2194 ep->destructor = destructor; in fc_exch_seq_send()
2195 ep->arg = arg; in fc_exch_seq_send()
2196 ep->r_a_tov = lport->r_a_tov; in fc_exch_seq_send()
2197 ep->lp = lport; in fc_exch_seq_send()
2198 sp = &ep->seq; in fc_exch_seq_send()
2200 ep->fh_type = fh->fh_type; /* save for possbile timeout handling */ in fc_exch_seq_send()
2201 ep->f_ctl = ntoh24(fh->fh_f_ctl); in fc_exch_seq_send()
2202 fc_exch_setup_hdr(ep, fp, ep->f_ctl); in fc_exch_seq_send()
2205 if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) { in fc_exch_seq_send()
2207 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); in fc_exch_seq_send()
2214 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_seq_send()
2215 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */ in fc_exch_seq_send()
2217 if (ep->f_ctl & FC_FC_SEQ_INIT) in fc_exch_seq_send()
2218 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_exch_seq_send()
2219 spin_unlock_bh(&ep->ex_lock); in fc_exch_seq_send()
2224 rc = fc_exch_done_locked(ep); in fc_exch_seq_send()
2225 spin_unlock_bh(&ep->ex_lock); in fc_exch_seq_send()
2227 fc_exch_delete(ep); in fc_exch_seq_send()
2239 static void fc_exch_rrq(struct fc_exch *ep) in fc_exch_rrq() argument
2246 lport = ep->lp; in fc_exch_rrq()
2255 hton24(rrq->rrq_s_id, ep->sid); in fc_exch_rrq()
2256 rrq->rrq_ox_id = htons(ep->oxid); in fc_exch_rrq()
2257 rrq->rrq_rx_id = htons(ep->rxid); in fc_exch_rrq()
2259 did = ep->did; in fc_exch_rrq()
2260 if (ep->esb_stat & ESB_ST_RESP) in fc_exch_rrq()
2261 did = ep->sid; in fc_exch_rrq()
2267 if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep, in fc_exch_rrq()
2272 FC_EXCH_DBG(ep, "exch: RRQ send failed\n"); in fc_exch_rrq()
2273 spin_lock_bh(&ep->ex_lock); in fc_exch_rrq()
2274 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) { in fc_exch_rrq()
2275 spin_unlock_bh(&ep->ex_lock); in fc_exch_rrq()
2277 fc_exch_release(ep); in fc_exch_rrq()
2280 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_rrq()
2281 fc_exch_timer_set_locked(ep, ep->r_a_tov); in fc_exch_rrq()
2282 spin_unlock_bh(&ep->ex_lock); in fc_exch_rrq()
2292 struct fc_exch *ep = NULL; /* request or subject exchange */ in fc_exch_els_rrq() local
2310 ep = fc_exch_lookup(lport, xid); in fc_exch_els_rrq()
2312 if (!ep) in fc_exch_els_rrq()
2314 spin_lock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2315 FC_EXCH_DBG(ep, "RRQ request from %x: xid %x rxid %x oxid %x\n", in fc_exch_els_rrq()
2317 if (ep->oxid != ntohs(rp->rrq_ox_id)) in fc_exch_els_rrq()
2319 if (ep->rxid != ntohs(rp->rrq_rx_id) && in fc_exch_els_rrq()
2320 ep->rxid != FC_XID_UNKNOWN) in fc_exch_els_rrq()
2323 if (ep->sid != sid) in fc_exch_els_rrq()
2329 if (ep->esb_stat & ESB_ST_REC_QUAL) { in fc_exch_els_rrq()
2330 ep->esb_stat &= ~ESB_ST_REC_QUAL; in fc_exch_els_rrq()
2331 atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ in fc_exch_els_rrq()
2333 if (ep->esb_stat & ESB_ST_COMPLETE) in fc_exch_els_rrq()
2334 fc_exch_timer_cancel(ep); in fc_exch_els_rrq()
2336 spin_unlock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2345 spin_unlock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2349 if (ep) in fc_exch_els_rrq()
2350 fc_exch_release(ep); /* drop hold from fc_exch_find */ in fc_exch_els_rrq()