Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 183157
b: refs/heads/master
c: 2794362
h: refs/heads/master
i:
  183155: fe3ebcc
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Mar 1, 2010
1 parent ebc9894 commit 27bb147
Show file tree
Hide file tree
Showing 4 changed files with 49 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: d88ec2e5c13261cf317b46832a7de216f6d06537
refs/heads/master: 27943620cbd960f710a385ff4a538e14ed3f1922
20 changes: 15 additions & 5 deletions trunk/drivers/ata/ata_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ static int piix_sidpr_scr_read(struct ata_link *link,
unsigned int reg, u32 *val);
static int piix_sidpr_scr_write(struct ata_link *link,
unsigned int reg, u32 val);
static bool piix_irq_check(struct ata_port *ap);
#ifdef CONFIG_PM
static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int piix_pci_device_resume(struct pci_dev *pdev);
Expand Down Expand Up @@ -317,8 +318,13 @@ static struct scsi_host_template piix_sht = {
ATA_BMDMA_SHT(DRV_NAME),
};

static struct ata_port_operations piix_pata_ops = {
static struct ata_port_operations piix_sata_ops = {
.inherits = &ata_bmdma32_port_ops,
.sff_irq_check = piix_irq_check,
};

static struct ata_port_operations piix_pata_ops = {
.inherits = &piix_sata_ops,
.cable_detect = ata_cable_40wire,
.set_piomode = piix_set_piomode,
.set_dmamode = piix_set_dmamode,
Expand All @@ -336,10 +342,6 @@ static struct ata_port_operations ich_pata_ops = {
.set_dmamode = ich_set_dmamode,
};

static struct ata_port_operations piix_sata_ops = {
.inherits = &ata_bmdma32_port_ops,
};

static struct ata_port_operations piix_sidpr_sata_ops = {
.inherits = &piix_sata_ops,
.hardreset = sata_std_hardreset,
Expand Down Expand Up @@ -970,6 +972,14 @@ static int piix_sidpr_scr_write(struct ata_link *link,
return 0;
}

static bool piix_irq_check(struct ata_port *ap)
{
if (unlikely(!ap->ioaddr.bmdma_addr))
return false;

return ap->ops->bmdma_status(ap) & ATA_DMA_INTR;
}

#ifdef CONFIG_PM
static int piix_broken_suspend(void)
{
Expand Down
35 changes: 32 additions & 3 deletions trunk/drivers/ata/libata-sff.c
Original file line number Diff line number Diff line change
Expand Up @@ -1763,7 +1763,7 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
unsigned int i;
unsigned int handled = 0;
unsigned int handled = 0, polling = 0;
unsigned long flags;

/* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
Expand All @@ -1777,8 +1777,37 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
continue;

qc = ata_qc_from_tag(ap, ap->link.active_tag);
if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING))
handled |= ata_sff_host_intr(ap, qc);
if (qc) {
if (!(qc->tf.flags & ATA_TFLAG_POLLING))
handled |= ata_sff_host_intr(ap, qc);
else
polling |= 1 << i;
}
}

/*
* If no port was expecting IRQ but the controller is actually
* asserting IRQ line, nobody cared will ensue. Check IRQ
* pending status if available and clear spurious IRQ.
*/
if (!handled) {
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];

if (polling & (1 << i))
continue;

if (!ap->ops->sff_irq_check ||
!ap->ops->sff_irq_check(ap))
continue;

if (printk_ratelimit())
ata_port_printk(ap, KERN_INFO,
"clearing spurious IRQ\n");

ap->ops->sff_check_status(ap);
ap->ops->sff_irq_clear(ap);
}
}

spin_unlock_irqrestore(&host->lock, flags);
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ struct ata_port_operations {
unsigned int (*sff_data_xfer)(struct ata_device *dev,
unsigned char *buf, unsigned int buflen, int rw);
u8 (*sff_irq_on)(struct ata_port *);
bool (*sff_irq_check)(struct ata_port *);
void (*sff_irq_clear)(struct ata_port *);

void (*bmdma_setup)(struct ata_queued_cmd *qc);
Expand Down

0 comments on commit 27bb147

Please sign in to comment.