Also add some ServerWorks-specific tweaks.
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);
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);
/* 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);
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;
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);
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;
/*
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;
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);
}