diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/libata-core.c | 187 |
1 files changed, 13 insertions, 174 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 01f2c59536bc..30a6020c5121 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1479,31 +1479,21 @@ static int ata_bus_probe(struct ata_port *ap) | |||
1479 | down_xfermask = 0; | 1479 | down_xfermask = 0; |
1480 | 1480 | ||
1481 | /* reset and determine device classes */ | 1481 | /* reset and determine device classes */ |
1482 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1482 | ap->ops->phy_reset(ap); |
1483 | classes[i] = ATA_DEV_UNKNOWN; | ||
1484 | 1483 | ||
1485 | if (ap->ops->probe_reset) { | 1484 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
1486 | rc = ap->ops->probe_reset(ap, classes); | 1485 | dev = &ap->device[i]; |
1487 | if (rc) { | ||
1488 | ata_port_printk(ap, KERN_ERR, | ||
1489 | "reset failed (errno=%d)\n", rc); | ||
1490 | return rc; | ||
1491 | } | ||
1492 | } else { | ||
1493 | ap->ops->phy_reset(ap); | ||
1494 | 1486 | ||
1495 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 1487 | if (!(ap->flags & ATA_FLAG_DISABLED) && |
1496 | if (!(ap->flags & ATA_FLAG_DISABLED)) | 1488 | dev->class != ATA_DEV_UNKNOWN) |
1497 | classes[i] = ap->device[i].class; | 1489 | classes[dev->devno] = dev->class; |
1498 | ap->device[i].class = ATA_DEV_UNKNOWN; | 1490 | else |
1499 | } | 1491 | classes[dev->devno] = ATA_DEV_NONE; |
1500 | 1492 | ||
1501 | ata_port_probe(ap); | 1493 | dev->class = ATA_DEV_UNKNOWN; |
1502 | } | 1494 | } |
1503 | 1495 | ||
1504 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1496 | ata_port_probe(ap); |
1505 | if (classes[i] == ATA_DEV_UNKNOWN) | ||
1506 | classes[i] = ATA_DEV_NONE; | ||
1507 | 1497 | ||
1508 | /* after the reset the device state is PIO 0 and the controller | 1498 | /* after the reset the device state is PIO 0 and the controller |
1509 | state is undefined. Record the mode */ | 1499 | state is undefined. Record the mode */ |
@@ -2610,37 +2600,11 @@ int ata_std_prereset(struct ata_port *ap) | |||
2610 | } | 2600 | } |
2611 | 2601 | ||
2612 | /** | 2602 | /** |
2613 | * ata_std_probeinit - initialize probing | ||
2614 | * @ap: port to be probed | ||
2615 | * | ||
2616 | * @ap is about to be probed. Initialize it. This function is | ||
2617 | * to be used as standard callback for ata_drive_probe_reset(). | ||
2618 | * | ||
2619 | * NOTE!!! Do not use this function as probeinit if a low level | ||
2620 | * driver implements only hardreset. Just pass NULL as probeinit | ||
2621 | * in that case. Using this function is probably okay but doing | ||
2622 | * so makes reset sequence different from the original | ||
2623 | * ->phy_reset implementation and Jeff nervous. :-P | ||
2624 | */ | ||
2625 | void ata_std_probeinit(struct ata_port *ap) | ||
2626 | { | ||
2627 | static const unsigned long deb_timing[] = { 5, 100, 5000 }; | ||
2628 | |||
2629 | /* resume link */ | ||
2630 | sata_phy_resume(ap, deb_timing); | ||
2631 | |||
2632 | /* wait for device */ | ||
2633 | if (ata_port_online(ap)) | ||
2634 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | ||
2635 | } | ||
2636 | |||
2637 | /** | ||
2638 | * ata_std_softreset - reset host port via ATA SRST | 2603 | * ata_std_softreset - reset host port via ATA SRST |
2639 | * @ap: port to reset | 2604 | * @ap: port to reset |
2640 | * @classes: resulting classes of attached devices | 2605 | * @classes: resulting classes of attached devices |
2641 | * | 2606 | * |
2642 | * Reset host port using ATA SRST. This function is to be used | 2607 | * Reset host port using ATA SRST. |
2643 | * as standard callback for ata_drive_*_reset() functions. | ||
2644 | * | 2608 | * |
2645 | * LOCKING: | 2609 | * LOCKING: |
2646 | * Kernel thread context (may sleep) | 2610 | * Kernel thread context (may sleep) |
@@ -2695,8 +2659,6 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) | |||
2695 | * @class: resulting class of attached device | 2659 | * @class: resulting class of attached device |
2696 | * | 2660 | * |
2697 | * SATA phy-reset host port using DET bits of SControl register. | 2661 | * SATA phy-reset host port using DET bits of SControl register. |
2698 | * This function is to be used as standard callback for | ||
2699 | * ata_drive_*_reset(). | ||
2700 | * | 2662 | * |
2701 | * LOCKING: | 2663 | * LOCKING: |
2702 | * Kernel thread context (may sleep) | 2664 | * Kernel thread context (may sleep) |
@@ -2775,9 +2737,6 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class) | |||
2775 | * the device might have been reset more than once using | 2737 | * the device might have been reset more than once using |
2776 | * different reset methods before postreset is invoked. | 2738 | * different reset methods before postreset is invoked. |
2777 | * | 2739 | * |
2778 | * This function is to be used as standard callback for | ||
2779 | * ata_drive_*_reset(). | ||
2780 | * | ||
2781 | * LOCKING: | 2740 | * LOCKING: |
2782 | * Kernel thread context (may sleep) | 2741 | * Kernel thread context (may sleep) |
2783 | */ | 2742 | */ |
@@ -2824,32 +2783,6 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes) | |||
2824 | DPRINTK("EXIT\n"); | 2783 | DPRINTK("EXIT\n"); |
2825 | } | 2784 | } |
2826 | 2785 | ||
2827 | /** | ||
2828 | * ata_std_probe_reset - standard probe reset method | ||
2829 | * @ap: prot to perform probe-reset | ||
2830 | * @classes: resulting classes of attached devices | ||
2831 | * | ||
2832 | * The stock off-the-shelf ->probe_reset method. | ||
2833 | * | ||
2834 | * LOCKING: | ||
2835 | * Kernel thread context (may sleep) | ||
2836 | * | ||
2837 | * RETURNS: | ||
2838 | * 0 on success, -errno otherwise. | ||
2839 | */ | ||
2840 | int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes) | ||
2841 | { | ||
2842 | ata_reset_fn_t hardreset; | ||
2843 | |||
2844 | hardreset = NULL; | ||
2845 | if (sata_scr_valid(ap)) | ||
2846 | hardreset = sata_std_hardreset; | ||
2847 | |||
2848 | return ata_drive_probe_reset(ap, ata_std_probeinit, | ||
2849 | ata_std_softreset, hardreset, | ||
2850 | ata_std_postreset, classes); | ||
2851 | } | ||
2852 | |||
2853 | int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, | 2786 | int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, |
2854 | unsigned int *classes) | 2787 | unsigned int *classes) |
2855 | { | 2788 | { |
@@ -2879,97 +2812,6 @@ int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, | |||
2879 | } | 2812 | } |
2880 | 2813 | ||
2881 | /** | 2814 | /** |
2882 | * ata_drive_probe_reset - Perform probe reset with given methods | ||
2883 | * @ap: port to reset | ||
2884 | * @probeinit: probeinit method (can be NULL) | ||
2885 | * @softreset: softreset method (can be NULL) | ||
2886 | * @hardreset: hardreset method (can be NULL) | ||
2887 | * @postreset: postreset method (can be NULL) | ||
2888 | * @classes: resulting classes of attached devices | ||
2889 | * | ||
2890 | * Reset the specified port and classify attached devices using | ||
2891 | * given methods. This function prefers softreset but tries all | ||
2892 | * possible reset sequences to reset and classify devices. This | ||
2893 | * function is intended to be used for constructing ->probe_reset | ||
2894 | * callback by low level drivers. | ||
2895 | * | ||
2896 | * Reset methods should follow the following rules. | ||
2897 | * | ||
2898 | * - Return 0 on sucess, -errno on failure. | ||
2899 | * - If classification is supported, fill classes[] with | ||
2900 | * recognized class codes. | ||
2901 | * - If classification is not supported, leave classes[] alone. | ||
2902 | * | ||
2903 | * LOCKING: | ||
2904 | * Kernel thread context (may sleep) | ||
2905 | * | ||
2906 | * RETURNS: | ||
2907 | * 0 on success, -EINVAL if no reset method is avaliable, -ENODEV | ||
2908 | * if classification fails, and any error code from reset | ||
2909 | * methods. | ||
2910 | */ | ||
2911 | int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, | ||
2912 | ata_reset_fn_t softreset, ata_reset_fn_t hardreset, | ||
2913 | ata_postreset_fn_t postreset, unsigned int *classes) | ||
2914 | { | ||
2915 | int rc = -EINVAL; | ||
2916 | |||
2917 | ata_eh_freeze_port(ap); | ||
2918 | |||
2919 | if (probeinit) | ||
2920 | probeinit(ap); | ||
2921 | |||
2922 | if (softreset && !sata_set_spd_needed(ap)) { | ||
2923 | rc = ata_do_reset(ap, softreset, classes); | ||
2924 | if (rc == 0 && classes[0] != ATA_DEV_UNKNOWN) | ||
2925 | goto done; | ||
2926 | ata_port_printk(ap, KERN_INFO, "softreset failed, " | ||
2927 | "will try hardreset in 5 secs\n"); | ||
2928 | ssleep(5); | ||
2929 | } | ||
2930 | |||
2931 | if (!hardreset) | ||
2932 | goto done; | ||
2933 | |||
2934 | while (1) { | ||
2935 | rc = ata_do_reset(ap, hardreset, classes); | ||
2936 | if (rc == 0) { | ||
2937 | if (classes[0] != ATA_DEV_UNKNOWN) | ||
2938 | goto done; | ||
2939 | break; | ||
2940 | } | ||
2941 | |||
2942 | if (sata_down_spd_limit(ap)) | ||
2943 | goto done; | ||
2944 | |||
2945 | ata_port_printk(ap, KERN_INFO, "hardreset failed, " | ||
2946 | "will retry in 5 secs\n"); | ||
2947 | ssleep(5); | ||
2948 | } | ||
2949 | |||
2950 | if (softreset) { | ||
2951 | ata_port_printk(ap, KERN_INFO, | ||
2952 | "hardreset succeeded without classification, " | ||
2953 | "will retry softreset in 5 secs\n"); | ||
2954 | ssleep(5); | ||
2955 | |||
2956 | rc = ata_do_reset(ap, softreset, classes); | ||
2957 | } | ||
2958 | |||
2959 | done: | ||
2960 | if (rc == 0) { | ||
2961 | if (postreset) | ||
2962 | postreset(ap, classes); | ||
2963 | |||
2964 | ata_eh_thaw_port(ap); | ||
2965 | |||
2966 | if (classes[0] == ATA_DEV_UNKNOWN) | ||
2967 | rc = -ENODEV; | ||
2968 | } | ||
2969 | return rc; | ||
2970 | } | ||
2971 | |||
2972 | /** | ||
2973 | * ata_dev_same_device - Determine whether new ID matches configured device | 2815 | * ata_dev_same_device - Determine whether new ID matches configured device |
2974 | * @dev: device to compare against | 2816 | * @dev: device to compare against |
2975 | * @new_class: class of the new device | 2817 | * @new_class: class of the new device |
@@ -5419,7 +5261,7 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, | |||
5419 | 5261 | ||
5420 | DPRINTK("ENTER\n"); | 5262 | DPRINTK("ENTER\n"); |
5421 | 5263 | ||
5422 | if (!ent->port_ops->probe_reset && !ent->port_ops->error_handler && | 5264 | if (!ent->port_ops->error_handler && |
5423 | !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { | 5265 | !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { |
5424 | printk(KERN_ERR "ata%u: no reset mechanism available\n", | 5266 | printk(KERN_ERR "ata%u: no reset mechanism available\n", |
5425 | port_no); | 5267 | port_no); |
@@ -5551,7 +5393,7 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5551 | */ | 5393 | */ |
5552 | } | 5394 | } |
5553 | 5395 | ||
5554 | if (!ap->ops->probe_reset) { | 5396 | if (ap->ops->error_handler) { |
5555 | unsigned long flags; | 5397 | unsigned long flags; |
5556 | 5398 | ||
5557 | ata_port_probe(ap); | 5399 | ata_port_probe(ap); |
@@ -5998,13 +5840,10 @@ EXPORT_SYMBOL_GPL(sata_phy_resume); | |||
5998 | EXPORT_SYMBOL_GPL(sata_phy_reset); | 5840 | EXPORT_SYMBOL_GPL(sata_phy_reset); |
5999 | EXPORT_SYMBOL_GPL(__sata_phy_reset); | 5841 | EXPORT_SYMBOL_GPL(__sata_phy_reset); |
6000 | EXPORT_SYMBOL_GPL(ata_bus_reset); | 5842 | EXPORT_SYMBOL_GPL(ata_bus_reset); |
6001 | EXPORT_SYMBOL_GPL(ata_std_probeinit); | ||
6002 | EXPORT_SYMBOL_GPL(ata_std_prereset); | 5843 | EXPORT_SYMBOL_GPL(ata_std_prereset); |
6003 | EXPORT_SYMBOL_GPL(ata_std_softreset); | 5844 | EXPORT_SYMBOL_GPL(ata_std_softreset); |
6004 | EXPORT_SYMBOL_GPL(sata_std_hardreset); | 5845 | EXPORT_SYMBOL_GPL(sata_std_hardreset); |
6005 | EXPORT_SYMBOL_GPL(ata_std_postreset); | 5846 | EXPORT_SYMBOL_GPL(ata_std_postreset); |
6006 | EXPORT_SYMBOL_GPL(ata_std_probe_reset); | ||
6007 | EXPORT_SYMBOL_GPL(ata_drive_probe_reset); | ||
6008 | EXPORT_SYMBOL_GPL(ata_dev_revalidate); | 5847 | EXPORT_SYMBOL_GPL(ata_dev_revalidate); |
6009 | EXPORT_SYMBOL_GPL(ata_dev_classify); | 5848 | EXPORT_SYMBOL_GPL(ata_dev_classify); |
6010 | EXPORT_SYMBOL_GPL(ata_dev_pair); | 5849 | EXPORT_SYMBOL_GPL(ata_dev_pair); |