aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-10-09 05:32:15 -0400
committerJeff Garzik <jeff@garzik.org>2006-12-01 22:40:28 -0500
commitd1adc1bbd6dde3e05a91e2d3e6ab42d202ea61d5 (patch)
tree49d88b2f55bb88e5334979b418296af384149cda /include/linux
parenta20c9e820864e18b59d2a4f2f04e8b6053986c95 (diff)
[PATCH] libata: handle 0xff status properly
libata waits for !BSY even when the status register reports 0xff. This causes long boot delays when D8 isn't pulled down properly. This patch does the followings. * don't wait if status register is 0xff in all wait functions * make ata_busy_sleep() return 0 on success and -errno on failure. -ENODEV is returned on 0xff status and -EBUSY on other failures. * make ata_bus_softreset() succeed on 0xff status. 0xff status is not reset failure. It indicates no device. This removes unnecessary retries on such ports. Note that the code change assumes unoccupied port reporting 0xff status does not produce valid device signature. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Joe Jin <lkmaillist@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/libata.h9
1 files changed, 4 insertions, 5 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 2300fcc37f80..6c003d852a88 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -746,9 +746,8 @@ extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
746extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); 746extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
747extern void ata_host_resume(struct ata_host *host); 747extern void ata_host_resume(struct ata_host *host);
748extern int ata_ratelimit(void); 748extern int ata_ratelimit(void);
749extern unsigned int ata_busy_sleep(struct ata_port *ap, 749extern int ata_busy_sleep(struct ata_port *ap,
750 unsigned long timeout_pat, 750 unsigned long timeout_pat, unsigned long timeout);
751 unsigned long timeout);
752extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), 751extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *),
753 void *data, unsigned long delay); 752 void *data, unsigned long delay);
754extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, 753extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
@@ -1064,7 +1063,7 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
1064 udelay(10); 1063 udelay(10);
1065 status = ata_chk_status(ap); 1064 status = ata_chk_status(ap);
1066 max--; 1065 max--;
1067 } while ((status & bits) && (max > 0)); 1066 } while (status != 0xff && (status & bits) && (max > 0));
1068 1067
1069 return status; 1068 return status;
1070} 1069}
@@ -1085,7 +1084,7 @@ static inline u8 ata_wait_idle(struct ata_port *ap)
1085{ 1084{
1086 u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); 1085 u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
1087 1086
1088 if (status & (ATA_BUSY | ATA_DRQ)) { 1087 if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) {
1089 unsigned long l = ap->ioaddr.status_addr; 1088 unsigned long l = ap->ioaddr.status_addr;
1090 if (ata_msg_warn(ap)) 1089 if (ata_msg_warn(ap))
1091 printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n", 1090 printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n",