aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorVasu Dev <vasu.dev@intel.com>2011-10-28 14:34:23 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-31 05:27:43 -0400
commit907c07d45199f954ddcf66c2c9763c87d012cb15 (patch)
tree4d25bde865cc84feebf93d73c7dd186a6e15be2a /drivers/scsi
parentb6e3c84034b93e6acc895711f74730e235dfe9d2 (diff)
[SCSI] libfc: improve flogi retries to avoid lport stuck
Adds more cases to do flogi retry, now also retry on getting bad response due to either no ELS response or flogi response payload length not large enough. In those cases flogi was not retried and that was leaving lport offline. Signed-off-by: Vasu Dev <vasu.dev@intel.com> Tested-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: Yi Zou <yi.zou@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/fcoe/fcoe.c13
-rw-r--r--drivers/scsi/libfc/fc_lport.c90
2 files changed, 54 insertions, 49 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 61384ee4049b..cefbe44bb84a 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -2347,14 +2347,11 @@ static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
2347 goto done; 2347 goto done;
2348 2348
2349 mac = fr_cb(fp)->granted_mac; 2349 mac = fr_cb(fp)->granted_mac;
2350 if (is_zero_ether_addr(mac)) { 2350 /* pre-FIP */
2351 /* pre-FIP */ 2351 if (is_zero_ether_addr(mac))
2352 if (fcoe_ctlr_recv_flogi(fip, lport, fp)) { 2352 fcoe_ctlr_recv_flogi(fip, lport, fp);
2353 fc_frame_free(fp); 2353 if (!is_zero_ether_addr(mac))
2354 return; 2354 fcoe_update_src_mac(lport, mac);
2355 }
2356 }
2357 fcoe_update_src_mac(lport, mac);
2358done: 2355done:
2359 fc_lport_flogi_resp(seq, fp, lport); 2356 fc_lport_flogi_resp(seq, fp, lport);
2360} 2357}
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index e0fb89133566..2cb12b9cd3e8 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1473,6 +1473,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1473 void *lp_arg) 1473 void *lp_arg)
1474{ 1474{
1475 struct fc_lport *lport = lp_arg; 1475 struct fc_lport *lport = lp_arg;
1476 struct fc_frame_header *fh;
1476 struct fc_els_flogi *flp; 1477 struct fc_els_flogi *flp;
1477 u32 did; 1478 u32 did;
1478 u16 csp_flags; 1479 u16 csp_flags;
@@ -1500,49 +1501,56 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1500 goto err; 1501 goto err;
1501 } 1502 }
1502 1503
1504 fh = fc_frame_header_get(fp);
1503 did = fc_frame_did(fp); 1505 did = fc_frame_did(fp);
1504 if (fc_frame_payload_op(fp) == ELS_LS_ACC && did) { 1506 if (fh->fh_r_ctl != FC_RCTL_ELS_REP || did == 0 ||
1505 flp = fc_frame_payload_get(fp, sizeof(*flp)); 1507 fc_frame_payload_op(fp) != ELS_LS_ACC) {
1506 if (flp) { 1508 FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n");
1507 mfs = ntohs(flp->fl_csp.sp_bb_data) &
1508 FC_SP_BB_DATA_MASK;
1509 if (mfs >= FC_SP_MIN_MAX_PAYLOAD &&
1510 mfs < lport->mfs)
1511 lport->mfs = mfs;
1512 csp_flags = ntohs(flp->fl_csp.sp_features);
1513 r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
1514 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
1515 if (csp_flags & FC_SP_FT_EDTR)
1516 e_d_tov /= 1000000;
1517
1518 lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
1519
1520 if ((csp_flags & FC_SP_FT_FPORT) == 0) {
1521 if (e_d_tov > lport->e_d_tov)
1522 lport->e_d_tov = e_d_tov;
1523 lport->r_a_tov = 2 * e_d_tov;
1524 fc_lport_set_port_id(lport, did, fp);
1525 printk(KERN_INFO "host%d: libfc: "
1526 "Port (%6.6x) entered "
1527 "point-to-point mode\n",
1528 lport->host->host_no, did);
1529 fc_lport_ptp_setup(lport, fc_frame_sid(fp),
1530 get_unaligned_be64(
1531 &flp->fl_wwpn),
1532 get_unaligned_be64(
1533 &flp->fl_wwnn));
1534 } else {
1535 lport->e_d_tov = e_d_tov;
1536 lport->r_a_tov = r_a_tov;
1537 fc_host_fabric_name(lport->host) =
1538 get_unaligned_be64(&flp->fl_wwnn);
1539 fc_lport_set_port_id(lport, did, fp);
1540 fc_lport_enter_dns(lport);
1541 }
1542 }
1543 } else {
1544 FC_LPORT_DBG(lport, "FLOGI RJT or bad response\n");
1545 fc_lport_error(lport, fp); 1509 fc_lport_error(lport, fp);
1510 goto err;
1511 }
1512
1513 flp = fc_frame_payload_get(fp, sizeof(*flp));
1514 if (!flp) {
1515 FC_LPORT_DBG(lport, "FLOGI bad response\n");
1516 fc_lport_error(lport, fp);
1517 goto err;
1518 }
1519
1520 mfs = ntohs(flp->fl_csp.sp_bb_data) &
1521 FC_SP_BB_DATA_MASK;
1522 if (mfs >= FC_SP_MIN_MAX_PAYLOAD &&
1523 mfs < lport->mfs)
1524 lport->mfs = mfs;
1525 csp_flags = ntohs(flp->fl_csp.sp_features);
1526 r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
1527 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
1528 if (csp_flags & FC_SP_FT_EDTR)
1529 e_d_tov /= 1000000;
1530
1531 lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
1532
1533 if ((csp_flags & FC_SP_FT_FPORT) == 0) {
1534 if (e_d_tov > lport->e_d_tov)
1535 lport->e_d_tov = e_d_tov;
1536 lport->r_a_tov = 2 * e_d_tov;
1537 fc_lport_set_port_id(lport, did, fp);
1538 printk(KERN_INFO "host%d: libfc: "
1539 "Port (%6.6x) entered "
1540 "point-to-point mode\n",
1541 lport->host->host_no, did);
1542 fc_lport_ptp_setup(lport, fc_frame_sid(fp),
1543 get_unaligned_be64(
1544 &flp->fl_wwpn),
1545 get_unaligned_be64(
1546 &flp->fl_wwnn));
1547 } else {
1548 lport->e_d_tov = e_d_tov;
1549 lport->r_a_tov = r_a_tov;
1550 fc_host_fabric_name(lport->host) =
1551 get_unaligned_be64(&flp->fl_wwnn);
1552 fc_lport_set_port_id(lport, did, fp);
1553 fc_lport_enter_dns(lport);
1546 } 1554 }
1547 1555
1548out: 1556out: