diff options
author | Avi Kivity <avi@redhat.com> | 2009-10-06 10:39:54 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-10-06 10:39:54 +0200 |
commit | 2455aed9dc69d2cfae95ab10c229f96604f8cebb (patch) | |
tree | 3964c6d564cd322293be32c5aef9584615dc547b /hw | |
parent | Merge commit '3f84865ade594a2ec1ef613ab5fd11949f3d49de' into upstream-merge (diff) | |
parent | qemu: clean up target page usage in msix (diff) | |
download | qemu-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.c | 18 | ||||
-rw-r--r-- | hw/fdc.c | 71 | ||||
-rw-r--r-- | hw/fdc.h | 7 | ||||
-rw-r--r-- | hw/mips_jazz.c | 5 | ||||
-rw-r--r-- | hw/mips_malta.c | 9 | ||||
-rw-r--r-- | hw/mips_r4k.c | 6 | ||||
-rw-r--r-- | hw/msix.c | 49 | ||||
-rw-r--r-- | hw/msix.h | 5 | ||||
-rw-r--r-- | hw/pc.c | 12 | ||||
-rw-r--r-- | hw/pc.h | 1 | ||||
-rw-r--r-- | hw/pci-hotplug.c | 44 | ||||
-rw-r--r-- | hw/pci.c | 54 | ||||
-rw-r--r-- | hw/pci.h | 2 | ||||
-rw-r--r-- | hw/ppc_prep.c | 9 | ||||
-rw-r--r-- | hw/qdev-properties.c | 2 | ||||
-rw-r--r-- | hw/qdev.c | 16 | ||||
-rw-r--r-- | hw/qdev.h | 4 | ||||
-rw-r--r-- | hw/rtl8139.c | 10 | ||||
-rw-r--r-- | hw/scsi-disk.c | 8 | ||||
-rw-r--r-- | hw/scsi-generic.c | 2 | ||||
-rw-r--r-- | hw/serial.c | 77 | ||||
-rw-r--r-- | hw/sun4m.c | 16 | ||||
-rw-r--r-- | hw/sun4u.c | 12 | ||||
-rw-r--r-- | hw/tcx.c | 6 | ||||
-rw-r--r-- | hw/usb-msd.c | 8 | ||||
-rw-r--r-- | hw/virtio-blk.c | 1 | ||||
-rw-r--r-- | hw/virtio-pci.c | 26 |
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); - } - } - } -} - - @@ -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) @@ -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]); } } @@ -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 @@ -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); @@ -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); @@ -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; @@ -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 { @@ -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 = { @@ -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); } @@ -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); @@ -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 */ } |