]> err.no Git - linux-2.6/blobdiff - drivers/ata/sata_nv.c
[PATCH] user of the jiffies rounding patch: ATA subsystem
[linux-2.6] / drivers / ata / sata_nv.c
index 0d316eb3c2149da3ac09266985dc7624f92f84db..cbca983165de8869553fafcbf9d00c4aed9d8892 100644 (file)
@@ -270,14 +270,6 @@ static const struct pci_device_id nv_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
-       { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */
-       { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */
-       { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */
-       { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */
-       { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */
-       { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */
-       { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */
-       { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */
        { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
                PCI_ANY_ID, PCI_ANY_ID,
                PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
@@ -536,7 +528,7 @@ static void nv_adma_mode(struct ata_port *ap)
 
        if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
                return;
-               
+
        WARN_ON(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
 
        tmp = readw(mmio + NV_ADMA_CTL);
@@ -576,7 +568,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
                /* Subtract 1 since an extra entry may be needed for padding, see
                   libata-scsi.c */
                sg_tablesize = LIBATA_MAX_PRD - 1;
-               
+
                /* Since the legacy DMA engine is in use, we need to disable ADMA
                   on the port. */
                adma_enable = 0;
@@ -588,7 +580,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
                sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN;
                adma_enable = 1;
        }
-       
+
        pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &current_reg);
 
        if(ap->port_no == 1)
@@ -597,7 +589,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
        else
                config_mask = NV_MCP_SATA_CFG_20_PORT0_EN |
                              NV_MCP_SATA_CFG_20_PORT0_PWB_EN;
-       
+
        if(adma_enable) {
                new_reg = current_reg | config_mask;
                pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE;
@@ -606,10 +598,10 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
                new_reg = current_reg & ~config_mask;
                pp->flags |= NV_ADMA_ATAPI_SETUP_COMPLETE;
        }
-       
+
        if(current_reg != new_reg)
                pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, new_reg);
-       
+
        blk_queue_bounce_limit(sdev->request_queue, bounce_limit);
        blk_queue_segment_boundary(sdev->request_queue, segment_boundary);
        blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize);
@@ -708,7 +700,6 @@ static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
 static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
 {
        struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
-       int handled;
 
        /* freeze if hotplugged */
        if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) {
@@ -727,13 +718,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
        }
 
        /* handle interrupt */
-       handled = ata_host_intr(ap, qc);
-       if (unlikely(!handled)) {
-               /* spurious, clear it */
-               ata_check_status(ap);
-       }
-
-       return 1;
+       return ata_host_intr(ap, qc);
 }
 
 static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
@@ -760,6 +745,11 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
                        if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
                                u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804)
                                        >> (NV_INT_PORT_SHIFT * i);
+                               if(ata_tag_valid(ap->active_tag))
+                                       /** NV_INT_DEV indication seems unreliable at times
+                                           at least in ADMA mode. Force it on always when a
+                                           command is active, to prevent losing interrupts. */
+                                       irq_stat |= NV_INT_DEV;
                                handled += nv_host_intr(ap, irq_stat);
                                continue;
                        }
@@ -822,13 +812,13 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
                        handled++; /* irq handled if we got here */
                }
        }
-       
+
        if(notifier_clears[0] || notifier_clears[1]) {
                /* Note: Both notifier clear registers must be written
                   if either is set, even if one is zero, according to NVIDIA. */
-               writel(notifier_clears[0], 
+               writel(notifier_clears[0],
                        nv_adma_notifier_clear_block(host->ports[0]));
-               writel(notifier_clears[1], 
+               writel(notifier_clears[1],
                        nv_adma_notifier_clear_block(host->ports[1]));
        }