From 4cb2ea28c55cf5e5ef83aec535099ffce3c583df Mon Sep 17 00:00:00 2001 From: john cooper Date: Thu, 25 Mar 2010 01:33:33 -0400 Subject: Add virtio disk identification support Add virtio-blk device id (s/n) support via virtio request. Signed-off-by: john cooper Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/block/virtio_blk.c') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 2138a7ae050c..759dee8330ac 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -70,6 +70,8 @@ static void blk_done(struct virtqueue *vq) vbr->req->sense_len = vbr->in_hdr.sense_len; vbr->req->errors = vbr->in_hdr.errors; } + if (blk_special_request(vbr->req)) + vbr->req->errors = (error != 0); __blk_end_request_all(vbr->req, error); list_del(&vbr->list); @@ -103,6 +105,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, vbr->out_hdr.sector = 0; vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); break; + case REQ_TYPE_SPECIAL: + vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID; + vbr->out_hdr.sector = 0; + vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); + break; case REQ_TYPE_LINUX_BLOCK: if (req->cmd[0] == REQ_LB_OP_FLUSH) { vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; @@ -189,6 +196,29 @@ static void virtblk_prepare_flush(struct request_queue *q, struct request *req) req->cmd[0] = REQ_LB_OP_FLUSH; } +/* return id (s/n) string for *disk to *id_str + */ +static int virtblk_get_id(struct gendisk *disk, char *id_str) +{ + struct virtio_blk *vblk = disk->private_data; + struct request *req; + struct bio *bio; + + bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES, + GFP_KERNEL); + if (IS_ERR(bio)) + return PTR_ERR(bio); + + req = blk_make_request(vblk->disk->queue, bio, GFP_KERNEL); + if (IS_ERR(req)) { + bio_put(bio); + return PTR_ERR(req); + } + + req->cmd_type = REQ_TYPE_SPECIAL; + return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); +} + static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long data) { -- cgit v1.2.3 From 234f2725a5d03f78539f1d36cb32f2c4f9b1822c Mon Sep 17 00:00:00 2001 From: john cooper Date: Thu, 25 Mar 2010 01:34:02 -0400 Subject: Add virtio disk identification ioctl Return serial string to the guest application via ioctl driver call. Note this form of interface to the guest userland was the consensus when the prior version using the ATA_IDENTIFY came under dispute. Signed-off-by: john cooper Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/block/virtio_blk.c') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 759dee8330ac..67dcb193ab2e 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -225,6 +225,16 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, struct gendisk *disk = bdev->bd_disk; struct virtio_blk *vblk = disk->private_data; + if (cmd == 'VBID') { + void __user *usr_data = (void __user *)data; + char id_str[VIRTIO_BLK_ID_BYTES]; + int err; + + err = virtblk_get_id(disk, id_str); + if (!err && copy_to_user(usr_data, id_str, VIRTIO_BLK_ID_BYTES)) + err = -EFAULT; + return err; + } /* * Only allow the generic SCSI ioctls if the host can support it. */ -- cgit v1.2.3 From bdb4a1305723f985249210a803105dbc48e86b64 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 19 May 2010 22:15:40 -0600 Subject: virtio_blk: remove multichar constant. drivers/block/virtio_blk.c:228:13: warning: multi-character character constant Signed-off-by: Rusty Russell Cc: john cooper --- drivers/block/virtio_blk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/block/virtio_blk.c') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 67dcb193ab2e..e32b24b7a3a2 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -225,7 +225,7 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, struct gendisk *disk = bdev->bd_disk; struct virtio_blk *vblk = disk->private_data; - if (cmd == 'VBID') { + if (cmd == 0x56424944) { /* 'VBID' */ void __user *usr_data = (void __user *)data; char id_str[VIRTIO_BLK_ID_BYTES]; int err; -- cgit v1.2.3 From 09ec6b69d2b97d6fca16cfe91b4634506f4db0a7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 12 Apr 2010 16:18:36 +0300 Subject: virtio_blk: use virtqueue_xxx wrappers Switch virtio_blk to new virtqueue_xxx wrappers. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/block/virtio_blk.c') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index e32b24b7a3a2..83fa09a836ca 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -50,7 +50,7 @@ static void blk_done(struct virtqueue *vq) unsigned long flags; spin_lock_irqsave(&vblk->lock, flags); - while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) { + while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) { int error; switch (vbr->status) { @@ -158,7 +158,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, } } - if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) { + if (virtqueue_add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) { mempool_free(vbr, vblk->pool); return false; } @@ -187,7 +187,7 @@ static void do_virtblk_request(struct request_queue *q) } if (issued) - vblk->vq->vq_ops->kick(vblk->vq); + virtqueue_kick(vblk->vq); } static void virtblk_prepare_flush(struct request_queue *q, struct request *req) -- cgit v1.2.3