diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_exch.c')
-rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 51 |
1 files changed, 17 insertions, 34 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index e5df0d4db67e..104e0fba7c43 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
@@ -488,7 +488,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, | |||
488 | */ | 488 | */ |
489 | spin_lock_bh(&ep->ex_lock); | 489 | spin_lock_bh(&ep->ex_lock); |
490 | ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ | 490 | ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ |
491 | if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT)) | 491 | if (f_ctl & FC_FC_SEQ_INIT) |
492 | ep->esb_stat &= ~ESB_ST_SEQ_INIT; | 492 | ep->esb_stat &= ~ESB_ST_SEQ_INIT; |
493 | spin_unlock_bh(&ep->ex_lock); | 493 | spin_unlock_bh(&ep->ex_lock); |
494 | return error; | 494 | return error; |
@@ -676,9 +676,10 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport, | |||
676 | } | 676 | } |
677 | memset(ep, 0, sizeof(*ep)); | 677 | memset(ep, 0, sizeof(*ep)); |
678 | 678 | ||
679 | cpu = smp_processor_id(); | 679 | cpu = get_cpu(); |
680 | pool = per_cpu_ptr(mp->pool, cpu); | 680 | pool = per_cpu_ptr(mp->pool, cpu); |
681 | spin_lock_bh(&pool->lock); | 681 | spin_lock_bh(&pool->lock); |
682 | put_cpu(); | ||
682 | index = pool->next_index; | 683 | index = pool->next_index; |
683 | /* allocate new exch from pool */ | 684 | /* allocate new exch from pool */ |
684 | while (fc_exch_ptr_get(pool, index)) { | 685 | while (fc_exch_ptr_get(pool, index)) { |
@@ -734,19 +735,14 @@ err: | |||
734 | * EM is selected when a NULL match function pointer is encountered | 735 | * EM is selected when a NULL match function pointer is encountered |
735 | * or when a call to a match function returns true. | 736 | * or when a call to a match function returns true. |
736 | */ | 737 | */ |
737 | static struct fc_exch *fc_exch_alloc(struct fc_lport *lport, | 738 | static inline struct fc_exch *fc_exch_alloc(struct fc_lport *lport, |
738 | struct fc_frame *fp) | 739 | struct fc_frame *fp) |
739 | { | 740 | { |
740 | struct fc_exch_mgr_anchor *ema; | 741 | struct fc_exch_mgr_anchor *ema; |
741 | struct fc_exch *ep; | ||
742 | 742 | ||
743 | list_for_each_entry(ema, &lport->ema_list, ema_list) { | 743 | list_for_each_entry(ema, &lport->ema_list, ema_list) |
744 | if (!ema->match || ema->match(fp)) { | 744 | if (!ema->match || ema->match(fp)) |
745 | ep = fc_exch_em_alloc(lport, ema->mp); | 745 | return fc_exch_em_alloc(lport, ema->mp); |
746 | if (ep) | ||
747 | return ep; | ||
748 | } | ||
749 | } | ||
750 | return NULL; | 746 | return NULL; |
751 | } | 747 | } |
752 | 748 | ||
@@ -920,13 +916,9 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport, | |||
920 | * Find or create the sequence. | 916 | * Find or create the sequence. |
921 | */ | 917 | */ |
922 | if (fc_sof_is_init(fr_sof(fp))) { | 918 | if (fc_sof_is_init(fr_sof(fp))) { |
923 | sp = fc_seq_start_next(&ep->seq); | 919 | sp = &ep->seq; |
924 | if (!sp) { | ||
925 | reject = FC_RJT_SEQ_XS; /* exchange shortage */ | ||
926 | goto rel; | ||
927 | } | ||
928 | sp->id = fh->fh_seq_id; | ||
929 | sp->ssb_stat |= SSB_ST_RESP; | 920 | sp->ssb_stat |= SSB_ST_RESP; |
921 | sp->id = fh->fh_seq_id; | ||
930 | } else { | 922 | } else { |
931 | sp = &ep->seq; | 923 | sp = &ep->seq; |
932 | if (sp->id != fh->fh_seq_id) { | 924 | if (sp->id != fh->fh_seq_id) { |
@@ -1250,9 +1242,6 @@ static void fc_exch_recv_req(struct fc_lport *lport, struct fc_exch_mgr *mp, | |||
1250 | struct fc_frame_header *fh = fc_frame_header_get(fp); | 1242 | struct fc_frame_header *fh = fc_frame_header_get(fp); |
1251 | struct fc_seq *sp = NULL; | 1243 | struct fc_seq *sp = NULL; |
1252 | struct fc_exch *ep = NULL; | 1244 | struct fc_exch *ep = NULL; |
1253 | enum fc_sof sof; | ||
1254 | enum fc_eof eof; | ||
1255 | u32 f_ctl; | ||
1256 | enum fc_pf_rjt_reason reject; | 1245 | enum fc_pf_rjt_reason reject; |
1257 | 1246 | ||
1258 | /* We can have the wrong fc_lport at this point with NPIV, which is a | 1247 | /* We can have the wrong fc_lport at this point with NPIV, which is a |
@@ -1269,9 +1258,6 @@ static void fc_exch_recv_req(struct fc_lport *lport, struct fc_exch_mgr *mp, | |||
1269 | if (reject == FC_RJT_NONE) { | 1258 | if (reject == FC_RJT_NONE) { |
1270 | sp = fr_seq(fp); /* sequence will be held */ | 1259 | sp = fr_seq(fp); /* sequence will be held */ |
1271 | ep = fc_seq_exch(sp); | 1260 | ep = fc_seq_exch(sp); |
1272 | sof = fr_sof(fp); | ||
1273 | eof = fr_eof(fp); | ||
1274 | f_ctl = ntoh24(fh->fh_f_ctl); | ||
1275 | fc_seq_send_ack(sp, fp); | 1261 | fc_seq_send_ack(sp, fp); |
1276 | 1262 | ||
1277 | /* | 1263 | /* |
@@ -1336,17 +1322,15 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
1336 | goto rel; | 1322 | goto rel; |
1337 | } | 1323 | } |
1338 | sof = fr_sof(fp); | 1324 | sof = fr_sof(fp); |
1325 | sp = &ep->seq; | ||
1339 | if (fc_sof_is_init(sof)) { | 1326 | if (fc_sof_is_init(sof)) { |
1340 | sp = fc_seq_start_next(&ep->seq); | ||
1341 | sp->id = fh->fh_seq_id; | ||
1342 | sp->ssb_stat |= SSB_ST_RESP; | 1327 | sp->ssb_stat |= SSB_ST_RESP; |
1343 | } else { | 1328 | sp->id = fh->fh_seq_id; |
1344 | sp = &ep->seq; | 1329 | } else if (sp->id != fh->fh_seq_id) { |
1345 | if (sp->id != fh->fh_seq_id) { | 1330 | atomic_inc(&mp->stats.seq_not_found); |
1346 | atomic_inc(&mp->stats.seq_not_found); | 1331 | goto rel; |
1347 | goto rel; | ||
1348 | } | ||
1349 | } | 1332 | } |
1333 | |||
1350 | f_ctl = ntoh24(fh->fh_f_ctl); | 1334 | f_ctl = ntoh24(fh->fh_f_ctl); |
1351 | fr_seq(fp) = sp; | 1335 | fr_seq(fp) = sp; |
1352 | if (f_ctl & FC_FC_SEQ_INIT) | 1336 | if (f_ctl & FC_FC_SEQ_INIT) |
@@ -1763,7 +1747,6 @@ static void fc_exch_els_rec(struct fc_seq *sp, struct fc_frame *rfp) | |||
1763 | fc_exch_done(sp); | 1747 | fc_exch_done(sp); |
1764 | goto out; | 1748 | goto out; |
1765 | } | 1749 | } |
1766 | sp = fc_seq_start_next(sp); | ||
1767 | acc = fc_frame_payload_get(fp, sizeof(*acc)); | 1750 | acc = fc_frame_payload_get(fp, sizeof(*acc)); |
1768 | memset(acc, 0, sizeof(*acc)); | 1751 | memset(acc, 0, sizeof(*acc)); |
1769 | acc->reca_cmd = ELS_LS_ACC; | 1752 | acc->reca_cmd = ELS_LS_ACC; |
@@ -1944,7 +1927,7 @@ static void fc_exch_rrq(struct fc_exch *ep) | |||
1944 | did = ep->sid; | 1927 | did = ep->sid; |
1945 | 1928 | ||
1946 | fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did, | 1929 | fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did, |
1947 | fc_host_port_id(lport->host), FC_TYPE_ELS, | 1930 | lport->port_id, FC_TYPE_ELS, |
1948 | FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); | 1931 | FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); |
1949 | 1932 | ||
1950 | if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep, | 1933 | if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep, |