1bfdec7f8SLaurent Vivier /*
2bfdec7f8SLaurent Vivier * qdev fw helpers
3bfdec7f8SLaurent Vivier *
4bfdec7f8SLaurent Vivier * This program is free software; you can redistribute it and/or modify
5bfdec7f8SLaurent Vivier * it under the terms of the GNU General Public License as published by
6bfdec7f8SLaurent Vivier * the Free Software Foundation; either version 2 of the License,
7bfdec7f8SLaurent Vivier * or (at your option) any later version.
8bfdec7f8SLaurent Vivier *
9bfdec7f8SLaurent Vivier * This program is distributed in the hope that it will be useful,
10bfdec7f8SLaurent Vivier * but WITHOUT ANY WARRANTY; without even the implied warranty of
11bfdec7f8SLaurent Vivier * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12bfdec7f8SLaurent Vivier * GNU General Public License for more details.
13bfdec7f8SLaurent Vivier *
14bfdec7f8SLaurent Vivier * You should have received a copy of the GNU General Public License
15bfdec7f8SLaurent Vivier * along with this program; if not, see <http://www.gnu.org/licenses/>.
16bfdec7f8SLaurent Vivier */
17bfdec7f8SLaurent Vivier
18bfdec7f8SLaurent Vivier #include "qemu/osdep.h"
19bfdec7f8SLaurent Vivier #include "hw/fw-path-provider.h"
20*a27bd6c7SMarkus Armbruster #include "hw/qdev-core.h"
21bfdec7f8SLaurent Vivier
qdev_fw_name(DeviceState * dev)22bfdec7f8SLaurent Vivier const char *qdev_fw_name(DeviceState *dev)
23bfdec7f8SLaurent Vivier {
24bfdec7f8SLaurent Vivier DeviceClass *dc = DEVICE_GET_CLASS(dev);
25bfdec7f8SLaurent Vivier
26bfdec7f8SLaurent Vivier if (dc->fw_name) {
27bfdec7f8SLaurent Vivier return dc->fw_name;
28bfdec7f8SLaurent Vivier }
29bfdec7f8SLaurent Vivier
30bfdec7f8SLaurent Vivier return object_get_typename(OBJECT(dev));
31bfdec7f8SLaurent Vivier }
32bfdec7f8SLaurent Vivier
bus_get_fw_dev_path(BusState * bus,DeviceState * dev)33bfdec7f8SLaurent Vivier static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
34bfdec7f8SLaurent Vivier {
35bfdec7f8SLaurent Vivier BusClass *bc = BUS_GET_CLASS(bus);
36bfdec7f8SLaurent Vivier
37bfdec7f8SLaurent Vivier if (bc->get_fw_dev_path) {
38bfdec7f8SLaurent Vivier return bc->get_fw_dev_path(dev);
39bfdec7f8SLaurent Vivier }
40bfdec7f8SLaurent Vivier
41bfdec7f8SLaurent Vivier return NULL;
42bfdec7f8SLaurent Vivier }
43bfdec7f8SLaurent Vivier
qdev_get_fw_dev_path_from_handler(BusState * bus,DeviceState * dev)44bfdec7f8SLaurent Vivier static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
45bfdec7f8SLaurent Vivier {
46bfdec7f8SLaurent Vivier Object *obj = OBJECT(dev);
47bfdec7f8SLaurent Vivier char *d = NULL;
48bfdec7f8SLaurent Vivier
49bfdec7f8SLaurent Vivier while (!d && obj->parent) {
50bfdec7f8SLaurent Vivier obj = obj->parent;
51bfdec7f8SLaurent Vivier d = fw_path_provider_try_get_dev_path(obj, bus, dev);
52bfdec7f8SLaurent Vivier }
53bfdec7f8SLaurent Vivier return d;
54bfdec7f8SLaurent Vivier }
55bfdec7f8SLaurent Vivier
qdev_get_own_fw_dev_path_from_handler(BusState * bus,DeviceState * dev)56bfdec7f8SLaurent Vivier char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
57bfdec7f8SLaurent Vivier {
58bfdec7f8SLaurent Vivier Object *obj = OBJECT(dev);
59bfdec7f8SLaurent Vivier
60bfdec7f8SLaurent Vivier return fw_path_provider_try_get_dev_path(obj, bus, dev);
61bfdec7f8SLaurent Vivier }
62bfdec7f8SLaurent Vivier
qdev_get_fw_dev_path_helper(DeviceState * dev,char * p,int size)63bfdec7f8SLaurent Vivier static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
64bfdec7f8SLaurent Vivier {
65bfdec7f8SLaurent Vivier int l = 0;
66bfdec7f8SLaurent Vivier
67bfdec7f8SLaurent Vivier if (dev && dev->parent_bus) {
68bfdec7f8SLaurent Vivier char *d;
69bfdec7f8SLaurent Vivier l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
70bfdec7f8SLaurent Vivier d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
71bfdec7f8SLaurent Vivier if (!d) {
72bfdec7f8SLaurent Vivier d = bus_get_fw_dev_path(dev->parent_bus, dev);
73bfdec7f8SLaurent Vivier }
74bfdec7f8SLaurent Vivier if (d) {
75bfdec7f8SLaurent Vivier l += snprintf(p + l, size - l, "%s", d);
76bfdec7f8SLaurent Vivier g_free(d);
77bfdec7f8SLaurent Vivier } else {
78bfdec7f8SLaurent Vivier return l;
79bfdec7f8SLaurent Vivier }
80bfdec7f8SLaurent Vivier }
81bfdec7f8SLaurent Vivier l += snprintf(p + l , size - l, "/");
82bfdec7f8SLaurent Vivier
83bfdec7f8SLaurent Vivier return l;
84bfdec7f8SLaurent Vivier }
85bfdec7f8SLaurent Vivier
qdev_get_fw_dev_path(DeviceState * dev)86bfdec7f8SLaurent Vivier char *qdev_get_fw_dev_path(DeviceState *dev)
87bfdec7f8SLaurent Vivier {
88bfdec7f8SLaurent Vivier char path[128];
89bfdec7f8SLaurent Vivier int l;
90bfdec7f8SLaurent Vivier
91bfdec7f8SLaurent Vivier l = qdev_get_fw_dev_path_helper(dev, path, 128);
92bfdec7f8SLaurent Vivier
93bfdec7f8SLaurent Vivier path[l - 1] = '\0';
94bfdec7f8SLaurent Vivier
95bfdec7f8SLaurent Vivier return g_strdup(path);
96bfdec7f8SLaurent Vivier }
97