From: Brett Russ Updated patch to fix erroneous flush of COMRESET set and missing flush of COMRESET clear. Created a new routine scr_write_flush() to try to prevent this in the future. Also, this patch is based on libata-2.6 instead of the previous libata-dev-2.6 based patch. Signed-off-by: Brett Russ Signed-off-by: Andrew Morton --- 25-akpm/drivers/scsi/libata-core.c | 6 +++--- 25-akpm/include/linux/libata.h | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff -puN drivers/scsi/libata-core.c~libata-flush-comreset-set-and-clear drivers/scsi/libata-core.c --- 25/drivers/scsi/libata-core.c~libata-flush-comreset-set-and-clear 2005-03-28 16:07:30.000000000 -0800 +++ 25-akpm/drivers/scsi/libata-core.c 2005-03-28 16:07:30.000000000 -0800 @@ -1253,11 +1253,11 @@ void __sata_phy_reset(struct ata_port *a unsigned long timeout = jiffies + (HZ * 5); if (ap->flags & ATA_FLAG_SATA_RESET) { - scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */ - scr_read(ap, SCR_STATUS); /* dummy read; flush */ + /* issue phy wake/reset */ + scr_write_flush(ap, SCR_CONTROL, 0x301); udelay(400); /* FIXME: a guess */ } - scr_write(ap, SCR_CONTROL, 0x300); /* issue phy wake/clear reset */ + scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ /* wait for phy to become ready, if necessary */ do { diff -puN include/linux/libata.h~libata-flush-comreset-set-and-clear include/linux/libata.h --- 25/include/linux/libata.h~libata-flush-comreset-set-and-clear 2005-03-28 16:07:30.000000000 -0800 +++ 25-akpm/include/linux/libata.h 2005-03-28 16:07:30.000000000 -0800 @@ -584,6 +584,13 @@ static inline void scr_write(struct ata_ ap->ops->scr_write(ap, reg, val); } +static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, + u32 val) +{ + ap->ops->scr_write(ap, reg, val); + (void) ap->ops->scr_read(ap, reg); +} + static inline unsigned int sata_dev_present(struct ata_port *ap) { return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; _