From mboxrd@z Thu Jan 1 00:00:00 1970
From: Pat LaVarre
Subject: Re: SATA ATAPI work in progress
Date: 14 May 2004 12:23:20 -0600
Sender: linux-ide-owner@vger.kernel.org
Message-ID: <1084559000.4017.52.camel@patibmrh9>
References: <1084393233.3999.2.camel@patibmrh9> <40A28BB6.7090204@pobox.com>
<1084403654.3196.31.camel@patibmrh9> <40A3E595.8000003@pobox.com>
Mime-Version: 1.0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Return-path:
Received: from email-out1.iomega.com ([147.178.1.82]:50892 "EHLO
email.iomega.com") by vger.kernel.org with ESMTP id S261610AbUENSXo
(ORCPT );
Fri, 14 May 2004 14:23:44 -0400
In-Reply-To: <40A3E595.8000003@pobox.com>
List-Id: linux-ide@vger.kernel.org
To: Jeff Garzik
Cc: linux-ide@vger.kernel.org
Jeff G:
> This is important because some AHCI SATA controllers can only transfer
> a _single_ DRQ block per disk transaction. In anticipation of the
> demise of PIO, no doubt :)
Eh? What's a "disk transaction"?
Do we mean to say that some SATA controllers choke over the (rare)
device rudeness of an INTRQ for every two bytes of the standard x24 (36)
bytes of op x12 (18) Inquiry, for example?
> ...
The rest of your instructions I believe I can follow as written. Below
I explain why I find some of them surprising, in case that's interesting
or useful to anyone here.
Pat LaVarre
-----
> For an ATA device, we
> * write the taskfile, except for command
> * set up the DMA engine
> * write the command
> * write DMA-start bit
>
> And the functions used by the low-level drivers, ata_bmdma_start_mmio
> and ata_bmdma_start_pio, are hardcoded to use this ordering. By
> contrast, for ATAPI you should do:
> * set up DMA engine
> * write entire taskfile, including command
> * proceed through state diagram until DRQ==1
> * write SCSI CDB
> * write DMA-start bit
Why we care whether we write the taskfile apart from the command before
or after DMA engine setup, I do not understand.
> > + int bcl = (8 * 0x400); /* PIO "byte count limit" */
>
> Make this a more obvious "8 * 1024".
A point of pain for me moving into the world near linux-ide was
discovering that `dd` wanted me to say 512 rather than the more familiar
and plainly rounded value x200.
> For the sake of correctness, I prefer to call this "DRQ block size"
> rather than the more ambigous "byte count limit".
"Byte count limit" is the unfortunate phrase found at t13.org.
I will assume I should use your term but may once provide a
cross-referencing translation to the standard unfortunate phrase as a
comment.
> > + struct ata_taskfile *tf = &qc->tf;
> > + tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
> > + tf->protocol = qc->dev->xfer_protocol;
> > + tf->command = ATA_CMD_PACKET; /* often 0xA0 */
>
> kill the comment, this should be obvious to anyone who reads the
> public specs. That's why we have the constant, after all...
See below.
> > + tf->feature = ATAPI_PKT_DMA; /* often x01 */
>
> kill the comment
I understood your objection to: ATA_CMD_PACKET; /* often 0xA0 */
to mean I should never tell people what hovering the mouse over an
identifier should (but often doesn't) tell them.
Me, I didn't know ATA_CMD_PACKET meant xA0 until I looked it up. I'm
likely to forget again in future. ATA_CMD_PACKET is a Linux only term,
whereas "A0" I find in every source I read, be it xA0 or A0h or 0A0h
etc., be the source English, bus traces, machine code hex dumps, ....
> > + } else {
> > + DPRINTK("PIO ATAPI 0x%lX %d\n", qc->flags,
> qc->tf.protocol);
> > + qc->tf.protocol = ATA_PROT_ATAPI;
> > + tf->lbam = bcl >> 8;
> > + tf->lbah = bcl;
> > + }
> > + qc->flags |= ATA_QCFLAG_ATAPI;
> > + return 0;
> > }
>
> key flags that should be used, but are just being deleted in the
> previous chunk:
> ATA_QCFLAG_SG
> ATA_NIEN
> ATA_QCFLAG_POLL
>
> Their proper placement is left as an exercise to the reader, who seems
> to be doing well so far :)
Thank you for your kind words.
> > + if (dev->class == ATA_DEV_ATAPI) { /* (thus !=
> ATA_DEV_ATAPI_UNSUP) */
> > + return atapi_xlat;
> > + }
> > +
>
> Remove the extraneous braces ... :)
Understood to mean do not enclose in { } unless two or more statements
appear as part of the then or else of an if.
> > + if (dev->class == ATA_DEV_ATAPI) { /* (thus !=
> ATA_DEV_ATAPI_UNSUP) */
> > + return atapi_xlat;
> > + }
> > +
>
> Remove ... the comment :)
Will do, without me yet having fully confirmed that ATA_DEV_ATAPI_UNSUP
means known to be ATAPI but treated as ATA_DEV_UNKNOWN.
Pat LaVarre