diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2008-02-04 23:49:56 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-02-04 07:49:57 -0500 |
commit | a586d4f6016f7139d8c26df0e6927131168d3b5b (patch) | |
tree | 1c47e1a6b6b8fb18baa42f32980f29c4ae9cbbdc /drivers/block | |
parent | f35d9d8aae08940b7fdd1bb8110619da2ece6b28 (diff) |
virtio: simplify config mechanism.
Previously we used a type/len pair within the config space, but this
seems overkill. We now simply define a structure which represents the
layout in the config space: the config space can now only be extended
at the end.
The main driver-visible changes:
1) We indicate what fields are present with an explicit feature bit.
2) Virtqueues are explicitly numbered, and not in the config space.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/virtio_blk.c | 35 |
1 files changed, 13 insertions, 22 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 924ddd8bccd2..1c63d5b64c20 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -162,8 +162,6 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
162 | { | 162 | { |
163 | struct virtio_blk *vblk; | 163 | struct virtio_blk *vblk; |
164 | int err, major; | 164 | int err, major; |
165 | void *token; | ||
166 | unsigned int len; | ||
167 | u64 cap; | 165 | u64 cap; |
168 | u32 v; | 166 | u32 v; |
169 | 167 | ||
@@ -178,7 +176,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
178 | vblk->vdev = vdev; | 176 | vblk->vdev = vdev; |
179 | 177 | ||
180 | /* We expect one virtqueue, for output. */ | 178 | /* We expect one virtqueue, for output. */ |
181 | vblk->vq = vdev->config->find_vq(vdev, blk_done); | 179 | vblk->vq = vdev->config->find_vq(vdev, 0, blk_done); |
182 | if (IS_ERR(vblk->vq)) { | 180 | if (IS_ERR(vblk->vq)) { |
183 | err = PTR_ERR(vblk->vq); | 181 | err = PTR_ERR(vblk->vq); |
184 | goto out_free_vblk; | 182 | goto out_free_vblk; |
@@ -216,15 +214,12 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
216 | vblk->disk->fops = &virtblk_fops; | 214 | vblk->disk->fops = &virtblk_fops; |
217 | 215 | ||
218 | /* If barriers are supported, tell block layer that queue is ordered */ | 216 | /* If barriers are supported, tell block layer that queue is ordered */ |
219 | token = vdev->config->find(vdev, VIRTIO_CONFIG_BLK_F, &len); | 217 | if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) |
220 | if (virtio_use_bit(vdev, token, len, VIRTIO_BLK_F_BARRIER)) | ||
221 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); | 218 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); |
222 | 219 | ||
223 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); | 220 | /* Host must always specify the capacity. */ |
224 | if (err) { | 221 | __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity), |
225 | dev_err(&vdev->dev, "Bad/missing capacity in config\n"); | 222 | &cap); |
226 | goto out_cleanup_queue; | ||
227 | } | ||
228 | 223 | ||
229 | /* If capacity is too big, truncate with warning. */ | 224 | /* If capacity is too big, truncate with warning. */ |
230 | if ((sector_t)cap != cap) { | 225 | if ((sector_t)cap != cap) { |
@@ -234,27 +229,23 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
234 | } | 229 | } |
235 | set_capacity(vblk->disk, cap); | 230 | set_capacity(vblk->disk, cap); |
236 | 231 | ||
237 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SIZE_MAX, &v); | 232 | /* Host can optionally specify maximum segment size and number of |
233 | * segments. */ | ||
234 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, | ||
235 | offsetof(struct virtio_blk_config, size_max), | ||
236 | &v); | ||
238 | if (!err) | 237 | if (!err) |
239 | blk_queue_max_segment_size(vblk->disk->queue, v); | 238 | blk_queue_max_segment_size(vblk->disk->queue, v); |
240 | else if (err != -ENOENT) { | ||
241 | dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); | ||
242 | goto out_cleanup_queue; | ||
243 | } | ||
244 | 239 | ||
245 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); | 240 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, |
241 | offsetof(struct virtio_blk_config, seg_max), | ||
242 | &v); | ||
246 | if (!err) | 243 | if (!err) |
247 | blk_queue_max_hw_segments(vblk->disk->queue, v); | 244 | blk_queue_max_hw_segments(vblk->disk->queue, v); |
248 | else if (err != -ENOENT) { | ||
249 | dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); | ||
250 | goto out_cleanup_queue; | ||
251 | } | ||
252 | 245 | ||
253 | add_disk(vblk->disk); | 246 | add_disk(vblk->disk); |
254 | return 0; | 247 | return 0; |
255 | 248 | ||
256 | out_cleanup_queue: | ||
257 | blk_cleanup_queue(vblk->disk->queue); | ||
258 | out_put_disk: | 249 | out_put_disk: |
259 | put_disk(vblk->disk); | 250 | put_disk(vblk->disk); |
260 | out_unregister_blkdev: | 251 | out_unregister_blkdev: |