Fix compiler warnings
[qemu.git] / hw / qdev.c
blobff2f0962ba95fd7a0286ea3b71171fbf289f7532
1 /*
2 * Dynamic device configuration and creation.
4 * Copyright (c) 2009 CodeSourcery
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 /* The theory here is that it should be possible to create a machine without
21 knowledge of specific devices. Historically board init routines have
22 passed a bunch of arguments to each device, requiring the board know
23 exactly which device it is dealing with. This file provides an abstract
24 API for device configuration and initialization. Devices will generally
25 inherit from a particular bus (e.g. PCI or I2C) rather than
26 this API directly. */
28 #include "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31 #include "monitor.h"
33 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
34 static BusState *main_system_bus;
36 static DeviceInfo *device_info_list;
38 static BusState *qbus_find_recursive(BusState *bus, const char *name,
39 const BusInfo *info);
40 static BusState *qbus_find(const char *path);
42 /* Register a new device type. */
43 void qdev_register(DeviceInfo *info)
45 assert(info->size >= sizeof(DeviceState));
46 assert(!info->next);
48 info->next = device_info_list;
49 device_info_list = info;
52 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
54 DeviceInfo *info;
56 /* first check device names */
57 for (info = device_info_list; info != NULL; info = info->next) {
58 if (bus_info && info->bus_info != bus_info)
59 continue;
60 if (strcmp(info->name, name) != 0)
61 continue;
62 return info;
65 /* failing that check the aliases */
66 for (info = device_info_list; info != NULL; info = info->next) {
67 if (bus_info && info->bus_info != bus_info)
68 continue;
69 if (!info->alias)
70 continue;
71 if (strcmp(info->alias, name) != 0)
72 continue;
73 return info;
75 return NULL;
78 /* Create a new device. This only initializes the device state structure
79 and allows properties to be set. qdev_init should be called to
80 initialize the actual device emulation. */
81 DeviceState *qdev_create(BusState *bus, const char *name)
83 DeviceInfo *info;
84 DeviceState *dev;
86 if (!bus) {
87 if (!main_system_bus) {
88 main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
90 bus = main_system_bus;
93 info = qdev_find_info(bus->info, name);
94 if (!info) {
95 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
98 dev = qemu_mallocz(info->size);
99 dev->info = info;
100 dev->parent_bus = bus;
101 qdev_prop_set_defaults(dev, dev->info->props);
102 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
103 qdev_prop_set_compat(dev);
104 LIST_INSERT_HEAD(&bus->children, dev, sibling);
105 return dev;
108 static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
110 int pos = 0;
111 int ret;
113 ret = snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
114 info->name, info->bus_info->name);
115 pos += MIN(len-pos,ret);
116 if (info->alias) {
117 ret = snprintf(dest+pos, len-pos, ", alias \"%s\"", info->alias);
118 pos += MIN(len-pos,ret);
120 if (info->desc) {
121 ret = snprintf(dest+pos, len-pos, ", desc \"%s\"", info->desc);
122 pos += MIN(len-pos,ret);
124 if (info->no_user) {
125 ret = snprintf(dest+pos, len-pos, ", no-user");
126 pos += MIN(len-pos,ret);
128 return pos;
131 static int set_property(const char *name, const char *value, void *opaque)
133 DeviceState *dev = opaque;
135 if (strcmp(name, "driver") == 0)
136 return 0;
137 if (strcmp(name, "bus") == 0)
138 return 0;
140 if (-1 == qdev_prop_parse(dev, name, value)) {
141 qemu_error("can't set property \"%s\" to \"%s\" for \"%s\"\n",
142 name, value, dev->info->name);
143 return -1;
145 return 0;
148 DeviceState *qdev_device_add(QemuOpts *opts)
150 const char *driver, *path, *id;
151 DeviceInfo *info;
152 DeviceState *qdev;
153 BusState *bus;
155 driver = qemu_opt_get(opts, "driver");
156 if (!driver) {
157 qemu_error("-device: no driver specified\n");
158 return NULL;
160 if (strcmp(driver, "?") == 0) {
161 char msg[256];
162 for (info = device_info_list; info != NULL; info = info->next) {
163 qdev_print_devinfo(info, msg, sizeof(msg));
164 qemu_error("%s\n", msg);
166 return NULL;
169 /* find driver */
170 info = qdev_find_info(NULL, driver);
171 if (!info) {
172 qemu_error("Device \"%s\" not found. Try -device '?' for a list.\n",
173 driver);
174 return NULL;
176 if (info->no_user) {
177 qemu_error("device \"%s\" can't be added via command line\n",
178 info->name);
179 return NULL;
182 /* find bus */
183 path = qemu_opt_get(opts, "bus");
184 if (path != NULL) {
185 bus = qbus_find(path);
186 } else {
187 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
189 if (!bus)
190 return NULL;
192 /* create device, set properties */
193 qdev = qdev_create(bus, driver);
194 id = qemu_opts_id(opts);
195 if (id) {
196 qdev->id = id;
198 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
199 qdev_free(qdev);
200 return NULL;
202 if (qdev_init(qdev) != 0) {
203 qdev_free(qdev);
204 return NULL;
206 return qdev;
209 /* Initialize a device. Device properties should be set before calling
210 this function. IRQs and MMIO regions should be connected/mapped after
211 calling this function. */
212 int qdev_init(DeviceState *dev)
214 return dev->info->init(dev, dev->info);
217 /* Unlink device from bus and free the structure. */
218 void qdev_free(DeviceState *dev)
220 LIST_REMOVE(dev, sibling);
221 qemu_free(dev);
224 /* Get a character (serial) device interface. */
225 CharDriverState *qdev_init_chardev(DeviceState *dev)
227 static int next_serial;
228 static int next_virtconsole;
229 /* FIXME: This is a nasty hack that needs to go away. */
230 if (strncmp(dev->info->name, "virtio", 6) == 0) {
231 return virtcon_hds[next_virtconsole++];
232 } else {
233 return serial_hds[next_serial++];
237 BusState *qdev_get_parent_bus(DeviceState *dev)
239 return dev->parent_bus;
242 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
244 assert(dev->num_gpio_in == 0);
245 dev->num_gpio_in = n;
246 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
249 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
251 assert(dev->num_gpio_out == 0);
252 dev->num_gpio_out = n;
253 dev->gpio_out = pins;
256 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
258 assert(n >= 0 && n < dev->num_gpio_in);
259 return dev->gpio_in[n];
262 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
264 assert(n >= 0 && n < dev->num_gpio_out);
265 dev->gpio_out[n] = pin;
268 VLANClientState *qdev_get_vlan_client(DeviceState *dev,
269 NetCanReceive *can_receive,
270 NetReceive *receive,
271 NetReceiveIOV *receive_iov,
272 NetCleanup *cleanup,
273 void *opaque)
275 NICInfo *nd = dev->nd;
276 assert(nd);
277 nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
278 receive, receive_iov, cleanup, opaque);
279 return nd->vc;
283 void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
285 memcpy(macaddr, dev->nd->macaddr, 6);
288 static int next_block_unit[IF_COUNT];
290 /* Get a block device. This should only be used for single-drive devices
291 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
292 appropriate bus. */
293 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
295 int unit = next_block_unit[type]++;
296 DriveInfo *dinfo;
298 dinfo = drive_get(type, 0, unit);
299 return dinfo ? dinfo->bdrv : NULL;
302 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
304 BusState *bus;
306 LIST_FOREACH(bus, &dev->child_bus, sibling) {
307 if (strcmp(name, bus->name) == 0) {
308 return bus;
311 return NULL;
314 static int next_scsi_bus;
316 /* Create a scsi bus, and attach devices to it. */
317 /* TODO: Actually create a scsi bus for hotplug to use. */
318 void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
320 int bus = next_scsi_bus++;
321 int unit;
322 DriveInfo *dinfo;
324 for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
325 dinfo = drive_get(IF_SCSI, bus, unit);
326 if (!dinfo) {
327 continue;
329 attach(host, dinfo->bdrv, unit);
333 static BusState *qbus_find_recursive(BusState *bus, const char *name,
334 const BusInfo *info)
336 DeviceState *dev;
337 BusState *child, *ret;
338 int match = 1;
340 if (name && (strcmp(bus->name, name) != 0)) {
341 match = 0;
343 if (info && (bus->info != info)) {
344 match = 0;
346 if (match) {
347 return bus;
350 LIST_FOREACH(dev, &bus->children, sibling) {
351 LIST_FOREACH(child, &dev->child_bus, sibling) {
352 ret = qbus_find_recursive(child, name, info);
353 if (ret) {
354 return ret;
358 return NULL;
361 static void qbus_list_bus(DeviceState *dev, char *dest, int len)
363 BusState *child;
364 const char *sep = " ";
365 int pos = 0;
367 pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
368 dev->id ? dev->id : dev->info->name);
369 LIST_FOREACH(child, &dev->child_bus, sibling) {
370 pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
371 sep = ", ";
375 static void qbus_list_dev(BusState *bus, char *dest, int len)
377 DeviceState *dev;
378 const char *sep = " ";
379 int pos = 0;
381 pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
382 bus->name);
383 LIST_FOREACH(dev, &bus->children, sibling) {
384 pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
385 sep, dev->info->name);
386 if (dev->id)
387 pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
388 sep = ", ";
392 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
394 BusState *child;
396 LIST_FOREACH(child, &dev->child_bus, sibling) {
397 if (strcmp(child->name, elem) == 0) {
398 return child;
401 return NULL;
404 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
406 DeviceState *dev;
409 * try to match in order:
410 * (1) instance id, if present
411 * (2) driver name
412 * (3) driver alias, if present
414 LIST_FOREACH(dev, &bus->children, sibling) {
415 if (dev->id && strcmp(dev->id, elem) == 0) {
416 return dev;
419 LIST_FOREACH(dev, &bus->children, sibling) {
420 if (strcmp(dev->info->name, elem) == 0) {
421 return dev;
424 LIST_FOREACH(dev, &bus->children, sibling) {
425 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
426 return dev;
429 return NULL;
432 static BusState *qbus_find(const char *path)
434 DeviceState *dev;
435 BusState *bus;
436 char elem[128], msg[256];
437 int pos, len;
439 /* find start element */
440 if (path[0] == '/') {
441 bus = main_system_bus;
442 pos = 0;
443 } else {
444 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
445 qemu_error("path parse error (\"%s\")\n", path);
446 return NULL;
448 bus = qbus_find_recursive(main_system_bus, elem, NULL);
449 if (!bus) {
450 qemu_error("bus \"%s\" not found\n", elem);
451 return NULL;
453 pos = len;
456 for (;;) {
457 if (path[pos] == '\0') {
458 /* we are done */
459 return bus;
462 /* find device */
463 if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
464 qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
465 return NULL;
467 pos += len;
468 dev = qbus_find_dev(bus, elem);
469 if (!dev) {
470 qbus_list_dev(bus, msg, sizeof(msg));
471 qemu_error("device \"%s\" not found\n%s\n", elem, msg);
472 return NULL;
474 if (path[pos] == '\0') {
475 /* last specified element is a device. If it has exactly
476 * one child bus accept it nevertheless */
477 switch (dev->num_child_bus) {
478 case 0:
479 qemu_error("device has no child bus (%s)\n", path);
480 return NULL;
481 case 1:
482 return LIST_FIRST(&dev->child_bus);
483 default:
484 qbus_list_bus(dev, msg, sizeof(msg));
485 qemu_error("device has multiple child busses (%s)\n%s\n",
486 path, msg);
487 return NULL;
491 /* find bus */
492 if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
493 qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
494 return NULL;
496 pos += len;
497 bus = qbus_find_bus(dev, elem);
498 if (!bus) {
499 qbus_list_bus(dev, msg, sizeof(msg));
500 qemu_error("child bus \"%s\" not found\n%s\n", elem, msg);
501 return NULL;
506 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
508 BusState *bus;
509 char *buf;
510 int i,len;
512 bus = qemu_mallocz(info->size);
513 bus->info = info;
514 bus->parent = parent;
516 if (name) {
517 /* use supplied name */
518 bus->name = qemu_strdup(name);
519 } else if (parent && parent->id) {
520 /* parent device has id -> use it for bus name */
521 len = strlen(parent->id) + 16;
522 buf = qemu_malloc(len);
523 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
524 bus->name = buf;
525 } else {
526 /* no id -> use lowercase bus type for bus name */
527 len = strlen(info->name) + 16;
528 buf = qemu_malloc(len);
529 len = snprintf(buf, len, "%s.%d", info->name,
530 parent ? parent->num_child_bus : 0);
531 for (i = 0; i < len; i++)
532 buf[i] = qemu_tolower(buf[i]);
533 bus->name = buf;
536 LIST_INIT(&bus->children);
537 if (parent) {
538 LIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
539 parent->num_child_bus++;
541 return bus;
544 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
545 static void qbus_print(Monitor *mon, BusState *bus, int indent);
547 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
548 const char *prefix, int indent)
550 char buf[64];
552 if (!props)
553 return;
554 while (props->name) {
555 if (props->info->print) {
556 props->info->print(dev, props, buf, sizeof(buf));
557 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
559 props++;
563 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
565 BusState *child;
566 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
567 dev->id ? dev->id : "");
568 indent += 2;
569 if (dev->num_gpio_in) {
570 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
572 if (dev->num_gpio_out) {
573 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
575 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
576 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
577 if (dev->parent_bus->info->print_dev)
578 dev->parent_bus->info->print_dev(mon, dev, indent);
579 LIST_FOREACH(child, &dev->child_bus, sibling) {
580 qbus_print(mon, child, indent);
584 static void qbus_print(Monitor *mon, BusState *bus, int indent)
586 struct DeviceState *dev;
588 qdev_printf("bus: %s\n", bus->name);
589 indent += 2;
590 qdev_printf("type %s\n", bus->info->name);
591 LIST_FOREACH(dev, &bus->children, sibling) {
592 qdev_print(mon, dev, indent);
595 #undef qdev_printf
597 void do_info_qtree(Monitor *mon)
599 if (main_system_bus)
600 qbus_print(mon, main_system_bus, 0);
603 void do_info_qdm(Monitor *mon)
605 DeviceInfo *info;
606 char msg[256];
608 for (info = device_info_list; info != NULL; info = info->next) {
609 qdev_print_devinfo(info, msg, sizeof(msg));
610 monitor_printf(mon, "%s\n", msg);