+++ /dev/null
-Subject: Better handle other FC initiators
-From: Brian King <brking@linux.vnet.ibm.com>
-References: 471217 - LTC51238
-
-The ibmvfc driver currently always sets the role of all rports
-to FC_PORT_ROLE_FCP_TARGET, which is not correct for other initiators.
-This can cause problems if other initiators are on the fabric
-when we then try to scan the rport for LUNs. Fix this by looking
-at the service parameters returned in the PRLI to set the roles
-appropriately. Also look at the returned service parameters to
-decide whether or not we were actually able to successfully log into
-the target.
-
-Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
-Signed-off-by: Olaf Hering <olh@suse.de>
----
-
- drivers/scsi/ibmvscsi/ibmvfc.c | 62 ++++++++++++++++++++++++++++++++++++++---
- 1 file changed, 58 insertions(+), 4 deletions(-)
-
---- a/drivers/scsi/ibmvscsi/ibmvfc.c
-+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
-@@ -2768,6 +2768,40 @@ static void ibmvfc_retry_tgt_init(struct
- ibmvfc_init_tgt(tgt, job_step);
- }
-
-+/* Defined in FC-LS */
-+static const struct {
-+ int code;
-+ int retry;
-+ int logged_in;
-+} prli_rsp [] = {
-+ { 0, 1, 0 },
-+ { 1, 0, 1 },
-+ { 2, 1, 0 },
-+ { 3, 1, 0 },
-+ { 4, 0, 0 },
-+ { 5, 0, 0 },
-+ { 6, 0, 1 },
-+ { 7, 0, 0 },
-+ { 8, 1, 0 },
-+};
-+
-+/**
-+ * ibmvfc_get_prli_rsp - Find PRLI response index
-+ * @flags: PRLI response flags
-+ *
-+ **/
-+static int ibmvfc_get_prli_rsp(u16 flags)
-+{
-+ int i;
-+ int code = (flags & 0x0f00) >> 8;
-+
-+ for (i = 0; i < ARRAY_SIZE(prli_rsp); i++)
-+ if (prli_rsp[i].code == code)
-+ return i;
-+
-+ return 0;
-+}
-+
- /**
- * ibmvfc_tgt_prli_done - Completion handler for Process Login
- * @evt: ibmvfc event struct
-@@ -2778,15 +2812,36 @@ static void ibmvfc_tgt_prli_done(struct
- struct ibmvfc_target *tgt = evt->tgt;
- struct ibmvfc_host *vhost = evt->vhost;
- struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli;
-+ struct ibmvfc_prli_svc_parms *parms = &rsp->parms;
- u32 status = rsp->common.status;
-+ int index;
-
- vhost->discovery_threads--;
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
- switch (status) {
- case IBMVFC_MAD_SUCCESS:
-- tgt_dbg(tgt, "Process Login succeeded\n");
-- tgt->need_login = 0;
-- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT);
-+ tgt_dbg(tgt, "Process Login succeeded: %X %02X %04X\n",
-+ parms->type, parms->flags, parms->service_parms);
-+
-+ if (parms->type == IBMVFC_SCSI_FCP_TYPE) {
-+ index = ibmvfc_get_prli_rsp(parms->flags);
-+ if (prli_rsp[index].logged_in) {
-+ if (parms->flags & IBMVFC_PRLI_EST_IMG_PAIR) {
-+ tgt->need_login = 0;
-+ tgt->ids.roles = 0;
-+ if (parms->service_parms & IBMVFC_PRLI_TARGET_FUNC)
-+ tgt->ids.roles |= FC_PORT_ROLE_FCP_TARGET;
-+ if (parms->service_parms & IBMVFC_PRLI_INITIATOR_FUNC)
-+ tgt->ids.roles |= FC_PORT_ROLE_FCP_INITIATOR;
-+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT);
-+ } else
-+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
-+ } else if (prli_rsp[index].retry)
-+ ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
-+ else
-+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
-+ } else
-+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
- break;
- case IBMVFC_MAD_DRIVER_FAILED:
- break;
-@@ -2875,7 +2930,6 @@ static void ibmvfc_tgt_plogi_done(struct
- tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name);
- tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name);
- tgt->ids.port_id = tgt->scsi_id;
-- tgt->ids.roles = FC_PORT_ROLE_FCP_TARGET;
- memcpy(&tgt->service_parms, &rsp->service_parms,
- sizeof(tgt->service_parms));
- memcpy(&tgt->service_parms_change, &rsp->service_parms_change,