1 /* 2 * QEMU USB OHCI Emulation 3 * Copyright (c) 2006 Openedhand Ltd. 4 * Copyright (c) 2010 CodeSourcery 5 * Copyright (c) 2024 Red Hat, Inc. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "hw/irq.h" 23 #include "qapi/error.h" 24 #include "qemu/module.h" 25 #include "qemu/timer.h" 26 #include "hw/usb.h" 27 #include "migration/vmstate.h" 28 #include "hw/sysbus.h" 29 #include "hw/qdev-dma.h" 30 #include "hw/qdev-properties.h" 31 #include "trace.h" 32 #include "hcd-ohci.h" 33 34 35 static void ohci_sysbus_realize(DeviceState *dev, Error **errp) 36 { 37 OHCISysBusState *s = SYSBUS_OHCI(dev); 38 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 39 Error *err = NULL; 40 41 usb_ohci_init(&s->ohci, dev, s->num_ports, s->dma_offset, 42 s->masterbus, s->firstport, 43 &address_space_memory, ohci_sysbus_die, &err); 44 if (err) { 45 error_propagate(errp, err); 46 return; 47 } 48 sysbus_init_irq(sbd, &s->ohci.irq); 49 sysbus_init_mmio(sbd, &s->ohci.mem); 50 } 51 52 static void ohci_sysbus_reset(DeviceState *dev) 53 { 54 OHCISysBusState *s = SYSBUS_OHCI(dev); 55 OHCIState *ohci = &s->ohci; 56 57 ohci_hard_reset(ohci); 58 } 59 60 static Property ohci_sysbus_properties[] = { 61 DEFINE_PROP_STRING("masterbus", OHCISysBusState, masterbus), 62 DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3), 63 DEFINE_PROP_UINT32("firstport", OHCISysBusState, firstport, 0), 64 DEFINE_PROP_DMAADDR("dma-offset", OHCISysBusState, dma_offset, 0), 65 DEFINE_PROP_END_OF_LIST(), 66 }; 67 68 static void ohci_sysbus_class_init(ObjectClass *klass, void *data) 69 { 70 DeviceClass *dc = DEVICE_CLASS(klass); 71 72 dc->realize = ohci_sysbus_realize; 73 set_bit(DEVICE_CATEGORY_USB, dc->categories); 74 dc->desc = "OHCI USB Controller"; 75 device_class_set_props(dc, ohci_sysbus_properties); 76 device_class_set_legacy_reset(dc, ohci_sysbus_reset); 77 } 78 79 static const TypeInfo ohci_sysbus_types[] = { 80 { 81 .name = TYPE_SYSBUS_OHCI, 82 .parent = TYPE_SYS_BUS_DEVICE, 83 .instance_size = sizeof(OHCISysBusState), 84 .class_init = ohci_sysbus_class_init, 85 }, 86 }; 87 88 DEFINE_TYPES(ohci_sysbus_types); 89