aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_amd.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-02-02 02:50:52 -0500
committerJeff Garzik <jeff@garzik.org>2007-05-01 07:49:53 -0400
commitd4b2bab4f26345ea1803feb23ea92fbe3f6b77bc (patch)
tree30a9826351e597828de2b402f1c41b9fca94cf95 /drivers/ata/pata_amd.c
parentdc87c3985e9b442c60994308a96f887579addc39 (diff)
libata: add deadline support to prereset and reset methods
Add @deadline to prereset and reset methods and make them honor it. ata_wait_ready() which directly takes @deadline is implemented to be used as the wait function. This patch is in preparation for EH timing improvements. * ata_wait_ready() never does busy sleep. It's only used from EH and no wait in EH is that urgent. This function also prints 'be patient' message automatically after 5 secs of waiting if more than 3 secs is remaining till deadline. * ata_bus_post_reset() now fails with error code if any of its wait fails. This is important because earlier reset tries will have shorter timeout than the spec requires. If a device fails to respond before the short timeout, reset should be retried with longer timeout rather than silently ignoring the device. There are three behavior differences. 1. Timeout is applied to both devices at once, not separately. This is more consistent with what the spec says. 2. When a device passes devchk but fails to become ready before deadline. Previouly, post_reset would just succeed and let device classification remove the device. New code fails the reset thus causing reset retry. After a few times, EH will give up disabling the port. 3. When slave device passes devchk but fails to become accessible (TF-wise) after reset. Original code disables dev1 after 30s timeout and continues as if the device doesn't exist, while the patched code fails reset. When this happens, new code fails reset on whole port rather than proceeding with only the primary device. If the failing device is suffering transient problems, new code retries reset which is a better behavior. If the failing device is actually broken, the net effect is identical to it, but not to the other device sharing the channel. In the previous code, reset would have succeeded after 30s thus detecting the working one. In the new code, reset fails and whole port gets disabled. IMO, it's a pathological case anyway (broken device sharing bus with working one) and doesn't really matter. * ata_bus_softreset() is changed to return error code from ata_bus_post_reset(). It used to return 0 unconditionally. * Spin up waiting is to be removed and not converted to honor deadline. * To be on the safe side, deadline is set to 40s for the time being. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/pata_amd.c')
-rw-r--r--drivers/ata/pata_amd.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 536ee892ab72..67c7e87dec04 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -121,12 +121,13 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
121/** 121/**
122 * amd_probe_init - perform reset handling 122 * amd_probe_init - perform reset handling
123 * @ap: ATA port 123 * @ap: ATA port
124 * @deadline: deadline jiffies for the operation
124 * 125 *
125 * Reset sequence checking enable bits to see which ports are 126 * Reset sequence checking enable bits to see which ports are
126 * active. 127 * active.
127 */ 128 */
128 129
129static int amd_pre_reset(struct ata_port *ap) 130static int amd_pre_reset(struct ata_port *ap, unsigned long deadline)
130{ 131{
131 static const struct pci_bits amd_enable_bits[] = { 132 static const struct pci_bits amd_enable_bits[] = {
132 { 0x40, 1, 0x02, 0x02 }, 133 { 0x40, 1, 0x02, 0x02 },
@@ -138,8 +139,7 @@ static int amd_pre_reset(struct ata_port *ap)
138 if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) 139 if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
139 return -ENOENT; 140 return -ENOENT;
140 141
141 return ata_std_prereset(ap); 142 return ata_std_prereset(ap, deadline);
142
143} 143}
144 144
145static void amd_error_handler(struct ata_port *ap) 145static void amd_error_handler(struct ata_port *ap)
@@ -227,7 +227,8 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
227 * space for us. 227 * space for us.
228 */ 228 */
229 229
230static int nv_pre_reset(struct ata_port *ap) { 230static int nv_pre_reset(struct ata_port *ap, unsigned long deadline)
231{
231 static const struct pci_bits nv_enable_bits[] = { 232 static const struct pci_bits nv_enable_bits[] = {
232 { 0x50, 1, 0x02, 0x02 }, 233 { 0x50, 1, 0x02, 0x02 },
233 { 0x50, 1, 0x01, 0x01 } 234 { 0x50, 1, 0x01, 0x01 }
@@ -238,7 +239,7 @@ static int nv_pre_reset(struct ata_port *ap) {
238 if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no])) 239 if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
239 return -ENOENT; 240 return -ENOENT;
240 241
241 return ata_std_prereset(ap); 242 return ata_std_prereset(ap, deadline);
242} 243}
243 244
244static void nv_error_handler(struct ata_port *ap) 245static void nv_error_handler(struct ata_port *ap)