~ubuntu-branches/ubuntu/vivid/qemu-linaro/vivid

« back to all changes in this revision

Viewing changes to hw/virtio-blk.c

  • Committer: Ricardo Salveti de Araujo
  • Date: 2012-09-20 18:39:31 UTC
  • mfrom: (12922.1.2 qemu-linaro)
  • Revision ID: ricardo.salveti@linaro.org-20120920183931-sp3cg6kpdl8dmwo9
* New upstream release.
  - support emulated systems with more than 2G of memory. (LP: #1030588)
* Drop powerpc-missing-include.patch - merged upstream.
* Update debian/control:
  - drop perl build dependency.
  - add libfdt-dev build dependency.
* Update debian/qemu-keymaps.install file.
* Update debian/rules:
  - update QEMU_CPU for ARM architecture: armv4l -> armv7l.
  - update conf_audio_drv: default to PulseAudio since PA is the default on
    Ubuntu.
  - enable KVM on ARM architecture.
  - enable flat device tree support (--enable-fdt). (LP: #1030594)

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#include "qemu-common.h"
15
15
#include "qemu-error.h"
16
16
#include "trace.h"
 
17
#include "hw/block-common.h"
17
18
#include "blockdev.h"
18
19
#include "virtio-blk.h"
19
20
#include "scsi-defs.h"
29
30
    void *rq;
30
31
    QEMUBH *bh;
31
32
    BlockConf *conf;
32
 
    char *serial;
 
33
    VirtIOBlkConf *blk;
33
34
    unsigned short sector_mask;
34
35
    DeviceState *qdev;
35
36
} VirtIOBlock;
145
146
    return req;
146
147
}
147
148
 
148
 
#ifdef __linux__
149
149
static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
150
150
{
151
 
    struct sg_io_hdr hdr;
 
151
#ifdef __linux__
152
152
    int ret;
153
 
    int status;
154
153
    int i;
155
 
 
156
 
    if ((req->dev->vdev.guest_features & (1 << VIRTIO_BLK_F_SCSI)) == 0) {
157
 
        virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
158
 
        g_free(req);
159
 
        return;
160
 
    }
 
154
#endif
 
155
    int status = VIRTIO_BLK_S_OK;
161
156
 
162
157
    /*
163
158
     * We require at least one output segment each for the virtio_blk_outhdr
173
168
    }
174
169
 
175
170
    /*
176
 
     * No support for bidirection commands yet.
177
 
     */
178
 
    if (req->elem.out_num > 2 && req->elem.in_num > 3) {
179
 
        virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
180
 
        g_free(req);
181
 
        return;
182
 
    }
183
 
 
184
 
    /*
185
171
     * The scsi inhdr is placed in the second-to-last input segment, just
186
172
     * before the regular inhdr.
187
173
     */
188
174
    req->scsi = (void *)req->elem.in_sg[req->elem.in_num - 2].iov_base;
189
175
 
 
176
    if (!req->dev->blk->scsi) {
 
177
        status = VIRTIO_BLK_S_UNSUPP;
 
178
        goto fail;
 
179
    }
 
180
 
 
181
    /*
 
182
     * No support for bidirection commands yet.
 
183
     */
 
184
    if (req->elem.out_num > 2 && req->elem.in_num > 3) {
 
185
        status = VIRTIO_BLK_S_UNSUPP;
 
186
        goto fail;
 
187
    }
 
188
 
 
189
#ifdef __linux__
 
190
    struct sg_io_hdr hdr;
190
191
    memset(&hdr, 0, sizeof(struct sg_io_hdr));
191
192
    hdr.interface_id = 'S';
192
193
    hdr.cmd_len = req->elem.out_sg[1].iov_len;
230
231
    ret = bdrv_ioctl(req->dev->bs, SG_IO, &hdr);
231
232
    if (ret) {
232
233
        status = VIRTIO_BLK_S_UNSUPP;
233
 
        hdr.status = ret;
234
 
        hdr.resid = hdr.dxfer_len;
235
 
    } else if (hdr.status) {
236
 
        status = VIRTIO_BLK_S_IOERR;
237
 
    } else {
238
 
        status = VIRTIO_BLK_S_OK;
 
234
        goto fail;
239
235
    }
240
236
 
241
237
    /*
258
254
 
259
255
    virtio_blk_req_complete(req, status);
260
256
    g_free(req);
261
 
}
262
257
#else
263
 
static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
264
 
{
265
 
    virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
 
258
    abort();
 
259
#endif
 
260
 
 
261
fail:
 
262
    /* Just put anything nonzero so that the ioctl fails in the guest.  */
 
263
    stl_p(&req->scsi->errors, 255);
 
264
    virtio_blk_req_complete(req, status);
266
265
    g_free(req);
267
266
}
268
 
#endif /* __linux__ */
269
267
 
270
268
typedef struct MultiReqBuffer {
271
269
    BlockRequest        blkreq[32];
394
392
         * terminated by '\0' only when shorter than buffer.
395
393
         */
396
394
        strncpy(req->elem.in_sg[0].iov_base,
397
 
                s->serial ? s->serial : "",
 
395
                s->blk->serial ? s->blk->serial : "",
398
396
                MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
399
397
        virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
400
398
        g_free(req);
481
479
    VirtIOBlock *s = to_virtio_blk(vdev);
482
480
    struct virtio_blk_config blkcfg;
483
481
    uint64_t capacity;
484
 
    int cylinders, heads, secs;
485
482
    int blk_size = s->conf->logical_block_size;
486
483
 
487
484
    bdrv_get_geometry(s->bs, &capacity);
488
 
    bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
489
485
    memset(&blkcfg, 0, sizeof(blkcfg));
490
486
    stq_raw(&blkcfg.capacity, capacity);
491
487
    stl_raw(&blkcfg.seg_max, 128 - 2);
492
 
    stw_raw(&blkcfg.cylinders, cylinders);
 
488
    stw_raw(&blkcfg.cylinders, s->conf->cyls);
493
489
    stl_raw(&blkcfg.blk_size, blk_size);
494
490
    stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size);
495
491
    stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
496
 
    blkcfg.heads = heads;
497
 
    blkcfg.sectors = secs & ~s->sector_mask;
 
492
    blkcfg.heads = s->conf->heads;
 
493
    /*
 
494
     * We must ensure that the block device capacity is a multiple of
 
495
     * the logical block size. If that is not the case, lets use
 
496
     * sector_mask to adopt the geometry to have a correct picture.
 
497
     * For those devices where the capacity is ok for the given geometry
 
498
     * we dont touch the sector value of the geometry, since some devices
 
499
     * (like s390 dasd) need a specific value. Here the capacity is already
 
500
     * cyls*heads*secs*blk_size and the sector value is not block size
 
501
     * divided by 512 - instead it is the amount of blk_size blocks
 
502
     * per track (cylinder).
 
503
     */
 
504
    if (bdrv_getlength(s->bs) /  s->conf->heads / s->conf->secs % blk_size) {
 
505
        blkcfg.sectors = s->conf->secs & ~s->sector_mask;
 
506
    } else {
 
507
        blkcfg.sectors = s->conf->secs;
 
508
    }
498
509
    blkcfg.size_max = 0;
499
510
    blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
500
511
    blkcfg.alignment_offset = 0;
509
520
    features |= (1 << VIRTIO_BLK_F_GEOMETRY);
510
521
    features |= (1 << VIRTIO_BLK_F_TOPOLOGY);
511
522
    features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
 
523
    features |= (1 << VIRTIO_BLK_F_SCSI);
512
524
 
513
525
    if (bdrv_enable_write_cache(s->bs))
514
526
        features |= (1 << VIRTIO_BLK_F_WCACHE);
537
549
static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
538
550
{
539
551
    VirtIOBlock *s = opaque;
 
552
    int ret;
540
553
 
541
554
    if (version_id != 2)
542
555
        return -EINVAL;
543
556
 
544
 
    virtio_load(&s->vdev, f);
 
557
    ret = virtio_load(&s->vdev, f);
 
558
    if (ret) {
 
559
        return ret;
 
560
    }
 
561
 
545
562
    while (qemu_get_sbyte(f)) {
546
563
        VirtIOBlockReq *req = virtio_blk_alloc_request(s);
547
564
        qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
568
585
    .resize_cb = virtio_blk_resize,
569
586
};
570
587
 
571
 
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
572
 
                              char **serial)
 
588
VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
573
589
{
574
590
    VirtIOBlock *s;
575
 
    int cylinders, heads, secs;
576
591
    static int virtio_blk_id;
577
 
    DriveInfo *dinfo;
578
592
 
579
 
    if (!conf->bs) {
 
593
    if (!blk->conf.bs) {
580
594
        error_report("drive property not set");
581
595
        return NULL;
582
596
    }
583
 
    if (!bdrv_is_inserted(conf->bs)) {
 
597
    if (!bdrv_is_inserted(blk->conf.bs)) {
584
598
        error_report("Device needs media, but drive is empty");
585
599
        return NULL;
586
600
    }
587
601
 
588
 
    if (!*serial) {
589
 
        /* try to fall back to value set with legacy -drive serial=... */
590
 
        dinfo = drive_get_by_blockdev(conf->bs);
591
 
        if (*dinfo->serial) {
592
 
            *serial = strdup(dinfo->serial);
593
 
        }
 
602
    blkconf_serial(&blk->conf, &blk->serial);
 
603
    if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
 
604
        return NULL;
594
605
    }
595
606
 
596
607
    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
600
611
    s->vdev.get_config = virtio_blk_update_config;
601
612
    s->vdev.get_features = virtio_blk_get_features;
602
613
    s->vdev.reset = virtio_blk_reset;
603
 
    s->bs = conf->bs;
604
 
    s->conf = conf;
605
 
    s->serial = *serial;
 
614
    s->bs = blk->conf.bs;
 
615
    s->conf = &blk->conf;
 
616
    s->blk = blk;
606
617
    s->rq = NULL;
607
618
    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
608
 
    bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
609
619
 
610
620
    s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
611
621
 
614
624
    register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
615
625
                    virtio_blk_save, virtio_blk_load, s);
616
626
    bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
617
 
    bdrv_set_buffer_alignment(s->bs, conf->logical_block_size);
 
627
    bdrv_set_buffer_alignment(s->bs, s->conf->logical_block_size);
618
628
 
619
629
    bdrv_iostatus_enable(s->bs);
620
 
    add_boot_device_path(conf->bootindex, dev, "/disk@0,0");
 
630
    add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
621
631
 
622
632
    return &s->vdev;
623
633
}
626
636
{
627
637
    VirtIOBlock *s = to_virtio_blk(vdev);
628
638
    unregister_savevm(s->qdev, "virtio-blk", s);
 
639
    blockdev_mark_auto_del(s->bs);
629
640
    virtio_cleanup(vdev);
630
641
}