diff options
-rw-r--r-- | block_int.h | 27 | ||||
-rw-r--r-- | hw/ide/core.c | 10 | ||||
-rw-r--r-- | hw/ide/internal.h | 7 | ||||
-rw-r--r-- | hw/ide/qdev.c | 7 | ||||
-rw-r--r-- | hw/s390-virtio-bus.c | 4 | ||||
-rw-r--r-- | hw/s390-virtio-bus.h | 2 | ||||
-rw-r--r-- | hw/scsi-disk.c | 69 | ||||
-rw-r--r-- | hw/scsi-generic.c | 24 | ||||
-rw-r--r-- | hw/scsi.h | 3 | ||||
-rw-r--r-- | hw/usb-msd.c | 12 | ||||
-rw-r--r-- | hw/virtio-blk.c | 4 | ||||
-rw-r--r-- | hw/virtio-pci.c | 11 | ||||
-rw-r--r-- | hw/virtio.h | 3 |
13 files changed, 110 insertions, 73 deletions
diff --git a/block_int.h b/block_int.h index 223a437b6a..930a5a4d11 100644 --- a/block_int.h +++ b/block_int.h @@ -202,4 +202,31 @@ extern BlockDriverState *bdrv_first; int is_windows_drive(const char *filename); #endif +struct DriveInfo; + +typedef struct BlockConf { + struct DriveInfo *dinfo; + uint16_t physical_block_size; + uint16_t min_io_size; + uint32_t opt_io_size; +} BlockConf; + +static inline unsigned int get_physical_block_exp(BlockConf *conf) +{ + unsigned int exp = 0, size; + + for (size = conf->physical_block_size; size > 512; size >>= 1) { + exp++; + } + + return exp; +} + +#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \ + DEFINE_PROP_DRIVE("drive", _state, _conf.dinfo), \ + DEFINE_PROP_UINT16("physical_block_size", _state, \ + _conf.physical_block_size, 512), \ + DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 512), \ + DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 512) + #endif /* BLOCK_INT_H */ diff --git a/hw/ide/core.c b/hw/ide/core.c index 603e53776e..4cfaf38211 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2594,7 +2594,8 @@ void ide_bus_reset(IDEBus *bus) ide_clear_hob(bus); } -void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version) +void ide_init_drive(IDEState *s, DriveInfo *dinfo, BlockConf *conf, + const char *version) { int cylinders, heads, secs; uint64_t nb_sectors; @@ -2619,6 +2620,9 @@ void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version) } strncpy(s->drive_serial_str, drive_get_serial(s->bs), sizeof(s->drive_serial_str)); + if (conf) { + s->conf = conf; + } } if (strlen(s->drive_serial_str) == 0) snprintf(s->drive_serial_str, sizeof(s->drive_serial_str), @@ -2648,9 +2652,9 @@ void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1, s->sector_write_timer = qemu_new_timer(vm_clock, ide_sector_write_timer_cb, s); if (i == 0) - ide_init_drive(s, hd0, NULL); + ide_init_drive(s, hd0, NULL, NULL); if (i == 1) - ide_init_drive(s, hd1, NULL); + ide_init_drive(s, hd1, NULL, NULL); } bus->irq = irq; } diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 1cc4b550f7..9945993655 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -7,6 +7,7 @@ * non-internal declarations are in hw/ide.h */ #include <hw/ide.h> +#include "block_int.h" /* debug IDE devices */ //#define DEBUG_IDE @@ -397,6 +398,7 @@ struct IDEState { /* set for lba48 access */ uint8_t lba48; BlockDriverState *bs; + BlockConf *conf; char version[9]; /* ATAPI specific */ uint8_t sense_key; @@ -449,7 +451,7 @@ struct IDEBus { struct IDEDevice { DeviceState qdev; uint32_t unit; - DriveInfo *dinfo; + BlockConf conf; char *version; }; @@ -551,7 +553,8 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr); void ide_data_writel(void *opaque, uint32_t addr, uint32_t val); uint32_t ide_data_readl(void *opaque, uint32_t addr); -void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version); +void ide_init_drive(IDEState *s, DriveInfo *dinfo, BlockConf *conf, + const char *version); void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1, qemu_irq irq); void ide_init_ioport(IDEBus *bus, int iobase, int iobase2); diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 0b84a4f1d0..b18693d945 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -40,7 +40,7 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base) IDEDeviceInfo *info = DO_UPCAST(IDEDeviceInfo, qdev, base); IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus); - if (!dev->dinfo) { + if (!dev->conf.dinfo) { fprintf(stderr, "%s: no drive specified\n", qdev->info->name); goto err; } @@ -99,7 +99,8 @@ typedef struct IDEDrive { static int ide_drive_initfn(IDEDevice *dev) { IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus); - ide_init_drive(bus->ifs + dev->unit, dev->dinfo, dev->version); + ide_init_drive(bus->ifs + dev->unit, dev->conf.dinfo, &dev->conf, + dev->version); return 0; } @@ -109,7 +110,7 @@ static IDEDeviceInfo ide_drive_info = { .init = ide_drive_initfn, .qdev.props = (Property[]) { DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1), - DEFINE_PROP_DRIVE("drive", IDEDrive, dev.dinfo), + DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), DEFINE_PROP_STRING("ver", IDEDrive, dev.version), DEFINE_PROP_END_OF_LIST(), } diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c index 6b6dafc196..fa0a74fae4 100644 --- a/hw/s390-virtio-bus.c +++ b/hw/s390-virtio-bus.c @@ -123,7 +123,7 @@ static int s390_virtio_blk_init(VirtIOS390Device *dev) { VirtIODevice *vdev; - vdev = virtio_blk_init((DeviceState *)dev, dev->dinfo); + vdev = virtio_blk_init((DeviceState *)dev, dev->block.dinfo); if (!vdev) { return -1; } @@ -337,7 +337,7 @@ static VirtIOS390DeviceInfo s390_virtio_blk = { .qdev.name = "virtio-blk-s390", .qdev.size = sizeof(VirtIOS390Device), .qdev.props = (Property[]) { - DEFINE_PROP_DRIVE("drive", VirtIOS390Device, dinfo), + DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block), DEFINE_PROP_END_OF_LIST(), }, }; diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h index 8e4763a184..0ea8f54745 100644 --- a/hw/s390-virtio-bus.h +++ b/hw/s390-virtio-bus.h @@ -38,7 +38,7 @@ typedef struct VirtIOS390Device { ram_addr_t feat_offs; uint8_t feat_len; VirtIODevice *vdev; - DriveInfo *dinfo; + BlockConf block; NICConf nic; uint32_t host_features; /* Max. number of ports we can have for a the virtio-serial device */ diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 1285122092..d510da4aad 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -60,6 +60,7 @@ typedef struct SCSIDiskReq { struct SCSIDiskState { SCSIDevice qdev; + BlockDriverState *bs; /* The qemu block layer uses a fixed 512 byte sector size. This is the number of 512 byte blocks in a single scsi sector. */ int cluster_size; @@ -168,7 +169,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag) r->iov.iov_len = n * 512; qemu_iovec_init_external(&r->qiov, &r->iov, 1); - r->req.aiocb = bdrv_aio_readv(s->qdev.dinfo->bdrv, r->sector, &r->qiov, n, + r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n, scsi_read_complete, r); if (r->req.aiocb == NULL) scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR); @@ -179,11 +180,10 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag) static int scsi_handle_write_error(SCSIDiskReq *r, int error) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - BlockInterfaceErrorAction action = - drive_get_on_error(s->qdev.dinfo->bdrv, 0); + BlockInterfaceErrorAction action = drive_get_on_error(s->bs, 0); if (action == BLOCK_ERR_IGNORE) { - bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_IGNORE, 0); + bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, 0); return 0; } @@ -191,11 +191,11 @@ static int scsi_handle_write_error(SCSIDiskReq *r, int error) || action == BLOCK_ERR_STOP_ANY) { r->status |= SCSI_REQ_STATUS_RETRY; vm_stop(0); - bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_STOP, 0); + bdrv_mon_event(s->bs, BDRV_ACTION_STOP, 0); } else { scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR); - bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_REPORT, 0); + bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, 0); } return 1; @@ -238,7 +238,7 @@ static void scsi_write_request(SCSIDiskReq *r) n = r->iov.iov_len / 512; if (n) { qemu_iovec_init_external(&r->qiov, &r->iov, 1); - r->req.aiocb = bdrv_aio_writev(s->qdev.dinfo->bdrv, r->sector, &r->qiov, n, + r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n, scsi_write_complete, r); if (r->req.aiocb == NULL) scsi_command_complete(r, CHECK_CONDITION, @@ -319,7 +319,6 @@ static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag) static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) { - BlockDriverState *bdrv = req->dev->dinfo->bdrv; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); int buflen = 0; @@ -338,7 +337,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) return -1; } - if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM) { + if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) { outbuf[buflen++] = 5; } else { outbuf[buflen++] = 0; @@ -358,8 +357,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) case 0x80: /* Device serial number, optional */ { - const char *serial = req->dev->dinfo->serial ? - req->dev->dinfo->serial : "0"; + const char *serial = req->dev->conf.dinfo->serial ? + req->dev->conf.dinfo->serial : "0"; int l = strlen(serial); if (l > req->cmd.xfer) @@ -378,7 +377,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) case 0x83: /* Device identification page, mandatory */ { int max_len = 255 - 8; - int id_len = strlen(bdrv_get_device_name(bdrv)); + int id_len = strlen(bdrv_get_device_name(s->bs)); if (id_len > max_len) id_len = max_len; @@ -391,7 +390,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[buflen++] = 0; // reserved outbuf[buflen++] = id_len; // length of data following - memcpy(outbuf+buflen, bdrv_get_device_name(bdrv), id_len); + memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len); buflen += id_len; break; } @@ -429,7 +428,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) return buflen; } - if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM) { + if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) { outbuf[0] = 5; outbuf[1] = 0x80; memcpy(&outbuf[16], "QEMU CD-ROM ", 16); @@ -460,7 +459,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); - BlockDriverState *bdrv = req->dev->dinfo->bdrv; + BlockDriverState *bdrv = s->bs; int cylinders, heads, secs; switch (page) { @@ -532,7 +531,7 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p) case 8: /* Caching page. */ p[0] = 8; p[1] = 0x12; - if (bdrv_enable_write_cache(s->qdev.dinfo->bdrv)) { + if (bdrv_enable_write_cache(s->bs)) { p[2] = 4; /* WCE */ } return 20; @@ -549,7 +548,7 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p) p[5] = 0xff; /* CD DA, DA accurate, RW supported, RW corrected, C2 errors, ISRC, UPC, Bar code */ - p[6] = 0x2d | (bdrv_is_locked(s->qdev.dinfo->bdrv)? 2 : 0); + p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0); /* Locking supported, jumper present, eject, tray */ p[7] = 0; /* no volume & mute control, no changer */ @@ -575,7 +574,6 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p) static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); - BlockDriverState *bdrv = req->dev->dinfo->bdrv; uint64_t nb_sectors; int page, dbd, buflen; uint8_t *p; @@ -588,13 +586,13 @@ static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf) p[1] = 0; /* Default media type. */ p[3] = 0; /* Block descriptor length. */ - if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM || - bdrv_is_read_only(bdrv)) { + if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM || + bdrv_is_read_only(s->bs)) { p[2] = 0x80; /* Readonly. */ } p += 4; - bdrv_get_geometry(bdrv, &nb_sectors); + bdrv_get_geometry(s->bs, &nb_sectors); if ((~dbd) & nb_sectors) { outbuf[3] = 8; /* Block descriptor length */ nb_sectors /= s->cluster_size; @@ -635,14 +633,13 @@ static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf) static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); - BlockDriverState *bdrv = req->dev->dinfo->bdrv; int start_track, format, msf, toclen; uint64_t nb_sectors; msf = req->cmd.buf[1] & 2; format = req->cmd.buf[2] & 0xf; start_track = req->cmd.buf[6]; - bdrv_get_geometry(bdrv, &nb_sectors); + bdrv_get_geometry(s->bs, &nb_sectors); DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1); nb_sectors /= s->cluster_size; switch (format) { @@ -671,13 +668,12 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); - BlockDriverState *bdrv = req->dev->dinfo->bdrv; uint64_t nb_sectors; int buflen = 0; switch (req->cmd.buf[0]) { case TEST_UNIT_READY: - if (!bdrv_is_inserted(bdrv)) + if (!bdrv_is_inserted(s->bs)) goto not_ready; break; case REQUEST_SENSE: @@ -731,18 +727,18 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf) goto illegal_request; break; case START_STOP: - if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) { + if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) { /* load/eject medium */ - bdrv_eject(bdrv, !(req->cmd.buf[4] & 1)); + bdrv_eject(s->bs, !(req->cmd.buf[4] & 1)); } break; case ALLOW_MEDIUM_REMOVAL: - bdrv_set_locked(bdrv, req->cmd.buf[4] & 1); + bdrv_set_locked(s->bs, req->cmd.buf[4] & 1); break; case READ_CAPACITY: /* The normal LEN field for this command is zero. */ memset(outbuf, 0, 8); - bdrv_get_geometry(bdrv, &nb_sectors); + bdrv_get_geometry(s->bs, &nb_sectors); if (!nb_sectors) goto not_ready; nb_sectors /= s->cluster_size; @@ -764,7 +760,7 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf) buflen = 8; break; case SYNCHRONIZE_CACHE: - bdrv_flush(bdrv); + bdrv_flush(s->bs); break; case GET_CONFIGURATION: memset(outbuf, 0, 8); @@ -778,7 +774,7 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf) if ((req->cmd.buf[1] & 31) == 0x10) { DPRINTF("SAI READ CAPACITY(16)\n"); memset(outbuf, 0, req->cmd.xfer); - bdrv_get_geometry(bdrv, &nb_sectors); + bdrv_get_geometry(s->bs, &nb_sectors); if (!nb_sectors) goto not_ready; nb_sectors /= s->cluster_size; @@ -993,7 +989,7 @@ static void scsi_destroy(SCSIDevice *dev) r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests)); scsi_remove_request(r); } - drive_uninit(s->qdev.dinfo); + drive_uninit(s->qdev.conf.dinfo); } static int scsi_disk_initfn(SCSIDevice *dev) @@ -1001,19 +997,20 @@ static int scsi_disk_initfn(SCSIDevice *dev) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); uint64_t nb_sectors; - if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) { + if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) { qemu_error("scsi-disk: drive property not set\n"); return -1; } + s->bs = s->qdev.conf.dinfo->bdrv; - if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) { + if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) { s->cluster_size = 4; } else { s->cluster_size = 1; } s->qdev.blocksize = 512 * s->cluster_size; s->qdev.type = TYPE_DISK; - bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors); + bdrv_get_geometry(s->bs, &nb_sectors); nb_sectors /= s->cluster_size; if (nb_sectors) nb_sectors--; @@ -1034,7 +1031,7 @@ static SCSIDeviceInfo scsi_disk_info = { .cancel_io = scsi_cancel_io, .get_buf = scsi_get_buf, .qdev.props = (Property[]) { - DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.dinfo), + DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), DEFINE_PROP_STRING("ver", SCSIDiskState, version), DEFINE_PROP_END_OF_LIST(), }, diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index f60ad96d79..de778efa3b 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -58,6 +58,7 @@ typedef struct SCSIGenericReq { struct SCSIGenericState { SCSIDevice qdev; + BlockDriverState *bs; int lun; int driver_status; uint8_t sensebuf[SCSI_SENSE_BUF_SIZE]; @@ -212,7 +213,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag) return; } - ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete); + ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete); if (ret == -1) { scsi_command_complete(r, -EINVAL); return; @@ -263,7 +264,7 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag) return 0; } - ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete); + ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete); if (ret == -1) { scsi_command_complete(r, -EINVAL); return 1; @@ -357,7 +358,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, qemu_free(r->buf); r->buflen = 0; r->buf = NULL; - ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_NONE, scsi_command_complete); + ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete); if (ret == -1) { scsi_command_complete(r, -EINVAL); return 0; @@ -452,7 +453,7 @@ static void scsi_destroy(SCSIDevice *d) r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests)); scsi_remove_request(r); } - drive_uninit(s->qdev.dinfo); + drive_uninit(s->qdev.conf.dinfo); } static int scsi_generic_initfn(SCSIDevice *dev) @@ -461,26 +462,27 @@ static int scsi_generic_initfn(SCSIDevice *dev) int sg_version; struct sg_scsi_id scsiid; - if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) { + if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) { qemu_error("scsi-generic: drive property not set\n"); return -1; } + s->bs = s->qdev.conf.dinfo->bdrv; /* check we are really using a /dev/sg* file */ - if (!bdrv_is_sg(s->qdev.dinfo->bdrv)) { + if (!bdrv_is_sg(s->bs)) { qemu_error("scsi-generic: not /dev/sg*\n"); return -1; } /* check we are using a driver managing SG_IO (version 3 and after */ - if (bdrv_ioctl(s->qdev.dinfo->bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 || + if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 || sg_version < 30000) { qemu_error("scsi-generic: scsi generic interface too old\n"); return -1; } /* get LUN of the /dev/sg? */ - if (bdrv_ioctl(s->qdev.dinfo->bdrv, SG_GET_SCSI_ID, &scsiid)) { + if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) { qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n"); return -1; } @@ -491,11 +493,11 @@ static int scsi_generic_initfn(SCSIDevice *dev) s->qdev.type = scsiid.scsi_type; DPRINTF("device type %d\n", s->qdev.type); if (s->qdev.type == TYPE_TAPE) { - s->qdev.blocksize = get_stream_blocksize(s->qdev.dinfo->bdrv); + s->qdev.blocksize = get_stream_blocksize(s->bs); if (s->qdev.blocksize == -1) s->qdev.blocksize = 0; } else { - s->qdev.blocksize = get_blocksize(s->qdev.dinfo->bdrv); + s->qdev.blocksize = get_blocksize(s->bs); /* removable media returns 0 if not present */ if (s->qdev.blocksize <= 0) { if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM) @@ -522,7 +524,7 @@ static SCSIDeviceInfo scsi_generic_info = { .cancel_io = scsi_cancel_io, .get_buf = scsi_get_buf, .qdev.props = (Property[]) { - DEFINE_PROP_DRIVE("drive", SCSIGenericState, qdev.dinfo), + DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf), DEFINE_PROP_END_OF_LIST(), }, }; @@ -3,6 +3,7 @@ #include "qdev.h" #include "block.h" +#include "block_int.h" #define SCSI_CMD_BUF_SIZE 16 @@ -49,7 +50,7 @@ struct SCSIDevice { DeviceState qdev; uint32_t id; - DriveInfo *dinfo; + BlockConf conf; SCSIDeviceInfo *info; QTAILQ_HEAD(, SCSIRequest) requests; int blocksize; diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 1fb62ad13c..36991f8833 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -47,7 +47,7 @@ typedef struct { uint32_t residue; uint32_t tag; SCSIBus bus; - DriveInfo *dinfo; + BlockConf conf; SCSIDevice *scsi_dev; int result; /* For async completion. */ @@ -523,20 +523,20 @@ static int usb_msd_initfn(USBDevice *dev) { MSDState *s = DO_UPCAST(MSDState, dev, dev); - if (!s->dinfo || !s->dinfo->bdrv) { + if (!s->conf.dinfo || !s->conf.dinfo->bdrv) { qemu_error("usb-msd: drive property not set\n"); return -1; } s->dev.speed = USB_SPEED_FULL; scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete); - s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->dinfo, 0); + s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->conf.dinfo, 0); s->bus.qbus.allow_hotplug = 0; usb_msd_handle_reset(dev); - if (bdrv_key_required(s->dinfo->bdrv)) { + if (bdrv_key_required(s->conf.dinfo->bdrv)) { if (s->dev.qdev.hotplugged) { - monitor_read_bdrv_key_start(cur_mon, s->dinfo->bdrv, + monitor_read_bdrv_key_start(cur_mon, s->conf.dinfo->bdrv, usb_msd_password_cb, s); s->dev.auto_attach = 0; } else { @@ -611,7 +611,7 @@ static struct USBDeviceInfo msd_info = { .usbdevice_name = "disk", .usbdevice_init = usb_msd_init, .qdev.props = (Property[]) { - DEFINE_PROP_DRIVE("drive", MSDState, dinfo), + DEFINE_BLOCK_PROPERTIES(MSDState, conf), DEFINE_PROP_END_OF_LIST(), }, }; diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 363ffc1be9..6aa7f15ee2 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -457,7 +457,7 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id) return 0; } -VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo) +VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf) { VirtIOBlock *s; int cylinders, heads, secs; @@ -470,7 +470,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo) s->vdev.get_config = virtio_blk_update_config; s->vdev.get_features = virtio_blk_get_features; s->vdev.reset = virtio_blk_reset; - s->bs = dinfo->bdrv; + s->bs = conf->dinfo->bdrv; s->rq = NULL; bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs); bdrv_set_geometry_hint(s->bs, cylinders, heads, secs); diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 709d13e4ce..f3373ae50e 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -22,6 +22,7 @@ #include "sysemu.h" #include "msix.h" #include "net.h" +#include "block_int.h" #include "loader.h" /* from Linux's linux/virtio_pci.h */ @@ -92,7 +93,7 @@ typedef struct { uint32_t addr; uint32_t class_code; uint32_t nvectors; - DriveInfo *dinfo; + BlockConf block; NICConf nic; uint32_t host_features; /* Max. number of ports we can have for a the virtio-serial device */ @@ -457,11 +458,11 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev) proxy->class_code != PCI_CLASS_STORAGE_OTHER) proxy->class_code = PCI_CLASS_STORAGE_SCSI; - if (!proxy->dinfo) { + if (!proxy->block.dinfo) { qemu_error("virtio-blk-pci: drive property not set\n"); return -1; } - vdev = virtio_blk_init(&pci_dev->qdev, proxy->dinfo); + vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block); vdev->nvectors = proxy->nvectors; virtio_init_pci(proxy, vdev, PCI_VENDOR_ID_REDHAT_QUMRANET, @@ -481,7 +482,7 @@ static int virtio_blk_exit_pci(PCIDevice *pci_dev) { VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - drive_uninit(proxy->dinfo); + drive_uninit(proxy->block.dinfo); return virtio_exit_pci(pci_dev); } @@ -558,7 +559,7 @@ static PCIDeviceInfo virtio_info[] = { .exit = virtio_blk_exit_pci, .qdev.props = (Property[]) { DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), - DEFINE_PROP_DRIVE("drive", VirtIOPCIProxy, dinfo), + DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block), DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/virtio.h b/hw/virtio.h index 62e882bb67..3baa2a34da 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -18,6 +18,7 @@ #include "net.h" #include "qdev.h" #include "sysemu.h" +#include "block_int.h" /* from Linux's linux/virtio_config.h */ @@ -169,7 +170,7 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding, void *opaque); /* Base devices. */ -VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo); +VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf); VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf); VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports); VirtIODevice *virtio_balloon_init(DeviceState *dev); |