aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c75
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--include/linux/libata.h2
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 = {
91static unsigned int ata_dev_init_params(struct ata_device *dev, 91static unsigned int ata_dev_init_params(struct ata_device *dev,
92 u16 heads, u16 sectors); 92 u16 heads, u16 sectors);
93static unsigned int ata_dev_set_xfermode(struct ata_device *dev); 93static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
94static unsigned int ata_dev_set_feature(struct ata_device *dev,
95 u8 enable, u8 feature);
96static void ata_dev_xfermask(struct ata_device *dev); 94static void ata_dev_xfermask(struct ata_device *dev);
97static unsigned long ata_dev_blacklisted(const struct ata_device *dev); 95static 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 */
3778int 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 */
4569static unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, 4634unsigned 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);
6732EXPORT_SYMBOL_GPL(ata_wait_after_reset); 6796EXPORT_SYMBOL_GPL(ata_wait_after_reset);
6733EXPORT_SYMBOL_GPL(sata_link_debounce); 6797EXPORT_SYMBOL_GPL(sata_link_debounce);
6734EXPORT_SYMBOL_GPL(sata_link_resume); 6798EXPORT_SYMBOL_GPL(sata_link_resume);
6799EXPORT_SYMBOL_GPL(sata_link_scr_lpm);
6735EXPORT_SYMBOL_GPL(ata_std_prereset); 6800EXPORT_SYMBOL_GPL(ata_std_prereset);
6736EXPORT_SYMBOL_GPL(sata_link_hardreset); 6801EXPORT_SYMBOL_GPL(sata_link_hardreset);
6737EXPORT_SYMBOL_GPL(sata_std_hardreset); 6802EXPORT_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,
86extern int ata_dev_configure(struct ata_device *dev); 86extern int ata_dev_configure(struct ata_device *dev);
87extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); 87extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
88extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); 88extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
89extern unsigned int ata_dev_set_feature(struct ata_device *dev,
90 u8 enable, u8 feature);
89extern void ata_sg_clean(struct ata_queued_cmd *qc); 91extern void ata_sg_clean(struct ata_queued_cmd *qc);
90extern void ata_qc_free(struct ata_queued_cmd *qc); 92extern void ata_qc_free(struct ata_queued_cmd *qc);
91extern void ata_qc_issue(struct ata_queued_cmd *qc); 93extern 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);
953extern int sata_link_resume(struct ata_link *link, const unsigned long *params, 953extern int sata_link_resume(struct ata_link *link, const unsigned long *params,
954 unsigned long deadline); 954 unsigned long deadline);
955extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
956 bool spm_wakeup);
955extern int sata_link_hardreset(struct ata_link *link, 957extern 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 *));