diff options
-rw-r--r-- | drivers/scsi/ipr.c | 33 | ||||
-rw-r--r-- | drivers/scsi/ipr.h | 1 |
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 | }; |