From: Jeff Raubitschek <jhr@google.com>
To: Jeff Garzik <jgarzik@pobox.com>
Cc: linux-ide@vger.kernel.org
Subject: [PATCH libata-dev-2.6:passthru] passthru fixes
Date: Tue, 13 Sep 2005 07:26:36 -0700 [thread overview]
Message-ID: <20050913142636.GB5679@google.com> (raw)
Fix a few problems seen with the passthru branch:
- leaked scsi_request on buffer allocate failure
- passthru sense routines were refering to tf->command
which is not read in tf_read, instead use drv_stat for
status register.
- passthru sense passed back to user on ata_task_ioctl
Patch is against the current libata-dev passthru branch.
Signed-off-by: Jeff Raubitschek <jhr@google.com>
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -116,8 +116,10 @@ int ata_cmd_ioctl(struct scsi_device *sc
if (args[3]) {
argsize = SECTOR_SIZE * args[3];
argbuf = kmalloc(argsize, GFP_KERNEL);
- if (argbuf == NULL)
- return -ENOMEM;
+ if (argbuf == NULL) {
+ rc = -ENOMEM;
+ goto error;
+ }
scsi_cmd[1] = (4 << 1); /* PIO Data-in */
scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev,
@@ -182,6 +184,7 @@ int ata_task_ioctl(struct scsi_device *s
u8 scsi_cmd[MAX_COMMAND_SIZE];
u8 args[7];
struct scsi_request *sreq;
+ unsigned char *sb;
if (NULL == (void *)arg)
return -EINVAL;
@@ -192,7 +195,7 @@ int ata_task_ioctl(struct scsi_device *s
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; /* Always ask for sense data */
scsi_cmd[4] = args[1];
scsi_cmd[6] = args[2];
scsi_cmd[8] = args[3];
@@ -211,15 +214,29 @@ int ata_task_ioctl(struct scsi_device *s
from scsi_ioctl_send_command() for default case... */
scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5);
- if (sreq->sr_result) {
+ sb = sreq->sr_sense_buffer;
+
+ /* Retrieve data from check condition */
+ if((sb[1] == NO_SENSE) && (sb[2] == 0) && (sb[3] == 0x1D)) {
+ unsigned char *desc= sb + 8;
+
+ args[0]=desc[13];
+ args[1]=desc[3];
+ args[2]=desc[5];
+ args[3]=desc[7];
+ args[4]=desc[9];
+ args[5]=desc[11];
+ } else if (sreq->sr_result) {
rc = -EIO;
goto error;
}
- /* Need code to retrieve data from check condition? */
-
error:
scsi_release_request(sreq);
+
+ if (rc == 0 && copy_to_user(arg, args, sizeof(args)))
+ return -EFAULT;
+
return rc;
}
@@ -323,6 +340,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(s
* ata_dump_status - user friendly display of error info
* @id: id of the port in question
* @tf: ptr to filled out taskfile
+ * @stat: ATA command/status register
*
* Decode and dump the ATA error/status registers for the user so
* that they have some idea what really happened at the non
@@ -331,9 +349,9 @@ struct ata_queued_cmd *ata_scsi_qc_new(s
* LOCKING:
* inherited from caller
*/
-void ata_dump_status(unsigned id, struct ata_taskfile *tf)
+void ata_dump_status(unsigned id, struct ata_taskfile *tf, u8 stat)
{
- u8 stat = tf->command, err = tf->feature;
+ u8 err = tf->feature;
printk(KERN_WARNING "ata%u: status=0x%02x { ", id, stat);
if (stat & ATA_BUSY) {
@@ -479,6 +497,7 @@ void ata_to_sense_error(unsigned id, u8
/*
* ata_gen_ata_desc_sense - Generate check condition sense block.
* @qc: Command that completed.
+ * @stat: ATA status register
*
* This function is specific to the ATA descriptor format sense
* block specified for the ATA pass through commands. Regardless
@@ -489,7 +508,7 @@ void ata_to_sense_error(unsigned id, u8
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
+void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc, u8 stat)
{
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
@@ -510,10 +529,15 @@ void ata_gen_ata_desc_sense(struct ata_q
* Use ata_to_sense_error() to map status register bits
* onto sense key, asc & ascq.
*/
- if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
+ if (unlikely(stat & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
&sb[1], &sb[2], &sb[3]);
sb[1] &= 0x0f;
+ } else {
+ /* ATA PASS THROUGH INFORMATION AVAILABLE */
+ sb[1] = NO_SENSE;
+ sb[2] = 0;
+ sb[3] = 0x1D;
}
/*
@@ -540,7 +564,7 @@ void ata_gen_ata_desc_sense(struct ata_q
desc[9] = tf->lbam;
desc[11] = tf->lbah;
desc[12] = tf->device;
- desc[13] = tf->command; /* == status reg */
+ desc[13] = stat;
/*
* Fill in Extend bit, and the high order bytes
@@ -558,6 +582,7 @@ void ata_gen_ata_desc_sense(struct ata_q
/**
* ata_gen_fixed_sense - generate a SCSI fixed sense block
* @qc: Command that we are erroring out
+ * @stat: ATA status register
*
* Leverage ata_to_sense_error() to give us the codes. Fit our
* LBA in here if there's room.
@@ -565,7 +590,7 @@ void ata_gen_ata_desc_sense(struct ata_q
* LOCKING:
* inherited from caller
*/
-void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
+void ata_gen_fixed_sense(struct ata_queued_cmd *qc, u8 stat)
{
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
@@ -585,7 +610,7 @@ void ata_gen_fixed_sense(struct ata_queu
* Use ata_to_sense_error() to map status register bits
* onto sense key, asc & ascq.
*/
- if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
+ if (unlikely(stat & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
&sb[2], &sb[12], &sb[13]);
sb[2] &= 0x0f;
@@ -998,7 +1023,7 @@ static int ata_scsi_qc_complete(struct a
*/
if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) &&
((cmd->cmnd[2] & 0x20) || need_sense)) {
- ata_gen_ata_desc_sense(qc);
+ ata_gen_ata_desc_sense(qc, drv_stat);
} else {
if (!need_sense) {
cmd->result = SAM_STAT_GOOD;
@@ -1009,13 +1034,13 @@ static int ata_scsi_qc_complete(struct a
* good for smaller LBA (and maybe CHS?)
* devices.
*/
- ata_gen_fixed_sense(qc);
+ ata_gen_fixed_sense(qc, drv_stat);
}
}
if (need_sense) {
/* The ata_gen_..._sense routines fill in tf */
- ata_dump_status(qc->ap->id, &qc->tf);
+ ata_dump_status(qc->ap->id, &qc->tf, drv_stat);
}
qc->scsidone(cmd);
next reply other threads:[~2005-09-13 14:26 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-13 14:26 Jeff Raubitschek [this message]
2005-09-14 12:18 ` [PATCH libata-dev-2.6:passthru] passthru fixes Jeff Garzik
2005-09-21 14:32 ` John W. Linville
2005-10-04 14:22 ` Jeff Garzik
2005-10-10 20:39 ` Mark Lord
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=20050913142636.GB5679@google.com \
--to=jhr@google.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).