diff options
author | Abhijeet Joglekar <abjoglek@cisco.com> | 2009-04-21 19:26:58 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-04-27 11:18:51 -0400 |
commit | 76f6804e7e7bb836cbdf4a73fe6c5485e4cc04c2 (patch) | |
tree | 84a01586a05b430ca327709173a65e53b793ca88 /drivers/scsi/libfc | |
parent | 0d228c0f7f9e3ade147e57682915c55b92448230 (diff) |
[SCSI] libfc: Do not retry if the new state is not the same as old state
For instance, if there is a Plogi pending (remote port is in Plogi state),
and the state changes to say NONE (because the port is being logged off),
then when the Plogi resp times out, do not start a retry.
This patch partially reverts an earlier patch (libfc: check for err when
recv and state is incorrect), by moving the state check back to before
checking for error. However, if the state does not match, then there is
an additional check to see if its an error ptr or a real frame before
jumping to err or out respectively.
Signed-off-by: Abhijeet Joglekar <abjoglek@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 60 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 48 |
2 files changed, 63 insertions, 45 deletions
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index b8178ef398d7..52c4f2dfcfd3 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
@@ -1032,17 +1032,19 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1032 | 1032 | ||
1033 | FC_DEBUG_LPORT("Received a RFT_ID response\n"); | 1033 | FC_DEBUG_LPORT("Received a RFT_ID response\n"); |
1034 | 1034 | ||
1035 | if (IS_ERR(fp)) { | ||
1036 | fc_lport_error(lport, fp); | ||
1037 | goto err; | ||
1038 | } | ||
1039 | |||
1040 | if (lport->state != LPORT_ST_RFT_ID) { | 1035 | if (lport->state != LPORT_ST_RFT_ID) { |
1041 | FC_DBG("Received a RFT_ID response, but in state %s\n", | 1036 | FC_DBG("Received a RFT_ID response, but in state %s\n", |
1042 | fc_lport_state(lport)); | 1037 | fc_lport_state(lport)); |
1038 | if (IS_ERR(fp)) | ||
1039 | goto err; | ||
1043 | goto out; | 1040 | goto out; |
1044 | } | 1041 | } |
1045 | 1042 | ||
1043 | if (IS_ERR(fp)) { | ||
1044 | fc_lport_error(lport, fp); | ||
1045 | goto err; | ||
1046 | } | ||
1047 | |||
1046 | fh = fc_frame_header_get(fp); | 1048 | fh = fc_frame_header_get(fp); |
1047 | ct = fc_frame_payload_get(fp, sizeof(*ct)); | 1049 | ct = fc_frame_payload_get(fp, sizeof(*ct)); |
1048 | 1050 | ||
@@ -1084,17 +1086,19 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1084 | 1086 | ||
1085 | FC_DEBUG_LPORT("Received a RPN_ID response\n"); | 1087 | FC_DEBUG_LPORT("Received a RPN_ID response\n"); |
1086 | 1088 | ||
1087 | if (IS_ERR(fp)) { | ||
1088 | fc_lport_error(lport, fp); | ||
1089 | goto err; | ||
1090 | } | ||
1091 | |||
1092 | if (lport->state != LPORT_ST_RPN_ID) { | 1089 | if (lport->state != LPORT_ST_RPN_ID) { |
1093 | FC_DBG("Received a RPN_ID response, but in state %s\n", | 1090 | FC_DBG("Received a RPN_ID response, but in state %s\n", |
1094 | fc_lport_state(lport)); | 1091 | fc_lport_state(lport)); |
1092 | if (IS_ERR(fp)) | ||
1093 | goto err; | ||
1095 | goto out; | 1094 | goto out; |
1096 | } | 1095 | } |
1097 | 1096 | ||
1097 | if (IS_ERR(fp)) { | ||
1098 | fc_lport_error(lport, fp); | ||
1099 | goto err; | ||
1100 | } | ||
1101 | |||
1098 | fh = fc_frame_header_get(fp); | 1102 | fh = fc_frame_header_get(fp); |
1099 | ct = fc_frame_payload_get(fp, sizeof(*ct)); | 1103 | ct = fc_frame_payload_get(fp, sizeof(*ct)); |
1100 | if (fh && ct && fh->fh_type == FC_TYPE_CT && | 1104 | if (fh && ct && fh->fh_type == FC_TYPE_CT && |
@@ -1134,17 +1138,19 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1134 | 1138 | ||
1135 | FC_DEBUG_LPORT("Received a SCR response\n"); | 1139 | FC_DEBUG_LPORT("Received a SCR response\n"); |
1136 | 1140 | ||
1137 | if (IS_ERR(fp)) { | ||
1138 | fc_lport_error(lport, fp); | ||
1139 | goto err; | ||
1140 | } | ||
1141 | |||
1142 | if (lport->state != LPORT_ST_SCR) { | 1141 | if (lport->state != LPORT_ST_SCR) { |
1143 | FC_DBG("Received a SCR response, but in state %s\n", | 1142 | FC_DBG("Received a SCR response, but in state %s\n", |
1144 | fc_lport_state(lport)); | 1143 | fc_lport_state(lport)); |
1144 | if (IS_ERR(fp)) | ||
1145 | goto err; | ||
1145 | goto out; | 1146 | goto out; |
1146 | } | 1147 | } |
1147 | 1148 | ||
1149 | if (IS_ERR(fp)) { | ||
1150 | fc_lport_error(lport, fp); | ||
1151 | goto err; | ||
1152 | } | ||
1153 | |||
1148 | op = fc_frame_payload_op(fp); | 1154 | op = fc_frame_payload_op(fp); |
1149 | if (op == ELS_LS_ACC) | 1155 | if (op == ELS_LS_ACC) |
1150 | fc_lport_enter_ready(lport); | 1156 | fc_lport_enter_ready(lport); |
@@ -1360,17 +1366,19 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1360 | 1366 | ||
1361 | FC_DEBUG_LPORT("Received a LOGO response\n"); | 1367 | FC_DEBUG_LPORT("Received a LOGO response\n"); |
1362 | 1368 | ||
1363 | if (IS_ERR(fp)) { | ||
1364 | fc_lport_error(lport, fp); | ||
1365 | goto err; | ||
1366 | } | ||
1367 | |||
1368 | if (lport->state != LPORT_ST_LOGO) { | 1369 | if (lport->state != LPORT_ST_LOGO) { |
1369 | FC_DBG("Received a LOGO response, but in state %s\n", | 1370 | FC_DBG("Received a LOGO response, but in state %s\n", |
1370 | fc_lport_state(lport)); | 1371 | fc_lport_state(lport)); |
1372 | if (IS_ERR(fp)) | ||
1373 | goto err; | ||
1371 | goto out; | 1374 | goto out; |
1372 | } | 1375 | } |
1373 | 1376 | ||
1377 | if (IS_ERR(fp)) { | ||
1378 | fc_lport_error(lport, fp); | ||
1379 | goto err; | ||
1380 | } | ||
1381 | |||
1374 | op = fc_frame_payload_op(fp); | 1382 | op = fc_frame_payload_op(fp); |
1375 | if (op == ELS_LS_ACC) | 1383 | if (op == ELS_LS_ACC) |
1376 | fc_lport_enter_reset(lport); | 1384 | fc_lport_enter_reset(lport); |
@@ -1444,17 +1452,19 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1444 | 1452 | ||
1445 | FC_DEBUG_LPORT("Received a FLOGI response\n"); | 1453 | FC_DEBUG_LPORT("Received a FLOGI response\n"); |
1446 | 1454 | ||
1447 | if (IS_ERR(fp)) { | ||
1448 | fc_lport_error(lport, fp); | ||
1449 | goto err; | ||
1450 | } | ||
1451 | |||
1452 | if (lport->state != LPORT_ST_FLOGI) { | 1455 | if (lport->state != LPORT_ST_FLOGI) { |
1453 | FC_DBG("Received a FLOGI response, but in state %s\n", | 1456 | FC_DBG("Received a FLOGI response, but in state %s\n", |
1454 | fc_lport_state(lport)); | 1457 | fc_lport_state(lport)); |
1458 | if (IS_ERR(fp)) | ||
1459 | goto err; | ||
1455 | goto out; | 1460 | goto out; |
1456 | } | 1461 | } |
1457 | 1462 | ||
1463 | if (IS_ERR(fp)) { | ||
1464 | fc_lport_error(lport, fp); | ||
1465 | goto err; | ||
1466 | } | ||
1467 | |||
1458 | fh = fc_frame_header_get(fp); | 1468 | fh = fc_frame_header_get(fp); |
1459 | did = ntoh24(fh->fh_d_id); | 1469 | did = ntoh24(fh->fh_d_id); |
1460 | if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { | 1470 | if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { |
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 0472bb73221e..eef70b4b7b92 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
@@ -505,17 +505,19 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
505 | FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", | 505 | FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", |
506 | rport->port_id); | 506 | rport->port_id); |
507 | 507 | ||
508 | if (IS_ERR(fp)) { | ||
509 | fc_rport_error_retry(rport, fp); | ||
510 | goto err; | ||
511 | } | ||
512 | |||
513 | if (rdata->rp_state != RPORT_ST_PLOGI) { | 508 | if (rdata->rp_state != RPORT_ST_PLOGI) { |
514 | FC_DBG("Received a PLOGI response, but in state %s\n", | 509 | FC_DBG("Received a PLOGI response, but in state %s\n", |
515 | fc_rport_state(rport)); | 510 | fc_rport_state(rport)); |
511 | if (IS_ERR(fp)) | ||
512 | goto err; | ||
516 | goto out; | 513 | goto out; |
517 | } | 514 | } |
518 | 515 | ||
516 | if (IS_ERR(fp)) { | ||
517 | fc_rport_error_retry(rport, fp); | ||
518 | goto err; | ||
519 | } | ||
520 | |||
519 | op = fc_frame_payload_op(fp); | 521 | op = fc_frame_payload_op(fp); |
520 | if (op == ELS_LS_ACC && | 522 | if (op == ELS_LS_ACC && |
521 | (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { | 523 | (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { |
@@ -614,17 +616,19 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
614 | FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", | 616 | FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", |
615 | rport->port_id); | 617 | rport->port_id); |
616 | 618 | ||
617 | if (IS_ERR(fp)) { | ||
618 | fc_rport_error_retry(rport, fp); | ||
619 | goto err; | ||
620 | } | ||
621 | |||
622 | if (rdata->rp_state != RPORT_ST_PRLI) { | 619 | if (rdata->rp_state != RPORT_ST_PRLI) { |
623 | FC_DBG("Received a PRLI response, but in state %s\n", | 620 | FC_DBG("Received a PRLI response, but in state %s\n", |
624 | fc_rport_state(rport)); | 621 | fc_rport_state(rport)); |
622 | if (IS_ERR(fp)) | ||
623 | goto err; | ||
625 | goto out; | 624 | goto out; |
626 | } | 625 | } |
627 | 626 | ||
627 | if (IS_ERR(fp)) { | ||
628 | fc_rport_error_retry(rport, fp); | ||
629 | goto err; | ||
630 | } | ||
631 | |||
628 | op = fc_frame_payload_op(fp); | 632 | op = fc_frame_payload_op(fp); |
629 | if (op == ELS_LS_ACC) { | 633 | if (op == ELS_LS_ACC) { |
630 | pp = fc_frame_payload_get(fp, sizeof(*pp)); | 634 | pp = fc_frame_payload_get(fp, sizeof(*pp)); |
@@ -678,17 +682,19 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
678 | FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n", | 682 | FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n", |
679 | rport->port_id); | 683 | rport->port_id); |
680 | 684 | ||
681 | if (IS_ERR(fp)) { | ||
682 | fc_rport_error_retry(rport, fp); | ||
683 | goto err; | ||
684 | } | ||
685 | |||
686 | if (rdata->rp_state != RPORT_ST_LOGO) { | 685 | if (rdata->rp_state != RPORT_ST_LOGO) { |
687 | FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n", | 686 | FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n", |
688 | fc_rport_state(rport)); | 687 | fc_rport_state(rport)); |
688 | if (IS_ERR(fp)) | ||
689 | goto err; | ||
689 | goto out; | 690 | goto out; |
690 | } | 691 | } |
691 | 692 | ||
693 | if (IS_ERR(fp)) { | ||
694 | fc_rport_error_retry(rport, fp); | ||
695 | goto err; | ||
696 | } | ||
697 | |||
692 | op = fc_frame_payload_op(fp); | 698 | op = fc_frame_payload_op(fp); |
693 | if (op == ELS_LS_ACC) { | 699 | if (op == ELS_LS_ACC) { |
694 | fc_rport_enter_rtv(rport); | 700 | fc_rport_enter_rtv(rport); |
@@ -764,17 +770,19 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
764 | FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", | 770 | FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", |
765 | rport->port_id); | 771 | rport->port_id); |
766 | 772 | ||
767 | if (IS_ERR(fp)) { | ||
768 | fc_rport_error(rport, fp); | ||
769 | goto err; | ||
770 | } | ||
771 | |||
772 | if (rdata->rp_state != RPORT_ST_RTV) { | 773 | if (rdata->rp_state != RPORT_ST_RTV) { |
773 | FC_DBG("Received a RTV response, but in state %s\n", | 774 | FC_DBG("Received a RTV response, but in state %s\n", |
774 | fc_rport_state(rport)); | 775 | fc_rport_state(rport)); |
776 | if (IS_ERR(fp)) | ||
777 | goto err; | ||
775 | goto out; | 778 | goto out; |
776 | } | 779 | } |
777 | 780 | ||
781 | if (IS_ERR(fp)) { | ||
782 | fc_rport_error(rport, fp); | ||
783 | goto err; | ||
784 | } | ||
785 | |||
778 | op = fc_frame_payload_op(fp); | 786 | op = fc_frame_payload_op(fp); |
779 | if (op == ELS_LS_ACC) { | 787 | if (op == ELS_LS_ACC) { |
780 | struct fc_els_rtv_acc *rtv; | 788 | struct fc_els_rtv_acc *rtv; |