lkml.org 
[lkml]   [2019]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.1 150/219] libata: don't request sense data on !ZAC ATA devices
    Date
    From: Tejun Heo <tj@kernel.org>

    [ Upstream commit ca156e006add67e4beea7896be395160735e09b0 ]

    ZAC support added sense data requesting on error for both ZAC and ATA
    devices. This seems to cause erratic error handling behaviors on some
    SSDs where the device reports sense data availability and then
    delivers the wrong content making EH take the wrong actions. The
    failure mode was sporadic on a LITE-ON ssd and couldn't be reliably
    reproduced.

    There is no value in requesting sense data from non-ZAC ATA devices
    while there's a significant risk of introducing EH misbehaviors which
    are difficult to reproduce and fix. Let's do the sense data dancing
    only for ZAC devices.

    Reviewed-by: Hannes Reinecke <hare@suse.com>
    Tested-by: Masato Suzuki <masato.suzuki@wdc.com>
    Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
    Signed-off-by: Tejun Heo <tj@kernel.org>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/ata/libata-eh.c | 8 +++++---
    1 file changed, 5 insertions(+), 3 deletions(-)

    diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
    index 938ed513b070..6215680418c4 100644
    --- a/drivers/ata/libata-eh.c
    +++ b/drivers/ata/libata-eh.c
    @@ -1486,7 +1486,7 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
    tf->hob_lbah = buf[10];
    tf->nsect = buf[12];
    tf->hob_nsect = buf[13];
    - if (ata_id_has_ncq_autosense(dev->id))
    + 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;
    @@ -1733,7 +1733,8 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
    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 ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary) {
    + 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;
    @@ -1787,10 +1788,11 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
    }

    switch (qc->dev->class) {
    - case ATA_DEV_ATA:
    case ATA_DEV_ZAC:
    if (stat & ATA_SENSE)
    ata_eh_request_sense(qc, qc->scsicmd);
    + /* fall through */
    + case ATA_DEV_ATA:
    if (err & ATA_ICRC)
    qc->err_mask |= AC_ERR_ATA_BUS;
    if (err & (ATA_UNC | ATA_AMNF))
    --
    2.20.1
    \
     
     \ /
      Last update: 2019-07-15 17:15    [W:2.250 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site