]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/block/virtio_blk.c
virtio: de-structify virtio_block status byte
[linux-2.6-omap-h63xx.git] / drivers / block / virtio_blk.c
index 559c322c4ffabf8052a7533b98925fb67c236b4d..fb283af38023d9102b9d774e42f23138bf8a1cd0 100644 (file)
@@ -9,8 +9,7 @@
 #define VIRTIO_MAX_SG  (3+MAX_PHYS_SEGMENTS)
 #define PART_BITS 4
 
-static unsigned char virtblk_index = 'a';
-static int major, minor;
+static int major, index;
 
 struct virtio_blk
 {
@@ -36,7 +35,7 @@ struct virtblk_req
        struct list_head list;
        struct request *req;
        struct virtio_blk_outhdr out_hdr;
-       struct virtio_blk_inhdr in_hdr;
+       u8 status;
 };
 
 static void blk_done(struct virtqueue *vq)
@@ -49,7 +48,7 @@ static void blk_done(struct virtqueue *vq)
        spin_lock_irqsave(&vblk->lock, flags);
        while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) {
                int uptodate;
-               switch (vbr->in_hdr.status) {
+               switch (vbr->status) {
                case VIRTIO_BLK_S_OK:
                        uptodate = 1;
                        break;
@@ -102,7 +101,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
        sg_init_table(vblk->sg, VIRTIO_MAX_SG);
        sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr));
        num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);
-       sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr));
+       sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status));
 
        if (rq_data_dir(vbr->req) == WRITE) {
                vbr->out_hdr.type |= VIRTIO_BLK_T_OUT;
@@ -171,6 +170,11 @@ static struct block_device_operations virtblk_fops = {
        .getgeo = virtblk_getgeo,
 };
 
+static int index_to_minor(int index)
+{
+       return index << PART_BITS;
+}
+
 static int virtblk_probe(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk;
@@ -178,7 +182,7 @@ static int virtblk_probe(struct virtio_device *vdev)
        u64 cap;
        u32 v;
 
-       if (minor >= 1 << MINORBITS)
+       if (index_to_minor(index) >= 1 << MINORBITS)
                return -ENOSPC;
 
        vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL);
@@ -217,13 +221,25 @@ static int virtblk_probe(struct virtio_device *vdev)
                goto out_put_disk;
        }
 
-       sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++);
+       if (index < 26) {
+               sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
+       } else if (index < (26 + 1) * 26) {
+               sprintf(vblk->disk->disk_name, "vd%c%c",
+                       'a' + index / 26 - 1, 'a' + index % 26);
+       } else {
+               const unsigned int m1 = (index / 26 - 1) / 26 - 1;
+               const unsigned int m2 = (index / 26 - 1) % 26;
+               const unsigned int m3 =  index % 26;
+               sprintf(vblk->disk->disk_name, "vd%c%c%c",
+                       'a' + m1, 'a' + m2, 'a' + m3);
+       }
+
        vblk->disk->major = major;
-       vblk->disk->first_minor = minor;
+       vblk->disk->first_minor = index_to_minor(index);
        vblk->disk->private_data = vblk;
        vblk->disk->fops = &virtblk_fops;
-
-       minor += 1 << PART_BITS;
+       vblk->disk->driverfs_dev = &vdev->dev;
+       index++;
 
        /* If barriers are supported, tell block layer that queue is ordered */
        if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER))