aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/ipr.c33
-rw-r--r--drivers/scsi/ipr.h1
2 files changed, 24 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,
6112 * We have told the host to stop giving us new requests, but 6112 * We have told the host to stop giving us new requests, but
6113 * ERP ops don't count. FIXME 6113 * ERP ops don't count. FIXME
6114 */ 6114 */
6115 if (unlikely(!hrrq->allow_cmds && !hrrq->ioa_is_dead)) { 6115 if (unlikely(!hrrq->allow_cmds && !hrrq->ioa_is_dead && !hrrq->removing_ioa)) {
6116 spin_unlock_irqrestore(hrrq->lock, hrrq_flags); 6116 spin_unlock_irqrestore(hrrq->lock, hrrq_flags);
6117 return SCSI_MLQUEUE_HOST_BUSY; 6117 return SCSI_MLQUEUE_HOST_BUSY;
6118 } 6118 }
@@ -6121,7 +6121,7 @@ static int ipr_queuecommand(struct Scsi_Host *shost,
6121 * FIXME - Create scsi_set_host_offline interface 6121 * FIXME - Create scsi_set_host_offline interface
6122 * and the ioa_is_dead check can be removed 6122 * and the ioa_is_dead check can be removed
6123 */ 6123 */
6124 if (unlikely(hrrq->ioa_is_dead || !res)) { 6124 if (unlikely(hrrq->ioa_is_dead || hrrq->removing_ioa || !res)) {
6125 spin_unlock_irqrestore(hrrq->lock, hrrq_flags); 6125 spin_unlock_irqrestore(hrrq->lock, hrrq_flags);
6126 goto err_nodev; 6126 goto err_nodev;
6127 } 6127 }
@@ -6741,14 +6741,17 @@ static int ipr_ioa_bringdown_done(struct ipr_cmnd *ipr_cmd)
6741 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 6741 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
6742 6742
6743 ENTER; 6743 ENTER;
6744 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) {
6745 ipr_trace;
6746 spin_unlock_irq(ioa_cfg->host->host_lock);
6747 scsi_unblock_requests(ioa_cfg->host);
6748 spin_lock_irq(ioa_cfg->host->host_lock);
6749 }
6750
6744 ioa_cfg->in_reset_reload = 0; 6751 ioa_cfg->in_reset_reload = 0;
6745 ioa_cfg->reset_retries = 0; 6752 ioa_cfg->reset_retries = 0;
6746 list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); 6753 list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
6747 wake_up_all(&ioa_cfg->reset_wait_q); 6754 wake_up_all(&ioa_cfg->reset_wait_q);
6748
6749 spin_unlock_irq(ioa_cfg->host->host_lock);
6750 scsi_unblock_requests(ioa_cfg->host);
6751 spin_lock_irq(ioa_cfg->host->host_lock);
6752 LEAVE; 6755 LEAVE;
6753 6756
6754 return IPR_RC_JOB_RETURN; 6757 return IPR_RC_JOB_RETURN;
@@ -8494,7 +8497,8 @@ static void _ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
8494 spin_unlock(&ioa_cfg->hrrq[i]._lock); 8497 spin_unlock(&ioa_cfg->hrrq[i]._lock);
8495 } 8498 }
8496 wmb(); 8499 wmb();
8497 scsi_block_requests(ioa_cfg->host); 8500 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa)
8501 scsi_block_requests(ioa_cfg->host);
8498 8502
8499 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); 8503 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
8500 ioa_cfg->reset_cmd = ipr_cmd; 8504 ioa_cfg->reset_cmd = ipr_cmd;
@@ -8549,9 +8553,11 @@ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
8549 ipr_fail_all_ops(ioa_cfg); 8553 ipr_fail_all_ops(ioa_cfg);
8550 wake_up_all(&ioa_cfg->reset_wait_q); 8554 wake_up_all(&ioa_cfg->reset_wait_q);
8551 8555
8552 spin_unlock_irq(ioa_cfg->host->host_lock); 8556 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) {
8553 scsi_unblock_requests(ioa_cfg->host); 8557 spin_unlock_irq(ioa_cfg->host->host_lock);
8554 spin_lock_irq(ioa_cfg->host->host_lock); 8558 scsi_unblock_requests(ioa_cfg->host);
8559 spin_lock_irq(ioa_cfg->host->host_lock);
8560 }
8555 return; 8561 return;
8556 } else { 8562 } else {
8557 ioa_cfg->in_ioa_bringdown = 1; 8563 ioa_cfg->in_ioa_bringdown = 1;
@@ -9695,6 +9701,7 @@ static void __ipr_remove(struct pci_dev *pdev)
9695{ 9701{
9696 unsigned long host_lock_flags = 0; 9702 unsigned long host_lock_flags = 0;
9697 struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); 9703 struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
9704 int i;
9698 ENTER; 9705 ENTER;
9699 9706
9700 spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); 9707 spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
@@ -9704,6 +9711,12 @@ static void __ipr_remove(struct pci_dev *pdev)
9704 spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); 9711 spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
9705 } 9712 }
9706 9713
9714 for (i = 0; i < ioa_cfg->hrrq_num; i++) {
9715 spin_lock(&ioa_cfg->hrrq[i]._lock);
9716 ioa_cfg->hrrq[i].removing_ioa = 1;
9717 spin_unlock(&ioa_cfg->hrrq[i]._lock);
9718 }
9719 wmb();
9707 ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL); 9720 ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL);
9708 9721
9709 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); 9722 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 1a9a246932ae..21a6ff1ed5c6 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -493,6 +493,7 @@ struct ipr_hrr_queue {
493 u8 allow_interrupts:1; 493 u8 allow_interrupts:1;
494 u8 ioa_is_dead:1; 494 u8 ioa_is_dead:1;
495 u8 allow_cmds:1; 495 u8 allow_cmds:1;
496 u8 removing_ioa:1;
496 497
497 struct blk_iopoll iopoll; 498 struct blk_iopoll iopoll;
498}; 499};