scsi-disk.c 49.9 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
    uint32_t removable;
69
    bool media_changed;
70
    bool media_event;
71
    QEMUBH *bh;
G
Gerd Hoffmann 已提交
72
    char *version;
73
    char *serial;
74
    bool tray_open;
75
    bool tray_locked;
P
pbrook 已提交
76 77
};

K
Kevin Wolf 已提交
78
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
P
Paolo Bonzini 已提交
79
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf);
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 86 87
    if (r->iov.iov_base) {
        qemu_vfree(r->iov.iov_base);
    }
P
pbrook 已提交
88 89
}

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

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

111 112
static uint32_t scsi_init_iovec(SCSIDiskReq *r)
{
113 114 115 116
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    if (!r->iov.iov_base) {
        r->buflen = SCSI_DMA_BUF_SIZE;
117
        r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
118 119
    }
    r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
120 121 122 123
    qemu_iovec_init_external(&r->qiov, &r->iov, 1);
    return r->qiov.size / 512;
}

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

P
Paolo Bonzini 已提交
130 131
    if (r->req.aiocb != NULL) {
        r->req.aiocb = NULL;
132
        bdrv_acct_done(s->qdev.conf.bs, &r->acct);
P
Paolo Bonzini 已提交
133
    }
134

P
pbrook 已提交
135
    if (ret) {
K
Kevin Wolf 已提交
136 137 138
        if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
            return;
        }
P
pbrook 已提交
139
    }
K
Kevin Wolf 已提交
140

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

143
    n = r->qiov.size / 512;
K
Kevin Wolf 已提交
144 145
    r->sector += n;
    r->sector_count -= n;
146
    scsi_req_data(&r->req, r->qiov.size);
P
pbrook 已提交
147 148
}

149 150 151 152 153 154 155
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;
156
        bdrv_acct_done(s->qdev.conf.bs, &r->acct);
157 158 159 160 161 162 163 164 165 166
    }

    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 已提交
167

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

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

188 189 190
    /* No data transfer may already be in progress */
    assert(r->req.aiocb == NULL);

191 192 193 194 195 196
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
        DPRINTF("Data transfer direction invalid\n");
        scsi_read_complete(r, -EINVAL);
        return;
    }

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

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

215
    if (action == BLOCK_ERR_IGNORE) {
216
        bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE, is_read);
217
        return 0;
218
    }
219 220 221

    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
            || action == BLOCK_ERR_STOP_ANY) {
K
Kevin Wolf 已提交
222 223 224 225

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

226
        bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_STOP, is_read);
227
        vm_stop(RUN_STATE_IO_ERROR);
228
        bdrv_iostatus_set_err(s->qdev.conf.bs, error);
229
    } else {
230
        switch (error) {
231 232 233
        case ENOMEDIUM:
            scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
            break;
234
        case ENOMEM:
235
            scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
236 237
            break;
        case EINVAL:
238
            scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
239 240
            break;
        default:
241
            scsi_check_condition(r, SENSE_CODE(IO_ERROR));
242
            break;
243
        }
244
        bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_REPORT, is_read);
245 246 247 248
    }
    return 1;
}

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

P
Paolo Bonzini 已提交
255 256
    if (r->req.aiocb != NULL) {
        r->req.aiocb = NULL;
257
        bdrv_acct_done(s->qdev.conf.bs, &r->acct);
P
Paolo Bonzini 已提交
258
    }
259

P
pbrook 已提交
260
    if (ret) {
K
Kevin Wolf 已提交
261
        if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
262
            return;
K
Kevin Wolf 已提交
263
        }
P
pbrook 已提交
264 265
    }

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

278
static void scsi_write_data(SCSIRequest *req)
279
{
280
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
281
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
282 283
    uint32_t n;

284 285 286
    /* No data transfer may already be in progress */
    assert(r->req.aiocb == NULL);

287 288 289
    if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {
        DPRINTF("Data transfer direction invalid\n");
        scsi_write_complete(r, -EINVAL);
290
        return;
291 292
    }

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

310
static void scsi_dma_restart_bh(void *opaque)
311
{
312
    SCSIDiskState *s = opaque;
313 314
    SCSIRequest *req;
    SCSIDiskReq *r;
315 316 317

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

319 320
    QTAILQ_FOREACH(req, &s->qdev.requests, next) {
        r = DO_UPCAST(SCSIDiskReq, req, req);
321
        if (r->status & SCSI_REQ_STATUS_RETRY) {
K
Kevin Wolf 已提交
322
            int status = r->status;
323

K
Kevin Wolf 已提交
324 325 326 327 328
            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:
329
                scsi_read_data(&r->req);
K
Kevin Wolf 已提交
330 331
                break;
            case SCSI_REQ_STATUS_RETRY_WRITE:
332
                scsi_write_data(&r->req);
K
Kevin Wolf 已提交
333
                break;
334
            case SCSI_REQ_STATUS_RETRY_FLUSH:
P
Paolo Bonzini 已提交
335 336
                scsi_send_command(&r->req, r->req.cmd.buf);
                break;
K
Kevin Wolf 已提交
337
            }
338 339 340 341
        }
    }
}

342
static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
343
{
344
    SCSIDiskState *s = opaque;
345

346
    if (!running) {
347
        return;
348
    }
349 350 351 352 353 354
    if (!s->bh) {
        s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
        qemu_bh_schedule(s->bh);
    }
}

P
pbrook 已提交
355
/* Return a pointer to the data buffer.  */
356
static uint8_t *scsi_get_buf(SCSIRequest *req)
P
pbrook 已提交
357
{
358
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
P
pbrook 已提交
359

360
    return (uint8_t *)r->iov.iov_base;
P
pbrook 已提交
361 362
}

363 364
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
{
G
Gerd Hoffmann 已提交
365
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
    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;
        }

383
        outbuf[buflen++] = s->qdev.type & 0x1f;
384 385 386 387 388
        outbuf[buflen++] = page_code ; // this page
        outbuf[buflen++] = 0x00;

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

410 411 412 413 414 415
            if (!s->serial) {
                DPRINTF("Inquiry (EVPD[Serial number] not supported\n");
                return -1;
            }

            l = strlen(s->serial);
416
            if (l > req->cmd.xfer) {
417
                l = req->cmd.xfer;
418 419
            }
            if (l > 20) {
420
                l = 20;
421
            }
422 423 424 425

            DPRINTF("Inquiry EVPD[Serial number] "
                    "buffer size %zd\n", req->cmd.xfer);
            outbuf[buflen++] = l;
426
            memcpy(outbuf+buflen, s->serial, l);
427 428 429 430 431 432 433
            buflen += l;
            break;
        }

        case 0x83: /* Device identification page, mandatory */
        {
            int max_len = 255 - 8;
434
            int id_len = strlen(bdrv_get_device_name(s->qdev.conf.bs));
435

436
            if (id_len > max_len) {
437
                id_len = max_len;
438
            }
439 440 441
            DPRINTF("Inquiry EVPD[Device identification] "
                    "buffer size %zd\n", req->cmd.xfer);

H
Hannes Reinecke 已提交
442
            outbuf[buflen++] = 4 + id_len;
443 444 445 446 447
            outbuf[buflen++] = 0x2; // ASCII
            outbuf[buflen++] = 0;   // not officially assigned
            outbuf[buflen++] = 0;   // reserved
            outbuf[buflen++] = id_len; // length of data following

448
            memcpy(outbuf+buflen, bdrv_get_device_name(s->qdev.conf.bs), id_len);
449 450 451
            buflen += id_len;
            break;
        }
452
        case 0xb0: /* block limits */
C
Christoph Hellwig 已提交
453
        {
454 455
            unsigned int unmap_sectors =
                    s->qdev.conf.discard_granularity / s->qdev.blocksize;
456 457 458 459
            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 已提交
460

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

            /* 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 已提交
495 496
            break;
        }
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
        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;
521
    if (buflen > SCSI_MAX_INQUIRY_LEN) {
522
        buflen = SCSI_MAX_INQUIRY_LEN;
523
    }
524 525
    memset(outbuf, 0, buflen);

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

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

553
    /* Sync data transfer and TCQ.  */
554
    outbuf[7] = 0x10 | (req->bus->info->tcq ? 0x02 : 0);
555 556 557
    return buflen;
}

558 559 560 561 562 563
static inline bool media_is_dvd(SCSIDiskState *s)
{
    uint64_t nb_sectors;
    if (s->qdev.type != TYPE_ROM) {
        return false;
    }
564
    if (!bdrv_is_inserted(s->qdev.conf.bs)) {
565 566
        return false;
    }
567
    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
568 569 570
    return nb_sectors > CD_MAX_SECTORS;
}

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

584 585 586
static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
                                   uint8_t *outbuf)
{
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
    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) {
608
        if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
            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;
        }
630
        bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
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

        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:
675 676 677
    return -1;
}

678
static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf)
679
{
680 681 682 683 684
    uint8_t event_code, media_status;

    media_status = 0;
    if (s->tray_open) {
        media_status = MS_TRAY_OPEN;
685
    } else if (bdrv_is_inserted(s->qdev.conf.bs)) {
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
        media_status = MS_MEDIA_PRESENT;
    }

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

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

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

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

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

732
static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
733
{
734 735
    int current;

736 737 738
    if (s->qdev.type != TYPE_ROM) {
        return -1;
    }
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
    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;
764 765 766 767 768 769 770 771 772 773 774 775
}

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

776
static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
777
                           int page_control)
778
{
779 780 781 782
    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),
783 784
        [MODE_PAGE_R_W_ERROR]              = (1 << TYPE_DISK) | (1 << TYPE_ROM),
        [MODE_PAGE_AUDIO_CTL]              = (1 << TYPE_ROM),
785 786 787
        [MODE_PAGE_CAPABILITIES]           = (1 << TYPE_ROM),
    };

788
    BlockDriverState *bdrv = s->qdev.conf.bs;
789
    int cylinders, heads, secs;
790
    uint8_t *p = *p_outbuf;
791

792 793 794 795 796 797
    if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) {
        return -1;
    }

    p[0] = page;

798 799 800 801 802 803
    /*
     * 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.
     */
804
    switch (page) {
805
    case MODE_PAGE_HD_GEOMETRY:
806
        p[1] = 0x16;
807
        if (page_control == 1) { /* Changeable Values */
808
            break;
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
        /* 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;
834
        break;
835

836
    case MODE_PAGE_FLEXIBLE_DISK_GEOMETRY:
837
        p[1] = 0x1e;
838
        if (page_control == 1) { /* Changeable Values */
839
            break;
840
        }
841 842 843 844 845 846 847
        /* 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
Paolo Bonzini 已提交
848
        p[6] = s->qdev.blocksize >> 8;
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871
        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;
872
        break;
873

874
    case MODE_PAGE_CACHING:
875 876
        p[0] = 8;
        p[1] = 0x12;
877
        if (page_control == 1) { /* Changeable Values */
878
            break;
879
        }
880
        if (bdrv_enable_write_cache(s->qdev.conf.bs)) {
881 882
            p[2] = 4; /* WCE */
        }
883
        break;
884

885 886 887 888 889 890 891 892 893 894 895 896
    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;

897
    case MODE_PAGE_CAPABILITIES:
898
        p[1] = 0x14;
899
        if (page_control == 1) { /* Changeable Values */
900
            break;
901
        }
902 903 904

        p[2] = 0x3b; /* CD-R & CD-RW read */
        p[3] = 0; /* Writing not supported */
905 906 907 908 909
        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 */
910
        p[6] = 0x2d | (s->tray_locked ? 2 : 0);
911 912 913
        /* Locking supported, jumper present, eject, tray */
        p[7] = 0; /* no volume & mute control, no
                     changer */
914
        p[8] = (50 * 176) >> 8; /* 50x read speed */
915
        p[9] = (50 * 176) & 0xff;
916 917 918
        p[10] = 2 >> 8; /* Two volume levels */
        p[11] = 2 & 0xff;
        p[12] = 2048 >> 8; /* 2M buffer */
919
        p[13] = 2048 & 0xff;
920
        p[14] = (16 * 176) >> 8; /* 16x read speed current */
921
        p[15] = (16 * 176) & 0xff;
922
        p[18] = (16 * 176) >> 8; /* 16x write speed */
923
        p[19] = (16 * 176) & 0xff;
924
        p[20] = (16 * 176) >> 8; /* 16x write speed current */
925
        p[21] = (16 * 176) & 0xff;
926
        break;
927 928

    default:
929
        return -1;
930
    }
931 932 933

    *p_outbuf += p[1] + 2;
    return p[1] + 2;
934 935
}

936
static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
937
{
938
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
939
    uint64_t nb_sectors;
940
    int page, dbd, buflen, ret, page_control;
941
    uint8_t *p;
942
    uint8_t dev_specific_param;
943

944 945 946
    dbd = r->req.cmd.buf[1]  & 0x8;
    page = r->req.cmd.buf[2] & 0x3f;
    page_control = (r->req.cmd.buf[2] & 0xc0) >> 6;
947
    DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
948 949
        (r->req.cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, r->req.cmd.xfer, page_control);
    memset(outbuf, 0, r->req.cmd.xfer);
950 951
    p = outbuf;

952
    if (bdrv_is_read_only(s->qdev.conf.bs)) {
953 954 955 956 957
        dev_specific_param = 0x80; /* Readonly.  */
    } else {
        dev_specific_param = 0x00;
    }

958
    if (r->req.cmd.buf[0] == MODE_SENSE) {
959 960 961 962 963 964 965 966 967
        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;
968 969
    }

970
    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
971
    if (!dbd && nb_sectors) {
972
        if (r->req.cmd.buf[0] == MODE_SENSE) {
973 974 975 976
            outbuf[3] = 8; /* Block descriptor length  */
        } else { /* MODE_SENSE_10 */
            outbuf[7] = 8; /* Block descriptor length  */
        }
P
Paolo Bonzini 已提交
977
        nb_sectors /= (s->qdev.blocksize / 512);
978
        if (nb_sectors > 0xffffff) {
979
            nb_sectors = 0;
980
        }
981 982 983 984 985 986
        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
Paolo Bonzini 已提交
987
        p[6] = s->qdev.blocksize >> 8;
988 989 990 991
        p[7] = 0;
        p += 8;
    }

992 993 994 995
    if (page_control == 3) {
        /* Saved Values */
        scsi_check_condition(r, SENSE_CODE(SAVING_PARAMS_NOT_SUPPORTED));
        return -1;
996 997
    }

998 999 1000 1001 1002 1003 1004 1005 1006
    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;
        }
1007 1008 1009
    }

    buflen = p - outbuf;
1010 1011 1012 1013 1014
    /*
     * 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.
     */
1015
    if (r->req.cmd.buf[0] == MODE_SENSE) {
1016 1017 1018 1019 1020
        outbuf[0] = buflen - 1;
    } else { /* MODE_SENSE_10 */
        outbuf[0] = ((buflen - 2) >> 8) & 0xff;
        outbuf[1] = (buflen - 2) & 0xff;
    }
1021
    if (buflen > r->req.cmd.xfer) {
1022
        buflen = r->req.cmd.xfer;
1023
    }
1024 1025 1026
    return buflen;
}

1027 1028 1029 1030 1031 1032 1033 1034 1035
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];
1036
    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
1037
    DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
P
Paolo Bonzini 已提交
1038
    nb_sectors /= s->qdev.blocksize / 512;
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
    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;
    }
1057
    if (toclen > req->cmd.xfer) {
1058
        toclen = req->cmd.xfer;
1059
    }
1060 1061 1062
    return toclen;
}

1063
static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
1064 1065 1066 1067 1068 1069 1070
{
    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) {
1071 1072
        if (!start && !s->tray_open && s->tray_locked) {
            scsi_check_condition(r,
1073
                                 bdrv_is_inserted(s->qdev.conf.bs)
1074 1075 1076
                                 ? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED)
                                 : SENSE_CODE(NOT_READY_REMOVAL_PREVENTED));
            return -1;
1077
        }
1078
        bdrv_eject(s->qdev.conf.bs, !start);
1079
        s->tray_open = !start;
1080
    }
1081
    return 0;
1082 1083
}

1084
static int scsi_disk_emulate_command(SCSIDiskReq *r)
1085
{
1086
    SCSIRequest *req = &r->req;
1087 1088
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
    uint64_t nb_sectors;
1089
    uint8_t *outbuf;
1090 1091
    int buflen = 0;

1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
    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);
1105
        r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
1106 1107 1108
    }

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

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

1253 1254 1255 1256 1257 1258
            /* Protection, exponent and lowest lba field left blank. */
            buflen = req->cmd.xfer;
            break;
        }
        DPRINTF("Unsupported Service Action In\n");
        goto illegal_request;
1259
    case VERIFY_10:
1260
        break;
1261
    default:
1262
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1263
        return -1;
1264 1265 1266 1267
    }
    return buflen;

not_ready:
1268
    if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
1269
        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
1270
    } else {
1271
        scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
1272
    }
1273
    return -1;
1274 1275

illegal_request:
1276 1277 1278
    if (r->req.status == -1) {
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
    }
1279
    return -1;
1280 1281
}

P
pbrook 已提交
1282 1283 1284 1285 1286
/* 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.  */

1287
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
P
pbrook 已提交
1288
{
1289 1290
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
P
Paolo Bonzini 已提交
1291
    int32_t len;
P
pbrook 已提交
1292
    uint8_t command;
1293
    int rc;
P
pbrook 已提交
1294 1295

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

P
pbrook 已提交
1298 1299 1300
#ifdef DEBUG_SCSI
    {
        int i;
1301
        for (i = 1; i < r->req.cmd.len; i++) {
P
pbrook 已提交
1302 1303 1304 1305 1306
            printf(" 0x%02x", buf[i]);
        }
        printf("\n");
    }
#endif
1307

P
pbrook 已提交
1308
    switch (command) {
1309
    case TEST_UNIT_READY:
1310
    case INQUIRY:
1311 1312
    case MODE_SENSE:
    case MODE_SENSE_10:
1313 1314 1315 1316
    case RESERVE:
    case RESERVE_10:
    case RELEASE:
    case RELEASE_10:
1317
    case START_STOP:
1318
    case ALLOW_MEDIUM_REMOVAL:
1319
    case READ_CAPACITY_10:
1320
    case READ_TOC:
1321
    case READ_DVD_STRUCTURE:
1322
    case GET_CONFIGURATION:
1323 1324
    case GET_EVENT_STATUS_NOTIFICATION:
    case MECHANISM_STATUS:
1325
    case SERVICE_ACTION_IN_16:
1326
    case VERIFY_10:
1327
        rc = scsi_disk_emulate_command(r);
1328
        if (rc < 0) {
1329
            return 0;
1330
        }
1331 1332

        r->iov.iov_len = rc;
1333
        break;
1334
    case SYNCHRONIZE_CACHE:
1335 1336
        bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
        r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_flush_complete, r);
1337 1338 1339 1340
        if (r->req.aiocb == NULL) {
            scsi_flush_complete(r, -EIO);
        }
        return 0;
1341 1342
    case READ_6:
    case READ_10:
G
Gerd Hoffmann 已提交
1343 1344
    case READ_12:
    case READ_16:
1345
        len = r->req.cmd.xfer / s->qdev.blocksize;
1346
        DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
P
Paolo Bonzini 已提交
1347
        if (r->req.cmd.lba > s->qdev.max_lba) {
1348
            goto illegal_lba;
1349
        }
P
Paolo Bonzini 已提交
1350 1351
        r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
        r->sector_count = len * (s->qdev.blocksize / 512);
P
pbrook 已提交
1352
        break;
1353 1354
    case WRITE_6:
    case WRITE_10:
G
Gerd Hoffmann 已提交
1355 1356
    case WRITE_12:
    case WRITE_16:
1357
    case WRITE_VERIFY_10:
1358 1359
    case WRITE_VERIFY_12:
    case WRITE_VERIFY_16:
1360
        len = r->req.cmd.xfer / s->qdev.blocksize;
1361
        DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
1362 1363
                (command & 0xe) == 0xe ? "And Verify " : "",
                r->req.cmd.lba, len);
P
Paolo Bonzini 已提交
1364
        if (r->req.cmd.lba > s->qdev.max_lba) {
1365
            goto illegal_lba;
1366
        }
P
Paolo Bonzini 已提交
1367 1368
        r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
        r->sector_count = len * (s->qdev.blocksize / 512);
P
pbrook 已提交
1369
        break;
1370
    case MODE_SELECT:
1371
        DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
1372 1373
        /* We don't support mode parameter changes.
           Allow the mode parameter header + block descriptors only. */
1374
        if (r->req.cmd.xfer > 12) {
1375 1376 1377 1378
            goto fail;
        }
        break;
    case MODE_SELECT_10:
1379
        DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
1380 1381
        /* We don't support mode parameter changes.
           Allow the mode parameter header + block descriptors only. */
1382
        if (r->req.cmd.xfer > 16) {
1383 1384 1385 1386 1387
            goto fail;
        }
        break;
    case SEEK_6:
    case SEEK_10:
1388 1389
        DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
                r->req.cmd.lba);
P
Paolo Bonzini 已提交
1390
        if (r->req.cmd.lba > s->qdev.max_lba) {
1391 1392
            goto illegal_lba;
        }
1393 1394
        break;
    case WRITE_SAME_16:
1395
        len = r->req.cmd.xfer / s->qdev.blocksize;
1396 1397 1398 1399

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

P
Paolo Bonzini 已提交
1400
        if (r->req.cmd.lba > s->qdev.max_lba) {
1401 1402 1403 1404 1405 1406 1407 1408 1409 1410
            goto illegal_lba;
        }

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

P
Paolo Bonzini 已提交
1411 1412 1413
        rc = bdrv_discard(s->qdev.conf.bs,
                          r->req.cmd.lba * (s->qdev.blocksize / 512),
                          len * (s->qdev.blocksize / 512));
1414 1415 1416 1417 1418
        if (rc < 0) {
            /* XXX: better error code ?*/
            goto fail;
        }

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

J
Jan Kiszka 已提交
1447 1448 1449 1450 1451
static void scsi_disk_reset(DeviceState *dev)
{
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
    uint64_t nb_sectors;

1452
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
J
Jan Kiszka 已提交
1453

1454
    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
P
Paolo Bonzini 已提交
1455
    nb_sectors /= s->qdev.blocksize / 512;
J
Jan Kiszka 已提交
1456 1457 1458
    if (nb_sectors) {
        nb_sectors--;
    }
P
Paolo Bonzini 已提交
1459
    s->qdev.max_lba = nb_sectors;
J
Jan Kiszka 已提交
1460 1461 1462 1463 1464 1465
}

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

1466
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
1467
    blockdev_mark_auto_del(s->qdev.conf.bs);
G
Gerd Hoffmann 已提交
1468 1469
}

1470
static void scsi_cd_change_media_cb(void *opaque, bool load)
1471
{
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486
    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);
1487
    s->media_event = true;
1488 1489
}

1490 1491 1492 1493 1494
static bool scsi_cd_is_tray_open(void *opaque)
{
    return ((SCSIDiskState *)opaque)->tray_open;
}

1495 1496 1497 1498 1499 1500
static bool scsi_cd_is_medium_locked(void *opaque)
{
    return ((SCSIDiskState *)opaque)->tray_locked;
}

static const BlockDevOps scsi_cd_block_ops = {
1501
    .change_media_cb = scsi_cd_change_media_cb,
1502
    .is_tray_open = scsi_cd_is_tray_open,
1503 1504 1505
    .is_medium_locked = scsi_cd_is_medium_locked,
};

1506 1507 1508 1509 1510 1511 1512 1513 1514
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);
    }
}

1515
static int scsi_initfn(SCSIDevice *dev)
P
pbrook 已提交
1516
{
1517
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1518
    DriveInfo *dinfo;
P
pbrook 已提交
1519

1520
    if (!s->qdev.conf.bs) {
1521
        error_report("scsi-disk: drive property not set");
1522 1523 1524
        return -1;
    }

1525
    if (!s->removable && !bdrv_is_inserted(s->qdev.conf.bs)) {
1526 1527 1528 1529
        error_report("Device needs media, but drive is empty");
        return -1;
    }

1530
    if (!s->serial) {
1531
        /* try to fall back to value set with legacy -drive serial=... */
1532
        dinfo = drive_get_by_blockdev(s->qdev.conf.bs);
1533
        if (*dinfo->serial) {
1534
            s->serial = g_strdup(dinfo->serial);
1535
        }
1536 1537
    }

1538
    if (!s->version) {
1539
        s->version = g_strdup(QEMU_VERSION);
1540 1541
    }

1542
    if (bdrv_is_sg(s->qdev.conf.bs)) {
1543
        error_report("scsi-disk: unwanted /dev/sg*");
1544 1545 1546
        return -1;
    }

1547
    if (s->removable) {
1548
        bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_cd_block_ops, s);
P
pbrook 已提交
1549
    }
1550
    bdrv_set_buffer_alignment(s->qdev.conf.bs, s->qdev.blocksize);
1551

1552
    qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
1553
    bdrv_iostatus_enable(s->qdev.conf.bs);
1554
    add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
1555 1556 1557
    return 0;
}

1558 1559
static int scsi_hd_initfn(SCSIDevice *dev)
{
1560 1561 1562 1563
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
    s->qdev.blocksize = s->qdev.conf.logical_block_size;
    s->qdev.type = TYPE_DISK;
    return scsi_initfn(&s->qdev);
1564 1565 1566 1567
}

static int scsi_cd_initfn(SCSIDevice *dev)
{
1568 1569 1570 1571 1572
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
    s->qdev.blocksize = 2048;
    s->qdev.type = TYPE_ROM;
    s->removable = true;
    return scsi_initfn(&s->qdev);
1573 1574 1575 1576
}

static int scsi_disk_initfn(SCSIDevice *dev)
{
1577
    DriveInfo *dinfo;
1578 1579

    if (!dev->conf.bs) {
1580
        return scsi_initfn(dev);  /* ... and die there */
1581 1582
    }

1583 1584 1585 1586 1587 1588
    dinfo = drive_get_by_blockdev(dev->conf.bs);
    if (dinfo->media_cd) {
        return scsi_cd_initfn(dev);
    } else {
        return scsi_hd_initfn(dev);
    }
1589 1590
}

P
Paolo Bonzini 已提交
1591
static const SCSIReqOps scsi_disk_reqops = {
P
Paolo Bonzini 已提交
1592
    .size         = sizeof(SCSIDiskReq),
1593 1594 1595 1596 1597 1598
    .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 已提交
1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610
};

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

1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
#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,
1625
        .alloc_req    = scsi_new_request,
1626
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639
        .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,
1640
        .alloc_req    = scsi_new_request,
1641
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653
        .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,
1654
        .alloc_req    = scsi_new_request,
1655
        .unit_attention_reported = scsi_disk_unit_attention_reported,
1656 1657 1658 1659 1660 1661
        .qdev.props   = (Property[]) {
            DEFINE_SCSI_DISK_PROPERTIES(),
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
            DEFINE_PROP_END_OF_LIST(),
        }
    }
1662 1663 1664 1665
};

static void scsi_disk_register_devices(void)
{
1666 1667 1668 1669 1670
    int i;

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