linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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)




  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).