aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-05-19 13:17:54 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-07-14 15:59:32 -0400
commit87fbc5a060faf2394bee88a93519f9b9d434727c (patch)
tree6f90cacb1471e64051473c4e1e664b2dea8603e0 /drivers/ata/libata-core.c
parentd8af0eb6046c56e7238171ca420622541db24926 (diff)
libata: improve EH internal command timeout handling
ATA_TMOUT_INTERNAL which was 30secs were used for all internal commands which is way too long when something goes wrong. This patch implements command type based stepped timeouts. Different command types can use different timeouts and each command type can use different timeout values after timeouts. ie. the initial timeout is set to a value which should cover most of the cases but not too long so that run away cases don't delay things too much. After the first try times out, the second try can use longer timeout and if that one times out too, it can go for full 30sec timeout. IDENTIFYs use 5s - 10s - 30s timeout and all other commands use 5s - 10s timeouts. This patch significantly cuts down the needed time to handle failure cases while still allowing libata to work with nut job devices through retries. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index c5c3b1b516e1..9bef1a84fe3f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -144,7 +144,7 @@ static int libata_dma_mask = ATA_DMA_MASK_ATA|ATA_DMA_MASK_ATAPI|ATA_DMA_MASK_CF
144module_param_named(dma, libata_dma_mask, int, 0444); 144module_param_named(dma, libata_dma_mask, int, 0444);
145MODULE_PARM_DESC(dma, "DMA enable/disable (0x1==ATA, 0x2==ATAPI, 0x4==CF)"); 145MODULE_PARM_DESC(dma, "DMA enable/disable (0x1==ATA, 0x2==ATAPI, 0x4==CF)");
146 146
147static int ata_probe_timeout = ATA_TMOUT_INTERNAL / 1000; 147static int ata_probe_timeout;
148module_param(ata_probe_timeout, int, 0444); 148module_param(ata_probe_timeout, int, 0444);
149MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); 149MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
150 150
@@ -1611,6 +1611,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
1611 struct ata_link *link = dev->link; 1611 struct ata_link *link = dev->link;
1612 struct ata_port *ap = link->ap; 1612 struct ata_port *ap = link->ap;
1613 u8 command = tf->command; 1613 u8 command = tf->command;
1614 int auto_timeout = 0;
1614 struct ata_queued_cmd *qc; 1615 struct ata_queued_cmd *qc;
1615 unsigned int tag, preempted_tag; 1616 unsigned int tag, preempted_tag;
1616 u32 preempted_sactive, preempted_qc_active; 1617 u32 preempted_sactive, preempted_qc_active;
@@ -1683,8 +1684,14 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
1683 1684
1684 spin_unlock_irqrestore(ap->lock, flags); 1685 spin_unlock_irqrestore(ap->lock, flags);
1685 1686
1686 if (!timeout) 1687 if (!timeout) {
1687 timeout = ata_probe_timeout * 1000; 1688 if (ata_probe_timeout)
1689 timeout = ata_probe_timeout * 1000;
1690 else {
1691 timeout = ata_internal_cmd_timeout(dev, command);
1692 auto_timeout = 1;
1693 }
1694 }
1688 1695
1689 rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout)); 1696 rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout));
1690 1697
@@ -1760,6 +1767,9 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
1760 1767
1761 spin_unlock_irqrestore(ap->lock, flags); 1768 spin_unlock_irqrestore(ap->lock, flags);
1762 1769
1770 if ((err_mask & AC_ERR_TIMEOUT) && auto_timeout)
1771 ata_internal_cmd_timed_out(dev, command);
1772
1763 return err_mask; 1773 return err_mask;
1764} 1774}
1765 1775