diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2013-10-14 03:41:51 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2013-10-16 20:25:37 -0400 |
commit | 855e0c5288177bcb193f6f6316952d2490478e1c (patch) | |
tree | 7c5cfed44c9def1a7ca3388f37a9520de52af44b /drivers/block/virtio_blk.c | |
parent | 0b90d0622ad290b3717a13489b396af52aea9d2d (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.c | 77 |
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, | |||
456 | static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) | 456 | static 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 | ||