]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | Subject: Better handle other FC initiators |
2 | From: Brian King <brking@linux.vnet.ibm.com> | |
3 | References: 471217 - LTC51238 | |
4 | ||
5 | The ibmvfc driver currently always sets the role of all rports | |
6 | to FC_PORT_ROLE_FCP_TARGET, which is not correct for other initiators. | |
7 | This can cause problems if other initiators are on the fabric | |
8 | when we then try to scan the rport for LUNs. Fix this by looking | |
9 | at the service parameters returned in the PRLI to set the roles | |
10 | appropriately. Also look at the returned service parameters to | |
11 | decide whether or not we were actually able to successfully log into | |
12 | the target. | |
13 | ||
14 | Signed-off-by: Brian King <brking@linux.vnet.ibm.com> | |
15 | Signed-off-by: Olaf Hering <olh@suse.de> | |
16 | --- | |
17 | ||
18 | drivers/scsi/ibmvscsi/ibmvfc.c | 62 ++++++++++++++++++++++++++++++++++++++--- | |
19 | 1 file changed, 58 insertions(+), 4 deletions(-) | |
20 | ||
21 | --- a/drivers/scsi/ibmvscsi/ibmvfc.c | |
22 | +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |
23 | @@ -2768,6 +2768,40 @@ static void ibmvfc_retry_tgt_init(struct | |
24 | ibmvfc_init_tgt(tgt, job_step); | |
25 | } | |
26 | ||
27 | +/* Defined in FC-LS */ | |
28 | +static const struct { | |
29 | + int code; | |
30 | + int retry; | |
31 | + int logged_in; | |
32 | +} prli_rsp [] = { | |
33 | + { 0, 1, 0 }, | |
34 | + { 1, 0, 1 }, | |
35 | + { 2, 1, 0 }, | |
36 | + { 3, 1, 0 }, | |
37 | + { 4, 0, 0 }, | |
38 | + { 5, 0, 0 }, | |
39 | + { 6, 0, 1 }, | |
40 | + { 7, 0, 0 }, | |
41 | + { 8, 1, 0 }, | |
42 | +}; | |
43 | + | |
44 | +/** | |
45 | + * ibmvfc_get_prli_rsp - Find PRLI response index | |
46 | + * @flags: PRLI response flags | |
47 | + * | |
48 | + **/ | |
49 | +static int ibmvfc_get_prli_rsp(u16 flags) | |
50 | +{ | |
51 | + int i; | |
52 | + int code = (flags & 0x0f00) >> 8; | |
53 | + | |
54 | + for (i = 0; i < ARRAY_SIZE(prli_rsp); i++) | |
55 | + if (prli_rsp[i].code == code) | |
56 | + return i; | |
57 | + | |
58 | + return 0; | |
59 | +} | |
60 | + | |
61 | /** | |
62 | * ibmvfc_tgt_prli_done - Completion handler for Process Login | |
63 | * @evt: ibmvfc event struct | |
64 | @@ -2778,15 +2812,36 @@ static void ibmvfc_tgt_prli_done(struct | |
65 | struct ibmvfc_target *tgt = evt->tgt; | |
66 | struct ibmvfc_host *vhost = evt->vhost; | |
67 | struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli; | |
68 | + struct ibmvfc_prli_svc_parms *parms = &rsp->parms; | |
69 | u32 status = rsp->common.status; | |
70 | + int index; | |
71 | ||
72 | vhost->discovery_threads--; | |
73 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); | |
74 | switch (status) { | |
75 | case IBMVFC_MAD_SUCCESS: | |
76 | - tgt_dbg(tgt, "Process Login succeeded\n"); | |
77 | - tgt->need_login = 0; | |
78 | - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT); | |
79 | + tgt_dbg(tgt, "Process Login succeeded: %X %02X %04X\n", | |
80 | + parms->type, parms->flags, parms->service_parms); | |
81 | + | |
82 | + if (parms->type == IBMVFC_SCSI_FCP_TYPE) { | |
83 | + index = ibmvfc_get_prli_rsp(parms->flags); | |
84 | + if (prli_rsp[index].logged_in) { | |
85 | + if (parms->flags & IBMVFC_PRLI_EST_IMG_PAIR) { | |
86 | + tgt->need_login = 0; | |
87 | + tgt->ids.roles = 0; | |
88 | + if (parms->service_parms & IBMVFC_PRLI_TARGET_FUNC) | |
89 | + tgt->ids.roles |= FC_PORT_ROLE_FCP_TARGET; | |
90 | + if (parms->service_parms & IBMVFC_PRLI_INITIATOR_FUNC) | |
91 | + tgt->ids.roles |= FC_PORT_ROLE_FCP_INITIATOR; | |
92 | + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT); | |
93 | + } else | |
94 | + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); | |
95 | + } else if (prli_rsp[index].retry) | |
96 | + ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli); | |
97 | + else | |
98 | + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); | |
99 | + } else | |
100 | + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); | |
101 | break; | |
102 | case IBMVFC_MAD_DRIVER_FAILED: | |
103 | break; | |
104 | @@ -2875,7 +2930,6 @@ static void ibmvfc_tgt_plogi_done(struct | |
105 | tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name); | |
106 | tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name); | |
107 | tgt->ids.port_id = tgt->scsi_id; | |
108 | - tgt->ids.roles = FC_PORT_ROLE_FCP_TARGET; | |
109 | memcpy(&tgt->service_parms, &rsp->service_parms, | |
110 | sizeof(tgt->service_parms)); | |
111 | memcpy(&tgt->service_parms_change, &rsp->service_parms_change, |