* [Qemu-devel] [patch 00/19] acpi pci hotplug
@ 2009-02-10 20:30 Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 01/19] qemu: add pci helper functions Marcelo Tosatti
` (20 more replies)
0 siblings, 21 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
ACPI PCI hotplug, hopefully addressing all comments.
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 01/19] qemu: add pci helper functions
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
@ 2009-02-10 20:30 ` Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 02/19] qemu: return PCIDevice on net device init and record devfn Marcelo Tosatti
` (19 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: pci-helpers --]
[-- Type: text/plain, Size: 1783 bytes --]
Add pci_find_bus/pci_find_device to be used by PCI hotplug.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/pci.c
===================================================================
--- trunk.orig/hw/pci.c
+++ trunk/hw/pci.c
@@ -711,6 +711,26 @@ static void pci_bridge_write_config(PCID
pci_default_write_config(d, address, val, len);
}
+PCIBus *pci_find_bus(int bus_num)
+{
+ PCIBus *bus = first_bus;
+
+ while (bus && bus->bus_num != bus_num)
+ bus = bus->next;
+
+ return bus;
+}
+
+PCIDevice *pci_find_device(int bus_num, int slot, int function)
+{
+ PCIBus *bus = pci_find_bus(bus_num);
+
+ if (!bus)
+ return NULL;
+
+ return bus->devices[PCI_DEVFN(slot, function)];
+}
+
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
pci_map_irq_fn map_irq, const char *name)
{
Index: trunk/hw/pci.h
===================================================================
--- trunk.orig/hw/pci.h
+++ trunk/hw/pci.h
@@ -8,6 +8,10 @@
extern target_phys_addr_t pci_mem_base;
+#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
+#define PCI_FUNC(devfn) ((devfn) & 0x07)
+
/* Device classes and subclasses */
#define PCI_CLASS_STORAGE_SCSI 0x0100
@@ -222,6 +226,8 @@ void pci_data_write(void *opaque, uint32
uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
int pci_bus_num(PCIBus *s);
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
+PCIBus *pci_find_bus(int bus_num);
+PCIDevice *pci_find_device(int bus_num, int slot, int function);
void pci_info(void);
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 02/19] qemu: return PCIDevice on net device init and record devfn
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 01/19] qemu: add pci helper functions Marcelo Tosatti
@ 2009-02-10 20:30 ` Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 03/19] qemu: dynamic drive/drive_opt index allocation Marcelo Tosatti
` (18 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: net-return-pcidev --]
[-- Type: text/plain, Size: 9060 bytes --]
Change the PCI network drivers init functions to return the PCIDev, to
inform which slot has been hot-plugged.
Also record PCIDevice structure on NICInfo to locate for release on
hot-removal.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/e1000.c
===================================================================
--- trunk.orig/hw/e1000.c
+++ trunk/hw/e1000.c
@@ -1034,7 +1034,7 @@ e1000_mmio_map(PCIDevice *pci_dev, int r
excluded_regs[i] - 4);
}
-void
+PCIDevice *
pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
{
E1000State *d;
@@ -1092,4 +1092,6 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd,
qemu_format_nic_info_str(d->vc, d->nd->macaddr);
register_savevm(info_str, -1, 2, nic_save, nic_load, d);
+
+ return (PCIDevice *)d;
}
Index: trunk/hw/eepro100.c
===================================================================
--- trunk.orig/hw/eepro100.c
+++ trunk/hw/eepro100.c
@@ -1735,7 +1735,7 @@ static void nic_save(QEMUFile * f, void
qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
}
-static void nic_init(PCIBus * bus, NICInfo * nd,
+static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd,
const char *name, uint32_t device)
{
PCIEEPRO100State *d;
@@ -1783,22 +1783,23 @@ static void nic_init(PCIBus * bus, NICIn
qemu_register_reset(nic_reset, s);
register_savevm(name, -1, 3, nic_save, nic_load, s);
+ return (PCIDevice *)d;
}
-void pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn)
{
- nic_init(bus, nd, "i82551", i82551);
+ return nic_init(bus, nd, "i82551", i82551);
//~ uint8_t *pci_conf = d->dev.config;
}
-void pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn)
{
- nic_init(bus, nd, "i82557b", i82557B);
+ return nic_init(bus, nd, "i82557b", i82557B);
}
-void pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn)
{
- nic_init(bus, nd, "i82559er", i82559ER);
+ return nic_init(bus, nd, "i82559er", i82559ER);
}
/* eof */
Index: trunk/hw/ne2000.c
===================================================================
--- trunk.orig/hw/ne2000.c
+++ trunk/hw/ne2000.c
@@ -777,7 +777,7 @@ static void ne2000_map(PCIDevice *pci_de
register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
}
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
{
PCINE2000State *d;
NE2000State *s;
@@ -807,4 +807,6 @@ void pci_ne2000_init(PCIBus *bus, NICInf
qemu_format_nic_info_str(s->vc, s->macaddr);
register_savevm("ne2000", -1, 3, ne2000_save, ne2000_load, s);
+
+ return (PCIDevice *)d;
}
Index: trunk/hw/pci.c
===================================================================
--- trunk.orig/hw/pci.c
+++ trunk/hw/pci.c
@@ -662,7 +662,7 @@ static const char * const pci_nic_models
NULL
};
-typedef void (*PCINICInitFn)(PCIBus *, NICInfo *, int);
+typedef PCIDevice *(*PCINICInitFn)(PCIBus *, NICInfo *, int);
static PCINICInitFn pci_nic_init_fns[] = {
pci_ne2000_init,
@@ -677,16 +677,23 @@ static PCINICInitFn pci_nic_init_fns[] =
};
/* Initialize a PCI NIC. */
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
+PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
const char *default_model)
{
+ PCIDevice *pci_dev;
int i;
qemu_check_nic_model_list(nd, pci_nic_models, default_model);
for (i = 0; pci_nic_models[i]; i++)
- if (strcmp(nd->model, pci_nic_models[i]) == 0)
- pci_nic_init_fns[i](bus, nd, devfn);
+ if (strcmp(nd->model, pci_nic_models[i]) == 0) {
+ pci_dev = pci_nic_init_fns[i](bus, nd, devfn);
+ if (pci_dev)
+ nd->private = pci_dev;
+ return pci_dev;
+ }
+
+ return NULL;
}
typedef struct {
Index: trunk/hw/pci.h
===================================================================
--- trunk.orig/hw/pci.h
+++ trunk/hw/pci.h
@@ -220,7 +220,7 @@ typedef int (*pci_map_irq_fn)(PCIDevice
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
qemu_irq *pic, int devfn_min, int nirq);
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
+PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
const char *default_model);
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
@@ -269,23 +269,23 @@ void usb_ohci_init_pci(struct PCIBus *bu
/* eepro100.c */
-void pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn);
/* ne2000.c */
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
/* rtl8139.c */
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
/* e1000.c */
-void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
/* pcnet.c */
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
/* prep_pci.c */
PCIBus *pci_prep_init(qemu_irq *pic);
Index: trunk/hw/pcnet.c
===================================================================
--- trunk.orig/hw/pcnet.c
+++ trunk/hw/pcnet.c
@@ -1985,7 +1985,7 @@ static void pci_physical_memory_read(voi
cpu_physical_memory_read(addr, buf, len);
}
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
{
PCNetState *d;
uint8_t *pci_conf;
@@ -2032,6 +2032,7 @@ void pci_pcnet_init(PCIBus *bus, NICInfo
d->pci_dev = &d->dev;
pcnet_common_init(d, nd);
+ return (PCIDevice *)d;
}
/* SPARC32 interface */
Index: trunk/hw/rtl8139.c
===================================================================
--- trunk.orig/hw/rtl8139.c
+++ trunk/hw/rtl8139.c
@@ -3414,7 +3414,7 @@ static void rtl8139_timer(void *opaque)
}
#endif /* RTL8139_ONBOARD_TIMER */
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
{
PCIRTL8139State *d;
RTL8139State *s;
@@ -3466,4 +3466,5 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
qemu_mod_timer(s->timer,
rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
#endif /* RTL8139_ONBOARD_TIMER */
+ return (PCIDevice *)d;
}
Index: trunk/hw/virtio-net.c
===================================================================
--- trunk.orig/hw/virtio-net.c
+++ trunk/hw/virtio-net.c
@@ -560,7 +560,7 @@ static int virtio_net_load(QEMUFile *f,
return 0;
}
-void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
{
VirtIONet *n;
static int virtio_net_id;
@@ -574,7 +574,7 @@ void virtio_net_init(PCIBus *bus, NICInf
sizeof(struct virtio_net_config),
sizeof(VirtIONet));
if (!n)
- return;
+ return NULL;
n->vdev.get_config = virtio_net_get_config;
n->vdev.set_config = virtio_net_set_config;
@@ -599,12 +599,13 @@ void virtio_net_init(PCIBus *bus, NICInf
n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN);
if (!n->mac_table.macs)
- return;
+ return NULL;
n->vlans = qemu_mallocz(MAX_VLAN >> 3);
if (!n->vlans)
- return;
+ return NULL;
register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION,
virtio_net_save, virtio_net_load, n);
+ return (PCIDevice *)n;
}
Index: trunk/hw/virtio-net.h
===================================================================
--- trunk.orig/hw/virtio-net.h
+++ trunk/hw/virtio-net.h
@@ -85,7 +85,7 @@ struct virtio_net_hdr_mrg_rxbuf
uint16_t num_buffers; /* Number of merged rx buffers */
};
-void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn);
/*
* Control virtqueue data structures
Index: trunk/net.h
===================================================================
--- trunk.orig/net.h
+++ trunk/net.h
@@ -64,6 +64,7 @@ struct NICInfo {
const char *model;
const char *name;
VLANState *vlan;
+ void *private;
};
extern int nb_nics;
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 03/19] qemu: dynamic drive/drive_opt index allocation
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 01/19] qemu: add pci helper functions Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 02/19] qemu: return PCIDevice on net device init and record devfn Marcelo Tosatti
@ 2009-02-10 20:30 ` Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 04/19] qemu: dynamic nic info " Marcelo Tosatti
` (17 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: dynamic-drive-and-opt-index --]
[-- Type: text/plain, Size: 3713 bytes --]
Dynamically allocate drive options and drive table index, to reuse
indexes when devices are removed.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/sysemu.h
===================================================================
--- trunk.orig/sysemu.h
+++ trunk/sysemu.h
@@ -134,6 +134,7 @@ typedef struct DriveInfo {
BlockInterfaceType type;
int bus;
int unit;
+ int used;
BlockInterfaceErrorAction onerror;
char serial[21];
} DriveInfo;
Index: trunk/vl.c
===================================================================
--- trunk.orig/vl.c
+++ trunk/vl.c
@@ -246,6 +246,7 @@ static int nb_drives_opt;
static struct drive_opt {
const char *file;
char opt[1024];
+ int used;
} drives_opt[MAX_DRIVES];
static CPUState *cur_cpu;
@@ -2135,22 +2136,50 @@ static int bt_parse(const char *opt)
#define MTD_ALIAS "if=mtd"
#define SD_ALIAS "index=0,if=sd"
+static int drive_opt_get_free_idx(void)
+{
+ int index;
+
+ for (index = 0; index < MAX_DRIVES; index++)
+ if (!drives_opt[index].used) {
+ drives_opt[index].used = 1;
+ return index;
+ }
+
+ return -1;
+}
+
+static int drive_get_free_idx(void)
+{
+ int index;
+
+ for (index = 0; index < MAX_DRIVES; index++)
+ if (!drives_table[index].used) {
+ drives_table[index].used = 1;
+ return index;
+ }
+
+ return -1;
+}
+
static int drive_add(const char *file, const char *fmt, ...)
{
va_list ap;
+ int index = drive_opt_get_free_idx();
- if (nb_drives_opt >= MAX_DRIVES) {
+ if (nb_drives_opt >= MAX_DRIVES || index == -1) {
fprintf(stderr, "qemu: too many drives\n");
exit(1);
}
- drives_opt[nb_drives_opt].file = file;
+ drives_opt[index].file = file;
va_start(ap, fmt);
- vsnprintf(drives_opt[nb_drives_opt].opt,
+ vsnprintf(drives_opt[index].opt,
sizeof(drives_opt[0].opt), fmt, ap);
va_end(ap);
- return nb_drives_opt++;
+ nb_drives_opt++;
+ return index;
}
int drive_get_index(BlockInterfaceType type, int bus, int unit)
@@ -2159,10 +2188,11 @@ int drive_get_index(BlockInterfaceType t
/* seek interface, bus and unit */
- for (index = 0; index < nb_drives; index++)
+ for (index = 0; index < MAX_DRIVES; index++)
if (drives_table[index].type == type &&
drives_table[index].bus == bus &&
- drives_table[index].unit == unit)
+ drives_table[index].unit == unit &&
+ drives_table[index].used)
return index;
return -1;
@@ -2227,6 +2257,7 @@ static int drive_init(struct drive_opt *
int index;
int cache;
int bdrv_flags, onerror;
+ int drives_table_idx;
char *str = arg->opt;
static const char * const params[] = { "bus", "unit", "if", "index",
"cyls", "heads", "secs", "trans",
@@ -2501,11 +2532,12 @@ static int drive_init(struct drive_opt *
snprintf(buf, sizeof(buf), "%s%s%i",
devname, mediastr, unit_id);
bdrv = bdrv_new(buf);
- drives_table[nb_drives].bdrv = bdrv;
- drives_table[nb_drives].type = type;
- drives_table[nb_drives].bus = bus_id;
- drives_table[nb_drives].unit = unit_id;
- drives_table[nb_drives].onerror = onerror;
+ drives_table_idx = drive_get_free_idx();
+ drives_table[drives_table_idx].bdrv = bdrv;
+ drives_table[drives_table_idx].type = type;
+ drives_table[drives_table_idx].bus = bus_id;
+ drives_table[drives_table_idx].unit = unit_id;
+ drives_table[drives_table_idx].onerror = onerror;
strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));
nb_drives++;
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 04/19] qemu: dynamic nic info index allocation
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (2 preceding siblings ...)
2009-02-10 20:30 ` [Qemu-devel] [patch 03/19] qemu: dynamic drive/drive_opt index allocation Marcelo Tosatti
@ 2009-02-10 20:30 ` Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 05/19] qemu: drive removal support Marcelo Tosatti
` (16 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: dynamic-nic-info --]
[-- Type: text/plain, Size: 1899 bytes --]
Dynamically allocate nic info index, so to reuse indexes when devices are
removed.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/net.c
===================================================================
--- trunk.orig/net.c
+++ trunk/net.c
@@ -1501,6 +1501,16 @@ VLANState *qemu_find_vlan(int id)
return vlan;
}
+static int nic_get_free_idx(void)
+{
+ int index;
+
+ for (index = 0; index < MAX_NICS; index++)
+ if (!nd_table[index].used)
+ return index;
+ return -1;
+}
+
void qemu_check_nic_model(NICInfo *nd, const char *model)
{
const char *models[2];
@@ -1557,19 +1567,20 @@ int net_client_init(const char *device,
if (!strcmp(device, "nic")) {
NICInfo *nd;
uint8_t *macaddr;
+ int idx = nic_get_free_idx();
- if (nb_nics >= MAX_NICS) {
+ if (idx == -1 || nb_nics >= MAX_NICS) {
fprintf(stderr, "Too Many NICs\n");
return -1;
}
- nd = &nd_table[nb_nics];
+ nd = &nd_table[idx];
macaddr = nd->macaddr;
macaddr[0] = 0x52;
macaddr[1] = 0x54;
macaddr[2] = 0x00;
macaddr[3] = 0x12;
macaddr[4] = 0x34;
- macaddr[5] = 0x56 + nb_nics;
+ macaddr[5] = 0x56 + idx;
if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
if (parse_macaddr(macaddr, buf) < 0) {
@@ -1582,6 +1593,7 @@ int net_client_init(const char *device,
}
nd->vlan = vlan;
nd->name = name;
+ nd->used = 1;
name = NULL;
nb_nics++;
vlan->nb_guest_devs++;
Index: trunk/net.h
===================================================================
--- trunk.orig/net.h
+++ trunk/net.h
@@ -65,6 +65,7 @@ struct NICInfo {
const char *name;
VLANState *vlan;
void *private;
+ int used;
};
extern int nb_nics;
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 05/19] qemu: drive removal support
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (3 preceding siblings ...)
2009-02-10 20:30 ` [Qemu-devel] [patch 04/19] qemu: dynamic nic info " Marcelo Tosatti
@ 2009-02-10 20:30 ` Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 06/19] qemu: record devfn on block driver instance Marcelo Tosatti
` (15 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: drive-remove --]
[-- Type: text/plain, Size: 2154 bytes --]
To be used by hot-remove.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/sysemu.h
===================================================================
--- trunk.orig/sysemu.h
+++ trunk/sysemu.h
@@ -135,6 +135,7 @@ typedef struct DriveInfo {
int bus;
int unit;
int used;
+ int drive_opt_idx;
BlockInterfaceErrorAction onerror;
char serial[21];
} DriveInfo;
@@ -148,6 +149,8 @@ extern DriveInfo drives_table[MAX_DRIVES
extern int drive_get_index(BlockInterfaceType type, int bus, int unit);
extern int drive_get_max_bus(BlockInterfaceType type);
+extern void drive_uninit(BlockDriverState *bdrv);
+extern void drive_remove(int index);
extern const char *drive_get_serial(BlockDriverState *bdrv);
extern BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv);
Index: trunk/vl.c
===================================================================
--- trunk.orig/vl.c
+++ trunk/vl.c
@@ -2182,6 +2182,12 @@ static int drive_add(const char *file, c
return index;
}
+void drive_remove(int index)
+{
+ drives_opt[index].used = 0;
+ nb_drives_opt--;
+}
+
int drive_get_index(BlockInterfaceType type, int bus, int unit)
{
int index;
@@ -2239,6 +2245,20 @@ static void bdrv_format_print(void *opaq
fprintf(stderr, " %s", name);
}
+void drive_uninit(BlockDriverState *bdrv)
+{
+ int i;
+
+ for (i = 0; i < MAX_DRIVES; i++)
+ if (drives_table[i].bdrv == bdrv) {
+ drives_table[i].bdrv = NULL;
+ drives_table[i].used = 0;
+ drive_remove(drives_table[i].drive_opt_idx);
+ nb_drives--;
+ break;
+ }
+}
+
static int drive_init(struct drive_opt *arg, int snapshot,
QEMUMachine *machine)
{
@@ -2538,6 +2558,7 @@ static int drive_init(struct drive_opt *
drives_table[drives_table_idx].bus = bus_id;
drives_table[drives_table_idx].unit = unit_id;
drives_table[drives_table_idx].onerror = onerror;
+ drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));
nb_drives++;
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 06/19] qemu: record devfn on block driver instance
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (4 preceding siblings ...)
2009-02-10 20:30 ` [Qemu-devel] [patch 05/19] qemu: drive removal support Marcelo Tosatti
@ 2009-02-10 20:30 ` Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 07/19] qemu: move drives_opt for external use Marcelo Tosatti
` (14 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: record-pcidev-on-bdrv --]
[-- Type: text/plain, Size: 2416 bytes --]
Record PCIDev on the BlockDriverState structure to locate for release
on hot-removal.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/block_int.h
===================================================================
--- trunk.orig/block_int.h
+++ trunk/block_int.h
@@ -127,6 +127,7 @@ struct BlockDriverState {
int type;
char device_name[32];
BlockDriverState *next;
+ void *private;
};
struct BlockDriverAIOCB {
Index: trunk/hw/ide.c
===================================================================
--- trunk.orig/hw/ide.c
+++ trunk/hw/ide.c
@@ -28,6 +28,7 @@
#include "scsi-disk.h"
#include "pcmcia.h"
#include "block.h"
+#include "block_int.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "ppc_mac.h"
@@ -3352,6 +3353,7 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
{
PCIIDEState *d;
uint8_t *pci_conf;
+ int i;
/* register a function 1 of PIIX3 */
d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
@@ -3378,6 +3380,10 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+ for (i = 0; i < 4; i++)
+ if (hd_table[i])
+ hd_table[i]->private = &d->dev;
+
register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
}
Index: trunk/hw/lsi53c895a.c
===================================================================
--- trunk.orig/hw/lsi53c895a.c
+++ trunk/hw/lsi53c895a.c
@@ -13,6 +13,7 @@
#include "hw.h"
#include "pci.h"
#include "scsi-disk.h"
+#include "block_int.h"
//#define DEBUG_LSI
//#define DEBUG_LSI_REG
@@ -1958,6 +1959,7 @@ void lsi_scsi_attach(void *opaque, Block
s->scsi_dev[id] = scsi_generic_init(bd, 1, lsi_command_complete, s);
if (s->scsi_dev[id] == NULL)
s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s);
+ bd->private = &s->pci_dev;
}
void *lsi_scsi_init(PCIBus *bus, int devfn)
Index: trunk/hw/virtio-blk.c
===================================================================
--- trunk.orig/hw/virtio-blk.c
+++ trunk/hw/virtio-blk.c
@@ -314,6 +314,7 @@ void *virtio_blk_init(PCIBus *bus, Block
s->vdev.reset = virtio_blk_reset;
s->bs = bs;
s->rq = NULL;
+ bs->private = &s->vdev.pci_dev;
bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 07/19] qemu: move drives_opt for external use
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (5 preceding siblings ...)
2009-02-10 20:30 ` [Qemu-devel] [patch 06/19] qemu: record devfn on block driver instance Marcelo Tosatti
@ 2009-02-10 20:30 ` Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 08/19] qemu: net/drive add/remove tweaks Marcelo Tosatti
` (13 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: move-drives-opt-for-external-use --]
[-- Type: text/plain, Size: 1164 bytes --]
Device hotplug will use that structure from a separate
file.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/sysemu.h
===================================================================
--- trunk.orig/sysemu.h
+++ trunk/sysemu.h
@@ -154,6 +154,15 @@ extern void drive_remove(int index);
extern const char *drive_get_serial(BlockDriverState *bdrv);
extern BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv);
+struct drive_opt {
+ const char *file;
+ char opt[1024];
+ int used;
+};
+
+extern struct drive_opt drives_opt[MAX_DRIVES];
+extern int nb_drives_opt;
+
/* serial ports */
#define MAX_SERIAL_PORTS 4
Index: trunk/vl.c
===================================================================
--- trunk.orig/vl.c
+++ trunk/vl.c
@@ -242,12 +242,8 @@ int alt_grab = 0;
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
#endif
-static int nb_drives_opt;
-static struct drive_opt {
- const char *file;
- char opt[1024];
- int used;
-} drives_opt[MAX_DRIVES];
+int nb_drives_opt;
+struct drive_opt drives_opt[MAX_DRIVES];
static CPUState *cur_cpu;
static CPUState *next_cpu;
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 08/19] qemu: net/drive add/remove tweaks
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (6 preceding siblings ...)
2009-02-10 20:30 ` [Qemu-devel] [patch 07/19] qemu: move drives_opt for external use Marcelo Tosatti
@ 2009-02-10 20:30 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 09/19] qemu: add net_client_uninit / qemu_find_vlan_client Marcelo Tosatti
` (12 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: net-drive-add-remove-tweaks --]
[-- Type: text/plain, Size: 2860 bytes --]
Export net/drive add/remove functions for device hotplug usage.
Return the table index on add.
Return failure instead of exiting if limit has been reached
on drive_add.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/net.c
===================================================================
--- trunk.orig/net.c
+++ trunk/net.c
@@ -1597,7 +1597,7 @@ int net_client_init(const char *device,
name = NULL;
nb_nics++;
vlan->nb_guest_devs++;
- ret = 0;
+ ret = idx;
} else
if (!strcmp(device, "none")) {
/* does nothing. It is needed to signal that no network cards
Index: trunk/sysemu.h
===================================================================
--- trunk.orig/sysemu.h
+++ trunk/sysemu.h
@@ -163,6 +163,9 @@ struct drive_opt {
extern struct drive_opt drives_opt[MAX_DRIVES];
extern int nb_drives_opt;
+extern int drive_add(const char *file, const char *fmt, ...);
+extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);
+
/* serial ports */
#define MAX_SERIAL_PORTS 4
Index: trunk/vl.c
===================================================================
--- trunk.orig/vl.c
+++ trunk/vl.c
@@ -2158,14 +2158,14 @@ static int drive_get_free_idx(void)
return -1;
}
-static int drive_add(const char *file, const char *fmt, ...)
+int drive_add(const char *file, const char *fmt, ...)
{
va_list ap;
int index = drive_opt_get_free_idx();
if (nb_drives_opt >= MAX_DRIVES || index == -1) {
fprintf(stderr, "qemu: too many drives\n");
- exit(1);
+ return -1;
}
drives_opt[index].file = file;
@@ -2255,8 +2255,7 @@ void drive_uninit(BlockDriverState *bdrv
}
}
-static int drive_init(struct drive_opt *arg, int snapshot,
- QEMUMachine *machine)
+int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
{
char buf[128];
char file[1024];
@@ -2269,6 +2268,7 @@ static int drive_init(struct drive_opt *
int cyls, heads, secs, translation;
BlockDriverState *bdrv;
BlockDriver *drv = NULL;
+ QEMUMachine *machine = opaque;
int max_devs;
int index;
int cache;
@@ -2535,7 +2535,7 @@ static int drive_init(struct drive_opt *
*/
if (drive_get_index(type, bus_id, unit_id) != -1)
- return 0;
+ return -2;
/* init */
@@ -2585,7 +2585,7 @@ static int drive_init(struct drive_opt *
break;
}
if (!file[0])
- return 0;
+ return -2;
bdrv_flags = 0;
if (snapshot) {
bdrv_flags |= BDRV_O_SNAPSHOT;
@@ -2602,7 +2602,7 @@ static int drive_init(struct drive_opt *
file);
return -1;
}
- return 0;
+ return drives_table_idx;
}
/***********************************************************/
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 09/19] qemu: add net_client_uninit / qemu_find_vlan_client
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (7 preceding siblings ...)
2009-02-10 20:30 ` [Qemu-devel] [patch 08/19] qemu: net/drive add/remove tweaks Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 10/19] qemu: add cpu_unregister_io_memory and make io mem table index dynamic Marcelo Tosatti
` (11 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: net-client-uninit --]
[-- Type: text/plain, Size: 1843 bytes --]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/net.c
===================================================================
--- trunk.orig/net.c
+++ trunk/net.c
@@ -366,6 +366,19 @@ void qemu_del_vlan_client(VLANClientStat
pvc = &(*pvc)->next;
}
+VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque)
+{
+ VLANClientState **pvc = &vlan->first_client;
+
+ while (*pvc != NULL)
+ if ((*pvc)->opaque == opaque)
+ return *pvc;
+ else
+ pvc = &(*pvc)->next;
+
+ return NULL;
+}
+
int qemu_can_send_packet(VLANClientState *vc1)
{
VLANState *vlan = vc1->vlan;
@@ -1713,6 +1726,14 @@ int net_client_init(const char *device,
return ret;
}
+void net_client_uninit(NICInfo *nd)
+{
+ nd->vlan->nb_guest_devs--;
+ nb_nics--;
+ nd->used = 0;
+ free((void *)nd->model);
+}
+
int net_client_parse(const char *str)
{
const char *p;
Index: trunk/net.h
===================================================================
--- trunk.orig/net.h
+++ trunk/net.h
@@ -42,6 +42,7 @@ VLANClientState *qemu_new_vlan_client(VL
IOCanRWHandler *fd_can_read,
void *opaque);
void qemu_del_vlan_client(VLANClientState *vc);
+VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque);
int qemu_can_send_packet(VLANClientState *vc);
ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov,
int iovcnt);
@@ -94,6 +95,7 @@ void net_checksum_calculate(uint8_t *dat
/* from net.c */
int net_client_init(const char *device, const char *p);
+void net_client_uninit(NICInfo *nd);
int net_client_parse(const char *str);
void net_slirp_smb(const char *exported_dir);
void net_slirp_redir(const char *redir_str);
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 10/19] qemu: add cpu_unregister_io_memory and make io mem table index dynamic
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (8 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 09/19] qemu: add net_client_uninit / qemu_find_vlan_client Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 11/19] qemu: add qemu_free_irqs Marcelo Tosatti
` (10 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: cpu-unregister-io-mem --]
[-- Type: text/plain, Size: 3021 bytes --]
So drivers can clear their mem io table entries on exit back to unassigned
state.
Also make the io mem index allocation dynamic.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/cpu-all.h
===================================================================
--- trunk.orig/cpu-all.h
+++ trunk/cpu-all.h
@@ -909,6 +909,7 @@ int cpu_register_io_memory(int io_index,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
+void cpu_unregister_io_memory(int table_address);
CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
Index: trunk/exec.c
===================================================================
--- trunk.orig/exec.c
+++ trunk/exec.c
@@ -179,7 +179,7 @@ static void io_mem_init(void);
CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-static int io_mem_nb;
+char io_mem_used[IO_MEM_NB_ENTRIES];
static int io_mem_watch;
#endif
@@ -2799,12 +2799,28 @@ static void *subpage_init (target_phys_a
return mmio;
}
+static int get_free_io_mem_idx(void)
+{
+ int i;
+
+ for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
+ if (!io_mem_used[i]) {
+ io_mem_used[i] = 1;
+ return i;
+ }
+
+ return -1;
+}
+
static void io_mem_init(void)
{
+ int i;
+
cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);
cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL);
- io_mem_nb = 5;
+ for (i=0; i<5; i++)
+ io_mem_used[i] = 1;
io_mem_watch = cpu_register_io_memory(0, watch_mem_read,
watch_mem_write, NULL);
@@ -2829,9 +2845,9 @@ int cpu_register_io_memory(int io_index,
int i, subwidth = 0;
if (io_index <= 0) {
- if (io_mem_nb >= IO_MEM_NB_ENTRIES)
- return -1;
- io_index = io_mem_nb++;
+ io_index = get_free_io_mem_idx();
+ if (io_index == -1)
+ return io_index;
} else {
if (io_index >= IO_MEM_NB_ENTRIES)
return -1;
@@ -2847,6 +2863,19 @@ int cpu_register_io_memory(int io_index,
return (io_index << IO_MEM_SHIFT) | subwidth;
}
+void cpu_unregister_io_memory(int io_table_address)
+{
+ int i;
+ int io_index = io_table_address >> IO_MEM_SHIFT;
+
+ for (i=0;i < 3; i++) {
+ io_mem_read[io_index][i] = unassigned_mem_read[i];
+ io_mem_write[io_index][i] = unassigned_mem_write[i];
+ }
+ io_mem_opaque[io_index] = NULL;
+ io_mem_used[io_index] = 0;
+}
+
CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
{
return io_mem_write[io_index >> IO_MEM_SHIFT];
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 11/19] qemu: add qemu_free_irqs
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (9 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 10/19] qemu: add cpu_unregister_io_memory and make io mem table index dynamic Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 12/19] qemu: add pci_unregister_device Marcelo Tosatti
` (9 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: qemu-free-irqs --]
[-- Type: text/plain, Size: 890 bytes --]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/irq.c
===================================================================
--- trunk.orig/hw/irq.c
+++ trunk/hw/irq.c
@@ -56,6 +56,12 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_ha
return s;
}
+void qemu_free_irqs(qemu_irq *s)
+{
+ qemu_free(s[0]);
+ qemu_free(s);
+}
+
static void qemu_notirq(void *opaque, int line, int level)
{
struct IRQState *irq = opaque;
Index: trunk/hw/irq.h
===================================================================
--- trunk.orig/hw/irq.h
+++ trunk/hw/irq.h
@@ -27,6 +27,7 @@ static inline void qemu_irq_pulse(qemu_i
/* Returns an array of N IRQs. */
qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
+void qemu_free_irqs(qemu_irq *s);
/* Returns a new IRQ with opposite polarity. */
qemu_irq qemu_irq_invert(qemu_irq irq);
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 12/19] qemu: add pci_unregister_device
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (10 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 11/19] qemu: add qemu_free_irqs Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 13/19] qemu: warn if PCI region is not power of two Marcelo Tosatti
` (8 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: pci-unregister --]
[-- Type: text/plain, Size: 3221 bytes --]
Unregister the pci device, unassign its IO and memory regions, and free
associated data.
Add a callback so drivers can free device state.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/pci.c
===================================================================
--- trunk.orig/hw/pci.c
+++ trunk/hw/pci.c
@@ -196,6 +196,48 @@ PCIDevice *pci_register_device(PCIBus *b
return pci_dev;
}
+static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
+{
+ return addr + pci_mem_base;
+}
+
+static void pci_unregister_io_regions(PCIDevice *pci_dev)
+{
+ PCIIORegion *r;
+ int i;
+
+ for(i = 0; i < PCI_NUM_REGIONS; i++) {
+ r = &pci_dev->io_regions[i];
+ if (!r->size || r->addr == -1)
+ continue;
+ if (r->type == PCI_ADDRESS_SPACE_IO) {
+ isa_unassign_ioport(r->addr, r->size);
+ } else {
+ cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
+ r->size,
+ IO_MEM_UNASSIGNED);
+ }
+ }
+}
+
+int pci_unregister_device(PCIDevice *pci_dev)
+{
+ int ret = 0;
+
+ if (pci_dev->unregister)
+ ret = pci_dev->unregister(pci_dev);
+ if (ret)
+ return ret;
+
+ pci_unregister_io_regions(pci_dev);
+
+ qemu_free_irqs(pci_dev->irq);
+ pci_irq_index--;
+ pci_dev->bus->devices[pci_dev->devfn] = NULL;
+ qemu_free(pci_dev);
+ return 0;
+}
+
void pci_register_io_region(PCIDevice *pci_dev, int region_num,
uint32_t size, int type,
PCIMapIORegionFunc *map_func)
@@ -218,11 +260,6 @@ void pci_register_io_region(PCIDevice *p
*(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
}
-static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
-{
- return addr + pci_mem_base;
-}
-
static void pci_update_mappings(PCIDevice *d)
{
PCIIORegion *r;
Index: trunk/hw/pci.h
===================================================================
--- trunk.orig/hw/pci.h
+++ trunk/hw/pci.h
@@ -125,6 +125,7 @@ typedef uint32_t PCIConfigReadFunc(PCIDe
uint32_t address, int len);
typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type);
+typedef int PCIUnregisterFunc(PCIDevice *pci_dev);
#define PCI_ADDRESS_SPACE_MEM 0x00
#define PCI_ADDRESS_SPACE_IO 0x01
@@ -189,6 +190,7 @@ struct PCIDevice {
/* do not access the following fields */
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
+ PCIUnregisterFunc *unregister;
/* ??? This is a PC-specific hack, and should be removed. */
int irq_index;
@@ -203,6 +205,7 @@ PCIDevice *pci_register_device(PCIBus *b
int instance_size, int devfn,
PCIConfigReadFunc *config_read,
PCIConfigWriteFunc *config_write);
+int pci_unregister_device(PCIDevice *pci_dev);
void pci_register_io_region(PCIDevice *pci_dev, int region_num,
uint32_t size, int type,
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 13/19] qemu: warn if PCI region is not power of two
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (11 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 12/19] qemu: add pci_unregister_device Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 14/19] qemu: LSI SCSI and e1000 unregister callbacks Marcelo Tosatti
` (7 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: pci-warning-size --]
[-- Type: text/plain, Size: 663 bytes --]
Otherwise the PCI size for such regions can be calculated erroneously.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/pci.c
===================================================================
--- trunk.orig/hw/pci.c
+++ trunk/hw/pci.c
@@ -247,6 +247,13 @@ void pci_register_io_region(PCIDevice *p
if ((unsigned int)region_num >= PCI_NUM_REGIONS)
return;
+
+ if (size & (size-1)) {
+ fprintf(stderr, "ERROR: PCI region size must be pow2 "
+ "type=0x%x, size=0x%x\n", type, size);
+ exit(1);
+ }
+
r = &pci_dev->io_regions[region_num];
r->addr = -1;
r->size = size;
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 14/19] qemu: LSI SCSI and e1000 unregister callbacks
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (12 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 13/19] qemu: warn if PCI region is not power of two Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 15/19] qemu: zero ioport_opaque on isa_unassign_ioport Marcelo Tosatti
` (6 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: lsi-and-e1000-unregister --]
[-- Type: text/plain, Size: 1599 bytes --]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/e1000.c
===================================================================
--- trunk.orig/hw/e1000.c
+++ trunk/hw/e1000.c
@@ -1034,6 +1034,16 @@ e1000_mmio_map(PCIDevice *pci_dev, int r
excluded_regs[i] - 4);
}
+static int
+pci_e1000_uninit(PCIDevice *dev)
+{
+ E1000State *d = (E1000State *) dev;
+
+ cpu_unregister_io_memory(d->mmio_index);
+
+ return 0;
+}
+
PCIDevice *
pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
{
@@ -1092,6 +1102,7 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd,
qemu_format_nic_info_str(d->vc, d->nd->macaddr);
register_savevm(info_str, -1, 2, nic_save, nic_load, d);
+ d->dev.unregister = pci_e1000_uninit;
return (PCIDevice *)d;
}
Index: trunk/hw/lsi53c895a.c
===================================================================
--- trunk.orig/hw/lsi53c895a.c
+++ trunk/hw/lsi53c895a.c
@@ -1962,6 +1962,18 @@ void lsi_scsi_attach(void *opaque, Block
bd->private = &s->pci_dev;
}
+static int lsi_scsi_uninit(PCIDevice *d)
+{
+ LSIState *s = (LSIState *) d;
+
+ cpu_unregister_io_memory(s->mmio_io_addr);
+ cpu_unregister_io_memory(s->ram_io_addr);
+
+ qemu_free(s->queue);
+
+ return 0;
+}
+
void *lsi_scsi_init(PCIBus *bus, int devfn)
{
LSIState *s;
@@ -2004,6 +2016,7 @@ void *lsi_scsi_init(PCIBus *bus, int dev
s->queue = qemu_malloc(sizeof(lsi_queue));
s->queue_len = 1;
s->active_commands = 0;
+ s->pci_dev.unregister = lsi_scsi_uninit;
lsi_soft_reset(s);
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 15/19] qemu: zero ioport_opaque on isa_unassign_ioport
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (13 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 14/19] qemu: LSI SCSI and e1000 unregister callbacks Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 16/19] qemu: initialize hot add system / acpi gpe Marcelo Tosatti
` (5 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: zero-ioport-opaque --]
[-- Type: text/plain, Size: 542 bytes --]
If the io port is unassigned, the previous private pointer is
meaningless.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/vl.c
===================================================================
--- trunk.orig/vl.c
+++ trunk/vl.c
@@ -404,6 +404,8 @@ void isa_unassign_ioport(int start, int
ioport_write_table[0][i] = default_ioport_writeb;
ioport_write_table[1][i] = default_ioport_writew;
ioport_write_table[2][i] = default_ioport_writel;
+
+ ioport_opaque[i] = NULL;
}
}
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 16/19] qemu: initialize hot add system / acpi gpe
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (14 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 15/19] qemu: zero ioport_opaque on isa_unassign_ioport Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 17/19] qemu: pci hotplug GPE support Marcelo Tosatti
` (4 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: gpe --]
[-- Type: text/plain, Size: 2776 bytes --]
ACPI GPE support, used by PCI (and CPU) hotplug.
From: Glauber Costa <gcosta@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/acpi.c
===================================================================
--- trunk.orig/hw/acpi.c
+++ trunk/hw/acpi.c
@@ -561,3 +561,71 @@ void qemu_system_powerdown(void)
}
}
#endif
+
+#define GPE_BASE 0xafe0
+
+struct gpe_regs {
+ uint16_t sts; /* status */
+ uint16_t en; /* enabled */
+};
+
+static struct gpe_regs gpe;
+
+static uint32_t gpe_readb(void *opaque, uint32_t addr)
+{
+ uint32_t val = 0;
+ struct gpe_regs *g = opaque;
+ switch (addr) {
+ case GPE_BASE:
+ val = g->sts & 0xFF;
+ break;
+ case GPE_BASE + 1:
+ val = (g->sts >> 8) & 0xFF;
+ break;
+ case GPE_BASE + 2:
+ val = g->en & 0xFF;
+ break;
+ case GPE_BASE + 3:
+ val = (g->en >> 8) & 0xFF;
+ break;
+ default:
+ break;
+ }
+
+#if defined(DEBUG)
+ printf("gpe read %lx == %lx\n", addr, val);
+#endif
+ return val;
+}
+
+static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+ struct gpe_regs *g = opaque;
+ switch (addr) {
+ case GPE_BASE:
+ g->sts = (g->sts & ~0xFFFF) | (val & 0xFFFF);
+ break;
+ case GPE_BASE + 1:
+ g->sts = (g->sts & 0xFFFF) | (val << 8);
+ break;
+ case GPE_BASE + 2:
+ g->en = (g->en & ~0xFFFF) | (val & 0xFFFF);
+ break;
+ case GPE_BASE + 3:
+ g->en = (g->en & 0xFFFF) | (val << 8);
+ break;
+ default:
+ break;
+ }
+
+#if defined(DEBUG)
+ printf("gpe write %lx <== %d\n", addr, val);
+#endif
+}
+
+void qemu_system_hot_add_init(void)
+{
+ register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
+ register_ioport_read(GPE_BASE, 4, 1, gpe_readb, &gpe);
+
+}
Index: trunk/hw/pc.c
===================================================================
--- trunk.orig/hw/pc.c
+++ trunk/hw/pc.c
@@ -1010,6 +1010,8 @@ vga_bios_error:
pci_nic_init(pci_bus, nd, -1, "ne2k_pci");
}
+ qemu_system_hot_add_init();
+
if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
fprintf(stderr, "qemu: too many IDE bus\n");
exit(1);
Index: trunk/sysemu.h
===================================================================
--- trunk.orig/sysemu.h
+++ trunk/sysemu.h
@@ -166,6 +166,9 @@ extern int nb_drives_opt;
extern int drive_add(const char *file, const char *fmt, ...);
extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);
+/* acpi */
+void qemu_system_hot_add_init(void);
+
/* serial ports */
#define MAX_SERIAL_PORTS 4
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 17/19] qemu: pci hotplug GPE support
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (15 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 16/19] qemu: initialize hot add system / acpi gpe Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 18/19] From: Markus Armbruster <armbru@pond.sub.org> Marcelo Tosatti
` (3 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: gpe-pci-hotplug --]
[-- Type: text/plain, Size: 3390 bytes --]
Enable the corresponding bit on the PCIST region and trigger the SCI
and handle the _EJ0 notifications.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/acpi.c
===================================================================
--- trunk.orig/hw/acpi.c
+++ trunk/hw/acpi.c
@@ -563,13 +563,21 @@ void qemu_system_powerdown(void)
#endif
#define GPE_BASE 0xafe0
+#define PCI_BASE 0xae00
+#define PCI_EJ_BASE 0xae08
struct gpe_regs {
uint16_t sts; /* status */
uint16_t en; /* enabled */
};
+struct pci_status {
+ uint32_t up;
+ uint32_t down;
+};
+
static struct gpe_regs gpe;
+static struct pci_status pci0_status;
static uint32_t gpe_readb(void *opaque, uint32_t addr)
{
@@ -623,9 +631,95 @@ static void gpe_writeb(void *opaque, uin
#endif
}
+static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
+{
+ uint32_t val = 0;
+ struct pci_status *g = opaque;
+ switch (addr) {
+ case PCI_BASE:
+ val = g->up;
+ break;
+ case PCI_BASE + 4:
+ val = g->down;
+ break;
+ default:
+ break;
+ }
+
+#if defined(DEBUG)
+ printf("pcihotplug read %lx == %lx\n", addr, val);
+#endif
+ return val;
+}
+
+static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ struct pci_status *g = opaque;
+ switch (addr) {
+ case PCI_BASE:
+ g->up = val;
+ break;
+ case PCI_BASE + 4:
+ g->down = val;
+ break;
+ }
+
+#if defined(DEBUG)
+ printf("pcihotplug write %lx <== %d\n", addr, val);
+#endif
+}
+
+static uint32_t pciej_read(void *opaque, uint32_t addr)
+{
+#if defined(DEBUG)
+ printf("pciej read %lx == %lx\n", addr, val);
+#endif
+ return 0;
+}
+
+static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ int slot = ffs(val) - 1;
+
+#if defined(DEBUG)
+ printf("pciej write %lx <== %d\n", addr, val);
+#endif
+}
+
void qemu_system_hot_add_init(void)
{
register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
register_ioport_read(GPE_BASE, 4, 1, gpe_readb, &gpe);
+ register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
+ register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, &pci0_status);
+
+ register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, NULL);
+ register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, NULL);
+}
+
+static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot)
+{
+ g->sts |= 2;
+ g->en |= 2;
+ p->up |= (1 << slot);
+}
+
+static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
+{
+ g->sts |= 2;
+ g->en |= 2;
+ p->down |= (1 << slot);
+}
+
+void qemu_system_device_hot_add(int bus, int slot, int state)
+{
+ qemu_set_irq(pm_state->irq, 1);
+ pci0_status.up = 0;
+ pci0_status.down = 0;
+ if (state)
+ enable_device(&pci0_status, &gpe, slot);
+ else
+ disable_device(&pci0_status, &gpe, slot);
+ qemu_set_irq(pm_state->irq, 0);
}
Index: trunk/sysemu.h
===================================================================
--- trunk.orig/sysemu.h
+++ trunk/sysemu.h
@@ -168,6 +168,7 @@ extern int drive_init(struct drive_opt *
/* acpi */
void qemu_system_hot_add_init(void);
+void qemu_system_device_hot_add(int pcibus, int slot, int state);
/* serial ports */
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 18/19] From: Markus Armbruster <armbru@pond.sub.org>
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (16 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 17/19] qemu: pci hotplug GPE support Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 19/19] qemu: PCI device, disk and host network hot-add / hot-remove Marcelo Tosatti
` (2 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: pci-helper-parser --]
[-- Type: text/plain, Size: 2945 bytes --]
This code parses full PCI device addresses. It then rejects domains
other than zero, because these are not supported in QEMU.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/hw/pci.c
===================================================================
--- trunk.orig/hw/pci.c
+++ trunk/hw/pci.c
@@ -26,6 +26,7 @@
#include "console.h"
#include "net.h"
#include "virtio-net.h"
+#include "sysemu.h"
//#define DEBUG_PCI
@@ -158,6 +159,82 @@ static int pci_set_default_subsystem_id(
return 0;
}
+/*
+ * Parse [[<domain>:]<bus>:]<slot>, return -1 on error
+ */
+static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
+{
+ const char *p;
+ char *e;
+ unsigned long val;
+ unsigned long dom = 0, bus = 0;
+ unsigned slot = 0;
+
+ p = addr;
+ val = strtoul(p, &e, 16);
+ if (e == p)
+ return -1;
+ if (*e == ':') {
+ bus = val;
+ p = e + 1;
+ val = strtoul(p, &e, 16);
+ if (e == p)
+ return -1;
+ if (*e == ':') {
+ dom = bus;
+ bus = val;
+ p = e + 1;
+ val = strtoul(p, &e, 16);
+ if (e == p)
+ return -1;
+ }
+ }
+
+ if (dom > 0xffff || bus > 0xff || val > 0x1f)
+ return -1;
+
+ slot = val;
+
+ if (*e)
+ return -1;
+
+ /* Note: QEMU doesn't implement domains other than 0 */
+ if (dom != 0 || pci_find_bus(bus) == NULL)
+ return -1;
+
+ *domp = dom;
+ *busp = bus;
+ *slotp = slot;
+ return 0;
+}
+
+int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
+{
+ char devaddr[32];
+
+ if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
+ return -1;
+
+ return pci_parse_devaddr(devaddr, domp, busp, slotp);
+}
+
+int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
+{
+ char devaddr[32];
+
+ if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
+ return -1;
+
+ if (!strcmp(devaddr, "auto")) {
+ *domp = *busp = 0;
+ *slotp = -1;
+ /* want to support dom/bus auto-assign at some point */
+ return 0;
+ }
+
+ return pci_parse_devaddr(devaddr, domp, busp, slotp);
+}
+
/* -1 for devfn means auto assign */
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
int instance_size, int devfn,
Index: trunk/hw/pci.h
===================================================================
--- trunk.orig/hw/pci.h
+++ trunk/hw/pci.h
@@ -232,6 +232,9 @@ void pci_for_each_device(int bus_num, vo
PCIBus *pci_find_bus(int bus_num);
PCIDevice *pci_find_device(int bus_num, int slot, int function);
+int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp);
+int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp);
+
void pci_info(void);
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
pci_map_irq_fn map_irq, const char *name);
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [patch 19/19] qemu: PCI device, disk and host network hot-add / hot-remove
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (17 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 18/19] From: Markus Armbruster <armbru@pond.sub.org> Marcelo Tosatti
@ 2009-02-10 20:31 ` Marcelo Tosatti
2009-02-11 2:26 ` [Qemu-devel] " Anthony Liguori
2009-02-11 12:42 ` [Qemu-devel] [patch 00/19] acpi pci hotplug Markus Armbruster
2009-02-11 15:19 ` [Qemu-devel] " Anthony Liguori
20 siblings, 1 reply; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-10 20:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel
[-- Attachment #1: dev-and-disk-hotadd --]
[-- Type: text/plain, Size: 14597 bytes --]
Add monitor command to hot-add PCI devices (nic and storage).
Syntax is:
pci_add pci_addr=[[<domain>:]<bus>:]<slot> nic|storage params
It returns the domain, bus and slot for the newly added device on success.
It is possible to attach a disk to a device after PCI initialization via
the drive_add command. If so, a manual scan of the SCSI bus on the guest
is necessary.
Save QEMUMachine necessary for drive_init.
Add monitor command to hot-remove devices, remove device data on _EJ0 notification.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: trunk/Makefile.target
===================================================================
--- trunk.orig/Makefile.target
+++ trunk/Makefile.target
@@ -583,6 +583,7 @@ OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
+OBJS += device-hotplug.o pci-hotplug.o
CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
endif
ifeq ($(TARGET_BASE_ARCH), ppc)
Index: trunk/hw/boards.h
===================================================================
--- trunk.orig/hw/boards.h
+++ trunk/hw/boards.h
@@ -25,6 +25,8 @@ typedef struct QEMUMachine {
int qemu_register_machine(QEMUMachine *m);
void register_machines(void);
+extern QEMUMachine *current_machine;
+
/* Axis ETRAX. */
extern QEMUMachine bareetraxfs_machine;
extern QEMUMachine axisdev88_machine;
Index: trunk/hw/device-hotplug.c
===================================================================
--- /dev/null
+++ trunk/hw/device-hotplug.c
@@ -0,0 +1,61 @@
+#include "hw.h"
+#include "boards.h"
+#include "net.h"
+#include "block_int.h"
+#include "sysemu.h"
+
+int add_init_drive(const char *opts)
+{
+ int drive_opt_idx, drive_idx;
+ int ret = -1;
+
+ drive_opt_idx = drive_add(NULL, "%s", opts);
+ if (!drive_opt_idx)
+ return ret;
+
+ drive_idx = drive_init(&drives_opt[drive_opt_idx], 0, current_machine);
+ if (drive_idx == -1) {
+ drive_remove(drive_opt_idx);
+ return ret;
+ }
+
+ return drive_idx;
+}
+
+void destroy_nic(dev_match_fn *match_fn, void *arg)
+{
+ int i;
+ NICInfo *nic;
+
+ for (i = 0; i < MAX_NICS; i++)
+ nic = &nd_table[i];
+ if (nic->used) {
+ if (nic->private && match_fn(nic->private, arg)) {
+ if (nic->vlan) {
+ VLANClientState *vc;
+ vc = qemu_find_vlan_client(nic->vlan, nic->private);
+ if (vc)
+ qemu_del_vlan_client(vc);
+ }
+ net_client_uninit(nic);
+ }
+ }
+}
+
+void destroy_bdrvs(dev_match_fn *match_fn, void *arg)
+{
+ int i;
+ struct BlockDriverState *bs;
+
+ for (i = 0; i <= MAX_DRIVES; i++) {
+ bs = drives_table[i].bdrv;
+ if (bs) {
+ if (bs->private && match_fn(bs->private, arg)) {
+ drive_uninit(bs);
+ bdrv_delete(bs);
+ }
+ }
+ }
+}
+
+
Index: trunk/monitor.c
===================================================================
--- trunk.orig/monitor.c
+++ trunk/monitor.c
@@ -1511,6 +1511,20 @@ static const term_cmd_t term_cmds[] = {
"", "cancel the current VM migration" },
{ "migrate_set_speed", "s", do_migrate_set_speed,
"value", "set maximum speed (in bytes) for migrations" },
+#if defined(TARGET_I386)
+ { "drive_add", "ss", drive_hot_add, "pci_addr=[[<domain>:]<bus>:]<slot>\n"
+ "[file=file][,if=type][,bus=n]\n"
+ "[,unit=m][,media=d][index=i]\n"
+ "[,cyls=c,heads=h,secs=s[,trans=t]]\n"
+ "[snapshot=on|off][,cache=on|off]",
+ "add drive to PCI storage controller" },
+ { "pci_add", "sss", pci_device_hot_add, "pci_addr=auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...", "hot-add PCI device" },
+ { "pci_del", "s", pci_device_hot_remove, "pci_addr=[[<domain>:]<bus>:]<slot>", "hot remove PCI device" },
+ { "host_net_add", "ss", net_host_device_add,
+ "[tap,user,socket,vde] options", "add host VLAN client" },
+ { "host_net_remove", "is", net_host_device_remove,
+ "vlan_id name", "remove host VLAN client" },
+#endif
{ "balloon", "i", do_balloon,
"target", "request VM to change it's memory allocation (in MB)" },
{ "set_link", "ss", do_set_link, "name [up|down]" },
Index: trunk/sysemu.h
===================================================================
--- trunk.orig/sysemu.h
+++ trunk/sysemu.h
@@ -170,6 +170,20 @@ extern int drive_init(struct drive_opt *
void qemu_system_hot_add_init(void);
void qemu_system_device_hot_add(int pcibus, int slot, int state);
+/* device-hotplug */
+
+typedef int (dev_match_fn)(void *dev_private, void *arg);
+
+int add_init_drive(const char *opts);
+void destroy_nic(dev_match_fn *match_fn, void *arg);
+void destroy_bdrvs(dev_match_fn *match_fn, void *arg);
+
+/* pci-hotplug */
+void pci_device_hot_add(const char *pci_addr, const char *type, const char *opts);
+void drive_hot_add(const char *pci_addr, const char *opts);
+void pci_device_hot_remove(const char *pci_addr);
+void pci_device_hot_remove_success(int pcibus, int slot);
+
/* serial ports */
#define MAX_SERIAL_PORTS 4
Index: trunk/vl.c
===================================================================
--- trunk.orig/vl.c
+++ trunk/vl.c
@@ -3405,6 +3405,7 @@ static void qemu_bh_update_timeout(int *
/* machine registration */
static QEMUMachine *first_machine = NULL;
+QEMUMachine *current_machine = NULL;
int qemu_register_machine(QEMUMachine *m)
{
@@ -5587,6 +5588,8 @@ int main(int argc, char **argv, char **e
machine->init(ram_size, vga_ram_size, boot_devices,
kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
+ current_machine = machine;
+
/* Set KVM's vcpu state to qemu's initial CPUState. */
if (kvm_enabled()) {
int ret;
Index: trunk/hw/acpi.c
===================================================================
--- trunk.orig/hw/acpi.c
+++ trunk/hw/acpi.c
@@ -679,8 +679,12 @@ static uint32_t pciej_read(void *opaque,
static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
{
+#if defined (TARGET_I386)
int slot = ffs(val) - 1;
+ pci_device_hot_remove_success(0, slot);
+#endif
+
#if defined(DEBUG)
printf("pciej write %lx <== %d\n", addr, val);
#endif
Index: trunk/net.c
===================================================================
--- trunk.orig/net.c
+++ trunk/net.c
@@ -1734,6 +1734,62 @@ void net_client_uninit(NICInfo *nd)
free((void *)nd->model);
}
+static int net_host_check_device(const char *device)
+{
+ int i;
+ const char *valid_param_list[] = { "tap", "socket"
+#ifdef CONFIG_SLIRP
+ ,"user"
+#endif
+#ifdef CONFIG_VDE
+ ,"vde"
+#endif
+ };
+ for (i = 0; i < sizeof(valid_param_list) / sizeof(char *); i++) {
+ if (!strncmp(valid_param_list[i], device,
+ strlen(valid_param_list[i])))
+ return 1;
+ }
+
+ return 0;
+}
+
+void net_host_device_add(const char *device, const char *opts)
+{
+ if (!net_host_check_device(device)) {
+ term_printf("invalid host network device %s\n", device);
+ return;
+ }
+ net_client_init(device, opts);
+}
+
+void net_host_device_remove(int vlan_id, const char *device)
+{
+ VLANState *vlan;
+ VLANClientState *vc;
+
+ if (!net_host_check_device(device)) {
+ term_printf("invalid host network device %s\n", device);
+ return;
+ }
+
+ vlan = qemu_find_vlan(vlan_id);
+ if (!vlan) {
+ term_printf("can't find vlan %d\n", vlan_id);
+ return;
+ }
+
+ for(vc = vlan->first_client; vc != NULL; vc = vc->next)
+ if (!strcmp(vc->name, device))
+ break;
+
+ if (!vc) {
+ term_printf("can't find device %s\n", device);
+ return;
+ }
+ qemu_del_vlan_client(vc);
+}
+
int net_client_parse(const char *str)
{
const char *p;
Index: trunk/net.h
===================================================================
--- trunk.orig/net.h
+++ trunk/net.h
@@ -102,6 +102,8 @@ void net_slirp_redir(const char *redir_s
void net_cleanup(void);
int slirp_is_inited(void);
void net_client_check(void);
+void net_host_device_add(const char *device, const char *opts);
+void net_host_device_remove(int vlan_id, const char *device);
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
Index: trunk/hw/pci-hotplug.c
===================================================================
--- /dev/null
+++ trunk/hw/pci-hotplug.c
@@ -0,0 +1,195 @@
+#include "hw.h"
+#include "boards.h"
+#include "pci.h"
+#include "net.h"
+#include "sysemu.h"
+#include "pc.h"
+#include "console.h"
+#include "block_int.h"
+#include "virtio-blk.h"
+
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+static PCIDevice *qemu_pci_hot_add_nic(PCIBus *pci_bus, const char *opts)
+{
+ int ret;
+
+ ret = net_client_init ("nic", opts);
+ if (ret < 0 || !nd_table[ret].model)
+ return NULL;
+ return pci_nic_init (pci_bus, &nd_table[ret], -1, "rtl8139");
+}
+
+void drive_hot_add(const char *pci_addr, const char *opts)
+{
+ int dom, pci_bus;
+ unsigned slot;
+ int drive_idx, type, bus;
+ int success = 0;
+ PCIDevice *dev;
+
+ if (pci_read_devaddr(pci_addr, &dom, &pci_bus, &slot)) {
+ term_printf("Invalid pci address\n");
+ return;
+ }
+
+ dev = pci_find_device(pci_bus, slot, 0);
+ if (!dev) {
+ term_printf("no pci device with address %s\n", pci_addr);
+ return;
+ }
+
+ drive_idx = add_init_drive(opts);
+ if (drive_idx < 0)
+ return;
+ type = drives_table[drive_idx].type;
+ bus = drive_get_max_bus (type);
+
+ switch (type) {
+ case IF_SCSI:
+ success = 1;
+ lsi_scsi_attach (dev, drives_table[drive_idx].bdrv,
+ drives_table[drive_idx].unit);
+ break;
+ default:
+ term_printf("Can't hot-add drive to type %d\n", type);
+ }
+
+ if (success)
+ term_printf("OK bus %d, unit %d\n", drives_table[drive_idx].bus,
+ drives_table[drive_idx].unit);
+ return;
+}
+
+static PCIDevice *qemu_pci_hot_add_storage(PCIBus *pci_bus, const char *opts)
+{
+ void *opaque = NULL;
+ int type = -1, drive_idx = -1;
+ char buf[128];
+
+ if (get_param_value(buf, sizeof(buf), "if", opts)) {
+ if (!strcmp(buf, "scsi"))
+ type = IF_SCSI;
+ else if (!strcmp(buf, "virtio")) {
+ type = IF_VIRTIO;
+ }
+ } else {
+ term_printf("no if= specified\n");
+ return NULL;
+ }
+
+ if (get_param_value(buf, sizeof(buf), "file", opts)) {
+ drive_idx = add_init_drive(opts);
+ if (drive_idx < 0)
+ return NULL;
+ } else if (type == IF_VIRTIO) {
+ term_printf("virtio requires a backing file/device.\n");
+ return NULL;
+ }
+
+ switch (type) {
+ case IF_SCSI:
+ opaque = lsi_scsi_init (pci_bus, -1);
+ if (opaque && drive_idx >= 0)
+ lsi_scsi_attach (opaque, drives_table[drive_idx].bdrv,
+ drives_table[drive_idx].unit);
+ break;
+ case IF_VIRTIO:
+ opaque = virtio_blk_init (pci_bus, drives_table[drive_idx].bdrv);
+ break;
+ default:
+ term_printf ("type %s not a hotpluggable PCI device.\n", buf);
+ }
+
+ return opaque;
+}
+
+void pci_device_hot_add(const char *pci_addr, const char *type, const char *opts)
+{
+ PCIDevice *dev = NULL;
+ PCIBus *pci_bus;
+ int dom, bus;
+ unsigned slot;
+
+ if (pci_assign_devaddr(pci_addr, &dom, &bus, &slot)) {
+ term_printf("Invalid pci address\n");
+ return;
+ }
+
+ pci_bus = pci_find_bus(bus);
+ if (!pci_bus) {
+ term_printf("Can't find pci_bus %d\n", bus);
+ return;
+ }
+
+ if (strcmp(type, "nic") == 0)
+ dev = qemu_pci_hot_add_nic(pci_bus, opts);
+ else if (strcmp(type, "storage") == 0)
+ dev = qemu_pci_hot_add_storage(pci_bus, opts);
+ else
+ term_printf("invalid type: %s\n", type);
+
+ if (dev) {
+ qemu_system_device_hot_add(bus, PCI_SLOT(dev->devfn), 1);
+ term_printf("OK domain %d, bus %d, slot %d, function %d\n",
+ 0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn));
+ } else
+ term_printf("failed to add %s\n", opts);
+}
+#endif
+
+void pci_device_hot_remove(const char *pci_addr)
+{
+ PCIDevice *d;
+ int dom, bus;
+ unsigned slot;
+
+ if (pci_read_devaddr(pci_addr, &dom, &bus, &slot)) {
+ term_printf("Invalid pci address\n");
+ return;
+ }
+
+ d = pci_find_device(bus, slot, 0);
+ if (!d) {
+ term_printf("slot %d empty\n", slot);
+ return;
+ }
+
+ qemu_system_device_hot_add(bus, slot, 0);
+}
+
+static int pci_match_fn(void *dev_private, void *arg)
+{
+ PCIDevice *dev = dev_private;
+ PCIDevice *match = arg;
+
+ return (dev == match);
+}
+
+/*
+ * OS has executed _EJ0 method, we now can remove the device
+ */
+void pci_device_hot_remove_success(int pcibus, int slot)
+{
+ PCIDevice *d = pci_find_device(pcibus, slot, 0);
+ int class_code;
+
+ if (!d) {
+ term_printf("invalid slot %d\n", slot);
+ return;
+ }
+
+ 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;
+ }
+
+ pci_unregister_device(d);
+}
+
Index: trunk/hw/pci.h
===================================================================
--- trunk.orig/hw/pci.h
+++ trunk/hw/pci.h
@@ -14,6 +14,9 @@ extern target_phys_addr_t pci_mem_base;
/* Device classes and subclasses */
+#define PCI_BASE_CLASS_STORAGE 0x01
+#define PCI_BASE_CLASS_NETWORK 0x02
+
#define PCI_CLASS_STORAGE_SCSI 0x0100
#define PCI_CLASS_STORAGE_IDE 0x0101
#define PCI_CLASS_STORAGE_OTHER 0x0180
--
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] Re: [patch 19/19] qemu: PCI device, disk and host network hot-add / hot-remove
2009-02-10 20:31 ` [Qemu-devel] [patch 19/19] qemu: PCI device, disk and host network hot-add / hot-remove Marcelo Tosatti
@ 2009-02-11 2:26 ` Anthony Liguori
2009-02-11 15:00 ` Marcelo Tosatti
0 siblings, 1 reply; 25+ messages in thread
From: Anthony Liguori @ 2009-02-11 2:26 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: qemu-devel
Marcelo Tosatti wrote:
> Index: trunk/hw/pci-hotplug.c
> ===================================================================
> --- /dev/null
> +++ trunk/hw/pci-hotplug.c
>
New files need copyright/license at the top. Feel free to just resend
this patch or even a patch on top of this one.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [patch 00/19] acpi pci hotplug
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (18 preceding siblings ...)
2009-02-10 20:31 ` [Qemu-devel] [patch 19/19] qemu: PCI device, disk and host network hot-add / hot-remove Marcelo Tosatti
@ 2009-02-11 12:42 ` Markus Armbruster
2009-02-11 15:19 ` [Qemu-devel] " Anthony Liguori
20 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2009-02-11 12:42 UTC (permalink / raw)
To: qemu-devel
Marcelo Tosatti <mtosatti@redhat.com> writes:
> ACPI PCI hotplug, hopefully addressing all comments.
Sure addresses mine. Thanks!
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] Re: [patch 19/19] qemu: PCI device, disk and host network hot-add / hot-remove
2009-02-11 2:26 ` [Qemu-devel] " Anthony Liguori
@ 2009-02-11 15:00 ` Marcelo Tosatti
2009-02-11 15:32 ` Avi Kivity
0 siblings, 1 reply; 25+ messages in thread
From: Marcelo Tosatti @ 2009-02-11 15:00 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On Tue, Feb 10, 2009 at 08:26:08PM -0600, Anthony Liguori wrote:
> Marcelo Tosatti wrote:
>> Index: trunk/hw/pci-hotplug.c
>> ===================================================================
>> --- /dev/null
>> +++ trunk/hw/pci-hotplug.c
>>
>
> New files need copyright/license at the top. Feel free to just resend
> this patch or even a patch on top of this one.
>
> Regards,
>
> Anthony Liguori
There you go
Index: trunk/hw/device-hotplug.c
===================================================================
--- trunk.orig/hw/device-hotplug.c
+++ trunk/hw/device-hotplug.c
@@ -1,3 +1,27 @@
+/*
+ * QEMU device hotplug helpers
+ *
+ * Copyright (c) 2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
#include "hw.h"
#include "boards.h"
#include "net.h"
Index: trunk/hw/pci-hotplug.c
===================================================================
--- trunk.orig/hw/pci-hotplug.c
+++ trunk/hw/pci-hotplug.c
@@ -1,3 +1,27 @@
+/*
+ * QEMU PCI hotplug support
+ *
+ * Copyright (c) 2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
#include "hw.h"
#include "boards.h"
#include "pci.h"
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] Re: [patch 00/19] acpi pci hotplug
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
` (19 preceding siblings ...)
2009-02-11 12:42 ` [Qemu-devel] [patch 00/19] acpi pci hotplug Markus Armbruster
@ 2009-02-11 15:19 ` Anthony Liguori
20 siblings, 0 replies; 25+ messages in thread
From: Anthony Liguori @ 2009-02-11 15:19 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: qemu-devel
Marcelo Tosatti wrote:
> ACPI PCI hotplug, hopefully addressing all comments.
>
Applied all. Thanks.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] Re: [patch 19/19] qemu: PCI device, disk and host network hot-add / hot-remove
2009-02-11 15:00 ` Marcelo Tosatti
@ 2009-02-11 15:32 ` Avi Kivity
0 siblings, 0 replies; 25+ messages in thread
From: Avi Kivity @ 2009-02-11 15:32 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori
Marcelo Tosatti wrote:
> Index: trunk/hw/device-hotplug.c
> ===================================================================
> --- trunk.orig/hw/device-hotplug.c
> +++ trunk/hw/device-hotplug.c
> @@ -1,3 +1,27 @@
> +/*
> + * QEMU device hotplug helpers
> + *
> + * Copyright (c) 2004 Fabrice Bellard
> + *
>
Surely, 2008-2009 Red Hat, Inc?
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2009-02-11 15:32 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-10 20:30 [Qemu-devel] [patch 00/19] acpi pci hotplug Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 01/19] qemu: add pci helper functions Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 02/19] qemu: return PCIDevice on net device init and record devfn Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 03/19] qemu: dynamic drive/drive_opt index allocation Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 04/19] qemu: dynamic nic info " Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 05/19] qemu: drive removal support Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 06/19] qemu: record devfn on block driver instance Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 07/19] qemu: move drives_opt for external use Marcelo Tosatti
2009-02-10 20:30 ` [Qemu-devel] [patch 08/19] qemu: net/drive add/remove tweaks Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 09/19] qemu: add net_client_uninit / qemu_find_vlan_client Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 10/19] qemu: add cpu_unregister_io_memory and make io mem table index dynamic Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 11/19] qemu: add qemu_free_irqs Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 12/19] qemu: add pci_unregister_device Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 13/19] qemu: warn if PCI region is not power of two Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 14/19] qemu: LSI SCSI and e1000 unregister callbacks Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 15/19] qemu: zero ioport_opaque on isa_unassign_ioport Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 16/19] qemu: initialize hot add system / acpi gpe Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 17/19] qemu: pci hotplug GPE support Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 18/19] From: Markus Armbruster <armbru@pond.sub.org> Marcelo Tosatti
2009-02-10 20:31 ` [Qemu-devel] [patch 19/19] qemu: PCI device, disk and host network hot-add / hot-remove Marcelo Tosatti
2009-02-11 2:26 ` [Qemu-devel] " Anthony Liguori
2009-02-11 15:00 ` Marcelo Tosatti
2009-02-11 15:32 ` Avi Kivity
2009-02-11 12:42 ` [Qemu-devel] [patch 00/19] acpi pci hotplug Markus Armbruster
2009-02-11 15:19 ` [Qemu-devel] " Anthony Liguori
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.