lkml.org 
[lkml]   [2020]   [Mar]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 26/27] ata: move ata_eh_analyze_ncq_error() & co. to libata-sata.c
    Date
    * move ata_eh_analyze_ncq_error() and ata_eh_read_log_10h() to
    libata-sata.c

    * add static inline for ata_eh_analyze_ncq_error() for
    CONFIG_SATA_HOST=n case (link->sactive is non-zero only if
    NCQ commands are actually queued so empty function body is
    sufficient)

    Code size savings on m68k arch using (modified) atari_defconfig:

    text data bss dec hex filename
    before:
    16164 18 0 16182 3f36 drivers/ata/libata-eh.o
    after:
    15446 18 0 15464 3c68 drivers/ata/libata-eh.o

    Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
    ---
    drivers/ata/libata-eh.c | 131 --------------------------------------
    drivers/ata/libata-sata.c | 131 ++++++++++++++++++++++++++++++++++++++
    include/linux/libata.h | 3 +-
    3 files changed, 133 insertions(+), 132 deletions(-)

    diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
    index 9ca777a24117..702f4aa4d509 100644
    --- a/drivers/ata/libata-eh.c
    +++ b/drivers/ata/libata-eh.c
    @@ -1352,62 +1352,6 @@ static const char *ata_err_string(unsigned int err_mask)
    return "unknown error";
    }

    -/**
    - * ata_eh_read_log_10h - Read log page 10h for NCQ error details
    - * @dev: Device to read log page 10h from
    - * @tag: Resulting tag of the failed command
    - * @tf: Resulting taskfile registers of the failed command
    - *
    - * Read log page 10h to obtain NCQ error details and clear error
    - * condition.
    - *
    - * LOCKING:
    - * Kernel thread context (may sleep).
    - *
    - * RETURNS:
    - * 0 on success, -errno otherwise.
    - */
    -static int ata_eh_read_log_10h(struct ata_device *dev,
    - int *tag, struct ata_taskfile *tf)
    -{
    - u8 *buf = dev->link->ap->sector_buf;
    - unsigned int err_mask;
    - u8 csum;
    - int i;
    -
    - err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1);
    - if (err_mask)
    - return -EIO;
    -
    - csum = 0;
    - for (i = 0; i < ATA_SECT_SIZE; i++)
    - csum += buf[i];
    - if (csum)
    - ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n",
    - csum);
    -
    - if (buf[0] & 0x80)
    - return -ENOENT;
    -
    - *tag = buf[0] & 0x1f;
    -
    - tf->command = buf[2];
    - tf->feature = buf[3];
    - tf->lbal = buf[4];
    - tf->lbam = buf[5];
    - tf->lbah = buf[6];
    - tf->device = buf[7];
    - tf->hob_lbal = buf[8];
    - tf->hob_lbam = buf[9];
    - tf->hob_lbah = buf[10];
    - tf->nsect = buf[12];
    - tf->hob_nsect = buf[13];
    - if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id))
    - tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
    -
    - return 0;
    -}
    -
    /**
    * atapi_eh_tur - perform ATAPI TEST_UNIT_READY
    * @dev: target ATAPI device
    @@ -1587,81 +1531,6 @@ static void ata_eh_analyze_serror(struct ata_link *link)
    ehc->i.action |= action;
    }

    -/**
    - * ata_eh_analyze_ncq_error - analyze NCQ error
    - * @link: ATA link to analyze NCQ error for
    - *
    - * Read log page 10h, determine the offending qc and acquire
    - * error status TF. For NCQ device errors, all LLDDs have to do
    - * is setting AC_ERR_DEV in ehi->err_mask. This function takes
    - * care of the rest.
    - *
    - * LOCKING:
    - * Kernel thread context (may sleep).
    - */
    -void ata_eh_analyze_ncq_error(struct ata_link *link)
    -{
    - struct ata_port *ap = link->ap;
    - struct ata_eh_context *ehc = &link->eh_context;
    - struct ata_device *dev = link->device;
    - struct ata_queued_cmd *qc;
    - struct ata_taskfile tf;
    - int tag, rc;
    -
    - /* if frozen, we can't do much */
    - if (ap->pflags & ATA_PFLAG_FROZEN)
    - return;
    -
    - /* is it NCQ device error? */
    - if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV))
    - return;
    -
    - /* has LLDD analyzed already? */
    - ata_qc_for_each_raw(ap, qc, tag) {
    - if (!(qc->flags & ATA_QCFLAG_FAILED))
    - continue;
    -
    - if (qc->err_mask)
    - return;
    - }
    -
    - /* okay, this error is ours */
    - memset(&tf, 0, sizeof(tf));
    - rc = ata_eh_read_log_10h(dev, &tag, &tf);
    - if (rc) {
    - ata_link_err(link, "failed to read log page 10h (errno=%d)\n",
    - rc);
    - return;
    - }
    -
    - if (!(link->sactive & (1 << tag))) {
    - ata_link_err(link, "log page 10h reported inactive tag %d\n",
    - tag);
    - return;
    - }
    -
    - /* we've got the perpetrator, condemn it */
    - qc = __ata_qc_from_tag(ap, tag);
    - memcpy(&qc->result_tf, &tf, sizeof(tf));
    - qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
    - qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
    - if (dev->class == ATA_DEV_ZAC &&
    - ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) {
    - char sense_key, asc, ascq;
    -
    - sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
    - asc = (qc->result_tf.auxiliary >> 8) & 0xff;
    - ascq = qc->result_tf.auxiliary & 0xff;
    - ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq);
    - ata_scsi_set_sense_information(dev, qc->scsicmd,
    - &qc->result_tf);
    - qc->flags |= ATA_QCFLAG_SENSE_VALID;
    - }
    -
    - ehc->i.err_mask &= ~AC_ERR_DEV;
    -}
    -EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error);
    -
    /**
    * ata_eh_analyze_tf - analyze taskfile of a failed qc
    * @qc: qc to analyze
    diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
    index eff744727dc0..13c105912167 100644
    --- a/drivers/ata/libata-sata.c
    +++ b/drivers/ata/libata-sata.c
    @@ -1347,3 +1347,134 @@ int sata_async_notification(struct ata_port *ap)
    }
    }
    EXPORT_SYMBOL_GPL(sata_async_notification);
    +
    +/**
    + * ata_eh_read_log_10h - Read log page 10h for NCQ error details
    + * @dev: Device to read log page 10h from
    + * @tag: Resulting tag of the failed command
    + * @tf: Resulting taskfile registers of the failed command
    + *
    + * Read log page 10h to obtain NCQ error details and clear error
    + * condition.
    + *
    + * LOCKING:
    + * Kernel thread context (may sleep).
    + *
    + * RETURNS:
    + * 0 on success, -errno otherwise.
    + */
    +static int ata_eh_read_log_10h(struct ata_device *dev,
    + int *tag, struct ata_taskfile *tf)
    +{
    + u8 *buf = dev->link->ap->sector_buf;
    + unsigned int err_mask;
    + u8 csum;
    + int i;
    +
    + err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1);
    + if (err_mask)
    + return -EIO;
    +
    + csum = 0;
    + for (i = 0; i < ATA_SECT_SIZE; i++)
    + csum += buf[i];
    + if (csum)
    + ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n",
    + csum);
    +
    + if (buf[0] & 0x80)
    + return -ENOENT;
    +
    + *tag = buf[0] & 0x1f;
    +
    + tf->command = buf[2];
    + tf->feature = buf[3];
    + tf->lbal = buf[4];
    + tf->lbam = buf[5];
    + tf->lbah = buf[6];
    + tf->device = buf[7];
    + tf->hob_lbal = buf[8];
    + tf->hob_lbam = buf[9];
    + tf->hob_lbah = buf[10];
    + tf->nsect = buf[12];
    + tf->hob_nsect = buf[13];
    + if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id))
    + tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
    +
    + return 0;
    +}
    +
    +/**
    + * ata_eh_analyze_ncq_error - analyze NCQ error
    + * @link: ATA link to analyze NCQ error for
    + *
    + * Read log page 10h, determine the offending qc and acquire
    + * error status TF. For NCQ device errors, all LLDDs have to do
    + * is setting AC_ERR_DEV in ehi->err_mask. This function takes
    + * care of the rest.
    + *
    + * LOCKING:
    + * Kernel thread context (may sleep).
    + */
    +void ata_eh_analyze_ncq_error(struct ata_link *link)
    +{
    + struct ata_port *ap = link->ap;
    + struct ata_eh_context *ehc = &link->eh_context;
    + struct ata_device *dev = link->device;
    + struct ata_queued_cmd *qc;
    + struct ata_taskfile tf;
    + int tag, rc;
    +
    + /* if frozen, we can't do much */
    + if (ap->pflags & ATA_PFLAG_FROZEN)
    + return;
    +
    + /* is it NCQ device error? */
    + if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV))
    + return;
    +
    + /* has LLDD analyzed already? */
    + ata_qc_for_each_raw(ap, qc, tag) {
    + if (!(qc->flags & ATA_QCFLAG_FAILED))
    + continue;
    +
    + if (qc->err_mask)
    + return;
    + }
    +
    + /* okay, this error is ours */
    + memset(&tf, 0, sizeof(tf));
    + rc = ata_eh_read_log_10h(dev, &tag, &tf);
    + if (rc) {
    + ata_link_err(link, "failed to read log page 10h (errno=%d)\n",
    + rc);
    + return;
    + }
    +
    + if (!(link->sactive & (1 << tag))) {
    + ata_link_err(link, "log page 10h reported inactive tag %d\n",
    + tag);
    + return;
    + }
    +
    + /* we've got the perpetrator, condemn it */
    + qc = __ata_qc_from_tag(ap, tag);
    + memcpy(&qc->result_tf, &tf, sizeof(tf));
    + qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
    + qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
    + if (dev->class == ATA_DEV_ZAC &&
    + ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) {
    + char sense_key, asc, ascq;
    +
    + sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
    + asc = (qc->result_tf.auxiliary >> 8) & 0xff;
    + ascq = qc->result_tf.auxiliary & 0xff;
    + ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq);
    + ata_scsi_set_sense_information(dev, qc->scsicmd,
    + &qc->result_tf);
    + qc->flags |= ATA_QCFLAG_SENSE_VALID;
    + }
    +
    + ehc->i.err_mask &= ~AC_ERR_DEV;
    +}
    +EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error);
    diff --git a/include/linux/libata.h b/include/linux/libata.h
    index 556fc5d367aa..422bb71f3bf5 100644
    --- a/include/linux/libata.h
    +++ b/include/linux/libata.h
    @@ -1182,6 +1182,7 @@ extern int sata_link_hardreset(struct ata_link *link,
    bool *online, int (*check_ready)(struct ata_link *));
    extern int sata_link_resume(struct ata_link *link, const unsigned long *params,
    unsigned long deadline);
    +extern void ata_eh_analyze_ncq_error(struct ata_link *link);
    #else
    static inline const unsigned long *
    sata_ehc_deb_timing(struct ata_eh_context *ehc)
    @@ -1218,6 +1219,7 @@ static inline int sata_link_resume(struct ata_link *link,
    {
    return -EOPNOTSUPP;
    }
    +static inline void ata_eh_analyze_ncq_error(struct ata_link *link) { }
    #endif
    extern int sata_link_debounce(struct ata_link *link,
    const unsigned long *params, unsigned long deadline);
    @@ -1342,7 +1344,6 @@ extern void ata_eh_thaw_port(struct ata_port *ap);

    extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
    extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
    -extern void ata_eh_analyze_ncq_error(struct ata_link *link);

    extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
    ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
    --
    2.24.1
    \
     
     \ /
      Last update: 2020-03-17 15:44    [W:4.809 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site