aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-14 23:28:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-14 23:28:47 -0500
commitb746f9c7941f227ad582b4f0bc981f3adcbc46b2 (patch)
treefe3da3dedfe8d66f90cdcfa3d9ce847fdc411c20 /drivers/block
parentce6513f758b1852a2f24f76f07d0fae304d24ad3 (diff)
parent2bf4fd31394a3f875ea093ee8a209f30b378cbf3 (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.c83
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,
456static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) 458static 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
903static int virtblk_freeze(struct virtio_device *vdev) 894static 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