aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 6780f4d16e81..5e590504f3aa 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -463,6 +463,41 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
463} 463}
464 464
465/** 465/**
466 * ata_eh_acquire - acquire EH ownership
467 * @ap: ATA port to acquire EH ownership for
468 *
469 * Acquire EH ownership for @ap. This is the basic exclusion
470 * mechanism for ports sharing a host. Only one port hanging off
471 * the same host can claim the ownership of EH.
472 *
473 * LOCKING:
474 * EH context.
475 */
476void ata_eh_acquire(struct ata_port *ap)
477{
478 mutex_lock(&ap->host->eh_mutex);
479 WARN_ON_ONCE(ap->host->eh_owner);
480 ap->host->eh_owner = current;
481}
482
483/**
484 * ata_eh_release - release EH ownership
485 * @ap: ATA port to release EH ownership for
486 *
487 * Release EH ownership for @ap if the caller. The caller must
488 * have acquired EH ownership using ata_eh_acquire() previously.
489 *
490 * LOCKING:
491 * EH context.
492 */
493void ata_eh_release(struct ata_port *ap)
494{
495 WARN_ON_ONCE(ap->host->eh_owner != current);
496 ap->host->eh_owner = NULL;
497 mutex_unlock(&ap->host->eh_mutex);
498}
499
500/**
466 * ata_scsi_timed_out - SCSI layer time out callback 501 * ata_scsi_timed_out - SCSI layer time out callback
467 * @cmd: timed out SCSI command 502 * @cmd: timed out SCSI command
468 * 503 *
@@ -639,11 +674,13 @@ void ata_scsi_error(struct Scsi_Host *host)
639 /* If we timed raced normal completion and there is nothing to 674 /* If we timed raced normal completion and there is nothing to
640 recover nr_timedout == 0 why exactly are we doing error recovery ? */ 675 recover nr_timedout == 0 why exactly are we doing error recovery ? */
641 676
642 repeat:
643 /* invoke error handler */ 677 /* invoke error handler */
644 if (ap->ops->error_handler) { 678 if (ap->ops->error_handler) {
645 struct ata_link *link; 679 struct ata_link *link;
646 680
681 /* acquire EH ownership */
682 ata_eh_acquire(ap);
683 repeat:
647 /* kill fast drain timer */ 684 /* kill fast drain timer */
648 del_timer_sync(&ap->fastdrain_timer); 685 del_timer_sync(&ap->fastdrain_timer);
649 686
@@ -718,6 +755,7 @@ void ata_scsi_error(struct Scsi_Host *host)
718 host->host_eh_scheduled = 0; 755 host->host_eh_scheduled = 0;
719 756
720 spin_unlock_irqrestore(ap->lock, flags); 757 spin_unlock_irqrestore(ap->lock, flags);
758 ata_eh_release(ap);
721 } else { 759 } else {
722 WARN_ON(ata_qc_from_tag(ap, ap->link.active_tag) == NULL); 760 WARN_ON(ata_qc_from_tag(ap, ap->link.active_tag) == NULL);
723 ap->ops->eng_timeout(ap); 761 ap->ops->eng_timeout(ap);
@@ -2818,8 +2856,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
2818 "reset failed (errno=%d), retrying in %u secs\n", 2856 "reset failed (errno=%d), retrying in %u secs\n",
2819 rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000)); 2857 rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000));
2820 2858
2859 ata_eh_release(ap);
2821 while (delta) 2860 while (delta)
2822 delta = schedule_timeout_uninterruptible(delta); 2861 delta = schedule_timeout_uninterruptible(delta);
2862 ata_eh_acquire(ap);
2823 } 2863 }
2824 2864
2825 if (try == max_tries - 1) { 2865 if (try == max_tries - 1) {
@@ -3635,8 +3675,10 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3635 if (time_before_eq(deadline, now)) 3675 if (time_before_eq(deadline, now))
3636 break; 3676 break;
3637 3677
3678 ata_eh_release(ap);
3638 deadline = wait_for_completion_timeout(&ap->park_req_pending, 3679 deadline = wait_for_completion_timeout(&ap->park_req_pending,
3639 deadline - now); 3680 deadline - now);
3681 ata_eh_acquire(ap);
3640 } while (deadline); 3682 } while (deadline);
3641 ata_for_each_link(link, ap, EDGE) { 3683 ata_for_each_link(link, ap, EDGE) {
3642 ata_for_each_dev(dev, link, ALL) { 3684 ata_for_each_dev(dev, link, ALL) {