Пример #1
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;
}
Пример #2
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("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_dev_ops(s->bs, &virtio_block_ops, s);
    bdrv_set_buffer_alignment(s->bs, conf->logical_block_size);

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

    return &s->vdev;
}
Пример #3
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;
}
Пример #4
0
static void scsi_read_complete(void * opaque, int ret)
{
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
    SCSIDevice *s = r->req.dev;
    int len;

    r->req.aiocb = NULL;
    if (ret) {
        DPRINTF("IO error ret %d\n", ret);
        scsi_command_complete(r, ret);
        return;
    }
    len = r->io_header.dxfer_len - r->io_header.resid;
    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);

    r->len = -1;
    if (len == 0) {
        scsi_command_complete(r, 0);
    } else {
        /* Snoop READ CAPACITY output to set the blocksize.  */
        if (r->req.cmd.buf[0] == READ_CAPACITY_10) {
            s->blocksize = ldl_be_p(&r->buf[4]);
            s->max_lba = ldl_be_p(&r->buf[0]);
        } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
                   (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
            s->blocksize = ldl_be_p(&r->buf[8]);
            s->max_lba = ldq_be_p(&r->buf[0]);
        }
        bdrv_set_buffer_alignment(s->conf.bs, s->blocksize);

        scsi_req_data(&r->req, len);
        if (!r->req.io_canceled) {
            scsi_req_unref(&r->req);
        }
    }
}