scsi-disk.c 48.4 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
    QEMUBH *bh;
G
Gerd Hoffmann 已提交
76
    char *version;
77
    char *serial;
78
    bool tray_open;
79
    bool tray_locked;
P
pbrook 已提交
80 81
};

K
Kevin Wolf 已提交
82
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
83
static int scsi_disk_emulate_command(SCSIDiskReq *r);
K
Kevin Wolf 已提交
84

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

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

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

/* Cancel a pending data transfer.  */
104
static void scsi_cancel_io(SCSIRequest *req)
P
pbrook 已提交
105
{
106 107 108 109 110
    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 已提交
111
    }
112
    r->req.aiocb = NULL;
P
pbrook 已提交
113 114
}

115 116
static uint32_t scsi_init_iovec(SCSIDiskReq *r)
{
117 118 119 120 121 122 123
    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);
124 125 126 127
    qemu_iovec_init_external(&r->qiov, &r->iov, 1);
    return r->qiov.size / 512;
}

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

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

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

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

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

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
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 已提交
171

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

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

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

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

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

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

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

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

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

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

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

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

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

270
    n = r->qiov.size / 512;
271 272
    r->sector += n;
    r->sector_count -= n;
P
pbrook 已提交
273
    if (r->sector_count == 0) {
274
        scsi_req_complete(&r->req, GOOD);
P
pbrook 已提交
275
    } else {
276 277 278
        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 已提交
279 280 281
    }
}

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

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

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

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

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

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

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

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:
340
                ret = scsi_disk_emulate_command(r);
341
                if (ret == 0) {
342
                    scsi_req_complete(&r->req, GOOD);
343
                }
K
Kevin Wolf 已提交
344
            }
345 346 347 348
        }
    }
}

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

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

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

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

370 371
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
{
G
Gerd Hoffmann 已提交
372
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
    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 已提交
390
        if (s->qdev.type == TYPE_ROM) {
391 392 393 394 395 396 397 398 399
            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 已提交
400 401
        {
            int pages;
402 403
            DPRINTF("Inquiry EVPD[Supported pages] "
                    "buffer size %zd\n", req->cmd.xfer);
H
Hannes Reinecke 已提交
404
            pages = buflen++;
405
            outbuf[buflen++] = 0x00; // list of supported pages (this page)
406
            if (s->serial) {
407
                outbuf[buflen++] = 0x80; // unit serial number
408
            }
409
            outbuf[buflen++] = 0x83; // device identification
H
Hannes Reinecke 已提交
410
            if (s->qdev.type == TYPE_DISK) {
411 412
                outbuf[buflen++] = 0xb0; // block limits
                outbuf[buflen++] = 0xb2; // thin provisioning
H
Hannes Reinecke 已提交
413 414
            }
            outbuf[pages] = buflen - pages - 1; // number of pages
415
            break;
H
Hannes Reinecke 已提交
416
        }
417 418
        case 0x80: /* Device serial number, optional */
        {
419
            int l;
420

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

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

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

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

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

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

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

H
Hannes Reinecke 已提交
472
            if (s->qdev.type == TYPE_ROM) {
H
Hannes Reinecke 已提交
473 474 475 476
                DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
                        page_code);
                return -1;
            }
C
Christoph Hellwig 已提交
477 478 479 480 481 482 483 484 485 486 487 488 489 490
            /* 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;
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505

            /* 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 已提交
506 507
            break;
        }
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
        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;
532
    if (buflen > SCSI_MAX_INQUIRY_LEN) {
533
        buflen = SCSI_MAX_INQUIRY_LEN;
534
    }
535 536
    memset(outbuf, 0, buflen);

H
Hannes Reinecke 已提交
537 538
    outbuf[0] = s->qdev.type & 0x1f;
    if (s->qdev.type == TYPE_ROM) {
539
        outbuf[1] = 0x80;
L
Laszlo Ast 已提交
540
        memcpy(&outbuf[16], "QEMU CD-ROM     ", 16);
541
    } else {
542
        outbuf[1] = s->removable ? 0x80 : 0;
L
Laszlo Ast 已提交
543
        memcpy(&outbuf[16], "QEMU HARDDISK   ", 16);
544
    }
L
Laszlo Ast 已提交
545
    memcpy(&outbuf[8], "QEMU    ", 8);
G
Gerd Hoffmann 已提交
546
    memset(&outbuf[32], 0, 4);
547
    memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
548 549 550 551 552 553
    /*
     * 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 已提交
554
    outbuf[2] = 5;
555
    outbuf[3] = 2; /* Format 2 */
556 557 558 559 560 561 562 563 564

    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;
    }

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

570 571 572 573 574 575 576 577 578 579 580 581 582
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;
}

583 584 585 586 587 588 589 590 591 592 593 594 595
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;
}

596 597 598
static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
                                   uint8_t *outbuf)
{
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 685 686
    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:
687 688 689 690 691 692 693 694 695 696
    return -1;
}

static int scsi_get_event_status_notification(SCSIDiskState *s,
                                              SCSIDiskReq *r, uint8_t *outbuf)
{
    scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
    return -1;
}

697
static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
698
{
699 700
    int current;

701 702 703
    if (s->qdev.type != TYPE_ROM) {
        return -1;
    }
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
    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;
729 730 731 732 733 734 735 736 737 738 739 740
}

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;
}

741
static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
742
                           int page_control)
743
{
744 745 746 747
    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),
748 749
        [MODE_PAGE_R_W_ERROR]              = (1 << TYPE_DISK) | (1 << TYPE_ROM),
        [MODE_PAGE_AUDIO_CTL]              = (1 << TYPE_ROM),
750 751 752
        [MODE_PAGE_CAPABILITIES]           = (1 << TYPE_ROM),
    };

753
    BlockDriverState *bdrv = s->bs;
754
    int cylinders, heads, secs;
755
    uint8_t *p = *p_outbuf;
756

757 758 759 760 761 762
    if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) {
        return -1;
    }

    p[0] = page;

763 764 765 766 767 768
    /*
     * 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.
     */
769
    switch (page) {
770
    case MODE_PAGE_HD_GEOMETRY:
771
        p[1] = 0x16;
772
        if (page_control == 1) { /* Changeable Values */
773
            break;
774
        }
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
        /* 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;
799
        break;
800

801
    case MODE_PAGE_FLEXIBLE_DISK_GEOMETRY:
802
        p[1] = 0x1e;
803
        if (page_control == 1) { /* Changeable Values */
804
            break;
805
        }
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
        /* 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;
837
        break;
838

839
    case MODE_PAGE_CACHING:
840 841
        p[0] = 8;
        p[1] = 0x12;
842
        if (page_control == 1) { /* Changeable Values */
843
            break;
844
        }
845
        if (bdrv_enable_write_cache(s->bs)) {
846 847
            p[2] = 4; /* WCE */
        }
848
        break;
849

850 851 852 853 854 855 856 857 858 859 860 861
    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;

862
    case MODE_PAGE_CAPABILITIES:
863
        p[1] = 0x14;
864
        if (page_control == 1) { /* Changeable Values */
865
            break;
866
        }
867 868 869

        p[2] = 0x3b; /* CD-R & CD-RW read */
        p[3] = 0; /* Writing not supported */
870 871 872 873 874
        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 */
875
        p[6] = 0x2d | (s->tray_locked ? 2 : 0);
876 877 878
        /* Locking supported, jumper present, eject, tray */
        p[7] = 0; /* no volume & mute control, no
                     changer */
879
        p[8] = (50 * 176) >> 8; /* 50x read speed */
880
        p[9] = (50 * 176) & 0xff;
881 882 883
        p[10] = 2 >> 8; /* Two volume levels */
        p[11] = 2 & 0xff;
        p[12] = 2048 >> 8; /* 2M buffer */
884
        p[13] = 2048 & 0xff;
885
        p[14] = (16 * 176) >> 8; /* 16x read speed current */
886
        p[15] = (16 * 176) & 0xff;
887
        p[18] = (16 * 176) >> 8; /* 16x write speed */
888
        p[19] = (16 * 176) & 0xff;
889
        p[20] = (16 * 176) >> 8; /* 16x write speed current */
890
        p[21] = (16 * 176) & 0xff;
891
        break;
892 893

    default:
894
        return -1;
895
    }
896 897 898

    *p_outbuf += p[1] + 2;
    return p[1] + 2;
899 900
}

901
static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
902
{
903
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
904
    uint64_t nb_sectors;
905
    int page, dbd, buflen, ret, page_control;
906
    uint8_t *p;
907
    uint8_t dev_specific_param;
908

909 910 911
    dbd = r->req.cmd.buf[1]  & 0x8;
    page = r->req.cmd.buf[2] & 0x3f;
    page_control = (r->req.cmd.buf[2] & 0xc0) >> 6;
912
    DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
913 914
        (r->req.cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, r->req.cmd.xfer, page_control);
    memset(outbuf, 0, r->req.cmd.xfer);
915 916
    p = outbuf;

917
    if (bdrv_is_read_only(s->bs)) {
918 919 920 921 922
        dev_specific_param = 0x80; /* Readonly.  */
    } else {
        dev_specific_param = 0x00;
    }

923
    if (r->req.cmd.buf[0] == MODE_SENSE) {
924 925 926 927 928 929 930 931 932
        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;
933 934
    }

935
    bdrv_get_geometry(s->bs, &nb_sectors);
936
    if (!dbd && nb_sectors) {
937
        if (r->req.cmd.buf[0] == MODE_SENSE) {
938 939 940 941
            outbuf[3] = 8; /* Block descriptor length  */
        } else { /* MODE_SENSE_10 */
            outbuf[7] = 8; /* Block descriptor length  */
        }
942
        nb_sectors /= s->cluster_size;
943
        if (nb_sectors > 0xffffff) {
944
            nb_sectors = 0;
945
        }
946 947 948 949 950 951 952 953 954 955 956
        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;
    }

957 958 959 960
    if (page_control == 3) {
        /* Saved Values */
        scsi_check_condition(r, SENSE_CODE(SAVING_PARAMS_NOT_SUPPORTED));
        return -1;
961 962
    }

963 964 965 966 967 968 969 970 971
    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;
        }
972 973 974
    }

    buflen = p - outbuf;
975 976 977 978 979
    /*
     * 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.
     */
980
    if (r->req.cmd.buf[0] == MODE_SENSE) {
981 982 983 984 985
        outbuf[0] = buflen - 1;
    } else { /* MODE_SENSE_10 */
        outbuf[0] = ((buflen - 2) >> 8) & 0xff;
        outbuf[1] = (buflen - 2) & 0xff;
    }
986
    if (buflen > r->req.cmd.xfer) {
987
        buflen = r->req.cmd.xfer;
988
    }
989 990 991
    return buflen;
}

992 993 994 995 996 997 998 999 1000
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];
1001
    bdrv_get_geometry(s->bs, &nb_sectors);
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
    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;
    }
1022
    if (toclen > req->cmd.xfer) {
1023
        toclen = req->cmd.xfer;
1024
    }
1025 1026 1027
    return toclen;
}

1028
static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
1029 1030 1031 1032 1033 1034 1035
{
    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) {
1036 1037 1038 1039 1040 1041
        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;
1042
        }
1043
        bdrv_eject(s->bs, !start);
1044
        s->tray_open = !start;
1045
    }
1046
    return 0;
1047 1048
}

1049
static int scsi_disk_emulate_command(SCSIDiskReq *r)
1050
{
1051
    SCSIRequest *req = &r->req;
1052 1053
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
    uint64_t nb_sectors;
1054
    uint8_t *outbuf;
1055 1056
    int buflen = 0;

1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
    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;
1074 1075
    switch (req->cmd.buf[0]) {
    case TEST_UNIT_READY:
1076
        if (s->tray_open || !bdrv_is_inserted(s->bs)) {
1077
            goto not_ready;
1078
        }
H
Hannes Reinecke 已提交
1079
        break;
1080 1081
    case INQUIRY:
        buflen = scsi_disk_emulate_inquiry(req, outbuf);
1082
        if (buflen < 0) {
1083
            goto illegal_request;
1084
        }
H
Hannes Reinecke 已提交
1085
        break;
1086 1087
    case MODE_SENSE:
    case MODE_SENSE_10:
1088
        buflen = scsi_disk_emulate_mode_sense(r, outbuf);
1089
        if (buflen < 0) {
1090
            goto illegal_request;
1091
        }
1092
        break;
1093 1094
    case READ_TOC:
        buflen = scsi_disk_emulate_read_toc(req, outbuf);
1095
        if (buflen < 0) {
1096
            goto illegal_request;
1097
        }
1098
        break;
1099
    case RESERVE:
1100
        if (req->cmd.buf[1] & 1) {
1101
            goto illegal_request;
1102
        }
1103 1104
        break;
    case RESERVE_10:
1105
        if (req->cmd.buf[1] & 3) {
1106
            goto illegal_request;
1107
        }
1108 1109
        break;
    case RELEASE:
1110
        if (req->cmd.buf[1] & 1) {
1111
            goto illegal_request;
1112
        }
1113 1114
        break;
    case RELEASE_10:
1115
        if (req->cmd.buf[1] & 3) {
1116
            goto illegal_request;
1117
        }
1118
        break;
1119
    case START_STOP:
1120 1121 1122
        if (scsi_disk_emulate_start_stop(r) < 0) {
            return -1;
        }
H
Hannes Reinecke 已提交
1123
        break;
1124
    case ALLOW_MEDIUM_REMOVAL:
1125
        s->tray_locked = req->cmd.buf[4] & 1;
1126
        bdrv_lock_medium(s->bs, req->cmd.buf[4] & 1);
H
Hannes Reinecke 已提交
1127
        break;
1128
    case READ_CAPACITY_10:
1129
        /* The normal LEN field for this command is zero.  */
H
Hannes Reinecke 已提交
1130 1131
        memset(outbuf, 0, 8);
        bdrv_get_geometry(s->bs, &nb_sectors);
1132
        if (!nb_sectors) {
1133
            goto not_ready;
1134
        }
1135 1136 1137 1138 1139 1140
        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. */
1141
        if (nb_sectors > UINT32_MAX) {
1142
            nb_sectors = UINT32_MAX;
1143
        }
1144 1145 1146 1147 1148 1149 1150 1151 1152
        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 已提交
1153
        break;
1154 1155 1156 1157 1158 1159
    case MECHANISM_STATUS:
        buflen = scsi_emulate_mechanism_status(s, outbuf);
        if (buflen < 0) {
            goto illegal_request;
        }
        break;
1160
    case GET_CONFIGURATION:
1161
        buflen = scsi_get_configuration(s, outbuf);
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
        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;
        }
1177
        break;
1178
    case SERVICE_ACTION_IN_16:
1179
        /* Service Action In subcommands. */
1180
        if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
1181 1182
            DPRINTF("SAI READ CAPACITY(16)\n");
            memset(outbuf, 0, req->cmd.xfer);
1183
            bdrv_get_geometry(s->bs, &nb_sectors);
1184
            if (!nb_sectors) {
1185
                goto not_ready;
1186
            }
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
            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 已提交
1204 1205
            outbuf[12] = 0;
            outbuf[13] = get_physical_block_exp(&s->qdev.conf);
1206 1207 1208 1209 1210 1211

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

1212 1213 1214 1215 1216 1217
            /* Protection, exponent and lowest lba field left blank. */
            buflen = req->cmd.xfer;
            break;
        }
        DPRINTF("Unsupported Service Action In\n");
        goto illegal_request;
1218
    case VERIFY_10:
1219
        break;
1220
    default:
1221
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1222
        return -1;
1223 1224 1225 1226
    }
    return buflen;

not_ready:
1227
    if (s->tray_open || !bdrv_is_inserted(s->bs)) {
1228
        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
1229
    } else {
1230
        scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
1231
    }
1232
    return -1;
1233 1234

illegal_request:
1235 1236 1237
    if (r->req.status == -1) {
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
    }
1238
    return -1;
1239 1240
}

P
pbrook 已提交
1241 1242 1243 1244 1245
/* 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.  */

1246
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
P
pbrook 已提交
1247
{
1248 1249
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
P
Paolo Bonzini 已提交
1250
    int32_t len;
P
pbrook 已提交
1251
    uint8_t command;
1252
    int rc;
P
pbrook 已提交
1253 1254

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

P
pbrook 已提交
1257 1258 1259
#ifdef DEBUG_SCSI
    {
        int i;
1260
        for (i = 1; i < r->req.cmd.len; i++) {
P
pbrook 已提交
1261 1262 1263 1264 1265
            printf(" 0x%02x", buf[i]);
        }
        printf("\n");
    }
#endif
1266

P
pbrook 已提交
1267
    switch (command) {
1268
    case TEST_UNIT_READY:
1269
    case INQUIRY:
1270 1271
    case MODE_SENSE:
    case MODE_SENSE_10:
1272 1273 1274 1275
    case RESERVE:
    case RESERVE_10:
    case RELEASE:
    case RELEASE_10:
1276
    case START_STOP:
1277
    case ALLOW_MEDIUM_REMOVAL:
1278
    case READ_CAPACITY_10:
1279
    case READ_TOC:
1280
    case READ_DVD_STRUCTURE:
1281
    case GET_CONFIGURATION:
1282 1283
    case GET_EVENT_STATUS_NOTIFICATION:
    case MECHANISM_STATUS:
1284
    case SERVICE_ACTION_IN_16:
1285
    case VERIFY_10:
1286
        rc = scsi_disk_emulate_command(r);
1287
        if (rc < 0) {
1288
            return 0;
1289
        }
1290 1291

        r->iov.iov_len = rc;
1292
        break;
1293 1294 1295 1296 1297 1298 1299
    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;
1300 1301
    case READ_6:
    case READ_10:
G
Gerd Hoffmann 已提交
1302 1303
    case READ_12:
    case READ_16:
1304
        len = r->req.cmd.xfer / s->qdev.blocksize;
1305
        DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
1306
        if (r->req.cmd.lba > s->max_lba) {
1307
            goto illegal_lba;
1308
        }
1309
        r->sector = r->req.cmd.lba * s->cluster_size;
P
pbrook 已提交
1310
        r->sector_count = len * s->cluster_size;
P
pbrook 已提交
1311
        break;
1312 1313
    case WRITE_6:
    case WRITE_10:
G
Gerd Hoffmann 已提交
1314 1315
    case WRITE_12:
    case WRITE_16:
1316
    case WRITE_VERIFY_10:
1317 1318
    case WRITE_VERIFY_12:
    case WRITE_VERIFY_16:
1319
        len = r->req.cmd.xfer / s->qdev.blocksize;
1320
        DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
1321 1322
                (command & 0xe) == 0xe ? "And Verify " : "",
                r->req.cmd.lba, len);
1323
        if (r->req.cmd.lba > s->max_lba) {
1324
            goto illegal_lba;
1325
        }
1326
        r->sector = r->req.cmd.lba * s->cluster_size;
P
pbrook 已提交
1327
        r->sector_count = len * s->cluster_size;
P
pbrook 已提交
1328
        break;
1329
    case MODE_SELECT:
1330
        DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
1331 1332
        /* We don't support mode parameter changes.
           Allow the mode parameter header + block descriptors only. */
1333
        if (r->req.cmd.xfer > 12) {
1334 1335 1336 1337
            goto fail;
        }
        break;
    case MODE_SELECT_10:
1338
        DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
1339 1340
        /* We don't support mode parameter changes.
           Allow the mode parameter header + block descriptors only. */
1341
        if (r->req.cmd.xfer > 16) {
1342 1343 1344 1345 1346
            goto fail;
        }
        break;
    case SEEK_6:
    case SEEK_10:
1347 1348 1349
        DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
                r->req.cmd.lba);
        if (r->req.cmd.lba > s->max_lba) {
1350 1351
            goto illegal_lba;
        }
1352 1353
        break;
    case WRITE_SAME_16:
1354
        len = r->req.cmd.xfer / s->qdev.blocksize;
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376

        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;
        }

1377
        break;
1378 1379
    case REQUEST_SENSE:
        abort();
P
pbrook 已提交
1380
    default:
1381
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1382
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1383
        return 0;
P
pbrook 已提交
1384
    fail:
1385
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1386
        return 0;
1387
    illegal_lba:
1388
        scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
1389
        return 0;
P
pbrook 已提交
1390
    }
1391
    if (r->sector_count == 0 && r->iov.iov_len == 0) {
1392
        scsi_req_complete(&r->req, GOOD);
P
pbrook 已提交
1393
    }
1394
    len = r->sector_count * 512 + r->iov.iov_len;
1395 1396
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        return -len;
P
pbrook 已提交
1397
    } else {
1398
        if (!r->sector_count) {
P
pbrook 已提交
1399
            r->sector_count = -1;
1400
        }
1401
        return len;
P
pbrook 已提交
1402 1403 1404
    }
}

J
Jan Kiszka 已提交
1405 1406 1407 1408 1409
static void scsi_disk_reset(DeviceState *dev)
{
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
    uint64_t nb_sectors;

1410
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
J
Jan Kiszka 已提交
1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423

    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);

1424
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
1425
    blockdev_mark_auto_del(s->qdev.conf.bs);
G
Gerd Hoffmann 已提交
1426 1427
}

1428
static void scsi_cd_change_media_cb(void *opaque, bool load)
1429
{
1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444
    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);
1445 1446
}

1447 1448 1449 1450 1451
static bool scsi_cd_is_tray_open(void *opaque)
{
    return ((SCSIDiskState *)opaque)->tray_open;
}

1452 1453 1454 1455 1456 1457
static bool scsi_cd_is_medium_locked(void *opaque)
{
    return ((SCSIDiskState *)opaque)->tray_locked;
}

static const BlockDevOps scsi_cd_block_ops = {
1458
    .change_media_cb = scsi_cd_change_media_cb,
1459
    .is_tray_open = scsi_cd_is_tray_open,
1460 1461 1462
    .is_medium_locked = scsi_cd_is_medium_locked,
};

1463 1464 1465 1466 1467 1468 1469 1470 1471
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 已提交
1472
static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
P
pbrook 已提交
1473
{
1474
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1475
    DriveInfo *dinfo;
P
pbrook 已提交
1476

1477
    if (!s->qdev.conf.bs) {
1478
        error_report("scsi-disk: drive property not set");
1479 1480
        return -1;
    }
1481
    s->bs = s->qdev.conf.bs;
1482

H
Hannes Reinecke 已提交
1483
    if (scsi_type == TYPE_DISK && !bdrv_is_inserted(s->bs)) {
1484 1485 1486 1487
        error_report("Device needs media, but drive is empty");
        return -1;
    }

1488
    if (!s->serial) {
1489 1490
        /* try to fall back to value set with legacy -drive serial=... */
        dinfo = drive_get_by_blockdev(s->bs);
1491
        if (*dinfo->serial) {
1492
            s->serial = g_strdup(dinfo->serial);
1493
        }
1494 1495
    }

1496
    if (!s->version) {
1497
        s->version = g_strdup(QEMU_VERSION);
1498 1499
    }

1500
    if (bdrv_is_sg(s->bs)) {
1501
        error_report("scsi-disk: unwanted /dev/sg*");
1502 1503 1504
        return -1;
    }

H
Hannes Reinecke 已提交
1505
    if (scsi_type == TYPE_ROM) {
1506
        bdrv_set_dev_ops(s->bs, &scsi_cd_block_ops, s);
1507
        s->qdev.blocksize = 2048;
H
Hannes Reinecke 已提交
1508
    } else if (scsi_type == TYPE_DISK) {
1509
        s->qdev.blocksize = s->qdev.conf.logical_block_size;
H
Hannes Reinecke 已提交
1510 1511 1512
    } else {
        error_report("scsi-disk: Unhandled SCSI type %02x", scsi_type);
        return -1;
P
pbrook 已提交
1513
    }
1514
    s->cluster_size = s->qdev.blocksize / 512;
1515
    bdrv_set_buffer_alignment(s->bs, s->qdev.blocksize);
1516

H
Hannes Reinecke 已提交
1517
    s->qdev.type = scsi_type;
1518
    qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
L
Luiz Capitulino 已提交
1519
    bdrv_iostatus_enable(s->bs);
1520
    add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
1521 1522 1523
    return 0;
}

1524 1525
static int scsi_hd_initfn(SCSIDevice *dev)
{
H
Hannes Reinecke 已提交
1526
    return scsi_initfn(dev, TYPE_DISK);
1527 1528 1529 1530
}

static int scsi_cd_initfn(SCSIDevice *dev)
{
H
Hannes Reinecke 已提交
1531
    return scsi_initfn(dev, TYPE_ROM);
1532 1533 1534 1535
}

static int scsi_disk_initfn(SCSIDevice *dev)
{
1536
    DriveInfo *dinfo;
H
Hannes Reinecke 已提交
1537
    uint8_t scsi_type;
1538 1539

    if (!dev->conf.bs) {
H
Hannes Reinecke 已提交
1540
        scsi_type = TYPE_DISK;  /* will die in scsi_initfn() */
1541
    } else {
1542
        dinfo = drive_get_by_blockdev(dev->conf.bs);
H
Hannes Reinecke 已提交
1543
        scsi_type = dinfo->media_cd ? TYPE_ROM : TYPE_DISK;
1544 1545
    }

H
Hannes Reinecke 已提交
1546
    return scsi_initfn(dev, scsi_type);
1547 1548
}

P
Paolo Bonzini 已提交
1549 1550
static SCSIReqOps scsi_disk_reqops = {
    .size         = sizeof(SCSIDiskReq),
1551 1552 1553 1554 1555 1556
    .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 已提交
1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
};

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;
}

1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582
#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,
1583
        .alloc_req    = scsi_new_request,
1584
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597
        .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,
1598
        .alloc_req    = scsi_new_request,
1599
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611
        .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,
1612
        .alloc_req    = scsi_new_request,
1613
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1614 1615 1616 1617 1618 1619
        .qdev.props   = (Property[]) {
            DEFINE_SCSI_DISK_PROPERTIES(),
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
            DEFINE_PROP_END_OF_LIST(),
        }
    }
1620 1621 1622 1623
};

static void scsi_disk_register_devices(void)
{
1624 1625 1626 1627 1628
    int i;

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