aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_promise.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2005-08-22 01:59:24 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-23 01:05:55 -0400
commitc1389503710ef4b4e5d21bea284afde19e9619cf (patch)
tree270bf8ea0c2ac354273766d8a1ddfb12cd58b608 /drivers/scsi/sata_promise.c
parentc0b34ad2956036cdba87792d6c46d8f491539df1 (diff)
[PATCH] fix atapi_packet_task vs. intr race (take 2)
Interrupts from devices sharing the same IRQ could cause ata_host_intr to finish commands being processed by atapi_packet_task if the commands are using ATA_PROT_ATAPI_NODATA or ATA_PROT_ATAPI_DMA protocol. This is because libata interrupt handler is unaware that interrupts are not expected during that period. This patch adds ATA_FLAG_NOINTR flag to tell the interrupt handler that we're not expecting interrupts. Note that once proper HSM is implemented for interrupt-driven PIO, this should be merged into it and this flag will be removed. ahci.c is a different kind of beast, so it's left alone. * The following drivers use ata_qc_issue_prot and ata_interrupt, so changes in libata core will do. ata_piix sata_sil sata_svw sata_via sata_sis sata_uli * The following drivers use ata_qc_issue_prot and custom intr handler. They need this change to work correctly. sata_nv sata_vsc * The following drivers use custom issue function and intr handler. Currently all custom issue functions don't support ATAPI, so this change is irrelevant, updated for consistency and to avoid later mistakes. sata_promise sata_qstor sata_sx4 Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/sata_promise.c')
-rw-r--r--drivers/scsi/sata_promise.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index cc613b3c6ce6..6defd7962359 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -445,7 +445,8 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
445 VPRINTK("port %u\n", i); 445 VPRINTK("port %u\n", i);
446 ap = host_set->ports[i]; 446 ap = host_set->ports[i];
447 tmp = mask & (1 << (i + 1)); 447 tmp = mask & (1 << (i + 1));
448 if (tmp && ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { 448 if (tmp && ap &&
449 !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
449 struct ata_queued_cmd *qc; 450 struct ata_queued_cmd *qc;
450 451
451 qc = ata_qc_from_tag(ap, ap->active_tag); 452 qc = ata_qc_from_tag(ap, ap->active_tag);