aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2009-02-02 19:39:40 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-03-12 13:58:12 -0400
commita3b7aeaba29e3dd995ece05ba50db9e0650c16b6 (patch)
treeb67ee797f1dd21d33e889efbdabd5e408d179e3d /drivers/scsi/ibmvscsi
parentea41e41588c248ee8b8162869c1e1c0565a4b3f6 (diff)
[SCSI] ibmvfc: Better handle other FC initiators
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: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/ibmvscsi')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c62
1 files changed, 58 insertions, 4 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index ed1e728763a2..93d1fbe4ee5d 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2767,6 +2767,40 @@ static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt,
2767 ibmvfc_init_tgt(tgt, job_step); 2767 ibmvfc_init_tgt(tgt, job_step);
2768} 2768}
2769 2769
2770/* Defined in FC-LS */
2771static const struct {
2772 int code;
2773 int retry;
2774 int logged_in;
2775} prli_rsp [] = {
2776 { 0, 1, 0 },
2777 { 1, 0, 1 },
2778 { 2, 1, 0 },
2779 { 3, 1, 0 },
2780 { 4, 0, 0 },
2781 { 5, 0, 0 },
2782 { 6, 0, 1 },
2783 { 7, 0, 0 },
2784 { 8, 1, 0 },
2785};
2786
2787/**
2788 * ibmvfc_get_prli_rsp - Find PRLI response index
2789 * @flags: PRLI response flags
2790 *
2791 **/
2792static int ibmvfc_get_prli_rsp(u16 flags)
2793{
2794 int i;
2795 int code = (flags & 0x0f00) >> 8;
2796
2797 for (i = 0; i < ARRAY_SIZE(prli_rsp); i++)
2798 if (prli_rsp[i].code == code)
2799 return i;
2800
2801 return 0;
2802}
2803
2770/** 2804/**
2771 * ibmvfc_tgt_prli_done - Completion handler for Process Login 2805 * ibmvfc_tgt_prli_done - Completion handler for Process Login
2772 * @evt: ibmvfc event struct 2806 * @evt: ibmvfc event struct
@@ -2777,15 +2811,36 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
2777 struct ibmvfc_target *tgt = evt->tgt; 2811 struct ibmvfc_target *tgt = evt->tgt;
2778 struct ibmvfc_host *vhost = evt->vhost; 2812 struct ibmvfc_host *vhost = evt->vhost;
2779 struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli; 2813 struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli;
2814 struct ibmvfc_prli_svc_parms *parms = &rsp->parms;
2780 u32 status = rsp->common.status; 2815 u32 status = rsp->common.status;
2816 int index;
2781 2817
2782 vhost->discovery_threads--; 2818 vhost->discovery_threads--;
2783 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); 2819 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
2784 switch (status) { 2820 switch (status) {
2785 case IBMVFC_MAD_SUCCESS: 2821 case IBMVFC_MAD_SUCCESS:
2786 tgt_dbg(tgt, "Process Login succeeded\n"); 2822 tgt_dbg(tgt, "Process Login succeeded: %X %02X %04X\n",
2787 tgt->need_login = 0; 2823 parms->type, parms->flags, parms->service_parms);
2788 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT); 2824
2825 if (parms->type == IBMVFC_SCSI_FCP_TYPE) {
2826 index = ibmvfc_get_prli_rsp(parms->flags);
2827 if (prli_rsp[index].logged_in) {
2828 if (parms->flags & IBMVFC_PRLI_EST_IMG_PAIR) {
2829 tgt->need_login = 0;
2830 tgt->ids.roles = 0;
2831 if (parms->service_parms & IBMVFC_PRLI_TARGET_FUNC)
2832 tgt->ids.roles |= FC_PORT_ROLE_FCP_TARGET;
2833 if (parms->service_parms & IBMVFC_PRLI_INITIATOR_FUNC)
2834 tgt->ids.roles |= FC_PORT_ROLE_FCP_INITIATOR;
2835 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT);
2836 } else
2837 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2838 } else if (prli_rsp[index].retry)
2839 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
2840 else
2841 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2842 } else
2843 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2789 break; 2844 break;
2790 case IBMVFC_MAD_DRIVER_FAILED: 2845 case IBMVFC_MAD_DRIVER_FAILED:
2791 break; 2846 break;
@@ -2874,7 +2929,6 @@ static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt)
2874 tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name); 2929 tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name);
2875 tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name); 2930 tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name);
2876 tgt->ids.port_id = tgt->scsi_id; 2931 tgt->ids.port_id = tgt->scsi_id;
2877 tgt->ids.roles = FC_PORT_ROLE_FCP_TARGET;
2878 memcpy(&tgt->service_parms, &rsp->service_parms, 2932 memcpy(&tgt->service_parms, &rsp->service_parms,
2879 sizeof(tgt->service_parms)); 2933 sizeof(tgt->service_parms));
2880 memcpy(&tgt->service_parms_change, &rsp->service_parms_change, 2934 memcpy(&tgt->service_parms_change, &rsp->service_parms_change,