summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 20:42:16 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 20:42:16 +0100
commit426d266c12e9116497e3055212f823a56e1a6914 (patch)
treec65828dd2f7aca6da8267f2a405ba39789eb6581 /drivers/scsi/ipr.c
parentx86, ACPI, mm: Revert movablemem_map support (diff)
parent[SCSI] Merge tag 'fcoe-02-19-13' into for-linus (diff)
downloadlinux-426d266c12e9116497e3055212f823a56e1a6914.tar.xz
linux-426d266c12e9116497e3055212f823a56e1a6914.zip
Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley: "This is an assorted set of stragglers into the merge window with driver updates for qla2xxx, megaraid_sas, storvsc and ufs. It also includes pulls of the uapi tree (all the remaining SCSI pieces) and the fcoe tree (updates to fcoe and libfc)" * tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (81 commits) [SCSI] ufs: Separate PCI code into glue driver [SCSI] ufs: Segregate PCI Specific Code [SCSI] scsi: fix lpfc build when wmb() is defined as mb() [SCSI] storvsc: Handle dynamic resizing of the device [SCSI] storvsc: Restructure error handling code on command completion [SCSI] storvsc: avoid usage of WRITE_SAME [SCSI] aacraid: suppress two GCC warnings [SCSI] hpsa: check for dma_mapping_error in hpsa_passthru ioctls [SCSI] hpsa: reorganize error handling in hpsa_passthru_ioctl [SCSI] hpsa: check for dma_mapping_error in hpsa_map_sg_chain_block [SCSI] hpsa: Check for dma_mapping_error for all code paths using fill_cmd [SCSI] hpsa: Check for dma_mapping_error in hpsa_map_one [SCSI] dc395x: uninitialized variable in device_alloc() [SCSI] Fix range check in scsi_host_dif_capable() [SCSI] storvsc: Initialize the sglist [SCSI] mpt2sas: Add support for OEM specific controller [SCSI] ipr: Fix oops while resetting an ipr adapter [SCSI] fnic: Fnic Trace Utility [SCSI] fnic: New debug flags and debug log messages [SCSI] fnic: fnic driver may hit BUG_ON on device reset ...
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 8fa79b83f2d3..f328089a1060 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -6112,7 +6112,7 @@ static int ipr_queuecommand(struct Scsi_Host *shost,
* We have told the host to stop giving us new requests, but
* ERP ops don't count. FIXME
*/
- if (unlikely(!hrrq->allow_cmds && !hrrq->ioa_is_dead)) {
+ if (unlikely(!hrrq->allow_cmds && !hrrq->ioa_is_dead && !hrrq->removing_ioa)) {
spin_unlock_irqrestore(hrrq->lock, hrrq_flags);
return SCSI_MLQUEUE_HOST_BUSY;
}
@@ -6121,7 +6121,7 @@ static int ipr_queuecommand(struct Scsi_Host *shost,
* FIXME - Create scsi_set_host_offline interface
* and the ioa_is_dead check can be removed
*/
- if (unlikely(hrrq->ioa_is_dead || !res)) {
+ if (unlikely(hrrq->ioa_is_dead || hrrq->removing_ioa || !res)) {
spin_unlock_irqrestore(hrrq->lock, hrrq_flags);
goto err_nodev;
}
@@ -6741,14 +6741,17 @@ static int ipr_ioa_bringdown_done(struct ipr_cmnd *ipr_cmd)
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
ENTER;
+ if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) {
+ ipr_trace;
+ spin_unlock_irq(ioa_cfg->host->host_lock);
+ scsi_unblock_requests(ioa_cfg->host);
+ spin_lock_irq(ioa_cfg->host->host_lock);
+ }
+
ioa_cfg->in_reset_reload = 0;
ioa_cfg->reset_retries = 0;
list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
wake_up_all(&ioa_cfg->reset_wait_q);
-
- spin_unlock_irq(ioa_cfg->host->host_lock);
- scsi_unblock_requests(ioa_cfg->host);
- spin_lock_irq(ioa_cfg->host->host_lock);
LEAVE;
return IPR_RC_JOB_RETURN;
@@ -8494,7 +8497,8 @@ static void _ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
spin_unlock(&ioa_cfg->hrrq[i]._lock);
}
wmb();
- scsi_block_requests(ioa_cfg->host);
+ if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa)
+ scsi_block_requests(ioa_cfg->host);
ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
ioa_cfg->reset_cmd = ipr_cmd;
@@ -8549,9 +8553,11 @@ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
ipr_fail_all_ops(ioa_cfg);
wake_up_all(&ioa_cfg->reset_wait_q);
- spin_unlock_irq(ioa_cfg->host->host_lock);
- scsi_unblock_requests(ioa_cfg->host);
- spin_lock_irq(ioa_cfg->host->host_lock);
+ if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) {
+ spin_unlock_irq(ioa_cfg->host->host_lock);
+ scsi_unblock_requests(ioa_cfg->host);
+ spin_lock_irq(ioa_cfg->host->host_lock);
+ }
return;
} else {
ioa_cfg->in_ioa_bringdown = 1;
@@ -9695,6 +9701,7 @@ static void __ipr_remove(struct pci_dev *pdev)
{
unsigned long host_lock_flags = 0;
struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
+ int i;
ENTER;
spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
@@ -9704,6 +9711,12 @@ static void __ipr_remove(struct pci_dev *pdev)
spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
}
+ for (i = 0; i < ioa_cfg->hrrq_num; i++) {
+ spin_lock(&ioa_cfg->hrrq[i]._lock);
+ ioa_cfg->hrrq[i].removing_ioa = 1;
+ spin_unlock(&ioa_cfg->hrrq[i]._lock);
+ }
+ wmb();
ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);