示例#1
0
static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOBlock *s = VIRTIO_BLK(dev);
    VirtIOBlkConf *blk = &(s->blk);
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
    Error *err = NULL;
#endif
    static int virtio_blk_id;

    if (!blk->conf.bs) {
        error_setg(errp, "drive property not set");
        return;
    }
    if (!bdrv_is_inserted(blk->conf.bs)) {
        error_setg(errp, "Device needs media, but drive is empty");
        return;
    }

    blkconf_serial(&blk->conf, &blk->serial);
    s->original_wce = bdrv_enable_write_cache(blk->conf.bs);
    if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
        error_setg(errp, "Error setting geometry");
        return;
    }

    virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
                sizeof(struct virtio_blk_config));

    s->bs = blk->conf.bs;
    s->conf = &blk->conf;
    s->rq = NULL;
    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;

    s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
    s->complete_request = virtio_blk_complete_request;
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
    virtio_blk_data_plane_create(vdev, blk, &s->dataplane, &err);
    if (err != NULL) {
        error_propagate(errp, err);
        virtio_cleanup(vdev);
        return;
    }
    s->migration_state_notifier.notify = virtio_blk_migration_state_changed;
    add_migration_state_change_notifier(&s->migration_state_notifier);
#endif

    s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
    register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
                    virtio_blk_save, virtio_blk_load, s);
    bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
    bdrv_set_guest_block_size(s->bs, s->conf->logical_block_size);

    bdrv_iostatus_enable(s->bs);

    add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
}
示例#2
0
文件: palm.c 项目: hackndev/qemu
static void ld_microdrive_attach(struct pxa2xx_state_s *cpu)
{
    struct pcmcia_card_s *md;
    BlockDriverState *bs = bs_table[0];

    if (bs && bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
        md = dscm1xxxx_init(bs);
        pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
    }
}
示例#3
0
static int virtio_blk_device_init(VirtIODevice *vdev)
{
    DeviceState *qdev = DEVICE(vdev);
    VirtIOBlock *s = VIRTIO_BLK(vdev);
    VirtIOBlkConf *blk = &(s->blk);
    static int virtio_blk_id;

    if (!blk->conf.bs) {
        error_report("drive property not set");
        return -1;
    }
    if (!bdrv_is_inserted(blk->conf.bs)) {
        error_report("Device needs media, but drive is empty");
        return -1;
    }

    blkconf_serial(&blk->conf, &blk->serial);
    if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
        return -1;
    }

    virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
                sizeof(struct virtio_blk_config));

    vdev->get_config = virtio_blk_update_config;
    vdev->set_config = virtio_blk_set_config;
    vdev->get_features = virtio_blk_get_features;
    vdev->set_status = virtio_blk_set_status;
    vdev->reset = virtio_blk_reset;
    s->bs = blk->conf.bs;
    s->conf = &blk->conf;
    memcpy(&(s->blk), blk, sizeof(struct VirtIOBlkConf));
    s->rq = NULL;
    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;

    s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
    if (!virtio_blk_data_plane_create(vdev, blk, &s->dataplane)) {
        virtio_common_cleanup(vdev);
        return -1;
    }
#endif

    s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
    register_savevm(qdev, "virtio-blk", virtio_blk_id++, 2,
                    virtio_blk_save, virtio_blk_load, s);
    bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
    bdrv_set_buffer_alignment(s->bs, s->conf->logical_block_size);

    bdrv_iostatus_enable(s->bs);

    add_boot_device_path(s->conf->bootindex, qdev, "/disk@0,0");
    return 0;
}
示例#4
0
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
                              char **serial)
{
    VirtIOBlock *s;
    int cylinders, heads, secs;
    static int virtio_blk_id;
    DriveInfo *dinfo;

    if (!conf->bs) {
        error_report("virtio-blk-pci: drive property not set");
        return NULL;
    }
    if (!bdrv_is_inserted(conf->bs)) {
        error_report("Device needs media, but drive is empty");
        return NULL;
    }

    if (!*serial) {
        /* try to fall back to value set with legacy -drive serial=... */
        dinfo = drive_get_by_blockdev(conf->bs);
        if (*dinfo->serial) {
            *serial = strdup(dinfo->serial);
        }
    }

    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                          sizeof(struct virtio_blk_config),
                                          sizeof(VirtIOBlock));

    s->vdev.get_config = virtio_blk_update_config;
    s->vdev.get_features = virtio_blk_get_features;
    s->vdev.reset = virtio_blk_reset;
    s->bs = conf->bs;
    s->conf = conf;
    s->serial = *serial;
    s->rq = NULL;
    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
    bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);

    s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);

    qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
    s->qdev = dev;
    register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
                    virtio_blk_save, virtio_blk_load, s);
    bdrv_set_removable(s->bs, 0);
    bdrv_set_change_cb(s->bs, virtio_blk_change_cb, s);
    s->bs->buffer_alignment = conf->logical_block_size;

    add_boot_device_path(conf->bootindex, dev, "/disk@0,0");

    return &s->vdev;
}
示例#5
0
static int milkymist_memcard_init(SysBusDevice *dev)
{
    MilkymistMemcardState *s = FROM_SYSBUS(typeof(*s), dev);
    DriveInfo *dinfo;

    dinfo = drive_get_next(IF_SD);
    s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
    s->enabled = dinfo ? bdrv_is_inserted(dinfo->bdrv) : 0;

    memory_region_init_io(&s->regs_region, &memcard_mmio_ops, s,
            "milkymist-memcard", R_MAX * 4);
    sysbus_init_mmio(dev, &s->regs_region);

    return 0;
}
示例#6
0
static void tosa_microdrive_attach(PXA2xxState *cpu)
{
    PCMCIACardState *md;
    BlockDriverState *bs;
    DriveInfo *dinfo;

    dinfo = drive_get(IF_IDE, 0, 0);
    if (!dinfo)
        return;
    bs = dinfo->bdrv;
    if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
        md = dscm1xxxx_init(dinfo);
        pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
    }
}
示例#7
0
static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu)
{
    struct pcmcia_card_s *md;
    int index;
    BlockDriverState *bs;

    index = drive_get_index(IF_IDE, 0, 0);
    if (index == -1)
        return;
    bs = drives_table[index].bdrv;
    if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
        md = dscm1xxxx_init(bs);
        pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
    }
}
示例#8
0
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
{
    VirtIOBlock *s;
    int cylinders, heads, secs;
    static int virtio_blk_id;
    DriveInfo *dinfo;

    if (!conf->bs) {
        error_report("virtio-blk-pci: drive property not set");
        return NULL;
    }
    if (!bdrv_is_inserted(conf->bs)) {
        error_report("Device needs media, but drive is empty");
        return NULL;
    }

    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                          sizeof(struct virtio_blk_config),
                                          sizeof(VirtIOBlock));

    s->vdev.get_config = virtio_blk_update_config;
    s->vdev.get_features = virtio_blk_get_features;
    s->vdev.reset = virtio_blk_reset;
    s->bs = conf->bs;
    s->conf = conf;
    s->rq = NULL;
    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
    bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);

    /* NB: per existing s/n string convention the string is terminated
     * by '\0' only when less than sizeof (s->sn)
     */
    dinfo = drive_get_by_blockdev(s->bs);
    strncpy(s->sn, dinfo->serial, sizeof (s->sn));

    s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);

    qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
    s->qdev = dev;
    register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
                    virtio_blk_save, virtio_blk_load, s);
    bdrv_set_removable(s->bs, 0);
    s->bs->buffer_alignment = conf->logical_block_size;

    add_boot_device_path(conf->bootindex, dev, "/disk@0,0");

    return &s->vdev;
}
示例#9
0
VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
{
    VirtIOBlock *s;
    static int virtio_blk_id;

    if (!blk->conf.bs) {
        error_report("drive property not set");
        return NULL;
    }
    if (!bdrv_is_inserted(blk->conf.bs)) {
        error_report("Device needs media, but drive is empty");
        return NULL;
    }

    blkconf_serial(&blk->conf, &blk->serial);
    if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
        return NULL;
    }

    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                          sizeof(struct virtio_blk_config),
                                          sizeof(VirtIOBlock));

    s->vdev.get_config = virtio_blk_update_config;
    s->vdev.set_config = virtio_blk_set_config;
    s->vdev.get_features = virtio_blk_get_features;
    s->vdev.set_status = virtio_blk_set_status;
    s->vdev.reset = virtio_blk_reset;
    s->bs = blk->conf.bs;
    s->conf = &blk->conf;
    s->blk = blk;
    s->rq = NULL;
    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;

    s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);

    qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
    s->qdev = dev;
    register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
                    virtio_blk_save, virtio_blk_load, s);
    bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
    bdrv_set_buffer_alignment(s->bs, s->conf->logical_block_size);

    bdrv_iostatus_enable(s->bs);
    add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");

    return &s->vdev;
}
示例#10
0
int bdrv_can_snapshot(BlockDriverState *bs)
{
    BlockDriver *drv = bs->drv;
    if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
        return 0;
    }

    if (!drv->bdrv_snapshot_create) {
        if (bs->file != NULL) {
            return bdrv_can_snapshot(bs->file->bs);
        }
        return 0;
    }

    return 1;
}
示例#11
0
bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
{
    bool ok = true;
    BlockDriverState *bs = NULL;

    while (ok && (bs = bdrv_next(bs))) {
        AioContext *ctx = bdrv_get_aio_context(bs);

        aio_context_acquire(ctx);
        if (bdrv_is_inserted(bs) && !bdrv_is_read_only(bs)) {
            ok = bdrv_can_snapshot(bs);
        }
        aio_context_release(ctx);
    }

    *first_bad_bs = bs;
    return ok;
}
示例#12
0
文件: raw.c 项目: AmesianX/qemu-kvm
static int raw_is_inserted(BlockDriverState *bs)
{
    return bdrv_is_inserted(bs->file);
}
示例#13
0
VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
{
    VirtIOBlock *s;
    int cylinders, heads, secs;
    static int virtio_blk_id;
    DriveInfo *dinfo;

    if (!blk->conf.bs) {
        error_report("drive property not set");
        return NULL;
    }
    if (!bdrv_is_inserted(blk->conf.bs)) {
        error_report("Device needs media, but drive is empty");
        return NULL;
    }

    if (!blk->serial) {
        /* try to fall back to value set with legacy -drive serial=... */
        dinfo = drive_get_by_blockdev(blk->conf.bs);
        if (*dinfo->serial) {
            blk->serial = strdup(dinfo->serial);
        }
    }

    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                          sizeof(struct virtio_blk_config),
                                          sizeof(VirtIOBlock));

    s->vdev.get_config = virtio_blk_update_config;
    s->vdev.get_features = virtio_blk_get_features;
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
    s->vdev.set_status = virtio_blk_set_status;
#endif
    s->vdev.reset = virtio_blk_reset;
    s->bs = blk->conf.bs;
    s->conf = &blk->conf;
    s->blk = blk;
    s->rq = NULL;
    s->sector_mask = (s->conf->logical_block_size / 512) - 1;
    bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
    bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);

    s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
    if (!virtio_blk_data_plane_create(&s->vdev, blk, &s->dataplane)) {
        virtio_cleanup(&s->vdev);
        return NULL;
    }
#endif

    s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
    s->qdev = dev;
    register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
                    virtio_blk_save, virtio_blk_load, s);
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
    if (s->dataplane) {
        register_device_unmigratable(dev, "virtio-blk", s);
    }
#endif
    bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
    s->bs->buffer_alignment = s->conf->logical_block_size;

    bdrv_iostatus_enable(s->bs);
    add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");

    return &s->vdev;
}