aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r--drivers/s390/scsi/zfcp_fc.c333
1 files changed, 214 insertions, 119 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 30cf91a787a3..297e6b71ce9c 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -11,11 +11,14 @@
11 11
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/utsname.h>
14#include <scsi/fc/fc_els.h> 15#include <scsi/fc/fc_els.h>
15#include <scsi/libfc.h> 16#include <scsi/libfc.h>
16#include "zfcp_ext.h" 17#include "zfcp_ext.h"
17#include "zfcp_fc.h" 18#include "zfcp_fc.h"
18 19
20struct kmem_cache *zfcp_fc_req_cache;
21
19static u32 zfcp_fc_rscn_range_mask[] = { 22static u32 zfcp_fc_rscn_range_mask[] = {
20 [ELS_ADDR_FMT_PORT] = 0xFFFFFF, 23 [ELS_ADDR_FMT_PORT] = 0xFFFFFF,
21 [ELS_ADDR_FMT_AREA] = 0xFFFF00, 24 [ELS_ADDR_FMT_AREA] = 0xFFFF00,
@@ -260,24 +263,18 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
260 zfcp_fc_incoming_rscn(fsf_req); 263 zfcp_fc_incoming_rscn(fsf_req);
261} 264}
262 265
263static void zfcp_fc_ns_gid_pn_eval(void *data) 266static void zfcp_fc_ns_gid_pn_eval(struct zfcp_fc_req *fc_req)
264{ 267{
265 struct zfcp_fc_gid_pn *gid_pn = data; 268 struct zfcp_fsf_ct_els *ct_els = &fc_req->ct_els;
266 struct zfcp_fsf_ct_els *ct = &gid_pn->ct; 269 struct zfcp_fc_gid_pn_rsp *gid_pn_rsp = &fc_req->u.gid_pn.rsp;
267 struct zfcp_fc_gid_pn_req *gid_pn_req = sg_virt(ct->req);
268 struct zfcp_fc_gid_pn_resp *gid_pn_resp = sg_virt(ct->resp);
269 struct zfcp_port *port = gid_pn->port;
270 270
271 if (ct->status) 271 if (ct_els->status)
272 return; 272 return;
273 if (gid_pn_resp->ct_hdr.ct_cmd != FC_FS_ACC) 273 if (gid_pn_rsp->ct_hdr.ct_cmd != FC_FS_ACC)
274 return; 274 return;
275 275
276 /* paranoia */
277 if (gid_pn_req->gid_pn.fn_wwpn != port->wwpn)
278 return;
279 /* looks like a valid d_id */ 276 /* looks like a valid d_id */
280 port->d_id = ntoh24(gid_pn_resp->gid_pn.fp_fid); 277 ct_els->port->d_id = ntoh24(gid_pn_rsp->gid_pn.fp_fid);
281} 278}
282 279
283static void zfcp_fc_complete(void *data) 280static void zfcp_fc_complete(void *data)
@@ -285,69 +282,73 @@ static void zfcp_fc_complete(void *data)
285 complete(data); 282 complete(data);
286} 283}
287 284
285static void zfcp_fc_ct_ns_init(struct fc_ct_hdr *ct_hdr, u16 cmd, u16 mr_size)
286{
287 ct_hdr->ct_rev = FC_CT_REV;
288 ct_hdr->ct_fs_type = FC_FST_DIR;
289 ct_hdr->ct_fs_subtype = FC_NS_SUBTYPE;
290 ct_hdr->ct_cmd = cmd;
291 ct_hdr->ct_mr_size = mr_size / 4;
292}
293
288static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, 294static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port,
289 struct zfcp_fc_gid_pn *gid_pn) 295 struct zfcp_fc_req *fc_req)
290{ 296{
291 struct zfcp_adapter *adapter = port->adapter; 297 struct zfcp_adapter *adapter = port->adapter;
292 DECLARE_COMPLETION_ONSTACK(completion); 298 DECLARE_COMPLETION_ONSTACK(completion);
299 struct zfcp_fc_gid_pn_req *gid_pn_req = &fc_req->u.gid_pn.req;
300 struct zfcp_fc_gid_pn_rsp *gid_pn_rsp = &fc_req->u.gid_pn.rsp;
293 int ret; 301 int ret;
294 302
295 /* setup parameters for send generic command */ 303 /* setup parameters for send generic command */
296 gid_pn->port = port; 304 fc_req->ct_els.port = port;
297 gid_pn->ct.handler = zfcp_fc_complete; 305 fc_req->ct_els.handler = zfcp_fc_complete;
298 gid_pn->ct.handler_data = &completion; 306 fc_req->ct_els.handler_data = &completion;
299 gid_pn->ct.req = &gid_pn->sg_req; 307 fc_req->ct_els.req = &fc_req->sg_req;
300 gid_pn->ct.resp = &gid_pn->sg_resp; 308 fc_req->ct_els.resp = &fc_req->sg_rsp;
301 sg_init_one(&gid_pn->sg_req, &gid_pn->gid_pn_req, 309 sg_init_one(&fc_req->sg_req, gid_pn_req, sizeof(*gid_pn_req));
302 sizeof(struct zfcp_fc_gid_pn_req)); 310 sg_init_one(&fc_req->sg_rsp, gid_pn_rsp, sizeof(*gid_pn_rsp));
303 sg_init_one(&gid_pn->sg_resp, &gid_pn->gid_pn_resp, 311
304 sizeof(struct zfcp_fc_gid_pn_resp)); 312 zfcp_fc_ct_ns_init(&gid_pn_req->ct_hdr,
305 313 FC_NS_GID_PN, ZFCP_FC_CT_SIZE_PAGE);
306 /* setup nameserver request */ 314 gid_pn_req->gid_pn.fn_wwpn = port->wwpn;
307 gid_pn->gid_pn_req.ct_hdr.ct_rev = FC_CT_REV; 315
308 gid_pn->gid_pn_req.ct_hdr.ct_fs_type = FC_FST_DIR; 316 ret = zfcp_fsf_send_ct(&adapter->gs->ds, &fc_req->ct_els,
309 gid_pn->gid_pn_req.ct_hdr.ct_fs_subtype = FC_NS_SUBTYPE;
310 gid_pn->gid_pn_req.ct_hdr.ct_options = 0;
311 gid_pn->gid_pn_req.ct_hdr.ct_cmd = FC_NS_GID_PN;
312 gid_pn->gid_pn_req.ct_hdr.ct_mr_size = ZFCP_FC_CT_SIZE_PAGE / 4;
313 gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn;
314
315 ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct,
316 adapter->pool.gid_pn_req, 317 adapter->pool.gid_pn_req,
317 ZFCP_FC_CTELS_TMO); 318 ZFCP_FC_CTELS_TMO);
318 if (!ret) { 319 if (!ret) {
319 wait_for_completion(&completion); 320 wait_for_completion(&completion);
320 zfcp_fc_ns_gid_pn_eval(gid_pn); 321 zfcp_fc_ns_gid_pn_eval(fc_req);
321 } 322 }
322 return ret; 323 return ret;
323} 324}
324 325
325/** 326/**
326 * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request 327 * zfcp_fc_ns_gid_pn - initiate GID_PN nameserver request
327 * @port: port where GID_PN request is needed 328 * @port: port where GID_PN request is needed
328 * return: -ENOMEM on error, 0 otherwise 329 * return: -ENOMEM on error, 0 otherwise
329 */ 330 */
330static int zfcp_fc_ns_gid_pn(struct zfcp_port *port) 331static int zfcp_fc_ns_gid_pn(struct zfcp_port *port)
331{ 332{
332 int ret; 333 int ret;
333 struct zfcp_fc_gid_pn *gid_pn; 334 struct zfcp_fc_req *fc_req;
334 struct zfcp_adapter *adapter = port->adapter; 335 struct zfcp_adapter *adapter = port->adapter;
335 336
336 gid_pn = mempool_alloc(adapter->pool.gid_pn, GFP_ATOMIC); 337 fc_req = mempool_alloc(adapter->pool.gid_pn, GFP_ATOMIC);
337 if (!gid_pn) 338 if (!fc_req)
338 return -ENOMEM; 339 return -ENOMEM;
339 340
340 memset(gid_pn, 0, sizeof(*gid_pn)); 341 memset(fc_req, 0, sizeof(*fc_req));
341 342
342 ret = zfcp_fc_wka_port_get(&adapter->gs->ds); 343 ret = zfcp_fc_wka_port_get(&adapter->gs->ds);
343 if (ret) 344 if (ret)
344 goto out; 345 goto out;
345 346
346 ret = zfcp_fc_ns_gid_pn_request(port, gid_pn); 347 ret = zfcp_fc_ns_gid_pn_request(port, fc_req);
347 348
348 zfcp_fc_wka_port_put(&adapter->gs->ds); 349 zfcp_fc_wka_port_put(&adapter->gs->ds);
349out: 350out:
350 mempool_free(gid_pn, adapter->pool.gid_pn); 351 mempool_free(fc_req, adapter->pool.gid_pn);
351 return ret; 352 return ret;
352} 353}
353 354
@@ -419,11 +420,11 @@ void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fc_els_flogi *plogi)
419 420
420static void zfcp_fc_adisc_handler(void *data) 421static void zfcp_fc_adisc_handler(void *data)
421{ 422{
422 struct zfcp_fc_els_adisc *adisc = data; 423 struct zfcp_fc_req *fc_req = data;
423 struct zfcp_port *port = adisc->els.port; 424 struct zfcp_port *port = fc_req->ct_els.port;
424 struct fc_els_adisc *adisc_resp = &adisc->adisc_resp; 425 struct fc_els_adisc *adisc_resp = &fc_req->u.adisc.rsp;
425 426
426 if (adisc->els.status) { 427 if (fc_req->ct_els.status) {
427 /* request rejected or timed out */ 428 /* request rejected or timed out */
428 zfcp_erp_port_forced_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, 429 zfcp_erp_port_forced_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
429 "fcadh_1"); 430 "fcadh_1");
@@ -445,42 +446,42 @@ static void zfcp_fc_adisc_handler(void *data)
445 out: 446 out:
446 atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); 447 atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
447 put_device(&port->dev); 448 put_device(&port->dev);
448 kmem_cache_free(zfcp_data.adisc_cache, adisc); 449 kmem_cache_free(zfcp_fc_req_cache, fc_req);
449} 450}
450 451
451static int zfcp_fc_adisc(struct zfcp_port *port) 452static int zfcp_fc_adisc(struct zfcp_port *port)
452{ 453{
453 struct zfcp_fc_els_adisc *adisc; 454 struct zfcp_fc_req *fc_req;
454 struct zfcp_adapter *adapter = port->adapter; 455 struct zfcp_adapter *adapter = port->adapter;
456 struct Scsi_Host *shost = adapter->scsi_host;
455 int ret; 457 int ret;
456 458
457 adisc = kmem_cache_zalloc(zfcp_data.adisc_cache, GFP_ATOMIC); 459 fc_req = kmem_cache_zalloc(zfcp_fc_req_cache, GFP_ATOMIC);
458 if (!adisc) 460 if (!fc_req)
459 return -ENOMEM; 461 return -ENOMEM;
460 462
461 adisc->els.port = port; 463 fc_req->ct_els.port = port;
462 adisc->els.req = &adisc->req; 464 fc_req->ct_els.req = &fc_req->sg_req;
463 adisc->els.resp = &adisc->resp; 465 fc_req->ct_els.resp = &fc_req->sg_rsp;
464 sg_init_one(adisc->els.req, &adisc->adisc_req, 466 sg_init_one(&fc_req->sg_req, &fc_req->u.adisc.req,
465 sizeof(struct fc_els_adisc)); 467 sizeof(struct fc_els_adisc));
466 sg_init_one(adisc->els.resp, &adisc->adisc_resp, 468 sg_init_one(&fc_req->sg_rsp, &fc_req->u.adisc.rsp,
467 sizeof(struct fc_els_adisc)); 469 sizeof(struct fc_els_adisc));
468 470
469 adisc->els.handler = zfcp_fc_adisc_handler; 471 fc_req->ct_els.handler = zfcp_fc_adisc_handler;
470 adisc->els.handler_data = adisc; 472 fc_req->ct_els.handler_data = fc_req;
471 473
472 /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports 474 /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
473 without FC-AL-2 capability, so we don't set it */ 475 without FC-AL-2 capability, so we don't set it */
474 adisc->adisc_req.adisc_wwpn = fc_host_port_name(adapter->scsi_host); 476 fc_req->u.adisc.req.adisc_wwpn = fc_host_port_name(shost);
475 adisc->adisc_req.adisc_wwnn = fc_host_node_name(adapter->scsi_host); 477 fc_req->u.adisc.req.adisc_wwnn = fc_host_node_name(shost);
476 adisc->adisc_req.adisc_cmd = ELS_ADISC; 478 fc_req->u.adisc.req.adisc_cmd = ELS_ADISC;
477 hton24(adisc->adisc_req.adisc_port_id, 479 hton24(fc_req->u.adisc.req.adisc_port_id, fc_host_port_id(shost));
478 fc_host_port_id(adapter->scsi_host));
479 480
480 ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els, 481 ret = zfcp_fsf_send_els(adapter, port->d_id, &fc_req->ct_els,
481 ZFCP_FC_CTELS_TMO); 482 ZFCP_FC_CTELS_TMO);
482 if (ret) 483 if (ret)
483 kmem_cache_free(zfcp_data.adisc_cache, adisc); 484 kmem_cache_free(zfcp_fc_req_cache, fc_req);
484 485
485 return ret; 486 return ret;
486} 487}
@@ -528,68 +529,42 @@ void zfcp_fc_test_link(struct zfcp_port *port)
528 put_device(&port->dev); 529 put_device(&port->dev);
529} 530}
530 531
531static void zfcp_free_sg_env(struct zfcp_fc_gpn_ft *gpn_ft, int buf_num) 532static struct zfcp_fc_req *zfcp_alloc_sg_env(int buf_num)
532{ 533{
533 struct scatterlist *sg = &gpn_ft->sg_req; 534 struct zfcp_fc_req *fc_req;
534
535 kmem_cache_free(zfcp_data.gpn_ft_cache, sg_virt(sg));
536 zfcp_sg_free_table(gpn_ft->sg_resp, buf_num);
537
538 kfree(gpn_ft);
539}
540 535
541static struct zfcp_fc_gpn_ft *zfcp_alloc_sg_env(int buf_num) 536 fc_req = kmem_cache_zalloc(zfcp_fc_req_cache, GFP_KERNEL);
542{ 537 if (!fc_req)
543 struct zfcp_fc_gpn_ft *gpn_ft;
544 struct zfcp_fc_gpn_ft_req *req;
545
546 gpn_ft = kzalloc(sizeof(*gpn_ft), GFP_KERNEL);
547 if (!gpn_ft)
548 return NULL; 538 return NULL;
549 539
550 req = kmem_cache_zalloc(zfcp_data.gpn_ft_cache, GFP_KERNEL); 540 if (zfcp_sg_setup_table(&fc_req->sg_rsp, buf_num)) {
551 if (!req) { 541 kmem_cache_free(zfcp_fc_req_cache, fc_req);
552 kfree(gpn_ft); 542 return NULL;
553 gpn_ft = NULL;
554 goto out;
555 } 543 }
556 sg_init_one(&gpn_ft->sg_req, req, sizeof(*req));
557 544
558 if (zfcp_sg_setup_table(gpn_ft->sg_resp, buf_num)) { 545 sg_init_one(&fc_req->sg_req, &fc_req->u.gpn_ft.req,
559 zfcp_free_sg_env(gpn_ft, buf_num); 546 sizeof(struct zfcp_fc_gpn_ft_req));
560 gpn_ft = NULL;
561 }
562out:
563 return gpn_ft;
564}
565 547
548 return fc_req;
549}
566 550
567static int zfcp_fc_send_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft, 551static int zfcp_fc_send_gpn_ft(struct zfcp_fc_req *fc_req,
568 struct zfcp_adapter *adapter, int max_bytes) 552 struct zfcp_adapter *adapter, int max_bytes)
569{ 553{
570 struct zfcp_fsf_ct_els *ct = &gpn_ft->ct; 554 struct zfcp_fsf_ct_els *ct_els = &fc_req->ct_els;
571 struct zfcp_fc_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); 555 struct zfcp_fc_gpn_ft_req *req = &fc_req->u.gpn_ft.req;
572 DECLARE_COMPLETION_ONSTACK(completion); 556 DECLARE_COMPLETION_ONSTACK(completion);
573 int ret; 557 int ret;
574 558
575 /* prepare CT IU for GPN_FT */ 559 zfcp_fc_ct_ns_init(&req->ct_hdr, FC_NS_GPN_FT, max_bytes);
576 req->ct_hdr.ct_rev = FC_CT_REV;
577 req->ct_hdr.ct_fs_type = FC_FST_DIR;
578 req->ct_hdr.ct_fs_subtype = FC_NS_SUBTYPE;
579 req->ct_hdr.ct_options = 0;
580 req->ct_hdr.ct_cmd = FC_NS_GPN_FT;
581 req->ct_hdr.ct_mr_size = max_bytes / 4;
582 req->gpn_ft.fn_domain_id_scope = 0;
583 req->gpn_ft.fn_area_id_scope = 0;
584 req->gpn_ft.fn_fc4_type = FC_TYPE_FCP; 560 req->gpn_ft.fn_fc4_type = FC_TYPE_FCP;
585 561
586 /* prepare zfcp_send_ct */ 562 ct_els->handler = zfcp_fc_complete;
587 ct->handler = zfcp_fc_complete; 563 ct_els->handler_data = &completion;
588 ct->handler_data = &completion; 564 ct_els->req = &fc_req->sg_req;
589 ct->req = &gpn_ft->sg_req; 565 ct_els->resp = &fc_req->sg_rsp;
590 ct->resp = gpn_ft->sg_resp;
591 566
592 ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL, 567 ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct_els, NULL,
593 ZFCP_FC_CTELS_TMO); 568 ZFCP_FC_CTELS_TMO);
594 if (!ret) 569 if (!ret)
595 wait_for_completion(&completion); 570 wait_for_completion(&completion);
@@ -610,11 +585,11 @@ static void zfcp_fc_validate_port(struct zfcp_port *port, struct list_head *lh)
610 list_move_tail(&port->list, lh); 585 list_move_tail(&port->list, lh);
611} 586}
612 587
613static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft, 588static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_req *fc_req,
614 struct zfcp_adapter *adapter, int max_entries) 589 struct zfcp_adapter *adapter, int max_entries)
615{ 590{
616 struct zfcp_fsf_ct_els *ct = &gpn_ft->ct; 591 struct zfcp_fsf_ct_els *ct_els = &fc_req->ct_els;
617 struct scatterlist *sg = gpn_ft->sg_resp; 592 struct scatterlist *sg = &fc_req->sg_rsp;
618 struct fc_ct_hdr *hdr = sg_virt(sg); 593 struct fc_ct_hdr *hdr = sg_virt(sg);
619 struct fc_gpn_ft_resp *acc = sg_virt(sg); 594 struct fc_gpn_ft_resp *acc = sg_virt(sg);
620 struct zfcp_port *port, *tmp; 595 struct zfcp_port *port, *tmp;
@@ -623,7 +598,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
623 u32 d_id; 598 u32 d_id;
624 int ret = 0, x, last = 0; 599 int ret = 0, x, last = 0;
625 600
626 if (ct->status) 601 if (ct_els->status)
627 return -EIO; 602 return -EIO;
628 603
629 if (hdr->ct_cmd != FC_FS_ACC) { 604 if (hdr->ct_cmd != FC_FS_ACC) {
@@ -687,7 +662,7 @@ void zfcp_fc_scan_ports(struct work_struct *work)
687 struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter, 662 struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter,
688 scan_work); 663 scan_work);
689 int ret, i; 664 int ret, i;
690 struct zfcp_fc_gpn_ft *gpn_ft; 665 struct zfcp_fc_req *fc_req;
691 int chain, max_entries, buf_num, max_bytes; 666 int chain, max_entries, buf_num, max_bytes;
692 667
693 chain = adapter->adapter_features & FSF_FEATURE_ELS_CT_CHAINED_SBALS; 668 chain = adapter->adapter_features & FSF_FEATURE_ELS_CT_CHAINED_SBALS;
@@ -702,25 +677,145 @@ void zfcp_fc_scan_ports(struct work_struct *work)
702 if (zfcp_fc_wka_port_get(&adapter->gs->ds)) 677 if (zfcp_fc_wka_port_get(&adapter->gs->ds))
703 return; 678 return;
704 679
705 gpn_ft = zfcp_alloc_sg_env(buf_num); 680 fc_req = zfcp_alloc_sg_env(buf_num);
706 if (!gpn_ft) 681 if (!fc_req)
707 goto out; 682 goto out;
708 683
709 for (i = 0; i < 3; i++) { 684 for (i = 0; i < 3; i++) {
710 ret = zfcp_fc_send_gpn_ft(gpn_ft, adapter, max_bytes); 685 ret = zfcp_fc_send_gpn_ft(fc_req, adapter, max_bytes);
711 if (!ret) { 686 if (!ret) {
712 ret = zfcp_fc_eval_gpn_ft(gpn_ft, adapter, max_entries); 687 ret = zfcp_fc_eval_gpn_ft(fc_req, adapter, max_entries);
713 if (ret == -EAGAIN) 688 if (ret == -EAGAIN)
714 ssleep(1); 689 ssleep(1);
715 else 690 else
716 break; 691 break;
717 } 692 }
718 } 693 }
719 zfcp_free_sg_env(gpn_ft, buf_num); 694 zfcp_sg_free_table(&fc_req->sg_rsp, buf_num);
695 kmem_cache_free(zfcp_fc_req_cache, fc_req);
720out: 696out:
721 zfcp_fc_wka_port_put(&adapter->gs->ds); 697 zfcp_fc_wka_port_put(&adapter->gs->ds);
722} 698}
723 699
700static int zfcp_fc_gspn(struct zfcp_adapter *adapter,
701 struct zfcp_fc_req *fc_req)
702{
703 DECLARE_COMPLETION_ONSTACK(completion);
704 char devno[] = "DEVNO:";
705 struct zfcp_fsf_ct_els *ct_els = &fc_req->ct_els;
706 struct zfcp_fc_gspn_req *gspn_req = &fc_req->u.gspn.req;
707 struct zfcp_fc_gspn_rsp *gspn_rsp = &fc_req->u.gspn.rsp;
708 int ret;
709
710 zfcp_fc_ct_ns_init(&gspn_req->ct_hdr, FC_NS_GSPN_ID,
711 FC_SYMBOLIC_NAME_SIZE);
712 hton24(gspn_req->gspn.fp_fid, fc_host_port_id(adapter->scsi_host));
713
714 sg_init_one(&fc_req->sg_req, gspn_req, sizeof(*gspn_req));
715 sg_init_one(&fc_req->sg_rsp, gspn_rsp, sizeof(*gspn_rsp));
716
717 ct_els->handler = zfcp_fc_complete;
718 ct_els->handler_data = &completion;
719 ct_els->req = &fc_req->sg_req;
720 ct_els->resp = &fc_req->sg_rsp;
721
722 ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct_els, NULL,
723 ZFCP_FC_CTELS_TMO);
724 if (ret)
725 return ret;
726
727 wait_for_completion(&completion);
728 if (ct_els->status)
729 return ct_els->status;
730
731 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_NPIV &&
732 !(strstr(gspn_rsp->gspn.fp_name, devno)))
733 snprintf(fc_host_symbolic_name(adapter->scsi_host),
734 FC_SYMBOLIC_NAME_SIZE, "%s%s %s NAME: %s",
735 gspn_rsp->gspn.fp_name, devno,
736 dev_name(&adapter->ccw_device->dev),
737 init_utsname()->nodename);
738 else
739 strlcpy(fc_host_symbolic_name(adapter->scsi_host),
740 gspn_rsp->gspn.fp_name, FC_SYMBOLIC_NAME_SIZE);
741
742 return 0;
743}
744
745static void zfcp_fc_rspn(struct zfcp_adapter *adapter,
746 struct zfcp_fc_req *fc_req)
747{
748 DECLARE_COMPLETION_ONSTACK(completion);
749 struct Scsi_Host *shost = adapter->scsi_host;
750 struct zfcp_fsf_ct_els *ct_els = &fc_req->ct_els;
751 struct zfcp_fc_rspn_req *rspn_req = &fc_req->u.rspn.req;
752 struct fc_ct_hdr *rspn_rsp = &fc_req->u.rspn.rsp;
753 int ret, len;
754
755 zfcp_fc_ct_ns_init(&rspn_req->ct_hdr, FC_NS_RSPN_ID,
756 FC_SYMBOLIC_NAME_SIZE);
757 hton24(rspn_req->rspn.fr_fid.fp_fid, fc_host_port_id(shost));
758 len = strlcpy(rspn_req->rspn.fr_name, fc_host_symbolic_name(shost),
759 FC_SYMBOLIC_NAME_SIZE);
760 rspn_req->rspn.fr_name_len = len;
761
762 sg_init_one(&fc_req->sg_req, rspn_req, sizeof(*rspn_req));
763 sg_init_one(&fc_req->sg_rsp, rspn_rsp, sizeof(*rspn_rsp));
764
765 ct_els->handler = zfcp_fc_complete;
766 ct_els->handler_data = &completion;
767 ct_els->req = &fc_req->sg_req;
768 ct_els->resp = &fc_req->sg_rsp;
769
770 ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct_els, NULL,
771 ZFCP_FC_CTELS_TMO);
772 if (!ret)
773 wait_for_completion(&completion);
774}
775
776/**
777 * zfcp_fc_sym_name_update - Retrieve and update the symbolic port name
778 * @work: ns_up_work of the adapter where to update the symbolic port name
779 *
780 * Retrieve the current symbolic port name that may have been set by
781 * the hardware using the GSPN request and update the fc_host
782 * symbolic_name sysfs attribute. When running in NPIV mode (and hence
783 * the port name is unique for this system), update the symbolic port
784 * name to add Linux specific information and update the FC nameserver
785 * using the RSPN request.
786 */
787void zfcp_fc_sym_name_update(struct work_struct *work)
788{
789 struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter,
790 ns_up_work);
791 int ret;
792 struct zfcp_fc_req *fc_req;
793
794 if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT &&
795 fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
796 return;
797
798 fc_req = kmem_cache_zalloc(zfcp_fc_req_cache, GFP_KERNEL);
799 if (!fc_req)
800 return;
801
802 ret = zfcp_fc_wka_port_get(&adapter->gs->ds);
803 if (ret)
804 goto out_free;
805
806 ret = zfcp_fc_gspn(adapter, fc_req);
807 if (ret || fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
808 goto out_ds_put;
809
810 memset(fc_req, 0, sizeof(*fc_req));
811 zfcp_fc_rspn(adapter, fc_req);
812
813out_ds_put:
814 zfcp_fc_wka_port_put(&adapter->gs->ds);
815out_free:
816 kmem_cache_free(zfcp_fc_req_cache, fc_req);
817}
818
724static void zfcp_fc_ct_els_job_handler(void *data) 819static void zfcp_fc_ct_els_job_handler(void *data)
725{ 820{
726 struct fc_bsg_job *job = data; 821 struct fc_bsg_job *job = data;