Skip to content

Commit

Permalink
AHCI: Clear GHC.IS to prevent unexpectly asserting INTx
Browse files Browse the repository at this point in the history
Due to PCI subsystem behaviour, unloading AHCI driver will disable
MSI and enable INTx. When HBA supports MSIx or Multiple MSI, Driver's
irq handler doesn't clear GHC.IS register. It works well when reading or
writing data and GHC.IS is always non-zero. But when unloading driver
(or any other operation which causes disable MSIx and enable INTx), PCI
 subsystem uses config write(Rx04.bit10) to enable INTx. Because
GHC.IS is non-zero, HBA will falsely assume some port needs interrupt
service. Then it asserts INTx. To make things worse, when AHCI controller
shares the same interrupt pin with other PCI device, that PCI device's ISR
will be called and nobody de-asserts previous INTx.
This patch clears GHC.IS in ahci_port_stop() even when using MSIx or
MMSI to prevent this case. It ensures GHC.IS is zero before PCI subsystem
enables INTx.

tj: Minor updates to the comment.

Signed-off-by: Raymond Pang <raymond_rule@hotmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
  • Loading branch information
Pang Raymond authored and Tejun Heo committed Jul 20, 2016
1 parent 01c2920 commit 0516900
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/ata/libahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2392,12 +2392,20 @@ static int ahci_port_start(struct ata_port *ap)
static void ahci_port_stop(struct ata_port *ap)
{
const char *emsg = NULL;
struct ahci_host_priv *hpriv = ap->host->private_data;
void __iomem *host_mmio = hpriv->mmio;
int rc;

/* de-initialize port */
rc = ahci_deinit_port(ap, &emsg);
if (rc)
ata_port_warn(ap, "%s (%d)\n", emsg, rc);

/*
* Clear GHC.IS to prevent stuck INTx after disabling MSI and
* re-enabling INTx.
*/
writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT);
}

void ahci_print_info(struct ata_host *host, const char *scc_s)
Expand Down

0 comments on commit 0516900

Please sign in to comment.