aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2009-11-24 10:54:09 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:02:11 -0500
commit9d05ce2c0a6704ff84df02cbb3baef94fcac4f5d (patch)
tree2388ff365f068511ceb6e9bfbc13fe2425f0ae4c
parent4318e08c84e4916ac463002ffb7f9901ddb3c385 (diff)
[SCSI] zfcp: Use common code definitions for FC ELS structs
Use common code definitions for FC plogi, logo, rscn and adisc structs instead of inventing private ones. Move the private struct for issuing ELS ADISC inside zfcp to zfcp_fc header file. Reviewed-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-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));