diff options
| -rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 6bbb9447b75d..c710d908fda6 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
| @@ -926,6 +926,20 @@ err: | |||
| 926 | kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); | 926 | kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); |
| 927 | } | 927 | } |
| 928 | 928 | ||
| 929 | static bool | ||
| 930 | fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata) | ||
| 931 | { | ||
| 932 | if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN) | ||
| 933 | return true; | ||
| 934 | if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) && | ||
| 935 | (lport->service_params & FCP_SPPF_INIT_FCN)) | ||
| 936 | return true; | ||
| 937 | if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) && | ||
| 938 | (lport->service_params & FCP_SPPF_TARG_FCN)) | ||
| 939 | return true; | ||
| 940 | return false; | ||
| 941 | } | ||
| 942 | |||
| 929 | /** | 943 | /** |
| 930 | * fc_rport_enter_plogi() - Send Port Login (PLOGI) request | 944 | * fc_rport_enter_plogi() - Send Port Login (PLOGI) request |
| 931 | * @rdata: The remote port to send a PLOGI to | 945 | * @rdata: The remote port to send a PLOGI to |
| @@ -938,6 +952,12 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata) | |||
| 938 | struct fc_lport *lport = rdata->local_port; | 952 | struct fc_lport *lport = rdata->local_port; |
| 939 | struct fc_frame *fp; | 953 | struct fc_frame *fp; |
| 940 | 954 | ||
| 955 | if (!fc_rport_compatible_roles(lport, rdata)) { | ||
| 956 | FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n"); | ||
| 957 | fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT); | ||
| 958 | return; | ||
| 959 | } | ||
| 960 | |||
| 941 | FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n", | 961 | FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n", |
| 942 | fc_rport_state(rdata)); | 962 | fc_rport_state(rdata)); |
| 943 | 963 | ||
| @@ -1646,6 +1666,13 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport, | |||
| 1646 | rjt_data.explan = ELS_EXPL_NONE; | 1666 | rjt_data.explan = ELS_EXPL_NONE; |
| 1647 | goto reject; | 1667 | goto reject; |
| 1648 | } | 1668 | } |
| 1669 | if (!fc_rport_compatible_roles(lport, rdata)) { | ||
| 1670 | FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n"); | ||
| 1671 | mutex_unlock(&rdata->rp_mutex); | ||
| 1672 | rjt_data.reason = ELS_RJT_LOGIC; | ||
| 1673 | rjt_data.explan = ELS_EXPL_NONE; | ||
| 1674 | goto reject; | ||
| 1675 | } | ||
| 1649 | 1676 | ||
| 1650 | /* | 1677 | /* |
| 1651 | * Get session payload size from incoming PLOGI. | 1678 | * Get session payload size from incoming PLOGI. |
