diff options
| author | john cooper <john.cooper@redhat.com> | 2010-03-25 01:33:33 -0400 |
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-05-19 08:45:40 -0400 |
| commit | 4cb2ea28c55cf5e5ef83aec535099ffce3c583df (patch) | |
| tree | 5ec629c60a32c67946bb2ce17bf71eb282d18e47 | |
| parent | 537b60d17894b7c19a6060feae40299d7109d6e7 (diff) | |
Add virtio disk identification support
Add virtio-blk device id (s/n) support via virtio request.
Signed-off-by: john cooper <john.cooper@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
| -rw-r--r-- | drivers/block/virtio_blk.c | 30 | ||||
| -rw-r--r-- | include/linux/virtio_blk.h | 5 |
2 files changed, 35 insertions, 0 deletions
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) | |||
| 70 | vbr->req->sense_len = vbr->in_hdr.sense_len; | 70 | vbr->req->sense_len = vbr->in_hdr.sense_len; |
| 71 | vbr->req->errors = vbr->in_hdr.errors; | 71 | vbr->req->errors = vbr->in_hdr.errors; |
| 72 | } | 72 | } |
| 73 | if (blk_special_request(vbr->req)) | ||
| 74 | vbr->req->errors = (error != 0); | ||
| 73 | 75 | ||
| 74 | __blk_end_request_all(vbr->req, error); | 76 | __blk_end_request_all(vbr->req, error); |
| 75 | list_del(&vbr->list); | 77 | list_del(&vbr->list); |
| @@ -103,6 +105,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | |||
| 103 | vbr->out_hdr.sector = 0; | 105 | vbr->out_hdr.sector = 0; |
| 104 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); | 106 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); |
| 105 | break; | 107 | break; |
| 108 | case REQ_TYPE_SPECIAL: | ||
| 109 | vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID; | ||
| 110 | vbr->out_hdr.sector = 0; | ||
| 111 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); | ||
| 112 | break; | ||
| 106 | case REQ_TYPE_LINUX_BLOCK: | 113 | case REQ_TYPE_LINUX_BLOCK: |
| 107 | if (req->cmd[0] == REQ_LB_OP_FLUSH) { | 114 | if (req->cmd[0] == REQ_LB_OP_FLUSH) { |
| 108 | vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; | 115 | vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; |
| @@ -189,6 +196,29 @@ static void virtblk_prepare_flush(struct request_queue *q, struct request *req) | |||
| 189 | req->cmd[0] = REQ_LB_OP_FLUSH; | 196 | req->cmd[0] = REQ_LB_OP_FLUSH; |
| 190 | } | 197 | } |
| 191 | 198 | ||
| 199 | /* return id (s/n) string for *disk to *id_str | ||
| 200 | */ | ||
| 201 | static int virtblk_get_id(struct gendisk *disk, char *id_str) | ||
| 202 | { | ||
| 203 | struct virtio_blk *vblk = disk->private_data; | ||
| 204 | struct request *req; | ||
| 205 | struct bio *bio; | ||
| 206 | |||
| 207 | bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES, | ||
| 208 | GFP_KERNEL); | ||
| 209 | if (IS_ERR(bio)) | ||
| 210 | return PTR_ERR(bio); | ||
| 211 | |||
| 212 | req = blk_make_request(vblk->disk->queue, bio, GFP_KERNEL); | ||
| 213 | if (IS_ERR(req)) { | ||
| 214 | bio_put(bio); | ||
| 215 | return PTR_ERR(req); | ||
| 216 | } | ||
| 217 | |||
| 218 | req->cmd_type = REQ_TYPE_SPECIAL; | ||
| 219 | return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); | ||
| 220 | } | ||
| 221 | |||
| 192 | static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | 222 | static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, |
| 193 | unsigned cmd, unsigned long data) | 223 | unsigned cmd, unsigned long data) |
| 194 | { | 224 | { |
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h index e52029e98919..167720d695ed 100644 --- a/include/linux/virtio_blk.h +++ b/include/linux/virtio_blk.h | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | #define VIRTIO_BLK_F_FLUSH 9 /* Cache flush command support */ | 17 | #define VIRTIO_BLK_F_FLUSH 9 /* Cache flush command support */ |
| 18 | #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ | 18 | #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ |
| 19 | 19 | ||
| 20 | #define VIRTIO_BLK_ID_BYTES 20 /* ID string length */ | ||
| 21 | |||
| 20 | struct virtio_blk_config { | 22 | struct virtio_blk_config { |
| 21 | /* The capacity (in 512-byte sectors). */ | 23 | /* The capacity (in 512-byte sectors). */ |
| 22 | __u64 capacity; | 24 | __u64 capacity; |
| @@ -67,6 +69,9 @@ struct virtio_blk_config { | |||
| 67 | /* Cache flush command */ | 69 | /* Cache flush command */ |
| 68 | #define VIRTIO_BLK_T_FLUSH 4 | 70 | #define VIRTIO_BLK_T_FLUSH 4 |
| 69 | 71 | ||
| 72 | /* Get device ID command */ | ||
| 73 | #define VIRTIO_BLK_T_GET_ID 8 | ||
| 74 | |||
| 70 | /* Barrier before this op. */ | 75 | /* Barrier before this op. */ |
| 71 | #define VIRTIO_BLK_T_BARRIER 0x80000000 | 76 | #define VIRTIO_BLK_T_BARRIER 0x80000000 |
| 72 | 77 | ||
