aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_qstor.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_qstor.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_qstor.c')
-rw-r--r--drivers/scsi/sata_qstor.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index dca9ed7ac760..08a84042ce09 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -386,7 +386,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
386 DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", 386 DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n",
387 sff1, sff0, port_no, sHST, sDST); 387 sff1, sff0, port_no, sHST, sDST);
388 handled = 1; 388 handled = 1;
389 if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { 389 if (ap && !(ap->flags &
390 (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) {
390 struct ata_queued_cmd *qc; 391 struct ata_queued_cmd *qc;
391 struct qs_port_priv *pp = ap->private_data; 392 struct qs_port_priv *pp = ap->private_data;
392 if (!pp || pp->state != qs_state_pkt) 393 if (!pp || pp->state != qs_state_pkt)
@@ -417,7 +418,8 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
417 for (port_no = 0; port_no < host_set->n_ports; ++port_no) { 418 for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
418 struct ata_port *ap; 419 struct ata_port *ap;
419 ap = host_set->ports[port_no]; 420 ap = host_set->ports[port_no];
420 if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { 421 if (ap &&
422 !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
421 struct ata_queued_cmd *qc; 423 struct ata_queued_cmd *qc;
422 struct qs_port_priv *pp = ap->private_data; 424 struct qs_port_priv *pp = ap->private_data;
423 if (!pp || pp->state != qs_state_mmio) 425 if (!pp || pp->state != qs_state_mmio)