scsi-disk: add migration support
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
56b1fc4823
commit
43b978b932
@ -111,12 +111,12 @@ static void scsi_cancel_io(SCSIRequest *req)
|
||||
r->req.aiocb = NULL;
|
||||
}
|
||||
|
||||
static uint32_t scsi_init_iovec(SCSIDiskReq *r)
|
||||
static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size)
|
||||
{
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
|
||||
if (!r->iov.iov_base) {
|
||||
r->buflen = SCSI_DMA_BUF_SIZE;
|
||||
r->buflen = size;
|
||||
r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
|
||||
}
|
||||
r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
|
||||
@ -124,6 +124,35 @@ static uint32_t scsi_init_iovec(SCSIDiskReq *r)
|
||||
return r->qiov.size / 512;
|
||||
}
|
||||
|
||||
static void scsi_disk_save_request(QEMUFile *f, SCSIRequest *req)
|
||||
{
|
||||
SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
|
||||
|
||||
qemu_put_be64s(f, &r->sector);
|
||||
qemu_put_be32s(f, &r->sector_count);
|
||||
qemu_put_be32s(f, &r->buflen);
|
||||
if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
|
||||
qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len);
|
||||
}
|
||||
}
|
||||
|
||||
static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req)
|
||||
{
|
||||
SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
|
||||
|
||||
qemu_get_be64s(f, &r->sector);
|
||||
qemu_get_be32s(f, &r->sector_count);
|
||||
qemu_get_be32s(f, &r->buflen);
|
||||
if (r->buflen) {
|
||||
scsi_init_iovec(r, r->buflen);
|
||||
if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
|
||||
qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len);
|
||||
}
|
||||
}
|
||||
|
||||
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
|
||||
}
|
||||
|
||||
static void scsi_dma_complete(void *opaque, int ret)
|
||||
{
|
||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||
@ -241,7 +270,7 @@ static void scsi_read_data(SCSIRequest *req)
|
||||
r->req.aiocb = dma_bdrv_read(s->qdev.conf.bs, r->req.sg, r->sector,
|
||||
scsi_dma_complete, r);
|
||||
} else {
|
||||
n = scsi_init_iovec(r);
|
||||
n = scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
|
||||
bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
|
||||
r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
|
||||
scsi_read_complete, r);
|
||||
@ -316,7 +345,7 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||
if (r->sector_count == 0) {
|
||||
scsi_req_complete(&r->req, GOOD);
|
||||
} else {
|
||||
scsi_init_iovec(r);
|
||||
scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
|
||||
DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size);
|
||||
scsi_req_data(&r->req, r->qiov.size);
|
||||
}
|
||||
@ -1621,6 +1650,8 @@ static const SCSIReqOps scsi_disk_reqops = {
|
||||
.write_data = scsi_write_data,
|
||||
.cancel_io = scsi_cancel_io,
|
||||
.get_buf = scsi_get_buf,
|
||||
.load_request = scsi_disk_load_request,
|
||||
.save_request = scsi_disk_save_request,
|
||||
};
|
||||
|
||||
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
|
||||
@ -1755,6 +1786,22 @@ static Property scsi_hd_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_scsi_disk_state = {
|
||||
.name = "scsi-disk",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.minimum_version_id_old = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_SCSI_DEVICE(qdev, SCSIDiskState),
|
||||
VMSTATE_BOOL(media_changed, SCSIDiskState),
|
||||
VMSTATE_BOOL(media_event, SCSIDiskState),
|
||||
VMSTATE_BOOL(eject_request, SCSIDiskState),
|
||||
VMSTATE_BOOL(tray_open, SCSIDiskState),
|
||||
VMSTATE_BOOL(tray_locked, SCSIDiskState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
@ -1768,6 +1815,7 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
|
||||
dc->desc = "virtual SCSI disk";
|
||||
dc->reset = scsi_disk_reset;
|
||||
dc->props = scsi_hd_properties;
|
||||
dc->vmsd = &vmstate_scsi_disk_state;
|
||||
}
|
||||
|
||||
static TypeInfo scsi_hd_info = {
|
||||
@ -1795,6 +1843,7 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
|
||||
dc->desc = "virtual SCSI CD-ROM";
|
||||
dc->reset = scsi_disk_reset;
|
||||
dc->props = scsi_cd_properties;
|
||||
dc->vmsd = &vmstate_scsi_disk_state;
|
||||
}
|
||||
|
||||
static TypeInfo scsi_cd_info = {
|
||||
@ -1822,6 +1871,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
|
||||
dc->desc = "SCSI block device passthrough";
|
||||
dc->reset = scsi_disk_reset;
|
||||
dc->props = scsi_block_properties;
|
||||
dc->vmsd = &vmstate_scsi_disk_state;
|
||||
}
|
||||
|
||||
static TypeInfo scsi_block_info = {
|
||||
@ -1851,6 +1901,7 @@ static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
|
||||
dc->desc = "virtual SCSI disk or CD-ROM (legacy)";
|
||||
dc->reset = scsi_disk_reset;
|
||||
dc->props = scsi_disk_properties;
|
||||
dc->vmsd = &vmstate_scsi_disk_state;
|
||||
}
|
||||
|
||||
static TypeInfo scsi_disk_info = {
|
||||
|
Loading…
Reference in New Issue
Block a user