Lines Matching refs:ep
257 static inline void fc_exch_hold(struct fc_exch *ep) in fc_exch_hold() argument
259 atomic_inc(&ep->ex_refcnt); in fc_exch_hold()
272 static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp, in fc_exch_setup_hdr() argument
278 fr_sof(fp) = ep->class; in fc_exch_setup_hdr()
279 if (ep->seq.cnt) in fc_exch_setup_hdr()
280 fr_sof(fp) = fc_sof_normal(ep->class); in fc_exch_setup_hdr()
284 if (fc_sof_needs_ack(ep->class)) in fc_exch_setup_hdr()
308 fh->fh_ox_id = htons(ep->oxid); in fc_exch_setup_hdr()
309 fh->fh_rx_id = htons(ep->rxid); in fc_exch_setup_hdr()
310 fh->fh_seq_id = ep->seq.id; in fc_exch_setup_hdr()
311 fh->fh_seq_cnt = htons(ep->seq.cnt); in fc_exch_setup_hdr()
321 static void fc_exch_release(struct fc_exch *ep) in fc_exch_release() argument
325 if (atomic_dec_and_test(&ep->ex_refcnt)) { in fc_exch_release()
326 mp = ep->em; in fc_exch_release()
327 if (ep->destructor) in fc_exch_release()
328 ep->destructor(&ep->seq, ep->arg); in fc_exch_release()
329 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE)); in fc_exch_release()
330 mempool_free(ep, mp->ep_pool); in fc_exch_release()
338 static inline void fc_exch_timer_cancel(struct fc_exch *ep) in fc_exch_timer_cancel() argument
340 if (cancel_delayed_work(&ep->timeout_work)) { in fc_exch_timer_cancel()
341 FC_EXCH_DBG(ep, "Exchange timer canceled\n"); in fc_exch_timer_cancel()
342 atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ in fc_exch_timer_cancel()
355 static inline void fc_exch_timer_set_locked(struct fc_exch *ep, in fc_exch_timer_set_locked() argument
358 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) in fc_exch_timer_set_locked()
361 FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec); in fc_exch_timer_set_locked()
363 fc_exch_hold(ep); /* hold for timer */ in fc_exch_timer_set_locked()
364 if (!queue_delayed_work(fc_exch_workqueue, &ep->timeout_work, in fc_exch_timer_set_locked()
366 fc_exch_release(ep); in fc_exch_timer_set_locked()
374 static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) in fc_exch_timer_set() argument
376 spin_lock_bh(&ep->ex_lock); in fc_exch_timer_set()
377 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_timer_set()
378 spin_unlock_bh(&ep->ex_lock); in fc_exch_timer_set()
387 static int fc_exch_done_locked(struct fc_exch *ep) in fc_exch_done_locked() argument
397 if (ep->state & FC_EX_DONE) in fc_exch_done_locked()
399 ep->esb_stat |= ESB_ST_COMPLETE; in fc_exch_done_locked()
401 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { in fc_exch_done_locked()
402 ep->state |= FC_EX_DONE; in fc_exch_done_locked()
403 fc_exch_timer_cancel(ep); in fc_exch_done_locked()
432 struct fc_exch *ep) in fc_exch_ptr_set() argument
434 ((struct fc_exch **)(pool + 1))[index] = ep; in fc_exch_ptr_set()
441 static void fc_exch_delete(struct fc_exch *ep) in fc_exch_delete() argument
446 pool = ep->pool; in fc_exch_delete()
452 index = (ep->xid - ep->em->min_xid) >> fc_cpu_order; in fc_exch_delete()
461 list_del(&ep->ex_list); in fc_exch_delete()
463 fc_exch_release(ep); /* drop hold for exch in mp */ in fc_exch_delete()
469 struct fc_exch *ep; in fc_seq_send_locked() local
475 ep = fc_seq_exch(sp); in fc_seq_send_locked()
477 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL)) { in fc_seq_send_locked()
482 WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT)); in fc_seq_send_locked()
485 fc_exch_setup_hdr(ep, fp, f_ctl); in fc_seq_send_locked()
486 fr_encaps(fp) = ep->encaps; in fc_seq_send_locked()
512 ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ in fc_seq_send_locked()
514 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_seq_send_locked()
531 struct fc_exch *ep; in fc_seq_send() local
533 ep = fc_seq_exch(sp); in fc_seq_send()
534 spin_lock_bh(&ep->ex_lock); in fc_seq_send()
536 spin_unlock_bh(&ep->ex_lock); in fc_seq_send()
549 static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id) in fc_seq_alloc() argument
553 sp = &ep->seq; in fc_seq_alloc()
567 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_start_next_locked() local
569 sp = fc_seq_alloc(ep, ep->seq_id++); in fc_seq_start_next_locked()
570 FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n", in fc_seq_start_next_locked()
571 ep->f_ctl, sp->id); in fc_seq_start_next_locked()
582 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_start_next() local
584 spin_lock_bh(&ep->ex_lock); in fc_seq_start_next()
586 spin_unlock_bh(&ep->ex_lock); in fc_seq_start_next()
601 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_set_resp() local
604 spin_lock_bh(&ep->ex_lock); in fc_seq_set_resp()
605 while (ep->resp_active && ep->resp_task != current) { in fc_seq_set_resp()
606 prepare_to_wait(&ep->resp_wq, &wait, TASK_UNINTERRUPTIBLE); in fc_seq_set_resp()
607 spin_unlock_bh(&ep->ex_lock); in fc_seq_set_resp()
611 spin_lock_bh(&ep->ex_lock); in fc_seq_set_resp()
613 finish_wait(&ep->resp_wq, &wait); in fc_seq_set_resp()
614 ep->resp = resp; in fc_seq_set_resp()
615 ep->arg = arg; in fc_seq_set_resp()
616 spin_unlock_bh(&ep->ex_lock); in fc_seq_set_resp()
628 static int fc_exch_abort_locked(struct fc_exch *ep, in fc_exch_abort_locked() argument
635 if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) || in fc_exch_abort_locked()
636 ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) in fc_exch_abort_locked()
642 sp = fc_seq_start_next_locked(&ep->seq); in fc_exch_abort_locked()
647 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_abort_locked()
649 if (ep->sid) { in fc_exch_abort_locked()
653 fp = fc_frame_alloc(ep->lp, 0); in fc_exch_abort_locked()
655 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_abort_locked()
656 fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid, in fc_exch_abort_locked()
659 error = fc_seq_send_locked(ep->lp, sp, fp); in fc_exch_abort_locked()
670 ep->esb_stat |= ESB_ST_ABNORMAL; in fc_exch_abort_locked()
686 struct fc_exch *ep; in fc_seq_exch_abort() local
689 ep = fc_seq_exch(req_sp); in fc_seq_exch_abort()
690 spin_lock_bh(&ep->ex_lock); in fc_seq_exch_abort()
691 error = fc_exch_abort_locked(ep, timer_msec); in fc_seq_exch_abort()
692 spin_unlock_bh(&ep->ex_lock); in fc_seq_exch_abort()
718 static bool fc_invoke_resp(struct fc_exch *ep, struct fc_seq *sp, in fc_invoke_resp() argument
725 spin_lock_bh(&ep->ex_lock); in fc_invoke_resp()
726 ep->resp_active++; in fc_invoke_resp()
727 if (ep->resp_task != current) in fc_invoke_resp()
728 ep->resp_task = !ep->resp_task ? current : NULL; in fc_invoke_resp()
729 resp = ep->resp; in fc_invoke_resp()
730 arg = ep->arg; in fc_invoke_resp()
731 spin_unlock_bh(&ep->ex_lock); in fc_invoke_resp()
738 spin_lock_bh(&ep->ex_lock); in fc_invoke_resp()
739 if (--ep->resp_active == 0) in fc_invoke_resp()
740 ep->resp_task = NULL; in fc_invoke_resp()
741 spin_unlock_bh(&ep->ex_lock); in fc_invoke_resp()
743 if (ep->resp_active == 0) in fc_invoke_resp()
744 wake_up(&ep->resp_wq); in fc_invoke_resp()
755 struct fc_exch *ep = container_of(work, struct fc_exch, in fc_exch_timeout() local
757 struct fc_seq *sp = &ep->seq; in fc_exch_timeout()
761 FC_EXCH_DBG(ep, "Exchange timed out\n"); in fc_exch_timeout()
763 spin_lock_bh(&ep->ex_lock); in fc_exch_timeout()
764 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) in fc_exch_timeout()
767 e_stat = ep->esb_stat; in fc_exch_timeout()
769 ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; in fc_exch_timeout()
770 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
772 fc_exch_rrq(ep); in fc_exch_timeout()
776 rc = fc_exch_done_locked(ep); in fc_exch_timeout()
777 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
779 fc_exch_delete(ep); in fc_exch_timeout()
780 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_TIMEOUT)); in fc_exch_timeout()
781 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_timeout()
782 fc_seq_exch_abort(sp, 2 * ep->r_a_tov); in fc_exch_timeout()
786 spin_unlock_bh(&ep->ex_lock); in fc_exch_timeout()
791 fc_exch_release(ep); in fc_exch_timeout()
804 struct fc_exch *ep; in fc_exch_em_alloc() local
810 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC); in fc_exch_em_alloc()
811 if (!ep) { in fc_exch_em_alloc()
815 memset(ep, 0, sizeof(*ep)); in fc_exch_em_alloc()
843 fc_exch_hold(ep); /* hold for exch in mp */ in fc_exch_em_alloc()
844 spin_lock_init(&ep->ex_lock); in fc_exch_em_alloc()
850 spin_lock_bh(&ep->ex_lock); in fc_exch_em_alloc()
852 fc_exch_ptr_set(pool, index, ep); in fc_exch_em_alloc()
853 list_add_tail(&ep->ex_list, &pool->ex_list); in fc_exch_em_alloc()
854 fc_seq_alloc(ep, ep->seq_id++); in fc_exch_em_alloc()
861 ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid; in fc_exch_em_alloc()
862 ep->em = mp; in fc_exch_em_alloc()
863 ep->pool = pool; in fc_exch_em_alloc()
864 ep->lp = lport; in fc_exch_em_alloc()
865 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */ in fc_exch_em_alloc()
866 ep->rxid = FC_XID_UNKNOWN; in fc_exch_em_alloc()
867 ep->class = mp->class; in fc_exch_em_alloc()
868 ep->resp_active = 0; in fc_exch_em_alloc()
869 init_waitqueue_head(&ep->resp_wq); in fc_exch_em_alloc()
870 INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout); in fc_exch_em_alloc()
872 return ep; in fc_exch_em_alloc()
876 mempool_free(ep, mp->ep_pool); in fc_exch_em_alloc()
910 struct fc_exch *ep = NULL; in fc_exch_find() local
915 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order); in fc_exch_find()
916 if (ep) { in fc_exch_find()
917 WARN_ON(ep->xid != xid); in fc_exch_find()
918 fc_exch_hold(ep); in fc_exch_find()
922 return ep; in fc_exch_find()
935 struct fc_exch *ep = fc_seq_exch(sp); in fc_exch_done() local
938 spin_lock_bh(&ep->ex_lock); in fc_exch_done()
939 rc = fc_exch_done_locked(ep); in fc_exch_done()
940 spin_unlock_bh(&ep->ex_lock); in fc_exch_done()
942 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_done()
944 fc_exch_delete(ep); in fc_exch_done()
959 struct fc_exch *ep; in fc_exch_resp() local
962 ep = fc_exch_alloc(lport, fp); in fc_exch_resp()
963 if (ep) { in fc_exch_resp()
964 ep->class = fc_frame_class(fp); in fc_exch_resp()
969 ep->f_ctl |= FC_FC_EX_CTX; /* we're responding */ in fc_exch_resp()
970 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not new */ in fc_exch_resp()
972 ep->sid = ntoh24(fh->fh_d_id); in fc_exch_resp()
973 ep->did = ntoh24(fh->fh_s_id); in fc_exch_resp()
974 ep->oid = ep->did; in fc_exch_resp()
981 ep->rxid = ep->xid; in fc_exch_resp()
982 ep->oxid = ntohs(fh->fh_ox_id); in fc_exch_resp()
983 ep->esb_stat |= ESB_ST_RESP | ESB_ST_SEQ_INIT; in fc_exch_resp()
985 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_exch_resp()
987 fc_exch_hold(ep); /* hold for caller */ in fc_exch_resp()
988 spin_unlock_bh(&ep->ex_lock); /* lock from fc_exch_alloc */ in fc_exch_resp()
990 return ep; in fc_exch_resp()
1008 struct fc_exch *ep = NULL; in fc_seq_lookup_recip() local
1022 ep = fc_exch_find(mp, xid); in fc_seq_lookup_recip()
1023 if (!ep) { in fc_seq_lookup_recip()
1028 if (ep->rxid == FC_XID_UNKNOWN) in fc_seq_lookup_recip()
1029 ep->rxid = ntohs(fh->fh_rx_id); in fc_seq_lookup_recip()
1030 else if (ep->rxid != ntohs(fh->fh_rx_id)) { in fc_seq_lookup_recip()
1051 ep = fc_exch_find(mp, xid); in fc_seq_lookup_recip()
1053 if (ep) { in fc_seq_lookup_recip()
1058 ep = fc_exch_resp(lport, mp, fp); in fc_seq_lookup_recip()
1059 if (!ep) { in fc_seq_lookup_recip()
1063 xid = ep->xid; /* get our XID */ in fc_seq_lookup_recip()
1064 } else if (!ep) { in fc_seq_lookup_recip()
1071 spin_lock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1077 sp = &ep->seq; in fc_seq_lookup_recip()
1081 sp = &ep->seq; in fc_seq_lookup_recip()
1102 spin_unlock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1110 WARN_ON(ep != fc_seq_exch(sp)); in fc_seq_lookup_recip()
1113 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_seq_lookup_recip()
1114 spin_unlock_bh(&ep->ex_lock); in fc_seq_lookup_recip()
1120 fc_exch_done(&ep->seq); in fc_seq_lookup_recip()
1121 fc_exch_release(ep); /* hold from fc_exch_find/fc_exch_resp */ in fc_seq_lookup_recip()
1137 struct fc_exch *ep; in fc_seq_lookup_orig() local
1145 ep = fc_exch_find(mp, xid); in fc_seq_lookup_orig()
1146 if (!ep) in fc_seq_lookup_orig()
1148 if (ep->seq.id == fh->fh_seq_id) { in fc_seq_lookup_orig()
1152 sp = &ep->seq; in fc_seq_lookup_orig()
1154 ep->rxid == FC_XID_UNKNOWN) { in fc_seq_lookup_orig()
1155 ep->rxid = ntohs(fh->fh_rx_id); in fc_seq_lookup_orig()
1158 fc_exch_release(ep); in fc_seq_lookup_orig()
1170 static void fc_exch_set_addr(struct fc_exch *ep, in fc_exch_set_addr() argument
1173 ep->oid = orig_id; in fc_exch_set_addr()
1174 if (ep->esb_stat & ESB_ST_RESP) { in fc_exch_set_addr()
1175 ep->sid = resp_id; in fc_exch_set_addr()
1176 ep->did = orig_id; in fc_exch_set_addr()
1178 ep->sid = orig_id; in fc_exch_set_addr()
1179 ep->did = resp_id; in fc_exch_set_addr()
1224 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_send_last() local
1227 f_ctl |= ep->f_ctl; in fc_seq_send_last()
1228 fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0); in fc_seq_send_last()
1229 fc_seq_send_locked(ep->lp, sp, fp); in fc_seq_send_last()
1244 struct fc_exch *ep = fc_seq_exch(sp); in fc_seq_send_ack() local
1245 struct fc_lport *lport = ep->lp; in fc_seq_send_ack()
1276 fc_exch_setup_hdr(ep, fp, f_ctl); in fc_seq_send_ack()
1368 static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp) in fc_exch_recv_abts() argument
1375 if (!ep) in fc_exch_recv_abts()
1378 fp = fc_frame_alloc(ep->lp, sizeof(*ap)); in fc_exch_recv_abts()
1382 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1383 if (ep->esb_stat & ESB_ST_COMPLETE) { in fc_exch_recv_abts()
1384 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1389 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { in fc_exch_recv_abts()
1390 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_recv_abts()
1391 fc_exch_hold(ep); /* hold for REC_QUAL */ in fc_exch_recv_abts()
1393 fc_exch_timer_set_locked(ep, ep->r_a_tov); in fc_exch_recv_abts()
1397 sp = &ep->seq; in fc_exch_recv_abts()
1407 ep->esb_stat |= ESB_ST_ABNORMAL; in fc_exch_recv_abts()
1408 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_abts()
1466 struct fc_exch *ep = NULL; in fc_exch_recv_req() local
1491 ep = fc_seq_exch(sp); in fc_exch_recv_req()
1493 ep->encaps = fr_encaps(fp); in fc_exch_recv_req()
1506 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_recv_req()
1508 fc_exch_release(ep); /* release from lookup */ in fc_exch_recv_req()
1527 struct fc_exch *ep; in fc_exch_recv_seq_resp() local
1532 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id)); in fc_exch_recv_seq_resp()
1533 if (!ep) { in fc_exch_recv_seq_resp()
1537 if (ep->esb_stat & ESB_ST_COMPLETE) { in fc_exch_recv_seq_resp()
1541 if (ep->rxid == FC_XID_UNKNOWN) in fc_exch_recv_seq_resp()
1542 ep->rxid = ntohs(fh->fh_rx_id); in fc_exch_recv_seq_resp()
1543 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) { in fc_exch_recv_seq_resp()
1547 if (ep->did != ntoh24(fh->fh_s_id) && in fc_exch_recv_seq_resp()
1548 ep->did != FC_FID_FLOGI) { in fc_exch_recv_seq_resp()
1553 sp = &ep->seq; in fc_exch_recv_seq_resp()
1565 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1567 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_recv_seq_resp()
1568 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1576 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1577 rc = fc_exch_done_locked(ep); in fc_exch_recv_seq_resp()
1578 WARN_ON(fc_seq_exch(sp) != ep); in fc_exch_recv_seq_resp()
1579 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_seq_resp()
1581 fc_exch_delete(ep); in fc_exch_recv_seq_resp()
1597 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_recv_seq_resp()
1600 fc_exch_release(ep); in fc_exch_recv_seq_resp()
1603 fc_exch_release(ep); in fc_exch_recv_seq_resp()
1636 static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) in fc_exch_abts_resp() argument
1646 FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, in fc_exch_abts_resp()
1649 if (cancel_delayed_work_sync(&ep->timeout_work)) { in fc_exch_abts_resp()
1650 FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n"); in fc_exch_abts_resp()
1651 fc_exch_release(ep); /* release from pending timer hold */ in fc_exch_abts_resp()
1654 spin_lock_bh(&ep->ex_lock); in fc_exch_abts_resp()
1668 if ((ep->esb_stat & ESB_ST_REC_QUAL) == 0 && in fc_exch_abts_resp()
1670 ap->ba_seq_id == ep->seq_id) && low != high) { in fc_exch_abts_resp()
1671 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_abts_resp()
1672 fc_exch_hold(ep); /* hold for recovery qualifier */ in fc_exch_abts_resp()
1685 sp = &ep->seq; in fc_exch_abts_resp()
1689 if (ep->fh_type != FC_TYPE_FCP && in fc_exch_abts_resp()
1691 rc = fc_exch_done_locked(ep); in fc_exch_abts_resp()
1692 spin_unlock_bh(&ep->ex_lock); in fc_exch_abts_resp()
1694 fc_exch_hold(ep); in fc_exch_abts_resp()
1696 fc_exch_delete(ep); in fc_exch_abts_resp()
1697 if (!fc_invoke_resp(ep, sp, fp)) in fc_exch_abts_resp()
1700 fc_exch_timer_set(ep, ep->r_a_tov); in fc_exch_abts_resp()
1701 fc_exch_release(ep); in fc_exch_abts_resp()
1715 struct fc_exch *ep; in fc_exch_recv_bls() local
1722 ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ? in fc_exch_recv_bls()
1724 if (ep && (f_ctl & FC_FC_SEQ_INIT)) { in fc_exch_recv_bls()
1725 spin_lock_bh(&ep->ex_lock); in fc_exch_recv_bls()
1726 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_recv_bls()
1727 spin_unlock_bh(&ep->ex_lock); in fc_exch_recv_bls()
1739 if (ep) in fc_exch_recv_bls()
1740 FC_EXCH_DBG(ep, "BLS rctl %x - %s received\n", in fc_exch_recv_bls()
1750 if (ep) in fc_exch_recv_bls()
1751 fc_exch_abts_resp(ep, fp); in fc_exch_recv_bls()
1756 fc_exch_recv_abts(ep, fp); in fc_exch_recv_bls()
1763 if (ep) in fc_exch_recv_bls()
1764 fc_exch_release(ep); /* release hold taken by fc_exch_find */ in fc_exch_recv_bls()
1826 static void fc_exch_reset(struct fc_exch *ep) in fc_exch_reset() argument
1831 spin_lock_bh(&ep->ex_lock); in fc_exch_reset()
1832 fc_exch_abort_locked(ep, 0); in fc_exch_reset()
1833 ep->state |= FC_EX_RST_CLEANUP; in fc_exch_reset()
1834 fc_exch_timer_cancel(ep); in fc_exch_reset()
1835 if (ep->esb_stat & ESB_ST_REC_QUAL) in fc_exch_reset()
1836 atomic_dec(&ep->ex_refcnt); /* drop hold for rec_qual */ in fc_exch_reset()
1837 ep->esb_stat &= ~ESB_ST_REC_QUAL; in fc_exch_reset()
1838 sp = &ep->seq; in fc_exch_reset()
1839 rc = fc_exch_done_locked(ep); in fc_exch_reset()
1840 spin_unlock_bh(&ep->ex_lock); in fc_exch_reset()
1842 fc_exch_hold(ep); in fc_exch_reset()
1845 fc_exch_delete(ep); in fc_exch_reset()
1847 fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED)); in fc_exch_reset()
1848 fc_seq_set_resp(sp, NULL, ep->arg); in fc_exch_reset()
1849 fc_exch_release(ep); in fc_exch_reset()
1868 struct fc_exch *ep; in fc_exch_pool_reset() local
1873 list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) { in fc_exch_pool_reset()
1874 if ((lport == ep->lp) && in fc_exch_pool_reset()
1875 (sid == 0 || sid == ep->sid) && in fc_exch_pool_reset()
1876 (did == 0 || did == ep->did)) { in fc_exch_pool_reset()
1877 fc_exch_hold(ep); in fc_exch_pool_reset()
1880 fc_exch_reset(ep); in fc_exch_pool_reset()
1882 fc_exch_release(ep); in fc_exch_pool_reset()
1950 struct fc_exch *ep; in fc_exch_els_rec() local
1968 ep = fc_exch_lookup(lport, in fc_exch_els_rec()
1971 if (!ep) in fc_exch_els_rec()
1973 if (ep->oid != sid || oxid != ep->oxid) in fc_exch_els_rec()
1975 if (rxid != FC_XID_UNKNOWN && rxid != ep->rxid) in fc_exch_els_rec()
1986 acc->reca_rx_id = htons(ep->rxid); in fc_exch_els_rec()
1987 if (ep->sid == ep->oid) in fc_exch_els_rec()
1988 hton24(acc->reca_rfid, ep->did); in fc_exch_els_rec()
1990 hton24(acc->reca_rfid, ep->sid); in fc_exch_els_rec()
1991 acc->reca_fc4value = htonl(ep->seq.rec_data); in fc_exch_els_rec()
1992 acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP | in fc_exch_els_rec()
1998 fc_exch_release(ep); in fc_exch_els_rec()
2002 fc_exch_release(ep); in fc_exch_els_rec()
2080 struct fc_exch *ep; in fc_exch_seq_send() local
2086 ep = fc_exch_alloc(lport, fp); in fc_exch_seq_send()
2087 if (!ep) { in fc_exch_seq_send()
2091 ep->esb_stat |= ESB_ST_SEQ_INIT; in fc_exch_seq_send()
2093 fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id)); in fc_exch_seq_send()
2094 ep->resp = resp; in fc_exch_seq_send()
2095 ep->destructor = destructor; in fc_exch_seq_send()
2096 ep->arg = arg; in fc_exch_seq_send()
2097 ep->r_a_tov = FC_DEF_R_A_TOV; in fc_exch_seq_send()
2098 ep->lp = lport; in fc_exch_seq_send()
2099 sp = &ep->seq; in fc_exch_seq_send()
2101 ep->fh_type = fh->fh_type; /* save for possbile timeout handling */ in fc_exch_seq_send()
2102 ep->f_ctl = ntoh24(fh->fh_f_ctl); in fc_exch_seq_send()
2103 fc_exch_setup_hdr(ep, fp, ep->f_ctl); in fc_exch_seq_send()
2106 if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) { in fc_exch_seq_send()
2108 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); in fc_exch_seq_send()
2115 fc_exch_timer_set_locked(ep, timer_msec); in fc_exch_seq_send()
2116 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */ in fc_exch_seq_send()
2118 if (ep->f_ctl & FC_FC_SEQ_INIT) in fc_exch_seq_send()
2119 ep->esb_stat &= ~ESB_ST_SEQ_INIT; in fc_exch_seq_send()
2120 spin_unlock_bh(&ep->ex_lock); in fc_exch_seq_send()
2125 rc = fc_exch_done_locked(ep); in fc_exch_seq_send()
2126 spin_unlock_bh(&ep->ex_lock); in fc_exch_seq_send()
2128 fc_exch_delete(ep); in fc_exch_seq_send()
2139 static void fc_exch_rrq(struct fc_exch *ep) in fc_exch_rrq() argument
2146 lport = ep->lp; in fc_exch_rrq()
2155 hton24(rrq->rrq_s_id, ep->sid); in fc_exch_rrq()
2156 rrq->rrq_ox_id = htons(ep->oxid); in fc_exch_rrq()
2157 rrq->rrq_rx_id = htons(ep->rxid); in fc_exch_rrq()
2159 did = ep->did; in fc_exch_rrq()
2160 if (ep->esb_stat & ESB_ST_RESP) in fc_exch_rrq()
2161 did = ep->sid; in fc_exch_rrq()
2167 if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep, in fc_exch_rrq()
2172 spin_lock_bh(&ep->ex_lock); in fc_exch_rrq()
2173 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) { in fc_exch_rrq()
2174 spin_unlock_bh(&ep->ex_lock); in fc_exch_rrq()
2176 fc_exch_release(ep); in fc_exch_rrq()
2179 ep->esb_stat |= ESB_ST_REC_QUAL; in fc_exch_rrq()
2180 fc_exch_timer_set_locked(ep, ep->r_a_tov); in fc_exch_rrq()
2181 spin_unlock_bh(&ep->ex_lock); in fc_exch_rrq()
2191 struct fc_exch *ep = NULL; /* request or subject exchange */ in fc_exch_els_rrq() local
2209 ep = fc_exch_lookup(lport, xid); in fc_exch_els_rrq()
2211 if (!ep) in fc_exch_els_rrq()
2213 spin_lock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2214 if (ep->oxid != ntohs(rp->rrq_ox_id)) in fc_exch_els_rrq()
2216 if (ep->rxid != ntohs(rp->rrq_rx_id) && in fc_exch_els_rrq()
2217 ep->rxid != FC_XID_UNKNOWN) in fc_exch_els_rrq()
2220 if (ep->sid != sid) in fc_exch_els_rrq()
2226 if (ep->esb_stat & ESB_ST_REC_QUAL) { in fc_exch_els_rrq()
2227 ep->esb_stat &= ~ESB_ST_REC_QUAL; in fc_exch_els_rrq()
2228 atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ in fc_exch_els_rrq()
2230 if (ep->esb_stat & ESB_ST_COMPLETE) in fc_exch_els_rrq()
2231 fc_exch_timer_cancel(ep); in fc_exch_els_rrq()
2233 spin_unlock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2242 spin_unlock_bh(&ep->ex_lock); in fc_exch_els_rrq()
2246 if (ep) in fc_exch_els_rrq()
2247 fc_exch_release(ep); /* drop hold from fc_exch_find */ in fc_exch_els_rrq()