SCSI changes that enable sending vendor-specific commands via virtio-scsi.

Memory changes for QOMification and automatic tracking of MR lifetime.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJT8et9AAoJEBvWZb6bTYbyIJAQAI3AlLSe27xWoUGfQUgWH30z
 Rt/pShHz3BJMfQpD79JfTH8u6uBpkQmKtflerNT7FhXN9ULDzNq+b/jRtke8nkuy
 ctCt05FhhK00rfWpUoRue4XiCuvbizBU7MK0DI3yCyNdXQyYnFvgnvsJtlqox8Zh
 J5HZcBJEmdCiWBxq7UPk0qBitp4PqNoy7jlD/Ex3m7fJN5WK2cyspQIT9zmhehVn
 B8Nwp+RitDDbXbwm0r18col5rFr/6Nj6+dW1gr+7sVJDLNsmJEqC2l3Kgk0wbPkG
 Uqwbih29me9PC9/L1VLGHY0ApKDQ8JGE0GrYgEg162hbhoxEHkjjoHMhDUfV6Pj8
 NkqcjjWl11UUhgkNqrGafayXbBVnOiEglxy8uXCeq14y9Xd/gjK9Fz6MQvRSOjms
 PFmaKknhdmpxh0DuZmTix7WBmKim8zOiCE0/vrAPvwx5L+d1bn5xh6yQvtVjBMpU
 Sru3Mhdm9bL9dUDBgOM/G6WCxSTVLBlExOblcYkQh03MfabD7bfplcrKYPXt5ull
 Y8YLjqkoIfoy5t0ErvtlpdBJjeEz99JXU+wLQ6NYHnzwzTV+oUtSaEph14mAFOcY
 XkFKdoPDI9PnyEfvy4193du8z/dSbhu7sWgHWbTCQyrcaNnSaVhlH43NUC+p23YN
 8vfEsVLd1X7MFkDBUmWp
 =M+/m
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

SCSI changes that enable sending vendor-specific commands via virtio-scsi.

Memory changes for QOMification and automatic tracking of MR lifetime.

# gpg: Signature made Mon 18 Aug 2014 13:03:09 BST using RSA key ID 9B4D86F2
# gpg: Good signature from "Paolo Bonzini <pbonzini@redhat.com>"
# gpg:                 aka "Paolo Bonzini <bonzini@gnu.org>"

* remotes/bonzini/tags/for-upstream:
  mtree: remove write-only field
  memory: Use canonical path component as the name
  memory: Use memory_region_name for name access
  memory: constify memory_region_name
  exec: Abstract away ref to memory region names
  loader: Abstract away ref to memory region names
  tpm_tis: remove instance_finalize callback
  memory: remove memory_region_destroy
  memory: convert memory_region_destroy to object_unparent
  ioport: split deletion and destruction
  nic: do not destroy memory regions in cleanup functions
  vga: do not dynamically allocate chain4_alias
  sysbus: remove unused function sysbus_del_io
  qom: object: move unparenting to the child property's release callback
  qom: object: delete properties before calling instance_finalize
  virtio-scsi: implement parse_cdb
  scsi-block, scsi-generic: implement parse_cdb
  scsi-block: extract scsi_block_is_passthrough
  scsi-bus: introduce parse_cdb in SCSIDeviceClass and SCSIBusInfo
  scsi-bus: prepare scsi_req_new for introduction of parse_cdb

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-08-19 13:00:57 +01:00
commit 0e4a773705
62 changed files with 183 additions and 308 deletions

View File

@ -257,15 +257,6 @@ static void host_memory_backend_init(Object *obj)
host_memory_backend_set_policy, NULL, NULL, NULL); host_memory_backend_set_policy, NULL, NULL, NULL);
} }
static void host_memory_backend_finalize(Object *obj)
{
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
if (memory_region_size(&backend->mr)) {
memory_region_destroy(&backend->mr);
}
}
MemoryRegion * MemoryRegion *
host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp) host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
{ {
@ -360,7 +351,6 @@ static const TypeInfo host_memory_backend_info = {
.class_init = host_memory_backend_class_init, .class_init = host_memory_backend_class_init,
.instance_size = sizeof(HostMemoryBackend), .instance_size = sizeof(HostMemoryBackend),
.instance_init = host_memory_backend_init, .instance_init = host_memory_backend_init,
.instance_finalize = host_memory_backend_finalize,
.interfaces = (InterfaceInfo[]) { .interfaces = (InterfaceInfo[]) {
{ TYPE_USER_CREATABLE }, { TYPE_USER_CREATABLE },
{ } { }

View File

@ -74,11 +74,16 @@ Region lifecycle
---------------- ----------------
A region is created by one of the constructor functions (memory_region_init*()) A region is created by one of the constructor functions (memory_region_init*())
and destroyed by the destructor (memory_region_destroy()). In between, and attached to an object. It is then destroyed by object_unparent() or simply
a region can be added to an address space by using memory_region_add_subregion() when the parent object dies.
and removed using memory_region_del_subregion(). Region attributes may be
changed at any point; they take effect once the region becomes exposed to the In between, a region can be added to an address space
guest. by using memory_region_add_subregion() and removed using
memory_region_del_subregion(). Destroying the region implicitly
removes the region from the address space.
Region attributes may be changed at any point; they take effect once
the region becomes exposed to the guest.
Overlapping regions and priority Overlapping regions and priority
-------------------------------- --------------------------------

4
exec.c
View File

@ -1044,7 +1044,7 @@ static void *file_ram_alloc(RAMBlock *block,
} }
/* Make name safe to use with mkstemp by replacing '/' with '_'. */ /* Make name safe to use with mkstemp by replacing '/' with '_'. */
sanitized_name = g_strdup(block->mr->name); sanitized_name = g_strdup(memory_region_name(block->mr));
for (c = sanitized_name; *c != '\0'; c++) { for (c = sanitized_name; *c != '\0'; c++) {
if (*c == '/') if (*c == '/')
*c = '_'; *c = '_';
@ -1242,7 +1242,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
new_block->host = phys_mem_alloc(new_block->length); new_block->host = phys_mem_alloc(new_block->length);
if (!new_block->host) { if (!new_block->host) {
fprintf(stderr, "Cannot set up guest memory '%s': %s\n", fprintf(stderr, "Cannot set up guest memory '%s': %s\n",
new_block->mr->name, strerror(errno)); memory_region_name(new_block->mr), strerror(errno));
exit(1); exit(1);
} }
memory_try_enable_merging(new_block->host, new_block->length); memory_try_enable_merging(new_block->host, new_block->length);

View File

@ -1388,14 +1388,6 @@ static int ac97_initfn (PCIDevice *dev)
return 0; return 0;
} }
static void ac97_exitfn (PCIDevice *dev)
{
AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev);
memory_region_destroy (&s->io_nam);
memory_region_destroy (&s->io_nabm);
}
static int ac97_init (PCIBus *bus) static int ac97_init (PCIBus *bus)
{ {
pci_create_simple (bus, -1, "AC97"); pci_create_simple (bus, -1, "AC97");
@ -1413,7 +1405,6 @@ static void ac97_class_init (ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass); PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
k->init = ac97_initfn; k->init = ac97_initfn;
k->exit = ac97_exitfn;
k->vendor_id = PCI_VENDOR_ID_INTEL; k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5; k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
k->revision = 0x01; k->revision = 0x01;

View File

@ -1042,13 +1042,6 @@ static int es1370_initfn (PCIDevice *dev)
return 0; return 0;
} }
static void es1370_exitfn (PCIDevice *dev)
{
ES1370State *s = DO_UPCAST (ES1370State, dev, dev);
memory_region_destroy (&s->io);
}
static int es1370_init (PCIBus *bus) static int es1370_init (PCIBus *bus)
{ {
pci_create_simple (bus, -1, "ES1370"); pci_create_simple (bus, -1, "ES1370");
@ -1061,7 +1054,6 @@ static void es1370_class_init (ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass); PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
k->init = es1370_initfn; k->init = es1370_initfn;
k->exit = es1370_exitfn;
k->vendor_id = PCI_VENDOR_ID_ENSONIQ; k->vendor_id = PCI_VENDOR_ID_ENSONIQ;
k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370; k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370;
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO; k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;

View File

@ -1156,7 +1156,6 @@ static void intel_hda_exit(PCIDevice *pci)
IntelHDAState *d = INTEL_HDA(pci); IntelHDAState *d = INTEL_HDA(pci);
msi_uninit(&d->pci); msi_uninit(&d->pci);
memory_region_destroy(&d->mmio);
} }
static int intel_hda_post_load(void *opaque, int version) static int intel_hda_post_load(void *opaque, int version)

View File

@ -839,7 +839,6 @@ static void nvme_exit(PCIDevice *pci_dev)
g_free(n->cq); g_free(n->cq);
g_free(n->sq); g_free(n->sq);
msix_uninit_exclusive_bar(pci_dev); msix_uninit_exclusive_bar(pci_dev);
memory_region_destroy(&n->iomem);
} }
static Property nvme_props[] = { static Property nvme_props[] = {

View File

@ -781,7 +781,6 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
if (ret < 0) { if (ret < 0) {
vmstate_unregister_ram(&pfl->mem, DEVICE(pfl)); vmstate_unregister_ram(&pfl->mem, DEVICE(pfl));
memory_region_destroy(&pfl->mem);
error_setg(errp, "failed to read the initial flash content"); error_setg(errp, "failed to read the initial flash content");
return; return;
} }

View File

@ -617,7 +617,6 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9); ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
if (ret < 0) { if (ret < 0) {
vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl)); vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl));
memory_region_destroy(&pfl->orig_mem);
error_setg(errp, "failed to read the initial flash content"); error_setg(errp, "failed to read the initial flash content");
return; return;
} }

View File

@ -135,7 +135,6 @@ static void serial_pci_exit(PCIDevice *dev)
SerialState *s = &pci->state; SerialState *s = &pci->state;
serial_exit_core(s); serial_exit_core(s);
memory_region_destroy(&s->io);
qemu_free_irq(s->irq); qemu_free_irq(s->irq);
} }
@ -149,10 +148,8 @@ static void multi_serial_pci_exit(PCIDevice *dev)
s = pci->state + i; s = pci->state + i;
serial_exit_core(s); serial_exit_core(s);
memory_region_del_subregion(&pci->iobar, &s->io); memory_region_del_subregion(&pci->iobar, &s->io);
memory_region_destroy(&s->io);
g_free(pci->name[i]); g_free(pci->name[i]);
} }
memory_region_destroy(&pci->iobar);
qemu_free_irqs(pci->irqs, pci->ports); qemu_free_irqs(pci->irqs, pci->ports);
} }

View File

@ -955,7 +955,7 @@ void do_info_roms(Monitor *mon, const QDict *qdict)
if (rom->mr) { if (rom->mr) {
monitor_printf(mon, "%s" monitor_printf(mon, "%s"
" size=0x%06zx name=\"%s\"\n", " size=0x%06zx name=\"%s\"\n",
rom->mr->name, memory_region_name(rom->mr),
rom->romsize, rom->romsize,
rom->name); rom->name);
} else if (!rom->fw_file) { } else if (!rom->fw_file) {

View File

@ -242,11 +242,6 @@ void sysbus_add_io(SysBusDevice *dev, hwaddr addr,
memory_region_add_subregion(get_system_io(), addr, mem); memory_region_add_subregion(get_system_io(), addr, mem);
} }
void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem)
{
memory_region_del_subregion(get_system_io(), mem);
}
MemoryRegion *sysbus_address_space(SysBusDevice *dev) MemoryRegion *sysbus_address_space(SysBusDevice *dev)
{ {
return get_system_memory(); return get_system_memory();

View File

@ -168,15 +168,18 @@ static uint8_t expand4to8[16];
static void vga_update_memory_access(VGACommonState *s) static void vga_update_memory_access(VGACommonState *s)
{ {
MemoryRegion *region, *old_region = s->chain4_alias;
hwaddr base, offset, size; hwaddr base, offset, size;
if (s->legacy_address_space == NULL) { if (s->legacy_address_space == NULL) {
return; return;
} }
s->chain4_alias = NULL; if (s->has_chain4_alias) {
memory_region_del_subregion(s->legacy_address_space, &s->chain4_alias);
object_unparent(OBJECT(&s->chain4_alias));
s->has_chain4_alias = false;
s->plane_updated = 0xf;
}
if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) == if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) { VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
offset = 0; offset = 0;
@ -201,18 +204,11 @@ static void vga_update_memory_access(VGACommonState *s)
break; break;
} }
base += isa_mem_base; base += isa_mem_base;
region = g_malloc(sizeof(*region)); memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
memory_region_init_alias(region, memory_region_owner(&s->vram),
"vga.chain4", &s->vram, offset, size); "vga.chain4", &s->vram, offset, size);
memory_region_add_subregion_overlap(s->legacy_address_space, base, memory_region_add_subregion_overlap(s->legacy_address_space, base,
region, 2); &s->chain4_alias, 2);
s->chain4_alias = region; s->has_chain4_alias = true;
}
if (old_region) {
memory_region_del_subregion(s->legacy_address_space, old_region);
memory_region_destroy(old_region);
g_free(old_region);
s->plane_updated = 0xf;
} }
} }
@ -1321,7 +1317,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
s->font_offsets[1] = offset; s->font_offsets[1] = offset;
full_update = 1; full_update = 1;
} }
if (s->plane_updated & (1 << 2) || s->chain4_alias) { if (s->plane_updated & (1 << 2) || s->has_chain4_alias) {
/* if the plane 2 was modified since the last display, it /* if the plane 2 was modified since the last display, it
indicates the font may have been modified */ indicates the font may have been modified */
s->plane_updated = 0; s->plane_updated = 0;

View File

@ -94,7 +94,8 @@ typedef struct VGACommonState {
uint32_t vram_size; uint32_t vram_size;
uint32_t vram_size_mb; /* property */ uint32_t vram_size_mb; /* property */
uint32_t latch; uint32_t latch;
MemoryRegion *chain4_alias; bool has_chain4_alias;
MemoryRegion chain4_alias;
uint8_t sr_index; uint8_t sr_index;
uint8_t sr[256]; uint8_t sr[256];
uint8_t gr_index; uint8_t gr_index;

View File

@ -697,8 +697,6 @@ static void free_assigned_device(AssignedDevice *dev)
if (region->u.r_baseport) { if (region->u.r_baseport) {
memory_region_del_subregion(&region->container, memory_region_del_subregion(&region->container,
&region->real_iomem); &region->real_iomem);
memory_region_destroy(&region->real_iomem);
memory_region_destroy(&region->container);
} }
} else if (pci_region->type & IORESOURCE_MEM) { } else if (pci_region->type & IORESOURCE_MEM) {
if (region->u.r_virtbase) { if (region->u.r_virtbase) {
@ -712,9 +710,6 @@ static void free_assigned_device(AssignedDevice *dev)
memory_region_del_subregion(&region->container, memory_region_del_subregion(&region->container,
&dev->mmio); &dev->mmio);
} }
memory_region_destroy(&region->real_iomem);
memory_region_destroy(&region->container);
if (munmap(region->u.r_virtbase, if (munmap(region->u.r_virtbase,
(pci_region->size + 0xFFF) & 0xFFFFF000)) { (pci_region->size + 0xFFF) & 0xFFFFF000)) {
error_report("Failed to unmap assigned device region: %s", error_report("Failed to unmap assigned device region: %s",
@ -1680,8 +1675,6 @@ static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev)
return; return;
} }
memory_region_destroy(&dev->mmio);
if (munmap(dev->msix_table, MSIX_PAGE_SIZE) == -1) { if (munmap(dev->msix_table, MSIX_PAGE_SIZE) == -1) {
error_report("error unmapping msix_table! %s", strerror(errno)); error_report("error unmapping msix_table! %s", strerror(errno));
} }
@ -1953,7 +1946,6 @@ static void assigned_dev_load_option_rom(AssignedDevice *dev)
error_printf("Device option ROM contents are probably invalid " error_printf("Device option ROM contents are probably invalid "
"(check dmesg).\nSkip option ROM probe with rombar=0, " "(check dmesg).\nSkip option ROM probe with rombar=0, "
"or load from file with romfile=\n"); "or load from file with romfile=\n");
memory_region_destroy(&dev->dev.rom);
goto close_rom; goto close_rom;
} }

View File

@ -584,7 +584,7 @@ static int vapic_map_rom_writable(VAPICROMState *s)
if (s->rom_mapped_writable) { if (s->rom_mapped_writable) {
memory_region_del_subregion(as, &s->rom); memory_region_del_subregion(as, &s->rom);
memory_region_destroy(&s->rom); object_unparent(OBJECT(&s->rom));
} }
/* grab RAM memory region (region @rom_paddr may still be pc.rom) */ /* grab RAM memory region (region @rom_paddr may still be pc.rom) */

View File

@ -1228,8 +1228,6 @@ void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
void ahci_uninit(AHCIState *s) void ahci_uninit(AHCIState *s)
{ {
memory_region_destroy(&s->mem);
memory_region_destroy(&s->idp);
g_free(s->dev); g_free(s->dev);
} }

View File

@ -384,13 +384,8 @@ static void pci_cmd646_ide_exitfn(PCIDevice *dev)
for (i = 0; i < 2; ++i) { for (i = 0; i < 2; ++i) {
memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
memory_region_destroy(&d->bmdma[i].extra_io);
memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
memory_region_destroy(&d->bmdma[i].addr_ioport);
memory_region_destroy(&d->cmd646_bar[i].cmd);
memory_region_destroy(&d->cmd646_bar[i].data);
} }
memory_region_destroy(&d->bmdma_bar);
} }
void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,

View File

@ -207,11 +207,8 @@ static void pci_piix_ide_exitfn(PCIDevice *dev)
for (i = 0; i < 2; ++i) { for (i = 0; i < 2; ++i) {
memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
memory_region_destroy(&d->bmdma[i].extra_io);
memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
memory_region_destroy(&d->bmdma[i].addr_ioport);
} }
memory_region_destroy(&d->bmdma_bar);
} }
/* hd_table must contain 4 block drivers */ /* hd_table must contain 4 block drivers */

View File

@ -198,11 +198,8 @@ static void vt82c686b_ide_exitfn(PCIDevice *dev)
for (i = 0; i < 2; ++i) { for (i = 0; i < 2; ++i) {
memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
memory_region_destroy(&d->bmdma[i].extra_io);
memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
memory_region_destroy(&d->bmdma[i].addr_ioport);
} }
memory_region_destroy(&d->bmdma_bar);
} }
void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)

View File

@ -613,18 +613,6 @@ static int tpci200_initfn(PCIDevice *pci_dev)
return 0; return 0;
} }
static void tpci200_exitfn(PCIDevice *pci_dev)
{
TPCI200State *s = TPCI200(pci_dev);
memory_region_destroy(&s->mmio);
memory_region_destroy(&s->io);
memory_region_destroy(&s->las0);
memory_region_destroy(&s->las1);
memory_region_destroy(&s->las2);
memory_region_destroy(&s->las3);
}
static const VMStateDescription vmstate_tpci200 = { static const VMStateDescription vmstate_tpci200 = {
.name = "tpci200", .name = "tpci200",
.version_id = 1, .version_id = 1,
@ -645,7 +633,6 @@ static void tpci200_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->init = tpci200_initfn; k->init = tpci200_initfn;
k->exit = tpci200_exitfn;
k->vendor_id = PCI_VENDOR_ID_TEWS; k->vendor_id = PCI_VENDOR_ID_TEWS;
k->device_id = PCI_DEVICE_ID_TEWS_TPCI200; k->device_id = PCI_DEVICE_ID_TEWS_TPCI200;
k->class_id = PCI_CLASS_BRIDGE_OTHER; k->class_id = PCI_CLASS_BRIDGE_OTHER;

View File

@ -297,7 +297,7 @@ static void gt64120_pci_mapping(GT64120State *s)
if (s->PCI0IO_length) if (s->PCI0IO_length)
{ {
memory_region_del_subregion(get_system_memory(), &s->PCI0IO_mem); memory_region_del_subregion(get_system_memory(), &s->PCI0IO_mem);
memory_region_destroy(&s->PCI0IO_mem); object_unparent(OBJECT(&s->PCI0IO_mem));
} }
/* Map new IO address */ /* Map new IO address */
s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21; s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21;

View File

@ -793,11 +793,8 @@ static void pci_ivshmem_uninit(PCIDevice *dev)
error_free(s->migration_blocker); error_free(s->migration_blocker);
} }
memory_region_destroy(&s->ivshmem_mmio);
memory_region_del_subregion(&s->bar, &s->ivshmem); memory_region_del_subregion(&s->bar, &s->ivshmem);
vmstate_unregister_ram(&s->ivshmem, DEVICE(dev)); vmstate_unregister_ram(&s->ivshmem, DEVICE(dev));
memory_region_destroy(&s->ivshmem);
memory_region_destroy(&s->bar);
unregister_savevm(DEVICE(dev), "ivshmem", s); unregister_savevm(DEVICE(dev), "ivshmem", s);
} }

View File

@ -436,7 +436,7 @@ static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
} }
memory_region_del_subregion(get_system_memory(), &f->container); memory_region_del_subregion(get_system_memory(), &f->container);
memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs)); memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs));
memory_region_destroy(&f->container); object_unparent(OBJECT(&f->container));
} }
void omap_gpmc_reset(struct omap_gpmc_s *s) void omap_gpmc_reset(struct omap_gpmc_s *s)

View File

@ -293,8 +293,6 @@ pci_testdev_uninit(PCIDevice *dev)
g_free(d->tests[i].hdr); g_free(d->tests[i].hdr);
} }
g_free(d->tests); g_free(d->tests);
memory_region_destroy(&d->mmio);
memory_region_destroy(&d->portio);
} }
static void qdev_pci_testdev_reset(DeviceState *dev) static void qdev_pci_testdev_reset(DeviceState *dev)

View File

@ -2282,7 +2282,7 @@ static void vfio_vga_quirk_teardown(VFIODevice *vdev)
while (!QLIST_EMPTY(&vdev->vga.region[i].quirks)) { while (!QLIST_EMPTY(&vdev->vga.region[i].quirks)) {
VFIOQuirk *quirk = QLIST_FIRST(&vdev->vga.region[i].quirks); VFIOQuirk *quirk = QLIST_FIRST(&vdev->vga.region[i].quirks);
memory_region_del_subregion(&vdev->vga.region[i].mem, &quirk->mem); memory_region_del_subregion(&vdev->vga.region[i].mem, &quirk->mem);
memory_region_destroy(&quirk->mem); object_unparent(OBJECT(&quirk->mem));
QLIST_REMOVE(quirk, next); QLIST_REMOVE(quirk, next);
g_free(quirk); g_free(quirk);
} }
@ -2306,7 +2306,7 @@ static void vfio_bar_quirk_teardown(VFIODevice *vdev, int nr)
while (!QLIST_EMPTY(&bar->quirks)) { while (!QLIST_EMPTY(&bar->quirks)) {
VFIOQuirk *quirk = QLIST_FIRST(&bar->quirks); VFIOQuirk *quirk = QLIST_FIRST(&bar->quirks);
memory_region_del_subregion(&bar->mem, &quirk->mem); memory_region_del_subregion(&bar->mem, &quirk->mem);
memory_region_destroy(&quirk->mem); object_unparent(OBJECT(&quirk->mem));
QLIST_REMOVE(quirk, next); QLIST_REMOVE(quirk, next);
g_free(quirk); g_free(quirk);
} }
@ -2873,15 +2873,11 @@ static void vfio_unmap_bar(VFIODevice *vdev, int nr)
memory_region_del_subregion(&bar->mem, &bar->mmap_mem); memory_region_del_subregion(&bar->mem, &bar->mmap_mem);
munmap(bar->mmap, memory_region_size(&bar->mmap_mem)); munmap(bar->mmap, memory_region_size(&bar->mmap_mem));
memory_region_destroy(&bar->mmap_mem);
if (vdev->msix && vdev->msix->table_bar == nr) { if (vdev->msix && vdev->msix->table_bar == nr) {
memory_region_del_subregion(&bar->mem, &vdev->msix->mmap_mem); memory_region_del_subregion(&bar->mem, &vdev->msix->mmap_mem);
munmap(vdev->msix->mmap, memory_region_size(&vdev->msix->mmap_mem)); munmap(vdev->msix->mmap, memory_region_size(&vdev->msix->mmap_mem));
memory_region_destroy(&vdev->msix->mmap_mem);
} }
memory_region_destroy(&bar->mem);
} }
static int vfio_mmap_bar(VFIODevice *vdev, VFIOBAR *bar, static int vfio_mmap_bar(VFIODevice *vdev, VFIOBAR *bar,
@ -3034,9 +3030,6 @@ static void vfio_unmap_bars(VFIODevice *vdev)
if (vdev->has_vga) { if (vdev->has_vga) {
vfio_vga_quirk_teardown(vdev); vfio_vga_quirk_teardown(vdev);
pci_unregister_vga(&vdev->pdev); pci_unregister_vga(&vdev->pdev);
memory_region_destroy(&vdev->vga.region[QEMU_PCI_VGA_MEM].mem);
memory_region_destroy(&vdev->vga.region[QEMU_PCI_VGA_IO_LO].mem);
memory_region_destroy(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem);
} }
} }

View File

@ -863,9 +863,6 @@ static void nic_cleanup(NetClientState *nc)
{ {
dp8393xState *s = qemu_get_nic_opaque(nc); dp8393xState *s = qemu_get_nic_opaque(nc);
memory_region_del_subregion(s->address_space, &s->mmio);
memory_region_destroy(&s->mmio);
timer_del(s->watchdog); timer_del(s->watchdog);
timer_free(s->watchdog); timer_free(s->watchdog);

View File

@ -1516,8 +1516,6 @@ pci_e1000_uninit(PCIDevice *dev)
timer_free(d->autoneg_timer); timer_free(d->autoneg_timer);
timer_del(d->mit_timer); timer_del(d->mit_timer);
timer_free(d->mit_timer); timer_free(d->mit_timer);
memory_region_destroy(&d->mmio);
memory_region_destroy(&d->io);
qemu_del_nic(d->nic); qemu_del_nic(d->nic);
} }

View File

@ -1843,9 +1843,6 @@ static void pci_nic_uninit(PCIDevice *pci_dev)
{ {
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
memory_region_destroy(&s->mmio_bar);
memory_region_destroy(&s->io_bar);
memory_region_destroy(&s->flash_bar);
vmstate_unregister(&pci_dev->qdev, s->vmstate, s); vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
eeprom93xx_free(&pci_dev->qdev, s->eeprom); eeprom93xx_free(&pci_dev->qdev, s->eeprom);
qemu_del_nic(s->nic); qemu_del_nic(s->nic);

View File

@ -443,9 +443,6 @@ static void mcf_fec_cleanup(NetClientState *nc)
{ {
mcf_fec_state *s = qemu_get_nic_opaque(nc); mcf_fec_state *s = qemu_get_nic_opaque(nc);
memory_region_del_subregion(s->sysmem, &s->iomem);
memory_region_destroy(&s->iomem);
g_free(s); g_free(s);
} }

View File

@ -748,7 +748,6 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
NE2000State *s = &d->ne2000; NE2000State *s = &d->ne2000;
memory_region_destroy(&s->io);
qemu_del_nic(s->nic); qemu_del_nic(s->nic);
qemu_free_irq(s->irq); qemu_free_irq(s->irq);
} }

View File

@ -282,8 +282,6 @@ static void pci_pcnet_uninit(PCIDevice *dev)
PCIPCNetState *d = PCI_PCNET(dev); PCIPCNetState *d = PCI_PCNET(dev);
qemu_free_irq(d->state.irq); qemu_free_irq(d->state.irq);
memory_region_destroy(&d->state.mmio);
memory_region_destroy(&d->io_bar);
timer_del(d->state.poll_timer); timer_del(d->state.poll_timer);
timer_free(d->state.poll_timer); timer_free(d->state.poll_timer);
qemu_del_nic(d->state.nic); qemu_del_nic(d->state.nic);

View File

@ -3462,8 +3462,6 @@ static void pci_rtl8139_uninit(PCIDevice *dev)
{ {
RTL8139State *s = RTL8139(dev); RTL8139State *s = RTL8139(dev);
memory_region_destroy(&s->bar_io);
memory_region_destroy(&s->bar_mem);
if (s->cplus_txbuffer) { if (s->cplus_txbuffer) {
g_free(s->cplus_txbuffer); g_free(s->cplus_txbuffer);
s->cplus_txbuffer = NULL; s->cplus_txbuffer = NULL;

View File

@ -485,13 +485,6 @@ static int stellaris_enet_init(SysBusDevice *sbd)
return 0; return 0;
} }
static void stellaris_enet_unrealize(DeviceState *dev, Error **errp)
{
stellaris_enet_state *s = STELLARIS_ENET(dev);
memory_region_destroy(&s->mmio);
}
static Property stellaris_enet_properties[] = { static Property stellaris_enet_properties[] = {
DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf), DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
@ -503,7 +496,6 @@ static void stellaris_enet_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = stellaris_enet_init; k->init = stellaris_enet_init;
dc->unrealize = stellaris_enet_unrealize;
dc->props = stellaris_enet_properties; dc->props = stellaris_enet_properties;
dc->vmsd = &vmstate_stellaris_enet; dc->vmsd = &vmstate_stellaris_enet;
} }

View File

@ -2182,10 +2182,6 @@ static void vmxnet3_pci_uninit(PCIDevice *pci_dev)
vmxnet3_cleanup_msix(s); vmxnet3_cleanup_msix(s);
vmxnet3_cleanup_msi(s); vmxnet3_cleanup_msi(s);
memory_region_destroy(&s->bar0);
memory_region_destroy(&s->bar1);
memory_region_destroy(&s->msix_bar);
} }
static void vmxnet3_qdev_reset(DeviceState *dev) static void vmxnet3_qdev_reset(DeviceState *dev)

View File

@ -81,7 +81,6 @@ msi_error:
slotid_error: slotid_error:
shpc_cleanup(dev, &bridge_dev->bar); shpc_cleanup(dev, &bridge_dev->bar);
shpc_error: shpc_error:
memory_region_destroy(&bridge_dev->bar);
pci_bridge_exitfn(dev); pci_bridge_exitfn(dev);
bridge_error: bridge_error:
return err; return err;
@ -95,7 +94,6 @@ static void pci_bridge_dev_exitfn(PCIDevice *dev)
} }
slotid_cap_cleanup(dev); slotid_cap_cleanup(dev);
shpc_cleanup(dev, &bridge_dev->bar); shpc_cleanup(dev, &bridge_dev->bar);
memory_region_destroy(&bridge_dev->bar);
pci_bridge_exitfn(dev); pci_bridge_exitfn(dev);
} }

View File

@ -319,7 +319,6 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
bar_nr, MSIX_EXCLUSIVE_BAR_PBA_OFFSET, bar_nr, MSIX_EXCLUSIVE_BAR_PBA_OFFSET,
MSIX_EXCLUSIVE_CAP_OFFSET); MSIX_EXCLUSIVE_CAP_OFFSET);
if (ret) { if (ret) {
memory_region_destroy(&dev->msix_exclusive_bar);
return ret; return ret;
} }
@ -359,11 +358,9 @@ void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar)
msix_free_irq_entries(dev); msix_free_irq_entries(dev);
dev->msix_entries_nr = 0; dev->msix_entries_nr = 0;
memory_region_del_subregion(pba_bar, &dev->msix_pba_mmio); memory_region_del_subregion(pba_bar, &dev->msix_pba_mmio);
memory_region_destroy(&dev->msix_pba_mmio);
g_free(dev->msix_pba); g_free(dev->msix_pba);
dev->msix_pba = NULL; dev->msix_pba = NULL;
memory_region_del_subregion(table_bar, &dev->msix_table_mmio); memory_region_del_subregion(table_bar, &dev->msix_table_mmio);
memory_region_destroy(&dev->msix_table_mmio);
g_free(dev->msix_table); g_free(dev->msix_table);
dev->msix_table = NULL; dev->msix_table = NULL;
g_free(dev->msix_entry_used); g_free(dev->msix_entry_used);
@ -375,7 +372,6 @@ void msix_uninit_exclusive_bar(PCIDevice *dev)
{ {
if (msix_present(dev)) { if (msix_present(dev)) {
msix_uninit(dev, &dev->msix_exclusive_bar, &dev->msix_exclusive_bar); msix_uninit(dev, &dev->msix_exclusive_bar, &dev->msix_exclusive_bar);
memory_region_destroy(&dev->msix_exclusive_bar);
} }
} }

View File

@ -799,7 +799,6 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
pci_config_free(pci_dev); pci_config_free(pci_dev);
address_space_destroy(&pci_dev->bus_master_as); address_space_destroy(&pci_dev->bus_master_as);
memory_region_destroy(&pci_dev->bus_master_enable_region);
} }
/* -1 for devfn means auto assign */ /* -1 for devfn means auto assign */
@ -1996,7 +1995,6 @@ static void pci_del_option_rom(PCIDevice *pdev)
return; return;
vmstate_unregister_ram(&pdev->rom, &pdev->qdev); vmstate_unregister_ram(&pdev->rom, &pdev->qdev);
memory_region_destroy(&pdev->rom);
pdev->has_rom = false; pdev->has_rom = false;
} }

View File

@ -219,12 +219,6 @@ static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
static void pci_bridge_region_cleanup(PCIBridge *br, PCIBridgeWindows *w) static void pci_bridge_region_cleanup(PCIBridge *br, PCIBridgeWindows *w)
{ {
memory_region_destroy(&w->alias_io);
memory_region_destroy(&w->alias_mem);
memory_region_destroy(&w->alias_pref_mem);
memory_region_destroy(&w->alias_vga[QEMU_PCI_VGA_IO_LO]);
memory_region_destroy(&w->alias_vga[QEMU_PCI_VGA_IO_HI]);
memory_region_destroy(&w->alias_vga[QEMU_PCI_VGA_MEM]);
g_free(w); g_free(w);
} }
@ -389,8 +383,6 @@ void pci_bridge_exitfn(PCIDevice *pci_dev)
QLIST_REMOVE(&s->sec_bus, sibling); QLIST_REMOVE(&s->sec_bus, sibling);
pci_bridge_region_del(s, s->windows); pci_bridge_region_del(s, s->windows);
pci_bridge_region_cleanup(s, s->windows); pci_bridge_region_cleanup(s, s->windows);
memory_region_destroy(&s->address_space_mem);
memory_region_destroy(&s->address_space_io);
/* object_unparent() is called automatically during device deletion */ /* object_unparent() is called automatically during device deletion */
} }

View File

@ -94,7 +94,6 @@ void pcie_host_mmcfg_unmap(PCIExpressHost *e)
{ {
if (e->base_addr != PCIE_BASE_ADDR_UNMAPPED) { if (e->base_addr != PCIE_BASE_ADDR_UNMAPPED) {
memory_region_del_subregion(get_system_memory(), &e->mmio); memory_region_del_subregion(get_system_memory(), &e->mmio);
memory_region_destroy(&e->mmio);
e->base_addr = PCIE_BASE_ADDR_UNMAPPED; e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
} }
} }

View File

@ -667,7 +667,6 @@ void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)
g_free(shpc->cmask); g_free(shpc->cmask);
g_free(shpc->wmask); g_free(shpc->wmask);
g_free(shpc->w1cmask); g_free(shpc->w1cmask);
memory_region_destroy(&shpc->mmio);
g_free(shpc); g_free(shpc);
} }

View File

@ -422,7 +422,7 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram,
&sdram->containers[n]); &sdram->containers[n]);
memory_region_del_subregion(&sdram->containers[n], memory_region_del_subregion(&sdram->containers[n],
&sdram->ram_memories[n]); &sdram->ram_memories[n]);
memory_region_destroy(&sdram->containers[n]); object_unparent(OBJECT(&sdram->containers[n]));
} }
*bcrp = bcr & 0xFFDEE001; *bcrp = bcr & 0xFFDEE001;
if (enabled && (bcr & 0x00000001)) { if (enabled && (bcr & 0x00000001)) {

View File

@ -378,7 +378,6 @@ static void esp_pci_scsi_uninit(PCIDevice *d)
PCIESPState *pci = PCI_ESP(d); PCIESPState *pci = PCI_ESP(d);
qemu_free_irq(pci->esp.irq); qemu_free_irq(pci->esp.irq);
memory_region_destroy(&pci->io);
} }
static void esp_pci_class_init(ObjectClass *klass, void *data) static void esp_pci_class_init(ObjectClass *klass, void *data)

View File

@ -2072,15 +2072,6 @@ static const VMStateDescription vmstate_lsi_scsi = {
} }
}; };
static void lsi_scsi_uninit(PCIDevice *d)
{
LSIState *s = LSI53C895A(d);
memory_region_destroy(&s->mmio_io);
memory_region_destroy(&s->ram_io);
memory_region_destroy(&s->io_io);
}
static const struct SCSIBusInfo lsi_scsi_info = { static const struct SCSIBusInfo lsi_scsi_info = {
.tcq = true, .tcq = true,
.max_target = LSI_MAX_DEVS, .max_target = LSI_MAX_DEVS,
@ -2134,7 +2125,6 @@ static void lsi_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->init = lsi_scsi_init; k->init = lsi_scsi_init;
k->exit = lsi_scsi_uninit;
k->vendor_id = PCI_VENDOR_ID_LSI_LOGIC; k->vendor_id = PCI_VENDOR_ID_LSI_LOGIC;
k->device_id = PCI_DEVICE_ID_LSI_53C895A; k->device_id = PCI_DEVICE_ID_LSI_53C895A;
k->class_id = PCI_CLASS_STORAGE_SCSI; k->class_id = PCI_CLASS_STORAGE_SCSI;

View File

@ -2129,9 +2129,6 @@ static void megasas_scsi_uninit(PCIDevice *d)
if (megasas_use_msi(s)) { if (megasas_use_msi(s)) {
msi_uninit(d); msi_uninit(d);
} }
memory_region_destroy(&s->mmio_io);
memory_region_destroy(&s->port_io);
memory_region_destroy(&s->queue_io);
} }
static const struct SCSIBusInfo megasas_scsi_info = { static const struct SCSIBusInfo megasas_scsi_info = {

View File

@ -9,7 +9,6 @@
static char *scsibus_get_dev_path(DeviceState *dev); static char *scsibus_get_dev_path(DeviceState *dev);
static char *scsibus_get_fw_dev_path(DeviceState *dev); static char *scsibus_get_fw_dev_path(DeviceState *dev);
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
static void scsi_req_dequeue(SCSIRequest *req); static void scsi_req_dequeue(SCSIRequest *req);
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len); static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len);
static void scsi_target_free_buf(SCSIRequest *req); static void scsi_target_free_buf(SCSIRequest *req);
@ -54,6 +53,20 @@ static void scsi_device_destroy(SCSIDevice *s)
} }
} }
int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private)
{
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
int rc;
assert(cmd->len == 0);
rc = scsi_req_parse_cdb(dev, cmd, buf);
if (bus->info->parse_cdb) {
rc = bus->info->parse_cdb(dev, cmd, buf, hba_private);
}
return rc;
}
static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint32_t lun, static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private) uint8_t *buf, void *hba_private)
{ {
@ -561,13 +574,44 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private) uint8_t *buf, void *hba_private)
{ {
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
const SCSIReqOps *ops;
SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(d);
SCSIRequest *req; SCSIRequest *req;
SCSICommand cmd; SCSICommand cmd = { .len = 0 };
int ret;
if (scsi_req_parse(&cmd, d, buf) != 0) { if ((d->unit_attention.key == UNIT_ATTENTION ||
bus->unit_attention.key == UNIT_ATTENTION) &&
(buf[0] != INQUIRY &&
buf[0] != REPORT_LUNS &&
buf[0] != GET_CONFIGURATION &&
buf[0] != GET_EVENT_STATUS_NOTIFICATION &&
/*
* If we already have a pending unit attention condition,
* report this one before triggering another one.
*/
!(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
ops = &reqops_unit_attention;
} else if (lun != d->lun ||
buf[0] == REPORT_LUNS ||
(buf[0] == REQUEST_SENSE && d->sense_len)) {
ops = &reqops_target_command;
} else {
ops = NULL;
}
if (ops != NULL || !sc->parse_cdb) {
ret = scsi_req_parse_cdb(d, &cmd, buf);
} else {
ret = sc->parse_cdb(d, &cmd, buf, hba_private);
}
if (ret != 0) {
trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]); trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]);
req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private); req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
} else { } else {
assert(cmd.len != 0);
trace_scsi_req_parsed(d->id, lun, tag, buf[0], trace_scsi_req_parsed(d->id, lun, tag, buf[0],
cmd.mode, cmd.xfer); cmd.mode, cmd.xfer);
if (cmd.lba != -1) { if (cmd.lba != -1) {
@ -577,25 +621,8 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
if (cmd.xfer > INT32_MAX) { if (cmd.xfer > INT32_MAX) {
req = scsi_req_alloc(&reqops_invalid_field, d, tag, lun, hba_private); req = scsi_req_alloc(&reqops_invalid_field, d, tag, lun, hba_private);
} else if ((d->unit_attention.key == UNIT_ATTENTION || } else if (ops) {
bus->unit_attention.key == UNIT_ATTENTION) && req = scsi_req_alloc(ops, d, tag, lun, hba_private);
(buf[0] != INQUIRY &&
buf[0] != REPORT_LUNS &&
buf[0] != GET_CONFIGURATION &&
buf[0] != GET_EVENT_STATUS_NOTIFICATION &&
/*
* If we already have a pending unit attention condition,
* report this one before triggering another one.
*/
!(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun,
hba_private);
} else if (lun != d->lun ||
buf[0] == REPORT_LUNS ||
(buf[0] == REQUEST_SENSE && d->sense_len)) {
req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
hba_private);
} else { } else {
req = scsi_device_alloc_req(d, tag, lun, buf, hba_private); req = scsi_device_alloc_req(d, tag, lun, buf, hba_private);
} }
@ -1182,10 +1209,11 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
return lba; return lba;
} }
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
{ {
int rc; int rc;
cmd->lba = -1;
switch (buf[0] >> 5) { switch (buf[0] >> 5) {
case 0: case 0:
cmd->len = 6; cmd->len = 6;

View File

@ -2501,12 +2501,8 @@ static int scsi_block_initfn(SCSIDevice *dev)
return scsi_initfn(&s->qdev); return scsi_initfn(&s->qdev);
} }
static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag, static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
uint32_t lun, uint8_t *buf,
void *hba_private)
{ {
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
switch (buf[0]) { switch (buf[0]) {
case READ_6: case READ_6:
case READ_10: case READ_10:
@ -2523,9 +2519,9 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
case WRITE_VERIFY_12: case WRITE_VERIFY_12:
case WRITE_VERIFY_16: case WRITE_VERIFY_16:
/* If we are not using O_DIRECT, we might read stale data from the /* If we are not using O_DIRECT, we might read stale data from the
* host cache if writes were made using other commands than these * host cache if writes were made using other commands than these
* ones (such as WRITE SAME or EXTENDED COPY, etc.). So, without * ones (such as WRITE SAME or EXTENDED COPY, etc.). So, without
* O_DIRECT everything must go through SG_IO. * O_DIRECT everything must go through SG_IO.
*/ */
if (!(bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE)) { if (!(bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE)) {
break; break;
@ -2542,14 +2538,45 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
* just make scsi-block operate the same as scsi-generic for them. * just make scsi-block operate the same as scsi-generic for them.
*/ */
if (s->qdev.type != TYPE_ROM) { if (s->qdev.type != TYPE_ROM) {
return scsi_req_alloc(&scsi_disk_dma_reqops, &s->qdev, tag, lun, return false;
hba_private);
} }
break;
default:
break;
} }
return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun, return true;
hba_private);
} }
static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
uint32_t lun, uint8_t *buf,
void *hba_private)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
if (scsi_block_is_passthrough(s, buf)) {
return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
hba_private);
} else {
return scsi_req_alloc(&scsi_disk_dma_reqops, &s->qdev, tag, lun,
hba_private);
}
}
static int scsi_block_parse_cdb(SCSIDevice *d, SCSICommand *cmd,
uint8_t *buf, void *hba_private)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
if (scsi_block_is_passthrough(s, buf)) {
return scsi_bus_parse_cdb(&s->qdev, cmd, buf, hba_private);
} else {
return scsi_req_parse_cdb(&s->qdev, cmd, buf);
}
}
#endif #endif
#define DEFINE_SCSI_DISK_PROPERTIES() \ #define DEFINE_SCSI_DISK_PROPERTIES() \
@ -2658,6 +2685,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
sc->init = scsi_block_initfn; sc->init = scsi_block_initfn;
sc->destroy = scsi_destroy; sc->destroy = scsi_destroy;
sc->alloc_req = scsi_block_new_request; sc->alloc_req = scsi_block_new_request;
sc->parse_cdb = scsi_block_parse_cdb;
dc->fw_name = "disk"; dc->fw_name = "disk";
dc->desc = "SCSI block device passthrough"; dc->desc = "SCSI block device passthrough";
dc->reset = scsi_disk_reset; dc->reset = scsi_disk_reset;

View File

@ -490,6 +490,12 @@ static Property scsi_generic_properties[] = {
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };
static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
uint8_t *buf, void *hba_private)
{
return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
}
static void scsi_generic_class_initfn(ObjectClass *klass, void *data) static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
@ -498,6 +504,7 @@ static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
sc->init = scsi_generic_initfn; sc->init = scsi_generic_initfn;
sc->destroy = scsi_destroy; sc->destroy = scsi_destroy;
sc->alloc_req = scsi_new_request; sc->alloc_req = scsi_new_request;
sc->parse_cdb = scsi_generic_parse_cdb;
dc->fw_name = "disk"; dc->fw_name = "disk";
dc->desc = "pass through generic scsi device (/dev/sg*)"; dc->desc = "pass through generic scsi device (/dev/sg*)";
dc->reset = scsi_generic_reset; dc->reset = scsi_generic_reset;

View File

@ -406,6 +406,30 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
virtio_scsi_complete_cmd_req(req); virtio_scsi_complete_cmd_req(req);
} }
static int virtio_scsi_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
uint8_t *buf, void *hba_private)
{
VirtIOSCSIReq *req = hba_private;
if (cmd->len == 0) {
cmd->len = MIN(VIRTIO_SCSI_CDB_SIZE, SCSI_CMD_BUF_SIZE);
memcpy(cmd->buf, buf, cmd->len);
}
/* Extract the direction and mode directly from the request, for
* host device passthrough.
*/
cmd->xfer = req->qsgl.size;
if (cmd->xfer == 0) {
cmd->mode = SCSI_XFER_NONE;
} else if (iov_size(req->elem.in_sg, req->elem.in_num) > req->resp_size) {
cmd->mode = SCSI_XFER_FROM_DEV;
} else {
cmd->mode = SCSI_XFER_TO_DEV;
}
return 0;
}
static QEMUSGList *virtio_scsi_get_sg_list(SCSIRequest *r) static QEMUSGList *virtio_scsi_get_sg_list(SCSIRequest *r)
{ {
VirtIOSCSIReq *req = r->hba_private; VirtIOSCSIReq *req = r->hba_private;
@ -658,6 +682,7 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = {
.change = virtio_scsi_change, .change = virtio_scsi_change,
.hotplug = virtio_scsi_hotplug, .hotplug = virtio_scsi_hotplug,
.hot_unplug = virtio_scsi_hot_unplug, .hot_unplug = virtio_scsi_hot_unplug,
.parse_cdb = virtio_scsi_parse_cdb,
.get_sg_list = virtio_scsi_get_sg_list, .get_sg_list = virtio_scsi_get_sg_list,
.save_request = virtio_scsi_save_request, .save_request = virtio_scsi_save_request,
.load_request = virtio_scsi_load_request, .load_request = virtio_scsi_load_request,

View File

@ -1087,7 +1087,6 @@ pvscsi_init(PCIDevice *pci_dev)
s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s); s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
if (!s->completion_worker) { if (!s->completion_worker) {
pvscsi_cleanup_msi(s); pvscsi_cleanup_msi(s);
memory_region_destroy(&s->io_space);
return -ENOMEM; return -ENOMEM;
} }
@ -1107,8 +1106,6 @@ pvscsi_uninit(PCIDevice *pci_dev)
qemu_bh_delete(s->completion_worker); qemu_bh_delete(s->completion_worker);
pvscsi_cleanup_msi(s); pvscsi_cleanup_msi(s);
memory_region_destroy(&s->io_space);
} }
static void static void

View File

@ -896,14 +896,6 @@ static void tpm_tis_initfn(Object *obj)
&s->mmio); &s->mmio);
} }
static void tpm_tis_uninitfn(Object *obj)
{
TPMState *s = TPM(obj);
memory_region_del_subregion(get_system_memory(), &s->mmio);
memory_region_destroy(&s->mmio);
}
static void tpm_tis_class_init(ObjectClass *klass, void *data) static void tpm_tis_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
@ -919,7 +911,6 @@ static const TypeInfo tpm_tis_info = {
.parent = TYPE_ISA_DEVICE, .parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(TPMState), .instance_size = sizeof(TPMState),
.instance_init = tpm_tis_initfn, .instance_init = tpm_tis_initfn,
.instance_finalize = tpm_tis_uninitfn,
.class_init = tpm_tis_class_init, .class_init = tpm_tis_class_init,
}; };

View File

@ -1256,13 +1256,6 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
return usb_uhci_common_initfn(dev); return usb_uhci_common_initfn(dev);
} }
static void usb_uhci_exit(PCIDevice *dev)
{
UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
memory_region_destroy(&s->io_bar);
}
static Property uhci_properties[] = { static Property uhci_properties[] = {
DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
@ -1279,7 +1272,6 @@ static void uhci_class_init(ObjectClass *klass, void *data)
UHCIInfo *info = data; UHCIInfo *info = data;
k->init = info->initfn ? info->initfn : usb_uhci_common_initfn; k->init = info->initfn ? info->initfn : usb_uhci_common_initfn;
k->exit = info->unplug ? usb_uhci_exit : NULL;
k->vendor_id = info->vendor_id; k->vendor_id = info->vendor_id;
k->device_id = info->device_id; k->device_id = info->device_id;
k->revision = info->revision; k->revision = info->revision;

View File

@ -1020,10 +1020,7 @@ static int virtio_pci_init(PCIDevice *pci_dev)
static void virtio_pci_exit(PCIDevice *pci_dev) static void virtio_pci_exit(PCIDevice *pci_dev)
{ {
VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
msix_uninit_exclusive_bar(pci_dev); msix_uninit_exclusive_bar(pci_dev);
memory_region_destroy(&proxy->bar);
} }
static void virtio_pci_reset(DeviceState *qdev) static void virtio_pci_reset(DeviceState *qdev)

View File

@ -425,13 +425,6 @@ static int i6300esb_init(PCIDevice *dev)
return 0; return 0;
} }
static void i6300esb_exit(PCIDevice *dev)
{
I6300State *d = DO_UPCAST(I6300State, dev, dev);
memory_region_destroy(&d->io_mem);
}
static WatchdogTimerModel model = { static WatchdogTimerModel model = {
.wdt_name = "i6300esb", .wdt_name = "i6300esb",
.wdt_description = "Intel 6300ESB", .wdt_description = "Intel 6300ESB",
@ -445,7 +438,6 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
k->config_read = i6300esb_config_read; k->config_read = i6300esb_config_read;
k->config_write = i6300esb_config_write; k->config_write = i6300esb_config_write;
k->init = i6300esb_init; k->init = i6300esb_init;
k->exit = i6300esb_exit;
k->vendor_id = PCI_VENDOR_ID_INTEL; k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_ESB_9; k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
k->class_id = PCI_CLASS_SYSTEM_OTHER; k->class_id = PCI_CLASS_SYSTEM_OTHER;

View File

@ -453,25 +453,6 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s)
return 0; return 0;
} }
static void xen_pt_unregister_regions(XenPCIPassthroughState *s)
{
XenHostPCIDevice *d = &s->real_device;
int i;
for (i = 0; i < PCI_NUM_REGIONS - 1; i++) {
XenHostPCIIORegion *r = &d->io_regions[i];
if (r->base_addr == 0 || r->size == 0) {
continue;
}
memory_region_destroy(&s->bar[i]);
}
if (d->rom.base_addr && d->rom.size) {
memory_region_destroy(&s->rom);
}
}
/* region mapping */ /* region mapping */
static int xen_pt_bar_from_region(XenPCIPassthroughState *s, MemoryRegion *mr) static int xen_pt_bar_from_region(XenPCIPassthroughState *s, MemoryRegion *mr)
@ -810,7 +791,6 @@ static void xen_pt_unregister_device(PCIDevice *d)
/* delete all emulated config registers */ /* delete all emulated config registers */
xen_pt_config_delete(s); xen_pt_config_delete(s);
xen_pt_unregister_regions(s);
memory_listener_unregister(&s->memory_listener); memory_listener_unregister(&s->memory_listener);
memory_listener_unregister(&s->io_listener); memory_listener_unregister(&s->io_listener);

View File

@ -593,7 +593,6 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)
return 0; return 0;
error_out: error_out:
memory_region_destroy(&msix->mmio);
g_free(s->msix); g_free(s->msix);
s->msix = NULL; s->msix = NULL;
return rc; return rc;
@ -616,7 +615,6 @@ void xen_pt_msix_delete(XenPCIPassthroughState *s)
} }
memory_region_del_subregion(&s->bar[msix->bar_index], &msix->mmio); memory_region_del_subregion(&s->bar[msix->bar_index], &msix->mmio);
memory_region_destroy(&msix->mmio);
g_free(s->msix); g_free(s->msix);
s->msix = NULL; s->msix = NULL;

View File

@ -162,7 +162,6 @@ struct MemoryRegion {
QTAILQ_HEAD(subregions, MemoryRegion) subregions; QTAILQ_HEAD(subregions, MemoryRegion) subregions;
QTAILQ_ENTRY(MemoryRegion) subregions_link; QTAILQ_ENTRY(MemoryRegion) subregions_link;
QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced; QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
const char *name;
uint8_t dirty_log_mask; uint8_t dirty_log_mask;
unsigned ioeventfd_nb; unsigned ioeventfd_nb;
MemoryRegionIoeventfd *ioeventfds; MemoryRegionIoeventfd *ioeventfds;
@ -429,15 +428,6 @@ void memory_region_init_iommu(MemoryRegion *mr,
const char *name, const char *name,
uint64_t size); uint64_t size);
/**
* memory_region_destroy: Destroy a memory region and reclaim all resources.
*
* @mr: the region to be destroyed. May not currently be a subregion
* (see memory_region_add_subregion()) or referenced in an alias
* (see memory_region_init_alias()).
*/
void memory_region_destroy(MemoryRegion *mr);
/** /**
* memory_region_owner: get a memory region's owner. * memory_region_owner: get a memory region's owner.
* *
@ -520,7 +510,7 @@ void memory_region_unregister_iommu_notifier(Notifier *n);
* *
* @mr: the memory region being queried * @mr: the memory region being queried
*/ */
const char *memory_region_name(MemoryRegion *mr); const char *memory_region_name(const MemoryRegion *mr);
/** /**
* memory_region_is_logging: return whether a memory region is logging writes * memory_region_is_logging: return whether a memory region is logging writes

View File

@ -76,6 +76,8 @@ typedef struct SCSIDeviceClass {
DeviceClass parent_class; DeviceClass parent_class;
int (*init)(SCSIDevice *dev); int (*init)(SCSIDevice *dev);
void (*destroy)(SCSIDevice *s); void (*destroy)(SCSIDevice *s);
int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private);
SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun, SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private); uint8_t *buf, void *hba_private);
void (*unit_attention_reported)(SCSIDevice *s); void (*unit_attention_reported)(SCSIDevice *s);
@ -131,6 +133,8 @@ struct SCSIReqOps {
struct SCSIBusInfo { struct SCSIBusInfo {
int tcq; int tcq;
int max_channel, max_target, max_lun; int max_channel, max_target, max_lun;
int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private);
void (*transfer_data)(SCSIRequest *req, uint32_t arg); void (*transfer_data)(SCSIRequest *req, uint32_t arg);
void (*complete)(SCSIRequest *req, uint32_t arg, size_t resid); void (*complete)(SCSIRequest *req, uint32_t arg, size_t resid);
void (*cancel)(SCSIRequest *req); void (*cancel)(SCSIRequest *req);
@ -244,6 +248,9 @@ void scsi_req_free(SCSIRequest *req);
SCSIRequest *scsi_req_ref(SCSIRequest *req); SCSIRequest *scsi_req_ref(SCSIRequest *req);
void scsi_req_unref(SCSIRequest *req); void scsi_req_unref(SCSIRequest *req);
int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private);
int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf);
void scsi_req_build_sense(SCSIRequest *req, SCSISense sense); void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
void scsi_req_print(SCSIRequest *req); void scsi_req_print(SCSIRequest *req);
void scsi_req_continue(SCSIRequest *req); void scsi_req_continue(SCSIRequest *req);

View File

@ -71,7 +71,6 @@ void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
int priority); int priority);
void sysbus_add_io(SysBusDevice *dev, hwaddr addr, void sysbus_add_io(SysBusDevice *dev, hwaddr addr,
MemoryRegion *mem); MemoryRegion *mem);
void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem);
MemoryRegion *sysbus_address_space(SysBusDevice *dev); MemoryRegion *sysbus_address_space(SysBusDevice *dev);
/* Legacy helper function for creating devices. */ /* Legacy helper function for creating devices. */

View File

@ -149,6 +149,14 @@ void portio_list_set_flush_coalesced(PortioList *piolist)
void portio_list_destroy(PortioList *piolist) void portio_list_destroy(PortioList *piolist)
{ {
MemoryRegionPortioList *mrpio;
unsigned i;
for (i = 0; i < piolist->nr; ++i) {
mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr);
object_unparent(OBJECT(&mrpio->mr));
g_free(mrpio);
}
g_free(piolist->regions); g_free(piolist->regions);
} }
@ -291,8 +299,5 @@ void portio_list_del(PortioList *piolist)
for (i = 0; i < piolist->nr; ++i) { for (i = 0; i < piolist->nr; ++i) {
mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr); mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr);
memory_region_del_subregion(piolist->address_space, &mrpio->mr); memory_region_del_subregion(piolist->address_space, &mrpio->mr);
memory_region_destroy(&mrpio->mr);
g_free(mrpio);
piolist->regions[i] = NULL;
} }
} }

View File

@ -914,7 +914,6 @@ void memory_region_init(MemoryRegion *mr,
if (size == UINT64_MAX) { if (size == UINT64_MAX) {
mr->size = int128_2_64(); mr->size = int128_2_64();
} }
mr->name = g_strdup(name);
if (name) { if (name) {
object_property_add_child_array(owner, name, OBJECT(mr)); object_property_add_child_array(owner, name, OBJECT(mr));
@ -1259,16 +1258,9 @@ static void memory_region_finalize(Object *obj)
assert(memory_region_transaction_depth == 0); assert(memory_region_transaction_depth == 0);
mr->destructor(mr); mr->destructor(mr);
memory_region_clear_coalescing(mr); memory_region_clear_coalescing(mr);
g_free((char *)mr->name);
g_free(mr->ioeventfds); g_free(mr->ioeventfds);
} }
void memory_region_destroy(MemoryRegion *mr)
{
object_unparent(OBJECT(mr));
}
Object *memory_region_owner(MemoryRegion *mr) Object *memory_region_owner(MemoryRegion *mr)
{ {
Object *obj = OBJECT(mr); Object *obj = OBJECT(mr);
@ -1313,9 +1305,9 @@ uint64_t memory_region_size(MemoryRegion *mr)
return int128_get64(mr->size); return int128_get64(mr->size);
} }
const char *memory_region_name(MemoryRegion *mr) const char *memory_region_name(const MemoryRegion *mr)
{ {
return mr->name; return object_get_canonical_path_component(OBJECT(mr));
} }
bool memory_region_is_ram(MemoryRegion *mr) bool memory_region_is_ram(MemoryRegion *mr)
@ -1979,7 +1971,6 @@ typedef struct MemoryRegionList MemoryRegionList;
struct MemoryRegionList { struct MemoryRegionList {
const MemoryRegion *mr; const MemoryRegion *mr;
bool printed;
QTAILQ_ENTRY(MemoryRegionList) queue; QTAILQ_ENTRY(MemoryRegionList) queue;
}; };
@ -2009,7 +2000,7 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
/* check if the alias is already in the queue */ /* check if the alias is already in the queue */
QTAILQ_FOREACH(ml, alias_print_queue, queue) { QTAILQ_FOREACH(ml, alias_print_queue, queue) {
if (ml->mr == mr->alias && !ml->printed) { if (ml->mr == mr->alias) {
found = true; found = true;
} }
} }
@ -2017,7 +2008,6 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
if (!found) { if (!found) {
ml = g_new(MemoryRegionList, 1); ml = g_new(MemoryRegionList, 1);
ml->mr = mr->alias; ml->mr = mr->alias;
ml->printed = false;
QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue); QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue);
} }
mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx
@ -2032,8 +2022,8 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
mr->romd_mode ? 'R' : '-', mr->romd_mode ? 'R' : '-',
!mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W' !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
: '-', : '-',
mr->name, memory_region_name(mr),
mr->alias->name, memory_region_name(mr->alias),
mr->alias_offset, mr->alias_offset,
mr->alias_offset mr->alias_offset
+ (int128_nz(mr->size) ? + (int128_nz(mr->size) ?
@ -2051,7 +2041,7 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
mr->romd_mode ? 'R' : '-', mr->romd_mode ? 'R' : '-',
!mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W' !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
: '-', : '-',
mr->name); memory_region_name(mr));
} }
QTAILQ_INIT(&submr_print_queue); QTAILQ_INIT(&submr_print_queue);
@ -2099,10 +2089,8 @@ void mtree_info(fprintf_function mon_printf, void *f)
mon_printf(f, "aliases\n"); mon_printf(f, "aliases\n");
/* print aliased regions */ /* print aliased regions */
QTAILQ_FOREACH(ml, &ml_head, queue) { QTAILQ_FOREACH(ml, &ml_head, queue) {
if (!ml->printed) { mon_printf(f, "%s\n", memory_region_name(ml->mr));
mon_printf(f, "%s\n", ml->mr->name); mtree_print_mr(mon_printf, f, ml->mr, 0, 0, &ml_head);
mtree_print_mr(mon_printf, f, ml->mr, 0, 0, &ml_head);
}
} }
QTAILQ_FOREACH_SAFE(ml, &ml_head, queue, ml2) { QTAILQ_FOREACH_SAFE(ml, &ml_head, queue, ml2) {

View File

@ -387,19 +387,9 @@ static void object_property_del_child(Object *obj, Object *child, Error **errp)
void object_unparent(Object *obj) void object_unparent(Object *obj)
{ {
if (!obj->parent) {
return;
}
object_ref(obj);
if (obj->class->unparent) {
(obj->class->unparent)(obj);
}
if (obj->parent) { if (obj->parent) {
object_property_del_child(obj->parent, obj, NULL); object_property_del_child(obj->parent, obj, NULL);
obj->parent = NULL;
} }
object_unref(obj);
} }
static void object_deinit(Object *obj, TypeImpl *type) static void object_deinit(Object *obj, TypeImpl *type)
@ -418,8 +408,8 @@ static void object_finalize(void *data)
Object *obj = data; Object *obj = data;
TypeImpl *ti = obj->class->type; TypeImpl *ti = obj->class->type;
object_deinit(obj, ti);
object_property_del_all(obj); object_property_del_all(obj);
object_deinit(obj, ti);
g_assert(obj->ref == 0); g_assert(obj->ref == 0);
if (obj->free) { if (obj->free) {
@ -1042,6 +1032,10 @@ static void object_finalize_child_property(Object *obj, const char *name,
{ {
Object *child = opaque; Object *child = opaque;
if (child->class->unparent) {
(child->class->unparent)(child);
}
child->parent = NULL;
object_unref(child); object_unref(child);
} }