aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/virtio_blk.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-02-04 23:49:56 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-02-04 07:49:57 -0500
commita586d4f6016f7139d8c26df0e6927131168d3b5b (patch)
tree1c47e1a6b6b8fb18baa42f32980f29c4ae9cbbdc /drivers/block/virtio_blk.c
parentf35d9d8aae08940b7fdd1bb8110619da2ece6b28 (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/virtio_blk.c')
-rw-r--r--drivers/block/virtio_blk.c35
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
256out_cleanup_queue:
257 blk_cleanup_queue(vblk->disk->queue);
258out_put_disk: 249out_put_disk:
259 put_disk(vblk->disk); 250 put_disk(vblk->disk);
260out_unregister_blkdev: 251out_unregister_blkdev: