aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c2
-rw-r--r--drivers/s390/scsi/zfcp_dbf.h1
-rw-r--r--drivers/s390/scsi/zfcp_def.h9
-rw-r--r--drivers/s390/scsi/zfcp_fc.c55
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c32
-rw-r--r--drivers/s390/scsi/zfcp_fsf.h2
6 files changed, 61 insertions, 40 deletions
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index bf691fbc4d29..150bd5390b1d 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -936,6 +936,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
936 rct->reason_code = hdr->reason_code; 936 rct->reason_code = hdr->reason_code;
937 rct->expl = hdr->reason_code_expl; 937 rct->expl = hdr->reason_code_expl;
938 rct->vendor_unique = hdr->vendor_unique; 938 rct->vendor_unique = hdr->vendor_unique;
939 rct->max_res_size = hdr->max_res_size;
939 rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr), 940 rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
940 ZFCP_DBF_SAN_MAX_PAYLOAD); 941 ZFCP_DBF_SAN_MAX_PAYLOAD);
941 debug_event(adapter->san_dbf, level, r, sizeof(*r)); 942 debug_event(adapter->san_dbf, level, r, sizeof(*r));
@@ -1043,6 +1044,7 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
1043 zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code); 1044 zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code);
1044 zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl); 1045 zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl);
1045 zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique); 1046 zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique);
1047 zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
1046 } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || 1048 } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
1047 strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || 1049 strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
1048 strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { 1050 strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 5d6b2dff855b..74998ff88e57 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -171,6 +171,7 @@ struct zfcp_san_dbf_record_ct_response {
171 u8 reason_code; 171 u8 reason_code;
172 u8 expl; 172 u8 expl;
173 u8 vendor_unique; 173 u8 vendor_unique;
174 u16 max_res_size;
174 u32 len; 175 u32 len;
175} __attribute__ ((packed)); 176} __attribute__ ((packed));
176 177
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index ce4094966236..510662783a6f 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -197,7 +197,6 @@ struct zfcp_ls_adisc {
197#define ZFCP_CT_UNABLE_TO_PERFORM_CMD 0x09 197#define ZFCP_CT_UNABLE_TO_PERFORM_CMD 0x09
198#define ZFCP_CT_GID_PN 0x0121 198#define ZFCP_CT_GID_PN 0x0121
199#define ZFCP_CT_GPN_FT 0x0172 199#define ZFCP_CT_GPN_FT 0x0172
200#define ZFCP_CT_MAX_SIZE 0x1020
201#define ZFCP_CT_ACCEPT 0x8002 200#define ZFCP_CT_ACCEPT 0x8002
202#define ZFCP_CT_REJECT 0x8001 201#define ZFCP_CT_REJECT 0x8001
203 202
@@ -325,8 +324,6 @@ struct ct_iu_gid_pn_resp {
325 * @wka_port: port where the request is sent to 324 * @wka_port: port where the request is sent to
326 * @req: scatter-gather list for request 325 * @req: scatter-gather list for request
327 * @resp: scatter-gather list for response 326 * @resp: scatter-gather list for response
328 * @req_count: number of elements in request scatter-gather list
329 * @resp_count: number of elements in response scatter-gather list
330 * @handler: handler function (called for response to the request) 327 * @handler: handler function (called for response to the request)
331 * @handler_data: data passed to handler function 328 * @handler_data: data passed to handler function
332 * @timeout: FSF timeout for this request 329 * @timeout: FSF timeout for this request
@@ -337,8 +334,6 @@ struct zfcp_send_ct {
337 struct zfcp_wka_port *wka_port; 334 struct zfcp_wka_port *wka_port;
338 struct scatterlist *req; 335 struct scatterlist *req;
339 struct scatterlist *resp; 336 struct scatterlist *resp;
340 unsigned int req_count;
341 unsigned int resp_count;
342 void (*handler)(unsigned long); 337 void (*handler)(unsigned long);
343 unsigned long handler_data; 338 unsigned long handler_data;
344 int timeout; 339 int timeout;
@@ -363,8 +358,6 @@ struct zfcp_gid_pn_data {
363 * @d_id: destiniation id of port where request is sent to 358 * @d_id: destiniation id of port where request is sent to
364 * @req: scatter-gather list for request 359 * @req: scatter-gather list for request
365 * @resp: scatter-gather list for response 360 * @resp: scatter-gather list for response
366 * @req_count: number of elements in request scatter-gather list
367 * @resp_count: number of elements in response scatter-gather list
368 * @handler: handler function (called for response to the request) 361 * @handler: handler function (called for response to the request)
369 * @handler_data: data passed to handler function 362 * @handler_data: data passed to handler function
370 * @completion: completion for synchronization purposes 363 * @completion: completion for synchronization purposes
@@ -377,8 +370,6 @@ struct zfcp_send_els {
377 u32 d_id; 370 u32 d_id;
378 struct scatterlist *req; 371 struct scatterlist *req;
379 struct scatterlist *resp; 372 struct scatterlist *resp;
380 unsigned int req_count;
381 unsigned int resp_count;
382 void (*handler)(unsigned long); 373 void (*handler)(unsigned long);
383 unsigned long handler_data; 374 unsigned long handler_data;
384 struct completion *completion; 375 struct completion *completion;
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 217c3b04fd01..eabdfe24456e 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -40,9 +40,12 @@ struct gpn_ft_resp_acc {
40 u64 wwpn; 40 u64 wwpn;
41} __attribute__ ((packed)); 41} __attribute__ ((packed));
42 42
43#define ZFCP_GPN_FT_ENTRIES ((PAGE_SIZE - sizeof(struct ct_hdr)) \ 43#define ZFCP_CT_SIZE_ONE_PAGE (PAGE_SIZE - sizeof(struct ct_hdr))
44 / sizeof(struct gpn_ft_resp_acc)) 44#define ZFCP_GPN_FT_ENTRIES (ZFCP_CT_SIZE_ONE_PAGE \
45 / sizeof(struct gpn_ft_resp_acc))
45#define ZFCP_GPN_FT_BUFFERS 4 46#define ZFCP_GPN_FT_BUFFERS 4
47#define ZFCP_GPN_FT_MAX_SIZE (ZFCP_GPN_FT_BUFFERS * PAGE_SIZE \
48 - sizeof(struct ct_hdr))
46#define ZFCP_GPN_FT_MAX_ENTRIES ZFCP_GPN_FT_BUFFERS * (ZFCP_GPN_FT_ENTRIES + 1) 49#define ZFCP_GPN_FT_MAX_ENTRIES ZFCP_GPN_FT_BUFFERS * (ZFCP_GPN_FT_ENTRIES + 1)
47 50
48struct ct_iu_gpn_ft_resp { 51struct ct_iu_gpn_ft_resp {
@@ -282,8 +285,6 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
282 gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; 285 gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT;
283 gid_pn->ct.req = &gid_pn->req; 286 gid_pn->ct.req = &gid_pn->req;
284 gid_pn->ct.resp = &gid_pn->resp; 287 gid_pn->ct.resp = &gid_pn->resp;
285 gid_pn->ct.req_count = 1;
286 gid_pn->ct.resp_count = 1;
287 sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req, 288 sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req,
288 sizeof(struct ct_iu_gid_pn_req)); 289 sizeof(struct ct_iu_gid_pn_req));
289 sg_init_one(&gid_pn->resp, &gid_pn->ct_iu_resp, 290 sg_init_one(&gid_pn->resp, &gid_pn->ct_iu_resp,
@@ -295,7 +296,7 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
295 gid_pn->ct_iu_req.header.gs_subtype = ZFCP_CT_NAME_SERVER; 296 gid_pn->ct_iu_req.header.gs_subtype = ZFCP_CT_NAME_SERVER;
296 gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS; 297 gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS;
297 gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN; 298 gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN;
298 gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE; 299 gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4;
299 gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; 300 gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn;
300 301
301 init_completion(&compl_rec.done); 302 init_completion(&compl_rec.done);
@@ -405,8 +406,6 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
405 sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc, 406 sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc,
406 sizeof(struct zfcp_ls_adisc)); 407 sizeof(struct zfcp_ls_adisc));
407 408
408 adisc->els.req_count = 1;
409 adisc->els.resp_count = 1;
410 adisc->els.adapter = adapter; 409 adisc->els.adapter = adapter;
411 adisc->els.port = port; 410 adisc->els.port = port;
412 adisc->els.d_id = port->d_id; 411 adisc->els.d_id = port->d_id;
@@ -446,17 +445,17 @@ void zfcp_test_link(struct zfcp_port *port)
446 zfcp_erp_port_forced_reopen(port, 0, 65, NULL); 445 zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
447} 446}
448 447
449static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft) 448static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
450{ 449{
451 struct scatterlist *sg = &gpn_ft->sg_req; 450 struct scatterlist *sg = &gpn_ft->sg_req;
452 451
453 kfree(sg_virt(sg)); /* free request buffer */ 452 kfree(sg_virt(sg)); /* free request buffer */
454 zfcp_sg_free_table(gpn_ft->sg_resp, ZFCP_GPN_FT_BUFFERS); 453 zfcp_sg_free_table(gpn_ft->sg_resp, buf_num);
455 454
456 kfree(gpn_ft); 455 kfree(gpn_ft);
457} 456}
458 457
459static struct zfcp_gpn_ft *zfcp_alloc_sg_env(void) 458static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num)
460{ 459{
461 struct zfcp_gpn_ft *gpn_ft; 460 struct zfcp_gpn_ft *gpn_ft;
462 struct ct_iu_gpn_ft_req *req; 461 struct ct_iu_gpn_ft_req *req;
@@ -473,8 +472,8 @@ static struct zfcp_gpn_ft *zfcp_alloc_sg_env(void)
473 } 472 }
474 sg_init_one(&gpn_ft->sg_req, req, sizeof(*req)); 473 sg_init_one(&gpn_ft->sg_req, req, sizeof(*req));
475 474
476 if (zfcp_sg_setup_table(gpn_ft->sg_resp, ZFCP_GPN_FT_BUFFERS)) { 475 if (zfcp_sg_setup_table(gpn_ft->sg_resp, buf_num)) {
477 zfcp_free_sg_env(gpn_ft); 476 zfcp_free_sg_env(gpn_ft, buf_num);
478 gpn_ft = NULL; 477 gpn_ft = NULL;
479 } 478 }
480out: 479out:
@@ -483,7 +482,8 @@ out:
483 482
484 483
485static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, 484static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
486 struct zfcp_adapter *adapter) 485 struct zfcp_adapter *adapter,
486 int max_bytes)
487{ 487{
488 struct zfcp_send_ct *ct = &gpn_ft->ct; 488 struct zfcp_send_ct *ct = &gpn_ft->ct;
489 struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); 489 struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
@@ -496,8 +496,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
496 req->header.gs_subtype = ZFCP_CT_NAME_SERVER; 496 req->header.gs_subtype = ZFCP_CT_NAME_SERVER;
497 req->header.options = ZFCP_CT_SYNCHRONOUS; 497 req->header.options = ZFCP_CT_SYNCHRONOUS;
498 req->header.cmd_rsp_code = ZFCP_CT_GPN_FT; 498 req->header.cmd_rsp_code = ZFCP_CT_GPN_FT;
499 req->header.max_res_size = (sizeof(struct gpn_ft_resp_acc) * 499 req->header.max_res_size = max_bytes / 4;
500 (ZFCP_GPN_FT_MAX_ENTRIES - 1)) >> 2;
501 req->flags = 0; 500 req->flags = 0;
502 req->domain_id_scope = 0; 501 req->domain_id_scope = 0;
503 req->area_id_scope = 0; 502 req->area_id_scope = 0;
@@ -510,8 +509,6 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
510 ct->timeout = 10; 509 ct->timeout = 10;
511 ct->req = &gpn_ft->sg_req; 510 ct->req = &gpn_ft->sg_req;
512 ct->resp = gpn_ft->sg_resp; 511 ct->resp = gpn_ft->sg_resp;
513 ct->req_count = 1;
514 ct->resp_count = ZFCP_GPN_FT_BUFFERS;
515 512
516 init_completion(&compl_rec.done); 513 init_completion(&compl_rec.done);
517 compl_rec.handler = NULL; 514 compl_rec.handler = NULL;
@@ -538,7 +535,7 @@ static void zfcp_validate_port(struct zfcp_port *port)
538 zfcp_port_dequeue(port); 535 zfcp_port_dequeue(port);
539} 536}
540 537
541static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) 538static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
542{ 539{
543 struct zfcp_send_ct *ct = &gpn_ft->ct; 540 struct zfcp_send_ct *ct = &gpn_ft->ct;
544 struct scatterlist *sg = gpn_ft->sg_resp; 541 struct scatterlist *sg = gpn_ft->sg_resp;
@@ -558,13 +555,17 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
558 return -EIO; 555 return -EIO;
559 } 556 }
560 557
561 if (hdr->max_res_size) 558 if (hdr->max_res_size) {
559 dev_warn(&adapter->ccw_device->dev,
560 "The name server reported %d words residual data\n",
561 hdr->max_res_size);
562 return -E2BIG; 562 return -E2BIG;
563 }
563 564
564 down(&zfcp_data.config_sema); 565 down(&zfcp_data.config_sema);
565 566
566 /* first entry is the header */ 567 /* first entry is the header */
567 for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) { 568 for (x = 1; x < max_entries && !last; x++) {
568 if (x % (ZFCP_GPN_FT_ENTRIES + 1)) 569 if (x % (ZFCP_GPN_FT_ENTRIES + 1))
569 acc++; 570 acc++;
570 else 571 else
@@ -609,6 +610,12 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
609{ 610{
610 int ret, i; 611 int ret, i;
611 struct zfcp_gpn_ft *gpn_ft; 612 struct zfcp_gpn_ft *gpn_ft;
613 int chain, max_entries, buf_num, max_bytes;
614
615 chain = adapter->adapter_features & FSF_FEATURE_ELS_CT_CHAINED_SBALS;
616 buf_num = chain ? ZFCP_GPN_FT_BUFFERS : 1;
617 max_entries = chain ? ZFCP_GPN_FT_MAX_ENTRIES : ZFCP_GPN_FT_ENTRIES;
618 max_bytes = chain ? ZFCP_GPN_FT_MAX_SIZE : ZFCP_CT_SIZE_ONE_PAGE;
612 619
613 if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) 620 if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT)
614 return 0; 621 return 0;
@@ -617,23 +624,23 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
617 if (ret) 624 if (ret)
618 return ret; 625 return ret;
619 626
620 gpn_ft = zfcp_alloc_sg_env(); 627 gpn_ft = zfcp_alloc_sg_env(buf_num);
621 if (!gpn_ft) { 628 if (!gpn_ft) {
622 ret = -ENOMEM; 629 ret = -ENOMEM;
623 goto out; 630 goto out;
624 } 631 }
625 632
626 for (i = 0; i < 3; i++) { 633 for (i = 0; i < 3; i++) {
627 ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter); 634 ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter, max_bytes);
628 if (!ret) { 635 if (!ret) {
629 ret = zfcp_scan_eval_gpn_ft(gpn_ft); 636 ret = zfcp_scan_eval_gpn_ft(gpn_ft, max_entries);
630 if (ret == -EAGAIN) 637 if (ret == -EAGAIN)
631 ssleep(1); 638 ssleep(1);
632 else 639 else
633 break; 640 break;
634 } 641 }
635 } 642 }
636 zfcp_free_sg_env(gpn_ft); 643 zfcp_free_sg_env(gpn_ft, buf_num);
637out: 644out:
638 zfcp_wka_port_put(&adapter->nsp); 645 zfcp_wka_port_put(&adapter->nsp);
639 return ret; 646 return ret;
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 17620ecda335..9bba56b16831 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1013,12 +1013,29 @@ skip_fsfstatus:
1013 send_ct->handler(send_ct->handler_data); 1013 send_ct->handler(send_ct->handler_data);
1014} 1014}
1015 1015
1016static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req, 1016static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
1017 struct scatterlist *sg_req, 1017 struct scatterlist *sg_req,
1018 struct scatterlist *sg_resp, int max_sbals) 1018 struct scatterlist *sg_resp,
1019 int max_sbals)
1019{ 1020{
1021 struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(req);
1022 u32 feat = req->adapter->adapter_features;
1020 int bytes; 1023 int bytes;
1021 1024
1025 if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
1026 if (sg_req->length > PAGE_SIZE || sg_resp->length > PAGE_SIZE ||
1027 !sg_is_last(sg_req) || !sg_is_last(sg_resp))
1028 return -EOPNOTSUPP;
1029
1030 sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
1031 sbale[2].addr = sg_virt(sg_req);
1032 sbale[2].length = sg_req->length;
1033 sbale[3].addr = sg_virt(sg_resp);
1034 sbale[3].length = sg_resp->length;
1035 sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
1036 return 0;
1037 }
1038
1022 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, 1039 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,
1023 sg_req, max_sbals); 1040 sg_req, max_sbals);
1024 if (bytes <= 0) 1041 if (bytes <= 0)
@@ -1060,8 +1077,8 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
1060 goto out; 1077 goto out;
1061 } 1078 }
1062 1079
1063 ret = zfcp_fsf_setup_sbals(req, ct->req, ct->resp, 1080 ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp,
1064 FSF_MAX_SBALS_PER_REQ); 1081 FSF_MAX_SBALS_PER_REQ);
1065 if (ret) 1082 if (ret)
1066 goto failed_send; 1083 goto failed_send;
1067 1084
@@ -1171,7 +1188,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
1171 goto out; 1188 goto out;
1172 } 1189 }
1173 1190
1174 ret = zfcp_fsf_setup_sbals(req, els->req, els->resp, 2); 1191 ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2);
1175 1192
1176 if (ret) 1193 if (ret)
1177 goto failed_send; 1194 goto failed_send;
@@ -1440,7 +1457,8 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1440 * Alternately, an ADISC/PDISC ELS should suffice, as well. 1457 * Alternately, an ADISC/PDISC ELS should suffice, as well.
1441 */ 1458 */
1442 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; 1459 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
1443 if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { 1460 if (req->qtcb->bottom.support.els1_length >=
1461 FSF_PLOGI_MIN_LEN) {
1444 if (plogi->serv_param.wwpn != port->wwpn) 1462 if (plogi->serv_param.wwpn != port->wwpn)
1445 port->d_id = 0; 1463 port->d_id = 0;
1446 else { 1464 else {
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index fa2a31780611..8bb200252347 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -164,6 +164,7 @@
164#define FSF_FEATURE_LUN_SHARING 0x00000004 164#define FSF_FEATURE_LUN_SHARING 0x00000004
165#define FSF_FEATURE_NOTIFICATION_LOST 0x00000008 165#define FSF_FEATURE_NOTIFICATION_LOST 0x00000008
166#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010 166#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
167#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
167#define FSF_FEATURE_UPDATE_ALERT 0x00000100 168#define FSF_FEATURE_UPDATE_ALERT 0x00000100
168#define FSF_FEATURE_MEASUREMENT_DATA 0x00000200 169#define FSF_FEATURE_MEASUREMENT_DATA 0x00000200
169 170
@@ -322,6 +323,7 @@ struct fsf_nport_serv_param {
322 u8 vendor_version_level[16]; 323 u8 vendor_version_level[16];
323} __attribute__ ((packed)); 324} __attribute__ ((packed));
324 325
326#define FSF_PLOGI_MIN_LEN 112
325struct fsf_plogi { 327struct fsf_plogi {
326 u32 code; 328 u32 code;
327 struct fsf_nport_serv_param serv_param; 329 struct fsf_nport_serv_param serv_param;