scsi-disk.c 39.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

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

K
Kevin Wolf 已提交
44 45 46 47
#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
48
#define SCSI_REQ_STATUS_RETRY_FLUSH     0x04
49

50 51
typedef struct SCSIDiskState SCSIDiskState;

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

63
struct SCSIDiskState
P
pbrook 已提交
64
{
65
    SCSIDevice qdev;
66
    BlockDriverState *bs;
P
pbrook 已提交
67 68 69
    /* 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;
70
    uint32_t removable;
71
    uint64_t max_lba;
72
    QEMUBH *bh;
G
Gerd Hoffmann 已提交
73
    char *version;
74
    char *serial;
75
    bool tray_open;
P
pbrook 已提交
76 77
};

K
Kevin Wolf 已提交
78
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
79
static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
K
Kevin Wolf 已提交
80

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

85
    qemu_vfree(r->iov.iov_base);
P
pbrook 已提交
86 87
}

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

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

static void scsi_read_complete(void * opaque, int ret)
{
111
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
112
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
K
Kevin Wolf 已提交
113
    int n;
P
pbrook 已提交
114

P
Paolo Bonzini 已提交
115 116 117 118
    if (r->req.aiocb != NULL) {
        r->req.aiocb = NULL;
        bdrv_acct_done(s->bs, &r->acct);
    }
119

P
pbrook 已提交
120
    if (ret) {
K
Kevin Wolf 已提交
121 122 123
        if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
            return;
        }
P
pbrook 已提交
124
    }
K
Kevin Wolf 已提交
125

126
    DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->iov.iov_len);
P
pbrook 已提交
127

K
Kevin Wolf 已提交
128 129 130
    n = r->iov.iov_len / 512;
    r->sector += n;
    r->sector_count -= n;
P
Paolo Bonzini 已提交
131
    scsi_req_data(&r->req, r->iov.iov_len);
P
pbrook 已提交
132 133
}

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
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 已提交
152

153 154
/* Read more data from scsi device into buffer.  */
static void scsi_read_data(SCSIRequest *req)
P
pbrook 已提交
155
{
156
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
K
Kevin Wolf 已提交
157
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
P
pbrook 已提交
158 159
    uint32_t n;

P
pbrook 已提交
160
    if (r->sector_count == (uint32_t)-1) {
161
        DPRINTF("Read buf_len=%zd\n", r->iov.iov_len);
P
pbrook 已提交
162
        r->sector_count = 0;
P
Paolo Bonzini 已提交
163
        scsi_req_data(&r->req, r->iov.iov_len);
P
pbrook 已提交
164
        return;
P
pbrook 已提交
165
    }
P
pbrook 已提交
166 167
    DPRINTF("Read sector_count=%d\n", r->sector_count);
    if (r->sector_count == 0) {
168 169
        /* This also clears the sense buffer for REQUEST SENSE.  */
        scsi_req_complete(&r->req, GOOD);
P
pbrook 已提交
170
        return;
P
pbrook 已提交
171 172
    }

173 174 175
    /* No data transfer may already be in progress */
    assert(r->req.aiocb == NULL);

176 177 178 179 180 181
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        DPRINTF("Data transfer direction invalid\n");
        scsi_read_complete(r, -EINVAL);
        return;
    }

P
pbrook 已提交
182 183 184 185
    n = r->sector_count;
    if (n > SCSI_DMA_BUF_SIZE / 512)
        n = SCSI_DMA_BUF_SIZE / 512;

186 187
    r->iov.iov_len = n * 512;
    qemu_iovec_init_external(&r->qiov, &r->iov, 1);
188 189

    bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
190
    r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
191
                              scsi_read_complete, r);
192 193 194
    if (r->req.aiocb == NULL) {
        scsi_read_complete(r, -EIO);
    }
P
pbrook 已提交
195 196
}

K
Kevin Wolf 已提交
197 198 199
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
{
    int is_read = (type == SCSI_REQ_STATUS_RETRY_READ);
200
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
K
Kevin Wolf 已提交
201
    BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
202

203
    if (action == BLOCK_ERR_IGNORE) {
K
Kevin Wolf 已提交
204
        bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
205
        return 0;
206
    }
207 208 209

    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
            || action == BLOCK_ERR_STOP_ANY) {
K
Kevin Wolf 已提交
210 211 212 213 214

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

        bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
J
Jan Kiszka 已提交
215
        vm_stop(VMSTOP_DISKFULL);
216
    } else {
217 218
        switch (error) {
        case ENOMEM:
219
            scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
220 221
            break;
        case EINVAL:
222
            scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
223 224
            break;
        default:
225
            scsi_check_condition(r, SENSE_CODE(IO_ERROR));
226
            break;
227
        }
K
Kevin Wolf 已提交
228
        bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
229 230 231 232
    }
    return 1;
}

P
pbrook 已提交
233 234
static void scsi_write_complete(void * opaque, int ret)
{
235
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
236
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
P
pbrook 已提交
237
    uint32_t len;
238 239
    uint32_t n;

P
Paolo Bonzini 已提交
240 241 242 243
    if (r->req.aiocb != NULL) {
        r->req.aiocb = NULL;
        bdrv_acct_done(s->bs, &r->acct);
    }
244

P
pbrook 已提交
245
    if (ret) {
K
Kevin Wolf 已提交
246
        if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
247
            return;
K
Kevin Wolf 已提交
248
        }
P
pbrook 已提交
249 250
    }

251
    n = r->iov.iov_len / 512;
252 253
    r->sector += n;
    r->sector_count -= n;
P
pbrook 已提交
254
    if (r->sector_count == 0) {
255
        scsi_req_complete(&r->req, GOOD);
P
pbrook 已提交
256 257 258 259 260
    } else {
        len = r->sector_count * 512;
        if (len > SCSI_DMA_BUF_SIZE) {
            len = SCSI_DMA_BUF_SIZE;
        }
261
        r->iov.iov_len = len;
262
        DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len);
P
Paolo Bonzini 已提交
263
        scsi_req_data(&r->req, len);
P
pbrook 已提交
264 265 266
    }
}

267
static void scsi_write_data(SCSIRequest *req)
268
{
269
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
270
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
271 272
    uint32_t n;

273 274 275
    /* No data transfer may already be in progress */
    assert(r->req.aiocb == NULL);

276 277 278
    if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {
        DPRINTF("Data transfer direction invalid\n");
        scsi_write_complete(r, -EINVAL);
279
        return;
280 281
    }

282
    n = r->iov.iov_len / 512;
283
    if (n) {
284
        qemu_iovec_init_external(&r->qiov, &r->iov, 1);
285 286

        bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
287
        r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
288
                                   scsi_write_complete, r);
289
        if (r->req.aiocb == NULL) {
290
            scsi_write_complete(r, -ENOMEM);
291
        }
292 293 294 295
    } else {
        /* Invoke completion routine to fetch data from host.  */
        scsi_write_complete(r, 0);
    }
P
pbrook 已提交
296
}
P
pbrook 已提交
297

298
static void scsi_dma_restart_bh(void *opaque)
299
{
300
    SCSIDiskState *s = opaque;
301 302
    SCSIRequest *req;
    SCSIDiskReq *r;
303 304 305

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

307 308
    QTAILQ_FOREACH(req, &s->qdev.requests, next) {
        r = DO_UPCAST(SCSIDiskReq, req, req);
309
        if (r->status & SCSI_REQ_STATUS_RETRY) {
K
Kevin Wolf 已提交
310
            int status = r->status;
311 312
            int ret;

K
Kevin Wolf 已提交
313 314 315 316 317
            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:
318
                scsi_read_data(&r->req);
K
Kevin Wolf 已提交
319 320
                break;
            case SCSI_REQ_STATUS_RETRY_WRITE:
321
                scsi_write_data(&r->req);
K
Kevin Wolf 已提交
322
                break;
323 324 325
            case SCSI_REQ_STATUS_RETRY_FLUSH:
                ret = scsi_disk_emulate_command(r, r->iov.iov_base);
                if (ret == 0) {
326
                    scsi_req_complete(&r->req, GOOD);
327
                }
K
Kevin Wolf 已提交
328
            }
329 330 331 332
        }
    }
}

333 334
static void scsi_dma_restart_cb(void *opaque, int running, int reason)
{
335
    SCSIDiskState *s = opaque;
336 337 338 339 340 341 342 343 344 345

    if (!running)
        return;

    if (!s->bh) {
        s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
        qemu_bh_schedule(s->bh);
    }
}

P
pbrook 已提交
346
/* Return a pointer to the data buffer.  */
347
static uint8_t *scsi_get_buf(SCSIRequest *req)
P
pbrook 已提交
348
{
349
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
P
pbrook 已提交
350

351
    return (uint8_t *)r->iov.iov_base;
P
pbrook 已提交
352 353
}

354 355
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
{
G
Gerd Hoffmann 已提交
356
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
    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 已提交
374
        if (s->qdev.type == TYPE_ROM) {
375 376 377 378 379 380 381 382 383
            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 已提交
384 385
        {
            int pages;
386 387
            DPRINTF("Inquiry EVPD[Supported pages] "
                    "buffer size %zd\n", req->cmd.xfer);
H
Hannes Reinecke 已提交
388
            pages = buflen++;
389
            outbuf[buflen++] = 0x00; // list of supported pages (this page)
390 391
            if (s->serial)
                outbuf[buflen++] = 0x80; // unit serial number
392
            outbuf[buflen++] = 0x83; // device identification
H
Hannes Reinecke 已提交
393
            if (s->qdev.type == TYPE_DISK) {
394 395
                outbuf[buflen++] = 0xb0; // block limits
                outbuf[buflen++] = 0xb2; // thin provisioning
H
Hannes Reinecke 已提交
396 397
            }
            outbuf[pages] = buflen - pages - 1; // number of pages
398
            break;
H
Hannes Reinecke 已提交
399
        }
400 401
        case 0x80: /* Device serial number, optional */
        {
402
            int l;
403

404 405 406 407 408 409
            if (!s->serial) {
                DPRINTF("Inquiry (EVPD[Serial number] not supported\n");
                return -1;
            }

            l = strlen(s->serial);
410 411 412 413 414 415 416 417
            if (l > req->cmd.xfer)
                l = req->cmd.xfer;
            if (l > 20)
                l = 20;

            DPRINTF("Inquiry EVPD[Serial number] "
                    "buffer size %zd\n", req->cmd.xfer);
            outbuf[buflen++] = l;
418
            memcpy(outbuf+buflen, s->serial, l);
419 420 421 422 423 424 425
            buflen += l;
            break;
        }

        case 0x83: /* Device identification page, mandatory */
        {
            int max_len = 255 - 8;
426
            int id_len = strlen(bdrv_get_device_name(s->bs));
427 428 429 430 431 432

            if (id_len > max_len)
                id_len = max_len;
            DPRINTF("Inquiry EVPD[Device identification] "
                    "buffer size %zd\n", req->cmd.xfer);

H
Hannes Reinecke 已提交
433
            outbuf[buflen++] = 4 + id_len;
434 435 436 437 438
            outbuf[buflen++] = 0x2; // ASCII
            outbuf[buflen++] = 0;   // not officially assigned
            outbuf[buflen++] = 0;   // reserved
            outbuf[buflen++] = id_len; // length of data following

439
            memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len);
440 441 442
            buflen += id_len;
            break;
        }
443
        case 0xb0: /* block limits */
C
Christoph Hellwig 已提交
444
        {
445 446
            unsigned int unmap_sectors =
                    s->qdev.conf.discard_granularity / s->qdev.blocksize;
447 448 449 450
            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 已提交
451

H
Hannes Reinecke 已提交
452
            if (s->qdev.type == TYPE_ROM) {
H
Hannes Reinecke 已提交
453 454 455 456
                DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
                        page_code);
                return -1;
            }
C
Christoph Hellwig 已提交
457 458 459 460 461 462 463 464 465 466 467 468 469 470
            /* 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;
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485

            /* 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 已提交
486 487
            break;
        }
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
        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;
    if (buflen > SCSI_MAX_INQUIRY_LEN)
        buflen = SCSI_MAX_INQUIRY_LEN;

    memset(outbuf, 0, buflen);

H
Hannes Reinecke 已提交
517 518
    outbuf[0] = s->qdev.type & 0x1f;
    if (s->qdev.type == TYPE_ROM) {
519
        outbuf[1] = 0x80;
L
Laszlo Ast 已提交
520
        memcpy(&outbuf[16], "QEMU CD-ROM     ", 16);
521
    } else {
522
        outbuf[1] = s->removable ? 0x80 : 0;
L
Laszlo Ast 已提交
523
        memcpy(&outbuf[16], "QEMU HARDDISK   ", 16);
524
    }
L
Laszlo Ast 已提交
525
    memcpy(&outbuf[8], "QEMU    ", 8);
G
Gerd Hoffmann 已提交
526
    memset(&outbuf[32], 0, 4);
527
    memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
528 529 530 531 532 533
    /*
     * 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 已提交
534
    outbuf[2] = 5;
535
    outbuf[3] = 2; /* Format 2 */
536 537 538 539 540 541 542 543 544

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

545 546 547 548 549
    /* Sync data transfer and TCQ.  */
    outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0);
    return buflen;
}

550
static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
551
                           int page_control)
552
{
553
    BlockDriverState *bdrv = s->bs;
554
    int cylinders, heads, secs;
555
    uint8_t *p = *p_outbuf;
556

557 558 559 560 561 562
    /*
     * 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.
     */
563 564
    switch (page) {
    case 4: /* Rigid disk device geometry page. */
565 566 567
        if (s->qdev.type == TYPE_ROM) {
            return -1;
        }
568 569
        p[0] = 4;
        p[1] = 0x16;
570
        if (page_control == 1) { /* Changeable Values */
571
            break;
572
        }
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
        /* 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;
597
        break;
598 599

    case 5: /* Flexible disk device geometry page. */
600 601 602
        if (s->qdev.type == TYPE_ROM) {
            return -1;
        }
603 604
        p[0] = 5;
        p[1] = 0x1e;
605
        if (page_control == 1) { /* Changeable Values */
606
            break;
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
        /* 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;
639
        break;
640 641 642 643

    case 8: /* Caching page.  */
        p[0] = 8;
        p[1] = 0x12;
644
        if (page_control == 1) { /* Changeable Values */
645
            break;
646
        }
647
        if (bdrv_enable_write_cache(s->bs)) {
648 649
            p[2] = 4; /* WCE */
        }
650
        break;
651 652

    case 0x2a: /* CD Capabilities and Mechanical Status page. */
653 654 655
        if (s->qdev.type != TYPE_ROM) {
            return -1;
        }
656 657
        p[0] = 0x2a;
        p[1] = 0x14;
658
        if (page_control == 1) { /* Changeable Values */
659
            break;
660
        }
661 662 663 664 665 666 667
        p[2] = 3; // CD-R & CD-RW read
        p[3] = 0; // Writing not supported
        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 */
668
        p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0);
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
        /* Locking supported, jumper present, eject, tray */
        p[7] = 0; /* no volume & mute control, no
                     changer */
        p[8] = (50 * 176) >> 8; // 50x read speed
        p[9] = (50 * 176) & 0xff;
        p[10] = 0 >> 8; // No volume
        p[11] = 0 & 0xff;
        p[12] = 2048 >> 8; // 2M buffer
        p[13] = 2048 & 0xff;
        p[14] = (16 * 176) >> 8; // 16x read speed current
        p[15] = (16 * 176) & 0xff;
        p[18] = (16 * 176) >> 8; // 16x write speed
        p[19] = (16 * 176) & 0xff;
        p[20] = (16 * 176) >> 8; // 16x write speed current
        p[21] = (16 * 176) & 0xff;
684
        break;
685 686

    default:
687
        return -1;
688
    }
689 690 691

    *p_outbuf += p[1] + 2;
    return p[1] + 2;
692 693
}

694
static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
695
{
696
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
697
    uint64_t nb_sectors;
698
    int page, dbd, buflen, ret, page_control;
699
    uint8_t *p;
700
    uint8_t dev_specific_param;
701

702 703 704
    dbd = r->req.cmd.buf[1]  & 0x8;
    page = r->req.cmd.buf[2] & 0x3f;
    page_control = (r->req.cmd.buf[2] & 0xc0) >> 6;
705
    DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
706 707
        (r->req.cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, r->req.cmd.xfer, page_control);
    memset(outbuf, 0, r->req.cmd.xfer);
708 709
    p = outbuf;

710
    if (bdrv_is_read_only(s->bs)) {
711 712 713 714 715
        dev_specific_param = 0x80; /* Readonly.  */
    } else {
        dev_specific_param = 0x00;
    }

716
    if (r->req.cmd.buf[0] == MODE_SENSE) {
717 718 719 720 721 722 723 724 725
        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;
726 727
    }

728
    bdrv_get_geometry(s->bs, &nb_sectors);
729
    if (!dbd && nb_sectors) {
730
        if (r->req.cmd.buf[0] == MODE_SENSE) {
731 732 733 734
            outbuf[3] = 8; /* Block descriptor length  */
        } else { /* MODE_SENSE_10 */
            outbuf[7] = 8; /* Block descriptor length  */
        }
735 736
        nb_sectors /= s->cluster_size;
        if (nb_sectors > 0xffffff)
737
            nb_sectors = 0;
738 739 740 741 742 743 744 745 746 747 748
        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;
    }

749 750 751 752
    if (page_control == 3) {
        /* Saved Values */
        scsi_check_condition(r, SENSE_CODE(SAVING_PARAMS_NOT_SUPPORTED));
        return -1;
753 754
    }

755 756 757 758 759 760 761 762 763
    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;
        }
764 765 766
    }

    buflen = p - outbuf;
767 768 769 770 771
    /*
     * 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.
     */
772
    if (r->req.cmd.buf[0] == MODE_SENSE) {
773 774 775 776 777
        outbuf[0] = buflen - 1;
    } else { /* MODE_SENSE_10 */
        outbuf[0] = ((buflen - 2) >> 8) & 0xff;
        outbuf[1] = (buflen - 2) & 0xff;
    }
778 779
    if (buflen > r->req.cmd.xfer)
        buflen = r->req.cmd.xfer;
780 781 782
    return buflen;
}

783 784 785 786 787 788 789 790 791
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];
792
    bdrv_get_geometry(s->bs, &nb_sectors);
793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817
    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;
    }
    if (toclen > req->cmd.xfer)
        toclen = req->cmd.xfer;
    return toclen;
}

818 819 820 821 822 823 824 825 826
static void scsi_disk_emulate_start_stop(SCSIDiskReq *r)
{
    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) {
        bdrv_eject(s->bs, !start);
827
        s->tray_open = !start;
828 829 830
    }
}

831
static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
832
{
833
    SCSIRequest *req = &r->req;
834 835
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
    uint64_t nb_sectors;
836 837 838 839
    int buflen = 0;

    switch (req->cmd.buf[0]) {
    case TEST_UNIT_READY:
840
        if (!bdrv_is_inserted(s->bs))
841
            goto not_ready;
H
Hannes Reinecke 已提交
842
        break;
843 844 845 846
    case INQUIRY:
        buflen = scsi_disk_emulate_inquiry(req, outbuf);
        if (buflen < 0)
            goto illegal_request;
H
Hannes Reinecke 已提交
847
        break;
848 849
    case MODE_SENSE:
    case MODE_SENSE_10:
850
        buflen = scsi_disk_emulate_mode_sense(r, outbuf);
851 852 853
        if (buflen < 0)
            goto illegal_request;
        break;
854 855 856 857 858
    case READ_TOC:
        buflen = scsi_disk_emulate_read_toc(req, outbuf);
        if (buflen < 0)
            goto illegal_request;
        break;
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874
    case RESERVE:
        if (req->cmd.buf[1] & 1)
            goto illegal_request;
        break;
    case RESERVE_10:
        if (req->cmd.buf[1] & 3)
            goto illegal_request;
        break;
    case RELEASE:
        if (req->cmd.buf[1] & 1)
            goto illegal_request;
        break;
    case RELEASE_10:
        if (req->cmd.buf[1] & 3)
            goto illegal_request;
        break;
875
    case START_STOP:
876
        scsi_disk_emulate_start_stop(r);
H
Hannes Reinecke 已提交
877
        break;
878
    case ALLOW_MEDIUM_REMOVAL:
879
        bdrv_set_locked(s->bs, req->cmd.buf[4] & 1);
H
Hannes Reinecke 已提交
880
        break;
881
    case READ_CAPACITY_10:
882
        /* The normal LEN field for this command is zero.  */
H
Hannes Reinecke 已提交
883 884
        memset(outbuf, 0, 8);
        bdrv_get_geometry(s->bs, &nb_sectors);
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
        if (!nb_sectors)
            goto not_ready;
        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. */
        if (nb_sectors > UINT32_MAX)
            nb_sectors = UINT32_MAX;
        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 已提交
904
        break;
905 906 907 908 909 910 911
    case GET_CONFIGURATION:
        memset(outbuf, 0, 8);
        /* ??? This should probably return much more information.  For now
           just return the basic header indicating the CD-ROM profile.  */
        outbuf[7] = 8; // CD-ROM
        buflen = 8;
        break;
912
    case SERVICE_ACTION_IN_16:
913
        /* Service Action In subcommands. */
914
        if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
915 916
            DPRINTF("SAI READ CAPACITY(16)\n");
            memset(outbuf, 0, req->cmd.xfer);
917
            bdrv_get_geometry(s->bs, &nb_sectors);
918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
            if (!nb_sectors)
                goto not_ready;
            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 已提交
937 938
            outbuf[12] = 0;
            outbuf[13] = get_physical_block_exp(&s->qdev.conf);
939 940 941 942 943 944

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

945 946 947 948 949 950
            /* Protection, exponent and lowest lba field left blank. */
            buflen = req->cmd.xfer;
            break;
        }
        DPRINTF("Unsupported Service Action In\n");
        goto illegal_request;
951
    case VERIFY_10:
952
        break;
953
    default:
954
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
955
        return -1;
956 957 958 959
    }
    return buflen;

not_ready:
960
    if (!bdrv_is_inserted(s->bs)) {
961
        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
962
    } else {
963
        scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
964
    }
965
    return -1;
966 967

illegal_request:
968 969 970
    if (r->req.status == -1) {
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
    }
971
    return -1;
972 973
}

P
pbrook 已提交
974 975 976 977 978
/* 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.  */

979
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
P
pbrook 已提交
980
{
981 982
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
P
Paolo Bonzini 已提交
983
    int32_t len;
P
pbrook 已提交
984 985
    uint8_t command;
    uint8_t *outbuf;
986
    int rc;
P
pbrook 已提交
987 988

    command = buf[0];
989
    outbuf = (uint8_t *)r->iov.iov_base;
990
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
991

P
pbrook 已提交
992 993 994
#ifdef DEBUG_SCSI
    {
        int i;
995
        for (i = 1; i < r->req.cmd.len; i++) {
P
pbrook 已提交
996 997 998 999 1000
            printf(" 0x%02x", buf[i]);
        }
        printf("\n");
    }
#endif
1001

P
pbrook 已提交
1002
    switch (command) {
1003
    case TEST_UNIT_READY:
1004
    case INQUIRY:
1005 1006
    case MODE_SENSE:
    case MODE_SENSE_10:
1007 1008 1009 1010
    case RESERVE:
    case RESERVE_10:
    case RELEASE:
    case RELEASE_10:
1011
    case START_STOP:
1012
    case ALLOW_MEDIUM_REMOVAL:
1013
    case READ_CAPACITY_10:
1014
    case READ_TOC:
1015
    case GET_CONFIGURATION:
1016
    case SERVICE_ACTION_IN_16:
1017
    case VERIFY_10:
1018 1019
        rc = scsi_disk_emulate_command(r, outbuf);
        if (rc < 0) {
1020
            return 0;
1021
        }
1022 1023

        r->iov.iov_len = rc;
1024
        break;
1025 1026 1027 1028 1029 1030 1031
    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;
1032 1033
    case READ_6:
    case READ_10:
G
Gerd Hoffmann 已提交
1034 1035
    case READ_12:
    case READ_16:
1036
        len = r->req.cmd.xfer / s->qdev.blocksize;
1037 1038
        DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
        if (r->req.cmd.lba > s->max_lba)
1039
            goto illegal_lba;
1040
        r->sector = r->req.cmd.lba * s->cluster_size;
P
pbrook 已提交
1041
        r->sector_count = len * s->cluster_size;
P
pbrook 已提交
1042
        break;
1043 1044
    case WRITE_6:
    case WRITE_10:
G
Gerd Hoffmann 已提交
1045 1046
    case WRITE_12:
    case WRITE_16:
1047
    case WRITE_VERIFY_10:
1048 1049
    case WRITE_VERIFY_12:
    case WRITE_VERIFY_16:
1050
        len = r->req.cmd.xfer / s->qdev.blocksize;
1051
        DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
1052 1053 1054
                (command & 0xe) == 0xe ? "And Verify " : "",
                r->req.cmd.lba, len);
        if (r->req.cmd.lba > s->max_lba)
1055
            goto illegal_lba;
1056
        r->sector = r->req.cmd.lba * s->cluster_size;
P
pbrook 已提交
1057
        r->sector_count = len * s->cluster_size;
P
pbrook 已提交
1058
        break;
1059
    case MODE_SELECT:
1060
        DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
1061 1062
        /* We don't support mode parameter changes.
           Allow the mode parameter header + block descriptors only. */
1063
        if (r->req.cmd.xfer > 12) {
1064 1065 1066 1067
            goto fail;
        }
        break;
    case MODE_SELECT_10:
1068
        DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
1069 1070
        /* We don't support mode parameter changes.
           Allow the mode parameter header + block descriptors only. */
1071
        if (r->req.cmd.xfer > 16) {
1072 1073 1074 1075 1076
            goto fail;
        }
        break;
    case SEEK_6:
    case SEEK_10:
1077 1078 1079
        DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
                r->req.cmd.lba);
        if (r->req.cmd.lba > s->max_lba) {
1080 1081
            goto illegal_lba;
        }
1082 1083
        break;
    case WRITE_SAME_16:
1084
        len = r->req.cmd.xfer / s->qdev.blocksize;
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106

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

1107
        break;
1108 1109
    case REQUEST_SENSE:
        abort();
P
pbrook 已提交
1110
    default:
1111
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1112
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1113
        return 0;
P
pbrook 已提交
1114
    fail:
1115
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1116
        return 0;
1117
    illegal_lba:
1118
        scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
1119
        return 0;
P
pbrook 已提交
1120
    }
1121
    if (r->sector_count == 0 && r->iov.iov_len == 0) {
1122
        scsi_req_complete(&r->req, GOOD);
P
pbrook 已提交
1123
    }
1124
    len = r->sector_count * 512 + r->iov.iov_len;
1125 1126
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        return -len;
P
pbrook 已提交
1127 1128 1129
    } else {
        if (!r->sector_count)
            r->sector_count = -1;
1130
        return len;
P
pbrook 已提交
1131 1132 1133
    }
}

J
Jan Kiszka 已提交
1134 1135 1136 1137 1138
static void scsi_disk_reset(DeviceState *dev)
{
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
    uint64_t nb_sectors;

1139
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
J
Jan Kiszka 已提交
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152

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

1153
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
1154
    blockdev_mark_auto_del(s->qdev.conf.bs);
G
Gerd Hoffmann 已提交
1155 1156
}

H
Hannes Reinecke 已提交
1157
static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
P
pbrook 已提交
1158
{
1159
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1160
    DriveInfo *dinfo;
P
pbrook 已提交
1161

1162
    if (!s->qdev.conf.bs) {
1163
        error_report("scsi-disk: drive property not set");
1164 1165
        return -1;
    }
1166
    s->bs = s->qdev.conf.bs;
1167

H
Hannes Reinecke 已提交
1168
    if (scsi_type == TYPE_DISK && !bdrv_is_inserted(s->bs)) {
1169 1170 1171 1172
        error_report("Device needs media, but drive is empty");
        return -1;
    }

1173
    if (!s->serial) {
1174 1175
        /* try to fall back to value set with legacy -drive serial=... */
        dinfo = drive_get_by_blockdev(s->bs);
1176
        if (*dinfo->serial) {
1177
            s->serial = g_strdup(dinfo->serial);
1178
        }
1179 1180
    }

1181
    if (!s->version) {
1182
        s->version = g_strdup(QEMU_VERSION);
1183 1184
    }

1185
    if (bdrv_is_sg(s->bs)) {
1186
        error_report("scsi-disk: unwanted /dev/sg*");
1187 1188 1189
        return -1;
    }

H
Hannes Reinecke 已提交
1190
    if (scsi_type == TYPE_ROM) {
1191
        s->qdev.blocksize = 2048;
H
Hannes Reinecke 已提交
1192
    } else if (scsi_type == TYPE_DISK) {
1193
        s->qdev.blocksize = s->qdev.conf.logical_block_size;
H
Hannes Reinecke 已提交
1194 1195 1196
    } else {
        error_report("scsi-disk: Unhandled SCSI type %02x", scsi_type);
        return -1;
P
pbrook 已提交
1197
    }
1198
    s->cluster_size = s->qdev.blocksize / 512;
1199
    s->bs->buffer_alignment = s->qdev.blocksize;
1200

H
Hannes Reinecke 已提交
1201
    s->qdev.type = scsi_type;
1202
    qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
H
Hannes Reinecke 已提交
1203
    bdrv_set_removable(s->bs, scsi_type == TYPE_ROM);
1204
    add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
1205 1206 1207
    return 0;
}

1208 1209
static int scsi_hd_initfn(SCSIDevice *dev)
{
H
Hannes Reinecke 已提交
1210
    return scsi_initfn(dev, TYPE_DISK);
1211 1212 1213 1214
}

static int scsi_cd_initfn(SCSIDevice *dev)
{
H
Hannes Reinecke 已提交
1215
    return scsi_initfn(dev, TYPE_ROM);
1216 1217 1218 1219
}

static int scsi_disk_initfn(SCSIDevice *dev)
{
1220
    DriveInfo *dinfo;
H
Hannes Reinecke 已提交
1221
    uint8_t scsi_type;
1222 1223

    if (!dev->conf.bs) {
H
Hannes Reinecke 已提交
1224
        scsi_type = TYPE_DISK;  /* will die in scsi_initfn() */
1225
    } else {
1226
        dinfo = drive_get_by_blockdev(dev->conf.bs);
H
Hannes Reinecke 已提交
1227
        scsi_type = dinfo->media_cd ? TYPE_ROM : TYPE_DISK;
1228 1229
    }

H
Hannes Reinecke 已提交
1230
    return scsi_initfn(dev, scsi_type);
1231 1232
}

P
Paolo Bonzini 已提交
1233 1234
static SCSIReqOps scsi_disk_reqops = {
    .size         = sizeof(SCSIDiskReq),
1235 1236 1237 1238 1239 1240
    .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 已提交
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255
};

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;
    SCSIDiskReq *r;

    req = scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, hba_private);
    r = DO_UPCAST(SCSIDiskReq, req, req);
    r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
    return req;
}

1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269
#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,
1270
        .alloc_req    = scsi_new_request,
1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
        .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,
1284
        .alloc_req    = scsi_new_request,
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
        .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,
1297
        .alloc_req    = scsi_new_request,
1298 1299 1300 1301 1302 1303
        .qdev.props   = (Property[]) {
            DEFINE_SCSI_DISK_PROPERTIES(),
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
            DEFINE_PROP_END_OF_LIST(),
        }
    }
1304 1305 1306 1307
};

static void scsi_disk_register_devices(void)
{
1308 1309 1310 1311 1312
    int i;

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