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.c49
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
163static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) 163static 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
188static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn) 188static 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
204static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req) 203static 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
580static void zfcp_fc_validate_port(struct zfcp_port *port) 579static 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) +