diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/sata_qstor.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 9d3128ca3443..7446a335fc92 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -425,24 +425,27 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) | |||
425 | if (ap && | 425 | if (ap && |
426 | !(ap->flags & ATA_FLAG_DISABLED)) { | 426 | !(ap->flags & ATA_FLAG_DISABLED)) { |
427 | struct ata_queued_cmd *qc; | 427 | struct ata_queued_cmd *qc; |
428 | struct qs_port_priv *pp = ap->private_data; | 428 | struct qs_port_priv *pp; |
429 | if (!pp || pp->state != qs_state_mmio) | ||
430 | continue; | ||
431 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 429 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
432 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { | 430 | if (!qc || !(qc->flags & ATA_QCFLAG_ACTIVE)) { |
433 | 431 | /* | |
434 | /* check main status, clearing INTRQ */ | 432 | * The qstor hardware generates spurious |
435 | u8 status = ata_check_status(ap); | 433 | * interrupts from time to time when switching |
436 | if ((status & ATA_BUSY)) | 434 | * in and out of packet mode. |
437 | continue; | 435 | * There's no obvious way to know if we're |
438 | DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", | 436 | * here now due to that, so just ack the irq |
439 | ap->print_id, qc->tf.protocol, status); | 437 | * and pretend we knew it was ours.. (ugh). |
440 | 438 | * This does not affect packet mode. | |
441 | /* complete taskfile transaction */ | 439 | */ |
442 | qc->err_mask |= ac_err_mask(status); | 440 | ata_check_status(ap); |
443 | ata_qc_complete(qc); | ||
444 | handled = 1; | 441 | handled = 1; |
442 | continue; | ||
445 | } | 443 | } |
444 | pp = ap->private_data; | ||
445 | if (!pp || pp->state != qs_state_mmio) | ||
446 | continue; | ||
447 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) | ||
448 | handled |= ata_host_intr(ap, qc); | ||
446 | } | 449 | } |
447 | } | 450 | } |
448 | return handled; | 451 | return handled; |
@@ -452,12 +455,13 @@ static irqreturn_t qs_intr(int irq, void *dev_instance) | |||
452 | { | 455 | { |
453 | struct ata_host *host = dev_instance; | 456 | struct ata_host *host = dev_instance; |
454 | unsigned int handled = 0; | 457 | unsigned int handled = 0; |
458 | unsigned long flags; | ||
455 | 459 | ||
456 | VPRINTK("ENTER\n"); | 460 | VPRINTK("ENTER\n"); |
457 | 461 | ||
458 | spin_lock(&host->lock); | 462 | spin_lock_irqsave(&host->lock, flags); |
459 | handled = qs_intr_pkt(host) | qs_intr_mmio(host); | 463 | handled = qs_intr_pkt(host) | qs_intr_mmio(host); |
460 | spin_unlock(&host->lock); | 464 | spin_unlock_irqrestore(&host->lock, flags); |
461 | 465 | ||
462 | VPRINTK("EXIT\n"); | 466 | VPRINTK("EXIT\n"); |
463 | 467 | ||