scsi-generic.c 14.5 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 * 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>
 *
M
Matthew Fernandez 已提交
10
 * This code is licensed under the LGPL.
11 12 13 14
 *
 */

#include "qemu-common.h"
15
#include "qemu/error-report.h"
P
Paolo Bonzini 已提交
16
#include "hw/scsi/scsi.h"
17
#include "sysemu/blockdev.h"
18

19
#ifdef __linux__
20 21 22 23

//#define DEBUG_SCSI

#ifdef DEBUG_SCSI
24 25
#define DPRINTF(fmt, ...) \
do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
26
#else
27
#define DPRINTF(fmt, ...) do {} while(0)
28 29
#endif

30 31
#define BADF(fmt, ...) \
do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
32 33 34 35 36 37

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <scsi/sg.h>
P
Paolo Bonzini 已提交
38
#include "block/scsi.h"
39

P
Paolo Bonzini 已提交
40 41 42 43 44 45 46
#define SG_ERR_DRIVER_TIMEOUT  0x06
#define SG_ERR_DRIVER_SENSE    0x08

#define SG_ERR_DID_OK          0x00
#define SG_ERR_DID_NO_CONNECT  0x01
#define SG_ERR_DID_BUS_BUSY    0x02
#define SG_ERR_DID_TIME_OUT    0x03
47 48 49 50 51

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

52 53
typedef struct SCSIGenericReq {
    SCSIRequest req;
54 55 56 57
    uint8_t *buf;
    int buflen;
    int len;
    sg_io_hdr_t io_header;
58
} SCSIGenericReq;
59

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
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);
    }
}

P
Paolo Bonzini 已提交
82
static void scsi_free_request(SCSIRequest *req)
83
{
P
Paolo Bonzini 已提交
84 85
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

86
    g_free(r->buf);
87 88 89 90 91
}

/* Helper function for command completion.  */
static void scsi_command_complete(void *opaque, int ret)
{
92
    int status;
93
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
94

95
    r->req.aiocb = NULL;
96 97 98
    if (r->req.io_canceled) {
        goto done;
    }
P
Paolo Bonzini 已提交
99
    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
100
        r->req.sense_len = r->io_header.sb_len_wr;
P
Paolo Bonzini 已提交
101
    }
A
aurel32 已提交
102

103 104
    if (ret != 0) {
        switch (ret) {
P
Paolo Bonzini 已提交
105
        case -EDOM:
106
            status = TASK_SET_FULL;
P
Paolo Bonzini 已提交
107
            break;
108
        case -ENOMEM:
109
            status = CHECK_CONDITION;
110
            scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
111 112
            break;
        default:
113
            status = CHECK_CONDITION;
114
            scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
115 116 117
            break;
        }
    } else {
P
Paolo Bonzini 已提交
118 119 120 121
        if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
            r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
            r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
            (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
122
            status = BUSY;
123
            BADF("Driver Timeout\n");
P
Paolo Bonzini 已提交
124 125 126
        } else if (r->io_header.host_status) {
            status = CHECK_CONDITION;
            scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
127 128
        } else if (r->io_header.status) {
            status = r->io_header.status;
129
        } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
130 131 132 133
            status = CHECK_CONDITION;
        } else {
            status = GOOD;
        }
134
    }
A
aurel32 已提交
135
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
136
            r, r->req.tag, status);
G
Gerd Hoffmann 已提交
137

138
    scsi_req_complete(&r->req, status);
139
done:
140 141 142
    if (!r->req.io_canceled) {
        scsi_req_unref(&r->req);
    }
143 144 145
}

/* Cancel a pending data transfer.  */
146
static void scsi_cancel_io(SCSIRequest *req)
147
{
148 149 150 151 152
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    DPRINTF("Cancel tag=0x%x\n", req->tag);
    if (r->req.aiocb) {
        bdrv_aio_cancel(r->req.aiocb);
153 154 155 156 157

        /* This reference was left in by scsi_*_data.  We take ownership of
         * it independent of whether bdrv_aio_cancel completes the request
         * or not.  */
        scsi_req_unref(&r->req);
158
    }
159
    r->req.aiocb = NULL;
160 161 162
}

static int execute_command(BlockDriverState *bdrv,
163
                           SCSIGenericReq *r, int direction,
164 165 166 167 168 169
			   BlockDriverCompletionFunc *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;
170 171
    r->io_header.cmdp = r->req.cmd.buf;
    r->io_header.cmd_len = r->req.cmd.len;
172 173
    r->io_header.mx_sb_len = sizeof(r->req.sense);
    r->io_header.sbp = r->req.sense;
174 175 176 177
    r->io_header.timeout = MAX_UINT;
    r->io_header.usr_ptr = r;
    r->io_header.flags |= SG_FLAG_DIRECT_IO;

178
    r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
179 180 181
    if (r->req.aiocb == NULL) {
        return -EIO;
    }
182 183 184 185 186 187

    return 0;
}

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

192
    r->req.aiocb = NULL;
193
    if (ret || r->req.io_canceled) {
194 195 196 197
        scsi_command_complete(r, ret);
        return;
    }
    len = r->io_header.dxfer_len - r->io_header.resid;
198
    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
199 200

    r->len = -1;
201
    if (len == 0) {
A
aurel32 已提交
202
        scsi_command_complete(r, 0);
203
    } else {
204
        /* Snoop READ CAPACITY output to set the blocksize.  */
205 206
        if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
            (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
207
            s->blocksize = ldl_be_p(&r->buf[4]);
208
            s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
209 210 211
        } 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]);
P
Paolo Bonzini 已提交
212
            s->max_lba = ldq_be_p(&r->buf[0]);
213
        }
214
        bdrv_set_guest_block_size(s->conf.bs, s->blocksize);
215

P
Paolo Bonzini 已提交
216
        scsi_req_data(&r->req, len);
217 218 219
        if (!r->req.io_canceled) {
            scsi_req_unref(&r->req);
        }
220
    }
221 222 223
}

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

230
    DPRINTF("scsi_read_data 0x%x\n", req->tag);
231 232 233

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

239
    ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
240 241
    if (ret < 0) {
        scsi_command_complete(r, ret);
242 243 244 245 246
    }
}

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

    DPRINTF("scsi_write_complete() ret = %d\n", ret);
251
    r->req.aiocb = NULL;
252
    if (ret || r->req.io_canceled) {
253 254 255 256
        scsi_command_complete(r, ret);
        return;
    }

257
    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
258 259 260
        s->type == TYPE_TAPE) {
        s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
        DPRINTF("block size %d\n", s->blocksize);
A
aurel32 已提交
261 262
    }

263 264 265 266 267
    scsi_command_complete(r, ret);
}

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

274
    DPRINTF("scsi_write_data 0x%x\n", req->tag);
275 276
    if (r->len == 0) {
        r->len = r->buflen;
P
Paolo Bonzini 已提交
277
        scsi_req_data(&r->req, r->len);
278
        return;
279 280
    }

281 282
    /* The request is used as the AIO opaque value, so add a ref.  */
    scsi_req_ref(&r->req);
283
    ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
284 285
    if (ret < 0) {
        scsi_command_complete(r, ret);
286 287 288 289
    }
}

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

294 295 296 297 298 299 300 301
    return r->buf;
}

/* 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.  */

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

308 309 310 311 312 313 314 315 316
#ifdef DEBUG_SCSI
    {
        int i;
        for (i = 1; i < r->req.cmd.len; i++) {
            printf(" 0x%02x", cmd[i]);
        }
        printf("\n");
    }
#endif
317

318
    if (r->req.cmd.xfer == 0) {
319
        if (r->buf != NULL)
320
            g_free(r->buf);
321 322
        r->buflen = 0;
        r->buf = NULL;
323 324
        /* The request is used as the AIO opaque value, so add a ref.  */
        scsi_req_ref(&r->req);
325
        ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
326 327 328
        if (ret < 0) {
            scsi_command_complete(r, ret);
            return 0;
329 330 331 332
        }
        return 0;
    }

333
    if (r->buflen != r->req.cmd.xfer) {
334
        if (r->buf != NULL)
335 336
            g_free(r->buf);
        r->buf = g_malloc(r->req.cmd.xfer);
337
        r->buflen = r->req.cmd.xfer;
338 339 340
    }

    memset(r->buf, 0, r->buflen);
341
    r->len = r->req.cmd.xfer;
G
Gerd Hoffmann 已提交
342
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
343
        r->len = 0;
344
        return -r->req.cmd.xfer;
P
Paolo Bonzini 已提交
345
    } else {
346
        return r->req.cmd.xfer;
347 348 349
    }
}

A
aurel32 已提交
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
static int get_stream_blocksize(BlockDriverState *bdrv)
{
    uint8_t cmd[6];
    uint8_t buf[12];
    uint8_t sensebuf[8];
    sg_io_hdr_t io_header;
    int ret;

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

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

374
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
375
    if (ret < 0 || io_header.driver_status || io_header.host_status) {
A
aurel32 已提交
376
        return -1;
377
    }
A
aurel32 已提交
378 379 380
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
}

381 382
static void scsi_generic_reset(DeviceState *dev)
{
383
    SCSIDevice *s = SCSI_DEVICE(dev);
384

385
    scsi_device_purge_requests(s, SENSE_CODE(RESET));
386 387
}

388
static void scsi_unrealize(SCSIDevice *s, Error **errp)
389
{
390 391
    scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
    blockdev_mark_auto_del(s->conf.bs);
392 393
}

394
static void scsi_generic_realize(SCSIDevice *s, Error **errp)
395
{
396
    int rc;
397 398 399
    int sg_version;
    struct sg_scsi_id scsiid;

400
    if (!s->conf.bs) {
401 402
        error_setg(errp, "drive property not set");
        return;
403
    }
404

405
    if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
406 407
        error_setg(errp, "Device doesn't support drive option werror");
        return;
408
    }
409
    if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
410 411
        error_setg(errp, "Device doesn't support drive option rerror");
        return;
412 413
    }

414
    /* check we are using a driver managing SG_IO (version 3 and after */
415 416
    rc = bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version);
    if (rc < 0) {
417 418 419 420
        error_setg(errp, "cannot get SG_IO version number: %s.  "
                         "Is this a SCSI device?",
                         strerror(-rc));
        return;
421 422
    }
    if (sg_version < 30000) {
423 424
        error_setg(errp, "scsi generic interface too old");
        return;
425
    }
426 427

    /* get LUN of the /dev/sg? */
428
    if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
429 430
        error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
        return;
431
    }
432 433

    /* define device state */
434 435
    s->type = scsiid.scsi_type;
    DPRINTF("device type %d\n", s->type);
P
Paolo Bonzini 已提交
436 437 438 439
    if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
        add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
    }

440 441
    switch (s->type) {
    case TYPE_TAPE:
442 443 444 445
        s->blocksize = get_stream_blocksize(s->conf.bs);
        if (s->blocksize == -1) {
            s->blocksize = 0;
        }
446 447 448 449 450 451 452 453 454 455 456 457 458
        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;
A
aurel32 已提交
459
    }
460 461

    DPRINTF("block size %d\n", s->blocksize);
462
}
463

P
Paolo Bonzini 已提交
464
const SCSIReqOps scsi_generic_req_ops = {
P
Paolo Bonzini 已提交
465
    .size         = sizeof(SCSIGenericReq),
466 467 468 469 470 471
    .free_req     = scsi_free_request,
    .send_command = scsi_send_command,
    .read_data    = scsi_read_data,
    .write_data   = scsi_write_data,
    .cancel_io    = scsi_cancel_io,
    .get_buf      = scsi_get_buf,
472 473
    .load_request = scsi_generic_load_request,
    .save_request = scsi_generic_save_request,
P
Paolo Bonzini 已提交
474 475 476
};

static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
P
Paolo Bonzini 已提交
477
                                     uint8_t *buf, void *hba_private)
P
Paolo Bonzini 已提交
478 479 480 481 482 483 484
{
    SCSIRequest *req;

    req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
    return req;
}

485
static Property scsi_generic_properties[] = {
486 487
    DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
    DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
488 489 490
    DEFINE_PROP_END_OF_LIST(),
};

491 492 493 494 495 496
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);
}

497 498
static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
{
499
    DeviceClass *dc = DEVICE_CLASS(klass);
500 501
    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);

502 503
    sc->realize      = scsi_generic_realize;
    sc->unrealize    = scsi_unrealize;
504
    sc->alloc_req    = scsi_new_request;
505
    sc->parse_cdb    = scsi_generic_parse_cdb;
506 507 508 509
    dc->fw_name = "disk";
    dc->desc = "pass through generic scsi device (/dev/sg*)";
    dc->reset = scsi_generic_reset;
    dc->props = scsi_generic_properties;
510
    dc->vmsd  = &vmstate_scsi_device;
511 512
}

513
static const TypeInfo scsi_generic_info = {
514 515 516 517
    .name          = "scsi-generic",
    .parent        = TYPE_SCSI_DEVICE,
    .instance_size = sizeof(SCSIDevice),
    .class_init    = scsi_generic_class_initfn,
518
};
519

A
Andreas Färber 已提交
520
static void scsi_generic_register_types(void)
521
{
522
    type_register_static(&scsi_generic_info);
523
}
A
Andreas Färber 已提交
524 525

type_init(scsi_generic_register_types)
526

527
#endif /* __linux__ */