diff options
-rw-r--r-- | drivers/scsi/libata-core.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 63857a90ac28..35ae5b41f662 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -3430,16 +3430,31 @@ skip_map: | |||
3430 | * LOCKING: | 3430 | * LOCKING: |
3431 | * None. (grabs host lock) | 3431 | * None. (grabs host lock) |
3432 | */ | 3432 | */ |
3433 | |||
3434 | void ata_poll_qc_complete(struct ata_queued_cmd *qc) | 3433 | void ata_poll_qc_complete(struct ata_queued_cmd *qc) |
3435 | { | 3434 | { |
3436 | struct ata_port *ap = qc->ap; | 3435 | struct ata_port *ap = qc->ap; |
3437 | unsigned long flags; | 3436 | unsigned long flags; |
3438 | 3437 | ||
3439 | spin_lock_irqsave(&ap->host_set->lock, flags); | 3438 | spin_lock_irqsave(&ap->host_set->lock, flags); |
3440 | ap->flags &= ~ATA_FLAG_NOINTR; | 3439 | |
3441 | ata_irq_on(ap); | 3440 | if (ap->ops->error_handler) { |
3442 | ata_qc_complete(qc); | 3441 | /* EH might have kicked in while host_set lock is released */ |
3442 | qc = ata_qc_from_tag(ap, qc->tag); | ||
3443 | if (qc) { | ||
3444 | if (!(qc->err_mask & AC_ERR_HSM)) { | ||
3445 | ap->flags &= ~ATA_FLAG_NOINTR; | ||
3446 | ata_irq_on(ap); | ||
3447 | ata_qc_complete(qc); | ||
3448 | } else | ||
3449 | ata_port_freeze(ap); | ||
3450 | } | ||
3451 | } else { | ||
3452 | /* old EH */ | ||
3453 | ap->flags &= ~ATA_FLAG_NOINTR; | ||
3454 | ata_irq_on(ap); | ||
3455 | ata_qc_complete(qc); | ||
3456 | } | ||
3457 | |||
3443 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | 3458 | spin_unlock_irqrestore(&ap->host_set->lock, flags); |
3444 | } | 3459 | } |
3445 | 3460 | ||