@@ -91,8 +91,6 @@ const struct ata_port_operations sata_port_ops = {
9191static unsigned int ata_dev_init_params (struct ata_device * dev ,
9292 u16 heads , u16 sectors );
9393static 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 );
9694static void ata_dev_xfermask (struct ata_device * dev );
9795static unsigned long ata_dev_blacklisted (const struct ata_device * dev );
9896
@@ -3628,7 +3626,7 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
36283626 * @params: timing parameters { interval, duratinon, timeout } in msec
36293627 * @deadline: deadline jiffies for the operation
36303628 *
3631- * Make sure SStatus of @link reaches stable state, determined by
3629+ * Make sure SStatus of @link reaches stable state, determined by
36323630 * holding the same value where DET is not 1 for @duration polled
36333631 * every @interval, before @timeout. Timeout constraints the
36343632 * beginning of the stable state. Because DET gets stuck at 1 on
@@ -3759,6 +3757,72 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
37593757 return rc != - EINVAL ? rc : 0 ;
37603758}
37613759
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+
37623826/**
37633827 * ata_std_prereset - prepare for reset
37643828 * @link: ATA link to be reset
@@ -4551,6 +4615,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
45514615 DPRINTK ("EXIT, err_mask=%x\n" , err_mask );
45524616 return err_mask ;
45534617}
4618+
45544619/**
45554620 * ata_dev_set_feature - Issue SET FEATURES - SATA FEATURES
45564621 * @dev: Device to which command will be sent
@@ -4566,8 +4631,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
45664631 * RETURNS:
45674632 * 0 on success, AC_ERR_* mask otherwise.
45684633 */
4569- static unsigned int ata_dev_set_feature (struct ata_device * dev , u8 enable ,
4570- u8 feature )
4634+ unsigned int ata_dev_set_feature (struct ata_device * dev , u8 enable , u8 feature )
45714635{
45724636 struct ata_taskfile tf ;
45734637 unsigned int err_mask ;
@@ -6732,6 +6796,7 @@ EXPORT_SYMBOL_GPL(sata_set_spd);
67326796EXPORT_SYMBOL_GPL (ata_wait_after_reset );
67336797EXPORT_SYMBOL_GPL (sata_link_debounce );
67346798EXPORT_SYMBOL_GPL (sata_link_resume );
6799+ EXPORT_SYMBOL_GPL (sata_link_scr_lpm );
67356800EXPORT_SYMBOL_GPL (ata_std_prereset );
67366801EXPORT_SYMBOL_GPL (sata_link_hardreset );
67376802EXPORT_SYMBOL_GPL (sata_std_hardreset );
0 commit comments