Revision b443ae67 hw/scsi-disk.c

b/hw/scsi-disk.c
65 65
    uint32_t status;
66 66
} SCSIDiskReq;
67 67

  
68
typedef enum { SCSI_HD, SCSI_CD } SCSIDriveKind;
69

  
68 70
struct SCSIDiskState
69 71
{
70 72
    SCSIDevice qdev;
......
78 80
    char *version;
79 81
    char *serial;
80 82
    SCSISense sense;
83
    SCSIDriveKind drive_kind;
81 84
};
82 85

  
83 86
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
......
406 409
            return -1;
407 410
        }
408 411

  
409
        if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
412
        if (s->drive_kind == SCSI_CD) {
410 413
            outbuf[buflen++] = 5;
411 414
        } else {
412 415
            outbuf[buflen++] = 0;
......
424 427
            outbuf[buflen++] = 0x00; // list of supported pages (this page)
425 428
            outbuf[buflen++] = 0x80; // unit serial number
426 429
            outbuf[buflen++] = 0x83; // device identification
427
            if (bdrv_get_type_hint(s->bs) != BDRV_TYPE_CDROM) {
430
            if (s->drive_kind == SCSI_HD) {
428 431
                outbuf[buflen++] = 0xb0; // block limits
429 432
                outbuf[buflen++] = 0xb2; // thin provisioning
430 433
            }
......
477 480
            unsigned int opt_io_size =
478 481
                    s->qdev.conf.opt_io_size / s->qdev.blocksize;
479 482

  
480
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
483
            if (s->drive_kind == SCSI_CD) {
481 484
                DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
482 485
                        page_code);
483 486
                return -1;
......
547 550
        return buflen;
548 551
    }
549 552

  
550
    if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
553
    if (s->drive_kind == SCSI_CD) {
551 554
        outbuf[0] = 5;
552 555
        outbuf[1] = 0x80;
553 556
        memcpy(&outbuf[16], "QEMU CD-ROM     ", 16);
......
678 681
        return p[1] + 2;
679 682

  
680 683
    case 0x2a: /* CD Capabilities and Mechanical Status page. */
681
        if (bdrv_get_type_hint(bdrv) != BDRV_TYPE_CDROM)
684
        if (s->drive_kind != SCSI_CD)
682 685
            return 0;
683 686
        p[0] = 0x2a;
684 687
        p[1] = 0x14;
......
905 908
            goto illegal_request;
906 909
        break;
907 910
    case START_STOP:
908
        if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) {
911
        if (s->drive_kind == SCSI_CD && (req->cmd.buf[4] & 2)) {
909 912
            /* load/eject medium */
910 913
            bdrv_eject(s->bs, !(req->cmd.buf[4] & 1));
911 914
        }
......
1232 1235
    blockdev_mark_auto_del(s->qdev.conf.bs);
1233 1236
}
1234 1237

  
1235
static int scsi_disk_initfn(SCSIDevice *dev)
1238
static int scsi_initfn(SCSIDevice *dev, SCSIDriveKind kind)
1236 1239
{
1237 1240
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1238
    int is_cd;
1239 1241
    DriveInfo *dinfo;
1240 1242

  
1241 1243
    if (!s->qdev.conf.bs) {
......
1243 1245
        return -1;
1244 1246
    }
1245 1247
    s->bs = s->qdev.conf.bs;
1246
    is_cd = bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM;
1248
    s->drive_kind = kind;
1247 1249

  
1248
    if (!is_cd && !bdrv_is_inserted(s->bs)) {
1250
    if (kind == SCSI_HD && !bdrv_is_inserted(s->bs)) {
1249 1251
        error_report("Device needs media, but drive is empty");
1250 1252
        return -1;
1251 1253
    }
......
1265 1267
        return -1;
1266 1268
    }
1267 1269

  
1268
    if (is_cd) {
1270
    if (kind == SCSI_CD) {
1269 1271
        s->qdev.blocksize = 2048;
1270 1272
    } else {
1271 1273
        s->qdev.blocksize = s->qdev.conf.logical_block_size;
......
1275 1277

  
1276 1278
    s->qdev.type = TYPE_DISK;
1277 1279
    qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
1278
    bdrv_set_removable(s->bs, is_cd);
1280
    bdrv_set_removable(s->bs, kind == SCSI_CD);
1279 1281
    add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
1280 1282
    return 0;
1281 1283
}
1282 1284

  
1283
static SCSIDeviceInfo scsi_disk_info = {
1284
    .qdev.name    = "scsi-disk",
1285
    .qdev.fw_name = "disk",
1286
    .qdev.desc    = "virtual scsi disk or cdrom",
1287
    .qdev.size    = sizeof(SCSIDiskState),
1288
    .qdev.reset   = scsi_disk_reset,
1289
    .init         = scsi_disk_initfn,
1290
    .destroy      = scsi_destroy,
1291
    .send_command = scsi_send_command,
1292
    .read_data    = scsi_read_data,
1293
    .write_data   = scsi_write_data,
1294
    .cancel_io    = scsi_cancel_io,
1295
    .get_buf      = scsi_get_buf,
1296
    .qdev.props   = (Property[]) {
1297
        DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),
1298
        DEFINE_PROP_STRING("ver",  SCSIDiskState, version),
1299
        DEFINE_PROP_STRING("serial",  SCSIDiskState, serial),
1300
        DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1301
        DEFINE_PROP_END_OF_LIST(),
1302
    },
1285
static int scsi_hd_initfn(SCSIDevice *dev)
1286
{
1287
    return scsi_initfn(dev, SCSI_HD);
1288
}
1289

  
1290
static int scsi_cd_initfn(SCSIDevice *dev)
1291
{
1292
    return scsi_initfn(dev, SCSI_CD);
1293
}
1294

  
1295
static int scsi_disk_initfn(SCSIDevice *dev)
1296
{
1297
    SCSIDriveKind kind;
1298

  
1299
    if (!dev->conf.bs) {
1300
        kind = SCSI_HD;         /* will die in scsi_initfn() */
1301
    } else {
1302
        kind = bdrv_get_type_hint(dev->conf.bs) == BDRV_TYPE_CDROM
1303
            ? SCSI_CD : SCSI_HD;
1304
    }
1305

  
1306
    return scsi_initfn(dev, kind);
1307
}
1308

  
1309
#define DEFINE_SCSI_DISK_PROPERTIES()                           \
1310
    DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),          \
1311
    DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
1312
    DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)
1313

  
1314
static SCSIDeviceInfo scsi_disk_info[] = {
1315
    {
1316
        .qdev.name    = "scsi-hd",
1317
        .qdev.fw_name = "disk",
1318
        .qdev.desc    = "virtual SCSI disk",
1319
        .qdev.size    = sizeof(SCSIDiskState),
1320
        .qdev.reset   = scsi_disk_reset,
1321
        .init         = scsi_hd_initfn,
1322
        .destroy      = scsi_destroy,
1323
        .send_command = scsi_send_command,
1324
        .read_data    = scsi_read_data,
1325
        .write_data   = scsi_write_data,
1326
        .cancel_io    = scsi_cancel_io,
1327
        .get_buf      = scsi_get_buf,
1328
        .qdev.props   = (Property[]) {
1329
            DEFINE_SCSI_DISK_PROPERTIES(),
1330
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1331
            DEFINE_PROP_END_OF_LIST(),
1332
        }
1333
    },{
1334
        .qdev.name    = "scsi-cd",
1335
        .qdev.fw_name = "disk",
1336
        .qdev.desc    = "virtual SCSI CD-ROM",
1337
        .qdev.size    = sizeof(SCSIDiskState),
1338
        .qdev.reset   = scsi_disk_reset,
1339
        .init         = scsi_cd_initfn,
1340
        .destroy      = scsi_destroy,
1341
        .send_command = scsi_send_command,
1342
        .read_data    = scsi_read_data,
1343
        .write_data   = scsi_write_data,
1344
        .cancel_io    = scsi_cancel_io,
1345
        .get_buf      = scsi_get_buf,
1346
        .qdev.props   = (Property[]) {
1347
            DEFINE_SCSI_DISK_PROPERTIES(),
1348
            DEFINE_PROP_END_OF_LIST(),
1349
        },
1350
    },{
1351
        .qdev.name    = "scsi-disk", /* legacy -device scsi-disk */
1352
        .qdev.fw_name = "disk",
1353
        .qdev.desc    = "virtual SCSI disk or CD-ROM (legacy)",
1354
        .qdev.size    = sizeof(SCSIDiskState),
1355
        .qdev.reset   = scsi_disk_reset,
1356
        .init         = scsi_disk_initfn,
1357
        .destroy      = scsi_destroy,
1358
        .send_command = scsi_send_command,
1359
        .read_data    = scsi_read_data,
1360
        .write_data   = scsi_write_data,
1361
        .cancel_io    = scsi_cancel_io,
1362
        .get_buf      = scsi_get_buf,
1363
        .qdev.props   = (Property[]) {
1364
            DEFINE_SCSI_DISK_PROPERTIES(),
1365
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1366
            DEFINE_PROP_END_OF_LIST(),
1367
        }
1368
    }
1303 1369
};
1304 1370

  
1305 1371
static void scsi_disk_register_devices(void)
1306 1372
{
1307
    scsi_qdev_register(&scsi_disk_info);
1373
    int i;
1374

  
1375
    for (i = 0; i < ARRAY_SIZE(scsi_disk_info); i++) {
1376
        scsi_qdev_register(&scsi_disk_info[i]);
1377
    }
1308 1378
}
1309 1379
device_init(scsi_disk_register_devices)

Also available in: Unified diff