aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2008-08-21 07:43:35 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-08-29 10:04:35 -0400
commit9528539cc2d506aa232b0d93881ac4d19738752f (patch)
tree5f14bde1d4798c281a6fb587d8fce0c0a16dab5d /drivers/s390/scsi
parentf48bf7fb00f74d93105ba69522a3f6c9435d6af3 (diff)
[SCSI] zfcp: Fix reference counter for remote ports
Fix the remote port reference counter handling during ELS ADISC commands and find the remote port by WWPN not by D_IDs that could change. Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_fc.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 27edabe5b20..05e6b09c48f 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -39,18 +39,6 @@ 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
42static struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *adapter,
43 u32 d_id)
44{
45 struct zfcp_port *port;
46
47 list_for_each_entry(port, &adapter->port_list_head, list)
48 if ((port->d_id == d_id) &&
49 !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status))
50 return port;
51 return NULL;
52}
53
54static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, 42static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
55 struct fcp_rscn_element *elem) 43 struct fcp_rscn_element *elem)
56{ 44{
@@ -341,12 +329,13 @@ void zfcp_test_link(struct zfcp_port *port)
341 329
342 zfcp_port_get(port); 330 zfcp_port_get(port);
343 retval = zfcp_fc_adisc(port); 331 retval = zfcp_fc_adisc(port);
344 if (retval == 0 || retval == -EBUSY) 332 if (retval == 0)
345 return; 333 return;
346 334
347 /* send of ADISC was not possible */ 335 /* send of ADISC was not possible */
348 zfcp_port_put(port); 336 zfcp_port_put(port);
349 zfcp_erp_port_forced_reopen(port, 0, 65, NULL); 337 if (retval != -EBUSY)
338 zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
350} 339}
351 340
352static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter) 341static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
@@ -503,9 +492,13 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
503 acc->port_id[2]; 492 acc->port_id[2];
504 493
505 /* skip the adapter's port and known remote ports */ 494 /* skip the adapter's port and known remote ports */
506 if (acc->wwpn == fc_host_port_name(adapter->scsi_host) || 495 if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
507 zfcp_get_port_by_did(adapter, d_id))
508 continue; 496 continue;
497 port = zfcp_get_port_by_wwpn(adapter, acc->wwpn);
498 if (port) {
499 zfcp_port_get(port);
500 continue;
501 }
509 502
510 port = zfcp_port_enqueue(adapter, acc->wwpn, 503 port = zfcp_port_enqueue(adapter, acc->wwpn,
511 ZFCP_STATUS_PORT_DID_DID | 504 ZFCP_STATUS_PORT_DID_DID |