diff options
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index eaead76c9443..3bad6f189190 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -3311,6 +3311,103 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) | |||
3311 | } | 3311 | } |
3312 | 3312 | ||
3313 | /** | 3313 | /** |
3314 | * ata_wait_ready - wait for link to become ready | ||
3315 | * @link: link to be waited on | ||
3316 | * @deadline: deadline jiffies for the operation | ||
3317 | * @check_ready: callback to check link readiness | ||
3318 | * | ||
3319 | * Wait for @link to become ready. @check_ready should return | ||
3320 | * positive number if @link is ready, 0 if it isn't, -ENODEV if | ||
3321 | * link doesn't seem to be occupied, other errno for other error | ||
3322 | * conditions. | ||
3323 | * | ||
3324 | * Transient -ENODEV conditions are allowed for | ||
3325 | * ATA_TMOUT_FF_WAIT. | ||
3326 | * | ||
3327 | * LOCKING: | ||
3328 | * EH context. | ||
3329 | * | ||
3330 | * RETURNS: | ||
3331 | * 0 if @linke is ready before @deadline; otherwise, -errno. | ||
3332 | */ | ||
3333 | int ata_wait_ready(struct ata_link *link, unsigned long deadline, | ||
3334 | int (*check_ready)(struct ata_link *link)) | ||
3335 | { | ||
3336 | unsigned long start = jiffies; | ||
3337 | unsigned long nodev_deadline = start + ATA_TMOUT_FF_WAIT; | ||
3338 | int warned = 0; | ||
3339 | |||
3340 | if (time_after(nodev_deadline, deadline)) | ||
3341 | nodev_deadline = deadline; | ||
3342 | |||
3343 | while (1) { | ||
3344 | unsigned long now = jiffies; | ||
3345 | int ready, tmp; | ||
3346 | |||
3347 | ready = tmp = check_ready(link); | ||
3348 | if (ready > 0) | ||
3349 | return 0; | ||
3350 | |||
3351 | /* -ENODEV could be transient. Ignore -ENODEV if link | ||
3352 | * is online. Also, some SATA devices take a long | ||
3353 | * time to clear 0xff after reset. For example, | ||
3354 | * HHD424020F7SV00 iVDR needs >= 800ms while Quantum | ||
3355 | * GoVault needs even more than that. Wait for | ||
3356 | * ATA_TMOUT_FF_WAIT on -ENODEV if link isn't offline. | ||
3357 | * | ||
3358 | * Note that some PATA controllers (pata_ali) explode | ||
3359 | * if status register is read more than once when | ||
3360 | * there's no device attached. | ||
3361 | */ | ||
3362 | if (ready == -ENODEV) { | ||
3363 | if (ata_link_online(link)) | ||
3364 | ready = 0; | ||
3365 | else if ((link->ap->flags & ATA_FLAG_SATA) && | ||
3366 | !ata_link_offline(link) && | ||
3367 | time_before(now, nodev_deadline)) | ||
3368 | ready = 0; | ||
3369 | } | ||
3370 | |||
3371 | if (ready) | ||
3372 | return ready; | ||
3373 | if (time_after(now, deadline)) | ||
3374 | return -EBUSY; | ||
3375 | |||
3376 | if (!warned && time_after(now, start + 5 * HZ) && | ||
3377 | (deadline - now > 3 * HZ)) { | ||
3378 | ata_link_printk(link, KERN_WARNING, | ||
3379 | "link is slow to respond, please be patient " | ||
3380 | "(ready=%d)\n", tmp); | ||
3381 | warned = 1; | ||
3382 | } | ||
3383 | |||
3384 | msleep(50); | ||
3385 | } | ||
3386 | } | ||
3387 | |||
3388 | /** | ||
3389 | * ata_wait_after_reset - wait for link to become ready after reset | ||
3390 | * @link: link to be waited on | ||
3391 | * @deadline: deadline jiffies for the operation | ||
3392 | * @check_ready: callback to check link readiness | ||
3393 | * | ||
3394 | * Wait for @link to become ready after reset. | ||
3395 | * | ||
3396 | * LOCKING: | ||
3397 | * EH context. | ||
3398 | * | ||
3399 | * RETURNS: | ||
3400 | * 0 if @linke is ready before @deadline; otherwise, -errno. | ||
3401 | */ | ||
3402 | extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, | ||
3403 | int (*check_ready)(struct ata_link *link)) | ||
3404 | { | ||
3405 | msleep(ATA_WAIT_AFTER_RESET_MSECS); | ||
3406 | |||
3407 | return ata_wait_ready(link, deadline, check_ready); | ||
3408 | } | ||
3409 | |||
3410 | /** | ||
3314 | * sata_link_debounce - debounce SATA phy status | 3411 | * sata_link_debounce - debounce SATA phy status |
3315 | * @link: ATA link to debounce SATA phy status for | 3412 | * @link: ATA link to debounce SATA phy status for |
3316 | * @params: timing parameters { interval, duratinon, timeout } in msec | 3413 | * @params: timing parameters { interval, duratinon, timeout } in msec |
@@ -6075,6 +6172,7 @@ EXPORT_SYMBOL_GPL(ata_noop_qc_prep); | |||
6075 | EXPORT_SYMBOL_GPL(ata_port_probe); | 6172 | EXPORT_SYMBOL_GPL(ata_port_probe); |
6076 | EXPORT_SYMBOL_GPL(ata_dev_disable); | 6173 | EXPORT_SYMBOL_GPL(ata_dev_disable); |
6077 | EXPORT_SYMBOL_GPL(sata_set_spd); | 6174 | EXPORT_SYMBOL_GPL(sata_set_spd); |
6175 | EXPORT_SYMBOL_GPL(ata_wait_after_reset); | ||
6078 | EXPORT_SYMBOL_GPL(sata_link_debounce); | 6176 | EXPORT_SYMBOL_GPL(sata_link_debounce); |
6079 | EXPORT_SYMBOL_GPL(sata_link_resume); | 6177 | EXPORT_SYMBOL_GPL(sata_link_resume); |
6080 | EXPORT_SYMBOL_GPL(ata_std_prereset); | 6178 | EXPORT_SYMBOL_GPL(ata_std_prereset); |