diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 49 |
1 files changed, 22 insertions, 27 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index df23bcead23d..c7efdc51df63 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -145,10 +145,11 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |||
145 | struct fcp_rscn_element *elem) | 145 | struct fcp_rscn_element *elem) |
146 | { | 146 | { |
147 | unsigned long flags; | 147 | unsigned long flags; |
148 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
148 | struct zfcp_port *port; | 149 | struct zfcp_port *port; |
149 | 150 | ||
150 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 151 | read_lock_irqsave(&adapter->port_list_lock, flags); |
151 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { | 152 | list_for_each_entry(port, &adapter->port_list, list) { |
152 | if ((port->d_id & range) == (elem->nport_did & range)) | 153 | if ((port->d_id & range) == (elem->nport_did & range)) |
153 | zfcp_fc_test_link(port); | 154 | zfcp_fc_test_link(port); |
154 | if (!port->d_id) | 155 | if (!port->d_id) |
@@ -156,8 +157,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |||
156 | ZFCP_STATUS_COMMON_ERP_FAILED, | 157 | ZFCP_STATUS_COMMON_ERP_FAILED, |
157 | "fcrscn1", NULL); | 158 | "fcrscn1", NULL); |
158 | } | 159 | } |
159 | 160 | read_unlock_irqrestore(&adapter->port_list_lock, flags); | |
160 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
161 | } | 161 | } |
162 | 162 | ||
163 | static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) | 163 | static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) |
@@ -187,18 +187,17 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) | |||
187 | 187 | ||
188 | static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn) | 188 | static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn) |
189 | { | 189 | { |
190 | unsigned long flags; | ||
190 | struct zfcp_adapter *adapter = req->adapter; | 191 | struct zfcp_adapter *adapter = req->adapter; |
191 | struct zfcp_port *port; | 192 | struct zfcp_port *port; |
192 | unsigned long flags; | ||
193 | 193 | ||
194 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 194 | read_lock_irqsave(&adapter->port_list_lock, flags); |
195 | list_for_each_entry(port, &adapter->port_list_head, list) | 195 | list_for_each_entry(port, &adapter->port_list, list) |
196 | if (port->wwpn == wwpn) | 196 | if (port->wwpn == wwpn) { |
197 | zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req); | ||
197 | break; | 198 | break; |
198 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 199 | } |
199 | 200 | read_unlock_irqrestore(&adapter->port_list_lock, flags); | |
200 | if (port && (port->wwpn == wwpn)) | ||
201 | zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req); | ||
202 | } | 201 | } |
203 | 202 | ||
204 | static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req) | 203 | static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req) |
@@ -579,20 +578,17 @@ static int zfcp_fc_send_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
579 | 578 | ||
580 | static void zfcp_fc_validate_port(struct zfcp_port *port) | 579 | static void zfcp_fc_validate_port(struct zfcp_port *port) |
581 | { | 580 | { |
582 | struct zfcp_adapter *adapter = port->adapter; | ||
583 | |||
584 | if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)) | 581 | if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)) |
585 | return; | 582 | return; |
586 | 583 | ||
587 | atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); | 584 | atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); |
588 | 585 | ||
589 | if ((port->supported_classes != 0) || | 586 | if ((port->supported_classes != 0) || |
590 | !list_empty(&port->unit_list_head)) { | 587 | !list_empty(&port->unit_list)) { |
591 | zfcp_port_put(port); | 588 | zfcp_port_put(port); |
592 | return; | 589 | return; |
593 | } | 590 | } |
594 | zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL); | 591 | zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL); |
595 | zfcp_erp_wait(adapter); | ||
596 | zfcp_port_put(port); | 592 | zfcp_port_put(port); |
597 | zfcp_port_dequeue(port); | 593 | zfcp_port_dequeue(port); |
598 | } | 594 | } |
@@ -605,6 +601,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries) | |||
605 | struct gpn_ft_resp_acc *acc = sg_virt(sg); | 601 | struct gpn_ft_resp_acc *acc = sg_virt(sg); |
606 | struct zfcp_adapter *adapter = ct->wka_port->adapter; | 602 | struct zfcp_adapter *adapter = ct->wka_port->adapter; |
607 | struct zfcp_port *port, *tmp; | 603 | struct zfcp_port *port, *tmp; |
604 | unsigned long flags; | ||
608 | u32 d_id; | 605 | u32 d_id; |
609 | int ret = 0, x, last = 0; | 606 | int ret = 0, x, last = 0; |
610 | 607 | ||
@@ -643,21 +640,20 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries) | |||
643 | /* skip the adapter's port and known remote ports */ | 640 | /* skip the adapter's port and known remote ports */ |
644 | if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) | 641 | if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) |
645 | continue; | 642 | continue; |
646 | port = zfcp_get_port_by_wwpn(adapter, acc->wwpn); | ||
647 | if (port) | ||
648 | continue; | ||
649 | 643 | ||
650 | port = zfcp_port_enqueue(adapter, acc->wwpn, | 644 | port = zfcp_port_enqueue(adapter, acc->wwpn, |
651 | ZFCP_STATUS_COMMON_NOESC, d_id); | 645 | ZFCP_STATUS_COMMON_NOESC, d_id); |
652 | if (IS_ERR(port)) | 646 | if (!IS_ERR(port)) |
653 | ret = PTR_ERR(port); | ||
654 | else | ||
655 | zfcp_erp_port_reopen(port, 0, "fcegpf1", NULL); | 647 | zfcp_erp_port_reopen(port, 0, "fcegpf1", NULL); |
648 | else if (PTR_ERR(port) != -EEXIST) | ||
649 | ret = PTR_ERR(port); | ||
656 | } | 650 | } |
657 | 651 | ||
658 | zfcp_erp_wait(adapter); | 652 | zfcp_erp_wait(adapter); |
659 | list_for_each_entry_safe(port, tmp, &adapter->port_list_head, list) | 653 | write_lock_irqsave(&adapter->port_list_lock, flags); |
654 | list_for_each_entry_safe(port, tmp, &adapter->port_list, list) | ||
660 | zfcp_fc_validate_port(port); | 655 | zfcp_fc_validate_port(port); |
656 | write_unlock_irqrestore(&adapter->port_list_lock, flags); | ||
661 | mutex_unlock(&zfcp_data.config_mutex); | 657 | mutex_unlock(&zfcp_data.config_mutex); |
662 | return ret; | 658 | return ret; |
663 | } | 659 | } |
@@ -760,15 +756,14 @@ int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job) | |||
760 | 756 | ||
761 | els_fc_job->els.adapter = adapter; | 757 | els_fc_job->els.adapter = adapter; |
762 | if (rport) { | 758 | if (rport) { |
763 | read_lock_irq(&zfcp_data.config_lock); | ||
764 | port = zfcp_get_port_by_wwpn(adapter, rport->port_name); | 759 | port = zfcp_get_port_by_wwpn(adapter, rport->port_name); |
765 | if (port) | ||
766 | els_fc_job->els.d_id = port->d_id; | ||
767 | read_unlock_irq(&zfcp_data.config_lock); | ||
768 | if (!port) { | 760 | if (!port) { |
769 | kfree(els_fc_job); | 761 | kfree(els_fc_job); |
770 | return -EINVAL; | 762 | return -EINVAL; |
771 | } | 763 | } |
764 | |||
765 | els_fc_job->els.d_id = port->d_id; | ||
766 | zfcp_port_put(port); | ||
772 | } else { | 767 | } else { |
773 | port_did = job->request->rqst_data.h_els.port_id; | 768 | port_did = job->request->rqst_data.h_els.port_id; |
774 | els_fc_job->els.d_id = (port_did[0] << 16) + | 769 | els_fc_job->els.d_id = (port_did[0] << 16) + |