Revision 10c4c98a

b/hw/i2c.c
17 17
    int saved_address;
18 18
};
19 19

  
20
static struct BusInfo i2c_bus_info = {
21
    .name = "I2C",
22
    .size = sizeof(i2c_bus),
23
};
24

  
20 25
static void i2c_bus_save(QEMUFile *f, void *opaque)
21 26
{
22 27
    i2c_bus *bus = (i2c_bus *)opaque;
......
44 49
{
45 50
    i2c_bus *bus;
46 51

  
47
    bus = FROM_QBUS(i2c_bus, qbus_create(BUS_TYPE_I2C, sizeof(i2c_bus),
48
                                         parent, name));
52
    bus = FROM_QBUS(i2c_bus, qbus_create(&i2c_bus_info, parent, name));
49 53
    register_savevm("i2c_bus", -1, 1, i2c_bus_save, i2c_bus_load, bus);
50 54
    return bus;
51 55
}
......
156 160
{
157 161
    assert(info->qdev.size >= sizeof(i2c_slave));
158 162
    info->qdev.init = i2c_slave_qdev_init;
159
    info->qdev.bus_type = BUS_TYPE_I2C;
163
    info->qdev.bus_info = &i2c_bus_info;
160 164
    qdev_register(&info->qdev);
161 165
}
162 166

  
b/hw/pci.c
45 45
    /* The bus IRQ state is the logical OR of the connected devices.
46 46
       Keep a count of the number of devices with raised IRQs.  */
47 47
    int nirq;
48
    int irq_count[];
48
    int *irq_count;
49
};
50

  
51
static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
52

  
53
static struct BusInfo pci_bus_info = {
54
    .name       = "PCI",
55
    .size       = sizeof(PCIBus),
56
    .print_dev  = pcibus_dev_print,
49 57
};
50 58

  
51 59
static void pci_update_mappings(PCIDevice *d);
......
109 117
    PCIBus *bus;
110 118
    static int nbus = 0;
111 119

  
112
    bus = FROM_QBUS(PCIBus, qbus_create(BUS_TYPE_PCI,
113
                                        sizeof(PCIBus) + (nirq * sizeof(int)),
114
                                        parent, name));
120
    bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, parent, name));
115 121
    bus->set_irq = set_irq;
116 122
    bus->map_irq = map_irq;
117 123
    bus->irq_opaque = pic;
118 124
    bus->devfn_min = devfn_min;
119 125
    bus->nirq = nirq;
126
    bus->irq_count = qemu_malloc(nirq * sizeof(bus->irq_count[0]));
120 127
    bus->next = first_bus;
121 128
    first_bus = bus;
122 129
    register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
......
892 899
void pci_qdev_register(PCIDeviceInfo *info)
893 900
{
894 901
    info->qdev.init = pci_qdev_init;
895
    info->qdev.bus_type = BUS_TYPE_PCI;
902
    info->qdev.bus_info = &pci_bus_info;
896 903
    qdev_register(&info->qdev);
897 904
}
898 905

  
......
991 998
{
992 999
    return pci_find_capability_list(pdev, cap_id, NULL);
993 1000
}
1001

  
1002
static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
1003
{
1004
    PCIDevice *d = (PCIDevice *)dev;
1005
    const pci_class_desc *desc;
1006
    char ctxt[64];
1007
    PCIIORegion *r;
1008
    int i, class;
1009

  
1010
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
1011
    desc = pci_class_descriptions;
1012
    while (desc->desc && class != desc->class)
1013
        desc++;
1014
    if (desc->desc) {
1015
        snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
1016
    } else {
1017
        snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
1018
    }
1019

  
1020
    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
1021
                   "pci id %04x:%04x (sub %04x:%04x)\n",
1022
                   indent, "", ctxt,
1023
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7,
1024
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
1025
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))),
1026
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_VENDOR_ID))),
1027
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_ID))));
1028
    for (i = 0; i < PCI_NUM_REGIONS; i++) {
1029
        r = &d->io_regions[i];
1030
        if (!r->size)
1031
            continue;
1032
        monitor_printf(mon, "%*sbar %d: %s at 0x%x [0x%x]\n", indent, "",
1033
                       i, r->type & PCI_ADDRESS_SPACE_IO ? "i/o" : "mem",
1034
                       r->addr, r->addr + r->size - 1);
1035
    }
1036
}
b/hw/qdev.c
48 48

  
49 49
/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
50 50
static BusState *main_system_bus;
51
extern struct BusInfo system_bus_info;
51 52

  
52 53
static DeviceType *device_type_list;
53 54

  
......
72 73
    DeviceType *t;
73 74
    DeviceState *dev;
74 75

  
75
    for (t = device_type_list; t; t = t->next) {
76
        if (strcmp(t->info->name, name) == 0) {
77
            break;
76
    if (!bus) {
77
        if (!main_system_bus) {
78
            main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
78 79
        }
80
        bus = main_system_bus;
81
    }
82

  
83
    for (t = device_type_list; t; t = t->next) {
84
        if (t->info->bus_info != bus->info)
85
            continue;
86
        if (strcmp(t->info->name, name) != 0)
87
            continue;
88
        break;
79 89
    }
80 90
    if (!t) {
81
        hw_error("Unknown device '%s'\n", name);
91
        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
82 92
    }
83 93

  
84 94
    dev = qemu_mallocz(t->info->size);
85 95
    dev->type = t;
86

  
87
    if (!bus) {
88
        /* ???: This assumes system busses have no additional state.  */
89
        if (!main_system_bus) {
90
            main_system_bus = qbus_create(BUS_TYPE_SYSTEM, sizeof(BusState),
91
                                          NULL, "main-system-bus");
92
        }
93
        bus = main_system_bus;
94
    }
95
    if (t->info->bus_type != bus->type) {
96
        /* TODO: Print bus type names.  */
97
        hw_error("Device '%s' on wrong bus type (%d/%d)", name,
98
                 t->info->bus_type, bus->type);
99
    }
100 96
    dev->parent_bus = bus;
101 97
    LIST_INSERT_HEAD(&bus->children, dev, sibling);
102 98
    return dev;
......
320 316
   }
321 317
}
322 318

  
323
BusState *qbus_create(BusType type, size_t size,
324
                      DeviceState *parent, const char *name)
319
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
325 320
{
326 321
    BusState *bus;
327 322

  
328
    bus = qemu_mallocz(size);
329
    bus->type = type;
323
    bus = qemu_mallocz(info->size);
324
    bus->info = info;
330 325
    bus->parent = parent;
331 326
    bus->name = qemu_strdup(name);
332 327
    LIST_INIT(&bus->children);
......
336 331
    return bus;
337 332
}
338 333

  
339
static const char *bus_type_names[] = {
340
    [ BUS_TYPE_SYSTEM ] = "System",
341
    [ BUS_TYPE_PCI ]    = "PCI",
342
    [ BUS_TYPE_SCSI ]   = "SCSI",
343
    [ BUS_TYPE_I2C ]    = "I2C",
344
    [ BUS_TYPE_SSI ]    = "SSI",
345
};
346

  
347 334
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
348 335
static void qbus_print(Monitor *mon, BusState *bus, int indent);
349 336

  
......
377 364
            break;
378 365
        }
379 366
    }
380
    switch (dev->parent_bus->type) {
381
    case BUS_TYPE_SYSTEM:
382
        sysbus_dev_print(mon, dev, indent);
383
        break;
384
    default:
385
        break;
386
    }
367
    if (dev->parent_bus->info->print_dev)
368
        dev->parent_bus->info->print_dev(mon, dev, indent);
387 369
    LIST_FOREACH(child, &dev->child_bus, sibling) {
388 370
        qbus_print(mon, child, indent);
389 371
    }
......
395 377

  
396 378
    qdev_printf("bus: %s\n", bus->name);
397 379
    indent += 2;
398
    qdev_printf("type %s\n", bus_type_names[bus->type]);
380
    qdev_printf("type %s\n", bus->info->name);
399 381
    LIST_FOREACH(dev, &bus->children, sibling) {
400 382
        qdev_print(mon, dev, indent);
401 383
    }
b/hw/qdev.h
10 10

  
11 11
typedef struct BusState BusState;
12 12

  
13
typedef struct BusInfo BusInfo;
14

  
13 15
/* This structure should not be accessed directly.  We declare it here
14 16
   so that it can be embedded in individual device state structures.  */
15 17
struct DeviceState {
......
25 27
    LIST_ENTRY(DeviceState) sibling;
26 28
};
27 29

  
28
typedef enum {
29
    BUS_TYPE_SYSTEM,
30
    BUS_TYPE_PCI,
31
    BUS_TYPE_SCSI,
32
    BUS_TYPE_I2C,
33
    BUS_TYPE_SSI
34
} BusType;
30
typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
31
struct BusInfo {
32
    const char *name;
33
    size_t size;
34
    bus_dev_printfn print_dev;
35
};
35 36

  
36 37
struct BusState {
37 38
    DeviceState *parent;
39
    BusInfo *info;
38 40
    const char *name;
39
    BusType type;
40 41
    LIST_HEAD(, DeviceState) children;
41 42
    LIST_ENTRY(BusState) sibling;
42 43
};
......
84 85

  
85 86
    /* Private to qdev / bus.  */
86 87
    qdev_initfn init;
87
    BusType bus_type;
88
    BusInfo *bus_info;
88 89
};
89 90

  
90 91
void qdev_register(DeviceInfo *info);
......
116 117

  
117 118
/*** BUS API. ***/
118 119

  
119
BusState *qbus_create(BusType type, size_t size,
120
                      DeviceState *parent, const char *name);
120
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
121 121

  
122 122
#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
123 123

  
124 124
/*** monitor commands ***/
125 125

  
126 126
void do_info_qtree(Monitor *mon);
127
void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
128 127

  
129 128
#endif
b/hw/ssi.c
13 13
    BusState qbus;
14 14
};
15 15

  
16
static struct BusInfo ssi_bus_info = {
17
    .name = "SSI",
18
    .size = sizeof(SSIBus),
19
};
20

  
16 21
static void ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
17 22
{
18 23
    SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev);
......
33 38
{
34 39
    assert(info->qdev.size >= sizeof(SSISlave));
35 40
    info->qdev.init = ssi_slave_init;
36
    info->qdev.bus_type = BUS_TYPE_SSI;
41
    info->qdev.bus_info = &ssi_bus_info;
37 42
    qdev_register(&info->qdev);
38 43
}
39 44

  
......
48 53
SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
49 54
{
50 55
    BusState *bus;
51
    bus = qbus_create(BUS_TYPE_SSI, sizeof(SSIBus), parent, name);
56
    bus = qbus_create(&ssi_bus_info, parent, name);
52 57
    return FROM_QBUS(SSIBus, bus);
53 58
}
54 59

  
b/hw/sysbus.c
22 22
#include "sysemu.h"
23 23
#include "monitor.h"
24 24

  
25
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
26

  
27
struct BusInfo system_bus_info = {
28
    .name       = "System",
29
    .size       = sizeof(BusState),
30
    .print_dev  = sysbus_dev_print,
31
};
32

  
25 33
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
26 34
{
27 35
    assert(n >= 0 && n < dev->num_irq);
......
108 116
void sysbus_register_withprop(SysBusDeviceInfo *info)
109 117
{
110 118
    info->qdev.init = sysbus_device_init;
111
    info->qdev.bus_type = BUS_TYPE_SYSTEM;
119
    info->qdev.bus_info = &system_bus_info;
112 120

  
113 121
    assert(info->qdev.size >= sizeof(SysBusDevice));
114 122
    qdev_register(&info->qdev);
......
153 161
    return dev;
154 162
}
155 163

  
156
void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent)
164
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent)
157 165
{
158 166
    SysBusDevice *s = sysbus_from_qdev(dev);
159 167
    int i;

Also available in: Unified diff