aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-sff.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r--drivers/ata/libata-sff.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 730ef3c384ca..02441fd57e9e 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1763,24 +1763,50 @@ 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 */
1770 spin_lock_irqsave(&host->lock, flags); 1770 spin_lock_irqsave(&host->lock, flags);
1771 1771
1772 for (i = 0; i < host->n_ports; i++) { 1772 for (i = 0; i < host->n_ports; i++) {
1773 struct ata_port *ap; 1773 struct ata_port *ap = host->ports[i];
1774 struct ata_queued_cmd *qc;
1774 1775
1775 ap = host->ports[i]; 1776 if (unlikely(ap->flags & ATA_FLAG_DISABLED))
1776 if (ap && 1777 continue;
1777 !(ap->flags & ATA_FLAG_DISABLED)) {
1778 struct ata_queued_cmd *qc;
1779 1778
1780 qc = ata_qc_from_tag(ap, ap->link.active_tag); 1779 qc = ata_qc_from_tag(ap, ap->link.active_tag);
1781 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) && 1780 if (qc) {
1782 (qc->flags & ATA_QCFLAG_ACTIVE)) 1781 if (!(qc->tf.flags & ATA_TFLAG_POLLING))
1783 handled |= ata_sff_host_intr(ap, qc); 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);
1784 } 1810 }
1785 } 1811 }
1786 1812
@@ -3011,6 +3037,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
3011 * @ppi: array of port_info, must be enough for two ports 3037 * @ppi: array of port_info, must be enough for two ports
3012 * @sht: scsi_host_template to use when registering the host 3038 * @sht: scsi_host_template to use when registering the host
3013 * @host_priv: host private_data 3039 * @host_priv: host private_data
3040 * @hflag: host flags
3014 * 3041 *
3015 * This is a helper function which can be called from a driver's 3042 * This is a helper function which can be called from a driver's
3016 * xxx_init_one() probe function if the hardware uses traditional 3043 * xxx_init_one() probe function if the hardware uses traditional
@@ -3031,8 +3058,8 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
3031 * Zero on success, negative on errno-based value on error. 3058 * Zero on success, negative on errno-based value on error.
3032 */ 3059 */
3033int ata_pci_sff_init_one(struct pci_dev *pdev, 3060int ata_pci_sff_init_one(struct pci_dev *pdev,
3034 const struct ata_port_info * const *ppi, 3061 const struct ata_port_info * const *ppi,
3035 struct scsi_host_template *sht, void *host_priv) 3062 struct scsi_host_template *sht, void *host_priv, int hflag)
3036{ 3063{
3037 struct device *dev = &pdev->dev; 3064 struct device *dev = &pdev->dev;
3038 const struct ata_port_info *pi = NULL; 3065 const struct ata_port_info *pi = NULL;
@@ -3067,6 +3094,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
3067 if (rc) 3094 if (rc)
3068 goto out; 3095 goto out;
3069 host->private_data = host_priv; 3096 host->private_data = host_priv;
3097 host->flags |= hflag;
3070 3098
3071 pci_set_master(pdev); 3099 pci_set_master(pdev);
3072 rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); 3100 rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);