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:28 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).