From dwery. Index: linux-2.6.16/drivers/scsi/libata-core.c =================================================================== --- linux-2.6.16.orig/drivers/scsi/libata-core.c +++ linux-2.6.16/drivers/scsi/libata-core.c @@ -335,7 +335,7 @@ static void ata_tf_read_pio(struct ata_p { struct ata_ioports *ioaddr = &ap->ioaddr; - tf->command = ata_check_status(ap); + tf->command = ap->ops->check_status(ap); tf->feature = inb(ioaddr->error_addr); tf->nsect = inb(ioaddr->nsect_addr); tf->lbal = inb(ioaddr->lbal_addr); @@ -369,7 +369,7 @@ static void ata_tf_read_mmio(struct ata_ { struct ata_ioports *ioaddr = &ap->ioaddr; - tf->command = ata_check_status(ap); + tf->command = ap->ops->check_status(ap); tf->feature = readb((void __iomem *)ioaddr->error_addr); tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); @@ -791,6 +791,9 @@ static unsigned int ata_mmio_devchk(stru static unsigned int ata_devchk(struct ata_port *ap, unsigned int device) { + if (ap->ops->dev_check) + return ap->ops->dev_check(ap, device); + if (ap->flags & ATA_FLAG_MMIO) return ata_mmio_devchk(ap, device); return ata_pio_devchk(ap, device); @@ -2256,10 +2259,10 @@ void ata_bus_reset(struct ata_port *ap) rc = ata_bus_softreset(ap, devmask); else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) { /* set up device control */ - if (ap->flags & ATA_FLAG_MMIO) - writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); - else - outb(ap->ctl, ioaddr->ctl_addr); +// if (ap->flags & ATA_FLAG_MMIO) +// writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); +// else +// outb(ap->ctl, ioaddr->ctl_addr); rc = ata_bus_edd(ap); } Index: linux-2.6.16/include/linux/libata.h =================================================================== --- linux-2.6.16.orig/include/linux/libata.h +++ linux-2.6.16/include/linux/libata.h @@ -387,6 +387,7 @@ struct ata_port_operations { u8 (*check_status)(struct ata_port *ap); u8 (*check_altstatus)(struct ata_port *ap); void (*dev_select)(struct ata_port *ap, unsigned int device); + unsigned int (*dev_check)(struct ata_port *ap, unsigned int device); void (*phy_reset) (struct ata_port *ap); void (*set_mode) (struct ata_port *ap); @@ -406,6 +407,7 @@ struct ata_port_operations { irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); void (*irq_clear) (struct ata_port *); + void (*irq_on) (struct ata_port *); u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, @@ -746,7 +748,9 @@ static inline u8 ata_irq_on(struct ata_p ap->ctl &= ~ATA_NIEN; ap->last_ctl = ap->ctl; - if (ap->flags & ATA_FLAG_MMIO) + if (ap->ops->irq_on) + ap->ops->irq_on(ap); + else if (ap->flags & ATA_FLAG_MMIO) writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); else outb(ap->ctl, ioaddr->ctl_addr); @@ -769,6 +773,7 @@ static inline u8 ata_irq_on(struct ata_p * LOCKING: */ +/* XXX move to ops */ static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) { unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;