]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.25/patches.drivers/ibmvfc_prli_initiator_fix.patch
Revert "Move xen patchset to new version's subdir."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / ibmvfc_prli_initiator_fix.patch
diff --git a/src/patches/suse-2.6.27.25/patches.drivers/ibmvfc_prli_initiator_fix.patch b/src/patches/suse-2.6.27.25/patches.drivers/ibmvfc_prli_initiator_fix.patch
new file mode 100644 (file)
index 0000000..fc4e0b7
--- /dev/null
@@ -0,0 +1,111 @@
+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,