All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jon Escombe <lists@dresco.co.uk>
To: linux-kernel@vger.kernel.org
Cc: jgarzik@pobox.com
Subject: Re: [patch] libata passthrough - return register data from HDIO_* commands
Date: Mon, 15 Aug 2005 23:11:02 +0100	[thread overview]
Message-ID: <430112F6.3090906@dresco.co.uk> (raw)
In-Reply-To: <42FE2FBA.3000605@dresco.co.uk>

[-- Attachment #1: Type: text/plain, Size: 1244 bytes --]


> Here is a first attempt at a patch to return register data from the 
> libata passthrough HDIO ioctl handlers, I needed this as the ATA 
> 'unload immediate' command returns the success in the lbal register. 
> This patch applies on top of 2.6.12 and Jeffs 
> 2.6.12-git4-passthru1.patch. (Apologies, but Thunderbird appears to 
> have replaced the tabs with spaces).
>
> One oddity is that the sr_result field is correctly being set in 
> ata_gen_ata_desc_sense(), however the high word is different when 
> we're back in the ioctl hander. I've coded round this for now by only 
> checking the low word, but this needs more investigation.
>
> Jeff, could this functionality be incorporated into the pasthrough 
> patch when complete?


I'd failed to realise that scsi_finish_command() sets the high byte of 
the result field to DRIVER_SENSE when there is sense data. Patch updated 
to reflect this...

Haven't had any feedback on the patch itself - but this now does what I 
wanted it do to.  (I can't find a way to make Thunderbird retain tabs in 
the message body, so sending as an attachment).

Regards,
Jon.



______________________________________________________________
Email via Mailtraq4Free from Enstar (www.mailtraqdirect.co.uk)

[-- Attachment #2: passthrough_check_condition.patch --]
[-- Type: text/x-patch, Size: 3001 bytes --]

--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -89,6 +89,7 @@
 	u8 args[4], *argbuf = NULL;
 	int argsize = 0;
 	struct scsi_request *sreq;
+	unsigned char *sb, *desc;
 
 	if (NULL == (void *)arg)
 		return -EINVAL;
@@ -100,6 +101,9 @@
 	if (!sreq)
 		return -EINTR;
 
+	sb = sreq->sr_sense_buffer;
+	desc = sb + 8;
+
 	memset(scsi_cmd, 0, sizeof(scsi_cmd));
 
 	if (args[3]) {
@@ -109,12 +113,12 @@
 			return -ENOMEM;
 
 		scsi_cmd[1]  = (4 << 1); /* PIO Data-in */
-		scsi_cmd[2]  = 0x0e;     /* no off.line or cc, read from dev,
+		scsi_cmd[2]  = 0x2e;     /* no off.line, read from dev, request cc
 		                            block count in sector count field */
 		sreq->sr_data_direction = DMA_FROM_DEVICE;
 	} else {
 		scsi_cmd[1]  = (3 << 1); /* Non-data */
-		/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+		scsi_cmd[2]  = 0x20;     /* no off.line or data xfer, request check condtion */
 		sreq->sr_data_direction = DMA_NONE;
 	}
 
@@ -135,16 +139,24 @@
 	   from scsi_ioctl_send_command() for default case... */
 	scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5);
 
-	if (sreq->sr_result) {
+	if (!sreq->sr_result == ((DRIVER_SENSE << 24) + SAM_STAT_CHECK_CONDITION)) {
 		rc = -EIO;
 		goto error;
 	}
 
-	/* Need code to retrieve data from check condition? */
+	/* Retrieve data from check condition */
+	args[1] = desc[3];
+	args[2] = desc[5];
+	args[3] = desc[7];
+	args[4] = desc[9];
+	args[5] = desc[11];
+	args[0] = desc[13];
 
 	if ((argbuf)
 	 && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
 		rc = -EFAULT;
+	if (copy_to_user(arg, args, sizeof(args)))
+		rc = -EFAULT;
 error:
 	scsi_release_request(sreq);
 
@@ -171,6 +183,7 @@
 	u8 scsi_cmd[MAX_COMMAND_SIZE];
 	u8 args[7];
 	struct scsi_request *sreq;
+	unsigned char *sb, *desc;
 
 	if (NULL == (void *)arg)
 		return -EINVAL;
@@ -181,7 +194,7 @@
 	memset(scsi_cmd, 0, sizeof(scsi_cmd));
 	scsi_cmd[0]  = ATA_16;
 	scsi_cmd[1]  = (3 << 1); /* Non-data */
-	/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+	scsi_cmd[2]  = 0x20;     /* no off.line, or data xfer, request cc */
 	scsi_cmd[4]  = args[1];
 	scsi_cmd[6]  = args[2];
 	scsi_cmd[8]  = args[3];
@@ -195,18 +208,29 @@
 		goto error;
 	}
 
+	sb = sreq->sr_sense_buffer;
+	desc = sb + 8;
+
 	sreq->sr_data_direction = DMA_NONE;
 	/* Good values for timeout and retries?  Values below
 	   from scsi_ioctl_send_command() for default case... */
 	scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5);
 
-	if (sreq->sr_result) {
+	if (!sreq->sr_result == ((DRIVER_SENSE << 24) + SAM_STAT_CHECK_CONDITION)) {
 		rc = -EIO;
 		goto error;
 	}
 
-	/* Need code to retrieve data from check condition? */
+	/* Retrieve data from check condition */
+	args[1] = desc[3];
+	args[2] = desc[5];
+	args[3] = desc[7];
+	args[4] = desc[9];
+	args[5] = desc[11];
+	args[0] = desc[13];
 
+	if (copy_to_user(arg, args, sizeof(args)))
+		rc = -EFAULT;
 error:
 	scsi_release_request(sreq);
 	return rc;

  reply	other threads:[~2005-08-15 22:12 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-08-13 17:36 [patch] libata passthrough - return register data from HDIO_* commands Jon Escombe
2005-08-15 22:11 ` Jon Escombe [this message]
2005-08-19 19:06   ` John W. Linville
2005-08-19 19:19     ` John W. Linville
2005-08-19 19:31       ` Jon Escombe
2005-08-19 20:06         ` John W. Linville
2005-08-22  4:43   ` 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=430112F6.3090906@dresco.co.uk \
    --to=lists@dresco.co.uk \
    --cc=jgarzik@pobox.com \
    --cc=linux-kernel@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.