From: Albert Lee <albertcc@tw.ibm.com>
To: Jeff Garzik <jgarzik@pobox.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>,
Doug Maxey <dwm@maxeymade.com>, Jens Axboe <axboe@suse.de>,
Linux IDE <linux-ide@vger.kernel.org>
Subject: [PATCH 2/2] libata-2.6: Ignore interrupt before the ATAPI CDB is sent to the device
Date: Fri, 29 Apr 2005 17:39:00 +0800 [thread overview]
Message-ID: <427200B4.4050308@tw.ibm.com> (raw)
In-Reply-To: <4271FE02.1080009@tw.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 525 bytes --]
Hi Jeff,
Problem:
Sometimes the interrupt handler is invoked before atapi_packet_task() sending CDB to the device.
The interrupt handler completes the command and later when atapi_packet_task() runs, the command is already gone.
Changes:
- Add 2 PIO states to libata.h.
- Prevent the interrupt handler from completing the command before the ATAPI CDB is sent to the device.
Attached please find the patch against the libata-2.6 tree for your review. Thanks.
Albert
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
[-- Attachment #2: atapi_state_fix.diff --]
[-- Type: text/plain, Size: 2520 bytes --]
--- linux-2.6.11.7-twe/include/linux/libata.h 2005-04-25 14:59:15.000000000 +0800
+++ linux-2.6.11.7-mod/include/linux/libata.h 2005-04-25 15:06:25.000000000 +0800
@@ -161,6 +161,8 @@
PIO_ST_LAST,
PIO_ST_LAST_POLL,
PIO_ST_ERR,
+ PIO_ST_PKT,
+ PIO_ST_CDB_SENT,
};
/* forward declarations */
--- linux-2.6.11.7-twe/drivers/scsi/libata-core.c 2005-04-25 16:19:05.000000000 +0800
+++ linux-2.6.11.7-mod/drivers/scsi/libata-core.c 2005-04-29 16:20:32.000000000 +0800
@@ -2632,6 +2632,7 @@
default:
ata_altstatus(ap);
drv_stat = ata_chk_status(ap);
+ ap->pio_task_state = PIO_ST_IDLE;
/* ack bmdma irq events */
ap->ops->irq_clear(ap);
@@ -2934,17 +2935,20 @@
case ATA_PROT_ATAPI:
ata_qc_set_polling(qc);
ata_tf_to_host_nolock(ap, &qc->tf);
+ ap->pio_task_state = PIO_ST_PKT;
queue_work(ata_wq, &ap->packet_task);
break;
case ATA_PROT_ATAPI_NODATA:
ata_tf_to_host_nolock(ap, &qc->tf);
+ ap->pio_task_state = PIO_ST_PKT;
queue_work(ata_wq, &ap->packet_task);
break;
case ATA_PROT_ATAPI_DMA:
ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
ap->ops->bmdma_setup(qc); /* set up bmdma */
+ ap->pio_task_state = PIO_ST_PKT;
queue_work(ata_wq, &ap->packet_task);
break;
@@ -3142,6 +3146,13 @@
{
u8 status, host_stat;
+ /* ATAPI: Ignore interrupt if CDB is not sent yet */
+ if (is_atapi_taskfile(&qc->tf) &&
+ ap->pio_task_state != PIO_ST_CDB_SENT) {
+ DPRINTK("ata%u: not my atapi interrupt\n", ap->id);
+ goto idle_irq;
+ }
+
switch (qc->tf.protocol) {
case ATA_PROT_DMA:
@@ -3174,6 +3185,8 @@
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
ap->id, qc->tf.protocol, status);
+ ap->pio_task_state = PIO_ST_IDLE;
+
/* ack bmdma irq events */
ap->ops->irq_clear(ap);
@@ -3260,6 +3273,7 @@
struct ata_port *ap = _data;
struct ata_queued_cmd *qc;
u8 status;
+ unsigned long flags;
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
@@ -3275,10 +3289,13 @@
if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)
goto err_out;
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+
/* send SCSI cdb */
DPRINTK("send cdb\n");
assert(ap->cdb_len >= 12);
ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
+ ap->pio_task_state = PIO_ST_CDB_SENT;
/* if we are DMA'ing, irq handler takes over from here */
if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
@@ -3295,6 +3312,8 @@
queue_work(ata_wq, &ap->pio_task);
}
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
return;
err_out:
next prev parent reply other threads:[~2005-04-29 9:39 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-29 9:27 [PATCH 0/2] libata-2.6: Fix races caused by the interrupt handler Albert Lee
2005-04-29 9:34 ` [PATCH 1/2] libata-2.6: Prevent the interrupt handler from completing a command twice Albert Lee
2005-05-15 22:47 ` Jeff Garzik
2005-04-29 9:39 ` Albert Lee [this message]
2005-05-15 22:49 ` [PATCH 2/2] libata-2.6: Ignore interrupt before the ATAPI CDB is sent to the device Jeff Garzik
2005-05-16 10:37 ` Albert Lee
2005-06-08 8:02 ` [PATCH 1/1] libata: Handle ATAPI interrupt before CDB is sent Albert Lee
2005-06-08 10:01 ` Bartlomiej Zolnierkiewicz
2005-06-08 12:17 ` Albert Lee
2005-06-09 7:13 ` Albert Lee
2005-06-28 3:06 ` [PATCH 2/2] libata-2.6: Ignore interrupt before the ATAPI CDB is sent to the device Jeff Garzik
2005-06-28 10:05 ` 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=427200B4.4050308@tw.ibm.com \
--to=albertcc@tw.ibm.com \
--cc=axboe@suse.de \
--cc=bzolnier@gmail.com \
--cc=dwm@maxeymade.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 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.