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

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