/*
 * Generic SCSI Device support
 *
 * Copyright (c) 2007 Bull S.A.S.
 * Based on code by Paul Brook
 * Based on code by Fabrice Bellard
 *
 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
 *
 * This code is licensed under the LGPL.
 *
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/ctype.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "hw/scsi/scsi.h"
#include "migration/qemu-file-types.h"
#include "hw/qdev-properties.h"
#include "hw/scsi/emulation.h"
#include "sysemu/block-backend.h"
#include "trace.h"

#ifdef __linux__

#include <scsi/sg.h>
#include "scsi/constants.h"

#ifndef MAX_UINT
#define MAX_UINT ((unsigned int)-1)
#endif

typedef struct SCSIGenericReq {
    SCSIRequest req;
    uint8_t *buf;
    int buflen;
    int len;
    sg_io_hdr_t io_header;
} SCSIGenericReq;

static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    qemu_put_sbe32s(f, &r->buflen);
    if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        assert(!r->req.sg);
        qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
    }
}

static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    qemu_get_sbe32s(f, &r->buflen);
    if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        assert(!r->req.sg);
        qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
    }
}

static void scsi_free_request(SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    g_free(r->buf);
}

/* Helper function for command completion.  */
static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
{
    int status;
    SCSISense sense;

    assert(r->req.aiocb == NULL);

    if (r->req.io_canceled) {
        scsi_req_cancel_complete(&r->req);
        goto done;
    }
    status = sg_io_sense_from_errno(-ret, &r->io_header, &sense);
    if (status == CHECK_CONDITION) {
        if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
            r->req.sense_len = r->io_header.sb_len_wr;
        } else {
            scsi_req_build_sense(&r->req, sense);
        }
    }

    trace_scsi_generic_command_complete_noio(r, r->req.tag, status);

    scsi_req_complete(&r->req, status);
done:
    scsi_req_unref(&r->req);
}

static void scsi_command_complete(void *opaque, int ret)
{
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
    SCSIDevice *s = r->req.dev;

    assert(r->req.aiocb != NULL);
    r->req.aiocb = NULL;

    aio_context_acquire(blk_get_aio_context(s->conf.blk));
    scsi_command_complete_noio(r, ret);
    aio_context_release(blk_get_aio_context(s->conf.blk));
}

static int execute_command(BlockBackend *blk,
                           SCSIGenericReq *r, int direction,
                           BlockCompletionFunc *complete)
{
    r->io_header.interface_id = 'S';
    r->io_header.dxfer_direction = direction;
    r->io_header.dxferp = r->buf;
    r->io_header.dxfer_len = r->buflen;
    r->io_header.cmdp = r->req.cmd.buf;
    r->io_header.cmd_len = r->req.cmd.len;
    r->io_header.mx_sb_len = sizeof(r->req.sense);
    r->io_header.sbp = r->req.sense;
    r->io_header.timeout = MAX_UINT;
    r->io_header.usr_ptr = r;
    r->io_header.flags |= SG_FLAG_DIRECT_IO;

    r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
    if (r->req.aiocb == NULL) {
        return -EIO;
    }

    return 0;
}

static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
{
    uint8_t page, page_idx;

    /*
     *  EVPD set to zero returns the standard INQUIRY data.
     *
     *  Check if scsi_version is unset (-1) to avoid re-defining it
     *  each time an INQUIRY with standard data is received.
     *  scsi_version is initialized with -1 in scsi_generic_reset
     *  and scsi_disk_reset, making sure that we'll set the
     *  scsi_version after a reset. If the version field of the
     *  INQUIRY response somehow changes after a guest reboot,
     *  we'll be able to keep track of it.
     *
     *  On SCSI-2 and older, first 3 bits of byte 2 is the
     *  ANSI-approved version, while on later versions the
     *  whole byte 2 contains the version. Check if we're dealing
     *  with a newer version and, in that case, assign the
     *  whole byte.
     */
    if (s->scsi_version == -1 && !(r->req.cmd.buf[1] & 0x01)) {
        s->scsi_version = r->buf[2] & 0x07;
        if (s->scsi_version > 2) {
            s->scsi_version = r->buf[2];
        }
    }

    if (s->type == TYPE_DISK && (r->req.cmd.buf[1] & 0x01)) {
        page = r->req.cmd.buf[2];
        if (page == 0xb0) {
            uint32_t max_transfer =
                blk_get_max_transfer(s->conf.blk) / s->blocksize;

            assert(max_transfer);
            stl_be_p(&r->buf[8], max_transfer);
            /* Also take care of the opt xfer len. */
            stl_be_p(&r->buf[12],
                    MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
        } else if (s->needs_vpd_bl_emulation && page == 0x00 && r->buflen >= 4) {
            /*
             * Now we're capable of supplying the VPD Block Limits
             * response if the hardware can't. Add it in the INQUIRY
             * Supported VPD pages response in case we are using the
             * emulation for this device.
             *
             * This way, the guest kernel will be aware of the support
             * and will use it to proper setup the SCSI device.
             *
             * VPD page numbers must be sorted, so insert 0xb0 at the
             * right place with an in-place insert.  When the while loop
             * begins the device response is at r[0] to r[page_idx - 1].
             */
            page_idx = lduw_be_p(r->buf + 2) + 4;
            page_idx = MIN(page_idx, r->buflen);
            while (page_idx > 4 && r->buf[page_idx - 1] >= 0xb0) {
                if (page_idx < r->buflen) {
                    r->buf[page_idx] = r->buf[page_idx - 1];
                }
                page_idx--;
            }
            if (page_idx < r->buflen) {
                r->buf[page_idx] = 0xb0;
            }
            stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1);
        }
    }
}

static int scsi_generic_emulate_block_limits(SCSIGenericReq *r, SCSIDevice *s)
{
    int len;
    uint8_t buf[64];

    SCSIBlockLimits bl = {
        .max_io_sectors = blk_get_max_transfer(s->conf.blk) / s->blocksize
    };

    memset(r->buf, 0, r->buflen);
    stb_p(buf, s->type);
    stb_p(buf + 1, 0xb0);
    len = scsi_emulate_block_limits(buf + 4, &bl);
    assert(len <= sizeof(buf) - 4);
    stw_be_p(buf + 2, len);

    memcpy(r->buf, buf, MIN(r->buflen, len + 4));

    r->io_header.sb_len_wr = 0;

    /*
    * We have valid contents in the reply buffer but the
    * io_header can report a sense error coming from
    * the hardware in scsi_command_complete_noio. Clean
    * up the io_header to avoid reporting it.
    */
    r->io_header.driver_status = 0;
    r->io_header.status = 0;

    return r->buflen;
}

static void scsi_read_complete(void * opaque, int ret)
{
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
    SCSIDevice *s = r->req.dev;
    int len;

    assert(r->req.aiocb != NULL);
    r->req.aiocb = NULL;

    aio_context_acquire(blk_get_aio_context(s->conf.blk));

    if (ret || r->req.io_canceled) {
        scsi_command_complete_noio(r, ret);
        goto done;
    }

    len = r->io_header.dxfer_len - r->io_header.resid;
    trace_scsi_generic_read_complete(r->req.tag, len);

    r->len = -1;

    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
        SCSISense sense =
            scsi_parse_sense_buf(r->req.sense, r->io_header.sb_len_wr);

        /*
         * Check if this is a VPD Block Limits request that
         * resulted in sense error but would need emulation.
         * In this case, emulate a valid VPD response.
         */
        if (sense.key == ILLEGAL_REQUEST &&
            s->needs_vpd_bl_emulation &&
            r->req.cmd.buf[0] == INQUIRY &&
            (r->req.cmd.buf[1] & 0x01) &&
            r->req.cmd.buf[2] == 0xb0) {
            len = scsi_generic_emulate_block_limits(r, s);
            /*
             * It's okay to jup to req_complete: no need to
             * let scsi_handle_inquiry_reply handle an
             * INQUIRY VPD BL request we created manually.
             */
        }
        if (sense.key) {
            goto req_complete;
        }
    }

    if (len == 0) {
        scsi_command_complete_noio(r, 0);
        goto done;
    }

    /* Snoop READ CAPACITY output to set the blocksize.  */
    if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
        (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
        s->blocksize = ldl_be_p(&r->buf[4]);
        s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
    } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
               (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
        s->blocksize = ldl_be_p(&r->buf[8]);
        s->max_lba = ldq_be_p(&r->buf[0]);
    }
    blk_set_guest_block_size(s->conf.blk, s->blocksize);

    /* Patch MODE SENSE device specific parameters if the BDS is opened
     * readonly.
     */
    if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
        blk_is_read_only(s->conf.blk) &&
        (r->req.cmd.buf[0] == MODE_SENSE ||
         r->req.cmd.buf[0] == MODE_SENSE_10) &&
        (r->req.cmd.buf[1] & 0x8) == 0) {
        if (r->req.cmd.buf[0] == MODE_SENSE) {
            r->buf[2] |= 0x80;
        } else  {
            r->buf[3] |= 0x80;
        }
    }
    if (r->req.cmd.buf[0] == INQUIRY) {
        scsi_handle_inquiry_reply(r, s);
    }

req_complete:
    scsi_req_data(&r->req, len);
    scsi_req_unref(&r->req);

done:
    aio_context_release(blk_get_aio_context(s->conf.blk));
}

/* Read more data from scsi device into buffer.  */
static void scsi_read_data(SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
    SCSIDevice *s = r->req.dev;
    int ret;

    trace_scsi_generic_read_data(req->tag);

    /* The request is used as the AIO opaque value, so add a ref.  */
    scsi_req_ref(&r->req);
    if (r->len == -1) {
        scsi_command_complete_noio(r, 0);
        return;
    }

    ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
                          scsi_read_complete);
    if (ret < 0) {
        scsi_command_complete_noio(r, ret);
    }
}

static void scsi_write_complete(void * opaque, int ret)
{
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
    SCSIDevice *s = r->req.dev;

    trace_scsi_generic_write_complete(ret);

    assert(r->req.aiocb != NULL);
    r->req.aiocb = NULL;

    aio_context_acquire(blk_get_aio_context(s->conf.blk));

    if (ret || r->req.io_canceled) {
        scsi_command_complete_noio(r, ret);
        goto done;
    }

    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
        s->type == TYPE_TAPE) {
        s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
        trace_scsi_generic_write_complete_blocksize(s->blocksize);
    }

    scsi_command_complete_noio(r, ret);

done:
    aio_context_release(blk_get_aio_context(s->conf.blk));
}

/* Write data to a scsi device.  Returns nonzero on failure.
   The transfer may complete asynchronously.  */
static void scsi_write_data(SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
    SCSIDevice *s = r->req.dev;
    int ret;

    trace_scsi_generic_write_data(req->tag);
    if (r->len == 0) {
        r->len = r->buflen;
        scsi_req_data(&r->req, r->len);
        return;
    }

    /* The request is used as the AIO opaque value, so add a ref.  */
    scsi_req_ref(&r->req);
    ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
    if (ret < 0) {
        scsi_command_complete_noio(r, ret);
    }
}

/* Return a pointer to the data buffer.  */
static uint8_t *scsi_get_buf(SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    return r->buf;
}

static void scsi_generic_command_dump(uint8_t *cmd, int len)
{
    int i;
    char *line_buffer, *p;

    line_buffer = g_malloc(len * 5 + 1);

    for (i = 0, p = line_buffer; i < len; i++) {
        p += sprintf(p, " 0x%02x", cmd[i]);
    }
    trace_scsi_generic_send_command(line_buffer);

    g_free(line_buffer);
}

/* Execute a scsi command.  Returns the length of the data expected by the
   command.  This will be Positive for data transfers from the device
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
   and zero if the command does not transfer any data.  */

static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
    SCSIDevice *s = r->req.dev;
    int ret;

    if (trace_event_get_state_backends(TRACE_SCSI_GENERIC_SEND_COMMAND)) {
        scsi_generic_command_dump(cmd, r->req.cmd.len);
    }

    if (r->req.cmd.xfer == 0) {
        g_free(r->buf);
        r->buflen = 0;
        r->buf = NULL;
        /* The request is used as the AIO opaque value, so add a ref.  */
        scsi_req_ref(&r->req);
        ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
                              scsi_command_complete);
        if (ret < 0) {
            scsi_command_complete_noio(r, ret);
            return 0;
        }
        return 0;
    }

    if (r->buflen != r->req.cmd.xfer) {
        g_free(r->buf);
        r->buf = g_malloc(r->req.cmd.xfer);
        r->buflen = r->req.cmd.xfer;
    }

    memset(r->buf, 0, r->buflen);
    r->len = r->req.cmd.xfer;
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        r->len = 0;
        return -r->req.cmd.xfer;
    } else {
        return r->req.cmd.xfer;
    }
}

static int read_naa_id(const uint8_t *p, uint64_t *p_wwn)
{
    int i;

    if ((p[1] & 0xF) == 3) {
        /* NAA designator type */
        if (p[3] != 8) {
            return -EINVAL;
        }
        *p_wwn = ldq_be_p(p + 4);
        return 0;
    }

    if ((p[1] & 0xF) == 8) {
        /* SCSI name string designator type */
        if (p[3] < 20 || memcmp(&p[4], "naa.", 4)) {
            return -EINVAL;
        }
        if (p[3] > 20 && p[24] != ',') {
            return -EINVAL;
        }
        *p_wwn = 0;
        for (i = 8; i < 24; i++) {
            char c = qemu_toupper(p[i]);
            c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10);
            *p_wwn = (*p_wwn << 4) | c;
        }
        return 0;
    }

    return -EINVAL;
}

int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size,
                        uint8_t *buf, uint8_t buf_size)
{
    sg_io_hdr_t io_header;
    uint8_t sensebuf[8];
    int ret;

    memset(&io_header, 0, sizeof(io_header));
    io_header.interface_id = 'S';
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
    io_header.dxfer_len = buf_size;
    io_header.dxferp = buf;
    io_header.cmdp = cmd;
    io_header.cmd_len = cmd_size;
    io_header.mx_sb_len = sizeof(sensebuf);
    io_header.sbp = sensebuf;
    io_header.timeout = 6000; /* XXX */

    ret = blk_ioctl(blk, SG_IO, &io_header);
    if (ret < 0 || io_header.driver_status || io_header.host_status) {
        return -1;
    }
    return 0;
}

/*
 * Executes an INQUIRY request with EVPD set to retrieve the
 * available VPD pages of the device. If the device does
 * not support the Block Limits page (page 0xb0), set
 * the needs_vpd_bl_emulation flag for future use.
 */
static void scsi_generic_set_vpd_bl_emulation(SCSIDevice *s)
{
    uint8_t cmd[6];
    uint8_t buf[250];
    uint8_t page_len;
    int ret, i;

    memset(cmd, 0, sizeof(cmd));
    memset(buf, 0, sizeof(buf));
    cmd[0] = INQUIRY;
    cmd[1] = 1;
    cmd[2] = 0x00;
    cmd[4] = sizeof(buf);

    ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd),
                              buf, sizeof(buf));
    if (ret < 0) {
        /*
         * Do not assume anything if we can't retrieve the
         * INQUIRY response to assert the VPD Block Limits
         * support.
         */
        s->needs_vpd_bl_emulation = false;
        return;
    }

    page_len = buf[3];
    for (i = 4; i < MIN(sizeof(buf), page_len + 4); i++) {
        if (buf[i] == 0xb0) {
            s->needs_vpd_bl_emulation = false;
            return;
        }
    }
    s->needs_vpd_bl_emulation = true;
}

static void scsi_generic_read_device_identification(SCSIDevice *s)
{
    uint8_t cmd[6];
    uint8_t buf[250];
    int ret;
    int i, len;

    memset(cmd, 0, sizeof(cmd));
    memset(buf, 0, sizeof(buf));
    cmd[0] = INQUIRY;
    cmd[1] = 1;
    cmd[2] = 0x83;
    cmd[4] = sizeof(buf);

    ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd),
                              buf, sizeof(buf));
    if (ret < 0) {
        return;
    }

    len = MIN((buf[2] << 8) | buf[3], sizeof(buf) - 4);
    for (i = 0; i + 3 <= len; ) {
        const uint8_t *p = &buf[i + 4];
        uint64_t wwn;

        if (i + (p[3] + 4) > len) {
            break;
        }

        if ((p[1] & 0x10) == 0) {
            /* Associated with the logical unit */
            if (read_naa_id(p, &wwn) == 0) {
                s->wwn = wwn;
            }
        } else if ((p[1] & 0x10) == 0x10) {
            /* Associated with the target port */
            if (read_naa_id(p, &wwn) == 0) {
                s->port_wwn = wwn;
            }
        }

        i += p[3] + 4;
    }
}

void scsi_generic_read_device_inquiry(SCSIDevice *s)
{
    scsi_generic_read_device_identification(s);
    if (s->type == TYPE_DISK) {
        scsi_generic_set_vpd_bl_emulation(s);
    } else {
        s->needs_vpd_bl_emulation = false;
    }
}

static int get_stream_blocksize(BlockBackend *blk)
{
    uint8_t cmd[6];
    uint8_t buf[12];
    int ret;

    memset(cmd, 0, sizeof(cmd));
    memset(buf, 0, sizeof(buf));
    cmd[0] = MODE_SENSE;
    cmd[4] = sizeof(buf);

    ret = scsi_SG_IO_FROM_DEV(blk, cmd, sizeof(cmd), buf, sizeof(buf));
    if (ret < 0) {
        return -1;
    }

    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
}

static void scsi_generic_reset(DeviceState *dev)
{
    SCSIDevice *s = SCSI_DEVICE(dev);

    s->scsi_version = s->default_scsi_version;
    scsi_device_purge_requests(s, SENSE_CODE(RESET));
}

static void scsi_generic_realize(SCSIDevice *s, Error **errp)
{
    int rc;
    int sg_version;
    struct sg_scsi_id scsiid;

    if (!s->conf.blk) {
        error_setg(errp, "drive property not set");
        return;
    }

    if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
        error_setg(errp, "Device doesn't support drive option werror");
        return;
    }
    if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
        error_setg(errp, "Device doesn't support drive option rerror");
        return;
    }

    /* check we are using a driver managing SG_IO (version 3 and after */
    rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
    if (rc < 0) {
        error_setg_errno(errp, -rc, "cannot get SG_IO version number");
        if (rc != -EPERM) {
            error_append_hint(errp, "Is this a SCSI device?\n");
        }
        return;
    }
    if (sg_version < 30000) {
        error_setg(errp, "scsi generic interface too old");
        return;
    }

    /* get LUN of the /dev/sg? */
    if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
        error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
        return;
    }
    if (!blkconf_apply_backend_options(&s->conf,
                                       blk_is_read_only(s->conf.blk),
                                       true, errp)) {
        return;
    }

    /* define device state */
    s->type = scsiid.scsi_type;
    trace_scsi_generic_realize_type(s->type);

    switch (s->type) {
    case TYPE_TAPE:
        s->blocksize = get_stream_blocksize(s->conf.blk);
        if (s->blocksize == -1) {
            s->blocksize = 0;
        }
        break;

        /* Make a guess for block devices, we'll fix it when the guest sends.
         * READ CAPACITY.  If they don't, they likely would assume these sizes
         * anyway. (TODO: they could also send MODE SENSE).
         */
    case TYPE_ROM:
    case TYPE_WORM:
        s->blocksize = 2048;
        break;
    default:
        s->blocksize = 512;
        break;
    }

    trace_scsi_generic_realize_blocksize(s->blocksize);

    /* Only used by scsi-block, but initialize it nevertheless to be clean.  */
    s->default_scsi_version = -1;
    scsi_generic_read_device_inquiry(s);
}

const SCSIReqOps scsi_generic_req_ops = {
    .size         = sizeof(SCSIGenericReq),
    .free_req     = scsi_free_request,
    .send_command = scsi_send_command,
    .read_data    = scsi_read_data,
    .write_data   = scsi_write_data,
    .get_buf      = scsi_get_buf,
    .load_request = scsi_generic_load_request,
    .save_request = scsi_generic_save_request,
};

static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
                                     uint8_t *buf, void *hba_private)
{
    return scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
}

static Property scsi_generic_properties[] = {
    DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
    DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
    DEFINE_PROP_END_OF_LIST(),
};

static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
                                  uint8_t *buf, void *hba_private)
{
    return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
}

static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);

    sc->realize      = scsi_generic_realize;
    sc->alloc_req    = scsi_new_request;
    sc->parse_cdb    = scsi_generic_parse_cdb;
    dc->fw_name = "disk";
    dc->desc = "pass through generic scsi device (/dev/sg*)";
    dc->reset = scsi_generic_reset;
    device_class_set_props(dc, scsi_generic_properties);
    dc->vmsd  = &vmstate_scsi_device;
}

static const TypeInfo scsi_generic_info = {
    .name          = "scsi-generic",
    .parent        = TYPE_SCSI_DEVICE,
    .instance_size = sizeof(SCSIDevice),
    .class_init    = scsi_generic_class_initfn,
};

static void scsi_generic_register_types(void)
{
    type_register_static(&scsi_generic_info);
}

type_init(scsi_generic_register_types)

#endif /* __linux__ */
