* move ata_sstatus_online() to libata.h and make it inline * move sata_down_spd_limit() to libata-core-sata.c * add static inline for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 35276 572 40 35888 8c30 drivers/ata/libata-core.o after: 34996 572 40 35608 8b18 drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@xxxxxxxxxxx> --- drivers/ata/libata-core-sata.c | 80 ++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 85 ---------------------------------- drivers/ata/libata.h | 11 ++++- 3 files changed, 90 insertions(+), 86 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index 8ad8f97660df..fb956c8aee9a 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -285,6 +285,86 @@ void sata_print_link_status(struct ata_link *link) } } +/** + * 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 + 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_scr_lpm - manipulate SControl IPM and SPM fields * @link: ATA link to manipulate SControl for diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 73f732a32261..1d0744f18754 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -167,11 +167,6 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -static bool ata_sstatus_online(u32 sstatus) -{ - return (sstatus & 0xf) == 0x3; -} - /** * ata_link_next - link iteration helper * @link: the previous link, NULL to start @@ -2760,86 +2755,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 - 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; -} - static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) { struct ata_link *host_link = &link->ap->link; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 909c2cae52a0..518a8e08a26d 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -64,7 +64,6 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags); extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, unsigned int readid_flags); extern int ata_dev_configure(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 enable, u8 feature); @@ -87,6 +86,11 @@ extern void __ata_port_probe(struct ata_port *ap); extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, u8 page, void *buf, unsigned int sectors); +static inline bool ata_sstatus_online(u32 sstatus) +{ + return (sstatus & 0xf) == 0x3; +} + static inline bool ata_log_supported(struct ata_device *dev, u8 log) { struct ata_port *ap = dev->link->ap; @@ -103,6 +107,7 @@ static inline bool ata_log_supported(struct ata_device *dev, u8 log) int ata_do_link_spd_horkage(struct ata_device *dev); int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz); void sata_print_link_status(struct ata_link *link); +int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); #else static inline int ata_do_link_spd_horkage(struct ata_device *dev) { return 0; } static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, @@ -112,6 +117,10 @@ static inline int ata_dev_config_ncq(struct ata_device *dev, char *desc, return 0; } static inline void sata_print_link_status(struct ata_link *link) { } +static inline int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) +{ + return -EOPNOTSUPP; +} #endif /* libata-acpi.c */ -- 2.24.1