Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 45863
b: refs/heads/master
c: 0291f95
h: refs/heads/master
i:
  45861: f016503
  45859: 9e33b33
  45855: 7a8d6c6
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Jan 25, 2007
1 parent c569608 commit 40e8156
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 17234246eb82898cf98e3c29e81d941c738e0587
refs/heads/master: 0291f95fdb5fcd91cc077aafabea2c5b109fa8a8
57 changes: 49 additions & 8 deletions trunk/drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ enum {
AHCI_CMD_CLR_BUSY = (1 << 10),

RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */
RX_FIS_SDB = 0x58, /* offset of SDB FIS data */
RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */

board_ahci = 0,
Expand Down Expand Up @@ -202,6 +203,10 @@ struct ahci_port_priv {
dma_addr_t cmd_tbl_dma;
void *rx_fis;
dma_addr_t rx_fis_dma;
/* for NCQ spurious interrupt analysis */
int ncq_saw_spurious_sdb_cnt;
unsigned int ncq_saw_d2h:1;
unsigned int ncq_saw_dmas:1;
};

static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
Expand Down Expand Up @@ -1109,8 +1114,9 @@ static void ahci_host_intr(struct ata_port *ap)
void __iomem *mmio = ap->host->mmio_base;
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
struct ata_eh_info *ehi = &ap->eh_info;
struct ahci_port_priv *pp = ap->private_data;
u32 status, qc_active;
int rc;
int rc, known_irq = 0;

status = readl(port_mmio + PORT_IRQ_STAT);
writel(status, port_mmio + PORT_IRQ_STAT);
Expand All @@ -1137,17 +1143,52 @@ static void ahci_host_intr(struct ata_port *ap)

/* hmmm... a spurious interupt */

/* some devices send D2H reg with I bit set during NCQ command phase */
if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
/* if !NCQ, ignore. No modern ATA device has broken HSM
* implementation for non-NCQ commands.
*/
if (!ap->sactive)
return;

/* ignore interim PIO setup fis interrupts */
if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS))
return;
if (status & PORT_IRQ_D2H_REG_FIS) {
if (!pp->ncq_saw_d2h)
ata_port_printk(ap, KERN_INFO,
"D2H reg with I during NCQ, "
"this message won't be printed again\n");
pp->ncq_saw_d2h = 1;
known_irq = 1;
}

if (status & PORT_IRQ_DMAS_FIS) {
if (!pp->ncq_saw_dmas)
ata_port_printk(ap, KERN_INFO,
"DMAS FIS during NCQ, "
"this message won't be printed again\n");
pp->ncq_saw_dmas = 1;
known_irq = 1;
}

if (status & PORT_IRQ_SDB_FIS &&
pp->ncq_saw_spurious_sdb_cnt < 10) {
/* SDB FIS containing spurious completions might be
* dangerous, we need to know more about them. Print
* more of it.
*/
const u32 *f = pp->rx_fis + RX_FIS_SDB;

ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ "
"issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n",
readl(port_mmio + PORT_CMD_ISSUE),
readl(port_mmio + PORT_SCR_ACT), f[0], f[1],
pp->ncq_saw_spurious_sdb_cnt < 10 ?
"" : ", shutting up");

pp->ncq_saw_spurious_sdb_cnt++;
known_irq = 1;
}

if (ata_ratelimit())
if (!known_irq)
ata_port_printk(ap, KERN_INFO, "spurious interrupt "
"(irq_stat 0x%x active_tag %d sactive 0x%x)\n",
"(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
status, ap->active_tag, ap->sactive);
}

Expand Down

0 comments on commit 40e8156

Please sign in to comment.