linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Albert Lee <albertcc@tw.ibm.com>
To: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: Jeff Garzik <jgarzik@pobox.com>,
	Linux IDE <linux-ide@vger.kernel.org>,
	Doug Maxey <dwm@maxeymade.com>, Tejun Heo <htejun@gmail.com>,
	Mark Lord <mlord@pobox.com>, Brett Russ <russb@emc.com>
Subject: Re: [PATCH/RFC 3/4] libata: interrupt driven pio for libata-core
Date: Fri, 30 Sep 2005 16:02:53 +0800	[thread overview]
Message-ID: <433CF12D.900@tw.ibm.com> (raw)
In-Reply-To: <58cb370e05092903083e0d001c@mail.gmail.com>

Hi Bart:

>Hi,
>
>On 9/27/05, Albert Lee <albertcc@tw.ibm.com> wrote:
>  
>
>>Patch 3/4: interrupt driven pio for libata-core
>>
>>Changes:
>>- add PIO_ST_FIRST for the state before sending ATAPI CDB or sending
>>    
>>
>
>HSM_ST_FIRST
>
>Could you add some brief comments about HSM_* states
>(one line per state should be OK)?
>  
>
Hmm, will add the comments in the follow up patch.

>  
>
>>@@ -3344,43 +3356,96 @@ int ata_qc_issue_prot(struct ata_queued_
>> {
>>        struct ata_port *ap = qc->ap;
>>
>>+               } else {
>>+                       /* interrupt driven PIO */
>>+                       if (qc->tf.flags & ATA_TFLAG_WRITE) {
>>+                               /* PIO data out protocol */
>>+                               ap->hsm_task_state = HSM_ST_FIRST;
>>+                               queue_work(ata_wq, &ap->packet_task);
>>    
>>
>
>atapi_packet_task() is now abused to do ATA PIO out which is
>very confusing given that name of the function (and all the comments)
>remains unchanged.  Please correct it (I think it would be good idea to
>separate HSM_ST_CDB from HSM_ST_FIRST).
>  
>

You're right, will rename the atapi_packet_task() and revise the related 
variable and comments.

HSM_ST_CDB and HSM_ST_FIRST are almost the same except the content of 
the data being sent.
Could we keep them as one state?

>  
>
>>        case ATA_PROT_ATAPI:
>>-               ata_qc_set_polling(qc);
>>+               if (qc->tf.flags & ATA_TFLAG_POLLING)
>>+                       ata_qc_set_polling(qc);
>>+
>>                ata_tf_to_host_nolock(ap, &qc->tf);
>>-               queue_work(ata_wq, &ap->packet_task);
>>+               ap->hsm_task_state = HSM_ST_FIRST;
>>+
>>+               /* send cdb by polling if no cdb interrupt */
>>+               if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
>>+                   (qc->tf.flags & ATA_TFLAG_POLLING))
>>+                       queue_work(ata_wq, &ap->packet_task);
>>                break;
>>
>>        case ATA_PROT_ATAPI_NODATA:
>>-               ap->flags |= ATA_FLAG_NOINTR;
>>+               if (qc->tf.flags & ATA_TFLAG_POLLING)
>>+                       ata_qc_set_polling(qc);
>>+
>>                ata_tf_to_host_nolock(ap, &qc->tf);
>>-               queue_work(ata_wq, &ap->packet_task);
>>+               ap->hsm_task_state = HSM_ST_FIRST;
>>+
>>+               /* send cdb by polling if no cdb interrupt */
>>+               if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
>>+                   (qc->tf.flags & ATA_TFLAG_POLLING))
>>+                       queue_work(ata_wq, &ap->packet_task);
>>                break;
>>    
>>
>
>ATA_PROT_ATAPI_NODATA case is now identical
>to ATA_PROT_ATAPI one - no need to duplicate code.
>
>It may be also worth to split ata_qc_issue_prot() on IRQ
>and polling versions because it is really hard to read now.
>  
>
Nice catch, will remove the redundant code.
will also cleanup the ata_qc_issue_prot() code to simplify the PIO data 
out codepath.
(Hopefully the simplified ata_qc_issue_prot() is easier to read and we 
could have one version for both polling and IRQ version.)

>  
>
>>+/**
>>  *     ata_host_intr - Handle host interrupt for given (port, task)
>>  *     @ap: Port on which interrupt arrived (possibly...)
>>  *     @qc: Taskfile currently active in engine
>>@@ -3641,47 +3742,142 @@ void ata_bmdma_stop(struct ata_queued_cm
>> inline unsigned int ata_host_intr (struct ata_port *ap,
>>                                   struct ata_queued_cmd *qc)
>> {
>>    
>>
>
>We should check first if we are polling and if so we shouldn't touch hardware
>et all as we can interface with ata_pio_task or atapi_packet_task.  Just think
>about HSM_ST case when hardware is ready for the next transfer and IRQ
>happens (from some other device).
>
>Please note that this bug is present in original libata code.
>
>  
>
The (qc->tf.flags & ATA_TFLAG_POLLING) flag is checked in ata_interrupt().
So, the race between the irq handler and ata_pio_task() is avoided.

When the state is HSM_ST_FIRST,  ata_host_intr() checks the 
(qc->dev->flags & ATA_DFLAG_CDB_INTR) flag.
Also in atapi_packet_task(), the host lock is aquired during the state 
transition from HSM_ST_FIRST to next state.
So, the race between the irq handler and atapi_packet_task() is avoided.

>>-       u8 status, host_stat;
>>-
>>-       switch (qc->tf.protocol) {
>>+       u8 status, host_stat = 0;
>>
>>-       case ATA_PROT_DMA:
>>-       case ATA_PROT_ATAPI_DMA:
>>-       case ATA_PROT_ATAPI:
>>    
>>
>
>Your patch changes behavior for ATA_PROT_ATAPI case - now DMA
>engine won't be checked.  We had discussion about fixing it before
>but I don't remember what was the conclusion - in any case it is worth
>to at least mention this change in the patch description.
>
>  
>

Sorry I forgot to mention it in the description of previous patch
For the ATA_PROT_ATAPI case, the behavior is changed in the irq handler:
  - The DMA status register is no longer checked.
  - HSM state and device busy flag are used together to see whether it 
is our irq or not.

This new behavior seems to be working ok on my test machine.
However, not sure whether this 100% works on all hardware.
Need more test and comment.

>>-               /* check status of DMA engine */
>>-               host_stat = ap->ops->bmdma_status(ap);
>>-               VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
>>+       VPRINTK("ata%u: protocol %d task_state %d\n",
>>+               ap->id, qc->tf.protocol, ap->hsm_task_state);
>>
>>-               /* if it's not our irq... */
>>-               if (!(host_stat & ATA_DMA_INTR))
>>+       /* Check whether we are expecting interrupt in this state */
>>+       switch (ap->hsm_task_state) {
>>+       case HSM_ST_FIRST:
>>+               /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
>>+                * The flag was turned on only for atapi devices.
>>+                * No need to check is_atapi_taskfile(&qc->tf) again.
>>+                */
>>+               if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
>>                        goto idle_irq;
>>+               break;
>>... (snip) ...
>>+
>>+
>>+fsm_start:
>>+       switch (ap->hsm_task_state) {
>>+       case HSM_ST_FIRST:
>>+               /* Some pre-ATAPI-4 devices assert INTRQ
>>+                * at this state when ready to receive CDB.
>>+                */
>>+
>>+               /* check device status */
>>+               if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) {
>>+                       /* Wrong status. Let EH handle this */
>>+                       ap->hsm_task_state = HSM_ST_ERR;
>>+                       goto fsm_start;
>>+               }
>>+
>>+               atapi_send_cdb(ap, qc);
>>    
>>
>
>This case can happen also for ATA PIO out:
>ata_qc_issue_prot() -> IRQ happens -> ata_host_intr().
>
>Sending CDB unconditionally is wrong.
>
>
>  
>
The (qc->dev->flags & ATA_DFLAG_CDB_INTR) flag is only turned on for 
atapi devices.
So, when we are in the HSM_ST_FIRST state, ATA devices are filtered out 
and won't enter the irq handler.


Thanks for the review and advice, will revise and send follow up patch 
later.
(Will also have look at the READ/WRITE MULTIPLE mentioned by Jeff.)

Albert




  reply	other threads:[~2005-09-30  8:03 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-09 16:14 [PATCH RFC] libata: interrupt driven pio Albert Lee
2005-09-09 17:35 ` Jeff Garzik
2005-09-09 18:14   ` Doug Maxey
2005-09-22  4:00   ` [PATCH/RFC 0/3] libata: interrupt driven pio (revised) Albert Lee
2005-09-22  4:09     ` [PATCH/RFC 1/3] libata: interrupt driven pio for libata-core Albert Lee
2005-09-23  9:25       ` Albert Lee
2005-09-22  4:11     ` [PATCH/RFC 2/3] libata: rename task states/variables Albert Lee
2005-09-23  9:34       ` Albert Lee
2005-09-22  4:14     ` [PATCH/RFC 3/3] libata: interrupt driven pio for LLD Albert Lee
2005-09-22 12:56       ` Mark Lord
2005-09-23  2:40         ` Albert Lee
2005-09-23  9:46     ` [PATCH/RFC 0/3] libata: interrupt driven pio (revised) Jeff Garzik
2005-09-27  9:31       ` [PATCH/RFC 0/4] libata: interrupt driven pio (revised 2) Albert Lee
2005-09-27  9:34         ` [PATCH/RFC 1/4] libata: indent and whitespace change Albert Lee
2005-09-27  9:36         ` [PATCH/RFC 2/4] libata: rename host states Albert Lee
2005-09-28 15:59           ` Jeff Garzik
2005-09-27  9:38         ` [PATCH/RFC 3/4] libata: interrupt driven pio for libata-core Albert Lee
2005-09-28 16:09           ` Jeff Garzik
2005-09-29 10:08           ` Bartlomiej Zolnierkiewicz
2005-09-30  8:02             ` Albert Lee [this message]
2005-09-30  9:28               ` Bartlomiej Zolnierkiewicz
2005-09-30 11:28                 ` Albert Lee
2005-09-30 12:00                   ` Bartlomiej Zolnierkiewicz
2005-09-30 11:04             ` [PATCH/RFC 0/4] libata: irq driven pio follow-up patches Albert Lee
2005-09-30 11:07               ` [PATCH/RFC 1/4] irq-pio: add comments and cleanup Albert Lee
2005-09-30 11:09               ` [PATCH/RFC 2/4] irq-pio: rename atapi_packet_task() and comments Albert Lee
2005-09-30 11:11               ` [PATCH/RFC 3/4] irq-pio: simplify if condition in ata_dataout_task() Albert Lee
2005-09-30 11:14               ` [PATCH/RFC 4/4] irq-pio: cleanup ata_qc_issue_prot() Albert Lee
2005-09-30 11:21               ` [PATCH/RFC 0/4] libata: irq driven pio follow-up patches Jeff Garzik
2005-10-03 11:46                 ` [PATCH/RFC 0/4] libata: more " Albert Lee
2005-10-03 13:00                   ` [PATCH/RFC 1/4] irq-pio: move functions Albert Lee
2005-10-03 13:02                   ` [PATCH/RFC 2/4] irq-pio: remove ap->dataout_task Albert Lee
2005-10-04 10:09                     ` Jeff Garzik
2005-10-04 11:54                       ` Albert Lee
2005-10-03 13:18                   ` [PATCH/RFC 3/4] irq-pio: integrate ata_pio_first_block() with ata_pio_task() Albert Lee
2005-10-04 10:10                     ` Jeff Garzik
2005-10-03 13:19                   ` [PATCH/RFC 4/4] irq-pio: add read/write multiple support Albert Lee
2005-10-03 13:35                     ` Mark Lord
2005-10-04  9:43                       ` Jeff Garzik
2005-10-04 12:00                         ` Albert Lee
2005-10-04 12:07                           ` Jeff Garzik
2005-10-04 12:22                             ` [PATCH/RFC 0/4] libata: CHS follow-up patches Albert Lee
2005-10-04 12:27                               ` [PATCH/RFC 1/4] CHS: white space beautification Albert Lee
2005-10-04 12:49                                 ` Jeff Garzik
2005-10-04 12:29                               ` [PATCH/RFC 2/4] CHS: tidy up SCSI lba and transfer length calculation Albert Lee
2005-10-04 12:30                               ` [PATCH/RFC 3/4] CHS: add CHS support to ata_scsi_start_stop_xlat() Albert Lee
2005-10-04 12:34                               ` [PATCH/RFC 4/4] CHS: calculate LBA28/LBA48 commands and protocol on the fly Albert Lee
2005-10-04 12:52                                 ` Jeff Garzik
2005-10-05 11:16                                   ` [PATCH/RFC 0/4] libata: more CHS follow-up patches Albert Lee
2005-10-05 11:20                                     ` [PATCH/RFC 1/4] CHS: move the initialization of taskfile LBA flags Albert Lee
2005-10-05 11:23                                     ` [PATCH/RFC 2/4] CHS: calculate read/write commands and protocol on the fly Albert Lee
2005-10-05 11:25                                     ` [PATCH/RFC 3/4] CHS: support overriding the ata_rwcmd_protocol() function Albert Lee
2005-10-05 11:27                                     ` [PATCH/RFC 4/4] CHS: optimize LBA28/LBA48 usage Albert Lee
2005-10-05 11:59                                     ` [PATCH/RFC 1/4] CHS: move the initialization of taskfile LBA flags (resend) Albert Lee
2005-10-05 12:02                                     ` [PATCH/RFC 2/4] CHS: calculate read/write commands and protocol on the fly (resend) Albert Lee
2005-10-05 12:03                                     ` [PATCH/RFC 3/4] CHS: support overriding the ata_rwcmd_protocol() function (resend) Albert Lee
2005-10-05 12:04                                     ` [PATCH/RFC 4/4] CHS: optimize LBA28/LBA48 usage (resend) Albert Lee
2005-10-06 11:26                                     ` [PATCH/RFC 0/4] libata: more CHS follow-up patches Jeff Garzik
2005-10-07  6:53                                       ` [PATCH 0/3] libata: CHS follow-up patches (resend #2) Albert Lee
2005-10-07  6:58                                         ` [PATCH 1/3] CHS: move the initialization of taskfile LBA flags Albert Lee
2005-10-07  7:01                                         ` [PATCH 2/3] CHS: calculate read/write commands and protocol on the fly Albert Lee
2005-10-07  7:04                                         ` [PATCH 3/3] CHS: LBA28/LBA48 optimization Albert Lee
2005-10-07  8:32                                         ` [PATCH 0/3] libata: CHS follow-up patches (resend #4) Albert Lee
2005-10-07  8:34                                           ` [PATCH 1/3] CHS: move the initialization of taskfile LBA flags " Albert Lee
2005-10-07  8:36                                           ` [PATCH 2/3] CHS: calculate read/write commands and protocol on the fly " Albert Lee
2005-10-07  8:37                                           ` [PATCH 3/3] CHS: LBA28/LBA48 optimization " Albert Lee
2005-10-09 13:41                                           ` [PATCH 0/3] libata: CHS follow-up patches " Jeff Garzik
2005-10-11 11:05                                             ` [PATCH 0/4] libata: CHS follow-up patches (resend #5) Albert Lee
2005-10-11 11:09                                               ` [PATCH 1/4] CHS: move the initialization of taskfile LBA flags " Albert Lee
2005-10-11 11:11                                               ` [PATCH 2/4] CHS: calculate read/write commands and protocol on the fly " Albert Lee
2005-10-11 11:21                                               ` [PATCH 4/4] CHS: LBA28/LBA48 optimization " Albert Lee
2005-10-11 13:09                                                 ` Mark Lord
2005-10-11 13:12                                                 ` Mark Lord
2005-10-12  5:05                                                   ` Albert Lee
2005-10-04 15:48                                 ` [PATCH/RFC 4/4] CHS: calculate LBA28/LBA48 commands and protocol on the fly Alan Cox
2005-10-04 10:19                     ` [PATCH/RFC 4/4] irq-pio: add read/write multiple support Jeff Garzik
2005-09-27  9:39         ` [PATCH/RFC 4/4] libata: interrupt driven pio for LLD Albert Lee

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=433CF12D.900@tw.ibm.com \
    --to=albertcc@tw.ibm.com \
    --cc=bzolnier@gmail.com \
    --cc=dwm@maxeymade.com \
    --cc=htejun@gmail.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=mlord@pobox.com \
    --cc=russb@emc.com \
    /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).