aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fc.c
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 /drivers/s390/scsi/zfcp_fc.c
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>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r--drivers/s390/scsi/zfcp_fc.c131
1 files changed, 66 insertions, 65 deletions
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}