From: Albert Lee <albertcc@tw.ibm.com>
To: Jeff Garzik <jgarzik@pobox.com>
Cc: Linux IDE <linux-ide@vger.kernel.org>,
Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>,
Doug Maxey <dwm@maxeymade.com>, Tejun Heo <htejun@gmail.com>
Subject: [PATCH/RFC 3/3] libata: check qc->err_mask for the internal commands
Date: Wed, 09 Nov 2005 13:12:03 +0800 [thread overview]
Message-ID: <43718523.1000408@tw.ibm.com> (raw)
In-Reply-To: <437181D5.8070903@tw.ibm.com>
Patch 3/3:
check qc->err_mask for the internal commands.
Problem:
The results of internal commands issued by libata itself were not checked.
For example, ata_dev_identify() only checks the device status (qc->tf.command).
However, checking the device status is not enough to detect all errors.
Changes:
- check qc->err_mask for the internal commands:
- ata_dev_identify()
- ata_dev_set_xfermode()
- ata_dev_reread_id()
- ata_dev_init_params()
- atapi_request_sense()
The patch accesses qc (and ap) after the qc is completed.
This is bad from the object life cycle point of view and might cause race.
However, since libata has complete control over the hardware when libata issues the internal commands
and it seems noboby else may issue command at the same time,
accessing qc after ata_qc_complete() looks to be ok here.
p.s.
The patch above can also make ata_dev_identify() detect the
"phantom slave device" problem.
The "phantom slave device" was seen in specific PATA master-only configuration.
The master device responds to some commands issued to the slave device, and
make a illusion that the slave device exists.
The device status register of the "phantom slave device" always read as zero.
So, using (qc->tf.command & ATA_ERR) cannot detect the error.
Checking qc->err_mask can make ata_dev_identify() detect such
"phantom slave device" and exclude the phantom device.
For your review and advice, thanks.
Albert
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
============
--- err_mask/drivers/scsi/libata-core.c 2005-11-09 10:15:33.000000000 +0800
+++ phantom/drivers/scsi/libata-core.c 2005-11-09 10:15:54.000000000 +0800
@@ -1132,7 +1132,7 @@ retry:
ap->ops->tf_read(ap, &qc->tf);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
- if (qc->tf.command & ATA_ERR) {
+ if (qc->err_mask) {
/*
* arg! EDD works for all test cases, but seems to return
* the ATA signature for some ATAPI devices. Until the
@@ -1144,8 +1144,10 @@ retry:
* ATA software reset (SRST, the default) does not appear
* to have this problem.
*/
- if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
+ if ((using_edd) && (dev->class == ATA_DEV_ATA) &&
+ (qc->tf.command & ATA_ERR)) {
u8 err = qc->tf.feature;
+
if (err & ATA_ABORTED) {
dev->class = ATA_DEV_ATAPI;
qc->cursg = 0;
@@ -2267,11 +2269,19 @@ static void ata_dev_set_xfermode(struct
spin_unlock_irqrestore(&ap->host_set->lock, flags);
if (rc)
- ata_port_disable(ap);
- else
- wait_for_completion(&wait);
+ goto err_out;
+
+ wait_for_completion(&wait);
+
+ if (qc->err_mask)
+ goto err_out;
DPRINTK("EXIT\n");
+
+ return;
+err_out:
+ printk(KERN_ERR "ata%u: set XFER MODE failed\n", ap->id);
+ ata_port_disable(ap);
}
/**
@@ -2319,6 +2329,9 @@ static void ata_dev_reread_id(struct ata
wait_for_completion(&wait);
+ if (qc->err_mask)
+ goto err_out;
+
swap_buf_le16(dev->id, ATA_ID_WORDS);
ata_dump_id(dev);
@@ -2327,6 +2340,7 @@ static void ata_dev_reread_id(struct ata
return;
err_out:
+ printk(KERN_ERR "ata%u: reread IDENTIFY device data failed\n", ap->id);
ata_port_disable(ap);
}
@@ -2371,11 +2385,19 @@ static void ata_dev_init_params(struct a
spin_unlock_irqrestore(&ap->host_set->lock, flags);
if (rc)
- ata_port_disable(ap);
- else
- wait_for_completion(&wait);
+ goto err_out;
+
+ wait_for_completion(&wait);
+
+ if (qc->err_mask)
+ goto err_out;
DPRINTK("EXIT\n");
+
+ return;
+err_out:
+ printk(KERN_ERR "ata%u: init CHS dev params failed\n", ap->id);
+ ata_port_disable(ap);
}
/**
--- err_mask/drivers/scsi/libata-scsi.c 2005-11-08 16:25:51.000000000 +0800
+++ phantom/drivers/scsi/libata-scsi.c 2005-11-09 10:37:39.000000000 +0800
@@ -2008,11 +2008,19 @@ void atapi_request_sense(struct ata_port
spin_unlock_irqrestore(&ap->host_set->lock, flags);
if (rc)
- ata_port_disable(ap);
- else
- wait_for_completion(&wait);
+ goto err_out;
+
+ wait_for_completion(&wait);
+
+ if (qc->err_mask)
+ goto err_out;
DPRINTK("EXIT\n");
+
+ return;
+err_out:
+ printk(KERN_ERR "ata%u: atapi request sense failed\n", ap->id);
+ ata_port_disable(ap);
}
static int atapi_qc_complete(struct ata_queued_cmd *qc)
next prev parent reply other threads:[~2005-11-09 5:12 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-09 4:57 [PATCH/RFC 0/3] libata: misc fixes Albert Lee
2005-11-09 5:03 ` [PATCH 1/3] libata: if condition fix for ata_dev_identify() Albert Lee
2005-11-09 5:07 ` [PATCH/RFC 2/3] libata: move err_mask to ata_queued_cmd Albert Lee
2005-11-09 6:25 ` Jeff Garzik
2005-11-10 7:56 ` [PATCH/RFC 0/4] libata: move err_mask to ata_queued_cmd (revised) Albert Lee
2005-11-10 7:59 ` [PATCH/RFC 1/4] libata: minor patch before moving err_mask Albert Lee
2005-11-10 8:01 ` [PATCH/RFC 2/4] libata: move err_mask to ata_queued_cmd Albert Lee
2005-11-10 8:03 ` [PATCH/RFC 3/4] libata: determine the err_mask when the error is found Albert Lee
2005-11-10 8:05 ` [PATCH/RFC 4/4] libata: determine the err_mask directly in atapi_packet_task() Albert Lee
2005-12-04 2:01 ` [PATCH/RFC 0/4] libata: move err_mask to ata_queued_cmd (revised) Jeff Garzik
2005-12-05 6:58 ` [PATCH 0/4] libata: move err_mask to ata_queued_cmd (revised #2) Albert Lee
2005-12-05 7:36 ` [PATCH 1/4] libata: minor patch before moving err_mask Albert Lee
2005-12-05 7:38 ` [PATCH 2/4] libata: move err_mask to ata_queued_cmd Albert Lee
2005-12-05 7:40 ` [PATCH 3/4] libata: determine the err_mask when the error is found Albert Lee
2005-12-05 7:42 ` [PATCH 4/4] libata: determine the err_mask directly in atapi_packet_task() Albert Lee
2005-12-06 3:34 ` [PATCH/RFC 1/1] libata: err_mask misc fix Albert Lee
2005-12-12 20:26 ` Jeff Garzik
2005-11-09 5:12 ` Albert Lee [this message]
2005-11-09 6:31 ` [PATCH/RFC 3/3] libata: check qc->err_mask for the internal commands Jeff Garzik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43718523.1000408@tw.ibm.com \
--to=albertcc@tw.ibm.com \
--cc=bzolnier@gmail.com \
--cc=dwm@maxeymade.com \
--cc=htejun@gmail.com \
--cc=jgarzik@pobox.com \
--cc=linux-ide@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).