mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
ata: libata: Move sata_down_spd_limit() to libata-sata.c
Move the definition of the function sata_down_spd_limit() to libata-sata.c where it belongs, together with sata_set_spd(). The helper function ata_sstatus_online() is also changed to be an inline function defined in drivers/ata/libata.h. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de>
This commit is contained in:
parent
5bb52d9265
commit
b642212d88
@ -167,11 +167,6 @@ static inline bool ata_dev_print_info(const struct ata_device *dev)
|
||||
return ehc->i.flags & ATA_EHI_PRINTINFO;
|
||||
}
|
||||
|
||||
static bool ata_sstatus_online(u32 sstatus)
|
||||
{
|
||||
return (sstatus & 0xf) == 0x3;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_link_next - link iteration helper
|
||||
* @link: the previous link, NULL to start
|
||||
@ -3200,86 +3195,6 @@ struct ata_device *ata_dev_pair(struct ata_device *adev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_dev_pair);
|
||||
|
||||
/**
|
||||
* sata_down_spd_limit - adjust SATA spd limit downward
|
||||
* @link: Link to adjust SATA spd limit for
|
||||
* @spd_limit: Additional limit
|
||||
*
|
||||
* Adjust SATA spd limit of @link downward. Note that this
|
||||
* function only adjusts the limit. The change must be applied
|
||||
* using sata_set_spd().
|
||||
*
|
||||
* If @spd_limit is non-zero, the speed is limited to equal to or
|
||||
* lower than @spd_limit if such speed is supported. If
|
||||
* @spd_limit is slower than any supported speed, only the lowest
|
||||
* supported speed is allowed.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, negative errno on failure
|
||||
*/
|
||||
int sata_down_spd_limit(struct ata_link *link, u32 spd_limit)
|
||||
{
|
||||
u32 sstatus, spd, mask;
|
||||
int rc, bit;
|
||||
|
||||
if (!sata_scr_valid(link))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* If SCR can be read, use it to determine the current SPD.
|
||||
* If not, use cached value in link->sata_spd.
|
||||
*/
|
||||
rc = sata_scr_read(link, SCR_STATUS, &sstatus);
|
||||
if (rc == 0 && ata_sstatus_online(sstatus))
|
||||
spd = (sstatus >> 4) & 0xf;
|
||||
else
|
||||
spd = link->sata_spd;
|
||||
|
||||
mask = link->sata_spd_limit;
|
||||
if (mask <= 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* unconditionally mask off the highest bit */
|
||||
bit = fls(mask) - 1;
|
||||
mask &= ~(1 << bit);
|
||||
|
||||
/*
|
||||
* Mask off all speeds higher than or equal to the current one. At
|
||||
* this point, if current SPD is not available and we previously
|
||||
* recorded the link speed from SStatus, the driver has already
|
||||
* masked off the highest bit so mask should already be 1 or 0.
|
||||
* Otherwise, we should not force 1.5Gbps on a link where we have
|
||||
* not previously recorded speed from SStatus. Just return in this
|
||||
* case.
|
||||
*/
|
||||
if (spd > 1)
|
||||
mask &= (1 << (spd - 1)) - 1;
|
||||
else if (link->sata_spd)
|
||||
return -EINVAL;
|
||||
|
||||
/* were we already at the bottom? */
|
||||
if (!mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (spd_limit) {
|
||||
if (mask & ((1 << spd_limit) - 1))
|
||||
mask &= (1 << spd_limit) - 1;
|
||||
else {
|
||||
bit = ffs(mask) - 1;
|
||||
mask = 1 << bit;
|
||||
}
|
||||
}
|
||||
|
||||
link->sata_spd_limit = mask;
|
||||
|
||||
ata_link_warn(link, "limiting SATA link speed to %s\n",
|
||||
sata_spd_string(fls(mask)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ATA_ACPI
|
||||
/**
|
||||
* ata_timing_cycle2mode - find xfer mode for the specified cycle duration
|
||||
|
@ -517,6 +517,86 @@ int sata_set_spd(struct ata_link *link)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sata_set_spd);
|
||||
|
||||
/**
|
||||
* sata_down_spd_limit - adjust SATA spd limit downward
|
||||
* @link: Link to adjust SATA spd limit for
|
||||
* @spd_limit: Additional limit
|
||||
*
|
||||
* Adjust SATA spd limit of @link downward. Note that this
|
||||
* function only adjusts the limit. The change must be applied
|
||||
* using sata_set_spd().
|
||||
*
|
||||
* If @spd_limit is non-zero, the speed is limited to equal to or
|
||||
* lower than @spd_limit if such speed is supported. If
|
||||
* @spd_limit is slower than any supported speed, only the lowest
|
||||
* supported speed is allowed.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, negative errno on failure
|
||||
*/
|
||||
int sata_down_spd_limit(struct ata_link *link, u32 spd_limit)
|
||||
{
|
||||
u32 sstatus, spd, mask;
|
||||
int rc, bit;
|
||||
|
||||
if (!sata_scr_valid(link))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* If SCR can be read, use it to determine the current SPD.
|
||||
* If not, use cached value in link->sata_spd.
|
||||
*/
|
||||
rc = sata_scr_read(link, SCR_STATUS, &sstatus);
|
||||
if (rc == 0 && ata_sstatus_online(sstatus))
|
||||
spd = (sstatus >> 4) & 0xf;
|
||||
else
|
||||
spd = link->sata_spd;
|
||||
|
||||
mask = link->sata_spd_limit;
|
||||
if (mask <= 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* unconditionally mask off the highest bit */
|
||||
bit = fls(mask) - 1;
|
||||
mask &= ~(1 << bit);
|
||||
|
||||
/*
|
||||
* Mask off all speeds higher than or equal to the current one. At
|
||||
* this point, if current SPD is not available and we previously
|
||||
* recorded the link speed from SStatus, the driver has already
|
||||
* masked off the highest bit so mask should already be 1 or 0.
|
||||
* Otherwise, we should not force 1.5Gbps on a link where we have
|
||||
* not previously recorded speed from SStatus. Just return in this
|
||||
* case.
|
||||
*/
|
||||
if (spd > 1)
|
||||
mask &= (1 << (spd - 1)) - 1;
|
||||
else if (link->sata_spd)
|
||||
return -EINVAL;
|
||||
|
||||
/* were we already at the bottom? */
|
||||
if (!mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (spd_limit) {
|
||||
if (mask & ((1 << spd_limit) - 1))
|
||||
mask &= (1 << spd_limit) - 1;
|
||||
else {
|
||||
bit = ffs(mask) - 1;
|
||||
mask = 1 << bit;
|
||||
}
|
||||
}
|
||||
|
||||
link->sata_spd_limit = mask;
|
||||
|
||||
ata_link_warn(link, "limiting SATA link speed to %s\n",
|
||||
sata_spd_string(fls(mask)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sata_link_hardreset - reset link via SATA phy reset
|
||||
* @link: link to reset
|
||||
|
@ -38,6 +38,12 @@ extern int libata_noacpi;
|
||||
extern int libata_allow_tpm;
|
||||
extern const struct device_type ata_port_type;
|
||||
extern struct ata_link *ata_dev_phys_link(struct ata_device *dev);
|
||||
|
||||
static inline bool ata_sstatus_online(u32 sstatus)
|
||||
{
|
||||
return (sstatus & 0xf) == 0x3;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ATA_FORCE
|
||||
extern void ata_force_cbl(struct ata_port *ap);
|
||||
#else
|
||||
@ -65,7 +71,6 @@ extern bool ata_dev_power_init_tf(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, bool set_active);
|
||||
extern void ata_dev_power_set_standby(struct ata_device *dev);
|
||||
extern void ata_dev_power_set_active(struct ata_device *dev);
|
||||
extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
|
||||
extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
|
||||
extern unsigned int ata_dev_set_feature(struct ata_device *dev,
|
||||
u8 subcmd, u8 action);
|
||||
@ -87,6 +92,16 @@ extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
|
||||
|
||||
#define to_ata_port(d) container_of(d, struct ata_port, tdev)
|
||||
|
||||
/* libata-sata.c */
|
||||
#ifdef CONFIG_SATA_HOST
|
||||
int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
|
||||
#else
|
||||
static inline int sata_down_spd_limit(struct ata_link *link, u32 spd_limit)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* libata-acpi.c */
|
||||
#ifdef CONFIG_ATA_ACPI
|
||||
extern unsigned int ata_acpi_gtf_filter;
|
||||
|
Loading…
Reference in New Issue
Block a user