diff options
-rw-r--r-- | drivers/ata/libata-core.c | 52 | ||||
-rw-r--r-- | include/linux/libata.h | 2 |
2 files changed, 44 insertions, 10 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index d2336673601c..315f46841f68 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2786,9 +2786,9 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) | |||
2786 | } | 2786 | } |
2787 | 2787 | ||
2788 | /** | 2788 | /** |
2789 | * sata_std_hardreset - reset host port via SATA phy reset | 2789 | * sata_port_hardreset - reset port via SATA phy reset |
2790 | * @ap: port to reset | 2790 | * @ap: port to reset |
2791 | * @class: resulting class of attached device | 2791 | * @timing: timing parameters { interval, duratinon, timeout } in msec |
2792 | * | 2792 | * |
2793 | * SATA phy-reset host port using DET bits of SControl register. | 2793 | * SATA phy-reset host port using DET bits of SControl register. |
2794 | * | 2794 | * |
@@ -2798,10 +2798,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) | |||
2798 | * RETURNS: | 2798 | * RETURNS: |
2799 | * 0 on success, -errno otherwise. | 2799 | * 0 on success, -errno otherwise. |
2800 | */ | 2800 | */ |
2801 | int sata_std_hardreset(struct ata_port *ap, unsigned int *class) | 2801 | int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing) |
2802 | { | 2802 | { |
2803 | struct ata_eh_context *ehc = &ap->eh_context; | ||
2804 | const unsigned long *timing = sata_ehc_deb_timing(ehc); | ||
2805 | u32 scontrol; | 2803 | u32 scontrol; |
2806 | int rc; | 2804 | int rc; |
2807 | 2805 | ||
@@ -2814,24 +2812,24 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class) | |||
2814 | * and Sil3124. | 2812 | * and Sil3124. |
2815 | */ | 2813 | */ |
2816 | if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) | 2814 | if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) |
2817 | return rc; | 2815 | goto out; |
2818 | 2816 | ||
2819 | scontrol = (scontrol & 0x0f0) | 0x304; | 2817 | scontrol = (scontrol & 0x0f0) | 0x304; |
2820 | 2818 | ||
2821 | if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) | 2819 | if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) |
2822 | return rc; | 2820 | goto out; |
2823 | 2821 | ||
2824 | sata_set_spd(ap); | 2822 | sata_set_spd(ap); |
2825 | } | 2823 | } |
2826 | 2824 | ||
2827 | /* issue phy wake/reset */ | 2825 | /* issue phy wake/reset */ |
2828 | if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) | 2826 | if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) |
2829 | return rc; | 2827 | goto out; |
2830 | 2828 | ||
2831 | scontrol = (scontrol & 0x0f0) | 0x301; | 2829 | scontrol = (scontrol & 0x0f0) | 0x301; |
2832 | 2830 | ||
2833 | if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol))) | 2831 | if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol))) |
2834 | return rc; | 2832 | goto out; |
2835 | 2833 | ||
2836 | /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 | 2834 | /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 |
2837 | * 10.4.2 says at least 1 ms. | 2835 | * 10.4.2 says at least 1 ms. |
@@ -2839,7 +2837,40 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class) | |||
2839 | msleep(1); | 2837 | msleep(1); |
2840 | 2838 | ||
2841 | /* bring phy back */ | 2839 | /* bring phy back */ |
2842 | sata_phy_resume(ap, timing); | 2840 | rc = sata_phy_resume(ap, timing); |
2841 | out: | ||
2842 | DPRINTK("EXIT, rc=%d\n", rc); | ||
2843 | return rc; | ||
2844 | } | ||
2845 | |||
2846 | /** | ||
2847 | * sata_std_hardreset - reset host port via SATA phy reset | ||
2848 | * @ap: port to reset | ||
2849 | * @class: resulting class of attached device | ||
2850 | * | ||
2851 | * SATA phy-reset host port using DET bits of SControl register, | ||
2852 | * wait for !BSY and classify the attached device. | ||
2853 | * | ||
2854 | * LOCKING: | ||
2855 | * Kernel thread context (may sleep) | ||
2856 | * | ||
2857 | * RETURNS: | ||
2858 | * 0 on success, -errno otherwise. | ||
2859 | */ | ||
2860 | int sata_std_hardreset(struct ata_port *ap, unsigned int *class) | ||
2861 | { | ||
2862 | const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context); | ||
2863 | int rc; | ||
2864 | |||
2865 | DPRINTK("ENTER\n"); | ||
2866 | |||
2867 | /* do hardreset */ | ||
2868 | rc = sata_port_hardreset(ap, timing); | ||
2869 | if (rc) { | ||
2870 | ata_port_printk(ap, KERN_ERR, | ||
2871 | "COMRESET failed (errno=%d)\n", rc); | ||
2872 | return rc; | ||
2873 | } | ||
2843 | 2874 | ||
2844 | /* TODO: phy layer with polling, timeouts, etc. */ | 2875 | /* TODO: phy layer with polling, timeouts, etc. */ |
2845 | if (ata_port_offline(ap)) { | 2876 | if (ata_port_offline(ap)) { |
@@ -6159,6 +6190,7 @@ EXPORT_SYMBOL_GPL(__sata_phy_reset); | |||
6159 | EXPORT_SYMBOL_GPL(ata_bus_reset); | 6190 | EXPORT_SYMBOL_GPL(ata_bus_reset); |
6160 | EXPORT_SYMBOL_GPL(ata_std_prereset); | 6191 | EXPORT_SYMBOL_GPL(ata_std_prereset); |
6161 | EXPORT_SYMBOL_GPL(ata_std_softreset); | 6192 | EXPORT_SYMBOL_GPL(ata_std_softreset); |
6193 | EXPORT_SYMBOL_GPL(sata_port_hardreset); | ||
6162 | EXPORT_SYMBOL_GPL(sata_std_hardreset); | 6194 | EXPORT_SYMBOL_GPL(sata_std_hardreset); |
6163 | EXPORT_SYMBOL_GPL(ata_std_postreset); | 6195 | EXPORT_SYMBOL_GPL(ata_std_postreset); |
6164 | EXPORT_SYMBOL_GPL(ata_dev_classify); | 6196 | EXPORT_SYMBOL_GPL(ata_dev_classify); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index d3bf7b936c3f..41fa0890dbfb 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -702,6 +702,8 @@ extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param); | |||
702 | extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param); | 702 | extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param); |
703 | extern int ata_std_prereset(struct ata_port *ap); | 703 | extern int ata_std_prereset(struct ata_port *ap); |
704 | extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); | 704 | extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); |
705 | extern int sata_port_hardreset(struct ata_port *ap, | ||
706 | const unsigned long *timing); | ||
705 | extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); | 707 | extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); |
706 | extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); | 708 | extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); |
707 | extern void ata_port_disable(struct ata_port *); | 709 | extern void ata_port_disable(struct ata_port *); |