]> Git Repo - qemu.git/blob - hw/qdev.c
qom: register legacy properties as new style properties (v2)
[qemu.git] / hw / qdev.c
1 /*
2  *  Dynamic device configuration and creation.
3  *
4  *  Copyright (c) 2009 CodeSourcery
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
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.  */
27
28 #include "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31 #include "monitor.h"
32
33 static int qdev_hotplug = 0;
34 static bool qdev_hot_added = false;
35 static bool qdev_hot_removed = false;
36
37 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
38 static BusState *main_system_bus;
39 static void main_system_bus_create(void);
40
41 DeviceInfo *device_info_list;
42
43 static BusState *qbus_find_recursive(BusState *bus, const char *name,
44                                      const BusInfo *info);
45 static BusState *qbus_find(const char *path);
46
47 /* Register a new device type.  */
48 void qdev_register(DeviceInfo *info)
49 {
50     assert(info->size >= sizeof(DeviceState));
51     assert(!info->next);
52
53     info->next = device_info_list;
54     device_info_list = info;
55 }
56
57 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
58 {
59     DeviceInfo *info;
60
61     /* first check device names */
62     for (info = device_info_list; info != NULL; info = info->next) {
63         if (bus_info && info->bus_info != bus_info)
64             continue;
65         if (strcmp(info->name, name) != 0)
66             continue;
67         return info;
68     }
69
70     /* failing that check the aliases */
71     for (info = device_info_list; info != NULL; info = info->next) {
72         if (bus_info && info->bus_info != bus_info)
73             continue;
74         if (!info->alias)
75             continue;
76         if (strcmp(info->alias, name) != 0)
77             continue;
78         return info;
79     }
80     return NULL;
81 }
82
83 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
84 {
85     DeviceState *dev;
86     Property *prop;
87
88     assert(bus->info == info->bus_info);
89     dev = g_malloc0(info->size);
90     dev->info = info;
91     dev->parent_bus = bus;
92     qdev_prop_set_defaults(dev, dev->info->props);
93     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
94     qdev_prop_set_globals(dev);
95     QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
96     if (qdev_hotplug) {
97         assert(bus->allow_hotplug);
98         dev->hotplugged = 1;
99         qdev_hot_added = true;
100     }
101     dev->instance_id_alias = -1;
102     QTAILQ_INIT(&dev->properties);
103     dev->state = DEV_STATE_CREATED;
104
105     for (prop = dev->info->props; prop && prop->name; prop++) {
106         qdev_property_add_legacy(dev, prop, NULL);
107     }
108
109     for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
110         qdev_property_add_legacy(dev, prop, NULL);
111     }
112
113     return dev;
114 }
115
116 /* Create a new device.  This only initializes the device state structure
117    and allows properties to be set.  qdev_init should be called to
118    initialize the actual device emulation.  */
119 DeviceState *qdev_create(BusState *bus, const char *name)
120 {
121     DeviceState *dev;
122
123     dev = qdev_try_create(bus, name);
124     if (!dev) {
125         if (bus) {
126             hw_error("Unknown device '%s' for bus '%s'\n", name,
127                      bus->info->name);
128         } else {
129             hw_error("Unknown device '%s' for default sysbus\n", name);
130         }
131     }
132
133     return dev;
134 }
135
136 DeviceState *qdev_try_create(BusState *bus, const char *name)
137 {
138     DeviceInfo *info;
139
140     if (!bus) {
141         bus = sysbus_get_default();
142     }
143
144     info = qdev_find_info(bus->info, name);
145     if (!info) {
146         return NULL;
147     }
148
149     return qdev_create_from_info(bus, info);
150 }
151
152 static void qdev_print_devinfo(DeviceInfo *info)
153 {
154     error_printf("name \"%s\", bus %s",
155                  info->name, info->bus_info->name);
156     if (info->alias) {
157         error_printf(", alias \"%s\"", info->alias);
158     }
159     if (info->desc) {
160         error_printf(", desc \"%s\"", info->desc);
161     }
162     if (info->no_user) {
163         error_printf(", no-user");
164     }
165     error_printf("\n");
166 }
167
168 static int set_property(const char *name, const char *value, void *opaque)
169 {
170     DeviceState *dev = opaque;
171
172     if (strcmp(name, "driver") == 0)
173         return 0;
174     if (strcmp(name, "bus") == 0)
175         return 0;
176
177     if (qdev_prop_parse(dev, name, value) == -1) {
178         return -1;
179     }
180     return 0;
181 }
182
183 int qdev_device_help(QemuOpts *opts)
184 {
185     const char *driver;
186     DeviceInfo *info;
187     Property *prop;
188
189     driver = qemu_opt_get(opts, "driver");
190     if (driver && !strcmp(driver, "?")) {
191         for (info = device_info_list; info != NULL; info = info->next) {
192             if (info->no_user) {
193                 continue;       /* not available, don't show */
194             }
195             qdev_print_devinfo(info);
196         }
197         return 1;
198     }
199
200     if (!driver || !qemu_opt_get(opts, "?")) {
201         return 0;
202     }
203
204     info = qdev_find_info(NULL, driver);
205     if (!info) {
206         return 0;
207     }
208
209     for (prop = info->props; prop && prop->name; prop++) {
210         /*
211          * TODO Properties without a parser are just for dirty hacks.
212          * qdev_prop_ptr is the only such PropertyInfo.  It's marked
213          * for removal.  This conditional should be removed along with
214          * it.
215          */
216         if (!prop->info->parse) {
217             continue;           /* no way to set it, don't show */
218         }
219         error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
220     }
221     for (prop = info->bus_info->props; prop && prop->name; prop++) {
222         if (!prop->info->parse) {
223             continue;           /* no way to set it, don't show */
224         }
225         error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
226     }
227     return 1;
228 }
229
230 DeviceState *qdev_device_add(QemuOpts *opts)
231 {
232     const char *driver, *path, *id;
233     DeviceInfo *info;
234     DeviceState *qdev;
235     BusState *bus;
236
237     driver = qemu_opt_get(opts, "driver");
238     if (!driver) {
239         qerror_report(QERR_MISSING_PARAMETER, "driver");
240         return NULL;
241     }
242
243     /* find driver */
244     info = qdev_find_info(NULL, driver);
245     if (!info || info->no_user) {
246         qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
247         error_printf_unless_qmp("Try with argument '?' for a list.\n");
248         return NULL;
249     }
250
251     /* find bus */
252     path = qemu_opt_get(opts, "bus");
253     if (path != NULL) {
254         bus = qbus_find(path);
255         if (!bus) {
256             return NULL;
257         }
258         if (bus->info != info->bus_info) {
259             qerror_report(QERR_BAD_BUS_FOR_DEVICE,
260                            driver, bus->info->name);
261             return NULL;
262         }
263     } else {
264         bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
265         if (!bus) {
266             qerror_report(QERR_NO_BUS_FOR_DEVICE,
267                            info->name, info->bus_info->name);
268             return NULL;
269         }
270     }
271     if (qdev_hotplug && !bus->allow_hotplug) {
272         qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
273         return NULL;
274     }
275
276     /* create device, set properties */
277     qdev = qdev_create_from_info(bus, info);
278     id = qemu_opts_id(opts);
279     if (id) {
280         qdev->id = id;
281     }
282     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
283         qdev_free(qdev);
284         return NULL;
285     }
286     if (qdev_init(qdev) < 0) {
287         qerror_report(QERR_DEVICE_INIT_FAILED, driver);
288         return NULL;
289     }
290     qdev->opts = opts;
291     return qdev;
292 }
293
294 /* Initialize a device.  Device properties should be set before calling
295    this function.  IRQs and MMIO regions should be connected/mapped after
296    calling this function.
297    On failure, destroy the device and return negative value.
298    Return 0 on success.  */
299 int qdev_init(DeviceState *dev)
300 {
301     int rc;
302
303     assert(dev->state == DEV_STATE_CREATED);
304     rc = dev->info->init(dev, dev->info);
305     if (rc < 0) {
306         qdev_free(dev);
307         return rc;
308     }
309     if (dev->info->vmsd) {
310         vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
311                                        dev->instance_id_alias,
312                                        dev->alias_required_for_version);
313     }
314     dev->state = DEV_STATE_INITIALIZED;
315     if (dev->hotplugged && dev->info->reset) {
316         dev->info->reset(dev);
317     }
318     return 0;
319 }
320
321 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
322                                  int required_for_version)
323 {
324     assert(dev->state == DEV_STATE_CREATED);
325     dev->instance_id_alias = alias_id;
326     dev->alias_required_for_version = required_for_version;
327 }
328
329 int qdev_unplug(DeviceState *dev)
330 {
331     if (!dev->parent_bus->allow_hotplug) {
332         qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
333         return -1;
334     }
335     assert(dev->info->unplug != NULL);
336
337     if (dev->ref != 0) {
338         qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
339         return -1;
340     }
341
342     qdev_hot_removed = true;
343
344     return dev->info->unplug(dev);
345 }
346
347 static int qdev_reset_one(DeviceState *dev, void *opaque)
348 {
349     if (dev->info->reset) {
350         dev->info->reset(dev);
351     }
352
353     return 0;
354 }
355
356 BusState *sysbus_get_default(void)
357 {
358     if (!main_system_bus) {
359         main_system_bus_create();
360     }
361     return main_system_bus;
362 }
363
364 static int qbus_reset_one(BusState *bus, void *opaque)
365 {
366     if (bus->info->reset) {
367         return bus->info->reset(bus);
368     }
369     return 0;
370 }
371
372 void qdev_reset_all(DeviceState *dev)
373 {
374     qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
375 }
376
377 void qbus_reset_all_fn(void *opaque)
378 {
379     BusState *bus = opaque;
380     qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
381 }
382
383 /* can be used as ->unplug() callback for the simple cases */
384 int qdev_simple_unplug_cb(DeviceState *dev)
385 {
386     /* just zap it */
387     qdev_free(dev);
388     return 0;
389 }
390
391
392 /* Like qdev_init(), but terminate program via error_report() instead of
393    returning an error value.  This is okay during machine creation.
394    Don't use for hotplug, because there callers need to recover from
395    failure.  Exception: if you know the device's init() callback can't
396    fail, then qdev_init_nofail() can't fail either, and is therefore
397    usable even then.  But relying on the device implementation that
398    way is somewhat unclean, and best avoided.  */
399 void qdev_init_nofail(DeviceState *dev)
400 {
401     DeviceInfo *info = dev->info;
402
403     if (qdev_init(dev) < 0) {
404         error_report("Initialization of device %s failed", info->name);
405         exit(1);
406     }
407 }
408
409 static void qdev_property_del_all(DeviceState *dev)
410 {
411     while (!QTAILQ_EMPTY(&dev->properties)) {
412         DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
413
414         QTAILQ_REMOVE(&dev->properties, prop, node);
415
416         if (prop->release) {
417             prop->release(dev, prop->name, prop->opaque);
418         }
419
420         g_free(prop->name);
421         g_free(prop->type);
422         g_free(prop);
423     }
424 }
425
426 /* Unlink device from bus and free the structure.  */
427 void qdev_free(DeviceState *dev)
428 {
429     BusState *bus;
430     Property *prop;
431
432     qdev_property_del_all(dev);
433
434     if (dev->state == DEV_STATE_INITIALIZED) {
435         while (dev->num_child_bus) {
436             bus = QLIST_FIRST(&dev->child_bus);
437             qbus_free(bus);
438         }
439         if (dev->info->vmsd)
440             vmstate_unregister(dev, dev->info->vmsd, dev);
441         if (dev->info->exit)
442             dev->info->exit(dev);
443         if (dev->opts)
444             qemu_opts_del(dev->opts);
445     }
446     QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
447     for (prop = dev->info->props; prop && prop->name; prop++) {
448         if (prop->info->free) {
449             prop->info->free(dev, prop);
450         }
451     }
452     g_free(dev);
453 }
454
455 void qdev_machine_creation_done(void)
456 {
457     /*
458      * ok, initial machine setup is done, starting from now we can
459      * only create hotpluggable devices
460      */
461     qdev_hotplug = 1;
462 }
463
464 bool qdev_machine_modified(void)
465 {
466     return qdev_hot_added || qdev_hot_removed;
467 }
468
469 /* Get a character (serial) device interface.  */
470 CharDriverState *qdev_init_chardev(DeviceState *dev)
471 {
472     static int next_serial;
473
474     /* FIXME: This function needs to go away: use chardev properties!  */
475     return serial_hds[next_serial++];
476 }
477
478 BusState *qdev_get_parent_bus(DeviceState *dev)
479 {
480     return dev->parent_bus;
481 }
482
483 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
484 {
485     assert(dev->num_gpio_in == 0);
486     dev->num_gpio_in = n;
487     dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
488 }
489
490 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
491 {
492     assert(dev->num_gpio_out == 0);
493     dev->num_gpio_out = n;
494     dev->gpio_out = pins;
495 }
496
497 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
498 {
499     assert(n >= 0 && n < dev->num_gpio_in);
500     return dev->gpio_in[n];
501 }
502
503 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
504 {
505     assert(n >= 0 && n < dev->num_gpio_out);
506     dev->gpio_out[n] = pin;
507 }
508
509 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
510 {
511     qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
512     if (nd->vlan)
513         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
514     if (nd->netdev)
515         qdev_prop_set_netdev(dev, "netdev", nd->netdev);
516     if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
517         qdev_prop_exists(dev, "vectors")) {
518         qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
519     }
520     nd->instantiated = 1;
521 }
522
523 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
524 {
525     BusState *bus;
526
527     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
528         if (strcmp(name, bus->name) == 0) {
529             return bus;
530         }
531     }
532     return NULL;
533 }
534
535 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
536                        qbus_walkerfn *busfn, void *opaque)
537 {
538     DeviceState *dev;
539     int err;
540
541     if (busfn) {
542         err = busfn(bus, opaque);
543         if (err) {
544             return err;
545         }
546     }
547
548     QTAILQ_FOREACH(dev, &bus->children, sibling) {
549         err = qdev_walk_children(dev, devfn, busfn, opaque);
550         if (err < 0) {
551             return err;
552         }
553     }
554
555     return 0;
556 }
557
558 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
559                        qbus_walkerfn *busfn, void *opaque)
560 {
561     BusState *bus;
562     int err;
563
564     if (devfn) {
565         err = devfn(dev, opaque);
566         if (err) {
567             return err;
568         }
569     }
570
571     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
572         err = qbus_walk_children(bus, devfn, busfn, opaque);
573         if (err < 0) {
574             return err;
575         }
576     }
577
578     return 0;
579 }
580
581 static BusState *qbus_find_recursive(BusState *bus, const char *name,
582                                      const BusInfo *info)
583 {
584     DeviceState *dev;
585     BusState *child, *ret;
586     int match = 1;
587
588     if (name && (strcmp(bus->name, name) != 0)) {
589         match = 0;
590     }
591     if (info && (bus->info != info)) {
592         match = 0;
593     }
594     if (match) {
595         return bus;
596     }
597
598     QTAILQ_FOREACH(dev, &bus->children, sibling) {
599         QLIST_FOREACH(child, &dev->child_bus, sibling) {
600             ret = qbus_find_recursive(child, name, info);
601             if (ret) {
602                 return ret;
603             }
604         }
605     }
606     return NULL;
607 }
608
609 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
610 {
611     DeviceState *dev, *ret;
612     BusState *child;
613
614     QTAILQ_FOREACH(dev, &bus->children, sibling) {
615         if (dev->id && strcmp(dev->id, id) == 0)
616             return dev;
617         QLIST_FOREACH(child, &dev->child_bus, sibling) {
618             ret = qdev_find_recursive(child, id);
619             if (ret) {
620                 return ret;
621             }
622         }
623     }
624     return NULL;
625 }
626
627 static void qbus_list_bus(DeviceState *dev)
628 {
629     BusState *child;
630     const char *sep = " ";
631
632     error_printf("child busses at \"%s\":",
633                  dev->id ? dev->id : dev->info->name);
634     QLIST_FOREACH(child, &dev->child_bus, sibling) {
635         error_printf("%s\"%s\"", sep, child->name);
636         sep = ", ";
637     }
638     error_printf("\n");
639 }
640
641 static void qbus_list_dev(BusState *bus)
642 {
643     DeviceState *dev;
644     const char *sep = " ";
645
646     error_printf("devices at \"%s\":", bus->name);
647     QTAILQ_FOREACH(dev, &bus->children, sibling) {
648         error_printf("%s\"%s\"", sep, dev->info->name);
649         if (dev->id)
650             error_printf("/\"%s\"", dev->id);
651         sep = ", ";
652     }
653     error_printf("\n");
654 }
655
656 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
657 {
658     BusState *child;
659
660     QLIST_FOREACH(child, &dev->child_bus, sibling) {
661         if (strcmp(child->name, elem) == 0) {
662             return child;
663         }
664     }
665     return NULL;
666 }
667
668 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
669 {
670     DeviceState *dev;
671
672     /*
673      * try to match in order:
674      *   (1) instance id, if present
675      *   (2) driver name
676      *   (3) driver alias, if present
677      */
678     QTAILQ_FOREACH(dev, &bus->children, sibling) {
679         if (dev->id  &&  strcmp(dev->id, elem) == 0) {
680             return dev;
681         }
682     }
683     QTAILQ_FOREACH(dev, &bus->children, sibling) {
684         if (strcmp(dev->info->name, elem) == 0) {
685             return dev;
686         }
687     }
688     QTAILQ_FOREACH(dev, &bus->children, sibling) {
689         if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
690             return dev;
691         }
692     }
693     return NULL;
694 }
695
696 static BusState *qbus_find(const char *path)
697 {
698     DeviceState *dev;
699     BusState *bus;
700     char elem[128];
701     int pos, len;
702
703     /* find start element */
704     if (path[0] == '/') {
705         bus = main_system_bus;
706         pos = 0;
707     } else {
708         if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
709             assert(!path[0]);
710             elem[0] = len = 0;
711         }
712         bus = qbus_find_recursive(main_system_bus, elem, NULL);
713         if (!bus) {
714             qerror_report(QERR_BUS_NOT_FOUND, elem);
715             return NULL;
716         }
717         pos = len;
718     }
719
720     for (;;) {
721         assert(path[pos] == '/' || !path[pos]);
722         while (path[pos] == '/') {
723             pos++;
724         }
725         if (path[pos] == '\0') {
726             return bus;
727         }
728
729         /* find device */
730         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
731             assert(0);
732             elem[0] = len = 0;
733         }
734         pos += len;
735         dev = qbus_find_dev(bus, elem);
736         if (!dev) {
737             qerror_report(QERR_DEVICE_NOT_FOUND, elem);
738             if (!monitor_cur_is_qmp()) {
739                 qbus_list_dev(bus);
740             }
741             return NULL;
742         }
743
744         assert(path[pos] == '/' || !path[pos]);
745         while (path[pos] == '/') {
746             pos++;
747         }
748         if (path[pos] == '\0') {
749             /* last specified element is a device.  If it has exactly
750              * one child bus accept it nevertheless */
751             switch (dev->num_child_bus) {
752             case 0:
753                 qerror_report(QERR_DEVICE_NO_BUS, elem);
754                 return NULL;
755             case 1:
756                 return QLIST_FIRST(&dev->child_bus);
757             default:
758                 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
759                 if (!monitor_cur_is_qmp()) {
760                     qbus_list_bus(dev);
761                 }
762                 return NULL;
763             }
764         }
765
766         /* find bus */
767         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
768             assert(0);
769             elem[0] = len = 0;
770         }
771         pos += len;
772         bus = qbus_find_bus(dev, elem);
773         if (!bus) {
774             qerror_report(QERR_BUS_NOT_FOUND, elem);
775             if (!monitor_cur_is_qmp()) {
776                 qbus_list_bus(dev);
777             }
778             return NULL;
779         }
780     }
781 }
782
783 void qbus_create_inplace(BusState *bus, BusInfo *info,
784                          DeviceState *parent, const char *name)
785 {
786     char *buf;
787     int i,len;
788
789     bus->info = info;
790     bus->parent = parent;
791
792     if (name) {
793         /* use supplied name */
794         bus->name = g_strdup(name);
795     } else if (parent && parent->id) {
796         /* parent device has id -> use it for bus name */
797         len = strlen(parent->id) + 16;
798         buf = g_malloc(len);
799         snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
800         bus->name = buf;
801     } else {
802         /* no id -> use lowercase bus type for bus name */
803         len = strlen(info->name) + 16;
804         buf = g_malloc(len);
805         len = snprintf(buf, len, "%s.%d", info->name,
806                        parent ? parent->num_child_bus : 0);
807         for (i = 0; i < len; i++)
808             buf[i] = qemu_tolower(buf[i]);
809         bus->name = buf;
810     }
811
812     QTAILQ_INIT(&bus->children);
813     if (parent) {
814         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
815         parent->num_child_bus++;
816     } else if (bus != main_system_bus) {
817         /* TODO: once all bus devices are qdevified,
818            only reset handler for main_system_bus should be registered here. */
819         qemu_register_reset(qbus_reset_all_fn, bus);
820     }
821 }
822
823 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
824 {
825     BusState *bus;
826
827     bus = g_malloc0(info->size);
828     bus->qdev_allocated = 1;
829     qbus_create_inplace(bus, info, parent, name);
830     return bus;
831 }
832
833 static void main_system_bus_create(void)
834 {
835     /* assign main_system_bus before qbus_create_inplace()
836      * in order to make "if (bus != main_system_bus)" work */
837     main_system_bus = g_malloc0(system_bus_info.size);
838     main_system_bus->qdev_allocated = 1;
839     qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
840                         "main-system-bus");
841 }
842
843 void qbus_free(BusState *bus)
844 {
845     DeviceState *dev;
846
847     while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
848         qdev_free(dev);
849     }
850     if (bus->parent) {
851         QLIST_REMOVE(bus, sibling);
852         bus->parent->num_child_bus--;
853     } else {
854         assert(bus != main_system_bus); /* main_system_bus is never freed */
855         qemu_unregister_reset(qbus_reset_all_fn, bus);
856     }
857     g_free((void*)bus->name);
858     if (bus->qdev_allocated) {
859         g_free(bus);
860     }
861 }
862
863 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
864 static void qbus_print(Monitor *mon, BusState *bus, int indent);
865
866 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
867                              const char *prefix, int indent)
868 {
869     char buf[64];
870
871     if (!props)
872         return;
873     while (props->name) {
874         /*
875          * TODO Properties without a print method are just for dirty
876          * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
877          * marked for removal.  The test props->info->print should be
878          * removed along with it.
879          */
880         if (props->info->print) {
881             props->info->print(dev, props, buf, sizeof(buf));
882             qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
883         }
884         props++;
885     }
886 }
887
888 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
889 {
890     BusState *child;
891     qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
892                 dev->id ? dev->id : "");
893     indent += 2;
894     if (dev->num_gpio_in) {
895         qdev_printf("gpio-in %d\n", dev->num_gpio_in);
896     }
897     if (dev->num_gpio_out) {
898         qdev_printf("gpio-out %d\n", dev->num_gpio_out);
899     }
900     qdev_print_props(mon, dev, dev->info->props, "dev", indent);
901     qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
902     if (dev->parent_bus->info->print_dev)
903         dev->parent_bus->info->print_dev(mon, dev, indent);
904     QLIST_FOREACH(child, &dev->child_bus, sibling) {
905         qbus_print(mon, child, indent);
906     }
907 }
908
909 static void qbus_print(Monitor *mon, BusState *bus, int indent)
910 {
911     struct DeviceState *dev;
912
913     qdev_printf("bus: %s\n", bus->name);
914     indent += 2;
915     qdev_printf("type %s\n", bus->info->name);
916     QTAILQ_FOREACH(dev, &bus->children, sibling) {
917         qdev_print(mon, dev, indent);
918     }
919 }
920 #undef qdev_printf
921
922 void do_info_qtree(Monitor *mon)
923 {
924     if (main_system_bus)
925         qbus_print(mon, main_system_bus, 0);
926 }
927
928 void do_info_qdm(Monitor *mon)
929 {
930     DeviceInfo *info;
931
932     for (info = device_info_list; info != NULL; info = info->next) {
933         qdev_print_devinfo(info);
934     }
935 }
936
937 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
938 {
939     QemuOpts *opts;
940
941     opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
942     if (!opts) {
943         return -1;
944     }
945     if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
946         qemu_opts_del(opts);
947         return 0;
948     }
949     if (!qdev_device_add(opts)) {
950         qemu_opts_del(opts);
951         return -1;
952     }
953     return 0;
954 }
955
956 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
957 {
958     const char *id = qdict_get_str(qdict, "id");
959     DeviceState *dev;
960
961     dev = qdev_find_recursive(main_system_bus, id);
962     if (NULL == dev) {
963         qerror_report(QERR_DEVICE_NOT_FOUND, id);
964         return -1;
965     }
966     return qdev_unplug(dev);
967 }
968
969 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
970 {
971     int l = 0;
972
973     if (dev && dev->parent_bus) {
974         char *d;
975         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
976         if (dev->parent_bus->info->get_fw_dev_path) {
977             d = dev->parent_bus->info->get_fw_dev_path(dev);
978             l += snprintf(p + l, size - l, "%s", d);
979             g_free(d);
980         } else {
981             l += snprintf(p + l, size - l, "%s", dev->info->name);
982         }
983     }
984     l += snprintf(p + l , size - l, "/");
985
986     return l;
987 }
988
989 char* qdev_get_fw_dev_path(DeviceState *dev)
990 {
991     char path[128];
992     int l;
993
994     l = qdev_get_fw_dev_path_helper(dev, path, 128);
995
996     path[l-1] = '\0';
997
998     return strdup(path);
999 }
1000
1001 void qdev_ref(DeviceState *dev)
1002 {
1003     dev->ref++;
1004 }
1005
1006 void qdev_unref(DeviceState *dev)
1007 {
1008     g_assert(dev->ref > 0);
1009     dev->ref--;
1010 }
1011
1012 void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1013                        DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1014                        DevicePropertyRelease *release,
1015                        void *opaque, Error **errp)
1016 {
1017     DeviceProperty *prop = g_malloc0(sizeof(*prop));
1018
1019     prop->name = g_strdup(name);
1020     prop->type = g_strdup(type);
1021
1022     prop->get = get;
1023     prop->set = set;
1024     prop->release = release;
1025     prop->opaque = opaque;
1026
1027     QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1028 }
1029
1030 static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1031 {
1032     DeviceProperty *prop;
1033
1034     QTAILQ_FOREACH(prop, &dev->properties, node) {
1035         if (strcmp(prop->name, name) == 0) {
1036             return prop;
1037         }
1038     }
1039
1040     return NULL;
1041 }
1042
1043 void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1044                        Error **errp)
1045 {
1046     DeviceProperty *prop = qdev_property_find(dev, name);
1047
1048     if (prop == NULL) {
1049         error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1050         return;
1051     }
1052
1053     if (!prop->get) {
1054         error_set(errp, QERR_PERMISSION_DENIED);
1055     } else {
1056         prop->get(dev, v, prop->opaque, name, errp);
1057     }
1058 }
1059
1060 void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1061                        Error **errp)
1062 {
1063     DeviceProperty *prop = qdev_property_find(dev, name);
1064
1065     if (prop == NULL) {
1066         error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1067         return;
1068     }
1069
1070     if (!prop->set) {
1071         error_set(errp, QERR_PERMISSION_DENIED);
1072     } else {
1073         prop->set(dev, prop->opaque, v, name, errp);
1074     }
1075 }
1076
1077 const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1078 {
1079     DeviceProperty *prop = qdev_property_find(dev, name);
1080
1081     if (prop == NULL) {
1082         error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1083         return NULL;
1084     }
1085
1086     return prop->type;
1087 }
1088
1089 /**
1090  * Legacy property handling
1091  */
1092
1093 static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1094                                      const char *name, Error **errp)
1095 {
1096     Property *prop = opaque;
1097
1098     if (prop->info->print) {
1099         char buffer[1024];
1100         char *ptr = buffer;
1101
1102         prop->info->print(dev, prop, buffer, sizeof(buffer));
1103         visit_type_str(v, &ptr, name, errp);
1104     } else {
1105         error_set(errp, QERR_PERMISSION_DENIED);
1106     }
1107 }
1108
1109 static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1110                                      const char *name, Error **errp)
1111 {
1112     Property *prop = opaque;
1113
1114     if (dev->state != DEV_STATE_CREATED) {
1115         error_set(errp, QERR_PERMISSION_DENIED);
1116         return;
1117     }
1118
1119     if (prop->info->parse) {
1120         Error *local_err = NULL;
1121         char *ptr = NULL;
1122
1123         visit_type_str(v, &ptr, name, &local_err);
1124         if (!local_err) {
1125             int ret;
1126             ret = prop->info->parse(dev, prop, ptr);
1127             if (ret != 0) {
1128                 error_set(errp, QERR_INVALID_PARAMETER_VALUE,
1129                           name, prop->info->name);
1130             }
1131             g_free(ptr);
1132         } else {
1133             error_propagate(errp, local_err);
1134         }
1135     } else {
1136         error_set(errp, QERR_PERMISSION_DENIED);
1137     }
1138 }
1139
1140 /**
1141  * @qdev_add_legacy_property - adds a legacy property
1142  *
1143  * Do not use this is new code!  Properties added through this interface will
1144  * be given types in the "legacy<>" type namespace.
1145  *
1146  * Legacy properties are always processed as strings.  The format of the string
1147  * depends on the property type.
1148  */
1149 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1150                               Error **errp)
1151 {
1152     gchar *type;
1153
1154     type = g_strdup_printf("legacy<%s>", prop->info->name);
1155
1156     qdev_property_add(dev, prop->name, type,
1157                       qdev_get_legacy_property,
1158                       qdev_set_legacy_property,
1159                       NULL,
1160                       prop, errp);
1161
1162     g_free(type);
1163 }
This page took 0.088477 seconds and 4 git commands to generate.