/*
 * Copyright (c) 1999-2015 Douglas Gilbert.
 * All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the BSD_LICENSE file.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef SG_LIB_LINUX

#include "sg_io_linux.h"


/* Version 1.06 20151217 */

#ifdef __GNUC__
static int pr2ws(const char * fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
#else
static int pr2ws(const char * fmt, ...);
#endif


static int
pr2ws(const char * fmt, ...)
{
    va_list args;
    int n;

    va_start(args, fmt);
    n = vfprintf(sg_warnings_strm ? sg_warnings_strm : stderr, fmt, args);
    va_end(args);
    return n;
}


void
sg_print_masked_status(int masked_status)
{
    int scsi_status = (masked_status << 1) & 0x7e;

    sg_print_scsi_status(scsi_status);
}

static const char * linux_host_bytes[] = {
    "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT",
    "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR",
    "DID_RESET", "DID_BAD_INTR", "DID_PASSTHROUGH", "DID_SOFT_ERROR",
    "DID_IMM_RETRY", "DID_REQUEUE", "DID_TRANSPORT_DISRUPTED",
    "DID_TRANSPORT_FAILFAST", "DID_TARGET_FAILURE", "DID_NEXUS_FAILURE",
    "DID_ALLOC_FAILURE", "DID_MEDIUM_ERROR",
};

#define LINUX_HOST_BYTES_SZ \
        (int)(sizeof(linux_host_bytes) / sizeof(linux_host_bytes[0]))

void
sg_print_host_status(int host_status)
{
    pr2ws("Host_status=0x%02x ", host_status);
    if ((host_status < 0) || (host_status >= LINUX_HOST_BYTES_SZ))
        pr2ws("is invalid ");
    else
        pr2ws("[%s] ", linux_host_bytes[host_status]);
}

static const char * linux_driver_bytes[] = {
    "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA",
    "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD",
    "DRIVER_SENSE"
};

#define LINUX_DRIVER_BYTES_SZ \
    (int)(sizeof(linux_driver_bytes) / sizeof(linux_driver_bytes[0]))

#if 0
static const char * linux_driver_suggests[] = {
    "SUGGEST_OK", "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP",
    "SUGGEST_DIE", "UNKNOWN","UNKNOWN","UNKNOWN",
    "SUGGEST_SENSE"
};

#define LINUX_DRIVER_SUGGESTS_SZ \
    (int)(sizeof(linux_driver_suggests) / sizeof(linux_driver_suggests[0]))
#endif


void
sg_print_driver_status(int driver_status)
{
    int driv;
    const char * driv_cp = "invalid";

    driv = driver_status & SG_LIB_DRIVER_MASK;
    if (driv < LINUX_DRIVER_BYTES_SZ)
        driv_cp = linux_driver_bytes[driv];
#if 0
    sugg = (driver_status & SG_LIB_SUGGEST_MASK) >> 4;
    if (sugg < LINUX_DRIVER_SUGGESTS_SZ)
        sugg_cp = linux_driver_suggests[sugg];
#endif
    pr2ws("Driver_status=0x%02x", driver_status);
    pr2ws(" [%s] ", driv_cp);
}

/* Returns 1 if no errors found and thus nothing printed; otherwise
   prints error/warning (prefix by 'leadin') and returns 0. */
static int
sg_linux_sense_print(const char * leadin, int scsi_status, int host_status,
                     int driver_status, const unsigned char * sense_buffer,
                     int sb_len, int raw_sinfo)
{
    int done_leadin = 0;
    int done_sense = 0;

    scsi_status &= 0x7e; /*sanity */
    if ((0 == scsi_status) && (0 == host_status) && (0 == driver_status))
        return 1;       /* No problems */
    if (0 != scsi_status) {
        if (leadin)
            pr2ws("%s: ", leadin);
        done_leadin = 1;
        pr2ws("SCSI status: ");
        sg_print_scsi_status(scsi_status);
        pr2ws("\n");
        if (sense_buffer && ((scsi_status == SAM_STAT_CHECK_CONDITION) ||
                             (scsi_status == SAM_STAT_COMMAND_TERMINATED))) {
            /* SAM_STAT_COMMAND_TERMINATED is obsolete */
            sg_print_sense(0, sense_buffer, sb_len, raw_sinfo);
            done_sense = 1;
        }
    }
    if (0 != host_status) {
        if (leadin && (! done_leadin))
            pr2ws("%s: ", leadin);
        if (done_leadin)
            pr2ws("plus...: ");
        else
            done_leadin = 1;
        sg_print_host_status(host_status);
        pr2ws("\n");
    }
    if (0 != driver_status) {
        if (done_sense &&
            (SG_LIB_DRIVER_SENSE == (SG_LIB_DRIVER_MASK & driver_status)))
            return 0;
        if (leadin && (! done_leadin))
            pr2ws("%s: ", leadin);
        if (done_leadin)
            pr2ws("plus...: ");
        else
            done_leadin = 1;
        sg_print_driver_status(driver_status);
        pr2ws("\n");
        if (sense_buffer && (! done_sense) &&
            (SG_LIB_DRIVER_SENSE == (SG_LIB_DRIVER_MASK & driver_status)))
            sg_print_sense(0, sense_buffer, sb_len, raw_sinfo);
    }
    return 0;
}

#ifdef SG_IO

int
sg_normalize_sense(const struct sg_io_hdr * hp,
                   struct sg_scsi_sense_hdr * sshp)
{
    if ((NULL == hp) || (0 == hp->sb_len_wr)) {
        if (sshp)
            memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr));
        return 0;
    }
    return sg_scsi_normalize_sense(hp->sbp, hp->sb_len_wr, sshp);
}

/* Returns 1 if no errors found and thus nothing printed; otherwise
   returns 0. */
int
sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp,
                int raw_sinfo)
{
    return sg_linux_sense_print(leadin, hp->status, hp->host_status,
                                hp->driver_status, hp->sbp, hp->sb_len_wr,
                                raw_sinfo);
}
#endif

/* Returns 1 if no errors found and thus nothing printed; otherwise
   returns 0. */
int
sg_chk_n_print(const char * leadin, int masked_status, int host_status,
               int driver_status, const unsigned char * sense_buffer,
               int sb_len, int raw_sinfo)
{
    int scsi_status = (masked_status << 1) & 0x7e;

    return sg_linux_sense_print(leadin, scsi_status, host_status,
                                driver_status, sense_buffer, sb_len,
                                raw_sinfo);
}

#ifdef SG_IO
int
sg_err_category3(struct sg_io_hdr * hp)
{
    return sg_err_category_new(hp->status, hp->host_status,
                               hp->driver_status, hp->sbp, hp->sb_len_wr);
}
#endif

int
sg_err_category(int masked_status, int host_status, int driver_status,
                const unsigned char * sense_buffer, int sb_len)
{
    int scsi_status = (masked_status << 1) & 0x7e;

    return sg_err_category_new(scsi_status, host_status, driver_status,
                               sense_buffer, sb_len);
}

int
sg_err_category_new(int scsi_status, int host_status, int driver_status,
                    const unsigned char * sense_buffer, int sb_len)
{
    int masked_driver_status = (SG_LIB_DRIVER_MASK & driver_status);

    scsi_status &= 0x7e;
    if ((0 == scsi_status) && (0 == host_status) &&
        (0 == masked_driver_status))
        return SG_LIB_CAT_CLEAN;
    if ((SAM_STAT_CHECK_CONDITION == scsi_status) ||
        (SAM_STAT_COMMAND_TERMINATED == scsi_status) ||
        (SG_LIB_DRIVER_SENSE == masked_driver_status))
        return sg_err_category_sense(sense_buffer, sb_len);
    if (0 != host_status) {
        if ((SG_LIB_DID_NO_CONNECT == host_status) ||
            (SG_LIB_DID_BUS_BUSY == host_status) ||
            (SG_LIB_DID_TIME_OUT == host_status))
            return SG_LIB_CAT_TIMEOUT;
        if (SG_LIB_DID_NEXUS_FAILURE == host_status)
            return SG_LIB_CAT_RES_CONFLICT;
    }
    if (SG_LIB_DRIVER_TIMEOUT == masked_driver_status)
        return SG_LIB_CAT_TIMEOUT;
    return SG_LIB_CAT_OTHER;
}

#endif  /* if SG_LIB_LINUX defined */
