#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
{
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)
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;
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;
.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;
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);
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))