From: "Luciano A. Stertz" <luciano@tteng.com.br>
To: linux-ide@vger.kernel.org
Subject: Re: T10/04-262 ATA pass thru - patch.
Date: Wed, 29 Sep 2004 15:29:59 -0300 [thread overview]
Message-ID: <415AFF27.7080906@tteng.com.br> (raw)
In-Reply-To: <20040928001633.A8363@florence.linkmargin.com>
Just trying to understand the SATA SMART problem as a whole. With your
patch, it's possible to send ATA commands that are encapsulated in CDBs,
right? If so, to enable sending direct ATA commands to a SATA device,
one has to create a ioctl that receives the command and creates a CDB
from it, as John Linville did a few weeks ago. This way a user-space
application (e.g. smartmontools) can use this ioctl to send ATA
commands. Am I right?
If I understand it correctly, the kernel receives an ATA command,
creates a CDB, gets the ATA command from the CDB and issues it.
It's a nice workaround, but user space software will still have to be
aware that the target device appears as SCSI but isn't in fact a SCSI
device... I guess that the ideal situation would be:
1. The user space program sends SCSI commands to the device, without
even have to worry if it's really a SCSI device;
2. The kernel issues equivalent ATA commands and fills in the requested
data.
I don't know if it's possible / practical, but would be very convenient
to user space developers. If it doesn't make sense to have this
translation done in the kernel, maybe in a user space library?
Luciano Stertz
Andy Warner wrote:
> Here is a *very* rough and ready patch that implements
> the ATA pass-thru CDB. The patch should apply cleanly
> to any bk://gkernel.bkbits.net/libata-2.6 clone.
>
> The 16-byte command opcode is a totally arbitrary 0x85,
> allocation of a legit opcode is still pending.
>
> The 12-byte command is not supported yet.
>
> Only the following protocols are currently
> supported: Non-Data, PIO-In, PIO-Out, DMA.
>
> Multiple Count is currently ignored, and
> read/write multiple are handled as vanilla PIO.
>
> UDMA (protocols 11 & 12 in T10/04-262) probably
> work, since at the libata level all DMA appear to
> be handled the same.
>
> Not supported are any of the reset protocols, packet,
> queued, device diagnostics or FPDMA. I have no plans
> to add packet support or queued support any time soon.
> This should be enough to start SMART work, though.
>
> This is my first patch generated from a bk-based
> tree, so let me know if there are any problems
> due to the way I've generated the patch.
>
> Feedback/complaints -> me.
>
>
> ------------------------------------------------------------------------
>
> diff -ur -X /tmp/dontdiff libata-2.6-vanilla/drivers/scsi/libata-core.c t10-parser/drivers/scsi/libata-core.c
> --- libata-2.6-vanilla/drivers/scsi/libata-core.c 2004-09-27 17:30:29.000000000 -0500
> +++ t10-parser/drivers/scsi/libata-core.c 2004-09-27 21:30:23.000000000 -0500
> @@ -1946,7 +1946,7 @@
> sg->offset = (unsigned long) buf & ~PAGE_MASK;
> sg_dma_len(sg) = buflen;
>
> - WARN_ON(buflen > PAGE_SIZE);
> +// WARN_ON(buflen > PAGE_SIZE);
> }
>
> void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
> diff -ur -X /tmp/dontdiff libata-2.6-vanilla/drivers/scsi/libata-scsi.c t10-parser/drivers/scsi/libata-scsi.c
> --- libata-2.6-vanilla/drivers/scsi/libata-scsi.c 2004-09-27 17:30:29.000000000 -0500
> +++ t10-parser/drivers/scsi/libata-scsi.c 2004-09-27 23:42:44.733522940 -0500
> @@ -623,10 +623,22 @@
> {
> struct scsi_cmnd *cmd = qc->scsicmd;
>
> - if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
> - ata_to_sense_error(qc, drv_stat);
> - else
> - cmd->result = SAM_STAT_GOOD;
> + /*
> + * If this was a pass-thru command, and the user requested
> + * a check condition return including register values.
> + * Note that check condition is generated, and the ATA
> + * register values are returned, whether the command completed
> + * successfully or not. If there was no error, SK, ASC and
> + * ASCQ will all be zero.
> + */
> + if ((cmd->cmnd[0] == ATA_16) && (cmd->cmnd[2] & 0x20)) {
> +/*DWD*/ printk("XX 0x%0x/0x%0x\n", qc->tf.flags, qc->tf.protocol) ;
> + } else {
> + if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
> + ata_to_sense_error(qc, drv_stat);
> + else
> + cmd->result = SAM_STAT_GOOD;
> + }
>
> qc->scsidone(cmd);
>
> @@ -688,7 +700,6 @@
>
> if (xlat_func(qc, scsicmd))
> goto err_out;
> -
> /* select device, send command to hardware */
> if (ata_qc_issue(qc))
> goto err_out;
> @@ -1368,6 +1379,98 @@
> return dev;
> }
>
> +/*
> + * ata_scsi_map_proto() - Map the protocol specified
> + * in the pass-thru CDB onto the
> + * protocol values used by taskfiles.
> + */
> +static u8
> +ata_scsi_map_proto(u8 byte1)
> +{
> + switch((byte1 & 0x1e) >> 1) {
> + case 3: /* Non-data */
> + return ATA_PROT_NODATA;
> +
> + case 6: /* DMA */
> + return ATA_PROT_DMA;
> +
> + case 4: /* PIO Data-in */
> + case 5: /* PIO Data-out */
> + if (byte1 & 0xe0) {
> + return ATA_PROT_PIO_MULT;
> + }
> + return ATA_PROT_PIO;
> +
> + case 10: /* Device Reset */
> + case 0: /* Hard Reset */
> + case 1: /* SRST */
> + case 2: /* Bus Idle */
> + case 7: /* Packet */
> + case 8: /* DMA Queued */
> + case 9: /* Device Diagnostic */
> + case 11: /* UDMA Data-in */
> + case 12: /* UDMA Data-Out */
> + case 13: /* FPDMA */
> + default: /* Reserved */
> + break;
> + }
> +
> + return ATA_PROT_UNKNOWN;
> +}
> +
> +static unsigned int
> +ata_scsi_pass_thru_16(struct ata_queued_cmd *qc, u8 *scsicmd)
> +{
> + struct ata_taskfile *tf = &(qc->tf);
> + struct scsi_cmnd *cmd = qc->scsicmd;
> +
> + if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN) {
> + return 1;
> + }
> +
> + /*
> + * If the CDB claims to contain extended
> + * ATA commands copy the upper byte register values.
> + *
> + * NOTE: at present copy all register fields,
> + * regardless of which ones are valid according
> + * to the .En bits. TODO: research optimal
> + * algorithm for this.
> + */
> + if (scsicmd[1] & 0x01) {
> + tf->hob_feature = scsicmd[3];
> + tf->hob_nsect = scsicmd[5];
> + tf->hob_lbal = scsicmd[7];
> + tf->hob_lbam = scsicmd[9];
> + tf->hob_lbah = scsicmd[11];
> + tf->flags |= ATA_TFLAG_LBA48 ;
> + } else {
> + tf->flags &= ~ATA_TFLAG_LBA48 ;
> + }
> +
> + tf->feature = scsicmd[4];
> + tf->nsect = scsicmd[6];
> + tf->lbal = scsicmd[8];
> + tf->lbam = scsicmd[10];
> + tf->lbah = scsicmd[12];
> +
> + tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE) ;
> + tf->device = scsicmd[13];
> + tf->command = scsicmd[14];
> +
> + /*
> + * TODO: find out if we need to do more here to
> + * cover scatter/gather case.
> + */
> + qc->nsect = cmd->bufflen / ATA_SECT_SIZE ;
> +
> + if (cmd->sc_data_direction == SCSI_DATA_WRITE) {
> + tf->flags |= ATA_TFLAG_WRITE;
> + }
> +
> + return 0;
> +}
> +
> /**
> * ata_get_xlat_func - check if SCSI to ATA translation is possible
> * @dev: ATA device
> @@ -1400,6 +1503,9 @@
> case VERIFY:
> case VERIFY_16:
> return ata_scsi_verify_xlat;
> +
> + case ATA_16:
> + return ata_scsi_pass_thru_16 ;
> }
>
> return NULL;
> diff -ur -X /tmp/dontdiff libata-2.6-vanilla/include/scsi/scsi.h t10-parser/include/scsi/scsi.h
> --- libata-2.6-vanilla/include/scsi/scsi.h 2004-09-27 17:30:40.000000000 -0500
> +++ t10-parser/include/scsi/scsi.h 2004-09-27 22:11:07.000000000 -0500
> @@ -113,6 +113,9 @@
> /* values for service action in */
> #define SAI_READ_CAPACITY_16 0x10
>
> +/* Temporary values for T10/04-262 until official values are allocated */
> +#define ATA_16 0x85 /* 16-byte pass-thru [0x85 == unused]*/
> +#define ATA_12 0xb3 /* 12-byte pass-thru [0xb3 == obsolete set limits command] */
>
> /*
> * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
--
Luciano A. Stertz
luciano@tteng.com.br
T&T Engenheiros Associados Ltda
http://www.tteng.com.br
Fone/Fax (51) 3224 8425
next prev parent reply other threads:[~2004-09-29 18:25 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-09-28 5:16 T10/04-262 ATA pass thru - patch Andy Warner
2004-09-28 5:39 ` Andy Warner
2004-09-29 16:49 ` John W. Linville
2004-09-29 18:19 ` Andy Warner
2004-09-29 17:12 ` John W. Linville
2004-09-29 20:44 ` Andy Warner
2004-09-29 18:29 ` Luciano A. Stertz [this message]
2004-09-29 17:20 ` John W. Linville
2004-09-29 18:32 ` Jeff Garzik
2004-09-29 19:31 ` Luciano A. Stertz
2004-09-29 19:38 ` Luciano A. Stertz
2004-09-29 18:55 ` John W. Linville
2004-10-05 18:53 ` Luciano A. Stertz
2004-10-05 19:06 ` Andy Warner
2004-10-05 22:19 ` Jeff Garzik
2004-10-05 22:37 ` Andy Warner
2004-10-05 22:41 ` Jeff Garzik
2004-10-06 6:04 ` Jens Axboe
2004-10-07 3:34 ` Jeff Garzik
2004-10-06 12:21 ` Luciano A. Stertz
2004-09-30 18:13 ` [patch libata-2.6] libata: SMART support via ATA pass-thru John W. Linville
2004-09-30 19:52 ` 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=415AFF27.7080906@tteng.com.br \
--to=luciano@tteng.com.br \
--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 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.