aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/ata_piix.c20
-rw-r--r--drivers/ata/libata-sff.c35
-rw-r--r--include/linux/libata.h1
3 files changed, 48 insertions, 8 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index b5f614b9c245..c33806654e46 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -173,6 +173,7 @@ static int piix_sidpr_scr_read(struct ata_link *link,
173 unsigned int reg, u32 *val); 173 unsigned int reg, u32 *val);
174static int piix_sidpr_scr_write(struct ata_link *link, 174static int piix_sidpr_scr_write(struct ata_link *link,
175 unsigned int reg, u32 val); 175 unsigned int reg, u32 val);
176static bool piix_irq_check(struct ata_port *ap);
176#ifdef CONFIG_PM 177#ifdef CONFIG_PM
177static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); 178static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
178static int piix_pci_device_resume(struct pci_dev *pdev); 179static int piix_pci_device_resume(struct pci_dev *pdev);
@@ -317,8 +318,13 @@ static struct scsi_host_template piix_sht = {
317 ATA_BMDMA_SHT(DRV_NAME), 318 ATA_BMDMA_SHT(DRV_NAME),
318}; 319};
319 320
320static struct ata_port_operations piix_pata_ops = { 321static struct ata_port_operations piix_sata_ops = {
321 .inherits = &ata_bmdma32_port_ops, 322 .inherits = &ata_bmdma32_port_ops,
323 .sff_irq_check = piix_irq_check,
324};
325
326static struct ata_port_operations piix_pata_ops = {
327 .inherits = &piix_sata_ops,
322 .cable_detect = ata_cable_40wire, 328 .cable_detect = ata_cable_40wire,
323 .set_piomode = piix_set_piomode, 329 .set_piomode = piix_set_piomode,
324 .set_dmamode = piix_set_dmamode, 330 .set_dmamode = piix_set_dmamode,
@@ -336,10 +342,6 @@ static struct ata_port_operations ich_pata_ops = {
336 .set_dmamode = ich_set_dmamode, 342 .set_dmamode = ich_set_dmamode,
337}; 343};
338 344
339static struct ata_port_operations piix_sata_ops = {
340 .inherits = &ata_bmdma32_port_ops,
341};
342
343static struct ata_port_operations piix_sidpr_sata_ops = { 345static struct ata_port_operations piix_sidpr_sata_ops = {
344 .inherits = &piix_sata_ops, 346 .inherits = &piix_sata_ops,
345 .hardreset = sata_std_hardreset, 347 .hardreset = sata_std_hardreset,
@@ -970,6 +972,14 @@ static int piix_sidpr_scr_write(struct ata_link *link,
970 return 0; 972 return 0;
971} 973}
972 974
975static bool piix_irq_check(struct ata_port *ap)
976{
977 if (unlikely(!ap->ioaddr.bmdma_addr))
978 return false;
979
980 return ap->ops->bmdma_status(ap) & ATA_DMA_INTR;
981}
982
973#ifdef CONFIG_PM 983#ifdef CONFIG_PM
974static int piix_broken_suspend(void) 984static int piix_broken_suspend(void)
975{ 985{
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index c62ed13b0596..c2661ea70330 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1763,7 +1763,7 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
1763{ 1763{
1764 struct ata_host *host = dev_instance; 1764 struct ata_host *host = dev_instance;
1765 unsigned int i; 1765 unsigned int i;
1766 unsigned int handled = 0; 1766 unsigned int handled = 0, polling = 0;
1767 unsigned long flags; 1767 unsigned long flags;
1768 1768
1769 /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */ 1769 /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
@@ -1777,8 +1777,37 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
1777 continue; 1777 continue;
1778 1778
1779 qc = ata_qc_from_tag(ap, ap->link.active_tag); 1779 qc = ata_qc_from_tag(ap, ap->link.active_tag);
1780 if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING)) 1780 if (qc) {
1781 handled |= ata_sff_host_intr(ap, qc); 1781 if (!(qc->tf.flags & ATA_TFLAG_POLLING))
1782 handled |= ata_sff_host_intr(ap, qc);
1783 else
1784 polling |= 1 << i;
1785 }
1786 }
1787
1788 /*
1789 * If no port was expecting IRQ but the controller is actually
1790 * asserting IRQ line, nobody cared will ensue. Check IRQ
1791 * pending status if available and clear spurious IRQ.
1792 */
1793 if (!handled) {
1794 for (i = 0; i < host->n_ports; i++) {
1795 struct ata_port *ap = host->ports[i];
1796
1797 if (polling & (1 << i))
1798 continue;
1799
1800 if (!ap->ops->sff_irq_check ||
1801 !ap->ops->sff_irq_check(ap))
1802 continue;
1803
1804 if (printk_ratelimit())
1805 ata_port_printk(ap, KERN_INFO,
1806 "clearing spurious IRQ\n");
1807
1808 ap->ops->sff_check_status(ap);
1809 ap->ops->sff_irq_clear(ap);
1810 }
1782 } 1811 }
1783 1812
1784 spin_unlock_irqrestore(&host->lock, flags); 1813 spin_unlock_irqrestore(&host->lock, flags);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 73112250862c..5fb888462359 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -857,6 +857,7 @@ struct ata_port_operations {
857 unsigned int (*sff_data_xfer)(struct ata_device *dev, 857 unsigned int (*sff_data_xfer)(struct ata_device *dev,
858 unsigned char *buf, unsigned int buflen, int rw); 858 unsigned char *buf, unsigned int buflen, int rw);
859 u8 (*sff_irq_on)(struct ata_port *); 859 u8 (*sff_irq_on)(struct ata_port *);
860 bool (*sff_irq_check)(struct ata_port *);
860 void (*sff_irq_clear)(struct ata_port *); 861 void (*sff_irq_clear)(struct ata_port *);
861 862
862 void (*bmdma_setup)(struct ata_queued_cmd *qc); 863 void (*bmdma_setup)(struct ata_queued_cmd *qc);