/*
 * 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 "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;

    /*
     * 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 (s->needs_vpd_bl_emulation && ret == 0 &&
        (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) &&
        r->req.cmd.buf[0] == INQUIRY &&
        (r->req.cmd.buf[1] & 0x01) &&
        r->req.cmd.buf[2] == 0xb0) {
        SCSISense sense =
            scsi_parse_sense_buf(r->req.sense, r->io_header.sb_len_wr);
        if (sense.key == ILLEGAL_REQUEST) {
            len = scsi_generic_emulate_block_limits(r, s);
            /*
             * No need to let scsi_read_complete go on and handle an
             * INQUIRY VPD BL request we created manually.
             */
            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;
    dc->props = 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__ */
