aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_disc.c8
-rw-r--r--drivers/scsi/libfc/fc_elsct.c2
-rw-r--r--drivers/scsi/libfc/fc_exch.c51
-rw-r--r--drivers/scsi/libfc/fc_fcp.c103
-rw-r--r--drivers/scsi/libfc/fc_libfc.h8
-rw-r--r--drivers/scsi/libfc/fc_lport.c58
-rw-r--r--drivers/scsi/libfc/fc_npiv.c7
-rw-r--r--drivers/scsi/libfc/fc_rport.c195
8 files changed, 211 insertions, 221 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index 1087a7f18e84..c7985da88099 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -132,7 +132,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
132 switch (fmt) { 132 switch (fmt) {
133 case ELS_ADDR_FMT_PORT: 133 case ELS_ADDR_FMT_PORT:
134 FC_DISC_DBG(disc, "Port address format for port " 134 FC_DISC_DBG(disc, "Port address format for port "
135 "(%6x)\n", ntoh24(pp->rscn_fid)); 135 "(%6.6x)\n", ntoh24(pp->rscn_fid));
136 dp = kzalloc(sizeof(*dp), GFP_KERNEL); 136 dp = kzalloc(sizeof(*dp), GFP_KERNEL);
137 if (!dp) { 137 if (!dp) {
138 redisc = 1; 138 redisc = 1;
@@ -440,7 +440,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
440 ids.port_id = ntoh24(np->fp_fid); 440 ids.port_id = ntoh24(np->fp_fid);
441 ids.port_name = ntohll(np->fp_wwpn); 441 ids.port_name = ntohll(np->fp_wwpn);
442 442
443 if (ids.port_id != fc_host_port_id(lport->host) && 443 if (ids.port_id != lport->port_id &&
444 ids.port_name != lport->wwpn) { 444 ids.port_name != lport->wwpn) {
445 rdata = lport->tt.rport_create(lport, ids.port_id); 445 rdata = lport->tt.rport_create(lport, ids.port_id);
446 if (rdata) { 446 if (rdata) {
@@ -449,7 +449,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
449 } else { 449 } else {
450 printk(KERN_WARNING "libfc: Failed to allocate " 450 printk(KERN_WARNING "libfc: Failed to allocate "
451 "memory for the newly discovered port " 451 "memory for the newly discovered port "
452 "(%6x)\n", ids.port_id); 452 "(%6.6x)\n", ids.port_id);
453 error = -ENOMEM; 453 error = -ENOMEM;
454 } 454 }
455 } 455 }
@@ -607,7 +607,7 @@ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
607 rdata->ids.port_name = port_name; 607 rdata->ids.port_name = port_name;
608 else if (rdata->ids.port_name != port_name) { 608 else if (rdata->ids.port_name != port_name) {
609 FC_DISC_DBG(disc, "GPN_ID accepted. WWPN changed. " 609 FC_DISC_DBG(disc, "GPN_ID accepted. WWPN changed. "
610 "Port-id %x wwpn %llx\n", 610 "Port-id %6.6x wwpn %16.16llx\n",
611 rdata->ids.port_id, port_name); 611 rdata->ids.port_id, port_name);
612 lport->tt.rport_logoff(rdata); 612 lport->tt.rport_logoff(rdata);
613 613
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
index 53748724f2c5..e9412b710fab 100644
--- a/drivers/scsi/libfc/fc_elsct.c
+++ b/drivers/scsi/libfc/fc_elsct.c
@@ -63,7 +63,7 @@ struct fc_seq *fc_elsct_send(struct fc_lport *lport, u32 did,
63 return NULL; 63 return NULL;
64 } 64 }
65 65
66 fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type, 66 fc_fill_fc_hdr(fp, r_ctl, did, lport->port_id, fh_type,
67 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 67 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
68 68
69 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec); 69 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
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,
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 17396c708b08..ec1f66c4a9d4 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -97,7 +97,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *);
97static void fc_fcp_complete_locked(struct fc_fcp_pkt *); 97static void fc_fcp_complete_locked(struct fc_fcp_pkt *);
98static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *); 98static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *);
99static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *); 99static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *);
100static void fc_timeout_error(struct fc_fcp_pkt *); 100static void fc_fcp_recovery(struct fc_fcp_pkt *);
101static void fc_fcp_timeout(unsigned long); 101static void fc_fcp_timeout(unsigned long);
102static void fc_fcp_rec(struct fc_fcp_pkt *); 102static void fc_fcp_rec(struct fc_fcp_pkt *);
103static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *); 103static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *);
@@ -121,7 +121,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *, struct fc_frame *);
121#define FC_DATA_UNDRUN 7 121#define FC_DATA_UNDRUN 7
122#define FC_ERROR 8 122#define FC_ERROR 8
123#define FC_HRD_ERROR 9 123#define FC_HRD_ERROR 9
124#define FC_CMD_TIME_OUT 10 124#define FC_CMD_RECOVERY 10
125 125
126/* 126/*
127 * Error recovery timeout values. 127 * Error recovery timeout values.
@@ -446,9 +446,16 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
446 len = fr_len(fp) - sizeof(*fh); 446 len = fr_len(fp) - sizeof(*fh);
447 buf = fc_frame_payload_get(fp, 0); 447 buf = fc_frame_payload_get(fp, 0);
448 448
449 /* if this I/O is ddped, update xfer len */ 449 /*
450 fc_fcp_ddp_done(fsp); 450 * if this I/O is ddped then clear it
451 451 * and initiate recovery since data
452 * frames are expected to be placed
453 * directly in that case.
454 */
455 if (fsp->xfer_ddp != FC_XID_UNKNOWN) {
456 fc_fcp_ddp_done(fsp);
457 goto err;
458 }
452 if (offset + len > fsp->data_len) { 459 if (offset + len > fsp->data_len) {
453 /* this should never happen */ 460 /* this should never happen */
454 if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && 461 if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) &&
@@ -456,8 +463,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
456 goto crc_err; 463 goto crc_err;
457 FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx " 464 FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx "
458 "data_len %x\n", len, offset, fsp->data_len); 465 "data_len %x\n", len, offset, fsp->data_len);
459 fc_fcp_retry_cmd(fsp); 466 goto err;
460 return;
461 } 467 }
462 if (offset != fsp->xfer_len) 468 if (offset != fsp->xfer_len)
463 fsp->state |= FC_SRB_DISCONTIG; 469 fsp->state |= FC_SRB_DISCONTIG;
@@ -478,13 +484,14 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
478 484
479 if (~crc != le32_to_cpu(fr_crc(fp))) { 485 if (~crc != le32_to_cpu(fr_crc(fp))) {
480crc_err: 486crc_err:
481 stats = fc_lport_get_stats(lport); 487 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
482 stats->ErrorFrames++; 488 stats->ErrorFrames++;
483 /* FIXME - per cpu count, not total count! */ 489 /* per cpu count, not total count, but OK for limit */
484 if (stats->InvalidCRCCount++ < 5) 490 if (stats->InvalidCRCCount++ < 5)
485 printk(KERN_WARNING "libfc: CRC error on data " 491 printk(KERN_WARNING "libfc: CRC error on data "
486 "frame for port (%6x)\n", 492 "frame for port (%6.6x)\n",
487 fc_host_port_id(lport->host)); 493 lport->port_id);
494 put_cpu();
488 /* 495 /*
489 * Assume the frame is total garbage. 496 * Assume the frame is total garbage.
490 * We may have copied it over the good part 497 * We may have copied it over the good part
@@ -493,7 +500,7 @@ crc_err:
493 * Otherwise, ignore it. 500 * Otherwise, ignore it.
494 */ 501 */
495 if (fsp->state & FC_SRB_DISCONTIG) 502 if (fsp->state & FC_SRB_DISCONTIG)
496 fc_fcp_retry_cmd(fsp); 503 goto err;
497 return; 504 return;
498 } 505 }
499 } 506 }
@@ -509,6 +516,9 @@ crc_err:
509 if (unlikely(fsp->state & FC_SRB_RCV_STATUS) && 516 if (unlikely(fsp->state & FC_SRB_RCV_STATUS) &&
510 fsp->xfer_len == fsp->data_len - fsp->scsi_resid) 517 fsp->xfer_len == fsp->data_len - fsp->scsi_resid)
511 fc_fcp_complete_locked(fsp); 518 fc_fcp_complete_locked(fsp);
519 return;
520err:
521 fc_fcp_recovery(fsp);
512} 522}
513 523
514/** 524/**
@@ -834,8 +844,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
834 * exit here 844 * exit here
835 */ 845 */
836 return; 846 return;
837 } else 847 }
838 goto err;
839 } 848 }
840 if (flags & FCP_SNS_LEN_VAL) { 849 if (flags & FCP_SNS_LEN_VAL) {
841 snsl = ntohl(rp_ex->fr_sns_len); 850 snsl = ntohl(rp_ex->fr_sns_len);
@@ -885,7 +894,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
885 return; 894 return;
886 } 895 }
887 fsp->status_code = FC_DATA_OVRRUN; 896 fsp->status_code = FC_DATA_OVRRUN;
888 FC_FCP_DBG(fsp, "tgt %6x xfer len %zx greater than expected, " 897 FC_FCP_DBG(fsp, "tgt %6.6x xfer len %zx greater than expected, "
889 "len %x, data len %x\n", 898 "len %x, data len %x\n",
890 fsp->rport->port_id, 899 fsp->rport->port_id,
891 fsp->xfer_len, expected_len, fsp->data_len); 900 fsp->xfer_len, expected_len, fsp->data_len);
@@ -1100,7 +1109,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
1100 rpriv = rport->dd_data; 1109 rpriv = rport->dd_data;
1101 1110
1102 fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id, 1111 fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id,
1103 fc_host_port_id(rpriv->local_port->host), FC_TYPE_FCP, 1112 rpriv->local_port->port_id, FC_TYPE_FCP,
1104 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1113 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
1105 1114
1106 seq = lport->tt.exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy, 1115 seq = lport->tt.exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy,
@@ -1341,7 +1350,7 @@ static void fc_fcp_timeout(unsigned long data)
1341 else if (fsp->state & FC_SRB_RCV_STATUS) 1350 else if (fsp->state & FC_SRB_RCV_STATUS)
1342 fc_fcp_complete_locked(fsp); 1351 fc_fcp_complete_locked(fsp);
1343 else 1352 else
1344 fc_timeout_error(fsp); 1353 fc_fcp_recovery(fsp);
1345 fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; 1354 fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
1346unlock: 1355unlock:
1347 fc_fcp_unlock_pkt(fsp); 1356 fc_fcp_unlock_pkt(fsp);
@@ -1373,7 +1382,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
1373 1382
1374 fr_seq(fp) = fsp->seq_ptr; 1383 fr_seq(fp) = fsp->seq_ptr;
1375 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id, 1384 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id,
1376 fc_host_port_id(rpriv->local_port->host), FC_TYPE_ELS, 1385 rpriv->local_port->port_id, FC_TYPE_ELS,
1377 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1386 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
1378 if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC, 1387 if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC,
1379 fc_fcp_rec_resp, fsp, 1388 fc_fcp_rec_resp, fsp,
@@ -1385,7 +1394,7 @@ retry:
1385 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1394 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
1386 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1395 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
1387 else 1396 else
1388 fc_timeout_error(fsp); 1397 fc_fcp_recovery(fsp);
1389} 1398}
1390 1399
1391/** 1400/**
@@ -1454,7 +1463,7 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
1454 fc_fcp_retry_cmd(fsp); 1463 fc_fcp_retry_cmd(fsp);
1455 break; 1464 break;
1456 } 1465 }
1457 fc_timeout_error(fsp); 1466 fc_fcp_recovery(fsp);
1458 break; 1467 break;
1459 } 1468 }
1460 } else if (opcode == ELS_LS_ACC) { 1469 } else if (opcode == ELS_LS_ACC) {
@@ -1553,7 +1562,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
1553 break; 1562 break;
1554 1563
1555 default: 1564 default:
1556 FC_FCP_DBG(fsp, "REC %p fid %x error unexpected error %d\n", 1565 FC_FCP_DBG(fsp, "REC %p fid %6.6x error unexpected error %d\n",
1557 fsp, fsp->rport->port_id, error); 1566 fsp, fsp->rport->port_id, error);
1558 fsp->status_code = FC_CMD_PLOGO; 1567 fsp->status_code = FC_CMD_PLOGO;
1559 /* fall through */ 1568 /* fall through */
@@ -1563,13 +1572,13 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
1563 * Assume REC or LS_ACC was lost. 1572 * Assume REC or LS_ACC was lost.
1564 * The exchange manager will have aborted REC, so retry. 1573 * The exchange manager will have aborted REC, so retry.
1565 */ 1574 */
1566 FC_FCP_DBG(fsp, "REC fid %x error error %d retry %d/%d\n", 1575 FC_FCP_DBG(fsp, "REC fid %6.6x error error %d retry %d/%d\n",
1567 fsp->rport->port_id, error, fsp->recov_retry, 1576 fsp->rport->port_id, error, fsp->recov_retry,
1568 FC_MAX_RECOV_RETRY); 1577 FC_MAX_RECOV_RETRY);
1569 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1578 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
1570 fc_fcp_rec(fsp); 1579 fc_fcp_rec(fsp);
1571 else 1580 else
1572 fc_timeout_error(fsp); 1581 fc_fcp_recovery(fsp);
1573 break; 1582 break;
1574 } 1583 }
1575 fc_fcp_unlock_pkt(fsp); 1584 fc_fcp_unlock_pkt(fsp);
@@ -1578,12 +1587,12 @@ out:
1578} 1587}
1579 1588
1580/** 1589/**
1581 * fc_timeout_error() - Handler for fcp_pkt timeouts 1590 * fc_fcp_recovery() - Handler for fcp_pkt recovery
1582 * @fsp: The FCP packt that has timed out 1591 * @fsp: The FCP pkt that needs to be aborted
1583 */ 1592 */
1584static void fc_timeout_error(struct fc_fcp_pkt *fsp) 1593static void fc_fcp_recovery(struct fc_fcp_pkt *fsp)
1585{ 1594{
1586 fsp->status_code = FC_CMD_TIME_OUT; 1595 fsp->status_code = FC_CMD_RECOVERY;
1587 fsp->cdb_status = 0; 1596 fsp->cdb_status = 0;
1588 fsp->io_status = 0; 1597 fsp->io_status = 0;
1589 /* 1598 /*
@@ -1631,7 +1640,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
1631 srr->srr_rel_off = htonl(offset); 1640 srr->srr_rel_off = htonl(offset);
1632 1641
1633 fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id, 1642 fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id,
1634 fc_host_port_id(rpriv->local_port->host), FC_TYPE_FCP, 1643 rpriv->local_port->port_id, FC_TYPE_FCP,
1635 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1644 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
1636 1645
1637 seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL, 1646 seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
@@ -1689,7 +1698,7 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
1689 break; 1698 break;
1690 case ELS_LS_RJT: 1699 case ELS_LS_RJT:
1691 default: 1700 default:
1692 fc_timeout_error(fsp); 1701 fc_fcp_recovery(fsp);
1693 break; 1702 break;
1694 } 1703 }
1695 fc_fcp_unlock_pkt(fsp); 1704 fc_fcp_unlock_pkt(fsp);
@@ -1715,7 +1724,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
1715 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1724 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
1716 fc_fcp_rec(fsp); 1725 fc_fcp_rec(fsp);
1717 else 1726 else
1718 fc_timeout_error(fsp); 1727 fc_fcp_recovery(fsp);
1719 break; 1728 break;
1720 case -FC_EX_CLOSED: /* e.g., link failure */ 1729 case -FC_EX_CLOSED: /* e.g., link failure */
1721 /* fall through */ 1730 /* fall through */
@@ -1810,7 +1819,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
1810 /* 1819 /*
1811 * setup the data direction 1820 * setup the data direction
1812 */ 1821 */
1813 stats = fc_lport_get_stats(lport); 1822 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
1814 if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { 1823 if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
1815 fsp->req_flags = FC_SRB_READ; 1824 fsp->req_flags = FC_SRB_READ;
1816 stats->InputRequests++; 1825 stats->InputRequests++;
@@ -1823,6 +1832,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
1823 fsp->req_flags = 0; 1832 fsp->req_flags = 0;
1824 stats->ControlRequests++; 1833 stats->ControlRequests++;
1825 } 1834 }
1835 put_cpu();
1826 1836
1827 fsp->tgt_flags = rpriv->flags; 1837 fsp->tgt_flags = rpriv->flags;
1828 1838
@@ -1907,6 +1917,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
1907 } 1917 }
1908 break; 1918 break;
1909 case FC_ERROR: 1919 case FC_ERROR:
1920 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
1921 "due to FC_ERROR\n");
1910 sc_cmd->result = DID_ERROR << 16; 1922 sc_cmd->result = DID_ERROR << 16;
1911 break; 1923 break;
1912 case FC_DATA_UNDRUN: 1924 case FC_DATA_UNDRUN:
@@ -1915,12 +1927,19 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
1915 * scsi status is good but transport level 1927 * scsi status is good but transport level
1916 * underrun. 1928 * underrun.
1917 */ 1929 */
1918 sc_cmd->result = (fsp->state & FC_SRB_RCV_STATUS ? 1930 if (fsp->state & FC_SRB_RCV_STATUS) {
1919 DID_OK : DID_ERROR) << 16; 1931 sc_cmd->result = DID_OK << 16;
1932 } else {
1933 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml"
1934 " due to FC_DATA_UNDRUN (trans)\n");
1935 sc_cmd->result = DID_ERROR << 16;
1936 }
1920 } else { 1937 } else {
1921 /* 1938 /*
1922 * scsi got underrun, this is an error 1939 * scsi got underrun, this is an error
1923 */ 1940 */
1941 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
1942 "due to FC_DATA_UNDRUN (scsi)\n");
1924 CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid; 1943 CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid;
1925 sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status; 1944 sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status;
1926 } 1945 }
@@ -1929,12 +1948,16 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
1929 /* 1948 /*
1930 * overrun is an error 1949 * overrun is an error
1931 */ 1950 */
1951 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
1952 "due to FC_DATA_OVRRUN\n");
1932 sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status; 1953 sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status;
1933 break; 1954 break;
1934 case FC_CMD_ABORTED: 1955 case FC_CMD_ABORTED:
1956 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
1957 "due to FC_CMD_ABORTED\n");
1935 sc_cmd->result = (DID_ERROR << 16) | fsp->io_status; 1958 sc_cmd->result = (DID_ERROR << 16) | fsp->io_status;
1936 break; 1959 break;
1937 case FC_CMD_TIME_OUT: 1960 case FC_CMD_RECOVERY:
1938 sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status; 1961 sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status;
1939 break; 1962 break;
1940 case FC_CMD_RESET: 1963 case FC_CMD_RESET:
@@ -1944,6 +1967,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
1944 sc_cmd->result = (DID_NO_CONNECT << 16); 1967 sc_cmd->result = (DID_NO_CONNECT << 16);
1945 break; 1968 break;
1946 default: 1969 default:
1970 FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
1971 "due to unknown error\n");
1947 sc_cmd->result = (DID_ERROR << 16); 1972 sc_cmd->result = (DID_ERROR << 16);
1948 break; 1973 break;
1949 } 1974 }
@@ -2028,7 +2053,7 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
2028 if (lport->state != LPORT_ST_READY) 2053 if (lport->state != LPORT_ST_READY)
2029 return rc; 2054 return rc;
2030 2055
2031 FC_SCSI_DBG(lport, "Resetting rport (%6x)\n", rport->port_id); 2056 FC_SCSI_DBG(lport, "Resetting rport (%6.6x)\n", rport->port_id);
2032 2057
2033 fsp = fc_fcp_pkt_alloc(lport, GFP_NOIO); 2058 fsp = fc_fcp_pkt_alloc(lport, GFP_NOIO);
2034 if (fsp == NULL) { 2059 if (fsp == NULL) {
@@ -2076,12 +2101,12 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
2076 2101
2077 if (fc_fcp_lport_queue_ready(lport)) { 2102 if (fc_fcp_lport_queue_ready(lport)) {
2078 shost_printk(KERN_INFO, shost, "libfc: Host reset succeeded " 2103 shost_printk(KERN_INFO, shost, "libfc: Host reset succeeded "
2079 "on port (%6x)\n", fc_host_port_id(lport->host)); 2104 "on port (%6.6x)\n", lport->port_id);
2080 return SUCCESS; 2105 return SUCCESS;
2081 } else { 2106 } else {
2082 shost_printk(KERN_INFO, shost, "libfc: Host reset failed, " 2107 shost_printk(KERN_INFO, shost, "libfc: Host reset failed, "
2083 "port (%6x) is not ready.\n", 2108 "port (%6.6x) is not ready.\n",
2084 fc_host_port_id(lport->host)); 2109 lport->port_id);
2085 return FAILED; 2110 return FAILED;
2086 } 2111 }
2087} 2112}
@@ -2166,7 +2191,7 @@ void fc_fcp_destroy(struct fc_lport *lport)
2166 2191
2167 if (!list_empty(&si->scsi_pkt_queue)) 2192 if (!list_empty(&si->scsi_pkt_queue))
2168 printk(KERN_ERR "libfc: Leaked SCSI packets when destroying " 2193 printk(KERN_ERR "libfc: Leaked SCSI packets when destroying "
2169 "port (%6x)\n", fc_host_port_id(lport->host)); 2194 "port (%6.6x)\n", lport->port_id);
2170 2195
2171 mempool_destroy(si->scsi_pkt_pool); 2196 mempool_destroy(si->scsi_pkt_pool);
2172 kfree(si); 2197 kfree(si);
diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h
index 741fd5c72e13..f5c0ca4b6ef8 100644
--- a/drivers/scsi/libfc/fc_libfc.h
+++ b/drivers/scsi/libfc/fc_libfc.h
@@ -45,9 +45,9 @@ extern unsigned int fc_debug_logging;
45 45
46#define FC_LPORT_DBG(lport, fmt, args...) \ 46#define FC_LPORT_DBG(lport, fmt, args...) \
47 FC_CHECK_LOGGING(FC_LPORT_LOGGING, \ 47 FC_CHECK_LOGGING(FC_LPORT_LOGGING, \
48 printk(KERN_INFO "host%u: lport %6x: " fmt, \ 48 printk(KERN_INFO "host%u: lport %6.6x: " fmt, \
49 (lport)->host->host_no, \ 49 (lport)->host->host_no, \
50 fc_host_port_id((lport)->host), ##args)) 50 (lport)->port_id, ##args))
51 51
52#define FC_DISC_DBG(disc, fmt, args...) \ 52#define FC_DISC_DBG(disc, fmt, args...) \
53 FC_CHECK_LOGGING(FC_DISC_LOGGING, \ 53 FC_CHECK_LOGGING(FC_DISC_LOGGING, \
@@ -57,7 +57,7 @@ extern unsigned int fc_debug_logging;
57 57
58#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...) \ 58#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...) \
59 FC_CHECK_LOGGING(FC_RPORT_LOGGING, \ 59 FC_CHECK_LOGGING(FC_RPORT_LOGGING, \
60 printk(KERN_INFO "host%u: rport %6x: " fmt, \ 60 printk(KERN_INFO "host%u: rport %6.6x: " fmt, \
61 (lport)->host->host_no, \ 61 (lport)->host->host_no, \
62 (port_id), ##args)) 62 (port_id), ##args))
63 63
@@ -66,7 +66,7 @@ extern unsigned int fc_debug_logging;
66 66
67#define FC_FCP_DBG(pkt, fmt, args...) \ 67#define FC_FCP_DBG(pkt, fmt, args...) \
68 FC_CHECK_LOGGING(FC_FCP_LOGGING, \ 68 FC_CHECK_LOGGING(FC_FCP_LOGGING, \
69 printk(KERN_INFO "host%u: fcp: %6x: " fmt, \ 69 printk(KERN_INFO "host%u: fcp: %6.6x: " fmt, \
70 (pkt)->lp->host->host_no, \ 70 (pkt)->lp->host->host_no, \
71 pkt->rport->port_id, ##args)) 71 pkt->rport->port_id, ##args))
72 72
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index d126ecfff704..79c9e3ccd341 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -172,7 +172,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
172 struct fc_rport_priv *rdata, 172 struct fc_rport_priv *rdata,
173 enum fc_rport_event event) 173 enum fc_rport_event event)
174{ 174{
175 FC_LPORT_DBG(lport, "Received a %d event for port (%6x)\n", event, 175 FC_LPORT_DBG(lport, "Received a %d event for port (%6.6x)\n", event,
176 rdata->ids.port_id); 176 rdata->ids.port_id);
177 177
178 mutex_lock(&lport->lp_mutex); 178 mutex_lock(&lport->lp_mutex);
@@ -183,7 +183,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
183 fc_lport_enter_ns(lport, LPORT_ST_RNN_ID); 183 fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
184 } else { 184 } else {
185 FC_LPORT_DBG(lport, "Received an READY event " 185 FC_LPORT_DBG(lport, "Received an READY event "
186 "on port (%6x) for the directory " 186 "on port (%6.6x) for the directory "
187 "server, but the lport is not " 187 "server, but the lport is not "
188 "in the DNS state, it's in the " 188 "in the DNS state, it's in the "
189 "%d state", rdata->ids.port_id, 189 "%d state", rdata->ids.port_id,
@@ -228,9 +228,12 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
228 u64 remote_wwnn) 228 u64 remote_wwnn)
229{ 229{
230 mutex_lock(&lport->disc.disc_mutex); 230 mutex_lock(&lport->disc.disc_mutex);
231 if (lport->ptp_rdata) 231 if (lport->ptp_rdata) {
232 lport->tt.rport_logoff(lport->ptp_rdata); 232 lport->tt.rport_logoff(lport->ptp_rdata);
233 kref_put(&lport->ptp_rdata->kref, lport->tt.rport_destroy);
234 }
233 lport->ptp_rdata = lport->tt.rport_create(lport, remote_fid); 235 lport->ptp_rdata = lport->tt.rport_create(lport, remote_fid);
236 kref_get(&lport->ptp_rdata->kref);
234 lport->ptp_rdata->ids.port_name = remote_wwpn; 237 lport->ptp_rdata->ids.port_name = remote_wwpn;
235 lport->ptp_rdata->ids.node_name = remote_wwnn; 238 lport->ptp_rdata->ids.node_name = remote_wwnn;
236 mutex_unlock(&lport->disc.disc_mutex); 239 mutex_unlock(&lport->disc.disc_mutex);
@@ -241,17 +244,6 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
241} 244}
242 245
243/** 246/**
244 * fc_get_host_port_type() - Return the port type of the given Scsi_Host
245 * @shost: The SCSI host whose port type is to be determined
246 */
247void fc_get_host_port_type(struct Scsi_Host *shost)
248{
249 /* TODO - currently just NPORT */
250 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
251}
252EXPORT_SYMBOL(fc_get_host_port_type);
253
254/**
255 * fc_get_host_port_state() - Return the port state of the given Scsi_Host 247 * fc_get_host_port_state() - Return the port state of the given Scsi_Host
256 * @shost: The SCSI host whose port state is to be determined 248 * @shost: The SCSI host whose port state is to be determined
257 */ 249 */
@@ -572,8 +564,8 @@ void __fc_linkup(struct fc_lport *lport)
572 */ 564 */
573void fc_linkup(struct fc_lport *lport) 565void fc_linkup(struct fc_lport *lport)
574{ 566{
575 printk(KERN_INFO "host%d: libfc: Link up on port (%6x)\n", 567 printk(KERN_INFO "host%d: libfc: Link up on port (%6.6x)\n",
576 lport->host->host_no, fc_host_port_id(lport->host)); 568 lport->host->host_no, lport->port_id);
577 569
578 mutex_lock(&lport->lp_mutex); 570 mutex_lock(&lport->lp_mutex);
579 __fc_linkup(lport); 571 __fc_linkup(lport);
@@ -602,8 +594,8 @@ void __fc_linkdown(struct fc_lport *lport)
602 */ 594 */
603void fc_linkdown(struct fc_lport *lport) 595void fc_linkdown(struct fc_lport *lport)
604{ 596{
605 printk(KERN_INFO "host%d: libfc: Link down on port (%6x)\n", 597 printk(KERN_INFO "host%d: libfc: Link down on port (%6.6x)\n",
606 lport->host->host_no, fc_host_port_id(lport->host)); 598 lport->host->host_no, lport->port_id);
607 599
608 mutex_lock(&lport->lp_mutex); 600 mutex_lock(&lport->lp_mutex);
609 __fc_linkdown(lport); 601 __fc_linkdown(lport);
@@ -704,8 +696,8 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
704 break; 696 break;
705 case DISC_EV_FAILED: 697 case DISC_EV_FAILED:
706 printk(KERN_ERR "host%d: libfc: " 698 printk(KERN_ERR "host%d: libfc: "
707 "Discovery failed for port (%6x)\n", 699 "Discovery failed for port (%6.6x)\n",
708 lport->host->host_no, fc_host_port_id(lport->host)); 700 lport->host->host_no, lport->port_id);
709 mutex_lock(&lport->lp_mutex); 701 mutex_lock(&lport->lp_mutex);
710 fc_lport_enter_reset(lport); 702 fc_lport_enter_reset(lport);
711 mutex_unlock(&lport->lp_mutex); 703 mutex_unlock(&lport->lp_mutex);
@@ -750,10 +742,14 @@ static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id,
750 struct fc_frame *fp) 742 struct fc_frame *fp)
751{ 743{
752 if (port_id) 744 if (port_id)
753 printk(KERN_INFO "host%d: Assigned Port ID %6x\n", 745 printk(KERN_INFO "host%d: Assigned Port ID %6.6x\n",
754 lport->host->host_no, port_id); 746 lport->host->host_no, port_id);
755 747
748 lport->port_id = port_id;
749
750 /* Update the fc_host */
756 fc_host_port_id(lport->host) = port_id; 751 fc_host_port_id(lport->host) = port_id;
752
757 if (lport->tt.lport_set_port_id) 753 if (lport->tt.lport_set_port_id)
758 lport->tt.lport_set_port_id(lport, port_id, fp); 754 lport->tt.lport_set_port_id(lport, port_id, fp);
759} 755}
@@ -797,11 +793,11 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
797 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); 793 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
798 if (remote_wwpn == lport->wwpn) { 794 if (remote_wwpn == lport->wwpn) {
799 printk(KERN_WARNING "host%d: libfc: Received FLOGI from port " 795 printk(KERN_WARNING "host%d: libfc: Received FLOGI from port "
800 "with same WWPN %llx\n", 796 "with same WWPN %16.16llx\n",
801 lport->host->host_no, remote_wwpn); 797 lport->host->host_no, remote_wwpn);
802 goto out; 798 goto out;
803 } 799 }
804 FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\n", remote_wwpn); 800 FC_LPORT_DBG(lport, "FLOGI from port WWPN %16.16llx\n", remote_wwpn);
805 801
806 /* 802 /*
807 * XXX what is the right thing to do for FIDs? 803 * XXX what is the right thing to do for FIDs?
@@ -832,7 +828,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
832 */ 828 */
833 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 829 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
834 ep = fc_seq_exch(sp); 830 ep = fc_seq_exch(sp);
835 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 831 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, remote_fid, local_fid,
836 FC_TYPE_ELS, f_ctl, 0); 832 FC_TYPE_ELS, f_ctl, 0);
837 lport->tt.seq_send(lport, sp, fp); 833 lport->tt.seq_send(lport, sp, fp);
838 834
@@ -947,14 +943,18 @@ static void fc_lport_reset_locked(struct fc_lport *lport)
947 if (lport->dns_rdata) 943 if (lport->dns_rdata)
948 lport->tt.rport_logoff(lport->dns_rdata); 944 lport->tt.rport_logoff(lport->dns_rdata);
949 945
950 lport->ptp_rdata = NULL; 946 if (lport->ptp_rdata) {
947 lport->tt.rport_logoff(lport->ptp_rdata);
948 kref_put(&lport->ptp_rdata->kref, lport->tt.rport_destroy);
949 lport->ptp_rdata = NULL;
950 }
951 951
952 lport->tt.disc_stop(lport); 952 lport->tt.disc_stop(lport);
953 953
954 lport->tt.exch_mgr_reset(lport, 0, 0); 954 lport->tt.exch_mgr_reset(lport, 0, 0);
955 fc_host_fabric_name(lport->host) = 0; 955 fc_host_fabric_name(lport->host) = 0;
956 956
957 if (fc_host_port_id(lport->host)) 957 if (lport->port_id)
958 fc_lport_set_port_id(lport, 0, NULL); 958 fc_lport_set_port_id(lport, 0, NULL);
959} 959}
960 960
@@ -1492,7 +1492,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1492 lport->r_a_tov = 2 * e_d_tov; 1492 lport->r_a_tov = 2 * e_d_tov;
1493 fc_lport_set_port_id(lport, did, fp); 1493 fc_lport_set_port_id(lport, did, fp);
1494 printk(KERN_INFO "host%d: libfc: " 1494 printk(KERN_INFO "host%d: libfc: "
1495 "Port (%6x) entered " 1495 "Port (%6.6x) entered "
1496 "point-to-point mode\n", 1496 "point-to-point mode\n",
1497 lport->host->host_no, did); 1497 lport->host->host_no, did);
1498 fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id), 1498 fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id),
@@ -1699,7 +1699,7 @@ static int fc_lport_els_request(struct fc_bsg_job *job,
1699 fh = fc_frame_header_get(fp); 1699 fh = fc_frame_header_get(fp);
1700 fh->fh_r_ctl = FC_RCTL_ELS_REQ; 1700 fh->fh_r_ctl = FC_RCTL_ELS_REQ;
1701 hton24(fh->fh_d_id, did); 1701 hton24(fh->fh_d_id, did);
1702 hton24(fh->fh_s_id, fc_host_port_id(lport->host)); 1702 hton24(fh->fh_s_id, lport->port_id);
1703 fh->fh_type = FC_TYPE_ELS; 1703 fh->fh_type = FC_TYPE_ELS;
1704 hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | 1704 hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
1705 FC_FC_END_SEQ | FC_FC_SEQ_INIT); 1705 FC_FC_END_SEQ | FC_FC_SEQ_INIT);
@@ -1759,7 +1759,7 @@ static int fc_lport_ct_request(struct fc_bsg_job *job,
1759 fh = fc_frame_header_get(fp); 1759 fh = fc_frame_header_get(fp);
1760 fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL; 1760 fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
1761 hton24(fh->fh_d_id, did); 1761 hton24(fh->fh_d_id, did);
1762 hton24(fh->fh_s_id, fc_host_port_id(lport->host)); 1762 hton24(fh->fh_s_id, lport->port_id);
1763 fh->fh_type = FC_TYPE_CT; 1763 fh->fh_type = FC_TYPE_CT;
1764 hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | 1764 hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
1765 FC_FC_END_SEQ | FC_FC_SEQ_INIT); 1765 FC_FC_END_SEQ | FC_FC_SEQ_INIT);
diff --git a/drivers/scsi/libfc/fc_npiv.c b/drivers/scsi/libfc/fc_npiv.c
index c68f6c7341c2..dd2b43bb1c70 100644
--- a/drivers/scsi/libfc/fc_npiv.c
+++ b/drivers/scsi/libfc/fc_npiv.c
@@ -69,12 +69,15 @@ struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id)
69 struct fc_lport *lport = NULL; 69 struct fc_lport *lport = NULL;
70 struct fc_lport *vn_port; 70 struct fc_lport *vn_port;
71 71
72 if (fc_host_port_id(n_port->host) == port_id) 72 if (n_port->port_id == port_id)
73 return n_port; 73 return n_port;
74 74
75 if (port_id == FC_FID_FLOGI)
76 return n_port; /* for point-to-point */
77
75 mutex_lock(&n_port->lp_mutex); 78 mutex_lock(&n_port->lp_mutex);
76 list_for_each_entry(vn_port, &n_port->vports, list) { 79 list_for_each_entry(vn_port, &n_port->vports, list) {
77 if (fc_host_port_id(vn_port->host) == port_id) { 80 if (vn_port->port_id == port_id) {
78 lport = vn_port; 81 lport = vn_port;
79 break; 82 break;
80 } 83 }
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index b37d0ff28b35..39e440f0f54a 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -1442,136 +1442,115 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1442 struct fc_els_spp *spp; /* response spp */ 1442 struct fc_els_spp *spp; /* response spp */
1443 unsigned int len; 1443 unsigned int len;
1444 unsigned int plen; 1444 unsigned int plen;
1445 enum fc_els_rjt_reason reason = ELS_RJT_UNAB;
1446 enum fc_els_rjt_explan explan = ELS_EXPL_NONE;
1447 enum fc_els_spp_resp resp; 1445 enum fc_els_spp_resp resp;
1448 struct fc_seq_els_data rjt_data; 1446 struct fc_seq_els_data rjt_data;
1449 u32 f_ctl; 1447 u32 f_ctl;
1450 u32 fcp_parm; 1448 u32 fcp_parm;
1451 u32 roles = FC_RPORT_ROLE_UNKNOWN; 1449 u32 roles = FC_RPORT_ROLE_UNKNOWN;
1452 rjt_data.fp = NULL;
1453 1450
1451 rjt_data.fp = NULL;
1454 fh = fc_frame_header_get(rx_fp); 1452 fh = fc_frame_header_get(rx_fp);
1455 1453
1456 FC_RPORT_DBG(rdata, "Received PRLI request while in state %s\n", 1454 FC_RPORT_DBG(rdata, "Received PRLI request while in state %s\n",
1457 fc_rport_state(rdata)); 1455 fc_rport_state(rdata));
1458 1456
1459 switch (rdata->rp_state) {
1460 case RPORT_ST_PRLI:
1461 case RPORT_ST_RTV:
1462 case RPORT_ST_READY:
1463 case RPORT_ST_ADISC:
1464 reason = ELS_RJT_NONE;
1465 break;
1466 default:
1467 fc_frame_free(rx_fp);
1468 return;
1469 break;
1470 }
1471 len = fr_len(rx_fp) - sizeof(*fh); 1457 len = fr_len(rx_fp) - sizeof(*fh);
1472 pp = fc_frame_payload_get(rx_fp, sizeof(*pp)); 1458 pp = fc_frame_payload_get(rx_fp, sizeof(*pp));
1473 if (pp == NULL) { 1459 if (!pp)
1474 reason = ELS_RJT_PROT; 1460 goto reject_len;
1475 explan = ELS_EXPL_INV_LEN; 1461 plen = ntohs(pp->prli.prli_len);
1476 } else { 1462 if ((plen % 4) != 0 || plen > len || plen < 16)
1477 plen = ntohs(pp->prli.prli_len); 1463 goto reject_len;
1478 if ((plen % 4) != 0 || plen > len) { 1464 if (plen < len)
1479 reason = ELS_RJT_PROT; 1465 len = plen;
1480 explan = ELS_EXPL_INV_LEN; 1466 plen = pp->prli.prli_spp_len;
1481 } else if (plen < len) { 1467 if ((plen % 4) != 0 || plen < sizeof(*spp) ||
1482 len = plen; 1468 plen > len || len < sizeof(*pp) || plen < 12)
1483 } 1469 goto reject_len;
1484 plen = pp->prli.prli_spp_len; 1470 rspp = &pp->spp;
1485 if ((plen % 4) != 0 || plen < sizeof(*spp) || 1471
1486 plen > len || len < sizeof(*pp)) { 1472 fp = fc_frame_alloc(lport, len);
1487 reason = ELS_RJT_PROT; 1473 if (!fp) {
1488 explan = ELS_EXPL_INV_LEN; 1474 rjt_data.reason = ELS_RJT_UNAB;
1489 } 1475 rjt_data.explan = ELS_EXPL_INSUF_RES;
1490 rspp = &pp->spp; 1476 goto reject;
1491 } 1477 }
1492 if (reason != ELS_RJT_NONE || 1478 sp = lport->tt.seq_start_next(sp);
1493 (fp = fc_frame_alloc(lport, len)) == NULL) { 1479 WARN_ON(!sp);
1494 rjt_data.reason = reason; 1480 pp = fc_frame_payload_get(fp, len);
1495 rjt_data.explan = explan; 1481 WARN_ON(!pp);
1496 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 1482 memset(pp, 0, len);
1497 } else { 1483 pp->prli.prli_cmd = ELS_LS_ACC;
1498 sp = lport->tt.seq_start_next(sp); 1484 pp->prli.prli_spp_len = plen;
1499 WARN_ON(!sp); 1485 pp->prli.prli_len = htons(len);
1500 pp = fc_frame_payload_get(fp, len); 1486 len -= sizeof(struct fc_els_prli);
1501 WARN_ON(!pp);
1502 memset(pp, 0, len);
1503 pp->prli.prli_cmd = ELS_LS_ACC;
1504 pp->prli.prli_spp_len = plen;
1505 pp->prli.prli_len = htons(len);
1506 len -= sizeof(struct fc_els_prli);
1507
1508 /* reinitialize remote port roles */
1509 rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;
1510
1511 /*
1512 * Go through all the service parameter pages and build
1513 * response. If plen indicates longer SPP than standard,
1514 * use that. The entire response has been pre-cleared above.
1515 */
1516 spp = &pp->spp;
1517 while (len >= plen) {
1518 spp->spp_type = rspp->spp_type;
1519 spp->spp_type_ext = rspp->spp_type_ext;
1520 spp->spp_flags = rspp->spp_flags & FC_SPP_EST_IMG_PAIR;
1521 resp = FC_SPP_RESP_ACK;
1522 if (rspp->spp_flags & FC_SPP_RPA_VAL)
1523 resp = FC_SPP_RESP_NO_PA;
1524 switch (rspp->spp_type) {
1525 case 0: /* common to all FC-4 types */
1526 break;
1527 case FC_TYPE_FCP:
1528 fcp_parm = ntohl(rspp->spp_params);
1529 if (fcp_parm & FCP_SPPF_RETRY)
1530 rdata->flags |= FC_RP_FLAGS_RETRY;
1531 rdata->supported_classes = FC_COS_CLASS3;
1532 if (fcp_parm & FCP_SPPF_INIT_FCN)
1533 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
1534 if (fcp_parm & FCP_SPPF_TARG_FCN)
1535 roles |= FC_RPORT_ROLE_FCP_TARGET;
1536 rdata->ids.roles = roles;
1537
1538 spp->spp_params =
1539 htonl(lport->service_params);
1540 break;
1541 default:
1542 resp = FC_SPP_RESP_INVL;
1543 break;
1544 }
1545 spp->spp_flags |= resp;
1546 len -= plen;
1547 rspp = (struct fc_els_spp *)((char *)rspp + plen);
1548 spp = (struct fc_els_spp *)((char *)spp + plen);
1549 }
1550 1487
1551 /* 1488 /* reinitialize remote port roles */
1552 * Send LS_ACC. If this fails, the originator should retry. 1489 rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;
1553 */
1554 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
1555 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
1556 ep = fc_seq_exch(sp);
1557 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
1558 FC_TYPE_ELS, f_ctl, 0);
1559 lport->tt.seq_send(lport, sp, fp);
1560 1490
1561 /* 1491 /*
1562 * Get lock and re-check state. 1492 * Go through all the service parameter pages and build
1563 */ 1493 * response. If plen indicates longer SPP than standard,
1564 switch (rdata->rp_state) { 1494 * use that. The entire response has been pre-cleared above.
1565 case RPORT_ST_PRLI: 1495 */
1566 fc_rport_enter_ready(rdata); 1496 spp = &pp->spp;
1497 while (len >= plen) {
1498 spp->spp_type = rspp->spp_type;
1499 spp->spp_type_ext = rspp->spp_type_ext;
1500 spp->spp_flags = rspp->spp_flags & FC_SPP_EST_IMG_PAIR;
1501 resp = FC_SPP_RESP_ACK;
1502
1503 switch (rspp->spp_type) {
1504 case 0: /* common to all FC-4 types */
1567 break; 1505 break;
1568 case RPORT_ST_READY: 1506 case FC_TYPE_FCP:
1569 case RPORT_ST_ADISC: 1507 fcp_parm = ntohl(rspp->spp_params);
1508 if (fcp_parm & FCP_SPPF_RETRY)
1509 rdata->flags |= FC_RP_FLAGS_RETRY;
1510 rdata->supported_classes = FC_COS_CLASS3;
1511 if (fcp_parm & FCP_SPPF_INIT_FCN)
1512 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
1513 if (fcp_parm & FCP_SPPF_TARG_FCN)
1514 roles |= FC_RPORT_ROLE_FCP_TARGET;
1515 rdata->ids.roles = roles;
1516
1517 spp->spp_params = htonl(lport->service_params);
1570 break; 1518 break;
1571 default: 1519 default:
1520 resp = FC_SPP_RESP_INVL;
1572 break; 1521 break;
1573 } 1522 }
1523 spp->spp_flags |= resp;
1524 len -= plen;
1525 rspp = (struct fc_els_spp *)((char *)rspp + plen);
1526 spp = (struct fc_els_spp *)((char *)spp + plen);
1527 }
1528
1529 /*
1530 * Send LS_ACC. If this fails, the originator should retry.
1531 */
1532 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
1533 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
1534 ep = fc_seq_exch(sp);
1535 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
1536 FC_TYPE_ELS, f_ctl, 0);
1537 lport->tt.seq_send(lport, sp, fp);
1538
1539 switch (rdata->rp_state) {
1540 case RPORT_ST_PRLI:
1541 fc_rport_enter_ready(rdata);
1542 break;
1543 default:
1544 break;
1574 } 1545 }
1546 goto drop;
1547
1548reject_len:
1549 rjt_data.reason = ELS_RJT_PROT;
1550 rjt_data.explan = ELS_EXPL_INV_LEN;
1551reject:
1552 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
1553drop:
1575 fc_frame_free(rx_fp); 1554 fc_frame_free(rx_fp);
1576} 1555}
1577 1556