diff options
-rw-r--r-- | drivers/ata/libata-core.c | 30 | ||||
-rw-r--r-- | include/linux/libata.h | 9 |
2 files changed, 22 insertions, 17 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b4fbfebafd26..d2336673601c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2328,11 +2328,14 @@ static inline void ata_tf_to_host(struct ata_port *ap, | |||
2328 | * Sleep until ATA Status register bit BSY clears, | 2328 | * Sleep until ATA Status register bit BSY clears, |
2329 | * or a timeout occurs. | 2329 | * or a timeout occurs. |
2330 | * | 2330 | * |
2331 | * LOCKING: None. | 2331 | * LOCKING: |
2332 | * Kernel thread context (may sleep). | ||
2333 | * | ||
2334 | * RETURNS: | ||
2335 | * 0 on success, -errno otherwise. | ||
2332 | */ | 2336 | */ |
2333 | 2337 | int ata_busy_sleep(struct ata_port *ap, | |
2334 | unsigned int ata_busy_sleep (struct ata_port *ap, | 2338 | unsigned long tmout_pat, unsigned long tmout) |
2335 | unsigned long tmout_pat, unsigned long tmout) | ||
2336 | { | 2339 | { |
2337 | unsigned long timer_start, timeout; | 2340 | unsigned long timer_start, timeout; |
2338 | u8 status; | 2341 | u8 status; |
@@ -2340,27 +2343,32 @@ unsigned int ata_busy_sleep (struct ata_port *ap, | |||
2340 | status = ata_busy_wait(ap, ATA_BUSY, 300); | 2343 | status = ata_busy_wait(ap, ATA_BUSY, 300); |
2341 | timer_start = jiffies; | 2344 | timer_start = jiffies; |
2342 | timeout = timer_start + tmout_pat; | 2345 | timeout = timer_start + tmout_pat; |
2343 | while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { | 2346 | while (status != 0xff && (status & ATA_BUSY) && |
2347 | time_before(jiffies, timeout)) { | ||
2344 | msleep(50); | 2348 | msleep(50); |
2345 | status = ata_busy_wait(ap, ATA_BUSY, 3); | 2349 | status = ata_busy_wait(ap, ATA_BUSY, 3); |
2346 | } | 2350 | } |
2347 | 2351 | ||
2348 | if (status & ATA_BUSY) | 2352 | if (status != 0xff && (status & ATA_BUSY)) |
2349 | ata_port_printk(ap, KERN_WARNING, | 2353 | ata_port_printk(ap, KERN_WARNING, |
2350 | "port is slow to respond, please be patient " | 2354 | "port is slow to respond, please be patient " |
2351 | "(Status 0x%x)\n", status); | 2355 | "(Status 0x%x)\n", status); |
2352 | 2356 | ||
2353 | timeout = timer_start + tmout; | 2357 | timeout = timer_start + tmout; |
2354 | while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { | 2358 | while (status != 0xff && (status & ATA_BUSY) && |
2359 | time_before(jiffies, timeout)) { | ||
2355 | msleep(50); | 2360 | msleep(50); |
2356 | status = ata_chk_status(ap); | 2361 | status = ata_chk_status(ap); |
2357 | } | 2362 | } |
2358 | 2363 | ||
2364 | if (status == 0xff) | ||
2365 | return -ENODEV; | ||
2366 | |||
2359 | if (status & ATA_BUSY) { | 2367 | if (status & ATA_BUSY) { |
2360 | ata_port_printk(ap, KERN_ERR, "port failed to respond " | 2368 | ata_port_printk(ap, KERN_ERR, "port failed to respond " |
2361 | "(%lu secs, Status 0x%x)\n", | 2369 | "(%lu secs, Status 0x%x)\n", |
2362 | tmout / HZ, status); | 2370 | tmout / HZ, status); |
2363 | return 1; | 2371 | return -EBUSY; |
2364 | } | 2372 | } |
2365 | 2373 | ||
2366 | return 0; | 2374 | return 0; |
@@ -2451,10 +2459,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, | |||
2451 | * the bus shows 0xFF because the odd clown forgets the D7 | 2459 | * the bus shows 0xFF because the odd clown forgets the D7 |
2452 | * pulldown resistor. | 2460 | * pulldown resistor. |
2453 | */ | 2461 | */ |
2454 | if (ata_check_status(ap) == 0xFF) { | 2462 | if (ata_check_status(ap) == 0xFF) |
2455 | ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n"); | 2463 | return 0; |
2456 | return AC_ERR_OTHER; | ||
2457 | } | ||
2458 | 2464 | ||
2459 | ata_bus_post_reset(ap, devmask); | 2465 | ata_bus_post_reset(ap, devmask); |
2460 | 2466 | ||
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); | |||
746 | extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); | 746 | extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); |
747 | extern void ata_host_resume(struct ata_host *host); | 747 | extern void ata_host_resume(struct ata_host *host); |
748 | extern int ata_ratelimit(void); | 748 | extern int ata_ratelimit(void); |
749 | extern unsigned int ata_busy_sleep(struct ata_port *ap, | 749 | extern 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); | ||
752 | extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), | 751 | extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), |
753 | void *data, unsigned long delay); | 752 | void *data, unsigned long delay); |
754 | extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, | 753 | extern 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", |