qemu/hw/scsi/scsi-generic.c
<<
>>
Prefs
   1/*
   2 * Generic SCSI Device support
   3 *
   4 * Copyright (c) 2007 Bull S.A.S.
   5 * Based on code by Paul Brook
   6 * Based on code by Fabrice Bellard
   7 *
   8 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
   9 *
  10 * This code is licensed under the LGPL.
  11 *
  12 */
  13
  14#include "qemu/osdep.h"
  15#include "qapi/error.h"
  16#include "qemu-common.h"
  17#include "qemu/error-report.h"
  18#include "hw/scsi/scsi.h"
  19#include "sysemu/block-backend.h"
  20#include "sysemu/blockdev.h"
  21
  22#ifdef __linux__
  23
  24//#define DEBUG_SCSI
  25
  26#ifdef DEBUG_SCSI
  27#define DPRINTF(fmt, ...) \
  28do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
  29#else
  30#define DPRINTF(fmt, ...) do {} while(0)
  31#endif
  32
  33#define BADF(fmt, ...) \
  34do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
  35
  36#include <scsi/sg.h>
  37#include "block/scsi.h"
  38
  39#define SG_ERR_DRIVER_TIMEOUT  0x06
  40#define SG_ERR_DRIVER_SENSE    0x08
  41
  42#define SG_ERR_DID_OK          0x00
  43#define SG_ERR_DID_NO_CONNECT  0x01
  44#define SG_ERR_DID_BUS_BUSY    0x02
  45#define SG_ERR_DID_TIME_OUT    0x03
  46
  47#ifndef MAX_UINT
  48#define MAX_UINT ((unsigned int)-1)
  49#endif
  50
  51typedef struct SCSIGenericReq {
  52    SCSIRequest req;
  53    uint8_t *buf;
  54    int buflen;
  55    int len;
  56    sg_io_hdr_t io_header;
  57} SCSIGenericReq;
  58
  59static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
  60{
  61    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
  62
  63    qemu_put_sbe32s(f, &r->buflen);
  64    if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
  65        assert(!r->req.sg);
  66        qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
  67    }
  68}
  69
  70static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
  71{
  72    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
  73
  74    qemu_get_sbe32s(f, &r->buflen);
  75    if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
  76        assert(!r->req.sg);
  77        qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
  78    }
  79}
  80
  81static void scsi_free_request(SCSIRequest *req)
  82{
  83    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
  84
  85    g_free(r->buf);
  86}
  87
  88/* Helper function for command completion.  */
  89static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
  90{
  91    int status;
  92
  93    assert(r->req.aiocb == NULL);
  94
  95    if (r->req.io_canceled) {
  96        scsi_req_cancel_complete(&r->req);
  97        goto done;
  98    }
  99    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
 100        r->req.sense_len = r->io_header.sb_len_wr;
 101    }
 102
 103    if (ret != 0) {
 104        switch (ret) {
 105        case -EDOM:
 106            status = TASK_SET_FULL;
 107            break;
 108        case -ENOMEM:
 109            status = CHECK_CONDITION;
 110            scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
 111            break;
 112        default:
 113            status = CHECK_CONDITION;
 114            scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
 115            break;
 116        }
 117    } else {
 118        if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
 119            r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
 120            r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
 121            (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
 122            status = BUSY;
 123            BADF("Driver Timeout\n");
 124        } else if (r->io_header.host_status) {
 125            status = CHECK_CONDITION;
 126            scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
 127        } else if (r->io_header.status) {
 128            status = r->io_header.status;
 129        } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
 130            status = CHECK_CONDITION;
 131        } else {
 132            status = GOOD;
 133        }
 134    }
 135    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
 136            r, r->req.tag, status);
 137
 138    scsi_req_complete(&r->req, status);
 139done:
 140    scsi_req_unref(&r->req);
 141}
 142
 143static void scsi_command_complete(void *opaque, int ret)
 144{
 145    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
 146    SCSIDevice *s = r->req.dev;
 147
 148    assert(r->req.aiocb != NULL);
 149    r->req.aiocb = NULL;
 150
 151    aio_context_acquire(blk_get_aio_context(s->conf.blk));
 152    scsi_command_complete_noio(r, ret);
 153    aio_context_release(blk_get_aio_context(s->conf.blk));
 154}
 155
 156static int execute_command(BlockBackend *blk,
 157                           SCSIGenericReq *r, int direction,
 158                           BlockCompletionFunc *complete)
 159{
 160    r->io_header.interface_id = 'S';
 161    r->io_header.dxfer_direction = direction;
 162    r->io_header.dxferp = r->buf;
 163    r->io_header.dxfer_len = r->buflen;
 164    r->io_header.cmdp = r->req.cmd.buf;
 165    r->io_header.cmd_len = r->req.cmd.len;
 166    r->io_header.mx_sb_len = sizeof(r->req.sense);
 167    r->io_header.sbp = r->req.sense;
 168    r->io_header.timeout = MAX_UINT;
 169    r->io_header.usr_ptr = r;
 170    r->io_header.flags |= SG_FLAG_DIRECT_IO;
 171
 172    r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
 173    if (r->req.aiocb == NULL) {
 174        return -EIO;
 175    }
 176
 177    return 0;
 178}
 179
 180static void scsi_read_complete(void * opaque, int ret)
 181{
 182    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
 183    SCSIDevice *s = r->req.dev;
 184    int len;
 185
 186    assert(r->req.aiocb != NULL);
 187    r->req.aiocb = NULL;
 188
 189    aio_context_acquire(blk_get_aio_context(s->conf.blk));
 190
 191    if (ret || r->req.io_canceled) {
 192        scsi_command_complete_noio(r, ret);
 193        goto done;
 194    }
 195
 196    len = r->io_header.dxfer_len - r->io_header.resid;
 197    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
 198
 199    r->len = -1;
 200    if (len == 0) {
 201        scsi_command_complete_noio(r, 0);
 202        goto done;
 203    }
 204
 205    /* Snoop READ CAPACITY output to set the blocksize.  */
 206    if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
 207        (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
 208        s->blocksize = ldl_be_p(&r->buf[4]);
 209        s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
 210    } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
 211               (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
 212        s->blocksize = ldl_be_p(&r->buf[8]);
 213        s->max_lba = ldq_be_p(&r->buf[0]);
 214    }
 215    blk_set_guest_block_size(s->conf.blk, s->blocksize);
 216
 217    /* Patch MODE SENSE device specific parameters if the BDS is opened
 218     * readonly.
 219     */
 220    if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
 221        blk_is_read_only(s->conf.blk) &&
 222        (r->req.cmd.buf[0] == MODE_SENSE ||
 223         r->req.cmd.buf[0] == MODE_SENSE_10) &&
 224        (r->req.cmd.buf[1] & 0x8) == 0) {
 225        if (r->req.cmd.buf[0] == MODE_SENSE) {
 226            r->buf[2] |= 0x80;
 227        } else  {
 228            r->buf[3] |= 0x80;
 229        }
 230    }
 231    if (s->type == TYPE_DISK &&
 232        r->req.cmd.buf[0] == INQUIRY &&
 233        r->req.cmd.buf[2] == 0xb0) {
 234        uint32_t max_transfer =
 235            blk_get_max_transfer(s->conf.blk) / s->blocksize;
 236
 237        assert(max_transfer);
 238        stl_be_p(&r->buf[8], max_transfer);
 239        /* Also take care of the opt xfer len. */
 240        stl_be_p(&r->buf[12],
 241                 MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
 242    }
 243    scsi_req_data(&r->req, len);
 244    scsi_req_unref(&r->req);
 245
 246done:
 247    aio_context_release(blk_get_aio_context(s->conf.blk));
 248}
 249
 250/* Read more data from scsi device into buffer.  */
 251static void scsi_read_data(SCSIRequest *req)
 252{
 253    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 254    SCSIDevice *s = r->req.dev;
 255    int ret;
 256
 257    DPRINTF("scsi_read_data tag=0x%x\n", req->tag);
 258
 259    /* The request is used as the AIO opaque value, so add a ref.  */
 260    scsi_req_ref(&r->req);
 261    if (r->len == -1) {
 262        scsi_command_complete_noio(r, 0);
 263        return;
 264    }
 265
 266    ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
 267                          scsi_read_complete);
 268    if (ret < 0) {
 269        scsi_command_complete_noio(r, ret);
 270    }
 271}
 272
 273static void scsi_write_complete(void * opaque, int ret)
 274{
 275    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
 276    SCSIDevice *s = r->req.dev;
 277
 278    DPRINTF("scsi_write_complete() ret = %d\n", ret);
 279
 280    assert(r->req.aiocb != NULL);
 281    r->req.aiocb = NULL;
 282
 283    aio_context_acquire(blk_get_aio_context(s->conf.blk));
 284
 285    if (ret || r->req.io_canceled) {
 286        scsi_command_complete_noio(r, ret);
 287        goto done;
 288    }
 289
 290    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
 291        s->type == TYPE_TAPE) {
 292        s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
 293        DPRINTF("block size %d\n", s->blocksize);
 294    }
 295
 296    scsi_command_complete_noio(r, ret);
 297
 298done:
 299    aio_context_release(blk_get_aio_context(s->conf.blk));
 300}
 301
 302/* Write data to a scsi device.  Returns nonzero on failure.
 303   The transfer may complete asynchronously.  */
 304static void scsi_write_data(SCSIRequest *req)
 305{
 306    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 307    SCSIDevice *s = r->req.dev;
 308    int ret;
 309
 310    DPRINTF("scsi_write_data tag=0x%x\n", req->tag);
 311    if (r->len == 0) {
 312        r->len = r->buflen;
 313        scsi_req_data(&r->req, r->len);
 314        return;
 315    }
 316
 317    /* The request is used as the AIO opaque value, so add a ref.  */
 318    scsi_req_ref(&r->req);
 319    ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
 320    if (ret < 0) {
 321        scsi_command_complete_noio(r, ret);
 322    }
 323}
 324
 325/* Return a pointer to the data buffer.  */
 326static uint8_t *scsi_get_buf(SCSIRequest *req)
 327{
 328    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 329
 330    return r->buf;
 331}
 332
 333/* Execute a scsi command.  Returns the length of the data expected by the
 334   command.  This will be Positive for data transfers from the device
 335   (eg. disk reads), negative for transfers to the device (eg. disk writes),
 336   and zero if the command does not transfer any data.  */
 337
 338static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
 339{
 340    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 341    SCSIDevice *s = r->req.dev;
 342    int ret;
 343
 344#ifdef DEBUG_SCSI
 345    DPRINTF("Command: data=0x%02x", cmd[0]);
 346    {
 347        int i;
 348        for (i = 1; i < r->req.cmd.len; i++) {
 349            printf(" 0x%02x", cmd[i]);
 350        }
 351        printf("\n");
 352    }
 353#endif
 354
 355    if (r->req.cmd.xfer == 0) {
 356        g_free(r->buf);
 357        r->buflen = 0;
 358        r->buf = NULL;
 359        /* The request is used as the AIO opaque value, so add a ref.  */
 360        scsi_req_ref(&r->req);
 361        ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
 362                              scsi_command_complete);
 363        if (ret < 0) {
 364            scsi_command_complete_noio(r, ret);
 365            return 0;
 366        }
 367        return 0;
 368    }
 369
 370    if (r->buflen != r->req.cmd.xfer) {
 371        g_free(r->buf);
 372        r->buf = g_malloc(r->req.cmd.xfer);
 373        r->buflen = r->req.cmd.xfer;
 374    }
 375
 376    memset(r->buf, 0, r->buflen);
 377    r->len = r->req.cmd.xfer;
 378    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
 379        r->len = 0;
 380        return -r->req.cmd.xfer;
 381    } else {
 382        return r->req.cmd.xfer;
 383    }
 384}
 385
 386static int read_naa_id(const uint8_t *p, uint64_t *p_wwn)
 387{
 388    int i;
 389
 390    if ((p[1] & 0xF) == 3) {
 391        /* NAA designator type */
 392        if (p[3] != 8) {
 393            return -EINVAL;
 394        }
 395        *p_wwn = ldq_be_p(p + 4);
 396        return 0;
 397    }
 398
 399    if ((p[1] & 0xF) == 8) {
 400        /* SCSI name string designator type */
 401        if (p[3] < 20 || memcmp(&p[4], "naa.", 4)) {
 402            return -EINVAL;
 403        }
 404        if (p[3] > 20 && p[24] != ',') {
 405            return -EINVAL;
 406        }
 407        *p_wwn = 0;
 408        for (i = 8; i < 24; i++) {
 409            char c = qemu_toupper(p[i]);
 410            c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10);
 411            *p_wwn = (*p_wwn << 4) | c;
 412        }
 413        return 0;
 414    }
 415
 416    return -EINVAL;
 417}
 418
 419void scsi_generic_read_device_identification(SCSIDevice *s)
 420{
 421    uint8_t cmd[6];
 422    uint8_t buf[250];
 423    uint8_t sensebuf[8];
 424    sg_io_hdr_t io_header;
 425    int ret;
 426    int i, len;
 427
 428    memset(cmd, 0, sizeof(cmd));
 429    memset(buf, 0, sizeof(buf));
 430    cmd[0] = INQUIRY;
 431    cmd[1] = 1;
 432    cmd[2] = 0x83;
 433    cmd[4] = sizeof(buf);
 434
 435    memset(&io_header, 0, sizeof(io_header));
 436    io_header.interface_id = 'S';
 437    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
 438    io_header.dxfer_len = sizeof(buf);
 439    io_header.dxferp = buf;
 440    io_header.cmdp = cmd;
 441    io_header.cmd_len = sizeof(cmd);
 442    io_header.mx_sb_len = sizeof(sensebuf);
 443    io_header.sbp = sensebuf;
 444    io_header.timeout = 6000; /* XXX */
 445
 446    ret = blk_ioctl(s->conf.blk, SG_IO, &io_header);
 447    if (ret < 0 || io_header.driver_status || io_header.host_status) {
 448        return;
 449    }
 450
 451    len = MIN((buf[2] << 8) | buf[3], sizeof(buf) - 4);
 452    for (i = 0; i + 3 <= len; ) {
 453        const uint8_t *p = &buf[i + 4];
 454        uint64_t wwn;
 455
 456        if (i + (p[3] + 4) > len) {
 457            break;
 458        }
 459
 460        if ((p[1] & 0x10) == 0) {
 461            /* Associated with the logical unit */
 462            if (read_naa_id(p, &wwn) == 0) {
 463                s->wwn = wwn;
 464            }
 465        } else if ((p[1] & 0x10) == 0x10) {
 466            /* Associated with the target port */
 467            if (read_naa_id(p, &wwn) == 0) {
 468                s->port_wwn = wwn;
 469            }
 470        }
 471
 472        i += p[3] + 4;
 473    }
 474}
 475
 476static int get_stream_blocksize(BlockBackend *blk)
 477{
 478    uint8_t cmd[6];
 479    uint8_t buf[12];
 480    uint8_t sensebuf[8];
 481    sg_io_hdr_t io_header;
 482    int ret;
 483
 484    memset(cmd, 0, sizeof(cmd));
 485    memset(buf, 0, sizeof(buf));
 486    cmd[0] = MODE_SENSE;
 487    cmd[4] = sizeof(buf);
 488
 489    memset(&io_header, 0, sizeof(io_header));
 490    io_header.interface_id = 'S';
 491    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
 492    io_header.dxfer_len = sizeof(buf);
 493    io_header.dxferp = buf;
 494    io_header.cmdp = cmd;
 495    io_header.cmd_len = sizeof(cmd);
 496    io_header.mx_sb_len = sizeof(sensebuf);
 497    io_header.sbp = sensebuf;
 498    io_header.timeout = 6000; /* XXX */
 499
 500    ret = blk_ioctl(blk, SG_IO, &io_header);
 501    if (ret < 0 || io_header.driver_status || io_header.host_status) {
 502        return -1;
 503    }
 504    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
 505}
 506
 507static void scsi_generic_reset(DeviceState *dev)
 508{
 509    SCSIDevice *s = SCSI_DEVICE(dev);
 510
 511    scsi_device_purge_requests(s, SENSE_CODE(RESET));
 512}
 513
 514static void scsi_generic_realize(SCSIDevice *s, Error **errp)
 515{
 516    int rc;
 517    int sg_version;
 518    struct sg_scsi_id scsiid;
 519
 520    if (!s->conf.blk) {
 521        error_setg(errp, "drive property not set");
 522        return;
 523    }
 524
 525    if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
 526        error_setg(errp, "Device doesn't support drive option werror");
 527        return;
 528    }
 529    if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
 530        error_setg(errp, "Device doesn't support drive option rerror");
 531        return;
 532    }
 533
 534    /* check we are using a driver managing SG_IO (version 3 and after */
 535    rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
 536    if (rc < 0) {
 537        error_setg(errp, "cannot get SG_IO version number: %s.  "
 538                         "Is this a SCSI device?",
 539                         strerror(-rc));
 540        return;
 541    }
 542    if (sg_version < 30000) {
 543        error_setg(errp, "scsi generic interface too old");
 544        return;
 545    }
 546
 547    /* get LUN of the /dev/sg? */
 548    if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
 549        error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
 550        return;
 551    }
 552
 553    /* define device state */
 554    s->type = scsiid.scsi_type;
 555    DPRINTF("device type %d\n", s->type);
 556
 557    switch (s->type) {
 558    case TYPE_TAPE:
 559        s->blocksize = get_stream_blocksize(s->conf.blk);
 560        if (s->blocksize == -1) {
 561            s->blocksize = 0;
 562        }
 563        break;
 564
 565        /* Make a guess for block devices, we'll fix it when the guest sends.
 566         * READ CAPACITY.  If they don't, they likely would assume these sizes
 567         * anyway. (TODO: they could also send MODE SENSE).
 568         */
 569    case TYPE_ROM:
 570    case TYPE_WORM:
 571        s->blocksize = 2048;
 572        break;
 573    default:
 574        s->blocksize = 512;
 575        break;
 576    }
 577
 578    DPRINTF("block size %d\n", s->blocksize);
 579
 580    scsi_generic_read_device_identification(s);
 581}
 582
 583const SCSIReqOps scsi_generic_req_ops = {
 584    .size         = sizeof(SCSIGenericReq),
 585    .free_req     = scsi_free_request,
 586    .send_command = scsi_send_command,
 587    .read_data    = scsi_read_data,
 588    .write_data   = scsi_write_data,
 589    .get_buf      = scsi_get_buf,
 590    .load_request = scsi_generic_load_request,
 591    .save_request = scsi_generic_save_request,
 592};
 593
 594static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
 595                                     uint8_t *buf, void *hba_private)
 596{
 597    return scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
 598}
 599
 600static Property scsi_generic_properties[] = {
 601    DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
 602    DEFINE_PROP_END_OF_LIST(),
 603};
 604
 605static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
 606                                  uint8_t *buf, void *hba_private)
 607{
 608    return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
 609}
 610
 611static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
 612{
 613    DeviceClass *dc = DEVICE_CLASS(klass);
 614    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 615
 616    sc->realize      = scsi_generic_realize;
 617    sc->alloc_req    = scsi_new_request;
 618    sc->parse_cdb    = scsi_generic_parse_cdb;
 619    dc->fw_name = "disk";
 620    dc->desc = "pass through generic scsi device (/dev/sg*)";
 621    dc->reset = scsi_generic_reset;
 622    dc->props = scsi_generic_properties;
 623    dc->vmsd  = &vmstate_scsi_device;
 624}
 625
 626static const TypeInfo scsi_generic_info = {
 627    .name          = "scsi-generic",
 628    .parent        = TYPE_SCSI_DEVICE,
 629    .instance_size = sizeof(SCSIDevice),
 630    .class_init    = scsi_generic_class_initfn,
 631};
 632
 633static void scsi_generic_register_types(void)
 634{
 635    type_register_static(&scsi_generic_info);
 636}
 637
 638type_init(scsi_generic_register_types)
 639
 640#endif /* __linux__ */
 641