aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_def.h45
-rw-r--r--drivers/s390/scsi/zfcp_ext.h4
-rw-r--r--drivers/s390/scsi/zfcp_fc.c131
-rw-r--r--drivers/s390/scsi/zfcp_fc.h17
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c45
-rw-r--r--drivers/s390/scsi/zfcp_fsf.h20
6 files changed, 108 insertions, 154 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 0317e7f20850..fae8f2ebd43f 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -75,51 +75,6 @@
75 75
76#define ZFCP_DID_MASK 0x00FFFFFF 76#define ZFCP_DID_MASK 0x00FFFFFF
77 77
78/* see fc-fs */
79#define LS_RSCN 0x61
80#define LS_LOGO 0x05
81#define LS_PLOGI 0x03
82
83struct fcp_rscn_head {
84 u8 command;
85 u8 page_length; /* always 0x04 */
86 u16 payload_len;
87} __attribute__((packed));
88
89struct fcp_rscn_element {
90 u8 reserved:2;
91 u8 event_qual:4;
92 u8 addr_format:2;
93 u32 nport_did:24;
94} __attribute__((packed));
95
96/* see fc-ph */
97struct fcp_logo {
98 u32 command;
99 u32 nport_did;
100 u64 nport_wwpn;
101} __attribute__((packed));
102
103/*
104 * FC-FS stuff
105 */
106#define R_A_TOV 10 /* seconds */
107
108#define ZFCP_LS_RLS 0x0f
109#define ZFCP_LS_ADISC 0x52
110#define ZFCP_LS_RPS 0x56
111#define ZFCP_LS_RSCN 0x61
112#define ZFCP_LS_RNID 0x78
113
114struct zfcp_ls_adisc {
115 u8 code;
116 u8 field[3];
117 u32 hard_nport_id;
118 u64 wwpn;
119 u64 wwnn;
120 u32 nport_id;
121} __attribute__ ((packed));
122
123/* 78/*
124 * FC-GS-2 stuff 79 * FC-GS-2 stuff
125 */ 80 */
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 3832fe0ae2e4..c2b23b5a3d0a 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -9,6 +9,8 @@
9#ifndef ZFCP_EXT_H 9#ifndef ZFCP_EXT_H
10#define ZFCP_EXT_H 10#define ZFCP_EXT_H
11 11
12#include <linux/types.h>
13#include <scsi/fc/fc_els.h>
12#include "zfcp_def.h" 14#include "zfcp_def.h"
13 15
14/* zfcp_aux.c */ 16/* zfcp_aux.c */
@@ -98,7 +100,7 @@ extern void zfcp_fc_scan_ports(struct work_struct *);
98extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); 100extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
99extern void zfcp_fc_port_did_lookup(struct work_struct *); 101extern void zfcp_fc_port_did_lookup(struct work_struct *);
100extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *); 102extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);
101extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); 103extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fc_els_flogi *);
102extern void zfcp_fc_test_link(struct zfcp_port *); 104extern void zfcp_fc_test_link(struct zfcp_port *);
103extern void zfcp_fc_link_test_work(struct work_struct *); 105extern void zfcp_fc_link_test_work(struct work_struct *);
104extern void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *); 106extern void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 7d6b3cadfb73..e03410043cd7 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -9,20 +9,17 @@
9#define KMSG_COMPONENT "zfcp" 9#define KMSG_COMPONENT "zfcp"
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11 11
12#include <linux/types.h>
13#include <scsi/fc/fc_els.h>
14#include <scsi/libfc.h>
12#include "zfcp_ext.h" 15#include "zfcp_ext.h"
16#include "zfcp_fc.h"
13 17
14enum rscn_address_format { 18static u32 zfcp_fc_rscn_range_mask[] = {
15 RSCN_PORT_ADDRESS = 0x0, 19 [ELS_ADDR_FMT_PORT] = 0xFFFFFF,
16 RSCN_AREA_ADDRESS = 0x1, 20 [ELS_ADDR_FMT_AREA] = 0xFFFF00,
17 RSCN_DOMAIN_ADDRESS = 0x2, 21 [ELS_ADDR_FMT_DOM] = 0xFF0000,
18 RSCN_FABRIC_ADDRESS = 0x3, 22 [ELS_ADDR_FMT_FAB] = 0x000000,
19};
20
21static u32 rscn_range_mask[] = {
22 [RSCN_PORT_ADDRESS] = 0xFFFFFF,
23 [RSCN_AREA_ADDRESS] = 0xFFFF00,
24 [RSCN_DOMAIN_ADDRESS] = 0xFF0000,
25 [RSCN_FABRIC_ADDRESS] = 0x000000,
26}; 23};
27 24
28struct gpn_ft_resp_acc { 25struct gpn_ft_resp_acc {
@@ -144,7 +141,7 @@ void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs)
144} 141}
145 142
146static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, 143static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
147 struct fcp_rscn_element *elem) 144 struct fc_els_rscn_page *page)
148{ 145{
149 unsigned long flags; 146 unsigned long flags;
150 struct zfcp_adapter *adapter = fsf_req->adapter; 147 struct zfcp_adapter *adapter = fsf_req->adapter;
@@ -152,7 +149,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
152 149
153 read_lock_irqsave(&adapter->port_list_lock, flags); 150 read_lock_irqsave(&adapter->port_list_lock, flags);
154 list_for_each_entry(port, &adapter->port_list, list) { 151 list_for_each_entry(port, &adapter->port_list, list) {
155 if ((port->d_id & range) == (elem->nport_did & range)) 152 if ((port->d_id & range) == (ntoh24(page->rscn_fid) & range))
156 zfcp_fc_test_link(port); 153 zfcp_fc_test_link(port);
157 if (!port->d_id) 154 if (!port->d_id)
158 zfcp_erp_port_reopen(port, 155 zfcp_erp_port_reopen(port,
@@ -165,24 +162,24 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
165static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) 162static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
166{ 163{
167 struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data; 164 struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data;
168 struct fcp_rscn_head *fcp_rscn_head; 165 struct fc_els_rscn *head;
169 struct fcp_rscn_element *fcp_rscn_element; 166 struct fc_els_rscn_page *page;
170 u16 i; 167 u16 i;
171 u16 no_entries; 168 u16 no_entries;
172 u32 range_mask; 169 unsigned int afmt;
173 170
174 fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload.data; 171 head = (struct fc_els_rscn *) status_buffer->payload.data;
175 fcp_rscn_element = (struct fcp_rscn_element *) fcp_rscn_head; 172 page = (struct fc_els_rscn_page *) head;
176 173
177 /* see FC-FS */ 174 /* see FC-FS */
178 no_entries = fcp_rscn_head->payload_len / 175 no_entries = head->rscn_plen / sizeof(struct fc_els_rscn_page);
179 sizeof(struct fcp_rscn_element);
180 176
181 for (i = 1; i < no_entries; i++) { 177 for (i = 1; i < no_entries; i++) {
182 /* skip head and start with 1st element */ 178 /* skip head and start with 1st element */
183 fcp_rscn_element++; 179 page++;
184 range_mask = rscn_range_mask[fcp_rscn_element->addr_format]; 180 afmt = page->rscn_page_flags & ELS_RSCN_ADDR_FMT_MASK;
185 _zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element); 181 _zfcp_fc_incoming_rscn(fsf_req, zfcp_fc_rscn_range_mask[afmt],
182 page);
186 } 183 }
187 queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work); 184 queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
188} 185}
@@ -204,22 +201,22 @@ static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
204 201
205static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req) 202static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req)
206{ 203{
207 struct fsf_status_read_buffer *status_buffer = 204 struct fsf_status_read_buffer *status_buffer;
208 (struct fsf_status_read_buffer *)req->data; 205 struct fc_els_flogi *plogi;
209 struct fsf_plogi *els_plogi =
210 (struct fsf_plogi *) status_buffer->payload.data;
211 206
212 zfcp_fc_incoming_wwpn(req, els_plogi->serv_param.wwpn); 207 status_buffer = (struct fsf_status_read_buffer *) req->data;
208 plogi = (struct fc_els_flogi *) status_buffer->payload.data;
209 zfcp_fc_incoming_wwpn(req, plogi->fl_wwpn);
213} 210}
214 211
215static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req) 212static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req)
216{ 213{
217 struct fsf_status_read_buffer *status_buffer = 214 struct fsf_status_read_buffer *status_buffer =
218 (struct fsf_status_read_buffer *)req->data; 215 (struct fsf_status_read_buffer *)req->data;
219 struct fcp_logo *els_logo = 216 struct fc_els_logo *logo =
220 (struct fcp_logo *) status_buffer->payload.data; 217 (struct fc_els_logo *) status_buffer->payload.data;
221 218
222 zfcp_fc_incoming_wwpn(req, els_logo->nport_wwpn); 219 zfcp_fc_incoming_wwpn(req, logo->fl_n_port_wwn);
223} 220}
224 221
225/** 222/**
@@ -233,11 +230,11 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
233 unsigned int els_type = status_buffer->payload.data[0]; 230 unsigned int els_type = status_buffer->payload.data[0];
234 231
235 zfcp_dbf_san_incoming_els(fsf_req); 232 zfcp_dbf_san_incoming_els(fsf_req);
236 if (els_type == LS_PLOGI) 233 if (els_type == ELS_PLOGI)
237 zfcp_fc_incoming_plogi(fsf_req); 234 zfcp_fc_incoming_plogi(fsf_req);
238 else if (els_type == LS_LOGO) 235 else if (els_type == ELS_LOGO)
239 zfcp_fc_incoming_logo(fsf_req); 236 zfcp_fc_incoming_logo(fsf_req);
240 else if (els_type == LS_RSCN) 237 else if (els_type == ELS_RSCN)
241 zfcp_fc_incoming_rscn(fsf_req); 238 zfcp_fc_incoming_rscn(fsf_req);
242} 239}
243 240
@@ -379,33 +376,36 @@ void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
379 * 376 *
380 * Evaluate PLOGI playload and copy important fields into zfcp_port structure 377 * Evaluate PLOGI playload and copy important fields into zfcp_port structure
381 */ 378 */
382void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi) 379void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fc_els_flogi *plogi)
383{ 380{
384 port->maxframe_size = plogi->serv_param.common_serv_param[7] | 381 if (plogi->fl_wwpn != port->wwpn) {
385 ((plogi->serv_param.common_serv_param[6] & 0x0F) << 8); 382 port->d_id = 0;
386 if (plogi->serv_param.class1_serv_param[0] & 0x80) 383 dev_warn(&port->adapter->ccw_device->dev,
384 "A port opened with WWPN 0x%016Lx returned data that "
385 "identifies it as WWPN 0x%016Lx\n",
386 (unsigned long long) port->wwpn,
387 (unsigned long long) plogi->fl_wwpn);
388 return;
389 }
390
391 port->wwnn = plogi->fl_wwnn;
392 port->maxframe_size = plogi->fl_csp.sp_bb_data;
393
394 if (plogi->fl_cssp[0].cp_class & FC_CPC_VALID)
387 port->supported_classes |= FC_COS_CLASS1; 395 port->supported_classes |= FC_COS_CLASS1;
388 if (plogi->serv_param.class2_serv_param[0] & 0x80) 396 if (plogi->fl_cssp[1].cp_class & FC_CPC_VALID)
389 port->supported_classes |= FC_COS_CLASS2; 397 port->supported_classes |= FC_COS_CLASS2;
390 if (plogi->serv_param.class3_serv_param[0] & 0x80) 398 if (plogi->fl_cssp[2].cp_class & FC_CPC_VALID)
391 port->supported_classes |= FC_COS_CLASS3; 399 port->supported_classes |= FC_COS_CLASS3;
392 if (plogi->serv_param.class4_serv_param[0] & 0x80) 400 if (plogi->fl_cssp[3].cp_class & FC_CPC_VALID)
393 port->supported_classes |= FC_COS_CLASS4; 401 port->supported_classes |= FC_COS_CLASS4;
394} 402}
395 403
396struct zfcp_els_adisc {
397 struct zfcp_send_els els;
398 struct scatterlist req;
399 struct scatterlist resp;
400 struct zfcp_ls_adisc ls_adisc;
401 struct zfcp_ls_adisc ls_adisc_acc;
402};
403
404static void zfcp_fc_adisc_handler(unsigned long data) 404static void zfcp_fc_adisc_handler(unsigned long data)
405{ 405{
406 struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data; 406 struct zfcp_fc_els_adisc *adisc = (struct zfcp_fc_els_adisc *) data;
407 struct zfcp_port *port = adisc->els.port; 407 struct zfcp_port *port = adisc->els.port;
408 struct zfcp_ls_adisc *ls_adisc = &adisc->ls_adisc_acc; 408 struct fc_els_adisc *adisc_resp = &adisc->adisc_resp;
409 409
410 if (adisc->els.status) { 410 if (adisc->els.status) {
411 /* request rejected or timed out */ 411 /* request rejected or timed out */
@@ -415,9 +415,9 @@ static void zfcp_fc_adisc_handler(unsigned long data)
415 } 415 }
416 416
417 if (!port->wwnn) 417 if (!port->wwnn)
418 port->wwnn = ls_adisc->wwnn; 418 port->wwnn = adisc_resp->adisc_wwnn;
419 419
420 if ((port->wwpn != ls_adisc->wwpn) || 420 if ((port->wwpn != adisc_resp->adisc_wwpn) ||
421 !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) { 421 !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) {
422 zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, 422 zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
423 "fcadh_2", NULL); 423 "fcadh_2", NULL);
@@ -434,32 +434,33 @@ static void zfcp_fc_adisc_handler(unsigned long data)
434 434
435static int zfcp_fc_adisc(struct zfcp_port *port) 435static int zfcp_fc_adisc(struct zfcp_port *port)
436{ 436{
437 struct zfcp_els_adisc *adisc; 437 struct zfcp_fc_els_adisc *adisc;
438 struct zfcp_adapter *adapter = port->adapter; 438 struct zfcp_adapter *adapter = port->adapter;
439 439
440 adisc = kzalloc(sizeof(struct zfcp_els_adisc), GFP_ATOMIC); 440 adisc = kzalloc(sizeof(struct zfcp_fc_els_adisc), GFP_ATOMIC);
441 if (!adisc) 441 if (!adisc)
442 return -ENOMEM; 442 return -ENOMEM;
443 443
444 adisc->els.req = &adisc->req; 444 adisc->els.req = &adisc->req;
445 adisc->els.resp = &adisc->resp; 445 adisc->els.resp = &adisc->resp;
446 sg_init_one(adisc->els.req, &adisc->ls_adisc, 446 sg_init_one(adisc->els.req, &adisc->adisc_req,
447 sizeof(struct zfcp_ls_adisc)); 447 sizeof(struct fc_els_adisc));
448 sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc, 448 sg_init_one(adisc->els.resp, &adisc->adisc_resp,
449 sizeof(struct zfcp_ls_adisc)); 449 sizeof(struct fc_els_adisc));
450 450
451 adisc->els.adapter = adapter; 451 adisc->els.adapter = adapter;
452 adisc->els.port = port; 452 adisc->els.port = port;
453 adisc->els.d_id = port->d_id; 453 adisc->els.d_id = port->d_id;
454 adisc->els.handler = zfcp_fc_adisc_handler; 454 adisc->els.handler = zfcp_fc_adisc_handler;
455 adisc->els.handler_data = (unsigned long) adisc; 455 adisc->els.handler_data = (unsigned long) adisc;
456 adisc->els.ls_code = adisc->ls_adisc.code = ZFCP_LS_ADISC; 456 adisc->els.ls_code = adisc->adisc_req.adisc_cmd = ELS_ADISC;
457 457
458 /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports 458 /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
459 without FC-AL-2 capability, so we don't set it */ 459 without FC-AL-2 capability, so we don't set it */
460 adisc->ls_adisc.wwpn = fc_host_port_name(adapter->scsi_host); 460 adisc->adisc_req.adisc_wwpn = fc_host_port_name(adapter->scsi_host);
461 adisc->ls_adisc.wwnn = fc_host_node_name(adapter->scsi_host); 461 adisc->adisc_req.adisc_wwnn = fc_host_node_name(adapter->scsi_host);
462 adisc->ls_adisc.nport_id = fc_host_port_id(adapter->scsi_host); 462 hton24(adisc->adisc_req.adisc_port_id,
463 fc_host_port_id(adapter->scsi_host));
463 464
464 return zfcp_fsf_send_els(&adisc->els); 465 return zfcp_fsf_send_els(&adisc->els);
465} 466}
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
index 814fc2d2525a..231e231b7fd7 100644
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -10,11 +10,28 @@
10#ifndef ZFCP_FC_H 10#ifndef ZFCP_FC_H
11#define ZFCP_FC_H 11#define ZFCP_FC_H
12 12
13#include <scsi/fc/fc_els.h>
13#include <scsi/fc/fc_fcp.h> 14#include <scsi/fc/fc_fcp.h>
14#include <scsi/scsi_cmnd.h> 15#include <scsi/scsi_cmnd.h>
15#include <scsi/scsi_tcq.h> 16#include <scsi/scsi_tcq.h>
16 17
17/** 18/**
19 * struct zfcp_fc_els_adisc - everything required in zfcp for issuing ELS ADISC
20 * @els: data required for issuing els fsf command
21 * @req: scatterlist entry for ELS ADISC request
22 * @resp: scatterlist entry for ELS ADISC response
23 * @adisc_req: ELS ADISC request data
24 * @adisc_resp: ELS ADISC response data
25 */
26struct zfcp_fc_els_adisc {
27 struct zfcp_send_els els;
28 struct scatterlist req;
29 struct scatterlist resp;
30 struct fc_els_adisc adisc_req;
31 struct fc_els_adisc adisc_resp;
32};
33
34/**
18 * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd 35 * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
19 * @fcp: fcp_cmnd to setup 36 * @fcp: fcp_cmnd to setup
20 * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB 37 * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 5f4cd03797e9..9d7bf965d398 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -10,6 +10,7 @@
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11 11
12#include <linux/blktrace_api.h> 12#include <linux/blktrace_api.h>
13#include <scsi/fc/fc_els.h>
13#include "zfcp_ext.h" 14#include "zfcp_ext.h"
14#include "zfcp_fc.h" 15#include "zfcp_fc.h"
15#include "zfcp_dbf.h" 16#include "zfcp_dbf.h"
@@ -477,17 +478,22 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
477 478
478static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) 479static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
479{ 480{
480 struct fsf_qtcb_bottom_config *bottom; 481 struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config;
481 struct zfcp_adapter *adapter = req->adapter; 482 struct zfcp_adapter *adapter = req->adapter;
482 struct Scsi_Host *shost = adapter->scsi_host; 483 struct Scsi_Host *shost = adapter->scsi_host;
484 struct fc_els_flogi *nsp, *plogi;
483 485
484 bottom = &req->qtcb->bottom.config; 486 /* adjust pointers for missing command code */
487 nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param
488 - sizeof(u32));
489 plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload
490 - sizeof(u32));
485 491
486 if (req->data) 492 if (req->data)
487 memcpy(req->data, bottom, sizeof(*bottom)); 493 memcpy(req->data, bottom, sizeof(*bottom));
488 494
489 fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; 495 fc_host_port_name(shost) = nsp->fl_wwpn;
490 fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; 496 fc_host_node_name(shost) = nsp->fl_wwnn;
491 fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; 497 fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
492 fc_host_speed(shost) = bottom->fc_link_speed; 498 fc_host_speed(shost) = bottom->fc_link_speed;
493 fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; 499 fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
@@ -501,8 +507,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
501 switch (bottom->fc_topology) { 507 switch (bottom->fc_topology) {
502 case FSF_TOPO_P2P: 508 case FSF_TOPO_P2P:
503 adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK; 509 adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
504 adapter->peer_wwpn = bottom->plogi_payload.wwpn; 510 adapter->peer_wwpn = plogi->fl_wwpn;
505 adapter->peer_wwnn = bottom->plogi_payload.wwnn; 511 adapter->peer_wwnn = plogi->fl_wwnn;
506 fc_host_port_type(shost) = FC_PORTTYPE_PTP; 512 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
507 break; 513 break;
508 case FSF_TOPO_FABRIC: 514 case FSF_TOPO_FABRIC:
@@ -1068,15 +1074,17 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
1068 int max_sbals) 1074 int max_sbals)
1069{ 1075{
1070 int ret; 1076 int ret;
1077 unsigned int fcp_chan_timeout;
1071 1078
1072 ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); 1079 ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
1073 if (ret) 1080 if (ret)
1074 return ret; 1081 return ret;
1075 1082
1076 /* common settings for ct/gs and els requests */ 1083 /* common settings for ct/gs and els requests */
1084 fcp_chan_timeout = 2 * FC_DEF_R_A_TOV / 1000;
1077 req->qtcb->bottom.support.service_class = FSF_CLASS_3; 1085 req->qtcb->bottom.support.service_class = FSF_CLASS_3;
1078 req->qtcb->bottom.support.timeout = 2 * R_A_TOV; 1086 req->qtcb->bottom.support.timeout = fcp_chan_timeout;
1079 zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ); 1087 zfcp_fsf_start_timer(req, (fcp_chan_timeout + 10) * HZ);
1080 1088
1081 return 0; 1089 return 0;
1082} 1090}
@@ -1151,7 +1159,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
1151 case FSF_ADAPTER_STATUS_AVAILABLE: 1159 case FSF_ADAPTER_STATUS_AVAILABLE:
1152 switch (header->fsf_status_qual.word[0]){ 1160 switch (header->fsf_status_qual.word[0]){
1153 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: 1161 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
1154 if (port && (send_els->ls_code != ZFCP_LS_ADISC)) 1162 if (port && (send_els->ls_code != ELS_ADISC))
1155 zfcp_fc_test_link(port); 1163 zfcp_fc_test_link(port);
1156 /*fall through */ 1164 /*fall through */
1157 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: 1165 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
@@ -1419,7 +1427,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1419{ 1427{
1420 struct zfcp_port *port = req->data; 1428 struct zfcp_port *port = req->data;
1421 struct fsf_qtcb_header *header = &req->qtcb->header; 1429 struct fsf_qtcb_header *header = &req->qtcb->header;
1422 struct fsf_plogi *plogi; 1430 struct fc_els_flogi *plogi;
1423 1431
1424 if (req->status & ZFCP_STATUS_FSFREQ_ERROR) 1432 if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
1425 goto out; 1433 goto out;
@@ -1469,23 +1477,10 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1469 * another GID_PN straight after a port has been opened. 1477 * another GID_PN straight after a port has been opened.
1470 * Alternately, an ADISC/PDISC ELS should suffice, as well. 1478 * Alternately, an ADISC/PDISC ELS should suffice, as well.
1471 */ 1479 */
1472 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; 1480 plogi = (struct fc_els_flogi *) req->qtcb->bottom.support.els;
1473 if (req->qtcb->bottom.support.els1_length >= 1481 if (req->qtcb->bottom.support.els1_length >=
1474 FSF_PLOGI_MIN_LEN) { 1482 FSF_PLOGI_MIN_LEN)
1475 if (plogi->serv_param.wwpn != port->wwpn) {
1476 port->d_id = 0;
1477 dev_warn(&port->adapter->ccw_device->dev,
1478 "A port opened with WWPN 0x%016Lx "
1479 "returned data that identifies it as "
1480 "WWPN 0x%016Lx\n",
1481 (unsigned long long) port->wwpn,
1482 (unsigned long long)
1483 plogi->serv_param.wwpn);
1484 } else {
1485 port->wwnn = plogi->serv_param.wwnn;
1486 zfcp_fc_plogi_evaluate(port, plogi); 1483 zfcp_fc_plogi_evaluate(port, plogi);
1487 }
1488 }
1489 break; 1484 break;
1490 case FSF_UNKNOWN_OP_SUBTYPE: 1485 case FSF_UNKNOWN_OP_SUBTYPE:
1491 req->status |= ZFCP_STATUS_FSFREQ_ERROR; 1486 req->status |= ZFCP_STATUS_FSFREQ_ERROR;
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index dcc7c1dbcf58..402e0235a357 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -309,22 +309,7 @@ struct fsf_qtcb_header {
309 u8 res4[16]; 309 u8 res4[16];
310} __attribute__ ((packed)); 310} __attribute__ ((packed));
311 311
312struct fsf_nport_serv_param {
313 u8 common_serv_param[16];
314 u64 wwpn;
315 u64 wwnn;
316 u8 class1_serv_param[16];
317 u8 class2_serv_param[16];
318 u8 class3_serv_param[16];
319 u8 class4_serv_param[16];
320 u8 vendor_version_level[16];
321} __attribute__ ((packed));
322
323#define FSF_PLOGI_MIN_LEN 112 312#define FSF_PLOGI_MIN_LEN 112
324struct fsf_plogi {
325 u32 code;
326 struct fsf_nport_serv_param serv_param;
327} __attribute__ ((packed));
328 313
329#define FSF_FCP_CMND_SIZE 288 314#define FSF_FCP_CMND_SIZE 288
330#define FSF_FCP_RSP_SIZE 128 315#define FSF_FCP_RSP_SIZE 128
@@ -377,13 +362,12 @@ struct fsf_qtcb_bottom_config {
377 u16 timer_interval; 362 u16 timer_interval;
378 u8 res2[8]; 363 u8 res2[8];
379 u32 s_id; 364 u32 s_id;
380 struct fsf_nport_serv_param nport_serv_param; 365 u8 nport_serv_param[128];
381 u8 reserved_nport_serv_param[16];
382 u8 res3[8]; 366 u8 res3[8];
383 u32 adapter_ports; 367 u32 adapter_ports;
384 u32 hardware_version; 368 u32 hardware_version;
385 u8 serial_number[32]; 369 u8 serial_number[32];
386 struct fsf_nport_serv_param plogi_payload; 370 u8 plogi_payload[112];
387 struct fsf_statistics_info stat_info; 371 struct fsf_statistics_info stat_info;
388 u8 res4[112]; 372 u8 res4[112];
389} __attribute__ ((packed)); 373} __attribute__ ((packed));