aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-scsi.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-01-22 23:09:37 -0500
committerJeff Garzik <jgarzik@pobox.com>2006-01-26 22:36:28 -0500
commita72ec4ce6d3ae92e76baf5b2c65cc26e5e775e83 (patch)
treef5a177cc30c9b39d8ae7dcad29d03d27534b9f78 /drivers/scsi/libata-scsi.c
parent041c5fc33cb7ed4fe5322585a611fb6e29a05d3a (diff)
[PATCH] libata: implement and apply ata_eh_qc_complete/retry()
Implement ata_eh_qc_complete/retry() using scsi_eh_finish_cmd() and scsi_eh_flush_done_q(). This removes all eh scsicmd finish hacks from low level drivers. This change was first suggested by Jeff Garzik. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r--drivers/scsi/libata-scsi.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 95e3c278dd43..ab6b53349d6f 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -738,17 +738,64 @@ int ata_scsi_error(struct Scsi_Host *host)
738 ap = (struct ata_port *) &host->hostdata[0]; 738 ap = (struct ata_port *) &host->hostdata[0];
739 ap->ops->eng_timeout(ap); 739 ap->ops->eng_timeout(ap);
740 740
741 /* TODO: this is per-command; when queueing is supported 741 assert(host->host_failed == 0 && list_empty(&host->eh_cmd_q));
742 * this code will either change or move to a more 742
743 * appropriate place 743 scsi_eh_flush_done_q(&ap->eh_done_q);
744 */
745 host->host_failed--;
746 INIT_LIST_HEAD(&host->eh_cmd_q);
747 744
748 DPRINTK("EXIT\n"); 745 DPRINTK("EXIT\n");
749 return 0; 746 return 0;
750} 747}
751 748
749static void ata_eh_scsidone(struct scsi_cmnd *scmd)
750{
751 /* nada */
752}
753
754static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
755{
756 struct ata_port *ap = qc->ap;
757 struct scsi_cmnd *scmd = qc->scsicmd;
758 unsigned long flags;
759
760 spin_lock_irqsave(&ap->host_set->lock, flags);
761 qc->scsidone = ata_eh_scsidone;
762 ata_qc_complete(qc);
763 assert(!ata_tag_valid(qc->tag));
764 spin_unlock_irqrestore(&ap->host_set->lock, flags);
765
766 scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
767}
768
769/**
770 * ata_eh_qc_complete - Complete an active ATA command from EH
771 * @qc: Command to complete
772 *
773 * Indicate to the mid and upper layers that an ATA command has
774 * completed. To be used from EH.
775 */
776void ata_eh_qc_complete(struct ata_queued_cmd *qc)
777{
778 struct scsi_cmnd *scmd = qc->scsicmd;
779 scmd->retries = scmd->allowed;
780 __ata_eh_qc_complete(qc);
781}
782
783/**
784 * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
785 * @qc: Command to retry
786 *
787 * Indicate to the mid and upper layers that an ATA command
788 * should be retried. To be used from EH.
789 *
790 * SCSI midlayer limits the number of retries to scmd->allowed.
791 * This function might need to adjust scmd->retries for commands
792 * which get retried due to unrelated NCQ failures.
793 */
794void ata_eh_qc_retry(struct ata_queued_cmd *qc)
795{
796 __ata_eh_qc_complete(qc);
797}
798
752/** 799/**
753 * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command 800 * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
754 * @qc: Storage for translated ATA taskfile 801 * @qc: Storage for translated ATA taskfile