diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_lport.c')
| -rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 90 |
1 files changed, 49 insertions, 41 deletions
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 | ||
| 1548 | out: | 1556 | out: |
