diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 30 |
1 files changed, 18 insertions, 12 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 | ||