diff options
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 65 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 14 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 31 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 149 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 7 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 215 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 137 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 19 |
8 files changed, 362 insertions, 275 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index ee13a455c823..181f88bb53b3 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -450,19 +450,6 @@ static void _zfcp_status_read_scheduler(struct work_struct *work) | |||
450 | stat_work)); | 450 | stat_work)); |
451 | } | 451 | } |
452 | 452 | ||
453 | static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) | ||
454 | { | ||
455 | struct zfcp_port *port; | ||
456 | |||
457 | port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, | ||
458 | ZFCP_DID_DIRECTORY_SERVICE); | ||
459 | if (IS_ERR(port)) | ||
460 | return PTR_ERR(port); | ||
461 | zfcp_port_put(port); | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | /** | 453 | /** |
467 | * zfcp_adapter_enqueue - enqueue a new adapter to the list | 454 | * zfcp_adapter_enqueue - enqueue a new adapter to the list |
468 | * @ccw_device: pointer to the struct cc_device | 455 | * @ccw_device: pointer to the struct cc_device |
@@ -552,7 +539,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
552 | 539 | ||
553 | zfcp_data.adapters++; | 540 | zfcp_data.adapters++; |
554 | 541 | ||
555 | zfcp_nameserver_enqueue(adapter); | 542 | zfcp_fc_nameserver_init(adapter); |
556 | 543 | ||
557 | return 0; | 544 | return 0; |
558 | 545 | ||
@@ -638,7 +625,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
638 | { | 625 | { |
639 | struct zfcp_port *port; | 626 | struct zfcp_port *port; |
640 | int retval; | 627 | int retval; |
641 | char *bus_id; | ||
642 | 628 | ||
643 | port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); | 629 | port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); |
644 | if (!port) | 630 | if (!port) |
@@ -648,6 +634,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
648 | 634 | ||
649 | INIT_LIST_HEAD(&port->unit_list_head); | 635 | INIT_LIST_HEAD(&port->unit_list_head); |
650 | INIT_LIST_HEAD(&port->unit_remove_lh); | 636 | INIT_LIST_HEAD(&port->unit_remove_lh); |
637 | INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup); | ||
651 | 638 | ||
652 | port->adapter = adapter; | 639 | port->adapter = adapter; |
653 | port->d_id = d_id; | 640 | port->d_id = d_id; |
@@ -657,34 +644,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
657 | atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); | 644 | atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); |
658 | atomic_set(&port->refcount, 0); | 645 | atomic_set(&port->refcount, 0); |
659 | 646 | ||
660 | if (status & ZFCP_STATUS_PORT_WKA) { | 647 | snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", wwpn); |
661 | switch (d_id) { | 648 | port->sysfs_device.parent = &adapter->ccw_device->dev; |
662 | case ZFCP_DID_DIRECTORY_SERVICE: | ||
663 | bus_id = "directory"; | ||
664 | break; | ||
665 | case ZFCP_DID_MANAGEMENT_SERVICE: | ||
666 | bus_id = "management"; | ||
667 | break; | ||
668 | case ZFCP_DID_KEY_DISTRIBUTION_SERVICE: | ||
669 | bus_id = "key_distribution"; | ||
670 | break; | ||
671 | case ZFCP_DID_ALIAS_SERVICE: | ||
672 | bus_id = "alias"; | ||
673 | break; | ||
674 | case ZFCP_DID_TIME_SERVICE: | ||
675 | bus_id = "time"; | ||
676 | break; | ||
677 | default: | ||
678 | kfree(port); | ||
679 | return ERR_PTR(-EINVAL); | ||
680 | } | ||
681 | snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "%s", bus_id); | ||
682 | port->sysfs_device.parent = &adapter->generic_services; | ||
683 | } else { | ||
684 | snprintf(port->sysfs_device.bus_id, | ||
685 | BUS_ID_SIZE, "0x%016llx", wwpn); | ||
686 | port->sysfs_device.parent = &adapter->ccw_device->dev; | ||
687 | } | ||
688 | 649 | ||
689 | port->sysfs_device.release = zfcp_sysfs_port_release; | 650 | port->sysfs_device.release = zfcp_sysfs_port_release; |
690 | dev_set_drvdata(&port->sysfs_device, port); | 651 | dev_set_drvdata(&port->sysfs_device, port); |
@@ -700,12 +661,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
700 | if (device_register(&port->sysfs_device)) | 661 | if (device_register(&port->sysfs_device)) |
701 | goto err_out_free; | 662 | goto err_out_free; |
702 | 663 | ||
703 | if (status & ZFCP_STATUS_PORT_WKA) | 664 | retval = sysfs_create_group(&port->sysfs_device.kobj, |
704 | retval = sysfs_create_group(&port->sysfs_device.kobj, | 665 | &zfcp_sysfs_port_attrs); |
705 | &zfcp_sysfs_ns_port_attrs); | ||
706 | else | ||
707 | retval = sysfs_create_group(&port->sysfs_device.kobj, | ||
708 | &zfcp_sysfs_port_attrs); | ||
709 | 666 | ||
710 | if (retval) { | 667 | if (retval) { |
711 | device_unregister(&port->sysfs_device); | 668 | device_unregister(&port->sysfs_device); |
@@ -718,9 +675,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
718 | list_add_tail(&port->list, &adapter->port_list_head); | 675 | list_add_tail(&port->list, &adapter->port_list_head); |
719 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); | 676 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); |
720 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); | 677 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); |
721 | if (d_id == ZFCP_DID_DIRECTORY_SERVICE) | ||
722 | if (!adapter->nameserver_port) | ||
723 | adapter->nameserver_port = port; | ||
724 | adapter->ports++; | 678 | adapter->ports++; |
725 | 679 | ||
726 | write_unlock_irq(&zfcp_data.config_lock); | 680 | write_unlock_irq(&zfcp_data.config_lock); |
@@ -749,12 +703,7 @@ void zfcp_port_dequeue(struct zfcp_port *port) | |||
749 | fc_remote_port_delete(port->rport); | 703 | fc_remote_port_delete(port->rport); |
750 | port->rport = NULL; | 704 | port->rport = NULL; |
751 | zfcp_adapter_put(port->adapter); | 705 | zfcp_adapter_put(port->adapter); |
752 | if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA) | 706 | sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs); |
753 | sysfs_remove_group(&port->sysfs_device.kobj, | ||
754 | &zfcp_sysfs_ns_port_attrs); | ||
755 | else | ||
756 | sysfs_remove_group(&port->sysfs_device.kobj, | ||
757 | &zfcp_sysfs_port_attrs); | ||
758 | device_unregister(&port->sysfs_device); | 707 | device_unregister(&port->sysfs_device); |
759 | } | 708 | } |
760 | 709 | ||
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index d088d30516f9..c1f69f611e69 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -519,7 +519,7 @@ static const char *zfcp_rec_dbf_ids[] = { | |||
519 | [75] = "physical port recovery escalation after failed port " | 519 | [75] = "physical port recovery escalation after failed port " |
520 | "recovery", | 520 | "recovery", |
521 | [76] = "port recovery escalation after failed unit recovery", | 521 | [76] = "port recovery escalation after failed unit recovery", |
522 | [77] = "recovery opening nameserver port", | 522 | [77] = "", |
523 | [78] = "duplicate request id", | 523 | [78] = "duplicate request id", |
524 | [79] = "link down", | 524 | [79] = "link down", |
525 | [80] = "exclusive read-only unit access unsupported", | 525 | [80] = "exclusive read-only unit access unsupported", |
@@ -829,8 +829,8 @@ void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action) | |||
829 | void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | 829 | void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) |
830 | { | 830 | { |
831 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; | 831 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; |
832 | struct zfcp_port *port = ct->port; | 832 | struct zfcp_wka_port *wka_port = ct->wka_port; |
833 | struct zfcp_adapter *adapter = port->adapter; | 833 | struct zfcp_adapter *adapter = wka_port->adapter; |
834 | struct ct_hdr *hdr = sg_virt(ct->req); | 834 | struct ct_hdr *hdr = sg_virt(ct->req); |
835 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; | 835 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; |
836 | struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; | 836 | struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; |
@@ -842,7 +842,7 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | |||
842 | r->fsf_reqid = (unsigned long)fsf_req; | 842 | r->fsf_reqid = (unsigned long)fsf_req; |
843 | r->fsf_seqno = fsf_req->seq_no; | 843 | r->fsf_seqno = fsf_req->seq_no; |
844 | r->s_id = fc_host_port_id(adapter->scsi_host); | 844 | r->s_id = fc_host_port_id(adapter->scsi_host); |
845 | r->d_id = port->d_id; | 845 | r->d_id = wka_port->d_id; |
846 | oct->cmd_req_code = hdr->cmd_rsp_code; | 846 | oct->cmd_req_code = hdr->cmd_rsp_code; |
847 | oct->revision = hdr->revision; | 847 | oct->revision = hdr->revision; |
848 | oct->gs_type = hdr->gs_type; | 848 | oct->gs_type = hdr->gs_type; |
@@ -863,8 +863,8 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | |||
863 | void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) | 863 | void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) |
864 | { | 864 | { |
865 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; | 865 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; |
866 | struct zfcp_port *port = ct->port; | 866 | struct zfcp_wka_port *wka_port = ct->wka_port; |
867 | struct zfcp_adapter *adapter = port->adapter; | 867 | struct zfcp_adapter *adapter = wka_port->adapter; |
868 | struct ct_hdr *hdr = sg_virt(ct->resp); | 868 | struct ct_hdr *hdr = sg_virt(ct->resp); |
869 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; | 869 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; |
870 | struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; | 870 | struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; |
@@ -875,7 +875,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) | |||
875 | strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); | 875 | strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); |
876 | r->fsf_reqid = (unsigned long)fsf_req; | 876 | r->fsf_reqid = (unsigned long)fsf_req; |
877 | r->fsf_seqno = fsf_req->seq_no; | 877 | r->fsf_seqno = fsf_req->seq_no; |
878 | r->s_id = port->d_id; | 878 | r->s_id = wka_port->d_id; |
879 | r->d_id = fc_host_port_id(adapter->scsi_host); | 879 | r->d_id = fc_host_port_id(adapter->scsi_host); |
880 | rct->cmd_rsp_code = hdr->cmd_rsp_code; | 880 | rct->cmd_rsp_code = hdr->cmd_rsp_code; |
881 | rct->revision = hdr->revision; | 881 | rct->revision = hdr->revision; |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 699ecaf2e503..0d6a388882d4 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -253,6 +253,7 @@ struct zfcp_ls_adisc { | |||
253 | #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 | 253 | #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 |
254 | 254 | ||
255 | /* FC-PH/FC-GS well-known address identifiers for generic services */ | 255 | /* FC-PH/FC-GS well-known address identifiers for generic services */ |
256 | #define ZFCP_DID_WKA 0xFFFFF0 | ||
256 | #define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA | 257 | #define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA |
257 | #define ZFCP_DID_TIME_SERVICE 0xFFFFFB | 258 | #define ZFCP_DID_TIME_SERVICE 0xFFFFFB |
258 | #define ZFCP_DID_DIRECTORY_SERVICE 0xFFFFFC | 259 | #define ZFCP_DID_DIRECTORY_SERVICE 0xFFFFFC |
@@ -264,13 +265,15 @@ struct zfcp_ls_adisc { | |||
264 | #define ZFCP_STATUS_PORT_DID_DID 0x00000002 | 265 | #define ZFCP_STATUS_PORT_DID_DID 0x00000002 |
265 | #define ZFCP_STATUS_PORT_PHYS_CLOSING 0x00000004 | 266 | #define ZFCP_STATUS_PORT_PHYS_CLOSING 0x00000004 |
266 | #define ZFCP_STATUS_PORT_NO_WWPN 0x00000008 | 267 | #define ZFCP_STATUS_PORT_NO_WWPN 0x00000008 |
267 | #define ZFCP_STATUS_PORT_NO_SCSI_ID 0x00000010 | ||
268 | #define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020 | 268 | #define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020 |
269 | 269 | ||
270 | /* for ports with well known addresses */ | 270 | /* well known address (WKA) port status*/ |
271 | #define ZFCP_STATUS_PORT_WKA \ | 271 | enum zfcp_wka_status { |
272 | (ZFCP_STATUS_PORT_NO_WWPN | \ | 272 | ZFCP_WKA_PORT_OFFLINE, |
273 | ZFCP_STATUS_PORT_NO_SCSI_ID) | 273 | ZFCP_WKA_PORT_CLOSING, |
274 | ZFCP_WKA_PORT_OPENING, | ||
275 | ZFCP_WKA_PORT_ONLINE, | ||
276 | }; | ||
274 | 277 | ||
275 | /* logical unit status */ | 278 | /* logical unit status */ |
276 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 | 279 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 |
@@ -340,7 +343,7 @@ typedef void (*zfcp_send_ct_handler_t)(unsigned long); | |||
340 | 343 | ||
341 | /** | 344 | /** |
342 | * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct | 345 | * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct |
343 | * @port: port where the request is sent to | 346 | * @wka_port: port where the request is sent to |
344 | * @req: scatter-gather list for request | 347 | * @req: scatter-gather list for request |
345 | * @resp: scatter-gather list for response | 348 | * @resp: scatter-gather list for response |
346 | * @req_count: number of elements in request scatter-gather list | 349 | * @req_count: number of elements in request scatter-gather list |
@@ -352,7 +355,7 @@ typedef void (*zfcp_send_ct_handler_t)(unsigned long); | |||
352 | * @status: used to pass error status to calling function | 355 | * @status: used to pass error status to calling function |
353 | */ | 356 | */ |
354 | struct zfcp_send_ct { | 357 | struct zfcp_send_ct { |
355 | struct zfcp_port *port; | 358 | struct zfcp_wka_port *wka_port; |
356 | struct scatterlist *req; | 359 | struct scatterlist *req; |
357 | struct scatterlist *resp; | 360 | struct scatterlist *resp; |
358 | unsigned int req_count; | 361 | unsigned int req_count; |
@@ -406,6 +409,17 @@ struct zfcp_send_els { | |||
406 | int status; | 409 | int status; |
407 | }; | 410 | }; |
408 | 411 | ||
412 | struct zfcp_wka_port { | ||
413 | struct zfcp_adapter *adapter; | ||
414 | wait_queue_head_t completion_wq; | ||
415 | enum zfcp_wka_status status; | ||
416 | atomic_t refcount; | ||
417 | u32 d_id; | ||
418 | u32 handle; | ||
419 | struct mutex mutex; | ||
420 | struct delayed_work work; | ||
421 | }; | ||
422 | |||
409 | struct zfcp_qdio_queue { | 423 | struct zfcp_qdio_queue { |
410 | struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */ | 424 | struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */ |
411 | u8 first; /* index of next free bfr | 425 | u8 first; /* index of next free bfr |
@@ -496,7 +510,7 @@ struct zfcp_adapter { | |||
496 | actions */ | 510 | actions */ |
497 | u32 erp_low_mem_count; /* nr of erp actions waiting | 511 | u32 erp_low_mem_count; /* nr of erp actions waiting |
498 | for memory */ | 512 | for memory */ |
499 | struct zfcp_port *nameserver_port; /* adapter's nameserver */ | 513 | struct zfcp_wka_port nsp; /* adapter's nameserver */ |
500 | debug_info_t *rec_dbf; | 514 | debug_info_t *rec_dbf; |
501 | debug_info_t *hba_dbf; | 515 | debug_info_t *hba_dbf; |
502 | debug_info_t *san_dbf; /* debug feature areas */ | 516 | debug_info_t *san_dbf; /* debug feature areas */ |
@@ -540,6 +554,7 @@ struct zfcp_port { | |||
540 | atomic_t erp_counter; | 554 | atomic_t erp_counter; |
541 | u32 maxframe_size; | 555 | u32 maxframe_size; |
542 | u32 supported_classes; | 556 | u32 supported_classes; |
557 | struct work_struct gid_pn_work; | ||
543 | }; | 558 | }; |
544 | 559 | ||
545 | struct zfcp_unit { | 560 | struct zfcp_unit { |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index b18c6dd37294..e7d3bce51429 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -23,7 +23,6 @@ enum zfcp_erp_steps { | |||
23 | ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001, | 23 | ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001, |
24 | ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, | 24 | ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, |
25 | ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, | 25 | ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, |
26 | ZFCP_ERP_STEP_NAMESERVER_OPEN = 0x0200, | ||
27 | ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400, | 26 | ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400, |
28 | ZFCP_ERP_STEP_PORT_OPENING = 0x0800, | 27 | ZFCP_ERP_STEP_PORT_OPENING = 0x0800, |
29 | ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000, | 28 | ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000, |
@@ -532,8 +531,7 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, | |||
532 | struct zfcp_port *port; | 531 | struct zfcp_port *port; |
533 | 532 | ||
534 | list_for_each_entry(port, &adapter->port_list_head, list) | 533 | list_for_each_entry(port, &adapter->port_list_head, list) |
535 | if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)) | 534 | _zfcp_erp_port_reopen(port, clear, id, ref); |
536 | _zfcp_erp_port_reopen(port, clear, id, ref); | ||
537 | } | 535 | } |
538 | 536 | ||
539 | static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id, | 537 | static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id, |
@@ -777,7 +775,6 @@ static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act) | |||
777 | static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) | 775 | static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) |
778 | { | 776 | { |
779 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | | 777 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | |
780 | ZFCP_STATUS_PORT_DID_DID | | ||
781 | ZFCP_STATUS_PORT_PHYS_CLOSING | | 778 | ZFCP_STATUS_PORT_PHYS_CLOSING | |
782 | ZFCP_STATUS_PORT_INVALID_WWPN, | 779 | ZFCP_STATUS_PORT_INVALID_WWPN, |
783 | &port->status); | 780 | &port->status); |
@@ -830,62 +827,6 @@ static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) | |||
830 | return ZFCP_ERP_CONTINUES; | 827 | return ZFCP_ERP_CONTINUES; |
831 | } | 828 | } |
832 | 829 | ||
833 | static void zfcp_erp_port_strategy_open_ns_wake(struct zfcp_erp_action *ns_act) | ||
834 | { | ||
835 | unsigned long flags; | ||
836 | struct zfcp_adapter *adapter = ns_act->adapter; | ||
837 | struct zfcp_erp_action *act, *tmp; | ||
838 | int status; | ||
839 | |||
840 | read_lock_irqsave(&adapter->erp_lock, flags); | ||
841 | list_for_each_entry_safe(act, tmp, &adapter->erp_running_head, list) { | ||
842 | if (act->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) { | ||
843 | status = atomic_read(&adapter->nameserver_port->status); | ||
844 | if (status & ZFCP_STATUS_COMMON_ERP_FAILED) | ||
845 | zfcp_erp_port_failed(act->port, 27, NULL); | ||
846 | zfcp_erp_action_ready(act); | ||
847 | } | ||
848 | } | ||
849 | read_unlock_irqrestore(&adapter->erp_lock, flags); | ||
850 | } | ||
851 | |||
852 | static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *act) | ||
853 | { | ||
854 | int retval; | ||
855 | |||
856 | switch (act->step) { | ||
857 | case ZFCP_ERP_STEP_UNINITIALIZED: | ||
858 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: | ||
859 | case ZFCP_ERP_STEP_PORT_CLOSING: | ||
860 | return zfcp_erp_port_strategy_open_port(act); | ||
861 | |||
862 | case ZFCP_ERP_STEP_PORT_OPENING: | ||
863 | if (atomic_read(&act->port->status) & ZFCP_STATUS_COMMON_OPEN) | ||
864 | retval = ZFCP_ERP_SUCCEEDED; | ||
865 | else | ||
866 | retval = ZFCP_ERP_FAILED; | ||
867 | /* this is needed anyway */ | ||
868 | zfcp_erp_port_strategy_open_ns_wake(act); | ||
869 | return retval; | ||
870 | |||
871 | default: | ||
872 | return ZFCP_ERP_FAILED; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | static int zfcp_erp_port_strategy_open_lookup(struct zfcp_erp_action *act) | ||
877 | { | ||
878 | int retval; | ||
879 | |||
880 | retval = zfcp_fc_ns_gid_pn_request(act); | ||
881 | if (retval == -ENOMEM) | ||
882 | return ZFCP_ERP_NOMEM; | ||
883 | act->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; | ||
884 | if (retval) | ||
885 | return ZFCP_ERP_FAILED; | ||
886 | return ZFCP_ERP_CONTINUES; | ||
887 | } | ||
888 | |||
889 | static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) | 830 | static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) |
890 | { | 831 | { |
891 | struct zfcp_adapter *adapter = act->adapter; | 832 | struct zfcp_adapter *adapter = act->adapter; |
@@ -900,11 +841,25 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) | |||
900 | return zfcp_erp_port_strategy_open_port(act); | 841 | return zfcp_erp_port_strategy_open_port(act); |
901 | } | 842 | } |
902 | 843 | ||
844 | void zfcp_erp_port_strategy_open_lookup(struct work_struct *work) | ||
845 | { | ||
846 | int retval; | ||
847 | struct zfcp_port *port = container_of(work, struct zfcp_port, | ||
848 | gid_pn_work); | ||
849 | |||
850 | retval = zfcp_fc_ns_gid_pn(&port->erp_action); | ||
851 | if (retval == -ENOMEM) | ||
852 | zfcp_erp_notify(&port->erp_action, ZFCP_ERP_NOMEM); | ||
853 | port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; | ||
854 | if (retval) | ||
855 | zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED); | ||
856 | |||
857 | } | ||
858 | |||
903 | static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | 859 | static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) |
904 | { | 860 | { |
905 | struct zfcp_adapter *adapter = act->adapter; | 861 | struct zfcp_adapter *adapter = act->adapter; |
906 | struct zfcp_port *port = act->port; | 862 | struct zfcp_port *port = act->port; |
907 | struct zfcp_port *ns_port = adapter->nameserver_port; | ||
908 | int p_status = atomic_read(&port->status); | 863 | int p_status = atomic_read(&port->status); |
909 | 864 | ||
910 | switch (act->step) { | 865 | switch (act->step) { |
@@ -913,29 +868,10 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
913 | case ZFCP_ERP_STEP_PORT_CLOSING: | 868 | case ZFCP_ERP_STEP_PORT_CLOSING: |
914 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) | 869 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) |
915 | return zfcp_erp_open_ptp_port(act); | 870 | return zfcp_erp_open_ptp_port(act); |
916 | if (!ns_port) { | 871 | if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { |
917 | dev_err(&adapter->ccw_device->dev, | 872 | schedule_work(&port->gid_pn_work); |
918 | "Attaching the name server port to the " | 873 | return ZFCP_ERP_CONTINUES; |
919 | "FCP device failed\n"); | ||
920 | return ZFCP_ERP_FAILED; | ||
921 | } | ||
922 | if (!(atomic_read(&ns_port->status) & | ||
923 | ZFCP_STATUS_COMMON_UNBLOCKED)) { | ||
924 | /* nameserver port may live again */ | ||
925 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, | ||
926 | &ns_port->status); | ||
927 | if (zfcp_erp_port_reopen(ns_port, 0, 77, act) >= 0) { | ||
928 | act->step = ZFCP_ERP_STEP_NAMESERVER_OPEN; | ||
929 | return ZFCP_ERP_CONTINUES; | ||
930 | } | ||
931 | return ZFCP_ERP_FAILED; | ||
932 | } | 874 | } |
933 | /* else nameserver port is already open, fall through */ | ||
934 | case ZFCP_ERP_STEP_NAMESERVER_OPEN: | ||
935 | if (!(atomic_read(&ns_port->status) & ZFCP_STATUS_COMMON_OPEN)) | ||
936 | return ZFCP_ERP_FAILED; | ||
937 | return zfcp_erp_port_strategy_open_lookup(act); | ||
938 | |||
939 | case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: | 875 | case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: |
940 | if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { | 876 | if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { |
941 | if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) { | 877 | if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) { |
@@ -948,25 +884,26 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
948 | 884 | ||
949 | case ZFCP_ERP_STEP_PORT_OPENING: | 885 | case ZFCP_ERP_STEP_PORT_OPENING: |
950 | /* D_ID might have changed during open */ | 886 | /* D_ID might have changed during open */ |
951 | if ((p_status & ZFCP_STATUS_COMMON_OPEN) && | 887 | if (p_status & ZFCP_STATUS_COMMON_OPEN) { |
952 | (p_status & ZFCP_STATUS_PORT_DID_DID)) | 888 | if (p_status & ZFCP_STATUS_PORT_DID_DID) |
953 | return ZFCP_ERP_SUCCEEDED; | 889 | return ZFCP_ERP_SUCCEEDED; |
890 | else { | ||
891 | act->step = ZFCP_ERP_STEP_PORT_CLOSING; | ||
892 | return ZFCP_ERP_CONTINUES; | ||
893 | } | ||
954 | /* fall through otherwise */ | 894 | /* fall through otherwise */ |
895 | } | ||
955 | } | 896 | } |
956 | return ZFCP_ERP_FAILED; | 897 | return ZFCP_ERP_FAILED; |
957 | } | 898 | } |
958 | 899 | ||
959 | static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *act) | ||
960 | { | ||
961 | if (atomic_read(&act->port->status) & (ZFCP_STATUS_PORT_WKA)) | ||
962 | return zfcp_erp_port_strategy_open_nameserver(act); | ||
963 | return zfcp_erp_port_strategy_open_common(act); | ||
964 | } | ||
965 | |||
966 | static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) | 900 | static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) |
967 | { | 901 | { |
968 | struct zfcp_port *port = erp_action->port; | 902 | struct zfcp_port *port = erp_action->port; |
969 | 903 | ||
904 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC) | ||
905 | goto close_init_done; | ||
906 | |||
970 | switch (erp_action->step) { | 907 | switch (erp_action->step) { |
971 | case ZFCP_ERP_STEP_UNINITIALIZED: | 908 | case ZFCP_ERP_STEP_UNINITIALIZED: |
972 | zfcp_erp_port_strategy_clearstati(port); | 909 | zfcp_erp_port_strategy_clearstati(port); |
@@ -979,12 +916,12 @@ static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) | |||
979 | return ZFCP_ERP_FAILED; | 916 | return ZFCP_ERP_FAILED; |
980 | break; | 917 | break; |
981 | } | 918 | } |
919 | |||
920 | close_init_done: | ||
982 | if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) | 921 | if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) |
983 | return ZFCP_ERP_EXIT; | 922 | return ZFCP_ERP_EXIT; |
984 | else | ||
985 | return zfcp_erp_port_strategy_open(erp_action); | ||
986 | 923 | ||
987 | return ZFCP_ERP_FAILED; | 924 | return zfcp_erp_port_strategy_open_common(erp_action); |
988 | } | 925 | } |
989 | 926 | ||
990 | static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) | 927 | static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) |
@@ -1296,12 +1233,10 @@ static void zfcp_erp_rport_register(struct zfcp_port *port) | |||
1296 | static void zfcp_erp_rports_del(struct zfcp_adapter *adapter) | 1233 | static void zfcp_erp_rports_del(struct zfcp_adapter *adapter) |
1297 | { | 1234 | { |
1298 | struct zfcp_port *port; | 1235 | struct zfcp_port *port; |
1299 | list_for_each_entry(port, &adapter->port_list_head, list) | 1236 | list_for_each_entry(port, &adapter->port_list_head, list) { |
1300 | if (port->rport && !(atomic_read(&port->status) & | 1237 | fc_remote_port_delete(port->rport); |
1301 | ZFCP_STATUS_PORT_WKA)) { | 1238 | port->rport = NULL; |
1302 | fc_remote_port_delete(port->rport); | 1239 | } |
1303 | port->rport = NULL; | ||
1304 | } | ||
1305 | } | 1240 | } |
1306 | 1241 | ||
1307 | static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) | 1242 | static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) |
@@ -1737,9 +1672,8 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, | |||
1737 | 1672 | ||
1738 | if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | | 1673 | if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | |
1739 | ZFCP_STATUS_COMMON_ACCESS_BOXED))) { | 1674 | ZFCP_STATUS_COMMON_ACCESS_BOXED))) { |
1740 | if (!(status & ZFCP_STATUS_PORT_WKA)) | 1675 | list_for_each_entry(unit, &port->unit_list_head, list) |
1741 | list_for_each_entry(unit, &port->unit_list_head, list) | 1676 | zfcp_erp_unit_access_changed(unit, id, ref); |
1742 | zfcp_erp_unit_access_changed(unit, id, ref); | ||
1743 | return; | 1677 | return; |
1744 | } | 1678 | } |
1745 | 1679 | ||
@@ -1762,10 +1696,7 @@ void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id, | |||
1762 | return; | 1696 | return; |
1763 | 1697 | ||
1764 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 1698 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
1765 | if (adapter->nameserver_port) | ||
1766 | zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref); | ||
1767 | list_for_each_entry(port, &adapter->port_list_head, list) | 1699 | list_for_each_entry(port, &adapter->port_list_head, list) |
1768 | if (port != adapter->nameserver_port) | 1700 | zfcp_erp_port_access_changed(port, id, ref); |
1769 | zfcp_erp_port_access_changed(port, id, ref); | ||
1770 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 1701 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
1771 | } | 1702 | } |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index a8dd105dc086..5c8a703b5ce1 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -91,17 +91,21 @@ extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8, void *); | |||
91 | extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8, void *); | 91 | extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8, void *); |
92 | extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *); | 92 | extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *); |
93 | extern void zfcp_erp_timeout_handler(unsigned long); | 93 | extern void zfcp_erp_timeout_handler(unsigned long); |
94 | extern void zfcp_erp_port_strategy_open_lookup(struct work_struct *); | ||
94 | 95 | ||
95 | /* zfcp_fc.c */ | 96 | /* zfcp_fc.c */ |
96 | extern int zfcp_scan_ports(struct zfcp_adapter *); | 97 | extern int zfcp_scan_ports(struct zfcp_adapter *); |
97 | extern void _zfcp_scan_ports_later(struct work_struct *); | 98 | extern void _zfcp_scan_ports_later(struct work_struct *); |
98 | extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); | 99 | extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); |
99 | extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *); | 100 | extern int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *); |
100 | extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); | 101 | extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); |
101 | extern void zfcp_test_link(struct zfcp_port *); | 102 | extern void zfcp_test_link(struct zfcp_port *); |
103 | extern void zfcp_fc_nameserver_init(struct zfcp_adapter *); | ||
102 | 104 | ||
103 | /* zfcp_fsf.c */ | 105 | /* zfcp_fsf.c */ |
104 | extern int zfcp_fsf_open_port(struct zfcp_erp_action *); | 106 | extern int zfcp_fsf_open_port(struct zfcp_erp_action *); |
107 | extern int zfcp_fsf_open_wka_port(struct zfcp_wka_port *); | ||
108 | extern int zfcp_fsf_close_wka_port(struct zfcp_wka_port *); | ||
105 | extern int zfcp_fsf_close_port(struct zfcp_erp_action *); | 109 | extern int zfcp_fsf_close_port(struct zfcp_erp_action *); |
106 | extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *); | 110 | extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *); |
107 | extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); | 111 | extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); |
@@ -153,7 +157,6 @@ extern struct fc_function_template zfcp_transport_functions; | |||
153 | /* zfcp_sysfs.c */ | 157 | /* zfcp_sysfs.c */ |
154 | extern struct attribute_group zfcp_sysfs_unit_attrs; | 158 | extern struct attribute_group zfcp_sysfs_unit_attrs; |
155 | extern struct attribute_group zfcp_sysfs_adapter_attrs; | 159 | extern struct attribute_group zfcp_sysfs_adapter_attrs; |
156 | extern struct attribute_group zfcp_sysfs_ns_port_attrs; | ||
157 | extern struct attribute_group zfcp_sysfs_port_attrs; | 160 | extern struct attribute_group zfcp_sysfs_port_attrs; |
158 | extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; | 161 | extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; |
159 | extern struct device_attribute *zfcp_sysfs_shost_attrs[]; | 162 | extern struct device_attribute *zfcp_sysfs_shost_attrs[]; |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 44456f74a12d..899e45b9e60b 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -39,6 +39,84 @@ struct zfcp_gpn_ft { | |||
39 | struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; | 39 | struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct zfcp_fc_ns_handler_data { | ||
43 | struct completion done; | ||
44 | void (*handler)(unsigned long); | ||
45 | unsigned long handler_data; | ||
46 | }; | ||
47 | |||
48 | static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port) | ||
49 | { | ||
50 | if (mutex_lock_interruptible(&wka_port->mutex)) | ||
51 | return -ERESTARTSYS; | ||
52 | |||
53 | if (wka_port->status != ZFCP_WKA_PORT_ONLINE) { | ||
54 | wka_port->status = ZFCP_WKA_PORT_OPENING; | ||
55 | if (zfcp_fsf_open_wka_port(wka_port)) | ||
56 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
57 | } | ||
58 | |||
59 | mutex_unlock(&wka_port->mutex); | ||
60 | |||
61 | wait_event_timeout( | ||
62 | wka_port->completion_wq, | ||
63 | wka_port->status == ZFCP_WKA_PORT_ONLINE || | ||
64 | wka_port->status == ZFCP_WKA_PORT_OFFLINE, | ||
65 | HZ >> 1); | ||
66 | |||
67 | if (wka_port->status == ZFCP_WKA_PORT_ONLINE) { | ||
68 | atomic_inc(&wka_port->refcount); | ||
69 | return 0; | ||
70 | } | ||
71 | return -EIO; | ||
72 | } | ||
73 | |||
74 | static void zfcp_wka_port_offline(struct work_struct *work) | ||
75 | { | ||
76 | struct delayed_work *dw = container_of(work, struct delayed_work, work); | ||
77 | struct zfcp_wka_port *wka_port = | ||
78 | container_of(dw, struct zfcp_wka_port, work); | ||
79 | |||
80 | wait_event(wka_port->completion_wq, | ||
81 | atomic_read(&wka_port->refcount) == 0); | ||
82 | |||
83 | mutex_lock(&wka_port->mutex); | ||
84 | if ((atomic_read(&wka_port->refcount) != 0) || | ||
85 | (wka_port->status != ZFCP_WKA_PORT_ONLINE)) | ||
86 | goto out; | ||
87 | |||
88 | wka_port->status = ZFCP_WKA_PORT_CLOSING; | ||
89 | if (zfcp_fsf_close_wka_port(wka_port)) { | ||
90 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
91 | wake_up(&wka_port->completion_wq); | ||
92 | } | ||
93 | out: | ||
94 | mutex_unlock(&wka_port->mutex); | ||
95 | } | ||
96 | |||
97 | static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port) | ||
98 | { | ||
99 | if (atomic_dec_return(&wka_port->refcount) != 0) | ||
100 | return; | ||
101 | /* wait 10 miliseconds, other reqs might pop in */ | ||
102 | schedule_delayed_work(&wka_port->work, HZ / 100); | ||
103 | } | ||
104 | |||
105 | void zfcp_fc_nameserver_init(struct zfcp_adapter *adapter) | ||
106 | { | ||
107 | struct zfcp_wka_port *wka_port = &adapter->nsp; | ||
108 | |||
109 | init_waitqueue_head(&wka_port->completion_wq); | ||
110 | |||
111 | wka_port->adapter = adapter; | ||
112 | wka_port->d_id = ZFCP_DID_DIRECTORY_SERVICE; | ||
113 | |||
114 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
115 | atomic_set(&wka_port->refcount, 0); | ||
116 | mutex_init(&wka_port->mutex); | ||
117 | INIT_DELAYED_WORK(&wka_port->work, zfcp_wka_port_offline); | ||
118 | } | ||
119 | |||
42 | static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | 120 | static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, |
43 | struct fcp_rscn_element *elem) | 121 | struct fcp_rscn_element *elem) |
44 | { | 122 | { |
@@ -47,9 +125,6 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |||
47 | 125 | ||
48 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 126 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
49 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { | 127 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { |
50 | if ((atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA) == | ||
51 | ZFCP_STATUS_PORT_WKA) | ||
52 | continue; | ||
53 | /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */ | 128 | /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */ |
54 | if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID)) | 129 | if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID)) |
55 | /* Try to connect to unused ports anyway. */ | 130 | /* Try to connect to unused ports anyway. */ |
@@ -158,7 +233,18 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) | |||
158 | zfcp_fc_incoming_rscn(fsf_req); | 233 | zfcp_fc_incoming_rscn(fsf_req); |
159 | } | 234 | } |
160 | 235 | ||
161 | static void zfcp_ns_gid_pn_handler(unsigned long data) | 236 | static void zfcp_fc_ns_handler(unsigned long data) |
237 | { | ||
238 | struct zfcp_fc_ns_handler_data *compl_rec = | ||
239 | (struct zfcp_fc_ns_handler_data *) data; | ||
240 | |||
241 | if (compl_rec->handler) | ||
242 | compl_rec->handler(compl_rec->handler_data); | ||
243 | |||
244 | complete(&compl_rec->done); | ||
245 | } | ||
246 | |||
247 | static void zfcp_fc_ns_gid_pn_eval(unsigned long data) | ||
162 | { | 248 | { |
163 | struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data; | 249 | struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data; |
164 | struct zfcp_send_ct *ct = &gid_pn->ct; | 250 | struct zfcp_send_ct *ct = &gid_pn->ct; |
@@ -167,43 +253,31 @@ static void zfcp_ns_gid_pn_handler(unsigned long data) | |||
167 | struct zfcp_port *port = gid_pn->port; | 253 | struct zfcp_port *port = gid_pn->port; |
168 | 254 | ||
169 | if (ct->status) | 255 | if (ct->status) |
170 | goto out; | 256 | return; |
171 | if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) { | 257 | if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) { |
172 | atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status); | 258 | atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status); |
173 | goto out; | 259 | return; |
174 | } | 260 | } |
175 | /* paranoia */ | 261 | /* paranoia */ |
176 | if (ct_iu_req->wwpn != port->wwpn) | 262 | if (ct_iu_req->wwpn != port->wwpn) |
177 | goto out; | 263 | return; |
178 | /* looks like a valid d_id */ | 264 | /* looks like a valid d_id */ |
179 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; | 265 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; |
180 | atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); | 266 | atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); |
181 | out: | ||
182 | mempool_free(gid_pn, port->adapter->pool.data_gid_pn); | ||
183 | } | 267 | } |
184 | 268 | ||
185 | /** | 269 | int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, |
186 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | 270 | struct zfcp_gid_pn_data *gid_pn) |
187 | * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed | ||
188 | * return: -ENOMEM on error, 0 otherwise | ||
189 | */ | ||
190 | int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action) | ||
191 | { | 271 | { |
192 | int ret; | ||
193 | struct zfcp_gid_pn_data *gid_pn; | ||
194 | struct zfcp_adapter *adapter = erp_action->adapter; | 272 | struct zfcp_adapter *adapter = erp_action->adapter; |
195 | 273 | struct zfcp_fc_ns_handler_data compl_rec; | |
196 | gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); | 274 | int ret; |
197 | if (!gid_pn) | ||
198 | return -ENOMEM; | ||
199 | |||
200 | memset(gid_pn, 0, sizeof(*gid_pn)); | ||
201 | 275 | ||
202 | /* setup parameters for send generic command */ | 276 | /* setup parameters for send generic command */ |
203 | gid_pn->port = erp_action->port; | 277 | gid_pn->port = erp_action->port; |
204 | gid_pn->ct.port = adapter->nameserver_port; | 278 | gid_pn->ct.wka_port = &adapter->nsp; |
205 | gid_pn->ct.handler = zfcp_ns_gid_pn_handler; | 279 | gid_pn->ct.handler = zfcp_fc_ns_handler; |
206 | gid_pn->ct.handler_data = (unsigned long) gid_pn; | 280 | gid_pn->ct.handler_data = (unsigned long) &compl_rec; |
207 | gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; | 281 | gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; |
208 | gid_pn->ct.req = &gid_pn->req; | 282 | gid_pn->ct.req = &gid_pn->req; |
209 | gid_pn->ct.resp = &gid_pn->resp; | 283 | gid_pn->ct.resp = &gid_pn->resp; |
@@ -223,10 +297,42 @@ int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action) | |||
223 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE; | 297 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE; |
224 | gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; | 298 | gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; |
225 | 299 | ||
300 | init_completion(&compl_rec.done); | ||
301 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; | ||
302 | compl_rec.handler_data = (unsigned long) gid_pn; | ||
226 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, | 303 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, |
227 | erp_action); | 304 | erp_action); |
305 | if (!ret) | ||
306 | wait_for_completion(&compl_rec.done); | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | ||
312 | * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed | ||
313 | * return: -ENOMEM on error, 0 otherwise | ||
314 | */ | ||
315 | int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) | ||
316 | { | ||
317 | int ret; | ||
318 | struct zfcp_gid_pn_data *gid_pn; | ||
319 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
320 | |||
321 | gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); | ||
322 | if (!gid_pn) | ||
323 | return -ENOMEM; | ||
324 | |||
325 | memset(gid_pn, 0, sizeof(*gid_pn)); | ||
326 | |||
327 | ret = zfcp_wka_port_get(&adapter->nsp); | ||
228 | if (ret) | 328 | if (ret) |
229 | mempool_free(gid_pn, adapter->pool.data_gid_pn); | 329 | goto out; |
330 | |||
331 | ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn); | ||
332 | |||
333 | zfcp_wka_port_put(&adapter->nsp); | ||
334 | out: | ||
335 | mempool_free(gid_pn, adapter->pool.data_gid_pn); | ||
230 | return ret; | 336 | return ret; |
231 | } | 337 | } |
232 | 338 | ||
@@ -339,30 +445,6 @@ void zfcp_test_link(struct zfcp_port *port) | |||
339 | zfcp_erp_port_forced_reopen(port, 0, 65, NULL); | 445 | zfcp_erp_port_forced_reopen(port, 0, 65, NULL); |
340 | } | 446 | } |
341 | 447 | ||
342 | static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter) | ||
343 | { | ||
344 | int ret; | ||
345 | |||
346 | if (!adapter->nameserver_port) | ||
347 | return -EINTR; | ||
348 | |||
349 | if (!(atomic_read(&adapter->nameserver_port->status) & | ||
350 | ZFCP_STATUS_COMMON_UNBLOCKED)) { | ||
351 | ret = zfcp_erp_port_reopen(adapter->nameserver_port, 0, 148, | ||
352 | NULL); | ||
353 | if (ret) | ||
354 | return ret; | ||
355 | zfcp_erp_wait(adapter); | ||
356 | } | ||
357 | return !(atomic_read(&adapter->nameserver_port->status) & | ||
358 | ZFCP_STATUS_COMMON_UNBLOCKED); | ||
359 | } | ||
360 | |||
361 | static void zfcp_gpn_ft_handler(unsigned long _done) | ||
362 | { | ||
363 | complete((struct completion *)_done); | ||
364 | } | ||
365 | |||
366 | static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft) | 448 | static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft) |
367 | { | 449 | { |
368 | struct scatterlist *sg = &gpn_ft->sg_req; | 450 | struct scatterlist *sg = &gpn_ft->sg_req; |
@@ -404,7 +486,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
404 | { | 486 | { |
405 | struct zfcp_send_ct *ct = &gpn_ft->ct; | 487 | struct zfcp_send_ct *ct = &gpn_ft->ct; |
406 | struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); | 488 | struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); |
407 | struct completion done; | 489 | struct zfcp_fc_ns_handler_data compl_rec; |
408 | int ret; | 490 | int ret; |
409 | 491 | ||
410 | /* prepare CT IU for GPN_FT */ | 492 | /* prepare CT IU for GPN_FT */ |
@@ -421,19 +503,20 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
421 | req->fc4_type = ZFCP_CT_SCSI_FCP; | 503 | req->fc4_type = ZFCP_CT_SCSI_FCP; |
422 | 504 | ||
423 | /* prepare zfcp_send_ct */ | 505 | /* prepare zfcp_send_ct */ |
424 | ct->port = adapter->nameserver_port; | 506 | ct->wka_port = &adapter->nsp; |
425 | ct->handler = zfcp_gpn_ft_handler; | 507 | ct->handler = zfcp_fc_ns_handler; |
426 | ct->handler_data = (unsigned long)&done; | 508 | ct->handler_data = (unsigned long)&compl_rec; |
427 | ct->timeout = 10; | 509 | ct->timeout = 10; |
428 | ct->req = &gpn_ft->sg_req; | 510 | ct->req = &gpn_ft->sg_req; |
429 | ct->resp = gpn_ft->sg_resp; | 511 | ct->resp = gpn_ft->sg_resp; |
430 | ct->req_count = 1; | 512 | ct->req_count = 1; |
431 | ct->resp_count = ZFCP_GPN_FT_BUFFERS; | 513 | ct->resp_count = ZFCP_GPN_FT_BUFFERS; |
432 | 514 | ||
433 | init_completion(&done); | 515 | init_completion(&compl_rec.done); |
516 | compl_rec.handler = NULL; | ||
434 | ret = zfcp_fsf_send_ct(ct, NULL, NULL); | 517 | ret = zfcp_fsf_send_ct(ct, NULL, NULL); |
435 | if (!ret) | 518 | if (!ret) |
436 | wait_for_completion(&done); | 519 | wait_for_completion(&compl_rec.done); |
437 | return ret; | 520 | return ret; |
438 | } | 521 | } |
439 | 522 | ||
@@ -443,8 +526,6 @@ static void zfcp_validate_port(struct zfcp_port *port) | |||
443 | 526 | ||
444 | atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); | 527 | atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); |
445 | 528 | ||
446 | if (port == adapter->nameserver_port) | ||
447 | return; | ||
448 | if ((port->supported_classes != 0) || (port->units != 0)) { | 529 | if ((port->supported_classes != 0) || (port->units != 0)) { |
449 | zfcp_port_put(port); | 530 | zfcp_port_put(port); |
450 | return; | 531 | return; |
@@ -461,7 +542,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) | |||
461 | struct scatterlist *sg = gpn_ft->sg_resp; | 542 | struct scatterlist *sg = gpn_ft->sg_resp; |
462 | struct ct_hdr *hdr = sg_virt(sg); | 543 | struct ct_hdr *hdr = sg_virt(sg); |
463 | struct gpn_ft_resp_acc *acc = sg_virt(sg); | 544 | struct gpn_ft_resp_acc *acc = sg_virt(sg); |
464 | struct zfcp_adapter *adapter = ct->port->adapter; | 545 | struct zfcp_adapter *adapter = ct->wka_port->adapter; |
465 | struct zfcp_port *port, *tmp; | 546 | struct zfcp_port *port, *tmp; |
466 | u32 d_id; | 547 | u32 d_id; |
467 | int ret = 0, x, last = 0; | 548 | int ret = 0, x, last = 0; |
@@ -491,6 +572,9 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) | |||
491 | d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | | 572 | d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | |
492 | acc->port_id[2]; | 573 | acc->port_id[2]; |
493 | 574 | ||
575 | /* don't attach ports with a well known address */ | ||
576 | if ((d_id & ZFCP_DID_WKA) == ZFCP_DID_WKA) | ||
577 | continue; | ||
494 | /* skip the adapter's port and known remote ports */ | 578 | /* skip the adapter's port and known remote ports */ |
495 | if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) | 579 | if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) |
496 | continue; | 580 | continue; |
@@ -529,13 +613,15 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
529 | if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) | 613 | if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) |
530 | return 0; | 614 | return 0; |
531 | 615 | ||
532 | ret = zfcp_scan_get_nameserver(adapter); | 616 | ret = zfcp_wka_port_get(&adapter->nsp); |
533 | if (ret) | 617 | if (ret) |
534 | return ret; | 618 | return ret; |
535 | 619 | ||
536 | gpn_ft = zfcp_alloc_sg_env(); | 620 | gpn_ft = zfcp_alloc_sg_env(); |
537 | if (!gpn_ft) | 621 | if (!gpn_ft) { |
538 | return -ENOMEM; | 622 | ret = -ENOMEM; |
623 | goto out; | ||
624 | } | ||
539 | 625 | ||
540 | for (i = 0; i < 3; i++) { | 626 | for (i = 0; i < 3; i++) { |
541 | ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter); | 627 | ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter); |
@@ -548,7 +634,8 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
548 | } | 634 | } |
549 | } | 635 | } |
550 | zfcp_free_sg_env(gpn_ft); | 636 | zfcp_free_sg_env(gpn_ft); |
551 | 637 | out: | |
638 | zfcp_wka_port_put(&adapter->nsp); | ||
552 | return ret; | 639 | return ret; |
553 | } | 640 | } |
554 | 641 | ||
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index af75fd2ef1e2..23dd9088153f 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -961,7 +961,6 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) | |||
961 | { | 961 | { |
962 | struct zfcp_adapter *adapter = req->adapter; | 962 | struct zfcp_adapter *adapter = req->adapter; |
963 | struct zfcp_send_ct *send_ct = req->data; | 963 | struct zfcp_send_ct *send_ct = req->data; |
964 | struct zfcp_port *port = send_ct->port; | ||
965 | struct fsf_qtcb_header *header = &req->qtcb->header; | 964 | struct fsf_qtcb_header *header = &req->qtcb->header; |
966 | 965 | ||
967 | send_ct->status = -EINVAL; | 966 | send_ct->status = -EINVAL; |
@@ -980,17 +979,14 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) | |||
980 | case FSF_ADAPTER_STATUS_AVAILABLE: | 979 | case FSF_ADAPTER_STATUS_AVAILABLE: |
981 | switch (header->fsf_status_qual.word[0]){ | 980 | switch (header->fsf_status_qual.word[0]){ |
982 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 981 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
983 | zfcp_test_link(port); | ||
984 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 982 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
985 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 983 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
986 | break; | 984 | break; |
987 | } | 985 | } |
988 | break; | 986 | break; |
989 | case FSF_ACCESS_DENIED: | 987 | case FSF_ACCESS_DENIED: |
990 | zfcp_fsf_access_denied_port(req, port); | ||
991 | break; | 988 | break; |
992 | case FSF_PORT_BOXED: | 989 | case FSF_PORT_BOXED: |
993 | zfcp_erp_port_boxed(port, 49, req); | ||
994 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 990 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | |
995 | ZFCP_STATUS_FSFREQ_RETRY; | 991 | ZFCP_STATUS_FSFREQ_RETRY; |
996 | break; | 992 | break; |
@@ -1041,8 +1037,8 @@ static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req, | |||
1041 | int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | 1037 | int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, |
1042 | struct zfcp_erp_action *erp_action) | 1038 | struct zfcp_erp_action *erp_action) |
1043 | { | 1039 | { |
1044 | struct zfcp_port *port = ct->port; | 1040 | struct zfcp_wka_port *wka_port = ct->wka_port; |
1045 | struct zfcp_adapter *adapter = port->adapter; | 1041 | struct zfcp_adapter *adapter = wka_port->adapter; |
1046 | struct zfcp_fsf_req *req; | 1042 | struct zfcp_fsf_req *req; |
1047 | int ret = -EIO; | 1043 | int ret = -EIO; |
1048 | 1044 | ||
@@ -1063,7 +1059,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | |||
1063 | goto failed_send; | 1059 | goto failed_send; |
1064 | 1060 | ||
1065 | req->handler = zfcp_fsf_send_ct_handler; | 1061 | req->handler = zfcp_fsf_send_ct_handler; |
1066 | req->qtcb->header.port_handle = port->handle; | 1062 | req->qtcb->header.port_handle = wka_port->handle; |
1067 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; | 1063 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; |
1068 | req->qtcb->bottom.support.timeout = ct->timeout; | 1064 | req->qtcb->bottom.support.timeout = ct->timeout; |
1069 | req->data = ct; | 1065 | req->data = ct; |
@@ -1435,9 +1431,6 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1435 | * another GID_PN straight after a port has been opened. | 1431 | * another GID_PN straight after a port has been opened. |
1436 | * Alternately, an ADISC/PDISC ELS should suffice, as well. | 1432 | * Alternately, an ADISC/PDISC ELS should suffice, as well. |
1437 | */ | 1433 | */ |
1438 | if (atomic_read(&port->status) & ZFCP_STATUS_PORT_NO_WWPN) | ||
1439 | break; | ||
1440 | |||
1441 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; | 1434 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; |
1442 | if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { | 1435 | if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { |
1443 | if (plogi->serv_param.wwpn != port->wwpn) | 1436 | if (plogi->serv_param.wwpn != port->wwpn) |
@@ -1568,6 +1561,130 @@ out: | |||
1568 | return retval; | 1561 | return retval; |
1569 | } | 1562 | } |
1570 | 1563 | ||
1564 | static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) | ||
1565 | { | ||
1566 | struct zfcp_wka_port *wka_port = req->data; | ||
1567 | struct fsf_qtcb_header *header = &req->qtcb->header; | ||
1568 | |||
1569 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) { | ||
1570 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
1571 | goto out; | ||
1572 | } | ||
1573 | |||
1574 | switch (header->fsf_status) { | ||
1575 | case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: | ||
1576 | dev_warn(&req->adapter->ccw_device->dev, | ||
1577 | "Opening WKA port 0x%x failed\n", wka_port->d_id); | ||
1578 | case FSF_ADAPTER_STATUS_AVAILABLE: | ||
1579 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | ||
1580 | case FSF_ACCESS_DENIED: | ||
1581 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
1582 | break; | ||
1583 | case FSF_PORT_ALREADY_OPEN: | ||
1584 | case FSF_GOOD: | ||
1585 | wka_port->handle = header->port_handle; | ||
1586 | wka_port->status = ZFCP_WKA_PORT_ONLINE; | ||
1587 | } | ||
1588 | out: | ||
1589 | wake_up(&wka_port->completion_wq); | ||
1590 | } | ||
1591 | |||
1592 | /** | ||
1593 | * zfcp_fsf_open_wka_port - create and send open wka-port request | ||
1594 | * @wka_port: pointer to struct zfcp_wka_port | ||
1595 | * Returns: 0 on success, error otherwise | ||
1596 | */ | ||
1597 | int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port) | ||
1598 | { | ||
1599 | struct qdio_buffer_element *sbale; | ||
1600 | struct zfcp_adapter *adapter = wka_port->adapter; | ||
1601 | struct zfcp_fsf_req *req; | ||
1602 | int retval = -EIO; | ||
1603 | |||
1604 | spin_lock_bh(&adapter->req_q.lock); | ||
1605 | if (zfcp_fsf_req_sbal_get(adapter)) | ||
1606 | goto out; | ||
1607 | |||
1608 | req = zfcp_fsf_req_create(adapter, | ||
1609 | FSF_QTCB_OPEN_PORT_WITH_DID, | ||
1610 | ZFCP_REQ_AUTO_CLEANUP, | ||
1611 | adapter->pool.fsf_req_erp); | ||
1612 | if (unlikely(IS_ERR(req))) { | ||
1613 | retval = PTR_ERR(req); | ||
1614 | goto out; | ||
1615 | } | ||
1616 | |||
1617 | sbale = zfcp_qdio_sbale_req(req); | ||
1618 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | ||
1619 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | ||
1620 | |||
1621 | req->handler = zfcp_fsf_open_wka_port_handler; | ||
1622 | req->qtcb->bottom.support.d_id = wka_port->d_id; | ||
1623 | req->data = wka_port; | ||
1624 | |||
1625 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | ||
1626 | retval = zfcp_fsf_req_send(req); | ||
1627 | if (retval) | ||
1628 | zfcp_fsf_req_free(req); | ||
1629 | out: | ||
1630 | spin_unlock_bh(&adapter->req_q.lock); | ||
1631 | return retval; | ||
1632 | } | ||
1633 | |||
1634 | static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req) | ||
1635 | { | ||
1636 | struct zfcp_wka_port *wka_port = req->data; | ||
1637 | |||
1638 | if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) { | ||
1639 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | ||
1640 | zfcp_erp_adapter_reopen(wka_port->adapter, 0, 107, req); | ||
1641 | } | ||
1642 | |||
1643 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
1644 | wake_up(&wka_port->completion_wq); | ||
1645 | } | ||
1646 | |||
1647 | /** | ||
1648 | * zfcp_fsf_close_wka_port - create and send close wka port request | ||
1649 | * @erp_action: pointer to struct zfcp_erp_action | ||
1650 | * Returns: 0 on success, error otherwise | ||
1651 | */ | ||
1652 | int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port) | ||
1653 | { | ||
1654 | struct qdio_buffer_element *sbale; | ||
1655 | struct zfcp_adapter *adapter = wka_port->adapter; | ||
1656 | struct zfcp_fsf_req *req; | ||
1657 | int retval = -EIO; | ||
1658 | |||
1659 | spin_lock_bh(&adapter->req_q.lock); | ||
1660 | if (zfcp_fsf_req_sbal_get(adapter)) | ||
1661 | goto out; | ||
1662 | |||
1663 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, | ||
1664 | ZFCP_REQ_AUTO_CLEANUP, | ||
1665 | adapter->pool.fsf_req_erp); | ||
1666 | if (unlikely(IS_ERR(req))) { | ||
1667 | retval = PTR_ERR(req); | ||
1668 | goto out; | ||
1669 | } | ||
1670 | |||
1671 | sbale = zfcp_qdio_sbale_req(req); | ||
1672 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | ||
1673 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | ||
1674 | |||
1675 | req->handler = zfcp_fsf_close_wka_port_handler; | ||
1676 | req->data = wka_port; | ||
1677 | req->qtcb->header.port_handle = wka_port->handle; | ||
1678 | |||
1679 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | ||
1680 | retval = zfcp_fsf_req_send(req); | ||
1681 | if (retval) | ||
1682 | zfcp_fsf_req_free(req); | ||
1683 | out: | ||
1684 | spin_unlock_bh(&adapter->req_q.lock); | ||
1685 | return retval; | ||
1686 | } | ||
1687 | |||
1571 | static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) | 1688 | static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) |
1572 | { | 1689 | { |
1573 | struct zfcp_port *port = req->data; | 1690 | struct zfcp_port *port = req->data; |
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 7e857571fe44..430e486e9183 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c | |||
@@ -273,22 +273,7 @@ out: | |||
273 | } | 273 | } |
274 | static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); | 274 | static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); |
275 | 275 | ||
276 | static struct attribute *zfcp_port_ns_attrs[] = { | 276 | static struct attribute *zfcp_port_attrs[] = { |
277 | &dev_attr_port_failed.attr, | ||
278 | &dev_attr_port_in_recovery.attr, | ||
279 | &dev_attr_port_status.attr, | ||
280 | &dev_attr_port_access_denied.attr, | ||
281 | NULL | ||
282 | }; | ||
283 | |||
284 | /** | ||
285 | * zfcp_sysfs_ns_port_attrs - sysfs attributes for nameserver | ||
286 | */ | ||
287 | struct attribute_group zfcp_sysfs_ns_port_attrs = { | ||
288 | .attrs = zfcp_port_ns_attrs, | ||
289 | }; | ||
290 | |||
291 | static struct attribute *zfcp_port_no_ns_attrs[] = { | ||
292 | &dev_attr_unit_add.attr, | 277 | &dev_attr_unit_add.attr, |
293 | &dev_attr_unit_remove.attr, | 278 | &dev_attr_unit_remove.attr, |
294 | &dev_attr_port_failed.attr, | 279 | &dev_attr_port_failed.attr, |
@@ -302,7 +287,7 @@ static struct attribute *zfcp_port_no_ns_attrs[] = { | |||
302 | * zfcp_sysfs_port_attrs - sysfs attributes for all other ports | 287 | * zfcp_sysfs_port_attrs - sysfs attributes for all other ports |
303 | */ | 288 | */ |
304 | struct attribute_group zfcp_sysfs_port_attrs = { | 289 | struct attribute_group zfcp_sysfs_port_attrs = { |
305 | .attrs = zfcp_port_no_ns_attrs, | 290 | .attrs = zfcp_port_attrs, |
306 | }; | 291 | }; |
307 | 292 | ||
308 | static struct attribute *zfcp_unit_attrs[] = { | 293 | static struct attribute *zfcp_unit_attrs[] = { |