diff options
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r-- | drivers/scsi/libfc/fc_disc.c | 8 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_elsct.c | 2 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 51 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_fcp.c | 103 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_libfc.h | 8 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 58 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_npiv.c | 7 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 195 |
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 | */ |
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, |
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 *); | |||
97 | static void fc_fcp_complete_locked(struct fc_fcp_pkt *); | 97 | static void fc_fcp_complete_locked(struct fc_fcp_pkt *); |
98 | static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *); | 98 | static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *); |
99 | static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *); | 99 | static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *); |
100 | static void fc_timeout_error(struct fc_fcp_pkt *); | 100 | static void fc_fcp_recovery(struct fc_fcp_pkt *); |
101 | static void fc_fcp_timeout(unsigned long); | 101 | static void fc_fcp_timeout(unsigned long); |
102 | static void fc_fcp_rec(struct fc_fcp_pkt *); | 102 | static void fc_fcp_rec(struct fc_fcp_pkt *); |
103 | static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *); | 103 | static 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))) { |
480 | crc_err: | 486 | crc_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; | ||
520 | err: | ||
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; |
1346 | unlock: | 1355 | unlock: |
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 | */ |
1584 | static void fc_timeout_error(struct fc_fcp_pkt *fsp) | 1593 | static 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 | */ | ||
247 | void 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 | } | ||
252 | EXPORT_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 | */ |
573 | void fc_linkup(struct fc_lport *lport) | 565 | void 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 | */ |
603 | void fc_linkdown(struct fc_lport *lport) | 595 | void 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 | |||
1548 | reject_len: | ||
1549 | rjt_data.reason = ELS_RJT_PROT; | ||
1550 | rjt_data.explan = ELS_EXPL_INV_LEN; | ||
1551 | reject: | ||
1552 | lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); | ||
1553 | drop: | ||
1575 | fc_frame_free(rx_fp); | 1554 | fc_frame_free(rx_fp); |
1576 | } | 1555 | } |
1577 | 1556 | ||