scsi-disk.c 49.7 KB
Newer Older
P
pbrook 已提交
1 2 3 4 5 6 7
/*
 * SCSI Device emulation
 *
 * Copyright (c) 2006 CodeSourcery.
 * Based on code by Fabrice Bellard
 *
 * Written by Paul Brook
8 9 10 11 12 13
 * Modifications:
 *  2009-Dec-12 Artyom Tarasenko : implemented stamdard inquiry for the case
 *                                 when the allocation length of CDB is smaller
 *                                 than 36.
 *  2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the
 *                                 MODE SENSE response.
P
pbrook 已提交
14
 *
M
Matthew Fernandez 已提交
15
 * This code is licensed under the LGPL.
P
pbrook 已提交
16 17
 *
 * Note that this file only handles the SCSI architecture model and device
18 19
 * commands.  Emulation of interface/link layer protocols is handled by
 * the host adapter emulator.
P
pbrook 已提交
20 21 22 23 24
 */

//#define DEBUG_SCSI

#ifdef DEBUG_SCSI
25 26
#define DPRINTF(fmt, ...) \
do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
P
pbrook 已提交
27
#else
28
#define DPRINTF(fmt, ...) do {} while(0)
P
pbrook 已提交
29 30
#endif

31 32
#define BADF(fmt, ...) \
do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
P
pbrook 已提交
33

P
pbrook 已提交
34
#include "qemu-common.h"
35
#include "qemu-error.h"
G
Gerd Hoffmann 已提交
36
#include "scsi.h"
G
Gerd Hoffmann 已提交
37
#include "scsi-defs.h"
38
#include "sysemu.h"
B
Blue Swirl 已提交
39
#include "blockdev.h"
40
#include "block_int.h"
41

42
#define SCSI_DMA_BUF_SIZE    131072
43
#define SCSI_MAX_INQUIRY_LEN 256
P
pbrook 已提交
44

K
Kevin Wolf 已提交
45 46 47 48
#define SCSI_REQ_STATUS_RETRY           0x01
#define SCSI_REQ_STATUS_RETRY_TYPE_MASK 0x06
#define SCSI_REQ_STATUS_RETRY_READ      0x00
#define SCSI_REQ_STATUS_RETRY_WRITE     0x02
49
#define SCSI_REQ_STATUS_RETRY_FLUSH     0x04
50

51 52
typedef struct SCSIDiskState SCSIDiskState;

53 54
typedef struct SCSIDiskReq {
    SCSIRequest req;
P
pbrook 已提交
55
    /* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
56 57
    uint64_t sector;
    uint32_t sector_count;
58
    uint32_t buflen;
59 60
    struct iovec iov;
    QEMUIOVector qiov;
61
    uint32_t status;
62
    BlockAcctCookie acct;
63
} SCSIDiskReq;
P
pbrook 已提交
64

65
struct SCSIDiskState
P
pbrook 已提交
66
{
67
    SCSIDevice qdev;
68
    BlockDriverState *bs;
P
pbrook 已提交
69 70 71
    /* The qemu block layer uses a fixed 512 byte sector size.
       This is the number of 512 byte blocks in a single scsi sector.  */
    int cluster_size;
72
    uint32_t removable;
73
    uint64_t max_lba;
74
    bool media_changed;
75
    bool media_event;
76
    QEMUBH *bh;
G
Gerd Hoffmann 已提交
77
    char *version;
78
    char *serial;
79
    bool tray_open;
80
    bool tray_locked;
P
pbrook 已提交
81 82
};

K
Kevin Wolf 已提交
83
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
P
Paolo Bonzini 已提交
84
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf);
K
Kevin Wolf 已提交
85

P
Paolo Bonzini 已提交
86
static void scsi_free_request(SCSIRequest *req)
P
pbrook 已提交
87
{
P
Paolo Bonzini 已提交
88 89
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);

90 91 92
    if (r->iov.iov_base) {
        qemu_vfree(r->iov.iov_base);
    }
P
pbrook 已提交
93 94
}

95 96
/* Helper function for command completion with sense.  */
static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
G
Gerd Hoffmann 已提交
97
{
B
Blue Swirl 已提交
98 99
    DPRINTF("Command complete tag=0x%x sense=%d/%d/%d\n",
            r->req.tag, sense.key, sense.asc, sense.ascq);
100 101
    scsi_req_build_sense(&r->req, sense);
    scsi_req_complete(&r->req, CHECK_CONDITION);
P
pbrook 已提交
102 103 104
}

/* Cancel a pending data transfer.  */
105
static void scsi_cancel_io(SCSIRequest *req)
P
pbrook 已提交
106
{
107 108 109 110 111
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);

    DPRINTF("Cancel tag=0x%x\n", req->tag);
    if (r->req.aiocb) {
        bdrv_aio_cancel(r->req.aiocb);
P
pbrook 已提交
112
    }
113
    r->req.aiocb = NULL;
P
pbrook 已提交
114 115
}

116 117
static uint32_t scsi_init_iovec(SCSIDiskReq *r)
{
118 119 120 121 122 123 124
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    if (!r->iov.iov_base) {
        r->buflen = SCSI_DMA_BUF_SIZE;
        r->iov.iov_base = qemu_blockalign(s->bs, r->buflen);
    }
    r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
125 126 127 128
    qemu_iovec_init_external(&r->qiov, &r->iov, 1);
    return r->qiov.size / 512;
}

P
pbrook 已提交
129 130
static void scsi_read_complete(void * opaque, int ret)
{
131
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
132
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
K
Kevin Wolf 已提交
133
    int n;
P
pbrook 已提交
134

P
Paolo Bonzini 已提交
135 136 137 138
    if (r->req.aiocb != NULL) {
        r->req.aiocb = NULL;
        bdrv_acct_done(s->bs, &r->acct);
    }
139

P
pbrook 已提交
140
    if (ret) {
K
Kevin Wolf 已提交
141 142 143
        if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
            return;
        }
P
pbrook 已提交
144
    }
K
Kevin Wolf 已提交
145

146
    DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size);
P
pbrook 已提交
147

148
    n = r->qiov.size / 512;
K
Kevin Wolf 已提交
149 150
    r->sector += n;
    r->sector_count -= n;
151
    scsi_req_data(&r->req, r->qiov.size);
P
pbrook 已提交
152 153
}

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
static void scsi_flush_complete(void * opaque, int ret)
{
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    if (r->req.aiocb != NULL) {
        r->req.aiocb = NULL;
        bdrv_acct_done(s->bs, &r->acct);
    }

    if (ret < 0) {
        if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
            return;
        }
    }

    scsi_req_complete(&r->req, GOOD);
}
K
Kevin Wolf 已提交
172

173 174
/* Read more data from scsi device into buffer.  */
static void scsi_read_data(SCSIRequest *req)
P
pbrook 已提交
175
{
176
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
K
Kevin Wolf 已提交
177
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
P
pbrook 已提交
178 179
    uint32_t n;

P
pbrook 已提交
180
    if (r->sector_count == (uint32_t)-1) {
181
        DPRINTF("Read buf_len=%zd\n", r->iov.iov_len);
P
pbrook 已提交
182
        r->sector_count = 0;
P
Paolo Bonzini 已提交
183
        scsi_req_data(&r->req, r->iov.iov_len);
P
pbrook 已提交
184
        return;
P
pbrook 已提交
185
    }
P
pbrook 已提交
186 187
    DPRINTF("Read sector_count=%d\n", r->sector_count);
    if (r->sector_count == 0) {
188 189
        /* This also clears the sense buffer for REQUEST SENSE.  */
        scsi_req_complete(&r->req, GOOD);
P
pbrook 已提交
190
        return;
P
pbrook 已提交
191 192
    }

193 194 195
    /* No data transfer may already be in progress */
    assert(r->req.aiocb == NULL);

196 197 198 199 200 201
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        DPRINTF("Data transfer direction invalid\n");
        scsi_read_complete(r, -EINVAL);
        return;
    }

202 203 204
    if (s->tray_open) {
        scsi_read_complete(r, -ENOMEDIUM);
    }
205
    n = scsi_init_iovec(r);
206
    bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
207
    r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
208
                              scsi_read_complete, r);
209 210 211
    if (r->req.aiocb == NULL) {
        scsi_read_complete(r, -EIO);
    }
P
pbrook 已提交
212 213
}

K
Kevin Wolf 已提交
214 215 216
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
{
    int is_read = (type == SCSI_REQ_STATUS_RETRY_READ);
217
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
K
Kevin Wolf 已提交
218
    BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
219

220
    if (action == BLOCK_ERR_IGNORE) {
K
Kevin Wolf 已提交
221
        bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
222
        return 0;
223
    }
224 225 226

    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
            || action == BLOCK_ERR_STOP_ANY) {
K
Kevin Wolf 已提交
227 228 229 230 231

        type &= SCSI_REQ_STATUS_RETRY_TYPE_MASK;
        r->status |= SCSI_REQ_STATUS_RETRY | type;

        bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
232
        vm_stop(RUN_STATE_IO_ERROR);
L
Luiz Capitulino 已提交
233
        bdrv_iostatus_set_err(s->bs, error);
234
    } else {
235
        switch (error) {
236 237 238
        case ENOMEDIUM:
            scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
            break;
239
        case ENOMEM:
240
            scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
241 242
            break;
        case EINVAL:
243
            scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
244 245
            break;
        default:
246
            scsi_check_condition(r, SENSE_CODE(IO_ERROR));
247
            break;
248
        }
K
Kevin Wolf 已提交
249
        bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
250 251 252 253
    }
    return 1;
}

P
pbrook 已提交
254 255
static void scsi_write_complete(void * opaque, int ret)
{
256
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
257
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
258 259
    uint32_t n;

P
Paolo Bonzini 已提交
260 261 262 263
    if (r->req.aiocb != NULL) {
        r->req.aiocb = NULL;
        bdrv_acct_done(s->bs, &r->acct);
    }
264

P
pbrook 已提交
265
    if (ret) {
K
Kevin Wolf 已提交
266
        if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
267
            return;
K
Kevin Wolf 已提交
268
        }
P
pbrook 已提交
269 270
    }

271
    n = r->qiov.size / 512;
272 273
    r->sector += n;
    r->sector_count -= n;
P
pbrook 已提交
274
    if (r->sector_count == 0) {
275
        scsi_req_complete(&r->req, GOOD);
P
pbrook 已提交
276
    } else {
277 278 279
        scsi_init_iovec(r);
        DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size);
        scsi_req_data(&r->req, r->qiov.size);
P
pbrook 已提交
280 281 282
    }
}

283
static void scsi_write_data(SCSIRequest *req)
284
{
285
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
286
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
287 288
    uint32_t n;

289 290 291
    /* No data transfer may already be in progress */
    assert(r->req.aiocb == NULL);

292 293 294
    if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {
        DPRINTF("Data transfer direction invalid\n");
        scsi_write_complete(r, -EINVAL);
295
        return;
296 297
    }

298
    n = r->qiov.size / 512;
299
    if (n) {
300 301 302
        if (s->tray_open) {
            scsi_write_complete(r, -ENOMEDIUM);
        }
303
        bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
304
        r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
305
                                       scsi_write_complete, r);
306
        if (r->req.aiocb == NULL) {
307
            scsi_write_complete(r, -ENOMEM);
308
        }
309
    } else {
310
        /* Called for the first time.  Ask the driver to send us more data.  */
311 312
        scsi_write_complete(r, 0);
    }
P
pbrook 已提交
313
}
P
pbrook 已提交
314

315
static void scsi_dma_restart_bh(void *opaque)
316
{
317
    SCSIDiskState *s = opaque;
318 319
    SCSIRequest *req;
    SCSIDiskReq *r;
320 321 322

    qemu_bh_delete(s->bh);
    s->bh = NULL;
323

324 325
    QTAILQ_FOREACH(req, &s->qdev.requests, next) {
        r = DO_UPCAST(SCSIDiskReq, req, req);
326
        if (r->status & SCSI_REQ_STATUS_RETRY) {
K
Kevin Wolf 已提交
327
            int status = r->status;
328

K
Kevin Wolf 已提交
329 330 331 332 333
            r->status &=
                ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK);

            switch (status & SCSI_REQ_STATUS_RETRY_TYPE_MASK) {
            case SCSI_REQ_STATUS_RETRY_READ:
334
                scsi_read_data(&r->req);
K
Kevin Wolf 已提交
335 336
                break;
            case SCSI_REQ_STATUS_RETRY_WRITE:
337
                scsi_write_data(&r->req);
K
Kevin Wolf 已提交
338
                break;
339
            case SCSI_REQ_STATUS_RETRY_FLUSH:
P
Paolo Bonzini 已提交
340 341
                scsi_send_command(&r->req, r->req.cmd.buf);
                break;
K
Kevin Wolf 已提交
342
            }
343 344 345 346
        }
    }
}

347
static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
348
{
349
    SCSIDiskState *s = opaque;
350

351
    if (!running) {
352
        return;
353
    }
354 355 356 357 358 359
    if (!s->bh) {
        s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
        qemu_bh_schedule(s->bh);
    }
}

P
pbrook 已提交
360
/* Return a pointer to the data buffer.  */
361
static uint8_t *scsi_get_buf(SCSIRequest *req)
P
pbrook 已提交
362
{
363
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
P
pbrook 已提交
364

365
    return (uint8_t *)r->iov.iov_base;
P
pbrook 已提交
366 367
}

368 369
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
{
G
Gerd Hoffmann 已提交
370
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
    int buflen = 0;

    if (req->cmd.buf[1] & 0x2) {
        /* Command support data - optional, not implemented */
        BADF("optional INQUIRY command support request not implemented\n");
        return -1;
    }

    if (req->cmd.buf[1] & 0x1) {
        /* Vital product data */
        uint8_t page_code = req->cmd.buf[2];
        if (req->cmd.xfer < 4) {
            BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
                 "less than 4\n", page_code, req->cmd.xfer);
            return -1;
        }

H
Hannes Reinecke 已提交
388
        if (s->qdev.type == TYPE_ROM) {
389 390 391 392 393 394 395 396 397
            outbuf[buflen++] = 5;
        } else {
            outbuf[buflen++] = 0;
        }
        outbuf[buflen++] = page_code ; // this page
        outbuf[buflen++] = 0x00;

        switch (page_code) {
        case 0x00: /* Supported page codes, mandatory */
H
Hannes Reinecke 已提交
398 399
        {
            int pages;
400 401
            DPRINTF("Inquiry EVPD[Supported pages] "
                    "buffer size %zd\n", req->cmd.xfer);
H
Hannes Reinecke 已提交
402
            pages = buflen++;
403
            outbuf[buflen++] = 0x00; // list of supported pages (this page)
404
            if (s->serial) {
405
                outbuf[buflen++] = 0x80; // unit serial number
406
            }
407
            outbuf[buflen++] = 0x83; // device identification
H
Hannes Reinecke 已提交
408
            if (s->qdev.type == TYPE_DISK) {
409 410
                outbuf[buflen++] = 0xb0; // block limits
                outbuf[buflen++] = 0xb2; // thin provisioning
H
Hannes Reinecke 已提交
411 412
            }
            outbuf[pages] = buflen - pages - 1; // number of pages
413
            break;
H
Hannes Reinecke 已提交
414
        }
415 416
        case 0x80: /* Device serial number, optional */
        {
417
            int l;
418

419 420 421 422 423 424
            if (!s->serial) {
                DPRINTF("Inquiry (EVPD[Serial number] not supported\n");
                return -1;
            }

            l = strlen(s->serial);
425
            if (l > req->cmd.xfer) {
426
                l = req->cmd.xfer;
427 428
            }
            if (l > 20) {
429
                l = 20;
430
            }
431 432 433 434

            DPRINTF("Inquiry EVPD[Serial number] "
                    "buffer size %zd\n", req->cmd.xfer);
            outbuf[buflen++] = l;
435
            memcpy(outbuf+buflen, s->serial, l);
436 437 438 439 440 441 442
            buflen += l;
            break;
        }

        case 0x83: /* Device identification page, mandatory */
        {
            int max_len = 255 - 8;
443
            int id_len = strlen(bdrv_get_device_name(s->bs));
444

445
            if (id_len > max_len) {
446
                id_len = max_len;
447
            }
448 449 450
            DPRINTF("Inquiry EVPD[Device identification] "
                    "buffer size %zd\n", req->cmd.xfer);

H
Hannes Reinecke 已提交
451
            outbuf[buflen++] = 4 + id_len;
452 453 454 455 456
            outbuf[buflen++] = 0x2; // ASCII
            outbuf[buflen++] = 0;   // not officially assigned
            outbuf[buflen++] = 0;   // reserved
            outbuf[buflen++] = id_len; // length of data following

457
            memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len);
458 459 460
            buflen += id_len;
            break;
        }
461
        case 0xb0: /* block limits */
C
Christoph Hellwig 已提交
462
        {
463 464
            unsigned int unmap_sectors =
                    s->qdev.conf.discard_granularity / s->qdev.blocksize;
465 466 467 468
            unsigned int min_io_size =
                    s->qdev.conf.min_io_size / s->qdev.blocksize;
            unsigned int opt_io_size =
                    s->qdev.conf.opt_io_size / s->qdev.blocksize;
C
Christoph Hellwig 已提交
469

H
Hannes Reinecke 已提交
470
            if (s->qdev.type == TYPE_ROM) {
H
Hannes Reinecke 已提交
471 472 473 474
                DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
                        page_code);
                return -1;
            }
C
Christoph Hellwig 已提交
475 476 477 478 479 480 481 482 483 484 485 486 487 488
            /* required VPD size with unmap support */
            outbuf[3] = buflen = 0x3c;

            memset(outbuf + 4, 0, buflen - 4);

            /* optimal transfer length granularity */
            outbuf[6] = (min_io_size >> 8) & 0xff;
            outbuf[7] = min_io_size & 0xff;

            /* optimal transfer length */
            outbuf[12] = (opt_io_size >> 24) & 0xff;
            outbuf[13] = (opt_io_size >> 16) & 0xff;
            outbuf[14] = (opt_io_size >> 8) & 0xff;
            outbuf[15] = opt_io_size & 0xff;
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503

            /* optimal unmap granularity */
            outbuf[28] = (unmap_sectors >> 24) & 0xff;
            outbuf[29] = (unmap_sectors >> 16) & 0xff;
            outbuf[30] = (unmap_sectors >> 8) & 0xff;
            outbuf[31] = unmap_sectors & 0xff;
            break;
        }
        case 0xb2: /* thin provisioning */
        {
            outbuf[3] = buflen = 8;
            outbuf[4] = 0;
            outbuf[5] = 0x40; /* write same with unmap supported */
            outbuf[6] = 0;
            outbuf[7] = 0;
C
Christoph Hellwig 已提交
504 505
            break;
        }
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
        default:
            BADF("Error: unsupported Inquiry (EVPD[%02X]) "
                 "buffer size %zd\n", page_code, req->cmd.xfer);
            return -1;
        }
        /* done with EVPD */
        return buflen;
    }

    /* Standard INQUIRY data */
    if (req->cmd.buf[2] != 0) {
        BADF("Error: Inquiry (STANDARD) page or code "
             "is non-zero [%02X]\n", req->cmd.buf[2]);
        return -1;
    }

    /* PAGE CODE == 0 */
    if (req->cmd.xfer < 5) {
        BADF("Error: Inquiry (STANDARD) buffer size %zd "
             "is less than 5\n", req->cmd.xfer);
        return -1;
    }

    buflen = req->cmd.xfer;
530
    if (buflen > SCSI_MAX_INQUIRY_LEN) {
531
        buflen = SCSI_MAX_INQUIRY_LEN;
532
    }
533 534
    memset(outbuf, 0, buflen);

H
Hannes Reinecke 已提交
535 536
    outbuf[0] = s->qdev.type & 0x1f;
    if (s->qdev.type == TYPE_ROM) {
537
        outbuf[1] = 0x80;
L
Laszlo Ast 已提交
538
        memcpy(&outbuf[16], "QEMU CD-ROM     ", 16);
539
    } else {
540
        outbuf[1] = s->removable ? 0x80 : 0;
L
Laszlo Ast 已提交
541
        memcpy(&outbuf[16], "QEMU HARDDISK   ", 16);
542
    }
L
Laszlo Ast 已提交
543
    memcpy(&outbuf[8], "QEMU    ", 8);
G
Gerd Hoffmann 已提交
544
    memset(&outbuf[32], 0, 4);
545
    memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
546 547 548 549 550 551
    /*
     * We claim conformance to SPC-3, which is required for guests
     * to ask for modern features like READ CAPACITY(16) or the
     * block characteristics VPD page by default.  Not all of SPC-3
     * is actually implemented, but we're good enough.
     */
C
Christoph Hellwig 已提交
552
    outbuf[2] = 5;
553
    outbuf[3] = 2; /* Format 2 */
554 555 556 557 558 559 560 561 562

    if (buflen > 36) {
        outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
    } else {
        /* If the allocation length of CDB is too small,
               the additional length is not adjusted */
        outbuf[4] = 36 - 5;
    }

563
    /* Sync data transfer and TCQ.  */
564
    outbuf[7] = 0x10 | (req->bus->info->tcq ? 0x02 : 0);
565 566 567
    return buflen;
}

568 569 570 571 572 573 574 575 576 577 578 579 580
static inline bool media_is_dvd(SCSIDiskState *s)
{
    uint64_t nb_sectors;
    if (s->qdev.type != TYPE_ROM) {
        return false;
    }
    if (!bdrv_is_inserted(s->bs)) {
        return false;
    }
    bdrv_get_geometry(s->bs, &nb_sectors);
    return nb_sectors > CD_MAX_SECTORS;
}

581 582 583 584 585 586 587 588 589 590 591 592 593
static inline bool media_is_cd(SCSIDiskState *s)
{
    uint64_t nb_sectors;
    if (s->qdev.type != TYPE_ROM) {
        return false;
    }
    if (!bdrv_is_inserted(s->bs)) {
        return false;
    }
    bdrv_get_geometry(s->bs, &nb_sectors);
    return nb_sectors <= CD_MAX_SECTORS;
}

594 595 596
static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
                                   uint8_t *outbuf)
{
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
    static const int rds_caps_size[5] = {
        [0] = 2048 + 4,
        [1] = 4 + 4,
        [3] = 188 + 4,
        [4] = 2048 + 4,
    };

    uint8_t media = r->req.cmd.buf[1];
    uint8_t layer = r->req.cmd.buf[6];
    uint8_t format = r->req.cmd.buf[7];
    int size = -1;

    if (s->qdev.type != TYPE_ROM) {
        return -1;
    }
    if (media != 0) {
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
        return -1;
    }

    if (format != 0xff) {
        if (s->tray_open || !bdrv_is_inserted(s->bs)) {
            scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
            return -1;
        }
        if (media_is_cd(s)) {
            scsi_check_condition(r, SENSE_CODE(INCOMPATIBLE_FORMAT));
            return -1;
        }
        if (format >= ARRAY_SIZE(rds_caps_size)) {
            return -1;
        }
        size = rds_caps_size[format];
        memset(outbuf, 0, size);
    }

    switch (format) {
    case 0x00: {
        /* Physical format information */
        uint64_t nb_sectors;
        if (layer != 0) {
            goto fail;
        }
        bdrv_get_geometry(s->bs, &nb_sectors);

        outbuf[4] = 1;   /* DVD-ROM, part version 1 */
        outbuf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
        outbuf[6] = 1;   /* one layer, read-only (per MMC-2 spec) */
        outbuf[7] = 0;   /* default densities */

        stl_be_p(&outbuf[12], (nb_sectors >> 2) - 1); /* end sector */
        stl_be_p(&outbuf[16], (nb_sectors >> 2) - 1); /* l0 end sector */
        break;
    }

    case 0x01: /* DVD copyright information, all zeros */
        break;

    case 0x03: /* BCA information - invalid field for no BCA info */
        return -1;

    case 0x04: /* DVD disc manufacturing information, all zeros */
        break;

    case 0xff: { /* List capabilities */
        int i;
        size = 4;
        for (i = 0; i < ARRAY_SIZE(rds_caps_size); i++) {
            if (!rds_caps_size[i]) {
                continue;
            }
            outbuf[size] = i;
            outbuf[size + 1] = 0x40; /* Not writable, readable */
            stw_be_p(&outbuf[size + 2], rds_caps_size[i]);
            size += 4;
        }
        break;
     }

    default:
        return -1;
    }

    /* Size of buffer, not including 2 byte size field */
    stw_be_p(outbuf, size - 2);
    return size;

fail:
685 686 687
    return -1;
}

688
static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf)
689
{
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
    uint8_t event_code, media_status;

    media_status = 0;
    if (s->tray_open) {
        media_status = MS_TRAY_OPEN;
    } else if (bdrv_is_inserted(s->bs)) {
        media_status = MS_MEDIA_PRESENT;
    }

    /* Event notification descriptor */
    event_code = MEC_NO_CHANGE;
    if (media_status != MS_TRAY_OPEN && s->media_event) {
        event_code = MEC_NEW_MEDIA;
        s->media_event = false;
    }

    outbuf[0] = event_code;
    outbuf[1] = media_status;

    /* These fields are reserved, just clear them. */
    outbuf[2] = 0;
    outbuf[3] = 0;
    return 4;
}

static int scsi_get_event_status_notification(SCSIDiskState *s, SCSIDiskReq *r,
                                              uint8_t *outbuf)
{
    int size;
    uint8_t *buf = r->req.cmd.buf;
    uint8_t notification_class_request = buf[4];
    if (s->qdev.type != TYPE_ROM) {
        return -1;
    }
    if ((buf[1] & 1) == 0) {
        /* asynchronous */
        return -1;
    }

    size = 4;
    outbuf[0] = outbuf[1] = 0;
    outbuf[3] = 1 << GESN_MEDIA; /* supported events */
    if (notification_class_request & (1 << GESN_MEDIA)) {
        outbuf[2] = GESN_MEDIA;
        size += scsi_event_status_media(s, &outbuf[size]);
    } else {
        outbuf[2] = 0x80;
    }
    stw_be_p(outbuf, size - 4);
    return size;
740 741
}

742
static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
743
{
744 745
    int current;

746 747 748
    if (s->qdev.type != TYPE_ROM) {
        return -1;
    }
749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773
    current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM;
    memset(outbuf, 0, 40);
    stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */
    stw_be_p(&outbuf[6], current);
    /* outbuf[8] - outbuf[19]: Feature 0 - Profile list */
    outbuf[10] = 0x03; /* persistent, current */
    outbuf[11] = 8; /* two profiles */
    stw_be_p(&outbuf[12], MMC_PROFILE_DVD_ROM);
    outbuf[14] = (current == MMC_PROFILE_DVD_ROM);
    stw_be_p(&outbuf[16], MMC_PROFILE_CD_ROM);
    outbuf[18] = (current == MMC_PROFILE_CD_ROM);
    /* outbuf[20] - outbuf[31]: Feature 1 - Core feature */
    stw_be_p(&outbuf[20], 1);
    outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */
    outbuf[23] = 8;
    stl_be_p(&outbuf[24], 1); /* SCSI */
    outbuf[28] = 1; /* DBE = 1, mandatory */
    /* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */
    stw_be_p(&outbuf[32], 3);
    outbuf[34] = 0x08 | 0x03; /* version 2, persistent, current */
    outbuf[35] = 4;
    outbuf[36] = 0x39; /* tray, load=1, eject=1, unlocked at powerup, lock=1 */
    /* TODO: Random readable, CD read, DVD read, drive serial number,
       power management */
    return 40;
774 775 776 777 778 779 780 781 782 783 784 785
}

static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf)
{
    if (s->qdev.type != TYPE_ROM) {
        return -1;
    }
    memset(outbuf, 0, 8);
    outbuf[5] = 1; /* CD-ROM */
    return 8;
}

786
static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
787
                           int page_control)
788
{
789 790 791 792
    static const int mode_sense_valid[0x3f] = {
        [MODE_PAGE_HD_GEOMETRY]            = (1 << TYPE_DISK),
        [MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1 << TYPE_DISK),
        [MODE_PAGE_CACHING]                = (1 << TYPE_DISK) | (1 << TYPE_ROM),
793 794
        [MODE_PAGE_R_W_ERROR]              = (1 << TYPE_DISK) | (1 << TYPE_ROM),
        [MODE_PAGE_AUDIO_CTL]              = (1 << TYPE_ROM),
795 796 797
        [MODE_PAGE_CAPABILITIES]           = (1 << TYPE_ROM),
    };

798
    BlockDriverState *bdrv = s->bs;
799
    int cylinders, heads, secs;
800
    uint8_t *p = *p_outbuf;
801

802 803 804 805 806 807
    if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) {
        return -1;
    }

    p[0] = page;

808 809 810 811 812 813
    /*
     * If Changeable Values are requested, a mask denoting those mode parameters
     * that are changeable shall be returned. As we currently don't support
     * parameter changes via MODE_SELECT all bits are returned set to zero.
     * The buffer was already menset to zero by the caller of this function.
     */
814
    switch (page) {
815
    case MODE_PAGE_HD_GEOMETRY:
816
        p[1] = 0x16;
817
        if (page_control == 1) { /* Changeable Values */
818
            break;
819
        }
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843
        /* if a geometry hint is available, use it */
        bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
        p[2] = (cylinders >> 16) & 0xff;
        p[3] = (cylinders >> 8) & 0xff;
        p[4] = cylinders & 0xff;
        p[5] = heads & 0xff;
        /* Write precomp start cylinder, disabled */
        p[6] = (cylinders >> 16) & 0xff;
        p[7] = (cylinders >> 8) & 0xff;
        p[8] = cylinders & 0xff;
        /* Reduced current start cylinder, disabled */
        p[9] = (cylinders >> 16) & 0xff;
        p[10] = (cylinders >> 8) & 0xff;
        p[11] = cylinders & 0xff;
        /* Device step rate [ns], 200ns */
        p[12] = 0;
        p[13] = 200;
        /* Landing zone cylinder */
        p[14] = 0xff;
        p[15] =  0xff;
        p[16] = 0xff;
        /* Medium rotation rate [rpm], 5400 rpm */
        p[20] = (5400 >> 8) & 0xff;
        p[21] = 5400 & 0xff;
844
        break;
845

846
    case MODE_PAGE_FLEXIBLE_DISK_GEOMETRY:
847
        p[1] = 0x1e;
848
        if (page_control == 1) { /* Changeable Values */
849
            break;
850
        }
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
        /* Transfer rate [kbit/s], 5Mbit/s */
        p[2] = 5000 >> 8;
        p[3] = 5000 & 0xff;
        /* if a geometry hint is available, use it */
        bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
        p[4] = heads & 0xff;
        p[5] = secs & 0xff;
        p[6] = s->cluster_size * 2;
        p[8] = (cylinders >> 8) & 0xff;
        p[9] = cylinders & 0xff;
        /* Write precomp start cylinder, disabled */
        p[10] = (cylinders >> 8) & 0xff;
        p[11] = cylinders & 0xff;
        /* Reduced current start cylinder, disabled */
        p[12] = (cylinders >> 8) & 0xff;
        p[13] = cylinders & 0xff;
        /* Device step rate [100us], 100us */
        p[14] = 0;
        p[15] = 1;
        /* Device step pulse width [us], 1us */
        p[16] = 1;
        /* Device head settle delay [100us], 100us */
        p[17] = 0;
        p[18] = 1;
        /* Motor on delay [0.1s], 0.1s */
        p[19] = 1;
        /* Motor off delay [0.1s], 0.1s */
        p[20] = 1;
        /* Medium rotation rate [rpm], 5400 rpm */
        p[28] = (5400 >> 8) & 0xff;
        p[29] = 5400 & 0xff;
882
        break;
883

884
    case MODE_PAGE_CACHING:
885 886
        p[0] = 8;
        p[1] = 0x12;
887
        if (page_control == 1) { /* Changeable Values */
888
            break;
889
        }
890
        if (bdrv_enable_write_cache(s->bs)) {
891 892
            p[2] = 4; /* WCE */
        }
893
        break;
894

895 896 897 898 899 900 901 902 903 904 905 906
    case MODE_PAGE_R_W_ERROR:
        p[1] = 10;
        p[2] = 0x80; /* Automatic Write Reallocation Enabled */
        if (s->qdev.type == TYPE_ROM) {
            p[3] = 0x20; /* Read Retry Count */
        }
        break;

    case MODE_PAGE_AUDIO_CTL:
        p[1] = 14;
        break;

907
    case MODE_PAGE_CAPABILITIES:
908
        p[1] = 0x14;
909
        if (page_control == 1) { /* Changeable Values */
910
            break;
911
        }
912 913 914

        p[2] = 0x3b; /* CD-R & CD-RW read */
        p[3] = 0; /* Writing not supported */
915 916 917 918 919
        p[4] = 0x7f; /* Audio, composite, digital out,
                        mode 2 form 1&2, multi session */
        p[5] = 0xff; /* CD DA, DA accurate, RW supported,
                        RW corrected, C2 errors, ISRC,
                        UPC, Bar code */
920
        p[6] = 0x2d | (s->tray_locked ? 2 : 0);
921 922 923
        /* Locking supported, jumper present, eject, tray */
        p[7] = 0; /* no volume & mute control, no
                     changer */
924
        p[8] = (50 * 176) >> 8; /* 50x read speed */
925
        p[9] = (50 * 176) & 0xff;
926 927 928
        p[10] = 2 >> 8; /* Two volume levels */
        p[11] = 2 & 0xff;
        p[12] = 2048 >> 8; /* 2M buffer */
929
        p[13] = 2048 & 0xff;
930
        p[14] = (16 * 176) >> 8; /* 16x read speed current */
931
        p[15] = (16 * 176) & 0xff;
932
        p[18] = (16 * 176) >> 8; /* 16x write speed */
933
        p[19] = (16 * 176) & 0xff;
934
        p[20] = (16 * 176) >> 8; /* 16x write speed current */
935
        p[21] = (16 * 176) & 0xff;
936
        break;
937 938

    default:
939
        return -1;
940
    }
941 942 943

    *p_outbuf += p[1] + 2;
    return p[1] + 2;
944 945
}

946
static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
947
{
948
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
949
    uint64_t nb_sectors;
950
    int page, dbd, buflen, ret, page_control;
951
    uint8_t *p;
952
    uint8_t dev_specific_param;
953

954 955 956
    dbd = r->req.cmd.buf[1]  & 0x8;
    page = r->req.cmd.buf[2] & 0x3f;
    page_control = (r->req.cmd.buf[2] & 0xc0) >> 6;
957
    DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
958 959
        (r->req.cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, r->req.cmd.xfer, page_control);
    memset(outbuf, 0, r->req.cmd.xfer);
960 961
    p = outbuf;

962
    if (bdrv_is_read_only(s->bs)) {
963 964 965 966 967
        dev_specific_param = 0x80; /* Readonly.  */
    } else {
        dev_specific_param = 0x00;
    }

968
    if (r->req.cmd.buf[0] == MODE_SENSE) {
969 970 971 972 973 974 975 976 977
        p[1] = 0; /* Default media type.  */
        p[2] = dev_specific_param;
        p[3] = 0; /* Block descriptor length.  */
        p += 4;
    } else { /* MODE_SENSE_10 */
        p[2] = 0; /* Default media type.  */
        p[3] = dev_specific_param;
        p[6] = p[7] = 0; /* Block descriptor length.  */
        p += 8;
978 979
    }

980
    bdrv_get_geometry(s->bs, &nb_sectors);
981
    if (!dbd && nb_sectors) {
982
        if (r->req.cmd.buf[0] == MODE_SENSE) {
983 984 985 986
            outbuf[3] = 8; /* Block descriptor length  */
        } else { /* MODE_SENSE_10 */
            outbuf[7] = 8; /* Block descriptor length  */
        }
987
        nb_sectors /= s->cluster_size;
988
        if (nb_sectors > 0xffffff) {
989
            nb_sectors = 0;
990
        }
991 992 993 994 995 996 997 998 999 1000 1001
        p[0] = 0; /* media density code */
        p[1] = (nb_sectors >> 16) & 0xff;
        p[2] = (nb_sectors >> 8) & 0xff;
        p[3] = nb_sectors & 0xff;
        p[4] = 0; /* reserved */
        p[5] = 0; /* bytes 5-7 are the sector size in bytes */
        p[6] = s->cluster_size * 2;
        p[7] = 0;
        p += 8;
    }

1002 1003 1004 1005
    if (page_control == 3) {
        /* Saved Values */
        scsi_check_condition(r, SENSE_CODE(SAVING_PARAMS_NOT_SUPPORTED));
        return -1;
1006 1007
    }

1008 1009 1010 1011 1012 1013 1014 1015 1016
    if (page == 0x3f) {
        for (page = 0; page <= 0x3e; page++) {
            mode_sense_page(s, page, &p, page_control);
        }
    } else {
        ret = mode_sense_page(s, page, &p, page_control);
        if (ret == -1) {
            return -1;
        }
1017 1018 1019
    }

    buflen = p - outbuf;
1020 1021 1022 1023 1024
    /*
     * The mode data length field specifies the length in bytes of the
     * following data that is available to be transferred. The mode data
     * length does not include itself.
     */
1025
    if (r->req.cmd.buf[0] == MODE_SENSE) {
1026 1027 1028 1029 1030
        outbuf[0] = buflen - 1;
    } else { /* MODE_SENSE_10 */
        outbuf[0] = ((buflen - 2) >> 8) & 0xff;
        outbuf[1] = (buflen - 2) & 0xff;
    }
1031
    if (buflen > r->req.cmd.xfer) {
1032
        buflen = r->req.cmd.xfer;
1033
    }
1034 1035 1036
    return buflen;
}

1037 1038 1039 1040 1041 1042 1043 1044 1045
static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
{
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
    int start_track, format, msf, toclen;
    uint64_t nb_sectors;

    msf = req->cmd.buf[1] & 2;
    format = req->cmd.buf[2] & 0xf;
    start_track = req->cmd.buf[6];
1046
    bdrv_get_geometry(s->bs, &nb_sectors);
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
    DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
    nb_sectors /= s->cluster_size;
    switch (format) {
    case 0:
        toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
        break;
    case 1:
        /* multi session : only a single session defined */
        toclen = 12;
        memset(outbuf, 0, 12);
        outbuf[1] = 0x0a;
        outbuf[2] = 0x01;
        outbuf[3] = 0x01;
        break;
    case 2:
        toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
        break;
    default:
        return -1;
    }
1067
    if (toclen > req->cmd.xfer) {
1068
        toclen = req->cmd.xfer;
1069
    }
1070 1071 1072
    return toclen;
}

1073
static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
1074 1075 1076 1077 1078 1079 1080
{
    SCSIRequest *req = &r->req;
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
    bool start = req->cmd.buf[4] & 1;
    bool loej = req->cmd.buf[4] & 2; /* load on start, eject on !start */

    if (s->qdev.type == TYPE_ROM && loej) {
1081 1082 1083 1084 1085 1086
        if (!start && !s->tray_open && s->tray_locked) {
            scsi_check_condition(r,
                                 bdrv_is_inserted(s->bs)
                                 ? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED)
                                 : SENSE_CODE(NOT_READY_REMOVAL_PREVENTED));
            return -1;
1087
        }
1088
        bdrv_eject(s->bs, !start);
1089
        s->tray_open = !start;
1090
    }
1091
    return 0;
1092 1093
}

1094
static int scsi_disk_emulate_command(SCSIDiskReq *r)
1095
{
1096
    SCSIRequest *req = &r->req;
1097 1098
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
    uint64_t nb_sectors;
1099
    uint8_t *outbuf;
1100 1101
    int buflen = 0;

1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
    if (!r->iov.iov_base) {
        /*
         * FIXME: we shouldn't return anything bigger than 4k, but the code
         * requires the buffer to be as big as req->cmd.xfer in several
         * places.  So, do not allow CDBs with a very large ALLOCATION
         * LENGTH.  The real fix would be to modify scsi_read_data and
         * dma_buf_read, so that they return data beyond the buflen
         * as all zeros.
         */
        if (req->cmd.xfer > 65536) {
            goto illegal_request;
        }
        r->buflen = MAX(4096, req->cmd.xfer);
        r->iov.iov_base = qemu_blockalign(s->bs, r->buflen);
    }

    outbuf = r->iov.iov_base;
1119 1120
    switch (req->cmd.buf[0]) {
    case TEST_UNIT_READY:
1121
        if (s->tray_open || !bdrv_is_inserted(s->bs)) {
1122
            goto not_ready;
1123
        }
H
Hannes Reinecke 已提交
1124
        break;
1125 1126
    case INQUIRY:
        buflen = scsi_disk_emulate_inquiry(req, outbuf);
1127
        if (buflen < 0) {
1128
            goto illegal_request;
1129
        }
H
Hannes Reinecke 已提交
1130
        break;
1131 1132
    case MODE_SENSE:
    case MODE_SENSE_10:
1133
        buflen = scsi_disk_emulate_mode_sense(r, outbuf);
1134
        if (buflen < 0) {
1135
            goto illegal_request;
1136
        }
1137
        break;
1138 1139
    case READ_TOC:
        buflen = scsi_disk_emulate_read_toc(req, outbuf);
1140
        if (buflen < 0) {
1141
            goto illegal_request;
1142
        }
1143
        break;
1144
    case RESERVE:
1145
        if (req->cmd.buf[1] & 1) {
1146
            goto illegal_request;
1147
        }
1148 1149
        break;
    case RESERVE_10:
1150
        if (req->cmd.buf[1] & 3) {
1151
            goto illegal_request;
1152
        }
1153 1154
        break;
    case RELEASE:
1155
        if (req->cmd.buf[1] & 1) {
1156
            goto illegal_request;
1157
        }
1158 1159
        break;
    case RELEASE_10:
1160
        if (req->cmd.buf[1] & 3) {
1161
            goto illegal_request;
1162
        }
1163
        break;
1164
    case START_STOP:
1165 1166 1167
        if (scsi_disk_emulate_start_stop(r) < 0) {
            return -1;
        }
H
Hannes Reinecke 已提交
1168
        break;
1169
    case ALLOW_MEDIUM_REMOVAL:
1170
        s->tray_locked = req->cmd.buf[4] & 1;
1171
        bdrv_lock_medium(s->bs, req->cmd.buf[4] & 1);
H
Hannes Reinecke 已提交
1172
        break;
1173
    case READ_CAPACITY_10:
1174
        /* The normal LEN field for this command is zero.  */
H
Hannes Reinecke 已提交
1175 1176
        memset(outbuf, 0, 8);
        bdrv_get_geometry(s->bs, &nb_sectors);
1177
        if (!nb_sectors) {
1178
            goto not_ready;
1179
        }
1180 1181 1182
        if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
            goto illegal_request;
        }
1183 1184 1185 1186 1187 1188
        nb_sectors /= s->cluster_size;
        /* Returned value is the address of the last sector.  */
        nb_sectors--;
        /* Remember the new size for read/write sanity checking. */
        s->max_lba = nb_sectors;
        /* Clip to 2TB, instead of returning capacity modulo 2TB. */
1189
        if (nb_sectors > UINT32_MAX) {
1190
            nb_sectors = UINT32_MAX;
1191
        }
1192 1193 1194 1195 1196 1197 1198 1199 1200
        outbuf[0] = (nb_sectors >> 24) & 0xff;
        outbuf[1] = (nb_sectors >> 16) & 0xff;
        outbuf[2] = (nb_sectors >> 8) & 0xff;
        outbuf[3] = nb_sectors & 0xff;
        outbuf[4] = 0;
        outbuf[5] = 0;
        outbuf[6] = s->cluster_size * 2;
        outbuf[7] = 0;
        buflen = 8;
H
Hannes Reinecke 已提交
1201
        break;
1202 1203 1204 1205 1206 1207
    case MECHANISM_STATUS:
        buflen = scsi_emulate_mechanism_status(s, outbuf);
        if (buflen < 0) {
            goto illegal_request;
        }
        break;
1208
    case GET_CONFIGURATION:
1209
        buflen = scsi_get_configuration(s, outbuf);
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
        if (buflen < 0) {
            goto illegal_request;
        }
        break;
    case GET_EVENT_STATUS_NOTIFICATION:
        buflen = scsi_get_event_status_notification(s, r, outbuf);
        if (buflen < 0) {
            goto illegal_request;
        }
        break;
    case READ_DVD_STRUCTURE:
        buflen = scsi_read_dvd_structure(s, r, outbuf);
        if (buflen < 0) {
            goto illegal_request;
        }
1225
        break;
1226
    case SERVICE_ACTION_IN_16:
1227
        /* Service Action In subcommands. */
1228
        if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
1229 1230
            DPRINTF("SAI READ CAPACITY(16)\n");
            memset(outbuf, 0, req->cmd.xfer);
1231
            bdrv_get_geometry(s->bs, &nb_sectors);
1232
            if (!nb_sectors) {
1233
                goto not_ready;
1234
            }
1235 1236 1237
            if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
                goto illegal_request;
            }
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
            nb_sectors /= s->cluster_size;
            /* Returned value is the address of the last sector.  */
            nb_sectors--;
            /* Remember the new size for read/write sanity checking. */
            s->max_lba = nb_sectors;
            outbuf[0] = (nb_sectors >> 56) & 0xff;
            outbuf[1] = (nb_sectors >> 48) & 0xff;
            outbuf[2] = (nb_sectors >> 40) & 0xff;
            outbuf[3] = (nb_sectors >> 32) & 0xff;
            outbuf[4] = (nb_sectors >> 24) & 0xff;
            outbuf[5] = (nb_sectors >> 16) & 0xff;
            outbuf[6] = (nb_sectors >> 8) & 0xff;
            outbuf[7] = nb_sectors & 0xff;
            outbuf[8] = 0;
            outbuf[9] = 0;
            outbuf[10] = s->cluster_size * 2;
            outbuf[11] = 0;
C
Christoph Hellwig 已提交
1255 1256
            outbuf[12] = 0;
            outbuf[13] = get_physical_block_exp(&s->qdev.conf);
1257 1258 1259 1260 1261 1262

            /* set TPE bit if the format supports discard */
            if (s->qdev.conf.discard_granularity) {
                outbuf[14] = 0x80;
            }

1263 1264 1265 1266 1267 1268
            /* Protection, exponent and lowest lba field left blank. */
            buflen = req->cmd.xfer;
            break;
        }
        DPRINTF("Unsupported Service Action In\n");
        goto illegal_request;
1269
    case VERIFY_10:
1270
        break;
1271
    default:
1272
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1273
        return -1;
1274 1275 1276 1277
    }
    return buflen;

not_ready:
1278
    if (s->tray_open || !bdrv_is_inserted(s->bs)) {
1279
        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
1280
    } else {
1281
        scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
1282
    }
1283
    return -1;
1284 1285

illegal_request:
1286 1287 1288
    if (r->req.status == -1) {
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
    }
1289
    return -1;
1290 1291
}

P
pbrook 已提交
1292 1293 1294 1295 1296
/* 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.  */

1297
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
P
pbrook 已提交
1298
{
1299 1300
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
P
Paolo Bonzini 已提交
1301
    int32_t len;
P
pbrook 已提交
1302
    uint8_t command;
1303
    int rc;
P
pbrook 已提交
1304 1305

    command = buf[0];
1306
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
1307

P
pbrook 已提交
1308 1309 1310
#ifdef DEBUG_SCSI
    {
        int i;
1311
        for (i = 1; i < r->req.cmd.len; i++) {
P
pbrook 已提交
1312 1313 1314 1315 1316
            printf(" 0x%02x", buf[i]);
        }
        printf("\n");
    }
#endif
1317

P
pbrook 已提交
1318
    switch (command) {
1319
    case TEST_UNIT_READY:
1320
    case INQUIRY:
1321 1322
    case MODE_SENSE:
    case MODE_SENSE_10:
1323 1324 1325 1326
    case RESERVE:
    case RESERVE_10:
    case RELEASE:
    case RELEASE_10:
1327
    case START_STOP:
1328
    case ALLOW_MEDIUM_REMOVAL:
1329
    case READ_CAPACITY_10:
1330
    case READ_TOC:
1331
    case READ_DVD_STRUCTURE:
1332
    case GET_CONFIGURATION:
1333 1334
    case GET_EVENT_STATUS_NOTIFICATION:
    case MECHANISM_STATUS:
1335
    case SERVICE_ACTION_IN_16:
1336
    case VERIFY_10:
1337
        rc = scsi_disk_emulate_command(r);
1338
        if (rc < 0) {
1339
            return 0;
1340
        }
1341 1342

        r->iov.iov_len = rc;
1343
        break;
1344 1345 1346 1347 1348 1349 1350
    case SYNCHRONIZE_CACHE:
        bdrv_acct_start(s->bs, &r->acct, 0, BDRV_ACCT_FLUSH);
        r->req.aiocb = bdrv_aio_flush(s->bs, scsi_flush_complete, r);
        if (r->req.aiocb == NULL) {
            scsi_flush_complete(r, -EIO);
        }
        return 0;
1351 1352
    case READ_6:
    case READ_10:
G
Gerd Hoffmann 已提交
1353 1354
    case READ_12:
    case READ_16:
1355
        len = r->req.cmd.xfer / s->qdev.blocksize;
1356
        DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
1357
        if (r->req.cmd.lba > s->max_lba) {
1358
            goto illegal_lba;
1359
        }
1360
        r->sector = r->req.cmd.lba * s->cluster_size;
P
pbrook 已提交
1361
        r->sector_count = len * s->cluster_size;
P
pbrook 已提交
1362
        break;
1363 1364
    case WRITE_6:
    case WRITE_10:
G
Gerd Hoffmann 已提交
1365 1366
    case WRITE_12:
    case WRITE_16:
1367
    case WRITE_VERIFY_10:
1368 1369
    case WRITE_VERIFY_12:
    case WRITE_VERIFY_16:
1370
        len = r->req.cmd.xfer / s->qdev.blocksize;
1371
        DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
1372 1373
                (command & 0xe) == 0xe ? "And Verify " : "",
                r->req.cmd.lba, len);
1374
        if (r->req.cmd.lba > s->max_lba) {
1375
            goto illegal_lba;
1376
        }
1377
        r->sector = r->req.cmd.lba * s->cluster_size;
P
pbrook 已提交
1378
        r->sector_count = len * s->cluster_size;
P
pbrook 已提交
1379
        break;
1380
    case MODE_SELECT:
1381
        DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
1382 1383
        /* We don't support mode parameter changes.
           Allow the mode parameter header + block descriptors only. */
1384
        if (r->req.cmd.xfer > 12) {
1385 1386 1387 1388
            goto fail;
        }
        break;
    case MODE_SELECT_10:
1389
        DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
1390 1391
        /* We don't support mode parameter changes.
           Allow the mode parameter header + block descriptors only. */
1392
        if (r->req.cmd.xfer > 16) {
1393 1394 1395 1396 1397
            goto fail;
        }
        break;
    case SEEK_6:
    case SEEK_10:
1398 1399 1400
        DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
                r->req.cmd.lba);
        if (r->req.cmd.lba > s->max_lba) {
1401 1402
            goto illegal_lba;
        }
1403 1404
        break;
    case WRITE_SAME_16:
1405
        len = r->req.cmd.xfer / s->qdev.blocksize;
1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427

        DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n",
                r->req.cmd.lba, len);

        if (r->req.cmd.lba > s->max_lba) {
            goto illegal_lba;
        }

        /*
         * We only support WRITE SAME with the unmap bit set for now.
         */
        if (!(buf[1] & 0x8)) {
            goto fail;
        }

        rc = bdrv_discard(s->bs, r->req.cmd.lba * s->cluster_size,
                          len * s->cluster_size);
        if (rc < 0) {
            /* XXX: better error code ?*/
            goto fail;
        }

1428
        break;
1429 1430
    case REQUEST_SENSE:
        abort();
P
pbrook 已提交
1431
    default:
1432
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1433
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1434
        return 0;
P
pbrook 已提交
1435
    fail:
1436
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1437
        return 0;
1438
    illegal_lba:
1439
        scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
1440
        return 0;
P
pbrook 已提交
1441
    }
1442
    if (r->sector_count == 0 && r->iov.iov_len == 0) {
1443
        scsi_req_complete(&r->req, GOOD);
P
pbrook 已提交
1444
    }
1445
    len = r->sector_count * 512 + r->iov.iov_len;
1446 1447
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        return -len;
P
pbrook 已提交
1448
    } else {
1449
        if (!r->sector_count) {
P
pbrook 已提交
1450
            r->sector_count = -1;
1451
        }
1452
        return len;
P
pbrook 已提交
1453 1454 1455
    }
}

J
Jan Kiszka 已提交
1456 1457 1458 1459 1460
static void scsi_disk_reset(DeviceState *dev)
{
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
    uint64_t nb_sectors;

1461
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
J
Jan Kiszka 已提交
1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474

    bdrv_get_geometry(s->bs, &nb_sectors);
    nb_sectors /= s->cluster_size;
    if (nb_sectors) {
        nb_sectors--;
    }
    s->max_lba = nb_sectors;
}

static void scsi_destroy(SCSIDevice *dev)
{
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);

1475
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
1476
    blockdev_mark_auto_del(s->qdev.conf.bs);
G
Gerd Hoffmann 已提交
1477 1478
}

1479
static void scsi_cd_change_media_cb(void *opaque, bool load)
1480
{
1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495
    SCSIDiskState *s = opaque;

    /*
     * When a CD gets changed, we have to report an ejected state and
     * then a loaded state to guests so that they detect tray
     * open/close and media change events.  Guests that do not use
     * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
     * states rely on this behavior.
     *
     * media_changed governs the state machine used for unit attention
     * report.  media_event is used by GET EVENT STATUS NOTIFICATION.
     */
    s->media_changed = load;
    s->tray_open = !load;
    s->qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM);
1496
    s->media_event = true;
1497 1498
}

1499 1500 1501 1502 1503
static bool scsi_cd_is_tray_open(void *opaque)
{
    return ((SCSIDiskState *)opaque)->tray_open;
}

1504 1505 1506 1507 1508 1509
static bool scsi_cd_is_medium_locked(void *opaque)
{
    return ((SCSIDiskState *)opaque)->tray_locked;
}

static const BlockDevOps scsi_cd_block_ops = {
1510
    .change_media_cb = scsi_cd_change_media_cb,
1511
    .is_tray_open = scsi_cd_is_tray_open,
1512 1513 1514
    .is_medium_locked = scsi_cd_is_medium_locked,
};

1515 1516 1517 1518 1519 1520 1521 1522 1523
static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
{
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
    if (s->media_changed) {
        s->media_changed = false;
        s->qdev.unit_attention = SENSE_CODE(MEDIUM_CHANGED);
    }
}

H
Hannes Reinecke 已提交
1524
static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
P
pbrook 已提交
1525
{
1526
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1527
    DriveInfo *dinfo;
P
pbrook 已提交
1528

1529
    if (!s->qdev.conf.bs) {
1530
        error_report("scsi-disk: drive property not set");
1531 1532
        return -1;
    }
1533
    s->bs = s->qdev.conf.bs;
1534

H
Hannes Reinecke 已提交
1535
    if (scsi_type == TYPE_DISK && !bdrv_is_inserted(s->bs)) {
1536 1537 1538 1539
        error_report("Device needs media, but drive is empty");
        return -1;
    }

1540
    if (!s->serial) {
1541 1542
        /* try to fall back to value set with legacy -drive serial=... */
        dinfo = drive_get_by_blockdev(s->bs);
1543
        if (*dinfo->serial) {
1544
            s->serial = g_strdup(dinfo->serial);
1545
        }
1546 1547
    }

1548
    if (!s->version) {
1549
        s->version = g_strdup(QEMU_VERSION);
1550 1551
    }

1552
    if (bdrv_is_sg(s->bs)) {
1553
        error_report("scsi-disk: unwanted /dev/sg*");
1554 1555 1556
        return -1;
    }

H
Hannes Reinecke 已提交
1557
    if (scsi_type == TYPE_ROM) {
1558
        bdrv_set_dev_ops(s->bs, &scsi_cd_block_ops, s);
1559
        s->qdev.blocksize = 2048;
H
Hannes Reinecke 已提交
1560
    } else if (scsi_type == TYPE_DISK) {
1561
        s->qdev.blocksize = s->qdev.conf.logical_block_size;
H
Hannes Reinecke 已提交
1562 1563 1564
    } else {
        error_report("scsi-disk: Unhandled SCSI type %02x", scsi_type);
        return -1;
P
pbrook 已提交
1565
    }
1566
    s->cluster_size = s->qdev.blocksize / 512;
1567
    bdrv_set_buffer_alignment(s->bs, s->qdev.blocksize);
1568

H
Hannes Reinecke 已提交
1569
    s->qdev.type = scsi_type;
1570
    qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
L
Luiz Capitulino 已提交
1571
    bdrv_iostatus_enable(s->bs);
1572
    add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
1573 1574 1575
    return 0;
}

1576 1577
static int scsi_hd_initfn(SCSIDevice *dev)
{
H
Hannes Reinecke 已提交
1578
    return scsi_initfn(dev, TYPE_DISK);
1579 1580 1581 1582
}

static int scsi_cd_initfn(SCSIDevice *dev)
{
H
Hannes Reinecke 已提交
1583
    return scsi_initfn(dev, TYPE_ROM);
1584 1585 1586 1587
}

static int scsi_disk_initfn(SCSIDevice *dev)
{
1588
    DriveInfo *dinfo;
H
Hannes Reinecke 已提交
1589
    uint8_t scsi_type;
1590 1591

    if (!dev->conf.bs) {
H
Hannes Reinecke 已提交
1592
        scsi_type = TYPE_DISK;  /* will die in scsi_initfn() */
1593
    } else {
1594
        dinfo = drive_get_by_blockdev(dev->conf.bs);
H
Hannes Reinecke 已提交
1595
        scsi_type = dinfo->media_cd ? TYPE_ROM : TYPE_DISK;
1596 1597
    }

H
Hannes Reinecke 已提交
1598
    return scsi_initfn(dev, scsi_type);
1599 1600
}

P
Paolo Bonzini 已提交
1601 1602
static SCSIReqOps scsi_disk_reqops = {
    .size         = sizeof(SCSIDiskReq),
1603 1604 1605 1606 1607 1608
    .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,
P
Paolo Bonzini 已提交
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620
};

static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
                                     uint32_t lun, void *hba_private)
{
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
    SCSIRequest *req;

    req = scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, hba_private);
    return req;
}

1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634
#define DEFINE_SCSI_DISK_PROPERTIES()                           \
    DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),          \
    DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
    DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)

static SCSIDeviceInfo scsi_disk_info[] = {
    {
        .qdev.name    = "scsi-hd",
        .qdev.fw_name = "disk",
        .qdev.desc    = "virtual SCSI disk",
        .qdev.size    = sizeof(SCSIDiskState),
        .qdev.reset   = scsi_disk_reset,
        .init         = scsi_hd_initfn,
        .destroy      = scsi_destroy,
1635
        .alloc_req    = scsi_new_request,
1636
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
        .qdev.props   = (Property[]) {
            DEFINE_SCSI_DISK_PROPERTIES(),
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
            DEFINE_PROP_END_OF_LIST(),
        }
    },{
        .qdev.name    = "scsi-cd",
        .qdev.fw_name = "disk",
        .qdev.desc    = "virtual SCSI CD-ROM",
        .qdev.size    = sizeof(SCSIDiskState),
        .qdev.reset   = scsi_disk_reset,
        .init         = scsi_cd_initfn,
        .destroy      = scsi_destroy,
1650
        .alloc_req    = scsi_new_request,
1651
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663
        .qdev.props   = (Property[]) {
            DEFINE_SCSI_DISK_PROPERTIES(),
            DEFINE_PROP_END_OF_LIST(),
        },
    },{
        .qdev.name    = "scsi-disk", /* legacy -device scsi-disk */
        .qdev.fw_name = "disk",
        .qdev.desc    = "virtual SCSI disk or CD-ROM (legacy)",
        .qdev.size    = sizeof(SCSIDiskState),
        .qdev.reset   = scsi_disk_reset,
        .init         = scsi_disk_initfn,
        .destroy      = scsi_destroy,
1664
        .alloc_req    = scsi_new_request,
1665
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1666 1667 1668 1669 1670 1671
        .qdev.props   = (Property[]) {
            DEFINE_SCSI_DISK_PROPERTIES(),
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
            DEFINE_PROP_END_OF_LIST(),
        }
    }
1672 1673 1674 1675
};

static void scsi_disk_register_devices(void)
{
1676 1677 1678 1679 1680
    int i;

    for (i = 0; i < ARRAY_SIZE(scsi_disk_info); i++) {
        scsi_qdev_register(&scsi_disk_info[i]);
    }
T
ths 已提交
1681
}
1682
device_init(scsi_disk_register_devices)