diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-08 15:22:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-08 15:22:45 -0400 |
commit | 36a07902c2134649c4af7f07980413ffb1a56085 (patch) | |
tree | be9c931f200aa3505647750ac87a6f8f124a5485 /drivers/ata/libata-eh.c | |
parent | f579bbcd9bb8b688df03191b92c56ab8af4d6322 (diff) | |
parent | 7affb32a32eabbbe42d6746923ec1d0bf7327234 (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
pata_atp867x: add Power Management support
pata_atp867x: PIO support fixes
pata_atp867x: clarifications in timings calculations and cable detection
pata_atp867x: fix it to not claim MWDMA support
libata: fix incorrect link online check during probe
ahci: filter FPDMA non-zero offset enable for Aspire 3810T
libata: make gtf_filter per-dev
libata: implement more acpi filtering options
libata: cosmetic updates
ahci: display all AHCI 1.3 HBA capability flags (v2)
pata_ali: trivial fix of a very frequent spelling mistake
ahci: disable 64bit DMA by default on SB600s
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r-- | drivers/ata/libata-eh.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index a04488f0de88..0a97822da211 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2667,14 +2667,14 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2667 | dev->pio_mode = XFER_PIO_0; | 2667 | dev->pio_mode = XFER_PIO_0; |
2668 | dev->flags &= ~ATA_DFLAG_SLEEPING; | 2668 | dev->flags &= ~ATA_DFLAG_SLEEPING; |
2669 | 2669 | ||
2670 | if (!ata_phys_link_offline(ata_dev_phys_link(dev))) { | 2670 | if (ata_phys_link_offline(ata_dev_phys_link(dev))) |
2671 | /* apply class override */ | 2671 | continue; |
2672 | if (lflags & ATA_LFLAG_ASSUME_ATA) | 2672 | |
2673 | classes[dev->devno] = ATA_DEV_ATA; | 2673 | /* apply class override */ |
2674 | else if (lflags & ATA_LFLAG_ASSUME_SEMB) | 2674 | if (lflags & ATA_LFLAG_ASSUME_ATA) |
2675 | classes[dev->devno] = ATA_DEV_SEMB_UNSUP; | 2675 | classes[dev->devno] = ATA_DEV_ATA; |
2676 | } else | 2676 | else if (lflags & ATA_LFLAG_ASSUME_SEMB) |
2677 | classes[dev->devno] = ATA_DEV_NONE; | 2677 | classes[dev->devno] = ATA_DEV_SEMB_UNSUP; |
2678 | } | 2678 | } |
2679 | 2679 | ||
2680 | /* record current link speed */ | 2680 | /* record current link speed */ |
@@ -2713,34 +2713,48 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2713 | ap->pflags &= ~ATA_PFLAG_EH_PENDING; | 2713 | ap->pflags &= ~ATA_PFLAG_EH_PENDING; |
2714 | spin_unlock_irqrestore(link->ap->lock, flags); | 2714 | spin_unlock_irqrestore(link->ap->lock, flags); |
2715 | 2715 | ||
2716 | /* Make sure onlineness and classification result correspond. | 2716 | /* |
2717 | * Make sure onlineness and classification result correspond. | ||
2717 | * Hotplug could have happened during reset and some | 2718 | * Hotplug could have happened during reset and some |
2718 | * controllers fail to wait while a drive is spinning up after | 2719 | * controllers fail to wait while a drive is spinning up after |
2719 | * being hotplugged causing misdetection. By cross checking | 2720 | * being hotplugged causing misdetection. By cross checking |
2720 | * link onlineness and classification result, those conditions | 2721 | * link on/offlineness and classification result, those |
2721 | * can be reliably detected and retried. | 2722 | * conditions can be reliably detected and retried. |
2722 | */ | 2723 | */ |
2723 | nr_unknown = 0; | 2724 | nr_unknown = 0; |
2724 | ata_for_each_dev(dev, link, ALL) { | 2725 | ata_for_each_dev(dev, link, ALL) { |
2725 | /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ | 2726 | if (ata_phys_link_online(ata_dev_phys_link(dev))) { |
2726 | if (classes[dev->devno] == ATA_DEV_UNKNOWN) { | 2727 | if (classes[dev->devno] == ATA_DEV_UNKNOWN) { |
2727 | classes[dev->devno] = ATA_DEV_NONE; | 2728 | ata_dev_printk(dev, KERN_DEBUG, "link online " |
2728 | if (ata_phys_link_online(ata_dev_phys_link(dev))) | 2729 | "but device misclassifed\n"); |
2730 | classes[dev->devno] = ATA_DEV_NONE; | ||
2729 | nr_unknown++; | 2731 | nr_unknown++; |
2732 | } | ||
2733 | } else if (ata_phys_link_offline(ata_dev_phys_link(dev))) { | ||
2734 | if (ata_class_enabled(classes[dev->devno])) | ||
2735 | ata_dev_printk(dev, KERN_DEBUG, "link offline, " | ||
2736 | "clearing class %d to NONE\n", | ||
2737 | classes[dev->devno]); | ||
2738 | classes[dev->devno] = ATA_DEV_NONE; | ||
2739 | } else if (classes[dev->devno] == ATA_DEV_UNKNOWN) { | ||
2740 | ata_dev_printk(dev, KERN_DEBUG, "link status unknown, " | ||
2741 | "clearing UNKNOWN to NONE\n"); | ||
2742 | classes[dev->devno] = ATA_DEV_NONE; | ||
2730 | } | 2743 | } |
2731 | } | 2744 | } |
2732 | 2745 | ||
2733 | if (classify && nr_unknown) { | 2746 | if (classify && nr_unknown) { |
2734 | if (try < max_tries) { | 2747 | if (try < max_tries) { |
2735 | ata_link_printk(link, KERN_WARNING, "link online but " | 2748 | ata_link_printk(link, KERN_WARNING, "link online but " |
2736 | "device misclassified, retrying\n"); | 2749 | "%d devices misclassified, retrying\n", |
2750 | nr_unknown); | ||
2737 | failed_link = link; | 2751 | failed_link = link; |
2738 | rc = -EAGAIN; | 2752 | rc = -EAGAIN; |
2739 | goto fail; | 2753 | goto fail; |
2740 | } | 2754 | } |
2741 | ata_link_printk(link, KERN_WARNING, | 2755 | ata_link_printk(link, KERN_WARNING, |
2742 | "link online but device misclassified, " | 2756 | "link online but %d devices misclassified, " |
2743 | "device detection might fail\n"); | 2757 | "device detection might fail\n", nr_unknown); |
2744 | } | 2758 | } |
2745 | 2759 | ||
2746 | /* reset successful, schedule revalidation */ | 2760 | /* reset successful, schedule revalidation */ |