aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_scsi.c
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2009-11-24 10:53:58 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:02:01 -0500
commitecf0c7721b104c0ce9c8ca534c911f6310cf92a8 (patch)
tree639032b36bcbbe905c98c6f0b3b521dc2f0b1806 /drivers/s390/scsi/zfcp_scsi.c
parent0a55256d158c18e4821c248a295b7f8f4423660f (diff)
[SCSI] zfcp: Replace global config_lock with local list locks
The global config_lock was used to protect the configuration organized in independent lists. It is not necessary to have a lock on driver level for this purpose. This patch replaces the global config_lock with a set of local list locks. 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@suse.de>
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c52
1 files changed, 23 insertions, 29 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index f54655998bd5..6feece3b2e36 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -128,49 +128,44 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
128} 128}
129 129
130static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter, 130static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter,
131 int channel, unsigned int id, 131 unsigned int id, u64 lun)
132 unsigned int lun)
133{ 132{
133 unsigned long flags;
134 struct zfcp_port *port; 134 struct zfcp_port *port;
135 struct zfcp_unit *unit; 135 struct zfcp_unit *unit = NULL;
136 int scsi_lun;
137 136
138 list_for_each_entry(port, &adapter->port_list_head, list) { 137 read_lock_irqsave(&adapter->port_list_lock, flags);
138 list_for_each_entry(port, &adapter->port_list, list) {
139 if (!port->rport || (id != port->rport->scsi_target_id)) 139 if (!port->rport || (id != port->rport->scsi_target_id))
140 continue; 140 continue;
141 list_for_each_entry(unit, &port->unit_list_head, list) { 141 unit = zfcp_get_unit_by_lun(port, lun);
142 scsi_lun = scsilun_to_int( 142 if (unit)
143 (struct scsi_lun *)&unit->fcp_lun); 143 break;
144 if (lun == scsi_lun)
145 return unit;
146 }
147 } 144 }
145 read_unlock_irqrestore(&adapter->port_list_lock, flags);
148 146
149 return NULL; 147 return unit;
150} 148}
151 149
152static int zfcp_scsi_slave_alloc(struct scsi_device *sdp) 150static int zfcp_scsi_slave_alloc(struct scsi_device *sdp)
153{ 151{
154 struct zfcp_adapter *adapter; 152 struct zfcp_adapter *adapter;
155 struct zfcp_unit *unit; 153 struct zfcp_unit *unit;
156 unsigned long flags; 154 u64 lun;
157 int retval = -ENXIO;
158 155
159 adapter = (struct zfcp_adapter *) sdp->host->hostdata[0]; 156 adapter = (struct zfcp_adapter *) sdp->host->hostdata[0];
160 if (!adapter) 157 if (!adapter)
161 goto out; 158 goto out;
162 159
163 read_lock_irqsave(&zfcp_data.config_lock, flags); 160 int_to_scsilun(sdp->lun, (struct scsi_lun *)&lun);
164 unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun); 161 unit = zfcp_unit_lookup(adapter, sdp->id, lun);
165 if (unit) { 162 if (unit) {
166 sdp->hostdata = unit; 163 sdp->hostdata = unit;
167 unit->device = sdp; 164 unit->device = sdp;
168 zfcp_unit_get(unit); 165 return 0;
169 retval = 0;
170 } 166 }
171 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
172out: 167out:
173 return retval; 168 return -ENXIO;
174} 169}
175 170
176static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) 171static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
@@ -338,12 +333,12 @@ void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
338 if (!shost) 333 if (!shost)
339 return; 334 return;
340 335
341 read_lock_irq(&zfcp_data.config_lock); 336 read_lock_irq(&adapter->port_list_lock);
342 list_for_each_entry(port, &adapter->port_list_head, list) 337 list_for_each_entry(port, &adapter->port_list, list)
343 if (port->rport) 338 if (port->rport)
344 port->rport = NULL; 339 port->rport = NULL;
340 read_unlock_irq(&adapter->port_list_lock);
345 341
346 read_unlock_irq(&zfcp_data.config_lock);
347 fc_remove_host(shost); 342 fc_remove_host(shost);
348 scsi_remove_host(shost); 343 scsi_remove_host(shost);
349 scsi_host_put(shost); 344 scsi_host_put(shost);
@@ -508,7 +503,7 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
508 * @rport: The FC rport where to teminate I/O 503 * @rport: The FC rport where to teminate I/O
509 * 504 *
510 * Abort all pending SCSI commands for a port by closing the 505 * Abort all pending SCSI commands for a port by closing the
511 * port. Using a reopen for avoids a conflict with a shutdown 506 * port. Using a reopen avoiding a conflict with a shutdown
512 * overwriting a reopen. 507 * overwriting a reopen.
513 */ 508 */
514static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport) 509static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
@@ -518,11 +513,7 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
518 struct zfcp_adapter *adapter = 513 struct zfcp_adapter *adapter =
519 (struct zfcp_adapter *)shost->hostdata[0]; 514 (struct zfcp_adapter *)shost->hostdata[0];
520 515
521 write_lock_irq(&zfcp_data.config_lock);
522 port = zfcp_get_port_by_wwpn(adapter, rport->port_name); 516 port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
523 if (port)
524 zfcp_port_get(port);
525 write_unlock_irq(&zfcp_data.config_lock);
526 517
527 if (port) { 518 if (port) {
528 zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL); 519 zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
@@ -589,10 +580,13 @@ void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
589 580
590void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter) 581void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter)
591{ 582{
583 unsigned long flags;
592 struct zfcp_port *port; 584 struct zfcp_port *port;
593 585
594 list_for_each_entry(port, &adapter->port_list_head, list) 586 read_lock_irqsave(&adapter->port_list_lock, flags);
587 list_for_each_entry(port, &adapter->port_list, list)
595 zfcp_scsi_schedule_rport_block(port); 588 zfcp_scsi_schedule_rport_block(port);
589 read_unlock_irqrestore(&adapter->port_list_lock, flags);
596} 590}
597 591
598void zfcp_scsi_rport_work(struct work_struct *work) 592void zfcp_scsi_rport_work(struct work_struct *work)