diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c --- a/drivers/scsi/libata-core.c Mon Nov 24 11:30:35 2003 +++ b/drivers/scsi/libata-core.c Mon Nov 24 11:30:35 2003 @@ -133,7 +133,11 @@ struct ata_ioports *ioaddr = &ap->ioaddr; unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; - outb(tf->ctl, ioaddr->ctl_addr); + if (tf->ctl != ap->last_ctl) { + outb(tf->ctl, ioaddr->ctl_addr); + ap->last_ctl = tf->ctl; + ata_wait_idle(ap); + } if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { outb(tf->hob_feature, ioaddr->error_addr); @@ -187,7 +191,11 @@ struct ata_ioports *ioaddr = &ap->ioaddr; unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; - writeb(tf->ctl, ap->ioaddr.ctl_addr); + if (tf->ctl != ap->last_ctl) { + writeb(tf->ctl, ap->ioaddr.ctl_addr); + ap->last_ctl = tf->ctl; + ata_wait_idle(ap); + } if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { writeb(tf->hob_feature, (void *) ioaddr->error_addr); @@ -1281,9 +1289,9 @@ /* software reset. causes dev0 to be selected */ if (ap->flags & ATA_FLAG_MMIO) { writeb(ap->ctl, ioaddr->ctl_addr); - udelay(10); /* FIXME: flush */ + udelay(20); /* FIXME: flush */ writeb(ap->ctl | ATA_SRST, ioaddr->ctl_addr); - udelay(10); /* FIXME: flush */ + udelay(20); /* FIXME: flush */ writeb(ap->ctl, ioaddr->ctl_addr); } else { outb(ap->ctl, ioaddr->ctl_addr); @@ -2755,6 +2763,7 @@ ap->cbl = ATA_CBL_NONE; ap->device[0].flags = ATA_DFLAG_MASTER; ap->active_tag = ATA_TAG_POISON; + ap->last_ctl = 0xFF; /* ata_engine init */ ap->eng.flags = 0; diff -Nru a/drivers/scsi/libata.h b/drivers/scsi/libata.h --- a/drivers/scsi/libata.h Mon Nov 24 11:30:35 2003 +++ b/drivers/scsi/libata.h Mon Nov 24 11:30:35 2003 @@ -26,7 +26,7 @@ #define __LIBATA_H__ #define DRV_NAME "libata" -#define DRV_VERSION "0.80" /* must be exactly four chars */ +#define DRV_VERSION "0.81" /* must be exactly four chars */ struct ata_scsi_args { struct ata_port *ap; diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c --- a/drivers/scsi/sata_promise.c Mon Nov 24 11:30:35 2003 +++ b/drivers/scsi/sata_promise.c Mon Nov 24 11:30:35 2003 @@ -213,6 +213,8 @@ board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, + { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20319 }, { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, diff -Nru a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c --- a/drivers/scsi/sata_svw.c Mon Nov 24 11:30:35 2003 +++ b/drivers/scsi/sata_svw.c Mon Nov 24 11:30:35 2003 @@ -44,7 +44,7 @@ #endif /* CONFIG_ALL_PPC */ #define DRV_NAME "ata_k2" -#define DRV_VERSION "1.02" +#define DRV_VERSION "1.03" static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) @@ -69,8 +69,11 @@ struct ata_ioports *ioaddr = &ap->ioaddr; unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; - writeb(tf->ctl, ioaddr->ctl_addr); - + if (tf->ctl != ap->last_ctl) { + writeb(tf->ctl, ioaddr->ctl_addr); + ap->last_ctl = tf->ctl; + ata_wait_idle(ap); + } if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->error_addr); writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr); @@ -311,13 +314,24 @@ rc = -ENODEV; goto err_out_unmap; } + + /* Clear a magic bit in SCR1 according to Darwin, those help + * some funky seagate drives (though so far, those were already + * set by the firmware on the machines I had access to + */ + writel(readl(mmio_base + 0x80) & ~0x00040000, mmio_base + 0x80); + + /* Clear SATA error & interrupts we don't use */ + writel(0xffffffff, mmio_base + 0x44); + writel(0x0, mmio_base + 0x88); + probe_ent->sht = &k2_sata_sht; - probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO; + probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | + ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; probe_ent->port_ops = &k2_sata_ops; - probe_ent->n_ports = 2; - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = SA_SHIRQ; + probe_ent->n_ports = 2; + probe_ent->irq = pdev->irq; + probe_ent->irq_flags = SA_SHIRQ; probe_ent->mmio_base = mmio_base; /* diff -Nru a/include/linux/libata.h b/include/linux/libata.h --- a/include/linux/libata.h Mon Nov 24 11:30:35 2003 +++ b/include/linux/libata.h Mon Nov 24 11:30:35 2003 @@ -310,6 +310,7 @@ struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ u8 ctl; /* cache of ATA control register */ + u8 last_ctl; /* Cache last written value */ unsigned int bus_state; unsigned int port_state; unsigned int pio_mask; @@ -522,12 +523,12 @@ struct ata_ioports *ioaddr = &ap->ioaddr; ap->ctl &= ~ATA_NIEN; + ap->last_ctl = ap->ctl; if (ap->flags & ATA_FLAG_MMIO) writeb(ap->ctl, ioaddr->ctl_addr); else outb(ap->ctl, ioaddr->ctl_addr); - return ata_wait_idle(ap); }