* move ata_log_supported() to libata.h and make it inline * move ata_dev_config_ncq*() to libata-core-sata.c * add static inline version of ata_dev_config_ncq() for CONFIG_SATA_HOST=n case Code size savings on m68k arch using atari_defconfig: text data bss dec hex filename before: 36627 572 40 37239 9177 drivers/ata/libata-core.o after: 35499 572 40 36111 8d0f drivers/ata/libata-core.o Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@xxxxxxxxxxx> --- drivers/ata/libata-core-sata.c | 138 ++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 148 --------------------------------- drivers/ata/libata.h | 18 ++++ 3 files changed, 156 insertions(+), 148 deletions(-) diff --git a/drivers/ata/libata-core-sata.c b/drivers/ata/libata-core-sata.c index fed8009981c0..f2629e069a55 100644 --- a/drivers/ata/libata-core-sata.c +++ b/drivers/ata/libata-core-sata.c @@ -120,6 +120,144 @@ int ata_do_link_spd_horkage(struct ata_device *dev) return 0; } +static void ata_dev_config_ncq_send_recv(struct ata_device *dev) +{ + struct ata_port *ap = dev->link->ap; + unsigned int err_mask; + + if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) { + ata_dev_warn(dev, "NCQ Send/Recv Log not supported\n"); + return; + } + err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV, + 0, ap->sector_buf, 1); + if (err_mask) { + ata_dev_dbg(dev, + "failed to get NCQ Send/Recv Log Emask 0x%x\n", + err_mask); + } else { + u8 *cmds = dev->ncq_send_recv_cmds; + + dev->flags |= ATA_DFLAG_NCQ_SEND_RECV; + memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE); + + if (dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) { + ata_dev_dbg(dev, "disabling queued TRIM support\n"); + cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &= + ~ATA_LOG_NCQ_SEND_RECV_DSM_TRIM; + } + } +} + +static void ata_dev_config_ncq_non_data(struct ata_device *dev) +{ + struct ata_port *ap = dev->link->ap; + unsigned int err_mask; + + if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) { + ata_dev_warn(dev, + "NCQ Send/Recv Log not supported\n"); + return; + } + err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, + 0, ap->sector_buf, 1); + if (err_mask) { + ata_dev_dbg(dev, + "failed to get NCQ Non-Data Log Emask 0x%x\n", + err_mask); + } else { + u8 *cmds = dev->ncq_non_data_cmds; + + memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE); + } +} + +static void ata_dev_config_ncq_prio(struct ata_device *dev) +{ + struct ata_port *ap = dev->link->ap; + unsigned int err_mask; + + if (!(dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) { + dev->flags &= ~ATA_DFLAG_NCQ_PRIO; + return; + } + + err_mask = ata_read_log_page(dev, + ATA_LOG_IDENTIFY_DEVICE, + ATA_LOG_SATA_SETTINGS, + ap->sector_buf, + 1); + if (err_mask) { + ata_dev_dbg(dev, + "failed to get Identify Device data, Emask 0x%x\n", + err_mask); + return; + } + + if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)) { + dev->flags |= ATA_DFLAG_NCQ_PRIO; + } else { + dev->flags &= ~ATA_DFLAG_NCQ_PRIO; + ata_dev_dbg(dev, "SATA page does not support priority\n"); + } + +} + +int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz) +{ + struct ata_port *ap = dev->link->ap; + int hdepth = 0, ddepth = ata_id_queue_depth(dev->id); + unsigned int err_mask; + char *aa_desc = ""; + + if (!ata_id_has_ncq(dev->id)) { + desc[0] = '\0'; + return 0; + } + if (dev->horkage & ATA_HORKAGE_NONCQ) { + snprintf(desc, desc_sz, "NCQ (not used)"); + return 0; + } + if (ap->flags & ATA_FLAG_NCQ) { + hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE); + dev->flags |= ATA_DFLAG_NCQ; + } + + if (!(dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA) && + (ap->flags & ATA_FLAG_FPDMA_AA) && + ata_id_has_fpdma_aa(dev->id)) { + err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE, + SATA_FPDMA_AA); + if (err_mask) { + ata_dev_err(dev, + "failed to enable AA (error_mask=0x%x)\n", + err_mask); + if (err_mask != AC_ERR_DEV) { + dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA; + return -EIO; + } + } else + aa_desc = ", AA"; + } + + if (hdepth >= ddepth) + snprintf(desc, desc_sz, "NCQ (depth %d)%s", ddepth, aa_desc); + else + snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, + ddepth, aa_desc); + + if ((ap->flags & ATA_FLAG_FPDMA_AUX)) { + if (ata_id_has_ncq_send_and_recv(dev->id)) + ata_dev_config_ncq_send_recv(dev); + if (ata_id_has_ncq_non_data(dev->id)) + ata_dev_config_ncq_non_data(dev); + if (ata_id_has_ncq_prio(dev->id)) + ata_dev_config_ncq_prio(dev); + } + + 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 52bd81bad484..0a90e0e65f0b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2034,15 +2034,6 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log, return err_mask; } -static bool ata_log_supported(struct ata_device *dev, u8 log) -{ - struct ata_port *ap = dev->link->ap; - - if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1)) - return false; - return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false; -} - static bool ata_identify_page_supported(struct ata_device *dev, u8 page) { struct ata_port *ap = dev->link->ap; @@ -2084,145 +2075,6 @@ static inline u8 ata_dev_knobble(struct ata_device *dev) return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); } -static void ata_dev_config_ncq_send_recv(struct ata_device *dev) -{ - struct ata_port *ap = dev->link->ap; - unsigned int err_mask; - - if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) { - ata_dev_warn(dev, "NCQ Send/Recv Log not supported\n"); - return; - } - err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV, - 0, ap->sector_buf, 1); - if (err_mask) { - ata_dev_dbg(dev, - "failed to get NCQ Send/Recv Log Emask 0x%x\n", - err_mask); - } else { - u8 *cmds = dev->ncq_send_recv_cmds; - - dev->flags |= ATA_DFLAG_NCQ_SEND_RECV; - memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE); - - if (dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) { - ata_dev_dbg(dev, "disabling queued TRIM support\n"); - cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &= - ~ATA_LOG_NCQ_SEND_RECV_DSM_TRIM; - } - } -} - -static void ata_dev_config_ncq_non_data(struct ata_device *dev) -{ - struct ata_port *ap = dev->link->ap; - unsigned int err_mask; - - if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) { - ata_dev_warn(dev, - "NCQ Send/Recv Log not supported\n"); - return; - } - err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, - 0, ap->sector_buf, 1); - if (err_mask) { - ata_dev_dbg(dev, - "failed to get NCQ Non-Data Log Emask 0x%x\n", - err_mask); - } else { - u8 *cmds = dev->ncq_non_data_cmds; - - memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE); - } -} - -static void ata_dev_config_ncq_prio(struct ata_device *dev) -{ - struct ata_port *ap = dev->link->ap; - unsigned int err_mask; - - if (!(dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) { - dev->flags &= ~ATA_DFLAG_NCQ_PRIO; - return; - } - - err_mask = ata_read_log_page(dev, - ATA_LOG_IDENTIFY_DEVICE, - ATA_LOG_SATA_SETTINGS, - ap->sector_buf, - 1); - if (err_mask) { - ata_dev_dbg(dev, - "failed to get Identify Device data, Emask 0x%x\n", - err_mask); - return; - } - - if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)) { - dev->flags |= ATA_DFLAG_NCQ_PRIO; - } else { - dev->flags &= ~ATA_DFLAG_NCQ_PRIO; - ata_dev_dbg(dev, "SATA page does not support priority\n"); - } - -} - -static int ata_dev_config_ncq(struct ata_device *dev, - char *desc, size_t desc_sz) -{ - struct ata_port *ap = dev->link->ap; - int hdepth = 0, ddepth = ata_id_queue_depth(dev->id); - unsigned int err_mask; - char *aa_desc = ""; - - if (!ata_id_has_ncq(dev->id)) { - desc[0] = '\0'; - return 0; - } - if (dev->horkage & ATA_HORKAGE_NONCQ) { - snprintf(desc, desc_sz, "NCQ (not used)"); - return 0; - } - if (ap->flags & ATA_FLAG_NCQ) { - hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE); - dev->flags |= ATA_DFLAG_NCQ; - } - - if (!(dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA) && - (ap->flags & ATA_FLAG_FPDMA_AA) && - ata_id_has_fpdma_aa(dev->id)) { - err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE, - SATA_FPDMA_AA); - if (err_mask) { - ata_dev_err(dev, - "failed to enable AA (error_mask=0x%x)\n", - err_mask); - if (err_mask != AC_ERR_DEV) { - dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA; - return -EIO; - } - } else - aa_desc = ", AA"; - } - - if (hdepth >= ddepth) - snprintf(desc, desc_sz, "NCQ (depth %d)%s", ddepth, aa_desc); - else - snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, - ddepth, aa_desc); - - if ((ap->flags & ATA_FLAG_FPDMA_AUX)) { - if (ata_id_has_ncq_send_and_recv(dev->id)) - ata_dev_config_ncq_send_recv(dev); - if (ata_id_has_ncq_non_data(dev->id)) - ata_dev_config_ncq_non_data(dev); - if (ata_id_has_ncq_prio(dev->id)) - ata_dev_config_ncq_prio(dev); - } - - return 0; -} - static void ata_dev_config_sense_reporting(struct ata_device *dev) { unsigned int err_mask; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 9eebe4e0be39..24b08efd79a3 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -15,6 +15,8 @@ #define DRV_NAME "libata" #define DRV_VERSION "3.00" /* must be exactly four chars */ +#include <asm/unaligned.h> + /* libata-core.c */ enum { /* flags for ata_dev_read_id() */ @@ -85,13 +87,29 @@ 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_log_supported(struct ata_device *dev, u8 log) +{ + struct ata_port *ap = dev->link->ap; + + if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1)) + return false; + return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false; +} + #define to_ata_port(d) container_of(d, struct ata_port, tdev) /* libata-core-sata.c */ #ifdef CONFIG_SATA_HOST 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); #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, + size_t desc_sz) +{ + desc[0] = '\0'; + return 0; +} #endif /* libata-acpi.c */ -- 2.24.1