aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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,