aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_exch.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@suse.de>2010-05-18 10:33:43 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-18 10:37:41 -0400
commit95bb335c0ebe96afe926387a1ef3a096bd884a82 (patch)
tree56115332b4f2f7ef300c36248a6a7d20db2e639d /drivers/scsi/libfc/fc_exch.c
parent1b4d0d8ea7b3cbd107f345ab766416f9b38ce66a (diff)
parent9cccde93fed1ca988eb2fb17ab9194bf7b5ed1b0 (diff)
[SCSI] Merge scsi-misc-2.6 into scsi-rc-fixes-2.6
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libfc/fc_exch.c')
-rw-r--r--drivers/scsi/libfc/fc_exch.c51
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 */
737static struct fc_exch *fc_exch_alloc(struct fc_lport *lport, 738static 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,