13cbee15bSj_mayer /* 23cbee15bSj_mayer * PowerMac MacIO device emulation 33cbee15bSj_mayer * 43cbee15bSj_mayer * Copyright (c) 2005-2007 Fabrice Bellard 53cbee15bSj_mayer * Copyright (c) 2007 Jocelyn Mayer 63cbee15bSj_mayer * 73cbee15bSj_mayer * Permission is hereby granted, free of charge, to any person obtaining a copy 83cbee15bSj_mayer * of this software and associated documentation files (the "Software"), to deal 93cbee15bSj_mayer * in the Software without restriction, including without limitation the rights 103cbee15bSj_mayer * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 113cbee15bSj_mayer * copies of the Software, and to permit persons to whom the Software is 123cbee15bSj_mayer * furnished to do so, subject to the following conditions: 133cbee15bSj_mayer * 143cbee15bSj_mayer * The above copyright notice and this permission notice shall be included in 153cbee15bSj_mayer * all copies or substantial portions of the Software. 163cbee15bSj_mayer * 173cbee15bSj_mayer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 183cbee15bSj_mayer * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 193cbee15bSj_mayer * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 203cbee15bSj_mayer * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 213cbee15bSj_mayer * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 223cbee15bSj_mayer * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 233cbee15bSj_mayer * THE SOFTWARE. 243cbee15bSj_mayer */ 2583c9f4caSPaolo Bonzini #include "hw/hw.h" 2683c9f4caSPaolo Bonzini #include "hw/ppc/mac.h" 2783c9f4caSPaolo Bonzini #include "hw/pci/pci.h" 280d09e41aSPaolo Bonzini #include "hw/ppc/mac_dbdma.h" 290d09e41aSPaolo Bonzini #include "hw/char/escc.h" 303cbee15bSj_mayer 31fcf1bbabSAndreas Färber #define TYPE_MACIO "macio" 32fcf1bbabSAndreas Färber #define MACIO(obj) OBJECT_CHECK(MacIOState, (obj), TYPE_MACIO) 33fcf1bbabSAndreas Färber 34d8c51b05SAnthony Liguori typedef struct MacIOState 35d8c51b05SAnthony Liguori { 36fcf1bbabSAndreas Färber /*< private >*/ 37d8c51b05SAnthony Liguori PCIDevice parent; 38fcf1bbabSAndreas Färber /*< public >*/ 39fcf1bbabSAndreas Färber 4023c5e4caSAvi Kivity MemoryRegion bar; 4145fa67fbSAndreas Färber CUDAState cuda; 4207a7484eSAndreas Färber void *dbdma; 4323c5e4caSAvi Kivity MemoryRegion *pic_mem; 4423c5e4caSAvi Kivity MemoryRegion *escc_mem; 45d8c51b05SAnthony Liguori } MacIOState; 463cbee15bSj_mayer 4795ed3b7cSAndreas Färber #define OLDWORLD_MACIO(obj) \ 4895ed3b7cSAndreas Färber OBJECT_CHECK(OldWorldMacIOState, (obj), TYPE_OLDWORLD_MACIO) 4995ed3b7cSAndreas Färber 5095ed3b7cSAndreas Färber typedef struct OldWorldMacIOState { 5195ed3b7cSAndreas Färber /*< private >*/ 5295ed3b7cSAndreas Färber MacIOState parent_obj; 5395ed3b7cSAndreas Färber /*< public >*/ 5495ed3b7cSAndreas Färber 5545fa67fbSAndreas Färber qemu_irq irqs[3]; 5607a7484eSAndreas Färber 5795ed3b7cSAndreas Färber MacIONVRAMState nvram; 5807a7484eSAndreas Färber MACIOIDEState ide; 5995ed3b7cSAndreas Färber } OldWorldMacIOState; 6095ed3b7cSAndreas Färber 6107a7484eSAndreas Färber #define NEWWORLD_MACIO(obj) \ 6207a7484eSAndreas Färber OBJECT_CHECK(NewWorldMacIOState, (obj), TYPE_NEWWORLD_MACIO) 6307a7484eSAndreas Färber 6407a7484eSAndreas Färber typedef struct NewWorldMacIOState { 6507a7484eSAndreas Färber /*< private >*/ 6607a7484eSAndreas Färber MacIOState parent_obj; 6707a7484eSAndreas Färber /*< public >*/ 6845fa67fbSAndreas Färber qemu_irq irqs[5]; 6907a7484eSAndreas Färber MACIOIDEState ide[2]; 7007a7484eSAndreas Färber } NewWorldMacIOState; 7107a7484eSAndreas Färber 72*0d54a502SAlexander Graf /* 73*0d54a502SAlexander Graf * The mac-io has two interfaces to the ESCC. One is called "escc-legacy", 74*0d54a502SAlexander Graf * while the other one is the normal, current ESCC interface. 75*0d54a502SAlexander Graf * 76*0d54a502SAlexander Graf * The magic below creates memory aliases to spawn the escc-legacy device 77*0d54a502SAlexander Graf * purely by rerouting the respective registers to our escc region. This 78*0d54a502SAlexander Graf * works because the only difference between the two memory regions is the 79*0d54a502SAlexander Graf * register layout, not their semantics. 80*0d54a502SAlexander Graf * 81*0d54a502SAlexander Graf * Reference: ftp://ftp.software.ibm.com/rs6000/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf 82*0d54a502SAlexander Graf */ 83*0d54a502SAlexander Graf static void macio_escc_legacy_setup(MacIOState *macio_state) 84*0d54a502SAlexander Graf { 85*0d54a502SAlexander Graf MemoryRegion *escc_legacy = g_new(MemoryRegion, 1); 86*0d54a502SAlexander Graf MemoryRegion *bar = &macio_state->bar; 87*0d54a502SAlexander Graf int i; 88*0d54a502SAlexander Graf static const int maps[] = { 89*0d54a502SAlexander Graf 0x00, 0x00, 90*0d54a502SAlexander Graf 0x02, 0x20, 91*0d54a502SAlexander Graf 0x04, 0x10, 92*0d54a502SAlexander Graf 0x06, 0x30, 93*0d54a502SAlexander Graf 0x08, 0x40, 94*0d54a502SAlexander Graf 0x0A, 0x50, 95*0d54a502SAlexander Graf 0x60, 0x60, 96*0d54a502SAlexander Graf 0x70, 0x70, 97*0d54a502SAlexander Graf 0x80, 0x70, 98*0d54a502SAlexander Graf 0x90, 0x80, 99*0d54a502SAlexander Graf 0xA0, 0x90, 100*0d54a502SAlexander Graf 0xB0, 0xA0, 101*0d54a502SAlexander Graf 0xC0, 0xB0, 102*0d54a502SAlexander Graf 0xD0, 0xC0, 103*0d54a502SAlexander Graf 0xE0, 0xD0, 104*0d54a502SAlexander Graf 0xF0, 0xE0, 105*0d54a502SAlexander Graf }; 106*0d54a502SAlexander Graf 107*0d54a502SAlexander Graf memory_region_init(escc_legacy, "escc-legacy", 256); 108*0d54a502SAlexander Graf for (i = 0; i < ARRAY_SIZE(maps); i += 2) { 109*0d54a502SAlexander Graf MemoryRegion *port = g_new(MemoryRegion, 1); 110*0d54a502SAlexander Graf memory_region_init_alias(port, "escc-legacy-port", macio_state->escc_mem, 111*0d54a502SAlexander Graf maps[i+1], 0x2); 112*0d54a502SAlexander Graf memory_region_add_subregion(escc_legacy, maps[i], port); 113*0d54a502SAlexander Graf } 114*0d54a502SAlexander Graf 115*0d54a502SAlexander Graf memory_region_add_subregion(bar, 0x12000, escc_legacy); 116*0d54a502SAlexander Graf } 117*0d54a502SAlexander Graf 118d8c51b05SAnthony Liguori static void macio_bar_setup(MacIOState *macio_state) 1193cbee15bSj_mayer { 12023c5e4caSAvi Kivity MemoryRegion *bar = &macio_state->bar; 1213cbee15bSj_mayer 12223c5e4caSAvi Kivity if (macio_state->escc_mem) { 12323c5e4caSAvi Kivity memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem); 124*0d54a502SAlexander Graf macio_escc_legacy_setup(macio_state); 1257fa9ae1aSblueswir1 } 1263cbee15bSj_mayer } 1273cbee15bSj_mayer 128d037834aSAndreas Färber static int macio_common_initfn(PCIDevice *d) 129d8c51b05SAnthony Liguori { 1307b925079SAndreas Färber MacIOState *s = MACIO(d); 13145fa67fbSAndreas Färber SysBusDevice *sysbus_dev; 13245fa67fbSAndreas Färber int ret; 1337b925079SAndreas Färber 134d8c51b05SAnthony Liguori d->config[0x3d] = 0x01; // interrupt on pin 1 1357b925079SAndreas Färber 13645fa67fbSAndreas Färber ret = qdev_init(DEVICE(&s->cuda)); 13745fa67fbSAndreas Färber if (ret < 0) { 13845fa67fbSAndreas Färber return ret; 13945fa67fbSAndreas Färber } 14045fa67fbSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 14145fa67fbSAndreas Färber memory_region_add_subregion(&s->bar, 0x16000, 14245fa67fbSAndreas Färber sysbus_mmio_get_region(sysbus_dev, 0)); 14345fa67fbSAndreas Färber 1447b925079SAndreas Färber macio_bar_setup(s); 1457b925079SAndreas Färber pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); 1467b925079SAndreas Färber 147d8c51b05SAnthony Liguori return 0; 148d8c51b05SAnthony Liguori } 149d8c51b05SAnthony Liguori 150d037834aSAndreas Färber static int macio_oldworld_initfn(PCIDevice *d) 151d037834aSAndreas Färber { 152d037834aSAndreas Färber MacIOState *s = MACIO(d); 15395ed3b7cSAndreas Färber OldWorldMacIOState *os = OLDWORLD_MACIO(d); 15495ed3b7cSAndreas Färber SysBusDevice *sysbus_dev; 155d037834aSAndreas Färber int ret = macio_common_initfn(d); 156d037834aSAndreas Färber if (ret < 0) { 157d037834aSAndreas Färber return ret; 158d037834aSAndreas Färber } 159d037834aSAndreas Färber 16045fa67fbSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 16145fa67fbSAndreas Färber sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]); 16245fa67fbSAndreas Färber 16395ed3b7cSAndreas Färber ret = qdev_init(DEVICE(&os->nvram)); 16495ed3b7cSAndreas Färber if (ret < 0) { 16595ed3b7cSAndreas Färber return ret; 16695ed3b7cSAndreas Färber } 16795ed3b7cSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&os->nvram); 16895ed3b7cSAndreas Färber memory_region_add_subregion(&s->bar, 0x60000, 16995ed3b7cSAndreas Färber sysbus_mmio_get_region(sysbus_dev, 0)); 17095ed3b7cSAndreas Färber pmac_format_nvram_partition(&os->nvram, os->nvram.size); 17195ed3b7cSAndreas Färber 172d037834aSAndreas Färber if (s->pic_mem) { 173d037834aSAndreas Färber /* Heathrow PIC */ 174d037834aSAndreas Färber memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem); 175d037834aSAndreas Färber } 176d037834aSAndreas Färber 17707a7484eSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&os->ide); 17845fa67fbSAndreas Färber sysbus_connect_irq(sysbus_dev, 0, os->irqs[1]); 17945fa67fbSAndreas Färber sysbus_connect_irq(sysbus_dev, 1, os->irqs[2]); 18007a7484eSAndreas Färber macio_ide_register_dma(&os->ide, s->dbdma, 0x16); 18107a7484eSAndreas Färber ret = qdev_init(DEVICE(&os->ide)); 18207a7484eSAndreas Färber if (ret < 0) { 18307a7484eSAndreas Färber return ret; 18407a7484eSAndreas Färber } 18507a7484eSAndreas Färber 186d037834aSAndreas Färber return 0; 187d037834aSAndreas Färber } 188d037834aSAndreas Färber 18995ed3b7cSAndreas Färber static void macio_oldworld_init(Object *obj) 19095ed3b7cSAndreas Färber { 19107a7484eSAndreas Färber MacIOState *s = MACIO(obj); 19295ed3b7cSAndreas Färber OldWorldMacIOState *os = OLDWORLD_MACIO(obj); 19395ed3b7cSAndreas Färber DeviceState *dev; 19495ed3b7cSAndreas Färber 19507a7484eSAndreas Färber qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs)); 19607a7484eSAndreas Färber 19795ed3b7cSAndreas Färber object_initialize(&os->nvram, TYPE_MACIO_NVRAM); 19895ed3b7cSAndreas Färber dev = DEVICE(&os->nvram); 19995ed3b7cSAndreas Färber qdev_prop_set_uint32(dev, "size", 0x2000); 20095ed3b7cSAndreas Färber qdev_prop_set_uint32(dev, "it_shift", 4); 20107a7484eSAndreas Färber 20207a7484eSAndreas Färber object_initialize(&os->ide, TYPE_MACIO_IDE); 20307a7484eSAndreas Färber qdev_set_parent_bus(DEVICE(&os->ide), sysbus_get_default()); 20407a7484eSAndreas Färber memory_region_add_subregion(&s->bar, 0x1f000 + (1 * 0x1000), &os->ide.mem); 20507a7484eSAndreas Färber object_property_add_child(obj, "ide", OBJECT(&os->ide), NULL); 20695ed3b7cSAndreas Färber } 20795ed3b7cSAndreas Färber 208d037834aSAndreas Färber static int macio_newworld_initfn(PCIDevice *d) 209d037834aSAndreas Färber { 210d037834aSAndreas Färber MacIOState *s = MACIO(d); 21107a7484eSAndreas Färber NewWorldMacIOState *ns = NEWWORLD_MACIO(d); 21207a7484eSAndreas Färber SysBusDevice *sysbus_dev; 213d037834aSAndreas Färber int ret = macio_common_initfn(d); 214d037834aSAndreas Färber if (ret < 0) { 215d037834aSAndreas Färber return ret; 216d037834aSAndreas Färber } 217d037834aSAndreas Färber 21845fa67fbSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 21945fa67fbSAndreas Färber sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]); 22045fa67fbSAndreas Färber 221d037834aSAndreas Färber if (s->pic_mem) { 222d037834aSAndreas Färber /* OpenPIC */ 223d037834aSAndreas Färber memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem); 224d037834aSAndreas Färber } 225d037834aSAndreas Färber 22607a7484eSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&ns->ide[0]); 22745fa67fbSAndreas Färber sysbus_connect_irq(sysbus_dev, 0, ns->irqs[1]); 22845fa67fbSAndreas Färber sysbus_connect_irq(sysbus_dev, 1, ns->irqs[2]); 22907a7484eSAndreas Färber macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x16); 23007a7484eSAndreas Färber ret = qdev_init(DEVICE(&ns->ide[0])); 23107a7484eSAndreas Färber if (ret < 0) { 23207a7484eSAndreas Färber return ret; 23307a7484eSAndreas Färber } 23407a7484eSAndreas Färber 23507a7484eSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&ns->ide[1]); 23645fa67fbSAndreas Färber sysbus_connect_irq(sysbus_dev, 0, ns->irqs[3]); 23745fa67fbSAndreas Färber sysbus_connect_irq(sysbus_dev, 1, ns->irqs[4]); 23802d583c7SMark Cave-Ayland macio_ide_register_dma(&ns->ide[1], s->dbdma, 0x1a); 23907a7484eSAndreas Färber ret = qdev_init(DEVICE(&ns->ide[1])); 24007a7484eSAndreas Färber if (ret < 0) { 24107a7484eSAndreas Färber return ret; 24207a7484eSAndreas Färber } 24307a7484eSAndreas Färber 244d037834aSAndreas Färber return 0; 245d037834aSAndreas Färber } 246d037834aSAndreas Färber 24707a7484eSAndreas Färber static void macio_newworld_init(Object *obj) 24807a7484eSAndreas Färber { 24907a7484eSAndreas Färber MacIOState *s = MACIO(obj); 25007a7484eSAndreas Färber NewWorldMacIOState *ns = NEWWORLD_MACIO(obj); 25107a7484eSAndreas Färber int i; 25207a7484eSAndreas Färber gchar *name; 25307a7484eSAndreas Färber 25407a7484eSAndreas Färber qdev_init_gpio_out(DEVICE(obj), ns->irqs, ARRAY_SIZE(ns->irqs)); 25507a7484eSAndreas Färber 25607a7484eSAndreas Färber for (i = 0; i < 2; i++) { 25707a7484eSAndreas Färber object_initialize(&ns->ide[i], TYPE_MACIO_IDE); 25807a7484eSAndreas Färber qdev_set_parent_bus(DEVICE(&ns->ide[i]), sysbus_get_default()); 25907a7484eSAndreas Färber memory_region_add_subregion(&s->bar, 0x1f000 + ((i + 1) * 0x1000), 26007a7484eSAndreas Färber &ns->ide[i].mem); 26107a7484eSAndreas Färber name = g_strdup_printf("ide[%i]", i); 26207a7484eSAndreas Färber object_property_add_child(obj, name, OBJECT(&ns->ide[i]), NULL); 26307a7484eSAndreas Färber g_free(name); 26407a7484eSAndreas Färber } 26507a7484eSAndreas Färber } 26607a7484eSAndreas Färber 267fcf1bbabSAndreas Färber static void macio_instance_init(Object *obj) 268fcf1bbabSAndreas Färber { 269fcf1bbabSAndreas Färber MacIOState *s = MACIO(obj); 27007a7484eSAndreas Färber MemoryRegion *dbdma_mem; 271fcf1bbabSAndreas Färber 272fcf1bbabSAndreas Färber memory_region_init(&s->bar, "macio", 0x80000); 27307a7484eSAndreas Färber 27445fa67fbSAndreas Färber object_initialize(&s->cuda, TYPE_CUDA); 27545fa67fbSAndreas Färber qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default()); 27645fa67fbSAndreas Färber object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL); 27745fa67fbSAndreas Färber 27807a7484eSAndreas Färber s->dbdma = DBDMA_init(&dbdma_mem); 27907a7484eSAndreas Färber memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem); 280fcf1bbabSAndreas Färber } 281fcf1bbabSAndreas Färber 282d037834aSAndreas Färber static void macio_oldworld_class_init(ObjectClass *oc, void *data) 283d037834aSAndreas Färber { 284d037834aSAndreas Färber PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); 285d037834aSAndreas Färber 286d037834aSAndreas Färber pdc->init = macio_oldworld_initfn; 287d037834aSAndreas Färber pdc->device_id = PCI_DEVICE_ID_APPLE_343S1201; 288d037834aSAndreas Färber } 289d037834aSAndreas Färber 290d037834aSAndreas Färber static void macio_newworld_class_init(ObjectClass *oc, void *data) 291d037834aSAndreas Färber { 292d037834aSAndreas Färber PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); 293d037834aSAndreas Färber 294d037834aSAndreas Färber pdc->init = macio_newworld_initfn; 295d037834aSAndreas Färber pdc->device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL; 296d037834aSAndreas Färber } 297d037834aSAndreas Färber 29840021f08SAnthony Liguori static void macio_class_init(ObjectClass *klass, void *data) 29940021f08SAnthony Liguori { 30040021f08SAnthony Liguori PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 30140021f08SAnthony Liguori 30240021f08SAnthony Liguori k->vendor_id = PCI_VENDOR_ID_APPLE; 30340021f08SAnthony Liguori k->class_id = PCI_CLASS_OTHERS << 8; 30440021f08SAnthony Liguori } 30540021f08SAnthony Liguori 306d037834aSAndreas Färber static const TypeInfo macio_oldworld_type_info = { 307d037834aSAndreas Färber .name = TYPE_OLDWORLD_MACIO, 308d037834aSAndreas Färber .parent = TYPE_MACIO, 30995ed3b7cSAndreas Färber .instance_size = sizeof(OldWorldMacIOState), 31095ed3b7cSAndreas Färber .instance_init = macio_oldworld_init, 311d037834aSAndreas Färber .class_init = macio_oldworld_class_init, 312d037834aSAndreas Färber }; 313d037834aSAndreas Färber 314d037834aSAndreas Färber static const TypeInfo macio_newworld_type_info = { 315d037834aSAndreas Färber .name = TYPE_NEWWORLD_MACIO, 316d037834aSAndreas Färber .parent = TYPE_MACIO, 31707a7484eSAndreas Färber .instance_size = sizeof(NewWorldMacIOState), 31807a7484eSAndreas Färber .instance_init = macio_newworld_init, 319d037834aSAndreas Färber .class_init = macio_newworld_class_init, 320d037834aSAndreas Färber }; 321d037834aSAndreas Färber 322fcf1bbabSAndreas Färber static const TypeInfo macio_type_info = { 323fcf1bbabSAndreas Färber .name = TYPE_MACIO, 32439bffca2SAnthony Liguori .parent = TYPE_PCI_DEVICE, 32539bffca2SAnthony Liguori .instance_size = sizeof(MacIOState), 326fcf1bbabSAndreas Färber .instance_init = macio_instance_init, 327d037834aSAndreas Färber .abstract = true, 32840021f08SAnthony Liguori .class_init = macio_class_init, 329d8c51b05SAnthony Liguori }; 330d8c51b05SAnthony Liguori 33183f7d43aSAndreas Färber static void macio_register_types(void) 332d8c51b05SAnthony Liguori { 333fcf1bbabSAndreas Färber type_register_static(&macio_type_info); 334d037834aSAndreas Färber type_register_static(&macio_oldworld_type_info); 335d037834aSAndreas Färber type_register_static(&macio_newworld_type_info); 336d8c51b05SAnthony Liguori } 337d8c51b05SAnthony Liguori 33883f7d43aSAndreas Färber type_init(macio_register_types) 339d8c51b05SAnthony Liguori 340d037834aSAndreas Färber void macio_init(PCIDevice *d, 34107a7484eSAndreas Färber MemoryRegion *pic_mem, 34223c5e4caSAvi Kivity MemoryRegion *escc_mem) 3433cbee15bSj_mayer { 344d037834aSAndreas Färber MacIOState *macio_state = MACIO(d); 3453cbee15bSj_mayer 34623c5e4caSAvi Kivity macio_state->pic_mem = pic_mem; 34723c5e4caSAvi Kivity macio_state->escc_mem = escc_mem; 3483cbee15bSj_mayer /* Note: this code is strongly inspirated from the corresponding code 3493cbee15bSj_mayer in PearPC */ 350deb54399Saliguori 3517b925079SAndreas Färber qdev_init_nofail(DEVICE(d)); 3523cbee15bSj_mayer } 353