diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-11-24 10:53:58 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:02:01 -0500 |
commit | ecf0c7721b104c0ce9c8ca534c911f6310cf92a8 (patch) | |
tree | 639032b36bcbbe905c98c6f0b3b521dc2f0b1806 /drivers/s390/scsi/zfcp_scsi.c | |
parent | 0a55256d158c18e4821c248a295b7f8f4423660f (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.c | 52 |
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 | ||
130 | static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter, | 130 | static 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 | ||
152 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdp) | 150 | static 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); | ||
172 | out: | 167 | out: |
173 | return retval; | 168 | return -ENXIO; |
174 | } | 169 | } |
175 | 170 | ||
176 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | 171 | static 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 | */ |
514 | static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport) | 509 | static 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 | ||
590 | void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter) | 581 | void 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 | ||
598 | void zfcp_scsi_rport_work(struct work_struct *work) | 592 | void zfcp_scsi_rport_work(struct work_struct *work) |