]> git.proxmox.com Git - qemu.git/blame - hw/virtio-blk.c
virtio-blk-ccw switch to new API.
[qemu.git] / hw / virtio-blk.c
CommitLineData
6e02c38d
AL
1/*
2 * Virtio Block Device
3 *
4 * Copyright IBM, Corp. 2007
5 *
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
11 *
12 */
13
5a61cb60 14#include "qemu-common.h"
1de7afc9 15#include "qemu/error-report.h"
6d519a5f 16#include "trace.h"
9db1c0f7 17#include "hw/block-common.h"
9c17d615 18#include "sysemu/blockdev.h"
83c9f4ca 19#include "hw/virtio-blk.h"
83c9f4ca 20#include "hw/scsi-defs.h"
1063b8b1
CH
21#ifdef __linux__
22# include <scsi/sg.h>
23#endif
1c028ddf 24#include "hw/virtio-bus.h"
6e02c38d 25
1c028ddf
KF
26/*
27 * Moving to QOM later in this series.
28 */
6e02c38d
AL
29static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
30{
31 return (VirtIOBlock *)vdev;
32}
33
34typedef struct VirtIOBlockReq
35{
36 VirtIOBlock *dev;
37 VirtQueueElement elem;
38 struct virtio_blk_inhdr *in;
39 struct virtio_blk_outhdr *out;
1063b8b1 40 struct virtio_scsi_inhdr *scsi;
d28a1b6e 41 QEMUIOVector qiov;
869a5c6d 42 struct VirtIOBlockReq *next;
a597e79c 43 BlockAcctCookie acct;
6e02c38d
AL
44} VirtIOBlockReq;
45
869a5c6d
AL
46static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
47{
48 VirtIOBlock *s = req->dev;
49
6d519a5f
SH
50 trace_virtio_blk_req_complete(req, status);
51
92e3c2a3 52 stb_p(&req->in->status, status);
d28a1b6e 53 virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
869a5c6d 54 virtio_notify(&s->vdev, s->vq);
869a5c6d
AL
55}
56
f35d68f0 57static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
1ceee0d5 58 bool is_read)
869a5c6d 59{
3e1caa5f 60 BlockErrorAction action = bdrv_get_error_action(req->dev->bs, is_read, error);
869a5c6d
AL
61 VirtIOBlock *s = req->dev;
62
3e1caa5f 63 if (action == BDRV_ACTION_STOP) {
869a5c6d
AL
64 req->next = s->rq;
65 s->rq = req;
3e1caa5f 66 } else if (action == BDRV_ACTION_REPORT) {
869a5c6d 67 virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
a597e79c
CH
68 bdrv_acct_done(s->bs, &req->acct);
69 g_free(req);
869a5c6d
AL
70 }
71
3e1caa5f
PB
72 bdrv_error_action(s->bs, action, is_read, error);
73 return action != BDRV_ACTION_IGNORE;
869a5c6d
AL
74}
75
6e02c38d
AL
76static void virtio_blk_rw_complete(void *opaque, int ret)
77{
78 VirtIOBlockReq *req = opaque;
6e02c38d 79
6d519a5f
SH
80 trace_virtio_blk_rw_complete(req, ret);
81
f35d68f0 82 if (ret) {
1ceee0d5 83 bool is_read = !(ldl_p(&req->out->type) & VIRTIO_BLK_T_OUT);
f35d68f0 84 if (virtio_blk_handle_rw_error(req, -ret, is_read))
869a5c6d 85 return;
6e02c38d
AL
86 }
87
f35d68f0 88 virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
a597e79c
CH
89 bdrv_acct_done(req->dev->bs, &req->acct);
90 g_free(req);
869a5c6d 91}
6e02c38d 92
aa659be3
CH
93static void virtio_blk_flush_complete(void *opaque, int ret)
94{
95 VirtIOBlockReq *req = opaque;
96
8c269b54
KW
97 if (ret) {
98 if (virtio_blk_handle_rw_error(req, -ret, 0)) {
99 return;
100 }
101 }
102
103 virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
a597e79c
CH
104 bdrv_acct_done(req->dev->bs, &req->acct);
105 g_free(req);
aa659be3
CH
106}
107
869a5c6d
AL
108static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
109{
7267c094 110 VirtIOBlockReq *req = g_malloc(sizeof(*req));
487414f1 111 req->dev = s;
de6c8042
SH
112 req->qiov.size = 0;
113 req->next = NULL;
869a5c6d 114 return req;
6e02c38d
AL
115}
116
117static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
118{
869a5c6d 119 VirtIOBlockReq *req = virtio_blk_alloc_request(s);
6e02c38d 120
869a5c6d
AL
121 if (req != NULL) {
122 if (!virtqueue_pop(s->vq, &req->elem)) {
7267c094 123 g_free(req);
869a5c6d
AL
124 return NULL;
125 }
6e02c38d
AL
126 }
127
128 return req;
129}
130
1063b8b1
CH
131static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
132{
47ce9ef7 133#ifdef __linux__
4277906d 134 int ret;
1063b8b1 135 int i;
47ce9ef7
SW
136#endif
137 int status = VIRTIO_BLK_S_OK;
1063b8b1
CH
138
139 /*
140 * We require at least one output segment each for the virtio_blk_outhdr
141 * and the SCSI command block.
142 *
143 * We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr
144 * and the sense buffer pointer in the input segments.
145 */
146 if (req->elem.out_num < 2 || req->elem.in_num < 3) {
147 virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
a597e79c 148 g_free(req);
1063b8b1
CH
149 return;
150 }
151
152 /*
f34e73cd
PB
153 * The scsi inhdr is placed in the second-to-last input segment, just
154 * before the regular inhdr.
1063b8b1 155 */
f34e73cd
PB
156 req->scsi = (void *)req->elem.in_sg[req->elem.in_num - 2].iov_base;
157
da3dcefa 158 if (!req->dev->blk.scsi) {
f34e73cd
PB
159 status = VIRTIO_BLK_S_UNSUPP;
160 goto fail;
1063b8b1
CH
161 }
162
163 /*
f34e73cd 164 * No support for bidirection commands yet.
1063b8b1 165 */
f34e73cd
PB
166 if (req->elem.out_num > 2 && req->elem.in_num > 3) {
167 status = VIRTIO_BLK_S_UNSUPP;
168 goto fail;
169 }
1063b8b1 170
f34e73cd
PB
171#ifdef __linux__
172 struct sg_io_hdr hdr;
1063b8b1
CH
173 memset(&hdr, 0, sizeof(struct sg_io_hdr));
174 hdr.interface_id = 'S';
175 hdr.cmd_len = req->elem.out_sg[1].iov_len;
176 hdr.cmdp = req->elem.out_sg[1].iov_base;
177 hdr.dxfer_len = 0;
178
179 if (req->elem.out_num > 2) {
180 /*
181 * If there are more than the minimally required 2 output segments
182 * there is write payload starting from the third iovec.
183 */
184 hdr.dxfer_direction = SG_DXFER_TO_DEV;
185 hdr.iovec_count = req->elem.out_num - 2;
186
187 for (i = 0; i < hdr.iovec_count; i++)
188 hdr.dxfer_len += req->elem.out_sg[i + 2].iov_len;
189
190 hdr.dxferp = req->elem.out_sg + 2;
191
192 } else if (req->elem.in_num > 3) {
193 /*
194 * If we have more than 3 input segments the guest wants to actually
195 * read data.
196 */
197 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
198 hdr.iovec_count = req->elem.in_num - 3;
199 for (i = 0; i < hdr.iovec_count; i++)
200 hdr.dxfer_len += req->elem.in_sg[i].iov_len;
201
202 hdr.dxferp = req->elem.in_sg;
1063b8b1
CH
203 } else {
204 /*
205 * Some SCSI commands don't actually transfer any data.
206 */
207 hdr.dxfer_direction = SG_DXFER_NONE;
208 }
209
210 hdr.sbp = req->elem.in_sg[req->elem.in_num - 3].iov_base;
211 hdr.mx_sb_len = req->elem.in_sg[req->elem.in_num - 3].iov_len;
1063b8b1
CH
212
213 ret = bdrv_ioctl(req->dev->bs, SG_IO, &hdr);
214 if (ret) {
215 status = VIRTIO_BLK_S_UNSUPP;
f34e73cd 216 goto fail;
1063b8b1
CH
217 }
218
5bb23927
PB
219 /*
220 * From SCSI-Generic-HOWTO: "Some lower level drivers (e.g. ide-scsi)
221 * clear the masked_status field [hence status gets cleared too, see
222 * block/scsi_ioctl.c] even when a CHECK_CONDITION or COMMAND_TERMINATED
223 * status has occurred. However they do set DRIVER_SENSE in driver_status
224 * field. Also a (sb_len_wr > 0) indicates there is a sense buffer.
225 */
226 if (hdr.status == 0 && hdr.sb_len_wr > 0) {
227 hdr.status = CHECK_CONDITION;
228 }
229
230 stl_p(&req->scsi->errors,
231 hdr.status | (hdr.msg_status << 8) |
232 (hdr.host_status << 16) | (hdr.driver_status << 24));
92e3c2a3
AJ
233 stl_p(&req->scsi->residual, hdr.resid);
234 stl_p(&req->scsi->sense_len, hdr.sb_len_wr);
235 stl_p(&req->scsi->data_len, hdr.dxfer_len);
1063b8b1
CH
236
237 virtio_blk_req_complete(req, status);
a597e79c 238 g_free(req);
730a9c53 239 return;
1063b8b1 240#else
f34e73cd
PB
241 abort();
242#endif
243
244fail:
245 /* Just put anything nonzero so that the ioctl fails in the guest. */
246 stl_p(&req->scsi->errors, 255);
247 virtio_blk_req_complete(req, status);
a597e79c 248 g_free(req);
1063b8b1 249}
1063b8b1 250
c20fd872
CH
251typedef struct MultiReqBuffer {
252 BlockRequest blkreq[32];
253 unsigned int num_writes;
254} MultiReqBuffer;
255
256static void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb)
869a5c6d 257{
91553dcc 258 int i, ret;
91553dcc 259
c20fd872
CH
260 if (!mrb->num_writes) {
261 return;
262 }
263
264 ret = bdrv_aio_multiwrite(bs, mrb->blkreq, mrb->num_writes);
91553dcc 265 if (ret != 0) {
c20fd872
CH
266 for (i = 0; i < mrb->num_writes; i++) {
267 if (mrb->blkreq[i].error) {
268 virtio_blk_rw_complete(mrb->blkreq[i].opaque, -EIO);
91553dcc
KW
269 }
270 }
271 }
c20fd872
CH
272
273 mrb->num_writes = 0;
91553dcc 274}
87b245db 275
c20fd872 276static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
aa659be3 277{
a597e79c
CH
278 bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH);
279
618fbb84
CH
280 /*
281 * Make sure all outstanding writes are posted to the backing device.
282 */
c20fd872 283 virtio_submit_multiwrite(req->dev->bs, mrb);
ad54ae80 284 bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
aa659be3
CH
285}
286
c20fd872 287static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
91553dcc 288{
c20fd872 289 BlockRequest *blkreq;
92e3c2a3 290 uint64_t sector;
c20fd872 291
92e3c2a3 292 sector = ldq_p(&req->out->sector);
6d519a5f 293
a597e79c
CH
294 bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
295
92e3c2a3
AJ
296 trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
297
298 if (sector & req->dev->sector_mask) {
8cfacf07
CH
299 virtio_blk_rw_complete(req, -EIO);
300 return;
301 }
52c05023
CH
302 if (req->qiov.size % req->dev->conf->logical_block_size) {
303 virtio_blk_rw_complete(req, -EIO);
304 return;
305 }
8cfacf07 306
c20fd872
CH
307 if (mrb->num_writes == 32) {
308 virtio_submit_multiwrite(req->dev->bs, mrb);
87b245db 309 }
91553dcc 310
c20fd872 311 blkreq = &mrb->blkreq[mrb->num_writes];
92e3c2a3 312 blkreq->sector = sector;
c20fd872
CH
313 blkreq->nb_sectors = req->qiov.size / BDRV_SECTOR_SIZE;
314 blkreq->qiov = &req->qiov;
315 blkreq->cb = virtio_blk_rw_complete;
316 blkreq->opaque = req;
317 blkreq->error = 0;
91553dcc 318
c20fd872 319 mrb->num_writes++;
d28a1b6e 320}
869a5c6d 321
d28a1b6e
AL
322static void virtio_blk_handle_read(VirtIOBlockReq *req)
323{
92e3c2a3
AJ
324 uint64_t sector;
325
326 sector = ldq_p(&req->out->sector);
87b245db 327
a597e79c
CH
328 bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
329
81b6b9fa
SH
330 trace_virtio_blk_handle_read(req, sector, req->qiov.size / 512);
331
92e3c2a3 332 if (sector & req->dev->sector_mask) {
8cfacf07
CH
333 virtio_blk_rw_complete(req, -EIO);
334 return;
335 }
52c05023
CH
336 if (req->qiov.size % req->dev->conf->logical_block_size) {
337 virtio_blk_rw_complete(req, -EIO);
338 return;
339 }
ad54ae80
PB
340 bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
341 req->qiov.size / BDRV_SECTOR_SIZE,
342 virtio_blk_rw_complete, req);
869a5c6d
AL
343}
344
bc6694d4
KW
345static void virtio_blk_handle_request(VirtIOBlockReq *req,
346 MultiReqBuffer *mrb)
347{
92e3c2a3
AJ
348 uint32_t type;
349
bc6694d4 350 if (req->elem.out_num < 1 || req->elem.in_num < 1) {
870cef1d 351 error_report("virtio-blk missing headers");
bc6694d4
KW
352 exit(1);
353 }
354
355 if (req->elem.out_sg[0].iov_len < sizeof(*req->out) ||
356 req->elem.in_sg[req->elem.in_num - 1].iov_len < sizeof(*req->in)) {
870cef1d 357 error_report("virtio-blk header not in correct element");
bc6694d4
KW
358 exit(1);
359 }
360
361 req->out = (void *)req->elem.out_sg[0].iov_base;
362 req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base;
363
92e3c2a3
AJ
364 type = ldl_p(&req->out->type);
365
366 if (type & VIRTIO_BLK_T_FLUSH) {
c20fd872 367 virtio_blk_handle_flush(req, mrb);
92e3c2a3 368 } else if (type & VIRTIO_BLK_T_SCSI_CMD) {
bc6694d4 369 virtio_blk_handle_scsi(req);
92e3c2a3 370 } else if (type & VIRTIO_BLK_T_GET_ID) {
2930b313 371 VirtIOBlock *s = req->dev;
372
a8686a9b
MA
373 /*
374 * NB: per existing s/n string convention the string is
375 * terminated by '\0' only when shorter than buffer.
376 */
377 strncpy(req->elem.in_sg[0].iov_base,
da3dcefa 378 s->blk.serial ? s->blk.serial : "",
a8686a9b 379 MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
2930b313 380 virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
a597e79c 381 g_free(req);
92e3c2a3 382 } else if (type & VIRTIO_BLK_T_OUT) {
bc6694d4
KW
383 qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
384 req->elem.out_num - 1);
c20fd872 385 virtio_blk_handle_write(req, mrb);
9e72c450
AZ
386 } else if (type == VIRTIO_BLK_T_IN || type == VIRTIO_BLK_T_BARRIER) {
387 /* VIRTIO_BLK_T_IN is 0, so we can't just & it. */
bc6694d4
KW
388 qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0],
389 req->elem.in_num - 1);
390 virtio_blk_handle_read(req);
9e72c450
AZ
391 } else {
392 virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
393 g_free(req);
bc6694d4
KW
394 }
395}
396
6e02c38d
AL
397static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
398{
399 VirtIOBlock *s = to_virtio_blk(vdev);
400 VirtIOBlockReq *req;
bc6694d4
KW
401 MultiReqBuffer mrb = {
402 .num_writes = 0,
bc6694d4 403 };
6e02c38d 404
392808b4
SH
405#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
406 /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
407 * dataplane here instead of waiting for .set_status().
408 */
409 if (s->dataplane) {
410 virtio_blk_data_plane_start(s->dataplane);
411 return;
412 }
413#endif
414
6e02c38d 415 while ((req = virtio_blk_get_request(s))) {
bc6694d4 416 virtio_blk_handle_request(req, &mrb);
6e02c38d 417 }
91553dcc 418
c20fd872 419 virtio_submit_multiwrite(s->bs, &mrb);
91553dcc 420
6e02c38d
AL
421 /*
422 * FIXME: Want to check for completions before returning to guest mode,
423 * so cached reads and writes are reported as quickly as possible. But
424 * that should be done in the generic block layer.
425 */
426}
427
213189ab 428static void virtio_blk_dma_restart_bh(void *opaque)
869a5c6d
AL
429{
430 VirtIOBlock *s = opaque;
431 VirtIOBlockReq *req = s->rq;
f1b52868
KW
432 MultiReqBuffer mrb = {
433 .num_writes = 0,
f1b52868 434 };
869a5c6d 435
213189ab
MA
436 qemu_bh_delete(s->bh);
437 s->bh = NULL;
869a5c6d
AL
438
439 s->rq = NULL;
440
441 while (req) {
f1b52868 442 virtio_blk_handle_request(req, &mrb);
869a5c6d
AL
443 req = req->next;
444 }
f1b52868 445
c20fd872 446 virtio_submit_multiwrite(s->bs, &mrb);
869a5c6d
AL
447}
448
1dfb4dd9
LC
449static void virtio_blk_dma_restart_cb(void *opaque, int running,
450 RunState state)
213189ab
MA
451{
452 VirtIOBlock *s = opaque;
453
392808b4 454 if (!running) {
213189ab 455 return;
392808b4 456 }
213189ab
MA
457
458 if (!s->bh) {
459 s->bh = qemu_bh_new(virtio_blk_dma_restart_bh, s);
460 qemu_bh_schedule(s->bh);
461 }
462}
463
6e02c38d
AL
464static void virtio_blk_reset(VirtIODevice *vdev)
465{
392808b4
SH
466#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
467 VirtIOBlock *s = to_virtio_blk(vdev);
468
469 if (s->dataplane) {
470 virtio_blk_data_plane_stop(s->dataplane);
471 }
472#endif
473
6e02c38d
AL
474 /*
475 * This should cancel pending requests, but can't do nicely until there
476 * are per-device request lists.
477 */
922453bc 478 bdrv_drain_all();
6e02c38d
AL
479}
480
bf011293 481/* coalesce internal state, copy to pci i/o region 0
482 */
6e02c38d
AL
483static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
484{
485 VirtIOBlock *s = to_virtio_blk(vdev);
486 struct virtio_blk_config blkcfg;
487 uint64_t capacity;
3a395142 488 int blk_size = s->conf->logical_block_size;
6e02c38d
AL
489
490 bdrv_get_geometry(s->bs, &capacity);
5c5dafdc 491 memset(&blkcfg, 0, sizeof(blkcfg));
6e02c38d
AL
492 stq_raw(&blkcfg.capacity, capacity);
493 stl_raw(&blkcfg.seg_max, 128 - 2);
e63e7fde 494 stw_raw(&blkcfg.cylinders, s->conf->cyls);
3a395142
PB
495 stl_raw(&blkcfg.blk_size, blk_size);
496 stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size);
497 stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
e63e7fde 498 blkcfg.heads = s->conf->heads;
136be99e
CB
499 /*
500 * We must ensure that the block device capacity is a multiple of
501 * the logical block size. If that is not the case, lets use
502 * sector_mask to adopt the geometry to have a correct picture.
503 * For those devices where the capacity is ok for the given geometry
504 * we dont touch the sector value of the geometry, since some devices
505 * (like s390 dasd) need a specific value. Here the capacity is already
506 * cyls*heads*secs*blk_size and the sector value is not block size
507 * divided by 512 - instead it is the amount of blk_size blocks
508 * per track (cylinder).
509 */
e63e7fde
MA
510 if (bdrv_getlength(s->bs) / s->conf->heads / s->conf->secs % blk_size) {
511 blkcfg.sectors = s->conf->secs & ~s->sector_mask;
136be99e 512 } else {
e63e7fde 513 blkcfg.sectors = s->conf->secs;
136be99e 514 }
c7085da7 515 blkcfg.size_max = 0;
9752c371
CH
516 blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
517 blkcfg.alignment_offset = 0;
13e3dce0 518 blkcfg.wce = bdrv_enable_write_cache(s->bs);
37d5ddd6 519 memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
6e02c38d
AL
520}
521
13e3dce0
PB
522static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
523{
524 VirtIOBlock *s = to_virtio_blk(vdev);
525 struct virtio_blk_config blkcfg;
526
527 memcpy(&blkcfg, config, sizeof(blkcfg));
528 bdrv_set_enable_write_cache(s->bs, blkcfg.wce != 0);
529}
530
8172539d 531static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
6e02c38d 532{
bf011293 533 VirtIOBlock *s = to_virtio_blk(vdev);
1063b8b1
CH
534
535 features |= (1 << VIRTIO_BLK_F_SEG_MAX);
536 features |= (1 << VIRTIO_BLK_F_GEOMETRY);
9752c371 537 features |= (1 << VIRTIO_BLK_F_TOPOLOGY);
8cfacf07 538 features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
a6c5c84a 539 features |= (1 << VIRTIO_BLK_F_SCSI);
aa659be3 540
da3dcefa 541 if (s->blk.config_wce) {
8a873ba7
SH
542 features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
543 }
aa659be3 544 if (bdrv_enable_write_cache(s->bs))
13e3dce0
PB
545 features |= (1 << VIRTIO_BLK_F_WCE);
546
c79662f7
NS
547 if (bdrv_is_read_only(s->bs))
548 features |= 1 << VIRTIO_BLK_F_RO;
1063b8b1
CH
549
550 return features;
6e02c38d
AL
551}
552
9315cbfd
PB
553static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
554{
555 VirtIOBlock *s = to_virtio_blk(vdev);
556 uint32_t features;
557
392808b4 558#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
cf139388
SH
559 if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
560 VIRTIO_CONFIG_S_DRIVER_OK))) {
392808b4
SH
561 virtio_blk_data_plane_stop(s->dataplane);
562 }
563#endif
564
9315cbfd
PB
565 if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
566 return;
567 }
568
569 features = vdev->guest_features;
570 bdrv_set_enable_write_cache(s->bs, !!(features & (1 << VIRTIO_BLK_F_WCE)));
571}
572
6e02c38d
AL
573static void virtio_blk_save(QEMUFile *f, void *opaque)
574{
575 VirtIOBlock *s = opaque;
869a5c6d
AL
576 VirtIOBlockReq *req = s->rq;
577
6e02c38d 578 virtio_save(&s->vdev, f);
869a5c6d
AL
579
580 while (req) {
581 qemu_put_sbyte(f, 1);
582 qemu_put_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
583 req = req->next;
584 }
585 qemu_put_sbyte(f, 0);
6e02c38d
AL
586}
587
588static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
589{
590 VirtIOBlock *s = opaque;
2a633c46 591 int ret;
6e02c38d 592
869a5c6d 593 if (version_id != 2)
6e02c38d
AL
594 return -EINVAL;
595
2a633c46
OW
596 ret = virtio_load(&s->vdev, f);
597 if (ret) {
598 return ret;
599 }
600
869a5c6d
AL
601 while (qemu_get_sbyte(f)) {
602 VirtIOBlockReq *req = virtio_blk_alloc_request(s);
603 qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
604 req->next = s->rq;
20a81e4d 605 s->rq = req;
b6a4805b
KW
606
607 virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr,
608 req->elem.in_num, 1);
609 virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr,
610 req->elem.out_num, 0);
869a5c6d 611 }
6e02c38d
AL
612
613 return 0;
614}
615
145feb17 616static void virtio_blk_resize(void *opaque)
e5051fc7
CH
617{
618 VirtIOBlock *s = opaque;
619
145feb17 620 virtio_notify_config(&s->vdev);
e5051fc7
CH
621}
622
0e49de52 623static const BlockDevOps virtio_block_ops = {
145feb17 624 .resize_cb = virtio_blk_resize,
0e49de52
MA
625};
626
1c028ddf 627void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk)
6e02c38d 628{
1c028ddf
KF
629 VirtIOBlock *s = VIRTIO_BLK(dev);
630 memcpy(&(s->blk), blk, sizeof(struct VirtIOBlkConf));
631}
632
633static VirtIODevice *virtio_blk_common_init(DeviceState *dev,
634 VirtIOBlkConf *blk, VirtIOBlock **ps)
635{
636 VirtIOBlock *s = *ps;
6e02c38d 637 static int virtio_blk_id;
cf21e106 638
12c5674b 639 if (!blk->conf.bs) {
6a84cb1f 640 error_report("drive property not set");
d75d25e3
MA
641 return NULL;
642 }
12c5674b 643 if (!bdrv_is_inserted(blk->conf.bs)) {
98f28ad7
MA
644 error_report("Device needs media, but drive is empty");
645 return NULL;
646 }
d75d25e3 647
911525db 648 blkconf_serial(&blk->conf, &blk->serial);
b7eb0c9f
MA
649 if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
650 return NULL;
651 }
a8686a9b 652
1c028ddf
KF
653 /*
654 * We have two cases here: the old virtio-blk-pci device, and the
655 * refactored virtio-blk.
656 */
657 if (s == NULL) {
658 /* virtio-blk-pci */
659 s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
660 sizeof(struct virtio_blk_config),
661 sizeof(VirtIOBlock));
662 } else {
663 /* virtio-blk */
664 virtio_init(VIRTIO_DEVICE(s), "virtio-blk", VIRTIO_ID_BLOCK,
665 sizeof(struct virtio_blk_config));
666 }
6e02c38d
AL
667
668 s->vdev.get_config = virtio_blk_update_config;
13e3dce0 669 s->vdev.set_config = virtio_blk_set_config;
6e02c38d 670 s->vdev.get_features = virtio_blk_get_features;
9315cbfd 671 s->vdev.set_status = virtio_blk_set_status;
6e02c38d 672 s->vdev.reset = virtio_blk_reset;
12c5674b
PB
673 s->bs = blk->conf.bs;
674 s->conf = &blk->conf;
da3dcefa 675 memcpy(&(s->blk), blk, sizeof(struct VirtIOBlkConf));
869a5c6d 676 s->rq = NULL;
1573a35d 677 s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
e63e7fde 678
6e02c38d 679 s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
392808b4
SH
680#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
681 if (!virtio_blk_data_plane_create(&s->vdev, blk, &s->dataplane)) {
682 virtio_cleanup(&s->vdev);
683 return NULL;
684 }
685#endif
6e02c38d 686
69b302b2 687 s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
9d0d3138 688 s->qdev = dev;
0be71e32 689 register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
6e02c38d 690 virtio_blk_save, virtio_blk_load, s);
0e49de52 691 bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
12c5674b 692 bdrv_set_buffer_alignment(s->bs, s->conf->logical_block_size);
6e02c38d 693
af239a62 694 bdrv_iostatus_enable(s->bs);
12c5674b 695 add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
1ca4d09a 696
53c25cea 697 return &s->vdev;
6e02c38d 698}
9d0d3138 699
1c028ddf
KF
700VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
701{
702 VirtIOBlock *s = NULL;
703 return virtio_blk_common_init(dev, blk, &s);
704}
705
9d0d3138
AW
706void virtio_blk_exit(VirtIODevice *vdev)
707{
708 VirtIOBlock *s = to_virtio_blk(vdev);
392808b4
SH
709
710#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
711 virtio_blk_data_plane_destroy(s->dataplane);
712 s->dataplane = NULL;
713#endif
69b302b2 714 qemu_del_vm_change_state_handler(s->change);
9d0d3138 715 unregister_savevm(s->qdev, "virtio-blk", s);
0e47931b 716 blockdev_mark_auto_del(s->bs);
d92551f2 717 virtio_cleanup(vdev);
9d0d3138 718}
1c028ddf
KF
719
720
721static int virtio_blk_device_init(VirtIODevice *vdev)
722{
723 DeviceState *qdev = DEVICE(vdev);
724 VirtIOBlock *s = VIRTIO_BLK(vdev);
725 VirtIOBlkConf *blk = &(s->blk);
726 if (virtio_blk_common_init(qdev, blk, &s) == NULL) {
727 return -1;
728 }
729 return 0;
730}
731
732static int virtio_blk_device_exit(DeviceState *dev)
733{
734 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
735 VirtIOBlock *s = VIRTIO_BLK(dev);
736#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
737 virtio_blk_data_plane_destroy(s->dataplane);
738 s->dataplane = NULL;
739#endif
740 qemu_del_vm_change_state_handler(s->change);
741 unregister_savevm(s->qdev, "virtio-blk", s);
742 blockdev_mark_auto_del(s->bs);
743 virtio_common_cleanup(vdev);
744 return 0;
745}
746
747static Property virtio_blk_properties[] = {
748 DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlock, blk),
749 DEFINE_PROP_END_OF_LIST(),
750};
751
752static void virtio_blk_class_init(ObjectClass *klass, void *data)
753{
754 DeviceClass *dc = DEVICE_CLASS(klass);
755 VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
756 dc->exit = virtio_blk_device_exit;
757 dc->props = virtio_blk_properties;
758 vdc->init = virtio_blk_device_init;
759 vdc->get_config = virtio_blk_update_config;
760 vdc->set_config = virtio_blk_set_config;
761 vdc->get_features = virtio_blk_get_features;
762 vdc->set_status = virtio_blk_set_status;
763 vdc->reset = virtio_blk_reset;
764}
765
766static const TypeInfo virtio_device_info = {
767 .name = TYPE_VIRTIO_BLK,
768 .parent = TYPE_VIRTIO_DEVICE,
769 .instance_size = sizeof(VirtIOBlock),
770 .class_init = virtio_blk_class_init,
771};
772
773static void virtio_register_types(void)
774{
775 type_register_static(&virtio_device_info);
776}
777
778type_init(virtio_register_types)