aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-11-17 10:50:01 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-17 10:50:01 -0500
commit64f043d80752a8e5f0d55255e7bb9a1a05af206f (patch)
tree3dc2a2511e29f6d8e2b26884ea090ce5d8c9f6c2 /drivers
parent556c66db0794b9b85481cb5e3cb57688eabad982 (diff)
[libata] add timeout to commands for which we call wait_completion()
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/libata-core.c32
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
1049static 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}