diff options
| author | Tejun Heo <tj@kernel.org> | 2010-09-01 11:50:05 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@redhat.com> | 2010-10-21 20:21:04 -0400 |
| commit | 1152b2617a6e1943b6b82e07c962950e56f1000c (patch) | |
| tree | 820b7ca42901b42b1ac5688dcba1f55a5930e176 | |
| parent | c93b263e0d4fa8ce5fec0142a98196d1a127e845 (diff) | |
libata: implement sata_link_scr_lpm() and make ata_dev_set_feature() global
Link power management is about to be reimplemented. Prepare for it.
* Implement sata_link_scr_lpm().
* Drop static from ata_dev_set_feature() and make it available to
other libata files.
* Trivial whitespace adjustments.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
| -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 *)); |
