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
 147    assert(r->req.aiocb != NULL);
 148    r->req.aiocb = NULL;
 149    scsi_command_complete_noio(r, ret);
 150}
 151
 152static int execute_command(BlockBackend *blk,
 153                           SCSIGenericReq *r, int direction,
 154                           BlockCompletionFunc *complete)
 155{
 156    r->io_header.interface_id = 'S';
 157    r->io_header.dxfer_direction = direction;
 158    r->io_header.dxferp = r->buf;
 159    r->io_header.dxfer_len = r->buflen;
 160    r->io_header.cmdp = r->req.cmd.buf;
 161    r->io_header.cmd_len = r->req.cmd.len;
 162    r->io_header.mx_sb_len = sizeof(r->req.sense);
 163    r->io_header.sbp = r->req.sense;
 164    r->io_header.timeout = MAX_UINT;
 165    r->io_header.usr_ptr = r;
 166    r->io_header.flags |= SG_FLAG_DIRECT_IO;
 167
 168    r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
 169    if (r->req.aiocb == NULL) {
 170        return -EIO;
 171    }
 172
 173    return 0;
 174}
 175
 176static void scsi_read_complete(void * opaque, int ret)
 177{
 178    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
 179    SCSIDevice *s = r->req.dev;
 180    int len;
 181
 182    assert(r->req.aiocb != NULL);
 183    r->req.aiocb = NULL;
 184
 185    if (ret || r->req.io_canceled) {
 186        scsi_command_complete_noio(r, ret);
 187        return;
 188    }
 189
 190    len = r->io_header.dxfer_len - r->io_header.resid;
 191    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
 192
 193    r->len = -1;
 194    if (len == 0) {
 195        scsi_command_complete_noio(r, 0);
 196        return;
 197    }
 198
 199    /* Snoop READ CAPACITY output to set the blocksize.  */
 200    if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
 201        (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
 202        s->blocksize = ldl_be_p(&r->buf[4]);
 203        s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
 204    } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
 205               (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
 206        s->blocksize = ldl_be_p(&r->buf[8]);
 207        s->max_lba = ldq_be_p(&r->buf[0]);
 208    }
 209    blk_set_guest_block_size(s->conf.blk, s->blocksize);
 210
 211    /* Patch MODE SENSE device specific parameters if the BDS is opened
 212     * readonly.
 213     */
 214    if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
 215        blk_is_read_only(s->conf.blk) &&
 216        (r->req.cmd.buf[0] == MODE_SENSE ||
 217         r->req.cmd.buf[0] == MODE_SENSE_10) &&
 218        (r->req.cmd.buf[1] & 0x8) == 0) {
 219        if (r->req.cmd.buf[0] == MODE_SENSE) {
 220            r->buf[2] |= 0x80;
 221        } else  {
 222            r->buf[3] |= 0x80;
 223        }
 224    }
 225    scsi_req_data(&r->req, len);
 226    scsi_req_unref(&r->req);
 227}
 228
 229/* Read more data from scsi device into buffer.  */
 230static void scsi_read_data(SCSIRequest *req)
 231{
 232    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 233    SCSIDevice *s = r->req.dev;
 234    int ret;
 235
 236    DPRINTF("scsi_read_data 0x%x\n", req->tag);
 237
 238    /* The request is used as the AIO opaque value, so add a ref.  */
 239    scsi_req_ref(&r->req);
 240    if (r->len == -1) {
 241        scsi_command_complete_noio(r, 0);
 242        return;
 243    }
 244
 245    ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
 246                          scsi_read_complete);
 247    if (ret < 0) {
 248        scsi_command_complete_noio(r, ret);
 249    }
 250}
 251
 252static void scsi_write_complete(void * opaque, int ret)
 253{
 254    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
 255    SCSIDevice *s = r->req.dev;
 256
 257    DPRINTF("scsi_write_complete() ret = %d\n", ret);
 258
 259    assert(r->req.aiocb != NULL);
 260    r->req.aiocb = NULL;
 261
 262    if (ret || r->req.io_canceled) {
 263        scsi_command_complete_noio(r, ret);
 264        return;
 265    }
 266
 267    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
 268        s->type == TYPE_TAPE) {
 269        s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
 270        DPRINTF("block size %d\n", s->blocksize);
 271    }
 272
 273    scsi_command_complete_noio(r, ret);
 274}
 275
 276/* Write data to a scsi device.  Returns nonzero on failure.
 277   The transfer may complete asynchronously.  */
 278static void scsi_write_data(SCSIRequest *req)
 279{
 280    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 281    SCSIDevice *s = r->req.dev;
 282    int ret;
 283
 284    DPRINTF("scsi_write_data 0x%x\n", req->tag);
 285    if (r->len == 0) {
 286        r->len = r->buflen;
 287        scsi_req_data(&r->req, r->len);
 288        return;
 289    }
 290
 291    /* The request is used as the AIO opaque value, so add a ref.  */
 292    scsi_req_ref(&r->req);
 293    ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
 294    if (ret < 0) {
 295        scsi_command_complete_noio(r, ret);
 296    }
 297}
 298
 299/* Return a pointer to the data buffer.  */
 300static uint8_t *scsi_get_buf(SCSIRequest *req)
 301{
 302    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 303
 304    return r->buf;
 305}
 306
 307/* Execute a scsi command.  Returns the length of the data expected by the
 308   command.  This will be Positive for data transfers from the device
 309   (eg. disk reads), negative for transfers to the device (eg. disk writes),
 310   and zero if the command does not transfer any data.  */
 311
 312static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
 313{
 314    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 315    SCSIDevice *s = r->req.dev;
 316    int ret;
 317
 318#ifdef DEBUG_SCSI
 319    {
 320        int i;
 321        for (i = 1; i < r->req.cmd.len; i++) {
 322            printf(" 0x%02x", cmd[i]);
 323        }
 324        printf("\n");
 325    }
 326#endif
 327
 328    if (r->req.cmd.xfer == 0) {
 329        g_free(r->buf);
 330        r->buflen = 0;
 331        r->buf = NULL;
 332        /* The request is used as the AIO opaque value, so add a ref.  */
 333        scsi_req_ref(&r->req);
 334        ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
 335                              scsi_command_complete);
 336        if (ret < 0) {
 337            scsi_command_complete_noio(r, ret);
 338            return 0;
 339        }
 340        return 0;
 341    }
 342
 343    if (r->buflen != r->req.cmd.xfer) {
 344        g_free(r->buf);
 345        r->buf = g_malloc(r->req.cmd.xfer);
 346        r->buflen = r->req.cmd.xfer;
 347    }
 348
 349    memset(r->buf, 0, r->buflen);
 350    r->len = r->req.cmd.xfer;
 351    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
 352        r->len = 0;
 353        return -r->req.cmd.xfer;
 354    } else {
 355        return r->req.cmd.xfer;
 356    }
 357}
 358
 359static int read_naa_id(const uint8_t *p, uint64_t *p_wwn)
 360{
 361    int i;
 362
 363    if ((p[1] & 0xF) == 3) {
 364        /* NAA designator type */
 365        if (p[3] != 8) {
 366            return -EINVAL;
 367        }
 368        *p_wwn = ldq_be_p(p + 4);
 369        return 0;
 370    }
 371
 372    if ((p[1] & 0xF) == 8) {
 373        /* SCSI name string designator type */
 374        if (p[3] < 20 || memcmp(&p[4], "naa.", 4)) {
 375            return -EINVAL;
 376        }
 377        if (p[3] > 20 && p[24] != ',') {
 378            return -EINVAL;
 379        }
 380        *p_wwn = 0;
 381        for (i = 8; i < 24; i++) {
 382            char c = toupper(p[i]);
 383            c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10);
 384            *p_wwn = (*p_wwn << 4) | c;
 385        }
 386        return 0;
 387    }
 388
 389    return -EINVAL;
 390}
 391
 392void scsi_generic_read_device_identification(SCSIDevice *s)
 393{
 394    uint8_t cmd[6];
 395    uint8_t buf[250];
 396    uint8_t sensebuf[8];
 397    sg_io_hdr_t io_header;
 398    int ret;
 399    int i, len;
 400
 401    memset(cmd, 0, sizeof(cmd));
 402    memset(buf, 0, sizeof(buf));
 403    cmd[0] = INQUIRY;
 404    cmd[1] = 1;
 405    cmd[2] = 0x83;
 406    cmd[4] = sizeof(buf);
 407
 408    memset(&io_header, 0, sizeof(io_header));
 409    io_header.interface_id = 'S';
 410    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
 411    io_header.dxfer_len = sizeof(buf);
 412    io_header.dxferp = buf;
 413    io_header.cmdp = cmd;
 414    io_header.cmd_len = sizeof(cmd);
 415    io_header.mx_sb_len = sizeof(sensebuf);
 416    io_header.sbp = sensebuf;
 417    io_header.timeout = 6000; /* XXX */
 418
 419    ret = blk_ioctl(s->conf.blk, SG_IO, &io_header);
 420    if (ret < 0 || io_header.driver_status || io_header.host_status) {
 421        return;
 422    }
 423
 424    len = MIN((buf[2] << 8) | buf[3], sizeof(buf) - 4);
 425    for (i = 0; i + 3 <= len; ) {
 426        const uint8_t *p = &buf[i + 4];
 427        uint64_t wwn;
 428
 429        if (i + (p[3] + 4) > len) {
 430            break;
 431        }
 432
 433        if ((p[1] & 0x10) == 0) {
 434            /* Associated with the logical unit */
 435            if (read_naa_id(p, &wwn) == 0) {
 436                s->wwn = wwn;
 437            }
 438        } else if ((p[1] & 0x10) == 0x10) {
 439            /* Associated with the target port */
 440            if (read_naa_id(p, &wwn) == 0) {
 441                s->port_wwn = wwn;
 442            }
 443        }
 444
 445        i += p[3] + 4;
 446    }
 447}
 448
 449static int get_stream_blocksize(BlockBackend *blk)
 450{
 451    uint8_t cmd[6];
 452    uint8_t buf[12];
 453    uint8_t sensebuf[8];
 454    sg_io_hdr_t io_header;
 455    int ret;
 456
 457    memset(cmd, 0, sizeof(cmd));
 458    memset(buf, 0, sizeof(buf));
 459    cmd[0] = MODE_SENSE;
 460    cmd[4] = sizeof(buf);
 461
 462    memset(&io_header, 0, sizeof(io_header));
 463    io_header.interface_id = 'S';
 464    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
 465    io_header.dxfer_len = sizeof(buf);
 466    io_header.dxferp = buf;
 467    io_header.cmdp = cmd;
 468    io_header.cmd_len = sizeof(cmd);
 469    io_header.mx_sb_len = sizeof(sensebuf);
 470    io_header.sbp = sensebuf;
 471    io_header.timeout = 6000; /* XXX */
 472
 473    ret = blk_ioctl(blk, SG_IO, &io_header);
 474    if (ret < 0 || io_header.driver_status || io_header.host_status) {
 475        return -1;
 476    }
 477    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
 478}
 479
 480static void scsi_generic_reset(DeviceState *dev)
 481{
 482    SCSIDevice *s = SCSI_DEVICE(dev);
 483
 484    scsi_device_purge_requests(s, SENSE_CODE(RESET));
 485}
 486
 487static void scsi_generic_realize(SCSIDevice *s, Error **errp)
 488{
 489    int rc;
 490    int sg_version;
 491    struct sg_scsi_id scsiid;
 492
 493    if (!s->conf.blk) {
 494        error_setg(errp, "drive property not set");
 495        return;
 496    }
 497
 498    if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
 499        error_setg(errp, "Device doesn't support drive option werror");
 500        return;
 501    }
 502    if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
 503        error_setg(errp, "Device doesn't support drive option rerror");
 504        return;
 505    }
 506
 507    /* check we are using a driver managing SG_IO (version 3 and after */
 508    rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
 509    if (rc < 0) {
 510        error_setg(errp, "cannot get SG_IO version number: %s.  "
 511                         "Is this a SCSI device?",
 512                         strerror(-rc));
 513        return;
 514    }
 515    if (sg_version < 30000) {
 516        error_setg(errp, "scsi generic interface too old");
 517        return;
 518    }
 519
 520    /* get LUN of the /dev/sg? */
 521    if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
 522        error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
 523        return;
 524    }
 525
 526    /* define device state */
 527    s->type = scsiid.scsi_type;
 528    DPRINTF("device type %d\n", s->type);
 529
 530    switch (s->type) {
 531    case TYPE_TAPE:
 532        s->blocksize = get_stream_blocksize(s->conf.blk);
 533        if (s->blocksize == -1) {
 534            s->blocksize = 0;
 535        }
 536        break;
 537
 538        /* Make a guess for block devices, we'll fix it when the guest sends.
 539         * READ CAPACITY.  If they don't, they likely would assume these sizes
 540         * anyway. (TODO: they could also send MODE SENSE).
 541         */
 542    case TYPE_ROM:
 543    case TYPE_WORM:
 544        s->blocksize = 2048;
 545        break;
 546    default:
 547        s->blocksize = 512;
 548        break;
 549    }
 550
 551    DPRINTF("block size %d\n", s->blocksize);
 552
 553    scsi_generic_read_device_identification(s);
 554}
 555
 556const SCSIReqOps scsi_generic_req_ops = {
 557    .size         = sizeof(SCSIGenericReq),
 558    .free_req     = scsi_free_request,
 559    .send_command = scsi_send_command,
 560    .read_data    = scsi_read_data,
 561    .write_data   = scsi_write_data,
 562    .get_buf      = scsi_get_buf,
 563    .load_request = scsi_generic_load_request,
 564    .save_request = scsi_generic_save_request,
 565};
 566
 567static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
 568                                     uint8_t *buf, void *hba_private)
 569{
 570    SCSIRequest *req;
 571
 572    req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
 573    return req;
 574}
 575
 576static Property scsi_generic_properties[] = {
 577    DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
 578    DEFINE_PROP_END_OF_LIST(),
 579};
 580
 581static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
 582                                  uint8_t *buf, void *hba_private)
 583{
 584    return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
 585}
 586
 587static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
 588{
 589    DeviceClass *dc = DEVICE_CLASS(klass);
 590    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 591
 592    sc->realize      = scsi_generic_realize;
 593    sc->alloc_req    = scsi_new_request;
 594    sc->parse_cdb    = scsi_generic_parse_cdb;
 595    dc->fw_name = "disk";
 596    dc->desc = "pass through generic scsi device (/dev/sg*)";
 597    dc->reset = scsi_generic_reset;
 598    dc->props = scsi_generic_properties;
 599    dc->vmsd  = &vmstate_scsi_device;
 600}
 601
 602static const TypeInfo scsi_generic_info = {
 603    .name          = "scsi-generic",
 604    .parent        = TYPE_SCSI_DEVICE,
 605    .instance_size = sizeof(SCSIDevice),
 606    .class_init    = scsi_generic_class_initfn,
 607};
 608
 609static void scsi_generic_register_types(void)
 610{
 611    type_register_static(&scsi_generic_info);
 612}
 613
 614type_init(scsi_generic_register_types)
 615
 616#endif /* __linux__ */
 617