diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-11-17 10:50:01 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-11-17 10:50:01 -0500 |
commit | 64f043d80752a8e5f0d55255e7bb9a1a05af206f (patch) | |
tree | 3dc2a2511e29f6d8e2b26884ea090ce5d8c9f6c2 | |
parent | 556c66db0794b9b85481cb5e3cb57688eabad982 (diff) |
[libata] add timeout to commands for which we call wait_completion()
-rw-r--r-- | drivers/scsi/libata-core.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index bb604dfbdef6..665ae79e1fd6 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1046,6 +1046,30 @@ static unsigned int ata_pio_modes(const struct ata_device *adev) | |||
1046 | return modes; | 1046 | return modes; |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | static int ata_qc_wait_err(struct ata_queued_cmd *qc, | ||
1050 | struct completion *wait) | ||
1051 | { | ||
1052 | int rc = 0; | ||
1053 | |||
1054 | if (wait_for_completion_timeout(wait, 30 * HZ) < 1) { | ||
1055 | /* timeout handling */ | ||
1056 | unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap)); | ||
1057 | |||
1058 | if (!err_mask) { | ||
1059 | printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n", | ||
1060 | qc->ap->id, qc->tf.command); | ||
1061 | } else { | ||
1062 | printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n", | ||
1063 | qc->ap->id, qc->tf.command); | ||
1064 | rc = -EIO; | ||
1065 | } | ||
1066 | |||
1067 | ata_qc_complete(qc, err_mask); | ||
1068 | } | ||
1069 | |||
1070 | return rc; | ||
1071 | } | ||
1072 | |||
1049 | /** | 1073 | /** |
1050 | * ata_dev_identify - obtain IDENTIFY x DEVICE page | 1074 | * ata_dev_identify - obtain IDENTIFY x DEVICE page |
1051 | * @ap: port on which device we wish to probe resides | 1075 | * @ap: port on which device we wish to probe resides |
@@ -1125,7 +1149,7 @@ retry: | |||
1125 | if (rc) | 1149 | if (rc) |
1126 | goto err_out; | 1150 | goto err_out; |
1127 | else | 1151 | else |
1128 | wait_for_completion(&wait); | 1152 | ata_qc_wait_err(qc, &wait); |
1129 | 1153 | ||
1130 | spin_lock_irqsave(&ap->host_set->lock, flags); | 1154 | spin_lock_irqsave(&ap->host_set->lock, flags); |
1131 | ap->ops->tf_read(ap, &qc->tf); | 1155 | ap->ops->tf_read(ap, &qc->tf); |
@@ -2269,7 +2293,7 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
2269 | if (rc) | 2293 | if (rc) |
2270 | ata_port_disable(ap); | 2294 | ata_port_disable(ap); |
2271 | else | 2295 | else |
2272 | wait_for_completion(&wait); | 2296 | ata_qc_wait_err(qc, &wait); |
2273 | 2297 | ||
2274 | DPRINTK("EXIT\n"); | 2298 | DPRINTK("EXIT\n"); |
2275 | } | 2299 | } |
@@ -2317,7 +2341,7 @@ static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev) | |||
2317 | if (rc) | 2341 | if (rc) |
2318 | goto err_out; | 2342 | goto err_out; |
2319 | 2343 | ||
2320 | wait_for_completion(&wait); | 2344 | ata_qc_wait_err(qc, &wait); |
2321 | 2345 | ||
2322 | swap_buf_le16(dev->id, ATA_ID_WORDS); | 2346 | swap_buf_le16(dev->id, ATA_ID_WORDS); |
2323 | 2347 | ||
@@ -2373,7 +2397,7 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) | |||
2373 | if (rc) | 2397 | if (rc) |
2374 | ata_port_disable(ap); | 2398 | ata_port_disable(ap); |
2375 | else | 2399 | else |
2376 | wait_for_completion(&wait); | 2400 | ata_qc_wait_err(qc, &wait); |
2377 | 2401 | ||
2378 | DPRINTK("EXIT\n"); | 2402 | DPRINTK("EXIT\n"); |
2379 | } | 2403 | } |