aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-eh.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 073b88156b3c..df3f3140c9c7 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -587,7 +587,6 @@ static void ata_eh_unload(struct ata_port *ap)
587void ata_scsi_error(struct Scsi_Host *host) 587void ata_scsi_error(struct Scsi_Host *host)
588{ 588{
589 struct ata_port *ap = ata_shost_to_port(host); 589 struct ata_port *ap = ata_shost_to_port(host);
590 int i;
591 unsigned long flags; 590 unsigned long flags;
592 LIST_HEAD(eh_work_q); 591 LIST_HEAD(eh_work_q);
593 592
@@ -597,6 +596,34 @@ void ata_scsi_error(struct Scsi_Host *host)
597 list_splice_init(&host->eh_cmd_q, &eh_work_q); 596 list_splice_init(&host->eh_cmd_q, &eh_work_q);
598 spin_unlock_irqrestore(host->host_lock, flags); 597 spin_unlock_irqrestore(host->host_lock, flags);
599 598
599 ata_scsi_cmd_error_handler(host, ap, &eh_work_q);
600
601 /* If we timed raced normal completion and there is nothing to
602 recover nr_timedout == 0 why exactly are we doing error recovery ? */
603 ata_scsi_port_error_handler(host, ap);
604
605 /* finish or retry handled scmd's and clean up */
606 WARN_ON(host->host_failed || !list_empty(&eh_work_q));
607
608 DPRINTK("EXIT\n");
609}
610
611/**
612 * ata_scsi_cmd_error_handler - error callback for a list of commands
613 * @host: scsi host containing the port
614 * @ap: ATA port within the host
615 * @eh_work_q: list of commands to process
616 *
617 * process the given list of commands and return those finished to the
618 * ap->eh_done_q. This function is the first part of the libata error
619 * handler which processes a given list of failed commands.
620 */
621void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
622 struct list_head *eh_work_q)
623{
624 int i;
625 unsigned long flags;
626
600 /* make sure sff pio task is not running */ 627 /* make sure sff pio task is not running */
601 ata_sff_flush_pio_task(ap); 628 ata_sff_flush_pio_task(ap);
602 629
@@ -632,7 +659,7 @@ void ata_scsi_error(struct Scsi_Host *host)
632 if (ap->ops->lost_interrupt) 659 if (ap->ops->lost_interrupt)
633 ap->ops->lost_interrupt(ap); 660 ap->ops->lost_interrupt(ap);
634 661
635 list_for_each_entry_safe(scmd, tmp, &eh_work_q, eh_entry) { 662 list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) {
636 struct ata_queued_cmd *qc; 663 struct ata_queued_cmd *qc;
637 664
638 for (i = 0; i < ATA_MAX_QUEUE; i++) { 665 for (i = 0; i < ATA_MAX_QUEUE; i++) {
@@ -676,8 +703,20 @@ void ata_scsi_error(struct Scsi_Host *host)
676 } else 703 } else
677 spin_unlock_wait(ap->lock); 704 spin_unlock_wait(ap->lock);
678 705
679 /* If we timed raced normal completion and there is nothing to 706}
680 recover nr_timedout == 0 why exactly are we doing error recovery ? */ 707EXPORT_SYMBOL(ata_scsi_cmd_error_handler);
708
709/**
710 * ata_scsi_port_error_handler - recover the port after the commands
711 * @host: SCSI host containing the port
712 * @ap: the ATA port
713 *
714 * Handle the recovery of the port @ap after all the commands
715 * have been recovered.
716 */
717void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)
718{
719 unsigned long flags;
681 720
682 /* invoke error handler */ 721 /* invoke error handler */
683 if (ap->ops->error_handler) { 722 if (ap->ops->error_handler) {
@@ -766,9 +805,6 @@ void ata_scsi_error(struct Scsi_Host *host)
766 ap->ops->eng_timeout(ap); 805 ap->ops->eng_timeout(ap);
767 } 806 }
768 807
769 /* finish or retry handled scmd's and clean up */
770 WARN_ON(host->host_failed || !list_empty(&eh_work_q));
771
772 scsi_eh_flush_done_q(&ap->eh_done_q); 808 scsi_eh_flush_done_q(&ap->eh_done_q);
773 809
774 /* clean up */ 810 /* clean up */
@@ -789,9 +825,8 @@ void ata_scsi_error(struct Scsi_Host *host)
789 wake_up_all(&ap->eh_wait_q); 825 wake_up_all(&ap->eh_wait_q);
790 826
791 spin_unlock_irqrestore(ap->lock, flags); 827 spin_unlock_irqrestore(ap->lock, flags);
792
793 DPRINTK("EXIT\n");
794} 828}
829EXPORT_SYMBOL_GPL(ata_scsi_port_error_handler);
795 830
796/** 831/**
797 * ata_port_wait_eh - Wait for the currently pending EH to complete 832 * ata_port_wait_eh - Wait for the currently pending EH to complete