27 #include <linux/slab.h>
29 #include <linux/export.h>
40 static u16 fc_cpu_order;
130 static void fc_exch_rrq(
struct fc_exch *);
131 static void fc_seq_ls_acc(
struct fc_frame *);
134 static void fc_exch_els_rec(
struct fc_frame *);
135 static void fc_exch_els_rrq(
struct fc_frame *);
230 static inline const char *fc_exch_name_lookup(
unsigned int op,
char **
table,
231 unsigned int max_index)
246 static const char *fc_exch_rctl_name(
unsigned int op)
248 return fc_exch_name_lookup(op, fc_exch_rctl_names,
256 static inline void fc_exch_hold(
struct fc_exch *ep)
283 if (fc_sof_needs_ack(ep->
class))
323 static void fc_exch_release(
struct fc_exch *ep)
340 static inline void fc_exch_timer_cancel(
struct fc_exch *ep)
357 static inline void fc_exch_timer_set_locked(
struct fc_exch *ep,
358 unsigned int timer_msec)
363 FC_EXCH_DBG(ep,
"Exchange timer armed : %d msecs\n", timer_msec);
375 static void fc_exch_timer_set(
struct fc_exch *ep,
unsigned int timer_msec)
378 fc_exch_timer_set_locked(ep, timer_msec);
386 static int fc_exch_done_locked(
struct fc_exch *ep)
403 fc_exch_timer_cancel(ep);
422 return exches[
index];
431 static inline void fc_exch_ptr_set(
struct fc_exch_pool *pool,
u16 index,
434 ((
struct fc_exch **)(pool + 1))[index] = ep;
441 static void fc_exch_delete(
struct fc_exch *ep)
447 spin_lock_bh(&pool->
lock);
452 index = (ep->
xid - ep->
em->min_xid) >> fc_cpu_order;
460 fc_exch_ptr_set(pool, index,
NULL);
462 spin_unlock_bh(&pool->
lock);
485 fc_exch_setup_hdr(ep, fp, f_ctl);
502 error = lport->
tt.frame_send(lport, fp);
545 static struct fc_seq *fc_seq_start_next_locked(
struct fc_seq *sp)
549 sp = fc_seq_alloc(ep, ep->
seq_id++);
560 static struct fc_seq *fc_seq_start_next(
struct fc_seq *sp)
565 sp = fc_seq_start_next_locked(sp);
574 static void fc_seq_set_resp(
struct fc_seq *sp,
596 static int fc_exch_abort_locked(
struct fc_exch *ep,
597 unsigned int timer_msec)
610 sp = fc_seq_start_next_locked(&ep->
seq);
616 fc_exch_timer_set_locked(ep, timer_msec);
628 fp = fc_frame_alloc(ep->
lp, 0);
632 error = fc_seq_send(ep->
lp, sp, fp);
647 static int fc_seq_exch_abort(
const struct fc_seq *req_sp,
648 unsigned int timer_msec)
655 error = fc_exch_abort_locked(ep, timer_msec);
692 rc = fc_exch_done_locked(ep);
698 fc_seq_exch_abort(sp, 2 * ep->
r_a_tov);
731 memset(ep, 0,
sizeof(*ep));
735 spin_lock_bh(&pool->
lock);
752 while (fc_exch_ptr_get(pool, index)) {
768 fc_exch_ptr_set(pool, index, ep);
770 fc_seq_alloc(ep, ep->
seq_id++);
772 spin_unlock_bh(&pool->
lock);
788 spin_unlock_bh(&pool->
lock);
812 return fc_exch_em_alloc(lport, ema->mp);
826 if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) {
828 spin_lock_bh(&pool->
lock);
829 ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order);
830 if (ep && ep->
xid == xid)
832 spin_unlock_bh(&pool->
lock);
843 static void fc_exch_done(
struct fc_seq *sp)
849 rc = fc_exch_done_locked(ep);
870 ep = fc_exch_alloc(lport, fp);
872 ep->
class = fc_frame_class(fp);
879 fh = fc_frame_header_get(fp);
930 ep = fc_exch_find(mp, xid);
951 fc_frame_payload_op(fp) ==
ELS_TEST) {
959 ep = fc_exch_find(mp, xid);
966 ep = fc_exch_resp(lport, mp, fp);
983 if (fc_sof_is_init(
fr_sof(fp))) {
991 if (f_ctl & FC_FC_END_SEQ) {
1026 fc_exch_done(&ep->
seq);
1027 fc_exch_release(ep);
1051 ep = fc_exch_find(mp, xid);
1059 if ((f_ctl & FC_FC_EX_CTX) != 0 &&
1064 fc_exch_release(ep);
1076 static void fc_exch_set_addr(
struct fc_exch *ep,
1077 u32 orig_id,
u32 resp_id)
1109 fc_exch_els_rrq(fp);
1112 fc_exch_els_rec(fp);
1126 static void fc_seq_send_last(
struct fc_seq *sp,
struct fc_frame *fp,
1134 fc_fill_fc_hdr(fp, rctl, ep->
did, ep->
sid, fh_type, f_ctl, 0);
1135 fc_seq_send(ep->
lp, sp, fp);
1145 static void fc_seq_send_ack(
struct fc_seq *sp,
const struct fc_frame *rx_fp)
1157 if (fc_sof_needs_ack(
fr_sof(rx_fp))) {
1158 fp = fc_frame_alloc(lport, 0);
1162 fh = fc_frame_header_get(fp);
1173 rx_fh = fc_frame_header_get(rx_fp);
1182 fc_exch_setup_hdr(ep, fp, f_ctl);
1188 if (f_ctl & FC_FC_END_SEQ)
1193 lport->
tt.frame_send(lport, fp);
1205 static void fc_exch_send_ba_rjt(
struct fc_frame *rx_fp,
1217 fp = fc_frame_alloc(lport,
sizeof(*rp));
1220 fh = fc_frame_header_get(fp);
1221 rx_fh = fc_frame_header_get(rx_fp);
1223 memset(fh, 0,
sizeof(*fh) +
sizeof(*rp));
1225 rp = fc_frame_payload_get(fp,
sizeof(*rp));
1254 f_ctl &= ~FC_FC_FIRST_SEQ;
1259 if (fc_sof_needs_ack(
fr_sof(fp)))
1262 lport->
tt.frame_send(lport, fp);
1274 static void fc_exch_recv_abts(
struct fc_exch *ep,
struct fc_frame *rx_fp)
1284 if (ep->
esb_stat & ESB_ST_COMPLETE) {
1291 fc_exch_timer_set_locked(ep, ep->
r_a_tov);
1293 fp = fc_frame_alloc(ep->
lp,
sizeof(*ap));
1298 fh = fc_frame_header_get(fp);
1299 ap = fc_frame_payload_get(fp,
sizeof(*ap));
1300 memset(ap, 0,
sizeof(*ap));
1309 sp = fc_seq_start_next_locked(sp);
1312 fc_frame_free(rx_fp);
1318 fc_frame_free(rx_fp);
1340 fc_seq_lookup_recip(lport, ema->mp, fp) ==
FC_RJT_NONE)
1388 return lport->
tt.lport_recv(lport, fp);
1390 reject = fc_seq_lookup_recip(lport, mp, fp);
1394 fc_seq_send_ack(sp, fp);
1411 lport->
tt.lport_recv(lport, fp);
1412 fc_exch_release(ep);
1414 FC_LPORT_DBG(lport,
"exch/seq lookup failed: reject %x\n",
1443 if (ep->
esb_stat & ESB_ST_COMPLETE) {
1460 if (fc_sof_is_init(sof)) {
1473 if (fc_sof_needs_ack(sof))
1474 fc_seq_send_ack(sp, fp);
1476 ex_resp_arg = ep->
arg;
1483 rc = fc_exch_done_locked(ep);
1504 resp(sp, fp, ex_resp_arg);
1507 fc_exch_release(ep);
1510 fc_exch_release(ep);
1525 sp = fc_seq_lookup_orig(mp, fp);
1543 static void fc_exch_abts_resp(
struct fc_exch *ep,
struct fc_frame *fp)
1552 int rc = 1, has_rec = 0;
1554 fh = fc_frame_header_get(fp);
1560 fc_exch_release(ep);
1566 ap = fc_frame_payload_get(fp,
sizeof(*ap));
1592 ex_resp_arg = ep->
arg;
1603 rc = fc_exch_done_locked(ep);
1609 resp(sp, fp, ex_resp_arg);
1614 fc_exch_timer_set(ep, ep->
r_a_tov);
1632 fh = fc_frame_header_get(fp);
1636 ep = fc_exch_find(mp, (f_ctl & FC_FC_EX_CTX) ?
1638 if (ep && (f_ctl & FC_FC_SEQ_INIT)) {
1665 fc_exch_abts_resp(ep, fp);
1670 fc_exch_recv_abts(ep, fp);
1678 fc_exch_release(ep);
1688 static void fc_seq_ls_acc(
struct fc_frame *rx_fp)
1695 fp = fc_frame_alloc(lport,
sizeof(*acc));
1698 acc = fc_frame_payload_get(fp,
sizeof(*acc));
1699 memset(acc, 0,
sizeof(*acc));
1702 lport->
tt.frame_send(lport, fp);
1722 fp = fc_frame_alloc(lport,
sizeof(*rjt));
1725 rjt = fc_frame_payload_get(fp,
sizeof(*rjt));
1726 memset(rjt, 0,
sizeof(*rjt));
1731 lport->
tt.frame_send(lport, fp);
1738 static void fc_exch_reset(
struct fc_exch *ep)
1746 fc_exch_abort_locked(ep, 0);
1748 fc_exch_timer_cancel(ep);
1756 rc = fc_exch_done_locked(ep);
1777 static void fc_exch_pool_reset(
struct fc_lport *lport,
1784 spin_lock_bh(&pool->
lock);
1787 if ((lport == ep->
lp) &&
1788 (sid == 0 || sid == ep->
sid) &&
1789 (did == 0 || did == ep->
did)) {
1791 spin_unlock_bh(&pool->
lock);
1795 fc_exch_release(ep);
1796 spin_lock_bh(&pool->
lock);
1808 spin_unlock_bh(&pool->
lock);
1829 fc_exch_pool_reset(lport,
1848 if (ema->mp->min_xid <= xid && xid <= ema->mp->max_xid)
1849 return fc_exch_find(ema->mp, xid);
1873 rp = fc_frame_payload_get(rfp,
sizeof(*rp));
1881 ep = fc_exch_lookup(lport,
1886 if (ep->
oid != sid || oxid != ep->
oxid)
1890 fp = fc_frame_alloc(lport,
sizeof(*acc));
1894 acc = fc_frame_payload_get(fp,
sizeof(*acc));
1895 memset(acc, 0,
sizeof(*acc));
1909 lport->
tt.frame_send(lport, fp);
1911 fc_exch_release(ep);
1915 fc_exch_release(ep);
1917 fc_seq_ls_rjt(rfp, reason, explan);
1928 static void fc_exch_rrq_resp(
struct fc_seq *sp,
struct fc_frame *fp,
void *arg)
1934 int err = PTR_ERR(fp);
1939 "frame error %d\n", err);
1943 op = fc_frame_payload_op(fp);
1953 FC_EXCH_DBG(aborted_ep,
"unexpected response op %x "
1959 fc_exch_done(&aborted_ep->
seq);
1961 fc_exch_release(aborted_ep);
1989 void (*destructor)(
struct fc_seq *,
1991 void *arg,
u32 timer_msec)
1999 ep = fc_exch_alloc(lport, fp);
2005 fh = fc_frame_header_get(fp);
2016 fc_exch_setup_hdr(ep, fp, ep->
f_ctl);
2024 if (
unlikely(lport->
tt.frame_send(lport, fp)))
2028 fc_exch_timer_set_locked(ep, timer_msec);
2029 ep->
f_ctl &= ~FC_FC_FIRST_SEQ;
2031 if (ep->
f_ctl & FC_FC_SEQ_INIT)
2038 rc = fc_exch_done_locked(ep);
2052 static void fc_exch_rrq(
struct fc_exch *ep)
2061 fp = fc_frame_alloc(lport,
sizeof(*rrq));
2065 rrq = fc_frame_payload_get(fp,
sizeof(*rrq));
2066 memset(rrq, 0,
sizeof(*rrq));
2078 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
2080 if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep,
2089 fc_exch_release(ep);
2093 fc_exch_timer_set_locked(ep, ep->
r_a_tov);
2101 static void fc_exch_els_rrq(
struct fc_frame *fp)
2111 rp = fc_frame_payload_get(fp,
sizeof(*rp));
2122 ep = fc_exch_lookup(lport, xid);
2143 if (ep->
esb_stat & ESB_ST_COMPLETE)
2144 fc_exch_timer_cancel(ep);
2160 fc_exch_release(ep);
2208 kref_get(&mp->
kref);
2217 static void fc_exch_mgr_destroy(
struct kref *
kref)
2234 kref_put(&ema->
mp->kref, fc_exch_mgr_destroy);
2274 u16 pool_exch_range;
2281 FC_LPORT_DBG(lport,
"Invalid min_xid 0x:%x and max_xid 0x:%x\n",
2300 if ((max_xid - min_xid + 1) / (fc_cpu_mask + 1) > pool_exch_range) {
2301 mp->
max_xid = pool_exch_range * (fc_cpu_mask + 1) +
2309 mp->
ep_pool = mempool_create_slab_pool(2, fc_em_cachep);
2323 pool_size =
sizeof(*pool) + pool_exch_range *
sizeof(
struct fc_exch *);
2333 INIT_LIST_HEAD(&pool->
ex_list);
2336 kref_init(&mp->
kref);
2347 kref_put(&mp->
kref, fc_exch_mgr_destroy);
2386 if (f_ctl & FC_FC_EX_CTX)
2396 if ((xid >= ema->
mp->min_xid) &&
2415 FC_LPORT_DBG(lport,
"Receiving frames for an lport that "
2416 "has not been initialized correctly\n");
2422 ema = fc_find_ema(f_ctl, lport, fh);
2424 FC_LPORT_DBG(lport,
"Unable to find Exchange Manager Anchor,"
2425 "fc_ctl <0x%x>, xid <0x%x>\n",
2427 (f_ctl & FC_FC_EX_CTX) ?
2439 if (f_ctl & FC_FC_END_SEQ)
2444 fc_exch_recv_bls(ema->
mp, fp);
2445 else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) ==
2447 fc_exch_recv_seq_resp(ema->
mp, fp);
2448 else if (f_ctl & FC_FC_SEQ_CTX)
2449 fc_exch_recv_resp(ema->
mp, fp);
2451 fc_exch_recv_req(lport, ema->
mp, fp);
2467 if (!lport->
tt.seq_start_next)
2468 lport->
tt.seq_start_next = fc_seq_start_next;
2470 if (!lport->
tt.seq_set_resp)
2471 lport->
tt.seq_set_resp = fc_seq_set_resp;
2473 if (!lport->
tt.exch_seq_send)
2474 lport->
tt.exch_seq_send = fc_exch_seq_send;
2476 if (!lport->
tt.seq_send)
2477 lport->
tt.seq_send = fc_seq_send;
2479 if (!lport->
tt.seq_els_rsp_send)
2480 lport->
tt.seq_els_rsp_send = fc_seq_els_rsp_send;
2482 if (!lport->
tt.exch_done)
2483 lport->
tt.exch_done = fc_exch_done;
2485 if (!lport->
tt.exch_mgr_reset)
2488 if (!lport->
tt.seq_exch_abort)
2489 lport->
tt.seq_exch_abort = fc_seq_exch_abort;
2491 if (!lport->
tt.seq_assign)
2492 lport->
tt.seq_assign = fc_seq_assign;
2494 if (!lport->
tt.seq_release)
2495 lport->
tt.seq_release = fc_seq_release;
2534 if (!fc_exch_workqueue)