aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-10-06 10:39:54 +0200
committerAvi Kivity <avi@redhat.com>2009-10-06 10:39:54 +0200
commit2455aed9dc69d2cfae95ab10c229f96604f8cebb (patch)
tree3964c6d564cd322293be32c5aef9584615dc547b /hw
parentMerge commit '3f84865ade594a2ec1ef613ab5fd11949f3d49de' into upstream-merge (diff)
parentqemu: clean up target page usage in msix (diff)
downloadqemu-kvm-2455aed9dc69d2cfae95ab10c229f96604f8cebb.tar.gz
qemu-kvm-2455aed9dc69d2cfae95ab10c229f96604f8cebb.tar.bz2
qemu-kvm-2455aed9dc69d2cfae95ab10c229f96604f8cebb.zip
Merge commit '5a1fc5e8529afb6041a3dfa406a94c187d2afc1d' into upstream-merge
* commit '5a1fc5e8529afb6041a3dfa406a94c187d2afc1d': qemu: clean up target page usage in msix fix comment on cpu_register_physical_memory_offset qemu/pci: reset device registers on bus reset qemu/pci: refactor code/symbolic constants qemu/virtio: fix reset with device removal qemu/qdev: type safety in reset handler serial: convert isa to qdev qdev: don't crash on unset drive properties. floppy: move dma setup + drive connect to fdctrl_init_common() floppy: add drive properties. store a pointer to QemuOpts in DeviceState, release it when zapping a device. allow if=none for drive_add refactor drive_hot_add drive cleanup fixes. Conflicts: hw/msix.c hw/pci.h Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/device-hotplug.c18
-rw-r--r--hw/fdc.c71
-rw-r--r--hw/fdc.h7
-rw-r--r--hw/mips_jazz.c5
-rw-r--r--hw/mips_malta.c9
-rw-r--r--hw/mips_r4k.c6
-rw-r--r--hw/msix.c49
-rw-r--r--hw/msix.h5
-rw-r--r--hw/pc.c12
-rw-r--r--hw/pc.h1
-rw-r--r--hw/pci-hotplug.c44
-rw-r--r--hw/pci.c54
-rw-r--r--hw/pci.h2
-rw-r--r--hw/ppc_prep.c9
-rw-r--r--hw/qdev-properties.c2
-rw-r--r--hw/qdev.c16
-rw-r--r--hw/qdev.h4
-rw-r--r--hw/rtl8139.c10
-rw-r--r--hw/scsi-disk.c8
-rw-r--r--hw/scsi-generic.c2
-rw-r--r--hw/serial.c77
-rw-r--r--hw/sun4m.c16
-rw-r--r--hw/sun4u.c12
-rw-r--r--hw/tcx.c6
-rw-r--r--hw/usb-msd.c8
-rw-r--r--hw/virtio-blk.c1
-rw-r--r--hw/virtio-pci.c26
27 files changed, 272 insertions, 208 deletions
diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index 69779caef..c0cfd31d4 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -62,21 +62,3 @@ void destroy_nic(dev_match_fn *match_fn, void *arg)
}
}
}
-
-void destroy_bdrvs(dev_match_fn *match_fn, void *arg)
-{
- DriveInfo *dinfo;
- struct BlockDriverState *bs;
-
- QTAILQ_FOREACH(dinfo, &drives, next) {
- bs = dinfo->bdrv;
- if (bs) {
- if (bs->private && match_fn(bs->private, arg)) {
- drive_uninit(bs);
- bdrv_delete(bs);
- }
- }
- }
-}
-
-
diff --git a/hw/fdc.c b/hw/fdc.c
index a7c65c70f..6a6e7a8de 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -81,6 +81,7 @@ typedef enum fdisk_flags_t {
} fdisk_flags_t;
typedef struct fdrive_t {
+ DriveInfo *dinfo;
BlockDriverState *bs;
/* Drive status */
fdrive_type_t drive;
@@ -97,10 +98,10 @@ typedef struct fdrive_t {
uint8_t ro; /* Is read-only */
} fdrive_t;
-static void fd_init (fdrive_t *drv, BlockDriverState *bs)
+static void fd_init (fdrive_t *drv)
{
/* Drive */
- drv->bs = bs;
+ drv->bs = drv->dinfo ? drv->dinfo->bdrv : NULL;
drv->drive = FDRIVE_DRV_NONE;
drv->perpendicular = 0;
/* Disk */
@@ -1829,74 +1830,67 @@ static void fdctrl_result_timer(void *opaque)
}
/* Init functions */
-static void fdctrl_connect_drives(fdctrl_t *fdctrl, BlockDriverState **fds)
+static void fdctrl_connect_drives(fdctrl_t *fdctrl)
{
unsigned int i;
for (i = 0; i < MAX_FD; i++) {
- fd_init(&fdctrl->drives[i], fds[i]);
+ fd_init(&fdctrl->drives[i]);
fd_revalidate(&fdctrl->drives[i]);
}
}
-fdctrl_t *fdctrl_init_isa(BlockDriverState **fds)
+fdctrl_t *fdctrl_init_isa(DriveInfo **fds)
{
- fdctrl_t *fdctrl;
ISADevice *dev;
- int dma_chann = 2;
-
- dev = isa_create_simple("isa-fdc");
- fdctrl = &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
-
- fdctrl->dma_chann = dma_chann;
- DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
-
- fdctrl_connect_drives(fdctrl, fds);
- return fdctrl;
+ dev = isa_create("isa-fdc");
+ qdev_prop_set_drive(&dev->qdev, "driveA", fds[0]);
+ qdev_prop_set_drive(&dev->qdev, "driveB", fds[1]);
+ if (qdev_init(&dev->qdev) != 0)
+ return NULL;
+ return &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state);
}
fdctrl_t *fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
target_phys_addr_t mmio_base,
- BlockDriverState **fds)
+ DriveInfo **fds)
{
fdctrl_t *fdctrl;
DeviceState *dev;
fdctrl_sysbus_t *sys;
dev = qdev_create(NULL, "sysbus-fdc");
- qdev_init(dev);
sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev);
fdctrl = &sys->state;
+ fdctrl->dma_chann = dma_chann; /* FIXME */
+ qdev_prop_set_drive(dev, "driveA", fds[0]);
+ qdev_prop_set_drive(dev, "driveB", fds[1]);
+ if (qdev_init(dev) != 0)
+ return NULL;
sysbus_connect_irq(&sys->busdev, 0, irq);
sysbus_mmio_map(&sys->busdev, 0, mmio_base);
- fdctrl->dma_chann = dma_chann;
- DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
- fdctrl_connect_drives(fdctrl, fds);
-
return fdctrl;
}
fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
- BlockDriverState **fds, qemu_irq *fdc_tc)
+ DriveInfo **fds, qemu_irq *fdc_tc)
{
DeviceState *dev;
fdctrl_sysbus_t *sys;
fdctrl_t *fdctrl;
dev = qdev_create(NULL, "SUNW,fdtwo");
- qdev_init(dev);
+ qdev_prop_set_drive(dev, "drive", fds[0]);
+ if (qdev_init(dev) != 0)
+ return NULL;
sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev);
fdctrl = &sys->state;
sysbus_connect_irq(&sys->busdev, 0, irq);
sysbus_mmio_map(&sys->busdev, 0, io_base);
*fdc_tc = qdev_get_gpio_in(dev, 0);
- fdctrl->dma_chann = -1;
-
- fdctrl_connect_drives(fdctrl, fds);
-
return fdctrl;
}
@@ -1927,6 +1921,10 @@ static int fdctrl_init_common(fdctrl_t *fdctrl)
fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
fdctrl->num_floppies = MAX_FD;
+ if (fdctrl->dma_chann != -1)
+ DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
+ fdctrl_connect_drives(fdctrl);
+
fdctrl_external_reset(fdctrl);
vmstate_register(-1, &vmstate_fdc, fdctrl);
qemu_register_reset(fdctrl_external_reset, fdctrl);
@@ -1939,6 +1937,7 @@ static int isabus_fdc_init1(ISADevice *dev)
fdctrl_t *fdctrl = &isa->state;
int iobase = 0x3f0;
int isairq = 6;
+ int dma_chann = 2;
register_ioport_read(iobase + 0x01, 5, 1,
&fdctrl_read_port, fdctrl);
@@ -1949,6 +1948,7 @@ static int isabus_fdc_init1(ISADevice *dev)
register_ioport_write(iobase + 0x07, 1, 1,
&fdctrl_write_port, fdctrl);
isa_init_irq(&isa->busdev, &fdctrl->irq, isairq);
+ fdctrl->dma_chann = dma_chann;
return fdctrl_init_common(fdctrl);
}
@@ -1962,6 +1962,7 @@ static int sysbus_fdc_init1(SysBusDevice *dev)
sysbus_init_mmio(dev, 0x08, io);
sysbus_init_irq(dev, &fdctrl->irq);
qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
+ fdctrl->dma_chann = -1;
return fdctrl_init_common(fdctrl);
}
@@ -1985,18 +1986,32 @@ static ISADeviceInfo isa_fdc_info = {
.init = isabus_fdc_init1,
.qdev.name = "isa-fdc",
.qdev.size = sizeof(fdctrl_isabus_t),
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_DRIVE("driveA", fdctrl_isabus_t, state.drives[0].dinfo),
+ DEFINE_PROP_DRIVE("driveB", fdctrl_isabus_t, state.drives[1].dinfo),
+ DEFINE_PROP_END_OF_LIST(),
+ },
};
static SysBusDeviceInfo sysbus_fdc_info = {
.init = sysbus_fdc_init1,
.qdev.name = "sysbus-fdc",
.qdev.size = sizeof(fdctrl_sysbus_t),
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_DRIVE("driveA", fdctrl_sysbus_t, state.drives[0].dinfo),
+ DEFINE_PROP_DRIVE("driveB", fdctrl_sysbus_t, state.drives[1].dinfo),
+ DEFINE_PROP_END_OF_LIST(),
+ },
};
static SysBusDeviceInfo sun4m_fdc_info = {
.init = sun4m_fdc_init1,
.qdev.name = "SUNW,fdtwo",
.qdev.size = sizeof(fdctrl_sysbus_t),
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_DRIVE("drive", fdctrl_sysbus_t, state.drives[0].dinfo),
+ DEFINE_PROP_END_OF_LIST(),
+ },
};
static void fdc_register_devices(void)
diff --git a/hw/fdc.h b/hw/fdc.h
index 1b81ec1db..c64e8b457 100644
--- a/hw/fdc.h
+++ b/hw/fdc.h
@@ -1,12 +1,13 @@
/* fdc.c */
+#include "sysemu.h"
#define MAX_FD 2
typedef struct fdctrl_t fdctrl_t;
-fdctrl_t *fdctrl_init_isa(BlockDriverState **fds);
+fdctrl_t *fdctrl_init_isa(DriveInfo **fds);
fdctrl_t *fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
target_phys_addr_t mmio_base,
- BlockDriverState **fds);
+ DriveInfo **fds);
fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
- BlockDriverState **fds, qemu_irq *fdc_tc);
+ DriveInfo **fds, qemu_irq *fdc_tc);
int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 2a70b8bec..9578f28a4 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -126,7 +126,7 @@ void mips_jazz_init (ram_addr_t ram_size,
int s_rtc, s_dma_dummy;
NICInfo *nd;
PITState *pit;
- BlockDriverState *fds[MAX_FD];
+ DriveInfo *fds[MAX_FD];
qemu_irq esp_reset;
ram_addr_t ram_offset;
ram_addr_t bios_offset;
@@ -234,8 +234,7 @@ void mips_jazz_init (ram_addr_t ram_size,
exit(1);
}
for (n = 0; n < MAX_FD; n++) {
- DriveInfo *dinfo = drive_get(IF_FLOPPY, 0, n);
- fds[n] = dinfo ? dinfo->bdrv : NULL;
+ fds[n] = drive_get(IF_FLOPPY, 0, n);
}
fdctrl_init_sysbus(rc4030[1], 0, 0x80003000, fds);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index ba276519e..4b5e470e2 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -786,7 +786,7 @@ void mips_malta_init (ram_addr_t ram_size,
int i;
DriveInfo *dinfo;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- BlockDriverState *fd[MAX_FD];
+ DriveInfo *fd[MAX_FD];
int fl_idx = 0;
int fl_sectors = 0;
@@ -942,13 +942,12 @@ void mips_malta_init (ram_addr_t ram_size,
isa_dev = isa_create_simple("i8042");
rtc_state = rtc_init(2000);
- serial_init(0x3f8, isa_reserve_irq(4), 115200, serial_hds[0]);
- serial_init(0x2f8, isa_reserve_irq(3), 115200, serial_hds[1]);
+ serial_isa_init(0, serial_hds[0]);
+ serial_isa_init(1, serial_hds[1]);
if (parallel_hds[0])
parallel_init(0, parallel_hds[0]);
for(i = 0; i < MAX_FD; i++) {
- dinfo = drive_get(IF_FLOPPY, 0, i);
- fd[i] = dinfo ? dinfo->bdrv : NULL;
+ fd[i] = drive_get(IF_FLOPPY, 0, i);
}
floppy_controller = fdctrl_init_isa(fd);
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index b3abc6155..d7b301a9c 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -31,9 +31,6 @@ static const int ide_iobase[2] = { 0x1f0, 0x170 };
static const int ide_iobase2[2] = { 0x3f6, 0x376 };
static const int ide_irq[2] = { 14, 15 };
-static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
-
static PITState *pit; /* PIT i8254 */
/* i8254 PIT is attached to the IRQ0 at PIC i8259 */
@@ -262,8 +259,7 @@ void mips_r4k_init (ram_addr_t ram_size,
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) {
- serial_init(serial_io[i], i8259[serial_irq[i]], 115200,
- serial_hds[i]);
+ serial_isa_init(i, serial_hds[i]);
}
}
diff --git a/hw/msix.c b/hw/msix.c
index 832eb0415..b68fb5f4c 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -40,6 +40,13 @@
#define MSIX_VECTOR_CTRL 12
#define MSIX_ENTRY_SIZE 16
#define MSIX_VECTOR_MASK 0x1
+
+/* How much space does an MSIX table need. */
+/* The spec requires giving the table structure
+ * a 4K aligned region all by itself. */
+#define MSIX_PAGE_SIZE 0x1000
+/* Reserve second half of the page for pending bits */
+#define MSIX_PAGE_PENDING (MSIX_PAGE_SIZE / 2)
#define MSIX_MAX_ENTRIES 32
@@ -166,12 +173,6 @@ static int kvm_msix_add(PCIDevice *dev, unsigned vector) { return -1; }
static void kvm_msix_del(PCIDevice *dev, unsigned vector) {}
#endif
-/* Reserve second half of the page for pending bits */
-static int msix_page_pending(PCIDevice *d)
-{
- return (d->msix_page_size / 2);
-}
-
/* Add MSI-X capability to the config space for the device. */
/* Given a bar and its size, add MSI-X table on top of it
* and fill MSI-X capability in the config space.
@@ -191,12 +192,13 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
/* Add space for MSI-X structures */
if (!bar_size) {
- new_size = pdev->msix_page_size;
- } else if (bar_size < pdev->msix_page_size) {
- bar_size = pdev->msix_page_size;
- new_size = pdev->msix_page_size * 2;
- } else
+ new_size = MSIX_PAGE_SIZE;
+ } else if (bar_size < MSIX_PAGE_SIZE) {
+ bar_size = MSIX_PAGE_SIZE;
+ new_size = MSIX_PAGE_SIZE * 2;
+ } else {
new_size = bar_size * 2;
+ }
pdev->msix_bar_size = new_size;
config_offset = pci_add_capability(pdev, PCI_CAP_ID_MSIX, MSIX_CAP_LENGTH);
@@ -208,8 +210,8 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
/* Table on top of BAR */
pci_set_long(config + MSIX_TABLE_OFFSET, bar_size | bar_nr);
/* Pending bits on top of that */
- pci_set_long(config + MSIX_PBA_OFFSET, (bar_size + msix_page_pending(pdev))
- | bar_nr);
+ pci_set_long(config + MSIX_PBA_OFFSET, (bar_size + MSIX_PAGE_PENDING) |
+ bar_nr);
pdev->msix_cap = config_offset;
/* Make flags bit writeable. */
pdev->wmask[config_offset + MSIX_ENABLE_OFFSET] |= MSIX_ENABLE_MASK;
@@ -242,7 +244,7 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
{
PCIDevice *dev = opaque;
- unsigned int offset = addr & (dev->msix_page_size - 1);
+ unsigned int offset = addr & (MSIX_PAGE_SIZE - 1);
void *page = dev->msix_table_page;
uint32_t val = 0;
@@ -264,7 +266,7 @@ static uint8_t msix_pending_mask(int vector)
static uint8_t *msix_pending_byte(PCIDevice *dev, int vector)
{
- return dev->msix_table_page + msix_page_pending(dev) + vector / 8;
+ return dev->msix_table_page + MSIX_PAGE_PENDING + vector / 8;
}
static int msix_is_pending(PCIDevice *dev, int vector)
@@ -292,7 +294,7 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
PCIDevice *dev = opaque;
- unsigned int offset = addr & (dev->msix_page_size - 1);
+ unsigned int offset = addr & (MSIX_PAGE_SIZE - 1);
int vector = offset / MSIX_ENTRY_SIZE;
int was_masked = msix_is_masked(dev, vector);
memcpy(dev->msix_table_page + offset, &val, 4);
@@ -325,7 +327,7 @@ void msix_mmio_map(PCIDevice *d, int region_num,
{
uint8_t *config = d->config + d->msix_cap;
uint32_t table = pci_get_long(config + MSIX_TABLE_OFFSET);
- uint32_t offset = table & ~(d->msix_page_size - 1);
+ uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1);
/* TODO: for assigned devices, we'll want to make it possible to map
* pending bits separately in case they are in a separate bar. */
int table_bir = table & PCI_MSIX_FLAGS_BIRMASK;
@@ -341,7 +343,7 @@ void msix_mmio_map(PCIDevice *d, int region_num,
/* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is
* modified, it should be retrieved with msix_bar_size. */
int msix_init(struct PCIDevice *dev, unsigned short nentries,
- unsigned bar_nr, unsigned bar_size, target_phys_addr_t page_size)
+ unsigned bar_nr, unsigned bar_size)
{
int ret;
/* Nothing to do if MSI is not supported by interrupt controller */
@@ -360,8 +362,7 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
dev->msix_entry_used = qemu_mallocz(MSIX_MAX_ENTRIES *
sizeof *dev->msix_entry_used);
- dev->msix_page_size = page_size;
- dev->msix_table_page = qemu_mallocz(dev->msix_page_size);
+ dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE);
dev->msix_mmio_index = cpu_register_io_memory(msix_mmio_read,
msix_mmio_write, dev);
@@ -421,8 +422,7 @@ void msix_save(PCIDevice *dev, QEMUFile *f)
return;
}
qemu_put_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE);
- qemu_put_buffer(f, dev->msix_table_page + msix_page_pending(dev),
- (n + 7) / 8);
+ qemu_put_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
}
/* Should be called after restoring the config space. */
@@ -439,8 +439,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
msix_free_irq_entries(dev);
qemu_get_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE);
- qemu_get_buffer(f, dev->msix_table_page + msix_page_pending(dev),
- (n + 7) / 8);
+ qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
}
/* Does device support MSI-X? */
@@ -497,7 +496,7 @@ void msix_reset(PCIDevice *dev)
return;
msix_free_irq_entries(dev);
dev->config[dev->msix_cap + MSIX_ENABLE_OFFSET] &= MSIX_ENABLE_MASK;
- memset(dev->msix_table_page, 0, dev->msix_page_size);
+ memset(dev->msix_table_page, 0, MSIX_PAGE_SIZE);
}
/* PCI spec suggests that devices make it possible for software to configure
diff --git a/hw/msix.h b/hw/msix.h
index 9367ba38f..3427778dc 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -3,9 +3,8 @@
#include "qemu-common.h"
-int msix_init(struct PCIDevice *dev, unsigned short nentries,
- unsigned bar_nr, unsigned bar_size,
- target_phys_addr_t page_size);
+int msix_init(PCIDevice *pdev, unsigned short nentries,
+ unsigned bar_nr, unsigned bar_size);
void msix_write_config(PCIDevice *pci_dev, uint32_t address,
uint32_t val, int len);
diff --git a/hw/pc.c b/hw/pc.c
index 8f8f2ea60..6debb7399 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1028,9 +1028,6 @@ static const int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360,
0x280, 0x380 };
static const int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
-static const int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-static const int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
-
static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
@@ -1146,9 +1143,8 @@ static void pc_init1(ram_addr_t ram_size,
qemu_irq *isa_irq;
qemu_irq *i8259;
IsaIrqState *isa_irq_state;
- DriveInfo *dinfo;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- BlockDriverState *fd[MAX_FD];
+ DriveInfo *fd[MAX_FD];
int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;
void *fw_cfg;
@@ -1362,8 +1358,7 @@ static void pc_init1(ram_addr_t ram_size,
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) {
- serial_init(serial_io[i], isa_reserve_irq(serial_irq[i]), 115200,
- serial_hds[i]);
+ serial_isa_init(i, serial_hds[i]);
}
}
@@ -1407,8 +1402,7 @@ static void pc_init1(ram_addr_t ram_size,
#endif
for(i = 0; i < MAX_FD; i++) {
- dinfo = drive_get(IF_FLOPPY, 0, i);
- fd[i] = dinfo ? dinfo->bdrv : NULL;
+ fd[i] = drive_get(IF_FLOPPY, 0, i);
}
floppy_controller = fdctrl_init_isa(fd);
diff --git a/hw/pc.h b/hw/pc.h
index 53a40490e..93eb34dc5 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -12,6 +12,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
qemu_irq irq, int baudbase,
CharDriverState *chr, int ioregister);
+SerialState *serial_isa_init(int index, CharDriverState *chr);
/* parallel.c */
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 282d15d35..ed06e6833 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -59,48 +59,51 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
int dom, pci_bus;
unsigned slot;
int type, bus;
- int success = 0;
PCIDevice *dev;
- DriveInfo *dinfo;
+ DriveInfo *dinfo = NULL;
const char *pci_addr = qdict_get_str(qdict, "pci_addr");
const char *opts = qdict_get_str(qdict, "opts");
BusState *scsibus;
- if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
- return;
- }
-
- dev = pci_find_device(pci_bus, slot, 0);
- if (!dev) {
- monitor_printf(mon, "no pci device with address %s\n", pci_addr);
- return;
- }
-
dinfo = add_init_drive(opts);
if (!dinfo)
- return;
+ goto err;
if (dinfo->devaddr) {
monitor_printf(mon, "Parameter addr not supported\n");
- return;
+ goto err;
}
type = dinfo->type;
bus = drive_get_max_bus (type);
switch (type) {
case IF_SCSI:
- success = 1;
+ if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
+ goto err;
+ }
+ dev = pci_find_device(pci_bus, slot, 0);
+ if (!dev) {
+ monitor_printf(mon, "no pci device with address %s\n", pci_addr);
+ goto err;
+ }
scsibus = QLIST_FIRST(&dev->qdev.child_bus);
scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus),
dinfo, dinfo->unit);
+ monitor_printf(mon, "OK bus %d, unit %d\n",
+ dinfo->bus,
+ dinfo->unit);
+ break;
+ case IF_NONE:
+ monitor_printf(mon, "OK\n");
break;
default:
monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
+ goto err;
}
+ return;
- if (success)
- monitor_printf(mon, "OK bus %d, unit %d\n",
- dinfo->bus,
- dinfo->unit);
+err:
+ if (dinfo)
+ drive_uninit(dinfo);
return;
}
@@ -289,9 +292,6 @@ void pci_device_hot_remove_success(PCIDevice *d)
class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
switch(class_code) {
- case PCI_BASE_CLASS_STORAGE:
- destroy_bdrvs(pci_match_fn, d);
- break;
case PCI_BASE_CLASS_NETWORK:
destroy_nic(pci_match_fn, d);
break;
diff --git a/hw/pci.c b/hw/pci.c
index dad246b9c..5adcc64c9 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -88,6 +88,29 @@ static const VMStateDescription vmstate_pcibus = {
}
};
+static inline int pci_bar(int reg)
+{
+ return reg == PCI_ROM_SLOT ? PCI_ROM_ADDRESS : PCI_BASE_ADDRESS_0 + reg * 4;
+}
+
+static void pci_device_reset(PCIDevice *dev)
+{
+ int r;
+
+ memset(dev->irq_state, 0, sizeof dev->irq_state);
+ dev->config[PCI_COMMAND] &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER);
+ dev->config[PCI_CACHE_LINE_SIZE] = 0x0;
+ dev->config[PCI_INTERRUPT_LINE] = 0x0;
+ for (r = 0; r < PCI_NUM_REGIONS; ++r) {
+ if (!dev->io_regions[r].size) {
+ continue;
+ }
+ pci_set_long(dev->config + pci_bar(r), dev->io_regions[r].type);
+ }
+ pci_update_mappings(dev);
+}
+
static void pci_bus_reset(void *opaque)
{
PCIBus *bus = opaque;
@@ -96,10 +119,10 @@ static void pci_bus_reset(void *opaque)
for (i = 0; i < bus->nirq; i++) {
bus->irq_count[i] = 0;
}
- for (i = 0; i < 256; i++) {
- if (bus->devices[i])
- memset(bus->devices[i]->irq_state, 0,
- sizeof(bus->devices[i]->irq_state));
+ for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
+ if (bus->devices[i]) {
+ pci_device_reset(bus->devices[i]);
+ }
}
}
@@ -503,12 +526,10 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
r->map_func = map_func;
wmask = ~(size - 1);
+ addr = pci_bar(region_num);
if (region_num == PCI_ROM_SLOT) {
- addr = 0x30;
/* ROM enable bit is writeable */
- wmask |= 1;
- } else {
- addr = 0x10 + region_num * 4;
+ wmask |= PCI_ROM_ADDRESS_ENABLE;
}
*(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
*(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask);
@@ -519,21 +540,15 @@ static void pci_update_mappings(PCIDevice *d)
{
PCIIORegion *r;
int cmd, i;
- uint32_t last_addr, new_addr, config_ofs;
+ uint32_t last_addr, new_addr;
cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
for(i = 0; i < PCI_NUM_REGIONS; i++) {
r = &d->io_regions[i];
- if (i == PCI_ROM_SLOT) {
- config_ofs = 0x30;
- } else {
- config_ofs = 0x10 + i * 4;
- }
if (r->size != 0) {
if (r->type & PCI_ADDRESS_SPACE_IO) {
if (cmd & PCI_COMMAND_IO) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
+ new_addr = pci_get_long(d->config + pci_bar(i));
new_addr = new_addr & ~(r->size - 1);
last_addr = new_addr + r->size - 1;
/* NOTE: we have only 64K ioports on PC */
@@ -546,10 +561,9 @@ static void pci_update_mappings(PCIDevice *d)
}
} else {
if (cmd & PCI_COMMAND_MEMORY) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
+ new_addr = pci_get_long(d->config + pci_bar(i));
/* the ROM slot has a specific enable bit */
- if (i == PCI_ROM_SLOT && !(new_addr & 1))
+ if (i == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE))
goto no_mem_map;
new_addr = new_addr & ~(r->size - 1);
last_addr = new_addr + r->size - 1;
@@ -573,7 +587,7 @@ static void pci_update_mappings(PCIDevice *d)
int class;
/* NOTE: specific hack for IDE in PC case:
only one byte must be mapped. */
- class = d->config[0x0a] | (d->config[0x0b] << 8);
+ class = pci_get_word(d->config + PCI_CLASS_DEVICE);
if (class == 0x0101 && r->size == 4) {
isa_unassign_ioport(r->addr + 2, 1);
} else {
diff --git a/hw/pci.h b/hw/pci.h
index aaa2a1e0d..bbdfc3145 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -128,6 +128,8 @@ typedef struct PCIIORegion {
#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c /* 16 bits */
#define PCI_SUBSYSTEM_ID 0x2e /* 16 bits */
+#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
+#define PCI_ROM_ADDRESS_ENABLE 0x01
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 0525b1e03..889284a23 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -563,9 +563,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
PCIBus *pci_bus;
qemu_irq *i8259;
int ppc_boot_device;
- DriveInfo *dinfo;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- BlockDriverState *fd[MAX_FD];
+ DriveInfo *fd[MAX_FD];
sysctrl = qemu_mallocz(sizeof(sysctrl_t));
@@ -686,7 +685,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
// pit = pit_init(0x40, i8259[0]);
rtc_init(2000);
- serial_init(0x3f8, i8259[4], 115200, serial_hds[0]);
+ if (serial_hds[0])
+ serial_isa_init(0, serial_hds[0]);
nb_nics1 = nb_nics;
if (nb_nics1 > NE2000_NB_MAX)
nb_nics1 = NE2000_NB_MAX;
@@ -720,8 +720,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
// SB16_init();
for(i = 0; i < MAX_FD; i++) {
- dinfo = drive_get(IF_FLOPPY, 0, i);
- fd[i] = dinfo ? dinfo->bdrv : NULL;
+ fd[i] = drive_get(IF_FLOPPY, 0, i);
}
fdctrl_init_isa(fd);
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index c4fb15c02..5c627fae4 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -208,7 +208,7 @@ static int parse_drive(DeviceState *dev, Property *prop, const char *str)
static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
{
DriveInfo **ptr = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, "%s", (*ptr)->id);
+ return snprintf(dest, len, "%s", (*ptr) ? (*ptr)->id : "<null>");
}
PropertyInfo qdev_prop_drive = {
diff --git a/hw/qdev.c b/hw/qdev.c
index ebddcaedb..86cf81be9 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -218,9 +218,17 @@ DeviceState *qdev_device_add(QemuOpts *opts)
qdev_free(qdev);
return NULL;
}
+ qdev->opts = opts;
return qdev;
}
+static void qdev_reset(void *opaque)
+{
+ DeviceState *dev = opaque;
+ if (dev->info->reset)
+ dev->info->reset(dev);
+}
+
/* Initialize a device. Device properties should be set before calling
this function. IRQs and MMIO regions should be connected/mapped after
calling this function. */
@@ -232,8 +240,7 @@ int qdev_init(DeviceState *dev)
rc = dev->info->init(dev, dev->info);
if (rc < 0)
return rc;
- if (dev->info->reset)
- qemu_register_reset(dev->info->reset, dev);
+ qemu_register_reset(qdev_reset, dev);
if (dev->info->vmsd)
vmstate_register(-1, dev->info->vmsd, dev);
dev->state = DEV_STATE_INITIALIZED;
@@ -272,11 +279,12 @@ void qdev_free(DeviceState *dev)
if (dev->info->vmsd)
vmstate_unregister(dev->info->vmsd, dev);
#endif
- if (dev->info->reset)
- qemu_unregister_reset(dev->info->reset, dev);
if (dev->info->exit)
dev->info->exit(dev);
+ if (dev->opts)
+ qemu_opts_del(dev->opts);
}
+ qemu_unregister_reset(qdev_reset, dev);
QLIST_REMOVE(dev, sibling);
qemu_free(dev);
}
diff --git a/hw/qdev.h b/hw/qdev.h
index ca7c21a3b..893ae925c 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -29,6 +29,7 @@ enum DevState {
struct DeviceState {
const char *id;
enum DevState state;
+ QemuOpts *opts;
int hotplugged;
DeviceInfo *info;
BusState *parent_bus;
@@ -114,6 +115,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
typedef int (*qdev_event)(DeviceState *dev);
+typedef void (*qdev_resetfn)(DeviceState *dev);
struct DeviceInfo {
const char *name;
@@ -124,7 +126,7 @@ struct DeviceInfo {
int no_user;
/* callbacks */
- QEMUResetHandler *reset;
+ qdev_resetfn reset;
/* device state */
const VMStateDescription *vmsd;
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index db9cb5afe..10daeb2f1 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -1173,9 +1173,9 @@ static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize)
s->RxBufAddr = 0;
}
-static void rtl8139_reset(void *opaque)
+static void rtl8139_reset(DeviceState *d)
{
- RTL8139State *s = opaque;
+ RTL8139State *s = container_of(d, RTL8139State, dev.qdev);
int i;
/* restore MAC address */
@@ -1371,7 +1371,7 @@ static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val)
if (val & CmdReset)
{
DEBUG_PRINT(("RTL8139: ChipCmd reset\n"));
- rtl8139_reset(s);
+ rtl8139_reset(&s->dev.qdev);
}
if (val & CmdRxEnb)
{
@@ -1544,7 +1544,7 @@ static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val)
} else if (opmode == 0x40) {
/* Reset. */
val = 0;
- rtl8139_reset(s);
+ rtl8139_reset(&s->dev.qdev);
}
s->Cfg9346 = val;
@@ -3464,7 +3464,7 @@ static int pci_rtl8139_init(PCIDevice *dev)
PCI_ADDRESS_SPACE_MEM, rtl8139_mmio_map);
qdev_get_macaddr(&dev->qdev, s->macaddr);
- rtl8139_reset(s);
+ rtl8139_reset(&s->dev.qdev);
s->vc = qdev_get_vlan_client(&dev->qdev,
rtl8139_can_receive, rtl8139_receive, NULL,
rtl8139_cleanup, s);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 0f029f897..3940726f2 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -936,6 +936,13 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
}
}
+static void scsi_destroy(SCSIDevice *dev)
+{
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+
+ drive_uninit(s->dinfo);
+}
+
static int scsi_disk_initfn(SCSIDevice *dev)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
@@ -969,6 +976,7 @@ static SCSIDeviceInfo scsi_disk_info = {
.qdev.desc = "virtual scsi disk or cdrom",
.qdev.size = sizeof(SCSIDiskState),
.init = scsi_disk_initfn,
+ .destroy = scsi_destroy,
.send_command = scsi_send_command,
.read_data = scsi_read_data,
.write_data = scsi_write_data,
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 86d1e54a5..6a8998999 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -668,6 +668,8 @@ static void scsi_destroy(SCSIDevice *d)
qemu_free(r);
r = n;
}
+
+ drive_uninit(s->dinfo);
}
static int scsi_generic_initfn(SCSIDevice *dev)
diff --git a/hw/serial.c b/hw/serial.c
index 4cdf2303a..e04492310 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -146,6 +146,13 @@ struct SerialState {
struct QEMUTimer *modem_status_poll;
};
+typedef struct ISASerialState {
+ ISADevice dev;
+ uint32_t iobase;
+ uint32_t isairq;
+ SerialState state;
+} ISASerialState;
+
static void serial_receive1(void *opaque, const uint8_t *buf, int size);
static void fifo_clear(SerialState *s, int fifo)
@@ -707,18 +714,13 @@ static void serial_reset(void *opaque)
qemu_irq_lower(s->irq);
}
-static void serial_init_core(SerialState *s, qemu_irq irq, int baudbase,
- CharDriverState *chr)
+static void serial_init_core(SerialState *s)
{
- if (!chr) {
+ if (!s->chr) {
fprintf(stderr, "Can't create serial device, empty char device\n");
exit(1);
}
- s->irq = irq;
- s->baudbase = baudbase;
- s->chr = chr;
-
s->modem_status_poll = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
s->fifo_timeout_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
@@ -731,7 +733,37 @@ static void serial_init_core(SerialState *s, qemu_irq irq, int baudbase,
serial_event, s);
}
-/* If fd is zero, it means that the serial device uses the console */
+static int serial_isa_initfn(ISADevice *dev)
+{
+ ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
+ SerialState *s = &isa->state;
+
+ s->baudbase = 115200;
+ isa_init_irq(dev, &s->irq, isa->isairq);
+ serial_init_core(s);
+ vmstate_register(isa->iobase, &vmstate_serial, s);
+
+ register_ioport_write(isa->iobase, 8, 1, serial_ioport_write, s);
+ register_ioport_read(isa->iobase, 8, 1, serial_ioport_read, s);
+ return 0;
+}
+
+static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
+
+SerialState *serial_isa_init(int index, CharDriverState *chr)
+{
+ ISADevice *dev;
+
+ dev = isa_create("isa-serial");
+ qdev_prop_set_uint32(&dev->qdev, "iobase", isa_serial_io[index]);
+ qdev_prop_set_uint32(&dev->qdev, "irq", isa_serial_irq[index]);
+ qdev_prop_set_chr(&dev->qdev, "chardev", chr);
+ if (qdev_init(&dev->qdev) != 0)
+ return NULL;
+ return &DO_UPCAST(ISASerialState, dev, dev)->state;
+}
+
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr)
{
@@ -739,7 +771,10 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
s = qemu_mallocz(sizeof(SerialState));
- serial_init_core(s, irq, baudbase, chr);
+ s->irq = irq;
+ s->baudbase = baudbase;
+ s->chr = chr;
+ serial_init_core(s);
vmstate_register(base, &vmstate_serial, s);
@@ -830,8 +865,11 @@ SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
s = qemu_mallocz(sizeof(SerialState));
s->it_shift = it_shift;
+ s->irq = irq;
+ s->baudbase = baudbase;
+ s->chr = chr;
- serial_init_core(s, irq, baudbase, chr);
+ serial_init_core(s);
vmstate_register(base, &vmstate_serial, s);
if (ioregister) {
@@ -842,3 +880,22 @@ SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
serial_update_msl(s);
return s;
}
+
+static ISADeviceInfo serial_isa_info = {
+ .qdev.name = "isa-serial",
+ .qdev.size = sizeof(ISASerialState),
+ .init = serial_isa_initfn,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, 0x3f8),
+ DEFINE_PROP_UINT32("irq", ISASerialState, isairq, 4),
+ DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
+ DEFINE_PROP_END_OF_LIST(),
+ },
+};
+
+static void serial_register_devices(void)
+{
+ isa_qdev_register(&serial_isa_info);
+}
+
+device_init(serial_register_devices)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index a869d15a8..01c7cb4a7 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -758,9 +758,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
qemu_irq fdc_tc;
qemu_irq *cpu_halt;
unsigned long kernel_size;
- BlockDriverState *fd[MAX_FD];
+ DriveInfo *fd[MAX_FD];
void *fw_cfg;
- DriveInfo *dinfo;
/* init CPUs */
if (!cpu_model)
@@ -834,10 +833,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
if (hwdef->fd_base) {
/* there is zero or one floppy drive */
memset(fd, 0, sizeof(fd));
- dinfo = drive_get(IF_FLOPPY, 0, 0);
- if (dinfo)
- fd[0] = dinfo->bdrv;
-
+ fd[0] = drive_get(IF_FLOPPY, 0, 0);
sun4m_fdctrl_init(slavio_irq[22], hwdef->fd_base, fd,
&fdc_tc);
}
@@ -1562,11 +1558,10 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
qemu_irq esp_reset;
qemu_irq fdc_tc;
unsigned long kernel_size;
- BlockDriverState *fd[MAX_FD];
+ DriveInfo *fd[MAX_FD];
void *fw_cfg;
DeviceState *dev;
unsigned int i;
- DriveInfo *dinfo;
/* init CPU */
if (!cpu_model)
@@ -1618,10 +1613,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
if (hwdef->fd_base != (target_phys_addr_t)-1) {
/* there is zero or one floppy drive */
memset(fd, 0, sizeof(fd));
- dinfo = drive_get(IF_FLOPPY, 0, 0);
- if (dinfo)
- fd[0] = dinfo->bdrv;
-
+ fd[0] = drive_get(IF_FLOPPY, 0, 0);
sun4m_fdctrl_init(slavio_irq[1], hwdef->fd_base, fd,
&fdc_tc);
}
diff --git a/hw/sun4u.c b/hw/sun4u.c
index e4097b43a..37e3dda41 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -337,9 +337,6 @@ void cpu_tick_set_limit(void *opaque, uint64_t limit)
ptimer_set_limit(opaque, -limit, 0);
}
-static const int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-static const int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
-
static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
@@ -573,9 +570,8 @@ static void sun4uv_init(ram_addr_t RAM_size,
PCIBus *pci_bus, *pci_bus2, *pci_bus3;
qemu_irq *irq;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- BlockDriverState *fd[MAX_FD];
+ DriveInfo *fd[MAX_FD];
void *fw_cfg;
- DriveInfo *dinfo;
/* init CPUs */
env = cpu_devinit(cpu_model, hwdef);
@@ -603,8 +599,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
}
for(; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) {
- serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200,
- serial_hds[i]);
+ serial_isa_init(i, serial_hds[i]);
}
}
@@ -630,8 +625,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
isa_create_simple("i8042");
for(i = 0; i < MAX_FD; i++) {
- dinfo = drive_get(IF_FLOPPY, 0, i);
- fd[i] = dinfo ? dinfo->bdrv : NULL;
+ fd[i] = drive_get(IF_FLOPPY, 0, i);
}
fdctrl_init_isa(fd);
nvram = m48t59_init_isa(0x0074, NVRAM_SIZE, 59);
diff --git a/hw/tcx.c b/hw/tcx.c
index 3816c531e..b177cc968 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -411,9 +411,9 @@ static const VMStateDescription vmstate_tcx = {
}
};
-static void tcx_reset(void *opaque)
+static void tcx_reset(DeviceState *d)
{
- TCXState *s = opaque;
+ TCXState *s = container_of(d, TCXState, busdev.qdev);
/* Initialize palette */
memset(s->r, 0, 256);
@@ -560,7 +560,7 @@ static int tcx_init1(SysBusDevice *dev)
tcx_screen_dump, NULL, s);
}
- tcx_reset(s);
+ tcx_reset(&s->busdev.qdev);
qemu_console_resize(s->ds, s->width, s->height);
return 0;
}
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index a19b31d68..e090014f7 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -508,13 +508,6 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
return ret;
}
-static void usb_msd_handle_destroy(USBDevice *dev)
-{
- MSDState *s = (MSDState *)dev;
-
- drive_uninit(s->dinfo->bdrv);
-}
-
static int usb_msd_initfn(USBDevice *dev)
{
MSDState *s = DO_UPCAST(MSDState, dev, dev);
@@ -599,7 +592,6 @@ static struct USBDeviceInfo msd_info = {
.handle_reset = usb_msd_handle_reset,
.handle_control = usb_msd_handle_control,
.handle_data = usb_msd_handle_data,
- .handle_destroy = usb_msd_handle_destroy,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("drive", MSDState, dinfo),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 2d6d71afa..2630b9930 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -504,7 +504,6 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo)
strncpy(s->serial_str, ps, sizeof(s->serial_str));
else
snprintf(s->serial_str, sizeof(s->serial_str), "0");
- s->bs->private = dev;
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 c6fbaacb2..0b1cea945 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -155,9 +155,9 @@ static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
return 0;
}
-static void virtio_pci_reset(void *opaque)
+static void virtio_pci_reset(DeviceState *d)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
virtio_reset(proxy->vdev);
msix_reset(&proxy->pci_dev);
}
@@ -184,7 +184,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
case VIRTIO_PCI_QUEUE_PFN:
pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
if (pa == 0)
- virtio_pci_reset(proxy);
+ virtio_pci_reset(&proxy->pci_dev.qdev);
else
virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
break;
@@ -198,7 +198,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
case VIRTIO_PCI_STATUS:
vdev->status = val & 0xFF;
if (vdev->status == 0)
- virtio_pci_reset(proxy);
+ virtio_pci_reset(&proxy->pci_dev.qdev);
break;
case VIRTIO_MSI_CONFIG_VECTOR:
msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
@@ -411,8 +411,7 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
config[0x3d] = 1;
- if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0,
- TARGET_PAGE_SIZE)) {
+ if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
pci_register_bar(&proxy->pci_dev, 1,
msix_bar_size(&proxy->pci_dev),
PCI_ADDRESS_SPACE_MEM,
@@ -429,8 +428,6 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
pci_register_bar(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO,
virtio_map);
- qemu_register_reset(virtio_pci_reset, proxy);
-
virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
}
@@ -458,6 +455,14 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
return 0;
}
+static int virtio_blk_exit_pci(PCIDevice *pci_dev)
+{
+ VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+ drive_uninit(proxy->dinfo);
+ return 0;
+}
+
static int virtio_console_init_pci(PCIDevice *pci_dev)
{
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
@@ -519,12 +524,14 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.name = "virtio-blk-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_blk_init_pci,
+ .exit = virtio_blk_exit_pci,
.qdev.props = (Property[]) {
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_PROP_DRIVE("drive", VirtIOPCIProxy, dinfo),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_PROP_END_OF_LIST(),
},
+ .qdev.reset = virtio_pci_reset,
},{
.qdev.name = "virtio-net-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
@@ -534,6 +541,7 @@ static PCIDeviceInfo virtio_info[] = {
NIC_NVECTORS_UNSPECIFIED),
DEFINE_PROP_END_OF_LIST(),
},
+ .qdev.reset = virtio_pci_reset,
},{
.qdev.name = "virtio-console-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
@@ -542,10 +550,12 @@ static PCIDeviceInfo virtio_info[] = {
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_PROP_END_OF_LIST(),
},
+ .qdev.reset = virtio_pci_reset,
},{
.qdev.name = "virtio-balloon-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_balloon_init_pci,
+ .qdev.reset = virtio_pci_reset,
},{
/* end of list */
}