]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/libata-eh.c
[libata] Improve timeout handling
[linux-2.6-omap-h63xx.git] / drivers / ata / libata-eh.c
index ea890911d4fa3f67863b8f52e7aebc258b4ce7e7..01831312c3607e3bc8aa98cfb42604e14cc3eba1 100644 (file)
@@ -547,7 +547,7 @@ void ata_scsi_error(struct Scsi_Host *host)
 
        /* For new EH, all qcs are finished in one of three ways -
         * normal completion, error completion, and SCSI timeout.
-        * Both cmpletions can race against SCSI timeout.  When normal
+        * Both completions can race against SCSI timeout.  When normal
         * completion wins, the qc never reaches EH.  When error
         * completion wins, the qc has ATA_QCFLAG_FAILED set.
         *
@@ -562,7 +562,19 @@ void ata_scsi_error(struct Scsi_Host *host)
                int nr_timedout = 0;
 
                spin_lock_irqsave(ap->lock, flags);
-
+               
+               /* This must occur under the ap->lock as we don't want
+                  a polled recovery to race the real interrupt handler
+                  
+                  The lost_interrupt handler checks for any completed but
+                  non-notified command and completes much like an IRQ handler.
+                  
+                  We then fall into the error recovery code which will treat
+                  this as if normal completion won the race */
+
+               if (ap->ops->lost_interrupt)
+                       ap->ops->lost_interrupt(ap);
+                       
                list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
                        struct ata_queued_cmd *qc;
 
@@ -606,6 +618,9 @@ void ata_scsi_error(struct Scsi_Host *host)
                ap->eh_tries = ATA_EH_MAX_TRIES;
        } else
                spin_unlock_wait(ap->lock);
+               
+       /* If we timed raced normal completion and there is nothing to
+          recover nr_timedout == 0 why exactly are we doing error recovery ? */
 
  repeat:
        /* invoke error handler */