Right now the spapr devices cannot be instantiated with -device, because the IRQs need to be passed to the spapr_*_create functions. Do this instead in the bus's init wrapper.
This is particularly important with the conversion from scsi-disk to scsi-{cd,hd} that Markus made. After his patches, if you specify a scsi-cd device attached to an if=none drive, the default VSCSI controller will not be created and, without qdevification, you will not be able to add yours. Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- hw/spapr.c | 16 ++++++---------- hw/spapr.h | 6 ++++++ hw/spapr_llan.c | 7 +------ hw/spapr_vio.c | 3 +++ hw/spapr_vio.h | 13 ++++--------- hw/spapr_vscsi.c | 8 +------- hw/spapr_vty.c | 8 +------- 7 files changed, 22 insertions(+), 39 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index 109b774..575dcaf 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -298,7 +298,6 @@ static void ppc_spapr_init(ram_addr_t ram_size, long kernel_size, initrd_size, fw_size; long pteg_shift = 17; char *filename; - int irq = 16; spapr = qemu_malloc(sizeof(*spapr)); cpu_ppc_hypercall = emulate_spapr_hypercall; @@ -308,6 +307,7 @@ static void ppc_spapr_init(ram_addr_t ram_size, * necessary */ spapr->fdt_addr = MIN(ram_size, 0x80000000) - FDT_MAX_SIZE; spapr->rtas_addr = spapr->fdt_addr - RTAS_MAX_SIZE; + spapr->next_irq = 16; /* init CPUs */ if (cpu_model == NULL) { @@ -360,15 +360,14 @@ static void ppc_spapr_init(ram_addr_t ram_size, /* Set up VIO bus */ spapr->vio_bus = spapr_vio_bus_init(); - for (i = 0; i < MAX_SERIAL_PORTS; i++, irq++) { + for (i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { spapr_vty_create(spapr->vio_bus, SPAPR_VTY_BASE_ADDRESS + i, - serial_hds[i], xics_find_qirq(spapr->icp, irq), - irq); + serial_hds[i]); } } - for (i = 0; i < nb_nics; i++, irq++) { + for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; if (!nd->model) { @@ -376,8 +375,7 @@ static void ppc_spapr_init(ram_addr_t ram_size, } if (strcmp(nd->model, "ibmveth") == 0) { - spapr_vlan_create(spapr->vio_bus, 0x1000 + i, nd, - xics_find_qirq(spapr->icp, irq), irq); + spapr_vlan_create(spapr->vio_bus, 0x1000 + i, nd); } else { fprintf(stderr, "pSeries (sPAPR) platform does not support " "NIC model '%s' (only ibmveth is supported)\n", @@ -387,9 +385,7 @@ static void ppc_spapr_init(ram_addr_t ram_size, } for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) { - spapr_vscsi_create(spapr->vio_bus, 0x2000 + i, - xics_find_qirq(spapr->icp, irq), irq); - irq++; + spapr_vscsi_create(spapr->vio_bus, 0x2000 + i); } if (kernel_filename) { diff --git a/hw/spapr.h b/hw/spapr.h index b52133a..eb9e5a9 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -8,6 +8,7 @@ typedef struct sPAPREnvironment { struct VIOsPAPRBus *vio_bus; struct icp_state *icp; + int next_irq; void *htab; long htab_size; target_phys_addr_t fdt_addr, rtas_addr; @@ -278,6 +279,11 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(CPUState *env, target_ulong opcode, target_ulong *args); +static inline int spapr_allocate_irq(sPAPREnvironment *spapr) +{ + return spapr->next_irq++; +} + static inline uint32_t rtas_ld(target_ulong phys, int n) { return ldl_phys(phys + 4*n); diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c index c18efc7..2597748 100644 --- a/hw/spapr_llan.c +++ b/hw/spapr_llan.c @@ -195,11 +195,9 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev) return 0; } -void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd, - qemu_irq qirq, uint32_t vio_irq_num) +void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd) { DeviceState *dev; - VIOsPAPRDevice *sdev; dev = qdev_create(&bus->bus, "spapr-vlan"); qdev_prop_set_uint32(dev, "reg", reg); @@ -207,9 +205,6 @@ void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd, qdev_set_nic_properties(dev, nd); qdev_init_nofail(dev); - sdev = (VIOsPAPRDevice *)dev; - sdev->qirq = qirq; - sdev->vio_irq_num = vio_irq_num; } static int spapr_vlan_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off) diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c index 481a804..6f34159 100644 --- a/hw/spapr_vio.c +++ b/hw/spapr_vio.c @@ -32,6 +32,7 @@ #include "hw/spapr.h" #include "hw/spapr_vio.h" +#include "hw/xics.h" #ifdef CONFIG_FDT #include <libfdt.h> @@ -602,6 +603,8 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo) } dev->qdev.id = id; + dev->vio_irq_num = spapr_allocate_irq (spapr); + dev->qirq = xics_find_qirq(spapr->icp, dev->vio_irq_num); rtce_init(dev); diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h index 603a8c4..faa5d94 100644 --- a/hw/spapr_vio.h +++ b/hw/spapr_vio.h @@ -62,6 +62,7 @@ typedef struct VIOsPAPRDevice { typedef struct VIOsPAPRBus { BusState bus; + int irq; } VIOsPAPRBus; typedef struct { @@ -98,15 +99,9 @@ uint64_t ldq_tce(VIOsPAPRDevice *dev, uint64_t taddr); int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq); void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len); -void spapr_vty_create(VIOsPAPRBus *bus, - uint32_t reg, CharDriverState *chardev, - qemu_irq qirq, uint32_t vio_irq_num); - -void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd, - qemu_irq qirq, uint32_t vio_irq_num); - -void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg, - qemu_irq qirq, uint32_t vio_irq_num); +void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev); +void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd); +void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg); int spapr_tce_set_bypass(uint32_t unit, uint32_t enable); void spapr_vio_quiesce(void); diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 1c901ef..99a4b06 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -952,20 +952,14 @@ static int spapr_vscsi_init(VIOsPAPRDevice *dev) return 0; } -void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg, - qemu_irq qirq, uint32_t vio_irq_num) +void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg) { DeviceState *dev; - VIOsPAPRDevice *sdev; dev = qdev_create(&bus->bus, "spapr-vscsi"); qdev_prop_set_uint32(dev, "reg", reg); qdev_init_nofail(dev); - - sdev = (VIOsPAPRDevice *)dev; - sdev->qirq = qirq; - sdev->vio_irq_num = vio_irq_num; } static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off) diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c index 6fc0105..fa97cf7 100644 --- a/hw/spapr_vty.c +++ b/hw/spapr_vty.c @@ -115,20 +115,14 @@ static target_ulong h_get_term_char(CPUState *env, sPAPREnvironment *spapr, return H_SUCCESS; } -void spapr_vty_create(VIOsPAPRBus *bus, - uint32_t reg, CharDriverState *chardev, - qemu_irq qirq, uint32_t vio_irq_num) +void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev) { DeviceState *dev; - VIOsPAPRDevice *sdev; dev = qdev_create(&bus->bus, "spapr-vty"); qdev_prop_set_uint32(dev, "reg", reg); qdev_prop_set_chr(dev, "chardev", chardev); qdev_init_nofail(dev); - sdev = (VIOsPAPRDevice *)dev; - sdev->qirq = qirq; - sdev->vio_irq_num = vio_irq_num; } static void vty_hcalls(VIOsPAPRBus *bus) -- 1.7.4.4