diff options
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 9c97783462d6..63857a90ac28 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -987,6 +987,12 @@ unsigned ata_exec_internal(struct ata_device *dev, | |||
987 | 987 | ||
988 | spin_lock_irqsave(&ap->host_set->lock, flags); | 988 | spin_lock_irqsave(&ap->host_set->lock, flags); |
989 | 989 | ||
990 | /* no internal command while frozen */ | ||
991 | if (ap->flags & ATA_FLAG_FROZEN) { | ||
992 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
993 | return AC_ERR_SYSTEM; | ||
994 | } | ||
995 | |||
990 | /* initialize internal qc */ | 996 | /* initialize internal qc */ |
991 | 997 | ||
992 | /* XXX: Tag 0 is used for drivers with legacy EH as some | 998 | /* XXX: Tag 0 is used for drivers with legacy EH as some |
@@ -2565,8 +2571,11 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes) | |||
2565 | sata_scr_write(ap, SCR_ERROR, serror); | 2571 | sata_scr_write(ap, SCR_ERROR, serror); |
2566 | 2572 | ||
2567 | /* re-enable interrupts */ | 2573 | /* re-enable interrupts */ |
2568 | if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ | 2574 | if (!ap->ops->error_handler) { |
2569 | ata_irq_on(ap); | 2575 | /* FIXME: hack. create a hook instead */ |
2576 | if (ap->ioaddr.ctl_addr) | ||
2577 | ata_irq_on(ap); | ||
2578 | } | ||
2570 | 2579 | ||
2571 | /* is double-select really necessary? */ | 2580 | /* is double-select really necessary? */ |
2572 | if (classes[0] != ATA_DEV_NONE) | 2581 | if (classes[0] != ATA_DEV_NONE) |
@@ -2681,6 +2690,8 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, | |||
2681 | { | 2690 | { |
2682 | int rc = -EINVAL; | 2691 | int rc = -EINVAL; |
2683 | 2692 | ||
2693 | ata_eh_freeze_port(ap); | ||
2694 | |||
2684 | if (probeinit) | 2695 | if (probeinit) |
2685 | probeinit(ap); | 2696 | probeinit(ap); |
2686 | 2697 | ||
@@ -2725,6 +2736,9 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, | |||
2725 | if (rc == 0) { | 2736 | if (rc == 0) { |
2726 | if (postreset) | 2737 | if (postreset) |
2727 | postreset(ap, classes); | 2738 | postreset(ap, classes); |
2739 | |||
2740 | ata_eh_thaw_port(ap); | ||
2741 | |||
2728 | if (classes[0] == ATA_DEV_UNKNOWN) | 2742 | if (classes[0] == ATA_DEV_UNKNOWN) |
2729 | rc = -ENODEV; | 2743 | rc = -ENODEV; |
2730 | } | 2744 | } |
@@ -4039,6 +4053,10 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | |||
4039 | struct ata_queued_cmd *qc = NULL; | 4053 | struct ata_queued_cmd *qc = NULL; |
4040 | unsigned int i; | 4054 | unsigned int i; |
4041 | 4055 | ||
4056 | /* no command while frozen */ | ||
4057 | if (unlikely(ap->flags & ATA_FLAG_FROZEN)) | ||
4058 | return NULL; | ||
4059 | |||
4042 | /* the last tag is reserved for internal command. */ | 4060 | /* the last tag is reserved for internal command. */ |
4043 | for (i = 0; i < ATA_MAX_QUEUE - 1; i++) | 4061 | for (i = 0; i < ATA_MAX_QUEUE - 1; i++) |
4044 | if (!test_and_set_bit(i, &ap->qactive)) { | 4062 | if (!test_and_set_bit(i, &ap->qactive)) { |
@@ -4953,6 +4971,7 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
4953 | 4971 | ||
4954 | ata_chk_status(ap); | 4972 | ata_chk_status(ap); |
4955 | host_set->ops->irq_clear(ap); | 4973 | host_set->ops->irq_clear(ap); |
4974 | ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */ | ||
4956 | count++; | 4975 | count++; |
4957 | } | 4976 | } |
4958 | 4977 | ||
@@ -5385,5 +5404,8 @@ EXPORT_SYMBOL_GPL(ata_scsi_device_resume); | |||
5385 | EXPORT_SYMBOL_GPL(ata_eng_timeout); | 5404 | EXPORT_SYMBOL_GPL(ata_eng_timeout); |
5386 | EXPORT_SYMBOL_GPL(ata_port_schedule_eh); | 5405 | EXPORT_SYMBOL_GPL(ata_port_schedule_eh); |
5387 | EXPORT_SYMBOL_GPL(ata_port_abort); | 5406 | EXPORT_SYMBOL_GPL(ata_port_abort); |
5407 | EXPORT_SYMBOL_GPL(ata_port_freeze); | ||
5408 | EXPORT_SYMBOL_GPL(ata_eh_freeze_port); | ||
5409 | EXPORT_SYMBOL_GPL(ata_eh_thaw_port); | ||
5388 | EXPORT_SYMBOL_GPL(ata_eh_qc_complete); | 5410 | EXPORT_SYMBOL_GPL(ata_eh_qc_complete); |
5389 | EXPORT_SYMBOL_GPL(ata_eh_qc_retry); | 5411 | EXPORT_SYMBOL_GPL(ata_eh_qc_retry); |