aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/virtio_blk.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2013-10-14 03:41:51 -0400
committerRusty Russell <rusty@rustcorp.com.au>2013-10-16 20:25:37 -0400
commit855e0c5288177bcb193f6f6316952d2490478e1c (patch)
tree7c5cfed44c9def1a7ca3388f37a9520de52af44b /drivers/block/virtio_blk.c
parent0b90d0622ad290b3717a13489b396af52aea9d2d (diff)
virtio: use size-based config accessors.
This lets the transport do endian conversion if necessary, and insulates the drivers from the difference. Most drivers can use the simple helpers virtio_cread() and virtio_cwrite(). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/block/virtio_blk.c')
-rw-r--r--drivers/block/virtio_blk.c77
1 files changed, 33 insertions, 44 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 89245b5adca1..6b66252fc4e6 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -456,18 +456,15 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
456static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) 456static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
457{ 457{
458 struct virtio_blk *vblk = bd->bd_disk->private_data; 458 struct virtio_blk *vblk = bd->bd_disk->private_data;
459 struct virtio_blk_geometry vgeo;
460 int err;
461 459
462 /* see if the host passed in geometry config */ 460 /* see if the host passed in geometry config */
463 err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY, 461 if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_GEOMETRY)) {
464 offsetof(struct virtio_blk_config, geometry), 462 virtio_cread(vblk->vdev, struct virtio_blk_config,
465 &vgeo); 463 geometry.cylinders, &geo->cylinders);
466 464 virtio_cread(vblk->vdev, struct virtio_blk_config,
467 if (!err) { 465 geometry.heads, &geo->heads);
468 geo->heads = vgeo.heads; 466 virtio_cread(vblk->vdev, struct virtio_blk_config,
469 geo->sectors = vgeo.sectors; 467 geometry.sectors, &geo->sectors);
470 geo->cylinders = vgeo.cylinders;
471 } else { 468 } else {
472 /* some standard values, similar to sd */ 469 /* some standard values, similar to sd */
473 geo->heads = 1 << 6; 470 geo->heads = 1 << 6;
@@ -529,8 +526,7 @@ static void virtblk_config_changed_work(struct work_struct *work)
529 goto done; 526 goto done;
530 527
531 /* Host must always specify the capacity. */ 528 /* Host must always specify the capacity. */
532 vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), 529 virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity);
533 &capacity, sizeof(capacity));
534 530
535 /* If capacity is too big, truncate with warning. */ 531 /* If capacity is too big, truncate with warning. */
536 if ((sector_t)capacity != capacity) { 532 if ((sector_t)capacity != capacity) {
@@ -608,9 +604,9 @@ static int virtblk_get_cache_mode(struct virtio_device *vdev)
608 u8 writeback; 604 u8 writeback;
609 int err; 605 int err;
610 606
611 err = virtio_config_val(vdev, VIRTIO_BLK_F_CONFIG_WCE, 607 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE,
612 offsetof(struct virtio_blk_config, wce), 608 struct virtio_blk_config, wce,
613 &writeback); 609 &writeback);
614 if (err) 610 if (err)
615 writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE); 611 writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE);
616 612
@@ -642,7 +638,6 @@ virtblk_cache_type_store(struct device *dev, struct device_attribute *attr,
642 struct virtio_blk *vblk = disk->private_data; 638 struct virtio_blk *vblk = disk->private_data;
643 struct virtio_device *vdev = vblk->vdev; 639 struct virtio_device *vdev = vblk->vdev;
644 int i; 640 int i;
645 u8 writeback;
646 641
647 BUG_ON(!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_CONFIG_WCE)); 642 BUG_ON(!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_CONFIG_WCE));
648 for (i = ARRAY_SIZE(virtblk_cache_types); --i >= 0; ) 643 for (i = ARRAY_SIZE(virtblk_cache_types); --i >= 0; )
@@ -652,11 +647,7 @@ virtblk_cache_type_store(struct device *dev, struct device_attribute *attr,
652 if (i < 0) 647 if (i < 0)
653 return -EINVAL; 648 return -EINVAL;
654 649
655 writeback = i; 650 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); 651 virtblk_update_cache_mode(vdev);
661 return count; 652 return count;
662} 653}
@@ -699,9 +690,9 @@ static int virtblk_probe(struct virtio_device *vdev)
699 index = err; 690 index = err;
700 691
701 /* We need to know how many segments before we allocate. */ 692 /* We need to know how many segments before we allocate. */
702 err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, 693 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SEG_MAX,
703 offsetof(struct virtio_blk_config, seg_max), 694 struct virtio_blk_config, seg_max,
704 &sg_elems); 695 &sg_elems);
705 696
706 /* We need at least one SG element, whatever they say. */ 697 /* We need at least one SG element, whatever they say. */
707 if (err || !sg_elems) 698 if (err || !sg_elems)
@@ -772,8 +763,7 @@ static int virtblk_probe(struct virtio_device *vdev)
772 set_disk_ro(vblk->disk, 1); 763 set_disk_ro(vblk->disk, 1);
773 764
774 /* Host must always specify the capacity. */ 765 /* Host must always specify the capacity. */
775 vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), 766 virtio_cread(vdev, struct virtio_blk_config, capacity, &cap);
776 &cap, sizeof(cap));
777 767
778 /* If capacity is too big, truncate with warning. */ 768 /* If capacity is too big, truncate with warning. */
779 if ((sector_t)cap != cap) { 769 if ((sector_t)cap != cap) {
@@ -794,46 +784,45 @@ static int virtblk_probe(struct virtio_device *vdev)
794 784
795 /* Host can optionally specify maximum segment size and number of 785 /* Host can optionally specify maximum segment size and number of
796 * segments. */ 786 * segments. */
797 err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, 787 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX,
798 offsetof(struct virtio_blk_config, size_max), 788 struct virtio_blk_config, size_max, &v);
799 &v);
800 if (!err) 789 if (!err)
801 blk_queue_max_segment_size(q, v); 790 blk_queue_max_segment_size(q, v);
802 else 791 else
803 blk_queue_max_segment_size(q, -1U); 792 blk_queue_max_segment_size(q, -1U);
804 793
805 /* Host can optionally specify the block size of the device */ 794 /* Host can optionally specify the block size of the device */
806 err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, 795 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE,
807 offsetof(struct virtio_blk_config, blk_size), 796 struct virtio_blk_config, blk_size,
808 &blk_size); 797 &blk_size);
809 if (!err) 798 if (!err)
810 blk_queue_logical_block_size(q, blk_size); 799 blk_queue_logical_block_size(q, blk_size);
811 else 800 else
812 blk_size = queue_logical_block_size(q); 801 blk_size = queue_logical_block_size(q);
813 802
814 /* Use topology information if available */ 803 /* Use topology information if available */
815 err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 804 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY,
816 offsetof(struct virtio_blk_config, physical_block_exp), 805 struct virtio_blk_config, physical_block_exp,
817 &physical_block_exp); 806 &physical_block_exp);
818 if (!err && physical_block_exp) 807 if (!err && physical_block_exp)
819 blk_queue_physical_block_size(q, 808 blk_queue_physical_block_size(q,
820 blk_size * (1 << physical_block_exp)); 809 blk_size * (1 << physical_block_exp));
821 810
822 err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 811 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY,
823 offsetof(struct virtio_blk_config, alignment_offset), 812 struct virtio_blk_config, alignment_offset,
824 &alignment_offset); 813 &alignment_offset);
825 if (!err && alignment_offset) 814 if (!err && alignment_offset)
826 blk_queue_alignment_offset(q, blk_size * alignment_offset); 815 blk_queue_alignment_offset(q, blk_size * alignment_offset);
827 816
828 err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 817 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY,
829 offsetof(struct virtio_blk_config, min_io_size), 818 struct virtio_blk_config, min_io_size,
830 &min_io_size); 819 &min_io_size);
831 if (!err && min_io_size) 820 if (!err && min_io_size)
832 blk_queue_io_min(q, blk_size * min_io_size); 821 blk_queue_io_min(q, blk_size * min_io_size);
833 822
834 err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 823 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY,
835 offsetof(struct virtio_blk_config, opt_io_size), 824 struct virtio_blk_config, opt_io_size,
836 &opt_io_size); 825 &opt_io_size);
837 if (!err && opt_io_size) 826 if (!err && opt_io_size)
838 blk_queue_io_opt(q, blk_size * opt_io_size); 827 blk_queue_io_opt(q, blk_size * opt_io_size);
839 828