static int spapr_vio_busdev_init(DeviceState *qdev) { VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); uint32_t liobn; char *id; if (dev->reg != -1) { /* * Explicitly assigned address, just verify that no-one else * is using it. other mechanism). We have to open code this * rather than using spapr_vio_find_by_reg() because sdev * itself is already in the list. */ VIOsPAPRDevice *other = reg_conflict(dev); if (other) { fprintf(stderr, "vio: %s and %s devices conflict at address %#x\n", object_get_typename(OBJECT(qdev)), object_get_typename(OBJECT(&other->qdev)), dev->reg); return -1; } } else { /* Need to assign an address */ VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus); do { dev->reg = bus->next_reg++; } while (reg_conflict(dev)); } /* Don't overwrite ids assigned on the command line */ if (!dev->qdev.id) { id = vio_format_dev_name(dev); if (!id) { return -1; } dev->qdev.id = id; } dev->qirq = spapr_allocate_msi(dev->vio_irq_num, &dev->vio_irq_num); if (!dev->qirq) { return -1; } liobn = SPAPR_VIO_BASE_LIOBN | dev->reg; dev->dma = spapr_tce_new_dma_context(liobn, pc->rtce_window_size); return pc->init(dev); }