aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c26
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);
5385EXPORT_SYMBOL_GPL(ata_eng_timeout); 5404EXPORT_SYMBOL_GPL(ata_eng_timeout);
5386EXPORT_SYMBOL_GPL(ata_port_schedule_eh); 5405EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
5387EXPORT_SYMBOL_GPL(ata_port_abort); 5406EXPORT_SYMBOL_GPL(ata_port_abort);
5407EXPORT_SYMBOL_GPL(ata_port_freeze);
5408EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
5409EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
5388EXPORT_SYMBOL_GPL(ata_eh_qc_complete); 5410EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
5389EXPORT_SYMBOL_GPL(ata_eh_qc_retry); 5411EXPORT_SYMBOL_GPL(ata_eh_qc_retry);