aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ahci.c31
-rw-r--r--drivers/scsi/libata-core.c23
2 files changed, 48 insertions, 6 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index c2c8fa828e24..5ec866b00479 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -672,17 +672,36 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
672 672
673 for (i = 0; i < host_set->n_ports; i++) { 673 for (i = 0; i < host_set->n_ports; i++) {
674 struct ata_port *ap; 674 struct ata_port *ap;
675 u32 tmp;
676 675
677 VPRINTK("port %u\n", i); 676 if (!(irq_stat & (1 << i)))
677 continue;
678
678 ap = host_set->ports[i]; 679 ap = host_set->ports[i];
679 tmp = irq_stat & (1 << i); 680 if (ap) {
680 if (tmp && ap) {
681 struct ata_queued_cmd *qc; 681 struct ata_queued_cmd *qc;
682 qc = ata_qc_from_tag(ap, ap->active_tag); 682 qc = ata_qc_from_tag(ap, ap->active_tag);
683 if (ahci_host_intr(ap, qc)) 683 if (!ahci_host_intr(ap, qc))
684 irq_ack |= (1 << i); 684 if (ata_ratelimit()) {
685 struct pci_dev *pdev =
686 to_pci_dev(ap->host_set->dev);
687 printk(KERN_WARNING
688 "ahci(%s): unhandled interrupt on port %u\n",
689 pci_name(pdev), i);
690 }
691
692 VPRINTK("port %u\n", i);
693 } else {
694 VPRINTK("port %u (no irq)\n", i);
695 if (ata_ratelimit()) {
696 struct pci_dev *pdev =
697 to_pci_dev(ap->host_set->dev);
698 printk(KERN_WARNING
699 "ahci(%s): interrupt on disabled port %u\n",
700 pci_name(pdev), i);
701 }
685 } 702 }
703
704 irq_ack |= (1 << i);
686 } 705 }
687 706
688 if (irq_ack) { 707 if (irq_ack) {
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index f0894bfa908b..ceffaef37d17 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -48,6 +48,7 @@
48#include <linux/completion.h> 48#include <linux/completion.h>
49#include <linux/suspend.h> 49#include <linux/suspend.h>
50#include <linux/workqueue.h> 50#include <linux/workqueue.h>
51#include <linux/jiffies.h>
51#include <scsi/scsi.h> 52#include <scsi/scsi.h>
52#include "scsi.h" 53#include "scsi.h"
53#include "scsi_priv.h" 54#include "scsi_priv.h"
@@ -4688,6 +4689,27 @@ static void __exit ata_exit(void)
4688module_init(ata_init); 4689module_init(ata_init);
4689module_exit(ata_exit); 4690module_exit(ata_exit);
4690 4691
4692static unsigned long ratelimit_time;
4693static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED;
4694
4695int ata_ratelimit(void)
4696{
4697 int rc;
4698 unsigned long flags;
4699
4700 spin_lock_irqsave(&ata_ratelimit_lock, flags);
4701
4702 if (time_after(jiffies, ratelimit_time)) {
4703 rc = 1;
4704 ratelimit_time = jiffies + (HZ/5);
4705 } else
4706 rc = 0;
4707
4708 spin_unlock_irqrestore(&ata_ratelimit_lock, flags);
4709
4710 return rc;
4711}
4712
4691/* 4713/*
4692 * libata is essentially a library of internal helper functions for 4714 * libata is essentially a library of internal helper functions for
4693 * low-level ATA host controller drivers. As such, the API/ABI is 4715 * low-level ATA host controller drivers. As such, the API/ABI is
@@ -4729,6 +4751,7 @@ EXPORT_SYMBOL_GPL(sata_phy_reset);
4729EXPORT_SYMBOL_GPL(__sata_phy_reset); 4751EXPORT_SYMBOL_GPL(__sata_phy_reset);
4730EXPORT_SYMBOL_GPL(ata_bus_reset); 4752EXPORT_SYMBOL_GPL(ata_bus_reset);
4731EXPORT_SYMBOL_GPL(ata_port_disable); 4753EXPORT_SYMBOL_GPL(ata_port_disable);
4754EXPORT_SYMBOL_GPL(ata_ratelimit);
4732EXPORT_SYMBOL_GPL(ata_scsi_ioctl); 4755EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
4733EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); 4756EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
4734EXPORT_SYMBOL_GPL(ata_scsi_error); 4757EXPORT_SYMBOL_GPL(ata_scsi_error);