diff options
-rw-r--r-- | drivers/ata/libata-core.c | 75 | ||||
-rw-r--r-- | drivers/ata/libata.h | 2 | ||||
-rw-r--r-- | include/linux/libata.h | 2 |
3 files changed, 74 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 380ceb000aad..b8024451234c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -91,8 +91,6 @@ const struct ata_port_operations sata_port_ops = { | |||
91 | static unsigned int ata_dev_init_params(struct ata_device *dev, | 91 | static unsigned int ata_dev_init_params(struct ata_device *dev, |
92 | u16 heads, u16 sectors); | 92 | u16 heads, u16 sectors); |
93 | static unsigned int ata_dev_set_xfermode(struct ata_device *dev); | 93 | static unsigned int ata_dev_set_xfermode(struct ata_device *dev); |
94 | static unsigned int ata_dev_set_feature(struct ata_device *dev, | ||
95 | u8 enable, u8 feature); | ||
96 | static void ata_dev_xfermask(struct ata_device *dev); | 94 | static void ata_dev_xfermask(struct ata_device *dev); |
97 | static unsigned long ata_dev_blacklisted(const struct ata_device *dev); | 95 | static unsigned long ata_dev_blacklisted(const struct ata_device *dev); |
98 | 96 | ||
@@ -3628,7 +3626,7 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, | |||
3628 | * @params: timing parameters { interval, duratinon, timeout } in msec | 3626 | * @params: timing parameters { interval, duratinon, timeout } in msec |
3629 | * @deadline: deadline jiffies for the operation | 3627 | * @deadline: deadline jiffies for the operation |
3630 | * | 3628 | * |
3631 | * Make sure SStatus of @link reaches stable state, determined by | 3629 | * Make sure SStatus of @link reaches stable state, determined by |
3632 | * holding the same value where DET is not 1 for @duration polled | 3630 | * holding the same value where DET is not 1 for @duration polled |
3633 | * every @interval, before @timeout. Timeout constraints the | 3631 | * every @interval, before @timeout. Timeout constraints the |
3634 | * beginning of the stable state. Because DET gets stuck at 1 on | 3632 | * beginning of the stable state. Because DET gets stuck at 1 on |
@@ -3760,6 +3758,72 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, | |||
3760 | } | 3758 | } |
3761 | 3759 | ||
3762 | /** | 3760 | /** |
3761 | * sata_link_scr_lpm - manipulate SControl IPM and SPM fields | ||
3762 | * @link: ATA link to manipulate SControl for | ||
3763 | * @policy: LPM policy to configure | ||
3764 | * @spm_wakeup: initiate LPM transition to active state | ||
3765 | * | ||
3766 | * Manipulate the IPM field of the SControl register of @link | ||
3767 | * according to @policy. If @policy is ATA_LPM_MAX_POWER and | ||
3768 | * @spm_wakeup is %true, the SPM field is manipulated to wake up | ||
3769 | * the link. This function also clears PHYRDY_CHG before | ||
3770 | * returning. | ||
3771 | * | ||
3772 | * LOCKING: | ||
3773 | * EH context. | ||
3774 | * | ||
3775 | * RETURNS: | ||
3776 | * 0 on succes, -errno otherwise. | ||
3777 | */ | ||
3778 | int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, | ||
3779 | bool spm_wakeup) | ||
3780 | { | ||
3781 | struct ata_eh_context *ehc = &link->eh_context; | ||
3782 | bool woken_up = false; | ||
3783 | u32 scontrol; | ||
3784 | int rc; | ||
3785 | |||
3786 | rc = sata_scr_read(link, SCR_CONTROL, &scontrol); | ||
3787 | if (rc) | ||
3788 | return rc; | ||
3789 | |||
3790 | switch (policy) { | ||
3791 | case ATA_LPM_MAX_POWER: | ||
3792 | /* disable all LPM transitions */ | ||
3793 | scontrol |= (0x3 << 8); | ||
3794 | /* initiate transition to active state */ | ||
3795 | if (spm_wakeup) { | ||
3796 | scontrol |= (0x4 << 12); | ||
3797 | woken_up = true; | ||
3798 | } | ||
3799 | break; | ||
3800 | case ATA_LPM_MED_POWER: | ||
3801 | /* allow LPM to PARTIAL */ | ||
3802 | scontrol &= ~(0x1 << 8); | ||
3803 | scontrol |= (0x2 << 8); | ||
3804 | break; | ||
3805 | case ATA_LPM_MIN_POWER: | ||
3806 | /* no restrictions on LPM transitions */ | ||
3807 | scontrol &= ~(0x3 << 8); | ||
3808 | break; | ||
3809 | default: | ||
3810 | WARN_ON(1); | ||
3811 | } | ||
3812 | |||
3813 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); | ||
3814 | if (rc) | ||
3815 | return rc; | ||
3816 | |||
3817 | /* give the link time to transit out of LPM state */ | ||
3818 | if (woken_up) | ||
3819 | msleep(10); | ||
3820 | |||
3821 | /* clear PHYRDY_CHG from SError */ | ||
3822 | ehc->i.serror &= ~SERR_PHYRDY_CHG; | ||
3823 | return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); | ||
3824 | } | ||
3825 | |||
3826 | /** | ||
3763 | * ata_std_prereset - prepare for reset | 3827 | * ata_std_prereset - prepare for reset |
3764 | * @link: ATA link to be reset | 3828 | * @link: ATA link to be reset |
3765 | * @deadline: deadline jiffies for the operation | 3829 | * @deadline: deadline jiffies for the operation |
@@ -4551,6 +4615,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) | |||
4551 | DPRINTK("EXIT, err_mask=%x\n", err_mask); | 4615 | DPRINTK("EXIT, err_mask=%x\n", err_mask); |
4552 | return err_mask; | 4616 | return err_mask; |
4553 | } | 4617 | } |
4618 | |||
4554 | /** | 4619 | /** |
4555 | * ata_dev_set_feature - Issue SET FEATURES - SATA FEATURES | 4620 | * ata_dev_set_feature - Issue SET FEATURES - SATA FEATURES |
4556 | * @dev: Device to which command will be sent | 4621 | * @dev: Device to which command will be sent |
@@ -4566,8 +4631,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) | |||
4566 | * RETURNS: | 4631 | * RETURNS: |
4567 | * 0 on success, AC_ERR_* mask otherwise. | 4632 | * 0 on success, AC_ERR_* mask otherwise. |
4568 | */ | 4633 | */ |
4569 | static unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, | 4634 | unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature) |
4570 | u8 feature) | ||
4571 | { | 4635 | { |
4572 | struct ata_taskfile tf; | 4636 | struct ata_taskfile tf; |
4573 | unsigned int err_mask; | 4637 | unsigned int err_mask; |
@@ -6732,6 +6796,7 @@ EXPORT_SYMBOL_GPL(sata_set_spd); | |||
6732 | EXPORT_SYMBOL_GPL(ata_wait_after_reset); | 6796 | EXPORT_SYMBOL_GPL(ata_wait_after_reset); |
6733 | EXPORT_SYMBOL_GPL(sata_link_debounce); | 6797 | EXPORT_SYMBOL_GPL(sata_link_debounce); |
6734 | EXPORT_SYMBOL_GPL(sata_link_resume); | 6798 | EXPORT_SYMBOL_GPL(sata_link_resume); |
6799 | EXPORT_SYMBOL_GPL(sata_link_scr_lpm); | ||
6735 | EXPORT_SYMBOL_GPL(ata_std_prereset); | 6800 | EXPORT_SYMBOL_GPL(ata_std_prereset); |
6736 | EXPORT_SYMBOL_GPL(sata_link_hardreset); | 6801 | EXPORT_SYMBOL_GPL(sata_link_hardreset); |
6737 | EXPORT_SYMBOL_GPL(sata_std_hardreset); | 6802 | EXPORT_SYMBOL_GPL(sata_std_hardreset); |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 1471462e3e3c..65b6a73c3ac7 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -86,6 +86,8 @@ extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | |||
86 | extern int ata_dev_configure(struct ata_device *dev); | 86 | extern int ata_dev_configure(struct ata_device *dev); |
87 | extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); | 87 | extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); |
88 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); | 88 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); |
89 | extern unsigned int ata_dev_set_feature(struct ata_device *dev, | ||
90 | u8 enable, u8 feature); | ||
89 | extern void ata_sg_clean(struct ata_queued_cmd *qc); | 91 | extern void ata_sg_clean(struct ata_queued_cmd *qc); |
90 | extern void ata_qc_free(struct ata_queued_cmd *qc); | 92 | extern void ata_qc_free(struct ata_queued_cmd *qc); |
91 | extern void ata_qc_issue(struct ata_queued_cmd *qc); | 93 | extern void ata_qc_issue(struct ata_queued_cmd *qc); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index c5bdc90fd319..7770eeb21039 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -952,6 +952,8 @@ extern int sata_link_debounce(struct ata_link *link, | |||
952 | const unsigned long *params, unsigned long deadline); | 952 | const unsigned long *params, unsigned long deadline); |
953 | extern int sata_link_resume(struct ata_link *link, const unsigned long *params, | 953 | extern int sata_link_resume(struct ata_link *link, const unsigned long *params, |
954 | unsigned long deadline); | 954 | unsigned long deadline); |
955 | extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, | ||
956 | bool spm_wakeup); | ||
955 | extern int sata_link_hardreset(struct ata_link *link, | 957 | extern int sata_link_hardreset(struct ata_link *link, |
956 | const unsigned long *timing, unsigned long deadline, | 958 | const unsigned long *timing, unsigned long deadline, |
957 | bool *online, int (*check_ready)(struct ata_link *)); | 959 | bool *online, int (*check_ready)(struct ata_link *)); |