From: Dan Williams <dan.j.williams@intel.com>
To: linux-scsi@vger.kernel.org
Cc: linux-ide@vger.kernel.org,
Richard Boyd <richard.g.boyd@intel.com>,
Jacek Danecki <jacek.danecki@intel.com>
Subject: [isci PATCH v2 10/18] isci: fix interrupt disable
Date: Sat, 10 Mar 2012 23:28:35 -0800 [thread overview]
Message-ID: <20120311072835.6320.23343.stgit@dwillia2-linux.jf.intel.com> (raw)
In-Reply-To: <20120311072518.6320.61717.stgit@dwillia2-linux.jf.intel.com>
There is a (dubious?) lost irq workaround in sci_controller_isr() that
effectively nullifies attempts to disable interrupts. Until the
workaround can be re-evaluated add some infrastructure to prevent the
interrupt handler from inadvertantly re-enabling interrupts.
The failure mode was interrupts continuing to run after the driver had
been removed and its iomappings torn down.
Reported-by: Jacek Danecki <jacek.danecki@intel.com>
Tested-by: Jacek Danecki <jacek.danecki@intel.com>
[richard: clear remaining interrupts at the end of reset]
Acked-by: Richard Boyd <richard.g.boyd@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/scsi/isci/host.c | 39 ++++++++++++++++++++++++++-------------
drivers/scsi/isci/host.h | 1 +
2 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 577a836..5832b13 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -192,22 +192,27 @@ static bool sci_controller_completion_queue_has_entries(struct isci_host *ihost)
static bool sci_controller_isr(struct isci_host *ihost)
{
- if (sci_controller_completion_queue_has_entries(ihost)) {
+ if (sci_controller_completion_queue_has_entries(ihost))
return true;
- } else {
- /*
- * we have a spurious interrupt it could be that we have already
- * emptied the completion queue from a previous interrupt */
- writel(SMU_ISR_COMPLETION, &ihost->smu_registers->interrupt_status);
- /*
- * There is a race in the hardware that could cause us not to be notified
- * of an interrupt completion if we do not take this step. We will mask
- * then unmask the interrupts so if there is another interrupt pending
- * the clearing of the interrupt source we get the next interrupt message. */
+ /* we have a spurious interrupt it could be that we have already
+ * emptied the completion queue from a previous interrupt
+ * FIXME: really!?
+ */
+ writel(SMU_ISR_COMPLETION, &ihost->smu_registers->interrupt_status);
+
+ /* There is a race in the hardware that could cause us not to be
+ * notified of an interrupt completion if we do not take this
+ * step. We will mask then unmask the interrupts so if there is
+ * another interrupt pending the clearing of the interrupt
+ * source we get the next interrupt message.
+ */
+ spin_lock(&ihost->scic_lock);
+ if (test_bit(IHOST_IRQ_ENABLED, &ihost->flags)) {
writel(0xFF000000, &ihost->smu_registers->interrupt_mask);
writel(0, &ihost->smu_registers->interrupt_mask);
}
+ spin_unlock(&ihost->scic_lock);
return false;
}
@@ -698,14 +703,15 @@ static u32 sci_controller_get_suggested_start_timeout(struct isci_host *ihost)
static void sci_controller_enable_interrupts(struct isci_host *ihost)
{
- BUG_ON(ihost->smu_registers == NULL);
+ set_bit(IHOST_IRQ_ENABLED, &ihost->flags);
writel(0, &ihost->smu_registers->interrupt_mask);
}
void sci_controller_disable_interrupts(struct isci_host *ihost)
{
- BUG_ON(ihost->smu_registers == NULL);
+ clear_bit(IHOST_IRQ_ENABLED, &ihost->flags);
writel(0xffffffff, &ihost->smu_registers->interrupt_mask);
+ readl(&ihost->smu_registers->interrupt_mask); /* flush */
}
static void sci_controller_enable_port_task_scheduler(struct isci_host *ihost)
@@ -1318,7 +1324,9 @@ void isci_host_deinit(struct isci_host *ihost)
*/
writel(0, &ihost->scu_registers->peg0.sgpio.interface_control);
+ spin_lock_irq(&ihost->scic_lock);
sci_controller_reset(ihost);
+ spin_unlock_irq(&ihost->scic_lock);
/* Cancel any/all outstanding port timers */
for (i = 0; i < ihost->logical_port_entries; i++) {
@@ -1605,6 +1613,9 @@ static void sci_controller_reset_hardware(struct isci_host *ihost)
/* The write to the UFQGP clears the UFQPR */
writel(0, &ihost->scu_registers->sdma.unsolicited_frame_get_pointer);
+
+ /* clear all interrupts */
+ writel(~SMU_INTERRUPT_STATUS_RESERVED_MASK, &ihost->smu_registers->interrupt_status);
}
static void sci_controller_resetting_state_enter(struct sci_base_state_machine *sm)
@@ -2391,7 +2402,9 @@ int isci_host_init(struct isci_host *ihost)
int i, err;
enum sci_status status;
+ spin_lock_irq(&ihost->scic_lock);
status = sci_controller_construct(ihost, scu_base(ihost), smu_base(ihost));
+ spin_unlock_irq(&ihost->scic_lock);
if (status != SCI_SUCCESS) {
dev_err(&ihost->pdev->dev,
"%s: sci_controller_construct failed - status = %x\n",
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 9dc910b..9701c1d 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -200,6 +200,7 @@ struct isci_host {
struct pci_dev *pdev;
#define IHOST_START_PENDING 0
#define IHOST_STOP_PENDING 1
+ #define IHOST_IRQ_ENABLED 2
unsigned long flags;
wait_queue_head_t eventq;
struct Scsi_Host *shost;
next prev parent reply other threads:[~2012-03-11 7:13 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-11 7:27 [isci PATCH v2 00/18] isci: suspend/resume support + general updates Dan Williams
2012-03-11 7:27 ` [isci PATCH v2 01/18] isci: improve 'invalid state' warnings Dan Williams
2012-03-11 7:27 ` [isci PATCH v2 02/18] isci: kill ->is_direct_attached Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 03/18] isci: kill sci_phy_protocol and sci_request_protocol Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 04/18] isci: Don't filter BROADCAST CHANGE primitives Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 05/18] isci: kill ->status, and ->state_lock in isci_host Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 06/18] isci: kill isci_port.domain_dev_list Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 07/18] isci: refactor initialization for S3/S4 Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 08/18] isci: fix controller stop Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 09/18] isci: fix 'link-up' events occur after 'start-complete' Dan Williams
2012-03-11 7:28 ` Dan Williams [this message]
2012-03-11 7:28 ` [isci PATCH v2 11/18] isci: kill isci_host.shost Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 12/18] libata: make ata_print_id atomic Dan Williams
2012-04-11 2:21 ` Dan Williams
2012-04-11 11:42 ` Jacek Danecki
2012-04-11 13:42 ` jack_wang
2012-04-12 19:58 ` Jeff Garzik
2012-03-11 7:28 ` [isci PATCH v2 13/18] libsas: continue revalidation Dan Williams
2012-03-11 7:28 ` [isci PATCH v2 14/18] libata: export ata_port suspend/resume infrastructure for sas Dan Williams
2012-03-11 7:29 ` [isci PATCH v2 15/18] libsas: drop sata port multiplier infrastructure Dan Williams
2012-03-11 7:29 ` [isci PATCH v2 16/18] libsas: suspend / resume support Dan Williams
2012-03-11 8:06 ` jack_wang
2012-03-11 7:29 ` [isci PATCH v2 17/18] isci: implement suspend/resume support Dan Williams
2012-03-11 7:29 ` [isci PATCH v2 18/18] isci: Changes in COMSAS timings enabling ISCI to detect buggy disc drives Dan Williams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120311072835.6320.23343.stgit@dwillia2-linux.jf.intel.com \
--to=dan.j.williams@intel.com \
--cc=jacek.danecki@intel.com \
--cc=linux-ide@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=richard.g.boyd@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.