diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 23:28:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 23:28:47 -0500 |
commit | b746f9c7941f227ad582b4f0bc981f3adcbc46b2 (patch) | |
tree | fe3da3dedfe8d66f90cdcfa3d9ce847fdc411c20 /drivers/block | |
parent | ce6513f758b1852a2f24f76f07d0fae304d24ad3 (diff) | |
parent | 2bf4fd31394a3f875ea093ee8a209f30b378cbf3 (diff) |
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull virtio updates from Rusty Russell:
"Nothing really exciting: some groundwork for changing virtio endian,
and some robustness fixes for broken virtio devices, plus minor
tweaks"
* tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
virtio_scsi: verify if queue is broken after virtqueue_get_buf()
x86, asmlinkage, lguest: Pass in globals into assembler statement
virtio: mmio: fix signature checking for BE guests
virtio_ring: adapt to notify() returning bool
virtio_net: verify if queue is broken after virtqueue_get_buf()
virtio_console: verify if queue is broken after virtqueue_get_buf()
virtio_blk: verify if queue is broken after virtqueue_get_buf()
virtio_ring: add new function virtqueue_is_broken()
virtio_test: verify if virtqueue_kick() succeeded
virtio_net: verify if virtqueue_kick() succeeded
virtio_ring: let virtqueue_{kick()/notify()} return a bool
virtio_ring: change host notification API
virtio_config: remove virtio_config_val
virtio: use size-based config accessors.
virtio_config: introduce size-based accessors.
virtio_ring: plug kmemleak false positive.
virtio: pm: use CONFIG_PM_SLEEP instead of CONFIG_PM
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/virtio_blk.c | 83 |
1 files changed, 37 insertions, 46 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 5cdf88b7ad9e..f3be496ac8fa 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -292,6 +292,8 @@ static void virtblk_done(struct virtqueue *vq) | |||
292 | req_done = true; | 292 | req_done = true; |
293 | } | 293 | } |
294 | } | 294 | } |
295 | if (unlikely(virtqueue_is_broken(vq))) | ||
296 | break; | ||
295 | } while (!virtqueue_enable_cb(vq)); | 297 | } while (!virtqueue_enable_cb(vq)); |
296 | /* In case queue is stopped waiting for more buffers. */ | 298 | /* In case queue is stopped waiting for more buffers. */ |
297 | if (req_done) | 299 | if (req_done) |
@@ -456,18 +458,15 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | |||
456 | static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) | 458 | static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) |
457 | { | 459 | { |
458 | struct virtio_blk *vblk = bd->bd_disk->private_data; | 460 | struct virtio_blk *vblk = bd->bd_disk->private_data; |
459 | struct virtio_blk_geometry vgeo; | ||
460 | int err; | ||
461 | 461 | ||
462 | /* see if the host passed in geometry config */ | 462 | /* see if the host passed in geometry config */ |
463 | err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY, | 463 | if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_GEOMETRY)) { |
464 | offsetof(struct virtio_blk_config, geometry), | 464 | virtio_cread(vblk->vdev, struct virtio_blk_config, |
465 | &vgeo); | 465 | geometry.cylinders, &geo->cylinders); |
466 | 466 | virtio_cread(vblk->vdev, struct virtio_blk_config, | |
467 | if (!err) { | 467 | geometry.heads, &geo->heads); |
468 | geo->heads = vgeo.heads; | 468 | virtio_cread(vblk->vdev, struct virtio_blk_config, |
469 | geo->sectors = vgeo.sectors; | 469 | geometry.sectors, &geo->sectors); |
470 | geo->cylinders = vgeo.cylinders; | ||
471 | } else { | 470 | } else { |
472 | /* some standard values, similar to sd */ | 471 | /* some standard values, similar to sd */ |
473 | geo->heads = 1 << 6; | 472 | geo->heads = 1 << 6; |
@@ -529,8 +528,7 @@ static void virtblk_config_changed_work(struct work_struct *work) | |||
529 | goto done; | 528 | goto done; |
530 | 529 | ||
531 | /* Host must always specify the capacity. */ | 530 | /* Host must always specify the capacity. */ |
532 | vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), | 531 | virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity); |
533 | &capacity, sizeof(capacity)); | ||
534 | 532 | ||
535 | /* If capacity is too big, truncate with warning. */ | 533 | /* If capacity is too big, truncate with warning. */ |
536 | if ((sector_t)capacity != capacity) { | 534 | if ((sector_t)capacity != capacity) { |
@@ -608,9 +606,9 @@ static int virtblk_get_cache_mode(struct virtio_device *vdev) | |||
608 | u8 writeback; | 606 | u8 writeback; |
609 | int err; | 607 | int err; |
610 | 608 | ||
611 | err = virtio_config_val(vdev, VIRTIO_BLK_F_CONFIG_WCE, | 609 | err = virtio_cread_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE, |
612 | offsetof(struct virtio_blk_config, wce), | 610 | struct virtio_blk_config, wce, |
613 | &writeback); | 611 | &writeback); |
614 | if (err) | 612 | if (err) |
615 | writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE); | 613 | writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE); |
616 | 614 | ||
@@ -642,7 +640,6 @@ virtblk_cache_type_store(struct device *dev, struct device_attribute *attr, | |||
642 | struct virtio_blk *vblk = disk->private_data; | 640 | struct virtio_blk *vblk = disk->private_data; |
643 | struct virtio_device *vdev = vblk->vdev; | 641 | struct virtio_device *vdev = vblk->vdev; |
644 | int i; | 642 | int i; |
645 | u8 writeback; | ||
646 | 643 | ||
647 | BUG_ON(!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_CONFIG_WCE)); | 644 | BUG_ON(!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_CONFIG_WCE)); |
648 | for (i = ARRAY_SIZE(virtblk_cache_types); --i >= 0; ) | 645 | for (i = ARRAY_SIZE(virtblk_cache_types); --i >= 0; ) |
@@ -652,11 +649,7 @@ virtblk_cache_type_store(struct device *dev, struct device_attribute *attr, | |||
652 | if (i < 0) | 649 | if (i < 0) |
653 | return -EINVAL; | 650 | return -EINVAL; |
654 | 651 | ||
655 | writeback = i; | 652 | virtio_cwrite8(vdev, offsetof(struct virtio_blk_config, wce), i); |
656 | vdev->config->set(vdev, | ||
657 | offsetof(struct virtio_blk_config, wce), | ||
658 | &writeback, sizeof(writeback)); | ||
659 | |||
660 | virtblk_update_cache_mode(vdev); | 653 | virtblk_update_cache_mode(vdev); |
661 | return count; | 654 | return count; |
662 | } | 655 | } |
@@ -699,9 +692,9 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
699 | index = err; | 692 | index = err; |
700 | 693 | ||
701 | /* We need to know how many segments before we allocate. */ | 694 | /* We need to know how many segments before we allocate. */ |
702 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, | 695 | err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SEG_MAX, |
703 | offsetof(struct virtio_blk_config, seg_max), | 696 | struct virtio_blk_config, seg_max, |
704 | &sg_elems); | 697 | &sg_elems); |
705 | 698 | ||
706 | /* We need at least one SG element, whatever they say. */ | 699 | /* We need at least one SG element, whatever they say. */ |
707 | if (err || !sg_elems) | 700 | if (err || !sg_elems) |
@@ -772,8 +765,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
772 | set_disk_ro(vblk->disk, 1); | 765 | set_disk_ro(vblk->disk, 1); |
773 | 766 | ||
774 | /* Host must always specify the capacity. */ | 767 | /* Host must always specify the capacity. */ |
775 | vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), | 768 | virtio_cread(vdev, struct virtio_blk_config, capacity, &cap); |
776 | &cap, sizeof(cap)); | ||
777 | 769 | ||
778 | /* If capacity is too big, truncate with warning. */ | 770 | /* If capacity is too big, truncate with warning. */ |
779 | if ((sector_t)cap != cap) { | 771 | if ((sector_t)cap != cap) { |
@@ -794,46 +786,45 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
794 | 786 | ||
795 | /* Host can optionally specify maximum segment size and number of | 787 | /* Host can optionally specify maximum segment size and number of |
796 | * segments. */ | 788 | * segments. */ |
797 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, | 789 | err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX, |
798 | offsetof(struct virtio_blk_config, size_max), | 790 | struct virtio_blk_config, size_max, &v); |
799 | &v); | ||
800 | if (!err) | 791 | if (!err) |
801 | blk_queue_max_segment_size(q, v); | 792 | blk_queue_max_segment_size(q, v); |
802 | else | 793 | else |
803 | blk_queue_max_segment_size(q, -1U); | 794 | blk_queue_max_segment_size(q, -1U); |
804 | 795 | ||
805 | /* Host can optionally specify the block size of the device */ | 796 | /* Host can optionally specify the block size of the device */ |
806 | err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, | 797 | err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE, |
807 | offsetof(struct virtio_blk_config, blk_size), | 798 | struct virtio_blk_config, blk_size, |
808 | &blk_size); | 799 | &blk_size); |
809 | if (!err) | 800 | if (!err) |
810 | blk_queue_logical_block_size(q, blk_size); | 801 | blk_queue_logical_block_size(q, blk_size); |
811 | else | 802 | else |
812 | blk_size = queue_logical_block_size(q); | 803 | blk_size = queue_logical_block_size(q); |
813 | 804 | ||
814 | /* Use topology information if available */ | 805 | /* Use topology information if available */ |
815 | err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, | 806 | err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, |
816 | offsetof(struct virtio_blk_config, physical_block_exp), | 807 | struct virtio_blk_config, physical_block_exp, |
817 | &physical_block_exp); | 808 | &physical_block_exp); |
818 | if (!err && physical_block_exp) | 809 | if (!err && physical_block_exp) |
819 | blk_queue_physical_block_size(q, | 810 | blk_queue_physical_block_size(q, |
820 | blk_size * (1 << physical_block_exp)); | 811 | blk_size * (1 << physical_block_exp)); |
821 | 812 | ||
822 | err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, | 813 | err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, |
823 | offsetof(struct virtio_blk_config, alignment_offset), | 814 | struct virtio_blk_config, alignment_offset, |
824 | &alignment_offset); | 815 | &alignment_offset); |
825 | if (!err && alignment_offset) | 816 | if (!err && alignment_offset) |
826 | blk_queue_alignment_offset(q, blk_size * alignment_offset); | 817 | blk_queue_alignment_offset(q, blk_size * alignment_offset); |
827 | 818 | ||
828 | err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, | 819 | err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, |
829 | offsetof(struct virtio_blk_config, min_io_size), | 820 | struct virtio_blk_config, min_io_size, |
830 | &min_io_size); | 821 | &min_io_size); |
831 | if (!err && min_io_size) | 822 | if (!err && min_io_size) |
832 | blk_queue_io_min(q, blk_size * min_io_size); | 823 | blk_queue_io_min(q, blk_size * min_io_size); |
833 | 824 | ||
834 | err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, | 825 | err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, |
835 | offsetof(struct virtio_blk_config, opt_io_size), | 826 | struct virtio_blk_config, opt_io_size, |
836 | &opt_io_size); | 827 | &opt_io_size); |
837 | if (!err && opt_io_size) | 828 | if (!err && opt_io_size) |
838 | blk_queue_io_opt(q, blk_size * opt_io_size); | 829 | blk_queue_io_opt(q, blk_size * opt_io_size); |
839 | 830 | ||
@@ -899,7 +890,7 @@ static void virtblk_remove(struct virtio_device *vdev) | |||
899 | ida_simple_remove(&vd_index_ida, index); | 890 | ida_simple_remove(&vd_index_ida, index); |
900 | } | 891 | } |
901 | 892 | ||
902 | #ifdef CONFIG_PM | 893 | #ifdef CONFIG_PM_SLEEP |
903 | static int virtblk_freeze(struct virtio_device *vdev) | 894 | static int virtblk_freeze(struct virtio_device *vdev) |
904 | { | 895 | { |
905 | struct virtio_blk *vblk = vdev->priv; | 896 | struct virtio_blk *vblk = vdev->priv; |
@@ -959,7 +950,7 @@ static struct virtio_driver virtio_blk = { | |||
959 | .probe = virtblk_probe, | 950 | .probe = virtblk_probe, |
960 | .remove = virtblk_remove, | 951 | .remove = virtblk_remove, |
961 | .config_changed = virtblk_config_changed, | 952 | .config_changed = virtblk_config_changed, |
962 | #ifdef CONFIG_PM | 953 | #ifdef CONFIG_PM_SLEEP |
963 | .freeze = virtblk_freeze, | 954 | .freeze = virtblk_freeze, |
964 | .restore = virtblk_restore, | 955 | .restore = virtblk_restore, |
965 | #endif | 956 | #endif |